Selaa lähdekoodia

Merge branch 'storyID-260' into Update/migrate

# Conflicts:
#	package-lock.json
#	src/components/ChineseMedicine.vue
#	src/views/diagnosis/Prescribing.vue
#	vue.config.js
cc12458 2 viikkoa sitten
vanhempi
commit
24ea2175d6

+ 1 - 1
.env.production

@@ -1,6 +1,6 @@
 NODE_ENV = 'production'
 BASE_URL = './'
-VUE_APP_BASE_API = '/'
+VUE_APP_BASE_API = '/kd'
 #appid
 
 VUE_APP_CODE_IMG='http://101.133.232.97:8063/'

+ 110 - 0
public/data/classify.json

@@ -0,0 +1,110 @@
+{
+    "classify": [
+        {
+            "label": "艾灸疗法",
+            "value": "1"
+        },
+        {
+            "label": "非艾·疗法",
+            "value": "2"
+        },
+        {
+            "label": "拔罐疗法",
+            "value": "3"
+        },
+        {
+            "label": "针刺疗法",
+            "value": "4"
+        },
+        {
+            "label": "敷熨熏浴",
+            "value": "5"
+        },
+        {
+            "label": "推拿疗法",
+            "value": "6"
+        },
+        {
+            "label": "耳穴疗法",
+            "value": "7"
+        },
+        {
+            "label": "刮痧疗法",
+            "value": "8"
+        },
+        {
+            "label": "物理疗法",
+            "value": "9"
+        },
+        {
+            "label": "中医肛肠",
+            "value": "10"
+        },
+        {
+            "label": "中医微创",
+            "value": "11"
+        },
+        {
+            "label": "其他疗法",
+            "value": "12"
+        }
+    ],
+    "detailCumulative": [
+        {
+            "label": "穴位",
+            "value": "1"
+        },
+        {
+            "label": "部位",
+            "value": "2"
+        },
+        {
+            "label": "耳穴",
+            "value": "3"
+        },
+        {
+            "label": "经络",
+            "value": "4"
+        },
+        {
+            "label": "其他详情",
+            "value": "5"
+        }
+    ],
+    "detailDefault": [
+        {
+            "label": "穴位",
+            "value": "1"
+        },
+        {
+            "label": "部位",
+            "value": "2"
+        },
+        {
+            "label": "耳穴",
+            "value": "3"
+        },
+        {
+            "label": "经络",
+            "value": "4"
+        },
+        {
+            "label": "其他详情",
+            "value": "5"
+        },
+        {
+            "label": "无详情",
+            "value": "6"
+        }
+    ],
+    "singleNumber": [
+        {
+            "label": "默认1",
+            "value": "0"
+        },
+        {
+            "label": "详情累计/计数系数",
+            "value": "1"
+        }
+    ]
+}

+ 11 - 2
src/api/business.js

@@ -1,4 +1,5 @@
 import request from '@/utils/request.js'
+import {analysisAgency, analysisDelivery} from '@/model/transition';
 
 // 获取处方列表
 export function getRecipeList(data) {
@@ -123,7 +124,15 @@ export function getPharmacyMsg(data) {
     return request({
         url: `/basis/pharmacyMgr/${data}`,
         method: 'get'
-    })
+    }).then((res) => {
+      if (!res.Data) return res;
+      res.Data = {
+        ...res.Data,
+        ...analysisAgency(res.Data),
+        ...analysisDelivery(res.Data),
+      }
+      return res;
+    });
 };
 
 // 修改药房信息
@@ -456,4 +465,4 @@ export function getDepartTreeData(data) {
         method: 'post',
         data
     })
-}
+}

+ 4 - 1
src/api/city.js

@@ -25,7 +25,10 @@ export function getSelectType(data) {
     })
 };
 
