Browse Source

完善医院反馈

hurixing 7 months ago
parent
commit
883c98399f

+ 2 - 0
package.json

@@ -30,7 +30,9 @@
     "qrcode": "^1.5.4",
     "qrcodejs2": "^0.0.2",
     "save": "^2.9.0",
+    "sockjs-client": "^1.6.1",
     "sortablejs": "1.10.2",
+    "stompjs": "^2.3.3",
     "tcplayer.js": "^5.0.1",
     "tim-js-sdk": "^2.27.5",
     "tim-profanity-filter-plugin": "^0.9.0",

+ 2 - 2
src/api/comboMeal/index.js

@@ -35,9 +35,9 @@ export function del(query) {
   })
   }
 
-export function tencentLearnPackage() {
+export function tencentLearnPackage(doctorId) {
   return request({
-    url: `/learn/package/tencent/learnPackage`,
+    url: `/learn/package/tencent/learnPackage?doctorId=${doctorId}`,
     method: 'post'
   })
 }

+ 18 - 0
src/api/patient/index.js

@@ -271,4 +271,22 @@ export function wXTencentPhoneSave(query) {
     method: 'post',
     data: query
   })
+}
+
+
+export function updatePadNo(query) {
+  return request({
+    url: `/patient/updatePadNo`,
+    method: 'post',
+    data: query
+  })
+}
+
+
+export function saveSummingUp(query) {
+  return request({
+    url: "reviewTask/saveSummingUp",
+    method: 'post',
+    data: query
+  })
 }

+ 7 - 0
src/api/wx/applicationBlank/index.js

@@ -23,4 +23,11 @@ export function updatePayStatusFulfill(id) {
     url: '/wx/application/blank/update/payStatusFulfill/' + id,
     method: 'get'
   })
+}
+
+export function succeedMessage() {
+  return request({
+    url: '/wx/application/blank/succeed/message',
+    method: 'get'
+  })
 }

BIN
src/assets/images/message-red.png


BIN
src/assets/images/message.png


+ 103 - 1
src/layout/components/Navbar.vue

@@ -8,6 +8,22 @@
 
     <div class="right-menu">
 
+      <el-dropdown class="message-badge" trigger="click">
+
+        <el-dropdown-menu></el-dropdown-menu>
+
+        <div 
+          class="message-icon"
+          :class="{
+            'connected': connectionStatus === 'connected',
+            'disconnected': connectionStatus === 'disconnected',
+          }"
+          @click="handleMessageClick"
+        >
+         
+        </div>
+      </el-dropdown>
+
       <el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
         <div class="avatar-wrapper">
           <div class="dot" :class="{ 'active': isActive }"></div>
@@ -47,7 +63,6 @@
       @mouseenter="showQR = true"
       @mouseleave="destroyQRCode"
     ></div>
-
   </div>
 </template>
 
@@ -60,6 +75,8 @@ import { getUserSign, } from '@/api/onLineChat/index'
 import { getInfo } from '@/api/login'
 import QRCode from 'qrcodejs2';
 import { getUserProfile } from "@/api/system/user";
