1. 医生线下接诊创建就诊人、患者端扫码认领就诊人
2. 生成处方后医生代付码
This commit is contained in:
李琦
2026-08-09 14:36:22 +08:00
parent 53c6f3fcfd
commit 206f0aaa50
12 changed files with 558 additions and 119 deletions

92
App.vue
View File

@@ -15,6 +15,7 @@
silentLogin().then((loginResult) => {
if (loginResult.success) {
this.tryHandlePendingSceneActions()
} else {
console.error('静默登录失败:', loginResult.message);
}
@@ -158,22 +159,28 @@
if (e === undefined)
return {};
const scene = decodeURIComponent(e.query.scene)
const rawScene = e.query && e.query.scene
? decodeURIComponent(e.query.scene)
: ''
// 这里接收扫码参数
if (scene) {
if (rawScene) {
// 就诊人认领cup={user_patient_id}
this.parseClaimPatientScene(rawScene)
// 医生代支付ppay={order_id}
this.parseProxyPayScene(rawScene)
// 判断scene中是否包含sal_id
let isSalespersonId = decodeURIComponent(e.query.scene).includes('sal_id');
const scene = decodeURIComponent(e.query.scene).split('STORE_QR_CODE_')
let isSalespersonId = rawScene.includes('sal_id');
const scene = rawScene.split('STORE_QR_CODE_')
if (scene[1]) {
uni.setStorageSync('stores_id', scene[1])
uni.setStorageSync('store_id', scene[1])
}
// uni.setStorageSync('stores_id', scene[1])
const st_id = decodeURIComponent(e.query.scene).split('&')
let store_id = decodeURIComponent(e.query.scene).split('STORE_QR_CODE_')
store_id = decodeURIComponent(store_id[1]).split('&')
const doctors_id = decodeURIComponent(e.query.scene).split('=')
if (store_id[0] !== 'undefined') {
const st_id = rawScene.split('&')
let store_id = rawScene.split('STORE_QR_CODE_')
store_id = decodeURIComponent(store_id[1] || '').split('&')
const doctors_id = rawScene.split('=')
if (store_id[0] && store_id[0] !== 'undefined') {
uni.setStorageSync('stores_id', store_id[0])
uni.setStorageSync('store_id', store_id[0])
}
@@ -192,25 +199,9 @@
console.log('userId', userId, st_id[0].split('su_id=')[1], res);
})
}
// 5.3 处理门店切换/设置
// const storeId = uni.getStorageSync('store_id');
// if (storeId) {
// storeChange({
// method: "post",
// data: {
// store_id: storeId
// }
// }).catch((err) => {
// console.error('切换门店失败:', err);
// });
// } else {
// uni.setStorageSync('store_id', res.data.data.data.store_id);
// }
// console.log(st_id, '4444111111111');
// console.log(scene, '4444');
}
// const scene = decodeURIComponent(e.query.scene).split('STORE_QR_CODE_')
// console.log(scene, '11111');
// 登录后触发认领弹窗 / 代付跳转
this.tryHandlePendingSceneActions()
},
onHide: function() {
// console.log('App Hide')
@@ -221,6 +212,51 @@
// uni.removeStorageSync('token')
},
methods: {
/**
* 解析就诊人认领 scenecup=123 或 up_id=123
*/
parseClaimPatientScene(rawScene) {
const cupMatch = String(rawScene).match(/(?:^|&)cup=(\d+)/)
const upMatch = String(rawScene).match(/(?:^|&)up_id=(\d+)/)
const id = Number((cupMatch && cupMatch[1]) || (upMatch && upMatch[1]) || 0)
if (id > 0) {
uni.setStorageSync('claim_user_patient_id', id)
}
},
/**
* 解析医生代支付 sceneppay=订单ID
* 新扫码时重置「已确认」标记,以便重新弹出确认框
*/
parseProxyPayScene(rawScene) {
const match = String(rawScene).match(/(?:^|&)ppay=(\d+)/)
const orderId = Number((match && match[1]) || 0)
if (orderId > 0) {
uni.setStorageSync('proxy_pay_order_id', orderId)
uni.removeStorageSync('proxy_pay_confirmed')
}
},
/**
* 登录后:弹出认领模态 / 代付确认模态(不再直接跳转代付页)
*/
tryHandlePendingSceneActions() {
const token = uni.getStorageSync('token')
if (!token) return
const claimId = Number(uni.getStorageSync('claim_user_patient_id') || 0)
if (claimId > 0) {
// 通知首页等挂载了认领弹窗的页面打开
setTimeout(() => {
uni.$emit('open-claim-patient-modal')
}, 400)
}
const proxyOrderId = Number(uni.getStorageSync('proxy_pay_order_id') || 0)
const proxyConfirmed = Number(uni.getStorageSync('proxy_pay_confirmed') || 0) === 1
// 有代付扫码且尚未确认:弹确认框;已确认过则不自动跳(避免反复打断)
if (proxyOrderId > 0 && !proxyConfirmed) {
setTimeout(() => {
uni.$emit('open-proxy-pay-confirm-modal')
}, 500)
}
},
initWebSocket() {
webSocketManager.connect();

View File

@@ -0,0 +1,147 @@
<template>
<!-- 居中模态框确认认领非底部抽屉 -->
<u-modal
v-model="show"
title="认领就诊人"
:content="modalContent"
:show-cancel-button="true"
confirm-text="确认认领"
cancel-text="取消"
confirm-color="#0d9488"
:mask-close-able="false"
@confirm="onConfirm"
@cancel="onClose"
></u-modal>
</template>
<script>
import { claimPatientApi } from '@/request/api/patient.js'
import { unwrapXkApi } from '@/utils/api-response.js'
import { registePay } from '@/request/api/api.js'
/**
* 扫码认领医生创建的就诊人(居中 u-modal
* App.vue 写入 claim_user_patient_id 后弹出
*/
export default {
name: 'ClaimPatientModal',
data() {
return {
show: false,
userPatientId: 0,
needPay: false,
price: '0',
registerId: 0,
claiming: false,
}
},
computed: {
modalContent() {
const id = this.userPatientId || '—'
let text = '医生为您创建了就诊人档案就诊人ID' + id + '),确认后绑定到当前微信账号。'
if (this.needPay) {
text += '需支付挂号费:¥' + this.price + '。'
}
return text
},
},
methods: {
/**
* 对外打开:读取 storage 中的认领 ID
*/
openFromStorage() {
const id = Number(uni.getStorageSync('claim_user_patient_id') || 0)
if (id < 1) return
const token = uni.getStorageSync('token')
if (!token) return
this.userPatientId = id
this.needPay = false
this.price = '0'
this.registerId = 0
this.show = true
},
/**
* 取消认领:关闭并清理扫码标记
*/
onClose() {
this.show = false
uni.removeStorageSync('claim_user_patient_id')
},
/**
* 确认认领;若有未付挂号费则拉起支付
*/
async onConfirm() {
if (this.claiming || this.userPatientId < 1) return
this.claiming = true
try {
const res = await claimPatientApi({ user_patient_id: this.userPatientId })
const { ok, payload, message } = unwrapXkApi(res)
if (!ok) {
uni.showToast({ title: message || '认领失败', icon: 'none' })
// 失败重新打开,允许重试
this.show = true
return
}
const needPay = Number(payload && payload.need_pay_register) === 1
const registerId = Number(payload && payload.register_id) || 0
const price = (payload && payload.price) || '0'
uni.removeStorageSync('claim_user_patient_id')
if (needPay && registerId > 0) {
this.needPay = true
this.registerId = registerId
this.price = String(price)
this.show = false
await this.payRegister(registerId)
} else {
uni.showToast({ title: '认领成功', icon: 'success' })
this.show = false
}
} catch (e) {
uni.showToast({ title: (e && e.message) || '认领失败', icon: 'none' })
this.show = true
} finally {
this.claiming = false
}
},
/**
* 认领后支付挂号费xk-api register/pay
*/
async payRegister(registerId) {
try {
const res = await registePay({
method: 'post',
data: { register_id: registerId },
})
if (res.data && (res.data.errcode == 0 || res.data.errcode === '0')) {
const data = res.data.data || {}
if (data.is_paid == 1 || data.is_pay == 1) {
uni.showToast({ title: '认领成功', icon: 'success' })
return
}
uni.requestPayment({
provider: data.appId,
timeStamp: data.timestamp || data.timeStamp,
nonceStr: data.nonceStr,
package: data.package,
signType: data.signType,
paySign: data.paySign,
success: () => {
uni.showToast({ title: '支付成功', icon: 'success' })
},
fail: () => {
uni.showToast({ title: '已认领,挂号费未支付', icon: 'none' })
},
})
} else {
uni.showToast({
title: (res.data && (res.data.message || res.data.msg)) || '获取支付参数失败',
icon: 'none',
})
}
} catch (e) {
uni.showToast({ title: '支付发起失败', icon: 'none' })
}
},
},
}
</script>

View File

@@ -0,0 +1,83 @@
<template>
<!-- 居中模态框确认代付非底部抽屉 -->
<u-modal
v-model="show"
title="医生代付确认"
:content="modalContent"
:show-cancel-button="true"
confirm-text="确认代付"
cancel-text="取消代付"
confirm-color="#0d9488"
:mask-close-able="false"
@confirm="onConfirm"
@cancel="onCancel"
></u-modal>
</template>
<script>
/**
* 扫码代付前确认模态框
* App.vue 写入 proxy_pay_order_id 后弹出;取消则清理 storage
*/
export default {
name: 'ProxyPayConfirmModal',
data() {
return {
show: false,
orderId: 0,
}
},
computed: {
modalContent() {
const id = this.orderId || '—'
return '医生邀请您代为支付药品订单订单ID' + id + ')。确认后进入支付页;取消则清除本次扫码,下次进入小程序不会再跳转。'
},
},
methods: {
/**
* 清理本次代付扫码会话storage
*/
clearProxyPaySession() {
uni.removeStorageSync('proxy_pay_order_id')
uni.removeStorageSync('proxy_pay_confirmed')
},
/**
* 对外打开:读取 storage 中的代付订单 ID
*/
openFromStorage() {
const id = Number(uni.getStorageSync('proxy_pay_order_id') || 0)
if (id < 1) return
// 已确认过并进过支付页:不再弹窗(避免首页 onShow 反复打断)
if (Number(uni.getStorageSync('proxy_pay_confirmed') || 0) === 1) return
const token = uni.getStorageSync('token')
if (!token) return
this.orderId = id
this.show = true
},
/**
* 取消代付:清理扫码标记,下次进小程序不再跳转
*/
onCancel() {
this.clearProxyPaySession()
this.show = false
uni.showToast({ title: '已取消代付', icon: 'none' })
},
/**
* 确认后进入订单支付页(保留 proxy_pay_order_id 供支付接口使用)
*/
onConfirm() {
const orderId = this.orderId || Number(uni.getStorageSync('proxy_pay_order_id') || 0)
if (orderId < 1) {
this.clearProxyPaySession()
this.show = false
return
}
uni.setStorageSync('proxy_pay_confirmed', 1)
this.show = false
uni.navigateTo({
url: '/subPackages/my/record-pay?order_id=' + orderId + '&proxy_pay=1',
})
},
},
}
</script>

View File

@@ -7,6 +7,8 @@
"^u-(.*)": "uview-ui/components/u-$1/u-$1.vue",
// 消息通知组件
"^MessageNotification": "@/components/MessageNotification/MessageNotification.vue",
"^ClaimPatientModal$": "@/components/claim-patient-modal/claim-patient-modal.vue",
"^ProxyPayConfirmModal$": "@/components/proxy-pay-confirm-modal/proxy-pay-confirm-modal.vue",
"^FollowUpDrugDrawer$": "@/subPackages/doctor/components/FollowUpDrugDrawer.vue",
// 列表骨架屏(分包组件,主包页需配合 componentPlaceholder
"^ListSkeleton$": "@/subPackages/common/components/ListSkeleton.vue",

View File

@@ -2,6 +2,8 @@
<view class="content safe-area-inset-bottom">
<!-- 全局消息通知组件 -->
<MessageNotification />
<ClaimPatientModal ref="claimPatientModal" />
<ProxyPayConfirmModal ref="proxyPayConfirmModal" />
<image-compress-popup ref="imageCompressPopup" />
<!-- 1. 自定义吸顶导航栏 -->
@@ -330,6 +332,8 @@ import { getSpecialPrescriptionHomeApi } from '@/request/api/specialPrescription
import { fetchUnpaidRegisterListApi } from '@/request/api/register';
import request from "@/request/api/request";
import MessageNotification from "@/components/MessageNotification/MessageNotification.vue";
import ClaimPatientModal from "@/components/claim-patient-modal/claim-patient-modal.vue";
import ProxyPayConfirmModal from "@/components/proxy-pay-confirm-modal/proxy-pay-confirm-modal.vue";
import ImageCompressPopup from '@/components/image-compress-popup/image-compress-popup.vue';
import { registerImageCompressPopup } from '@/utils/image-compress-modal.js';
import { setGuestMode, isGuestMode, isLoggedIn } from '@/common/utils/auth.js';
@@ -338,6 +342,8 @@ import {silentLogin} from "@/utils/login";
export default {
components: {
MessageNotification,
ClaimPatientModal,
ProxyPayConfirmModal,
ImageCompressPopup,
},
data() {
@@ -931,7 +937,21 @@ export default {
} catch (error) {
console.error('获取默认医生ID失败:', error);
}
}
},
/** 打开扫码认领就诊人弹窗 */
openClaimPatientModal() {
const modal = this.$refs.claimPatientModal;
if (modal && modal.openFromStorage) {
modal.openFromStorage();
}
},
/** 打开医生代付确认弹窗 */
openProxyPayConfirmModal() {
const modal = this.$refs.proxyPayConfirmModal;
if (modal && modal.openFromStorage) {
modal.openFromStorage();
}
},
},
onShow() {
this.storeId = uni.getStorageSync('store_id');
@@ -945,6 +965,16 @@ export default {
this.getDefaultDoctorId();
this.fetchUnpaidCounts();
this.fetchSpecialPrescriptionHome();
this.openClaimPatientModal();
this.openProxyPayConfirmModal();
},
mounted() {
uni.$on('open-claim-patient-modal', this.openClaimPatientModal);
uni.$on('open-proxy-pay-confirm-modal', this.openProxyPayConfirmModal);
},
onUnload() {
uni.$off('open-claim-patient-modal', this.openClaimPatientModal);
uni.$off('open-proxy-pay-confirm-modal', this.openProxyPayConfirmModal);
},
}
</script>

View File

@@ -1,6 +1,8 @@
<template>
<view class="content safe-area-inset-bottom">
<MessageNotification />
<ClaimPatientModal ref="claimPatientModal" />
<ProxyPayConfirmModal ref="proxyPayConfirmModal" />
<view class="head" @click="gologin">
<!-- 门店 -->
<view class="store">
@@ -239,11 +241,37 @@
}
})
},
/** 打开扫码认领就诊人弹窗 */
openClaimPatientModal() {
const modal = this.$refs.claimPatientModal
if (modal && modal.openFromStorage) {
modal.openFromStorage()
}
},
/** 打开医生代付确认弹窗 */
openProxyPayConfirmModal() {
const modal = this.$refs.proxyPayConfirmModal
if (modal && modal.openFromStorage) {
modal.openFromStorage()
}
},
},
mounted() {
this.getShow()
this.getList()
}
uni.$on('open-claim-patient-modal', this.openClaimPatientModal)
uni.$on('open-proxy-pay-confirm-modal', this.openProxyPayConfirmModal)
this.openClaimPatientModal()
this.openProxyPayConfirmModal()
},
onShow() {
this.openClaimPatientModal()
this.openProxyPayConfirmModal()
},
onUnload() {
uni.$off('open-claim-patient-modal', this.openClaimPatientModal)
uni.$off('open-proxy-pay-confirm-modal', this.openProxyPayConfirmModal)
},
}
</script>

