diff --git a/apps/web-antd/src/components/prescription-source/PrescriptionSourceContent.vue b/apps/web-antd/src/components/prescription-source/PrescriptionSourceContent.vue new file mode 100644 index 00000000..d4aa1cfd --- /dev/null +++ b/apps/web-antd/src/components/prescription-source/PrescriptionSourceContent.vue @@ -0,0 +1,276 @@ + + + + + + + + 开具机构 + + + + 机构名称: + {{ data.store.name }} + + + 暂无机构信息 + + + + + + 时间线 + + + + 就诊 + + {{ formatTime(registerInfo?.created_at) }} + · {{ userPatient?.name || '--' }} + + + 性别:{{ patientSexText }} · 年龄:{{ userPatient?.age ?? '--' }} + + + 诊断:{{ data.clinical_diagnose }} + + + + 开具 + {{ data.created_at || '--' }} + + 医生:{{ doctorInfo?.name || '--' }} · 科室:{{ + doctorInfo?.depart?.name || '--' + }} + + + 处方编号:{{ data.prescription_no }} · 类型:{{ prescriptionTypeText }} + + + + 审核 + + {{ data.pharmacist_view_time || '--' }} + + + 状态: + {{ statusText }} + · 药师:{{ pharmacistInfo?.name || '--' }} + + + 驳回原因:{{ data.reject_reason }} + + + 驳回原因:{{ data.cancel_remark }} + + + + + + + + + 处方基本信息 + + + + 处方编号: + {{ data.prescription_no }} + + + 处方类型: + {{ prescriptionTypeText }} + + + 处方状态: + {{ + statusText + }} + + + 总金额: + ¥{{ data.total_pay_price }} + + + 过期时间: + {{ expireTime }} + + + 驳回原因: + {{ data.reject_reason }} + + + + + + + + 医生信息 + + + + 开具医生: + {{ doctorInfo.name }} + + + 开具科室: + {{ doctorInfo.depart?.name || '--' }} + + + 开具机构: + {{ data.store?.name || '--' }} + + + 开具时间: + {{ data.created_at || '--' }} + + + 暂无医生信息 + + + + + + 患者信息 + + + + 患者姓名: + {{ userPatient.name }} + + + 年龄: + {{ userPatient.age }}岁 + + + 性别: + {{ patientSexText }} + + + 暂无患者信息 + + + + + + + + diff --git a/apps/web-antd/src/components/wx-user-patient/WxUserPatientDetailModal.vue b/apps/web-antd/src/components/wx-user-patient/WxUserPatientDetailModal.vue new file mode 100644 index 00000000..6ad91007 --- /dev/null +++ b/apps/web-antd/src/components/wx-user-patient/WxUserPatientDetailModal.vue @@ -0,0 +1,451 @@ + + + + + + + + + + + + + {{ profile.user?.nickname || '—' }} + + + 用户 ID:{{ profile.user?.id ?? '—' }} + + + + + + + + {{ profile.patient?.name || '—' }} + + + {{ + profile.patient?.sex === 1 + ? '男' + : profile.patient?.sex === 2 + ? '女' + : '—' + }} + + + {{ profile.patient?.age ? `${profile.patient.age}岁` : '—' }} + + + + — + + + + + + + + 健康信息 + + + {{ + historyText( + profile.health_inquiry.person_status, + profile.health_inquiry.person_history, + ) + }} + + + + {{ + historyText( + profile.health_inquiry.allergic_status, + profile.health_inquiry.allergic_history, + ) + }} + + + + {{ + historyText( + profile.health_inquiry.family_status, + profile.health_inquiry.family_history, + ) + }} + + + + {{ + functionText( + profile.health_inquiry.liver_function, + profile.health_inquiry.liver_index, + ) + }} + + + + + {{ + functionText( + profile.health_inquiry.renal_function, + profile.health_inquiry.renal_index, + ) + }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/web-antd/src/components/wx-user-patient/WxUserPatientDrawer.vue b/apps/web-antd/src/components/wx-user-patient/WxUserPatientDrawer.vue index dccfd521..8761104c 100644 --- a/apps/web-antd/src/components/wx-user-patient/WxUserPatientDrawer.vue +++ b/apps/web-antd/src/components/wx-user-patient/WxUserPatientDrawer.vue @@ -300,13 +300,15 @@ const orderColumns = [ /> — - + - — diff --git a/apps/web-antd/src/components/wx-user-patient/WxUserPatientsModal.vue b/apps/web-antd/src/components/wx-user-patient/WxUserPatientsModal.vue new file mode 100644 index 00000000..379ca016 --- /dev/null +++ b/apps/web-antd/src/components/wx-user-patient/WxUserPatientsModal.vue @@ -0,0 +1,147 @@ + + + + + + + + + {{ userNickname || '—' }} + 用户 ID:{{ userId || '—' }} + + + + + + + {{ record.name || '—' }} + + + 男 + 女 + — + + + + + + + 详情 + + + + + + + + diff --git a/apps/web-antd/src/components/wx-user-patient/api.ts b/apps/web-antd/src/components/wx-user-patient/api.ts index 229c3263..17bf5576 100644 --- a/apps/web-antd/src/components/wx-user-patient/api.ts +++ b/apps/web-antd/src/components/wx-user-patient/api.ts @@ -5,6 +5,31 @@ import { requestClient } from '#/api/request'; const prefix = 'user-patient-profile/'; +/** 用户管理列表(微信用户 + 就诊人,旧接口) */ +export async function getUserPatientProfileListApi(params?: { + page?: number; + pageSize?: number; + keyword?: string; +}) { + return requestClient.get(`${prefix}list`, { params }); +} + +/** 会员管理:微信用户分页 */ +export async function getWxUserListApi(params?: { + page?: number; + pageSize?: number; + keyword?: string; +}) { + return requestClient.get(`${prefix}user-list`, { params }); +} + +/** 某微信用户下的就诊人列表 */ +export async function getPatientListByUserApi(userId: number) { + return requestClient.get(`${prefix}patient-list-by-user`, { + params: { user_id: userId }, + }); +} + /** 小程序用户 + 就诊人基础信息 */ export async function getUserPatientProfileDetailApi(upId: number) { return requestClient.get(`${prefix}detail`, { diff --git a/apps/web-antd/src/components/wx-user-patient/index.ts b/apps/web-antd/src/components/wx-user-patient/index.ts index 184ca52f..21fef6dd 100644 --- a/apps/web-antd/src/components/wx-user-patient/index.ts +++ b/apps/web-antd/src/components/wx-user-patient/index.ts @@ -3,6 +3,8 @@ */ export { default as WxUserPatientCell } from './WxUserPatientCell.vue'; export { default as WxUserPatientDrawer } from './WxUserPatientDrawer.vue'; +export { default as WxUserPatientDetailModal } from './WxUserPatientDetailModal.vue'; +export { default as WxUserPatientsModal } from './WxUserPatientsModal.vue'; export { default as VisitTypeTag } from './VisitTypeTag.vue'; export { default as PrescriptionExpireTime } from './PrescriptionExpireTime.vue'; export * from './api'; diff --git a/apps/web-antd/src/views/business/order/prescription/components/source.vue b/apps/web-antd/src/views/business/order/prescription/components/source.vue index 179dd0e6..d316bb80 100644 --- a/apps/web-antd/src/views/business/order/prescription/components/source.vue +++ b/apps/web-antd/src/views/business/order/prescription/components/source.vue @@ -1,81 +1,18 @@ - + + + + + + + + - + 批量操作 - @@ -104,11 +123,12 @@ const openPrescriptionSourceModal = (id) => { 待审核 - 通过审核 - 拒绝审核:{{ row.reject_reason }} + 已通过 + 已拒绝:{{ row.reject_reason }} 无需审核 无需审核 - @@ -124,19 +144,16 @@ const openPrescriptionSourceModal = (id) => { label: '查看处方', type: 'link', icon: 'marketeq:eye', - // auth: ['超级订单', 'sys:user:save'], onClick: openPrescriptionDetail.bind(null, row.id), }, { label: '处方溯源', type: 'link', icon: 'marketeq:eye', - // auth: ['超级订单', 'sys:user:save'], onClick: openPrescriptionSourceModal.bind(null, row.id), }, ]" - :drop-down-actions="[ - ]" + :drop-down-actions="[]" /> @@ -147,28 +164,4 @@ const openPrescriptionSourceModal = (id) => { list-style-type: none; padding-left: 0; } - -.custom-list-item { - background-color: rgba(64, 158, 255, 0.04); - border-radius: 4px; - margin-bottom: 8px; - padding: 8px 12px; - font-size: 14px; - transition: background-color 0.3s; - - &:hover { - background-color: rgba(64, 158, 255, 0.1); - } - - &::before { - content: ''; - display: inline-block; - width: 6px; - height: 6px; - background-color: #409eff; - border-radius: 50%; - margin-right: 8px; - vertical-align: middle; - } -} diff --git a/apps/web-antd/src/views/business/order/product-order/components/cells/OrderUserInfoCell.vue b/apps/web-antd/src/views/business/order/product-order/components/cells/OrderUserInfoCell.vue index fbf9dd5a..43fa971e 100644 --- a/apps/web-antd/src/views/business/order/product-order/components/cells/OrderUserInfoCell.vue +++ b/apps/web-antd/src/views/business/order/product-order/components/cells/OrderUserInfoCell.vue @@ -1,14 +1,24 @@ - - + 下单用户: - + + {{ row.user?.nickname || '—' }} + + {{ row.user?.nickname || '—' }} @@ -63,14 +121,9 @@ function formatPatientAge(row: Record) { - - - + + 医生: @@ -82,28 +135,25 @@ function formatPatientAge(row: Record) { > {{ row.doctor.name }} - - - - - - - - - - — - 就诊人: - - {{ row.patient || '—' }} + + {{ patientName(row) }} + + + {{ patientName(row) }} ) { gap: 6px; line-height: 1.4; } - .order-user-info__row { display: flex; align-items: flex-start; gap: 6px; } - .order-user-info__text { flex: 1; min-width: 0; text-align: left; } - -.order-user-info__doctor-btn { +.order-user-info__doctor-btn, +.order-user-info__link-btn { font-size: 12px; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; - //display: block; text-align: left; } diff --git a/apps/web-antd/src/views/business/order/product-order/index.vue b/apps/web-antd/src/views/business/order/product-order/index.vue index db5a5ce2..7cf6a92c 100644 --- a/apps/web-antd/src/views/business/order/product-order/index.vue +++ b/apps/web-antd/src/views/business/order/product-order/index.vue @@ -52,6 +52,10 @@ import type { QuickDiscountOption } from '#/utils/pricePercentAdjust'; import { normalizeQuickOptions } from '#/utils/pricePercentAdjust'; import PrescriptionDetail from '#/views/doctor/doctor-reception/components/PrescriptionDetail.vue'; import DoctorCardModal from '#/views/doctor/doctor/components/DoctorCardModal.vue'; +import { + WxUserPatientDetailModal, + WxUserPatientsModal, +} from '#/components/wx-user-patient'; import DetailModal from './components/detail.vue'; import OrderUserInfoCell from './components/cells/OrderUserInfoCell.vue'; @@ -288,6 +292,14 @@ const [DoctorCardModals, DoctorCardModalApi] = useVbenModal({ connectedComponent: DoctorCardModal, }); +const [PatientsModal, PatientsModalApi] = useVbenModal({ + connectedComponent: WxUserPatientsModal, +}); + +const [PatientDetailModal, PatientDetailModalApi] = useVbenModal({ + connectedComponent: WxUserPatientDetailModal, +}); + /** 从订单列表以只读模式打开医生档案 */ function showOrderDoctorCard(row: Record) { const doctor = row.doctor; @@ -303,6 +315,37 @@ function showOrderDoctorCard(row: Record) { DoctorCardModalApi.open(); } +/** 点下单用户 → 该用户下就诊人列表 Modal */ +function openOrderUserPatients(payload: { + userId: number; + nickname: string; + avatarurl: string; +}) { + if (!payload?.userId) { + message.warning('缺少用户信息'); + return; + } + PatientsModalApi.setData({ + userId: payload.userId, + nickname: payload.nickname, + avatarurl: payload.avatarurl, + }); + PatientsModalApi.open(); +} + +/** 点就诊人 → 详情 Modal */ +function openOrderPatient(payload: { upId: number; patientName: string }) { + if (!payload?.upId) { + message.warning('缺少就诊人信息'); + return; + } + PatientDetailModalApi.setData({ + upId: payload.upId, + patientName: payload.patientName, + }); + PatientDetailModalApi.open(); +} + const [TraceDrawer, traceDrawerApi] = useVbenDrawer({ connectedComponent: OrderTraceDrawer, }); @@ -775,6 +818,8 @@ const openOrderAmountVerify = () => { + + @@ -822,7 +867,12 @@ const openOrderAmountVerify = () => { - + diff --git a/apps/web-antd/src/views/business/user-patient/index.vue b/apps/web-antd/src/views/business/user-patient/index.vue new file mode 100644 index 00000000..e35c4ece --- /dev/null +++ b/apps/web-antd/src/views/business/user-patient/index.vue @@ -0,0 +1,177 @@ + + + + + + + + 查询 + + + + + + + {{ record.nickname || '—' }} + + + + + + + + + {{ p.name || '—' }} + + + + — + + + {{ record.id ?? '—' }} + + + + + 就诊人 + + + + + + + diff --git a/apps/web-antd/src/views/pharmacist/audit-prescription/components/AuditPrescriptionCardList.vue b/apps/web-antd/src/views/pharmacist/audit-prescription/components/AuditPrescriptionCardList.vue index 2d497adb..1c59693f 100644 --- a/apps/web-antd/src/views/pharmacist/audit-prescription/components/AuditPrescriptionCardList.vue +++ b/apps/web-antd/src/views/pharmacist/audit-prescription/components/AuditPrescriptionCardList.vue @@ -18,6 +18,8 @@ import { getPrescriptionListApi, passApi } from '../api'; const props = defineProps<{ formValues?: Record; + /** 是否显示通过/拒绝(仅待审核 Tab) */ + canAudit?: boolean; }>(); const emit = defineEmits<{ @@ -34,6 +36,8 @@ const pageCount = ref(1); const loading = ref(false); const loadingMore = ref(false); const passingId = ref(null); +/** 请求序号:只应用最后一次 list 响应,避免切 Tab/搜索竞态盖错列表 */ +let requestSeq = 0; const scrollEl = ref(null); const sentinelEl = ref(null); @@ -63,7 +67,12 @@ function isUrgent(row: Record) { return remain > 0 && remain <= 2 * 3600; } +/** + * 拉取一页数据;reset 时清空列表 + * 用 requestSeq 丢弃过期响应,防止快速切 Tab 时旧 status 结果覆盖新 Tab + */ async function fetchPage(targetPage: number, reset = false) { + const seq = ++requestSeq; if (reset) { loading.value = true; } else { @@ -75,16 +84,21 @@ async function fetchPage(targetPage: number, reset = false) { pageSize: 12, ...(props.formValues || {}), }); + // 已有更新的请求在飞,丢弃本次结果 + if (seq !== requestSeq) return; const list = res?.items ?? []; page.value = res?.page ?? targetPage; pageCount.value = res?.page_count ?? 1; items.value = reset ? list : [...items.value, ...list]; } catch (e) { + if (seq !== requestSeq) return; console.error(e); message.error('加载审方列表失败'); } finally { - loading.value = false; - loadingMore.value = false; + if (seq === requestSeq) { + loading.value = false; + loadingMore.value = false; + } } } @@ -182,6 +196,8 @@ onBeforeUnmount(() => { /> 待审核 + 已通过 + 已拒绝 diff --git a/apps/web-antd/src/views/pharmacist/audit-prescription/components/source.vue b/apps/web-antd/src/views/pharmacist/audit-prescription/components/source.vue index 179dd0e6..c462b632 100644 --- a/apps/web-antd/src/views/pharmacist/audit-prescription/components/source.vue +++ b/apps/web-antd/src/views/pharmacist/audit-prescription/components/source.vue @@ -1,81 +1,18 @@