+import { succeedMessage } from "@/api/wx/applicationBlank";
+import {connectWebSocket,disconnectWebSocket} from "@/utils/websocket"
 export default {
   components: {
     Breadcrumb,
@@ -68,11 +85,14 @@ export default {
   },
   data() {
     return {
+      dialogVisible: true,
       isActive: false,  // 根据状态设置 isActive 的值
       showQR: false,
       qrcodeInstance: null,
       triggerRect: null,
       doctorId: "",
+      connectionStatus: 'disconnected',
+      // hasNewMessages: false
     };
   },
   computed: {
@@ -91,11 +111,39 @@ export default {
   created() {
     this.isActive = this.$store.getters.info.isOnline == 0
     this.getUser()
+    // this.linkWebSocket() // 连接websocket
+    this.succeedMessage2()
   },
   beforeDestroy() {
     this.destroyQRCode();
+    disconnectWebSocket(); // 组件销毁时断开连接
   },
   methods: {
+    succeedMessage2() {
+      succeedMessage().then(resp=>{
+        if(resp.data) {
+          this.connectionStatus = 'disconnected';
+        }else{
+          this.connectionStatus = 'connected';
+        }
+      })
+    },
+    handleMessageClick(){
+      this.succeedMessage2()
+    },
+    // 连接weosoke
+    // linkWebSocket() {
+    //   connectWebSocket("new-orders",
+    //     (message) => { // 连接成功回调
+    //       this.connectionStatus = 'connected';
+    //       console.log("连接成功", message);
+    //     },
+    //     () => { // 消息接收回调
+    //       this.hasNewMessages = true;
+    //       // 这里可以添加消息处理逻辑
+    //     }
+    //   );
+    // },
     async handleDownloadClick(event) {
       try {
         await this.$nextTick() // 确保二维码渲染完成
@@ -315,6 +363,60 @@ export default {
   pointer-events: auto; /* 允许内部交互 */
 }
 
+// .message-count-badge {
+//   position: absolute;
+//   top: -6px;
+//   right: 2px;
+//   background-color: #f56c6c;
+//   color: #fff;
+//   border-radius: 10px;
+//   padding: 0 5px;
+//   font-size: 12px;
+//   height: 16px;
+//   line-height: 16px;
+//   text-align: center;
+//   min-width: 16px;
+// }
+
+.message-icon {
+  width: 40px;
+  height: 40px;
+  position: relative;
+  cursor: pointer;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background-size: cover;
+  background-repeat: no-repeat;
+}
+
+        .message-icon.connected {
+            // color: #48bb78; 
+            // background: #f0fff4;
+            background-image: url('~@/assets/images/message.png');
+        }
+        
+        .message-icon.disconnected {
+            // color: #5a5e66;
+            // background: #f5f7fa;
+            background-image: url('~@/assets/images/message-red.png');
+        }
+        
+        
+        // .message-dot {
+        //     position: absolute;
+        //     top: 10px;
+        //     right: 10px;
+        //     width: 12px;
+        //     height: 12px;
+        //     border-radius: 50%;
+        //     background-color: red; /* 默认红色 */
+        // }
+
+// .message-icon:hover {
+//   color: #1890ff;
+// }
+
 
 .navbar {
   height: 50px;

+ 34 - 0
src/utils/websocket.js

@@ -0,0 +1,34 @@
+import SockJS from "sockjs-client/dist/sockjs";
+import Stomp from "stompjs";
+
+let stompClient = null;
+
+// 连接
+export function connectWebSocket(type, notifyCallback, listRefreshCallback) {
+  const socket = new SockJS("http://192.168.0.118:8111/ws-notification");
+  stompClient = Stomp.over(socket);
+
+  stompClient.connect({}, () => {
+    // 订阅新订单
+    if (type === "new-orders") {
+      stompClient.subscribe("/topic/new-orders", (message) => {
+        notifyCallback(message.body);
+        listRefreshCallback();
+      });
+    }
+    if (type === "return-orders") {
+      // 订阅退单
+      stompClient.subscribe("/topic/return-orders", (message) => {
+        notifyCallback(message.body);
+        listRefreshCallback();
+      });
+    }
+  });
+}
+
+// 关闭连接
+export function disconnectWebSocket() {
+  if (stompClient !== null) {
+    stompClient.disconnect();
+  }
+}

+ 23 - 15
src/views/officialAccounts/pay/index.vue

@@ -106,7 +106,7 @@ export default {
     }
   },
   created() {
-    this.getLearnPackage()
+    this.getValue()
   },
   // async mounted() {
   //   try {
@@ -117,8 +117,26 @@ export default {
   //   }
   // },
   methods: {
-    getLearnPackage(){
-        tencentLearnPackage().then(resp=>{
+    getValue(){
+            if(Object.keys(this.$route.query).length > 0){
+                const query = this.$route.query;
+                // this.WxTencentForm = JSON.parse(symmetryDecryptWX(decodeURIComponent(this.$route.query.userInfo)));
+                if(query.code  && query.state && query.payUser){
+                    const payUser = JSON.parse(symmetryDecryptWX(query.payUser))
+                    this.getLearnPackage(payUser.doctorId)
+                    console.log("2")
+                    this.handleSubmit(query.code,payUser.packageId,query.state,payUser.doctorId,payUser.mobile);
+                }
+                if(query.doctorId) {
+                  console.log("1")
+                  this.getLearnPackage(query.doctorId)
+                }
+                this.WxTencentForm.equipmentPledge = 1
+            }
+    },
+    getLearnPackage(doctorId){
+      tencentLearnPackage(doctorId).then(resp=>{
+            this.packages = []
             this.packages = resp.data.map(item => {
                 const newItem = { ...item }; // 创建新对象
                 switch (newItem.timeType) {
@@ -136,18 +154,8 @@ export default {
                         break;
                 }
                 return newItem;
-            });
-            if(Object.keys(this.$route.query).length > 0){
-                const query = this.$route.query;
-                // this.WxTencentForm = JSON.parse(symmetryDecryptWX(decodeURIComponent(this.$route.query.userInfo)));
-                if(query.code  && query.state && query.payUser){
-                    const payUser = JSON.parse(symmetryDecryptWX(query.payUser))
-                    console.log(payUser)
-                    this.handleSubmit(query.code,payUser.packageId,query.state,payUser.doctorId,payUser.mobile);
-                }
-                this.WxTencentForm.equipmentPledge = 1
-            }
-        })
+            })
+      })
     },
     formatPrice(price) {
       return (price / 100).toFixed(2)

+ 4 - 0
src/views/patient/add/index.vue

@@ -50,6 +50,10 @@
               </el-select>
             </el-form-item>
 
+            <el-form-item prop="remark" label="备注">
+              <el-input v-model.trim="form.remark" maxlength="110"/>
+            </el-form-item>
+
           </el-col>
         </el-row>
         <div style="margin-top: 20px;">

+ 760 - 0
src/views/patient/addTwo/index2.vue

@@ -0,0 +1,760 @@
+<template>
+  <div class="app-container">
+    <el-drawer title="详情" :visible.sync="drawer" :before-close="close" size="60%" destroy-on-close>
+      <el-form ref="form" :model="form" :rules="rules" label-width="120px" style="padding: 0 20px;">
+        <!-- 第二页 -->
+        <div v-if="next == '2'">
+          <el-row :gutter="24">
+            <el-col :span="3" style="display: flex;">
+              <div class="titles" style="  margin-top: 6px;">训练套餐</div>
+            </el-col>
+            <el-col :span="21" style="display: flex;">
+              <div class="item" style="flex: 1;">
+                <div v-for="item in packageData" :class="form.packageId == item.id ? 'item_box boxActive' : 'item_box'" 
+                  @click="changeRadio(item, 'packageId')">
+                  {{ item.packageName }}
+                </div>
+              </div>
+            </el-col>
+          </el-row>
+          <el-row :gutter="24" v-if="form.packageId">
+            <el-col :span="3" style="display: flex;">
+              <div class="titles" style=" ">训练套餐金额</div>
+            </el-col>
+            <el-col :span="6" style="display: flex;padding-left: 30px;">
+              {{ packageItem.priceYUAN }} 元
+            </el-col>
+          </el-row>
+          <el-row :gutter="24">
+            <el-col :span="3" style="display: flex;">
+              <div class="titles">训练时间</div>
+            </el-col>
+            <el-col :span="6" style="margin-left: -100px;">
+              <el-form-item prop="StartEndTime" label="">
+                <el-date-picker v-model="form.StartEndTime" type="daterange" disabled range-separator="至"
+                  start-placeholder="开始日期" end-placeholder="结束日期">
+                </el-date-picker>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="24">
+            <el-col :span="3" style="display: flex;">
+            </el-col>
+            <el-col :span="6" style="display: flex;">
+              <div class="titles" style="  margin-right: 40px;">是否租赁设备</div>
+              <el-switch v-model="isequipmentPledge" @change="handleSwitch" style="padding-top: 4px;"
+                :disabled="oldVal.padNo ? true : false">
+              </el-switch>
+            </el-col>
+            <el-col :span="6" style="margin-left: -124px;">
+              <el-form-item prop="equipmentPledgeYUAN">
+                <el-input-number v-if="isequipmentPledge" :min="0" :max="9999999" :precision="2"
+                  v-model.trim="form.equipmentPledgeYUAN" style="width: 200px;" placeholder="请输入押金金额" maxlength="20"
+                  :disabled="oldVal.padNo ? true : false" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+         
+          <!-- <div style="margin-top: 20px;"> -->
+
+          <el-row :gutter="24" v-if="isequipmentPledge">
+            <el-col :span="3" style="display: flex;">
+              <div class="titles">设备编号</div>
+            </el-col>
+            <el-col :span="6" style="display: flex;">
+              <el-form-item label="" prop="padNo">
+                <!-- <el-input style="margin-left:-100px;width:200px" v-model.trim="form.padNo" placeholder="请输入设备编号" /> -->
+                <el-select filterable style="margin-left:-100px;width:200px" v-model="form.padNo" placeholder="请输入设备编号"
+                  :disabled="oldVal.padNo ? true : false">
+                  <el-option v-for="item in padList" :key="item.sn" :label="item.sn" :value="item.sn">
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="24" v-if="isequipmentPledge">
+            <el-col :span="3" style="display: flex;">
+              <div class="titles">服务协议</div>
+            </el-col>
+            <el-col :span="10" style="margin-left:-80px ;">
+              <el-form-item label="">
+                <el-checkbox style="margin-right:20px;" v-model="xychecked">我已阅读此协议 <el-link type="primary"
+                    style="vertical-align: top;" @click.stop="handelXy">服务协议</el-link></el-checkbox>
+
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <div style="width: 100%; height: 1px; background-color: #ccc; margin: 20px 0;"></div>
+          <el-row :gutter="24">
+            <el-col :span="8">
+              <el-form-item label="指导人姓名" prop="mentor">
+                <el-input v-model.trim="form.mentor" style="width:200px" placeholder="请输入指导人姓名" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+
+              <el-form-item label="开单医生" prop="doctorId">
+                <el-select v-model="form.doctorId" style="width:200px" placeholder="请选择" @change="handelDoctor">
+                  <el-option v-for="item in doctorData" :key="item.id" :label="item.label" :value="item.value">
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="24">
+            <el-col :span="8">
+              <el-form-item label="患者来源" prop="patientSource">
+                <el-select v-model="form.patientSource" style="width:200px" placeholder="请选择">
+                  <el-option v-for="item in dict.type.patient_source" :key="item.value" :label="item.label"
+                    :value="item.value">
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+
+              <el-form-item label="所在科室" prop="hospitalDepartment">
+                <el-select v-model="form.hospitalDepartment" style="width:200px" placeholder="请选择" @change="handelDno">
+                  <el-option v-for="item in department" :key="item.value" :label="item.label" :value="item.value">
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="24">
+            <el-col :span="24">
+              <el-form-item label="指导人备注" prop="mentorRemark">
+                <el-input v-model.trim="form.mentorRemark" resize="none" type="textarea" style="width:636px"
+                  placeholder="请输入指导人备注" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </div>
+
+        <div style="display: flex;">
+          <!-- <div class="btn syb" @click="handelnshang" v-if="next != '1'">上一步</div> -->
+          <div class="btn" @click="handelnNext"> 保存</div>
+          <div class="btn bc" @click="handelPay">支付
+          </div>
+        </div>
+      </el-form>
+      <!-- 租赁协议 -->
+
+      <div style="height: 20px; width: 100%;"></div>
+    </el-drawer>
+    <el-dialog title="支付" :visible.sync="dialogVisible" width="40%" :before-close="handleClose" destroy-on-close :close-on-click-modal="false">
+      <div style="margin: 0 auto; text-align: center;">
+        <el-radio-group v-model="form.payMethod" @input="payChange">
+          <!-- <el-radio v-for="item in dict.type.pay_method" :label="item.value" :key="item.value" border>
+            <img src="@/assets/images/icon_pay1.png" style="width: 16px; height: 16px; vertical-align: sub;"
+              v-if="item.value == '1'" />
+            <img src="@/assets/images/icon_pay2.png" style="width: 16px; height: 16px; vertical-align: sub;"
+              v-if="item.value == '2'" />
+            {{ item.label }}</el-radio> -->
+          <el-radio label="1" key="1" border>
+            <img src="@/assets/images/icon_pay1.png" style="width: 16px; height: 16px; vertical-align: sub;"/>微信
+          </el-radio>
+        </el-radio-group>
+      </div>
+      <div class="code">
+        <div id="qrCode" ref="qrCodeDiv"></div>
+      </div>
+      <div style="margin-top: 40px; ">
+       
+        <div class="titles" style="text-align: left;">
+          <span style="display: inline-block; margin-left: 70px;">支付金额 </span>
+          <span
+            style="color: red; font-weight: 600; font-size: 18px; vertical-align: middle; display: inline-block; margin-left: 10px;">¥{{
+              payMoney / 100 }}</span>
+          <p style=" margin-left: 70px; font-weight: normal;"> <span style="font-weight: bold;">套餐描述</span> :{{
+            packageName }} </p>
+          <p style="line-height: 20px; margin-left: 70px; font-weight: normal;"> <span
+              style="font-weight: bold;">订单描述</span> :{{ description }} </p>
+          <!-- <p style="line-height: 40px; margin-left: 70px; font-weight: normal;"> <span
+                style="font-weight: bold;">套餐描述</span> :{{ packageName }} </p> -->
+        </div>
+        <!-- <div style="margin-left: 40px; margin-top: -18px;text-align: left;">
+            <p style="color: red; font-weight: 600; font-size: 20px;">¥{{ payMoney / 100 }}</p>
+          </div> -->
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="handleClose">取消支付</el-button>
+        <el-button type="primary" @click="handleOk">完成支付</el-button>
+      </span>
+    </el-dialog>
+    <el-dialog title="服务协议" :visible.sync="xyOpen" width="60%">
+      <div style="height: 68vh; overflow-x: hidden;">
+        <xy />
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="xyOpen = false">关 闭</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import QRCode from 'qrcodejs2';
+import xy from './xy.vue';
+import { listData as equipmentList } from "@/api/equipment/index";
+import { patientSave, learnSelectAll, selectDoctor, departmentList, createPreOrder, delPayOrder, selectPayResult, findPayParam, selectAllDoctorByDno } from '@/api/patient/index'
+export default {
+  dicts: ['equipment_class', 'education_type', 'dict_sex', 'medical_his_type', 'medical_current_type', 'diagnose_result_type', 'career', 'game_type', 'genetic_disease', 'department', 'patient_source', 'pay_status', 'pay_method'],
+  name: 'add_patient',
+  components: {
+    xy
+  },
+  data() {
+    return {
+      form: {
+        medicalCurrentTypes: [],
+        medicalHisTypes: [],
+        geneticDiseases: [],
+        diagnoseResultType: [],
+        tags: [],
+        packageId: undefined,
+        payMethod: '1',
+        equipmentPledgeYUAN: 1200,
+      },
+      packageItem: {
+        priceYUAN: 0
+      },
+      rules: {
+        padNo: [{ required: true, message: "设备编号不能为空" }],
+        education: [{ required: true, message: "教育程度不能为空" }],
+        occupation: [{ required: true, message: "职业不能为空" }],
+        equipmentPledgeYUAN: [{ required: true, message: "押金不能为空" }],
+        mentor: [{ required: true, message: "指导人不能为空" }],
+        mentorRemark: [{ required: true, message: "指导人备注不能为空" }],
+        patientSource: [{ required: true, message: "患者来源不能为空" }],
+        hospitalDepartment: [{ required: true, message: "所在科室不能为空" }],
+        doctorId: [{ required: true, message: "开单医生不能为空" }],
+        mentorMobile: [
+          { required: true, message: "手机号不能为空", trigger: "blur" },
+          {
+            pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
+            message: "请输入正确的手机号码",
+            trigger: "blur"
+          }
+        ],
+        // padNo: [{ required: true, message: "设备不能为空" }],
+      },
+      packageData: [],
+      next: '2',
+      isequipmentPledge: true,
+      doctorData: [],
+      description: '',
+      packageName: '',
+      payMoney: 0,
+      dialogVisible: false,
+      orderNo: '',
+      isEdit: '1',
+      padList: [],
+      xychecked: false,
+      xyOpen: false,
+      userId: '',
+      oldVal: {},
+      isShowPay: false,
+      isShowPay1: false,
+      drawer: false,
+      department: [],
+      orderType: '',
+      Sencond: 120,
+    };
+  },
+  beforeDestroy() {
+    window.removeEventListener('beforeunload', this.beforeUnload);
+
+  },
+  mounted() {
+    window.addEventListener('beforeunload', this.beforeUnload);
+  },
+
+  methods: {
+    beforeUnload(e) {
+      this.handleClose()
+      const confirmationMessage = "确定要离开此页面吗?未保存的数据将会丢失。";
+      e.returnValue = confirmationMessage;
+      return confirmationMessage;
+    },
+    // 打开
+    open(e) {
+      if (e) {
+        let obj = JSON.parse(e);
+        obj.packageId = undefined
+        this.xychecked = true
+        if (obj.orderStartTime) {
+          obj.StartEndTime = [obj.orderStartTime, obj.orderEndTime]
+        } else {
+          obj.StartEndTime = []
+        }
+        obj.medicalCurrentTypes = obj.medicalCurrentTypes ? obj.medicalCurrentTypes.split(',') : []
+        obj.medicalHisTypes = obj.medicalHisTypes ? obj.medicalHisTypes.split(',') : []
+        obj.geneticDiseases = obj.geneticDiseases ? obj.geneticDiseases.split(',') : []
+        obj.diagnoseResultType = obj.diagnoseResult ? obj.diagnoseResult.split(',') : []
+        obj.tags = obj.tags ? obj.tags.split(',') : []
+        this.isequipmentPledge = obj.equipmentPledgeYUAN > 0 ? true : false
+        if (obj.equipmentPledgeYUAN && obj.packageId) {
+          this.isShowPay1 = true
+        } else {
+          this.isShowPay1 = false
+        }
+        this.oldVal = JSON.parse(JSON.stringify(obj))
+        this.form = obj
+        this.form.payMethod='1'
+        this.userId = obj.id
+        this.isEdit = '1'
+      }
+      this.getlearnSelectAll()
+      this.handleGetEquipmentList()
+      this.getdepartmentList()
+      this.drawer = true
+    },
+    close() {
+      this.drawer = false
+      this.$emit('shuaxin')
+    },
+    /**获取科室 */
+    getdepartmentList() {
+      departmentList().then(res => {
+        this.department = res.data.map((item) => {
+          return {
+            value: item.id,
+            label: item.departmentName
+          }
+        })
+      })
+    },
+    handleGetEquipmentList() {
+      equipmentList({ page: 1, limit: 99999999, status: 'A', equipmentType: 'A' }).then(res => {
+        this.padList = res.data.records.map(item => {
+          return {
+            ...item,
+            label: this.dict.type.equipment_class.map(t => {
+              if (t.value == item.equipmentType) {
+                return t.label
+              }
+            }).filter(item => item).join('')
+          }
+        })
+      })
+    },
+    handleSwitch(e) {
+      this.form.equipmentPledgeYUAN = e ? 1200 : 0
+      if (!this.isequipmentPledge) {
+        if (e) {
+          this.isShowPay1 = true
+        }
+      } else {
+        this.isShowPay1 = false
+      }
+    },
+    //** 获取套餐数据 */
+    getlearnSelectAll() {
+      learnSelectAll(this.form).then(res => {
+        this.packageData = res.data
+        if (this.isEdit == '1') {
+          res.data.forEach(item => {
+            if (item.id == this.form.packageId) {
+              this.packageItem = item
+            }
+          })
+
+        }
+      })
+      selectDoctor({ id: '' }).then(res => {
+        this.doctorData = res.data.map((item) => {
+          return {
+            label: item.userName,
+            value: item.id,
+            departmentName: item.departmentName
+          }
+        })
+      })
+    },
+    /** 切换box */
+    changeBox(item, key) {
+      // 判断数组中是否存在该值
+      if (this.form[key].includes(item.value)) {
+        // 如果存在,则从数组中移除该值
+        this.form[key].splice(this.form[key].indexOf(item.value), 1);
+      } else {
+        // 如果不存在,则将该值添加到数组中
+        this.form[key].push(item.value);
+      }
+    },
+    /** 切换box单选 */
+    changeRadio(item, key) {
+      if (this.isEdit == '1' && this.form.packageId != undefined && this.oldVal.packageId) {
+        this.$alert('请先退掉当前套餐,才能切换套餐', '提示', {
+          confirmButtonText: '确定',
+          callback: action => {
+          }
+        });
+        return
+      } else {
+        if (this.form[key] == item.id) {
+          this.form[key] = undefined
+          this.form.StartEndTime = []
+        } else {
+          this.form[key] = item.id
+          if(this.oldVal.orderEndTime !== ''){
+            const end = new Date(this.oldVal.orderEndTime);
+            end.setDate(end.getDate() + 1);
+            if(end >= new Date()){
+              item.startTime = this.formatDate(end)
+              const start = new Date(item.startTime)
+              start.setDate(start.getDate() + item.days)
+              item.endTime = this.formatDate(start)
+            }
+          }
+          this.form.StartEndTime = [item.startTime, item.endTime]
+          this.packageItem = item
+          this.isShowPay = false
+        }
+      }
+
+    },
+    // 日期格式化方法
+    formatDate(date) {
+      const year = date.getFullYear();
+      const month = String(date.getMonth() + 1).padStart(2, '0');
+      const day = String(date.getDate()).padStart(2, '0');
+      return `${year}-${month}-${day}`;
+    },
+    /**下一步 */
+    handelnNext() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          this.form.medicalCurrentTypes = this.form.medicalCurrentTypes.toString()
+          this.form.medicalHisTypes = this.form.medicalHisTypes.toString()
+          this.form.geneticDiseases = this.form.geneticDiseases.toString()
+          this.form.tags = this.form.tags.toString()
+          this.form.diagnoseResult = this.form.diagnoseResultType.toString()
+          if (this.next == '2') {
+            // if (!this.form.packageId) {
+            //   this.$modal.msgWarning(`请选择训练套餐!!`);
+            //   return
+            // }
+            if (!this.isequipmentPledge) {
+              this.form.equipmentPledge = 0
+            }
+            if (this.isequipmentPledge && !this.xychecked) {
+              this.$modal.msgError(`请先阅读协议`);
+              return
+            }
+            this.form.orderStartTime = this.form.StartEndTime ? this.form.StartEndTime[0] : this.form.orderStartTime
+            this.form.orderEndTime = this.form.StartEndTime ? this.form.StartEndTime[1] : this.form.orderEndTime
+            patientSave(this.form).then(res => {
+              this.isShowPay = true
+              this.userId = res.data
+              this.form.id = res.data
+              if (this.isEdit == '1') {
+                this.$modal.msgSuccess(`修改成功`);
+                // let visitedViews = this.$store.state.tagsView.visitedViews
+                // this.$store.state.tagsView.visitedViews.map((item) => {
+                //   if (item.title == '维护患者') {
+                //     this.$tab.closePage(item).then(({ visitedViews }) => {
+                //       if (this.isActive(item)) {
+                //         this.toLastView(visitedViews, item)
+                //       }
+                //     })
+                //   }
+                // })
+                // this.$router.push('/patient/list');
+                // window.close();
+                return
+              } else {
+                this.$modal.msgSuccess(`添加成功`);
+              }
+            })
+          }
+        } else {
+          //当验证失败跳转到空白的所在区域
+          this.$nextTick(() => {
+            let isError = document.getElementsByClassName("is-error");
+            // var a = $(isError[0]).find("input") //this.$refs.cmd.$el.querySelector('input') 
+            // a.focus()  光标定位到所在input
+            isError[0].scrollIntoView({
+              // 滚动到指定节点
+              // 值有start,center,end,nearest
+              block: "center",
+              // 值有auto、instant,smooth,缓动动画
+              behavior: "smooth",
+            });
+          });
+          return false;
+        }
+      });
+
+    },
+    payChange(e) {
+      this.form.payMethod=e
+      this.payData.payMethod=e
+      this.$refs.qrCodeDiv.innerHTML = '' // 刷新时清空原二维码
+      createPreOrder(this.payData).then(res => {
+        this.orderNo = res.data.orderNo
+        new QRCode(this.$refs.qrCodeDiv, {
+          text: res.data.qrCode,
+          width: 200,
+          height: 200,
+          colorDark: "#333333", //二维码颜色
+          colorLight: "#ffffff", //二维码背景色
+          correctLevel: QRCode.CorrectLevel.L//容错率,L/M/H
+        })
+      })
+    },
+    handleClose() {
+      delPayOrder({ orderNo: this.orderNo, userId: this.userId, orderType: this.orderType }).then(res => {
+        this.dialogVisible = false
+      })
+    },
+    handleOk() {
+      selectPayResult(this.orderNo).then(res => {
+        if (res.data == '2') {
+          this.$modal.msgSuccess('支付成功');
+          let visitedViews = this.$store.state.tagsView.visitedViews
+          this.$store.state.tagsView.visitedViews.map((item) => {
+            if (item.title == '维护患者') {
+              this.$tab.closePage(item).then(({ visitedViews }) => {
+                if (this.isActive(item)) {
+                  this.toLastView(visitedViews, item)
+                }
+              })
+            }
+          })
+
+          this.$router.push('/patient/list');
+          window.close();
+          this.dialogVisible = false
+        } else {
+          this.dict.type.pay_status.map((item) => {
+            if (item.value == res.data) {
+              this.$modal.msgError(item.label);
+            }
+          })
+        }
+      })
+    },
+    // 获取出生日期
+    getBirthDate() {
+      // this.$refs["form"].validateField('idCard',valid => {
+      // })
+      if (this.form.idCard.length == 18) {
+        this.form.birthDate = this.form.idCard.substring(6, 10) + "-" + this.form.idCard.substring(10, 12) + "-" + this.form.idCard.substring(12, 14)
+        this.form.age = this.calculateAge(this.form.idCard)
+      }
+    },
+    // 获取年龄
+    calculateAge(iden) {
+      if (iden.length == 18) {
+        let ye = iden.substring(6, 10)
+        let date = new Date();
+        let year = date.getFullYear();
+        return year - ye
+      }
+    },
+    handelXy() {
+      this.xyOpen = true
+      this.xychecked = true
+    },
+    // 选择医生
+    handelDoctor(e) {
+      this.doctorData.map((item) => {
+        if (item.value == e) {
+          this.form.hospitalDepartment = item.departmentName
+        }
+      })
+    },
+    // 根据科室获取医生
+    handelDno(e) {
+      this.form.doctorId = undefined
+      selectDoctor({ id: e }).then(res => {
+        this.doctorData = res.data.map((item) => {
+          return {
+            label: item.userName,
+            value: item.id,
+            departmentName: item.departmentName
+          }
+        })
+      })
+    },
+    handelPay() {
+      if (this.userId == '') {
+        this.$modal.msgError('请先保存信息')
+        return
+      }
+      /** if(this.form.packageId === '' || this.form.packageId === null || this.form.packageId === undefined){
+        this.$modal.msgError('请选择套餐')
+        return
+      }
+
+      if (this.isequipmentPledge !== true) {
+        this.$modal.msgError('请选择租赁的设备')
+        return
+      } */
+
+      let orderType = ''
+      if (this.isequipmentPledge) {
+        if(this.oldVal.padNo){
+          orderType=''
+        }else{
+          orderType = 'A'
+        }
+      }
+      if (this.form.packageId != this.oldVal.packageId) {
+        if (this.isequipmentPledge) {
+          if(this.oldVal.padNo){
+            orderType = 'B'
+          }else{
+            orderType = 'A,B'
+          }
+        } else {
+          orderType = 'B'
+        }
+      }
+      if (this.form.equipmentPledgeYUAN != this.oldVal.equipmentPledgeYUAN) {
+        orderType = 'A'
+      }
+      if (this.form.equipmentPledgeYUAN != this.oldVal.equipmentPledgeYUAN && this.form.packageId != this.oldVal.packageId) {
+        orderType = 'A,B'
+      }
+      this.orderType = orderType
+      const params = {
+        userId: this.userId,
+        orderType,
+        padNo: this.form.padNo,
+        packageId: this.form.packageId,
+        packageName: this.packageItem.packageName,
+        equipmentPledge: this.isequipmentPledge ? this.form.equipmentPledgeYUAN : undefined,
+        orderStartTime: this.form.StartEndTime ? this.form.StartEndTime[0] : this.form.orderStartTime,
+        orderEndTime: this.form.StartEndTime ? this.form.StartEndTime[1] : this.form.orderEndTime,
+      }
+      if (this.isequipmentPledge && !this.form.padNo) {
+        this.$modal.msgError('请选择设备')
+        return
+      }
+      if(orderType==''){
+        this.$modal.msgError('暂无支付项目')
+        return
+      }
+      findPayParam(params).then(res => {
+        this.payMoney = res.data.payMoney
+        this.description = res.data.description
+        this.packageName = res.data.packageName
+        const data = {
+          orderType: res.data.packageType,
+          relationId: res.data.relationId,
+          payMoney: res.data.payMoney,
+          payMethod: this.form.payMethod,
+          description: res.data.description,
+          userId: this.userId,
+          userName: res.data.userName,
+          orgCode: res.data.orgCode,
+          orgName: res.data.orgName,
+          padNo: this.form.padNo,
+          packageId: this.form.packageId,
+          equipmentPledge: this.isequipmentPledge ? this.form.equipmentPledgeYUAN : undefined,
+        }
+        this.payData = data
+        this.dialogVisible = true
+        createPreOrder(data).then(res1 => {
+          this.getSencond()
+          this.orderNo = res1.data.orderNo
+          new QRCode(this.$refs.qrCodeDiv, {
+            text: res1.data.qrCode,
+            width: 200,
+            height: 200,
+            colorDark: "#333333", //二维码颜色
+            colorLight: "#ffffff", //二维码背景色
+            correctLevel: QRCode.CorrectLevel.L//容错率,L/M/H
+          })
+        })
+      })
+    },
+    getSencond() {
+      const that = this
+      const interval = window.setInterval(function () {
+        --that.Sencond
+        if (that.Sencond === 0) {
+          window.clearInterval(interval)
+          that.handleClose()
+        }
+      }, 1000)
+    }
+  }
+};
+</script>
+<style lang="scss" scoped>
+.titles {
+  // font-size: 20px;
+  font-weight: 600;
+  color: #606266;
+  padding-bottom: 20px;
+  text-align: left;
+  font-size: 14px;
+}
+
+.item {
+  display: flex;
+  flex-flow: row wrap;
+
+  .item_box {
+    width: 140px;
+    height: 40px;
+    line-height: 40px;
+    border-radius: 8px;
+    border: 1px solid #979797;
+    text-align: center;
+    cursor: pointer;
+    margin-left: 20px;
+    margin-bottom: 20px;
+    user-select: none;
+    font-size: 14px;
+    overflow: hidden;
+  }
+
+  .boxActive {
+    border: 1px solid #2A55FF !important;
+    background: #2A55FF;
+    color: #fff;
+  }
+}
+
+.btn {
+  width: 300px;
+  height: 44px;
+  line-height: 44px;
+  background: #2A55FF;
+  border-radius: 8px;
+  margin: 0 auto;
+  text-align: center;
+  color: #fff;
+  cursor: pointer;
+  margin-top: 20px;
+}
+
+.code {
+  width: 200px;
+  height: 200px;
+  // background-color: red;
+  margin: 0 auto;
+  margin-top: 20px;
+}
+
+.el-form-item--medium .el-form-item__label {
+  font-weight: 600 !important;
+  color: #333333 !important;
+  font-size: 16px !important;
+}
+
+.syb {
+  background-color: #fff !important;
+  color: #333 !important;
+  border: 1px solid #333;
+}
+
+.bc {
+  background-color: #67c23a !important;
+}
+</style>

+ 34 - 8
src/views/patient/list/cePingInfo.vue

@@ -174,19 +174,21 @@
       </span>
     </el-dialog>
 
-    <el-dialog title="" :visible.sync="printIsShow" width="40%" center>
-      <mmse-print-vue :defaultVal="defaultVal" :reviewPrint="reviewPrint" :reviewTime="reviewTime" v-if="currentPrintComponent === 'MMSE'"/>
-      <moca-print-vue :defaultVal="defaultVal" :reviewPrint="reviewPrint" :reviewTime="reviewTime" v-if="currentPrintComponent === 'MOCA'"/>
+    <el-dialog title="" :visible.sync="printIsShow" width="40%" center :before-close="handleCloseAA">
+      <mmse-print-vue :defaultVal="defaultVal" :reviewPrint="reviewPrint" :reviewTime="reviewTime" :conclusionShow="conclusionShow" v-if="currentPrintComponent === 'MMSE'"/>
+      <moca-print-vue :defaultVal="defaultVal" :reviewPrint="reviewPrint" :reviewTime="reviewTime" :conclusionShow="conclusionShow" v-if="currentPrintComponent === 'MOCA'"/>
+      <el-input v-if="conclusionShow" type="textarea" placeholder="请输入新的结论" v-model="reviewPrint.reviewTasks[0].summingUp" maxlength="50"></el-input>
       <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="editConclusion">{{this.conclusionShow ? "保存" : "编辑结论"}}</el-button>
         <el-button type="warning" @click="printIsShow = false">关闭</el-button>
-        <el-button v-print="'#printMe'" type="primary">打印</el-button>
+        <el-button v-print="'#printMe'" type="primary" v-if="!conclusionShow">打印</el-button>
       </div>
     </el-dialog>
   </div>
 </template>
 
 <script>
-import { printReviewResultDetail,reviewTaskList, findReviewResultDetail, reviewTaskSave, selectAnswerRecord, selectAnswerRecordDetail } from '@/api/patient/index'
+import { printReviewResultDetail,reviewTaskList, findReviewResultDetail, reviewTaskSave, selectAnswerRecord, selectAnswerRecordDetail,saveSummingUp } from '@/api/patient/index'
 import { getDetectInfoList } from '@/api/ea/index'
 import { debounce } from 'lodash-es'
 import mmsePrintVue from './print/mmsePrint.vue'
@@ -223,12 +225,29 @@ export default {
       printIsShow: false,  // 打印预览
       currentPrintComponent: '',
       reviewPrint: {},
-      reviewTime: ""
+      reviewTime: "",
+      conclusionShow: false
     }
   },
   methods: {
+    editConclusion() {
+      if(!this.conclusionShow) {
+        this.conclusionShow = true
+      }else {
+        this.conclusionShow = false
+        if(this.reviewPrint.reviewTasks[0].summingUp == "" || this.reviewPrint.reviewTasks[0].summingUp == undefined) {
+          this.$modal.msgError('结论为空,保存失败')
+        }else {
+          saveSummingUp({id: this.reviewPrint.reviewTasks[0].id,summingUp: this.reviewPrint.reviewTasks[0].summingUp}).then(resp=>{
+            if(resp.data === true) {
+              this.$modal.msgSuccess('保存成功')
+            }
+          })
+        }
+      }
+    },
     getPrintReviewResultDetail(row) {
-      console.log(row)
+      this.conclusionShow = false
       const data = {
         reviewTaskId: row.id,
         userId: row.userId,
@@ -247,7 +266,7 @@ export default {
     },
     
     handleCheckedCitiesChange() {
-      console.log("测试",this.checkedCities)
+      
     },
     evaluationHandleClose(done) {
       this.$confirm('确认关闭?')
@@ -318,6 +337,13 @@ export default {
       this.evaluationDialogVisible = true
       this.checkedCities = ["MMSE","MOCA"]
     },
+    handleCloseAA(done) {
+      this.$confirm('确认关闭?')
+        .then(_ => {
+          done();
+        })
+        .catch(_ => {});
+    },
     // 专业测评
     handelCePing: debounce(function () {
       let that = this

+ 1 - 0
src/views/patient/list/index.vue

@@ -52,6 +52,7 @@
           <dict-tag :options="dict.type.game_difficulty" :value="scope.row.gameDifficulty" />
         </template>
       </el-table-column> -->
+      <el-table-column prop="remark" label="备注"/>
       <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
         <template slot-scope="scope">
           <!-- <el-button size="mini" type="text" @click="handelCePing(scope.row)">专业测评</el-button> -->

+ 15 - 2
src/views/patient/list/print/mmsePrint.vue

@@ -143,8 +143,10 @@
 
                 <div style="text-align: left;">
                     <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: -10px;">  <!-- 减少底部间距 -->
-                        <p style="margin-left: 40px;"><strong>参考结论:</strong>{{patientStatus() === 1 ? '不正确状态': '正确状态'}}</p>
-                        <div style="text-align: right; margin-right: 60px; line-height: 1.2;">  <!-- 调整行距 -->
+                        <p style="margin-left: 40px;"><strong>参考结论:</strong>
+                        <strong v-if="!conclusionShow">{{summingUpValue()}}</strong>
+                        </p>
+                        <div style="text-align: right; margin-right: 60px; line-height: 1.2;width: 300px;">  <!-- 调整行距 -->
                             <p style="margin: 2px 0;"><strong>日期:</strong>{{formatDate(reviewTime)}}</p>  <!-- 压缩段落间距 -->
                             <p style="margin: 2px 0;margin-right: 75px;"><strong>测评师签字:</strong></p>  <!-- 压缩段落间距 -->
                         </div>
@@ -180,6 +182,10 @@ export default {
         reviewTime: {
             type: String,
             required: ''
+        },
+        conclusionShow: {
+            type: Boolean,
+            required: false
         }
     },
     watch:{
@@ -220,6 +226,13 @@ export default {
             // 设置线型图
             this.updatedLineData()
         },
+        summingUpValue (){
+            if(this.reviewPrint.reviewTasks[0].summingUp == "" || this.reviewPrint.reviewTasks[0].summingUp == undefined) {
+                return this.patientStatus() === 1 ? '存在认知功能障碍' : '认知状态正常'
+            }else {
+                return this.reviewPrint.reviewTasks[0].summingUp;
+            }
+        },
         updatedLineData(){
             this.barData1 = this.reviewPrint.reviewTasks.map(task =>{
                 const date = new Date(task.reviewTime);

+ 20 - 4
src/views/patient/list/print/mocaPrint.vue

@@ -183,8 +183,11 @@
 
         <div style="text-align: left;">
             <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: -10px;">  <!-- 减少底部间距 -->
-                <p style="margin-left: 40px;"><strong>参考结论:</strong>{{this.reviewPrint.totalPoints < 26 ? '不正确状态' : '正确状态'}}</p>
-                <div style="text-align: right; margin-right: 60px; line-height: 1.2;">  <!-- 调整行距 -->
+                <p style="margin-left: 40px;"><strong>参考结论:</strong> 
+                  <strong v-if="!conclusionShow">{{summingUpValue()}}</strong>
+                  <!-- this.reviewPrint.totalPoints < 26 ? '不正确状态' : '正确状态' -->
+                </p>
+                <div style="text-align: right; margin-right: 60px; line-height: 1.2;width: 300px;">  <!-- 调整行距 -->
                     <p style="margin: 2px 0;"><strong>日期:</strong>{{formatDate(reviewTime)}}</p>  <!-- 压缩段落间距 -->
                     <p style="margin: 2px 0;margin-right: 75px;"><strong>测评师签字:</strong></p>  <!-- 压缩段落间距 -->
                 </div>
@@ -219,7 +222,11 @@ export default {
         reviewTime: {
             type: String,
             required: ''
-        }
+        },
+        conclusionShow: {
+            type: Boolean,
+            required: false
+        },
     },
     watch:{
         reviewPrint:{
@@ -239,9 +246,18 @@ export default {
         }
     },
     mounted(){
-        this.initMMSE()
+      this.initMMSE()
+    },
+    created() {
     },
     methods: {
+        summingUpValue(){
+          if(this.reviewPrint.reviewTasks[0].summingUp == "" || this.reviewPrint.reviewTasks[0].summingUp == undefined) {
+            return this.reviewPrint.totalPoints < 26 ? '存在认知功能障碍' : '认知状态正常'
+          }else {
+            return this.reviewPrint.reviewTasks[0].summingUp
+          }
+        },
         getLabelForValue(value,educationData) {
             const matchingItem = educationData.find(item => item.value === value);
             return matchingItem ? matchingItem.label : '未知';

+ 38 - 3
src/views/patient/manager/index.vue

@@ -45,6 +45,7 @@
       <el-table-column prop="createTime" label="创建时间"></el-table-column>
       <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
         <template slot-scope="scope">
+          <el-button size="mini" type="text" v-if="scope.row.padNo" @click="handelPadNo(scope.row)">更换设备</el-button>
           <el-button size="mini" type="text" @click="handelEdit(scope.row)">购买套餐</el-button>
           <el-button size="mini" type="text" @click="openPackage(scope.row.id)">开通套餐</el-button>
         </template>
@@ -72,17 +73,29 @@
         <el-button type="primary" @click="checkDealPackage">确 定</el-button>
       </span>
     </el-dialog>
+
+    <el-dialog title="更换设备" :visible.sync="upPadNoVisible" width="40%">
+      <el-form :model="upAppUser">
+        <el-form-item label="设备编号" prop="padNo">
+          <el-select filterable  v-model="upAppUser.padNo" placeholder="请输入设备编号">
+            <el-option v-for="item in padList" :key="item.sn" :label="item.sn" :value="item.sn">
+            </el-option>
+          </el-select>
+        </el-form-item>     
+      </el-form>
+    </el-dialog>
   </div>
 </template>
 
 <script>
 import { listData, delpatient, patientDetail, learnSelectAll, queryMonthRecord, reviewTaskSave, dealPackage } from '@/api/patient/index'
 import { debounce } from 'lodash-es'
-import detail from '../addTwo/index.vue'
+import detail from '../addTwo/index2.vue'
 import {dropDownOrg} from '@/api/system/dept.js'
+import { listData as equipmentList } from "@/api/equipment/index";
 export default {
   name: "manager_list",
-  dicts: ['education_type'],
+  dicts: ['education_type','equipment_class'],
   components: { detail },
   data() {
     return {
@@ -110,7 +123,10 @@ export default {
         packageId: undefined
       },
       learningPackageList:[],
-      dropDownOrgList:[]
+      dropDownOrgList:[],
+      upPadNoVisible: false,
+      upAppUser: {},
+      padList: []
     };
   },
   created() {
@@ -142,6 +158,25 @@ export default {
   },
 
   methods: {
+    handelPadNo(row) {
+      equipmentList({ page: 1, limit: 99999999, status: 'A', equipmentType: 'A' }).then(res => {
+        this.padList = res.data.records.map(item => {
+          return {
+            ...item,
+            label: this.dict.type.equipment_class.map(t => {
+              if (t.value == item.equipmentType) {
+                return t.label
+              }
+            }).filter(item => item).join('')
+          }
+        })
+        this.upAppUser.id = row.id
+        this.upPadNoVisible = true
+      })
+    },
+    handleGetEquipmentList() {
+      
+    },
     /** 机构下拉框 */
     dropDownOrg() {
       dropDownOrg().then(resp =>{