View File

@@ -186,10 +186,10 @@ export async function registeInfo(params) {
return data
}
// 支付挂号
// 支付挂号xk-api register/pay易票联
export async function registePay(params) {
let data = await http('/oldApi/v1/register/pay', params)
return data
let data = await http('/xkApi/register/pay', params)
return normalizeXkApiResponse(data)
}
// 取消挂号
@@ -289,16 +289,16 @@ export async function getPrescriptInfo(params) {
return data
}
// 我的 处方支付
// 我的 处方支付xk-api
export async function getPrescriptPay(params) {
let data = await http('/oldApi/v1/product-order/pay', params)
return data
let data = await http('/xkApi/product-order/pay', params)
return normalizeXkApiResponse(data)
}
// 我的 处方-产品订单信息
// 我的 处方-产品订单信息xk-api appoint-medicine
export async function getProductInfo(params) {
let data = await http('/oldApi/v1/product-order/appoint-medicine', params)
return data
let data = await http('/xkApi/product-order/appoint-medicine', params)
return normalizeXkApiResponse(data)
}
// 消息
@@ -362,10 +362,21 @@ export async function getUseWayPay(params) {
return data
}
// 更新配送方式Laravel单品包邮重算
/**
* 更新配送方式xk-api单品包邮重算
* 代付时带 proxy_pay=1或与 getPayConfig 一样从 storage 自动附带
*/
export async function getDelivery(params) {
let data = await http('/xkApi/product-order/update-delivery', params)
return data
const payload = params && typeof params === 'object' ? { ...params } : { method: 'post', data: {} }
const data = payload.data && typeof payload.data === 'object' ? { ...payload.data } : {}
const orderId = Number(data.order_id || 0)
const proxyOrderId = Number(uni.getStorageSync('proxy_pay_order_id') || 0)
if (!data.proxy_pay && proxyOrderId > 0 && orderId === proxyOrderId) {
data.proxy_pay = 1
}
payload.data = data
let res = await http('/xkApi/product-order/update-delivery', payload)
return normalizeXkApiResponse(res)
}
// 更新代煎服务费用 http://xiaokang.com/member/v1/product-order/update-decoct-service
@@ -486,10 +497,21 @@ export async function PayList(params) {
// return data
// }
/**
* 商品订单支付xk-api
* 代付时在 data 中带 proxy_pay=1也可从 storage proxy_pay_order_id 自动附带
*/
export async function getPayConfig(params) {
let data = await http('/oldApi/v1/product-order/pay', params)
// let data = await http('/newApi/mobile/product-order/pay', params)
return data
const payload = params && typeof params === 'object' ? { ...params } : { method: 'post', data: {} }
const data = payload.data && typeof payload.data === 'object' ? { ...payload.data } : {}
const orderId = Number(data.order_id || 0)
const proxyOrderId = Number(uni.getStorageSync('proxy_pay_order_id') || 0)
if (!data.proxy_pay && proxyOrderId > 0 && orderId === proxyOrderId) {
data.proxy_pay = 1
}
payload.data = data
let res = await http('/xkApi/product-order/pay', payload)
return normalizeXkApiResponse(res)
}
// getOrdlist 获取订单列表 https://zjxk.app.ctkj88.com/member/order/lists
// export async function getOrdlist(params) {
@@ -508,10 +530,10 @@ export async function getCancle(params) {
// return data
// }
// 更换 订单详情 https://app.xiaokang88.com/member/v1/product-order/info
// 订单详情xk-api product-order/infodrug-info 页)
export async function getOrdDetail(params) {
let data = await http('/oldApi/v1/product-order/info', params)
return data
let data = await http('/xkApi/product-order/info', params)
return normalizeXkApiResponse(data)
}

View File

@@ -39,3 +39,8 @@ export async function changePatientDefaultApi(params = {}) {
export async function getPatientHealthInfoApi(params = {}) {
return await post('/patient/health-info', params, 3)
}
/** 扫码认领医生创建的就诊人 POST /patient/claim传 user_patient_id */
export async function claimPatientApi(params = {}) {
return await post('/patient/claim', params, 3)
}

View File

@@ -6,7 +6,7 @@
<text>{{ orderText }}</text>
</view>
<view class="head_cancle" v-if="orderInfo.ProductOrder.status!=0 && orderInfo.ProductOrder.cancel_status==1">
<view class="head_cancle" v-if="orderInfo.product_order.status!=0 && orderInfo.product_order.cancel_status==1">
订单已取消
</view>
<!-- 就诊人信息 -->
@@ -21,10 +21,10 @@
</view>
<!-- 快递自提 -->
<view class="_choose"
v-if="orderInfo.ProductOrder.status==0&&orderInfo.ProductOrder.is_pay==0 && orderInfo.ProductOrder.cancel_status==0">
v-if="orderInfo.product_order.status==0&&orderInfo.product_order.is_pay==0 && orderInfo.product_order.cancel_status==0">
<text>配送方式</text>
<view class="_fs" @click="toShowed">
<text>{{orderInfo.ProductOrder.delivery_method==0&&'快递到家'||orderInfo.ProductOrder.delivery_method==1&&'到店自取'}}</text>
<text>{{orderInfo.product_order.delivery_method==0&&'快递到家'||orderInfo.product_order.delivery_method==1&&'到店自取'}}</text>
<text class="iconfont icon-jiantou1"></text>
<u-action-sheet :list="list" v-model="toshowed" :tips="tips" border-radius="24"
:safe-area-inset-bottom="true" @click="chooseway"></u-action-sheet>
@@ -38,14 +38,14 @@
<view class="iconfont icon-jiantou1"></view>
</view>
</view>
<view class="name" @click="toChoose" v-if="!orderInfo.ProductOrder.address">
<view class="name" @click="toChoose" v-if="!orderInfo.product_order.address">
请先选择收货地址
</view>
<view class="name" @click="toChoose" v-if="orderInfo.ProductOrder.address">
<view class="name" @click="toChoose" v-if="orderInfo.product_order.address">
{{ parsedAddress.name || '请先选择收货地址' }}
{{ parsedAddress.mobile || '' }}
</view>
<view class="choose_area" v-if="orderInfo.ProductOrder.address">
<view class="choose_area" v-if="orderInfo.product_order.address">
{{ parsedAddress.region || '' }}{{ parsedAddress.detail_address || '' }}
</view>
</view>
@@ -65,7 +65,7 @@
</view>
<!-- 到店自取 -->
<view class="head" v-if="isshowed && orderInfo.ProductOrder.delivery_method == 1">
<view class="head" v-if="isshowed && orderInfo.product_order.delivery_method == 1">
<view class="state">
<text>到店自取</text>
</view>
@@ -85,8 +85,8 @@
<!-- granular -->
<view class="list"
v-if="orderInfo.ProductOrder.prescription_type==1">
<view class="it_" v-for="(item,index) in orderInfo.ProductOrderItems" :key="item.id">
v-if="orderInfo.product_order.prescription_type==1">
<view class="it_" v-for="(item,index) in orderInfo.product_order_items" :key="item.id">
<view class="it_name">{{item.drug_name}}
<text class="it_num" style="margin-left: 8rpx;">x{{item.number}}</text>
</view>
@@ -96,8 +96,8 @@
</view>
</view>
<view class="list_west" v-if="orderInfo.ProductOrder.prescription_type==2||orderInfo.ProductOrder.prescription_type==3||orderInfo.ProductOrder.prescription_type==5||orderInfo.ProductOrder.prescription_type==5||orderInfo.ProductOrder.prescription_type==6||orderInfo.ProductOrder.prescription_type==7">
<view class="list" v-for="(item,index) in orderInfo.ProductOrderItems" :key="item.id" @click.stop="goDrugDetail(item)">
<view class="list_west" v-if="orderInfo.product_order.prescription_type==2||orderInfo.product_order.prescription_type==3||orderInfo.product_order.prescription_type==5||orderInfo.product_order.prescription_type==5||orderInfo.product_order.prescription_type==6||orderInfo.product_order.prescription_type==7">
<view class="list" v-for="(item,index) in orderInfo.product_order_items" :key="item.id" @click.stop="goDrugDetail(item)">
<view class="img">
<image :src="item.drug_image || 'https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk-client-wx/static/empty/gwc.png'" mode=""></image>
</view>
@@ -109,7 +109,7 @@
class="drug-spec">{{ item.drug.specification }}</text>
<text v-if="item.drug && item.drug.function && canShowFunction(item.drug, prescriptionStatus)">{{ item.drug.function }}</text>
</view>
<view class="it_info" v-if="orderInfo.ProductOrder.prescription_type==2 && item.drug && canShowUsage(item.drug, prescriptionStatus)">
<view class="it_info" v-if="orderInfo.product_order.prescription_type==2 && item.drug && canShowUsage(item.drug, prescriptionStatus)">
{{ item.drug.usage }}
</view>
<!-- 有外部配送仓时按药展示配送来源含本仓药品 -->
@@ -134,32 +134,32 @@
<view class="goods">
<view class="good_">
<text>商品总价包含服务费</text>
<text class="price">{{orderInfo.ProductOrder.items_price}}</text>
<text class="price">{{orderInfo.product_order.items_price}}</text>
</view>
<view class="good_">
<text>快递费</text>
<text class="price">{{orderInfo.ProductOrder.trans_expenses}}</text>
<text class="price">{{orderInfo.product_order.trans_expenses}}</text>
</view>
<view class="good_">
<text>诊疗费</text>
<text class="price">{{orderInfo.ProductOrder.treatement_price}}</text>
<text class="price">{{orderInfo.product_order.treatement_price}}</text>
</view>
<view class="good_">
<text>加工费</text>
<view class="price"><text
v-if="payWay">{{payWay.dosage}}</text>{{orderInfo.ProductOrder.process_price}}</view>
v-if="payWay">{{payWay.dosage}}</text>{{orderInfo.product_order.process_price}}</view>
</view>
<view class="good_">
<text>总金额</text>
<view class="total">
合计:
<text class="price">{{orderInfo.ProductOrder.total_pay_price}}</text>
<text class="price">{{orderInfo.product_order.total_pay_price}}</text>
</view>
</view>
<view class="good_" v-if="orderInfo.ProductOrder&&orderInfo.ProductOrder.pay_time!='0'">
<view class="good_" v-if="orderInfo.product_order&&orderInfo.product_order.pay_time!='0'">
<text>支付时间</text>
<view class="price">
<text class="price">{{orderInfo.ProductOrder.pay_time | formatDate}}</text>
<text class="price">{{orderInfo.product_order.pay_time | formatDate}}</text>
</view>
</view>
</view>
@@ -194,7 +194,7 @@
<!-- 底部 -->
<view class="footer"
v-if="orderInfo.ProductOrder.status==0 && orderInfo.ProductOrder.is_pay==0 && orderInfo.ProductOrder.cancel_status==0">
v-if="orderInfo.product_order.status==0 && orderInfo.product_order.is_pay==0 && orderInfo.product_order.cancel_status==0">
<button class="to_pay" @click="toPay">立即支付</button>
</view>
<u-toast ref="uToast" />
@@ -228,7 +228,7 @@ export default {
check: false
},
orderInfo: {
ProductOrder: {}
product_order: {}
}, // 订单
chinese: [],
west: [],
@@ -294,26 +294,26 @@ export default {
computed: {
parsedAddress() {
try {
return JSON.parse(this.orderInfo.ProductOrder.address || '{}')
return JSON.parse(this.orderInfo.product_order.address || '{}')
} catch (e) {
return {}
}
},
canEditAddress() {
const o = this.orderInfo.ProductOrder
const o = this.orderInfo.product_order
return this.isshow && o.status == 0 && o.cancel_status == 0
},
canViewAddressReadonly() {
const o = this.orderInfo.ProductOrder
const o = this.orderInfo.product_order
return o.delivery_method == 0 && o.status != 0 && o.address && o.cancel_status == 0
},
// 整单存在任一外部配送仓时:隐藏顶部文案,改在药品行展示
hasDeliveryWarehouse() {
const o = this.orderInfo && this.orderInfo.ProductOrder
const o = this.orderInfo && this.orderInfo.product_order
if (o && Number(o.has_delivery_warehouse) === 1) {
return true
}
const items = (this.orderInfo && this.orderInfo.ProductOrderItems) || []
const items = (this.orderInfo && this.orderInfo.product_order_items) || []
for (let i = 0; i < items.length; i++) {
if (Number(items[i].delivery_warehouse_id || 0) > 0) {
return true
@@ -335,7 +335,7 @@ export default {
goDrugDetail(item) {
const drugId = item.drug_id || (item.drug && item.drug.id);
if (!drugId) return;
const orderStoreId = (this.orderInfo.ProductOrder && this.orderInfo.ProductOrder.store_id)
const orderStoreId = (this.orderInfo.product_order && this.orderInfo.product_order.store_id)
|| uni.getStorageSync('store_id')
|| '11001';
const q = [
@@ -440,7 +440,7 @@ export default {
// 快递到家:已有地址则直接切配送;否则去地址页(地址页会带 delivery_method=0 提交)
// 禁止在此处只改本地状态而不调接口,否则 onShow 可能用旧 delivery_method=1 覆盖
const hasAddress = !!(this.orderInfo.ProductOrder && this.orderInfo.ProductOrder.address_id)
const hasAddress = !!(this.orderInfo.product_order && this.orderInfo.product_order.address_id)
|| !!uni.getStorageSync('address_id')
if (hasAddress) {
this.toUpdata(0)
@@ -459,7 +459,7 @@ export default {
const targetDeliveryMethod = deliveryMethodIndex
const addressId = uni.getStorageSync('address_id')
|| (this.orderInfo.ProductOrder && this.orderInfo.ProductOrder.address_id)
|| (this.orderInfo.product_order && this.orderInfo.product_order.address_id)
|| 0
getDelivery({
@@ -531,9 +531,9 @@ export default {
if (res.data.errcode == 0) {
this.orderInfo = res.data.data
this.patientInfo = res.data.data.patient || null
this.order_id = res.data.data.ProductOrder.id
uni.setStorageSync('userWay_order_id', res.data.data.ProductOrder.id)
uni.setStorageSync('delivery_method', res.data.data.ProductOrder.delivery_method)
this.order_id = res.data.data.product_order.id
uni.setStorageSync('userWay_order_id', res.data.data.product_order.id)
uni.setStorageSync('delivery_method', res.data.data.product_order.delivery_method)
// 使用API返回的处方来源诊所信息优先使用处方来源诊所
if (res.data.data.store && res.data.data.store.store) {
@@ -548,8 +548,8 @@ export default {
}
// 检查 is_online 字段,动态控制 list 数组
if (res.data.data.ProductOrder && res.data.data.ProductOrder.is_online !== undefined) {
this.is_online = res.data.data.ProductOrder.is_online
if (res.data.data.product_order && res.data.data.product_order.is_online !== undefined) {
this.is_online = res.data.data.product_order.is_online
} else if (res.data.data.is_online !== undefined) {
this.is_online = res.data.data.is_online
}
@@ -565,8 +565,8 @@ export default {
}
// 根据返回的订单数据更新页面状态(配送方式)
if (res.data.data.ProductOrder && res.data.data.ProductOrder.delivery_method !== undefined) {
const deliveryMethod = res.data.data.ProductOrder.delivery_method
if (res.data.data.product_order && res.data.data.product_order.delivery_method !== undefined) {
const deliveryMethod = res.data.data.product_order.delivery_method
this.delivery_method = deliveryMethod
if (deliveryMethod == 1) {
this.isshowed = true

View File

@@ -6,7 +6,7 @@
<text>{{ orderText }}</text>
</view>
<view class="head_cancle" v-if="orderInfo.ProductOrder.status!=0 && orderInfo.ProductOrder.cancel_status==1">
<view class="head_cancle" v-if="orderInfo.product_order.status!=0 && orderInfo.product_order.cancel_status==1">
订单已取消
</view>
<!-- 就诊人信息 -->
@@ -20,7 +20,7 @@
</view>
</view>
<!-- 快递自提 -->
<view class="_choose" v-if="orderInfo.ProductOrder.status==0&&orderInfo.ProductOrder.is_pay==0 && orderInfo.ProductOrder.cancel_status==0">
<view class="_choose" v-if="orderInfo.product_order.status==0&&orderInfo.product_order.is_pay==0 && orderInfo.product_order.cancel_status==0">
<text>配送方式</text>
<view class="_fs" @click="toShowed">
<text>{{wayText}}</text>
@@ -30,22 +30,22 @@
</view>
</view>
<!-- 收货地址 已添加地址 -->
<view class="head" v-if="isshow&&orderInfo.ProductOrder.status==0" @click="toChoose">
<view class="head" v-if="isshow&&orderInfo.product_order.status==0" @click="toChoose">
<view class="state">
<text>收货地址</text>
<view class="qh">
<view class="iconfont icon-jiantou1"></view>
</view>
</view>
<view class="name" @click="toChoose" v-if="!orderInfo.ProductOrder.address">
<view class="name" @click="toChoose" v-if="!orderInfo.product_order.address">
请先选择收货地址
</view>
<view class="name" @click="toChoose" v-if="orderInfo.ProductOrder.address">
{{JSON.parse(orderInfo.ProductOrder.address).name || '请先选择收货地址'}}
{{JSON.parse(orderInfo.ProductOrder.address).mobile || ''}}
<view class="name" @click="toChoose" v-if="orderInfo.product_order.address">
{{JSON.parse(orderInfo.product_order.address).name || '请先选择收货地址'}}
{{JSON.parse(orderInfo.product_order.address).mobile || ''}}
</view>
<view class="choose_area" v-if="orderInfo.ProductOrder.address">
{{JSON.parse(orderInfo.ProductOrder.address).region || ''}}{{JSON.parse(orderInfo.ProductOrder.address).detail_address || ''}}
<view class="choose_area" v-if="orderInfo.product_order.address">
{{JSON.parse(orderInfo.product_order.address).region || ''}}{{JSON.parse(orderInfo.product_order.address).detail_address || ''}}
</view>
</view>
@@ -126,29 +126,29 @@
<view class="goods">
<view class="good_">
<text>商品总价包含服务费</text>
<text class="price">{{orderInfo.ProductOrder.items_price}}</text>
<text class="price">{{orderInfo.product_order.items_price}}</text>
</view>
<view class="good_">
<text>快递费</text>
<text class="price">{{orderInfo.ProductOrder.trans_expenses}}</text>
<text class="price">{{orderInfo.product_order.trans_expenses}}</text>
</view>
<view class="good_">
<text>诊疗费</text>
<text class="price">{{orderInfo.ProductOrder.treatement_price}}</text>
<text class="price">{{orderInfo.product_order.treatement_price}}</text>
</view>
<view class="good_">
<text>加工费</text>
<view class="price">
<text v-if="payWay">{{payWay.dosage}} </text>
{{orderInfo.ProductOrder.process_price}}
{{orderInfo.product_order.process_price}}
</view>
</view>
<view class="good_">
<!-- <text>{{orderInfo.ProductOrder.count}}</text> -->
<!-- <text>{{orderInfo.product_order.count}}</text> -->
<text>总金额</text>
<view class="total">
合计:
<text class="price">{{orderInfo.ProductOrder.total_pay_price}}</text>
<text class="price">{{orderInfo.product_order.total_pay_price}}</text>
</view>
</view>
</view>
@@ -189,8 +189,13 @@
></u-modal>
</view>
<!-- 代付提示条 + 取消代付清理扫码状态下次进小程序不再跳转 -->
<view class="proxy-pay-bar" v-if="proxyPay">
<text class="proxy-pay-tip">当前为医生代付订单</text>
<view class="proxy-pay-cancel" @click="cancelProxyPay">取消代付</view>
</view>
<!-- 底部 -->
<view class="footer" v-if="orderInfo.ProductOrder.status==0 && orderInfo.ProductOrder.is_pay==0 && orderInfo.ProductOrder.cancel_status==0">
<view class="footer" v-if="orderInfo.product_order.status==0 && orderInfo.product_order.is_pay==0 && orderInfo.product_order.cancel_status==0">
<button class="to_pay" @click="toPay">立即支付</button>
</view>
<u-toast ref="uToast" />
@@ -225,7 +230,7 @@
},
contented: `知情同意书`,
orderInfo: {
ProductOrder: {}
product_order: {}
}, // 订单
chinese: [],
west: [],
@@ -234,6 +239,7 @@
order_id: "", // 订单id
order_no: "", // 订单编号
p_id: "", // 处方id
proxyPay: 0, // 医生代付标记 1=代付
originalList: [{
text: '快递到家'
}, {
@@ -288,11 +294,11 @@
computed: {
// 整单存在任一外部配送仓时:隐藏顶部文案,改在药品行展示
hasDeliveryWarehouse() {
const o = this.orderInfo && this.orderInfo.ProductOrder
const o = this.orderInfo && this.orderInfo.product_order
if (o && Number(o.has_delivery_warehouse) === 1) {
return true
}
const items = (this.orderInfo && this.orderInfo.ProductOrderItems) || []
const items = (this.orderInfo && this.orderInfo.product_order_items) || []
for (let i = 0; i < items.length; i++) {
if (Number(items[i].delivery_warehouse_id || 0) > 0) {
return true
@@ -303,6 +309,16 @@
},
onLoad(e) {
this.p_id = e.id
// 代付扫码进入:记录 order_id 与 proxy_pay供 getPayConfig 附带
if (e && e.order_id) {
this.order_id = e.order_id
uni.setStorageSync('userWay_order_id', e.order_id)
}
if (e && (e.proxy_pay == 1 || e.proxy_pay === '1')) {
uni.setStorageSync('proxy_pay_order_id', this.order_id || e.order_id)
uni.setStorageSync('proxy_pay_confirmed', 1)
this.proxyPay = 1
}
// 获取订单提示文本
this.getOrderText();
},
@@ -312,6 +328,29 @@
methods: {
canShowUsage,
canShowInstruction,
/**
* 清理代付扫码会话(下次进小程序不再自动跳转代付)
*/
clearProxyPaySession() {
uni.removeStorageSync('proxy_pay_order_id')
uni.removeStorageSync('proxy_pay_confirmed')
this.proxyPay = 0
},
/**
* 取消代付:清理标记并离开支付页
*/
cancelProxyPay() {
this.clearProxyPaySession()
uni.showToast({ title: '已取消代付', icon: 'none' })
setTimeout(() => {
const pages = getCurrentPages()
if (pages && pages.length > 1) {
uni.navigateBack()
} else {
uni.switchTab({ url: '/pages/home/home' })
}
}, 400)
},
// 获取订单提示文本(无外部配送仓时才用于顶部与支付弹窗)
getOrderText() {
getOrderTextApi().then((res) => {
@@ -401,7 +440,7 @@
}
// 快递到家:已有地址则直接切配送;否则去地址页
const hasAddress = !!(this.orderInfo.ProductOrder && this.orderInfo.ProductOrder.address_id)
const hasAddress = !!(this.orderInfo.product_order && this.orderInfo.product_order.address_id)
|| !!uni.getStorageSync('address_id')
if (hasAddress) {
this.toUpdata(0)
@@ -422,7 +461,7 @@
const targetDeliveryMethod = deliveryMethodIndex
const addressId = uni.getStorageSync('address_id')
|| (this.orderInfo.ProductOrder && this.orderInfo.ProductOrder.address_id)
|| (this.orderInfo.product_order && this.orderInfo.product_order.address_id)
|| 0
getDelivery({
@@ -431,7 +470,9 @@
address_id: addressId,
delivery_method: targetDeliveryMethod,
order_id: this.order_id,
store_id: uni.getStorageSync('store_id') || '11001'
store_id: uni.getStorageSync('store_id') || '11001',
// 代付改配送:后端跳过订单 user_id 校验
proxy_pay: this.proxyPay || (Number(uni.getStorageSync('proxy_pay_order_id')) === Number(this.order_id) ? 1 : 0),
}
}).then((res) => {
const ok = res.data && (res.data.code === 0 || res.data.errcode === 0)
@@ -483,11 +524,18 @@
this.form['check'] = !this.form['check']
},
// 产品信息
// 产品信息(代付扫码仅有 order_id普通入口传 prescription_id
getInfo() {
let list = {
store_id: uni.getStorageSync('store_id'),
prescription_id: this.p_id
}
if (this.proxyPay && this.order_id) {
list.order_id = this.order_id
list.proxy_pay = 1
} else if (this.order_id && !this.p_id) {
list.order_id = this.order_id
} else {
list.prescription_id = this.p_id
}
getProductInfo({
method: "post",
@@ -500,9 +548,9 @@
this.chinese = res.data.data.chinese
this.west = res.data.data.west
this.granular = res.data.data.granular
this.order_id = res.data.data.ProductOrder.id
uni.setStorageSync('userWay_order_id', res.data.data.ProductOrder.id)
// this.order_no = res.data.data.ProductOrder.order_no
this.order_id = res.data.data.product_order.id
uni.setStorageSync('userWay_order_id', res.data.data.product_order.id)
// this.order_no = res.data.data.product_order.order_no
// console.log(this.west.content);
// 使用API返回的处方来源诊所信息优先使用处方来源诊所
@@ -518,8 +566,8 @@
}
// 检查 is_online 字段,动态控制 list 数组
if (res.data.data.ProductOrder && res.data.data.ProductOrder.is_online !== undefined) {
this.is_online = res.data.data.ProductOrder.is_online
if (res.data.data.product_order && res.data.data.product_order.is_online !== undefined) {
this.is_online = res.data.data.product_order.is_online
} else if (res.data.data.is_online !== undefined) {
this.is_online = res.data.data.is_online
}
@@ -535,8 +583,8 @@
}
// 根据返回的订单数据更新页面状态(配送方式)
if (res.data.data.ProductOrder && res.data.data.ProductOrder.delivery_method !== undefined) {
const deliveryMethod = res.data.data.ProductOrder.delivery_method
if (res.data.data.product_order && res.data.data.product_order.delivery_method !== undefined) {
const deliveryMethod = res.data.data.product_order.delivery_method
this.delivery_method = deliveryMethod
if (this.list[deliveryMethod]) {
this.wayText = this.list[deliveryMethod].text
@@ -653,6 +701,7 @@
data: {
order_id: this.order_id,
store_id: uni.getStorageSync('store_id') || '11001',
proxy_pay: this.proxyPay || (Number(uni.getStorageSync('proxy_pay_order_id')) === Number(this.order_id) ? 1 : 0),
}
}).then((res) => {
console.log(res.data.data.timeStamp, 'pay');
@@ -662,6 +711,7 @@
if (res.data.errcode == 0) {
if (!res.data.data.appId) {
that.clearProxyPaySession()
setTimeout(() => {
that.flag = false
uni.navigateTo({
@@ -681,6 +731,7 @@
paySign: res.data.data.paySign,
success: (res) => {
console.log('success:' + JSON.stringify(res));
that.clearProxyPaySession()
setTimeout(() => {
that.flag = false
uni.navigateTo({
@@ -705,7 +756,7 @@
uni.hideLoading();
that.flag = true
this.$refs.uToast.show({
title: res.data.msg,
title: res.data.msg || res.data.message,
type: 'default',
icon: false
})
@@ -1162,6 +1213,30 @@
}
}
.proxy-pay-bar {
width: 750rpx;
position: fixed;
left: 0;
bottom: calc(114rpx + env(safe-area-inset-bottom));
display: flex;
align-items: center;
justify-content: space-between;
padding: 16rpx 24rpx;
background: #fff7ed;
border-top: 1rpx solid #fed7aa;
z-index: 10;
.proxy-pay-tip {
font-size: 26rpx;
color: #c2410c;
}
.proxy-pay-cancel {
font-size: 26rpx;
color: #ea580c;
padding: 8rpx 20rpx;
border: 1rpx solid #fdba74;
border-radius: 8rpx;
}
}
.footer {
width: 750rpx;
height: 114rpx;

View File

@@ -620,6 +620,17 @@
}).then(async (res) => {
uni.showLoading({ title: '加载中' });
if (!(res.data && (res.data.errcode == 0 || res.data.errcode === '0'))) {
that.flag = true;
uni.hideLoading();
that.$refs.uToast && that.$refs.uToast.show({
title: (res.data && (res.data.message || res.data.msg)) || '获取支付参数失败',
type: 'default',
icon: false
});
return;
}
if (checkDev('open-im') && that.registList && that.registList.register_type === 1) {
createRoomByDoctorIdApi({
doctor_id: that.currentDoctorId,
@@ -638,7 +649,7 @@
});
}
if (res.data.data.is_paid == 1) {
if (res.data.data && res.data.data.is_paid == 1) {
await that.waitForRegisterDetail();
if (that.registList && (that.registList.register_type === 2 || that.registList.register_type === 3)) {
await that.handleOnlineConsultationAfterPayment();

View File

@@ -263,10 +263,10 @@
title: "加载中"
});
if (res.data.errcode != 0) {
if (!(res.data && (res.data.errcode == 0 || res.data.errcode === '0'))) {
uni.hideLoading();
that.$refs.uToast.show({
title: res.data.msg || '支付失败',
title: (res.data && (res.data.message || res.data.msg)) || '支付失败',
type: 'default',
icon: false
});