hn-hlw-app/pages/record/rx-paper.vue
2026-07-27 11:26:39 +08:00

393 lines
10 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<full-page>
<view v-if="data" class="relative prescription-container">
<view class="header">
<view class="row">
<view class="company">绍兴市同源健康管理有限公司越城</view>
<view class="prescription-type">
<view>普通</view>
<view>处方</view>
</view>
</view>
<view class="hospital">震元堂中医院互联网医院处方笺</view>
<view class="sub-header">
<span class="no">NO:{{ data.medOrgOrderNo }}</span>
</view>
</view>
<view class="patient-info">
<view class="info-row">
<view class="info-item" style="width: 28%">姓名:{{ data.name }}</view>
<view class="info-item" style="width: 20%">性别:{{ data.sex }}</view>
<view class="info-item" style="width: 28%">费别:</view>
<view class="info-item" style="width: 24%">年龄:{{ data.age }}</view>
</view>
<view class="info-row">
<view class="info-item" style="width: 60%">门诊病历号:{{ data.blhno }}</view>
<view class="info-item" style="width: 40%">科别:{{ data.deptName }}</view>
</view>
<view class="info-row">
<view class="info-item full-width">地址: {{ data.address }}</view>
</view>
<view class="info-row">
<view class="info-item full-width">电话号:{{ data.mobile }}</view>
</view>
</view>
<!-- 诊断信息 -->
<view class="diagnosis-section">
<view class="diagnosis-header">
<span>诊断:</span>
<span class="date">开方日期:{{ data.time }}</span>
</view>
<view class="diagnosis-items">
<view v-for="(i, idx) in diagnosis" :key="i.code">{{ idx + 1 }}. {{ i.name }}</view>
</view>
</view>
<!-- 药品处方区域 -->
<view class="medicine-section">
<view class="rp-symbol">Rp</view>
<view class="medicine-list">
<view v-for="i in drugList" :key="i.insurance_code" class="medicine-item">
<view class="medicine-name">{{ i.drugName }} x {{ i.quantity }} {{ i.unit }}</view>
<view class="medicine-spec">规格:{{ i.specification }}</view>
<view class="medicine-usage">用法:{{ i.memo }}</view>
</view>
</view>
</view>
<!-- 底部签章区域 -->
<view class="footer">
<view class="stamp-area">
<view class="signatures">
<view class="signature-item" style="width: 33%">
<view>医生:
<image v-if="doctorImg" class="signImage" :src="doctorImg"></image>
<text v-else>{{ data.doctorName }}</text>
</view>
<view class="stamp">
<!-- <image class="stamp-img" src="/static/stamp.png"></image> -->
</view>
</view>
<view class="signature-item" style="width: 33%">
<view>审方:<image v-if="yaoshiImg" class="signImage" :src="yaoshiImg"></image>
<text v-else>{{ data.pharmacist }}</text>
</view>
<view>发药</view>
</view>
<view class="signature-item" style="width: 34%">
<view class="stamp">收费盖章
<!-- <image class="stamp-img" src="/static/stamp.png"></image> -->
</view>
<view>配方</view>
<view>复核</view>
</view>
</view>
</view>
<view class="notice">注意请勿丢失处方当日有效因特殊情况该处方有效为天签名</view>
</view>
<image v-if="isExpired" class="expired-icon" src="/static/icons/expired.svg" />
</view>
<template #footer>
<footer-button v-if="canPay" text="医保结算" @onClick="handleInsurancePayment" />
<footer-button v-else-if="canViewOrder" text="查看订单" @onClick="viewOrder" />
</template>
</full-page>
</template>
<script setup>
import { computed, ref } from "vue";
import { onLoad } from "@dcloudio/uni-app";
import dayjs from 'dayjs';
import useUser from '@/hooks/useUser';
import { getRxDetail, getSealImage, getRxMedicinePurchaseOrderId } from '@/utils/api'
import fullPage from "@/components/full-page.vue";
import footerButton from "@/components/footer-button.vue";
import { loading as showLoading, hideLoading, toast } from "@/utils/widget";
const { userInfo } = useUser();
const data = ref(null);
const doctorImg = ref('')
const yaoshiImg = ref('')
const id = ref('');
const serviceTime = ref(0);
const isExpired = computed(() => {
if (data.value && data.value.prescriptionType === 'onlineMedicinePurchase') {
console.log(data.value.expireTime < serviceTime.value)
console.log(!data.value.purchaseOrder, data.value.purchaseOrder?.status === 'expired')
return data.value.expireTime < serviceTime.value && (!data.value.purchaseOrder || data.value.purchaseOrder.status === 'expired');
}
return false
})
const canPay = computed(() => {
if (data.value && data.value.prescriptionType === 'onlineMedicinePurchase') {
return !isExpired.value && (!data.value.purchaseOrder || ['unpay', 'ybPaid'].includes(data.value.purchaseOrder.status));
}
return false
})
const canViewOrder = computed(() => {
if (data.value && data.value.prescriptionType === 'onlineMedicinePurchase') {
return data.value.purchaseOrder && data.value.purchaseOrder.status === 'shipped';
}
return false
})
onLoad((options) => {
id.value = options.id;
getRx();
})
const diagnosis = computed(() => data.value && Array.isArray(data.value.diagnosisList) ? data.value.diagnosisList : [])
const drugList = computed(() => {
const drugs = data.value && Array.isArray(data.value.drugs) ? data.value.drugs : [];
return drugs.map((item) => {
const arr = [item.usageName, item.frequencyName, item.dosage ? `每次${item.dosage}${item.dosage_unit || ''}` : ''].filter(Boolean);
return { ...item, memo: arr.join(' ') }
})
})
async function getRx() {
showLoading();
const res = await getRxDetail(id.value, userInfo.value?.userId);
const { success, data: rx, message } = res || {};
hideLoading();
if (success) {
data.value = rx;
serviceTime.value = typeof res.now === 'number' ? res.now : 0;
data.value.time = rx.createTime ? dayjs(rx.createTime).format('YYYY-MM-DD HH:mm') : '';
getDoctorSign()
} else {
toast(message || '获取处方详情失败');
}
}
function getDoctorSign() {
if (data.value.doctorCode && !doctorImg.value) {
getSealImage(data.value.doctorCode).then(res => {
if (res.success && res.data) {
doctorImg.value = `data:image/png;base64,${res.data}`
}
})
}
if (data.value.pharmacistNo && !yaoshiImg.value) {
getSealImage(data.value.pharmacistNo).then(res => {
if (res.success && res.data) {
yaoshiImg.value = `data:image/png;base64,${res.data}`
}
})
}
}
async function handleInsurancePayment() {
showLoading();
const res = await getRxMedicinePurchaseOrderId({
accountId: userInfo.value.userId,
rpNo: id.value
});
hideLoading()
if (res && res.success) {
if (res.status === 'unpay') {
uni.navigateTo({
url: `/pages/consult/drug-purchase-order/drug-purchase-order?id=${res.id}`
})
}
else if (res.status === 'expired') {
await toast('订单已过期');
getRx();
}
else {
uni.navigateTo({
url: `/pages/consult/drug-purchase-list/detail?id=${res.id}`
})
}
} else {
toast(res.message || '获取在线配药订单失败');
}
}
function viewOrder() {
uni.navigateTo({
url: `/pages/consult/drug-purchase-list/detail?id=${data.value.purchaseOrder._id}`
})
}
</script>
<style scoped>
.prescription-container {
max-width: 750rpx;
margin: 0 auto;
font-family: "SimSun", serif;
background: #fff;
box-shadow: 0 4rpx 30rpx rgba(0, 0, 0, 0.1);
line-height: 1.5;
padding: 24rpx 24rpx 240rpx;
font-size: 28rpx;
}
/* 头部样式 */
.header {
border-bottom: 1px solid #000;
padding-bottom: 32rpx;
margin-bottom: 24rpx;
}
.row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12rpx;
}
.company {
font-size: 30rpx;
font-weight: bold;
}
.prescription-type {
font-size: 28rpx;
color: #666;
border: 1px solid #333;
width: 80rpx;
text-align: center;
}
.hospital {
font-size: 32rpx;
font-weight: bold;
text-align: center;
margin: 16rpx 0;
}
.sub-header {
display: flex;
justify-content: space-between;
font-size: 28rpx;
margin-top: 20rpx;
flex-direction: column;
}
/* 患者信息表格 */
.patient-info {
margin: 24rpx 0;
}
.info-row {
display: flex;
padding: 12rpx 8rpx;
}
.info-row:last-child {
border-bottom: none;
}
.info-item {
padding: 0 8rpx;
white-space: normal;
}
.full-width {
width: 100% !important;
}
/* 诊断区域 */
.diagnosis-section {
margin: 30rpx 0;
}
.diagnosis-header {
display: flex;
justify-content: space-between;
margin-bottom: 16rpx;
}
.date {
font-size: 26rpx;
color: #666;
}
/* 药品处方 */
.medicine-section {
position: relative;
padding-left: 60rpx;
margin: 36rpx 0;
}
.rp-symbol {
position: absolute;
left: 0;
top: 0;
font-weight: bold;
}
.medicine-item {
margin-bottom: 30rpx;
}
.medicine-name {
font-weight: bold;
}
.medicine-spec {
color: #666;
margin: 6rpx 0;
}
/* 底部签章 */
.footer {
border-top: 1px dashed #999;
padding-top: 30rpx;
margin-top: 40rpx;
}
.stamp-area {
margin-bottom: 30rpx;
}
.signatures {
display: flex;
margin-top: 30rpx;
}
.signature-item {
padding: 0 16rpx;
}
.stamp {
position: relative;
/* margin-top: 50rpx; */
}
.signImage {
display: inline-block;
width: 100rpx;
height: 40rpx;
}
.stamp-img {
position: absolute;
left: 0;
top: -150rpx;
width: 280rpx;
height: 280rpx;
}
.notice {
color: #d32f2f;
font-size: 24rpx;
margin-top: 30rpx;
}
.no {
margin-top: 10rpx;
}
.expired-icon {
position: absolute;
right: 80rpx;
top: 30%;
width: 240rpx;
height: 240rpx;
}
</style>