Procházet zdrojové kódy

[重构] 开方合理安全用药检测 & 签名

cc12458 před 5 měsíci
rodič
revize
88009a1258

+ 56 - 102
src/components/ChineseMedicine.vue

@@ -969,6 +969,7 @@
   </div>
 </template>
 <script>
+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";
@@ -994,6 +995,7 @@ import { mapState, mapGetters, mapActions, mapMutations } from "vuex";
 import popup from "@/components/Propup.vue";
 import accompanied from "./ui/accompanied.vue";
 import {CC_Basis2Dosage, CC_Dosage2Basis} from '@/utils/medicine';
+import {tryRun} from '@/tool';
 
 let medicineBlurTimer;
 export default {
@@ -1176,6 +1178,17 @@ export default {
         }
       ).map(forceUpdate);
     },
+    /**
+     * 检测合理用药
+     * @param [totalData] 药品数据
+     * @param {'check'|'update'} [mode] 模式
+     * @private
+     */
+    _checkReasonableSafeMedicines(totalData, mode = 'check') {
+      if (!Array.isArray(totalData)) totalData = this.recipe_tabs[this.recipe_tabs_c].totalTableD;
+      if (mode === 'update') this.$parent.updateReasonableSafeMedicines(totalData);
+      else this.$parent.checkReasonableSafeMedicines(totalData);
+    },
     // 打开父级安全合理用药监测
     openSafeDrug() {
       this.$parent.opensafeD();
@@ -1332,65 +1345,43 @@ export default {
         }
       }
 
