289 lines
11 KiB
Vue
289 lines
11 KiB
Vue
|
|
<template>
|
|||
|
|
<full-page v-if="order" pageStyle="background:#f5f5f5">
|
|||
|
|
<view :style="elderVarStyle">
|
|||
|
|
<confirm-popup
|
|||
|
|
:title="invoicePopup.title"
|
|||
|
|
:content="invoicePopup.content"
|
|||
|
|
:showCancel="false"
|
|||
|
|
confirmText="知道了"
|
|||
|
|
:visible="invoicePopup.visible"
|
|||
|
|
@confirm="invoicePopup.visible = false"
|
|||
|
|
@close="invoicePopup.visible = false" />
|
|||
|
|
<view v-if="headText[order.status]" class="bg-white p-15 shadow-lg">
|
|||
|
|
<view class="pb-10 text-drak text-lg font-semibold ">{{ headText[order.status].title }}</view>
|
|||
|
|
<view v-if="headText[order.status].dynicDesc" class="text-base text-dark leading-normal">{{ dynicDesc }}</view>
|
|||
|
|
<view v-else class="text-base text-dark leading-normal">{{ headText[order.status].desc }}</view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="mt-15 bg-white shadow-lg">
|
|||
|
|
<view class="flex border-b py-12 px-15">
|
|||
|
|
<view class="flex-shrink-0 mr-10 text-base text-gray">收货地址</view>
|
|||
|
|
<view class="flex-grow text-dark text-right">
|
|||
|
|
<view class="text-base">{{ order.receiveName }} {{ order.receivePhone }}</view>
|
|||
|
|
<view>
|
|||
|
|
<text v-if="order.receiveRegion && order.receiveRegion.length > 0" class="text-base">
|
|||
|
|
{{ order.receiveRegion.join('') }}
|
|||
|
|
</text>
|
|||
|
|
<text class="text-base">{{ order.receiveAddress }}</text>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
<view class="flex justify-between py-12 px-15">
|
|||
|
|
<view class="flex-shrink-0 mr-10 text-base text-gray">配送方式</view>
|
|||
|
|
<view class="text-base">{{ shippingType[order.shippingType] }}</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
<view class="mt-15 bg-white shadow-lg">
|
|||
|
|
<view v-for="(med, idx) in order.drugs" class="px-15" :class="idx === order.drugs.length - 1 ? 'border-b' : ''">
|
|||
|
|
<view class="flex justify-between py-10">
|
|||
|
|
<view class="mr-15 text-base font-semibold">{{ med.drugName }}</view>
|
|||
|
|
<view class="flex-shrink-0 text-base text-danger">¥{{ med.price }}</view>
|
|||
|
|
</view>
|
|||
|
|
<view class="flex pb-10">
|
|||
|
|
<view class="flex-grow mr-10 w-0 truncate text-sm text-gray">规格:{{ med.spec }}</view>
|
|||
|
|
<view class="flex-shrink-0 text-sm text-gray">x{{ med.quantity }}</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
<view class="flex justify-between py-10 px-15">
|
|||
|
|
<view>
|
|||
|
|
<text class="text-base text-dark">药品费</text>
|
|||
|
|
<text class="text-sm text-gray">(医保结算)</text>
|
|||
|
|
</view>
|
|||
|
|
<view class="text-base text-danger">¥{{ countDetails.drugFee }}</view>
|
|||
|
|
</view>
|
|||
|
|
<view class="flex justify-between pb-10 px-15">
|
|||
|
|
<view>
|
|||
|
|
<text class="text-base text-dark">互联网诊查费</text>
|
|||
|
|
<text v-if="order.regFee > 0" class="text-sm text-gray">(医保结算)</text>
|
|||
|
|
</view>
|
|||
|
|
<view class="text-base text-danger">¥{{ countDetails.regFee }}</view>
|
|||
|
|
</view>
|
|||
|
|
<view class="flex justify-between pb-10 px-15">
|
|||
|
|
<view>
|
|||
|
|
<text class="text-base text-dark">运费</text>
|
|||
|
|
<text v-if="order.shippingFee > 0 && order.payTime" class="text-sm text-gray">(支付宝支付)</text>
|
|||
|
|
</view>
|
|||
|
|
<view class="text-base text-danger">¥{{ countDetails.shippingFee }}</view>
|
|||
|
|
</view>
|
|||
|
|
<view class="text-right pb-10 px-15">
|
|||
|
|
<text class="text-base text-dark">总计:</text>
|
|||
|
|
<text class="text-base text-danger">¥{{ countDetails.totalFee }}</text>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
<view class="mt-15 px-15 bg-white shadwo-lg">
|
|||
|
|
<view class="flex justify-between py-10 border-b">
|
|||
|
|
<view class="text-sm text-gray">订单号</view>
|
|||
|
|
<view class="text-sm text-dark">{{ order.orderNo }}</view>
|
|||
|
|
</view>
|
|||
|
|
<view class="flex justify-between py-10 border-b">
|
|||
|
|
<view class="text-sm text-gray">下单时间</view>
|
|||
|
|
<view class="text-sm text-dark">{{ order.createTime }}</view>
|
|||
|
|
</view>
|
|||
|
|
<view v-if="order.tradeNo" class="flex justify-between py-10" :class="order.payTime ? 'border-b' : ''">
|
|||
|
|
<view class="text-sm text-gray">交易订单号</view>
|
|||
|
|
<view class="text-sm text-dark">{{ order.tradeNo }}</view>
|
|||
|
|
</view>
|
|||
|
|
<view v-if="order.payTime" class="flex justify-between py-10" :class="refundRecords.length ? 'border-b' : ''">
|
|||
|
|
<view class="text-sm text-gray">支付时间</view>
|
|||
|
|
<view class="text-sm text-dark">{{ order.payTime }}</view>
|
|||
|
|
</view>
|
|||
|
|
<view v-for="(i, idx) in refundRecords" :key="idx" class="flex justify-between py-10"
|
|||
|
|
:class="idx === refundRecords.length - 1 ? '' : 'border-b'">
|
|||
|
|
<view class="text-sm text-gray">退费时间 ({{ i.fee }})</view>
|
|||
|
|
<view class="text-sm text-dark">{{ i.time }}</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
<template #footer>
|
|||
|
|
<view class="flex justify-end bg-white px-15 py-10" :style="elderVarStyle">
|
|||
|
|
<view v-if="order.status === 'ybPaid'"
|
|||
|
|
class="flex-shrink-0 bg-primary border-primary text-base text-white px-15 py-5 rounded" @click="toPay">
|
|||
|
|
去支付
|
|||
|
|
</view>
|
|||
|
|
<view v-if="order.status === 'shipped'"
|
|||
|
|
class="flex-shrink-0 border-primary text-base text-primary px-15 py-5 rounded mr-10"
|
|||
|
|
@click="viewInvoice(order.patientId, order.orderNo)">电子发票</view>
|
|||
|
|
<view v-if="order.status === 'shipped' || order.status === 'ybFeeRefunded'"
|
|||
|
|
class="flex-shrink-0 bg-primary border-primary text-base text-white px-15 py-5 rounded"
|
|||
|
|
@click="viewShippingInfo(order._id)">
|
|||
|
|
查看物流
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</template>
|
|||
|
|
</full-page>
|
|||
|
|
</template>
|
|||
|
|
<script setup>
|
|||
|
|
import { computed, ref } from 'vue';
|
|||
|
|
import { onLoad } from '@dcloudio/uni-app';
|
|||
|
|
import BigNumber from 'bignumber.js';
|
|||
|
|
import dayjs from 'dayjs';
|
|||
|
|
import useElder from '@/hooks/useElder';
|
|||
|
|
import useUser from '@/hooks/useUser';
|
|||
|
|
import { getMedicinePurchaseOrder, getMedicineOrderTradeNo, getHisInvoice } from '@/utils/api';
|
|||
|
|
import { toast, loading as showLoading, hideLoading } from '@/utils/widget';
|
|||
|
|
import { pay } from '@/utils/pay';
|
|||
|
|
import { viewShippingInfo } from './util';
|
|||
|
|
|
|||
|
|
import fullPage from '@/components/full-page.vue';
|
|||
|
|
import confirmPopup from '@/components/confirm-popup.vue';
|
|||
|
|
|
|||
|
|
const shippingType = {
|
|||
|
|
ems: '快递邮寄',
|
|||
|
|
fengniao: '蜂鸟配送',
|
|||
|
|
}
|
|||
|
|
const headText = {
|
|||
|
|
ybPaid: { title: '待支付运费', desc: '为确保药品尽快发出,请及时支付运费。' },
|
|||
|
|
shipped: { title: '已配送', desc: '您可点击查看物流跟踪配送进度。' },
|
|||
|
|
refunded: { title: '已退费', dynicDesc: true },
|
|||
|
|
ybFeeRefunded: { title: '药诊费已退', dynicDesc: true },
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const { elderVarStyle } = useElder();
|
|||
|
|
const { userInfo } = useUser();
|
|||
|
|
const id = ref('');
|
|||
|
|
const order = ref(null);
|
|||
|
|
const autoCallPay = ref(false)
|
|||
|
|
const invoicePopup = ref({
|
|||
|
|
visible: false,
|
|||
|
|
title: '提示',
|
|||
|
|
content: ''
|
|||
|
|
})
|
|||
|
|
const countDetails = computed(() => {
|
|||
|
|
const drugFee = order.value && typeof order.value.drugFee === 'number' ? order.value.drugFee : undefined;
|
|||
|
|
const shippingFee = order.value && typeof order.value.shippingFee === 'number' ? order.value.shippingFee : undefined;
|
|||
|
|
const regFee = order.value && typeof order.value.regFee === 'number' ? order.value.regFee : undefined;
|
|||
|
|
const total = new BigNumber(drugFee || 0).plus(regFee || 0).plus(shippingFee || 0);
|
|||
|
|
const ybFee = new BigNumber(regFee || 0).plus(drugFee || 0).toNumber();
|
|||
|
|
return {
|
|||
|
|
drugFee: typeof drugFee === 'number' ? drugFee.toFixed(2) : '',
|
|||
|
|
regFee: typeof regFee === 'number' ? regFee.toFixed(2) : '',
|
|||
|
|
shippingFee: typeof shippingFee === 'number' ? shippingFee.toFixed(2) : '',
|
|||
|
|
totalFee: total.toFixed(2),
|
|||
|
|
ybFee: ybFee.toFixed(2),
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
const dynicDesc = computed(() => {
|
|||
|
|
if (order.value && order.value.status === 'refunded' && order.value.payTime && order.value.shippingFee > 0) {
|
|||
|
|
return `已退回药费+问诊费(¥${countDetails.value.ybFee})${order.value.shippingFee > 0 ? `,运费(¥${countDetails.value.shippingFee})` : ''}。`
|
|||
|
|
}
|
|||
|
|
if (order.value && ['ybFeeRefunded', 'refunded'].includes(order.value.status)) {
|
|||
|
|
return `已退回药费+问诊费(¥${countDetails.value.ybFee})。`
|
|||
|
|
}
|
|||
|
|
return '';
|
|||
|
|
})
|
|||
|
|
const refundRecords = computed(() => {
|
|||
|
|
return order.value && Array.isArray(order.value.refundRecords) ? order.value.refundRecords.filter(i => i.result === 'refunded').map(i => ({
|
|||
|
|
fee: `¥${i.amount.toFixed(2)}`,
|
|||
|
|
time: dayjs(i.refundTime || i.applyTime).format('YYYY-MM-DD HH:mm'),
|
|||
|
|
})) : [];
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
async function getDetail() {
|
|||
|
|
showLoading()
|
|||
|
|
const res = await getMedicinePurchaseOrder({ accountId: userInfo.value.userId, id: id.value });
|
|||
|
|
hideLoading();
|
|||
|
|
if (res && res.success) {
|
|||
|
|
order.value = res.data;
|
|||
|
|
if (order.value.status === 'unpay') {
|
|||
|
|
uni.redirectTo({
|
|||
|
|
url: `/pages/consult/drug-purchase-order/drug-purchase-order?&orderId=${order.value.id}`
|
|||
|
|
});
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
if (order.value.status === 'expired') {
|
|||
|
|
await toast('订单已过期')
|
|||
|
|
uni.navigateBack();
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
order.value.createTime = dayjs(order.value.createTime).format('YYYY-MM-DD HH:mm:ss');
|
|||
|
|
order.value.payTime = order.value.payTime ? dayjs(order.value.payTime).format('YYYY-MM-DD HH:mm:ss') : '';
|
|||
|
|
if (order.value.status === 'ybPaid' && autoCallPay.value) {
|
|||
|
|
autoCallPay.value = false;
|
|||
|
|
toPay()
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
await toast(res.message || '获取在线配药订单详情失败');
|
|||
|
|
uni.navigateBack();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async function toPay() {
|
|||
|
|
showLoading();
|
|||
|
|
const res = await getMedicineOrderTradeNo({
|
|||
|
|
accountId: userInfo.value.userId,
|
|||
|
|
id: id.value
|
|||
|
|
});
|
|||
|
|
hideLoading();
|
|||
|
|
if (res && res.success) {
|
|||
|
|
if (res.statusChanged) {
|
|||
|
|
await toast('订单状态已更新')
|
|||
|
|
getDetail()
|
|||
|
|
}
|
|||
|
|
if (res.tradeNo && res.payType === 'alipay') {
|
|||
|
|
payTrade(res.tradeNo);
|
|||
|
|
}
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
toast(res.message || '获取交易订单号失败')
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async function payTrade(tradeNo) {
|
|||
|
|
try {
|
|||
|
|
await pay(tradeNo);
|
|||
|
|
getDetail()
|
|||
|
|
} catch (e) {
|
|||
|
|
if (e === 'cancel') {
|
|||
|
|
toast('支付已取消')
|
|||
|
|
} else {
|
|||
|
|
toast(e)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 本地版本的viewInvoice,使用自定义弹窗
|
|||
|
|
async function viewInvoice(patientId, orderNo) {
|
|||
|
|
showLoading()
|
|||
|
|
const res = await getHisInvoice({
|
|||
|
|
patientId,
|
|||
|
|
orderNo
|
|||
|
|
});
|
|||
|
|
hideLoading()
|
|||
|
|
|
|||
|
|
if (res && res.success) {
|
|||
|
|
const url = typeof res.data === 'string' ? res.data : ''
|
|||
|
|
if (url) {
|
|||
|
|
uni.setClipboardData({
|
|||
|
|
data: url,
|
|||
|
|
success: () => {
|
|||
|
|
invoicePopup.value = {
|
|||
|
|
visible: true,
|
|||
|
|
title: '提示',
|
|||
|
|
content: '已复制发票地址,请在浏览器中打开'
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
} else {
|
|||
|
|
invoicePopup.value = {
|
|||
|
|
visible: true,
|
|||
|
|
title: '提示',
|
|||
|
|
content: '发票正在开具中,请稍后再试!'
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
invoicePopup.value = {
|
|||
|
|
visible: true,
|
|||
|
|
title: '提示',
|
|||
|
|
content: '发票正在开具中,请稍后再试!'
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
onLoad(options => {
|
|||
|
|
id.value = options.id || '';
|
|||
|
|
autoCallPay.value = options.autoCallPay === 'YES';
|
|||
|
|
getDetail()
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
</script>
|
|||
|
|
<style lang="scss" scoped></style>
|