Files
xk-doctor-wx/subPackages/sub_clinic_admin/order/components/PrescriptionDetailPopup.vue
李琦 27202c0740 1. 优化了一些交互,中药药品编辑交互
2. dev和生产环境统一鉴别
2026-05-30 13:53:14 +08:00

591 lines
16 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>
<u-popup v-model="show" mode="bottom" border-radius="20" height="85%" :closeable="true" @close="onClose">
<view class="popup-wrap">
<scroll-view v-if="view" scroll-y class="popup-scroll">
<view class="container safe-area-inset-bottom">
<!-- 处方头部 -->
<view class="head">
<view class="head_record_top">
<view class="record">
处方编号{{ view.prescriptionNo }}
</view>
<view class="record_state">
{{ view.typeText }}
</view>
</view>
<!-- 动态医院与公章 -->
<view class="head_record">
<image :src="view.sealImage || '/static/group/xkyard.png'" mode="aspectFit"></image>
<view class="record_yard">
<view class="yard">
{{ view.storeName }}
</view>
<view class="state">
处方笺
</view>
</view>
</view>
<!-- 时间 -->
<view class="head_record_time">
<text style="text-align: right;">开具日期{{ view.createdAt }}</text>
</view>
</view>
<!-- 患者信息 -->
<view class="my_info">
<view class="info">
<view class="info_item">
<view class="name">姓名<text>{{ view.patientName }}</text></view>
</view>
<view class="info_item">
<view class="name">性别<text>{{ view.patientSex }}</text></view>
</view>
<view class="info_item">
<view class="name">年龄<text>{{ view.patientAge }}</text></view>
</view>
<view class="info_item">
<view class="name">类别<text>{{ view.category }}</text></view>
</view>
</view>
<view class="info">
<view class="info_item">
<view class="name">科室<text>{{ view.departName }}</text></view>
</view>
<view class="info_item" v-if="view.patientMobile">
<view class="name">电话<text>{{ view.patientMobile }}</text></view>
</view>
</view>
<view class="info">
<view class="info_item">
<view class="names">诊断<text>{{ view.diagnose }}</text></view>
</view>
</view>
<!-- 中医专属字段 -->
<view v-if="view.tcmSyndrome || view.tcmMethod || view.tcmDisease" class="info">
<view v-if="view.tcmSyndrome" class="info_item">
<view class="names">中医证候<text>{{ view.tcmSyndrome }}</text></view>
</view>
<view v-if="view.tcmMethod" class="info_item">
<view class="names">中医治法<text>{{ view.tcmMethod }}</text></view>
</view>
<view v-if="view.tcmDisease" class="info_item">
<view class="names">中医疾病<text>{{ view.tcmDisease }}</text></view>
</view>
</view>
</view>
<view class="bg">
<!-- 处方明细区 (Rp) -->
<view class="my_medical">
<view class="title">Rp</view>
<view v-for="(recipe, rIdx) in view.recipes" :key="rIdx" class="item">
<view class="name">
<view class="_name" v-for="(drug, dIdx) in recipe.drugs" :key="dIdx">
<view class="text">
<text>{{ drug.name }}</text>
<text class="_abbr" v-if="drug.usage">[{{ drug.usage }}]</text>
</view>
<text class="name_num">{{ drug.qty }}</text>
</view>
</view>
<view class="details" v-if="recipe.usage || recipe.process">
<view class="text">
<text v-if="recipe.usage">用法{{ recipe.usage }}</text>
<text v-if="recipe.process" style="margin-left: 10rpx;">包装方式{{ recipe.process }}</text>
</view>
</view>
</view>
</view>
<!-- 医嘱 -->
<view class="doctor_order">
<view class="yz">
<text class="order_info_left">医嘱:</text>
<view class="order_info">
<view class="info">{{ view.doctorOrder !== '-' ? view.doctorOrder : '无' }}</view>
</view>
</view>
<view class="titles">处方开具已完毕</view>
</view>
</view>
<!-- 动态医生与药师签名区 -->
<view class="my_doctor">
<view class="doctor_info">
<view class="info">
<text>医师</text>
<image v-if="view.doctorSignImage" :src="checkImageUrl(view.doctorSignImage)" mode="aspectFit"></image>
<text v-else class="name">{{ view.doctorName }}</text>
</view>
<view class="info">
<text>审核药师</text>
<image v-if="view.pharmacistSignImage" :src="checkImageUrl(view.pharmacistSignImage)" mode="aspectFit"></image>
<text v-else class="name"></text>
</view>
<view class="info">
<text>发药人</text>
<image v-if="view.pharmacistSignImage" :src="checkImageUrl(view.pharmacistSignImage)" mode="aspectFit"></image>
<text v-else class="name"></text>
</view>
<view class="info">
<text>核对人</text>
<image v-if="view.pharmacistSignImage" :src="checkImageUrl(view.pharmacistSignImage)" mode="aspectFit"></image>
<text v-else class="name"></text>
</view>
<view class="info">
<text>调配人</text>
<image v-if="view.pharmacistSignImage" :src="checkImageUrl(view.pharmacistSignImage)" mode="aspectFit"></image>
<text v-else class="name"></text>
</view>
</view>
<!-- 价格 -->
<view class="price" v-if="view.totalPayPrice">
价格 {{ view.totalPayPrice }}
</view>
</view>
<!-- 动态有效期温馨提示 -->
<view class="my_prompt">
<view class="title">
温馨提示请遵医嘱服药处方{{ view.validHours }}小时有效
</view>
<image src="/static/group/img-yzf.png" mode="aspectFit" v-if="view.status == 2"></image>
</view>
</view>
</scroll-view>
<view v-else-if="loading" class="popup-loading">加载中...</view>
<view v-else class="popup-loading">暂无数据</view>
</view>
</u-popup>
</template>
<script>
import { getPrescriptionDetail } from '@/api/clinicAdmin.js'
import { mapPrescriptionDetailView } from '../../common/display.js'
export default {
name: 'PrescriptionDetailPopup',
data() {
return {
show: false,
loading: false,
view: null,
}
},
methods: {
// 解析签名图片,自动兼容 base64 和 http 链接
checkImageUrl(url) {
if (!url) return ''
return url.includes('http') ? url : 'data:image/jpeg;base64,' + url
},
open(prescriptionId) {
if (!prescriptionId) return
this.show = true
this.view = null
this.loading = true
getPrescriptionDetail(prescriptionId).then(w => {
if (w.ok && w.data) {
// 复用原有的处方解析逻辑
const mapped = mapPrescriptionDetailView(w.data)
// --- 动态注入你新版 UI 需要的独有字段 ---
mapped.storeName = w.data.store ? w.data.store.name : '未知诊所'
mapped.sealImage = w.data.store ? w.data.store.offical_seal : ''
mapped.typeText = w.data.type == 1 ? '普通' : '常用'
mapped.totalPayPrice = w.data.total_pay_price || '0.00'
mapped.doctorSignImage = w.data.doctor_sign_image || ''
mapped.pharmacistSignImage = w.data.Pharmacist_sign_image || ''
mapped.validHours = w.data.valid_hours || 72
mapped.status = w.data.status
mapped.patientMobile = w.data.patient ? w.data.patient.mobile : ''
this.view = mapped
}
}).finally(() => {
this.loading = false
})
},
onClose() {
this.view = null
},
},
}
</script>
<style lang="scss" scoped>
.popup-wrap {
height: 100%;
display: flex;
flex-direction: column;
background-color: #fff;
position: relative;
padding-top: 60rpx; /* 给默认的关闭按钮留出空间 */
}
.popup-scroll {
flex: 1;
height: 0;
}
.popup-loading {
text-align: center;
color: #999;
padding: 80rpx;
}
/* --- 原汁原味的 prescriptionDetail.vue 核心样式 (自适应修复版) --- */
.container {
width: 100%;
padding: 0 20rpx 40rpx;
box-sizing: border-box;
.bg {
min-height: 400rpx;
}
.head {
.head_record_top {
width: 100%;
margin: 14rpx auto 0;
display: flex;
align-items: center;
justify-content: space-between;
.record {
font-size: 28rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #6C7380;
}
.record_state {
width: 80rpx;
height: 42rpx;
line-height: 42rpx;
text-align: center;
font-size: 24rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #A7ABB0;
border: 1rpx solid #C4C7CC;
}
}
.head_record {
display: flex;
align-items: center;
justify-content: center;
position: relative;
image {
width: 160rpx;
height: 150rpx;
position: absolute;
left: 40%; /* 也可以根据需要调整居中印章 */
top: -8rpx;
opacity: 0.2; /* 添加微透明度防止完全遮盖文字 */
z-index: 0;
}
.record_yard {
text-align: center;
z-index: 1;
.yard {
font-size: 46rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #31353D;
}
.state {
height: 44rpx;
font-size: 32rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #31353D;
line-height: 38rpx;
}
}
}
.head_record_time {
text-align: right;
margin-top: 20rpx;
width: 100%;
height: 34rpx;
font-size: 24rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #6C7380;
line-height: 28rpx;
}
}
// 经典信息区
.my_info {
width: 100%;
margin: 4rpx auto;
border-top: 1rpx solid #31353D;
border-bottom: 1rpx solid #31353D;
display: flex;
flex-direction: column;
justify-content: space-around;
padding: 4rpx 4rpx;
.info {
width: 100%;
display: flex;
align-items: center;
flex-wrap: wrap;
.info_item {
.names {
display: flex;
align-items: center;
justify-content: space-around;
font-size: 28rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #6C7380;
text {
flex: 1;
display: block;
height: 40rpx;
font-size: 28rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #31353D;
line-height: 40rpx;
margin: 0 0rpx 0 8rpx;
}
}
.name {
display: flex;
align-items: center;
justify-content: space-around;
font-size: 28rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #6C7380;
text {
flex: 1;
display: block;
height: 40rpx;
font-size: 28rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #31353D;
line-height: 40rpx;
margin: 0 26rpx 0 6rpx;
}
}
}
}
}
// 药品列表
.my_medical {
width: 100%;
margin: 4rpx auto;
padding: 1rpx 10rpx;
box-sizing: border-box;
.title {
font-size: 32rpx;
font-family: PingFang SC-Semibold, PingFang SC;
font-weight: 600;
color: #31353D;
margin-bottom: 2rpx;
}
.item {
width: 100%;
padding: 1rpx 0;
.name {
font-size: 28rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #31353D;
display: flex;
flex-wrap: wrap;
._name {
display: flex;
justify-content: space-between;
margin: 2rpx 80rpx 2rpx 0;
.text {
margin-right: 16rpx;
display: flex;
flex-direction: column;
._abbr {
color: #A7ABB0;
font-size: 20rpx;
margin-top: 2rpx;
}
}
}
}
.details {
font-size: 28rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #6C7380;
display: flex;
flex-direction: column;
justify-content: space-around;
.text {
text {
word-spacing: 1rpx;
}
}
}
}
}
// 医嘱
.doctor_order {
width: 100%;
margin: 2rpx auto;
padding: 0 10rpx;
word-spacing: 2rpx;
box-sizing: border-box;
.yz {
display: flex;
width: 100%;
color: #6C7380;
.order_info_left {
margin-right: 3rpx;
}
.order_info {
font-size: 28rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
line-height: 40rpx;
margin-bottom: 2rpx;
.info {
flex: 1;
}
}
}
.titles {
width: 100%;
font-size: 24rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #A7ABB0;
margin: 8rpx 0 20rpx;
text-align: center;
}
}
// 电子签名及价格
.my_doctor {
width: 100%;
margin: 2rpx auto;
border-top: 1rpx solid #31353D;
border-bottom: 1rpx solid #31353D;
padding: 2rpx 4rpx;
box-sizing: border-box;
.doctor_info {
width: 100%;
display: flex;
align-items: center;
margin-bottom: 4rpx;
flex-wrap: wrap;
.info {
min-width: 222rpx;
max-width: 400rpx;
margin: 5rpx 0 8rpx;
text {
font-size: 24rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #31353D;
}
image {
width: 82rpx;
height: 62rpx;
vertical-align: middle;
margin-left: 10rpx;
}
.name {
display: inline-block;
width: 106rpx;
font-size: 32rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #31353D;
line-height: 38rpx;
border-bottom: 2rpx solid #000000;
margin-left: 16rpx;
text-align: center;
min-height: 38rpx;
}
}
}
.price {
width: 100%;
font-size: 24rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #31353D;
margin: 8rpx 0;
}
}
// 温馨提示
.my_prompt {
width: 100%;
margin: 0 auto;
padding: 0 4rpx;
position: relative;
box-sizing: border-box;
.title {
width: 100%;
font-size: 28rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #A7ABB0;
line-height: 40rpx;
margin: 32rpx 0;
}
image {
width: 159rpx;
height: 100rpx;
position: absolute;
left: 60%;
top: 0%;
}
}
}
</style>