-      if (scope.row.medid.indexOf("-") != -1) {
-        this._getRationalMed(scope.row.medid);
-      } else {
-        this._getRationalMedForPlat(scope.row.medid);
-      }
+      this.doseId = scope.row.medid;
+      // this.dosageRangeShow = false;
+      getReasonableSafeMedicineDosageRange(scope.row).then((data) => {
+        if (data.medid === this.doseId) {
+          this.minDose = data.matmindosage;
+          this.maxDose = data.matmaxdosage;
+        }
+      });
 
       this.countDoseMoney(scope.row.dose || 0, scope);
     },
     doseBlur(scope) {
-      let parent = this.$parent;
-      const rationalMed10 = parent.rationalMed10.find(item => item.reqID === scope.row.medid ) || {}
       if (!+scope.row.dose) scope.row.dose = '';
       if (typeof scope.row.dose === 'string') scope.row.dose = scope.row.dose.trim();
-      if (scope.row.dose === "") {
-        this.$message.error("请输入剂量");
-        rationalMed10.showDose = false;
-        parent.countDose();
-        this.maxDose = null;
-        this.minDose = null;
-        this.doseId = "";
-
-        return;
-      }
-      let unit = scope.row.unit;
-      let dose = Number(scope.row.dose);
-
-      if (unit != "g" && unit != "克" && !Number.isInteger(dose)) {
-        this.$message.error("剂量输入有误");
-
-        rationalMed10.showDose = false;
-        parent.countDose();
-        this.maxDose = null;
-        this.minDose = null;
-        this.doseId = "";
-
-        console.log(
-          document.querySelectorAll("#dose" + scope.row.id)[0],
-          "dayin "
-        );
-        document.querySelectorAll("#dose" + scope.row.id)[0].style.border =
-          "1px solid red";
-        document.querySelectorAll("#dose" + scope.row.id)[0].style.color =
-          "red";
-        return;
+      if (scope.row.dose === '') this.$message.error('请输入剂量');
+      else {
+        let unit = scope.row.unit;
+        let dose = Number(scope.row.dose);
+        if (unit != 'g' && unit != '克' && !Number.isInteger(dose)) {
+          this.$message.error('剂量输入有误');
+          document.querySelectorAll('#dose' + scope.row.id)[0].style.border = '1px solid red';
+          document.querySelectorAll('#dose' + scope.row.id)[0].style.color = 'red';
+        }
       }
 
-      if (this.maxDose && this.minDose) {
-        try {
-          const dose = CC_Dosage2Basis(scope.row);
-          rationalMed10.showDose = dose && (dose < this.minDose || dose > this.maxDose);
-        } catch (e) {}
-      } else {
-        rationalMed10.showDose = false;
-      }
+      getReasonableSafeMedicineDosageRange(scope.row).then(() => {
+        const totalData = this.recipe_tabs[this.recipe_tabs_c].totalTableD;
+        tryRun(() => {
+          Object.assign(totalData.find(item => item.pid === scope.row.pid), scope.row);
+          this._checkReasonableSafeMedicines(totalData, 'update');
+        });
+      });
 
-      parent.countDose();
       this.maxDose = null;
       this.minDose = null;
       this.doseId = "";
+      this.$parent.countDose();
     },
     doseEnter(scope) {
       if (
@@ -1542,16 +1533,6 @@ export default {
         1
       );
 
-      let father = this.$parent;
-      this.recipe_tabs[this.recipe_tabs_c].totalTableD.forEach(item2 => {
-        father.rationalMed.forEach((item1, index1) => {
-          if (item2.medid == item1.reqID || item2.medid == item1.matid) {
-            father.rationalMed.splice(index1, 1);
-            father.resetRationalMed();
-          }
-        });
-      });
-
       this.recipe_tabs[this.recipe_tabs_c].totalTableD = [
         {
           drugList: [],
@@ -1610,6 +1591,8 @@ export default {
       };
       this.nowRecipeMoney = 0;
 
+      this._checkReasonableSafeMedicines();
+
       this.getProver();
       this.getSelectType("中药药品用法", 0);
       this.getSelectType("剂型", 0);
@@ -1723,21 +1706,7 @@ export default {
       this.getSelectType("中药服药时间");
       this.getSelectType("中药频次");
       // 调用 父级合理用药接口
-      let father = this.$parent;
-      father.rationalMed = [];
-      for (let i = 1; i < 11; i++) {
-        father["rationalMed" + i] = [];
-      }
-
-      this.recipe_tabs[this.recipe_tabs_c].totalTableD.forEach(item => {
-        if (item.name) {
-          if (item.medid.indexOf("-") != -1) {
-            father.getRationalMed(item.medid);
-          } else {
-            father.getRationalMedForPlat(item.medid);
-          }
-        }
-      });
+      this._checkReasonableSafeMedicines();
 
       try {
         let pid = this.recipe_tabs[this.recipe_tabs_c].radio.split("@")[0];
@@ -1816,6 +1785,7 @@ export default {
       let obj = {
         color: item.kc == 0 ? "red" : "#000",
         id: scope.row.id,
+        pid: item.pid,
         name: item.ypmc,
         spec: item.gg, // 规格
         // dose: "", // 剂量
@@ -1832,6 +1802,8 @@ export default {
         inventory: item.kc, // 库存
         key: "",
         search_i: index,
+        matname: item.platformdrugname, // 知识库id
+        matid: item.platformdrugid, // 知识库name
         medid: item.pid, // 药品id
         originname: item.cdmc, // 产地名称
         showSearch: false,
@@ -1845,24 +1817,15 @@ export default {
         obj.dose = CC_Basis2Dosage(obj, (value) => !obj.unit || ['g', '克'].includes(obj.unit) || Number.isInteger(value))
       }
 
+      obj.matmindosage = '';
+      obj.matmaxdosage = '';
+      obj.dosageRange = '';
+
       const m = Object.assign(totalData[scope.row.id - 1], obj);
       if (defaultUsage) this.defaultUsageMap[obj.medid] = m;
 
       // 调用 父级合理用药接口
-      let father = this.$parent;
-
-      father.rationalMed.forEach((item1, index1) => {
-        if (this.clickPid == item1.reqID || this.clickPid == item1.matid) {
-          father.rationalMed.splice(index1, 1);
-          father.resetRationalMed();
-        }
-      });
-
-      if (obj.medid.indexOf("-") != -1) {
-        father.getRationalMed(obj.medid);
-      } else {
-        father.getRationalMedForPlat(obj.medid);
-      }
+      this._checkReasonableSafeMedicines(totalData);
 
       if (scope.row.id == totalData.length) {
         totalData.push({
@@ -1965,22 +1928,13 @@ export default {
     },
     // 表一和表二 数据删除
     deleteDis1(scope) {
-      let father = this.$parent;
-      father.rationalMed.forEach((item1, index1) => {
-        if (scope.row.medid == item1.reqID || scope.row.medid == item1.matid) {
-          father.rationalMed.splice(index1, 1);
-          father.resetRationalMed();
-        }
-      });
       let totalData = this.recipe_tabs[this.recipe_tabs_c].totalTableD;
       let index = scope.row.id - 1;
       this.recipe_tabs[this.recipe_tabs_c].totalTableD.splice(index, 1);
       totalData.filter((item, index) => {
-        // 调用 父级合理用药接口
-
-        // father.getRationalMed(item.medid)
         return (item.id = index + 1);
       });
+      this._checkReasonableSafeMedicines(totalData);
       this._splitDataToView(totalData);
       this.countNowRecipeMoney();
     },
@@ -2453,11 +2407,11 @@ export default {
     },
 
     // 切换中药类型时 切换 药房 获取 药品里面有没有这条数据
-    async changePharmacy(type, val) {
+    async changePharmacy(type, val, force = false) {
       // else 触发在 this.$emit("updateDp", res.Data)
       if (this.recipe_tabs[this.recipe_tabs_c].radio == val) {
         this.$parent.openAddress();
-        return;
+        if (!force) return;
       }
       if (!type) type = this.recipe_tabs[this.recipe_tabs_c].lastType || '';
       if (!val) val = this.recipe_tabs[this.recipe_tabs_c].radio || '';
@@ -2520,7 +2474,10 @@ export default {
                 if (item instanceof Object && item.oldYpid == item1.medid) {
                   item1 = {
                     id: 2,
+                    pid: item.pid,
                     name: item.ypmc,
+                    matname: item.platformdrugname, // 知识库id
+                    matid: item.platformdrugid, // 知识库name
                     spec: item.gg, // 规格
                     dose: item.dose, // 剂量
                     unit: item.dw, // 单位
@@ -2559,11 +2516,8 @@ export default {
             return (item.id = index + 1);
           }
         );
+        this._checkReasonableSafeMedicines();
         this._splitDataToView();
-        this.$parent.rationalMed = [];
-        this.recipe_tabs[this.recipe_tabs_c].totalTableD.forEach(item => {
-          this.$parent.getRationalMed(item.medid)
-        });
 
         // this.recipe_tabs[this.recipe_tabs_c].lastType = this.recipe_tabs[this.recipe_tabs_c]
         //     .radio // 存储这一次的 药房类型

+ 7 - 0
src/components/TCMDiagnosis.vue

@@ -264,6 +264,13 @@ export default {
         treatment: this.therapy
       };
     },
+    getIllness() {
+      return {
+        disease: {code: this.diseaseCode, id: this.zy_dise_id, name: this.name},
+        symptom: {code: this.zhengxingid, name: this.syndrome},
+        therapy: {code: this.therapyCode, name: this.therapy},
+      }
+    },
     optimalTherapyCode() {
       if (this.therapy && !this.therapyCode) try {
         this.therapyCode = this.therapyList.find(item => [item.therapy, item['therapyName']].includes(this.therapy)).therapyCode;

+ 2 - 1
src/request/api.js

@@ -1 +1,2 @@
-export * from './api.illness';
+export * from './api.illness';
+export * from './api.prescription';

+ 83 - 0
src/request/api.prescription.js

@@ -0,0 +1,83 @@
+import {findArray, getArray, toArray, tryRun} from '@/tool';
+
+import http from './http';
+import {ReasonableSafeMedicine} from './model';
+import {CC_Dosage2Basis} from '@/utils/medicine';
+
+/**
+ * 获取合理安全用药 剂量范围
+ * @param medicine
+ * @return {Promise<{dosageRange: string} & Object>}
+ */
+export async function getReasonableSafeMedicineDosageRange(medicine) {
+  if (!medicine.dosageRange) {
+    const data = await http.post(`/basis/knowlib/medicineInfoQuery`, null, {
+      params: {matid: medicine.matid},
+      meta: {share: true, key: medicine.matid},
+    }).then(res => res.data || {});
+
+    const matmindosage = tryRun(() => data['matmindosage']);
+    const matmaxdosage = tryRun(() => data['matmaxdosage']);
+    medicine['matmindosage'] = +matmindosage;
+    medicine['matmaxdosage'] = +matmaxdosage;
+    medicine['dosageRange'] = [matmindosage, matmaxdosage].filter(Boolean).join('-');
+  }
+
+  const dosage = CC_Dosage2Basis(medicine);
+
+  medicine['rs@10.1'] = '';
+  medicine['rs@10.2'] = '';
+  if (dosage && medicine.matmindosage && medicine.dose < medicine.matmindosage) medicine['rs@10.1'] = `${medicine.matname || medicine.name}${dosage}g(${medicine.dosageRange})`;
+  if (dosage && medicine.matmaxdosage && medicine.dose > medicine.matmaxdosage) medicine['rs@10.2'] = `${medicine.matname || medicine.name}${dosage}g(${medicine.dosageRange})`;
+
+
+  return medicine;
+}
+
+/**
+ * 检测合理安全用药
+ * @param {object[]} medicines 药品
+ * @param {object} params 参数
+ * @param {object} params.patient 患者信息
+ * @param {object} params.illness 疾病信息
+ * @return {Promise<*>}
+ */
+export function checkReasonableSafeMedicinesMethod(medicines, params) {
+  const find = (matid = '') => findArray(medicines, ['matid', matid.toString()]) || {};
+  const append = (medicine, field, value) => { medicine[field] = medicine[field] ? `${medicine[field]}|${value}` : value; };
+  return http.post(`/basis/knowlib/interactionReport`, {
+    medList: medicines.filter(medicine => medicine.matid).map(medicine => {
+      for (const key of Object.keys(medicine)) if (key.startsWith(`rs@`)) delete medicine[key];
+      return {
+        pid: medicine.pid, name: medicine.name,
+        medId: medicine.matid,
+        medName: medicine.matname,
+        medDose: CC_Dosage2Basis(medicine) || 0,
+        medUsage: medicine.usage || '',
+      };
+    }),
+    age: tryRun(() => params.patient.age),
+    gender: tryRun(() => ({'男': 'M', '女': 'F'}[params.patient.sex])),
+    gravidity: tryRun(() => ({'2': 'Y', '1': 'N'}[params.patient.isGravidity])),
+    disId: tryRun(() => params.illness.disease.id, ''),
+    synId: tryRun(() => params.illness.symptom.code, ''),
+  }, {meta: {share: true}}).then(res => {
+    for (const {field, key} of ReasonableSafeMedicine.config) {
+      if (!key) continue;
+      tryRun(() => {
+        getArray(res.data[key], item => {
+          const value = item.medDesc;
+          const medicine = find(item.medId);
+          if (key !== 'lowDose' || medicine.dose) {
+            append(medicine, field, value);
+            toArray(item.incMeds, item => {
+              const medicine = find(item.medId);
+              append(medicine, field, value);
+            });
+          }
+        });
+      });
+    }
+    return medicines;
+  });
+}

+ 1 - 0
src/request/model.js

@@ -0,0 +1 @@
+export * from './model.prescription';

+ 86 - 0
src/request/model.prescription.js

@@ -0,0 +1,86 @@
+import {findArray, stringToArray, tryRun} from '@/tool';
+
+export class ReasonableSafeMedicine {
+  constructor(sort = ReasonableSafeMedicine.sort) {
+    this.sort = sort;
+  }
+
+  analysis(medicines) { return ReasonableSafeMedicine.analysis(medicines, {sort: this.sort}); }
+
+
+  static config = [
+    {field: 'rs@10.1', key: 'lowDose', name: '剂量偏低', highlight: {value: true}},
+    {field: 'rs@10.2', key: 'overDose', name: '剂量偏高', highlight: {value: true}},
+    {field: 'rs@10', key: '', name: '超剂量药品', highlight: {value: true}},
+    {field: 'rs@02', key: 'taboo', name: '慎忌禁用药'},
+    {field: 'rs@03', key: 'pregnantTaboo', name: '孕妇慎忌禁'},
+    {field: 'rs@04', key: 'diet', name: '服药饮食禁忌'},
+    {field: 'rs@05', key: 'toxicity', name: '药物毒性说明', highlight: {label: true}},
+    {field: 'rs@06', key: 'disSyn', name: '病证用药禁忌'},
+    {field: 'rs@07', key: 'sbf', name: '十八反', highlight: {label: true}},
+    {field: 'rs@08', key: 'sjw', name: '十九畏', highlight: {label: true}},
+    {field: 'rs@09', key: 'by', name: '用药不宜'},
+    {field: 'rs@00', key: 'prepare', name: '炮制品'},
+  ];
+  static sort = '10,2,3,4,5,6,7,8,9';
+
+  /**
+   * 解析药品的合理安全用药数据
+   * @param medicines 药品
+   * @param {object} [config] 配置信息
+   * @param {string} [config.filter] 过滤规则
+   * @param {string} [config.sort] 排序规则
+   * @return {Readonly<{
+   *  [key: string]: { name: string; collection: Set<string>; gather: Set<string>; highlight?: {label: boolean; value: boolean;} }
+   *  toString(): string
+   * }>}
+   */
+  static analysis(medicines, config = {}) {
+    const sort = stringToArray(config.filter || config.sort || this.sort);
+    const data = {
+      * [Symbol.iterator]() { for (const key of sort) if (this[key]) yield this[key]; },
+      sign() {
+        const gather = new Set()
+        for (const item of this) item.gather.forEach(value => gather.add(value));
+        return Array.from(gather);
+      },
+      toString() {
+        const parse = (value, highlight) => { return value; };
+        let html = ``;
+        for (const {name, highlight = {}, collection} of this) {
+          html += `
+            <div class="item">
+                <div class="label">${name}:</div>
+                ${Array.from(collection, item => `
+                    <div class="value">${parse(item, highlight)}</div>
+                `).join('')}
+            </div>
+          `;
+        }
+        return html;
+      },
+    };
+    Object.defineProperty(data, 'sign', {enumerable: false, writable: true, configurable: true});
+    Object.defineProperty(data, 'toString', {enumerable: false, writable: true, configurable: true});
+
+    const append = (key, value, id) => {
+      if (!value) return '';
+      const config = findArray(this.config, ['field', `rs@${key}`]);
+      if (config) {
+        const child = data[+key] || (data[+key] = {...config, collection: new Set(), gather: new Set()});
+        stringToArray(value, '|', (v) => child.collection.add(v));
+        if (id) child.gather.add(id);
+      }
+    };
+    for (const medicine of medicines) {
+      for (const field of Object.keys(medicine)) {
+        const match = field.match(/rs@(\d+)(?:\.(\d+))?$/);
+        if (!match) continue;
+        const [_, category, subcategory] = match;
+        append(category, medicine[field], medicine.matid);
+        if (subcategory) append(`${category}.${subcategory}`, medicine[field], medicine.matid);
+      }
+    }
+    return Object.freeze(data);
+  }
+}

+ 7 - 0
src/tool/array.js

@@ -29,4 +29,11 @@ export function findArray(value, predicate, defaultValueIndex = -1) {
 
   const index = Math.max(value.findIndex(predicate), defaultValueIndex);
   return index === -1 ? void 0 : value[index];
+}
+
+export function stringToArray(value, separatorOrMap = ',', map) {
+  if (!value || typeof value !== 'string') return [];
+
+  if (typeof separatorOrMap === 'function') [map, separatorOrMap] = [separatorOrMap, ','];
+  return getArray(value.split(separatorOrMap).filter(Boolean), map);
 }

+ 14 - 1
src/tool/index.js

@@ -1,2 +1,15 @@
 export * from './array.js';
-export {default as randomUUID} from './uuid.js';
+export {default as randomUUID} from './uuid.js';
+
+export function tryRun(fn, defaultValue) {
+  try { return fn() || defaultValue; } catch (_) { return defaultValue; }
+}
+
+export function tryRunOrError(fn, defaultValue) {
+  try {
+    const value = fn() || defaultValue;
+    return [null, value];
+  } catch (error) {
+    return [error, defaultValue];
+  }
+}

+ 2 - 2
src/utils/minix/prescribing.js

@@ -204,11 +204,11 @@ export default {
             try {
                 const res = await getRationalSafeUse();
                 return {
-                    options: res.Data.rational_safe.split(',').filter(Boolean),
+                    filter: res.Data.rational_safe,
                     force: +res.Data.rational_safe_mandatoryOrNot === 1 // 0 否(可以继续开方) 1是(不可以继续开方)
                 }
             } catch (e) {
-                return {options: [], force: false,}
+                return {filter: '', force: false,}
             }
         },
         // 获取医保规则最大/最小药味数

+ 107 - 140
src/views/diagnosis/Prescribing.vue

@@ -498,100 +498,9 @@
       <div class="pre-title mr-t10" v-if="container_i!=2">
         <div class="flex-vertical-center-l title-container">
           <span></span>
-          <div>安全合理用药检测</div>
-        </div>
-        <div class="patiens-msg mr-t10" v-if="rationalMed.length>0">
-          <div class="p" v-if="raDoseShow">
-            <!-- {{item.matname}}({{item.matbzjj}}) -->
-            <!-- <div class="patiens-name">{{item.matname}}</div> -->
-            <div class="patiens-cate">超剂量药品:</div>
-            <div class="patiens-desc" v-for="(item,index) in rationalMed10" :key="index">
-              <span v-if="item.showDose">
-                <span class="matname">{{item.matname}}</span>
-                <span style="color:red;">({{item.matmindosage}}-{{item.matmaxdosage}})</span>
-              </span>
-            </div>
-          </div>
-
-          <div class="p" v-if="rationalMed2.length>0">
-            <div class="patiens-cate">慎忌禁用药:</div>
-            <div class="patiens-desc" v-for="(item,index) in rationalMed2" :key="index">
-              <span v-if="item.matsjj">
-                <span class="matname">{{item.matname}}</span>
-                ({{item.matsjj}})
-              </span>
-            </div>
-          </div>
-
-          <div class="p" v-if="rationalMed3.length>0">
-            <div class="patiens-cate">孕妇慎忌禁:</div>
-            <div class="patiens-desc" v-for="(item,index) in rationalMed3" :key="index">
-              <span v-if="item.matyfsjj">
-                <span class="matname">{{item.matname}}</span>
-                <span :style="{color:item.matyfsj==3?'red':''}">({{item.matyfsjj |fyfsjj}})</span>
-              </span>
-            </div>
-          </div>
-
-          <div class="p" v-if="rationalMed4.length>0">
-            <div class="patiens-cate">服药饮食禁忌:</div>
-            <div class="patiens-desc" v-for="(item,index) in rationalMed4" :key="index">
-              <span v-if="item.matysjj">
-                <span class="matname">{{item.matname}}</span>
-                ({{item.matysjj?item.matysjj:'无'}})
-              </span>
-            </div>
-          </div>
-
-          <div class="p" v-if="rationalMed5.length>0">
-            <div class="patiens-cate">药物毒性说明:</div>
-            <div class="patiens-desc" v-for="(item,index) in rationalMed5" :key="index">
-              <span v-if="item.matdxsm">
-                <span class="matname" style="color:red;">{{item.matname}}</span>
-                ({{item.matdxsm?item.matdxsm:'无'}})
-              </span>
-            </div>
-          </div>
-
-          <div class="p" v-if="rationalMed6.length>0">
-            <div class="patiens-cate">病证用药禁忌:</div>
-            <div class="patiens-desc" v-for="(item,index) in rationalMed6" :key="index">
-              <span v-if="item.matbzjj">
-                <span class="matname">{{item.matname}}</span>
-                ({{item.matbzjj?item.matbzjj:'无'}})
-              </span>
-            </div>
-          </div>
-
-          <div class="p" v-if="rationalMed7.length>0">
-            <div class="patiens-cate">十八反:</div>
-            <div class="patiens-desc" v-for="(item,index) in rationalMed7" :key="index">
-              <!-- <span v-if='item.matsbf'>{{fsbf(item.matsbf,item.matname)}}</span> -->
-              <span v-if="item.matsbf">
-                <span style="color:red;">{{item.matname}}</span>
-                反{{item.matsbf}}
-              </span>
-            </div>
-          </div>
-
-          <div class="p" v-if="rationalMed8.length>0">
-            <div class="patiens-cate">十九畏:</div>
-            <div class="patiens-desc" v-for="(item,index) in rationalMed8" :key="index">
-              <!-- <span v-if="item.matsjw">{{fsjw(item.matsjw,item.matname)}}</span> -->
-              <span v-if="item.matsjw">
-                <span style="color:red;">{{item.matname}}</span>
-                畏{{item.matsjw}}
-              </span>
-            </div>
-          </div>
-
-          <div class="p" v-if="rationalMed9.length>0">
-            <div class="patiens-cate">用药不宜:</div>
-            <div class="patiens-desc" v-for="(item,index) in rationalMed9" :key="index">
-              <span v-if="item.matby">{{fmatby(item.matby,item.matname) }}</span>
-            </div>
-          </div>
+          <div>安全合理用药检测<i style="margin-left: 2px;" class="el-icon-loading" v-if="reasonableSafeMedicinesLoading"></i></div>
         </div>
+        <div class="patiens-msg reasonable-safe-medicines-wrapper" v-html="reasonableSafeMedicinesHTML"></div>
       </div>
     </div>
 
@@ -1105,8 +1014,8 @@
       distanceTop="5vh"
       :destroyOnClose="true"
     >
-      <div slot="body">
-        <safeDrug v-if="showSafeD"></safeDrug>
+      <div slot="body" v-loading="reasonableSafeMedicinesLoading">
+        <div class="patiens-msg reasonable-safe-medicines-wrapper" v-html="reasonableSafeMedicinesHTML"></div>
       </div>
     </Popup>
 
@@ -1180,7 +1089,13 @@ import {
   getAcupointD,
   getMedDetail
 } from "@/api/knowledge.js";
-import {legacyDeduceIllnessPrescriptionMethod} from '@/request/api';
+import {
+  legacyDeduceIllnessPrescriptionMethod,
+  checkReasonableSafeMedicinesMethod,
+} from '@/request/api';
+import {
+  ReasonableSafeMedicine,
+} from '@/request/model';
 
 import { mapState, mapGetters, mapActions, mapMutations } from "vuex";
 import { getExperinceDetail } from "@/api/business.js";
@@ -1190,6 +1105,9 @@ import prescribing from "../../utils/minix/prescribing";
 import {formatPicture} from "@/utils/picture";
 import {CC_Dosage2Basis} from '@/utils/medicine';
 import AiEModal from '@/components/AiEModal.vue';
+import {tryRun} from '@/tool';
+
+const reasonableSafeMedicine = new ReasonableSafeMedicine();
 
 export default {
   mixins: [prescribing],
@@ -1306,6 +1224,11 @@ export default {
         loadMore: true,
         key: ""
       },
+      /**
+       * 合理安全用药解析数据
+       */
+      reasonableSafeMedicinesHTML: '',
+      reasonableSafeMedicinesLoading: false,
       // 保存右侧合理用药信息
       rationalMed: [],
       // 从1-9 分别对应 超剂量 到 19反
@@ -1906,6 +1829,7 @@ export default {
               dose: Number(item1.dose),
               drugName: item1.name,
               drugid: item1.medid,
+              platformdrugid: item1.matid,
               origin: item1.originname,
               seqn: item1.id,
               specification: item1.spec,
@@ -2280,6 +2204,9 @@ export default {
               usageList: [],
               id: item1.seqn,
               name: item1.drugName,
+              // pid:
+              matid: item1.platformdrugid, // 知识库
+              matname: item1.platformdrugname, // 知识库
               spec: item1.specification, // 规格
               dose: item1.dose, // 剂量
               unit: item1.unit, // 单位
@@ -2351,7 +2278,8 @@ export default {
 
         data1.changePharmacy(
           arr[arr.length - 1].radio,
-          arr[arr.length - 1].radio
+          arr[arr.length - 1].radio,
+          true,
         );
         data1.$forceUpdate();
         loading.close();
@@ -2562,6 +2490,7 @@ export default {
       data1.recipe_tabs[data1.recipe_tabs_c].bottom_form.usege = data.usrage;
 
       data1.recipe_tabs[data1.recipe_tabs_c].totalTableD = [];
+      this.checkReasonableSafeMedicines([]);
 
       if (!request) return;
 
@@ -2573,7 +2502,10 @@ export default {
           loadMore: true,
           usageList: [],
           id: item.seqn,
+          pid: item.pid,
           name: item.ypmc || item.drugname,
+          matname: item.platformdrugname, // 知识库id
+          matid: item.platformdrugid, // 知识库name
           spec: item.gg || item.specification, // 规格
           dose: item.dose, // 剂量
           unit: item.dw || item.unit, // 单位
@@ -2607,9 +2539,6 @@ export default {
 
       data1.recipe_tabs[data1.recipe_tabs_c].totalTableD.filter(
         (item3, index3) => {
-          this.rationalMed = [];
-          this.resetRationalMed();
-          this.getRationalMed(item3.medid);
           return (item3.id = index3 + 1);
         }
       );
@@ -2674,14 +2603,21 @@ export default {
             zhongPrescriptionVo = this.dealRecipe1(child);
             if (!zhongPrescriptionVo || !zhongPrescriptionVo.length) return cancel(tab.id);
             try {
-              const {options, force} = await this.getRationalSafeUse();
-              if (options.length) {
-                const results = await Promise.all(child.recipe_tabs.map((_, index) => this.getRationalMed2(index, (drugid, type) => {
-                  if (force && options.includes(type.toString())) try { zhongPrescriptionVo[index].zhongdetail.find(item => item.drugid === drugid).sign = this.getuserinfo.username; } catch (_) { }
-                })));
+              const {filter, force} = await this.getRationalSafeUse();
+              if (filter) {
+                const results = await Promise.all(child.recipe_tabs.map((item, index) => {
+                  return checkReasonableSafeMedicinesMethod(item.totalTableD, {
+                    patient: this.patiensMsg,
+                    illness: this.$refs.TCM.getIllness(),
+                  }).then(medicines => ReasonableSafeMedicine.analysis(medicines, {filter}));
+                }));
+                const sign = (index, value) => tryRun(() => {
+                  zhongPrescriptionVo[index].zhongdetail.find(item => item.platformdrugid === value).sign = this.getuserinfo.username;
+                });
                 const tips = results.map((item, index) => {
-                  const value = options.map(i => item[i] ? `<div class="title">${item[i].title}</div><div class="content">${item[i].collection.join('')}</div>` : '').join('');
-                  return value ? `<div style="padding-top: ${index ? 12 : 0}px;border-bottom: 1px dashed #dcdcdc;"><h2 style="margin-bottom: 16px;">${item.title}</h2>${value}</div>` : '';
+                  for (const value of item.sign()) sign(index, value);
+                  const value = item.toString();
+                  return value ? `<div style="padding-top: ${index ? 12 : 0}px;border-bottom: 1px dashed #dcdcdc;"><h2 style="margin-bottom: 16px;">处方${index + 1}</h2><div class="reasonable-safe-medicines-wrapper">${value}</div></div>` : '';
                 }).join('');
                 if (tips) {
                   if (!force) {
@@ -3843,6 +3779,32 @@ export default {
         this.rationalMed10 = removeRepeat(this.rationalMed10, "matid");
       }
     },
+    /**
+     * 检测合理安全用药
+     * 可供 子组件 调用 {@link ChineseMedicine }
+     * @param medicines 药品
+     * @return {Promise<*>}
+     */
+    async checkReasonableSafeMedicines(medicines) {
+      this.reasonableSafeMedicinesLoading = true;
+      medicines = await checkReasonableSafeMedicinesMethod(medicines, {
+        patient: this.patiensMsg,
+        illness: this.$refs.TCM.getIllness(),
+      });
+      return await this.updateReasonableSafeMedicines(medicines);
+    },
+    /**
+     * 更新合理安全用药
+     * 可供 子组件 调用 {@link ChineseMedicine }
+     * @param medicines 药品
+     * @return {Promise<>}
+     */
+    async updateReasonableSafeMedicines(medicines) {
+      const data = reasonableSafeMedicine.analysis(medicines);
+      this.reasonableSafeMedicinesHTML = data.toString();
+      this.reasonableSafeMedicinesLoading = false;
+      return data;
+    },
     // 推导处方
     async inferRecipe(type = 1, businesstype, res) {
       if (!this.patiensMsg.maindiagnosis.disid) {
@@ -4139,11 +4101,12 @@ export default {
                   kc: 0,
                   cdmc: "无",
                   pid: item1.matid,
+                  matname: item1.platformdrugname, // 知识库id
+                  matid: item1.platformdrugid || item1.matid, // 知识库name
                   color: "red",
                   dose: item1.dose,
                   usage: item1.useage || item1.usagestr, // child.usegeList[0].key,
                   showSearch: false,
-                  matid: item1.matid,
 
                   key: "",
                   search_i: index
@@ -4178,7 +4141,10 @@ export default {
                 loadMore: true,
                 usageList: [],
                 id: item.seqn,
+                pid: item.pid,
                 name: item.ypmc,
+                matname: item.platformdrugname, // 知识库id
+                matid: item.platformdrugid || item.matid, // 知识库name
                 spec: item.gg, // 规格
                 dose: item.dose, // 剂量
                 unit: item.dw, // 单位
@@ -4216,21 +4182,6 @@ export default {
 
             child.recipe_tabs[child.recipe_tabs_c].totalTableD.filter(
               (item3, index3) => {
-                if (item3.medid) {
-                  this.rationalMed = [];
-                  this.resetRationalMed();
-                  // if (item3.color != '#000') {
-                  //   this.getRationalMedForPlat(item3.medid)
-                  // } else {
-                  //   this.getRationalMed(item3.medid)
-                  // }
-                  if (item3.medid.indexOf("-") != -1) {
-                    this.getRationalMed(item3.medid);
-                  } else {
-                    this.getRationalMedForPlat(item3.medid);
-                  }
-                }
-
                 return (item3.id = index3 + 1);
               }
             );
@@ -4267,7 +4218,10 @@ export default {
                 loadMore: true,
                 usageList: [],
                 id: item.seqn,
+                pid: item.pid,
                 name: item.ypmc,
+                matname: item.platformdrugname, // 知识库id
+                matid: item.platformdrugid || item.matid, // 知识库name
                 spec: item.gg, // 规格
                 dose: item.dose, // 剂量
                 unit: item.dw, // 单位
@@ -4318,19 +4272,6 @@ export default {
             ].tableData = child.recipe_tabs[
               child.recipe_tabs_c
             ].totalTableD.filter(item2 => {
-              if (item2.medid) {
-                // if (item2.color != '#000') {
-                //   this.getRationalMedForPlat(item2.medid)
-                // } else {
-                //   this.getRationalMed(item2.medid)
-                // }
-                if (item2.medid.indexOf("-") != -1) {
-                  this.getRationalMed(item2.medid);
-                } else {
-                  this.getRationalMedForPlat(item2.medid);
-                }
-              }
-
               return Number(item2.id) % 2 != 0;
             });
             child.recipe_tabs[
@@ -4347,6 +4288,7 @@ export default {
           this.showPresc = false;
           this.showUnifyPresc = false;
           loading.close();
+          this.checkReasonableSafeMedicines(child.recipe_tabs[child.recipe_tabs_c].totalTableD);
           try { child.recipe_tabs[child.recipe_tabs_c].id = recipeId; } catch (e) {}
         }
       } else if (this.container_i == 2) {
@@ -5715,11 +5657,33 @@ export default {
 @import "../../style/media/diagnosis/prescribing.scss";
 </style>
 <style lang="scss">
-/* @media screen and (max-width: 768px) {
-  body {
-    width: 100% !important;
+.reasonable-safe-medicines-wrapper {
+  .item {
+    .label {
+      margin: 12px 0 6px;
+      font-size: 16px;
+      font-weight: 700;
+    }
+
+    .value {
+      line-height: 1.75;
+
+      span {
+        &:first-of-type {
+          color: #5386f6;
+        }
+
+        &:last-of-type {
+          color: #333;
+        }
+      }
+    }
+
+    .highlight {
+      color: #ff4d4f !important;
+    }
   }
-} */
+}
 
 .message-rational-safe-use-wrapper {
   align-items: flex-start;
@@ -5752,5 +5716,8 @@ export default {
     width: 100%;
     color: #333;
   }
+  .reasonable-safe-medicines-wrapper {
+    padding-bottom: 8px;
+  }
 }
 </style>