import request from '@/config/axios' import dayjs from 'dayjs' // ================== 时间字段序列化:发给后端统一用毫秒时间戳(13位) ================== // 医嘱/执行相关时间字段(orderTime/stopTime/executeTime/planTime/execTime)前端表单与 // 打印层仍使用 "YYYY-MM-DD HH:mm:ss" 字符串,仅在调用接口发送时转成毫秒时间戳; // planDate(按日期筛选执行记录)维持 YYYY-MM-DD 字符串不变。 const toTs = (val?: string | number): number | undefined => { if (val === undefined || val === null || val === '') return undefined if (typeof val === 'number') return val const t = dayjs(val).valueOf() return Number.isNaN(t) ? undefined : t } // ================== 时间字段反序列化:响应方向时间戳 → 字符串 ================== // 后端响应可能把上述时间字段返回为 Long 时间戳(13位毫秒 或 10位秒), // 在 GET 接口 .then 里统一转回 "YYYY-MM-DD HH:mm:ss",上层一律按字符串使用。 // - 数字:13位→毫秒;10位→秒(兼容) // - 字符串:原样返回(兼容后端混合返回) // - 空:返回 '' export const fromTs = (val?: any): string => { if (val === undefined || val === null || val === '') return '' if (typeof val === 'number') { const d = val >= 1e12 ? dayjs(val) : dayjs.unix(val) return d.isValid() ? d.format('YYYY-MM-DD HH:mm:ss') : '' } return String(val) } // 长期医嘱单:条目 orderTime / stopTime → 毫秒时间戳 const serializeLongOrder = (data: LongDoctorOrderForm) => ({ ...data, entries: (data.entries || []).map((e) => ({ ...e, orderTime: toTs(e.orderTime), stopTime: toTs(e.stopTime) })) }) // 临时医嘱单:条目 orderTime / executeTime → 毫秒时间戳 const serializeShortOrder = (data: ShortDoctorOrderForm) => ({ ...data, entries: (data.entries || []).map((e) => ({ ...e, orderTime: toTs(e.orderTime), executeTime: toTs(e.executeTime) })) }) // 护士执行记录:planTime / execTime → 毫秒时间戳 const serializeExecution = (data: DoctorOrderExecution) => ({ ...data, planTime: toTs(data.planTime), execTime: toTs(data.execTime) }) // 获取转院变更列表 export const getChangeCourtyardList = (query) => { return request.get({ url: 'bpm/process-instance/transfer-change-page', params: query }) } // 获取列表 export const getBedChangePage = (query) => { return request.get({ url: 'bpm/process-instance/bed-change-page', params: query }) } // 获取详情 export const getBedChangeRecordById = (id, status,isDetail) => { return request.get({ url: `elderly/bedChangeRecord/detail?id=${id}&status=${status}&isDetail=${isDetail}` }) } // 获取详情 export const getBedChangeRecordElderlyById = (id) => { return request.get({ url: `/elderly/bedChangeRecord/getElderlyById?elderId=${id}`, }) } // 新增 export const bedChangeCreate = (data) => { return request.post({ url: `bpm/elderly/bedChangeCreate`, data }) } // 对调 export const bedChangeRecord = (data) => { return request.post({ url: `/elderly/bedChangeRecord/swap`, data }) } // // 检测是否可以包房 export const checkPrivateRoom = (id,elderId=undefined) => { return request.get({ url: `elderly/bedChangeRecord/checkPrivateRoom?bedId=${id}&elderId=${elderId}` }) } // ============================================================ // 长期医嘱单(LongDoctorOrder)相关接口 // ============================================================ // 单条长期医嘱条目(对应一条长期医嘱 + 停止信息) export interface LongDoctorOrderEntry { id?: number longDoctorOrderId?: number orderTime?: string orderContent?: string // 给药三要素(结构化选择项) frequency?: string // 给药频次,存缩写,如 qd medTime?: string // 给药时间,存缩写,如 ac route?: string // 给药途径,存缩写,如 po doctorSign?: string nurseSign?: string stopTime?: string stopDoctorSign?: string stopNurseSign?: string remark?: string status?: number statusText?: string } // 长期医嘱单 VO:按长者分组的单据,含多条 entry export interface LongDoctorOrderVO { id?: number elderId?: number elderName?: string gender?: number | string genderName?: string bedName?: string nurseLevelName?: string tenantId?: number | string // 汇总字段(列表用,后端可冗余返回) entryCount?: number latestOrderTime?: string entries?: LongDoctorOrderEntry[] createTime?: string } export interface LongDoctorOrderForm { id?: number elderId: number entries: LongDoctorOrderEntry[] } // 长期医嘱单分页(list 时间字段自动反序列化,包括 entries[].orderTime/stopTime) export const getLongDoctorOrderPage = (query: Recordable) => { return request.get({ url: 'elderly/longDoctorOrder/page', params: query }).then((data: any) => { if (data?.list) { data.list = data.list.map((row: any) => ({ ...row, latestOrderTime: fromTs(row.latestOrderTime), createTime: fromTs(row.createTime), entries: (row.entries || []).map((e: any) => ({ ...e, orderTime: fromTs(e.orderTime), stopTime: fromTs(e.stopTime) })) })) } return data }) } // 长期医嘱单详情(entries[].orderTime/stopTime 自动反序列化) export const getLongDoctorOrder = (id: number) => { return request.get({ url: `elderly/longDoctorOrder/get?id=${id}` }).then((data: any) => { if (data?.entries) { data.entries = data.entries.map((e: any) => ({ ...e, orderTime: fromTs(e.orderTime), stopTime: fromTs(e.stopTime) })) } data.latestOrderTime = fromTs(data.latestOrderTime) data.createTime = fromTs(data.createTime) return data }) } // 新增长期医嘱单(orderTime/stopTime 自动转毫秒时间戳发送) export const createLongDoctorOrder = (data: LongDoctorOrderForm) => { return request.post({ url: 'elderly/longDoctorOrder/create', data: serializeLongOrder(data) }) } // 更新长期医嘱单(orderTime/stopTime 自动转毫秒时间戳发送) export const updateLongDoctorOrder = (data: LongDoctorOrderForm) => { return request.put({ url: 'elderly/longDoctorOrder/update', data: serializeLongOrder(data) }) } // 删除长期医嘱单 export const deleteLongDoctorOrder = (id: number) => { return request.delete({ url: `elderly/longDoctorOrder/delete?id=${id}` }) } // 单条长期医嘱条目状态切换(停止 / 启用) // status: 0=未开始 1=在用 2=已停止 export const updateLongDoctorOrderEntryStatus = (entryId: number, status: number) => { return request.put({ url: `elderly/longDoctorOrder/entry/updateStatus?id=${entryId}&status=${status}` }) } // 长期医嘱单状态字典(0 未开始 / 1 在用 / 2 已停止) export const LONG_ORDER_STATUS = { NOT_STARTED: 0, IN_USE: 1, STOPPED: 2 } export const LONG_ORDER_STATUS_OPTIONS = [ { label: '未开始', value: 0 }, { label: '在用', value: 1 }, { label: '已停止', value: 2 } ] export const getLongDoctorOrderStatusText = (status: number | string | undefined): string => { const item = LONG_ORDER_STATUS_OPTIONS.find((o) => o.value === Number(status)) return item ? item.label : '未知' } // ==================医嘱给药三要素字典(长期/临时医嘱共用)==================== export interface MedOption { value: string label: string // 下拉框主显:缩写 + 中文 cn: string // 中文含义 tip: string // 临床常见使用场景(hover tips) } // 给药频次 export const MED_FREQUENCY_OPTIONS: MedOption[] = [ { value: 'qd', label: 'qd 每日1次', cn: '每日1次', tip: '常规慢病长期口服用药' }, { value: 'bid', label: 'bid 每日2次', cn: '每日2次', tip: '多数普通口服药早晚分服' }, { value: 'tid', label: 'tid 每日3次', cn: '每日3次', tip: '需随三餐规律服用的药物' }, { value: 'qid', label: 'qid 每日4次', cn: '每日4次', tip: '严格间隔6小时的抗感染治疗' }, { value: 'qn', label: 'qn 每晚1次', cn: '每晚1次', tip: '助眠、长效降压、降脂类药物' }, { value: 'qod', label: 'qod 隔日1次', cn: '隔日1次', tip: '特殊半衰期较长的药物' }, { value: 'qw', label: 'qw 每周1次', cn: '每周1次', tip: '长效特殊制剂、慢病维持给药' }, { value: 'biw', label: 'biw 每周2次', cn: '每周2次', tip: '康复理疗、部分专科治疗' }, { value: 'tiw', label: 'tiw 每周3次', cn: '每周3次', tip: '透析、肌肉注射类治疗' }, { value: 'q2w', label: 'q2w 每2周1次', cn: '每2周1次', tip: '化疗、靶向、生物制剂给药' }, { value: 'q3w', label: 'q3w 每3周1次', cn: '每3周1次', tip: '化疗、靶向、生物制剂给药' }, { value: 'q4w', label: 'q4w 每4周1次', cn: '每4周1次', tip: '化疗、靶向、生物制剂给药' }, { value: 'q8h', label: 'q8h 每8小时1次', cn: '每8小时1次', tip: '重症、抗感染精准间隔给药' }, { value: 'q6h', label: 'q6h 每6小时1次', cn: '每6小时1次', tip: '重症、抗感染精准间隔给药' }, { value: 'q4h', label: 'q4h 每4小时1次', cn: '每4小时1次', tip: '重症、抗感染精准间隔给药' } ] // 给药时间 export const MED_TIME_OPTIONS: MedOption[] = [ { value: 'ac', label: 'ac 餐前', cn: '餐前服用', tip: '促胃动力、降糖、胃黏膜保护剂' }, { value: 'pc', label: 'pc 餐后', cn: '餐后服用', tip: '对胃肠道有刺激的普通药物' }, { value: 'hs', label: 'hs 睡前', cn: '睡前服用', tip: '助眠、长效降压、抗过敏药' }, { value: 'st', label: 'st 立即', cn: '立即执行', tip: '急诊急救、紧急处置类医嘱' }, { value: 'prn', label: 'prn 必要时', cn: '必要时使用', tip: '止痛、止吐、退热等对症药物' }, { value: 'sos', label: 'sos 紧急1次', cn: '紧急需要时1次', tip: '限24小时内仅用1次的应急药' }, { value: 'am', label: 'am 上午', cn: '上午', tip: '标注日间常规给药时间' }, { value: 'pm', label: 'pm 下午', cn: '下午', tip: '标注午后常规给药时间' } ] // 给药途径 export const MED_ROUTE_OPTIONS: MedOption[] = [ { value: 'po', label: 'po 口服', cn: '口服', tip: '绝大多数常规口服药物' }, { value: 'iv', label: 'iv 静脉推注', cn: '静脉推注', tip: '小容量药剂快速静脉给药' }, { value: 'ivgtt', label: 'ivgtt/iv drip 静脉滴注', cn: '静脉滴注/输液', tip: '大容量补液、抗感染输液' }, { value: 'im', label: 'im 肌内注射', cn: '肌内注射', tip: '常规疫苗、止痛针、部分抗生素' }, { value: 'sc', label: 'sc 皮下注射', cn: '皮下注射', tip: '胰岛素、低分子肝素等药物' }, { value: 'ih', label: 'ih 皮下注射', cn: '皮下注射', tip: '胰岛素、低分子肝素等药物' }, { value: 'igtt', label: 'igtt 胃肠滴注', cn: '胃肠滴注', tip: '鼻饲、肠内营养输注' }, { value: 'inh', label: 'inh 吸入给药', cn: '吸入给药', tip: '哮喘、慢阻肺的雾化治疗' }, { value: 'ext', label: 'ext 外用', cn: '外用', tip: '皮肤药膏、黏膜局部用药' }, // ↓↓↓ 9-08 新增给药途径项(与现有项 value 不重复) { value: 'id', label: 'id 皮内注射', cn: '皮内注射', tip: '皮试、疫苗过敏试验等' }, { value: 'sl', label: 'sl 舌下含服', cn: '舌下含服', tip: '硝酸甘油、速效救心丸等急救药' }, { value: 'top', label: 'top 皮肤外用/经皮给药', cn: '皮肤外用/经皮给药', tip: '软膏、贴片、涂抹类外用药' }, { value: 'pr', label: 'pr 直肠给药', cn: '直肠给药', tip: '栓剂、灌肠、退热等' }, { value: 'buccal', label: 'buccal 颊部给药', cn: '颊部给药', tip: '口腔黏膜贴片、含化药片' }, { value: 'ia', label: 'ia 动脉内注射', cn: '动脉内注射', tip: '介入治疗、动脉化疗等' }, { value: 'ip', label: 'ip 腹腔注射', cn: '腹腔注射', tip: '腹膜透析、腹腔化疗等' } ] // ==================临时医嘱单==================== // 单条临时医嘱条目(对应打印页一行) export interface ShortDoctorOrderEntry { id?: number orderTime?: string orderContent?: string // 给药三要素(结构化选择项) frequency?: string // 给药频次,存缩写,如 qd medTime?: string // 给药时间,存缩写,如 ac route?: string // 给药途径,存缩写,如 po doctorSign?: string executeTime?: string nurseSign?: string remark?: string } // 临时医嘱单 VO(按长者分组的单据,含多条 entry) export interface ShortDoctorOrderVO { id?: number elderId?: number elderName?: string gender?: number | string genderName?: string bedName?: string nurseLevelName?: string tenantId?: number | string // 汇总字段(后端可冗余返回,便于列表展示) entryCount?: number latestOrderTime?: string latestExecuteTime?: string entries?: ShortDoctorOrderEntry[] createTime?: string } export interface ShortDoctorOrderForm { id?: number elderId: number entries: ShortDoctorOrderEntry[] } // 临时医嘱单分页(list 时间字段自动反序列化,包括 entries[].orderTime/executeTime) export const getShortDoctorOrderPage = (query: Recordable) => { return request.get({ url: 'elderly/shortDoctorOrder/page', params: query }).then((data: any) => { if (data?.list) { data.list = data.list.map((row: any) => ({ ...row, latestOrderTime: fromTs(row.latestOrderTime), latestExecuteTime: fromTs(row.latestExecuteTime), createTime: fromTs(row.createTime), entries: (row.entries || []).map((e: any) => ({ ...e, orderTime: fromTs(e.orderTime), executeTime: fromTs(e.executeTime) })) })) } return data }) } // 临时医嘱单详情(entries[].orderTime/executeTime 自动反序列化) export const getShortDoctorOrder = (id: number) => { return request.get({ url: `elderly/shortDoctorOrder/get?id=${id}` }).then((data: any) => { if (data?.entries) { data.entries = data.entries.map((e: any) => ({ ...e, orderTime: fromTs(e.orderTime), executeTime: fromTs(e.executeTime) })) } data.latestOrderTime = fromTs(data.latestOrderTime) data.latestExecuteTime = fromTs(data.latestExecuteTime) data.createTime = fromTs(data.createTime) return data }) } // 新增临时医嘱单(orderTime/executeTime 自动转毫秒时间戳发送) export const createShortDoctorOrder = (data: ShortDoctorOrderForm) => { return request.post({ url: 'elderly/shortDoctorOrder/create', data: serializeShortOrder(data) }) } // 更新临时医嘱单(orderTime/executeTime 自动转毫秒时间戳发送) export const updateShortDoctorOrder = (data: ShortDoctorOrderForm) => { return request.put({ url: 'elderly/shortDoctorOrder/update', data: serializeShortOrder(data) }) } // 删除临时医嘱单 export const deleteShortDoctorOrder = (id: number) => { return request.delete({ url: `elderly/shortDoctorOrder/delete?id=${id}` }) } // ==================医嘱执行记录(护士执行单)==================== // 一条"护士执行"记录:前端按医嘱展开生成执行行后,护士点击执行即写入一条 export interface DoctorOrderExecution { id?: number orderType?: number // 1=长期医嘱 2=临时医嘱 orderEntryId?: number // 关联原医嘱条目 id(长期/临时各自的 entry id) elderId?: number elderName?: string elderAge?: number | string // 年龄(执行医嘱 makeRow / 长者执行记录弹窗都用到) bedName?: string orderContent?: string frequency?: string // 给药频次缩写 medTime?: string // 给药时间缩写 route?: string // 给药途径缩写 planTime?: string // 计划执行时间 YYYY-MM-DD HH:mm execTime?: string // 实际执行时间 execNurseSign?: string // 执行护士签名 status?: number // 0=待执行 1=已执行 2=已跳过 remark?: string tenantId?: number | string createTime?: string } export const EXEC_STATUS = { PENDING: 0, DONE: 1, SKIPPED: 2 } export const EXEC_STATUS_OPTIONS = [ { label: '待执行', value: 0 }, { label: '已执行', value: 1 }, { label: '已跳过', value: 2 } ] // 分页查询某日护士执行记录(list 时间字段自动反序列化,planDate 仍按 YYYY-MM-DD 字符串传参) export const getDoctorOrderExecutionPage = (query: Recordable) => { return request.get({ url: 'elderly/doctorOrderExecution/page', params: query }).then((data: any) => { if (data?.list) { data.list = data.list.map((row: any) => ({ ...row, planTime: fromTs(row.planTime), execTime: fromTs(row.execTime), createTime: fromTs(row.createTime) })) } return data }) } // 护士执行(新增/更新一条执行记录,planTime/execTime 自动转毫秒时间戳发送) export const executeDoctorOrder = (data: DoctorOrderExecution) => { return request.post({ url: 'elderly/doctorOrderExecution/execute', data: serializeExecution(data) }) } // 跳过/取消某次执行 export const skipDoctorOrderExecution = (id: number) => { return request.put({ url: `elderly/doctorOrderExecution/skip?id=${id}` }) } // 选项值 → 中文含义(空值返回空串) export const getMedCn = (options: MedOption[], val?: string): string => { if (!val) return '' const item = options.find((o) => o.value === val) return item ? item.cn : val } /** * 根据频次(frequency)与给药时间(medTime),在指定日期展开"计划执行时点"列表(返回 HH:mm 数组)。 * 说明: * - 日频次(qd/bid/tid/qid/qn/q8h/q6h/q4h) 按医学常规给出多个时点的 HH:mm; * - 周频次/间隔频次(qod/qw/biw/tiw/q2w/q3w/q4w) 无法对应到一天内的多个时点,统一给 1 个 09:00 代表点; * - medTime 仅对"单时点"频次(如 qd/qn/qod/qw 等)做微调(hs→21:00、am→09:00、pc→08:00 等); * - 该映射为前端启发式,真实排班以后端执行计划为准。 */ export const buildExecutionPlanTimes = (frequency?: string, medTime?: string): string[] => { const single = (base: string): string[] => [base] const byMedTime = (def: string): string => { switch (medTime) { case 'hs': return '21:00' case 'am': return '09:00' case 'pm': return '15:00' case 'ac': return '07:30' case 'pc': return '08:00' default: return def } } switch (frequency) { case 'qd': return single(byMedTime('09:00')) case 'bid': return medTime === 'hs' ? ['09:00', '21:00'] : ['09:00', '15:00'] case 'tid': return ['08:00', '12:00', '18:00'] case 'qid': return ['06:00', '12:00', '18:00', '22:00'] case 'qn': return single('21:00') case 'qod': return single(byMedTime('09:00')) case 'qw': return single(byMedTime('09:00')) case 'biw': return single('09:00') case 'tiw': return single('09:00') case 'q2w': return single('09:00') case 'q3w': return single('09:00') case 'q4w': return single('09:00') case 'q8h': return ['08:00', '16:00', '00:00'] case 'q6h': return ['06:00', '12:00', '18:00', '00:00'] case 'q4h': return ['04:00', '08:00', '12:00', '16:00', '20:00', '00:00'] default: return single('09:00') } }