Prechádzať zdrojové kódy

Merge branch '医保移动支付'

lighter 1 rok pred
rodič
commit
7daa0cc2fc

+ 1 - 0
package.json

@@ -4,6 +4,7 @@
   "scripts": {
     "dev": "vite",
     "build": "vite build",
+    "build:dev": "vite build --mode=development",
     "serve": "vite preview"
   },
   "dependencies": {

+ 33 - 0
src/api/medins-mobile-pay.js

@@ -0,0 +1,33 @@
+import request from '../utils/request'
+
+export function lockOrder(data) {
+    return request({
+        url: '/api/mobilePayPlugin/lockOrder',
+        method: 'post',
+        data,
+    })
+}
+
+export function medInsRegister(hisOrdNum) {
+    return request({
+        url: '/medInsMobilePay/medInsRegister',
+        method: 'get',
+        params: {hisOrdNum},
+    })
+}
+
+export function medInsUploadCost(data) {
+    return request({
+        url: '/medInsMobilePay/medInsUploadCost',
+        method: 'post',
+        data,
+    })
+}
+
+export function medInsPreSettle(data) {
+    return request({
+        url: '/medInsMobilePay/medInsPreSettle',
+        method: 'post',
+        data,
+    })
+}

+ 308 - 0
src/views/hospital-service/pay-mz-fee/UnPaidList-back.vue

@@ -0,0 +1,308 @@
+<template>
+  <window-size>
+    <van-empty :image="empty" description="您没有待缴费记录" v-if="showEmpty"></van-empty>
+    <div v-for="item in unpaidFees" :key="item.hisOrdNum">
+      <van-cell
+          :title="makeTitle(item)"
+          :label="item.priceTime"
+          is-link
+          center
+          @click="handleClickHisItem(item)">
+        <template #default>
+          <span style="color: orangered">{{ makeMoney(item.totalAmt) }}</span>
+        </template>
+      </van-cell>
+      <div style="height: 5px"></div>
+    </div>
+    <van-popup v-model:show="showPayMethodPicker" position="bottom">
+      <van-picker
+          :columns="payMethodColumns"
+          @cancel="showPayMethodPicker = false"
+          @confirm="handleConfirmPayMethod"
+      ></van-picker>
+    </van-popup>
+
+      <van-overlay :show="showOverlay" z-index="9999">
+
+        <div class="med-ins-mobile-pay">
+          <div class="wrapper">
+            <div class="block">
+              <div class="title">正在为您办理医保业务,请耐心等待</div>
+              <van-steps :active="currentStep">
+                <van-step v-for="item in progressText">
+                  {{ item }}
+                </van-step>
+              </van-steps>
+              <div style="height: 50px"></div>
+              <van-loading
+                  v-if="currentStep < 3"
+                  type="spinner"
+                  color="#1989fa"
+                  size="45px"
+                  vertical
+              >
+                {{loadingText[currentStep+1]}}
+              </van-loading>
+              <div v-if="currentStep >= 3">
+                <div class="fund-title">
+                  试算结束,以下为医保明细:
+                </div>
+                <div class="fund-detail">
+                  <div>
+                    医疗总计金额:¥{{fundDetail.feeSumamt}}
+                  </div>
+                  <div>
+                    医保报销金额:¥{{fundDetail.fundPay}}
+                  </div>
+                </div>
+                <div class="fund-detail">
+                  <div>
+                    个账支付金额:¥{{fundDetail.psnAcctPay}}
+                  </div>
+                  <div>
+                    现金支付金额:
+                    <span style="color: orangered">
+                      ¥{{fundDetail.ownPayAmt}}
+                    </span>
+                  </div>
+                </div>
+                <div class="pay-button">
+                  <van-button
+                      type="success"
+                      size="small"
+                      style="width: 180px"
+                  >
+                    前往支付(¥{{fundDetail.ownPayAmt}})
+                  </van-button>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+
+      </van-overlay>
+
+
+  </window-size>
+</template>
+
+<script setup>
+import {getFundPayAmt, getUnPaidFee} from '@/api/pay-mz-fee'
+import empty from '@/assets/empty.png'
+import {useRouter} from 'vue-router'
+import {computed, onMounted, ref} from 'vue'
+import {getOpenid,medInsRegister,medInsUploadCost,medInsPreSettle} from "@/api/medins-mobile-pay";
+
+const router = useRouter()
+const patientId = router.currentRoute.value.params.patientId
+const unpaidFees = ref([])
+const showEmpty = computed(() => {
+  return unpaidFees.value.length === 0
+})
+
+const currentHisItem = ref({})
+function handleClickHisItem(item) {
+  localStorage.setItem('hisOrdNum', item.hisOrdNum)
+  currentHisItem.value = item
+  showPayMethodPicker.value = true
+}
+
+const beforeToWxPay = (item) => {
+  getFundPayAmt(item.hisOrdNum).then(res => {
+    const routeParams = {
+      patientId: patientId,
+      hisOrdNum: item.hisOrdNum,
+      patientName: item.patName,
+      deptName: item.deptName,
+      doctorCode: item.doctorCode,
+      doctorName: item.doctorName,
+      totalAmt: item.totalAmt,
+      fundPay: res.fundPaySumamt,
+      acctPay: res.acctPay,
+      selfAmt: item.totalAmt - res.fundPaySumamt - res.acctPay
+    }
+    if (res.mdtrtId && !res.setlId) {
+      routeParams.mdtrtId = res.mdtrtId;
+      toMedinsSettle(routeParams);
+    } else {
+      toDetail(routeParams);
+    }
+  })
+}
+
+const toMedinsSettle = (params) => {
+  router.push({
+    name: 'medinsSettle',
+    params,
+  })
+}
+
+const toDetail = (params) => {
+  router.push({
+    name: 'unPaidDetail',
+    params,
+  })
+}
+
+function makeTitle(item) {
+  return item.deptName + ' | ' + item.doctorName
+}
+
+function makeMoney(money) {
+  const m = money / 100
+  return '¥' + m.toFixed(2)
+}
+
+const showPayMethodPicker = ref(false)
+const payMethodColumns = [
+  {text: '医保支付(限本人)', value: 'YB'},
+  {text: '微信支付', value: 'WX'}
+]
+
+function handleConfirmPayMethod({selectedValues}) {
+  const payMethod = selectedValues[0]
+  if (payMethod === 'YB') {
+    askForMedinsAuth()
+  } else {
+    beforeToWxPay(currentHisItem.value)
+  }
+}
+
+function askForMedinsAuth() {
+  location.href = 'https://exp.wecity.qq.com/oauth/code?' +
+      'authType=2&' +
+      'isDepart=2&' +
+      'appid=wxbde6b16acad84204&' +
+      'cityCode=430100&' +
+      'channel=AAGt1YEW0gQit2g7flFIZ13K&' +
+      'orgChnlCrtfCodg=BqK1kMStlhVDgN2uHf4EsLK/F2LjZPYJ81nK2eYQqxuRcOtN/4mSdyZLhMkSo4hy&' +
+      'orgCodg=H43010500370&' +
+      'bizType=04107&' +
+      'orgAppId=1I14E7CSC05E4460C80A0000D6788E13&' +
+      'redirectUrl=https://staticweb.hnthyy.cn/unPaidList/' + patientId
+}
+
+const authCode = ref('')
+const showOverlay = ref(false)
+const currentStep = ref(-1)
+const progressText = ref([
+  '查询参保信息',
+  '医保登记',
+  '费用上传',
+  '医保试算',
+])
+const loadingText = ref([
+  '正在查询参保信息...',
+  '正在办理医保登记...',
+  '正在进行费用上传...',
+  '正在进行医保试算...',
+  ''
+])
+const fundDetail = ref({})
+function startMedInsMobilePay() {
+  showOverlay.value = true
+  const hisOrdNum = localStorage.getItem('hisOrdNum')
+  getOpenid({
+    hisOrdNum,
+    authCode: authCode.value,
+  }).then(wxUser => {
+    currentStep.value += 1
+
+    medInsRegister(hisOrdNum).then(mdtrtId => {
+      currentStep.value += 1
+
+      medInsUploadCost({
+        hisOrdNum,
+        payAuthNo: wxUser.pay_auth_no,
+        userLongLat: wxUser.user_longitude_latitude
+      }).then(orderInfo => {
+        currentStep.value += 1
+
+        medInsPreSettle(orderInfo).then(res4 => {
+          currentStep.value += 1
+          fundDetail.value = res4
+        }).catch(e => {
+          currentStep.value = -1
+          showOverlay.value = false
+        })
+      }).catch(e => {
+        currentStep.value = -1
+        showOverlay.value = false
+      })
+
+    }).catch(e => {
+      currentStep.value = -1
+      showOverlay.value = false
+    })
+
+  }).catch(e => {
+    currentStep.value = -1
+    showOverlay.value = false
+  })
+}
+
+onMounted(() => {
+  getUnPaidFee(patientId).then((res) => {
+    unpaidFees.value = res
+    let hisOrdNum = localStorage.getItem('hisOrdNum')
+    if (hisOrdNum) {
+      for (let i = 0; i < res.length; i++) {
+        if (res[i].hisOrdNum === hisOrdNum) {
+          currentHisItem.value = res[i]
+        }
+      }
+    }
+  })
+  const queryParams = router.currentRoute.value.query
+  if (queryParams.retCode === '0') {
+    authCode.value = queryParams.authCode
+    startMedInsMobilePay()
+  }
+})
+
+</script>
+
+<style lang="scss">
+.med-ins-mobile-pay {
+  .wrapper {
+    width: 100vw;
+    height: 100vh;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+  .block {
+    border-radius: 8px;
+    width: 90%;
+    background-color: #fff;
+    padding-bottom: 80px;
+    .title {
+      padding: 20px 8px;
+      font-weight: bold;
+      margin-bottom: 30px;
+    }
+    .fund-title {
+      width: 100%;
+      text-align: center;
+      background-color: lightgrey;
+      padding: 4px 0;
+      font-size: 14px;
+      margin-bottom: 24px;
+    }
+    .fund-detail {
+      width: 100%;
+      display: flex;
+      > div {
+        font-size: 12px;
+        padding-left: 30px;
+        width: 50%;
+      }
+    }
+    .pay-button {
+      width: 100%;
+      text-align: center;
+      margin-top: 24px;
+    }
+  }
+}
+</style>

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

@@ -7,21 +7,30 @@
           :label="item.priceTime"
           is-link
           center
-          @click="onClickFeeItem(item)">
+          @click="handleClickHisItem(item)">
         <template #default>
           <span style="color: orangered">{{ makeMoney(item.totalAmt) }}</span>
         </template>
       </van-cell>
       <div style="height: 5px"></div>
     </div>
+    <van-popup v-model:show="showPayMethodPicker" position="bottom">
+      <van-picker
+          :columns="payMethodColumns"
+          @cancel="showPayMethodPicker = false"
+          @confirm="handleConfirmPayMethod"
+      ></van-picker>
+    </van-popup>
   </window-size>
 </template>
 
 <script setup>
-import {getFundPayAmt, getUnPaidFee} from '@/api/pay-mz-fee'
+import {getUnPaidFee} from '@/api/pay-mz-fee'
 import empty from '@/assets/empty.png'
-import { useRouter } from 'vue-router'
-import { computed, onMounted, ref } from 'vue'
+import {useRouter} from 'vue-router'
+import {computed, onMounted, ref} from 'vue'
+import {lockOrder} from "@/api/medins-mobile-pay";
+import store from "@/store";
 
 const router = useRouter()
 const patientId = router.currentRoute.value.params.patientId
@@ -30,37 +39,28 @@ const showEmpty = computed(() => {
   return unpaidFees.value.length === 0
 })
 
-const onClickFeeItem = (item) => {
-  getFundPayAmt(item.hisOrdNum).then(res => {
-    const routeParams = {
-      patientId: patientId,
-      hisOrdNum: item.hisOrdNum,
-      patientName: item.patName,
-      deptName: item.deptName,
-      doctorCode: item.doctorCode,
-      doctorName: item.doctorName,
-      totalAmt: item.totalAmt,
-      fundPay: res.fundPaySumamt,
-      acctPay: res.acctPay,
-      selfAmt: item.totalAmt - res.fundPaySumamt - res.acctPay
-    }
-    if (res.mdtrtId && !res.setlId) {
-      routeParams.mdtrtId = res.mdtrtId;
-      toMedinsSettle(routeParams);
-    } else {
-      toDetail(routeParams);
-    }
-  })
-}
+const showPayMethodPicker = ref(false)
 
-const toMedinsSettle = (params) => {
-  router.push({
-    name: 'medinsSettle',
-    params,
-  })
+const currentHisItem = ref({})
+function handleClickHisItem(item) {
+  localStorage.setItem('hisOrdNum', item.hisOrdNum)
+  currentHisItem.value = item
+  showPayMethodPicker.value = true
 }
 
-const toDetail = (params) => {
+const toWxPay = (item) => {
+  const params = {
+    patientId: patientId,
+    hisOrdNum: item.hisOrdNum,
+    patientName: item.patName,
+    deptName: item.deptName,
+    doctorCode: item.doctorCode,
+    doctorName: item.doctorName,
+    totalAmt: item.totalAmt,
+    fundPay: 0,
+    acctPay: 0,
+    selfAmt: item.totalAmt
+  }
   router.push({
     name: 'unPaidDetail',
     params,
@@ -76,10 +76,87 @@ function makeMoney(money) {
   return '¥' + m.toFixed(2)
 }
 
+const payMethodColumns = [
+  {text: '微信支付', value: 'WX'},
+  {text: '医保支付(限本人)', value: 'YB'}
+]
+
+function handleConfirmPayMethod({selectedValues}) {
+  const payMethod = selectedValues[0]
+  const hisOrdNum = localStorage.getItem('hisOrdNum')
+  lockOrder({hisOrdNum}).then(openid => {
+    store.commit('SET_LOADING', true);
+    if (payMethod === 'YB') {
+      startMedInsMobilePay(openid)
+    } else {
+      toWxPay(currentHisItem.value)
+    }
+  })
+}
+
+function startMedInsMobilePay(openid) {
+  location.href = 'https://pss.ybj.hunan.gov.cn' +
+      '/pss-hunan-h5/mobilePayment/paymentRecordList?' +
+      'channelCode=d32IFCxMsT&openId=' + openid
+}
+
 onMounted(() => {
   getUnPaidFee(patientId).then((res) => {
     unpaidFees.value = res
+    let hisOrdNum = localStorage.getItem('hisOrdNum')
+    if (hisOrdNum) {
+      for (let i = 0; i < res.length; i++) {
+        if (res[i].hisOrdNum === hisOrdNum) {
+          currentHisItem.value = res[i]
+        }
+      }
+    }
   })
 })
 
-</script>
+</script>
+
+<style lang="scss">
+.med-ins-mobile-pay {
+  .wrapper {
+    width: 100vw;
+    height: 100vh;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+  .block {
+    border-radius: 8px;
+    width: 90%;
+    background-color: #fff;
+    padding-bottom: 80px;
+    .title {
+      padding: 20px 8px;
+      font-weight: bold;
+      margin-bottom: 30px;
+    }
+    .fund-title {
+      width: 100%;
+      text-align: center;
+      background-color: lightgrey;
+      padding: 4px 0;
+      font-size: 14px;
+      margin-bottom: 24px;
+    }
+    .fund-detail {
+      width: 100%;
+      display: flex;
+      > div {
+        font-size: 12px;
+        padding-left: 30px;
+        width: 50%;
+      }
+    }
+    .pay-button {
+      width: 100%;
+      text-align: center;
+      margin-top: 24px;
+    }
+  }
+}
+</style>