Files
xk-doctor-wx/subPackages/sub_workbench/workbench_infoPatient.vue
2026-07-03 16:49:12 +08:00

814 lines
28 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>
<view class="page-bg safe-padding">
<!-- 状态头部 (Modern Banner) -->
<view class="status-banner"
:class="infoList.status==1&&'bg_blue'||infoList.status==2&&'bg_green'||infoList.status==3&&'bg_purple'||infoList.status==7&&'bg_red'">
<view class="status-content flex-row flex-jus-sp flex-ali-center">
<text class="fs-36 font-bold text-white">{{infoList.status==1&&'待接诊'||infoList.status==2&&'已接诊'||infoList.status==3&&'已完成'||infoList.status==7&&'已拒诊'}}</text>
<image class="status-icon"
:src="infoList.status==1&&'/static/info/djz.png'||infoList.status==2&&'/static/info/yjz.png'||infoList.status==3&&'/static/info/ywc.png'||infoList.status==7&&'/static/info/jz.png'"
mode="aspectFit"></image>
</view>
</view>
<!-- 内容区域 -->
<view class="content-container">
<!-- 就诊人信息 -->
<view class="modern-card">
<view class="card-title">就诊人</view>
<view class="info-row">
<text class="info-label">姓名</text>
<text class="info-value font-bold">{{infoList.patient.name}}</text>
</view>
<view class="info-row">
<text class="info-label">性别</text>
<text class="info-value">{{infoList.patient.sex%2==0?'女':'男'}}</text>
</view>
<view class="info-row">
<text class="info-label">年龄</text>
<text class="info-value">{{infoList.patient.age}}</text>
</view>
<view class="info-row">
<text class="info-label">手机号</text>
<text class="info-value">{{infoList.patient.mobile}}</text>
</view>
<view class="info-row">
<text class="info-label">身份证号</text>
<text class="info-value">{{infoList.patient.id_card}}</text>
</view>
</view>
<!-- 特色方信息 -->
<view v-if="infoList.special_prescription_patient_record" class="modern-card">
<view class="card-title">特色方</view>
<view class="special-rx-info flex-row flex-ali-center">
<u-image
v-if="infoList.special_prescription_patient_record.special_prescription && infoList.special_prescription_patient_record.special_prescription.cover_image"
width="96rpx"
height="96rpx"
border-radius="12"
:src="infoList.special_prescription_patient_record.special_prescription.cover_image"
/>
<view class="flex-1 m-l-16">
<view class="info-value font-bold">
{{ (infoList.special_prescription_patient_record.special_prescription && infoList.special_prescription_patient_record.special_prescription.name) || '特色方' }}
</view>
<view class="info-row" style="border-bottom: none; padding: 8rpx 0 0;">
<text class="info-label">剂量</text>
<text class="info-value">{{ infoList.special_prescription_patient_record.dose_count }} </text>
</view>
<view class="info-row" style="border-bottom: none; padding: 8rpx 0 0;">
<text class="info-label">规格</text>
<text class="info-value">{{ specialPrescriptionPurchaseLabel }}</text>
</view>
<view class="-8">
<u-tag
v-if="Number(infoList.special_prescription_patient_record.status) === 0"
text="待导入"
type="warning"
size="mini"
/>
<u-tag
v-else-if="Number(infoList.special_prescription_patient_record.status) === 1"
text="已应用"
type="success"
size="mini"
/>
<u-tag v-else text="已完成" type="info" size="mini" />
</view>
</view>
</view>
<view class="m-t-24">
<u-button
type="primary"
shape="circle"
:custom-style="{ backgroundColor: '#6ACDBB', color: '#fff', border: 'none' }"
@click="goImportSpecialPrescription"
>
导入
</u-button>
</view>
</view>
<!-- 挂号信息 -->
<view class="modern-card">
<view class="card-title">挂号信息</view>
<view class="info-row">
<text class="info-label">就诊时间</text>
<text class="info-value">{{ $u.timeFormat(infoList.created_at, 'yyyy-mm-dd')}}</text>
</view>
<view class="info-row">
<text class="info-label">就诊诊所</text>
<text class="info-value">{{ infoList.store.name}}</text>
</view>
<view class="info-row">
<text class="info-label">科室</text>
<text class="info-value">{{infoList.depart.name}}</text>
</view>
<view class="info-row">
<text class="info-label">医生</text>
<text class="info-value">{{infoList.doctor.name}}</text>
</view>
<view class="info-row">
<text class="info-label">挂号费用</text>
<text class="info-value error-text font-bold">{{infoList.price}}</text>
</view>
<view class="info-row">
<text class="info-label">挂号单号</text>
<text class="info-value">{{infoList.order_no}}</text>
</view>
</view>
<!-- 健康信息 -->
<view class="modern-card">
<view class="card-title">健康信息</view>
<view class="info-row">
<text class="info-label">既往史</text>
<text class="info-value">{{infoList.healthInquery.person_status==0?'无':infoList.healthInquery.person_history}}</text>
</view>
<view class="info-row">
<text class="info-label">过敏史</text>
<text class="info-value" :class="{'error-text font-bold': infoList.healthInquery.allergic_status!=0}">{{infoList.healthInquery.allergic_status==0?'无':infoList.healthInquery.allergic_history}}</text>
</view>
<view class="info-row">
<text class="info-label">家族遗传史</text>
<text class="info-value">{{infoList.healthInquery.family_status==0?'无':infoList.healthInquery.family_history}}</text>
</view>
<view class="info-row">
<text class="info-label">肝功能异常</text>
<text class="info-value" :class="{'error-text font-bold': infoList.healthInquery.liver_function!=0}">{{infoList.healthInquery.liver_function==0?'正常':'异常'}}</text>
</view>
<view class="info-row">
<text class="info-label">肾功能异常</text>
<text class="info-value" :class="{'error-text font-bold': infoList.healthInquery.renal_function!=0}">{{infoList.healthInquery.renal_function==0?'正常':'异常'}}</text>
</view>
</view>
<!-- 处方/拒诊信息 -->
<view class="modern-card">
<view class="card-title">{{ infoList.status==7?'拒诊原因' :'处方信息'}}</view>
<template v-if="infoList.status==7">
<view class="info-row">
<text class="info-label">原因</text>
<text class="info-value error-text font-bold">{{infoList.refuse_reason}}</text>
</view>
<view class="info-row">
<text class="info-label">拒诊时间</text>
<text class="info-value">{{$u.timeFormat(infoList.updated_at, 'yyyy-mm-dd')}}</text>
</view>
</template>
<template v-else>
<view class="m-b-24">
<u-tabs bar-width="40" :list="rxTabs" :is-scroll="false" :current="rxTabIndex" @change="onRxTabChange" active-color="#00A88A" inactive-color="#8A92A3" bg-color="transparent"></u-tabs>
</view>
<!-- 本次挂号 -->
<view v-if="rxTabIndex===0" class="rx-panel">
<view class="modern-rx-item" v-for="(item, rxIdx) in rxCurrentList" :key="item.id">
<view class="rx-header flex-row flex-jus-sp flex-ali-center">
<view class="rx-no-wrapper flex-row flex-ali-center">
<u-icon name="file-text" color="#00A88A" size="32" class="m-r-8"></u-icon>
<text class="rx-no font-bold color-title">{{item.prescription_no}}</text>
</view>
</view>
<view class="rx-actions flex-row flex-jus-end m-t-16">
<view v-if="item.can_withdraw" class="action-btn-ghost danger" @click="withdrawRxByIndex('current', rxIdx)">撤回</view>
<view class="action-btn-ghost primary m-l-16" @click="goToReusePrescription(item.id)">复用</view>
<view class="action-btn-ghost default m-l-16" @click="openPrescriptionDetail(item.id)">查看处方</view>
</view>
</view>
<view class="empty-state m-t-32" v-if="!rxLoadingMore && rxCurrentList.length===0">
<u-empty text="该患者并未开处方" mode="list"></u-empty>
</view>
<view class="load-tip flex-row flex-jus-center flex-ali-center" v-if="rxLoadingMore">
<u-loading mode="circle" color="#00A88A"></u-loading> <text class="m-l-8 fs-24 color-sub">加载中</text>
</view>
<view class="load-tip fs-24 color-sub" v-if="!rxCurrentHasMore && rxCurrentList.length>0">已加载全部</view>
</view>
<!-- 历史处方 -->
<view v-if="rxTabIndex===1" class="rx-panel">
<block v-for="(item, idx) in rxHistoryList" :key="item.id">
<view class="rx-timeline-divider flex-row flex-ali-center" v-if="historyShowDivider(idx)">
<view class="timeline-dot"></view>
<text class="timeline-text">挂号 {{ formatRegisterTime(item.register) }} · 单号 {{ historyOrderNo(item) }}</text>
</view>
<view class="modern-rx-item">
<view class="rx-header flex-row flex-jus-sp flex-ali-center">
<view class="rx-no-wrapper flex-row flex-ali-center">
<u-icon name="file-text" color="#8A92A3" size="32" class="m-r-8"></u-icon>
<text class="rx-no color-title">{{item.prescription_no}}</text>
</view>
</view>
<view class="rx-actions flex-row flex-jus-end m-t-16">
<view v-if="item.can_withdraw" class="action-btn-ghost danger" @click="withdrawRxByIndex('history', idx)">撤回</view>
<view class="action-btn-ghost primary m-l-16" @click="goToReusePrescription(item.id)">复用</view>
<view class="action-btn-ghost default m-l-16" @click="openPrescriptionDetail(item.id)">查看处方</view>
</view>
</view>
</block>
<view class="empty-state m-t-32" v-if="!rxLoadingMore && rxHistoryList.length===0">
<u-empty text="暂无历史处方" mode="history"></u-empty>
</view>
<view class="load-tip flex-row flex-jus-center flex-ali-center" v-if="rxLoadingMore">
<u-loading mode="circle" color="#00A88A"></u-loading> <text class="m-l-8 fs-24 color-sub">加载中</text>
</view>
<view class="load-tip fs-24 color-sub" v-if="!rxHistoryHasMore && rxHistoryList.length>0">已加载全部</view>
</view>
</template>
</view>
</view>
<u-modal v-model="show" title="操作提示" :show-cancel-button="true" :content="content" @confirm="confirm"
confirm-color="#00A88A" cancel-color="#8A92A3"></u-modal>
<d-loading-page :loading="loading"></d-loading-page>
<!-- 底部操作栏 -->
<view class="bottom-action-bar safe-area-inset-bottom shadow-up flex-row flex-jus-center flex-ali-center white" v-if="flag&&infoList.status!=3">
<u-button v-if="infoList.status==1" @click="$go('workbench_reason?id='+infoList.id)" shape="circle"
:custom-style="{ height: '88rpx', width: '330rpx', backgroundColor: '#F4F6F8', color: '#2A2E35', border: 'none', fontSize: '30rpx', fontWeight: 'bold' }">拒绝
</u-button>
<u-button v-if="infoList.status==1" @click="accept(infoList.id,infoList.user_patient_id)" shape="circle"
:custom-style="{ height: '88rpx', width: '330rpx', backgroundColor: '#00A88A', color: '#fff', border: 'none', fontSize: '30rpx', fontWeight: 'bold', boxShadow: '0 8rpx 20rpx rgba(0, 168, 138, 0.25)' }">接诊
</u-button>
<u-button v-if="infoList.status==2" @click="acceptEnds(infoList.id,infoList.user_patient_id)" shape="circle"
:custom-style="{ height: '88rpx', width: '330rpx', backgroundColor: '#F4F6F8', color: '#2A2E35', border: 'none', fontSize: '30rpx', fontWeight: 'bold' }">结束问诊
</u-button>
<u-button v-if="infoList.status==2" @click="goToPrescriptionV2" shape="circle"
:custom-style="{ height: '88rpx', width: '330rpx', backgroundColor: '#00A88A', color: '#fff', border: 'none', fontSize: '30rpx', fontWeight: 'bold' }">开具处方
</u-button>
</view>
</view>
</template>
<script>
import {
getPatientItem,
getRegisterPrescriptionList,
getPatientPrescriptionHistory,
withdrawPrescriptionWx,
receptionApi,
endOfDiagnosisApi
} from '@/api/reception.js'
import { pickSpecialPrescriptionRecord, resolveSpecialPrescriptionPurchaseLabel } from '@/subPackages/sub_workbench/prescription_v2/utils/specialPrescription.js'
function emptyHealthInquiry() {
return {
person_status: 0,
person_history: '',
allergic_status: 0,
allergic_history: '',
family_status: 0,
family_history: '',
liver_function: 0,
renal_function: 0
}
}
function normalizeRegisterDetail(raw) {
if (!raw || typeof raw !== 'object') {
raw = {}
}
const up = raw.userPatient || raw.user_patient || {}
const dept = raw.department || raw.depart || {}
const doc = raw.doctorInfo || raw.doctor_info || {}
const hi = raw.userPatientHealthInquiry || raw.user_patient_health_inquiry || emptyHealthInquiry()
const store = raw.store || {}
return Object.assign({}, raw, {
patient: up,
depart: dept && dept.name !== undefined ? dept : {
name: ''
},
doctor: doc && doc.name !== undefined ? doc : {
name: ''
},
store: store && store.name !== undefined ? store : {
name: ''
},
healthInquery: hi || emptyHealthInquiry(),
special_prescription_patient_record: pickSpecialPrescriptionRecord(raw),
})
}
export default {
data() {
return {
flag: true,
item: {},
status: "loading",
infoList: normalizeRegisterDetail(null),
loading: true,
id: "",
re_id: "",
show: false,
content: '确认结束本次问诊吗?',
rxTabs: [{
name: '本次挂号'
}, {
name: '历史处方'
}],
rxTabIndex: 0,
rxCurrentList: [],
rxHistoryList: [],
rxCurrentNextPage: 1,
rxHistoryNextPage: 1,
rxCurrentHasMore: true,
rxHistoryHasMore: true,
rxLoadingMore: false
};
},
computed: {
/** 特色方卡片规格SKU 名或单剂 */
specialPrescriptionPurchaseLabel() {
return resolveSpecialPrescriptionPurchaseLabel(this.infoList?.special_prescription_patient_record)
},
},
onLoad(op) {
this.id = op["id"]
this.re_id = op['re_id']
this.getList();
},
onReachBottom() {
if (this.infoList.status === 7) return
if (this.rxTabIndex === 0) {
this.loadRxCurrent(false)
} else {
this.loadRxHistory(false)
}
},
methods: {
apiOk(res) {
return res && (res.code === 0 || res.errcode === 0)
},
apiMsg(res) {
return res.message || res.msg || '请求失败'
},
historyShowDivider(idx) {
if (idx === 0) return true
const cur = this.rxHistoryList[idx]
const prev = this.rxHistoryList[idx - 1]
if (!cur || !prev) return false
const curRid = cur.register_id || (cur.register && cur.register.id)
const prevRid = prev.register_id || (prev.register && prev.register.id)
return curRid !== prevRid
},
formatRegisterTime(reg) {
if (!reg || reg.created_at === undefined || reg.created_at === null) return '-'
const t = reg.created_at
try {
return this.$u.timeFormat(t, 'yyyy-mm-dd hh:MM')
} catch (e) {
return String(t)
}
},
historyOrderNo(item) {
if (item && item.register && item.register.order_no) {
return item.register.order_no
}
return item && item.register_id ? item.register_id : ''
},
openPrescriptionDetail(prescriptionId) {
this.$go('/subPackages/sub_my/prescriptionDetail?id=' + prescriptionId)
},
withdrawRxByIndex(which, index) {
const list = which === 'current' ? this.rxCurrentList : this.rxHistoryList
const item = list[index]
if (!item) return
this.withdrawRx(item)
},
onRxTabChange(index) {
this.rxLoadingMore = false
this.rxTabIndex = index
if (index === 0) {
this.rxCurrentNextPage = 1
this.rxCurrentList = []
this.rxCurrentHasMore = true
this.loadRxCurrent(true)
} else {
this.rxHistoryNextPage = 1
this.rxHistoryList = []
this.rxHistoryHasMore = true
this.loadRxHistory(true)
}
},
loadRxCurrent(isReset) {
if (this.rxLoadingMore) return
if (!isReset && !this.rxCurrentHasMore) return
if (isReset) {
this.rxCurrentNextPage = 1
this.rxCurrentList = []
this.rxCurrentHasMore = true
}
const page = this.rxCurrentNextPage
this.rxLoadingMore = true
getRegisterPrescriptionList({
register_id: this.re_id,
page,
page_size: 20
}).then((res) => {
this.rxLoadingMore = false
if (!this.apiOk(res)) {
this.$toast(this.apiMsg(res))
return
}
const payload = res.result || res.data || {}
const list = payload.list || []
this.rxCurrentList = page === 1 ? list : this.rxCurrentList.concat(list)
this.rxCurrentHasMore = payload.has_more === true
if (list.length) {
this.rxCurrentNextPage = page + 1
} else {
this.rxCurrentHasMore = false
}
}).catch(() => {
this.rxLoadingMore = false
})
},
loadRxHistory(isReset) {
if (this.rxLoadingMore) return
if (!isReset && !this.rxHistoryHasMore) return
if (isReset) {
this.rxHistoryNextPage = 1
this.rxHistoryList = []
this.rxHistoryHasMore = true
}
const page = this.rxHistoryNextPage
this.rxLoadingMore = true
getPatientPrescriptionHistory({
patient_id: this.id,
page,
page_size: 20,
exclude_register_id: this.re_id
}).then((res) => {
this.rxLoadingMore = false
if (!this.apiOk(res)) {
this.$toast(this.apiMsg(res))
return
}
const payload = res.result || res.data || {}
const list = payload.list || []
this.rxHistoryList = page === 1 ? list : this.rxHistoryList.concat(list)
this.rxHistoryHasMore = payload.has_more === true
if (list.length) {
this.rxHistoryNextPage = page + 1
} else {
this.rxHistoryHasMore = false
}
}).catch(() => {
this.rxLoadingMore = false
})
},
withdrawRx(item) {
const prescriptionId = item.id
const registerId = item.register_id || this.re_id
uni.showModal({
title: '撤回处方',
content: '确认撤回该处方?(仅待支付可撤回)',
success: (r) => {
if (!r.confirm) return
withdrawPrescriptionWx({
prescription_id: prescriptionId,
register_id: registerId,
reason: ''
}).then((res) => {
if (!this.apiOk(res)) {
this.$toast(this.apiMsg(res))
return
}
this.$toast('已撤回')
if (this.rxTabIndex === 0) {
this.loadRxCurrent(true)
} else {
this.loadRxHistory(true)
}
})
}
})
},
/**
* 拼装开方页 URL
* @param {number|string} registerId 挂号 ID
* @param {number|string} patientId 就诊人 ID
* @param {boolean} importSpecial 是否自动导入特色方
*/
buildPrescriptionV2Url(registerId, patientId, importSpecial = false) {
let url = `/subPackages/sub_workbench/prescription_v2/index?register_id=${registerId}`;
if (patientId) {
url += `&patient_id=${patientId}`;
}
if (importSpecial) {
url += '&import_special=1';
}
return url;
},
/**
* 延迟跳转开方页(接诊成功后统一入口)
*/
navigateToPrescriptionV2(registerId, patientId, importSpecial = false) {
setTimeout(() => {
this.$go(this.buildPrescriptionV2Url(registerId, patientId, importSpecial));
}, 800);
},
// 接诊
accept(registerId, patientId) {
// 接诊前缓存特色方记录,避免 getList 异步刷新导致判断丢失
const hasSp = !!this.infoList?.special_prescription_patient_record;
receptionApi(registerId).then((res) => {
if (!this.apiOk(res)) {
this.$toast(this.apiMsg(res));
return;
}
this.$toast('已接诊');
this.getList();
if (!hasSp) {
this.navigateToPrescriptionV2(registerId, patientId, false);
return;
}
uni.showModal({
title: '导入特色方',
content: '该患者已选择特色方,是否立即导入?',
confirmColor: '#00A88A',
cancelColor: '#8A92A3',
success: (modalRes) => {
this.navigateToPrescriptionV2(registerId, patientId, !!modalRes.confirm);
},
});
});
},
// 结束问诊
acceptEnds(e) {
uni.setStorageSync('register_id_', e)
this.show = true;
},
confirm() {
const rid = uni.getStorageSync('register_id_')
endOfDiagnosisApi(rid).then((res) => {
if (this.apiOk(res)) {
this.$toast('已结束问诊');
setTimeout(() => {
this.getList()
}, 1000)
} else {
this.$toast(this.apiMsg(res));
}
})
},
getList() {
this.loading = true
getPatientItem(this.re_id).then((res) => {
this.loading = false
if (!this.apiOk(res)) {
this.$toast(this.apiMsg(res))
return
}
const raw = res.result || res.data || res
this.infoList = normalizeRegisterDetail(raw)
if (this.infoList.status !== 7) {
if (this.rxTabIndex === 0) {
this.loadRxCurrent(true)
} else {
this.loadRxHistory(true)
}
}
}).catch(() => {
this.loading = false
})
},
goToPrescriptionV2() {
const registerId = this.infoList.id;
const patientId = this.infoList.user_patient_id;
this.$go(this.buildPrescriptionV2Url(registerId, patientId, false));
},
goImportSpecialPrescription() {
const registerId = this.infoList.id;
const patientId = this.infoList.user_patient_id;
if (!registerId) {
this.$toast('挂号信息无效');
return;
}
this.$go(this.buildPrescriptionV2Url(registerId, patientId, true));
},
goToReusePrescription(prescriptionId) {
const registerId = this.infoList.id;
const patientId = this.infoList.user_patient_id;
if (!registerId || !patientId || !prescriptionId) {
this.$toast('参数错误');
return;
}
this.$go(`/subPackages/sub_workbench/prescription_v2/index?register_id=${registerId}&patient_id=${patientId}&reuse_prescription_id=${prescriptionId}`);
},
},
onShow() {
this.getList();
}
};
</script>
<style>
page {
background-color: #F4F6F8;
}
</style>
<style lang="scss" scoped>
.page-bg {
background-color: #F4F6F8;
min-height: 100vh;
}
.safe-padding {
padding-bottom: 240rpx; /* 留出底部操作栏空间 */
}
/* Flex Layout Helpers */
.flex-row { display: flex; flex-direction: row; }
.flex-col { display: flex; flex-direction: column; }
.flex-jus-sp { justify-content: space-between; }
.flex-jus-center { justify-content: center; }
.flex-jus-end { justify-content: flex-end; }
.flex-ali-center { align-items: center; }
/* Colors & Typography */
.white { background: #fff; }
.text-white { color: #ffffff; }
.fs-24 { font-size: 24rpx; }
.fs-36 { font-size: 36rpx; }
.font-bold { font-weight: bold; }
.color-title { color: #2A2E35; }
.color-sub { color: #8A92A3; }
.error-text { color: #F53F3F; }
.m-b-24 { margin-bottom: 24rpx; }
.m-t-16 { margin-top: 16rpx; }
.m-t-32 { margin-top: 32rpx; }
.m-r-8 { margin-right: 8rpx; }
.m-l-8 { margin-left: 8rpx; }
.m-l-16 { margin-left: 16rpx; }
/* Status Banner (Modernized) */
.status-banner {
padding: 40rpx 48rpx;
border-radius: 0 0 40rpx 40rpx;
box-shadow: 0 8rpx 20rpx rgba(0,0,0,0.05);
&.bg_blue { background: linear-gradient(135deg, #60A5FA 0%, #3B82F6 100%); }
&.bg_green { background: linear-gradient(135deg, #6ACDBB 0%, #00A88A 100%); }
&.bg_purple { background: linear-gradient(135deg, #A78BFA 0%, #8B5CF6 100%); }
&.bg_red { background: linear-gradient(135deg, #F87171 0%, #EF4444 100%); }
.status-icon {
width: 64rpx;
height: 64rpx;
opacity: 0.9;
}
}
.content-container {
padding: 0 32rpx;
margin-top: 32rpx;
}
/* Modern Card UI */
.modern-card {
background: #fff;
border-radius: 16rpx;
padding: 32rpx;
margin-bottom: 24rpx;
box-shadow: 0 4rpx 16rpx rgba(42, 46, 53, 0.04);
.card-title {
font-size: 32rpx;
font-weight: bold;
color: #2A2E35;
margin-bottom: 24rpx;
display: flex;
align-items: center;
position: relative;
padding-left: 20rpx;
&::before {
content: '';
position: absolute;
left: 0;
width: 8rpx;
height: 32rpx;
background: #00A88A;
border-radius: 4rpx;
}
}
}
/* Info Rows */
.info-row {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 16rpx;
line-height: 1.5;
&:last-child {
margin-bottom: 0;
}
.info-label {
width: 180rpx;
font-size: 28rpx;
color: #8A92A3;
flex-shrink: 0;
}
.info-value {
flex: 1;
font-size: 28rpx;
color: #2A2E35;
text-align: right;
word-break: break-all;
}
}
/* Rx Timeline & Items */
.rx-panel {
padding-top: 16rpx;
}
.rx-timeline-divider {
margin: 32rpx 0 16rpx;
.timeline-dot {
width: 12rpx;
height: 12rpx;
background-color: #D1D5DB;
border-radius: 50%;
margin-right: 16rpx;
}
.timeline-text {
font-size: 26rpx;
color: #9CA3AF;
font-weight: bold;
}
}
.modern-rx-item {
background: #F8FAFC;
border: 1px solid #F1F5F9;
border-radius: 12rpx;
padding: 24rpx;
margin-bottom: 16rpx;
transition: all 0.2s;
.rx-no {
font-size: 28rpx;
}
}
/* Modern Ghost Buttons */
.action-btn-ghost {
padding: 10rpx 32rpx;
border-radius: 30rpx;
font-size: 26rpx;
font-weight: bold;
border: 1px solid transparent;
display: flex;
align-items: center;
&.primary {
color: #00A88A;
background: #E8F6F4;
}
&.danger {
color: #F53F3F;
background: #FEF0F0;
}
&.default {
color: #6C7380;
background: #fff;
border-color: #E2E8F0;
}
}
.load-tip {
text-align: center;
padding: 24rpx 0;
}
/* Bottom Action Bar */
.bottom-action-bar {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
padding: 24rpx 32rpx calc(24rpx + env(safe-area-inset-bottom));
gap: 32rpx;
background-color: #fff;
z-index: 99;
&.shadow-up {
box-shadow: 0 -4rpx 20rpx rgba(0,0,0,0.04);
}
}
</style>