Sfoglia il codice sorgente

商城订单详情增加关联的医生完善信息与处方图片展示

cgp 10 ore fa
parent
commit
1f0bec45bd

+ 51 - 0
src/api/his/scrmPrescribe.js

@@ -0,0 +1,51 @@
+import request from '@/utils/request'
+
+/**
+ * 获取医生、药师签名及职称信息
+ * @param {Array<number>} doctorIds 医生ID和药师ID组成的数组
+ * @returns {Promise}
+ */
+export function getDoctorSignInfo(doctorIds) {
+  return request({
+    url: '/his/prescribeDataScrm/getSignInfo',
+    method: 'post',
+    data: doctorIds
+  })
+}
+
+/**
+ * 获取客户信息+问答信息
+ * @param {number} companyCustomerId 客户信息表主键id
+ * @returns {Promise}
+ */
+export function getCustomerInfoAndQuestionAnswer(companyCustomerId) {
+  return request({
+    url: `/his/prescribeDataScrm/getCustomerInfoAndQuestionAnswer/${companyCustomerId}`,
+    method: 'get'
+  })
+}
+
+/**
+ * 获取已保存的医生建议信息
+ * @param {number} prescribeId 处方ID
+ * @returns {Promise}
+ */
+export function getDoctorAdvice(prescribeId) {
+  return request({
+    url: `/his/prescribeDataScrm/getDoctorAdvice/${prescribeId}`,
+    method: 'get'
+  })
+}
+
+/**
+ * 根据订单号获取处方信息
+ * @param {string} orderCode 订单号
+ * @returns {Promise}
+ */
+export function getPrescribeInfoByOrderCode(orderCode) {
+  return request({
+    url: '/his/prescribeDataScrm/getPrescribeInfoByOrderCode',
+    method: 'get',
+    params: { orderCode }
+  })
+}

+ 393 - 0
src/views/hisStore/components/OrderDoctorAdvice.vue

