Browse Source

门诊优惠券

lighter 1 year ago
parent
commit
d7ab81ec6f

+ 17 - 0
src/api/coupon.js

@@ -0,0 +1,17 @@
+import request from '../utils/request'
+
+export function receiveAssessmentGift(source) {
+    return request({
+        url: '/coupon/receiveAssessmentGift',
+        method: 'get',
+        params: { source },
+    })
+}
+
+export function getMyCoupons(hisOrdNum) {
+    return request({
+        url: '/coupon/getMyCoupons',
+        method: 'get',
+        params: { hisOrdNum }
+    })
+}

+ 54 - 65
src/components/appointment-management-branch/index.vue

@@ -19,80 +19,69 @@
   </div>
 </template>
 
-<script>
+<script setup>
 import empty from '../../assets/empty.png'
 import {computed, onMounted, ref} from "vue";
 import {listMzyReqrec} from '../../api/appointment.js'
 import {useStore} from "vuex";
 
-export default {
-  props: {
-    patientId: {
-      type: String,
-      required: true
-    },
-    payMark: {
-      type: String,
-      required: true
-    }
+const props = defineProps({
+  patientId: {
+    type: String,
+    required: true
   },
-  setup(props) {
-    const showEmpty = ref(true)
-    const store = useStore()
-    const screenSize = store.state.screenSize
-    const boxWrapper = {
-      height: screenSize.h - 100 + 'px',
-      marginTop: '3px',
-      overflowY: 'auto'
-    }
-
-    const mzyReqsUnPaid = ref([])
-    const mzyReqsPaid = ref([])
-    const mzyReqsRefund = ref([])
+  payMark: {
+    type: String,
+    required: true
+  }
+})
 
-    const mzyReqsList = computed(() => {
-      switch (props.payMark) {
-        case '5':
-          return mzyReqsUnPaid.value
-        case '0':
-          return mzyReqsPaid.value
-        default:
-          return mzyReqsRefund.value
-      }
-    })
-    
-    const makeRedirectPath = (mzyReq) => {
-      let prefix = props.payMark === '5' ? '/payClinicAppointmentOrder/' : '/refundAppointment/'
-      return prefix + props.patientId + '/' + mzyReq.times
-    }
+const showEmpty = ref(true)
+const store = useStore()
+const screenSize = store.state.screenSize
+const boxWrapper = {
+  height: screenSize.h - 100 + 'px',
+  marginTop: '3px',
+  overflowY: 'auto'
+}
 
-    onMounted(() => {
-      const param = {patientId: props.patientId, payMark: props.payMark}
-      listMzyReqrec(param).then(res => {
-        showEmpty.value = false
-        switch (props.payMark) {
-          case '5':
-            mzyReqsUnPaid.value = res
-                break
-          case '0':
-            mzyReqsPaid.value = res
-                break
-          default:
-            mzyReqsRefund.value = res
-                break
-        }
-      }).catch(() => {
-        showEmpty.value = true
-      })
-    })
+const mzyReqsUnPaid = ref([])
+const mzyReqsPaid = ref([])
+const mzyReqsRefund = ref([])
 
-    return {
-      empty,
-      showEmpty,
-      boxWrapper,
-      mzyReqsList,
-      makeRedirectPath
-    }
+const mzyReqsList = computed(() => {
+  switch (props.payMark) {
+    case '5':
+      return mzyReqsUnPaid.value
+    case '0':
+      return mzyReqsPaid.value
+    default:
+      return mzyReqsRefund.value
   }
+})
+
+const makeRedirectPath = (mzyReq) => {
+  let prefix = props.payMark === '5' ? '/payClinicAppointmentOrder/' : '/refundAppointment/'
+  return prefix + props.patientId + '/' + mzyReq.times
 }
+
+onMounted(() => {
+  const param = {patientId: props.patientId, payMark: props.payMark}
+  listMzyReqrec(param).then(res => {
+    showEmpty.value = false
+    switch (props.payMark) {
+      case '5':
+        mzyReqsUnPaid.value = res
+        break
+      case '0':
+        mzyReqsPaid.value = res
+        break
+      default:
+        mzyReqsRefund.value = res
+        break
+    }
+  }).catch(() => {
+    showEmpty.value = true
+  })
+})
 </script>

+ 33 - 0
src/components/countdown-for-payment/index.vue

@@ -0,0 +1,33 @@
+<template>
+  <van-notice-bar left-icon="warning-o">
+    <template #default>
+      <div v-if="countdownFinished">
+        <span>有效支付时间已过期</span>
+      </div>
+      <div v-else>
+        <div style="display: inline-block">请在&nbsp;&nbsp;</div>
+        <div style="display: inline-block">
+          <van-count-down
+              style="color: orangered"
+              :time="60 * 15 * 1000"
+              format="mm分ss秒"
+              @finish="countDownFinish"
+          />
+        </div>
+        <div style="display: inline-block">&nbsp;&nbsp;内完成支付</div>
+      </div>
+    </template>
+  </van-notice-bar>
+</template>
+
+<script setup>
+import {ref} from "vue";
+
+const emits = defineEmits(['onFinish'])
+
+const countdownFinished = ref(false)
+const countDownFinish = () => {
+  countdownFinished.value = true
+  emits('onFinish')
+}
+</script>

+ 104 - 0
src/components/wx-order-detail/index.vue

@@ -0,0 +1,104 @@
+<template>
+  <div class="order-title">
+    订单详情
+  </div>
+  <div class="order-wrapper">
+    <van-cell title="医院名称" value="长沙泰和医院"></van-cell>
+    <van-cell title="费用类型" :value="createOrderRequest.body"></van-cell>
+    <van-cell title="就诊科室" :value="createOrderRequest.deptName"></van-cell>
+    <div v-if="createOrderRequest.orderType !== 3">
+      <van-cell title="医生姓名" :value="createOrderRequest.doctorName"></van-cell>
+    </div>
+    <div v-if="createOrderRequest.orderType === 1">
+      <van-cell title="医生职称" :value="createOrderRequest.chargeType"></van-cell>
+      <van-cell title="就诊日期" :value="createOrderRequest.week + '  ' + createOrderRequest.date"></van-cell>
+      <van-cell title="就诊时段" :value="createOrderRequest.ampm + '  ' + (createOrderRequest.apValue || '')"></van-cell>
+    </div>
+    <van-cell title="就诊人" :value="createOrderRequest.patientName"></van-cell>
+    <van-cell title="就诊卡号" :value="createOrderRequest.patientId"></van-cell>
+
+    <div v-if="createOrderRequest.orderType === 3">
+      <van-cell title="住院号" :value="createOrderRequest.inpatientNo"></van-cell>
+    </div>
+
+    <van-cell title="支付金额">
+      <template #value>
+        <span style="color: orangered">{{ fixDigits(createOrderRequest.cashpayAmt) }}</span>
+      </template>
+    </van-cell>
+    <van-cell title="支付时间" :value="createOrderRequest.payTime"></van-cell>
+
+    <div v-if="createOrderRequest.orderType === 2">
+      <van-cell title="项目清单"></van-cell>
+      <div style="text-align: center; margin-top: 8px; font-size: 12px; color: #0f5757">
+        <van-row>
+          <van-col span="10">名称</van-col>
+          <van-col span="5">单价</van-col>
+          <van-col span="4">数量</van-col>
+          <van-col span="5">金额</van-col>
+        </van-row>
+        <div style="height: 5px"></div>
+        <div v-for="(fee, index) in createOrderRequest.chargeList" :key="index">
+          <div style="height: 5px"></div>
+          <van-row>
+            <van-col span="10">{{ fee.itemName }}</van-col>
+            <van-col span="5">{{ fixPrice(fee.itemPrice) }}</van-col>
+            <van-col span="4">{{ fee.itemNumber }}</van-col>
+            <van-col span="5">{{ fixPrice(fee.itemTotalFee) }}</van-col>
+          </van-row>
+          <div style="height: 5px"></div>
+        </div>
+      </div>
+    </div>
+
+
+  </div>
+  <div class="close-wrapper">
+    <van-button size="small" type="danger" round plain
+                style="width: 120px" @click="closeComponent">
+      关闭
+    </van-button>
+  </div>
+</template>
+
+<script setup>
+import store from "../../store";
+
+const emits = defineEmits(['close'])
+
+const createOrderRequest = store.getters.getCreateOrderRequest
+
+function fixDigits(money) {
+  return '¥' + money.toFixed(2)
+}
+
+function fixPrice(money) {
+  let m = money / 100
+  return '¥' + m.toFixed(2)
+}
+
+function closeComponent() {
+  emits('close')
+}
+</script>
+
+<style scoped>
+.order-title {
+  height: 50px;
+  font-size: 16px;
+  font-weight: bold;
+  line-height: 50px;
+  text-align: center;
+  background-color: #f5f5f5;;
+}
+.order-wrapper {
+  height: calc(100vh - 100px);
+  overflow-y: auto;
+}
+.close-wrapper {
+  height: 50px;
+  line-height: 40px;
+  text-align: center;
+  background-color: #f5f5f5;;
+}
+</style>

+ 23 - 7
src/router/index.js

@@ -77,11 +77,6 @@ export const constantRoutes = [
     component: () => import('../views/hospital-service/appointment/AppointmentConfirm.vue'),
     meta: { title: '挂号确认' },
   },
-  {
-    path: '/payAppointmentFee',
-    component: () => import('../views/hospital-service/appointment/PayAppointmentFee.vue'),
-    meta: { title: '收银台' },
-  },
   {
     path: '/payClinicAppointmentOrder/:patientId/:times',
     component: () => import('../views/hospital-service/appointment/PayClinicAppointmentOrder.vue'),
@@ -118,13 +113,13 @@ export const constantRoutes = [
     meta: { title: '待缴费列表' },
   },
   {
-    path: '/medinsSettle/:patientId/:hisOrdNum/:patName/:deptName/:doctorName/:mdtrtId',
+    path: '/medinsSettle/:patientId/:hisOrdNum/:patientName/:deptName/:doctorName/:mdtrtId',
     name: 'medinsSettle',
     component: () => import('../views/hospital-service/pay-mz-fee/MedInsSettle.vue'),
     meta: { title: '医保结算' },
   },
   {
-    path: '/unPaidDetail/:patientId/:hisOrdNum/:patName/:deptName/:doctorCode/:doctorName/:totalAmt/:selfAmt/:fundPay?/:acctPay?',
+    path: '/unPaidDetail/:patientId/:hisOrdNum/:patientName/:deptName/:doctorCode/:doctorName/:totalAmt/:selfAmt/:fundPay?/:acctPay?',
     name: 'unPaidDetail',
     component: () => import('../views/hospital-service/pay-mz-fee/UnPaidDetail.vue'),
     meta: { title: '待缴费详情' },
@@ -247,6 +242,11 @@ export const constantRoutes = [
     component: () => import('../views/mine/my-collection/MyCollection.vue'),
     meta: { title: '我的收藏' },
   },
+  {
+    path: '/myCoupons',
+    component: () => import('../views/mine/my-coupons/MyCoupons.vue'),
+    meta: { title: '我的卡券' },
+  },
   {
     path: '/patientCardInfo/:patientId',
     component: () => import('../views/mine/patient-id-cards/PatientCardInfo.vue'),
@@ -406,6 +406,14 @@ export const constantRoutes = [
       title: '慢病患者登记表',
     },
   },
+  {
+    path: '/cashier',
+    name: 'cashier',
+    component: () => import('../views/public-pages/Cashier.vue'),
+    meta: {
+      title: '收银台'
+    }
+  },
   {
     path: '/resultSuccess',
     name: 'resultSuccess',
@@ -414,6 +422,14 @@ export const constantRoutes = [
       title: '',
     },
   },
+  {
+    path: '/paymentSuccess',
+    name: 'paymentSuccess',
+    component: () => import('../views/public-pages/PaymentSuccess.vue'),
+    meta: {
+      title: '支付完成'
+    }
+  },
   {
     path: '/500',
     component: () => import('../views/500.vue'),

+ 13 - 3
src/store/index.js

@@ -23,7 +23,8 @@ export default createStore({
     physicalExamListFinished: false,
     physicalExamIndexes: [],
     currentTjid: null,
-    appointmentManagementActiveTab: 'unpaid'
+    appointmentManagementActiveTab: 'unpaid',
+    createOrderRequest: {},
   },
 
   mutations: {
@@ -43,7 +44,8 @@ export default createStore({
     SET_PHYSICALEXAMLISTFINISHED: (state, payload) => (state.physicalExamListFinished = payload),
     SET_PHYSICALEXAMINDEXES: (state, payload) => (state.physicalExamIndexes = payload),
     SET_CURRENTTJID: (state, payload) => (state.currentTjid = payload),
-    SET_APPOINTMENTMANAGEMENTACTIVETAB: (state, payload) => {state.appointmentManagementActiveTab = payload}
+    SET_APPOINTMENTMANAGEMENTACTIVETAB: (state, payload) => {state.appointmentManagementActiveTab = payload},
+    CREATE_ORDER_REQUEST: (state, payload) => (state.createOrderRequest = payload),
   },
 
   getters: {
@@ -85,7 +87,11 @@ export default createStore({
         }
       }
       return {}
-    }
+    },
+
+    getCreateOrderRequest(state) {
+      return state.createOrderRequest
+    },
   },
 
   actions: {
@@ -121,5 +127,9 @@ export default createStore({
     storeCurrentBookItem({ commit }, payload) {
       commit('SET_CURRENTBOOK', payload['bookItem'])
     },
+
+    storeCreateOrderRequest({ commit }, payload) {
+      commit('CREATE_ORDER_REQUEST', payload['createOrderRequest'])
+    },
   },
 })

+ 0 - 1
src/utils/wx-pay.js

@@ -1,6 +1,5 @@
 import {createPayOrder, queryOrderState} from '../api/wx-jsapi'
 import store from '../store'
-
 export function wxPay(param) {
     return new Promise((resolve, reject) => {
         createPayOrder(param).then((res) => {

+ 99 - 90
src/views/hospital-service/appointment/AppointmentConfirm.vue

@@ -1,77 +1,72 @@
 <template>
-    <window-size>
-        <van-cell title="医生姓名" :value="appointment.doctorName"/>
-        <van-cell title="医生号别" :value="appointment.doctorTitle"/>
-        <van-cell title="就诊科室" :value="appointment.deptName"/>
-        <van-cell title="就诊日期">
-            <template #default>
-                <div style="color: orangered">
-                    {{ appointment.week }}&nbsp;&nbsp;{{ appointment.date }}
-                </div>
+  <window-size>
+    <van-cell title="医生姓名" :value="appointment.doctorName"/>
+    <van-cell title="医生号别" :value="appointment.doctorTitle"/>
+    <van-cell title="就诊科室" :value="appointment.deptName"/>
+    <van-cell title="就诊日期">
+      <template #default>
+        <div style="color: orangered">
+          {{ appointment.week }}&nbsp;&nbsp;{{ appointment.date }}
+        </div>
+      </template>
+    </van-cell>
+    <van-cell title="就诊时段">
+      <template #default>
+        <div style="color: orangered">
+          {{ appointment.ampm }}&nbsp;&nbsp;{{ appointment.apValue || '' }}
+        </div>
+      </template>
+    </van-cell>
+    <div style="height: 5px"></div>
+    <van-cell title="挂号金额">
+      <template #default>
+        <div style="color: orangered">¥{{ appointment.fee }}</div>
+      </template>
+    </van-cell>
+    <div style="height: 5px"></div>
+    <van-radio-group v-model="appointment.patientId">
+      <van-cell-group>
+        <div v-for="item in patientCards" :key="item.patientId">
+          <van-cell center icon="user-o" :label="item.patientId" clickable
+                    @click="changePatient(item.patientId)">
+            <template #title>
+              <span class="custom-title">{{ item.name }}</span>
+              &nbsp;
+              <van-tag type="primary" plain v-if="item.isDefault === 1">默认</van-tag>
             </template>
-        </van-cell>
-        <van-cell title="就诊时段">
-          <template #default>
-            <div style="color: orangered">
-              {{ appointment.ampm }}&nbsp;&nbsp;{{ appointment.apValue || '' }}
-            </div>
-          </template>
-        </van-cell>
-        <div style="height: 5px"></div>
-        <van-cell title="挂号金额">
-            <template #default>
-                <div style="color: orangered">¥{{ appointment.fee }}</div>
+            <template #right-icon>
+              <van-radio :name="item.patientId"/>
             </template>
-        </van-cell>
-        <div style="height: 5px"></div>
-        <van-radio-group v-model="appointment.patientId">
-            <van-cell-group>
-                <div v-for="item in patientCards" :key="item.patientId">
-                    <van-cell center icon="user-o" :label="item.patientId" clickable
-                              @click="changePatient(item.patientId)">
-                        <template #title>
-                            <span class="custom-title">{{ item.name }}</span>
-                            &nbsp;
-                            <van-tag type="primary" plain v-if="item.isDefault === 1">默认</van-tag>
-                        </template>
-                        <template #right-icon>
-                            <van-radio :name="item.patientId"/>
-                        </template>
-                    </van-cell>
-                </div>
-            </van-cell-group>
-        </van-radio-group>
-        <van-cell
-                v-if="showAddCard"
-                icon="add-o"
-                title="添加就诊人"
-                :value="addCardText"
-                is-link
-                to="/addElectronicHealthCard"
-        ></van-cell>
-        <div style="height: 10px"></div>
-        <van-button type="primary" block @click="confirmAppointment" :disabled="disableGhBtn">确认挂号</van-button>
-    </window-size>
+          </van-cell>
+        </div>
+      </van-cell-group>
+    </van-radio-group>
+    <van-cell
+        v-if="showAddCard"
+        icon="add-o"
+        title="添加就诊人"
+        :value="addCardText"
+        is-link
+        to="/addElectronicHealthCard"
+    ></van-cell>
+    <div style="height: 10px"></div>
+    <van-button type="primary" block @click="confirmAppointment" :disabled="disableGhBtn">确认挂号</van-button>
+  </window-size>
 </template>
 
 <script setup>
 import store from '../../../store'
-import {computed, onMounted, ref, watchEffect} from 'vue'
+import {computed, onMounted, ref} from 'vue'
 import {checkAppointmentRequirements, getGhFee} from '../../../api/appointment'
 import router from '../../../router'
 import {showConfirmDialog, showToast} from 'vant'
 
+const disableGhBtn = ref(true)
 const appointment = store.state.appointmentInfo
 const patientCards = computed(() => {
   return store.state.patientCards
 })
-watchEffect(() => {
-  patientCards.value.forEach((item) => {
-    if (item.isDefault === 1) {
-      appointment.patientId = item.patientId
-    }
-  })
-})
+
 const showAddCard = computed(() => {
   return patientCards.value.length < 5
 })
@@ -80,54 +75,68 @@ const addCardText = computed(() => {
 })
 const changePatient = (patientId) => {
   appointment.patientId = patientId
-  fetchGhFee()
+  queryAppointmentCost()
+}
+
+const queryAppointmentCost = () => {
+  getGhFee(appointment).then((res) => {
+    appointment.fee = res.fee
+    disableGhBtn.value = false
+    if (res.message) {
+      showToast({
+        message: res.message,
+        position: 'top',
+        duration: 3000,
+      })
+    }
+  }).catch(() => {
+    appointment.fee = '获取失败'
+    disableGhBtn.value = true
+  })
 }
+
 const confirmAppointment = () => {
   checkAppointmentRequirements(appointment.patientId, appointment.deptCode).then(() => {
-    patientCards.value.forEach((item) => {
-      if (item.patientId === appointment.patientId) {
-        appointment.patientName = item.name
-      }
-    })
     showConfirmDialog({
       title: '温馨提示',
       message: '实际看诊序号以至分诊台到诊登记为准。当天未就诊,不予退号、换号、转科,敬请谅解。',
       confirmButtonText: '确认挂号',
       cancelButtonText: '取消挂号'
     }).then(() => {
-      store.dispatch({
-        type: 'storeAppointmentInfo',
-        appointmentInfo: appointment
-      }).then(() => {
-        router.push('/payAppointmentFee')
-      })
+      fetchPatientName()
     }).catch(() => {
     })
   })
 }
 
-const disableGhBtn = ref(true)
+function fetchPatientName() {
+  patientCards.value.forEach((item) => {
+    if (item.patientId === appointment.patientId) {
+      appointment.patientName = item.name
+      toCashier()
+    }
+  })
+}
 
-const fetchGhFee = () => {
-  getGhFee(appointment)
-      .then((res) => {
-        appointment.fee = res.fee
-        disableGhBtn.value = false
-        if (res.message) {
-          showToast({
-            message: res.message,
-            position: 'top',
-            duration: 3000,
-          })
-        }
-      })
-      .catch(() => {
-        appointment.fee = '获取失败'
-        disableGhBtn.value = true
-      })
+function toCashier() {
+  const createOrderRequest = {...appointment}
+  createOrderRequest.body = '挂号费'
+  createOrderRequest.orderType = 1
+  createOrderRequest.totalFee = appointment.fee
+  createOrderRequest.fundpayAmt = 0
+  createOrderRequest.acctpayAmt = 0
+  createOrderRequest.couponAmt = 0
+  createOrderRequest.cashpayAmt = appointment.fee
+  store.dispatch({
+    type: 'storeCreateOrderRequest',
+    createOrderRequest,
+  }).then(() => {
+    router.push('/cashier')
+  })
 }
 
 onMounted(() => {
-  fetchGhFee()
+  appointment.patientId = store.getters.getDefaultCard.patientId
+  queryAppointmentCost()
 })
 </script>

+ 0 - 76
src/views/hospital-service/appointment/PayAppointmentFee.vue

@@ -1,76 +0,0 @@
-<template>
-  <window-size>
-    <van-notice-bar left-icon="warning-o">
-      <template #default>
-        <div v-if="data.disablePayButton">
-          <span>有效支付时间已过期</span>
-        </div>
-        <div v-else>
-          <div style="display: inline-block">请在&nbsp;&nbsp;</div>
-          <div style="display: inline-block">
-            <van-count-down
-              style="color: orangered"
-              :time="60 * 15 * 1000"
-              format="mm分ss秒"
-              @finish="countDownFinish"
-            />
-          </div>
-          <div style="display: inline-block">&nbsp;&nbsp;内完成支付</div>
-        </div>
-      </template>
-    </van-notice-bar>
-    <van-grid :column-num="1">
-      <van-grid-item>
-        <template #default>
-          <div style="font-size: 12px">支付金额(元)</div>
-          <div style="color: orangered; font-size: 30px; font-weight: bold; margin-top: 5px">
-            {{ data.appointment.fee }}
-          </div>
-        </template>
-      </van-grid-item>
-    </van-grid>
-    <div style="height: 5px"></div>
-    <van-cell title="费用类型" value="当班挂号"></van-cell>
-    <van-cell title="就诊科室" :value="data.appointment.deptName"></van-cell>
-    <van-cell title="医生姓名" :value="data.appointment.doctorName"></van-cell>
-    <van-cell title="就诊日期" :value="data.appointment.week + '  ' + data.appointment.date"></van-cell>
-    <van-cell title="就诊时段" :value="data.appointment.ampm + '  ' + (data.appointment.apValue || '')"></van-cell>
-    <van-cell title="就诊人" :value="data.appointment.patientName"></van-cell>
-    <van-cell title="就诊卡号" :value="data.appointment.patientId"></van-cell>
-    <div style="height: 10px"></div>
-    <van-button type="primary" block :disabled="data.disablePayButton" @click="pay">微信支付</van-button>
-  </window-size>
-</template>
-
-<script setup>
-import store from '../../../store'
-import { reactive } from 'vue'
-import { wxPay } from '../../../utils/wx-pay'
-import { showToast } from 'vant'
-import router from '../../../router'
-
-const data = reactive({
-  disablePayButton: false,
-  appointment: store.state.appointmentInfo,
-})
-const countDownFinish = () => {
-  data.disablePayButton = true
-}
-const pay = () => {
-  const param = {
-    body: '挂号费',
-    orderType: 1,
-    totalFee: data.appointment.fee,
-    patientId: data.appointment.patientId,
-    mzyRequestId: data.appointment.mzyRequestId,
-    apTime: data.appointment.apTime
-  }
-  wxPay(param).then((result) => {
-    showToast({
-      message: result,
-      position: 'top'
-    })
-    router.push('/hospitalService');
-  })
-}
-</script>

+ 36 - 71
src/views/hospital-service/appointment/PayClinicAppointmentOrder.vue

@@ -1,26 +1,7 @@
 <template>
   <window-size>
-    <van-empty :image="empty" description="您没有待缴费记录" v-if="showEmpty"></van-empty>
+    <van-empty v-if="showEmpty" :image="empty" description="您没有待缴费记录"></van-empty>
     <div v-else>
-      <van-notice-bar left-icon="warning-o">
-        <template #default>
-          <div v-if="disablePayButton">
-            <span>有效支付时间已过期</span>
-          </div>
-          <div v-else>
-            <div style="display: inline-block">请在&nbsp;&nbsp;</div>
-            <div style="display: inline-block">
-              <van-count-down
-                  style="color: orangered"
-                  :time="60 * 15 * 1000"
-                  format="mm分ss秒"
-                  @finish="countDownFinish"
-              />
-            </div>
-            <div style="display: inline-block">&nbsp;&nbsp;内完成支付</div>
-          </div>
-        </template>
-      </van-notice-bar>
       <van-grid :column-num="1">
         <van-grid-item>
           <template #default>
@@ -40,66 +21,50 @@
       <van-cell title="就诊人" :value="appointment.name"></van-cell>
       <van-cell title="就诊卡号" :value="appointment.patientId"></van-cell>
       <div style="height: 10px"></div>
-      <van-button type="primary" block :disabled="disablePayButton" @click="pay">微信支付</van-button>
+      <van-button type="primary" block @click="toCashier">去支付</van-button>
     </div>
   </window-size>
 </template>
 
-<script>
+<script setup>
 import empty from '../../../assets/empty.png'
 import {onMounted, ref} from 'vue'
-import { wxPay } from '../../../utils/wx-pay'
 import { getMzyReqrecInfo } from '../../../api/appointment.js'
-import { showToast } from 'vant'
 import {useRouter} from "vue-router";
-export default {
-  name: 'PayClinicAppointmentOrder',
-  setup() {
-    const router = useRouter()
-    const patientId = router.currentRoute.value.params.patientId
-    const times = router.currentRoute.value.params.times
-
-    const disablePayButton = ref(false)
-    const countDownFinish = () => {
-      disablePayButton.value = true
-    }
-    const appointment = ref({})
-    const showEmpty = ref(true)
-    const pay = () => {
-      const param = {
-        body: '诊间挂号',
-        orderType: 0,
-        totalFee: appointment.totalAmount,
-        patientId: appointment.patientId,
-        mzyRequestId: appointment.times
-      }
-      wxPay(param).then((result) => {
-        showToast({
-          message: result,
-          position: 'top',
-        });
-        router.push('/hospitalService')
-      })
-    }
+import store from "../../../store";
+const router = useRouter()
+const patientId = router.currentRoute.value.params.patientId
+const times = router.currentRoute.value.params.times
 
-    onMounted(() => {
-      const params = { patientId, times, filterUnpaidReq: true }
-      getMzyReqrecInfo(params).then(res => {
-        appointment.value = res
-        showEmpty.value = false
-      }).catch(() => {
-        showEmpty.value = true
-      })
-    })
+const appointment = ref({})
+const showEmpty = ref(true)
 
-    return {
-      empty,
-      showEmpty,
-      disablePayButton,
-      countDownFinish,
-      appointment,
-      pay,
-    }
-  },
+function toCashier() {
+  const createOrderRequest = {...appointment}
+  createOrderRequest.body = '诊间挂号'
+  createOrderRequest.orderType = 0
+  createOrderRequest.totalFee = appointment.totalAmount
+  createOrderRequest.mzyRequestId = appointment.times
+  createOrderRequest.fundpayAmt = 0
+  createOrderRequest.acctpayAmt = 0
+  createOrderRequest.cashpayAmt = appointment.totalAmount
+  createOrderRequest.couponAmt = 0
+  createOrderRequest.patientName = appointment.name
+  store.dispatch({
+    type: 'storeCreateOrderRequest',
+    createOrderRequest,
+  }).then(() => {
+    router.push('/cashier')
+  })
 }
+
+onMounted(() => {
+  const params = { patientId, times, filterUnpaidReq: true }
+  getMzyReqrecInfo(params).then(res => {
+    appointment.value = res
+    showEmpty.value = false
+  }).catch(() => {
+    showEmpty.value = true
+  })
+})
 </script>

+ 32 - 8
src/views/hospital-service/assessments/ClinicSatisfiedAssessment.vue

@@ -85,11 +85,18 @@ import {reactive, ref} from "vue";
 import {submitClinicSatisfiedAssessment} from '../../../api/assessments'
 import {showToast} from "vant";
 import {useRouter} from "vue-router";
+import {receiveAssessmentGift} from "../../../api/coupon";
 
 const router = useRouter()
+const routerValue = router.currentRoute.value
+const routerParams = routerValue.params.patientId
+const couponGift = routerValue.path.indexOf('clinicSatisfiedByPush') > -1
+    && routerParams.indexOf('AND') > -1
+
 const answer = reactive({
-  patientId: router.currentRoute.value.params.patientId
+  patientId: routerParams.split('AND')[0]
 })
+
 const disableSubmitButton = ref(false)
 const headQuestions = [
   {key: 11, label: '1-1、您对门急诊导诊及护理人员服务满意吗?'}, // checkboxOptions3
@@ -185,13 +192,30 @@ const submitAnswer = () => {
   }
   submitClinicSatisfiedAssessment(answer).then(() => {
     disableSubmitButton.value = true
-    router.push({
-      name: 'resultSuccess',
-      params: {
-        title: '提交成功',
-        subtitle: '感谢您的评价,您的意见对我们非常重要。',
-      },
-    })
+    if (couponGift) {
+      receiveAssessmentGift(routerParams).then((res) => {
+        showToast({
+          message: res,
+          position: 'top',
+          duration: 3000,
+        })
+        gotoResult()
+      }).catch(() => {
+        gotoResult()
+      })
+    } else {
+      gotoResult()
+    }
+  })
+}
+
+const gotoResult = () => {
+  router.push({
+    name: 'resultSuccess',
+    params: {
+      title: '提交成功',
+      subtitle: '感谢您的评价,您的意见对我们非常重要。',
+    },
   })
 }
 

+ 53 - 78
src/views/hospital-service/inpatient-service/DisplayPrepaid.vue

@@ -2,15 +2,15 @@
   <window-size>
     <van-cell title="就诊人" center>
       <template #default>
-        <p style="color: #333333">{{ params.name }}</p>
-        <span style="font-size: 12px">{{ params.inpatientNo }}</span>
+        <p style="color: #333333">{{ routeParams.name }}</p>
+        <span style="font-size: 12px">{{ routeParams.inpatientNo }}</span>
       </template>
     </van-cell>
     <van-cell title="医院名称" value="长沙泰和医院"></van-cell>
-    <van-cell title="住院科室" :value="params.deptName"></van-cell>
+    <van-cell title="住院科室" :value="routeParams.deptName"></van-cell>
     <van-cell title="可用余额">
       <template #default>
-        <span style="color: orangered">¥ {{ params.lastBalance }}</span>
+        <span style="color: orangered">¥ {{ routeParams.lastBalance }}</span>
       </template>
     </van-cell>
     <div style="height: 5px"></div>
@@ -64,87 +64,62 @@
       </van-col>
     </van-row>
     <div style="height: 20px"></div>
-    <van-button type="primary" block @click="beforePay">微信支付</van-button>
+    <van-button type="primary" block @click="beforePay">提交订单</van-button>
   </window-size>
 </template>
 
-<script>
+<script setup>
 import { ref } from 'vue'
-import { wxPay } from '../../../utils/wx-pay'
-import { showConfirmDialog, showToast } from 'vant'
+import { showConfirmDialog } from 'vant'
 import { useRouter } from 'vue-router'
-export default {
-  setup() {
-    const router = useRouter()
-    const params = router.currentRoute.value.params
-    const prepaidAmount = ref(500)
-    const otherAmount = ref(null)
-    const isPlainButton = (val) => {
-      return val !== prepaidAmount.value
-    }
-    const setPrepaidAmount = (val) => {
-      otherAmount.value = null
-      prepaidAmount.value = val
-    }
+import store from "../../../store";
 
-    const beforePay = () => {
-      if (otherAmount.value) {
-        prepaidAmount.value = otherAmount.value
-      }
-      showConfirmDialog({
-        message: '您正在为【' + params.name + '】缴纳住院预交金,金额为【' + prepaidAmount.value + '】。确认支付吗?',
-        title: '提示',
-        confirmButtonText: '支付',
-        cancelButtonText: '取消',
-      })
-        .then(() => {
-          pay()
-        })
-        .catch(() => {})
-    }
+const router = useRouter()
+const routeParams = router.currentRoute.value.params
+const prepaidAmount = ref(500)
+const otherAmount = ref(null)
+const isPlainButton = (val) => {
+  return val !== prepaidAmount.value
+}
+const setPrepaidAmount = (val) => {
+  otherAmount.value = null
+  prepaidAmount.value = val
+}
 
-    const pay = () => {
-      const param = {
-        body: '住院预交金',
-        orderType: 3,
-        totalFee: prepaidAmount.value,
-        patientId: params.patientId,
-        inpatientNo: params.inpatientNo,
-        admissTimes: params.admissTimes,
-      }
-      wxPay(param).then((result) => {
-        showToast({
-          message: result,
-          position: 'top'
-        })
-        router.push('/hospitalService')
-      })
-    }
-    return {
-      params,
-      isPlainButton,
-      setPrepaidAmount,
-      otherAmount,
-      beforePay,
-      pay,
-    }
-  },
+const beforePay = () => {
+  if (otherAmount.value) {
+    prepaidAmount.value = Number.parseInt(otherAmount.value)
+  }
+  showConfirmDialog({
+    message: '您正在为【' + routeParams.name + '】缴纳住院预交金,金额为【' + prepaidAmount.value + '】。确认支付吗?',
+    title: '提示',
+    confirmButtonText: '前往支付',
+    cancelButtonText: '取消',
+  }).then(() => {
+    toCashier()
+  }).catch(() => {})
 }
-</script>
 
-<style scoped>
-.input-amount {
-  width: 100%;
-  height: 30px;
-  padding: 0px 8px;
-  font-size: 12px;
-  color: rgb(7, 193, 96);
-  background-color: rgb(255, 255, 255);
-  border: 1px solid rgb(7, 193, 96);
-  line-height: 1.2;
-  text-align: center;
-  border-radius: 2px;
-  transition: opacity 0.2s ease 0s;
-  appearance: none;
+function toCashier() {
+  const createOrderRequest = {
+    body: '住院预交金',
+    orderType: 3,
+    totalFee: prepaidAmount.value,
+    patientId: routeParams.patientId,
+    inpatientNo: routeParams.inpatientNo,
+    admissTimes: routeParams.admissTimes,
+    deptName: routeParams.deptName,
+    fundpayAmt: 0,
+    acctpayAmt:0,
+    cashpayAmt: prepaidAmount.value,
+    couponAmt: 0,
+    patientName: routeParams.name
+  }
+  store.dispatch({
+    type: 'storeCreateOrderRequest',
+    createOrderRequest,
+  }).then(() => {
+    router.push('/cashier')
+  })
 }
-</style>
+</script>

+ 2 - 2
src/views/hospital-service/pay-mz-fee/FromGuideBillQrScan.vue

@@ -32,7 +32,7 @@ const onClickFeeItem = (item) => {
     const routeParams = {
       patientId: patientId,
       hisOrdNum: item.hisOrdNum,
-      patName: item.patName,
+      patientName: item.patName,
       deptName: item.deptName,
       doctorCode: item.doctorCode,
       doctorName: item.doctorName,
@@ -85,6 +85,6 @@ function makeTitle(item) {
 
 function makeMoney(money) {
   const m = money / 100
-  return '¥ ' + m.toFixed(2)
+  return '¥' + m.toFixed(2)
 }
 </script>

+ 1 - 1
src/views/hospital-service/pay-mz-fee/MedInsSettle.vue

@@ -120,7 +120,7 @@ onMounted(() => {
 })
 
 function makeMoney(money) {
-  return '¥ ' + Number.parseFloat(money).toFixed(2)
+  return '¥' + Number.parseFloat(money).toFixed(2)
 }
 
 </script>

+ 39 - 109
src/views/hospital-service/pay-mz-fee/UnPaidDetail.vue

@@ -1,28 +1,28 @@
 <template>
   <window-size>
-    <van-cell title="就诊人" :value="params.patName"></van-cell>
+    <van-cell title="就诊人" :value="routeParams.patientName"></van-cell>
     <van-cell title="医院名称" value="长沙泰和医院"></van-cell>
-    <van-cell title="开方科室" :value="params.deptName"></van-cell>
-    <van-cell title="开方医生" :value="params.doctorName"></van-cell>
+    <van-cell title="开方科室" :value="routeParams.deptName"></van-cell>
+    <van-cell title="开方医生" :value="routeParams.doctorName"></van-cell>
     <van-cell title="总金额">
       <template #default>
-        <span style="color: orangered">{{ makeMoney(params.totalAmt) }}</span>
+        <span style="color: orangered">{{ makeMoney(routeParams.totalAmt) }}</span>
       </template>
     </van-cell>
-    <div v-if="params.fundPay && params.fundPay !== 'undefined'">
+    <div v-if="routeParams.fundPay && routeParams.fundPay !== 'undefined'">
       <van-cell title="医保统筹支付">
         <template #default>
-          <span style="color: orangered">{{ makeMoney(params.fundPay) }}</span>
+          <span style="color: orangered">{{ makeMoney(routeParams.fundPay) }}</span>
         </template>
       </van-cell>
-      <van-cell v-if="params.acctPay" title="个人账户支付">
+      <van-cell v-if="routeParams.acctPay" title="个人账户支付">
         <template #default>
-          <span style="color: orangered">{{ makeMoney(params.acctPay) }}</span>
+          <span style="color: orangered">{{ makeMoney(routeParams.acctPay) }}</span>
         </template>
       </van-cell>
       <van-cell title="个人现金支付">
         <template #default>
-          <span style="color: orangered">{{ makeMoney(params.selfAmt) }}</span>
+          <span style="color: orangered">{{ makeMoney(routeParams.selfAmt) }}</span>
         </template>
       </van-cell>
     </div>
@@ -36,7 +36,7 @@
         <van-col span="5">金额(元)</van-col>
       </van-row>
       <div style="height: 5px"></div>
-      <div v-for="(fee, index) in fees" :key="index">
+      <div v-for="(fee, index) in chargeList" :key="index">
         <div style="height: 5px"></div>
         <van-row>
           <van-col span="10">{{ fee.itemName }}</van-col>
@@ -48,119 +48,49 @@
       </div>
     </div>
     <div style="height: 10px"></div>
-    <van-button block type="primary" @click="wechatPay">微信支付(¥ {{ makePrice(params.selfAmt) }})</van-button>
-
-    <van-dialog
-        v-model:show="showRate"
-        title="您的评价是我们前进的动力"
-        show-confirm-button
-        show-cancel-button
-        confirm-button-text="提交"
-        @cancel="router.push('/hospitalService')"
-        @confirm="submitComment">
-      <div style="font-size: 12px; color: rgb(128, 128, 128); padding: 8px 0 0 20px">请您对医生作出评价:</div>
-      <div style="padding: 8px 0 20px 20px">
-        <div>
-          评分:
-          <van-rate
-              v-model="comment.commentLevel"
-              :size="20"
-              color="#ffd21e"
-              void-icon="star"
-              void-color="#eee"
-          />
-          <span style="margin-left: 12px; font-size: 12px; color: rgb(128, 128, 128)">({{rateLevelExplain}})</span>
-        </div>
-        <van-field
-            v-model="comment.commentContent"
-            rows="5"
-            autosize
-            type="textarea"
-            placeholder="请在此输入评价内容..."
-            style="border: 1px solid lightgray; border-radius: 5px; margin-top: 12px"
-        />
-      </div>
-    </van-dialog>
+    <van-button block type="primary" @click="toCashier">提交订单</van-button>
   </window-size>
 </template>
 
 <script setup>
 import {useRouter} from 'vue-router'
 import {getUnPaidDetail} from '../../../api/pay-mz-fee'
-import {computed, onMounted, reactive, ref} from 'vue'
-import {wxPay} from '../../../utils/wx-pay'
+import {onMounted, ref} from 'vue'
 import store from '../../../store'
-import {showToast} from 'vant';
-import {commitNewComment} from "../../../api/comment";
 
 const router = useRouter()
-const params = router.currentRoute.value.params
-const fees = ref([])
-const showRate = ref(false)
-const comment = reactive({
-  commentLevel: 5,
-  commentContent: '',
-  doctorName: '',
-  hisOrdNum: '',
-  patientName: '',
-  patientId: ''
-})
-const rateLevelExplain = computed(() => {
-  switch (comment.commentLevel) {
-    case 5:
-      return '很满意'
-    case 4:
-      return '满意'
-    case 3:
-      return '一般'
-    case 2:
-      return '不满意'
-    case 1:
-      return '很不满意'
-  }
-})
-const submitComment = () => {
-  comment.doctorCode = params.doctorCode
-  comment.doctorName = params.doctorName
-  comment.hisOrdNum = params.hisOrdNum
-  comment.patientId = params.patientId
-  comment.patientName = params.patName
-  commitNewComment(comment).then(res => {
-    showToast({
-      message: res,
-      position: 'top',
-    });
-    router.push('/hospitalService')
-  })
-}
-const wechatPay = () => {
-  let bodyText = '门诊缴费'
-  if (fees.value.length === 1) {
-    bodyText = fees.value[0].itemName || '门诊缴费'
-  }
-  const param = {
-    body: bodyText,
+const routeParams = router.currentRoute.value.params
+const chargeList = ref([])
+
+function toCashier() {
+  const createOrderRequest = {
+    body: '门诊缴费',
     orderType: 2,
-    totalFee: makePrice(params.selfAmt),
-    patientId: params.patientId,
-    hisOrdNum: params.hisOrdNum,
+    totalFee: routeParams.totalAmt / 100,
+    fundpayAmt: routeParams.fundPay / 100,
+    acctpayAmt: routeParams.acctPay / 100,
+    cashpayAmt: routeParams.selfAmt / 100,
+    couponAmt: 0,
+    patientId: routeParams.patientId,
+    hisOrdNum: routeParams.hisOrdNum,
     yjReqNo: store.state.yjReqNo,
+    doctorCode: routeParams.doctorCode,
+    doctorName: routeParams.doctorName,
+    deptName: routeParams.deptName,
+    patientName: routeParams.patientName,
+    chargeList: chargeList.value
   }
-  wxPay(param).then((result) => {
-    showToast({
-      message: result,
-      position: 'top',
-    });
-    if (params.doctorCode === '99999') {
-      router.push('/hospitalService')
-    } else {
-      showRate.value = true
-    }
+  store.dispatch({
+    type: 'storeCreateOrderRequest',
+    createOrderRequest,
+  }).then(() => {
+    router.push('/cashier')
   })
 }
+
 onMounted(() => {
-  getUnPaidDetail(params.patientId, params.hisOrdNum).then((res) => {
-    fees.value = res
+  getUnPaidDetail(routeParams.patientId, routeParams.hisOrdNum).then((res) => {
+    chargeList.value = res
   })
 })
 
@@ -170,6 +100,6 @@ function makePrice(num) {
 
 function makeMoney(money) {
   const m = money / 100
-  return '¥ ' + m.toFixed(2)
+  return '¥' + m.toFixed(2)
 }
 </script>

+ 2 - 2
src/views/hospital-service/pay-mz-fee/UnPaidList.vue

@@ -30,7 +30,7 @@ const onClickFeeItem = (item) => {
     const routeParams = {
       patientId: patientId,
       hisOrdNum: item.hisOrdNum,
-      patName: item.patName,
+      patientName: item.patName,
       deptName: item.deptName,
       doctorCode: item.doctorCode,
       doctorName: item.doctorName,
@@ -68,7 +68,7 @@ function makeTitle(item) {
 
 function makeMoney(money) {
   const m = money / 100
-  return '¥ ' + m.toFixed(2)
+  return '¥' + m.toFixed(2)
 }
 
 onMounted(() => {

+ 1 - 0
src/views/mine/MineHome.vue

@@ -26,6 +26,7 @@
     <van-cell-group title="我的">
       <van-cell icon="friends" title="我的就诊人" is-link to="/myPatientIdCards"></van-cell>
       <van-cell icon="star" title="我的收藏" is-link to="/myCollection"></van-cell>
+      <van-cell icon="coupon" title="我的卡券" is-link to="/myCoupons"></van-cell>
     </van-cell-group>
 
     <van-cell-group title="记录">

+ 33 - 0
src/views/mine/my-coupons/MyCoupons.vue

@@ -0,0 +1,33 @@
+<template>
+  <window-size>
+    <van-coupon-list
+        :coupons="usableCoupons"
+        :disabled-coupons="unusableCoupons"
+        :show-exchange-bar="false"
+    ></van-coupon-list>
+  </window-size>
+</template>
+
+<script setup>
+import {onMounted, ref} from "vue";
+import {getMyCoupons} from "../../../api/coupon";
+
+const usableCoupons = ref([])
+const unusableCoupons = ref([])
+
+onMounted(() => {
+  getMyCoupons('NONE').then(res => {
+    usableCoupons.value = res.usableCoupons
+    unusableCoupons.value = res.unusableCoupons
+  })
+})
+</script>
+
+<style scoped>
+:deep(.van-checkbox) {
+  display: none;
+}
+:deep(.van-coupon-list__bottom) {
+  display: none;
+}
+</style>

+ 190 - 0
src/views/public-pages/Cashier.vue

@@ -0,0 +1,190 @@
+<template>
+  <window-size>
+    <payment-countdown @onFinish="countdownFinished = true"></payment-countdown>
+    <div class="to-be-paid-wrapper">
+      <div class="label">
+        收款单位:<span>长沙泰和医院</span>
+      </div>
+      <div class="label">
+        缴费类别:<span>{{ createOrderRequest.body }}</span>
+      </div>
+      <div class="label money-box">
+        待缴金额:
+        <span class="money">{{ psnCashpayAmt }}</span>
+        <div class="detail-box">
+          <div>
+            <div>
+              总计金额:{{makeMoneyStyle(createOrderRequest.totalFee)}}
+            </div>
+            <div>
+              医保报销:{{makeMoneyStyle(createOrderRequest.fundpayAmt)}}
+            </div>
+            <div>
+              个账支付:{{makeMoneyStyle(createOrderRequest.acctpayAmt)}}
+            </div>
+            <div>
+              卡券优惠:{{makeMoneyStyle(createOrderRequest.couponAmt)}}
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <div style="margin: 0 12px">
+      <van-coupon-cell
+          :coupons="usableCoupons"
+          :chosen-coupon="chosenCouponIndex"
+          @click="showCouponList = true"
+      />
+      <van-popup
+          v-model:show="showCouponList"
+          round
+          position="bottom"
+          style="height: 90%; padding-top: 4px;"
+      >
+        <van-coupon-list
+            :coupons="usableCoupons"
+            :chosen-coupon="chosenCouponIndex"
+            :disabled-coupons="unusableCoupons"
+            @change="onCouponChange"
+            :show-exchange-bar="false"
+        />
+      </van-popup>
+
+      <div style="margin-top: 32px">
+        <van-button block type="success" @click="weChatPay" :disabled="countdownFinished">微信支付</van-button>
+      </div>
+    </div>
+  </window-size>
+</template>
+
+<script setup>
+import store from "../../store";
+import {computed, onMounted, ref} from "vue";
+import {getMyCoupons} from "../../api/coupon";
+import {createPayOrder, queryOrderState} from "../../api/wx-jsapi";
+import router from "../../router";
+import PaymentCountdown from '../../components/countdown-for-payment/index.vue'
+
+const countdownFinished = ref(false)
+const createOrderRequest = store.getters.getCreateOrderRequest
+
+const psnCashpayAmt = computed(() => {
+  let cashpayAmt = createOrderRequest.totalFee - createOrderRequest.fundpayAmt -
+      createOrderRequest.acctpayAmt - createOrderRequest.couponAmt
+  cashpayAmt = cashpayAmt < 0 ? 0 : cashpayAmt
+  createOrderRequest.cashpayAmt = cashpayAmt
+  return makeMoneyStyle(cashpayAmt)
+})
+
+const showCouponList = ref(false);
+const chosenCouponIndex = ref(-1);
+const usableCoupons = ref([])
+const unusableCoupons = ref([])
+
+const onCouponChange = (index) => {
+  showCouponList.value = false;
+  chosenCouponIndex.value = index;
+  if (index === -1) {
+    createOrderRequest.couponId = null
+    createOrderRequest.couponAmt = 0
+  } else {
+    const coupon = usableCoupons.value[index]
+    createOrderRequest.couponId = coupon.id
+    createOrderRequest.couponAmt = coupon.value / 100
+  }
+}
+
+function makeMoneyStyle(m) {
+  return '¥' + m.toFixed(2)
+}
+
+function weChatPay() {
+  createPayOrder(createOrderRequest).then((order) => {
+    createOrderRequest.tradeNo = order.tradeNo
+    store.commit('SET_YJREQNO', null)
+    if (createOrderRequest.cashpayAmt === 0) {
+      queryOrderTradeState(order.tradeNo)
+    } else {
+      executePaymentAction(order)
+    }
+  })
+}
+
+function executePaymentAction(order) {
+  WeixinJSBridge.invoke('getBrandWCPayRequest', {
+    appId: order.appId,
+    timeStamp: order.timeStamp,
+    nonceStr: order.serialNo,
+    package: order.prepayId,
+    signType: order.signType,
+    paySign: order.paySign,
+    totalFee: order.totalFee,
+  }, () => {
+    queryOrderTradeState(order.tradeNo)
+  })
+}
+
+function queryOrderTradeState(tradeNo) {
+  queryOrderState(tradeNo).then((response) => {
+    createOrderRequest.payTime = response
+    store.dispatch({
+      type: 'storeCreateOrderRequest',
+      createOrderRequest
+    }).then(() => {
+      router.push('/paymentSuccess');
+    })
+  })
+}
+
+onMounted(() => {
+  const hisOrdNum = createOrderRequest.hisOrdNum || 'NONE'
+  getMyCoupons(hisOrdNum).then(res => {
+    usableCoupons.value = res.usableCoupons
+    unusableCoupons.value = res.unusableCoupons
+  })
+})
+</script>
+
+<style scoped>
+.to-be-paid-wrapper {
+  padding: 6px 12px 12px 12px;
+  border-radius: 8px;
+  box-shadow: #777777 1px 0 3px 0;
+  margin: 12px;
+  background-color: white;
+}
+
+.to-be-paid-wrapper > .label {
+  font-size: 14px;
+  color: #7a7a7a;
+  padding: 16px 0;
+  border-bottom: 1px solid #e1e1e1;
+}
+
+.label > span {
+  color: #333333;
+}
+
+.to-be-paid-wrapper .money {
+  margin-top: 8px;
+  font-size: 26px;
+  font-weight: bold;
+  color: orangered;
+}
+
+.money-box {
+  border: none!important;
+  position: relative;
+}
+
+.detail-box{
+  font-size: 10px;
+  position: absolute;
+  right: 0;
+  top: 0;
+  height: 100%;
+  display: flex;
+  align-items: center;
+}
+</style>

+ 283 - 0
src/views/public-pages/PaymentSuccess.vue

@@ -0,0 +1,283 @@
+<template>
+  <div style="height: 100vh">
+    <van-nav-bar title="支付完成" @click-right="closePage">
+      <template #right>
+        <van-icon name="close" size="18" /><span class="nav-bar-text">关闭</span>
+      </template>
+    </van-nav-bar>
+
+    <div style="background-color: white; padding: 12px 0">
+      <div class="icon-wrapper">
+        <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon-success">
+          <path fill="currentColor" d="M512 64a448 448 0 1 1 0 896 448 448 0 0 1 0-896zm-55.808 536.384-99.52-99.584a38.4 38.4 0 1 0-54.336 54.336l126.72 126.72a38.272 38.272 0 0 0 54.336 0l262.4-262.464a38.4 38.4 0 1 0-54.272-54.336L456.192 600.384z"></path>
+        </svg>
+        <div class="result_title">
+          <p>支付成功</p>
+        </div>
+      </div>
+
+      <div class="pay-brief-wrapper">
+        <div class="brief-line">
+          <div class="left-column">
+            就诊人:
+          </div>
+          <div class="right-column">
+            {{createOrderRequest.patientName}}
+          </div>
+        </div>
+        <div class="brief-line">
+          <div class="left-column">
+            门诊ID:
+          </div>
+          <div class="right-column">
+            {{createOrderRequest.patientId}}
+          </div>
+        </div>
+        <div class="brief-line">
+          <div class="left-column">
+            缴费类别:
+          </div>
+          <div class="right-column">
+            {{createOrderRequest.body}}
+          </div>
+        </div>
+        <div class="brief-line">
+          <div class="left-column">
+            支付金额:
+          </div>
+          <div class="right-column money-color">
+            ¥{{createOrderRequest.cashpayAmt}}
+          </div>
+        </div>
+        <div class="brief-line">
+          <div class="left-column">
+            支付时间:
+          </div>
+          <div class="right-column">
+            {{createOrderRequest.payTime}}
+          </div>
+        </div>
+      </div>
+      <div style="text-align: center;margin: 24px 0 12px 0">
+        <van-button size="small" type="warning" plain round
+                    style="width:120px" @click="checkMyOrder">
+          查看订单
+        </van-button>
+        <van-button size="small" type="warning" round
+                    style="width:120px;margin-left: 12px"
+                    @click="toHome">
+          回到首页
+        </van-button>
+      </div>
+    </div>
+
+    <div v-if="createOrderRequest.orderType === 2" class="comment-wrapper">
+      <div class="comment-bar-title">
+        <div class="comment-bar-title_icon">
+          <van-icon name="comment" />
+        </div>
+        <div class="comment-bar-title_text">
+          服务评价
+        </div>
+        <div class="comment-bar-title_subtext">
+          请为本次医生服务进行评价
+        </div>
+      </div>
+
+      <div class="comment-content-box">
+        <div>
+          <span style="color: #333333; font-size: 14px">评分:</span>
+          <van-rate
+              v-model="comment.commentLevel"
+              :size="20"
+              color="#ffd21e"
+              void-icon="star"
+              void-color="#eee"
+          />
+          <span style="margin-left: 12px; font-size: 12px; color: rgb(255,0,0)">({{rateLevelExplain}})</span>
+        </div>
+        <van-field
+            v-model="comment.commentContent"
+            rows="3"
+            autosize
+            type="textarea"
+            placeholder="您对医生的服务还有哪些建议或意见"
+            style="border: 1px solid lightgray; border-radius: 5px; margin-top: 12px"
+        />
+        <div class="comment-submit-box">
+          <van-button size="small" round type="danger" plain
+                      :disabled="disableSubmitComment"
+                      style="width: 120px" @click="submitComment">
+            提交
+          </van-button>
+        </div>
+      </div>
+    </div>
+
+    <van-popup v-model:show="showOrderDetail" position="top" :style="{ height: '100%' }">
+      <wx-order-detail @close="showOrderDetail = false" />
+    </van-popup>
+  </div>
+</template>
+
+<script setup>
+import {useRouter} from "vue-router";
+import store from "../../store";
+import {computed, reactive, ref} from "vue";
+import {commitNewComment} from "../../api/comment";
+import {showToast} from "vant";
+import WxOrderDetail from '../../components/wx-order-detail/index.vue'
+
+const router = useRouter()
+const createOrderRequest = store.getters.getCreateOrderRequest
+if (!createOrderRequest.patientId) {
+  router.push('/404')
+}
+
+function toHome() {
+  window.open('https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxbde6b16acad84204&redirect_uri=http://staticweb.hnthyy.cn/wxserver/redirect/page&response_type=code&scope=snsapi_base&state=1#wechat_redirect')
+}
+
+function closePage() {
+  WeixinJSBridge.call('closeWindow')
+}
+
+const comment = reactive({
+  commentLevel: 5,
+  commentContent: '',
+  doctorName: '',
+  hisOrdNum: '',
+  patientName: '',
+  patientId: ''
+})
+
+const rateLevelExplain = computed(() => {
+  switch (comment.commentLevel) {
+    case 5:
+      return '非常满意'
+    case 4:
+      return '满意'
+    case 3:
+      return '一般'
+    case 2:
+      return '不满意'
+    case 1:
+      return '非常不满意'
+  }
+})
+
+const showOrderDetail = ref(false)
+function checkMyOrder() {
+  showOrderDetail.value = true
+}
+
+const disableSubmitComment = ref(false)
+function submitComment() {
+  comment.doctorCode = createOrderRequest.doctorCode
+  comment.doctorName = createOrderRequest.doctorName
+  comment.hisOrdNum = createOrderRequest.hisOrdNum
+  comment.patientId = createOrderRequest.patientId
+  comment.patientName = createOrderRequest.patientName
+  commitNewComment(comment).then(res => {
+    disableSubmitComment.value = true
+    showToast({
+      message: res,
+      position: 'top',
+    });
+  })
+}
+</script>
+
+<style scoped>
+.nav-bar-text {
+  color: #1989fa;
+  margin-left: 4px;
+}
+
+.icon-wrapper {
+  width: 100%;
+  text-align: center;
+}
+
+.icon-success {
+  color: #67c23a;
+  width: 64px;
+  height: 64px;
+}
+.result_title {
+  margin-top: 8px;
+}
+.result_title > p {
+  margin: 0;
+  font-size: 14px;
+  font-weight: bold;
+  color: #303133;
+  line-height: 1.3;
+}
+
+.pay-brief-wrapper {
+  margin-top: 20px;
+  text-align: center;
+  font-size: 14px;
+}
+.brief-line {
+  display: flex;
+  margin-bottom: 4px;
+}
+.brief-line > div {
+  flex: 1;
+}
+.left-column {
+  text-align: left;
+  padding-left: 20px;
+}
+.right-column {
+  text-align: right;
+  padding-right: 20px;
+}
+.money-color {
+  color: orangered;
+}
+
+.comment-wrapper {
+  background-image: linear-gradient(#fca46d, #fcd5b3);
+  margin: 24px 12px;
+  border-radius: 10px;
+  padding-bottom: 12px;
+}
+
+.comment-bar-title {
+  display: flex;
+  align-items: center;
+  padding: 4px 0 2px 16px;
+}
+
+.comment-bar-title_icon {
+  color: #dc2424;
+  font-size: 18px;
+  margin-top: 3px;
+}
+.comment-bar-title_text {
+  color: #dc2424;
+  margin-left: 6px;
+  font-size: 14px;
+  line-height: 30px;
+}
+.comment-bar-title_subtext {
+  margin-left: 8px;
+  font-size: 12px;
+  color: white;
+  line-height: 30px;
+}
+.comment-content-box {
+  background-color: white;
+  margin: 0 12px;
+  padding: 12px;
+}
+
+.comment-submit-box {
+  width: 100%;
+  margin-top: 12px;
+  text-align: center;
+}
+</style>