Просмотр исходного кода

Merge branch 'release/execution-10'

cc12458 1 год назад
Родитель
Сommit
8a440c050d

+ 2 - 0
.gitignore

@@ -22,3 +22,5 @@ pnpm-debug.log*
 *.njsproj
 *.sln
 *.sw?
+
+cloudclinich5-**.zip

+ 12 - 0
src/api/diagnosis.js

@@ -29,6 +29,18 @@ export function addDiagnosisData(data) {
     })
 };
 
+export function addDiagnosisData2(data) {
+    return request({
+        url: '/outpatient/diagnosisMgr/Add',
+        method: 'post',
+        data,
+    }).then(res => {
+        if (res.ResultCode !== 0) throw Error(res.ResultInfo || `错误`);
+        if (!res.Data.mainDiagnosis) return {mainDiagnosis: res.Data};
+        return res.Data;
+    });
+}
+
 // 修改诊断页面数据
 export function editDiagnosisData(data) {
     return request({

+ 96 - 42
src/components/ChineseMedicine.vue

@@ -56,7 +56,7 @@
         </div>
         <!-- @change="getPharmacyID" -->
         <!-- @change="changePharmacy(recipe_tabs[recipe_tabs_c].lastType)" -->
-        <div class="t-con-radio flex-vertical-center-l">
+        <div class="t-con-radio flex-vertical-center-l" v-if="false">
           <div class="t-radio-group">
             <el-radio-group
               v-model="recipe_tabs[recipe_tabs_c].radio"
@@ -73,6 +73,17 @@
             </el-radio-group>
           </div>
         </div>
+        <div class="t-con-radio flex-vertical-center-l" style="flex-wrap: wrap;align-items: center;">
+          <div class="t-radio-group2" :class="{multiple: group.options.length > 1}" v-for="group in pharmacyTypeGroup" :key="group.name">
+            <label v-if="group.options.length > 1">{{group.name}}</label>
+            <el-radio v-for="item in group.options" :key="item.ptype"
+                      v-model="recipe_tabs[recipe_tabs_c].radio"
+                      :disabled="recipe_tabs[recipe_tabs_c].disable"
+                      :label="item.ptype"
+                      @click.native.prevent="recipe_tabs[recipe_tabs_c].disable || changePharmacy(recipe_tabs[recipe_tabs_c].lastType,item.ptype)"
+            >{{item.name}}</el-radio>
+          </div>
+        </div>
 
         <!-- <div class="add-presc1 flex-center" @click="clearRecipe()">清空处方</div> -->
       </div>
@@ -347,7 +358,7 @@
                 </el-table-column>
 
                 <el-table-column prop="spec" label="规格" width="100"></el-table-column>
-                <el-table-column prop="dose" label="剂量" width="40">
+                <el-table-column prop="dose" label="剂量" width="60">
                   <template slot-scope="scope" v-if="scope.row.name">
                     <div class="t_dose">
                       <el-input
@@ -583,7 +594,7 @@
                 </el-table-column>
                 <!-- fixed="left" -->
                 <el-table-column prop="spec" label="规格" width="100"></el-table-column>
-                <el-table-column prop="dose" label="剂量" width="40">
+                <el-table-column prop="dose" label="剂量" width="60">
                   <template slot-scope="scope" v-if="scope.row.name">
                     <div class="t_dose">
                       <el-input
@@ -624,7 +635,7 @@
                       <el-option
                         :label="item.value"
                         :value="item.key"
-                        v-for="(item,index) in scope.row.usageList"
+                        v-for="(item,index) in usageList"
                         :key="scope.row.id+'h'+index"
                       ></el-option>
                     </el-select>
@@ -982,6 +993,7 @@ import { debounce } from "@/utils/format.js";
 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';
 
 let medicineBlurTimer;
 export default {
@@ -1074,7 +1086,7 @@ export default {
             timeList: [], // 服药时间后台数据
             caozuo: "",
             zhutuo: "",
-            radio: 1,
+            radio: 1, // TODO 配送 :0 配送 注意:isPs isKD
             isDaiJian: 2,
             provinceList: [],
             cityList: [],
@@ -1102,6 +1114,7 @@ export default {
       isAutoCheck: "0", // 是否自动审核 0 手动 1自动 (自动的时候用his 的是否支付成功字段 判断显示)
       pharmacyList: [], // 药房选择器 数据
       pharmacyTypes: [],
+      pharmacyTypeGroup: [],
       clickPid: "", // 点击的药品id
       maxDose: null,
       minDose: null,
@@ -1327,17 +1340,12 @@ export default {
     },
     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("请输入剂量");
-
-        parent.rationalMed10.forEach(item => {
-          if (item.reqID == scope.row.medid) {
-            item.showDose = false;
-          }
-        });
-
+        rationalMed10.showDose = false;
         parent.countDose();
         this.maxDose = null;
         this.minDose = null;
@@ -1351,6 +1359,7 @@ export default {
       if (unit != "g" && unit != "克" && !Number.isInteger(dose)) {
         this.$message.error("剂量输入有误");
 
+        rationalMed10.showDose = false;
         parent.countDose();
         this.maxDose = null;
         this.minDose = null;
@@ -1366,26 +1375,14 @@ export default {
           "red";
         return;
       }
-      if (
-        Number(scope.row.dose) > Number(this.maxDose) ||
-        Number(scope.row.dose) < Number(this.minDose)
-      ) {
-        parent.rationalMed10.forEach(item => {
-          if (item.reqID == scope.row.medid) {
-            item.showDose = true;
-          }
-        });
-      }
 
-      if (
-        Number(scope.row.dose) <= Number(this.maxDose) &&
-        Number(scope.row.dose) >= Number(this.minDose)
-      ) {
-        parent.rationalMed10.forEach(item => {
-          if (item.reqID == scope.row.medid) {
-            item.showDose = false;
-          }
-        });
+      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;
       }
 
       parent.countDose();
@@ -1819,7 +1816,7 @@ export default {
         name: item.ypmc,
         spec: item.gg, // 规格
         // dose: "", // 剂量
-        dose: scope.row.color === "red" || oneself ? scope.row.dose : "",
+        dose: scope.row.color === "red" || oneself ? null : "",
         unit: item.dw, // 单位
         usage:
           oneself ? scope.row.usage : scope.row.color === "red"
@@ -1837,6 +1834,14 @@ export default {
         showSearch: false,
         showDoseSection: false // 展示剂量区间
       };
+      obj.ggnum = +item.ggnum || 1;
+      obj.xbzxs = +item.xbzxs || '34'.includes(item.zylx) ? obj.ggnum : 1;
+      
+      if (obj.dose == null) {
+        obj.oldDose = CC_Dosage2Basis(scope.row)
+        obj.dose = CC_Basis2Dosage(obj)
+      }
+
       Object.assign(totalData[scope.row.id - 1], obj);
 
       // 调用 父级合理用药接口
@@ -2285,8 +2290,8 @@ export default {
         matIds: ids
       });
       if (res.code == 0 && res.message) {
-        this.maxDose = res.data.matmaxdosage;
-        this.minDose = res.data.matmindosage;
+        this.maxDose = +res.data.matmaxdosage;
+        this.minDose = +res.data.matmindosage;
         this.doseId = id;
       }
     },
@@ -2314,8 +2319,8 @@ export default {
         matIds: ids
       });
       if (res.code == 0 && res.message) {
-        this.maxDose = res.data.matmaxdosage;
-        this.minDose = res.data.matmindosage;
+        this.maxDose = +res.data.matmaxdosage;
+        this.minDose = +res.data.matmindosage;
         this.doseId = id;
       }
     },
@@ -2373,18 +2378,43 @@ export default {
       });
       if (res.ResultCode == 0) {
         let pharmacyTypes = [];
+        let pharmacyTypeGroup = [];
         res.Data.forEach(item => {
           item.dosageForms = item.dosageForms.split(",");
           item.dosageForms.forEach(item1 => {
             pharmacyTypes.push({
               type: item1,
               ptype: item.pid + "@" + item1,
-              name: item.displayName //+ this.getRadioName(item1)
+              name: item.displayName + (item.dosageForms.length > 1 ? ` (${this.getRadioName(item1)})` : '')
             });
           });
+          if (item.dosageForms.length > 1) {
+            pharmacyTypeGroup.push({
+              name: item.displayName,
+              options: item.dosageForms.map(item1 => {
+                return {
+                  type: item1,
+                  ptype: item.pid + "@" + item1,
+                  name: this.getRadioName(item1),
+                }
+              })
+            })
+          } else if (item.dosageForms.length === 1) {
+            pharmacyTypeGroup.push({
+              name: item.displayName,
+              options: item.dosageForms.map(item1 => {
+                return {
+                  type: item1,
+                  ptype: item.pid + "@" + item1,
+                  name: item.displayName,
+                }
+              })
+            })
+          }
         });
         this.pharmacyList = res.Data;
         this.pharmacyTypes = pharmacyTypes;
+        this.pharmacyTypeGroup = pharmacyTypeGroup;
       }
     },
     // 获取药房id
@@ -2404,7 +2434,7 @@ export default {
 
     // 切换中药类型时 切换 药房 获取 药品里面有没有这条数据
     async changePharmacy(type, val) {
-      // TODO 此处 if 不会调用 触发在 [this.$emit("updateDp", res.Data)](src/components/ChineseMedicine.vue:2831)
+      // else 触发在 this.$emit("updateDp", res.Data)
       if (this.recipe_tabs[this.recipe_tabs_c].radio == val) {
         this.$parent.openAddress();
         return;
@@ -2422,14 +2452,14 @@ export default {
 
       this.recipe_tabs[this.recipe_tabs_c].totalTableD.forEach(item => {
         if (item.name) {
+          item.oldDose = CC_Dosage2Basis(item);
           let idDose =
             item.medid +
             "&" +
-            (item.dose || item.oldDose) +
+            item.oldDose +
             "&" +
             (item.usage || "");
           // drugIds.push(item.medid)
-          item.oldDose = item.dose;
           drugIds.push(idDose);
         }
       });
@@ -2486,10 +2516,11 @@ export default {
                     originname: item.cdmc, // 产地名称
                     showSearch: false,
                     usageList: [],
-                    oldDose: item1.oldDose
+                    oldDose: item.placeholderdose || item1.oldDose
                   };
                   /* 修正 */ item1.usage = item1.useage = getUsage(item1.usage);
-
+                  item1.ggnum = +item.ggnum || 1;
+                  item1.xbzxs = +item.xbzxs || '34'.includes(item.zylx) ? item1.ggnum : 1;
                   item1.color = item.kc > 0 ? "#000" : 'red';
                 }
 
@@ -2509,6 +2540,10 @@ export default {
           }
         );
         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 // 存储这一次的 药房类型
@@ -2643,6 +2678,7 @@ export default {
 
     // 根据表格获取数据类型
     async getSelectType(data, index) {
+      if (data === '中药药品用法' && this.usageList.length) return;
       let res = await getSelectType(data);
 
       if (data == "中药药品用法") {
@@ -2935,6 +2971,24 @@ export default {
         flex: 1;
       }
 
+      .t-radio-group2 {
+        padding: 4px 8px;
+
+        &.multiple {
+          border: 2px dashed #5386f6;
+
+          > label:first-of-type {
+            margin-right: 8px;
+            color: rgba(0, 0, 0, 0.6);
+
+            &:after {
+              margin-left: 2px;
+              content: ":";
+            }
+          }
+        }
+      }
+
       .add-presc1 {
         width: 84px;
         height: 34px;

+ 77 - 17
src/components/MedicineAccord.vue

@@ -21,21 +21,34 @@
           </div>
         </div>
         <!-- @change="getPharmacyID" -->
-        <div class="t-con-radio flex-vertical-center-l" v-if="!isPurposeType">
-          <div class="t-radio-group">
-            <el-radio-group
-              v-model="recipe_tabs[recipe_tabs_c].radio"
-              :disabled="recipe_tabs[recipe_tabs_c].disable"
-              @change="changePharmacy(recipe_tabs[recipe_tabs_c].lastType)"
-            >
-              <el-radio
-                :label="item.ptype"
-                v-for="(item,index) in pharmacyTypes"
-                :key="index"
+        <template v-if="!isPurposeType">
+          <div class="t-con-radio flex-vertical-center-l" v-if="false">
+            <div class="t-radio-group">
+              <el-radio-group
+                  v-model="recipe_tabs[recipe_tabs_c].radio"
+                  :disabled="recipe_tabs[recipe_tabs_c].disable"
+                  @change="changePharmacy(recipe_tabs[recipe_tabs_c].lastType)"
+              >
+                <el-radio
+                    :label="item.ptype"
+                    v-for="(item,index) in pharmacyTypes"
+                    :key="index"
+                >{{item.name}}</el-radio>
+              </el-radio-group>
+            </div>
+          </div>
+          <div class="t-con-radio flex-vertical-center-l" style="flex-wrap: wrap;align-items: center;">
+            <div class="t-radio-group2" :class="{multiple: group.options.length > 1}" v-for="group in pharmacyTypeGroup" :key="group.name">
+              <label v-if="group.options.length > 1">{{group.name}}</label>
+              <el-radio v-for="item in group.options" :key="item.ptype"
+                        v-model="recipe_tabs[recipe_tabs_c].radio"
+                        :disabled="recipe_tabs[recipe_tabs_c].disable"
+                        :label="item.ptype"
+                        @click.native.prevent="changePharmacy(recipe_tabs[recipe_tabs_c].lastType,item.ptype)"
               >{{item.name}}</el-radio>
-            </el-radio-group>
+            </div>
           </div>
-        </div>
+        </template>
 
         <!-- <div class="add-presc1 flex-center" @click="clearRecipe()">清空处方</div> -->
       </div>
@@ -176,7 +189,7 @@
                 </el-table-column>
 
                 <el-table-column prop="spec" label="规格" width="100"></el-table-column>
-                <el-table-column prop="dose" label="剂量" width="40">
+                <el-table-column prop="dose" label="剂量" width="60">
                   <template slot-scope="scope" v-if="scope.row.name">
                     <div class="t_dose">
                       <el-input
@@ -412,7 +425,7 @@
                 </el-table-column>
                 <!-- fixed="left" -->
                 <el-table-column prop="spec" label="规格" width="100"></el-table-column>
-                <el-table-column prop="dose" label="剂量" width="40">
+                <el-table-column prop="dose" label="剂量" width="60">
                   <template slot-scope="scope" v-if="scope.row.name">
                     <div class="t_dose">
                       <el-input
@@ -667,6 +680,7 @@ export default {
       countWay: "1", // 计算方式
       pharmacyList: [], // 药房选择器 数据
       pharmacyTypes: [],
+      pharmacyTypeGroup: [],
       clickPid: "", // 点击的药品id
       maxDose: null,
       minDose: null,
@@ -1315,6 +1329,8 @@ export default {
         showSearch: false,
         showDoseSection: false // 展示剂量区间
       };
+      obj.ggnum = +item.ggnum || 1;
+      obj.xbzxs = +item.xbzxs || '34'.includes(item.zylx) ? obj.ggnum : 1;
       Object.assign(totalData[scope.row.id - 1], obj);
 
       // 调用 父级合理用药接口
@@ -1826,15 +1842,39 @@ export default {
       });
       if (res.ResultCode == 0) {
         let pharmacyTypes = [];
+        let pharmacyTypeGroup = [];
         res.Data.forEach(item => {
           item.dosageForms = item.dosageForms.split(",");
           item.dosageForms.forEach(item1 => {
             pharmacyTypes.push({
               type: item1,
               ptype: item.pid + "@" + item1,
-              name: item.displayName //+ this.getRadioName(item1)
+              name: item.displayName + (item.dosageForms.length > 1 ? ` (${this.getRadioName(item1)})` : '')
             });
           });
+          if (item.dosageForms.length > 1) {
+            pharmacyTypeGroup.push({
+              name: item.displayName,
+              options: item.dosageForms.map(item1 => {
+                return {
+                  type: item1,
+                  ptype: item.pid + "@" + item1,
+                  name: this.getRadioName(item1),
+                }
+              })
+            })
+          } else if (item.dosageForms.length === 1) {
+            pharmacyTypeGroup.push({
+              name: item.displayName,
+              options: item.dosageForms.map(item1 => {
+                return {
+                  type: item1,
+                  ptype: item.pid + "@" + item1,
+                  name: item.displayName,
+                }
+              })
+            })
+          }
         });
 
         this.recipe_tabs[this.recipe_tabs_c].pharmacyID = res.Data[0].pid;
@@ -1842,6 +1882,7 @@ export default {
         this.recipe_tabs[this.recipe_tabs_c].lastType = pharmacyTypes[0].ptype;
         this.pharmacyList = res.Data;
         this.pharmacyTypes = pharmacyTypes;
+        this.pharmacyTypeGroup = pharmacyTypeGroup;
         this.$forceUpdate();
         this.getPharmacyMsg(res.Data[0].pid);
       }
@@ -1941,7 +1982,8 @@ export default {
                     oldDose: item1.oldDose
                   };
                   /* 修正 */ item1.usage = item1.useage = getUsage(item1.usage);
-
+                  item1.ggnum = +item.ggnum || 1;
+                  item1.xbzxs = +item.xbzxs || '34'.includes(item.zylx) ? item1.ggnum : 1;
                   item1.color = "#000";
                 }
 
@@ -2297,6 +2339,24 @@ export default {
       flex: 1;
     }
 
+    .t-radio-group2 {
+      padding: 4px 8px;
+
+      &.multiple {
+        border: 2px dashed #5386f6;
+
+        > label:first-of-type {
+          margin-right: 8px;
+          color: rgba(0, 0, 0, 0.6);
+
+          &:after {
+            margin-left: 2px;
+            content: ":";
+          }
+        }
+      }
+    }
+
     .add-presc1 {
       width: 84px;
       height: 34px;

+ 6 - 2
src/components/Propup.vue

@@ -17,14 +17,14 @@
         <slot name="body"></slot>
         <div class="btns flex-center" v-if="showBtns">
           <div class="confim flex-center" @click="confim()" v-if="confimText">{{confimText}}</div>
-          <div class="cancle flex-center" @click="cancle()" :style="cancleStyle">{{cancleText}}</div>
+          <div class="cancle flex-center" @click="cancle()" v-if="!hideCancleButton" :style="cancleStyle">{{cancleText}}</div>
         </div>
       </div>
       <div v-else>
         <slot name="body"></slot>
         <div class="btns flex-center" v-if="showBtns">
           <div class="confim flex-center" @click="confim()" v-if="confimText">{{confimText}}</div>
-          <div class="cancle flex-center" @click="cancle()" :style="cancleStyle">{{cancleText}}</div>
+          <div class="cancle flex-center" @click="cancle()" v-if="!hideCancleButton" :style="cancleStyle">{{cancleText}}</div>
         </div>
       </div>
     </el-dialog>
@@ -65,6 +65,10 @@ export default {
       type: Boolean,
       default: true
     },
+    hideCancleButton: {
+      type: Boolean,
+      default: false
+    },
     distanceTop: {
       type: String,
       default: "15vh"

+ 28 - 16
src/components/TCMDiagnosis.vue

@@ -9,7 +9,7 @@
       <div class="value">
         <el-popover placement="bottom" width="180" trigger="focus" :close-delay="100">
           <el-input
-            :class="{invalid: name && !zy_dise_id}"
+            :class="{invalid: name && (!zy_dise_id || invalid_dis)}"
             :size="size"
             slot="reference"
             :placeholder="key1?key1:'中医病名'"
@@ -43,7 +43,7 @@
       <div class="value">
         <el-popover placement="bottom" width="180" trigger="focus" :close-delay="100">
           <el-input
-            :size="size"
+            :size="size" :class="{invalid: syndrome && invalid_symptom}"
             slot="reference"
             :placeholder="key2?key2:'中医证型'"
             v-model="key2"
@@ -87,7 +87,7 @@ import {
   getXDiseaseName,
   getCCardType
 } from "@/api/knowledge.js";
-import { addDiagnosisData } from "@/api/diagnosis.js";
+import {addDiagnosisData2} from '@/api/diagnosis.js';
 import { addRecipeFrom } from "@/api/dataAnalysis.js";
 import { mapGetters } from "vuex";
 export default {
@@ -113,6 +113,9 @@ export default {
   },
   data() {
     return {
+      invalid_dis: false,
+      invalid_symptom: false,
+
       name: "", // 病名
       zy_dise_id: "", // 病名id
 
@@ -153,6 +156,7 @@ export default {
     key1: {
       handler: function() {
         if (this.key1 == "") {
+          this.invalid_dis = false;
           this.zy_dise_id = "";
           this.name = "";
         }
@@ -161,6 +165,7 @@ export default {
     key2: {
       handler: function() {
         if (this.key2 == "") {
+          this.invalid_symptom = false;
           this.syndrome = "";
           this.zhengxingid = "";
         }
@@ -263,6 +268,7 @@ export default {
     },
     // 病名选中
     handleBm(item) {
+      this.invalid_dis = false
       this.zy_dise_id = item.disid;
       this.name = item.disname;
       this.key1 = item.disname;
@@ -292,6 +298,7 @@ export default {
     },
     // 证型选中\
     handleZx(item) {
+      this.invalid_dis = false
       this.syndrome = item.symname;
       this.key2 = item.symname;
       this.zhengxingid = item.symid;
@@ -371,20 +378,25 @@ export default {
           zhengxing: ""
         }
       };
-      let res = await addDiagnosisData(params).catch(() => ({ResultCode: -1}));
-      if (+res.ResultCode === 0) {
-        if (!this.name) {
-          res.ResultCode = -1;
-          res.ResultInfo = `请选择${this.title}病名`;
-        } else if (!this.zy_dise_id) {
-          res.ResultCode = -1;
-          res.ResultInfo = `当前疾病编码与医保不匹配,请更换中医病名等诊断信息!`;
-        } else {
-          this.addRecipeFrom().catch();
-        }
+      try {
+        if (!this.name) throw {message: `请选择${this.title}病名`};
+        if (!this.zy_dise_id) throw {message: `当前疾病编码与医保不匹配,请更换中医病名等诊断信息!`};
+        let {mainDiagnosis} = await addDiagnosisData2(params);
+
+        this.invalid_dis = !mainDiagnosis.disid;
+        this.invalid_symptom = !mainDiagnosis.symptomid;
+        const tips = [
+          this.invalid_dis ? `${this.title}病名` : '',
+          this.invalid_symptom ? `证型` : '',
+        ].filter(Boolean).join(',');
+        if (tips) throw {message: `当前${tips}与医保不匹配,请更换${tips}等诊断信息!`};
+
+        this.addRecipeFrom().catch();
+        return true
+      } catch (e) {
+        this.$message.error(e.message);
       }
-      if (+res.ResultCode !== 0 && res.ResultInfo) this.$message.error(res.ResultInfo)
-      return +res.ResultCode === 0;
+      return false;
     }
   }
 };

+ 8 - 3
src/components/ui/accompanied.vue

@@ -31,6 +31,7 @@
         changeAndJoin,
 
     } from "@/api/knowledge.js";
+    import {CC_Dosage2Basis} from '@/utils/medicine';
     accompaniedData.forEach(item => {
         item.child.forEach(item1 => {
             item1.child.forEach(item2 => {
@@ -152,7 +153,8 @@
 
                 let ids = [];
                 drugs.forEach(item => {
-                    let idDose = item.pid + "&" + (item.dose || 0);
+                    item.oldDose = CC_Dosage2Basis(item);
+                    let idDose = item.pid + "&" + (item.oldDose || 0);
                     ids.push(idDose);
                 });
 
@@ -203,12 +205,14 @@
                                     key: "",
                                     search_i: index
                                 };
-
+                                obj.oldDose = item1.oldDose;
                                 noDrugs.push(obj);
                                 // noDrugs.push(item1.matname)
                             }
 
                             if (item instanceof Object && item.oldYpid == item1.matid) {
+                                item.ggnum = +item.ggnum || 1;
+                                item.xbzxs = +item.xbzxs || '34'.includes(item.zylx) ? item.ggnum : 1;
                                 hasDrugs.push(item);
                             }
                         });
@@ -248,7 +252,8 @@
                                 originname: item.cdmc, // 产地名称
                                 showSearch: false
                             };
-
+                            obj1.ggnum = +item.ggnum || 1;
+                            obj1.xbzxs = +item.xbzxs || '34'.includes(item.zylx) ? obj1.ggnum : 1;
                             parent.recipe_tabs[parent.recipe_tabs_c].totalTableD.push(obj1);
                             parent.getSelectType("中药药品用法", index);
                         });

+ 26 - 0
src/utils/medicine.js

@@ -0,0 +1,26 @@
+/**
+ * 药品输入剂量通过转换系数成基础剂量
+ * @param medicine 药品
+ * @param {number} medicine.dose 输入剂量
+ * @param {number} medicine.xbzxs 转换系数
+ * @returns {number} 基础剂量
+ */
+export function CC_Dosage2Basis({dose = 0, xbzxs = 1}) {
+    console.log('log-->CC_Dosage2Basis', `dose: ${dose}, xbzxs: ${xbzxs}`);
+    if (!xbzxs || xbzxs === 1) return +dose;
+    return +dose * xbzxs;
+}
+
+/**
+ * 药品基础剂量通过转换系数成输入剂量
+ * @param medicine 药品
+ * @param {number} medicine.oldDose 基础剂量
+ * @param {number} medicine.xbzxs 转换系数
+ * @param {boolean=false} keep 保留计算结果
+ * @returns {number} 输入剂量
+ */
+export function CC_Basis2Dosage({oldDose = 0, xbzxs = 1}, keep = false) {
+    console.log('log-->CC_Basis2Dosage', `basis: ${oldDose}, xbzxs: ${xbzxs}`);
+    if (!xbzxs || xbzxs === 1) return +oldDose;
+    return +oldDose / xbzxs;
+}

+ 14 - 4
src/utils/minix/prescribing.js

@@ -153,6 +153,7 @@ export default {
             this.openAddress()
 
         },
+        setUpdateDp(){/* 将模态框的值同步到处方数据 bottom_form */},
         openAddress() {
             clearTimeout(hack_openAddress_true);
             if (!this.isShowPs) this.isPs = 1;
@@ -171,19 +172,28 @@ export default {
                     });
                     let child = children[0];
 
-                    this.isDaiJian = child.recipe_tabs[child.recipe_tabs_c].bottom_form.isDaiJian
-                    this.isPs = child.recipe_tabs[child.recipe_tabs_c].bottom_form.radio
+                    const isDaiJian = child.recipe_tabs[child.recipe_tabs_c].bottom_form.isDaiJian
+                    const isPs = child.recipe_tabs[child.recipe_tabs_c].bottom_form.radio
+                    if (isPs != null) this.isPs = isPs;
+                    if (isDaiJian != null) this.isDaiJian = isDaiJian;
+                    this.setUpdateDp = (/* 模态框选择的值 */ model) => {
+                        child.recipe_tabs[child.recipe_tabs_c].bottom_form.isDaiJian = model.isDaiJian
+                        child.recipe_tabs[child.recipe_tabs_c].bottom_form.radio = model.iskD
+                    }
                 }, 200)
             } else {
                 this.showAddress = false;
             }
         },
+
         // 提交地址信息
-        submitAddress() {
+        submitAddress(cancel) {
+            this.showAddress = false;
+            if (cancel) return;
             const model = this.$refs.medAdress.form;
             this.psChange(model.iskD)
             this.djChange(model.isDaiJian)
-            this.showAddress = false;
+            this.setUpdateDp(model)
         },
         // 获取合理安全用药提醒配置
         async getRationalSafeUse() {

+ 2 - 2
src/views/business/DrugMapList.vue

@@ -27,7 +27,7 @@
         <el-button
           type="primary"
           size="mini"
-          @click="$router.push({path:'/index/drugmap?pid='+$route.query.id})"
+          @click="$router.push({path:'/index/drugmap?pid='+$route.query.id+'&isMapping='+isMap})"
         >新增</el-button>
         <el-button type="warning" size="mini" @click="$router.back()">返回</el-button>
       </div>
@@ -83,7 +83,7 @@
                   <div
                     class="flex-center"
                     @click="$router.push({path:'/index/drugmap?id='+scope.row
-                                    .matDrugId+'&pid='+$route.query.id})"
+                                    .matDrugId+'&pid='+$route.query.id+'&isMapping='+isMap})"
                   >编辑</div>
                   <!-- <div class="flex-center bg-yellow">删除
                   </div>-->

+ 34 - 29
src/views/business/DrugMaping.vue

@@ -45,33 +45,38 @@
             <span>第三方药品:</span>
             <!-- <div class="flex-center">选择药品</div> -->
             <div>
-              <!-- reserve-keyword -->
-              <!-- <el-select size="small" v-model="hisVal" multiple filterable remote placeholder="请输入关键词"
-                                :remote-method="remoteMethod2" :loading="loading2" @change="hisChange" reserve-keyword>
-                                <el-option v-for="item in hisOptions" :key="item.drugId" :label="item.name"
-                                    :value="item.drugId">
-                                </el-option>
-              </el-select>-->
-              <el-autocomplete
+               <el-select size="small" v-model="hisVal" multiple filterable remote placeholder="请输入关键词"
+                          :remote-method="remoteMethod2" :loading="loading2" @change="hisChange"
+                          reserve-keyword collapse-tags
+               >
+                <el-option v-for="item in hisOptions" :key="item.drugId" :label="item.name"
+                    :value="item.drugId">
+                </el-option>
+              </el-select>
+              <!--<el-autocomplete
                 size="mini"
                 class="inline-input"
                 v-model="hisVal"
                 :fetch-suggestions="remoteMethod2"
                 placeholder="请输入关键词"
                 value-key="showName"
-                :trigger-on-focus="false"
+                :trigger-on-focus="true"
                 @select="handleHisSelect"
-              ></el-autocomplete>
+              ></el-autocomplete>-->
             </div>
           </div>
           <span class="clear" @click="clearHis">全部清除</span>
         </div>
 
         <div class="footer">
-          <div class="flex-vertical-between item" v-for="(item,index) in hisChoose" :key="index">
+          <div class="flex-vertical-between item row-old" v-for="(item,index) in hisChoose" :key="item.drugId">
             <div>{{item.name}}/{{item.gg}}/{{item.dw}}</div>
             <div class="clear" @click="deleteHis(index)">+</div>
           </div>
+          <div class="flex-vertical-between item row-new" v-for="(item,index) in hisChooseNew" :key="item.drugId">
+            <div>{{item.name}}/{{item.gg}}/{{item.dw}}</div>
+            <div class="clear" @click="deleteHisNew(index)">+</div>
+          </div>
         </div>
       </div>
     </div>
@@ -106,6 +111,7 @@ export default {
       loading2: false,
       hisVal: [],
       hisOptions: [],
+      hisChooseNew: [],
       hisChoose: []
     };
   },
@@ -125,21 +131,12 @@ export default {
     },
     // his 药品选择
     hisChange(e) {
-      console.log(e);
-
-      this.hisChoose = [];
-      e.forEach(item => {
-        this.hisOptions.forEach(item1 => {
-          if (item1.drugId == item) {
-            this.hisChoose.push(item1);
-          }
-        });
-      });
+      this.hisChooseNew = e.map(id => this.hisOptions.find(item => item.drugId === id)).filter(Boolean);
     },
     // 第三方药品选中
     handleHisSelect(e) {
       // console.log(e, '第三方药品选中')
-      this.hisChoose.push(e);
+      this.hisChooseNew.push(e);
       this.hisVal = "";
     },
     // 平台药品搜索
@@ -173,6 +170,7 @@ export default {
     // 清空his 药品
     clearHis() {
       this.hisVal = [];
+      this.hisChooseNew = [];
       this.hisChoose = [];
       this.hisOptions = [];
       this.searchHisDrug("");
@@ -180,6 +178,10 @@ export default {
     // HIs 药品删除
     deleteHis(index) {
       this.hisChoose.splice(index, 1);
+      // this.hisVal.splice(index, 1);
+    },
+    deleteHisNew(index) {
+      this.hisChooseNew.splice(index, 1);
       this.hisVal.splice(index, 1);
     },
 
@@ -194,7 +196,8 @@ export default {
         });
         return;
       }
-      if (this.hisChoose.length == 0) {
+      const hisChoose = [...this.hisChoose, ...this.hisChooseNew];
+      if (hisChoose.length == 0) {
         this.$message({
           type: "warning",
           message: "请至少选择一种HIS药品",
@@ -203,18 +206,15 @@ export default {
         return;
       }
 
-      this.addOrUpdateDrug(type);
+      this.addOrUpdateDrug(type, hisChoose.map(item => item.drugId));
     },
 
     /// 新增或修改药品映射
-    async addOrUpdateDrug(type) {
-      let jgDrugId = [];
-      this.hisChoose.forEach(item => {
-        jgDrugId.push(item.drugId);
-      });
+    async addOrUpdateDrug(type, jgDrugId) {
       let params = [
         {
           // orgId: this.getuserinfo.organizationid,
+          isMapping: +this.$route.query.isMapping,
           orgId: this.$route.query.pid,
           matDrugId: this.myChoose[0].drugId,
           jgDrugId,
@@ -433,6 +433,11 @@ export default {
   min-height: 24px;
   // height: 0px;
 }
+
+.row {
+  &-old {}
+  &-new {}
+}
 </style>
 
 <style lang="scss" scoped>

+ 5 - 1
src/views/business/ExperienceAdd.vue

@@ -263,6 +263,7 @@ import {
   getExperinceDetail,
   editExperince
 } from "@/api/business";
+import {CC_Dosage2Basis} from '@/utils/medicine';
 
 export default {
   components: {
@@ -863,7 +864,8 @@ export default {
 
       this.totalTableD.forEach(item => {
         if (item.name) {
-          let idDose = item.medid + "&" + item.dose;
+          item.oldDose = CC_Dosage2Basis(item);
+          let idDose = item.medid + "&" + item.oldDose;
           // drugIds.push(item.medid)
           drugIds.push(idDose);
         }
@@ -923,6 +925,8 @@ export default {
                 item1.showSearch = false;
 
                 item1.color = "#000";
+                item1.ggnum = +item.ggnum || 1;
+                item1.xbzxs = +item.xbzxs || '34'.includes(item.zylx) ? item1.ggnum : 1;
               }
 
               this.$set(this.totalTableD, index1, item1);

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

@@ -1107,8 +1107,8 @@
     <!-- 选择代煎 地址栏 -->
     <Popup
       :showDialog="showAddress"
-      @cancle="submitAddress"
-      @confim="submitAddress"
+      @cancle="submitAddress(true)"
+      @confim="submitAddress()"
       title="请和患者确认以下信息"
       width="700px"
       distanceTop="5vh"
@@ -1116,8 +1116,6 @@
       <div slot="body">
         <medAdressNew
           ref="medAdress"
-          @psChange="psChange"
-          @djChange="djChange"
           :isDaijian="Number(isDaiJian)"
           :isPs="Number(isPs)"
           :isShowDj="isShowDj"
@@ -1183,6 +1181,7 @@ import { setTimeout } from "timers";
 import prescribing from "../../utils/minix/prescribing";
 
 import {formatPicture} from "@/utils/picture";
+import {CC_Dosage2Basis} from '@/utils/medicine';
 
 export default {
   mixins: [prescribing],
@@ -1786,7 +1785,9 @@ export default {
         medAdressData = this.$refs.medAdress.form;
       }
 
+      console.group("debug:20250558")
       data1.recipe_tabs.forEach((item, index) => {
+        console.log("填写值", item.bottom_form.radio)
         let obj = {
           seqn: index + 1,
           province:
@@ -1838,6 +1839,7 @@ export default {
           // preId: this.$route.query.recipeID ? this.$route.query.recipeID : ""
           preId: item.preId ? item.pageId : ""
         };
+        console.log("保存值", obj.isdelivery)
         item.totalTableD.forEach(item1 => {
           if (item1.name && item1.color != "red") {
             let obj1 = {
@@ -1881,7 +1883,7 @@ export default {
           zhongPrescriptionVo.push(obj);
         }
       });
-
+      console.groupEnd()
       return zhongPrescriptionVo;
     },
     // 处理中成药处方提交数据
@@ -2173,8 +2175,11 @@ export default {
             // if (isAutoCheck == 1) {
 
             // }
-
-            obj.bottom_form.radio = Number(item.isdelivery);
+            console.group("debug:20250558")
+            console.log('配送原始', item.isdelivery);
+            obj.bottom_form.radio = item.isdelivery == null ? null : Number(item.isdelivery);
+            console.log('配送赋值', obj.bottom_form.radio);
+            console.groupEnd()
             obj.bottom_form.savename = item.consigneeName;
             obj.bottom_form.phone = item.consigneePhone;
             obj.bottom_form.address = item.address;
@@ -2326,7 +2331,7 @@ export default {
         data1.bottom_form.zhutuo = data.command;
         data1.preId = data.preId ? data.preId : "";
         if (!!this.getEditPreNo()) {
-          data1.bottom_form.radio = Number(data.isdelivery);
+          data1.bottom_form.radio = data.isdelivery == null ? null : Number(data.isdelivery);
           data1.bottom_form.savename = data.consigneeName;
           data1.bottom_form.phone = data.consigneePhone;
           data1.bottom_form.address = data.address;
@@ -2542,7 +2547,8 @@ export default {
           originname: item.cdmc, // 产地名称
           showSearch: false
         };
-
+        obj1.ggnum = +item.ggnum || 1;
+        obj1.xbzxs = +item.xbzxs || '34'.includes(item.zylx) ? obj1.ggnum : 1;
         data1.recipe_tabs[data1.recipe_tabs_c].totalTableD.push(obj1);
         data1.getSelectType("中药药品用法", index);
       });
@@ -2829,8 +2835,8 @@ export default {
      const is = recipe.medicine.every(m => m.matid);
      if (is) {
        // 调用 方剂 换方
-       const medicine = recipe.medicine.map((m, i) => {
-         return {
+       const medicines = recipe.medicine.map((m, i) => {
+         const medicine = {
            matid: m.matid,
            matname: m.ypmc,
            dose: m.dose,
@@ -2838,9 +2844,12 @@ export default {
            useage: m.usagestr,
            seqn: i + 1,
          }
+         medicine.ggnum = +m.ggnum || 1;
+         medicine.xbzxs = +m.xbzxs || '34'.includes(m.zylx) ? medicine.ggnum : 1;
+         return medicine;
        });
        if (recipe.__RecipeFrom__ === '2') this.agreeAssignToTCM(recipe, void 0, true);
-       this.setDrugsInfo(medicine);
+       this.setDrugsInfo(medicines);
        this.changeAndJoin(1);
      } else if (recipe.__RecipeFrom__ === '2') {
        this.agreeInfo = recipe;
@@ -2931,7 +2940,8 @@ export default {
           originname: item.cdmc, // 产地名称
           showSearch: false
         };
-
+        obj1.ggnum = +item.ggnum || 1;
+        obj1.xbzxs = +item.xbzxs || '34'.includes(item.zylx) ? obj1.ggnum : 1;
         data1.recipe_tabs[data1.recipe_tabs_c].totalTableD.push(obj1);
         data1.getSelectType("中药药品用法", index);
       });
@@ -3667,7 +3677,7 @@ export default {
 
         if (item.matmaxdosage && item.matmindosage) {
           try {
-            const dose = +item.__medicine__.dose;
+            const dose = CC_Dosage2Basis(item.__medicine__);
             if (dose && (dose < item.matmindosage || dose > item.matmaxdosage)) item.showDose = true;
           } catch (e) {}
           this.rationalMed10.push(item);
@@ -3771,7 +3781,7 @@ export default {
 
           if (item.matmaxdosage && item.matmindosage) {
             try {
-              const dose = +item.__medicine__.dose;
+              const dose = CC_Dosage2Basis(item.__medicine__);
               if (dose < item.matmindosage || dose > item.matmaxdosage) item.showDose = true;
             } catch (e) {}
             this.rationalMed10.push(item);
@@ -4010,7 +4020,8 @@ export default {
 
       let ids = [];
       drugs.forEach(item => {
-        let idDose = item.matid + "&" + item.dose + "&" + (item.useage || "");
+        item.oldDose = CC_Dosage2Basis(item);
+        let idDose = item.matid + "&" + item.oldDose + "&" + (item.useage || "");
         ids.push(idDose);
       });
 
@@ -4068,12 +4079,16 @@ export default {
                   key: "",
                   search_i: index
                 };
+                obj.oldDose = item1.oldDose;
                 /* 修正 */ obj.usage = obj.useage = getUsage(obj.usage);
                 noDrugs.push(obj);
                 // noDrugs.push(item1.matname)
               }
 
               if (item instanceof Object && item.oldYpid == item1.matid) {
+                item.oldDose = item.placeholderdose || item1.oldDose;
+                item.ggnum = +item.ggnum || 1;
+                item.xbzxs = +item.xbzxs || '34'.includes(item.zylx) ? item.ggnum : 1;
                 if (item.kc > 0) hasDrugs.push(item);
                 else {
                   item.color = 'red';
@@ -4112,6 +4127,9 @@ export default {
                 color: item.color ? item.color : "#000"
               };
               /* 修正 */ obj1.usage = obj1.useage = getUsage(obj1.usage);
+              obj1.oldDose = +item.oldDose || '';
+              obj1.ggnum = +item.ggnum || 1;
+              obj1.xbzxs = +item.xbzxs || '34'.includes(item.zylx) ? obj1.ggnum : 1;
 
               child.recipe_tabs[child.recipe_tabs_c].totalTableD.push(obj1);
               child.getSelectType("中药药品用法", index);
@@ -4197,6 +4215,9 @@ export default {
                 showSearch: false
               };
               /* 修正 */ obj1.usage = obj1.useage = getUsage(obj1.usage);
+              obj1.oldDose = +item.oldDose || '';
+              obj1.ggnum = +item.ggnum || 1;
+              obj1.xbzxs = +item.xbzxs || '34'.includes(item.zylx) ? obj1.ggnum : 1;
 
               child.recipe_tabs[child.recipe_tabs_c].totalTableD.push(obj1);
               child.getSelectType("中药药品用法", index);

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

@@ -453,10 +453,11 @@ export default {
     },
     // 处理数据
     dealPriviewData() {
+      if (!this.priviewData) return;
       // this.isPs = false;
       // this.isDj = false;
       // 中药处方
-      if (this.priviewData.tcmPrescriptionFormVos.length > 0) {
+      if (Array.isArray(this.priviewData.tcmPrescriptionFormVos) && this.priviewData.tcmPrescriptionFormVos.length > 0) {
         this.priviewData.tcmPrescriptionFormVos.forEach((item, index) => {
           item.showSign = true;
           item.recipeType = 1;
@@ -483,7 +484,7 @@ export default {
         }
       }
 
-      this.recipeItem = this.recipes[0];
+      this.recipeItem = this.recipes[0] || {};
       // this.recipes.forEach(item => {
       //   if (item.recipeType == 1 && item.fried == "代煎") {
       //     this.isDj = true;

+ 95 - 41
src/views/knowledge/BookD.vue

@@ -1,6 +1,6 @@
 <script>
 import {getBook, getBookContent, getBookListOfRecommend, setBookStatus} from '@/api/knowledge.js';
-import {numberToChinese} from '@/utils/format';
+
 
 export default {
   name: 'KnowledgeBookDetail',
@@ -11,6 +11,8 @@ export default {
       recommend: [],
 
       containerHeight: 0,
+
+      selected: {},
     };
   },
   computed: {
@@ -28,34 +30,45 @@ export default {
     }, 200);
   },
   methods: {
-    async getBook() {
-      this.book = await getBook(this.book.id);
-      let index = 1;
-      const section = [];
-      for (const {catalogueName: name, catalogueId: id} of this.book.catalogueList) {
-        section.push({
-          id,
-          name: name === '序' ? name : `第${numberToChinese(index)}章 ${name}`,
-          content: '',
-          dirty: false,
-        });
-        if (name !== '序') { index += 1;}
-      }
-      this.section = section;
-    },
     async getRecommend() {
       try {
         this.recommend = await getBookListOfRecommend(this.book.id);
       } catch (e) {}
     },
-    async getContent(data, index, section) {
-      try {
-        let content = await getBookContent({bookId: this.book.id, catalogueId: data.id});
-        content = `&emsp;&emsp;${(content || '').replace(/\n|\r/g, '<br>&emsp;&emsp;')}`;
-        this.$set(this.section, index, Object.assign(data, {dirty: true, error: '', content}));
-      } catch (e) {
-        this.$set(this.section, index, Object.assign(data, {dirty: true, error: `出错了(${e})`}));
+    async getBook() {
+      this.book = await getBook(this.book.id);
+      let selected;
+      const get = (list, level = 1) => list.map(item => {
+        const children = Array.isArray(item.children) ? get(item.children, level + 1) : [];
+        const isLeaf = !children.length;
+        const section = {
+          id: item.catalogueId,
+          name: item.catalogueName,
+          children, isLeaf, level,
+          content: isLeaf ? '' : void 0,
+          dirty: !isLeaf,
+        }
+        if (section.isLeaf && !selected) selected = section;
+        return section;
+      });
+      this.section = get(this.book.catalogueList);
+      await this.load(selected);
+    },
+    async load(section) {
+      if (!section.isLeaf) return;
+
+      this.selected = {...section};
+      if (!section.dirty) {
+        try {
+          section.content = await getBookContent({bookId: this.book.id, catalogueId: section.id});
+          section.dirty = true;
+          this.$set(this.selected, 'content', section.content);
+          this.$set(this.selected, 'dirty', section.dirty);
+        } catch (e) {}
       }
+      this.$nextTick(() => {
+        document.querySelector(`#scrolling`).scrollTo({top: 0, behavior: 'smooth'});
+      });
     },
     async collected() {
       try {
@@ -67,16 +80,6 @@ export default {
 
       }
     },
-    load(ids) {
-      if (ids && !Array.isArray(ids)) {ids = [ids];}
-      for (const id of ids) {
-        const index = this.section.findIndex(item => item.id === id);
-        const data = this.section[index];
-        if (data.dirty || data.content) continue;
-        this.$set(this.section, index, Object.assign(data, {dirty: true, error: ''}));
-        this.getContent(data, index, this.section);
-      }
-    },
     async onPreview(book) {
       if (book) {
         await this.$router.push({path: `/index/knowledge/book/detail?id=${book.id}`});
@@ -118,14 +121,22 @@ export default {
       </div>
       <el-divider content-position="left">阅读<span v-if="book.readProgress">:{{ book.readProgress }}%</span>
       </el-divider>
-      <el-collapse style="margin: 0 12px;" @change="load">
-        <el-collapse-item v-for="item in section" :key="item.id" :title="item.name" :name="item.id">
-          <div class="book-content-container" v-loading="!item.content">
-            <div v-html="item.content"></div>
+      <div class="book-content-container" :style="{maxHeight: containerHeight}" :class="{scrollable: true}">
+        <div class="catalogue">
+          <div v-for="item in section" :key="item.id"
+               :class="['level-' + item.level, item.isLeaf ? 'section' : 'title']">
+            <span :class="{active: item.id === selected.id}" @click="load(item)">{{ item.name }}</span>
+            <div v-for="item in item.children" :key="item.id"
+                 :class="['level-' + item.level, item.isLeaf ? 'section' : 'title']">
+              <span :class="{active: item.id === selected.id}" @click="load(item)">{{ item.name }}</span>
+            </div>
           </div>
-        </el-collapse-item>
-      </el-collapse>
-      <el-backtop style="right: 300px;" target=".detail-wrapper"></el-backtop>
+        </div>
+        <div class="content" id="scrolling" :style="{height: containerHeight}" v-loading="!selected.dirty">
+          <div class="text" v-html="selected.content"></div>
+          <el-backtop style="right: 300px;" target="#scrolling"></el-backtop>
+        </div>
+      </div>
     </div>
     <el-card header="相关医书">
       <div class="book-wrapper" style="margin-bottom: 24px;" v-for="book in recommend" :key="book.id"
@@ -151,6 +162,7 @@ export default {
   .detail-wrapper {
     flex: auto;
     overflow-y: auto;
+    height: 100%;
     padding: 0 24px;
 
     .header {
@@ -214,7 +226,49 @@ export default {
 }
 
 .book-content-container {
-  min-height: 80px;
+  display: flex;
+
+  &.scrollable > div {
+    overflow-y: auto;
+  }
+
+  .catalogue {
+    flex: 1 0;
+    user-select: none;
+
+
+    .title {
+      margin: 24px 0;
+      color: #213547;
+      > span {
+        pointer-events: none;
+      }
+    }
+
+    .section {
+      margin: 6px 0;
+      color: #3c3c3cb3;
+
+      &:hover, .active {
+        cursor: pointer;
+        color: #5386f6;
+      }
+    }
+  }
+
+  .content {
+    flex: 4 4;
+
+    > .text {
+      padding: 24px;
+      line-height: 2.5;
+      white-space: pre-wrap;
+    }
+  }
+
+  ::v-deep.el-loading-mask {
+    background-color: transparent;
+  }
 }
 
 .book-wrapper {