@@ -0,0 +1,393 @@
+<template>
+  <div v-if="hasData" class="doctor-advice-container">
+    <el-divider content-position="left">医生完善信息</el-divider>
+
+    <!-- 患者基本信息 -->
+    <div v-if="customerInfo && Object.keys(customerInfo).length" class="info-section">
+      <div class="section-title">患者信息</div>
+      <el-row :gutter="20">
+        <el-col :span="12"><span class="info-label">患者姓名:</span><span class="info-value">{{ customerInfo.customerName || '-' }}</span></el-col>
+        <el-col :span="12"><span class="info-label">性别:</span><span class="info-value">{{ sexText }}</span></el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col :span="12"><span class="info-label">年龄:</span><span class="info-value">{{ customerInfo.age || '-' }}</span></el-col>
+        <el-col :span="12"><span class="info-label">电话:</span><span class="info-value">{{ customerInfo.phone || '-' }}</span></el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col :span="24"><span class="info-label">会诊时间:</span><span class="info-value">{{ customerInfo.createTime | formatDate }}</span></el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col :span="24"><span class="info-label">患者病情主诉:</span><span class="info-value">{{ customerInfo.patientMainComplaint || '-' }}</span></el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col :span="24"><span class="info-label">现病史:</span><span class="info-value">{{ customerInfo.presentIllness || '-' }}</span></el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col :span="24"><span class="info-label">过敏史:</span><span class="info-value">{{ customerInfo.allergyHistory || '-' }}</span></el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col :span="24"><span class="info-label">现用药:</span><span class="info-value">{{ customerInfo.currentMedication || '-' }}</span></el-col>
+      </el-row>
+    </div>
+
+    <!-- 患者病情问答 -->
+    <div v-if="questionAnswers && questionAnswers.length" class="info-section">
+      <div class="section-title">患者病情问答</div>
+      <div class="qa-list">
+        <div v-for="(item, idx) in questionAnswers" :key="idx" class="qa-item">
+          <span class="qa-title">{{ item.title }}</span>
+          <span class="qa-answer">{{ item.answerText || '未回答' }}</span>
+        </div>
+      </div>
+    </div>
+
+    <!-- 医生建议及处置 -->
+    <div v-if="hasAdvice" class="info-section">
+      <div class="section-title">医生建议及处置</div>
+      <el-form label-width="150px">
+        <el-form-item label="诊断">
+          <span class="form-value">{{ formData.diagnose || '-' }}</span>
+        </el-form-item>
+        <el-form-item label="舌诊、面诊、手诊">
+          <span class="form-value">{{ formData.facialDiagnosis || '-' }}</span>
+        </el-form-item>
+        <el-form-item label="饮食运动建议">
+          <span class="form-value">{{ formData.foodAndExerciseGuidance || '-' }}</span>
+        </el-form-item>
+        <el-form-item label="治疗方面">
+          <el-table :data="formData.healingList" border stripe size="small">
+            <el-table-column label="诊断内容" prop="diagnosisContent" min-width="200" />
+            <el-table-column label="建议治疗" prop="suggestTreatment" min-width="200" />
+          </el-table>
+        </el-form-item>
+        <el-form-item label="注意禁忌">
+          <span class="form-value">{{ formData.noteTaboos || '-' }}</span>
+        </el-form-item>
+      </el-form>
+    </div>
+
+    <!-- 医生及药师信息 -->
+    <div v-if="hasSign" class="info-section">
+      <el-divider content-position="left">医生及药师信息</el-divider>
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <span class="info-label">医生职称:</span>
+          <span class="info-value">{{ signInfo.doctorPosition || '-' }}</span>
+        </el-col>
+        <el-col :span="12">
+          <span class="info-label">执业医师证号:</span>
+          <span class="info-value">{{ signInfo.doctorPractiseCode || signInfo.doctorCertificateCode || '-' }}</span>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <span class="info-label">药师签字:</span>
+          <div v-if="signInfo.drugDoctorSignUrl" style="display: inline-flex; align-items: center;">
+            <el-image :src="signInfo.drugDoctorSignUrl" style="width: 100px; height: 40px;" fit="contain" />
+            <span style="margin-left: 8px; color: #909399;">(药师:{{ signInfo.drugDoctorName || '' }})</span>
+          </div>
+          <span v-else>{{ signInfo.drugDoctorName || '暂无药师签名' }}</span>
+        </el-col>
+        <el-col :span="12">
+          <span class="info-label">执业医师签字:</span>
+          <div v-if="signInfo.doctorSignUrl" style="display: inline-flex; align-items: center;">
+            <el-image :src="signInfo.doctorSignUrl" style="width: 100px; height: 40px;" fit="contain" />
+            <span style="margin-left: 8px; color: #909399;">(医生:{{ signInfo.doctorName || '' }})</span>
+          </div>
+          <span v-else>{{ signInfo.doctorName || '暂无医生签名' }}</span>
+        </el-col>
+      </el-row>
+    </div>
+
+    <!-- 处方图片展示 -->
+    <div v-if="prescribeInfo && (prescribeInfo.prescribeImgStoreUrl || prescribeInfo.prescribeImgUrl)" class="info-section">
+      <el-divider content-position="left">处方图片</el-divider>
+      <div style="display: flex; gap: 20px; justify-content: flex-start; flex-wrap: wrap;">
+        <!-- 西药图片(prescribeType=1 或 3) -->
+        <div v-if="shouldShowWesternImage(prescribeInfo.prescribeType)" style="text-align: center; flex: 1;">
+          <div style="margin-bottom: 5px; font-weight: 500;">西药处方</div>
+          <el-image
+            v-if="prescribeInfo.prescribeImgStoreUrl"
+            :src="prescribeInfo.prescribeImgStoreUrl"
+            :preview-src-list="[prescribeInfo.prescribeImgStoreUrl]"
+            style="width: 200px; height: auto; max-height: 200px; object-fit: contain; border: 1px solid #ddd; border-radius: 4px; cursor: pointer;"
+            fit="contain"
+          />
+          <div v-else style="color: #909399;">暂无西药处方图</div>
+        </div>
+        <!-- 中药图片(prescribeType=2 或 3) -->
+        <div v-if="shouldShowChineseImage(prescribeInfo.prescribeType)" style="text-align: center; flex: 1;">
+          <div style="margin-bottom: 5px; font-weight: 500;">中药处方</div>
+          <el-image
+            v-if="prescribeInfo.prescribeImgUrl"
+            :src="prescribeInfo.prescribeImgUrl"
+            :preview-src-list="[prescribeInfo.prescribeImgUrl]"
+            style="width: 200px; height: auto; max-height: 200px; object-fit: contain; border: 1px solid #ddd; border-radius: 4px; cursor: pointer;"
+            fit="contain"
+          />
+          <div v-else style="color: #909399;">暂无中药处方图</div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import {
+  getCustomerInfoAndQuestionAnswer,
+  getDoctorAdvice,
+  getDoctorSignInfo,
+  getPrescribeInfoByOrderCode
+} from "@/api/his/scrmPrescribe";
+
+export default {
+  name: "OrderDoctorAdvice",
+  props: {
+    orderCode: {
+      type: String,
+      required: true
+    }
+  },
+  data() {
+    return {
+      customerInfo: {},
+      questionAnswers: [],
+      formData: {
+        diagnose: '',
+        facialDiagnosis: '',
+        foodAndExerciseGuidance: '',
+        healingList: [],
+        noteTaboos: ''
+      },
+      signInfo: {
+        doctorPosition: '',
+        doctorPractiseCode: '',
+        doctorCertificateCode: '',
+        doctorName: '',
+        drugDoctorName: '',
+        doctorSignUrl: '',
+        drugDoctorSignUrl: ''
+      },
+      prescribeInfo: null,        // 存储处方信息(含图片和ID)
+      hasData: false
+    };
+  },
+  computed: {
+    sexText() {
+      const sex = this.customerInfo.sex;
+      if (sex === '1') return '男';
+      if (sex === '0') return '女';
+      return '未知';
+    },
+    hasAdvice() {
+      const d = this.formData;
+      return !!(d.diagnose || d.facialDiagnosis || d.foodAndExerciseGuidance || d.healingList.length || d.noteTaboos);
+    },
+    hasSign() {
+      return !!(this.signInfo.doctorName || this.signInfo.drugDoctorName || this.signInfo.doctorSignUrl || this.signInfo.drugDoctorSignUrl);
+    }
+  },
+  filters: {
+    formatDate(val) {
+      if (!val) return '-';
+      const date = new Date(val);
+      if (isNaN(date)) return '-';
+      const pad = n => String(n).padStart(2, '0');
+      return `${date.getFullYear()}-${pad(date.getMonth()+1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
+    }
+  },
+  watch: {
+    orderCode: {
+      immediate: true,
+      handler(newVal) {
+        if (newVal) {
+          this.fetchData();
+        }
+      }
+    }
+  },
+  methods: {
+    // 判断是否显示西药图片:处方类型为1(西药)或3(西药+中药)
+    shouldShowWesternImage(prescribeType) {
+      return prescribeType === 1 || prescribeType === 3;
+    },
+    // 判断是否显示中药图片:处方类型为2(中药)或3(西药+中药)
+    shouldShowChineseImage(prescribeType) {
+      return prescribeType === 2 || prescribeType === 3;
+    },
+    fetchData() {
+      // 1. 根据 orderCode 获取处方信息
+      getPrescribeInfoByOrderCode(this.orderCode).then(response => {
+        const prescribe = response.data;
+        if (!prescribe) {
+          this.hasData = false;
+          return;
+        }
+        // 保存处方信息(用于图片展示)
+        this.prescribeInfo = {
+          prescribeType: prescribe.prescribeType,
+          prescribeImgStoreUrl: prescribe.prescribeImgStoreUrl,
+          prescribeImgUrl: prescribe.prescribeImgUrl
+        };
+
+        // 提取需要的ID
+        const prescribeId = prescribe.prescribeId;
+        const companyCustomerId = prescribe.companyCustomerId;
+        const doctorId = prescribe.doctorId;
+        const drugDoctorId = prescribe.drugDoctorId;
+
+        // 如果没有至少一个有效ID,则无数据可展示
+        if (!prescribeId && !companyCustomerId && !doctorId && !drugDoctorId) {
+          this.hasData = false;
+          return;
+        }
+
+        // 2. 并行请求其他信息
+        const promises = [];
+
+        // 获取客户信息 + 问答(需要 companyCustomerId)
+        if (companyCustomerId) {
+          promises.push(
+            getCustomerInfoAndQuestionAnswer(companyCustomerId)
+              .then(res => res.data)
+              .catch(() => null)
+          );
+        } else {
+          promises.push(Promise.resolve(null));
+        }
+
+        // 获取医生建议(需要 prescribeId)
+        if (prescribeId) {
+          promises.push(
+            getDoctorAdvice(prescribeId)
+              .then(res => res.data)
+              .catch(() => null)
+          );
+        } else {
+          promises.push(Promise.resolve(null));
+        }
+
+        // 获取签名信息(需要 doctorId 或 drugDoctorId)
+        if (doctorId || drugDoctorId) {
+          const ids = [];
+          if (doctorId) ids.push(doctorId);
+          if (drugDoctorId) ids.push(drugDoctorId);
+          promises.push(
+            getDoctorSignInfo(ids)
+              .then(res => res.data)
+              .catch(() => null)
+          );
+        } else {
+          promises.push(Promise.resolve(null));
+        }
+
+        // 等待所有请求完成
+        return Promise.all(promises).then(([customerData, adviceData, signData]) => {
+          if (customerData) {
+            this.customerInfo = {
+              customerName: customerData.customerName,
+              sex: customerData.sex,
+              age: customerData.age,
+              phone: customerData.phone,
+              createTime: customerData.createTime,
+              patientMainComplaint: customerData.patientMainComplaint,
+              presentIllness: customerData.presentIllness,
+              allergyHistory: customerData.allergyHistory,
+              currentMedication: customerData.currentMedication
+            };
+            this.questionAnswers = customerData.customerQuestionAnswerVOList || [];
+          }
+          if (adviceData) {
+            this.formData.diagnose = adviceData.diagnose || '';
+            this.formData.facialDiagnosis = adviceData.facialDiagnosis || '';
+            this.formData.foodAndExerciseGuidance = adviceData.foodAndExerciseGuidance || '';
+            this.formData.noteTaboos = adviceData.noteTaboos || '';
+            if (adviceData.healingAreaJson) {
+              try {
+                const list = JSON.parse(adviceData.healingAreaJson);
+                if (Array.isArray(list)) this.formData.healingList = list;
+              } catch (e) {}
+            }
+          }
+          if (signData) {
+            this.signInfo = {
+              doctorPosition: signData.position || '',
+              doctorPractiseCode: signData.PractiseCode || '',
+              doctorCertificateCode: signData.certificateCode || '',
+              doctorName: signData.doctorName || '',
+              drugDoctorName: signData.drugDoctorName || '',
+              doctorSignUrl: signData.doctorSignUrl || '',
+              drugDoctorSignUrl: signData.drugDoctorSignUrl || ''
+            };
+          }
+
+          // 判断是否有任何数据(包括处方图片)
+          const hasCustomer = Object.keys(this.customerInfo).length > 0;
+          const hasQa = this.questionAnswers.length > 0;
+          const hasAdvice = this.hasAdvice;
+          const hasSign = this.hasSign;
+          const hasPrescribeImg = !!(this.prescribeInfo && (this.prescribeInfo.prescribeImgStoreUrl || this.prescribeInfo.prescribeImgUrl));
+          this.hasData = hasCustomer || hasQa || hasAdvice || hasSign || hasPrescribeImg;
+        });
+      }).catch(() => {
+        this.hasData = false;
+      });
+    }
+  }
+};
+</script>
+
+<style scoped>
+.doctor-advice-container {
+  margin-top: 20px;
+}
+.info-section {
+  margin-bottom: 20px;
+  background-color: #f5f7fa;
+  padding: 12px 16px;
+  border-radius: 8px;
+}
+.section-title {
+  font-weight: bold;
+  font-size: 16px;
+  margin-bottom: 12px;
+  color: #303133;
+}
+.info-label {
+  display: inline-block;
+  width: 100px;
+  color: #606266;
+  font-weight: 500;
+}
+.info-value {
+  color: #303133;
+  word-break: break-all;
+}
+.form-value {
+  color: #303133;
+  white-space: pre-wrap;
+}
+.qa-list {
+  display: flex;
+  flex-direction: column;
+  gap: 10px;
+}
+.qa-item {
+  display: flex;
+  align-items: baseline;
+  font-size: 14px;
+}
+.qa-title {
+  width: 45%;
+  color: #606266;
+  font-weight: 500;
+}
+.qa-answer {
+  width: 55%;
+  color: #409EFF;
+  font-weight: normal;
+}
+.el-row {
+  margin-bottom: 6px;
+}
+</style>

+ 10 - 0
src/views/hisStore/components/productOrder.vue

@@ -346,6 +346,8 @@
             </template>
           </el-table-column>
         </el-table>
+        <!-- 医生完善信息 -->
+        <order-doctor-advice v-if="order!=null" :order-code="order.orderCode" />
       </el-card>
     </div>
 
@@ -523,9 +525,17 @@ import {
   getStoreOrderPhone,
   updateAddressErpFsStoreOrder
 } from "@/api/hisStore/storeOrder";
+import OrderDoctorAdvice from "./OrderDoctorAdvice.vue";
 import { getTcmScheduleList } from "@/api/company/schedule";
 export default {
   name: "order",
+  components: {OrderDoctorAdvice},
+  props: {
+    orderCode: {
+      type: String,
+      default: ''
+    }
+  },
   data() {
     return {
       dialogVisibleImage: false,