فهرست منبع

Merge branch 'release/241125'

cc12458 1 سال پیش
والد
کامیت
d06341fb99

+ 1 - 1
.env.development

@@ -4,6 +4,6 @@ BASE_URL = '/'
 VUE_APP_BASE_API = '/WebAPI'
 
 VUE_APP_CODE_IMG='http://192.168.0.20:8063/'
-VUE_APP_UPLOAD='http://192.168.0.34:8063/'
+VUE_APP_UPLOAD='/'
 VUE_APP_XUEWEI = 'http://www.hzxunmai.com/'
 VUE_APP_DOWNLOAD = 'http://47.118.22.101:8080'

+ 3 - 3
package-lock.json

@@ -4601,9 +4601,9 @@
       "dev": true
     },
     "element-ui": {
-      "version": "2.15.1",
-      "resolved": "https://registry.npmmirror.com/element-ui/-/element-ui-2.15.1.tgz",
-      "integrity": "sha512-TqlScAKGH97XndSScUDeEHIzL1x7yg7DvQdKPEOUdiDcyIz3y3FJJBlpHYaJT96FOn1xpIcUZb+I2FJeU9EcrQ==",
+      "version": "2.15.14",
+      "resolved": "https://registry.npmmirror.com/element-ui/-/element-ui-2.15.14.tgz",
+      "integrity": "sha512-2v9fHL0ZGINotOlRIAJD5YuVB8V7WKxrE9Qy7dXhRipa035+kF7WuU/z+tEmLVPBcJ0zt8mOu1DKpWcVzBK8IA==",
       "requires": {
         "async-validator": "~1.8.1",
         "babel-helper-vue-jsx-merge-props": "^2.0.0",

+ 3 - 2
package.json

@@ -4,13 +4,14 @@
   "private": true,
   "scripts": {
     "serve": "vue-cli-service serve",
-    "build": "vue-cli-service build"
+    "build": "vue-cli-service build",
+    "build:test": "vue-cli-service build --mode test"
   },
   "dependencies": {
     "axios": "^0.21.1",
     "core-js": "^3.6.5",
     "echarts": "^4.8.0",
-    "element-ui": "^2.15.1",
+    "element-ui": "^2.15.14",
     "vue": "^2.6.11",
     "vue-print-nb": "^1.7.4",
     "vue-router": "^3.2.0",

+ 16 - 0
src/api/diagnosis.js

@@ -1,4 +1,5 @@
 import request from '@/utils/request.js'
+import {fromTongueAndFaceAnalysisModel} from "@/model/tongue-analysis,model";
 
 // 获取就诊病人信息
 export function getPatiiensMsg(data) {
@@ -440,4 +441,19 @@ export function getMaxMinDoaseNumber(data) {
         method: 'post',
         data
     })
+}
+
+export function getTongueAndFaceAnalysis(data) {
+    return request({
+        url: '/outpatient/electronicmedicalrecordMgr/getTongueFaceAnalysisResult',
+        method: 'post',
+        data,
+        params: {recordsId: data.recordsId},
+    }).then(res => {
+        if (res.ResultCode == 0) {
+            return res.Data = fromTongueAndFaceAnalysisModel(res.Data), res;
+        } else {
+            throw res
+        }
+    })
 }

+ 1 - 1
src/components/ChineseMedicine.vue

@@ -1841,7 +1841,7 @@ export default {
       }
 
       let obj = {
-        color: "#000",
+        color: item.kc == 0 ? "red" : "#000",
         id: scope.row.id,
         name: item.ypmc,
         spec: item.gg, // 规格

+ 12 - 0
src/components/ui/outpatientRecords.vue

@@ -72,6 +72,18 @@
                 </div>
             </div>
 
+          <div class="msg-item flex flex-row-left flex-col-top" v-if="info.image1 && info.image1.length>0">
+            <div style="margin: 4px 0 8px;">报告图片:</div>
+            <el-image
+                :preview-src-list="info.image1"
+                :src="item"
+                :key="index"
+                style="width:64px;height: 64px;margin-right: 10px;"
+                alt
+                v-for="(item,index) in info.image1"
+            />
+          </div>
+
             <div class="msg-item flex flex-row-left flex-col-top">
                 <div class="name">诊断:</div>
                 <div class="desc">

+ 61 - 0
src/model/tongue-analysis,model.js

@@ -0,0 +1,61 @@
+/**
+ * 解析舌象异常数据
+ * @param {{title: string; cover: string; descriptions: string[]; tags: string[];}[]} exception
+ * @param {{actualList: Record<string, any>[]}} [data]
+ * @return {string}
+ */
+function fromReportTongueExceptionData(exception, data) {
+    if (data == null || !Array.isArray(data.actualList)) return '';
+    return data.actualList.map(item => {
+        if (!item) return '';
+        let title = item.actualValue || '';
+        const suffix = item.contrast || 's';
+        if (suffix !== 's') {
+            title += ` (${suffix || ''}) `;
+            exception.push({
+                title, cover: item.splitImage,
+                descriptions: [
+                    item.features ? `【特征】${item.features}` : '',
+                    item.clinicalSignificance ? `【临床意义】${item.clinicalSignificance}` : '',
+                ].filter(Boolean),
+                tags: item.attrs ?? [],
+            });
+        }
+        return title;
+    }).join('<br>');
+}
+
+/**
+ * 解析舌面象数据
+ * @param {Record<string, any>} data
+ */
+export function fromTongueAndFaceAnalysisModel(data) {
+    if (data == null || typeof data !== 'object') data = {};
+    const tongueException = [];
+    const fromTongueException = fromReportTongueExceptionData.bind(null, tongueException);
+    const fromTongueValue = (data) => data && typeof data === 'object' ? data.standardValue || '' : '';
+
+    return {
+        tongueTable: {
+            column: ['舌象维度', '检测结果', '标准值'],
+            data: [
+                ['舌色', fromTongueException(data.tongueColor), fromTongueValue(data.tongueColor)],
+                ['苔色', fromTongueException(data.tongueCoatingColor), fromTongueValue(data.tongueCoatingColor)],
+                ['舌形', fromTongueException(data.tongueShape), fromTongueValue(data.tongueShape)],
+                ['苔质', fromTongueException(data.tongueCoating), fromTongueValue(data.tongueCoating)],
+                ['津液', fromTongueException(data.bodyFluid), fromTongueValue(data.bodyFluid)],
+                ['舌下', fromTongueException(data.sublingualVein), fromTongueValue(data.sublingualVein)],
+            ],
+        },
+        tongueException,
+        tongueAnalysis: {
+            ['结果']: data.tongueAnalysisResult,
+            ['舌上']: data.upImg,
+            ['舌下']: data.downImg,
+        },
+        faceAnalysis: {
+            ['结果']: data.faceAnalysisResult,
+            ['面象']: data.faceImg,
+        },
+    }
+}

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

@@ -4,6 +4,7 @@ export default {
     data() {
         return {
             showCase: false, // 参考医案弹窗
+            showUnifyPresc: false, // 统建处方弹窗
             showPresc: false, // 方剂 协定方弹窗
             showSafeD: false, // 安全合理用药
             isShrink: false, // 是否是收缩状态
@@ -77,6 +78,9 @@ export default {
         openPrec() {
             this.showPresc = true
         },
+        openUnifyPrescPrec() {
+            this.showUnifyPresc = true
+        },
         opensafeD() {
             this.showSafeD = true
         },

+ 4 - 0
src/utils/picture.js

@@ -0,0 +1,4 @@
+export function formatPicture(picture) {
+    if (!picture) return [];
+    return picture.split(',').filter(Boolean).map(url => /https?/.test(url) ? url : `${process.env.VUE_APP_UPLOAD}file/${url}`);
+}

+ 18 - 7
src/views/business/MedRecordDetail.vue

@@ -99,6 +99,19 @@
             <div class="right flex-plane-center-l flex-wrap">无</div>
           </div>
         </div>
+        <div class="r-msg-item flex-plane-center-l">
+          <span class="name">报告照片:</span>
+          <div class="right flex-plane-center-l flex-wrap">
+            <el-image
+                :preview-src-list="item.electronicmedicalrecord.image1"
+                style="width:100px;height:100px;margin-right:20px;"
+                :src="item1"
+                alt
+                v-for="(item1,index1) in item.electronicmedicalrecord.image1"
+                :key="index1"
+            />
+          </div>
+        </div>
         <div class="r-msg-item flex-plane-center-l">
           <span class="name">诊断:</span>
           <div
@@ -143,16 +156,16 @@
                     </div>
         </div>-->
 
-        <div>
+        <!--<div>
           <el-image
-            :preview-src-list="[item1]"
+            :preview-src-list="item.electronicmedicalrecord.image1"
             style="width:100px;height:100px;margin-right:20px;"
             :src="item1"
             alt
             v-for="(item1,index1) in item.electronicmedicalrecord.image1"
             :key="index1"
           />
-        </div>
+        </div>-->
       </div>
     </div>
   </div>
@@ -160,6 +173,7 @@
 <script>
 import { mapGetters, mapMutations } from "vuex";
 import { getPatiensMedDetail, patiensTrunCase } from "@/api/business.js";
+import {formatPicture} from "@/utils/picture";
 export default {
   data() {
     return {
@@ -227,10 +241,7 @@ export default {
       });
       if (res.ResultCode == 0) {
         res.Data.patientDetailVos.forEach((item, index) => {
-          item.electronicmedicalrecord.image1 = item.electronicmedicalrecord
-            .image1
-            ? item.electronicmedicalrecord.image1.split(",")
-            : [];
+          item.electronicmedicalrecord.image1 = formatPicture(item.electronicmedicalrecord.image1);
 
           if (index == res.Data.patientDetailVos.length - 1) {
             item.color = "#5386F6";

+ 2 - 0
src/views/business/MedicalContol.vue

@@ -134,6 +134,7 @@ import { getCDiseaseName, getCCardType } from "@/api/knowledge.js";
 import medcalPad from "@/components/ui/outpatientRecords";
 import proup from "@/components/Propup";
 import { mapGetters } from "vuex";
+import {formatPicture} from "@/utils/picture";
 export default {
   components: {
     proup,
@@ -298,6 +299,7 @@ export default {
       if (res.ResultCode == 0) {
         loading.close();
         this.medicalItem = res.Data;
+        this.medicalItem.image1 = formatPicture(this.medicalItem.image1);
         this.showCase = true;
       } else {
         loading.close();

+ 5 - 5
src/views/business/RecipeAuditD.vue

@@ -130,7 +130,7 @@
             <span>报告图片:</span>
             <div>
               <el-image
-                :preview-src-list="[item1]"
+                :preview-src-list="msg.electronicmedicalrecord.image1"
                 style="width:100px;height:100px;margin-right:20px;"
                 :src="item1"
                 alt
@@ -212,6 +212,9 @@ import chineseMadepad from "@/components/ui/chineseMadePad.vue";
 import suitPad from "@/components/ui/suitMadePad.vue";
 import { getRecordDetail } from "@/api/diagnosis";
 import { mapState, mapGetters, mapActions, mapMutations } from "vuex";
+
+import {formatPicture} from "@/utils/picture";
+
 export default {
   components: {
     chinesepad,
@@ -350,10 +353,7 @@ export default {
     async getRecipeAuditD() {
       let res = await getRecipeAuditD(this.$route.query.pid);
       if (res.ResultCode == 0) {
-        res.Data.electronicmedicalrecord.image1 = res.Data
-          .electronicmedicalrecord.image1
-          ? res.Data.electronicmedicalrecord.image1.split(",")
-          : [];
+        res.Data.electronicmedicalrecord.image1 = formatPicture(res.Data.electronicmedicalrecord.image1);
 
         res.Data.patientprescription.forEach(item => {
           item.reason = "";

+ 18 - 6
src/views/business/components/PriviewEdit.vue

@@ -255,6 +255,7 @@
 
 <script>
 import { fileUpload } from "@/api/upload.js";
+import { formatPicture } from "@/utils/picture";
 export default {
   props: {
     editListF: {
@@ -262,8 +263,16 @@ export default {
       default: () => {
         return [];
       }
+    },
+    imageUrl: {
+      type: Array,
+      default: () => { return []; }
     }
   },
+  model: {
+    prop: "imageUrl",
+    event: "upload",
+  },
   created() {
     this.editList = JSON.parse(JSON.stringify(this.editListF));
     if (this.$route.path == "/index/emr") {
@@ -277,6 +286,11 @@ export default {
       deep: true,
       handler: function() {
         this.editList = JSON.parse(JSON.stringify(this.editListF));
+        this.editList.forEach(item => {
+          if (item.level == 1 && item.id == 4) {
+            item.inputDefaultValue = "";
+          }
+        });
       }
     },
     editList: {
@@ -630,7 +644,6 @@ export default {
       },
       dialogVisible: false,
       dialogVisibleConfirm: false,
-      imageUrl: []
     };
   },
   methods: {
@@ -642,13 +655,11 @@ export default {
           message: "上传成功",
           showClose: true
         });
-        this.imageUrl.push(
-          process.env.VUE_APP_UPLOAD + "file/" + res.ResultInfo
-        );
+        this.$emit('upload', [...this.imageUrl, ...formatPicture(res.ResultInfo),]);
       }
     },
     handleAvatarSuccess(res, file) {
-      this.imageUrl = URL.createObjectURL(file.raw);
+      // this.imageUrl = URL.createObjectURL(file.raw);
     },
     beforeAvatarUpload(file) {
       console.log(file, "file文件");
@@ -666,7 +677,8 @@ export default {
       return false;
     },
     deleteImgList(ind) {
-      this.imageUrl.splice(ind, 1);
+      const value = this.imageUrl[ind];
+      this.$emit('upload', this.imageUrl.filter(url => url !== value ));
     },
     add(type, index, item) {
       const arr = {

+ 8 - 18
src/views/diagnosis/Diagnosis.vue

@@ -50,16 +50,17 @@
           <span>辅助检查:</span>
           {{patiensMsg.outpatientElectronicmedicalrecord.supplementaryexamination}}
         </p>
-        <p v-if="patiensMsg.outpatientElectronicmedicalrecord.image1.length>0">
+        <div v-if="patiensMsg.outpatientElectronicmedicalrecord.image1.length>0">
+          <div style="margin: 4px 0 8px;">报告上传:</div>
           <el-image
-            :preview-src-list="[item]"
+            :preview-src-list="patiensMsg.outpatientElectronicmedicalrecord.image1"
             :src="item"
             :key="index"
             style="width:64px;height: 64px;margin-right: 10px;"
             alt
             v-for="(item,index) in patiensMsg.outpatientElectronicmedicalrecord.image1"
           />
-        </p>
+        </div>
       </div>
     </div>
     <div class="diagnosis-container">
@@ -253,6 +254,9 @@ import { mapState, mapGetters, mapActions, mapMutations } from "vuex";
 import TCMDiagnosis from "../../components/TCMDiagnosis.vue";
 
 import { setTimeout } from "timers";
+
+import { formatPicture } from "@/utils/picture";
+
 export default {
   components: {
     TCMDiagnosis
@@ -810,21 +814,7 @@ export default {
           // // this.$router.back()
           // return
         }
-
-        if (res.Data.outpatientElectronicmedicalrecord.image1) {
-          let img1 = res.Data.outpatientElectronicmedicalrecord.image1.split(
-            ","
-          );
-          let arr = [];
-          img1.forEach(item => {
-            item = process.env.VUE_APP_UPLOAD + "file/" + item;
-
-            arr.push(item);
-          });
-          res.Data.outpatientElectronicmedicalrecord.image1 = arr;
-        } else {
-          res.Data.outpatientElectronicmedicalrecord.image1 = [];
-        }
+        res.Data.outpatientElectronicmedicalrecord.image1 = formatPicture(res.Data.outpatientElectronicmedicalrecord.image1);
 
         this.patiensMsg = res.Data;
       } else {

+ 33 - 14
src/views/diagnosis/Emr.vue

@@ -25,7 +25,7 @@
         </div>
       </div>
       <div class="emr-form">
-        <PriviewEdit :editListF="temItem.templateContent" ref="edit"></PriviewEdit>
+        <PriviewEdit ref="edit" :editListF="temItem.templateContent" v-model="previewPicture"></PriviewEdit>
       </div>
     </div>
 
@@ -53,6 +53,9 @@ import { getTemplateList, getLastTemId, saveLastTemId } from "@/api/emr";
 import { mapGetters, mapMutations } from "vuex";
 import uploadFile from "@/components/UploadFile.vue";
 import PriviewEdit from "../business/components/PriviewEdit.vue";
+
+import { formatPicture } from "@/utils/picture";
+
 export default {
   components: {
     uploadFile,
@@ -88,6 +91,7 @@ export default {
       ],
       temItem: {},
       priviewItem: {},
+      previewPicture: [],
       dialogVisible: false
     };
   },
@@ -376,7 +380,9 @@ export default {
         const resultList = [];
         for (let i = 0; i < childrenList.length; i++) {
           const item = childrenList[i];
+
           resultList.push(item);
+
           if (item.children) {
             resultList.push(...joinChildren(item.children));
           }
@@ -405,7 +411,9 @@ export default {
     backUploadData() {
       let sourceData = JSON.parse(JSON.stringify(this.$refs.edit.editList));
       let list = this.flat(sourceData);
+
       let joinArr = this.joinList(list);
+
       const paramsData = {
         chiefcomplaint: "", // 主诉
         fourmedicine: "", // 中医四诊
@@ -484,20 +492,26 @@ export default {
 
       return paramsData;
     },
-    // 获取与目标数组中不同的部
+    // 获取与目标数组中不同的部
     findDifferences(arr1, arr2) {
       return arr2.filter(value => !arr1.includes(value));
     },
-    // 获取与目标数组中相同的部
+    // 获取与目标数组中相同的部
     findSame(arr1, arr2) {
       return arr2.filter(value => arr1.includes(value));
     },
+    // 去重
+    removeRepate(arr) {
+      let arr1 = new Set(arr);
+      return Array.from(arr1);
+    },
     // 回显的值 赋值给模板
     showMsgToTem(data) {
       let _this = this;
       const paramsData = {
         chiefcomplaint: data.chiefcomplaint, // 主诉
-        fourmedicine: data.fourmedicine, // 中医四诊
+        // fourmedicine: data.fourmedicine, // 中医四诊
+        fourmedicine: "",
         historypresent: data.historypresent, // 现病史
         pasthistory: data.pasthistory, // 既往史
         physicalexamination: data.physicalexamination, // 体格检查
@@ -505,6 +519,7 @@ export default {
         echoData: JSON.parse(data.echoData)
       };
       let tem = this.$refs.edit.editList;
+
       tem.forEach(item => {
         if (
           item.id == 1 &&
@@ -576,7 +591,12 @@ export default {
               let diffValues = _this.findDifferences(radioLabels, echoItem);
 
               otherStr = diffValues.join(";");
-              item.fillValues = _this.findSame(radioLabels, echoItem);
+              item.fillValues = [
+                ...item.fillValues,
+                ..._this.findSame(radioLabels, echoItem)
+              ];
+
+              item.fillValues = _this.removeRepate(item.fillValues);
 
               item.radioList.forEach(item1 => {
                 if (echoItem.includes(item1.label)) {
@@ -783,7 +803,13 @@ export default {
                   this.temItem.templateContent = JSON.parse(
                     res.Data[0].templateContent
                   );
-                  this.showMsgToTem(res.Data[0]);
+
+                  //
+                  let tem = this.$refs.edit.editList;
+                  setTimeout(() => {
+                    this.showMsgToTem(res.Data[0]);
+                  }, 1000);
+
                   throw Error();
                 }
               });
@@ -795,14 +821,7 @@ export default {
         } else {
           this.showMsgToTem(res.Data[0]);
         }
-        if (!res.Data[0].image1) return;
-        res.Data[0].image1 = res.Data[0].image1.split(",");
-
-        res.Data[0].image1.forEach(item => {
-          this.$refs.edit.imageUrl.push(
-            process.env.VUE_APP_UPLOAD + "file/" + item
-          );
-        });
+        this.previewPicture = res.Data[0].image1 = formatPicture(res.Data[0].image1);
 
         setTimeout(() => {
           this.isEdit = false;

+ 65 - 17
src/views/diagnosis/Prescribing.vue

@@ -50,16 +50,17 @@
           <span>辅助检查:</span>
           {{patiensMsg.outpatientElectronicmedicalrecord.supplementaryexamination}}
         </p>
-        <p v-if="patiensMsg.outpatientElectronicmedicalrecord.image1.length>0">
+        <div v-if="patiensMsg.outpatientElectronicmedicalrecord.image1.length>0">
+          <div style="margin: 4px 0 8px;">报告上传:</div>
           <el-image
-            :preview-src-list="[item]"
+            :preview-src-list="patiensMsg.outpatientElectronicmedicalrecord.image1"
             :src="item"
             :key="index"
             style="width:64px;height: 64px;margin-right: 10px;"
             alt
             v-for="(item,index) in patiensMsg.outpatientElectronicmedicalrecord.image1"
           />
-        </p>
+        </div>
       </div>
       <!-- mr-t30 -->
       <div class="pre-title" v-if="false">
@@ -313,6 +314,8 @@
         </div>
         <!-- 右侧按钮 -->
         <div class="flex-vertical-center-r flex-wrap">
+          <el-button size="mini" @click="openUnifyPrescPrec" type="primary">统建处方</el-button>
+          <el-button size="mini" :loading="tongueAndFaceLoading" :disabled="!tongueAndFaceAnalysis" @click="openTongueAndFaceAnalysis" type="primary">舌象分析</el-button>
           <el-button
             size="mini"
             type="primary"
@@ -1055,6 +1058,34 @@
       </div>
     </Popup>
 
+    <!-- 查询统建处方 页面768 -->
+    <Popup
+      :showDialog="showUnifyPresc"
+      @cancle="showUnifyPresc=false"
+      title="查询统建处方"
+      :showBtns="false"
+      width="700px"
+      distanceTop="5vh"
+    >
+      <div slot="body">
+        <UnifyPrescription></UnifyPrescription>
+      </div>
+    </Popup>
+
+    <!-- 查询舌象分析 页面768 -->
+    <Popup
+        :showDialog="showTongueAnalysis"
+        @cancle="showTongueAnalysis=false"
+        title="分析详情"
+        :showBtns="false"
+        width="700px"
+        distanceTop="5vh"
+    >
+      <div slot="body">
+        <TongueAnalysis :dataset="tongueAndFaceAnalysis"></TongueAnalysis>
+      </div>
+    </Popup>
+
     <!-- 安全合理用药弹窗 -->
     <!-- 查询协定方 方剂 页面768 -->
     <Popup
@@ -1106,11 +1137,14 @@ import submitRecipe from "./components/submitRecipe.vue";
 import TCMDiagnosis from "../../components/TCMDiagnosis.vue";
 import doctorCase from "./components/doctorCase.vue";
 import prescription from "./components/prescription.vue";
+import UnifyPrescription from "./components/prescription-unify.vue";
+import TongueAnalysis from "./components/tongue-analysis.vue";
 import safeDrug from "./components/safeDrug.vue";
 import medAdress from "./components/medAddress.vue";
 import medAdressNew from "./components/medAddressNew.vue";
 import {
   getPatiensBasisM,
+  getTongueAndFaceAnalysis,
   addRecipe,
   getRecipeShowData,
   getRecipeDataByid,
@@ -1146,6 +1180,8 @@ import { getExperinceDetail } from "@/api/business.js";
 import { setTimeout } from "timers";
 import prescribing from "../../utils/minix/prescribing";
 
+import {formatPicture} from "@/utils/picture";
+
 export default {
   mixins: [prescribing],
   components: {
@@ -1156,6 +1192,8 @@ export default {
     TCMDiagnosis,
     submitRecipe,
     prescription,
+    UnifyPrescription,
+    TongueAnalysis,
     doctorCase,
     safeDrug,
     medAdress,
@@ -1163,6 +1201,10 @@ export default {
   },
   data() {
     return {
+      tongueAndFaceLoading: false, // 舌面象加载
+      tongueAndFaceAnalysis: null, // 舌面象数据
+      showTongueAnalysis: false, // 舌象分析弹窗
+
       showPriview: false, // 展示预览数据
       showDialog: false, // 方剂详情
       showDrug: false, // 药品详情
@@ -1325,6 +1367,7 @@ export default {
 
     if (this.getPatiensInfo.pid) {
       this.getPatiensBasisM();
+      this.getPatientBasisTongueAndFaceAnalysis();
     }
   },
   mounted() {
@@ -2515,6 +2558,7 @@ export default {
       this.showAgree = false;
       this.showExpr = false;
       this.showPresc = false;
+      this.showUnifyPresc = false;
 
       data1.getPharmacyID();
     },
@@ -3112,20 +3156,7 @@ export default {
           : [];
         this.patiensMsg = res.Data;
 
-        if (this.patiensMsg.outpatientElectronicmedicalrecord.image1) {
-          let img1 = res.Data.outpatientElectronicmedicalrecord.image1.split(
-            ","
-          );
-          let arr = [];
-          img1.forEach(item => {
-            item = process.env.VUE_APP_UPLOAD + "file/" + item;
-
-            arr.push(item);
-          });
-          res.Data.outpatientElectronicmedicalrecord.image1 = arr;
-        } else {
-          this.patiensMsg.outpatientElectronicmedicalrecord.image1 = [];
-        }
+        this.patiensMsg.outpatientElectronicmedicalrecord.image1 = formatPicture(this.patiensMsg.outpatientElectronicmedicalrecord.image1);
         // if (!this.patiensMsg.maindiagnosis.disid) {
         //   this.$message.warning("请先提交一条诊断信息");
         //   this.$router.replace({
@@ -3140,6 +3171,22 @@ export default {
         // }
       }
     },
+    async openTongueAndFaceAnalysis() {
+      if (!this.tongueAndFaceAnalysis) await this.getPatientBasisTongueAndFaceAnalysis()
+      if (this.tongueAndFaceAnalysis) this.showTongueAnalysis = true;
+    },
+    // 获取病人 舌面象数据
+    async getPatientBasisTongueAndFaceAnalysis() {
+      this.tongueAndFaceLoading = true;
+      try {
+        let res = await getTongueAndFaceAnalysis({
+          recordsId: this.getPatiensInfo ? this.getPatiensInfo.pid : ""
+          // recordsId: '8ed63872-6d1f-4fe6-b170-4d36e677a744',
+        });
+        this.tongueAndFaceAnalysis = res.Data && (res.Data.tongueAnalysis.结果 || res.Data.faceAnalysis.结果) ? res.Data : null;
+      } catch (e) {}
+      this.tongueAndFaceLoading = false;
+    },
     // 获取处方预览数据
     async _getRecipePriview(zhongyao, zhongchengyao, technology) {
       const loading = this.$loading({
@@ -4078,6 +4125,7 @@ export default {
           this.showTestCase = false;
           this.showDialog = false;
           this.showPresc = false;
+          this.showUnifyPresc = false;
           loading.close();
         }
       } else if (this.container_i == 2) {

+ 256 - 0
src/views/diagnosis/components/prescription-unify.vue

@@ -0,0 +1,256 @@
+<template>
+  <!-- 查询统建处方 -->
+  <div class="prescription">
+    <!-- 搜索条件 -->
+    <div class="top-filter">
+      <el-form label-position="left" label-width="70px" :model="form" inline>
+        <el-form-item label="方名">
+          <el-input v-model="form.name" size="small" placeholder="请输入"></el-input>
+        </el-form-item>
+        <el-form-item label="共享状态" v-if="activeName === '2'">
+          <el-select v-model="form.share" placeholder="请选择" size="small">
+            <!-- <el-option
+              :label="item.name"
+              :value="item.pid"
+              v-for="(item,index) in shareSelect"
+              :key="index"
+            ></el-option>-->
+            <el-option label="个人" :value="0"></el-option>
+            <el-option label="二级科室" :value="1"></el-option>
+            <el-option label="科室" :value="2"></el-option>
+            <el-option label="本院" :value="3"></el-option>
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <el-button size="small" type="primary" @click="searchDis">搜索</el-button>
+      <el-button size="small" type="warning" @click="clearDis">清空</el-button>
+    </div>
+    <!-- 表格数据展示 -->
+    <div class="table">
+      <!-- 统建处方(协定方)表格 -->
+      <el-table :data="tableData1" border style="width: 100%" v-if="activeName === '2'">
+        <el-table-column prop="name" label="方名" align="center"></el-table-column>
+        <el-table-column prop="chinesesymptom" label="是否可修改" align="center" width="95">
+          <template slot-scope="scope">
+            <div>{{ scope.row.type==0?'是':'否' }}</div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="effect" label="功效与适用症" align="center" width="150"></el-table-column>
+        <el-table-column prop="drugInformation" label="中药信息" align="center"></el-table-column>
+        <el-table-column prop="book" label="共享状态" align="center">
+          <template slot-scope="scope">
+            <div>{{ scope.row.showType |filterShowType}}</div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="address" label="操作" width="80" align="center">
+          <template slot-scope="scope">
+            <el-button size="mini" type="primary" @click="handleAgree(scope)">转方</el-button>
+            <!-- <el-button size="mini" type="warning" @click="viewCaseDetail(scope)">合方</el-button> -->
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <!-- 分页数据 -->
+    <div class="paging">
+      <el-pagination
+        @current-change="handleCurrentChange"
+        :current-page="currentPage"
+        :page-size="10"
+        :total="total"
+        background
+        layout=" prev, pager, next, jumper"
+      ></el-pagination>
+    </div>
+  </div>
+</template>
+<script>
+import { getAccordShareList } from "@/api/business.js";
+import { getEffectQuery, getPrescriptionsList } from "@/api/knowledge.js";
+import { getAgreeRecipe, getAccordDetail } from "@/api/diagnosis.js";
+export default {
+  data() {
+    return {
+      activeName: "2",
+      form: {
+        name: "", // 方名
+        type: "", // 类型
+        share: "", // 共享状态
+        purposeType: "1", // 用途类型 1 八病九方
+      },
+      shareSelect: [],
+      types: [],
+      tableData: [],
+      tableData1: [],
+      currentPage: 1,
+      total: 0
+    };
+  },
+  created() {
+    this.getAccordShareList();
+    this.getEffectQuery();
+    // this.getPrescriptionsList();
+    this.getAgreeRecipe();
+  },
+  filters: {
+    filterShowType(val) {
+      if (val == 0) return "个人";
+      if (val == 1) return "二级科室";
+      if (val == 2) return "科室";
+      if (val == 3) return "本院";
+    }
+  },
+  methods: {
+    clearDis() {
+      this.currentPage = 1;
+
+      this.form = {
+        name: "", // 方名
+        type: "", // 类型
+        share: "" // 共享状态
+      };
+      if (this.activeName === '2') {
+        this.getAgreeRecipe();
+      }
+    },
+    handleCurrentChange(e) {
+      this.currentPage = e;
+      if (this.activeName === '2') {
+        this.getAgreeRecipe();
+      }
+    },
+    searchDis() {
+      this.currentPage = 1;
+      if (this.activeName === '2') {
+        this.getAgreeRecipe();
+      }
+    },
+    handleClick() {
+      this.currentPage = 1;
+
+      this.form = {
+        name: "", // 方名
+        type: "", // 类型
+        share: "", // 共享状态
+        purposeType: "1", // 用途类型 1 八病九方
+      };
+      if (this.activeName === '2') {
+        this.getAgreeRecipe();
+      }
+    },
+    //   方剂换方/合方
+    handleFj(scope, type) {
+      let item = scope.row;
+      if (type == 1) {
+        // 换
+        this.$parent.$parent.$parent.inferChange(item);
+      } else {
+        // 合
+        this.$parent.$parent.$parent.inferChange1(item);
+      }
+    },
+    // 协定方转方
+    handleAgree(scope) {
+      this.getAccordDetail(scope.row.preId);
+    },
+    // 获取共享至信息
+    async getAccordShareList() {
+      let res = await getAccordShareList();
+      if (res.ResultCode == 0) {
+        this.shareSelect = res.Data;
+      }
+    },
+    // 获取方剂分类
+    async getEffectQuery() {
+      let res = await getEffectQuery({
+        effecttype: "1",
+        effictId: ""
+      });
+
+      if (res.code == 0) {
+        this.types = res.data.effects;
+      }
+    },
+    // 获取方剂列表
+    async getPrescriptionsList() {
+      let params = {
+        pageid: this.currentPage,
+        pagesize: 10,
+        searchtype: "",
+        keyword: this.form.name,
+        effected: this.form.type
+      };
+      let res = await getPrescriptionsList(params);
+      if (res.code == 0) {
+        this.total = res.data.TotalRecordCount;
+        this.tableData = res.data.pres;
+      }
+    },
+    //获取右侧协定方列表
+    async getAgreeRecipe() {
+      let params = {
+        type: this.form.share,
+        purposeType: this.form.purposeType,
+
+        name: this.form.name,
+        pageId: this.currentPage,
+        pageSize: 10
+      };
+      let res = await getAgreeRecipe(params);
+      if (res.ResultCode == 0) {
+        this.total = res.Data.TotalRecordCount;
+        this.tableData1 = res.Data.Items;
+      }
+    },
+    //   获取协定方详情
+    async getAccordDetail(id) {
+      let res = await getAccordDetail({
+        pid: id
+      });
+      if (res.ResultCode == 0) {
+        this.$parent.$parent.$parent.agreeInfo = res.Data;
+        this.$parent.$parent.$parent.turnRecipe2(res.Data);
+        if (res.Data.diseaseid) {
+          this.$parent.$parent.$parent.$refs.TCM.setParams({
+            namemedicine: res.Data.diseasename,
+            disid: res.Data.diseaseid,
+            symptomid: res.Data.symptomid,
+            syndrometypes: res.Data.symptomname,
+            treatment: res.Data.treatment
+          });
+
+          setTimeout(() => {
+            this.$parent.$parent.$parent.tcmClick(false);
+          }, 200);
+        }
+      }
+    }
+  }
+};
+</script>
+<style lang="scss" scoped>
+.top-filter {
+  display: flex;
+  align-items: center;
+  justify-content: flex-start;
+  margin-bottom: 10px;
+}
+
+.top-filter {
+  ::v-deep {
+    .el-input__inner {
+      width: 150px;
+    }
+
+    .el-form--inline .el-form-item {
+      margin-bottom: 0;
+    }
+  }
+}
+
+.paging {
+  margin-top: 10px;
+  display: flex;
+  justify-content: center;
+}
+</style>
+    

+ 6 - 9
src/views/diagnosis/components/submitRecipe.vue

@@ -150,13 +150,13 @@
                   <span>{{ msg.electronicmedicalrecord.supplementaryexamination }}</span>
                 </div>
               </div>
-              <div class="ms-row">
+              <div class="ms-row" v-if="msg.electronicmedicalrecord.image1.length">
                 <div class="row-item">
                   <span>报告照片:</span>
                   <div class="img-body">
                     <el-image
                       class="img-item"
-                      :preview-src-list="[item1]"
+                      :preview-src-list="msg.electronicmedicalrecord.image1"
                       :src="item1"
                       alt
                       v-for="(item1,index1) in msg.electronicmedicalrecord.image1"
@@ -325,6 +325,9 @@ import Popup from "@/components/Propup.vue";
 import chineseMedicinePad from "@/components/ui/chineseMedicinePad.vue";
 import chineseMadePad from "@/components/ui/chineseMadePad.vue";
 import suitMadePad from "@/components/ui/suitMadePad.vue";
+
+import { formatPicture } from "@/utils/picture";
+
 export default {
   components: {
     Popup,
@@ -496,13 +499,7 @@ export default {
       // });
       if (this.priviewData.prescriptionVo) {
         this.msg = this.priviewData.prescriptionVo;
-        if (this.msg.electronicmedicalrecord.image1) {
-          this.msg.electronicmedicalrecord.image1 = this.msg.electronicmedicalrecord.image1.split(
-            ","
-          );
-        } else {
-          this.msg.electronicmedicalrecord.image1 = [];
-        }
+        this.msg.electronicmedicalrecord.image1 = formatPicture(this.msg.electronicmedicalrecord.image1);
       }
     },
     // 删除处方

+ 179 - 0
src/views/diagnosis/components/tongue-analysis.vue

@@ -0,0 +1,179 @@
+<template>
+  <!-- 舌象分析详情 -->
+  <div class="tongue-analysis">
+    <template v-if="dataset && (dataset.tongueAnalysis.结果 || dataset.faceAnalysis.结果)">
+      <template v-if="dataset.tongueAnalysis && dataset.tongueAnalysis.结果">
+        <el-card class="tongue-exception-wrapper" v-if="showException">
+          <div slot="header" class="card-header-container">
+            <span>异常舌象分析</span>
+            <el-button size="small" type="primary" plain style="float: right;" @click="showException=false">
+              舌象分析
+            </el-button>
+          </div>
+          <div class="card-body-container">
+            <el-card v-for="item in dataset.tongueException" :key="item.title" class="inner" size="small">
+              <div class="card__title">{{ item.title }}</div>
+              <div class="card__content">
+                <div style="display: flex;">
+                  <el-image :src="item.cover" lazy fit="scale-down" :preview-src-list="[item.cover]"></el-image>
+                  <div>
+                    <el-tag v-for="value in item.tags" :key="value" type="danger">{{ value }}</el-tag>
+                  </div>
+                </div>
+                <p class="my-2 text-grey" v-for="value in item.descriptions" :key="value">{{ value }}</p>
+              </div>
+            </el-card>
+          </div>
+        </el-card>
+        <el-card v-else>
+          <div slot="header" class="card-header-container">
+            <span>舌象分析</span>
+            <el-button
+                v-if="dataset.tongueException && dataset.tongueException.length"
+                size="small" type="danger" plain style="float: right;" @click="showException=true">
+              异常舌象分析
+            </el-button>
+          </div>
+          <div class="card-body-container">
+            <el-table v-if="dataset.tongueTable" class="result-wrapper" :data="dataset.tongueTable.data" border
+                      size="small">
+              <el-table-column
+                  v-for="(col, index) in dataset.tongueTable.column" :key="col"
+                  :prop="index + ''" :label="col" align="center"
+              >
+                <template v-slot="{row, column}">
+                  <div v-html="row[index]"></div>
+                </template>
+              </el-table-column>
+            </el-table>
+            <div v-else class="result-wrapper">{{ dataset.tongueAnalysis.结果 }}</div>
+            <div class="picture-wrapper">
+              <el-image :src="dataset.tongueAnalysis.舌上" lazy fit="scale-down"
+                        :preview-src-list="preview"></el-image>
+              <el-image :src="dataset.tongueAnalysis.舌下" lazy fit="scale-down"
+                        :preview-src-list="preview"></el-image>
+            </div>
+          </div>
+        </el-card>
+      </template>
+      <el-card v-if="dataset.faceAnalysis && dataset.faceAnalysis.结果">
+        <div slot="header" class="card-header-container">
+          <span>面象分析</span>
+        </div>
+        <div class="card-body-container">
+          <div class="result-wrapper">{{ dataset.faceAnalysis.结果 }}</div>
+          <div class="picture-wrapper">
+            <el-image :src="dataset.faceAnalysis.面象" lazy fit="scale-down" :preview-src-list="preview"></el-image>
+          </div>
+        </div>
+      </el-card>
+    </template>
+    <el-empty v-else-if="!loading" description="暂无数据"></el-empty>
+  </div>
+</template>
+<script>
+import {getTongueAndFaceAnalysis} from "@/api/diagnosis.js";
+
+export default {
+  props: {
+    dataset: {
+      type: Object,
+      default() { return null; }
+    }
+  },
+  data() {
+    return {
+      showException: false
+    };
+  },
+  computed: {
+    preview: function () {
+      return [
+        this.dataset.tongueAnalysis.舌上,
+        this.dataset.tongueAnalysis.舌下,
+        this.dataset.faceAnalysis.面象,
+      ].filter(Boolean);
+    }
+  },
+};
+</script>
+<style lang="scss" scoped>
+.tongue-analysis {
+  .el-card:not(.inner) {
+    margin: 24px 0;
+
+    &:first-of-type { margin-top: 0 }
+
+    &:last-of-type { margin-bottom: 0 }
+
+    &.tongue-exception-wrapper {
+      .card-body-container {
+        display: grid;
+        grid-template-rows: repeat(1, minmax(0, 1fr));
+        grid-template-columns: repeat(2, minmax(0, 1fr));
+        gap: 12px;
+      }
+
+      .card__title {
+        padding: 6px 12px;
+        color: #F56C6C;
+      }
+
+      .card__content {
+        padding: 6px 12px 12px;
+      }
+
+      .el-image {
+        width: 100px;
+        height: 100px;
+        margin-right: 12px;
+        margin-bottom: 12px;
+      }
+
+      .inner ::v-deep .el-card__body {
+        padding: 0;
+      }
+
+      p {
+        line-height: 1.75;
+
+        &:not(:last-of-type) { margin-bottom: 8px; }
+      }
+    }
+  }
+
+  .card-header-container {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    height: 100%;
+  }
+
+  .card-body-container {
+    display: flex;
+
+    .result-wrapper {
+      flex: auto;
+    }
+
+    .picture-wrapper {
+      flex: none;
+      display: flex;
+      flex-direction: column;
+      justify-content: space-evenly;
+      margin-left: 12px;
+      max-width: 100px;
+
+      .el-image {
+        width: 100px;
+        height: 100px;
+      }
+    }
+  }
+
+  ::v-deep .el-card__header {
+    padding: 0 20px;
+    height: 56px;
+  }
+}
+</style>

+ 16 - 3
src/views/knowledge/DoctorCaseBefore.vue

@@ -4,7 +4,12 @@
       <div :class="['tabs-item',activeName==0?'active':'']" @click="handleTab('0')">专家</div>
       <div :class="['tabs-item',activeName==1?'active':'']" @click="handleTab('1')">疾病</div>
     </div>
-    <div class="content">
+    <form v-if="activeName === '1'" style="width: 350px;margin: 12px auto 0;" @submit.stop="handleSearch()">
+      <el-input placeholder="请输入关键词搜索" v-model="keyword" clearable @clear="handleSearch()">
+        <el-button slot="append" icon="el-icon-search" @click="handleSearch()"></el-button>
+      </el-input>
+    </form>
+    <div class="content" :class="{searchable: activeName === '1'}">
       <div class="content-item" v-for="(item,index) in list" :key="index">
         <div class="en">{{item.pyCode}}</div>
         <div class="list">
@@ -26,6 +31,7 @@ export default {
   data() {
     return {
       activeName: "0",
+      keyword: "",
       list: []
     };
   },
@@ -33,6 +39,9 @@ export default {
     this.initData();
   },
   methods: {
+    handleSearch() {
+      this.initData();
+    },
     handleTab(active) {
       this.activeName = active;
       this.initData();
@@ -45,7 +54,8 @@ export default {
     // 初始化数据
     async initData() {
       let res = await getDoctorCaseIndexL({
-        indextype: this.activeName
+        indextype: this.activeName,
+        keyWord: this.activeName === '1' ? this.keyword : '',
       });
       if (res.code == 0) {
         let isPy = /^[A-Za-z]/;
@@ -90,7 +100,7 @@ export default {
 .container {
   height: calc(100vh - 100px);
   background: #fff;
-  overflow: auto;
+  overflow: hidden;
 }
 
 .tabs {
@@ -115,6 +125,9 @@ export default {
 }
 
 .content {
+  &.searchable {
+    height: calc(100% - 40px - 40px);
+  }
   height: calc(100% - 40px);
   box-sizing: border-box;
   padding: 20px;

+ 5 - 2
vue.config.js

@@ -13,9 +13,9 @@ module.exports = {
 
                 // target: `http://192.168.1.10:8080/`, //王志飞本地
                 // target: `http://cloudclinicapi.9czn.cn/`, // 测试地址
-                target: `http://115.236.184.102:8081/`, // 萧山物理机
+                // target: `http://115.236.184.102:8081/`, // 萧山物理机
                 // target: 'http://192.168.204.124:8081/', // 客户正式服务器"
-
+                target: `http://121.43.162.141:80/`, // [萧山] 测试环境的后端地址
                 // target: `http://www.hzxunmai.com/`, // 正式域名
                 // target: `http://10.250.11.48:8080/`, // 正式域名
 
@@ -23,6 +23,9 @@ module.exports = {
                 pathRewrite: {
                     ['^' + process.env.VUE_APP_BASE_API]: ''
                 }
+            },
+            '/file': {
+                target: `http://121.43.162.141:80/`, // [萧山] 测试环境的后端地址
             }
         },