-// 获取药房详细信息
+/**
+ * 获取药房详细信息
+ * @deprecated {@link @/api/business.js#getPharmacyMsg}
+ */
 export function getPharmacyMsg(data) {
     return request({
         url: `/basis/pharmacyMgr/${data}`,

+ 19 - 0
src/api/diagnosis.js

@@ -111,6 +111,25 @@ export function getPatiensBasisM(data) {
     }).then(res => removeRedundantSemicolons(res));
 };
 
+// 刷新电子病历信息
+export function refreshElectronicInfo(data) {
+  return request({
+    url: '/test/outpatient/refreshElectronicInfo?patientId=' + data.patientId,
+    method: 'post',
+    ignoreErrorMessage: '请重试',
+  }).then(res => {
+    if (res.ResultCode !== 0) throw Error(res.ResultInfo || `请重试`);
+    if (res.Data == null) throw Error(`暂无新数据,请稍后刷新`);
+    const {pulseDiagnosisReportVo, ..._data} = res.Data;
+    const data = removeRedundantSemicolons(_data);
+    return data.outpatientElectronicmedicalrecord != null ? data : {
+      outpatientElectronicmedicalrecord: data,
+      pulseDiagnosisReportVo,
+    };
+  });
+}
+
+
 // 获取表格 药品列表
 export function getTableDrug(data, isPurposeType = false) {
     if (isPurposeType) {

+ 125 - 0
src/api/nonDrug.js

@@ -0,0 +1,125 @@
+import request from '@/utils/request.js'
+// 获取非药物目录列表
+export function getNondrugList(data) {
+    return request({
+        url: '/basis/stitutionsnondrugMgr/nondrugCataloguelistPain?page=' + data.page + '&limit=' + data.limit,
+        method: 'post',
+        data
+    })
+};
+// 新增非药物目录
+export function addNondrugCatalog(data) {
+    return request({
+        url: '/basis/stitutionsnondrugMgr/addNondrugCatalog',
+        method: 'post',
+        data
+    })
+};
+// 修改非药物目录
+export function updateNondrugCatalog(data) {
+    return request({
+        url: '/basis/stitutionsnondrugMgr/updateNondrugCatalog',
+        method: 'post',
+        data
+    })
+};
+// 非药物治疗目录详情列表
+export function getCatalogDetailsList(data) {
+    return request({
+        url: '/basis/stitutionsnondrugMgr/catalogDetailsList?pageNum=' + data.pageNum + '&pageSize=' + data.pageSize,
+        method: 'post',
+        data
+    })
+};
+// 获取机构非药物目录列表
+export function getOrgNondrugList(data) {
+    return request({
+        url: '/basis/stitutionsnondrugMgr/listNondrugItem?page=' + data.page + '&limit=' + data.limit,
+        method: 'post',
+        data
+    })
+};
+// 新增机构非药物项目
+export function addNondrugItem(data) {
+    return request({
+        url: '/basis/stitutionsnondrugMgr/addNondrugItem',
+        method: 'post',
+        data
+    })
+};
+// 修改机构非药物项目
+export function updateNondrugItem(data) {
+    return request({
+        url: '/basis/stitutionsnondrugMgr/updateNondrugItem',
+        method: 'post',
+        data
+    })
+};
+// 机构非药物项目名称模糊查询
+export function materialQuery(data) {
+    return request({
+        url: '/basis/stitutionsnondrugMgr/materialQuery',
+        method: 'post',
+        data
+    })
+};
+// 批量删除机构非药物项目
+export function batchDeleteNondrugItem(data) {
+    return request({
+        url: '/basis/stitutionsnondrugMgr/batchDeleteNondrugItem?ids=' + data.ids,
+        method: 'post'
+    })
+};
+// 非药物治疗映射管理列表
+export function getNondrugMapList(data) {
+    return request({
+        url: '/basis/stitutionsnondrugMgr/mappingList?pageNum=' + data.pageNum + '&pageSize=' + data.pageSize,
+        method: 'post',
+        data
+    })
+};
+// 非药物自动映射
+export function autoMapNondrug(data) {
+    return request({
+        url: '/basis/stitutionsnondrugMgr/autoMapNondrug?basisNondrugcatalogueId=' + data.basisNondrugcatalogueId,
+        method: 'post'
+    })
+};
+// 非药物清除映射关系
+export function clearMapNondrug(data) {
+    return request({
+        url: '/basis/stitutionsnondrugMgr/clearNondrugMapping?basisNondrugcatalogueId=' + data.basisNondrugcatalogueId,
+        method: 'post'
+    })
+};
+// 导入非药物类目
+export function importNondrug(data) {
+    return request({
+        url: '/basis/stitutionsnondrugMgr/importnodrug?appid=' + (data.appid || '') + '&deptId=' + (data.deptId || '') + '&institutionCode=' + (data.institutionCode || '') + '&institutionName=' + (data.institutionName || ''),
+        method: 'post',
+        data: data.formData
+    })
+};
+// 非药物手动映射
+export function manualMapping(data) {
+    return request({
+        url: '/basis/stitutionsnondrugMgr/manualMapping',
+        method: 'post',
+        data
+    })
+};
+// 导出非药物类目
+export function exportNondrug(data) {
+    return request({
+        url: '/basis/stitutionsnondrugMgr/export?basisNondrugcatalogueId=' + data.basisNondrugcatalogueId,
+        method: 'Post',
+    })
+};
+// 下载非药物导入模版
+export function downloadNondrugTemplate() {
+    return request({
+        url: '/basis/stitutionsnondrugMgr/exportTemplate',
+        method: 'post',
+    })
+};
+

+ 12 - 11
src/components/ChineseMedicine.vue

@@ -413,7 +413,7 @@
                   </template>
                 </el-table-column>
 
-                <el-table-column label="操作" width="64">
+                <el-table-column label="操作" width="64" min-width="64" fixed="right">
                   <template slot-scope="scope">
                     <div class="operate" v-if="scope.row.name">
                       <div>
@@ -648,7 +648,7 @@
                   </template>
                 </el-table-column>
 
-                <el-table-column label="操作" width="64">
+                <el-table-column label="操作" width="64" min-width="64" fixed="right">
                   <template slot-scope="scope">
                     <div class="operate" v-if="scope.row.name">
                       <div>
@@ -969,7 +969,7 @@
   </div>
 </template>
 <script>
-import {getReasonableSafeMedicineDosageRange} from '@/request/api';
+import { getReasonableSafeMedicineDosageRange } from '@/request/api';
 import { addAccordData, getAccordShareList } from "@/api/business.js";
 import { getDataByKey } from "@/api/system.js";
 import accordEdit from "@/views/business/AccordEdit.vue";
@@ -977,9 +977,9 @@ import {
   getProver,
   getArea,
   getSelectType,
-  getPharmacyMsg,
   getPatAddress
 } from "@/api/city.js";
+import { getPharmacyMsg } from "@/api/business.js";
 import {
   getTableDrug,
   getAddressForHospital,
@@ -1333,7 +1333,7 @@ export default {
     doseFocus(scope) {
       let width = window.innerWidth;
       if (width > 800) {
-        if (scope.row.id % 2 == 0) {
+        /*if (scope.row.id % 2 == 0) {
           document.getElementsByClassName(
             "el-table__body-wrapper"
           )[1].style.overflow = "hidden";
@@ -1341,7 +1341,7 @@ export default {
           document.getElementsByClassName(
             "el-table__body-wrapper"
           )[0].style.overflow = "hidden";
-        }
+        }*/
       }
 
       this.doseId = scope.row.medid;
@@ -1940,7 +1940,7 @@ export default {
     clickName(scope) {
       if (medicineBlurTimer) clearTimeout(medicineBlurTimer);
       // 隐藏滚动条
-      if (scope.row.id % 2 == 0) {
+      /*if (scope.row.id % 2 == 0) {
         document.getElementsByClassName(
           "el-table__body-wrapper"
         )[1].style.overflow = "hidden";
@@ -1948,7 +1948,7 @@ export default {
         document.getElementsByClassName(
           "el-table__body-wrapper"
         )[0].style.overflow = "hidden";
-      }
+      }*/
       let index = scope.row.id ? scope.row.id - 1 : 0;
       this.index = index;
 
@@ -1966,7 +1966,7 @@ export default {
     // 输入框获取 药品列表
     searchDrug(e, scope) {
       // 隐藏滚动条
-      if (scope.row.id % 2 == 0) {
+      /*if (scope.row.id % 2 == 0) {
         document.getElementsByClassName(
           "el-table__body-wrapper"
         )[1].style.overflow = "hidden";
@@ -1974,7 +1974,7 @@ export default {
         document.getElementsByClassName(
           "el-table__body-wrapper"
         )[0].style.overflow = "hidden";
-      }
+      }*/
       let index = scope.row.id ? scope.row.id - 1 : 0;
       // console.log(this.recipe_tabs[this.recipe_tabs_c].totalTableD[index], '我是key')
 
@@ -2581,6 +2581,8 @@ export default {
       let res = await getSelectType(data);
 
       if (data == "中药药品用法") {
+        this.usageList = res.Data;
+        if (!this.recipe_tabs[this.recipe_tabs_c].totalTableD[index]) return;
         if (this.recipe_tabs[this.recipe_tabs_c].totalTableD[index]["usage"]) {
           // res.Data.forEach(item => {
           //   if (
@@ -2597,7 +2599,6 @@ export default {
         }
         this.recipe_tabs[this.recipe_tabs_c].totalTableD[index].usageList =
           res.Data;
-        this.usageList = res.Data;
       } else if (data == "剂型") {
         this.recipe_tabs[this.recipe_tabs_c].bottom_form.doseTypeList =
           res.Data;

+ 2 - 2
src/components/SuitScience.vue

@@ -39,7 +39,7 @@
                 </template>
               </el-table-column>
 
-              <el-table-column label="操作" width="100">
+              <el-table-column label="操作" width="100" fixed="right">
                 <template slot-scope="scope" v-if="scope.row.name">
                   <div class="operate">
                     <img v-if="editable" src="../assets/add.png" alt @click="addData(scope)" />
@@ -78,7 +78,7 @@
                 </template>
               </el-table-column>
 
-              <el-table-column label="操作" width="100">
+              <el-table-column label="操作" width="100" fixed="right">
                 <template slot-scope="scope" v-if="scope.row.name">
                   <div class="operate">
                     <img v-if="editable" src="../assets/add.png" alt @click="addData(scope)" />

+ 85 - 0
src/model/transition.js

@@ -0,0 +1,85 @@
+const optionsAgency = [
+  {label: '代配', value: '0'},
+  {label: '代煎', value: '1'},
+  {label: '自煎', value: '2'},
+];
+const optionsDelivery = [
+  {label: '配送到本院(站)', value: '1'},
+  {label: '快递配送', value: '0'},
+];
+
+export const analysisAgency = (data) => {
+  const defaultAgency = (data.defaultAgency || '').toString().trim();
+  const displayAgency = (data.displayAgency || '').toString().trim();
+  // 保留原有逻辑
+  if (/^\d+/.test(displayAgency)) return {
+    // 默认代煎 0是 1否
+    defaultAgency: defaultAgency === '0' ? '1' : '2',
+    // 显示代煎 0显示 1隐藏
+    displayAgency: displayAgency === '1' ? [] : optionsAgency.filter(option => option.value !== '2').map(option => option.value),
+    optionsAgency: [...optionsAgency],
+  };
+  // 存在新值 (label:value,label:value)
+  if (displayAgency) {
+    const options = [...optionsAgency];
+    const values = [];
+    for (const string of displayAgency.split(',').filter(Boolean)) {
+      const [label, value] = string.split(':');
+      const option = options.find((option) => option.value === value);
+      if (label) {
+        if (option) option.label = label;
+        else options.push({ label, value });
+      }
+      values.push(value);
+    }
+    return {
+      defaultAgency: defaultAgency,
+      displayAgency: values,
+      optionsAgency: options,
+    };
+  }
+  // 默认配置
+  return {
+    defaultAgency: defaultAgency,
+    displayAgency: [],
+    optionsAgency,
+  };
+};
+
+export const analysisDelivery = (data) => {
+  const defaultDelivery = (data.defaultDelivery || '').toString().trim();
+  const displayDelivery = (data.displayDelivery || '').toString().trim();
+  // 保留原有逻辑
+  if (/^\d+/.test(displayDelivery)) return {
+    // 默认配送  0是 1否
+    defaultDelivery: defaultDelivery,
+    // 显示配送 0显示 1隐藏
+    displayDelivery: displayDelivery === '1' ? [] : optionsDelivery.map(option => option.value),
+    optionsDelivery: optionsDelivery,
+  };
+  // 存在新值 (label:value,label:value)
+  if (displayDelivery) {
+    const options = [...optionsDelivery];
+    const values = [];
+    for (const string of displayDelivery.split(',').filter(Boolean)) {
+      const [label, value] = string.split(':');
+      const option = options.find((option) => option.value === value);
+      if (label) {
+        if (option) option.label = label;
+        else options.push({ label, value });
+      }
+      values.push(value);
+    }
+    return {
+      defaultDelivery: defaultDelivery,
+      displayDelivery: values,
+      optionsDelivery: options,
+    };
+  }
+  // 默认配置
+  return {
+    defaultDelivery: defaultDelivery,
+    displayDelivery: [],
+    optionsDelivery,
+  };
+}

+ 17 - 0
src/router/business.js

@@ -54,6 +54,14 @@ export default [{
         title: '药品目录管理',
         pftitle: '业务管理'
     }
+}, {
+    path: 'nondruglist',
+    name: 'nondruglist',
+    component: () => import('@/views/business/NonDrugList.vue'),
+    meta: {
+        title: '非药物目录管理',
+        pftitle: '业务管理'
+    }
 }, {
     path: 'drugmap',
     name: 'drugmap',
@@ -71,6 +79,15 @@ export default [{
         pftitle: '业务管理',
         keeplive: true
     }
+}, {
+    path: 'nondrugmaplist',
+    name: 'nondrugmaplist',
+    component: () => import('@/views/business/NonDrugMapList.vue'),
+    meta: {
+        title: '非药物目录管理',
+        pftitle: '业务管理',
+        keeplive: true
+    }
 }, {
     path: 'pharmacy',
     name: 'pharmacy',

+ 13 - 6
src/utils/minix/prescribing.js

@@ -32,6 +32,9 @@ export default {
 
             isShowDj: true, // 是否展示代煎
             isShowPs: true, // 是否展示配送
+            optionsAgency: [], // 代煎选项
+            optionsDelivery: [], // 配送选项
+
 
             showAddress: false, // 展示选择代煎 地址
 
@@ -147,12 +150,16 @@ export default {
         },
         // 切换药房时 监听煎 配送是否显示
         onUpdateDp(e) {
-
-            let isShowDj = e.displayAgency == 0 ? true : false // 是否展示代煎 0 展示 1不展示
-            let isShowPs = e.displayDelivery == 0 ? true : false // 是否展示配送 0 展示 1不展示
-            this.isDaiJian = e.defaultAgency == 0 ? 1 : 2
-            this.isShowDj = isShowDj
-            this.isShowPs = isShowPs
+            const displayAgency = Array.isArray(e.displayAgency) ? e.displayAgency : [];
+            const displayDelivery = Array.isArray(e.displayDelivery) ? e.displayDelivery : [];
+            const optionsAgency = Array.isArray(e.optionsAgency) ? e.optionsAgency : [];
+            const optionsDelivery = Array.isArray(e.optionsDelivery) ? e.optionsDelivery : [];
+
+            this.isDaiJian = e.defaultAgency;
+            this.isShowDj = displayAgency.length > 0
+            this.isShowPs = displayDelivery.length > 0
+            this.optionsAgency = optionsAgency.filter(option => displayAgency.includes(option.value));
+            this.optionsDelivery = optionsDelivery.filter(option => displayDelivery.includes(option.value));
 
             this.openAddress()
 

+ 44 - 0
src/utils/url.js

@@ -0,0 +1,44 @@
+export function getURLSearchParams(value) {
+  if (!value) value = `${location.search}&${location.hash.split('?')[1] || ''}`;
+  return new URLSearchParams(value);
+}
+
+export function setSessionModalId(tag = 'modalId') {
+  const params = getURLSearchParams();
+  const modalId = params.get(tag);
+  if (modalId) sessionStorage.setItem(tag, modalId);
+
+  console.group(tag);
+  console.log('search: ', location.search);
+  console.log('hash: ', location.hash);
+  console.log('modalId: ', modalId);
+  console.groupEnd();
+
+  return modalId;
+}
+
+export function getSessionModalId(tag = 'modalId') {
+  const modalId = sessionStorage.getItem(tag);
+  return modalId ? modalId : setSessionModalId(tag);
+}
+
+export function inform(data = {}, tag = 'modalId') {
+  const modalId = getSessionModalId(tag);
+  if (modalId) {
+    sessionStorage.removeItem(tag);
+    const message = {
+      type: 'closeAnchorModal',
+      data: {...data, modalId},
+    }
+    window.parent.postMessage(message, '*');
+    console.group(tag);
+    console.log('modalId: ', modalId);
+    console.log('message: ', message);
+    console.groupEnd();
+  } else {
+    try {
+      const message = JSON.stringify(data);
+      window.parent.postMessage(message, '*');
+    } catch (e) { console.log(`通信失败:`, data); }
+  }
+}

+ 2 - 2
src/views/Home.vue

@@ -52,7 +52,7 @@ export default {
       code: "",
 
       checked: false,
-      src: process.env.VUE_APP_BASE_API + "captchaImage"
+      src: process.env.VUE_APP_BASE_API + "/captchaImage"
     };
   },
   created() {
@@ -67,7 +67,7 @@ export default {
     async getCodeimg() {
       let res = await getCodeimg();
       let time = new Date().getTime();
-      this.src = process.env.VUE_APP_BASE_API + "captchaImage?time=" + time;
+      this.src = process.env.VUE_APP_BASE_API + "/captchaImage?time=" + time;
     },
     async login() {
       localStorage.removeItem("token");

+ 1 - 0
src/views/business/Experience.vue

@@ -207,6 +207,7 @@ export default {
       if (data == "中药药品用法") {
         if (this.totalTableD[index].usage) {
           res.Data.forEach(item => {
+            if (!this.totalTableD[index]) return;
             if (item.value === this.totalTableD[index].usage) {
               this.totalTableD[index].usage = item.key;
             } else {

+ 1642 - 0
src/views/business/NonDrugList.vue

@@ -0,0 +1,1642 @@
+<template>
+  <div class="druglist">
+    <!-- 顶部筛选 -->
+    <div class="screening">
+      <div class="screening-title flex-vertical-center-l">
+        <img src="~@/assets/filters.png" alt />
+      </div>
+      <div class="screening-form flex-vertical-center-l flex-wrap">
+        <div class="screening-item flex-vertical-center-l">
+          <span>医共体名称:</span>
+          <div class="input">
+            <el-select
+              size="mini"
+              placeholder="请选择"
+              v-model="searchData.ygtid"
+              @change="onSearchYgtChange"
+            >
+              <el-option
+                :label="item.name"
+                :value="item.pid"
+                v-for="(item, index) in doctorBodyList"
+                :key="index"
+              ></el-option>
+            </el-select>
+          </div>
+        </div>
+        <div class="screening-item flex-vertical-center-l">
+          <span>医疗机构名称:</span>
+          <div class="input">
+            <el-select
+              size="mini"
+              placeholder="请选择"
+              clearable
+              v-model="searchData.stitutionsId"
+              @change="onSearchInstitutionChange"
+            >
+              <el-option
+                :label="item.label"
+                :value="item.value"
+                v-for="(item, index) in institutionList"
+                :key="index"
+              ></el-option>
+            </el-select>
+          </div>
+        </div>
+        <div class="screening-item flex-vertical-center-l">
+          <span>科室名称:</span>
+          <div class="input">
+            <el-select
+              size="mini"
+              placeholder="请选择"
+              clearable
+              v-model="searchData.departmentidSelsource"
+            >
+              <el-option
+                :label="item.label"
+                :value="item.value"
+                v-for="(item, index) in departList"
+                :key="index"
+              ></el-option>
+            </el-select>
+          </div>
+        </div>
+
+        <el-button type="primary" size="mini" @click="search()">搜索</el-button>
+        <el-button type="warning" size="mini" @click="clearFilter()"
+          >清空</el-button
+        >
+
+        <el-button type="primary" size="mini" @click="openEditDialog()"
+          >新增</el-button
+        >
+      </div>
+    </div>
+
+    <!-- 底部表格数据 -->
+    <div class="table">
+      <div class="today-table">
+        <div class="table-container">
+          <el-table
+            :data="tableData"
+            stripe
+            style="width: 100%"
+            border
+            height="100%"
+            cell-class-name="cell-max-height"
+          >
+            <el-table-column
+              prop="id"
+              label="序号"
+              width="50"
+              align="center"
+            ></el-table-column>
+            <el-table-column
+              prop="name"
+              width="200"
+              label="非药物目录名称"
+              align="center"
+            ></el-table-column>
+            <el-table-column
+              prop="ygtName"
+              width="200"
+              label="医共体"
+              align="center"
+            ></el-table-column>
+            <el-table-column
+              prop="stitutionsName"
+              width="200"
+              label="医疗机构"
+              align="center"
+            ></el-table-column>
+            <el-table-column
+              prop="departmentName"
+              label="科室"
+              align="center"
+            ></el-table-column>
+            <el-table-column
+              prop="describe"
+              label="非药物目录描述"
+              align="center"
+              show-overflow-tooltip
+            ></el-table-column>
+            <el-table-column label="操作" align="center" width="300">
+              <div class="flex-center operation" slot-scope="scope">
+                <div class="flex-center" @click="openEditDialog(scope.row)">
+                  修改
+                </div>
+                <div
+                  class="flex-center bg-yellow"
+                  @click="openMapPage(scope.row)"
+                >
+                  映射管理
+                </div>
+                <div class="flex-center" @click="openEditProject(scope.row)">
+                  编辑项目
+                </div>
+                <div class="flex-center bg-yellow">
+                  导入
+                  <input
+                    type="file"
+                    accept=".xlsx,.xls"
+                    runat="server"
+                    @change="uploadXSL($event, scope.row)"
+                  />
+                </div>
+                <div
+                  class="flex-center bg-yellow"
+                  @click="exportData(scope.row)"
+                >
+                  导出
+                </div>
+                <div
+                  class="flex-center bg-green"
+                  @click="downloadTemplate(scope.row)"
+                >
+                  模版下载
+                </div>
+              </div>
+            </el-table-column>
+          </el-table>
+        </div>
+        <div class="flex-vertical-center-r today-page">
+          <el-pagination
+            background
+            layout=" prev, pager, next, jumper, total"
+            :total="total"
+            :page-size="limit"
+            @current-change="sizeC($event)"
+          ></el-pagination>
+        </div>
+      </div>
+    </div>
+
+    <popup
+      distanceTop="5vh"
+      :showDialog="showEditDialog"
+      :loading="editLoading"
+      @cancle="
+        showEditDialog = false;
+        editLoading = false;
+      "
+      @confim="submitEditData()"
+      :title="editData.pid ? '修改非药物目录' : '新增非药物目录'"
+    >
+      <div class="flex-center" slot="body">
+        <div class="form">
+          <div class="form-item flex flex-col-center">
+            <span>*</span>
+            <div class="name">非药物目录名称:</div>
+            <div class="input">
+              <el-input
+                v-model="editData.name"
+                placeholder="请输入非药物目录名称"
+              ></el-input>
+            </div>
+          </div>
+          <div class="form-item flex flex-col-center">
+            <span>*</span>
+            <div class="name">医共体:</div>
+            <div class="input">
+              <el-select
+                style="width: 100%"
+                placeholder="请选择医共体"
+                v-model="editData.ygtid"
+                @change="onEditYgtChange"
+              >
+                <el-option
+                  :label="item.name"
+                  :value="item.pid"
+                  v-for="(item, index) in doctorBodyList"
+                  :key="index"
+                ></el-option>
+              </el-select>
+            </div>
+          </div>
+          <div class="form-item flex flex-col-center">
+            <span>&nbsp;</span>
+            <div class="name">医疗机构:</div>
+            <div class="input">
+              <el-select
+                style="width: 100%"
+                placeholder="请选择医疗机构"
+                clearable
+                v-model="editData.stitutionsId"
+                @change="onEditInstitutionChangeSingle"
+              >
+                <el-option
+                  :label="item.label"
+                  :value="item.value"
+                  v-for="(item, index) in editInstitutionList"
+                  :key="index"
+                ></el-option>
+              </el-select>
+            </div>
+          </div>
+          <div class="form-item flex flex-col-center">
+            <span>&nbsp;</span>
+            <div class="name">科室:</div>
+            <div class="input">
+              <el-select
+                style="width: 100%"
+                placeholder="请选择科室"
+                clearable
+                multiple
+                v-model="editData.departmentidSelsource"
+              >
+                <el-option
+                  :label="item.label"
+                  :value="item.value"
+                  v-for="(item, index) in editDepartList"
+                  :key="index"
+                ></el-option>
+              </el-select>
+            </div>
+          </div>
+          <div class="form-item flex-plane-center-l">
+            <span>&nbsp;</span>
+            <div class="name">非药物目录描述:</div>
+            <div class="input">
+              <el-input
+                type="textarea"
+                v-model="editData.describe"
+                placeholder="请输入描述"
+              ></el-input>
+            </div>
+          </div>
+        </div>
+      </div>
+    </popup>
+
+    <!-- 编辑项目弹窗 -->
+    <el-dialog
+      :visible.sync="showProjectDialog"
+      :title="projectDialogTitle"
+      width="100%"
+      :close-on-click-modal="false"
+      top="0"
+      custom-class="project-full-dialog"
+      :fullscreen="true"
+    >
+      <div class="project-dialog">
+        <div class="project-toolbar">
+          <el-button type="primary" size="mini" @click="openItemDialog()"
+            >新增</el-button
+          >
+        </div>
+        <el-table
+          :data="projectListData"
+          stripe
+          border
+          height="calc(100vh - 180px)"
+          size="mini"
+        >
+          <el-table-column
+            type="index"
+            label="序号"
+            width="50"
+            align="center"
+          ></el-table-column>
+          <el-table-column
+            prop="itemCode"
+            label="编码"
+            width="100"
+            align="center"
+          ></el-table-column>
+          <el-table-column
+            prop="itemName"
+            label="项目名称"
+            width="120"
+            align="center"
+          ></el-table-column>
+          <el-table-column
+            prop="connotation"
+            label="项目内涵"
+            width="120"
+            align="center"
+            show-overflow-tooltip
+          ></el-table-column>
+          <el-table-column
+            prop="excludedContent"
+            label="除外内容"
+            width="120"
+            align="center"
+            show-overflow-tooltip
+          ></el-table-column>
+          <el-table-column
+            prop="pricingUnit"
+            label="计价单位"
+            width="80"
+            align="center"
+          ></el-table-column>
+          <el-table-column
+            prop="price"
+            label="价格"
+            width="80"
+            align="center"
+          ></el-table-column>
+          <el-table-column
+            prop="remark"
+            label="备注"
+            width="120"
+            align="center"
+            show-overflow-tooltip
+          ></el-table-column>
+          <el-table-column
+            prop="limitPayScope"
+            label="限定支付范围"
+            width="140"
+            align="center"
+            show-overflow-tooltip
+          ></el-table-column>
+          <el-table-column label="详情默认值" width="100" align="center">
+            <template slot-scope="scope">
+              {{
+                getOptionLabel(detailDefaultOptions, scope.row.detailDefault)
+              }}
+            </template>
+          </el-table-column>
+          <el-table-column label="详情是否必填" width="110" align="center">
+            <template slot-scope="scope">
+              {{ scope.row.detailIsnull === "1" ? "是" : "否" }}
+            </template>
+          </el-table-column>
+          <el-table-column
+            prop="singleNumber"
+            label="单次数量"
+            width="120"
+            align="center"
+          >
+            <template slot-scope="scope">
+              {{
+                getOptionLabel(singleQuantityOptions, scope.row.singleNumber)
+              }}
+            </template>
+          </el-table-column>
+          <el-table-column label="详情累计项" width="100" align="center">
+            <template slot-scope="scope">
+              {{ getDetailCumulativeLabel(scope.row.detailCumulative) }}
+            </template>
+          </el-table-column>
+          <el-table-column
+            prop="countCoefficient"
+            label="计数系数"
+            width="80"
+            align="center"
+          ></el-table-column>
+          <el-table-column
+            prop="minTreatmentDuration"
+            label="最少治疗时长(分钟)"
+            width="120"
+            align="center"
+          ></el-table-column>
+          <el-table-column label="分类" width="80" align="center">
+            <template slot-scope="scope">
+              {{ getOptionLabel(categoryOptions, scope.row.classify) }}
+            </template>
+          </el-table-column>
+          <el-table-column label="操作" align="center" width="100">
+            <template slot-scope="scope">
+              <span class="op-text op-blue" @click="openItemDialog(scope.row)"
+                >修改</span
+              >
+              <span
+                class="op-text op-orange"
+                @click="deleteProjectItem(scope.row)"
+                >删除</span
+              >
+            </template>
+          </el-table-column>
+        </el-table>
+        <div class="flex-vertical-center-r today-page" style="margin-top: 10px">
+          <el-pagination
+            background
+            layout="prev, pager, next, jumper, total"
+            :total="projectTotal"
+            :page-size="projectLimit"
+            @current-change="projectPageChange($event)"
+          ></el-pagination>
+        </div>
+      </div>
+    </el-dialog>
+
+    <!-- 项目新增/修改弹窗 -->
+    <popup
+      distanceTop="10vh"
+      :showDialog="showItemDialog"
+      :loading="false"
+      @cancle="showItemDialog = false"
+      @confim="submitItemData()"
+      :title="itemEditData.pid ? '修改项目' : '新增项目'"
+      width="50%"
+    >
+      <div class="flex-center" slot="body">
+        <div class="form" style="width: 100%">
+          <div class="form-item flex flex-col-center">
+            <span>*</span>
+            <div class="name">编码:</div>
+            <div class="input">
+              <el-input
+                v-model="itemEditData.itemCode"
+                placeholder="请输入编码"
+              ></el-input>
+            </div>
+          </div>
+          <div class="form-item flex flex-col-center">
+            <span>*</span>
+            <div class="name">项目名称:</div>
+            <div class="input">
+              <el-input
+                v-model="itemEditData.itemName"
+                placeholder="请输入项目名称"
+              ></el-input>
+            </div>
+          </div>
+          <div class="form-item flex flex-col-center">
+            <span>&nbsp;</span>
+            <div class="name">项目内涵:</div>
+            <div class="input">
+              <el-input
+                v-model="itemEditData.connotation"
+                placeholder="请输入项目内涵"
+              ></el-input>
+            </div>
+          </div>
+          <div class="form-item flex flex-col-center">
+            <span>&nbsp;</span>
+            <div class="name">除外内容:</div>
+            <div class="input">
+              <el-input
+                v-model="itemEditData.excludedContent"
+                placeholder="请输入除外内容"
+              ></el-input>
+            </div>
+          </div>
+          <div class="form-item flex flex-col-center">
+            <span>*</span>
+            <div class="name">计价单位:</div>
+            <div class="input">
+              <el-input
+                v-model="itemEditData.pricingUnit"
+                placeholder="请输入计价单位"
+              ></el-input>
+            </div>
+          </div>
+          <div class="form-item flex flex-col-center">
+            <span>*</span>
+            <div class="name">价格:</div>
+            <div class="input">
+              <el-input
+                v-model="itemEditData.price"
+                placeholder="请输入价格"
+                type="number"
+                @input="itemEditData.price = itemEditData.price.replace(/[^0-9.]/g, '')"
+              ></el-input>
+            </div>
+          </div>
+          <div class="form-item flex flex-col-center">
+            <span>&nbsp;</span>
+            <div class="name">备注:</div>
+            <div class="input">
+              <el-input
+                v-model="itemEditData.remark"
+                placeholder="请输入备注"
+              ></el-input>
+            </div>
+          </div>
+          <div class="form-item flex flex-col-center">
+            <span>&nbsp;</span>
+            <div class="name">限定支付范围:</div>
+            <div class="input">
+              <el-input
+                v-model="itemEditData.limitPayScope"
+                placeholder="请输入限定支付范围"
+              ></el-input>
+            </div>
+          </div>
+          <div class="form-item flex flex-col-center">
+            <span>*</span>
+            <div class="name">详情默认值:</div>
+            <div class="input">
+              <el-select
+                style="width: 100%"
+                v-model="itemEditData.detailDefault"
+                placeholder="请选择"
+              >
+                <el-option
+                  v-for="item in detailDefaultOptions"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                ></el-option>
+              </el-select>
+            </div>
+          </div>
+          <div class="form-item flex flex-col-center">
+            <span>*</span>
+            <div class="name">详情是否必填:</div>
+            <div class="input">
+              <el-select
+                style="width: 100%"
+                v-model="itemEditData.detailIsnull"
+                placeholder="请选择"
+              >
+                <el-option
+                  v-for="item in detailRequiredOptions"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                ></el-option>
+              </el-select>
+            </div>
+          </div>
+          <div class="form-item flex flex-col-center">
+            <span>*</span>
+            <div class="name">单次数量:</div>
+            <div class="input">
+              <el-select
+                style="width: 100%"
+                v-model="itemEditData.singleNumber"
+                placeholder="请选择"
+              >
+                <el-option
+                  v-for="item in singleQuantityOptions"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                ></el-option>
+              </el-select>
+            </div>
+          </div>
+          <div class="form-item flex flex-col-center">
+            <span v-if="itemEditData.singleNumber !== '0'">*</span><span v-else>&nbsp;</span>
+            <div class="name">详情累计项:</div>
+            <div class="input">
+              <el-select
+                style="width: 100%"
+                v-model="itemEditData.detailCumulative"
+                placeholder="请选择"
+                multiple
+              >
+                <el-option
+                  v-for="item in detailCumulativeOptions"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                ></el-option>
+              </el-select>
+            </div>
+          </div>
+          <div class="form-item flex flex-col-center">
+            <span v-if="itemEditData.singleNumber !== '0'">*</span><span v-else>&nbsp;</span>
+            <div class="name">计数系数:</div>
+            <div class="input">
+              <el-input
+                v-model="itemEditData.countCoefficient"
+                placeholder="请输入计数系数"
+                type="number"
+                @input="itemEditData.countCoefficient = itemEditData.countCoefficient.replace(/[^0-9]/g, '')"
+              ></el-input>
+            </div>
+          </div>
+          <div class="form-item flex flex-col-center">
+            <span>&nbsp;</span>
+            <div class="name">最少治疗时长:</div>
+            <div class="input">
+              <el-input
+                v-model="itemEditData.minTreatmentDuration"
+                placeholder="请输入最少治疗时长"
+                type="number"
+                @input="itemEditData.minTreatmentDuration = itemEditData.minTreatmentDuration.replace(/[^0-9]/g, '')"
+              >
+                <template slot="append">分钟</template>
+              </el-input>
+            </div>
+          </div>
+          <div class="form-item flex flex-col-center">
+            <span>*</span>
+            <div class="name">分类:</div>
+            <div class="input">
+              <el-select
+                style="width: 100%"
+                v-model="itemEditData.classify"
+                placeholder="请选择"
+              >
+                <el-option
+                  v-for="item in categoryOptions"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                ></el-option>
+              </el-select>
+            </div>
+          </div>
+        </div>
+      </div>
+    </popup>
+  </div>
+</template>
+<script>
+import popup from "@/components/Propup.vue";
+import {
+  getNondrugList,
+  addNondrugCatalog,
+  updateNondrugCatalog,
+  getCatalogDetailsList,
+  addNondrugItem,
+  updateNondrugItem,
+  batchDeleteNondrugItem,
+  importNondrug,
+  exportNondrug,
+  downloadNondrugTemplate,
+} from "@/api/nonDrug.js";
+
+import { mapState, mapGetters, mapActions, mapMutations } from "vuex";
+import {
+  getDoctorBodySelect,
+  getMedSelect,
+  getDepartSelect,
+} from "@/api/system.js";
+import { errLog } from "vxe-pc-ui";
+
+let cache = new Map();
+export default {
+  components: {
+    popup,
+  },
+  data() {
+    return {
+      searchData: {
+        ygtid: "",
+        stitutionsId: "",
+        departmentidSelsource: "",
+      },
+      // 搜索区域下拉列表
+      institutionList: [],
+      departList: [],
+
+      tableData: [],
+      page: 1,
+      limit: 10,
+      total: 0,
+
+      // 编辑表单
+      showEditDialog: false,
+      editLoading: false,
+      editData: {
+        ygtid: "",
+        stitutionsId: "",
+        departmentidSelsource: [],
+        name: "",
+        describe: "",
+      },
+      // 编辑区域下拉列表
+      editInstitutionList: [],
+      editDepartList: [],
+
+      pid: "",
+      nowPid: "",
+
+      // 医共体
+      doctorBodyList: [],
+
+      // 编辑项目弹窗
+      showProjectDialog: false,
+      projectDialogTitle: "",
+      currentProjectPid: "",
+      currentProjectRow: null,
+      projectListData: [],
+      projectPage: 1,
+      projectLimit: 10,
+      projectTotal: 0,
+
+      // 项目新增/修改
+      showItemDialog: false,
+      itemEditData: {},
+
+      // 下拉选项(从 data/classify.json 加载)
+      detailDefaultOptions: [],
+      detailRequiredOptions: [
+        { label: "是", value: "1" },
+        { label: "否", value: "0" },
+      ],
+      singleQuantityOptions: [],
+      detailCumulativeOptions: [],
+      categoryOptions: [],
+    };
+  },
+  async created() {
+    this.getCascaderA();
+    await this.loadClassifyOptions();
+    await this.getList();
+    this.nowPid = this.getuserinfo.organizationid;
+  },
+  destroyed() {
+    cache.clear();
+  },
+  methods: {
+    // ===== 加载下拉选项 =====
+    async loadClassifyOptions() {
+      try {
+        const res = await fetch(`${window.BASE_URL}data/classify.json`);
+        const data = await res.json();
+        this.categoryOptions = data.classify || [];
+        this.detailDefaultOptions = data.detailDefault || [];
+        this.detailCumulativeOptions = data.detailCumulative || [];
+        this.singleQuantityOptions = data.singleNumber || [];
+      } catch (e) {
+        console.error("加载分类选项失败", e);
+      }
+    },
+    // ===== 搜索区域联动 =====
+    async onSearchYgtChange(ygtid) {
+      this.searchData.stitutionsId = "";
+      this.searchData.departmentidSelsource = "";
+      this.institutionList = [];
+      this.departList = [];
+      if (ygtid) await this.loadInstitutionList(ygtid, "search");
+    },
+    async onSearchInstitutionChange(institutionId) {
+      this.searchData.departmentidSelsource = "";
+      this.departList = [];
+      if (institutionId) await this.loadDepartList(institutionId, "search");
+    },
+
+    // ===== 编辑区域联动 =====
+    async onEditYgtChange(ygtid) {
+      this.editData.stitutionsId = "";
+      this.editData.departmentidSelsource = [];
+      this.editInstitutionList = [];
+      this.editDepartList = [];
+      if (ygtid) await this.loadInstitutionList(ygtid, "edit");
+    },
+    async onEditInstitutionChangeSingle(institutionId) {
+      this.editData.departmentidSelsource = [];
+      this.editDepartList = [];
+      if (institutionId) await this.loadDepartList(institutionId, "edit");
+    },
+
+    // ===== 通用数据加载 =====
+    async loadInstitutionList(organizationId, type) {
+      const key = "inst_" + organizationId;
+      let nodes = cache.has(key)
+        ? cache.get(key)
+        : await getMedSelect({ organizationId })
+            .then((res) =>
+              res && +res.ResultCode === 0
+                ? res.Data.map((item) => ({
+                    label: item.name,
+                    value: item.pid,
+                  }))
+                : [],
+            )
+            .catch(() => []);
+      cache.set(key, nodes);
+      if (type === "search") this.institutionList = nodes;
+      else this.editInstitutionList = nodes;
+      return nodes;
+    },
+    async loadDepartList(institutionId, type) {
+      const nodes = await this.getDepartNodes(institutionId);
+      if (type === "search") this.departList = nodes;
+      else this.editDepartList = nodes;
+      return nodes;
+    },
+    async getDepartNodes(institutionId) {
+      const key = "dept_" + institutionId;
+      if (cache.has(key)) return cache.get(key);
+      const nodes = await getDepartSelect({ institutionId })
+        .then((res) =>
+          res && +res.ResultCode === 0
+            ? res.Data.map((item) => ({ label: item.name, value: item.pid }))
+            : [],
+        )
+        .catch(() => []);
+      cache.set(key, nodes);
+      return nodes;
+    },
+
+    // ===== 获取医共体 =====
+    async getCascaderA() {
+      const res = await getDoctorBodySelect();
+      if (res && +res.ResultCode === 0) {
+        this.doctorBodyList = res.Data;
+      }
+    },
+
+    // ===== 映射管理跳转 =====
+    openMapPage(row) {
+      this.$router.push({
+        path: `/index/nondrugmaplist?pid=${row.pid}&ygtid=${row.ygtid ||
+          ""}&ygtName=${encodeURIComponent(
+          row.ygtName || "",
+        )}&stitutionsId=${row.stitutionsId ||
+          ""}&departmentidSelsource=${row.departmentidSelsource || ""}`,
+      });
+    },
+
+    // ===== 新增/编辑弹窗 =====
+    async openEditDialog(row = {}) {
+      this.editInstitutionList = [];
+      this.editDepartList = [];
+      this.editData = {
+        pid: row.pid,
+        describe: row.describe || "",
+        name: row.name || "",
+        ygtid: row.ygtid || this.searchData.ygtid,
+        stitutionsId: "",
+        departmentidSelsource: [],
+      };
+      this.editLoading = true;
+      this.showEditDialog = true;
+
+      if (this.editData.ygtid) {
+        await this.loadInstitutionList(this.editData.ygtid, "edit");
+
+        if (row.stitutionsId) {
+          // 加载科室
+          const nodes = await this.getDepartNodes(row.stitutionsId);
+          this.editDepartList = nodes;
+
+          // 用 $set 确保响应式更新,一次性设置避免中间态
+          this.$set(this.editData, "stitutionsId", row.stitutionsId);
+          this.$set(
+            this.editData,
+            "departmentidSelsource",
+            row.departmentidSelsource
+              ? row.departmentidSelsource.split(",").filter(Boolean)
+              : [],
+          );
+        }
+      }
+      this.editLoading = false;
+    },
+
+    // ===== 提交编辑 =====
+    async submitEditData() {
+      if (!this.editData.name || !this.editData.name.trim()) {
+        return this.$message.warning("请输入非药物目录名称");
+      }
+      if (!this.editData.ygtid) {
+        return this.$message.warning("请选择医共体");
+      }
+
+      // 校验唯一性:同一医共体/机构下,任一科室不可重复
+      {
+        const editDeptIds = Array.isArray(this.editData.departmentidSelsource)
+          ? this.editData.departmentidSelsource
+          : (this.editData.departmentidSelsource || "")
+              .split(",")
+              .filter(Boolean);
+        if (editDeptIds.length > 0 && this.editData.stitutionsId) {
+          const checkRes = await getNondrugList({
+            page: 1,
+            limit: 9999,
+            ygtid: this.editData.ygtid,
+          });
+          if (checkRes.ResultCode == 0) {
+            const items = (checkRes.Data.Items || []).filter(
+              (item) => item.pid !== this.editData.pid,
+            );
+            // 找出同一机构下的记录,逐个科室检查是否已存在
+            const matchedItems = items.filter(
+              (item) =>
+                (item.stitutionsId || "") === this.editData.stitutionsId &&
+                (item.departmentidSelsource || ""),
+            );
+            // 收集已存在的科室ID -> 名称映射
+            const existDeptMap = {};
+            matchedItems.forEach((item) => {
+              const ids = (item.departmentidSelsource || "")
+                .split(",")
+                .filter(Boolean);
+              ids.forEach((id) => {
+                if (!existDeptMap[id]) {
+                  existDeptMap[id] =
+                    item.departmentName || item.stitutionsName || "";
+                }
+              });
+            });
+            const conflictIds = editDeptIds.filter((id) => existDeptMap[id]);
+            if (conflictIds.length > 0) {
+              // 用 editDepartList 查出冲突科室名称
+              const conflictNames = conflictIds
+                .map((id) => {
+                  const dept = this.editDepartList.find(
+                    (d) => d.value === id,
+                  );
+                  return dept ? dept.label : id;
+                })
+                .join("、");
+              const ygtName =
+                this.doctorBodyList.find(
+                  (i) => i.pid === this.editData.ygtid,
+                )?.name || "";
+              const instName =
+                this.editInstitutionList.find(
+                  (i) => i.value === this.editData.stitutionsId,
+                )?.label || "";
+              return this.$message.warning(
+                `${ygtName}-${instName}-${conflictNames}的非药物目录已存在`,
+              );
+            }
+          }
+        }
+      }
+
+      const ygtItem = this.doctorBodyList.find(
+        (item) => item.pid === this.editData.ygtid,
+      );
+      // 构造 医共体 / 机构 / 科室 树
+      const instItem = this.editInstitutionList.find(
+        (item) => item.value === this.editData.stitutionsId,
+      );
+
+      // 多选科室:数组转逗号分隔字符串
+      const deptIds = Array.isArray(this.editData.departmentidSelsource)
+        ? this.editData.departmentidSelsource
+        : (this.editData.departmentidSelsource || "").split(",").filter(Boolean);
+      const deptIdsStr = deptIds.join(",");
+      const deptNamesStr = deptIds
+        .map((id) => {
+          const dept = this.editDepartList.find((d) => d.value === id);
+          return dept ? dept.label : "";
+        })
+        .filter(Boolean)
+        .join(",");
+
+      const params = {
+        pid: this.editData.pid || undefined,
+        name: this.editData.name,
+        describe: this.editData.describe,
+        ygtid: this.editData.ygtid,
+        ygtName: ygtItem ? ygtItem.name : "",
+        stitutionsId: this.editData.stitutionsId,
+        stitutionsName: instItem ? instItem.label : "",
+        departmentidSelsource: deptIdsStr,
+        departmentName: deptNamesStr,
+      };
+
+      params.groupInfo = [
+        {
+          pid: this.editData.ygtid,
+          name: ygtItem ? ygtItem.name : "",
+          children: params.stitutionsId
+            ? [
+                {
+                  pid: params.stitutionsId,
+                  name: instItem ? instItem.label : "",
+                  children: deptIds.length
+                    ? deptIds.map((id) => {
+                        const dept = this.editDepartList.find((d) => d.value === id);
+                        return {
+                          pid: id,
+                          name: dept ? dept.label : "",
+                          children: [],
+                        };
+                      })
+                    : [],
+                },
+              ]
+            : [],
+        },
+      ];
+      params.groupInfo = JSON.stringify(params.groupInfo);
+
+      const res = await (params.pid
+        ? updateNondrugCatalog(params)
+        : addNondrugCatalog(params));
+      if (res.ResultCode == 0) {
+        this.$message.success(params.pid ? "操作成功" : "添加成功");
+        this.showEditDialog = false;
+        await this.getList();
+      }
+    },
+
+    // ===== 列表相关 =====
+    sizeC(e) {
+      this.page = e;
+      this.getList();
+    },
+    search() {
+      this.page = 1;
+      this.getList();
+    },
+    clearFilter() {
+      this.searchData = {
+        ygtid: "",
+        stitutionsId: "",
+        departmentidSelsource: "",
+      };
+      this.institutionList = [];
+      this.departList = [];
+      this.getList();
+    },
+    async getList() {
+      let params = {
+        page: this.page,
+        limit: this.limit,
+        ygtid: this.searchData.ygtid,
+        stitutionsId: this.searchData.stitutionsId,
+        departmentidSelsource: this.searchData.departmentidSelsource,
+      };
+      let res = await getNondrugList(params);
+      if (res.ResultCode == 0) {
+        const items = res.Data.Items;
+        this.total = res.Data.TotalRecordCount;
+        items.forEach((item, index) => {
+          item.id = (this.page - 1) * this.limit + index + 1;
+        });
+        this.tableData = items;
+      }
+    },
+
+    // ===== 编辑项目 =====
+    openEditProject(row) {
+      this.currentProjectRow = row;
+      this.currentProjectPid = row.pid;
+      this.projectDialogTitle = (row.name || "");
+      this.projectPage = 1;
+      this.showProjectDialog = true;
+      this.getProjectList();
+    },
+
+    // ===== 编辑项目列表 =====
+    projectPageChange(e) {
+      this.projectPage = e;
+      this.getProjectList();
+    },
+    async getProjectList() {
+      const row = this.currentProjectRow || {};
+      const params = {
+        // page: this.projectPage,
+        // limit: this.projectLimit,
+        pageNum: this.projectPage,
+        pageSize: this.projectLimit,
+        appId: row.ygtid || "",
+        deptId: row.departmentidSelsource || "",
+        institutionCode: row.stitutionsId || "",
+      };
+      try {
+        const res = await getCatalogDetailsList(params);
+        if (res.ResultCode == 0) {
+          this.projectListData = res?.Data?.list || [];
+          this.projectTotal = res?.Data?.total || 0;
+        } else {
+          this.$message.error(res.ResultInfo || "获取列表失败");
+        }
+      } catch (e) {
+        this.$message.error(e.message || "获取列表失败");
+      }
+    },
+
+    // ===== 项目新增/修改 =====
+    openItemDialog(row) {
+      if (row && row.pid) {
+        this.itemEditData = { ...row };
+        if (
+          this.itemEditData.detailCumulative &&
+          typeof this.itemEditData.detailCumulative === "string"
+        ) {
+          this.itemEditData.detailCumulative = this.itemEditData.detailCumulative
+            .split(/[,、]/)
+            .filter(Boolean)
+            .map((v) => String(v));
+        } else if (Array.isArray(this.itemEditData.detailCumulative)) {
+          this.itemEditData.detailCumulative = this.itemEditData.detailCumulative.map((v) =>
+            String(v),
+          );
+        }
+        if (!Array.isArray(this.itemEditData.detailCumulative)) {
+          this.itemEditData.detailCumulative = [];
+        }
+      } else {
+        this.itemEditData = {
+          itemCode: "",
+          itemName: "",
+          connotation: "",
+          excludedContent: "",
+          pricingUnit: "",
+          price: "",
+          remark: "",
+          limitPayScope: "",
+          detailDefault: "",
+          detailIsnull: "",
+          singleNumber: "",
+          detailCumulative: [],
+          countCoefficient: "",
+          minTreatmentDuration: "",
+          classify: "",
+        };
+      }
+      this.showItemDialog = true;
+    },
+    async submitItemData() {
+      const d = this.itemEditData;
+      if (!d.itemCode || !d.itemCode.trim())
+        return this.$message.error("请输入编码");
+      if (!d.itemName || !d.itemName.trim())
+        return this.$message.error("请输入项目名称");
+      // 新增时校验编码和项目名称不能重复
+      if (!d.pid) {
+        const duplicateCode = this.projectListData.find(
+          (item) => item.itemCode === d.itemCode.trim(),
+        );
+        if (duplicateCode) {
+          return this.$message.error("编码已存在,请勿重复添加");
+        }
+        const duplicateName = this.projectListData.find(
+          (item) => item.itemName === d.itemName.trim(),
+        );
+        if (duplicateName) {
+          return this.$message.error("项目名称已存在,请勿重复添加");
+        }
+      }
+      if (!d.pricingUnit || !d.pricingUnit.trim())
+        return this.$message.error("请输入计价单位");
+      if (d.price === "" || d.price === null || d.price === undefined)
+        return this.$message.error("请输入价格");
+      if (Number(d.price) < 0)
+        return this.$message.error("价格不能为负数");
+      if (d.countCoefficient !== "" && d.countCoefficient !== null && d.countCoefficient !== undefined) {
+        if (!/^\d+$/.test(String(d.countCoefficient)) || Number(d.countCoefficient) <= 0)
+          return this.$message.error("计数系数必须为正整数");
+      }
+      if (!d.detailDefault) return this.$message.error("请选择详情默认值");
+      if (!d.detailIsnull && d.detailIsnull !== 0)
+        return this.$message.error("请选择详情是否必填");
+      if (!d.singleNumber) return this.$message.error("请选择单次数量");
+      if (d.singleNumber !== '0') {
+        if (!d.detailCumulative || !d.detailCumulative.length)
+          return this.$message.error("请选择详情累计项");
+        if (!d.countCoefficient)
+          return this.$message.error("请输入计数系数");
+      }
+      if (d.minTreatmentDuration !== '' && d.minTreatmentDuration !== null && d.minTreatmentDuration !== undefined) {
+        if (!/^\d+$/.test(String(d.minTreatmentDuration)) || Number(d.minTreatmentDuration) <= 0)
+          return this.$message.error("最少治疗时长必须为正整数");
+      }
+      if (!d.classify) return this.$message.error("请选择分类");
+      try {
+        const params = { ...this.itemEditData };
+        if (Array.isArray(params.detailCumulative)) {
+          params.detailCumulative = params.detailCumulative.join(",");
+        }
+        const row = this.currentProjectRow || {};
+        params.appId = row.ygtid || "";
+        params.institutionCode = row.stitutionsId || "";
+        params.deptId = row.departmentidSelsource || "";
+        const res = await (params.pid
+          ? updateNondrugItem(params)
+          : addNondrugItem(params));
+        if (res.ResultCode == 0) {
+          this.$message.success(params.pid ? "修改成功" : "新增成功");
+          this.showItemDialog = false;
+          this.getProjectList();
+        } else {
+          this.$message.error(res.ResultInfo || "操作失败");
+        }
+      } catch (e) {
+        this.$message.error(e.message || "操作失败");
+      }
+    },
+
+    // ===== 项目删除 =====
+    deleteProjectItem(row) {
+      this.$confirm("确认删除该条目吗?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(async () => {
+          try {
+            const res = await batchDeleteNondrugItem({ ids: row.pid });
+            if (res.ResultCode == 0) {
+              this.$message.success("删除成功");
+              this.getProjectList();
+            } else {
+              this.$message.error(res.ResultInfo || "删除失败");
+            }
+          } catch (e) {
+            this.$message.error(e.message || "删除失败");
+          }
+        })
+        .catch(() => {});
+    },
+
+    // ===== 标签映射 =====
+    getOptionLabel(options, value) {
+      if ((value === "" || value === null || value === undefined) && value !== 0) return "-";
+      const sv = String(value);
+      const item = options.find((o) => String(o.value) === sv);
+      return item ? item.label : value;
+    },
+    getDetailCumulativeLabel(val) {
+      if (!val) return "-";
+      const arr = String(val).split(/[,、]/).filter(Boolean);
+      return arr
+        .map((v) => this.getOptionLabel(this.detailCumulativeOptions, v))
+        .join(",");
+    },
+
+    // ===== 模版下载 =====
+    async downloadTemplate(row) {
+      const loading = this.$loading({
+        lock: true,
+        text: "正在下载,请稍后",
+        spinner: "el-icon-loading",
+        background: "rgba(0, 0, 0, 0.7)",
+      });
+      try {
+        const res = await downloadNondrugTemplate();
+        if (res && res.ResultCode == 0) {
+          let path = process.env.VUE_APP_UPLOAD + "file/" + res.ResultInfo;
+          const a = document.createElement("a");
+          a.setAttribute("download", "");
+          a.setAttribute("href", path);
+          a.click();
+          a.remove();
+          this.$message({
+            type: "success",
+            message: "下载成功",
+            showClose: true,
+          });
+        } else {
+          this.$message.error(res.ResultInfo || "下载失败");
+        }
+      } catch (e) {
+        this.$message.error(e.message || "下载失败");
+      } finally {
+        loading.close();
+      }
+    },
+
+    // ===== 导出 =====
+    async exportData(row) {
+      let params = {
+        basisNondrugcatalogueId: row.pid,
+      };
+      const loading = this.$loading({
+        lock: true,
+        text: "正在导出,请稍后",
+        spinner: "el-icon-loading",
+        background: "rgba(0, 0, 0, 0.7)",
+      });
+      let res = await exportNondrug(params).catch(() => {
+        loading.close();
+      });
+      if (res && res.ResultCode == 0) {
+        let path = process.env.VUE_APP_UPLOAD + "file/" + res.ResultInfo;
+        const a = document.createElement("a");
+        a.setAttribute("download", "");
+        a.setAttribute("href", path);
+        a.click();
+        a.remove();
+        this.$message({
+          type: "success",
+          message: "导出成功",
+          showClose: true,
+        });
+        loading.close();
+      }
+    },
+
+    // ===== 导入 =====
+    uploadXSL(e, row) {
+      const file = e.target.files[0];
+      if (!file) return;
+      let formData = new FormData();
+      formData.append("file", file);
+      importNondrug({
+        appid: row.ygtid || "",
+        deptId: row.departmentidSelsource || "",
+        institutionCode: row.stitutionsId || "",
+        institutionName: row.stitutionsName || "",
+        formData,
+      })
+        .then((res) => {
+          if (res.ResultCode == 0) {
+            this.$message({
+              message: "导入成功",
+              type: "success",
+              showClose: true,
+            });
+            this.getList();
+          } else {
+            this.$message({
+              message: res.ResultInfo || "导入失败",
+              type: "error",
+              showClose: true,
+            });
+          }
+        })
+        .catch(() => {
+          // this.$message({ message: "导入失败", type: "error", showClose: true });
+        });
+      e.target.value = "";
+    },
+  },
+  computed: {
+    ...mapGetters(["getuserinfo"]),
+  },
+};
+</script>
+<style lang="scss" scoped>
+@import "../../style/common.scss";
+@import "../../style/base.scss";
+
+.bg-yellow {
+  background: #ffae45;
+  position: relative;
+  width: 56px;
+  height: 28px;
+
+  border-radius: 4px;
+  cursor: pointer;
+  font-size: 14px;
+  font-family: PingFang SC;
+  font-weight: 400;
+  color: #ffffff;
+  margin-left: 10px;
+  margin-right: 10px;
+
+  input {
+    width: 74px;
+    height: 36px;
+    position: absolute;
+    top: 0;
+    left: 0;
+    bottom: 0;
+    right: 0;
+    opacity: 0;
+  }
+}
+
+.table {
+  padding: 10px 10px;
+  background: #ffffff;
+  border-radius: 5px;
+  margin-top: 10px;
+  height: 70vh;
+
+  .table-container {
+    height: 90%;
+  }
+
+  .today-table {
+    height: 100%;
+
+    .operation {
+      display: flex;
+      align-items: center;
+      justify-content: space-around;
+      flex-wrap: wrap;
+      div {
+        width: 60px;
+        height: 24px;
+        background: #5386f6;
+        border-radius: 2px;
+        font-size: 14px;
+        font-family: PingFang SC;
+        font-weight: 400;
+        color: #ffffff;
+        cursor: pointer;
+        margin: 5px 0;
+      }
+
+      .bg-yellow {
+        width: 80px;
+        height: 24px;
+        background: #ffae45;
+      }
+
+      .bg-red {
+        width: 80px;
+        height: 24px;
+        background: red;
+      }
+
+      .bg-green {
+        width: 80px;
+        height: 24px;
+        background: #67c23a;
+      }
+    }
+  }
+}
+
+.table-body::v-deep .el-table .cell {
+  text-align: center;
+}
+
+.el-table::v-deep {
+  .cell-max-height div {
+    max-height: 240px;
+    overflow-y: auto;
+  }
+}
+</style>
+
+<style lang="scss" scoped>
+@media screen and (min-width: 1681px) and (max-width: 1920px) {
+  .table {
+    height: 81vh;
+
+    .table-container {
+      height: 94%;
+    }
+  }
+
+  .today-table::v-deep .el-table td {
+    padding: 18px 0;
+  }
+
+  .today-table::v-deep .el-table th {
+    padding: 18px 0;
+  }
+}
+
+@media screen and (min-width: 1601px) and (max-width: 1680px) {
+  .table {
+    height: 80vh;
+
+    .table-container {
+      height: 94%;
+    }
+  }
+
+  .today-table::v-deep .el-table td {
+    padding: 18px 0;
+  }
+
+  .today-table::v-deep .el-table th {
+    padding: 18px 0;
+  }
+}
+
+@media screen and (min-width: 1361px) and (max-width: 1600px) {
+  .table {
+    height: 72vh;
+
+    .table-container {
+      height: 90%;
+    }
+  }
+
+  .today-table::v-deep .el-table td {
+    padding: 5px 0;
+  }
+
+  .today-table::v-deep .el-table th {
+    padding: 5px 0;
+  }
+}
+
+@media screen and(min-width:1281px) and (max-width: 1360px) {
+  .table {
+    height: 72vh;
+
+    .table-container {
+      height: 90%;
+    }
+  }
+
+  .today-table::v-deep .el-table td {
+    padding: 5px 0;
+  }
+
+  .today-table::v-deep .el-table th {
+    padding: 5px 0;
+  }
+}
+
+.form {
+  width: 50%;
+
+  .form-item {
+    margin-bottom: 10px;
+
+    span {
+      color: red;
+      width: 10px;
+      text-align: center;
+      flex-shrink: 0;
+    }
+
+    .name {
+      width: 150px;
+      white-space: nowrap;
+      flex-shrink: 0;
+    }
+
+    .input {
+      flex: 1;
+    }
+  }
+}
+
+.link-text {
+  color: #5386f6;
+  cursor: pointer;
+  text-decoration: underline;
+}
+
+.op-text {
+  cursor: pointer;
+  margin: 0 5px;
+  font-size: 14px;
+}
+.op-blue {
+  color: #5386f6;
+}
+.op-orange {
+  color: #ffae45;
+}
+
+.project-dialog {
+  .project-toolbar {
+    margin-bottom: 10px;
+  }
+}
+
+.group-form {
+  width: 100%;
+  padding: 0 20px;
+  box-sizing: border-box;
+
+  .group-form-item {
+    margin-bottom: 10px;
+
+    span {
+      color: red;
+    }
+
+    .name {
+      width: 90px;
+      text-align: right;
+      margin-right: 8px;
+    }
+
+    .input {
+      flex: 1;
+    }
+  }
+
+  .cond-label {
+    color: #333;
+    font-size: 14px;
+    white-space: nowrap;
+  }
+
+  .unit-label {
+    font-size: 14px;
+    color: #333;
+    white-space: nowrap;
+  }
+
+  .group-count {
+    position: absolute;
+    right: 8px;
+    top: 50%;
+    transform: translateY(-50%);
+    color: #ff4949;
+    font-size: 14px;
+    font-weight: bold;
+  }
+}
+
+.group-notice {
+  color: #e6a23c;
+  font-size: 13px;
+  margin-top: 10px;
+  padding-left: 30px;
+}
+
+.group-btns {
+  margin-top: 15px;
+
+  .group-btn-delete {
+    width: 108px;
+    height: 40px;
+    background: #ff4949;
+    border-radius: 3px;
+    font-size: 16px;
+    color: #fff;
+    cursor: pointer;
+    margin-left: auto;
+    margin-right: 30px;
+  }
+}
+</style>
+
+<style lang="scss">
+.project-full-dialog {
+  margin: 0 !important;
+  .el-dialog__header {
+    text-align: center;
+  }
+  .el-dialog__body {
+    padding: 10px 15px;
+  }
+}
+</style>

+ 572 - 0
src/views/business/NonDrugMapList.vue

@@ -0,0 +1,572 @@
+<template>
+  <div class="druglist">
+    <!-- 顶部筛选 -->
+    <div class="screening">
+      <div class="screening-title flex-vertical-center-l">
+        <img src="~@/assets/filters.png" alt />
+      </div>
+      <div class="screening-form flex-vertical-center-l flex-wrap">
+        <div class="screening-item flex-vertical-center-l">
+          <span>映射状态:</span>
+          <div class="input">
+            <el-select
+              size="mini"
+              placeholder="全部"
+              v-model="searchData.isMapping"
+              clearable
+            >
+              <el-option :value="0" label="未映射"></el-option>
+              <el-option :value="1" label="已映射"></el-option>
+            </el-select>
+          </div>
+        </div>
+        <div class="screening-item flex-vertical-center-l">
+          <span>平台非药物疗法:</span>
+          <div class="input">
+            <el-input
+              size="mini"
+              placeholder="请输入二级分类名称"
+              v-model="searchData.secondName"
+              @keydown.enter.native="search()"
+              clearable
+            ></el-input>
+          </div>
+        </div>
+
+        <el-button type="primary" size="mini" @click="search()">搜索</el-button>
+        <el-button type="warning" size="mini" @click="clearFilter()"
+          >清空</el-button
+        >
+        <div style="width: 60px;"></div>
+        <el-button type="warning" size="mini" @click="$router.back()"
+          >返回</el-button
+        >
+        <el-button type="primary" size="mini" @click="autoMap"
+          >自动映射</el-button
+        >
+        <el-button type="danger" size="mini" @click="clearMap"
+          >清空映射</el-button
+        >
+      </div>
+    </div>
+
+    <!-- 底部表格数据 -->
+    <div class="table">
+      <div class="today-table">
+        <div class="table-container">
+          <el-table
+            :data="tableData"
+            v-loading="loading"
+            stripe
+            style="width: 100%"
+            border
+            height="100%"
+            :header-cell-style="headerCellStyle"
+          >
+            <el-table-column
+              type="index"
+              label="序号"
+              width="60"
+              align="center"
+              :index="indexMethod"
+            ></el-table-column>
+            <el-table-column label="平台非药物疗法">
+              <el-table-column
+                label="一级分类"
+                prop="firstLevel"
+                align="center"
+              >
+                <template slot-scope="scope">
+                  <span
+                    :style="{
+                      color: String(scope.row.isMapping) !== '1' ? 'red' : '',
+                    }"
+                    >{{ scope.row.firstLevel || "-" }}</span
+                  >
+                </template>
+              </el-table-column>
+              <el-table-column
+                label="二级分类"
+                prop="secondLevel"
+                align="center"
+              >
+                <template slot-scope="scope">
+                  <span
+                    :style="{
+                      color: String(scope.row.isMapping) !== '1' ? 'red' : '',
+                    }"
+                    >{{ scope.row.secondLevel || "-" }}</span
+                  >
+                </template>
+              </el-table-column>
+            </el-table-column>
+            <el-table-column label="第三方非药物疗法">
+              <el-table-column label="项目名称" align="center">
+                <template slot-scope="scope">
+                  <el-select
+                    v-if="activeEditIndex === scope.$index"
+                    size="mini"
+                    :loading="editData[scope.$index].loading"
+                    :placeholder="editData[scope.$index].placeholder"
+                    filterable
+                    remote
+                    :remote-method="matSearchRemoteMethod"
+                    v-model="editData[scope.$index].matDrugId"
+                    @change="onSelectChange(scope.$index, $event)"
+                    @focus="focusEditRow(scope.$index)"
+                    @visible-change="onVisibleChange(scope.$index, $event)"
+                  >
+                    <el-option
+                      v-for="option in editData[scope.$index].options"
+                      :key="option.value"
+                      :label="option.label"
+                      :value="option.value"
+                    />
+                  </el-select>
+                  <div
+                    v-else
+                    class="clickable-name"
+                    @click="activateEdit(scope.$index)"
+                  >
+                    {{
+                      editData[scope.$index]
+                        ? editData[scope.$index].displayName || "-"
+                        : "-"
+                    }}
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="编码" width="150" align="center">
+                <template slot-scope="scope">
+                  <div>{{ scope.row.itemCode || "-" }}</div>
+                </template>
+              </el-table-column>
+              <el-table-column label="计价单位" width="100" align="center">
+                <template slot-scope="scope">
+                  <div>{{ scope.row.pricingUnit || "-" }}</div>
+                </template>
+              </el-table-column>
+              <el-table-column label="价格" width="100" align="center">
+                <template slot-scope="scope">
+                  <div>{{ scope.row.price || "-" }}</div>
+                </template>
+              </el-table-column>
+            </el-table-column>
+          </el-table>
+        </div>
+        <div class="flex-vertical-center-r today-page">
+          <div></div>
+          <el-pagination
+            background
+            layout=" prev, pager, next, jumper, total"
+            :total="total"
+            :page-size="limit"
+            @current-change="sizeC($event)"
+          ></el-pagination>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+import popup from "@/components/Propup.vue";
+import {
+  getNondrugMapList,
+  autoMapNondrug,
+  clearMapNondrug,
+  materialQuery,
+  manualMapping,
+} from "@/api/nonDrug.js";
+import { mapGetters } from "vuex";
+
+export default {
+  components: {
+    popup,
+  },
+  data() {
+    return {
+      searchData: {
+        pid: "",
+        appId: "",
+        deptId: "",
+        institutionCode: "",
+        isMapping: "",
+        secondName: "",
+      },
+      loading: false,
+      tableData: [],
+      page: 1,
+      limit: 10,
+      total: 0,
+
+      editIndex: -1,
+      activeEditIndex: -1,
+      editData: [],
+      editOriginalMatDrugId: "",
+      changeHandled: false,
+    };
+  },
+  activated() {
+    this.load();
+  },
+  methods: {
+    async load() {
+      this.activeEditIndex = -1;
+      this.searchData = {
+        pid: this.$route.query.pid || "",
+        appId: this.$route.query.ygtid || "",
+        deptId: this.$route.query.departmentidSelsource || "",
+        institutionCode: this.$route.query.stitutionsId || "",
+        isMapping: "",
+        secondName: "",
+      };
+      this.page = 1;
+      await this.getList();
+    },
+    sizeC(e) {
+      this.page = e;
+      this.getList();
+    },
+    search() {
+      this.page = 1;
+      this.getList();
+    },
+    async clearFilter() {
+      this.searchData = {
+        pid: this.$route.query.pid || "",
+        appId: this.$route.query.ygtid || "",
+        deptId: this.$route.query.departmentidSelsource || "",
+        institutionCode: this.$route.query.stitutionsId || "",
+        isMapping: "",
+        secondName: "",
+      };
+      this.page = 1;
+      this.getList();
+    },
+    async getList() {
+      this.loading = true;
+      try {
+        const {
+          appId,
+          deptId,
+          institutionCode,
+          isMapping,
+          secondName,
+        } = this.searchData;
+        let params = {
+          appId,
+          deptId,
+          institutionCode,
+          isMapping,
+          secondName,
+          pageNum: this.page,
+          pageSize: this.limit,
+        };
+        let res = await getNondrugMapList(params);
+        if (res.ResultCode == 0) {
+          const data = res.Data || {};
+          this.tableData = data.Items || [];
+          this.total = data.TotalRecordCount || 0;
+        } else throw { message: res.ResultInfo };
+        this.initEditData();
+      } catch (e) {
+        this.$message.error(e.message);
+      }
+      this.loading = false;
+    },
+    initEditData() {
+      this.editData = this.tableData.map((item) => {
+        const isMapped = String(item.isMapping) === "1";
+        const displayName = isMapped ? item.itemName || "-" : "-";
+        return {
+          id: item.id,
+          matDrugId: isMapped ? item.id : "",
+          matDrugName: item.itemName || "",
+          matDrugDw: item.pricingUnit || "",
+          displayName,
+          loading: false,
+          placeholder: displayName !== "-" ? displayName : "请输入项目名称搜索",
+          options: isMapped
+            ? [{ value: item.id, label: item.itemName, dw: item.pricingUnit }]
+            : [],
+        };
+      });
+    },
+    focusEditRow(index) {
+      this.editIndex = index;
+      const item = this.editData[index];
+      let name = "";
+      if (item.matDrugName) {
+        try {
+          name = item.matDrugName.match(/[\u4E00-\u9FFF]+/g)[0];
+        } catch (e) {
+          name = "";
+        }
+      }
+      this.matSearchRemoteMethod(name || " ", index);
+    },
+    activateEdit(index) {
+      this.activeEditIndex = index;
+      this.editOriginalMatDrugId = this.editData[index].matDrugId;
+      this.changeHandled = false;
+    },
+    async onSelectChange(index, value) {
+      this.changeHandled = true;
+      this.updateEditRow(index, value);
+      await this.doManualMapping(index);
+      this.activeEditIndex = -1;
+    },
+    onVisibleChange(index, visible) {
+      if (visible) return;
+      if (this.changeHandled) return;
+      if (this.editData[index].matDrugId !== this.editOriginalMatDrugId) {
+        this.doManualMapping(index);
+      }
+      this.activeEditIndex = -1;
+    },
+    async doManualMapping(index) {
+      try {
+        const row = this.tableData[index];
+        const item = this.editData[index];
+        let params = {
+          deptId: this.searchData.deptId,
+          firstName: row.firstLevel || "",
+          organizationid: this.searchData.appId,
+          platformClassifyId: row.id || "",
+          secondName: row.secondLevel || "",
+          sititutionNondrugId: item.matDrugId || "",
+          sititutionid: this.searchData.institutionCode,
+        };
+        const loading = this.$loading({
+          lock: true,
+          text: "正在映射",
+          spinner: "el-icon-loading",
+          background: "rgba(0, 0, 0, 0.7)",
+        });
+        const res = await manualMapping(params).catch((err) => {
+          loading.close();
+        });
+        if (res.ResultCode == 0) {
+          loading.close();
+          this.$message.success("映射保存成功");
+          await this.getList();
+        }
+      } catch (e) {
+        this.$message.error(e.message);
+      }
+    },
+    updateEditRow(index, value) {
+      const item = this.editData[index];
+      if (value) {
+        const option = item.options.find((o) => o.value === value);
+        item.displayName = option.label;
+        item.matDrugName = option.label;
+        item.matDrugDw = option.dw || "";
+      } else {
+        item.displayName = "-";
+        item.matDrugName = "";
+        item.matDrugDw = "";
+      }
+    },
+    async matSearchRemoteMethod(name, index) {
+      if (index == null) index = this.editIndex;
+      const item = this.editData[index];
+      if (!name) {
+        item.options = item.matDrugId
+          ? [{ value: item.matDrugId, label: item.matDrugName }]
+          : [];
+      } else {
+        item.loading = true;
+        item.options = await materialQuery({
+          name: name.trim(),
+          appId: this.searchData.appId,
+          deptId: this.searchData.deptId,
+          institutionCode: this.searchData.institutionCode,
+        })
+          .then((res) => {
+            if (res.ResultCode === 0)
+              return (res.Data || []).map((d) => ({
+                value: d.pid,
+                label: d.itemName || d.name,
+                dw: d.pricingUnit || d.dw,
+              }));
+            return [];
+          })
+          .catch(() => []);
+        item.loading = false;
+      }
+      return item.options;
+    },
+    // 自动映射
+    autoMap() {
+      this.$confirm("确认自动映射所有未映射的非药物疗法?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(async () => {
+          try {
+            const res = await autoMapNondrug({
+              basisNondrugcatalogueId: this.searchData.pid,
+            });
+            if (res.ResultCode == 0) {
+              this.$message.success("自动映射成功");
+              this.getList();
+            }
+          } catch (e) {
+            this.$message.error(e.message);
+          }
+        })
+        .catch(() => {});
+    },
+    // 清空映射
+    clearMap() {
+      this.$confirm("确认清空本列表的全部映射关系吗?", "提示", {
+        confirmButtonText: "确认",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(async () => {
+          try {
+            const res = await clearMapNondrug({
+              basisNondrugcatalogueId: this.searchData.pid,
+            });
+            if (res.ResultCode == 0) {
+              this.$message.success("清空映射成功");
+              this.getList();
+            } 
+          } catch (e) {
+            this.$message.error(e.message);
+          }
+        })
+        .catch(() => {});
+    },
+    indexMethod(index) {
+      return (this.page - 1) * this.limit + index + 1;
+    },
+    headerCellStyle({ rowIndex, columnIndex }) {
+      if (rowIndex === 0) {
+        // 序号列
+        if (columnIndex === 0) return { backgroundColor: "#f3fffb" };
+        // 平台非药物疗法
+        if (columnIndex === 1) return { backgroundColor: "#efe1c7" };
+        // 第三方非药物疗法
+        if (columnIndex === 2) return { backgroundColor: "#c7efef" };
+      }
+      if (rowIndex === 1) return { backgroundColor: "#c7efef" };
+      return {};
+    },
+  },
+  computed: {
+    ...mapGetters(["getuserinfo"]),
+  },
+};
+</script>
+<style lang="scss" scoped>
+@import "../../style/common.scss";
+@import "../../style/base.scss";
+
+.table {
+  padding: 5px 5px;
+  background: #ffffff;
+  border-radius: 5px;
+  margin-top: 10px;
+  height: 72vh;
+
+  .flex-vertical-center-r {
+    justify-content: space-between;
+  }
+
+  .table-container {
+    height: 90%;
+  }
+
+  .today-table {
+    height: 100%;
+  }
+}
+
+.clickable-name {
+  cursor: pointer;
+  min-height: 28px;
+  line-height: 28px;
+}
+
+.today-table::v-deep .el-table .cell {
+  text-align: center;
+}
+</style>
+
+<style lang="scss" scoped>
+@media screen and (min-width: 1681px) and (max-width: 1920px) {
+  .table {
+    height: 82vh;
+
+    .table-container {
+      height: 94%;
+    }
+  }
+
+  .today-table::v-deep .el-table td {
+    padding: 18px 0;
+  }
+
+  .today-table::v-deep .el-table th {
+    padding: 18px 0;
+  }
+}
+
+@media screen and (min-width: 1601px) and (max-width: 1680px) {
+  .table {
+    height: 81vh;
+
+    .table-container {
+      height: 94%;
+    }
+  }
+
+  .today-table::v-deep .el-table td {
+    padding: 18px 0;
+  }
+
+  .today-table::v-deep .el-table th {
+    padding: 18px 0;
+  }
+}
+
+@media screen and (min-width: 1361px) and (max-width: 1600px) {
+  .table {
+    height: 73vh;
+
+    .table-container {
+      height: 90%;
+    }
+  }
+
+  .today-table::v-deep .el-table td {
+    padding: 5px 0;
+  }
+
+  .today-table::v-deep .el-table th {
+    padding: 5px 0;
+  }
+}
+
+@media screen and(min-width:1281px) and (max-width: 1360px) {
+  .table {
+    height: 74vh;
+
+    .table-container {
+      height: 90%;
+    }
+  }
+
+  .today-table::v-deep .el-table td {
+    padding: 5px 0;
+  }
+
+  .today-table::v-deep .el-table th {
+    padding: 5px 0;
+  }
+}
+</style>

+ 50 - 95
src/views/business/PharmacyD.vue

@@ -193,9 +193,8 @@
           <div>代煎:</div>
         </div>
         <div class="right">
-          <el-select size="mini" v-model="form.daijian" placeholder="请选择">
-            <el-option label="显示" value="0"></el-option>
-            <el-option label="不显示" value="1"></el-option>
+          <el-select size="mini" v-model="form.daijian" placeholder="请选择" multiple clearable>
+            <el-option v-for="item in optionsAgency" :key="item.value" v-bind="item" />
           </el-select>
         </div>
       </div>
@@ -205,9 +204,8 @@
           <div>默认代煎:</div>
         </div>
         <div class="right">
-          <el-select size="mini" v-model="form.ddaijian" placeholder="请选择">
-            <el-option label="是" value="0"></el-option>
-            <el-option label="否" value="1"></el-option>
+          <el-select size="mini" v-model="form.ddaijian" placeholder="请选择" clearable>
+            <el-option v-for="item in optionsAgency" :key="item.value" v-bind="item" />
           </el-select>
         </div>
       </div>
@@ -226,9 +224,8 @@
           <div>配送:</div>
         </div>
         <div class="right">
-          <el-select size="mini" v-model="form.peisong" placeholder="请选择">
-            <el-option label="显示" value="0"></el-option>
-            <el-option label="不显示" value="1"></el-option>
+          <el-select size="mini" v-model="form.peisong" placeholder="请选择" multiple clearable>
+            <el-option v-for="item in optionsDelivery" :key="item.value" v-bind="item" />
           </el-select>
         </div>
       </div>
@@ -238,9 +235,8 @@
           <div>默认配送:</div>
         </div>
         <div class="right">
-          <el-select size="mini" v-model="form.dpeisong" placeholder="请选择">
-            <el-option label="是" value="0"></el-option>
-            <el-option label="否" value="1"></el-option>
+          <el-select size="mini" v-model="form.dpeisong" placeholder="请选择" clearable>
+            <el-option v-for="item in optionsDelivery" :key="item.value" v-bind="item" />
           </el-select>
         </div>
       </div>
@@ -305,6 +301,8 @@ import {
 export default {
   data() {
     return {
+      optionsAgency: [],
+      optionsDelivery: [],
       form: {
         area: "",
         medName: "", // 医疗结构
@@ -437,11 +435,7 @@ export default {
         });
         return;
       }
-      if (this.type == "add") {
-        this.addPharmacyData();
-      } else if (this.type == "edit") {
-        this.editPharmacMsg();
-      }
+      this.setPharmacyMsg();
     },
 
     // 获取医共体选择器
@@ -526,72 +520,13 @@ export default {
         }
       }
     },
-    //提交数据
-    async addPharmacyData() {
-      let ksIds = JSON.stringify(this.form.departName);
-      let departmentidSelsource = [];
-      let list = this.form.departName;
-
-      let departIds = [];
-      list.forEach(item => {
-        departIds = [...departIds, ...item];
-      });
-
-      departmentidSelsource = this.removalID(departIds);
-
-      let params = {
-        agencyPrice: this.form.daijianPrice,
-        areaCode: this.form.addressCode,
-        defaultAgency: this.form.ddaijian,
-        defaultDelivery: this.form.dpeisong,
-        defaultSpecialDeployment: this.form.dtiaopei,
-        defaultSystemOfCream: this.form.dzhigao,
-        deliveryPrice: this.form.peisongPrice,
-        departmentidSelsource: departmentidSelsource.join(","),
-        ksIds,
-        displayAgency: this.form.daijian,
-        displayDelivery: this.form.peisong,
-        displayName: this.form.showName,
-        displaySpecialDeployment: this.form.tiaopei,
-        displaySystemOfCream: this.form.zhigao,
-        dosageForms: this.form.doseType.join(","),
-        pharmacyId: this.form.id,
-        pharmacyName: this.form.name,
-        pharmacyProperties: this.form.attribute,
-        seqn: this.form.sqen,
-        specialDeploymentPrice: this.form.tiaopeiPrice,
-        // stitutionsId: this.getuserinfo.sititutionid,
-        systemOfCreamPrice: this.form.zhigaoPrice,
-        usableRange: this.form.area,
-        stitutionsId: this.form.medName
-      };
-      const loading = this.$loading({
-        lock: true,
-        text: "Loading",
-        spinner: "el-icon-loading",
-        background: "rgba(0, 0, 0, 0.7)"
-      });
-
-      let res = await addPharmacyData(params).catch(err => {
-        loading.close();
-      });
-      if (res.ResultCode == 0) {
-        this.$message({
-          message: "提交成功",
-          showClose: true,
-          type: "success"
-        });
-        loading.close();
-        setTimeout(() => {
-          this.$router.back();
-        }, 2000);
-      }
-    },
     // 获取详细数据
     async getPharmacyMsg() {
       let res = await getPharmacyMsg(this.pid);
       if (res.ResultCode == 0) {
         let data = res.Data;
+        this.optionsAgency = data.optionsAgency;
+        this.optionsDelivery = data.optionsDelivery;
         this.form = {
           area: data.usableRange,
           sqen: data.seqn,
@@ -623,8 +558,8 @@ export default {
         this.getDepartList(this.form.medName, data.ksIds ? "auto" : "1");
       }
     },
-    // 修改数据
-    async editPharmacMsg() {
+    // 设置详细数据
+    async setPharmacyMsg() {
       let ksIds = JSON.stringify(this.form.departName);
       let departmentidSelsource = [];
       let list = this.form.departName;
@@ -635,6 +570,21 @@ export default {
       });
 
       departmentidSelsource = this.removalID(departIds);
+
+      let displayAgency = '';
+      let displayDelivery = '';
+      if (Array.isArray(this.form.daijian)) {
+        displayAgency = this.form.daijian.map(value => {
+          const option = this.optionsAgency.find(option => option.value === value);
+          return option ? `${option.label}:${option.value}` : void 0;
+        }).filter(Boolean).join(',');
+      }
+      if (Array.isArray(this.form.peisong)) {
+        displayDelivery = this.form.peisong.map(value => {
+          const option = this.optionsDelivery.find(option => option.value === value);
+          return option ? `${option.label}:${option.value}` : void 0;
+        }).filter(Boolean).join(',');
+      }
       let params = {
         agencyPrice: this.form.daijianPrice,
         areaCode: this.form.addressCode,
@@ -645,8 +595,8 @@ export default {
         deliveryPrice: this.form.peisongPrice,
         departmentidSelsource: departmentidSelsource.join(","),
         ksIds,
-        displayAgency: this.form.daijian,
-        displayDelivery: this.form.peisong,
+        displayAgency,
+        displayDelivery,
         displayName: this.form.showName,
         displaySpecialDeployment: this.form.tiaopei,
         displaySystemOfCream: this.form.zhigao,
@@ -668,20 +618,25 @@ export default {
         spinner: "el-icon-loading",
         background: "rgba(0, 0, 0, 0.7)"
       });
-
-      let res = await editPharmacMsg(params).catch(err => {
-        loading.close();
-      });
-      if (res.ResultCode == 0) {
-        this.$message({
-          message: "提交成功",
-          showClose: true,
-          type: "success"
-        });
+      let request = Promise.reject();
+      if (this.type === 'edit') {
+        params.pid = this.pid;
+        request = editPharmacMsg(params);
+      } else if (this.type === 'add') {
+        request = addPharmacyData(params);
+      }
+      try {
+        const res = await request;
+        if (+res.ResultCode === 0) {
+          this.$message({
+            message: '提交成功',
+            showClose: true,
+            type: 'success',
+          });
+          setTimeout(() => { this.$router.back(); }, 1000);
+        }
+      } finally {
         loading.close();
-        setTimeout(() => {
-          this.$router.back();
-        }, 2000);
       }
     }
   },

+ 1 - 1
src/views/diagnosis/DialecticalQ.vue

@@ -70,7 +70,7 @@
             <i class="el-icon-d-arrow-right" v-if="!isShrink"></i>
             <i class="el-icon-d-arrow-left" v-if="isShrink"></i>
           </div>
-          当前病:
+          当前病
           <span>{{info.groupname}}</span>
         </div>
         <div class="continue-time flex-vertical-center-l">

+ 4 - 3
src/views/diagnosis/Emr.vue

@@ -76,6 +76,7 @@ import PriviewEdit from "../business/components/PriviewEdit.vue";
 
 import {formatPicture, toPicture} from "@/utils/picture";
 import SoundRecorder from '@/components/SoundRecorder.vue';
+import {inform} from '@/utils/url';
 
 export default {
   components: {
@@ -363,7 +364,7 @@ export default {
         origin: "EMR",
         msg: "刷新数据"
       };
-      window.parent.postMessage(JSON.stringify(msg), "*");
+      inform(msg);
       console.log(window.parent, "打印父级页面");
       console.log("---执行了发送消息的代码----");
     },
@@ -774,7 +775,7 @@ export default {
               origin: "EMR",
               msg: "刷新数据"
             };
-            window.parent.postMessage(JSON.stringify(msg), "*");
+            inform(msg);
             return;
           }
           next();
@@ -920,7 +921,7 @@ export default {
               origin: "EMR",
               msg: "刷新数据"
             };
-            window.parent.postMessage(JSON.stringify(msg), "*");
+            inform(msg);
             return;
           }
           next();

+ 37 - 7
src/views/diagnosis/Prescribing.vue

@@ -22,7 +22,11 @@
       <div class="pre-title mr-t10">
         <div class="flex-vertical-center-l title-container">
           <span></span>
-          <div>中医电子病历</div>
+          <div style="display: flex;justify-content: space-between; align-items: center; width: 100%">
+            中医电子病历
+            <el-button v-if="showRecordLoading" style="padding: 4px 8px; transform: translateY(2px)" size="mini" :loading="recordLoading" @click="loadRecord()">
+              {{ recordLoading ? '' : '刷新' }}</el-button>
+          </div>
         </div>
       </div>
       <div class="patiens-msg" v-if="patiensMsg.outpatientElectronicmedicalrecord">
@@ -398,7 +402,7 @@
           :showSubmit="showSubmit"
           :isShrink="isShrink"
           :isDaiJian="Number(isDaiJian)"
-          :isPs="isPs"
+          :isPs="Number(isPs)"
           @updateDp="onUpdateDp"
         ></chinese-medicine>
 
@@ -411,7 +415,7 @@
           @clear="clearContainer('1')"
           :totalAllMoney.sync="medicineC.allMoney"
           :showSubmit="showSubmit"
-          :isPs="isPs"
+          :isPs="Number(isPs)"
         ></medicineChinese>
         <suitScience
           @find="find($event)"
@@ -1027,6 +1031,8 @@
           :isPs="Number(isPs)"
           :isShowDj="isShowDj"
           :isShowPs="isShowPs"
+          :optionsAgency="optionsAgency"
+          :optionsDelivery="optionsDelivery"
         ></medAdressNew>
       </div>
     </Popup>
@@ -1051,6 +1057,7 @@ import medAdress from "./components/medAddress.vue";
 import medAdressNew from "./components/medAddressNew.vue";
 import {
   getPatiensBasisM,
+  refreshElectronicInfo,
   getTongueAndFaceAnalysisRecords,
   addRecipe,
   getRecipeShowData,
@@ -1124,6 +1131,7 @@ export default {
       AI_MODEL_URL: window.SIX_config.AI_MODEL_URL,
       unifyPrescriptionTitle: window.SIX_config.unifyPrescription,
 
+      recordLoading: false, // 中医电子病历
       tongueAndFaceLoading: false, // 舌面象加载
       tongueAndFaceAnalysis: null, // 舌面象数据
       showTongueAnalysis: false, // 舌象分析弹窗
@@ -1266,6 +1274,7 @@ export default {
         }
       ],
       patiensMsg: {}, // 患者信息
+      patientMsgPreviewImages: [], // 患者信息预览图片
       dianosisMsg: [], // 诊断信息
 
       ops: {
@@ -1338,6 +1347,23 @@ export default {
     }
   },
   methods: {
+    async loadRecord(tips = true) {
+      this.recordLoading = true;
+      try {
+        let data = await refreshElectronicInfo({
+          patientId: this.getPatiensInfo.pid
+        });
+        if (data.outpatientElectronicmedicalrecord) {
+          data.outpatientElectronicmedicalrecord.image1 = formatPicture(data.outpatientElectronicmedicalrecord.image1);
+          this.patientMsgPreviewImages = [...data.outpatientElectronicmedicalrecord.image1];
+        }
+        this.patiensMsg = {...this.patiensMsg, ...data};
+        if (tips) this.$message.success('刷新成功');
+      } catch (e) {
+        if (tips) this.$message.error(e.message);
+      }
+      this.recordLoading = false;
+    },
     // 处理路由参数
     async _processRouteQuery() {
       const query = this.$route.query || {};
@@ -2461,6 +2487,7 @@ export default {
       data1.recipe_tabs[data1.recipe_tabs_c].bottom_form.disable =
         data.type == "1";
       data1.recipe_tabs[data1.recipe_tabs_c].bottom_form.preType = data.type;
+      data1.recipe_tabs[data1.recipe_tabs_c].bottom_form.doseNum = data.num || '';
       data1.recipe_tabs[data1.recipe_tabs_c].bottom_form.doseType =
         data.curetype;
       data1.recipe_tabs[data1.recipe_tabs_c].bottom_form.nongjian =
@@ -3180,7 +3207,7 @@ export default {
 
         //   this.inferRecipe();
         // }
-      }
+      } else return false;
     },
     async openTongueAndFaceAnalysis() {
       if (!this.tongueAndFaceAnalysis) await this.getPatientBasisTongueAndFaceAnalysis()
@@ -3444,8 +3471,8 @@ export default {
     },
     // 推导处方
     async inferRecipe(type = 1, businesstype, res) {
-      if (!this.patiensMsg.maindiagnosis.disid) {
-        return;
+      if (!this.patiensMsg.maindiagnosis || !this.patiensMsg.maindiagnosis.disid) {
+        if (!this.getPatiensInfo.pid || (await this.getPatiensBasisM().catch(e => false)) === false) return;
       }
       // if (this.container_i == 1) return;
       if (type != 4) {
@@ -4158,7 +4185,10 @@ export default {
         : 0
       ).toFixed(2);
     },
-    ...mapGetters(["getPatiensInfo", "getuserinfo", "getDrugInfo", "getRecipeId", "getIsSee", "getPreNo"])
+    ...mapGetters(["getPatiensInfo", "getuserinfo", "getDrugInfo", "getRecipeId", "getIsSee", "getPreNo"]),
+    showRecordLoading() {
+      return true;
+    },
   },
   filters: {
     ftsjj(value) {

+ 28 - 35
src/views/diagnosis/components/medAddressNew.vue

@@ -3,34 +3,28 @@
     <div class="address-item" v-if="isShowDj">
       <div class="name">代煎信息</div>
       <div class="value">
-        <div class="daijiao-check flex flex-row-left flex-col-center" @click="changeDaijian(0)">
-          <div :class="['img-body',form.isDaiJian===0?'active':'']">
-            <img src="~@/assets/new-icon/checked.png" alt v-if="form.isDaiJian===0" />
+        <div class="daijiao-check flex flex-row-left flex-col-center"
+             v-for="item in optionsAgency" :key="item.value"
+             @click="changeDaijian(+item.value)">
+          <div v-if="+item.value === form.isDaiJian" class="img-body active">
+            <img src="~@/assets/new-icon/checked.png" alt />
           </div>
-          <span>代配</span>
-        </div>
-        <div class="daijiao-check flex flex-row-left flex-col-center" @click="changeDaijian(1)">
-          <div :class="['img-body',form.isDaiJian==1?'active':'']">
-            <img src="~@/assets/new-icon/checked.png" alt v-if="form.isDaiJian==1" />
-          </div>
-          <span>代煎</span>
+          <div v-else class="img-body"></div>
+          <span>{{ item.label }}</span>
         </div>
       </div>
     </div>
     <div class="address-item" v-if="isShowPs">
       <div class="name">配送信息</div>
       <div class="value">
-        <div class="daijiao-check flex flex-row-left flex-col-center" @click="changeKd(1)">
-          <div :class="['img-body',form.iskD==1?'active':'']">
-            <img src="~@/assets/new-icon/checked.png" alt v-if="form.iskD==1" />
-          </div>
-          <span>配送到本院(站)</span>
-        </div>
-        <div class="daijiao-check flex flex-row-left flex-col-center" @click="changeKd(0)">
-          <div :class="['img-body',form.iskD==0?'active':'']">
-            <img src="~@/assets/new-icon/checked.png" alt v-if="form.iskD==0" />
+        <div class="daijiao-check flex flex-row-left flex-col-center"
+             v-for="item in optionsDelivery" :key="item.value"
+             @click="changeKd(+item.value)">
+          <div v-if="+item.value === form.iskD" class="img-body active">
+            <img src="~@/assets/new-icon/checked.png" alt />
           </div>
-          <span>快递配送</span>
+          <div v-else class="img-body"></div>
+          <span>{{ item.label }}</span>
         </div>
       </div>
     </div>
@@ -115,6 +109,14 @@ export default {
       type: Number,
       default: 0
     },
+    optionsAgency: {
+      type: Array,
+      default: () => [],
+    },
+    optionsDelivery: {
+      type: Array,
+      default: () => [],
+    },
     isShowDj: {
       type: Boolean,
       default: true
@@ -200,31 +202,22 @@ export default {
   methods: {
     changeKd(data) {
       this.form.iskD = data;
-      if (data == 0) {
+      if (data === 0) {
         this.getAddressForHospital();
       } else {
         this.getPatAddress();
       }
       this.$emit("psChange", this.form.iskD);
     },
-    //   配送点击
-    changePeiSong(data = null) {
-      if (data === null) {
-        this.form.radio = this.form.radio == 1 ? 0 : 1;
-      } else {
-        this.form.radio = data;
-      }
-
-      // this.getaddress(this.form.radio);
-      this.$emit("psChange", this.form.radio);
-    },
     // 代煎选项点击
     changeDaijian(data = null) {
       if (data === null) {
-        this.form.isDaiJian = this.form.isDaiJian == 1 ? 0 : 1;
+        this.form.isDaiJian = this.form.isDaiJian === 1 ? 0 : 1;
       } else {
-        if (this.form.isDaiJian == data) {
-          this.form.isDaiJian = 2;
+        if (this.form.isDaiJian === data) {
+          // 有 自费 选项
+          if (this.optionsAgency.find(option => option.value === '2')) this.form.isDaiJian = data;
+          else this.form.isDaiJian = 2;
         } else {
           this.form.isDaiJian = data;
         }

+ 3 - 2
src/views/diagnosis/components/submitRecipe.vue

@@ -327,6 +327,7 @@ import chineseMadePad from "@/components/ui/chineseMadePad.vue";
 import suitMadePad from "@/components/ui/suitMadePad.vue";
 
 import { formatPicture } from "@/utils/picture";
+import {inform} from '@/utils/url';
 
 export default {
   components: {
@@ -596,7 +597,7 @@ export default {
           origin: "Recipe",
           msg: "刷新数据"
         };
-        window.parent.postMessage(JSON.stringify(msg), "*");
+        inform(msg);
         if (this.$route.query.from && this.$route.query.from == "validation") {
           setTimeout(() => {
             loading.close();
@@ -641,7 +642,7 @@ export default {
           origin: "Recipe",
           msg: "刷新数据"
         };
-        window.parent.postMessage(JSON.stringify(msg), "*");
+        inform(msg);
         this.$message.success("修改成功");
         setTimeout(() => {
           loading.close();

+ 3 - 0
src/views/hisEnter.vue

@@ -6,6 +6,7 @@ import { seeDoctor } from "@/api/patients.js";
 import { getPatiiensMsg } from "@/api/diagnosis.js";
 import { mapState, mapGetters, mapActions, mapMutations } from "vuex";
 import { getDataByKey } from "@/api/system.js";
+import { setSessionModalId } from '@/utils/url';
 export default {
   data() {
     return {
@@ -20,6 +21,8 @@ export default {
       let pid = this.$route.query.token;
       let token = this.$route.query.Authorization;
 
+      setSessionModalId();
+
       if (token) {
         localStorage.setItem("token", token);
         if (this.getuserinfo) this.getDataByKey();

+ 2 - 1
vue.config.js

@@ -17,7 +17,8 @@ module.exports = {
                 // target: 'http://192.168.204.124:8081/', // 客户正式服务器"
                 // target: `http://121.43.162.141:80/`, // [萧山] 测试环境的后端地址
                 // target: `https://wx.hzliuzhi.com:4433/fz/`, // [测试] 测试环境的后端地址
-                target: `https://tcm2.hzliuzhi.com/`, // @six 演示环境
+                target: `https://tcm2.hzliuzhi.com/`, // @six 演示环境 2.0
+                // target: `https://tcm.hzliuzhi.com/`, // @six 演示环境
                 // target: `http://www.hzxunmai.com/`, // 正式域名
                 // target: `http://10.250.11.48:8080/`, // 正式域名