From 09dc74e264b6262cbe41c9c8476e24705871d4a6 Mon Sep 17 00:00:00 2001
From: yxh <172933527@qq.com>
Date: 星期日, 08 十一月 2026 23:31:17 +0800
Subject: [PATCH] yxh
---
src/views/ecg/checktype/QueueSequenceForm.vue | 112 ++-
src/views/ecg/doctor/components/BedSwitchSelect.vue | 208 ++++++
src/views/ecg/callingscreen/bigscreen.vue | 31
src/views/ecg/doctor/components/DevInstallPanel.vue | 80 +-
src/views/ecg/doctor/components/DevReadyPanel.vue | 83 +-
src/views/ecg/doctor/components/PatientInfoBlock.vue | 50 +
src/store/modules/room.ts | 216 ++++++-
src/styles/index.scss | 24
src/views/ecg/doctor/components/RoutinePanel.vue | 438 +++++++++++++--
src/views/ecg/appointment/index.vue | 19
src/views/ecg/room/RoomLoginSelect.vue | 39 +
src/api/ecg/room/index.ts | 23
src/views/ecg/doctor/Routine.vue | 7
src/views/ecg/room/RoomSetting.vue | 6
src/store/modules/user.ts | 14
src/permission.ts | 26
src/views/ecg/appointment/CheckItemPanel.vue | 23
src/views/ecg/doctor/DevDismantle.vue | 18
src/api/ecg/appointment/index.ts | 38 +
src/layout/components/CurrentRoomTag.vue | 21
src/views/ecg/appointment/AppointmentForm.vue | 6
src/components/DoctorPageLayout/src/DoctorPageLayout.vue | 166 +++++
src/components/RoomBedSelect/src/RoomBedSelect.vue | 20
src/views/ecg/doctor/DevDataEntry.vue | 4
src/utils/releaseBed.ts | 8
25 files changed, 1,350 insertions(+), 330 deletions(-)
diff --git a/src/api/ecg/appointment/index.ts b/src/api/ecg/appointment/index.ts
index c8aa681..798a472 100644
--- a/src/api/ecg/appointment/index.ts
+++ b/src/api/ecg/appointment/index.ts
@@ -26,6 +26,11 @@
bookCheckType: number // 棰勭害妫�鏌ラ」鐩�
paid: number //宸蹭粯娆�
bookSeqNum: number
+ /**
+ * 銆愭湰闇�姹傘�戦潪褰撳ぉ棰勭害绛惧埌鐨�"宸茬‘璁�"鏍囪銆�
+ * 鍓嶇寮圭獥纭鍚庣疆 true 浼犵粰鍚庣锛氬悗绔嵁姝ゆ斁琛岄潪褰撳ぉ棰勭害锛屽苟鎸�**棰勭暀鍙�**鍙栧彿銆�
+ */
+ forceCheckIn?: boolean
// ========== 浠ヤ笅瀛楁鍚庣 AppointmentRespVO 涓�鐩存湁杩斿洖锛屾鍓� TS 鏈0鏄� ==========
// 闇�姹�1 浣跨敤锛氱姸鎬� / 寮�鍗曞尰甯� / 寮�鍗曟棩鏈� / 璺濅粖澶╂暟锛堢敱 doctorTime 璁$畻锛�/ 灏辫瘖鍗″彿
status?: string // 鐘舵�侊紙瀛楀吀 ecg_status锛�
@@ -44,11 +49,26 @@
createTime?: Date | number | string // 鍒涘缓鏃堕棿
}
+/**
+ * 銆愭湰闇�姹傘�戦绾﹁褰曢〉鐨勩�岄绾︽棩鏈熴�嶇敤鏃ユ湡鑼冨洿閫夋嫨鍣紝鍓嶇瀛楁鏄� `bookDateRange`锛圼'2026-11-01','2026-11-30']锛夛紝
+ * 鑰屽悗绔帴鏀剁殑鏄� `bookDateStart` / `bookDateEnd`锛堝惈棣栧熬涓ゅぉ锛夈��
+ * 杩欓噷缁熶竴杞崲锛岄伩鍏嶆瘡涓皟鐢ㄧ偣鍚勫啓涓�閬嶏細鍒嗛〉銆佸鍑洪兘璧板畠銆�
+ */
+const withBookDateRange = (params: any) => {
+ if (!params) return params
+ const { bookDateRange, ...rest } = params
+ if (Array.isArray(bookDateRange) && bookDateRange.length === 2 && bookDateRange[0] && bookDateRange[1]) {
+ rest.bookDateStart = `${bookDateRange[0]} 00:00:00`
+ rest.bookDateEnd = `${bookDateRange[1]} 23:59:59`
+ }
+ return rest
+}
+
// 棰勭害 API
export const AppointmentApi = {
// 鏌ヨ棰勭害鍒嗛〉
getAppointmentPage: async (params: any) => {
- return await request.get({ url: `/ecg/appointment/page`, params })
+ return await request.get({ url: `/ecg/appointment/page`, params: withBookDateRange(params) })
},
// 鏌ヨ棰勭害璇︽儏
@@ -69,6 +89,20 @@
// 浠嶩IS鏌ヨ棰勭害鎴栧紑鍗曚俊鎭�
queryAppointmentFromHis: async (patId: string) => {
return await request.get({ url: `/ecg/appointment/query-his-by-patient?patId=` + patId })
+ },
+
+ /**
+ * 銆愭湰闇�姹傦細绱ф�ユ偅鑰呬笉鎺掗槦鐩存帴妫�鏌ャ�戞寜銆岀敵璇峰崟鍙� / 灏辫瘖鍙� / 鎮h�呯紪鍙枫�嶆煡杩戜竴涓湀锛埪�30 澶╋級鐨勯绾﹁褰曘��
+ * 缁撴灉鎸夐绾︽椂闂村�掑簭锛沗checkTypes` 涓烘湰绐楀彛寮�灞曠殑妫�鏌ラ」鐩紙閫楀彿鍒嗛殧锛岀┖鍒欎笉闄愶級銆�
+ */
+ getEmergencyCandidates: async (code: string, checkTypes?: number[]) => {
+ const types = Array.isArray(checkTypes) && checkTypes.length > 0 ? checkTypes.join(',') : ''
+ return await request.get({
+ url:
+ `/ecg/appointment/emergency-candidates?code=` +
+ encodeURIComponent(code) +
+ (types ? `&checkTypes=${types}` : '')
+ })
},
// 鏂板棰勭害
@@ -92,7 +126,7 @@
// 瀵煎嚭棰勭害 Excel
exportAppointment: async (params) => {
- return await request.download({ url: `/ecg/appointment/export-excel`, params })
+ return await request.download({ url: `/ecg/appointment/export-excel`, params: withBookDateRange(params) })
},
// 棰勭害纭
diff --git a/src/api/ecg/room/index.ts b/src/api/ecg/room/index.ts
index 563e304..ca73801 100644
--- a/src/api/ecg/room/index.ts
+++ b/src/api/ecg/room/index.ts
@@ -85,7 +85,10 @@
export interface MonitorInfo {
openingBedNum : number
+ /** 鍦ㄥ骇宸ヤ綅鏁帮紙涓�浜哄宸ヤ綅鏃朵細澶т簬鍖荤敓鏁帮級 */
docBedNum : number
+ /** 銆愭湰闇�姹偮风粺璁℃寜浜哄悎骞躲�戝湪搴у尰鐢熸暟锛堟寜 doc_id 鍘婚噸锛� */
+ docNum : number
routingBedNum : number
openingFlag : number
checkTypeBedInfo: object
@@ -187,18 +190,34 @@
*
* 鐩告瘮鍘熸潵銆実etIpBed 鈫� bindIpToBed 鈫� bedDoctorOn銆嶄笁姝ユ嫾瑁咃紝杩欓噷鍙け璐ヤ竴娆″嵆鍙帓鏌ワ細
* 杩斿洖浣撳甫 clientIp 涓� reason锛坕p_invalid / nomatch / multi / occupied / error锛夈��
- * 鏈嶅姟绔悓鏃朵繚璇侊細涓�涓敤鎴峰彧鍗犱竴涓伐浣嶏紙鍏ュ骇鎴愬姛鍚庨噴鏀惧叾鍏跺畠宸ヤ綅锛夈��
+ * 鏈嶅姟绔繚璇侊細鍛戒腑"鎴戠殑宸ヤ綅"鏃跺箓绛夋仮澶嶏紱涓嶄細閲嶅鏂板锛堜竴浜哄宸ヤ綅鐢卞墠绔垏鎹級銆�
*/
autoSeat: async () => {
return await request.post({ url: `/clinic/room/auto-seat` })
},
- /** 鏌ヨ褰撳墠鐧诲綍浜哄凡鍏ュ骇鐨勫伐浣嶏紙绯荤粺椤舵爮"褰撳墠宸ヤ綅"鏍囩鐢級 */
+ /** 鏌ヨ褰撳墠鐧诲綍浜哄凡鍏ュ骇鐨勫伐浣嶏紙绯荤粺椤舵爮"褰撳墠宸ヤ綅"鏍囩鐢紝鍗曞�硷紱澶氬伐浣嶈鐢� getMySeats锛� */
getMySeat: async () => {
return await request.get({ url: `/clinic/room/my-seat` })
},
/**
+ * 銆愭湰闇�姹偮蜂竴浜哄宸ヤ綅銆戞煡璇㈠綋鍓嶇櫥褰曚汉鍗犳嵁鐨�**鍏ㄩ儴**宸ヤ綅锛堣妭鍋囨棩鍊肩彮澶氬矖浣嶏級銆�
+ * 杩斿洖鏁扮粍锛屾寜 roomId + bedNo 鍗囧簭锛涙湭鍗犲伐浣嶈繑鍥炵┖鏁扮粍銆�
+ */
+ getMySeats: async () => {
+ return await request.get({ url: `/clinic/room/my-seats` })
+ },
+
+ /**
+ * 銆愭湰闇�姹偮锋帴鐝嚜鍔╂帴绠°�戞妸璇ュ伐浣嶄粠"鍒汉鍗犵敤"鏀逛负"鎴戝崰鐢�"銆�
+ * 鍚庣锛氬璁℃棩蹇� 鈫� 寮哄埗鍘熷崰鐢ㄤ汉绂诲骇 鈫� 绔嬪嵆璁╂垜鍏ュ骇锛堝悓涓�浜嬪姟锛夈��
+ */
+ takeOverBed: async (params: { roomId: number | null; bedNo: string | null }) => {
+ return await request.post({ url: `/clinic/room/take-over-bed`, params })
+ },
+
+ /**
* 瀹㈡埛绔� IP 璇嗗埆璇婃柇锛氳繑鍥炲悇浠g悊澶淬�佺洿杩炲湴鍧�銆佽鑼冨寲缁撴灉銆佹槸鍚︽湇鍔″櫒鑷韩鍦板潃銆佹湇鍔″櫒缃戝崱鍒楄〃涓庣粨璁恒��
* 鐜板満鎺掓煡"宸ヤ綅缁戝畾鐨� IP 涓嶅"鐢紙閫夊伐浣嶉〉鐨勩�孖P 璇婃柇銆嶆寜閽級銆�
*/
diff --git a/src/components/DoctorPageLayout/src/DoctorPageLayout.vue b/src/components/DoctorPageLayout/src/DoctorPageLayout.vue
index 51091de..f1f54c2 100644
--- a/src/components/DoctorPageLayout/src/DoctorPageLayout.vue
+++ b/src/components/DoctorPageLayout/src/DoctorPageLayout.vue
@@ -38,7 +38,7 @@
footer 搴曢儴鍔熻兘鎸夐挳锛堝彲閫夛紱鍥哄畾鍦ㄩ〉闈㈠簳閮級
-->
<script setup lang="ts">
-import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
+import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import BedSwitchSelect from '@/views/ecg/doctor/components/BedSwitchSelect.vue'
import { useRoomStore } from '@/store/modules/room'
@@ -47,6 +47,47 @@
/* ==================== 涓�/鍥磋锛堝彧璇绘ā寮忥級 ==================== */
const roomStore = useRoomStore()
+
+/* ==================== 鏄剧ず瀵嗗害锛堝垎杈ㄧ巼閫傞厤锛� ==================== */
+
+/**
+ * 銆愪负浠�涔堟槸"瀵嗗害"鑰屼笉鏄�"鏁翠綋缂╂斁"銆�
+ * 鏇捐�冭檻鐢� `document.body.style.zoom = 0.9` 鍋氭暣浣撶缉鏀撅紝**瀹炴祴涓嶅彲琛�**锛�
+ * 鈶� CSS zoom **涓嶄細鏀瑰彉濯掍綋鏌ヨ**锛坺oom:1.25 鏃� innerWidth 浠嶆槸 1342銆�
+ * `(min-width:1200px)` 浠嶅懡涓級鈬� 鏍呮牸涓嶄細闅忎箣闄嶇骇锛�"缂╁皬"鍙嶈�岃瀛楁鏇存尋锛�
+ * 鈶� CSS zoom 浼氳 Element Plus 鐨勪笅鎷�/寮圭獥瀹氫綅閿欎綅 鈥斺�� 瀹冧滑闈�
+ * getBoundingClientRect + translate 璁$畻浣嶇疆锛宺ect 宸插惈缂╂斁鍊嶇巼锛�
+ * 鍐欏洖鐨� px 鍙堝湪缂╂斁鍧愭爣绯婚噷锛岀瓑浜庤鏀惧ぇ涓ゆ銆�
+ *
+ * 鎵�浠ユ敼涓�**鍙帇缂╅棿璺�**锛堢函 CSS锛岄浂瀹氫綅椋庨櫓锛夛細琛ㄥ崟琛岃窛銆佽〃鏍煎崟鍏冩牸鍐呰竟璺濄��
+ * 搴曟爮鍐呰竟璺濄�傜煯灞忚兘澶氭樉绀哄嚑琛岃褰曪紝瑙嗚涓婄瓑鏁堜簬"缂╂斁"锛屼絾涓嶇牬鍧忎换浣曞脊灞傘��
+ *
+ * 鐪熉锋暣浣撶缉鏀捐鐢�**娴忚鍣ㄨ嚜甯︾缉鏀�**锛圕trl + / Ctrl - / Ctrl 0锛夛細
+ * 鏍呮牸宸插仛鍝嶅簲寮忥紝娴忚鍣ㄧ缉鏀句細鏀瑰彉 innerWidth锛屼粠鑰岃嚜鍔ㄥ湪 4/2/1 鍒椾箣闂村垏鎹€��
+ */
+const DENSITY_KEY = 'ecg.doctor.density'
+type Density = 'normal' | 'compact'
+const density = ref<Density>('normal')
+const isCompact = computed(() => density.value === 'compact')
+
+const loadDensity = () => {
+ try {
+ const v = localStorage.getItem(DENSITY_KEY)
+ if (v === 'compact' || v === 'normal') density.value = v
+ } catch {
+ /* 闅愮妯″紡/绂佺敤瀛樺偍鏃跺拷鐣� */
+ }
+}
+// 璁颁綇閫夋嫨锛堢敤 watch 鑰屼笉鏄� el-select 鐨� @change锛氶伩鍏� EP 鍥炶皟鍙傛暟绫诲瀷涓庤仈鍚堢被鍨嬩笉鍖归厤锛�
+watch(density, (v) => {
+ try {
+ localStorage.setItem(DENSITY_KEY, v)
+ } catch {
+ /* 闅愮妯″紡/绂佺敤瀛樺偍鏃跺拷鐣� */
+ }
+})
+// 鍦� setup 闃舵灏辫鍙栵紝閬垮厤棣栧抚浠�"鏍囧噯"璺冲埌"绱у噾"鐨勯棯鍔�
+loadDensity()
/**
* 鏄惁鏄剧ず椤堕儴鎻愮ず鏉°��
@@ -94,11 +135,33 @@
}
)
-/** 榛樿瀹藉害锛坧x锛夛細鐢� asideWidth 瑙f瀽鑰屾潵锛岀敤浣滃垵濮嬪�间笌"鍙屽嚮澶嶄綅"鍊� */
-const defaultAsidePx = (() => {
+/**
+ * 銆岄粯璁ゃ�嶅彸鏍忓搴︼紙px锛夛細**鎸夌獥鍙e搴﹁嚜閫傚簲**銆�
+ *
+ * 鑳屾櫙锛氬師鏉ュ浐瀹� 400px銆傚尰鐢熺數鑴戝垎杈ㄧ巼宸紓澶э紙1920 / 1366 / 1024锛屼笖甯稿甫 125% 缂╂斁锛夛紝
+ * 绐勫睆涓婂彸鏍忓悆鎺� 400px 鍚庯紝宸︿晶鎮h�呬俊鎭紙4 鍒楁爡鏍硷紝姣忓垪瑕� 100px 鏍囩锛夊彧鍓╁嚑鐧惧儚绱狅紝
+ * 瀛楁琚帇鎴愪竴鏉$紳 鈥斺�� 鐜板満琛ㄧ幇涓�"閮ㄥ垎鍐呭鐪嬩笉鍒�"銆�
+ *
+ * 瑙勫垯锛歚min(閰嶇疆鍊�, 绐楀彛瀹� 脳 28%)`锛屼笖涓嶄綆浜� minAsideWidth銆�
+ * 1920 鈫� 400锛堜笌鍘熸潵涓�鑷达紝瀹藉睆鏃犲彉鍖栵級
+ * 1600 鈫� 400
+ * 1366 鈫� 382
+ * 1280 鈫� 358
+ * 1024 鈫� 287
+ */
+const calcDefaultAsidePx = () => {
const n = parseInt(props.asideWidth, 10)
- return Number.isFinite(n) && n > 0 ? n : 400
-})()
+ const base = Number.isFinite(n) && n > 0 ? n : 400
+ const vw = typeof window !== 'undefined' ? window.innerWidth : 1920
+ return Math.max(props.minAsideWidth, Math.min(base, Math.round(vw * 0.28)))
+}
+
+/**
+ * 鍖荤敓鏄惁**鎵嬪姩**璋冭繃瀹藉害锛堟嫋杩囧垎鐣岀嚎 / 鐢ㄩ敭鐩樿皟杩� / 鏈夎蹇嗗�硷級銆�
+ * 鎵嬪姩璋冭繃 鈫� 灏婇噸浠栫殑閫夋嫨锛岀獥鍙e彉鍖栨椂鍙仛"澶圭揣"锛�
+ * 娌¤皟杩� 鈫� 璺熼殢绐楀彛鑷�傚簲锛堟崲鍒板皬灞忚嚜鍔ㄦ敹绐勶級銆�
+ */
+const asideUserSet = ref(false)
/**
* 銆愬叧閿�戜笉渚濊禆 CSS `height: 100%` 鐨勮В鏋愶紝鏀逛负**瀹炴祴鐖跺鍣ㄥ彲鐢ㄩ珮搴�**銆�
@@ -125,8 +188,8 @@
/** 涓讳綋琛屽鍣細鎷栧姩鏃剁敤瀹冪畻"鍙充晶鏍忔渶澶氳兘鏈夊瀹�" */
const bodyRef = ref<HTMLElement>()
-/** 鍙充晶鏍忓綋鍓嶅搴︼紙px锛� */
-const asidePx = ref<number>(defaultAsidePx)
+/** 鍙充晶鏍忓綋鍓嶅搴︼紙px锛夛細鍒濆鍊间篃璧拌嚜閫傚簲锛岀獎灞忎笉浼氫竴涓婃潵灏卞崰鎺� 400px */
+const asidePx = ref<number>(calcDefaultAsidePx())
/** 鏄惁姝e湪鎷栧姩锛堢敤浜庢崲鍏夋爣銆佺閫変腑锛� */
const dragging = ref(false)
@@ -149,6 +212,7 @@
/** 璁颁綇鎷栧姩缁撴灉锛堥殣绉佹ā寮�/绂佺敤瀛樺偍鏃堕潤榛樺拷鐣ワ級 */
const saveAsidePx = () => {
+ asideUserSet.value = true
if (!props.storageKey) return
try {
localStorage.setItem(props.storageKey, String(asidePx.value))
@@ -162,15 +226,19 @@
if (!props.storageKey) return
try {
const v = parseInt(localStorage.getItem(props.storageKey) || '', 10)
- if (Number.isFinite(v) && v > 0) asidePx.value = clampAsidePx(v)
+ if (Number.isFinite(v) && v > 0) {
+ asidePx.value = clampAsidePx(v)
+ asideUserSet.value = true // 鏈夎蹇嗗�� = 鍖荤敓鎵嬪姩璋冭繃锛屽悗缁笉鍐嶈窡闅忕獥鍙h嚜閫傚簲
+ }
} catch {
/* ignore */
}
}
-/** 鍙屽嚮鍒嗙晫绾匡細鎭㈠榛樿瀹藉害骞舵竻闄よ蹇� */
+/** 鍙屽嚮鍒嗙晫绾匡細鎭㈠榛樿瀹藉害锛堥噸鏂版寜褰撳墠绐楀彛鑷�傚簲锛夊苟娓呴櫎璁板繂 */
const resetAsideWidth = () => {
- asidePx.value = clampAsidePx(defaultAsidePx)
+ asideUserSet.value = false
+ asidePx.value = clampAsidePx(calcDefaultAsidePx())
if (props.storageKey) {
try {
localStorage.removeItem(props.storageKey)
@@ -244,7 +312,12 @@
// 瀹藉害鍙樺寲锛堝惈绐楀彛缂╂斁锛夋椂閲嶆柊澶逛竴娆″彸鏍忓搴︼紝
// 鍚﹀垯鎷栧鍚庢妸绐楀彛缂╁皬锛屽彸渚ф爮鍙兘鎶婂乏渚у唴瀹规尋娌°��
- asidePx.value = clampAsidePx(asidePx.value)
+ //
+ // 銆愬垎杈ㄧ巼鑷�傚簲銆戞病鎵嬪姩璋冭繃鐨勶紙棣栨浣跨敤 / 鍙屽嚮澶嶄綅杩囷級鈫� 璺熼殢绐楀彛閲嶆柊绠楅粯璁ゅ搴︼紝
+ // 杩欐牱鍚屼竴浣嶅尰鐢熸崲鍒板皬灞忕瑪璁版湰涓婅嚜鍔ㄦ敹绐勶紱鎵嬪姩璋冭繃鐨勫彧鍋氬す绱э紝灏婇噸浠栫殑閫夋嫨銆�
+ asidePx.value = asideUserSet.value
+ ? clampAsidePx(asidePx.value)
+ : clampAsidePx(calcDefaultAsidePx())
}
/** 鐢� rAF 鍚堝苟杩炵画瑙﹀彂锛岄伩鍏� ResizeObserver 寰幆鍛婅 */
@@ -280,7 +353,7 @@
<div
ref="rootRef"
class="doctor-page"
- :class="{ 'is-resizing': dragging }"
+ :class="{ 'is-resizing': dragging, 'is-compact': isCompact }"
:style="{ height: measuredHeight }"
>
<!--
@@ -292,7 +365,22 @@
<div class="doctor-page__header-left">
<slot name="header"></slot>
</div>
- <BedSwitchSelect :enabled="bedSwitchEnabled" :op-types="bedSwitchOpTypes" />
+ <div class="doctor-page__header-tools">
+ <!--
+ 銆愬垎杈ㄧ巼閫傞厤銆戞樉绀哄瘑搴︼細绱у噾妯″紡鍘嬬缉琛岄珮/鍐呰竟璺濓紝鐭睆锛�768 楂橈級
+ 鑳藉鏄剧ず鍑犺璁板綍銆傞�夋嫨璁板湪 localStorage锛屾崲椤典繚鎸併��
+ -->
+ <el-select
+ v-model="density"
+ size="small"
+ class="doctor-page__density"
+ title="鏄剧ず瀵嗗害锛氱揣鍑戞ā寮忛�傚悎灏忓睆骞�/宸叉斁澶х缉鏀剧殑鐢佃剳"
+ >
+ <el-option label="鏍囧噯鏄剧ず" value="normal" />
+ <el-option label="绱у噾鏄剧ず" value="compact" />
+ </el-select>
+ <BedSwitchSelect :enabled="bedSwitchEnabled" :op-types="bedSwitchOpTypes" />
+ </div>
</div>
<!-- 鍥磋妯″紡锛堝彧璇伙級/ 鏈�夊伐浣� 鎻愮ず鏉★細璁╁尰鐢熶竴鐪肩煡閬�"鐜板湪鍙兘鐪嬶紝涓嶈兘鎿嶄綔" -->
@@ -395,6 +483,18 @@
flex: 1;
min-width: 0;
overflow: hidden;
+}
+
+/* 鍙充笂瑙掑伐鍏峰尯锛氭樉绀哄瘑搴� + 宸ヤ綅鍒囨崲锛堥兘鍥哄畾闈犲彸锛屼笉鍙備笌鍘嬬缉锛� */
+.doctor-page__header-tools {
+ display: flex;
+ flex: none;
+ align-items: center;
+ gap: 8px;
+}
+
+.doctor-page__density {
+ width: 104px;
}
/* ==========================================================================
@@ -577,4 +677,44 @@
margin-left: 0;
}
}
+
+/* ==========================================================================
+ 銆愬垎杈ㄧ巼閫傞厤銆戠揣鍑戞樉绀烘ā寮�
+ --------------------------------------------------------------------------
+ 鍙帇缂┿�岄棿璺濄�嶏紝涓嶆敼瀛楀彿 鈥斺�� 榛樿锛堟爣鍑嗭級**瀹屽叏涓嶅彈褰卞搷**锛屾墍鏈夎鍒欓兘鎸傚湪
+ `.is-compact` 涓嬶紝鍒囧洖鏍囧噯鍗虫仮澶嶅師鏍枫��
+
+ 閽堝鐨勭幇鍦洪棶棰橈細768 楂樼殑绗旇鏈紙鍐嶅彔鍔� 125% 缂╂斁锛変笂锛屾偅鑰呬俊鎭� + 宸插畬鎴愯褰�
+ + 搴曢儴鎸夐挳鍔犺捣鏉ヨ秴杩囧彲鐢ㄩ珮搴︼紝璁板綍鍒楄〃鍙墿涓�涓よ銆傚帇缂╁悗鑳芥妸楂樺害杩樼粰鍐呭銆�
+ ========================================================================== */
+.doctor-page.is-compact {
+ /* 鎮h�呬俊鎭� 18 椤圭敤鐨勬槸 EP 榛樿 18px 琛岃窛锛屾槸鏈�澶х殑楂樺害娴垂鐐� */
+ :deep(.el-form-item) {
+ margin-bottom: 4px;
+ }
+
+ /* 璁板綍琛ㄦ牸锛氬崟鍏冩牸涓婁笅鍐呰竟璺� 8px 鈫� 3px锛岃楂樻敹鍒� 18px */
+ :deep(.el-table .cell) {
+ padding: 0 8px;
+ line-height: 18px;
+ }
+
+ :deep(.el-table td.el-table__cell),
+ :deep(.el-table th.el-table__cell) {
+ padding: 3px 0;
+ }
+
+ .doctor-page__header {
+ height: 36px;
+ }
+
+ .doctor-page__readonly-tip {
+ padding: 2px 12px;
+ line-height: 18px;
+ }
+
+ .doctor-page__footer {
+ padding: 2px 0 2px 8px;
+ }
+}
</style>
diff --git a/src/components/RoomBedSelect/src/RoomBedSelect.vue b/src/components/RoomBedSelect/src/RoomBedSelect.vue
index b2ade54..6cf9896 100644
--- a/src/components/RoomBedSelect/src/RoomBedSelect.vue
+++ b/src/components/RoomBedSelect/src/RoomBedSelect.vue
@@ -7,7 +7,7 @@
import openImg from '@/assets/room/open.jpg'
import doctorImg from '@/assets/room/desk-doctor.jpg'
-const emit = defineEmits(['event-haveseat', 'event-leaveseat', 'event-setcurseat'])
+const emit = defineEmits(['event-haveseat', 'event-leaveseat', 'event-setcurseat', 'event-takeover'])
defineComponent({
name: 'RoomBedSelect'
@@ -57,6 +57,10 @@
}
const onSetCurSeatclick = (bed: RoomVO) => {
emit('event-setcurseat', bed)
+}
+/** 銆愭湰闇�姹偮锋帴鐝嚜鍔╂帴绠°�戞妸"鍒汉鍗犵敤"鐨勫伐浣嶆帴绠¤繃鏉ワ紙鐖剁粍浠惰礋璐d簩娆$‘璁や笌璋冩帴鍙o級 */
+const onTakeOverclick = (bed: RoomVO) => {
+ emit('event-takeover', bed)
}
</script>
@@ -110,18 +114,28 @@
</div>
<div class="bed-card__actions">
- <!-- 宸茶**鍒汉**鍗犵敤鏃剁鐢ㄣ�屽叆搴с�嶏紙涓嶆尋鎺夋鍦ㄦ搷浣滅殑浜猴級锛屽苟鐢� tooltip 璇存槑鍘熷洜 -->
+ <!-- 宸茶**鍒汉**鍗犵敤鏃剁鐢ㄣ�屽叆搴с�嶏紙涓嶆尋鎺夋鍦ㄦ搷浣滅殑浜猴級锛屽苟鐢� tooltip 璇存槑鍘熷洜锛�
+ 鍚屾椂鎻愪緵銆屾帴绠°�嶁�斺�斾笂涓�鐝尰鐢熶笅鐝病鐐圭搴ф椂锛屾帴鐝尰鐢熷彲鑷姪鎺ョ -->
<el-tooltip
v-if="!isMine"
:content="
occupiedByOther
- ? `璇ュ伐浣嶇敱銆�${bed.docName || '鍏朵粬鍖荤敓'}銆嶆搷浣滀腑锛屼笉鑳藉叆搴э紙涓嶆尋鎺夋鍦ㄦ搷浣滅殑浜猴級`
+ ? `璇ュ伐浣嶇敱銆�${bed.docName || '鍏朵粬鍖荤敓'}銆嶆搷浣滀腑銆傝嫢鏄笂涓�鐝尰鐢熷繕璁扮搴э紝鍙偣銆屾帴绠°�峘
: '鍏ュ骇鍒拌宸ヤ綅'
"
placement="top"
>
<span>
<el-button :disabled="occupiedByOther" @click="onHaveSeatclick(bed)"> 鍏ュ骇 </el-button>
+ <!-- 銆愭湰闇�姹偮锋帴鐝嚜鍔╂帴绠°�戜粎"琚粬浜哄崰鐢�"鏃跺嚭鐜帮紱鎺ョ鍚庡鏂逛細琚己鍒剁搴� -->
+ <el-button
+ v-if="occupiedByOther"
+ type="warning"
+ plain
+ @click="onTakeOverclick(bed)"
+ >
+ 鎺ョ
+ </el-button>
</span>
</el-tooltip>
<template v-else>
diff --git a/src/layout/components/CurrentRoomTag.vue b/src/layout/components/CurrentRoomTag.vue
index 6b7fcb3..1c9639b 100644
--- a/src/layout/components/CurrentRoomTag.vue
+++ b/src/layout/components/CurrentRoomTag.vue
@@ -30,19 +30,30 @@
})
const tagText = computed(() => {
- if (!hasView.value) return '鏈�夋嫨宸ヤ綅'
- if (canOperate.value) return `璇婂锛�${roomStore.getViewText}`
+ // 銆愭湰闇�姹傘�戦《鏍忕粺涓�鏄剧ず銆屽綋鍓嶅伐浣嶏細+ 瀹為檯宸ヤ綅銆嶏紝鏇夸唬鍘熸潵鐨勩�岃瘖瀹わ細鈥︺��/銆屽洿瑙傦細鈥︺�嶅墠缂�
+ if (!hasView.value) return '褰撳墠宸ヤ綅锛氭湭閫夋嫨'
+ // 銆愭湰闇�姹偮蜂竴浜哄宸ヤ綅銆戝崰澶氫釜宸ヤ綅鏃惰ˉ涓�涓暟閲忔彁绀猴紝渚夸簬鐭ラ亾"鎴戣繕鍦ㄥ埆鐨勫矖浣�"
+ const seatCount = roomStore.getMySeatCount
+ const countSuffix = seatCount > 1 ? `锛堟垜鐨勫伐浣� ${seatCount} 涓級` : ''
+ if (canOperate.value) return `褰撳墠宸ヤ綅锛�${roomStore.getViewText}${countSuffix}`
const owner = roomStore.viewOwnerName
- return `鍥磋锛�${roomStore.getViewText}${owner ? `锛堜富浜� ${owner}锛塦 : '锛堝彧璇伙級'}`
+ return `褰撳墠宸ヤ綅锛�${roomStore.getViewText}锛堝洿瑙�${owner ? `锛屼富浜� ${owner}` : '锛屽彧璇�'}锛塦
})
const tooltip = computed(() => {
if (!hasView.value) return '灏氭湭閫夋嫨宸ヤ綅锛岀偣鍑婚�夋嫨瑕佹煡鐪�/鍏ュ骇鐨勫伐浣�'
- if (canOperate.value) return `褰撳墠宸ヤ綅锛�${roomStore.getViewText}锛堢偣鍑诲垏鎹㈠伐浣嶏級`
+ const seats = roomStore.getMySeats || []
+ const seatListText =
+ seats.length > 0
+ ? '鎴戠殑宸ヤ綅锛�' + seats.map((s) => `${s.roomName || '璇婂' + (s.roomId ?? '')} 路 ${s.bedNo ?? ''}`).join('銆�')
+ : ''
+ if (canOperate.value) {
+ return `褰撳墠宸ヤ綅锛�${roomStore.getViewText}锛堢偣鍑诲垏鎹㈠伐浣嶏級` + (seatListText ? `锛�${seatListText}` : '')
+ }
const mine = roomStore.getSeatText
return `鍥磋妯″紡锛堝彧璇伙級锛氭鍦ㄦ煡鐪嬨��${roomStore.getViewText}銆峘
+ (roomStore.viewOwnerName ? `锛屼富浜� ${roomStore.viewOwnerName}` : '')
- + (mine ? `锛涙垜鍏ュ骇鐨勫伐浣嶏細${mine}` : '锛涙垜杩樻病鏈夊叆搴�')
+ + (seatListText ? `锛�${seatListText}` : (mine ? `锛涙垜鍏ュ骇鐨勫伐浣嶏細${mine}` : '锛涙垜杩樻病鏈夊叆搴�'))
+ '銆傜偣鍑诲彲鍒囨崲宸ヤ綅'
})
diff --git a/src/permission.ts b/src/permission.ts
index 719e23d..bca1eba 100644
--- a/src/permission.ts
+++ b/src/permission.ts
@@ -55,7 +55,31 @@
if (res.seated) {
return true
}
- // 銆愪富/鍥磋路鏈闇�姹傘�戞病鑷姩鍏ュ骇涔�**涓嶅啀寮哄埗璺�"閫夊伐浣嶉〉"**锛�
+
+ // 銆愭湰闇�姹傘�戞湰鏈� IP 瀵瑰簲鐨勫伐浣�**鏈変汉鍧愮潃**锛堜笂涓�鐝尰鐢熸病閫�鍑哄伐浣嶏級鈫� 鎻愮ず鏄惁鎺ョ銆�
+ // 鎺ョ鍚庣珛鍗虫垚涓鸿宸ヤ綅涓讳汉锛屽苟鎸夌幇鏈夐�昏緫鑷姩鍔犺浇璇ュ伐浣嶃�屽氨璇婁腑銆嶆偅鑰呫��
+ if (res.reason === 'occupied' && res.roomId != null && res.bedNo) {
+ const bedText = `${res.roomName || '璇婂' + res.roomId} 路 ${res.bedNo}`
+ try {
+ await ElMessageBox.confirm(
+ `鏈満瀵瑰簲鐨勫伐浣嶃��${bedText}銆嶅綋鍓嶇敱銆�${res.occupiedBy || '鍏朵粬鍖荤敓'}銆嶅崰鐢ㄣ�俓n` +
+ `鏄惁鎺ョ璇ュ伐浣嶇户缁伐浣滐紵锛堟帴绠″悗瀵规柟灏嗚寮哄埗绂诲骇锛塦,
+ '宸ヤ綅琚崰鐢�',
+ { confirmButtonText: '鎺ョ宸ヤ綅', cancelButtonText: '鍏堜笉鎺ョ锛堝彧璇诲洿瑙傦級', type: 'warning' }
+ )
+ const ok = await roomStore.takeOverBed(res.roomId, res.bedNo)
+ if (ok) {
+ ElMessage.success(`宸叉帴绠″伐浣嶏細${bedText}`)
+ return true
+ }
+ ElMessage.warning('鎺ョ澶辫触锛屽凡鎸夊彧璇诲洿瑙傝繘鍏ワ紙鍙◢鍚庡湪椤舵爮銆屽伐浣嶃�嶉噷鍐嶈瘯锛�')
+ } catch {
+ // 鐢ㄦ埛閫夋嫨涓嶆帴绠� 鈫� 鎸夊彧璇诲洿瑙傝繘鍏�
+ console.info('[room] 鐢ㄦ埛鏀惧純鎺ョ宸ヤ綅锛屾寜鍙鍥磋杩涘叆')
+ }
+ }
+
+ // 銆愪富/鍥磋銆戞病鑷姩鍏ュ骇涔�**涓嶅啀寮哄埗璺�"閫夊伐浣嶉〉"**锛�
// 鍏佽浠�"鏈叆搴� / 鍥磋"韬唤杩涘叆宸ヤ綔鍙帮紙鍙锛夛紝鐢卞伐浣滃彴椤堕儴鐨勩�屽伐浣嶃�嶄笅鎷�
// 閫夋嫨瑕佹煡鐪嬶紙鍥磋锛夋垨瑕佸叆搴х殑宸ヤ綅銆傝嫢涓�寰嬪脊鍥為�夊伐浣嶉〉锛屽氨姘歌繙鏃犳硶鍥磋鍒汉銆�
console.info('[room] 鏈嚜鍔ㄥ叆搴э紙' + (res.reason || 'nomatch') + '锛夛紝鎸�"鍙洿瑙�"鏀捐')
diff --git a/src/store/modules/room.ts b/src/store/modules/room.ts
index 9ae973d..d751770 100644
--- a/src/store/modules/room.ts
+++ b/src/store/modules/room.ts
@@ -38,6 +38,10 @@
reason?: 'nomatch' | 'occupied' | 'multi' | 'ip_invalid' | 'ip_is_server' | 'error'
/** 琚崰鐢ㄦ椂鐨勫崰鐢ㄤ汉锛屼究浜庢彁绀� */
occupiedBy?: string | null
+ /** 銆愭湰闇�姹傘�戣鍗犵敤鏃跺懡涓殑鍊欓�夊伐浣嶏紙渚�"鏄惁鎺ョ"纭鍚庣洿鎺ヨ皟鐢� takeOverBed锛� */
+ roomId?: number | null
+ bedNo?: string | null
+ roomName?: string | null
}
interface RoomInfoVO {
@@ -54,6 +58,13 @@
* 涓よ�呯浉鍚� 鈫� 鍙搷浣滐紱涓嶅悓 鈫� 鍙鍥磋銆�
*/
currentSeat: RoomSeatResp | null
+ /**
+ * 銆愭湰闇�姹偮蜂竴浜哄宸ヤ綅銆戝綋鍓嶇櫥褰曚汉鍗犳嵁鐨�**鍏ㄩ儴**宸ヤ綅锛堣妭鍋囨棩鍊肩彮澶氬矖浣嶏級銆�
+ *
+ * 涓� `currentSeat` 鐨勫尯鍒細`currentSeat` 鍙槸"榛樿/棣栭�夊彇"鐨勯偅涓�涓紙椤舵爮鏂囨鐢級锛�
+ * `mySeats` 鎵嶆槸瀹屾暣闆嗗悎锛沗getCanOperate` 鐢ㄥ畠鍒ゆ柇"褰撳墠鏌ョ湅鐨勫伐浣嶆槸鍚﹀睘浜庢垜"銆�
+ */
+ mySeats: RoomSeatResp[]
/** 褰撳墠鏌ョ湅宸ヤ綅鐨勪富浜虹殑濮撳悕锛堝洿瑙傛椂鐢ㄤ簬鎻愮ず"姝e湪鍥磋 X锛堜富浜� 寮犱笁锛�"锛� */
viewOwnerName: string | null
/** 褰撳墠鏌ョ湅鐨勫伐浣嶇幇鍦ㄦ槸鍚�**鏃犱汉鎿嶄綔**锛堜富浜哄凡绂诲骇锛涘彧鎻愮ず锛屼笉鑷姩鎺ョ锛� */
@@ -81,6 +92,8 @@
roomSelectMode: -1,
// 褰撳墠鍏ュ骇鐨勫伐浣嶏紙椤舵爮鏄剧ず锛涙湭鍏ュ骇涓� null锛�
currentSeat: null,
+ // 銆愭湰闇�姹偮蜂竴浜哄宸ヤ綅銆戞垜鍗犳嵁鐨勫叏閮ㄥ伐浣嶏紙鏈叆搴т负绌烘暟缁勶級
+ mySeats: [],
// 姝e湪鏌ョ湅鐨勫伐浣嶇殑涓讳汉濮撳悕锛堝洿瑙傛彁绀虹敤锛�
viewOwnerName: null,
// 姝e湪鏌ョ湅鐨勫伐浣嶇幇鍦ㄦ槸鍚︽棤浜烘搷浣滐紙涓讳汉宸茬搴� 鈫� 鍙彁绀猴紝涓嶈嚜鍔ㄦ帴绠★級
@@ -98,16 +111,35 @@
getCurrentSeat(): RoomSeatResp | null {
return this.currentSeat
},
+ /** 銆愭湰闇�姹偮蜂竴浜哄宸ヤ綅銆戞垜鍗犳嵁鐨勫叏閮ㄥ伐浣� */
+ getMySeats(): RoomSeatResp[] {
+ return this.mySeats || []
+ },
+ /** 銆愭湰闇�姹偮蜂竴浜哄宸ヤ綅銆戞垜鍗犳嵁鐨勫伐浣嶆暟閲忥紙椤舵爮鎻愮ず"鎴戠殑宸ヤ綅 N 涓�"锛� */
+ getMySeatCount(): number {
+ return (this.mySeats || []).length
+ },
/**
* 銆愪富/鍥磋銆戝綋鍓嶆槸鍚�**鍙互鎿嶄綔涓氬姟**銆�
*
- * 鍒ゅ畾锛氭垜鍏ュ骇鐨勫伐浣� == 鎴戞鍦ㄧ湅鐨勫伐浣嶏紙鏈嶅姟绔彟鏈変竴閬撶‖鏍¢獙锛歞oc_id 蹇呴』鏄垜锛夈��
- * 涓� false 鏃跺墠绔簲绂佺敤鎵�鏈夊啓鎿嶄綔鎸夐挳锛岀晫闈㈡樉绀�"鍥磋妯″紡 路 鍙"銆�
+ * 鍒ゅ畾锛堟湰闇�姹傛敼涓�"鍖呭惈"锛夛細
+ * 褰撳墠鏌ョ湅鐨勫伐浣� 鈭� 鎴戠殑宸ヤ綅鍒楄〃 鈬� 鍙搷浣滐紙鏈嶅姟绔彟鏈変竴閬撶‖鏍¢獙锛氳宸ヤ綅 doc_id 蹇呴』鏄垜锛夈��
+ * 涓�閿宸ヤ綅鍚庯紝鎴戜笉鍙兘鍚屾椂鍙湪"涓�涓�"宸ヤ綅涓婏紝鎵�浠ヤ笉鑳藉啀鐢�"鐩哥瓑"鍒ゆ柇銆�
+ * 鍏煎锛歚mySeats` 杩樻病鍙栧埌锛堟棫鎺ュ彛/鏃х紦瀛橈級鏃跺洖閫�鍒� `currentSeat` 鐩哥瓑鍒ゆ柇銆�
*/
getCanOperate(): boolean {
- const seat = this.currentSeat
const view = this.room
- if (!seat || !seat.seated || !view || view.roomId == null || !view.bedNo) {
+ if (!view || view.roomId == null || !view.bedNo) {
+ return false
+ }
+ const seats = this.mySeats || []
+ if (seats.length > 0) {
+ return seats.some(
+ (s) => String(s.roomId) === String(view.roomId) && String(s.bedNo) === String(view.bedNo)
+ )
+ }
+ const seat = this.currentSeat
+ if (!seat || !seat.seated) {
return false
}
return String(seat.roomId) === String(view.roomId) && String(seat.bedNo) === String(view.bedNo)
@@ -166,6 +198,9 @@
this.viewOwnerName = room.docName ?? null
this.viewTargetVacant = false
+ // 銆愭湰闇�姹偮蜂竴浜哄宸ヤ綅銆戞妸璇ュ伐浣嶅苟鍏ャ�屾垜鐨勫伐浣嶃�嶏紙宸插瓨鍦ㄥ垯鏇存柊锛屼笉瀛樺湪鍒欐柊澧烇級
+ this.upsertMySeat(this.currentSeat)
+
// 銆愪慨澶嶃�戝啓鍏ョ紦瀛橈紙sessionStorage锛夈��
//
// 鍘熷疄鐜版槸 `const bedInfo = wsCache.get(...); if (bedInfo) { ...; wsCache.set(...) }`
@@ -176,7 +211,38 @@
// 鎵嶅惎鍔ㄥ彇鏁板畾鏃跺櫒 鈬� **椤甸潰涓�鐗囩┖鐧斤紝鐪嬭捣鏉ュ儚"娌″姞杞芥帓闃熺梾浜�"**锛�
// 路 瑙掕壊涓� doctor 鐨勭敤鎴疯繕浼氳璺敱瀹堝崼寮瑰洖 /roomselect 閲嶆柊閫夎瘖瀹ゃ��
// 杩欓噷鏀逛负**鏃犳潯浠跺啓鍏�**锛涙仮澶嶈鏂囦欢鏈熬鐨� setupRoomStorePersistence()銆�
- wsCache.set(CACHE_KEY.ROOM, { isSetRoom: true, room: this.room, currentSeat: this.currentSeat })
+ wsCache.set(CACHE_KEY.ROOM, {
+ isSetRoom: true,
+ room: this.room,
+ currentSeat: this.currentSeat,
+ mySeats: this.mySeats
+ })
+ },
+ /** 銆愭湰闇�姹偮蜂竴浜哄宸ヤ綅銆戞妸涓�鏉″伐浣嶅苟鍏� mySeats锛堟寜 roomId+bedNo 鍘婚噸锛� */
+ upsertMySeat(seat: RoomSeatResp | null) {
+ if (!seat || seat.roomId == null || !seat.bedNo) return
+ const list = (this.mySeats || []).filter(
+ (s) => !(String(s.roomId) === String(seat.roomId) && String(s.bedNo) === String(seat.bedNo))
+ )
+ list.push(seat)
+ this.mySeats = list
+ },
+ /** 銆愭湰闇�姹偮蜂竴浜哄宸ヤ綅銆戠敤鍚庣杩斿洖鐨勫畬鏁村垪琛ㄦ浛鎹� mySeats锛屽苟鍚屾 currentSeat */
+ applyMySeats(seats: RoomSeatResp[]) {
+ this.mySeats = Array.isArray(seats) ? seats : []
+ if (this.mySeats.length === 0) {
+ this.currentSeat = null
+ return
+ }
+ // currentSeat锛氫紭鍏堝彇"褰撳墠鏌ョ湅鐨勫伐浣�"瀵瑰簲鐨勯偅鏉★紝鍚﹀垯绗竴鏉�
+ const view = this.room
+ const matched = this.mySeats.find(
+ (s) =>
+ null != view &&
+ String(s.roomId) === String(view.roomId) &&
+ String(s.bedNo) === String(view.bedNo)
+ )
+ this.currentSeat = matched ?? this.mySeats[0]
},
/**
* 銆愪富/鍥磋銆戞妸"鎴戞鍦ㄧ湅鐨勫伐浣�"鍒囧埌鍒汉锛堟垨鍒囧洖鑷繁锛夆�斺��**涓嶆敼鎴戠殑鍏ュ骇宸ヤ綅**銆�
@@ -201,7 +267,12 @@
this.isSetRoom = true
this.viewOwnerName = ownerName ?? bed.docName ?? null
this.viewTargetVacant = bed.docId == null
- wsCache.set(CACHE_KEY.ROOM, { isSetRoom: true, room: this.room, currentSeat: this.currentSeat })
+ wsCache.set(CACHE_KEY.ROOM, {
+ isSetRoom: true,
+ room: this.room,
+ currentSeat: this.currentSeat,
+ mySeats: this.mySeats
+ })
},
/**
* 銆愪富/鍥磋銆戝埛鏂�"鎴戞鍦ㄧ湅鐨勫伐浣�"鐨勬渶鏂扮姸鎬侊紙鐢ㄤ簬鍙戠幇涓讳汉宸茬搴э級銆�
@@ -232,6 +303,8 @@
this.isSetRoom = false
// 椤舵爮鏍囩鍚屾娓呯┖锛堢搴у悗鏄剧ず"鏈叆搴�"锛�
this.currentSeat = null
+ // 銆愭湰闇�姹偮蜂竴浜哄宸ヤ綅銆戠搴у悗 mySeats 涓�骞舵竻绌�
+ this.mySeats = []
this.viewOwnerName = null
this.viewTargetVacant = false
@@ -253,6 +326,12 @@
this.room = { ...this.room, ...cached.room }
this.isSetRoom = true
// 銆愪富/鍥磋銆戣繛"鎴戝叆搴х殑宸ヤ綅"涓�璧锋仮澶嶏細鍚﹀垯鍒锋柊鍚� getCanOperate 浼氳鍒や负鍙
+ // 銆愭湰闇�姹偮蜂竴浜哄宸ヤ綅銆戜紭鍏堟仮澶嶅畬鏁村垪琛紱鏃х紦瀛樻病鏈� mySeats 鏃剁敤 currentSeat 鍏滃簳
+ if (Array.isArray(cached?.mySeats) && cached.mySeats.length > 0) {
+ this.mySeats = cached.mySeats
+ } else if (cached?.currentSeat) {
+ this.mySeats = [cached.currentSeat]
+ }
if (cached?.currentSeat) {
this.currentSeat = cached.currentSeat
this.viewOwnerName = cached.currentSeat.docName ?? null
@@ -340,15 +419,21 @@
} as RoomVO)
// 椤舵爮"褰撳墠宸ヤ綅"鏍囩鐢�
this.currentSeat = resp as RoomSeatResp
+ // 銆愭湰闇�姹偮蜂竴浜哄宸ヤ綅銆戞妸璇ュ伐浣嶅苟鍏ユ垜鐨勫伐浣嶅垪琛�
+ this.upsertMySeat(this.currentSeat)
console.info('[room] 鎸塈P鑷姩鍏ュ骇鎴愬姛', resp)
return { seated: true, clientIp }
}
- console.info('[room] 鎸塈P鑷姩鍏ュ骇鏈垚鍔燂紝杞汉宸ラ�夊伐浣�', resp)
+ console.info('[room] 鎸塈P鑷姩鍏ュ骇鏈垚鍔�', resp)
return {
seated: false,
clientIp,
reason: (resp.reason || 'nomatch') as AutoSeatResult['reason'],
- occupiedBy: resp.ownerName ?? null
+ occupiedBy: resp.ownerName ?? resp.docName ?? null,
+ // 銆愭湰闇�姹傘�戣鍗犵敤鏃跺悗绔細甯﹀洖鍊欓�夊伐浣嶄俊鎭紝渚�"鏄惁鎺ョ"纭鍚庣洿鎺ヨ皟鐢�
+ roomId: resp.roomId ?? null,
+ bedNo: resp.bedNo ?? null,
+ roomName: resp.roomName ?? null
}
} catch (e) {
console.error('[tryAutoSeatByIp] 鑷姩鍏ュ骇鎺ュ彛寮傚父', e)
@@ -367,39 +452,106 @@
*/
async fetchMySeat(): Promise<RoomSeatResp | null> {
try {
- const resp: any = (await RoomApi.getMySeat()) || {}
- if (!resp.seated) {
+ // 銆愭湰闇�姹偮蜂竴浜哄宸ヤ綅銆戜紭鍏堝彇"鎴戠殑鍏ㄩ儴宸ヤ綅"锛涘悗绔湭鍗囩骇锛�404锛夋椂鍥為��鍗曞�兼帴鍙�
+ let seats: RoomSeatResp[] = []
+ let fallbackSingle: any = null
+ try {
+ const list: any = await RoomApi.getMySeats()
+ seats = Array.isArray(list) ? (list as RoomSeatResp[]) : []
+ } catch (e) {
+ console.warn('[fetchMySeat] /my-seats 涓嶅彲鐢紝鍥為�� /my-seat', e)
+ const resp: any = (await RoomApi.getMySeat()) || {}
+ if (resp.seated) {
+ fallbackSingle = resp
+ seats = [resp as RoomSeatResp]
+ }
+ }
+
+ if (seats.length === 0 && !fallbackSingle) {
+ this.mySeats = []
this.currentSeat = null
return null
}
- this.currentSeat = resp as RoomSeatResp
+
+ this.applyMySeats(seats)
+
const noViewTarget = !this.isSetRoom || this.room.roomId == null || !this.room.bedNo
- const viewingMyself =
- !noViewTarget &&
- String(this.room.roomId) === String(resp.roomId) &&
- String(this.room.bedNo) === String(resp.bedNo)
- if (!noViewTarget && !viewingMyself) {
- // 姝e湪鍥磋鍒汉 鈫� 鍙洿鏂�"鎴戝叆搴х殑宸ヤ綅"锛屼笉鍔ㄦ煡鐪嬬洰鏍�
- console.info('[room] 鏌ヨ鍒版垜鍏ュ骇鐨勫伐浣嶏紙褰撳墠姝e湪鍥磋浠栦汉锛屼笉鍒囨崲鏌ョ湅鐩爣锛�', resp)
+ const viewingMine = !noViewTarget && this.getCanOperate
+ if (!noViewTarget && !viewingMine) {
+ // 姝e湪鍥磋鍒汉 鈫� 鍙洿鏂�"鎴戠殑宸ヤ綅鍒楄〃"锛屼笉鍔ㄦ煡鐪嬬洰鏍�
+ console.info('[room] 宸插埛鏂版垜鐨勫伐浣嶅垪琛紙褰撳墠姝e湪鍥磋浠栦汉锛屼笉鍒囨崲鏌ョ湅鐩爣锛�', seats)
return this.currentSeat
}
- await this.setRoomInfoAction({
- id: resp.id ?? null,
- roomId: resp.roomId ?? null,
- roomName: resp.roomName ?? null,
- bedNo: resp.bedNo ?? null,
- ip: resp.ip ?? null,
- status: resp.status ?? null,
- docId: resp.docId ?? null,
- docName: resp.docName ?? null,
- checkTypes: resp.checkTypes ?? null,
- opType: resp.opType ?? null
- } as RoomVO)
- console.info('[room] 鏌ヨ鍒板綋鍓嶅叆搴у伐浣�', resp)
+
+ // 鏈�夋煡鐪嬬洰鏍� / 鐪嬬殑灏辨槸鑷繁鐨勬煇涓伐浣� 鈫� 瀵归綈鍒拌宸ヤ綅锛堜紭鍏堝綋鍓嶆煡鐪嬬殑閭d釜锛�
+ const target = this.currentSeat ?? seats[0]
+ if (target) {
+ await this.setRoomInfoAction({
+ id: target.id ?? null,
+ roomId: target.roomId ?? null,
+ roomName: target.roomName ?? null,
+ bedNo: target.bedNo ?? null,
+ ip: target.ip ?? null,
+ status: target.status ?? null,
+ docId: target.docId ?? null,
+ docName: target.docName ?? null,
+ checkTypes: target.checkTypes ?? null,
+ opType: target.opType ?? null
+ } as RoomVO)
+ }
+ console.info('[room] 鏌ヨ鍒版垜鐨勫伐浣嶅垪琛�', seats)
return this.currentSeat
} catch (e) {
console.error('[fetchMySeat] 鏌ヨ褰撳墠宸ヤ綅澶辫触', e)
return null
+ }
+ },
+
+ /**
+ * 銆愭湰闇�姹偮锋帴鐝嚜鍔╂帴绠°�戞妸鎸囧畾宸ヤ綅浠�"鍒汉鍗犵敤"鏀瑰埌鎴戝悕涓嬶紝骞跺垏鎹㈠埌璇ュ伐浣嶃��
+ *
+ * @returns 鏄惁鎺ョ鎴愬姛
+ */
+ async takeOverBed(roomId: number | null, bedNo: string | null): Promise<boolean> {
+ if (roomId == null || !bedNo) return false
+ try {
+ await RoomApi.takeOverBed({ roomId, bedNo })
+ // 鍒锋柊"鎴戠殑宸ヤ綅"锛堟鏃跺悗绔凡鎶婅宸ヤ綅 doc_id 璁句负鎴戯級
+ await this.fetchMySeat()
+ // 鍒囨崲鍒拌宸ヤ綅锛堣嫢鏄垰鎺ョ銆佷笖涓嶅湪鍒楄〃閲岋紝鍒欐墜鍔ㄨˉ涓�鏉″苟鍒囪繃鍘伙級
+ let seat = (this.mySeats || []).find(
+ (s) => String(s.roomId) === String(roomId) && String(s.bedNo) === String(bedNo)
+ )
+ if (!seat) {
+ const userStore = useUserStore()
+ const curUser: any = userStore.getUser || {}
+ seat = {
+ seated: true,
+ roomId,
+ bedNo,
+ roomName: this.room?.roomName ?? null,
+ docId: curUser.id ?? null,
+ docName: curUser.nickname ?? null
+ } as RoomSeatResp
+ this.mySeats = [...(this.mySeats || []), seat]
+ }
+ await this.setRoomInfoAction({
+ id: seat.id ?? null,
+ roomId: seat.roomId ?? null,
+ roomName: seat.roomName ?? null,
+ bedNo: seat.bedNo ?? null,
+ ip: seat.ip ?? null,
+ status: seat.status ?? null,
+ docId: seat.docId ?? null,
+ docName: seat.docName ?? null,
+ checkTypes: seat.checkTypes ?? null,
+ opType: seat.opType ?? null
+ } as RoomVO)
+ console.info('[room] 鎺ョ宸ヤ綅鎴愬姛', roomId, bedNo)
+ return true
+ } catch (e) {
+ console.error('[takeOverBed] 鎺ョ宸ヤ綅澶辫触', e)
+ return false
}
},
@@ -428,6 +580,8 @@
return false
}
await this.setRoomInfoAction(tempRoomVO)
+ // 銆愭湰闇�姹偮蜂竴浜哄宸ヤ綅銆戝叆搴у悗鍒锋柊"鎴戠殑鍏ㄩ儴宸ヤ綅"锛堝彲鑳藉凡鏈夊涓級
+ await this.fetchMySeat()
return true
},
diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts
index 7cbb93c..69547f2 100644
--- a/src/store/modules/user.ts
+++ b/src/store/modules/user.ts
@@ -3,7 +3,6 @@
import { getAccessToken, removeToken } from '@/utils/auth'
import { CACHE_KEY, useCache, deleteUserCache } from '@/hooks/web/useCache'
import { getInfo, loginOut } from '@/api/login'
-import { releaseBedOnExit } from '@/utils/releaseBed'
const { wsCache } = useCache()
@@ -80,11 +79,14 @@
wsCache.set(CACHE_KEY.USER, userInfo)
},
async loginOut() {
- // 鍏堥噴鏀捐瘖鐤楀簥浣嶏紙鍖荤敓甯稿湪銆岃瘖瀹ら�夋嫨銆嶉〉鍗犱簡搴婁綅灏辩洿鎺ラ��鍑虹郴缁燂級銆�
- // 鍚庣 `/system/auth/logout` 鍐呴儴铏界劧涔熶細绂诲骇锛屼絾锛�
- // 鈶� 鑻ヨ璇锋眰澶辫触/缃戠粶涓柇锛屽簥浣嶅氨鐣欏湪鍗犵敤鐘舵�侊紱
- // 鈶� 鏈帴鍙eけ璐ヤ篃涓嶄細闃绘柇閫�鍑烘祦绋嬶紙releaseBedOnExit 鍐呴儴宸插厹搴曪級銆�
- await releaseBedOnExit('manual-logout')
+ // 銆愭湰闇�姹偮烽�� B銆戦��鍑虹櫥褰�**涓嶅啀閲婃斁宸ヤ綅**銆�
+ //
+ // 涓轰粈涔堬細
+ // 鈶� 涓�浜哄宸ヤ綅鍚庯紝鍚屼竴鍖荤敓鍙兘鍚屾椂鍦ㄥ鍙扮數鑴戜笂鍚勬搷浣滀竴涓矖浣� 鈥斺��
+ // 鍏朵腑涓�鍙伴��鍑虹櫥褰曡嫢鎸� userId 閲婃斁"鍏ㄩ儴宸ヤ綅"锛屼細鎶婂彟涓�鍙版鍦ㄧ敤鐨勫矖浣嶄篃娓呮帀锛�
+ // 鈶� 宸ヤ綅閲婃斁鏀逛负涓夌鏄庣‘閫斿緞锛氬尰鐢熺偣銆岀搴с�嶏紱闂瘖缁熶竴娓呯┖锛�
+ // 绠$悊鍛樸�屾竻绌哄伐浣嶃��/ 鎺ョ彮鍖荤敓銆屾帴绠°�嶏紙`POST /clinic/room/take-over-bed`锛夈��
+ // 鍘熷厛杩欓噷璋冪敤 `releaseBedOnExit('manual-logout')` 鈫� `/ecg/doctor/release-my-beds`銆�
await loginOut()
removeToken()
deleteUserCache() // 鍒犻櫎鐢ㄦ埛缂撳瓨
diff --git a/src/styles/index.scss b/src/styles/index.scss
index fbe76f2..14b28e4 100644
--- a/src/styles/index.scss
+++ b/src/styles/index.scss
@@ -34,3 +34,27 @@
border-left-color: var(--el-color-primary);
}
}
+
+/* ==========================================================================
+ 銆愰渶姹偮峰垎杈ㄧ巼閫傞厤銆戝脊绐楀湪灏忓睆骞曚笂涓嶈秴鍑哄彲瑙嗗尯
+
+ 鑳屾櫙锛氬尰鐢熷伐浣滅數鑴戝垎杈ㄧ巼宸紓澶э紙1920 / 1366 / 1024锛屼笖甯稿甫 125% 缂╂斁锛夈��
+ 椤圭洰閲屽澶勫脊绐楀啓姝讳簡 `width="880px"` / `900px`锛屽湪 1024 瀹芥垨鏀惧ぇ鍚�
+ 浼氳秴鍑哄睆骞� 鈥斺�� 鍙充晶鐨勩�岀‘瀹�/鍙栨秷銆嶅拰鍐呭鐩存帴鐪嬩笉鍒般��
+
+ 澶勭悊锛堝叏灞�涓�澶勭敓鏁堬紝涓嶇敤閫愪釜鏀� 9 涓脊绐楃粍浠讹級锛�
+ 路 Element Plus 2.7 鐨� `.el-dialog` 瀹藉害鏄� `var(--el-dialog-width)`锛�
+ 杩欓噷鍐嶅姞 `max-width`锛屽啓姝荤殑 px 浼氳鑷姩澶逛綇锛�
+ 路 鐭睆锛堚墹800px 楂橈級鎶婇《閮ㄧ暀鐧戒粠榛樿 15vh 鏀跺埌 6vh锛�
+ 鎶婂疂璐电殑鍨傜洿绌洪棿杩樼粰鍐呭锛坄.el-overlay-dialog` 鏈韩宸� overflow:auto锛�
+ 鍐呭杩囬珮鏃舵暣浣撳彲婊氬姩锛夈��
+ ========================================================================== */
+.el-dialog {
+ max-width: 92vw;
+}
+
+@media (max-height: 800px) {
+ .el-dialog {
+ --el-dialog-margin-top: 6vh;
+ }
+}
diff --git a/src/utils/releaseBed.ts b/src/utils/releaseBed.ts
index a642a49..eb51e20 100644
--- a/src/utils/releaseBed.ts
+++ b/src/utils/releaseBed.ts
@@ -2,6 +2,14 @@
import { getAccessToken } from '@/utils/auth'
/**
+ * 銆�2026-11-05 璧凤細鏈枃浠跺凡鏃犺皟鐢ㄦ柟銆�
+ * ---------------------------------------------------
+ * 涓氬姟鏀逛负銆岄��鍑虹櫥褰�**涓嶉噴鏀�**宸ヤ綅銆嶏紙涓�浜哄宸ヤ綅/澶氱鐧诲綍锛氫竴鍙伴��鍑轰笉鑳芥竻鎺夊彟涓�鍙扮殑宀椾綅锛夛紝
+ * 閲婃斁宸ヤ綅鏀逛负涓夌鏄庣‘閫斿緞锛�
+ * 鈶� 鍖荤敓鐐广�岀搴с�嶏紱鈶� 闂瘖缁熶竴娓呯┖锛涒憿 绠$悊鍛樸�屾竻绌哄伐浣嶃��/ 鎺ョ彮鍖荤敓銆屾帴绠°�嶃��
+ * 鏈伐鍏峰嚱鏁颁繚鐣欙紙鍚庣 /ecg/doctor/release-my-beds 涔熶繚鐣欙級锛屼粎鐢ㄤ簬杩愮淮/绠$悊渚ч渶瑕佹椂鎵嬪姩璋冪敤銆�
+ *
+ * ---------- 浠ヤ笅涓哄師娉ㄩ噴 ----------
* 鎵嬪姩銆岄��鍑虹櫥褰曘�嶆椂閲婃斁璇婂宸ヤ綅銆�
*
* 鑳屾櫙
diff --git a/src/views/ecg/appointment/AppointmentForm.vue b/src/views/ecg/appointment/AppointmentForm.vue
index 65ecbfd..3458e95 100644
--- a/src/views/ecg/appointment/AppointmentForm.vue
+++ b/src/views/ecg/appointment/AppointmentForm.vue
@@ -286,7 +286,11 @@
bookTime: undefined,
bookDate: new Date().getTime(),
bookTimeslot: 9000930,
- bookCheckType: getCheckTypeName(100),
+ // 銆愭湰娆′慨澶嶃�戝師鏉ュ啓鐨勬槸 getCheckTypeName(100)锛屾妸**涓枃鍚嶇О**锛�"甯歌蹇冪數鍥�"锛夊杩涗簡
+ // bookCheckType锛岃�屽悗绔瓧娈垫槸 Integer銆傚悗鏋滐細鏂板缓/閲嶇疆鍚庝笉閲嶆柊閫夋鏌ラ」鐩洿鎺ヤ繚瀛橈紝
+ // 浼氭彁浜ゅ瓧绗︿覆 鈫� Jackson 鍙嶅簭鍒楀寲澶辫触 鈫� 500銆岀郴缁熷紓甯搞�嶃��
+ // 姝g‘鍐欐硶锛氫笌鏂板缓鍒濆鍊间竴鑷达紝鐢ㄦ鏌ョ被鍨嬬殑**鏁板瓧鍊�**锛�100=甯歌蹇冪數鍥撅級銆�
+ bookCheckType: 100,
paid: 0
}
formRef.value?.resetFields()
diff --git a/src/views/ecg/appointment/CheckItemPanel.vue b/src/views/ecg/appointment/CheckItemPanel.vue
index 63c379c..db4bc55 100644
--- a/src/views/ecg/appointment/CheckItemPanel.vue
+++ b/src/views/ecg/appointment/CheckItemPanel.vue
@@ -47,16 +47,29 @@
const _confirmAppointment = async () => {
if (!isCurrentDay(props.appointment.bookDate)) {
- ElMessageBox.confirm('闈炲綋澶╅绾﹂」锛岀‘瀹氳浠婂ぉ妫�鏌ュ悧锛�', 'Warning', {
- confirmButtonText: '濂界殑',
- cancelButtonText: '涓嶇敤',
- type: 'warning'
- })
+ // 銆愭湰闇�姹傘�戦潪褰撳ぉ棰勭害锛氬厛鎻愰啋锛岀‘璁ゅ悗**鎸夐鐣欏彿**绛惧叆锛堜笉鍗犵敤浠婂ぉ鍚屾椂娈电殑姝e父棰勭害鍙凤級
+ // 娉ㄦ剰 bookDate 浠庡悗绔洖鏉ユ槸**鏃堕棿鎴虫暟鍊�**锛堝 1792339200000锛夛紝蹇呴』鏍煎紡鍖栧悗鍐嶆嫾杩涙彁绀猴紝
+ // 鍚﹀垯浼氱洿鎺ユ樉绀轰竴涓叉暟瀛椼�俧ormatTimestamp 鈫� dayjs(x).format('YYYY-MM-DD')銆�
+ const bookDateText = props.appointment.bookDate
+ ? formatTimestamp(props.appointment.bookDate)
+ : '-'
+ ElMessageBox.confirm(
+ `璇ユ偅鑰呴绾︽棩鏈熶负 ${bookDateText}锛屼笉鏄粖澶┿�俓n` +
+ '鏄惁浠嶈浠婂ぉ绛惧埌锛熺‘璁ゅ悗灏嗗垎閰嶃�愰鐣欏彿銆戯紙涓嶄細鍗犵敤浠婂ぉ璇ユ椂娈电殑姝e父棰勭害鍙凤級銆�',
+ '闈炲綋澶╅绾︾鍒�',
+ {
+ confirmButtonText: '缁х画绛惧埌',
+ cancelButtonText: '鍙栨秷',
+ type: 'warning'
+ }
+ )
.then(async () => {
const tempAppointment = cloneDeep(props.appointment)
if (undefined !== bookTimeSlotVip.value && null !== bookTimeSlotVip.value) {
tempAppointment.bookTimeslot = bookTimeSlotVip.value
}
+ // 銆愭湰闇�姹傘�戞樉寮忓甫涓�"宸茬‘璁ょ鍏�"鏍囪锛氬悗绔嵁姝ゆ斁琛岄潪褰撳ぉ棰勭害锛屽苟鎸夐鐣欏彿鍙栧彿
+ tempAppointment.forceCheckIn = true
const data = await AppointmentApi.confirmAppointmentVip(tempAppointment)
seqNum.value = data
// 鍙戦�佹搷浣滄垚鍔熺殑浜嬩欢
diff --git a/src/views/ecg/appointment/index.vue b/src/views/ecg/appointment/index.vue
index ca116bd..1f29327 100644
--- a/src/views/ecg/appointment/index.vue
+++ b/src/views/ecg/appointment/index.vue
@@ -10,9 +10,19 @@
<el-input v-model="queryParams.patName" placeholder="璇疯緭鍏ユ偅鑰呭鍚�" clearable @keyup.enter="handleQuery"
class="!w-240px" />
</el-form-item>
- <el-form-item label="鎮h�呮墜鏈�" prop="patMobile">
- <el-input v-model="queryParams.patMobile" placeholder="璇疯緭鍏ユ偅鑰呮墜鏈�" clearable @keyup.enter="handleQuery"
- class="!w-240px" />
+ <!-- 銆愭湰闇�姹傘�戦绾︽棩鏈熸椂闂存鏌ヨ锛堟浛浠e凡鍘绘帀鐨勩�屾偅鑰呮墜鏈恒�嶆潯浠讹紝鍑忓皯鏌ヨ鏉′欢鏁伴噺锛� -->
+ <el-form-item label="棰勭害鏃ユ湡" prop="bookDateRange">
+ <el-date-picker
+ v-model="queryParams.bookDateRange"
+ type="daterange"
+ value-format="YYYY-MM-DD"
+ range-separator="鑷�"
+ start-placeholder="寮�濮嬫棩鏈�"
+ end-placeholder="缁撴潫鏃ユ湡"
+ unlink-panels
+ clearable
+ class="!w-320px"
+ />
</el-form-item>
<!--
<el-form-item label="鎮h�呯數璇�" prop="patPhone">
@@ -219,7 +229,6 @@
patName: undefined,
patGender: undefined,
patBirthday: undefined,
- patMobile: undefined,
patPhone: undefined,
patIdentityId: undefined,
patAddr: undefined,
@@ -229,6 +238,8 @@
patWardDesc: undefined,
patBedNo: undefined,
bookDate: undefined,
+ // 銆愭湰闇�姹傘�戦绾︽棩鏈熸椂闂存锛歔]=[寮�濮�,缁撴潫]锛孉PI 灞備細鎷嗘垚 bookDateStart(00:00:00) / bookDateEnd(23:59:59)
+ bookDateRange: [] as string[] | undefined,
bookTimeslot: undefined,
bookCheckType: undefined,
bookSrc: undefined
diff --git a/src/views/ecg/callingscreen/bigscreen.vue b/src/views/ecg/callingscreen/bigscreen.vue
index d31a8dc..143402a 100644
--- a/src/views/ecg/callingscreen/bigscreen.vue
+++ b/src/views/ecg/callingscreen/bigscreen.vue
@@ -273,20 +273,27 @@
border-left: none;
}
+ /*
+ 鈿狅笍 杩欓噷鍘熸湰鏄細
+ display: flex; flex-wrap: wrap;
+ .patient-item { width: 48%; margin-right: 2%; }
+ .patient-item:nth-child(2n) { margin-right: 0; }
+ 鎰忓浘鏄�"璇ュ垪鏁版嵁澶氭椂锛屽湪鍒楀唴閮ㄥ啀鍒嗘垚涓ゅ皬鍒�"銆�
+
+ 浣嗗畠浼氳鎮h�呮潯鐩�**宸﹀彸骞舵帓**锛屽鑷村ぇ灞忎笂鐪嬭捣鏉�"鎮h�呰窇鍒扮敾闈腑闂�"锛�
+ 路 .patient-item 娌℃湁 box-sizing: border-box锛宲adding 涓� 10px 8px锛�
+ 鍗曚釜澶栧 = 48% + 2% + 16px锛屼袱涓悎璁� = 0.98W + 32px锛�
+ 鍙湁鍒楀唴瀹瑰 W 鈮� 1600px 鏃舵墠鏀惧緱涓嬩袱涓� 鈫�
+ 澶у睆锛�1920 鍗曞垪 / 瀹藉睆澶氬垪锛変笂灏变細骞舵帓锛岀 2 涓偅鑰呮濂借惤鍦ㄧ敾闈㈡按骞充腑闂达紱
+ 路 鍒椾竴绐勫張閫�鍥炲崟鍒楋紝浜庢槸鍚屼竴鍧楀ぇ灞忎笉鍚屽垪琛ㄧ幇涓嶄竴鑷达紝瑙傛劅寰堟���
+
+ 鐜版敼涓�**濮嬬粓鍗曞垪銆佷粠涓婂線涓嬫帓鍒�**锛�
+ 鏁版嵁澶氾紙妯℃澘閲� >13 鏉★級鏃剁敱 v-if 鍒嗘敮鎷嗘垚涓や釜 .patient-column锛�
+ 涓嶄緷璧� flex 鎹㈣锛屽搴﹀悎璁′粛鏄� 2 浠斤紝涓庤〃澶� .column-title.double-column 瀵归綈銆�
+ */
&.double-column {
- flex: 2; /* 鍗犳嵁涓ゅ�嶅搴� */
+ flex: 2; /* 鍗犳嵁涓ゅ�嶅搴︼紙涓庤〃澶翠繚鎸佷竴鑷达級 */
min-width: 600px;
- display: flex;
- flex-wrap: wrap;
-
- .patient-item {
- width: 48%; /* 涓ゅ垪甯冨眬锛岀暀涓�鐐归棿璺� */
- margin-right: 2%;
-
- &:nth-child(2n) {
- margin-right: 0;
- }
- }
}
diff --git a/src/views/ecg/checktype/QueueSequenceForm.vue b/src/views/ecg/checktype/QueueSequenceForm.vue
index 56844a0..bef3e84 100644
--- a/src/views/ecg/checktype/QueueSequenceForm.vue
+++ b/src/views/ecg/checktype/QueueSequenceForm.vue
@@ -13,15 +13,18 @@
<template #title>
<div class="text-13px leading-6">
姝e湪缁存姢妫�鏌ラ」鐩細<b>{{ checkTypeName }}</b>
- <span class="text-gray-500">锛堟鏌ラ」鐩�� {{ checkTypeValue }}锛屽叡 {{ list.length }} 涓椂娈碉級</span>
+ <span class="text-gray-500">锛堟鏌ラ」鐩�� {{ checkTypeValue }}锛屽叡 {{ slotList.length }} 涓椂娈碉級</span>
</div>
</template>
<div class="text-12px leading-5">
- 路 <b>璧峰搴忓彿</b>锛氭瘡澶╄嚜鍔ㄩ噸缃椂鍥炲埌璇ュ�硷紱<b>涓婇檺</b>锛氬埌杈惧悗璇ユ椂娈佃涓恒�屽凡婊°�嶏紝鎮h�呯鍒颁細椤哄欢鍒板悗缁椂娈点��<br />
- 路 <b>褰撳墠搴忓彿</b>锛氬凡鍙戝埌鍑犲彿锛屼竴鑸棤闇�鎵嬪伐鏀癸紙姣忔棩閲嶇疆浼氳嚜鍔ㄥ洖鍒�"璧峰搴忓彿"锛夈��<br />
- 路 <b>棰勫畾棰濆害</b> = 涓婇檺 鈭� 璧峰搴忓彿锛堝彧璇伙級銆�<b>涓婇檺 = 璧峰搴忓彿 琛ㄧず璇ユ椂娈垫病鏈夊悕棰�</b>锛堝厑璁镐繚瀛橈紝棰勫畾棰濆害鏄剧ず 0 骞舵爣绾級銆�<br />
- 路 涓婇檺 <b>涓嶈兘灏忎簬</b>璧峰搴忓彿锛屽惁鍒欒鏃舵姘歌繙鏃犳硶鍙栧彿銆�<br />
- 路 鍚屼竴妫�鏌ラ」鐩笅<b>鍚屼竴鏃舵鍙兘鏈変竴鏉¤鍒�</b>锛岄噸澶嶆坊鍔犱細琚嫆缁濄��
+ 路 <b>鍙锋瑙勫垯</b>锛氭瘡涓椂娈垫寜椤哄簭鍗犵敤涓�娈佃繛缁彿 鈥斺�� 姝e父棰勭害鍙峰湪鍓嶏紝棰勭暀鍙风揣璺熷叾鍚庯紙鍙锋洿澶э級锛�
+ 涓嬩竴娈典粠涓婁竴娈电殑鏈�澶у彿缁х画锛屽洜姝�<b>鍙烽殢鏃舵閫掑銆佹鍐呰繛缁�</b>銆�<br />
+ 路 <b>璧峰搴忓彿</b>锛氱敱绯荤粺鑷姩璁$畻锛堜笂涓�娈电殑鏈�澶у彿锛夛紝<b>涓嶅彲鎵嬪伐淇敼</b>銆�<br />
+ 路 <b>涓婇檺</b>锛氳鍙锋睜銆屽彿婊$殑鏈�澶у簭鍙枫�嶏紱<b>褰撳墠搴忓彿</b>锛氬凡鍙戝埌鍑犲彿锛堟瘡鏃ラ噸缃洖璧峰搴忓彿锛夈��<br />
+ 路 <b>鍙栧彿椤哄簭</b>锛氭櫘閫氭偅鑰� 鈫� 鏈椂娈垫甯搁绾﹀彿锛涙弧浜� 鈫� 鏈椂娈�<b>棰勭暀鍙�</b>锛堢粰涓存椂鍔犲彿锛夛紱
+ 鍐嶆弧 鈫� <b>鎬婚鐣欐睜</b>锛堟棤棰勭害鏃舵鐨勬偅鑰呬篃鐩存帴璧版�婚鐣欐睜锛夈��<b>鎬婚鐣欐睜涓嶈涓婇檺锛屼繚璇佷竴瀹氳兘绛惧埌銆�</b><br />
+ 路 <b>棰勫畾棰濆害</b> = 涓婇檺 鈭� 璧峰搴忓彿锛堝彧璇伙級銆備笂闄� = 璧峰搴忓彿 琛ㄧず璇ュ彿姹犳棤鍚嶉锛堝厑璁镐繚瀛橈紝鏄剧ず 0 骞舵爣绾級銆�<br />
+ 路 涓婇檺 <b>涓嶈兘灏忎簬</b>璧峰搴忓彿锛涘悓涓�妫�鏌ラ」鐩笅<b>鍚屼竴鏃舵鍙兘鏈変竴鏉¤鍒�</b>銆�
</div>
</el-alert>
@@ -39,7 +42,7 @@
<el-table
v-loading="loading"
- :data="list"
+ :data="slotList"
:stripe="true"
border
class="qs-table"
@@ -58,14 +61,10 @@
<el-table-column label="姝e父棰勭害" align="center">
<el-table-column label="璧峰搴忓彿" align="center" width="90">
<template #default="scope">
- <el-input-number
- v-model="scope.row.queueSet"
- :min="0"
- :controls="false"
- size="small"
- style="width: 100%"
- @change="markChanged(scope.row)"
- />
+ <!-- 銆愭湰闇�姹傘�戣捣濮嬪簭鍙� = 鍙锋璧风偣锛岀敱绯荤粺鎸夐『搴忚嚜鍔ㄨ绠楋紝涓嶅厑璁告墜宸ユ敼 -->
+ <span class="qs-fixed" :title="'绯荤粺鑷姩璁$畻锛堜笂涓�娈电殑鏈�澶у彿锛�'">
+ {{ scope.row.queueSet ?? 0 }}
+ </span>
</template>
</el-table-column>
<el-table-column label="涓婇檺" align="center" width="80">
@@ -115,14 +114,10 @@
<el-table-column label="棰勭暀" align="center">
<el-table-column label="璧峰搴忓彿" align="center" width="90">
<template #default="scope">
- <el-input-number
- v-model="scope.row.queueVipSet"
- :min="0"
- :controls="false"
- size="small"
- style="width: 100%"
- @change="markChanged(scope.row)"
- />
+ <!-- 銆愭湰闇�姹傘�戦鐣欏彿娈佃捣鐐癸紝鍚屾牱鐢辩郴缁熻嚜鍔ㄨ绠� -->
+ <span class="qs-fixed" :title="'绯荤粺鑷姩璁$畻锛堟甯搁绾︾殑涓婇檺锛�'">
+ {{ scope.row.queueVipSet ?? 0 }}
+ </span>
</template>
</el-table-column>
<el-table-column label="涓婇檺" align="center" width="80">
@@ -190,6 +185,28 @@
</el-table-column>
</el-table>
+ <!--
+ 銆愭湰闇�姹傘�戞�婚鐣欐睜锛坱ime_slot = 0锛�
+ 路 鏈鏅�氬彿 + 鏈棰勭暀鍙烽兘鍙戝畬锛屾垨鎮h�呮病鏈夐绾︽椂娈垫椂锛屼粠鎬婚鐣欐睜鍙栧彿锛�
+ 路 鍙锋鏀惧湪褰撳ぉ鎵�鏈夋椂娈典箣鍚庯紙鍙锋渶澶� 鈬� 鎺掑叏澶╂渶鍚庯級锛屼笖**涓嶈涓婇檺**锛堟案杩滀笉浼氭弧锛夈��
+ -->
+ <el-alert type="warning" :closable="false" class="mt-10px">
+ <template #title>
+ <div class="text-13px">
+ 鎬婚鐣欐睜锛堟棤鏃舵 / 鎵�鏈夊彿婧愮敤灏芥椂鐨勫厹搴曪級锛�
+ <template v-if="totalPool">
+ 璧峰 <b>{{ totalPool.queueVipSet ?? 0 }}</b> 路
+ 宸插彂 <b>{{ totalPool.queueVipNo ?? 0 }}</b> 路
+ 涓婇檺 <b>{{ totalPool.queueVipFull ?? 0 }}</b>
+ <span class="text-gray-500">锛堜笉璁句笂闄愶紝婊″悗鑷姩缁х画鍙戝彿锛屼繚璇佷竴瀹氳兘绛惧埌锛�</span>
+ </template>
+ <template v-else>
+ <span class="text-gray-500">灏氭湭鍒濆鍖栵紙棣栨绛惧埌鏃剁郴缁熶細鑷姩鍒涘缓锛屽彿娈垫帴鍦ㄥ綋澶╂渶鍚庝竴娈典箣鍚庯級</span>
+ </template>
+ </div>
+ </template>
+ </el-alert>
+
<!-- 鏂板 / 缂栬緫琛ㄥ崟 -->
<Dialog v-model="formVisible" :title="formTitle" width="520px" append-to-body>
<el-form
@@ -219,27 +236,35 @@
閫夐」鏉ヨ嚜瀛楀吀 <code>ecg_book_timeslot</code>锛涗篃鏀寔鐩存帴杈撳叆璧峰/缁撴潫鏃堕棿鍚庡洖杞︽柊寤恒��
</div>
</el-form-item>
- <el-form-item label="鏅��-璧峰搴忓彿" prop="queueSet">
- <el-input-number v-model="formData.queueSet" :min="0" class="w-full" />
+ <el-form-item label="姝e父棰勭害-璧峰搴忓彿" prop="queueSet">
+ <!-- 銆愭湰闇�姹傘�戣捣濮嬪簭鍙� = 鍙锋璧风偣锛岀敱绯荤粺鎸夈�屾鏌ョ被鍨� 鈫� 鏃舵椤哄簭銆嶈嚜鍔ㄨ绠楋紝涓嶅彲鎵嬪伐鏀� -->
+ <el-input-number v-model="formData.queueSet" :min="0" class="w-full" disabled />
+ <div class="text-12px text-gray-500 leading-5 mt-1">
+ 绯荤粺鑷姩璁$畻锛�= 涓婁竴娈电殑鏈�澶у彿锛夛紝涓嶉渶瑕佸~鍐欍��
+ </div>
</el-form-item>
- <el-form-item label="鏅��-涓婇檺" prop="queueFull">
+ <el-form-item label="姝e父棰勭害-涓婇檺" prop="queueFull">
<!-- 銆愭湰娆¢渶姹傘�戜笂闄愬厑璁哥瓑浜庤捣濮嬪簭鍙凤紙=璇ユ椂娈垫棤鍚嶉锛夛紝鏁� min 鏀逛负 0 -->
<el-input-number v-model="formData.queueFull" :min="0" class="w-full" />
</el-form-item>
- <el-form-item label="VIP-璧峰搴忓彿" prop="queueVipSet">
- <el-input-number v-model="formData.queueVipSet" :min="0" class="w-full" />
+ <el-form-item label="棰勭暀-璧峰搴忓彿" prop="queueVipSet">
+ <!-- 銆愭湰闇�姹傘�戦鐣欏彿娈电揣璺熸甯搁绾﹀彿娈典箣鍚庯紝鐢辩郴缁熻嚜鍔ㄨ绠� -->
+ <el-input-number v-model="formData.queueVipSet" :min="0" class="w-full" disabled />
+ <div class="text-12px text-gray-500 leading-5 mt-1">
+ 绯荤粺鑷姩璁$畻锛�= 姝e父棰勭害鐨勪笂闄愶級锛屼笉闇�瑕佸~鍐欍��
+ </div>
</el-form-item>
- <el-form-item label="VIP-涓婇檺" prop="queueVipFull">
+ <el-form-item label="棰勭暀-涓婇檺" prop="queueVipFull">
<!-- 銆愭湰娆¢渶姹傘�戝悓鏅�氫笂闄愶細鍏佽绛変簬璧峰搴忓彿 -->
<el-input-number v-model="formData.queueVipFull" :min="0" class="w-full" />
</el-form-item>
- <el-form-item label="鏅��-褰撳墠搴忓彿">
+ <el-form-item label="姝e父棰勭害-褰撳墠搴忓彿">
<el-input-number v-model="formData.queueNo" :min="0" class="w-full" />
<div class="text-12px text-gray-500 leading-5 mt-1">
- 鏂板鏃舵鏃跺缓璁笌銆屾櫘閫�-璧峰搴忓彿銆嶄竴鑷淬��
+ 鏂板鏃舵鏃跺缓璁笌銆屾甯搁绾�-璧峰搴忓彿銆嶄竴鑷淬��
</div>
</el-form-item>
- <el-form-item label="VIP-褰撳墠搴忓彿">
+ <el-form-item label="棰勭暀-褰撳墠搴忓彿">
<el-input-number v-model="formData.queueVipNo" :min="0" class="w-full" />
</el-form-item>
</el-form>
@@ -276,6 +301,19 @@
() => `棰勭害鏃舵缁存姢${checkTypeName.value ? ' - ' + checkTypeName.value : ''}`
)
const changedCount = computed(() => changedRows.value.size)
+
+/**
+ * 銆愭湰闇�姹傘�戣〃鏍煎彧鏄剧ず"鐪熷疄鏃舵"锛坱ime_slot <> 0锛夛紱
+ * time_slot = 0 鐨勯偅涓�琛屾槸銆屾�婚鐣欐睜銆嶏紙鏃犳椂娈� / 鍏ㄦ弧鏃剁殑鍏滃簳鍙锋睜锛夛紝鍗曠嫭鍦ㄨ〃鏍间笅鏂瑰睍绀恒��
+ */
+const slotList = computed(() =>
+ (list.value || []).filter((r: QueueSequenceVO) => Number(r.timeSlot ?? 0) !== 0)
+)
+
+/** 鎬婚鐣欐睜琛岋紙time_slot = 0锛夛紱鏈垵濮嬪寲鏃朵负 undefined */
+const totalPool = computed(() =>
+ (list.value || []).find((r: QueueSequenceVO) => Number(r.timeSlot ?? 0) === 0)
+)
/** 鏃舵涓嬫媺閫夐」锛氬彇鑷瓧鍏� ecg_book_timeslot锛坴alue 涓� HHMMHHMM 鏁板瓧瀛楃涓诧紝label 褰㈠ 08:00-08:30锛� */
const timeSlotOptions = computed(() => {
@@ -503,6 +541,16 @@
}
/* 棰勫畾棰濆害锛堝彧璇伙級锛氬�间负 0 鏃舵祬绾㈠簳锛岃〃绀鸿鏃舵娌℃湁鍚嶉 */
+/* 銆愭湰闇�姹傘�戝彿娈佃捣鐐癸紙绯荤粺鑷姩璁$畻锛屽彧璇诲睍绀猴級 */
+.qs-fixed {
+ display: inline-block;
+ min-width: 34px;
+ padding: 1px 4px;
+ border-radius: 3px;
+ color: var(--el-text-color-secondary);
+ background-color: var(--el-fill-color-light);
+ font-variant-numeric: tabular-nums;
+}
.qs-quota {
display: inline-block;
padding: 1px 6px;
diff --git a/src/views/ecg/doctor/DevDataEntry.vue b/src/views/ecg/doctor/DevDataEntry.vue
index ad99029..a5b029b 100644
--- a/src/views/ecg/doctor/DevDataEntry.vue
+++ b/src/views/ecg/doctor/DevDataEntry.vue
@@ -8,7 +8,7 @@
v-loading="formLoading"
>
<el-row :gutter="20">
- <el-col :span="12">
+ <el-col :xs="24" :sm="24" :md="12" :lg="12">
<el-form-item label="鎮h�呯紪鍙�" prop="patId">
<el-input v-model="formData.patId" placeholder="璇疯緭鍏ユ偅鑰呯紪鍙�" @input="getRentInfoByPatId" />
</el-form-item>
@@ -32,7 +32,7 @@
<el-input v-model="formData.interference" placeholder="璇疯緭鍏ュ共鎵版暟" />
</el-form-item>
</el-col>
- <el-col :span="12">
+ <el-col :xs="24" :sm="24" :md="12" :lg="12">
<el-form-item label="璁惧缂栧彿" prop="devId">
<el-input v-model="formData.devId" placeholder="璇疯緭鍏ヨ澶囩紪鍙�" @input="getRentInfoByDevId" />
</el-form-item>
diff --git a/src/views/ecg/doctor/DevDismantle.vue b/src/views/ecg/doctor/DevDismantle.vue
index 5dc9076..9f3332e 100644
--- a/src/views/ecg/doctor/DevDismantle.vue
+++ b/src/views/ecg/doctor/DevDismantle.vue
@@ -10,32 +10,32 @@
>
<!-- ===== 缂栬緫鍖猴紙闇�瑕佸綍鍏ョ殑瀛楁锛�===== -->
<el-row :gutter="20">
- <el-col :span="6">
+ <el-col :xs="24" :sm="12" :md="12" :lg="6">
<el-form-item label="鐢宠鍗曞彿" prop="applyNo">
<el-input v-model="formData.applyNo" placeholder="璇疯緭鍏ョ敵璇峰崟鍙�" />
</el-form-item>
</el-col>
- <el-col :span="6">
+ <el-col :xs="24" :sm="12" :md="12" :lg="6">
<el-form-item label="妫�鏌ラ」鐩�" prop="">
{{ formData?.checkType && getCheckTypeName(formData?.checkType) }}
</el-form-item>
</el-col>
- <el-col :span="6">
+ <el-col :xs="24" :sm="12" :md="12" :lg="6">
<el-form-item label="鎮h�呯紪鍙�" prop="">
<el-input v-model="formData.patId" placeholder="璇疯緭鍏ユ偅鑰呯紪鍙�" @input="getRentInfoByPatId" />
</el-form-item>
</el-col>
- <el-col :span="6">
+ <el-col :xs="24" :sm="12" :md="12" :lg="6">
<el-form-item label="鎮h�呭鍚�" prop="patName">
<el-input v-model="formData.episodeId" placeholder="璇疯緭鍏ユ偅鑰呭鍚�" />
</el-form-item>
</el-col>
- <el-col :span="6">
+ <el-col :xs="24" :sm="12" :md="12" :lg="6">
<el-form-item label="璁惧缂栧彿" prop="devId">
<el-input v-model="formData.devId" placeholder="璇疯緭鍏ヨ澶囩紪鍙�" @input="getRentInfoByDevId" />
</el-form-item>
</el-col>
- <el-col :span="6">
+ <el-col :xs="24" :sm="12" :md="12" :lg="6">
<el-form-item label="鎷嗘満鏃堕棿" prop="returnTime">
<el-date-picker
v-model="formData.returnTime"
@@ -45,17 +45,17 @@
/>
</el-form-item>
</el-col>
- <el-col :span="6">
+ <el-col :xs="24" :sm="12" :md="12" :lg="6">
<el-form-item label="骞叉壈鏁�" prop="interference">
<el-input v-model="formData.interference" placeholder="璇疯緭鍏ュ共鎵版暟" />
</el-form-item>
</el-col>
- <el-col :span="6">
+ <el-col :xs="24" :sm="12" :md="12" :lg="6">
<el-form-item label="鑴辫惤" prop="detachment">
<el-switch v-model="formData.detachment" :active-value="1" :inactive-value="0" />
</el-form-item>
</el-col>
- <el-col :span="6">
+ <el-col :xs="24" :sm="12" :md="12" :lg="6">
<el-form-item label="鍩虹嚎绮�" prop="baseline">
<el-switch v-model="formData.baseline" :active-value="1" :inactive-value="0" />
</el-form-item>
diff --git a/src/views/ecg/doctor/Routine.vue b/src/views/ecg/doctor/Routine.vue
index a0baaba..e52cfe8 100644
--- a/src/views/ecg/doctor/Routine.vue
+++ b/src/views/ecg/doctor/Routine.vue
@@ -74,8 +74,11 @@
// ==================== 闇�姹�3锛氬仠姝㈠�欒瘖寮�鍏� ====================
// 璇箟锛氬紑鍚悗銆愬凡鏈夊�欒瘖鐥呬汉缁х画鍙彿锛屼絾涓嶅啀鏂板鍊欒瘖鐥呬汉銆戯紱鍏抽棴鍚庢仮澶嶃��
-// 涓庝笂闈㈢殑"鏆傚仠/鎭㈠"鏄�**涓や釜鐙珛姒傚康**锛氭殏鍋滀細鎶婂氨璇婁腑鎮h�呭己鍒跺畬鎴愩��
-// 骞舵妸鍊欒瘖鎮h�呰涪鍑哄伐浣嶏紱鏈紑鍏冲彧鎷︽埅"鏂板"锛屼笉鍔ㄥ凡鏈夋偅鑰呫��
+// 涓庝笂闈㈢殑"鏆傚仠/鎭㈠"鏄�**涓や釜鐙珛姒傚康**锛堟敞鎰忥細涓よ�呴兘鍙嫤鎴�"鏂板"锛岄兘涓嶅姩宸叉湁鎮h�咃級锛�
+// 路 鏆傚仠锛氬伐浣嶇姸鎬� 20銆屽湪搴с�嶁啋 30銆屾殏鍋溿�嶏紙绠$悊绔�/鐩戞帶椤靛彲瑙侊級锛屽悓鏃舵憳鍑哄垎娴侀槦鍒楋紱
+// 路 鍋滄鍊欒瘖锛氬伐浣嶇姸鎬佷粛鏄� 20銆屽湪搴с�嶏紝鍙啓 clinic_room.stop_ready 骞舵憳鍑哄垎娴侀槦鍒椼��
+// 涓よ�呴兘**涓嶄細**寮哄埗瀹屾垚銆屽氨璇婁腑銆嶆偅鑰呫�佷篃**涓嶄細**娓呯┖銆屽�欒瘖涓�嶆偅鑰咃紱
+// 鍙彿鎺ュ彛锛坣extPatient锛変笉妫�鏌ヨ繖涓や釜鐘舵�侊紝鎵�浠ュ凡鏈夊�欒瘖浠嶅彲姝e父鍙彿銆�
const stopReady = ref<boolean>(false)
const stopReadyFlag = ref<boolean>(true) // 闃茶繛鐐�
diff --git a/src/views/ecg/doctor/components/BedSwitchSelect.vue b/src/views/ecg/doctor/components/BedSwitchSelect.vue
index 02e54ae..8e64266 100644
--- a/src/views/ecg/doctor/components/BedSwitchSelect.vue
+++ b/src/views/ecg/doctor/components/BedSwitchSelect.vue
@@ -16,6 +16,7 @@
import { useRouter } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import { RoomApi, RoomVO } from '@/api/ecg/room'
+import { DoctorApi } from '@/api/ecg/doctor'
import { useRoomStore } from '@/store/modules/room'
defineOptions({ name: 'BedSwitchSelect' })
@@ -46,28 +47,72 @@
const canOperate = computed(() => roomStore.getCanOperate)
const dropdownText = computed(() => {
if (!roomStore.getIsSetRoom || !roomStore.getViewText) return '閫夋嫨宸ヤ綅'
- return canOperate.value
- ? roomStore.getViewText
- : `鍥磋 ${roomStore.getViewText}`
+ const seatCount = roomStore.getMySeatCount
+ const suffix = seatCount > 1 ? `锛堟垜鐨勫伐浣� ${seatCount} 涓級` : ''
+ const base = canOperate.value ? roomStore.getViewText : `鍥磋 ${roomStore.getViewText}`
+ return `${base}${suffix}`
})
const isSameBed = (a?: { roomId?: any; bedNo?: any } | null, b?: RoomVO | null) =>
!!a && !!b && String(a.roomId) === String(b.roomId) && String(a.bedNo) === String(b.bedNo)
-const isMySeat = (bed: RoomVO) => isSameBed(roomStore.getCurrentSeat, bed)
-const isViewing = (bed: RoomVO) => isSameBed(roomStore.getRoom, bed)
+const isMySeat = (bed: RoomVO) => {
+ // 銆愭湰闇�姹偮蜂竴浜哄宸ヤ綅銆戞寜"鎴戠殑宸ヤ綅鍒楄〃"鍒ゆ柇锛岃�屼笉鏄崟涓� currentSeat
+ const seats = roomStore.getMySeats || []
+ if (seats.some((s) => isSameBed(s, bed))) return true
+ return isSameBed(roomStore.getCurrentSeat, bed)
+}
+/**
+ * 鏈〉鏄惁鍏佽**鍑虹幇/鎿嶄綔**璇ヤ綔涓氱被鍨嬬殑宸ヤ綅銆�
+ *
+ * 銆愬彛寰勭‘璁わ紙2026-11-06锛夈�戞瘡涓伐浣滃彴**鍙樉绀烘湰鍙板厑璁告搷浣滅殑浣滀笟绫诲瀷涓庤瘖瀹�**锛�
+ * 路 鍙彿妫�鏌ラ〉 鈫� opType=0锛堟鏌ワ級
+ * 路 棰嗙敤 / 瑁呮満椤� 鈫� 鏈〉涓嶆彁渚涘垏鎹紙`enabled=false`锛屽伐浣嶅浐瀹氾級
+ * 鍥犳璇ヨ繃婊ゅ悓鏃朵綔鐢ㄤ簬銆屾垜鐨勫伐浣� / 绌洪棽宸ヤ綅 / 浠栦汉鍗犵敤锛堝洿瑙偮锋帴绠★級銆嶄笁绫汇��
+ */
+const isOpAllowed = (bed: RoomVO) => {
+ const types = props.opTypes
+ if (!Array.isArray(types) || types.length === 0) return true
+ return types.some((t) => Number(t) === Number(bed.opType))
+}
+
+/** 鎴戠殑宸ヤ綅锛堜笅鎷夐噷"鎴戠殑宸ヤ綅"鍒嗙粍锛屾寜 roomId+bedNo 鍘婚噸锛涘悓鏍峰彧淇濈暀鏈彴鍏佽鐨勪綔涓氱被鍨嬶級 */
+const myBeds = computed(() => (roomStore.getMySeats || [])
+ .map((s) => ({
+ id: s.id ?? null,
+ roomId: s.roomId ?? null,
+ roomName: s.roomName ?? null,
+ bedNo: s.bedNo ?? null,
+ ip: s.ip ?? null,
+ status: s.status ?? null,
+ docId: s.docId ?? null,
+ docName: s.docName ?? null,
+ checkTypes: s.checkTypes ?? null,
+ opType: s.opType ?? null
+ } as RoomVO))
+ .filter((b) => isOpAllowed(b)))
+/** 鍏跺畠宸ヤ綅锛堟帓闄ゆ垜鐨勫伐浣嶏紱`beds` 宸插湪 loadBeds 閲屾寜浣滀笟绫诲瀷杩囨护锛� */
+const otherBeds = computed(() => beds.value.filter((b) => !isMySeat(b)))
+
/**
* 鎸� `opTypes` 杩囨护宸ヤ綅锛坣ull/绌� = 涓嶈繃婊わ級銆�
*
- * 銆愭湰娆¢渶姹傘�戝彨鍙锋鏌ラ〉鍙厑璁稿垏鍒�**妫�鏌ョ被**宸ヤ綅锛坥pType=0锛夛紱
- * 棰嗙敤/瑁呮満椤典笉鎻愪緵鍒囨崲锛坄enabled=false`锛夛紝姝ゅ嚱鏁板彧鏈嶅姟浜庡墠鑰呫��
+ * <p>銆愬彛寰� 2026-11-06 纭銆戞瘡涓伐浣滃彴**鍙樉绀烘湰鍙板厑璁告搷浣滅殑浣滀笟绫诲瀷涓庤瘖瀹�**锛�
+ * 鍙彿妫�鏌ラ〉鍙湅 `opType=0`锛堟鏌ワ級锛涢鐢�/瑁呮満椤典笉鎻愪緵鍒囨崲锛坄enabled=false`锛夈��
+ * 闈炴湰椤电被鍨嬬殑宸ヤ綅鏁存潯涓嶆樉绀猴紙杩炲洿瑙�/鎺ョ鍏ュ彛涔熶笉缁欙級锛岄伩鍏�"鍦ㄦ鏌ラ〉鎿嶄綔瑁呮満璇婂"銆�
*/
const filterBeds = (all: RoomVO[]): RoomVO[] => {
const types = props.opTypes
if (!Array.isArray(types) || types.length === 0) return all
return all.filter((b) => types.some((t) => Number(t) === Number(b.opType)))
}
+
+/** 鍏跺畠宸ヤ綅閲岀殑銆岀┖闂层�嶅伐浣嶏紙鐐瑰嚮 = 鍏ュ骇锛� */
+const freeBeds = computed(() => otherBeds.value.filter((b) => b.docId == null))
+/** 鍏跺畠宸ヤ綅閲岀殑銆岃浠栦汉鍗犵敤銆嶅伐浣嶏紙鍙洿瑙傘�佸彲鎺ョ锛夆�斺�� `beds` 宸叉寜浣滀笟绫诲瀷杩囨护 */
+const occupiedBeds = computed(() => otherBeds.value.filter((b) => b.docId != null))
+const isViewing = (bed: RoomVO) => isSameBed(roomStore.getRoom, bed)
/** 鍥哄畾宸ヤ綅鐨勫彧璇绘枃妗堬紙`enabled=false` 鏃舵樉绀猴級 */
const fixedText = computed(() => {
@@ -93,10 +138,9 @@
const arr = map[key]
if (Array.isArray(arr)) all.push(...arr)
}
- beds.value = all
- // 銆愭湰娆¢渶姹傘�戞寜浣滀笟绫诲瀷杩囨护"鍙垏鎹㈢殑宸ヤ綅"锛堝彨鍙锋鏌ラ〉鍙垪妫�鏌ョ被宸ヤ綅锛�
- const visible = filterBeds(all)
- beds.value = visible
+ // 銆愬彛寰� 2026-11-06 纭銆戞瘡涓伐浣滃彴鍙樉绀烘湰鍙板厑璁告搷浣滅殑浣滀笟绫诲瀷涓庤瘖瀹わ細
+ // 闈炴湰椤电被鍨嬶紙濡傛鏌ラ〉閲岀殑瑁呮満璇婂 opType=2锛�**鏁存潯涓嶆樉绀�**锛屽埌瀵瑰簲宸ヤ綔鍙�/閫夊伐浣嶉〉澶勭悊銆�
+ beds.value = filterBeds(all)
// 姝e湪鍥磋鏃堕『渚垮埛鏂�"涓讳汉鏄惁宸茬寮�"锛堝彧鎻愮ず锛屼笉鑷姩鎺ョ锛�
const cur = roomStore.getRoom
if (cur?.roomId != null && cur.bedNo) {
@@ -137,27 +181,95 @@
}
}
-/** 閫変腑涓�涓伐浣� */
-const onPick = async (bed: RoomVO) => {
- // 鈶� 鎴戠殑宸ヤ綅 鈫� 鍒囧洖鑷繁
- if (isMySeat(bed)) {
- await roomStore.setRoomInfoAction(bed)
- ElMessage.success(`宸插垏鍥炴垜鐨勫伐浣嶏細${bed.roomName || ''} ${bed.bedNo || ''}`)
+/**
+ * 銆愭湰闇�姹傘�戝垏鎹㈠伐浣嶅墠妫�鏌�"褰撳墠宸ヤ綅鏄惁杩樻湁灏辫瘖涓偅鑰�"銆�
+ *
+ * 涓轰粈涔堟彁绀猴細鍙彿閫昏緫鏄�屾湰宸ヤ綅宸叉湁灏辫瘖涓偅鑰呭氨涓嶅啀鍙笅涓�浣嶃�嶏紝
+ * 鍖荤敓鍒囪蛋鍚庤鎮h�呬細涓�鐩村仠鍦ㄥ氨璇婁腑锛堝ぇ灞忎篃涓�鐩存樉绀猴級锛屾墍浠ュ垏鎹㈠墠瑕佹彁閱掋��
+ *
+ * @returns true 琛ㄧず鍙互缁х画鍒囨崲锛堟棤灏辫瘖涓偅鑰咃紝鎴栫敤鎴风‘璁ゅ垏鎹級
+ */
+const confirmSwitchWhenOnstage = async (): Promise<boolean> => {
+ const cur = roomStore.getRoom
+ if (!cur || cur.roomId == null || !cur.bedNo || !roomStore.getCanOperate) {
+ return true // 涓嶆槸"鑷繁鐨勫伐浣�"锛堝洿瑙傦級鈫� 涓嶆彁绀�
+ }
+ try {
+ const list: any = await DoctorApi.getToBeCheckedPatientList({
+ roomId: cur.roomId,
+ bedNo: cur.bedNo
+ } as any)
+ const onstage = (Array.isArray(list) ? list : []).find((p: any) => Number(p?.status) === 30)
+ if (!onstage) return true
+ await ElMessageBox.confirm(
+ `褰撳墠宸ヤ綅銆�${cur.roomName || ''} 路 ${cur.bedNo}銆嶈繕鏈夊氨璇婁腑鎮h�咃紙${onstage.patName || onstage.patId}锛夈�俓n` +
+ `鍒囨崲鍚庤鎮h�呬粛鍋滅暀鍦ㄣ�屽氨璇婁腑銆嶏紝涓旀湰宸ヤ綅涓嶄細鍐嶅彨涓嬩竴浣嶃�傛槸鍚︾户缁垏鎹紵`,
+ '鍒囨崲宸ヤ綅',
+ { confirmButtonText: '缁х画鍒囨崲', cancelButtonText: '鐣欏湪鏈伐浣�', type: 'warning' }
+ )
+ return true
+ } catch (e: any) {
+ // 鐢ㄦ埛鐐�"鐣欏湪鏈伐浣�"锛圗lMessageBox reject锛� 鈫� 涓嶅垏鎹紱鏌ヨ寮傚父 鈫� 涓嶉樆鏂�
+ if (e === 'cancel' || e === 'close') return false
+ console.warn('[BedSwitchSelect] 鏌ヨ褰撳墠宸ヤ綅灏辫瘖涓偅鑰呭け璐ワ紙涓嶉樆鏂垏鎹級', e)
+ return true
+ }
+}
+
+/** 銆愭湰闇�姹偮锋帴鐝嚜鍔╂帴绠°�戞帴绠�"鍒汉鍗犵敤"鐨勫伐浣� */
+const takeOverBed = async (bed: RoomVO) => {
+ const bedText = `${bed.roomName || ''} 路 ${bed.bedNo || ''}`
+ const owner = bed.docName || '鍏朵粬鍖荤敓'
+ try {
+ await ElMessageBox.confirm(
+ `宸ヤ綅銆�${bedText}銆嶅綋鍓嶇敱銆�${owner}銆嶅崰鐢ㄣ�俓n纭鎺ョ锛熸帴绠″悗銆�${owner}銆嶅皢琚己鍒剁搴э紙鍏堕〉闈細鎻愮ず閲嶆柊灏卞潗锛夈�俙,
+ '鎺ョ宸ヤ綅',
+ { confirmButtonText: '纭鎺ョ', cancelButtonText: '鍙栨秷', type: 'warning' }
+ )
+ } catch {
return
}
- // 鈶� 绌洪棽 鈫� 璇㈤棶鍚庡叆搴�
+ const ok = await roomStore.takeOverBed(bed.roomId, bed.bedNo)
+ if (!ok) {
+ ElMessage({ message: '鎺ョ澶辫触锛岃绋嶅悗閲嶈瘯鎴栬仈绯荤鐞嗗憳', type: 'error', duration: 4000 })
+ return
+ }
+ ElMessage.success(`宸叉帴绠″伐浣嶏細${bedText}`)
+ await loadBeds()
+}
+
+/** 閫変腑涓�涓伐浣嶏紙涔熷吋瀹�"鎺ョ"杩欑浼懡浠わ級 */
+const onPick = async (cmd: any) => {
+ // 鈸� 鎺ョ鍛戒护锛堜笅鎷夐噷"鎺ョ"閭d竴椤逛紶鐨勬槸 { takeover: bed }锛�
+ if (cmd && cmd.takeover) {
+ await takeOverBed(cmd.takeover as RoomVO)
+ return
+ }
+ const bed = cmd as RoomVO
+ if (!bed) return
+ // 鐐圭殑鏄綋鍓嶆鍦ㄧ湅鐨勫伐浣� 鈫� 鏃犻渶鍒囨崲
+ if (isViewing(bed)) return
+
+ // 鈶� 鎴戠殑宸ヤ綅锛堝宸ヤ綅涔嬩竴锛夆啋 鍙垏鎹㈡煡鐪嬬洰鏍囷紝涓嶉噸鍏ュ骇銆佷笉閲婃斁鍏跺畠宸ヤ綅
+ if (isMySeat(bed)) {
+ if (!(await confirmSwitchWhenOnstage())) return
+ await roomStore.setRoomInfoAction(bed)
+ ElMessage.success(`宸插垏鎹㈠埌鎴戠殑宸ヤ綅锛�${bed.roomName || ''} ${bed.bedNo || ''}`)
+ return
+ }
+ // 鈶� 绌洪棽 鈫� 璇㈤棶鍚庡叆搴э紙澶氬伐浣嶏細**鏂板**涓�涓垜鐨勫伐浣嶏紝涓嶉噴鏀惧叾瀹冨伐浣嶏級
if (bed.docId == null) {
- const mine = roomStore.getSeatText
try {
await ElMessageBox.confirm(
`鍏ュ骇鍒般��${bed.roomName || ''} / ${bed.bedNo || ''}銆嶏紵` +
- (mine ? `锛堜細閫�鍑哄師鏉ョ殑銆�${mine}銆嶏級` : ''),
+ `锛堝皢鏂板涓�涓�"鎴戠殑宸ヤ綅"锛屼笉閲婃斁鍏跺畠宸ヤ綅锛塦,
'鍏ュ骇纭',
{ confirmButtonText: '鍏ュ骇', cancelButtonText: '鍙栨秷', type: 'warning' }
)
} catch {
return
}
+ if (!(await confirmSwitchWhenOnstage())) return
const ok = await roomStore.seatRoom(bed)
if (!ok) {
ElMessage({ message: '鍏ュ骇澶辫触锛氳宸ヤ綅鍙兘宸茶浠栦汉鍗犵敤锛屾垨鐘舵�佷笉鍏佽锛堝凡鍏抽棴锛�', type: 'warning', duration: 4000 })
@@ -168,6 +280,7 @@
return
}
// 鈶� 宸茶鍒汉鍗犵敤 鈫� 鍥磋锛堝彧璇伙級
+ if (!(await confirmSwitchWhenOnstage())) return
await roomStore.setViewTargetAction(bed, bed.docName)
ElMessage({
message: `姝e湪鍥磋銆�${bed.roomName || ''} / ${bed.bedNo || ''}銆嶏紙涓讳汉 ${bed.docName || '鍏朵粬鍖荤敓'}锛夛紝鍙鏌ョ湅`,
@@ -209,14 +322,54 @@
</el-button>
<template #dropdown>
<el-dropdown-menu>
+ <!-- 銆愭湰闇�姹偮蜂竴浜哄宸ヤ綅銆戞垜鐨勫伐浣嶅垎缁勶細鍙竴閿垏鎹紙涓嶉噸鍏ュ骇銆佷笉閲婃斁鍏跺畠宸ヤ綅锛� -->
+ <el-dropdown-item v-if="myBeds.length > 0" disabled class="bed-switch__group">
+ 鎴戠殑宸ヤ綅锛坽{ myBeds.length }} 涓級
+ </el-dropdown-item>
<el-dropdown-item
- v-for="bed in beds"
- :key="`${bed.roomId}-${bed.bedNo}`"
+ v-for="bed in myBeds"
+ :key="`mine-${bed.roomId}-${bed.bedNo}`"
:command="bed"
:class="{ 'is-current': isViewing(bed) }"
>
{{ bedLabel(bed) }}
</el-dropdown-item>
+
+ <!-- 绌洪棽宸ヤ綅锛堢偣鍑� = 鍏ュ骇锛屾柊澧炰竴涓�"鎴戠殑宸ヤ綅"锛� -->
+ <el-dropdown-item v-if="freeBeds.length > 0" disabled class="bed-switch__group">
+ 绌洪棽宸ヤ綅锛堝彲鍏ュ骇锛�
+ </el-dropdown-item>
+ <el-dropdown-item
+ v-for="bed in freeBeds"
+ :key="`free-${bed.roomId}-${bed.bedNo}`"
+ :command="bed"
+ :class="{ 'is-current': isViewing(bed) }"
+ >
+ {{ bedLabel(bed) }}
+ </el-dropdown-item>
+
+ <!--
+ 銆愬彛寰� 2026-11-06銆戞瘡涓伐浣滃彴鍙樉绀烘湰鍙板厑璁告搷浣滅殑浣滀笟绫诲瀷/璇婂锛�
+ 闈炴湰椤典綔涓氱被鍨嬬殑宸ヤ綅锛堝妫�鏌ラ〉閲岀殑棰嗙敤/瑁呮満璇婂锛�**鏁存潯涓嶆樉绀�**锛�
+ 闇�瑕佸幓瀵瑰簲宸ヤ綔鍙帮紙棰嗙敤/瑁呮満椤碉級鎴栥�岄�夊伐浣嶉〉銆嶆煡鐪嬨��
+ -->
+ <!--
+ 銆愭湰闇�姹傘�戣浠栦汉鍗犵敤鐨勫伐浣嶏細**鍥磋 / 鎺ョ 涓や釜鍏ュ彛閮戒繚鐣�**
+ 路 銆屽洿瑙傘��= 鍒囨崲鏌ョ湅锛堝彧璇伙級锛岀敤浜庣湅鍒汉鍙彿鎯呭喌锛�
+ 路 銆屾帴绠°��= 涓婁竴鐝尰鐢熷繕璁扮搴ф椂锛屾妸宸ヤ綅寮哄埗杞粰鎴戙��
+ -->
+ <el-dropdown-item v-if="occupiedBeds.length > 0" disabled class="bed-switch__group">
+ 浠栦汉鍗犵敤锛堝彲鍥磋 / 鍙帴绠★級
+ </el-dropdown-item>
+ <template v-for="bed in occupiedBeds" :key="`occ-${bed.roomId}-${bed.bedNo}`">
+ <el-dropdown-item :command="bed" :class="{ 'is-current': isViewing(bed) }">
+ 鍥磋銆寋{ bed.roomName || '' }} 路 {{ bed.bedNo }}銆嶏紙{{ bed.docName || '鍏朵粬鍖荤敓' }}锛�
+ </el-dropdown-item>
+ <el-dropdown-item :command="{ takeover: bed }" class="bed-switch__takeover">
+ 鎺ョ銆寋{ bed.roomName || '' }} 路 {{ bed.bedNo }}銆嶏紙{{ bed.docName || '鍏朵粬鍖荤敓' }}锛�
+ </el-dropdown-item>
+ </template>
+
<el-dropdown-item v-if="beds.length === 0" disabled>鏆傛棤宸插紑鏀惧伐浣�</el-dropdown-item>
<el-dropdown-item divided @click="router.push({ path: '/roomselect' })">
鍘汇�岄�夊伐浣嶉〉銆嶁��
@@ -250,6 +403,17 @@
color: var(--el-text-color-secondary);
}
+/* 銆愭湰闇�姹偮蜂竴浜哄宸ヤ綅銆戜笅鎷夊垎缁勬爣棰� */
+:deep(.el-dropdown-menu__item.bed-switch__group) {
+ font-size: 12px;
+ color: var(--el-text-color-secondary);
+ cursor: default;
+}
+
+/* 銆愭湰闇�姹偮锋帴鐝嚜鍔╂帴绠°�戞帴绠¢」鐢ㄨ绀鸿壊锛岄伩鍏嶄笌"鍥磋"娣锋穯 */
+:deep(.el-dropdown-menu__item.bed-switch__takeover) {
+ color: var(--el-color-warning);
+}
:deep(.el-dropdown-menu__item.is-current) {
color: var(--el-color-primary);
font-weight: 600;
diff --git a/src/views/ecg/doctor/components/DevInstallPanel.vue b/src/views/ecg/doctor/components/DevInstallPanel.vue
index fbd7d95..7ba56dd 100644
--- a/src/views/ecg/doctor/components/DevInstallPanel.vue
+++ b/src/views/ecg/doctor/components/DevInstallPanel.vue
@@ -2,19 +2,19 @@
<el-form class="patient-compact-form" ref="formRef" :model="formData" :rules="formRules" label-width="100px" v-loading="formLoading">
<!-- ===== 缂栬緫鍖猴紙闇�瑕佸綍鍏ョ殑瀛楁锛�===== -->
<el-row :gutter="20">
- <el-col :span="6">
+ <el-col :xs="24" :sm="12" :md="12" :lg="6">
<el-form-item label="妫�鏌ラ」鐩�" prop="">
{{ getCheckTypeName(formData.checkType) }}
</el-form-item>
</el-col>
- <el-col :span="12">
+ <el-col :xs="24" :sm="24" :md="12" :lg="12">
<el-form-item label="鎮h�呯紪鍙�" prop="patId">
<el-input v-model="formData.patId" placeholder="璇疯緭鍏ユ偅鑰呯紪鍙�" @input="getRentInfoByPatId" />
- <Barcode v-if="displayBarCode" :value="displayBarCode" :width=100 />
- <el-button @click="copyBarcode()">澶嶅埗</el-button>
+ <Barcode v-if="showBarCode" :value="barcodeContent" :width=100 />
+ <el-button v-if="showCopyButton" :disabled="!barcodeContent" @click="copyBarcode()">澶嶅埗</el-button>
</el-form-item>
</el-col>
- <el-col :span="6">
+ <el-col :xs="24" :sm="12" :md="12" :lg="6">
<el-form-item label="璁惧缂栧彿" prop="devId">
<el-input v-model="formData.devId" placeholder="璇疯緭鍏ヨ澶囩紪鍙�" @input="getDevInfo" />
</el-form-item>
@@ -171,7 +171,6 @@
const formRef = ref() // 琛ㄥ崟 Ref
-const displayBarCode = ref<string>()
const formLoading = ref(false) // 琛ㄥ崟鐨勫姞杞戒腑锛�1锛変慨鏀规椂鐨勬暟鎹姞杞斤紱2锛夋彁浜ょ殑鎸夐挳绂佺敤
@@ -234,7 +233,6 @@
formData.value.doctorAdviceNo = queueVO?.doctorAdviceNo
formData.value.patIdentityId = queueVO?.patIdentityId
getReadyRentInfo(formData.value) // 鑾峰彇棰嗙敤淇℃伅
- copyBarcode()
}
defineExpose({ setPatient, getList: () => getList() }) // 鎻愪緵 setPatient 鏂规硶锛岀敤浜庤缃偅鑰�
@@ -344,7 +342,6 @@
formData.value.patId = tempPatId;
getReadyRentInfo(formData.value)
- copyBarcode()
}
// 鑾峰彇鎮h�呯殑棰嗙敤淇℃伅
@@ -474,46 +471,45 @@
getList()
}
-const getDisplayBarcode = (): string => {
- if (!formData.value.checkType)
- return ""
+/**
+ * 銆愭湰闇�姹傘�戞偅鑰呮潯鐮佸彛寰勶紙闂ㄨ瘖/鎬ヨ瘖/浣撴 = 灏辫瘖娴佹按鍙凤紱浣忛櫌涓嶅嚭鏉$爜锛屽彧鐣欍�屽鍒躲�嶏級
+ *
+ * 路 闂ㄨ瘖(1) / 鎬ヨ瘖(2) / 浣撴(4) 鈫� 鏉$爜鍐呭 = **灏辫瘖娴佹按鍙�**锛坋pisodeId锛�
+ * 路 浣忛櫌(3) 鈫� **涓嶆樉绀烘潯鐮�**锛屽彧淇濈暀銆屽鍒躲�嶆寜閽紙澶嶅埗鍐呭鍚屾牱鏄氨璇婃祦姘村彿锛�
+ * 路 銆屽鍒躲�嶆寜閽笌鏉$爜涓�鑷达細鍚屽彈銆屾鏌ョ被鍨� 鈫� 鎮h�呮潯鐮佹樉绀恒�嶉厤缃帶鍒�
+ * 锛堣妫�鏌ョ被鍨嬫湭鍕鹃�夎繖涓偅鑰呮潵婧愭椂锛屾潯鐮佸拰澶嶅埗鎸夐挳閮戒笉鏄剧ず锛�
+ */
+const patSourceValue = computed<number | null>(() => {
+ const source = formData.value.patDetails?.source ?? formData.value.patSrc
+ return source === null || source === undefined || source === '' ? null : Number(source)
+})
- // 銆愭湰娆′慨澶嶃�戙�屾偅鑰呮潯鐮佹樉绀恒�嶆湭閰嶇疆锛坣ull/绌猴級鈫� 涓嶆樉绀猴紙鎸夌幇鍦虹‘璁ゅ彛寰勶級
- const displayBarcode: number[] | undefined = checkTypeStore.getCheckTypeDispBarCode(formData.value.checkType!)
- if (displayBarcode == null || displayBarcode.length === 0)
- return ""
+/** 鏄惁閫氳繃浜嗐�屾偅鑰呮潯鐮佹樉绀恒�嶉厤缃紙鍕鹃�変簡褰撳墠鎮h�呮潵婧愶級 */
+const barcodeEnabled = computed<boolean>(() => {
+ if (formData.value.checkType == null) return false
+ const displayBarcode: number[] | undefined = checkTypeStore.getCheckTypeDispBarCode(formData.value.checkType)
+ if (displayBarcode == null || displayBarcode.length === 0) return false
+ const patSource = patSourceValue.value
+ if (patSource == null) return false
+ return displayBarcode.map(Number).includes(patSource)
+})
- // 銆愭湰娆′慨澶嶃�戞潵婧愪紭鍏堝彇 patDetails.source锛岀己澶辨椂鍥為��鍒板钩閾虹殑 patSrc
- // 锛堝師鏉ョ洿鎺ュ彇 patDetails.source锛宲atDetails 缂哄け鏃� `.includes` 杩樹細鎶涘紓甯革級
- const patSource = formData.value.patDetails?.source ?? formData.value.patSrc
- if (patSource == null)
- return ""
- if (!displayBarcode.map(Number).includes(Number(patSource)))
- return ""
+/** 鏉$爜 / 澶嶅埗鐨勫唴瀹癸細缁熶竴鍙栥�屽氨璇婃祦姘村彿銆� */
+const barcodeContent = computed<string>(() =>
+ barcodeEnabled.value ? (formData.value.episodeId ?? '') : ''
+)
- return getBarcode()
-}
+/** 鏄惁鏄剧ず鏉$爜锛氫綇闄紙鏉ユ簮 3锛変笉鏄剧ず锛涘唴瀹逛负绌烘椂涔熶笉鏄剧ず */
+const showBarCode = computed<boolean>(
+ () => barcodeEnabled.value && patSourceValue.value !== 3 && barcodeContent.value !== ''
+)
-const getBarcode = (): string => {
- if (!formData.value.checkType)
- return ""
-
- const patSource = formData.value.patDetails?.source ?? formData.value.patSrc
- if (patSource == null)
- return ""
-
- // 闂ㄨ瘖/鎬ヨ瘖 鈫� 鐢宠鍗曞彿锛涗綇闄�/浣撴 鈫� 灏辫瘖娴佹按鍙�
- if (1 === Number(patSource) || 2 === Number(patSource))
- return formData.value.applyNo ?? ""
- else if (3 === Number(patSource) || 4 === Number(patSource))
- return formData.value.episodeId ?? ""
-
- return ""
-}
+/** 鏄惁鏄剧ず銆屽鍒躲�嶆寜閽細涓庢潯鐮佷竴鑷达紙鍚屽彈閰嶇疆鎺у埗锛� */
+const showCopyButton = computed<boolean>(() => barcodeEnabled.value)
const copyBarcode = async () => {
- displayBarCode.value = getDisplayBarcode()
- await navigator.clipboard.writeText(getBarcode());
+ if (!barcodeContent.value) return
+ await navigator.clipboard.writeText(barcodeContent.value)
}
/** 鍒濆鍖� **/
diff --git a/src/views/ecg/doctor/components/DevReadyPanel.vue b/src/views/ecg/doctor/components/DevReadyPanel.vue
index e740c11..07a620e 100644
--- a/src/views/ecg/doctor/components/DevReadyPanel.vue
+++ b/src/views/ecg/doctor/components/DevReadyPanel.vue
@@ -14,19 +14,19 @@
>
<!-- ===== 缂栬緫鍖猴紙闇�瑕佸綍鍏ョ殑瀛楁锛�===== -->
<el-row :gutter="20">
- <el-col :span="6">
+ <el-col :xs="24" :sm="12" :md="12" :lg="6">
<el-form-item label="妫�鏌ラ」鐩�" prop="">
{{getCheckTypeName(formData.checkType)}}
</el-form-item>
</el-col>
- <el-col :span="12">
+ <el-col :xs="24" :sm="24" :md="12" :lg="12">
<el-form-item label="鎮h�呯紪鍙�" prop="patId">
<el-input v-model="formData.patId" placeholder="璇疯緭鍏ユ偅鑰呯紪鍙�" @input="getRentInfoByPatId" />
- <Barcode v-if="displayBarCode" :value="displayBarCode" :width=100 />
- <el-button @click="copyBarcode()">澶嶅埗</el-button>
+ <Barcode v-if="showBarCode" :value="barcodeContent" :width=100 />
+ <el-button v-if="showCopyButton" :disabled="!barcodeContent" @click="copyBarcode()">澶嶅埗</el-button>
</el-form-item>
</el-col>
- <el-col :span="6">
+ <el-col :xs="24" :sm="12" :md="12" :lg="6">
<el-form-item label="璁惧缂栧彿" prop="devId">
<el-input v-model="formData.devId" placeholder="璇疯緭鍏ヨ澶囩紪鍙�" @input="getDevInfo"/>
</el-form-item>
@@ -258,7 +258,6 @@
state: undefined,
})
-const displayBarCode = ref<string> ()
const getRentInfoByPatId = () => {
const tempPatId = formData.value.patId;
@@ -268,7 +267,6 @@
formData.value.patId = tempPatId;
getFreeRentInfo(formData.value)
- copyBarcode()
}
// 鏍规嵁鎮h�呮垨璁惧, 鑾峰彇 Free鐨勭璧�
@@ -437,7 +435,6 @@
formData.value.doctorAdviceNo = queueVO?.doctorAdviceNo
formData.value.patIdentityId = queueVO?.patIdentityId
getFreeRentInfo(formData.value) // 寰呮鏌ョ殑淇℃伅 @ dev_rent 琛�
- copyBarcode()
}
defineExpose({ setPatient, getList: () => getList() }) // 鎻愪緵 setPatient 鏂规硶锛岀敤浜庤缃偅鑰�
@@ -642,51 +639,45 @@
/**
* 鑾峰彇鏉″舰鐮侊紝鏄剧ず涓庡惁 鍚屼竴涓��
*/
-const getDisplayBarcode = (): string => {
- if (formData.value.checkType == null)
- return ""
+/**
+ * 銆愭湰闇�姹傘�戞偅鑰呮潯鐮佸彛寰勶紙闂ㄨ瘖/鎬ヨ瘖/浣撴 = 灏辫瘖娴佹按鍙凤紱浣忛櫌涓嶅嚭鏉$爜锛屽彧鐣欍�屽鍒躲�嶏級
+ *
+ * 路 闂ㄨ瘖(1) / 鎬ヨ瘖(2) / 浣撴(4) 鈫� 鏉$爜鍐呭 = **灏辫瘖娴佹按鍙�**锛坋pisodeId锛�
+ * 路 浣忛櫌(3) 鈫� **涓嶆樉绀烘潯鐮�**锛屽彧淇濈暀銆屽鍒躲�嶆寜閽紙澶嶅埗鍐呭鍚屾牱鏄氨璇婃祦姘村彿锛�
+ * 路 銆屽鍒躲�嶆寜閽笌鏉$爜涓�鑷达細鍚屽彈銆屾鏌ョ被鍨� 鈫� 鎮h�呮潯鐮佹樉绀恒�嶉厤缃帶鍒�
+ * 锛堣妫�鏌ョ被鍨嬫湭鍕鹃�夎繖涓偅鑰呮潵婧愭椂锛屾潯鐮佸拰澶嶅埗鎸夐挳閮戒笉鏄剧ず锛�
+ */
+const patSourceValue = computed<number | null>(() => {
+ const source = formData.value.patDetails?.source ?? formData.value.patSrc
+ return source === null || source === undefined || source === '' ? null : Number(source)
+})
- // 銆愭湰娆′慨澶嶃�戙�屾偅鑰呮潯鐮佹樉绀恒�嶆湭閰嶇疆锛坣ull/绌猴級鈫� 涓嶆樉绀猴紙鎸夌幇鍦虹‘璁ゅ彛寰勶級
+/** 鏄惁閫氳繃浜嗐�屾偅鑰呮潯鐮佹樉绀恒�嶉厤缃紙鍕鹃�変簡褰撳墠鎮h�呮潵婧愶級 */
+const barcodeEnabled = computed<boolean>(() => {
+ if (formData.value.checkType == null) return false
const displayBarcode: number[] | undefined = checkTypeStore.getCheckTypeDispBarCode(formData.value.checkType)
- if (displayBarcode == null || displayBarcode.length === 0)
- return ""
+ if (displayBarcode == null || displayBarcode.length === 0) return false
+ const patSource = patSourceValue.value
+ if (patSource == null) return false
+ return displayBarcode.map(Number).includes(patSource)
+})
- // 銆愭湰娆′慨澶嶃�戞潵婧愪紭鍏堝彇 patDetails.source锛岀己澶辨椂鍥為��鍒板钩閾虹殑 patSrc
- const patSource = formData.value.patDetails?.source ?? formData.value.patSrc
- if (patSource == null)
- return ""
+/** 鏉$爜 / 澶嶅埗鐨勫唴瀹癸細缁熶竴鍙栥�屽氨璇婃祦姘村彿銆� */
+const barcodeContent = computed<string>(() =>
+ barcodeEnabled.value ? (formData.value.episodeId ?? '') : ''
+)
- if (!displayBarcode.map(Number).includes(Number(patSource)))
- return ""
+/** 鏄惁鏄剧ず鏉$爜锛氫綇闄紙鏉ユ簮 3锛変笉鏄剧ず锛涘唴瀹逛负绌烘椂涔熶笉鏄剧ず */
+const showBarCode = computed<boolean>(
+ () => barcodeEnabled.value && patSourceValue.value !== 3 && barcodeContent.value !== ''
+)
- return getBarcode()
-}
-
-const getBarcode = (): string => {
- if (formData.value.checkType == null)
- return ""
-
- const patSource = formData.value.patDetails?.source ?? formData.value.patSrc
- if (patSource == null)
- return ""
-
- // 闂ㄨ瘖/鎬ヨ瘖 鈫� 鐢宠鍗曞彿锛涗綇闄�/浣撴 鈫� 灏辫瘖娴佹按鍙�
- if (1 === Number(patSource) || 2 === Number(patSource))
- return formData.value.applyNo??""
- else if (3 === Number(patSource) || 4 === Number(patSource))
- return formData.value.episodeId??""
-
- return ""
-}
+/** 鏄惁鏄剧ず銆屽鍒躲�嶆寜閽細涓庢潯鐮佷竴鑷达紙鍚屽彈閰嶇疆鎺у埗锛� */
+const showCopyButton = computed<boolean>(() => barcodeEnabled.value)
const copyBarcode = async () => {
- displayBarCode.value = getDisplayBarcode()
-
- const barCode = getBarcode()
- if (isStringEmpty(barCode))
- return
-
- await navigator.clipboard.writeText( barCode );
+ if (!barcodeContent.value) return
+ await navigator.clipboard.writeText(barcodeContent.value)
}
/** 鍒濆鍖� **/
diff --git a/src/views/ecg/doctor/components/PatientInfoBlock.vue b/src/views/ecg/doctor/components/PatientInfoBlock.vue
index 84d8aed..e002faa 100644
--- a/src/views/ecg/doctor/components/PatientInfoBlock.vue
+++ b/src/views/ecg/doctor/components/PatientInfoBlock.vue
@@ -55,7 +55,15 @@
* 鏄剧ず `-`锛屽睘棰勬湡銆�
*/
showAdviceNo?: boolean
- /** 姣忓垪鏍呮牸瀹藉害锛堥粯璁� 6 = 涓�琛� 4 涓級 */
+ /**
+ * 銆愬垎杈ㄧ巼鑷�傚簲銆�**鈮�1200px** 鏃舵瘡鍒楃殑鏍呮牸瀹藉害锛堥粯璁� 6 = 涓�琛� 4 涓級銆�
+ *
+ * 绐勫睆浼氳嚜鍔ㄩ檷绾э紝閬垮厤鍖荤敓鐢佃剳鍒嗚鲸鐜囦笉鍚屽鑷村瓧娈垫尋鎴愪竴鏉$紳锛�
+ * 路 鈮�1200px锛坙g锛� 鈫� 鐢ㄦ湰鍙傛暟锛堥粯璁� 6锛屼竴琛� 4 涓級
+ * 路 992~1199锛坢d锛� 鈫� 12锛屼竴琛� 2 涓�
+ * 路 768~991锛坰m锛� 鈫� 12锛屼竴琛� 2 涓�
+ * 路 <768锛坸s锛� 鈫� 24锛屼竴琛� 1 涓�
+ */
span?: number
}>()
@@ -125,21 +133,21 @@
</div>
<el-row :gutter="20">
- <el-col :span="colSpan">
+ <el-col :xs="24" :sm="12" :md="12" :lg="colSpan">
<el-form-item label="濮撳悕">
{{ d.patName || '-' }}
</el-form-item>
</el-col>
- <el-col :span="colSpan">
+ <el-col :xs="24" :sm="12" :md="12" :lg="colSpan">
<el-form-item label="灏辫瘖鍙�">
{{ d.episodeId || '-' }}
</el-form-item>
</el-col>
- <el-col v-if="showSeqNum" :span="colSpan">
+ <el-col v-if="showSeqNum" :xs="24" :sm="12" :md="12" :lg="colSpan">
<el-form-item label="鎺掗槦搴忓彿">
{{ seqNumText }}
</el-form-item>
- </el-col><el-col :span="colSpan">
+ </el-col><el-col :xs="24" :sm="12" :md="12" :lg="colSpan">
<!-- 鏍囩鐢便�屽氨璇婂崱鍙枫�嶆敼涓恒�岄棬璇婂彿銆嶏紙缁忕‘璁わ紝璇﹁銆婇儴缃叉竻鍗曘��5.1锛夛細
HIS 鍦ㄥ崱鍙锋Ы浣嶄紶绌猴紝medical_card 鍏ㄥ簱 159,116 琛屾棤涓�闈炵┖锛�
璇ヤ綅缃疄闄呭睍绀� outpatient_no銆俢ardNo.from 鏍囨敞鍊肩殑鐪熷疄鏉ユ簮锛�
@@ -150,34 +158,34 @@
{{ cardNo.from }}
</el-tag>
</el-form-item>
- </el-col> <el-col :span="colSpan">
+ </el-col> <el-col :xs="24" :sm="12" :md="12" :lg="colSpan">
<el-form-item label="鐘舵��">
<dict-tag v-if="d.status !== undefined && d.status !== null && statusDict" :type="statusDict"
:value="d.status" />
<span v-else>-</span>
</el-form-item>
</el-col>
- <el-col :span="colSpan">
+ <el-col :xs="24" :sm="12" :md="12" :lg="colSpan">
<el-form-item label="鐢宠缂栧彿">
{{ d.applyNo || '-' }}
</el-form-item>
- </el-col><el-col :span="colSpan">
+ </el-col><el-col :xs="24" :sm="12" :md="12" :lg="colSpan">
<el-form-item label="椤圭洰">
{{ checkType ? getCheckTypeName(checkType) : '-' }}
</el-form-item>
</el-col>
- <el-col :span="colSpan">
+ <el-col :xs="24" :sm="12" :md="12" :lg="colSpan">
<el-form-item label="澶氳��">
<dict-tag :type="DICT_TYPE.ECG_TOLERANCE" :value="d.tolerance ?? 0" />
</el-form-item>
- </el-col><el-col :span="colSpan">
+ </el-col><el-col :xs="24" :sm="12" :md="12" :lg="colSpan">
<el-form-item label="鏉ユ簮">
<dict-tag v-if="source !== undefined" :type="DICT_TYPE.ECG_PAT_SOURCE" :value="source" />
<span v-else>-</span>
</el-form-item>
</el-col>
- <el-col :span="colSpan">
+ <el-col :xs="24" :sm="12" :md="12" :lg="colSpan">
<el-form-item label="鎬у埆">
<!-- 1 鐢� / 2 濂筹紱0 鎴栫己澶憋紙HIS 鏈彁渚涳紝瀹炴祴搴撲腑鏈� 2123 琛� = 0锛夋樉绀�"鏈煡"銆�
娉ㄦ剰涓嶈兘鐩存帴鎶� 0 浜ょ粰 dict-tag 鈥斺�� 瀛楀吀閲屾病鏈� 0 杩欎竴椤癸紝浼氭覆鏌撴垚绌虹櫧銆� -->
@@ -186,53 +194,53 @@
<span v-else>鏈煡</span>
</el-form-item>
</el-col>
- <el-col :span="colSpan">
+ <el-col :xs="24" :sm="12" :md="12" :lg="colSpan">
<el-form-item label="鍑虹敓鏃ユ湡">
{{ formatDateOnly(d.patBirthday) || '-' }}
</el-form-item>
</el-col>
- <el-col :span="colSpan">
+ <el-col :xs="24" :sm="12" :md="12" :lg="colSpan">
<el-form-item label="骞撮緞">
{{ formatAge(d.patBirthday) || '-' }}
</el-form-item>
</el-col>
- <el-col :span="colSpan">
+ <el-col :xs="24" :sm="12" :md="12" :lg="colSpan">
<el-form-item label="鎮h�呯數璇�">
{{ phone }}
</el-form-item>
</el-col>
- <el-col :span="colSpan">
+ <el-col :xs="24" :sm="12" :md="12" :lg="colSpan">
<el-form-item label="鐥呭尯">
{{ ward }}
</el-form-item>
</el-col>
- <el-col :span="colSpan">
+ <el-col :xs="24" :sm="12" :md="12" :lg="colSpan">
<el-form-item label="鐥呭簥鍙�">
{{ patBed }}
</el-form-item>
</el-col>
- <el-col :span="colSpan">
+ <el-col :xs="24" :sm="12" :md="12" :lg="colSpan">
<el-form-item label="鐧昏鏃堕棿">
{{ formatDateTime(d.registerDate) || '-' }}
</el-form-item>
- </el-col><el-col :span="colSpan">
+ </el-col><el-col :xs="24" :sm="12" :md="12" :lg="colSpan">
<el-form-item label="寮�鍗曞尰甯�">
{{ d.doctor || '-' }}
</el-form-item>
</el-col>
- <el-col :span="colSpan">
+ <el-col :xs="24" :sm="12" :md="12" :lg="colSpan">
<el-form-item label="寮�鍗曟棩鏈�">
{{ formatDateTime(d.doctorTime) || '-' }}
</el-form-item>
</el-col>
- <el-col :span="colSpan">
+ <el-col :xs="24" :sm="12" :md="12" :lg="colSpan">
<el-form-item label="璺濅粖澶╂暟">
{{ formatDaysFromOrder(d.doctorTime) || '-' }}
</el-form-item>
</el-col>
- <el-col v-if="showAdvice" :span="colSpan">
+ <el-col v-if="showAdvice" :xs="24" :sm="12" :md="12" :lg="colSpan">
<el-form-item label="鍖诲槺鍙�">
{{ d.doctorAdviceNo || '-' }}
</el-form-item>
diff --git a/src/views/ecg/doctor/components/RoutinePanel.vue b/src/views/ecg/doctor/components/RoutinePanel.vue
index de37be3..bdeb2b1 100644
--- a/src/views/ecg/doctor/components/RoutinePanel.vue
+++ b/src/views/ecg/doctor/components/RoutinePanel.vue
@@ -1,43 +1,84 @@
<!-- 甯歌妫�鏌� 鍖荤敓鐣岄潰-->
<template>
<el-form class="patient-compact-form" ref="formRef" :model="formData" :rules="formRules" label-width="100px" v-loading="formLoading">
+ <!--
+ 銆愭湰闇�姹傘�戠揣鎬ュ姞鍋氭搷浣滄彁绀猴紙缂栬緫鍖轰笂鏂癸紝甯搁┗锛�
+ 绱ф�ョ梾浜轰笉鎺掗槦锛氬湪涓嬮潰涓変釜杈撳叆妗嗕换涓�涓噷杈撳叆鍚庢寜鍥炶溅锛屾煡鍒伴绾﹁褰曞嵆鍙洿鎺ュ仛妫�鏌ャ��
+ -->
+ <el-alert type="warning" :closable="false" class="emergency-tip">
+ <template #title>
+ <span class="emergency-tip__text">
+ 鏈夌揣鎬ョ梾浜烘椂锛岃杈撳叆<span class="emergency-tip__key">鐢宠鍗曞彿</span>銆佹垨<span class="emergency-tip__key">灏辫瘖鍙�</span>銆佹垨<span class="emergency-tip__key">鎮h�呯紪鍙�</span>鍚庢寜<span class="emergency-tip__enter">鍥炶溅閿�</span>锛屾煡鍒扮梾浜洪绾﹁褰曞嵆鍙仛妫�鏌ワ紒锛侊紒
+ </span>
+ </template>
+ </el-alert>
<!-- ===== 缂栬緫鍖猴紙闇�瑕佸綍鍏ョ殑瀛楁锛�===== -->
- <el-row :gutter="20">
- <el-col :span="6">
- <el-form-item label="鐢宠鍗曞彿" prop="applyNo">
- <el-input v-model="formData.applyNo" placeholder="璇疯緭鍏ョ敵璇峰崟鍙�" />
- </el-form-item>
- </el-col>
- <el-col :span="6">
- <el-form-item label="妫�鏌ラ」鐩�" prop="">
- {{ formData?.checkType && getCheckTypeName(formData?.checkType) }}
- </el-form-item>
- </el-col>
- <el-col :span="6">
- <el-form-item label="鎮h�呯紪鍙�" prop="patId">
- <el-input v-model="formData.patId" placeholder="璇疯緭鍏ユ偅鑰呯紪鍙�" @input="getRentInfoByPatId" />
- <Barcode v-if="displayBarCode" :value="displayBarCode" :width="100" />
- <el-button @click="copyBarcode()">澶嶅埗</el-button>
- </el-form-item>
- </el-col>
- <el-col :span="6">
- <el-form-item label="鎮h�呭鍚�" prop="patName">
- <el-input v-model="formData.patName" placeholder="璇疯緭鍏ユ偅鑰呭鍚�" />
- </el-form-item>
- </el-col>
- </el-row>
+ <el-row :gutter="4">
+ <el-col :xs="24" :sm="12" :md="12" :lg="6">
+ <el-form-item label="鐢宠鍗曞彿" prop="applyNo">
+ <!-- 銆愭湰闇�姹傦細绱ф�ュ姞鍋氥�戝洖杞﹀嵆鎸夌敵璇峰崟鍙锋煡杩戜竴涓湀鐨勯绾� -->
+ <el-input
+ v-model="formData.applyNo"
+ placeholder="璇疯緭鍏ョ敵璇峰崟鍙�"
+ @keyup.enter="searchEmergencyCandidates('applyNo')"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :xs="24" :sm="12" :md="12" :lg="6">
+ <el-form-item label="妫�鏌ラ」鐩�" prop="">
+ {{ formData?.checkType && getCheckTypeName(formData?.checkType) }}
+ </el-form-item>
+ </el-col>
+ <el-col :xs="24" :sm="12" :md="12" :lg="6">
+ <el-form-item label="灏辫瘖鍙�" prop="episodeId">
+ <!-- 銆愭湰闇�姹傦細绱ф�ュ姞鍋氥�戝洖杞﹀嵆鎸夊氨璇婂彿鏌ヨ繎涓�涓湀鐨勯绾� -->
+ <el-input
+ v-model="formData.episodeId"
+ placeholder="璇疯緭鍏ュ氨璇婃祦姘村彿"
+ @keyup.enter="searchEmergencyCandidates('episodeId')"
+ />
+ <!--
+ 銆愭湰闇�姹傘�戞潯鐮佷粠銆屾偅鑰呯紪鍙枫�嶆尓鍒拌繖閲岋紙灏辫瘖鍙蜂笅鏂癸級锛�
+ 路 鍐呭 = 灏辫瘖鍙凤紱榛樿鏄惁鏄剧ず鐢便�屾鏌ョ被鍨� 鈫� 鏄惁鏄剧ず鏉$爜銆嶉厤缃喅瀹氾紱
+ 路 鍖荤敓鍙敤鍒囨崲鎸夐挳鎵嬪姩鏄鹃殣锛堟樉绀轰腑鈫掋�岄殣钘忋�嶏紱闅愯棌涓啋銆屾潯鐮併�嶏級锛�
+ 路 銆屽鍒躲�嶅彧鍦ㄦ潯鐮佹樉绀烘椂鍑虹幇銆�
+ -->
+ <div v-if="showBarcodeToggle || showBarCode" class="barcode-row">
+ <Barcode v-if="showBarCode" :value="barcodeContent" :width="100" />
+ <el-button v-if="showBarcodeToggle" size="small" @click="toggleBarcode()">
+ {{ barcodeToggleLabel }}
+ </el-button>
+ <el-button v-if="showCopyButton" size="small" :disabled="!barcodeContent" @click="copyBarcode()">
+ 澶嶅埗
+ </el-button>
+ </div>
+ </el-form-item>
+ </el-col>
+ <!-- 銆愭湰闇�姹傘�戞偅鑰呭鍚嶈繖涓�鍒楀凡鍘绘帀锛氫笅鏂� PatientInfoBlock 宸叉湁濮撳悕灞曠ず -->
+ <el-col :xs="24" :sm="12" :md="12" :lg="6">
+ <el-form-item label="鎮h�呯紪鍙�" prop="patId">
+ <!-- 銆愭湰闇�姹傦細绱ф�ュ姞鍋氥�戝洖杞﹀嵆鎸夋偅鑰呯紪鍙锋煡杩戜竴涓湀鐨勯绾� -->
+ <el-input
+ v-model="formData.patId"
+ placeholder="璇疯緭鍏ユ偅鑰呯紪鍙�"
+ @input="getRentInfoByPatId"
+ @keyup.enter="searchEmergencyCandidates('patId')"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
<!-- ===== 鎮h�呬俊鎭紙闇�姹�1锛�18 椤圭粺涓�灞曠ず锛�**涓�琛屽洓鍒�**锛�=====
鍘熷厛鏈潰鏉挎妸 18 椤规墜鍐欏湪澶氳 el-col锛坰pan=6/18 娣锋帓锛夛紝
鐜扮粺涓�鏀圭敤 PatientInfoBlock 缁勪欢锛屼笌棰勭害绛惧埌/璁惧棰嗙敤/瑁呮満/鎷嗘満鍚勯〉**鍙e緞涓�鑷�**銆� -->
<PatientInfoBlock :data="formData" check-type-field="checkType" :span="6" />
<el-row>
- <el-col :span="6">
+ <el-col :xs="24" :sm="12" :md="12" :lg="6">
<el-form-item label="妫�鏌ユ椂闂�" prop="rentTime">
<el-date-picker v-model="formData.rentTime" type="date" value-format="x" placeholder="閫夋嫨鏃堕棿" />
</el-form-item>
</el-col>
- <el-col :span="18">
+ <el-col :xs="24" :sm="24" :md="12" :lg="18">
<el-form-item label="澶囨敞" prop="remark">
<el-input v-model="formData.remark" placeholder="璇疯緭鍏ュ娉�" />
</el-form-item>
@@ -50,8 +91,8 @@
<el-button size="small" @click="resetForm()">閲� 缃�</el-button>
<el-button size="small" @click="yddownload()" :loading="yddownloadLoading" :disabled="yddownloadLoading">骞虫澘杩愬姩蹇冪數鍥剧煡鎯呭悓鎰忎功</el-button>
<el-button size="small" @click="sgdownload()" :loading="sgdownloadLoading" :disabled="sgdownloadLoading">椋熺蹇冭剰鐢电敓鐞嗚瘖鐤楃煡鎯呭悓鎰忎功</el-button>
- <el-button size="small" v-if="needAutoFeeConfirm(formData.checkType)" @click="feeConfirm" :disabled="formLoading">纭垂</el-button>
- <el-button size="small" v-if="needAutoFeeConfirm(formData.checkType)" @click="feeCancel" :disabled="formLoading">鍙栨秷纭垂</el-button>
+ <el-button size="small" v-if="needAutoFeeConfirm(formData.checkType)" @click="feeConfirm" :disabled="formLoading || formData.id == null">纭垂</el-button>
+ <el-button size="small" v-if="needAutoFeeConfirm(formData.checkType)" @click="feeCancel" :disabled="formLoading || formData.id == null">鍙栨秷纭垂</el-button>
</div>
<!-- 鍖荤敓瑁呮満鍒楄〃 -->
@@ -145,13 +186,84 @@
@pagination="getList"
/>
</div>
+
+ <!--
+ 銆愭湰闇�姹傦細绱ф�ユ偅鑰呬笉鎺掗槦鐩存帴妫�鏌ャ�戦绾﹂�夋嫨妗�
+ 瑙﹀彂锛氬湪銆岀敵璇峰崟鍙� / 灏辫瘖鍙� / 鎮h�呯紪鍙枫�嶄换涓�杈撳叆妗嗗唴鎸夊洖杞︺��
+ 澶氭潯棰勭害鏃跺脊姝ゆ锛屾寜棰勭害鏃堕棿鍊掑簭锛堟渶杩戠殑鍦ㄥ墠锛夈��
+ -->
+ <Dialog v-model="emergencyVisible" title="閫夋嫨棰勭害璁板綍锛堢揣鎬ュ姞鍋氾級" width="880px" append-to-body>
+ <el-alert type="warning" :closable="false" class="mb-10px">
+ <template #title>
+ <span class="text-13px">
+ 鎵惧埌 {{ emergencyList.length }} 鏉¢绾﹁褰曪細**鐐归�変竴琛�**锛堟暣琛岄珮浜� + 宸︿晶钃濇潯 + 銆屽凡閫夈�嶆爣绛撅級鍚庣偣銆岄�夋嫨骞舵鏌ャ�嶏紝
+ 涔熷彲鐩存帴**鍙屽嚮**璇ヨ銆傞�変腑鍚庡彲鐩存帴妫�鏌ワ紝瀹屾垚鍚庡悓鏍疯繘鍏ャ�屽凡瀹屾垚鍒楄〃銆嶏紙涓嶆帓闃熴�佷笉鍗犲彿锛夈��
+ </span>
+ </template>
+ </el-alert>
+ <el-table
+ ref="emergencyTableRef"
+ class="emergency-table"
+ :data="emergencyList"
+ v-loading="emergencyLoading"
+ highlight-current-row
+ border
+ max-height="360px"
+ :row-class-name="emergencyRowClass"
+ @row-click="(row) => (emergencySelected = row)"
+ @current-change="(row) => (emergencySelected = row)"
+ @row-dblclick="(row) => confirmEmergency(row)"
+ >
+ <!-- 銆愭湰闇�姹傘�戦�変腑鏍囪瘑鍒楋細閫変腑琛屾樉绀恒�屸湏 宸查�夈�嶏紝閬垮厤鍙潬鑳屾櫙鑹插垎杈ㄤ笉娓� -->
+ <el-table-column label="閫夋嫨" width="80" align="center" fixed="left">
+ <template #default="scope">
+ <el-tag v-if="isEmergencySelected(scope.row)" type="primary" effect="dark" size="small">
+ 鉁� 宸查��
+ </el-tag>
+ <span v-else class="text-gray-400">鈥�</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="棰勭害鏃ユ湡" align="center" prop="bookDate" width="120">
+ <template #default="scope">{{ formatDate(scope.row.bookDate, 'YYYY-MM-DD') }}</template>
+ </el-table-column>
+ <el-table-column label="鏃舵" align="center" width="120">
+ <template #default="scope">{{ formatTimeslot(scope.row.bookTimeslot) }}</template>
+ </el-table-column>
+ <el-table-column label="妫�鏌ラ」鐩�" align="center" min-width="130">
+ <template #default="scope">{{ getCheckTypeName(scope.row.bookCheckType) }}</template>
+ </el-table-column>
+ <el-table-column label="鎮h�呭悕绉�" align="center" prop="patName" min-width="100" />
+ <el-table-column label="鎮h�呯紪鍙�" align="center" prop="patId" min-width="110" />
+ <el-table-column label="鐢宠鍗曞彿" align="center" prop="applyNo" min-width="130" />
+ <el-table-column label="鐘舵��" align="center" width="90">
+ <template #default="scope">
+ <dict-tag :type="DICT_TYPE.ECG_STATUS" :value="scope.row.status" />
+ </template>
+ </el-table-column>
+ </el-table>
+ <template #footer>
+ <!-- 搴曢儴鍥炴樉宸查�夊摢涓�鏉★紝閬垮厤閫夐敊 -->
+ <span v-if="emergencySelected" class="emergency-selected-hint">
+ 宸查�夛細{{ formatDate(emergencySelected.bookDate, 'YYYY-MM-DD') }}
+ {{ formatTimeslot(emergencySelected.bookTimeslot) }}
+ {{ getCheckTypeName(emergencySelected.bookCheckType) }}
+ <span class="text-gray-500">锛坽{ emergencySelected.patName }}锛�</span>
+ </span>
+ <el-button @click="emergencyVisible = false">鍙� 娑�</el-button>
+ <el-button type="primary" :disabled="!emergencySelected" @click="confirmEmergency()">
+ 閫夋嫨骞舵鏌�
+ </el-button>
+ </template>
+ </Dialog>
</template>
<script setup lang="ts">
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { DevRentApi, DevRentVO } from '@/api/ecg/devrent'
-import { dateFormatter } from '@/utils/formatTime'
+import { dateFormatter, formatDate } from '@/utils/formatTime'
+import { formatTimeslot } from '@/utils/formatter'
+import { AppointmentApi, AppointmentVO } from '@/api/ecg/appointment'
import { JobRecordApi, JobRecordVO } from '@/api/ecg/jobrecord'
import { isStringEmpty } from '@/utils/stringUtil'
import { calculateAge, curDayEnd, curDayStart, formatTimestamp } from '@/utils/dateUtil'
@@ -239,7 +351,6 @@
formData.value.doctorAdviceNo = queueVO?.doctorAdviceNo
formData.value.patIdentityId = queueVO?.patIdentityId
getFreeRentInfo(formData.value)
- copyBarcode()
}
defineExpose({ setPatient, getList: () => getList() }) // 鎻愪緵 setPatient 鏂规硶锛岀敤浜庤缃偅鑰�
@@ -304,7 +415,106 @@
})
const formRef = ref() // 琛ㄥ崟 Ref
-const displayBarCode = ref<string>()
+
+// =====================================================================================
+// 銆愭湰闇�姹傦細绱ф�ユ偅鑰呬笉鎺掗槦鐩存帴妫�鏌ャ��
+// 鍦ㄣ�岀敵璇峰崟鍙� / 灏辫瘖鍙� / 鎮h�呯紪鍙枫�嶄换涓�杈撳叆妗嗗洖杞� 鈫� 鏌ヨ繎涓�涓湀銆佹湰绐楀彛妫�鏌ラ」鐩殑棰勭害璁板綍
+// 鈫� 1 鏉$洿鎺ヨ鍏ワ紱澶氭潯寮归�夋嫨妗嗭紙鎸夐绾︽椂闂村�掑簭锛夆啋 璇诲叆鍚庡彲鐩存帴銆屾鏌ュ畬鎴愩��
+// 鈫� 鍚庣鍦�"浠婂ぉ娌℃湁寰呮鏌ュ崟"鏃舵寜棰勭害鍗曡ˉ寤猴紝浠庤�屽儚鎺掗槦鎮h�呬竴鏍疯繘鍏ャ�屽凡瀹屾垚鍒楄〃銆�
+// =====================================================================================
+const emergencyMode = ref(false) // 褰撳墠琛ㄥ崟鏄惁鏉ヨ嚜"绱ф�ュ姞鍋�"
+const emergencyVisible = ref(false) // 閫夋嫨妗�
+const emergencyLoading = ref(false)
+const emergencyList = ref<AppointmentVO[]>([])
+const emergencySelected = ref<AppointmentVO | undefined>()
+/** 閫夋嫨琛ㄦ牸寮曠敤锛堜繚鐣欙細鍚庣画濡傞渶 scrollToRow 绛夎兘鍔涘彲鐢級 */
+const emergencyTableRef = ref<any>()
+
+/** 閫変腑鍒ゆ柇锛堟ā鏉块噷鐢紝閬垮厤鐩存帴姣旇緝瀵硅薄寮曠敤锛� */
+const isEmergencySelected = (row: AppointmentVO) =>
+ null != emergencySelected.value && emergencySelected.value.id === row?.id
+
+/** 閫変腑琛屽姞 is-selected 绫伙紝閰嶅悎涓嬫柟鏍峰紡鍋氥�屾暣琛岄珮浜� + 宸︿晶钃濇潯 + 鍔犵矖銆� */
+const emergencyRowClass = ({ row }: { row: AppointmentVO }) =>
+ isEmergencySelected(row) ? 'is-selected' : ''
+
+/** 鏈獥鍙o紙璇婂锛夊紑灞曠殑妫�鏌ラ」鐩紝鐢ㄤ簬杩囨护鍊欓�夐绾︼紱涓虹┖琛ㄧず涓嶉檺鍒� */
+const currentWindowCheckTypes = (): number[] | undefined => {
+ const fromProp = props.room?.checkTypes
+ const types =
+ Array.isArray(fromProp) && fromProp.length > 0 ? fromProp : (roomStore.room?.checkTypes as number[] | undefined)
+ return Array.isArray(types) && types.length > 0 ? [...types] : undefined
+}
+
+/** 鍥炶溅锛氭寜杈撳叆妗嗛噷鐨勫�兼煡棰勭害鍊欓�� */
+const searchEmergencyCandidates = async (field: 'applyNo' | 'episodeId' | 'patId') => {
+ const code = String((formData.value as Record<string, any>)[field] ?? '').trim()
+ if (!code) return
+ emergencyLoading.value = true
+ try {
+ const list = (await AppointmentApi.getEmergencyCandidates(code, currentWindowCheckTypes())) as AppointmentVO[]
+ const rows = Array.isArray(list) ? list : []
+ if (rows.length === 0) {
+ message.warning('杩戜竴涓湀鍐呮病鏈夋壘鍒版湰绐楀彛妫�鏌ラ」鐩殑棰勭害璁板綍')
+ return
+ }
+ if (rows.length === 1) {
+ applyAppointment(rows[0])
+ message.success('宸茶鍏ラ绾﹁褰曪紝鍙洿鎺ョ偣銆屾鏌ュ畬鎴愩��')
+ return
+ }
+ emergencyList.value = rows
+ emergencySelected.value = undefined
+ emergencyVisible.value = true
+ } finally {
+ emergencyLoading.value = false
+ }
+}
+
+/** 閫夋嫨妗嗙‘璁わ紙涔熸敮鎸佸弻鍑昏鐩存帴纭锛� */
+const confirmEmergency = (row?: AppointmentVO) => {
+ const target = row ?? emergencySelected.value
+ if (!target) return
+ applyAppointment(target)
+ emergencyVisible.value = false
+}
+
+/**
+ * 鎶婇绾﹀崟璇诲叆琛ㄥ崟銆�
+ * 娉ㄦ剰锛氳繖閲屾槸"绱ф�ュ姞鍋�"锛�**涓嶆帓闃�**鈥斺�斾笉寤� queue 琛屻�佷笉鍙栧彿锛�
+ * 銆屾鏌ュ畬鎴愩�嶆椂鐢卞悗绔寜闇�琛ュ缓銆屽緟妫�鏌ャ�嶆鏌ュ崟锛堣 DevRentServiceImpl#prepareEmergencyDevRent锛夈��
+ */
+const applyAppointment = (appt: AppointmentVO) => {
+ resetForm()
+ emergencyMode.value = true
+ formData.value.applyNo = appt.applyNo
+ formData.value.episodeId = appt.episodeId
+ formData.value.patId = appt.patId
+ formData.value.patName = appt.patName
+ formData.value.checkType = appt.bookCheckType
+ formData.value.patGender = appt.patGender
+ formData.value.patBirthday = appt.patBirthday
+ formData.value.patSrc = appt.patSrc
+ formData.value.tolerance = appt.tolerance
+ formData.value.doctor = appt.doctor
+ formData.value.doctorTime = appt.doctorTime
+ formData.value.registerDate = appt.registerDate
+ formData.value.paid = appt.paid
+ formData.value.doctorAdviceNo = appt.doctorAdviceNo
+ formData.value.patMobile = appt.patMobile
+ formData.value.patPhone = appt.patPhone
+ formData.value.patIdentityId = appt.patIdentityId
+ formData.value.outpatientNo = appt.outpatientNo
+ formData.value.patWardDesc = appt.patWardDesc
+ formData.value.patBedNo = appt.patBedNo
+ formData.value.medicalCard = appt.medicalCard
+ // 鏉$爜/鎵撳嵃灏忕エ渚濊禆 patDetails.source
+ formData.value.patDetails = {
+ source: appt.patSrc,
+ appointmentId: appt.id
+ } as unknown as typeof formData.value.patDetails
+ message.success('宸茶鍏ラ绾﹁褰曪紝鍙洿鎺ョ偣銆屾鏌ュ畬鎴愩��')
+}
/** 鎻愪氦琛ㄥ崟 */
const submitForm = async () => {
@@ -315,12 +525,16 @@
try {
formData.value.roomId = props.room.roomId
formData.value.bedNo = props.room.bedNo
- const data = formData.value as unknown as DevRentVO
- await DevRentApi.routineFinish(data)
+ // 銆愭湰闇�姹傦細绱ф�ユ偅鑰呬笉鎺掗槦鐩存帴妫�鏌ャ�戝甫涓�"绱ф�ュ姞鍋�"鏍囪锛�
+ // 鍚庣鎹鍦ㄣ�屼粖澶╂病鏈夊緟妫�鏌ュ崟銆嶆椂鎸夐绾﹀崟琛ュ缓涓�琛岋紝浠庤�岃兘姝e父瀹屾垚骞跺啓鍏ャ�屽凡瀹屾垚鍒楄〃銆�
+ const data = formData.value as unknown as DevRentVO & { emergency?: boolean }
+ data.emergency = emergencyMode.value
+ // 鍚庣 routine-finish 宸茶繑鍥炴湰娆″畬鎴愮殑妫�鏌ュ崟 id锛堢揣鎬ュ姞鍋氭椂鏄湇鍔$鏂板缓鐨勯偅鏉★級
+ const rentId = (await DevRentApi.routineFinish(data)) as unknown as number | string | undefined
- // 鑷姩纭垂
+ // 鑷姩纭垂锛氱敤杩斿洖鐨� rentId锛涙棤 id 鏃堕潤榛樿烦杩囷紙涓嶅啀寮广�岃鍏堟鏌ャ�嶏級
if (needAutoFeeConfirm(formData.value.checkType)) {
- feeConfirm()
+ feeConfirm(rentId)
}
message.success(t('鎿嶄綔鎴愬姛'))
@@ -360,6 +574,9 @@
roomId: props.room.roomId,
bedNo: props.room.bedNo
}
+ // 銆愭湰闇�姹傘�戞崲鎮h��/閲嶇疆鏃讹細鏉$爜鏄鹃殣鍥炲埌"璺熼殢閰嶇疆榛樿"锛岀揣鎬ュ姞鍋氭爣璁版竻绌�
+ barcodeVisible.value = null
+ emergencyMode.value = false
formRef.value?.resetFields()
}
const yddownload = async () => {
@@ -439,7 +656,6 @@
formData.value.patId = tempPatId
getFreeRentInfo(formData.value)
- copyBarcode()
}
const getFreeRentInfo = async (devRentVO) => {
@@ -570,14 +786,21 @@
message.success(t('鎿嶄綔鎴愬姛'))
}
-const feeConfirm = async () => {
- if (formData.value.id == null) {
- message.error(t('璇峰厛妫�鏌�'))
+/**
+ * 纭垂銆�
+ * @param rentId 鏈妫�鏌ュ畬鎴愯繑鍥炵殑妫�鏌ュ崟 id锛涗笉浼犲垯鐢ㄨ〃鍗曢噷鐨� id銆�
+ * 銆愭湰娆′慨澶嶃�戝師瀹炵幇鍦� id 涓虹┖鏃跺脊銆岃鍏堟鏌ャ�嶁�斺�� 绱ф�ュ姞鍋氭偅鑰呮病鏈� id锛岀偣銆屾鏌ュ畬鎴愩�嶄細鍏堝脊杩欎釜閿欙紝
+ * 鍐嶅脊銆屾搷浣滄垚鍔熴�嶏紝璁╀汉璇互涓烘搷浣滃け璐ャ�傜幇鍦ㄦ敼涓洪潤榛樿烦杩囷紙鎸夐挳鏈韩涔熶細鍦ㄦ棤 id 鏃剁鐢級銆�
+ */
+const feeConfirm = async (rentId?: number | string | null) => {
+ const id = rentId ?? formData.value.id
+ if (id == null || id === '') {
+ console.warn('[feeConfirm] 鏃犳鏌ュ崟 id锛岃烦杩囩‘璐�')
return
}
try {
- const result = await DevRentApi.feeConfirm(formData.value.id)
+ const result = await DevRentApi.feeConfirm(id as number)
if (0 == result) {
//message.success(t('纭垂鎿嶄綔鎴愬姛'))
}
@@ -587,8 +810,9 @@
}
const feeCancel = async () => {
- if (formData.value.id == null) {
- message.error(t('璇峰厛妫�鏌�'))
+ // 銆愭湰娆′慨澶嶃�戞棤妫�鏌ュ崟 id 鏃堕潤榛樿烦杩囷紙鎸夐挳宸茬鐢級锛屼笉鍐嶅脊銆岃鍏堟鏌ャ��
+ if (formData.value.id == null || formData.value.id === '') {
+ console.warn('[feeCancel] 鏃犳鏌ュ崟 id锛岃烦杩囧彇娑堢‘璐�')
return
}
@@ -601,40 +825,57 @@
// 妗嗘灦 浼氱粰鍑� 鍚庡彴鐨� 閿欒淇℃伅
}
}
+/**
+ * 銆愭湰闇�姹傘�戞偅鑰呮潯鐮侊細浣嶇疆鍦ㄣ�屽氨璇婂彿銆嶄笅鏂癸紝鍐呭 = 灏辫瘖鍙凤紙episodeId锛夛紝鍙樉闅�
+ *
+ * 路 榛樿鍙鎬� = 銆屾鏌ョ被鍨� 鈫� 鏄惁鏄剧ず鏉$爜銆嶉厤缃噷**鍖呭惈璇ユ偅鑰呮潵婧�**
+ * - 宸插嬀閫夎鏉ユ簮 鈫� 榛樿鏄剧ず
+ * - 鏈厤缃� / 閰嶇疆閲屾病鏈夎鏉ユ簮 鈫� 榛樿涓嶆樉绀猴紙渚嬪浣忛櫌(3)閫氬父涓嶄細鍕鹃�夛級
+ * 路 鍖荤敓鍙敤鎸夐挳鎵嬪姩瑕嗙洊榛樿锛氭樉绀轰腑 鈫� 銆岄殣钘忋�嶏紱闅愯棌涓� 鈫� 銆屾潯鐮併��
+ * 路 銆屽鍒躲�嶆寜閽彧鍦ㄦ潯鐮佹樉绀烘椂鍑虹幇
+ */
+const barcodeVisible = ref<boolean | null>(null) // null = 鏈墜鍔ㄦ搷浣滐紝璺熼殢閰嶇疆榛樿
-const getDisplayBarcode = (): string => {
- if (formData.value.checkType == null) return ''
+const patSourceValue = computed<number | null>(() => {
+ const source = formData.value.patDetails?.source ?? formData.value.patSrc
+ return source === null || source === undefined || source === '' ? null : Number(source)
+})
- // 銆愭湰娆′慨澶嶃�戙�屾偅鑰呮潯鐮佹樉绀恒�嶆湭閰嶇疆锛坣ull/绌猴級鈫� 涓嶆樉绀猴紙鎸夌幇鍦虹‘璁ゅ彛寰勶級
- const displayBarcode: number[] | undefined = checkTypeStore.getCheckTypeDispBarCode(formData.value.checkType!)
- if (displayBarcode == null || displayBarcode.length === 0) return ''
+/** 閰嶇疆鍙e緞锛氳妫�鏌ョ被鍨嬬殑銆屾樉绀烘潯鐮併�嶆槸鍚﹀寘鍚綋鍓嶆偅鑰呮潵婧� */
+const barcodeEnabled = computed<boolean>(() => {
+ if (formData.value.checkType == null) return false
+ const displayBarcode: number[] | undefined = checkTypeStore.getCheckTypeDispBarCode(formData.value.checkType)
+ if (displayBarcode == null || displayBarcode.length === 0) return false
+ const patSource = patSourceValue.value
+ if (patSource == null) return false
+ return displayBarcode.map(Number).includes(patSource)
+})
- // 銆愭湰娆′慨澶嶃�戞潵婧愪紭鍏堝彇 patDetails.source锛岀己澶辨椂鍥為��鍒板钩閾虹殑 patSrc銆�
- // 鍘熸潵鍙 patDetails.source锛岃�� patDetails 鍘熷厛鍙湪"鑳芥煡鍒板緟妫�鏌ュ崟"鏃舵墠琚祴鍊硷紝
- // 澶у鏁版儏鍐典笅鏄� undefined 鈫� 鏉$爜姘歌繙涓嶆樉绀恒��
- const patSource = formData.value.patDetails?.source ?? formData.value.patSrc
- if (patSource == null) return ''
- if (!displayBarcode.map(Number).includes(Number(patSource))) return ''
+/** 鏉$爜 / 澶嶅埗鐨勫唴瀹癸細缁熶竴鍙栥�屽氨璇婂彿銆� */
+const barcodeContent = computed<string>(() => formData.value.episodeId ?? '')
- return getBarcode()
-}
+/** 瀹為檯鏄惁鏄剧ず锛氭墜鍔ㄨ鐩栦紭鍏堬紝鍚﹀垯璺熼厤缃粯璁� */
+const barcodeVisibleEffective = computed<boolean>(() => barcodeVisible.value ?? barcodeEnabled.value)
-const getBarcode = (): string => {
- if (formData.value.checkType == null) return ''
+/** 鏉$爜锛氬彲瑙佷笖鍐呭闈炵┖鎵嶆覆鏌� */
+const showBarCode = computed<boolean>(() => barcodeVisibleEffective.value && barcodeContent.value !== '')
- const patSource = formData.value.patDetails?.source ?? formData.value.patSrc
- if (patSource == null) return ''
+/** 銆屽鍒躲�嶆寜閽細鍙湪鏉$爜鏄剧ず鏃跺嚭鐜� */
+const showCopyButton = computed<boolean>(() => showBarCode.value)
- // 闂ㄨ瘖/鎬ヨ瘖 鈫� 鐢宠鍗曞彿锛涗綇闄�/浣撴 鈫� 灏辫瘖娴佹按鍙�
- if (1 === Number(patSource) || 2 === Number(patSource)) return formData.value.applyNo ?? ''
- else if (3 === Number(patSource) || 4 === Number(patSource)) return formData.value.episodeId ?? ''
+/** 鍒囨崲鎸夐挳锛氬彧瑕佹湁灏辫瘖鍙峰氨缁欙紙涓嶅彈閰嶇疆闄愬埗锛岄厤缃彧绠�"榛樿鏄惁鏄剧ず"锛� */
+const showBarcodeToggle = computed<boolean>(() => barcodeContent.value !== '')
- return ''
+/** 鍒囨崲鎸夐挳鏂囨锛氭樉绀轰腑 鈫� 闅愯棌锛涢殣钘忎腑 鈫� 鏉$爜 */
+const barcodeToggleLabel = computed<string>(() => (showBarCode.value ? '闅愯棌' : '鏉$爜'))
+
+const toggleBarcode = () => {
+ barcodeVisible.value = !barcodeVisibleEffective.value
}
const copyBarcode = async () => {
- displayBarCode.value = getDisplayBarcode()
- await navigator.clipboard.writeText(getBarcode())
+ if (!barcodeContent.value) return
+ await navigator.clipboard.writeText(barcodeContent.value)
}
/** 鍒濆鍖� **/
@@ -647,6 +888,73 @@
<style scoped lang="scss">
/* 銆愭湰娆¢渶姹傘�戙�屽凡瀹屾垚鍒楄〃銆嶆爣棰樻爮锛氬乏渚т富鑹茬珫绾� + 鍔犵矖灏忔爣棰橈紝绱у噾楂樺害涓嶆尋鍘嬭〃鏍� */
+/* 銆愭湰闇�姹傘�戠紪杈戝尯涓婃柟鐨勩�岀揣鎬ュ姞鍋氥�嶆搷浣滄彁绀猴細涓�琛屾樉绀恒�侀啋鐩絾涓嶅崰楂樺害 */
+.emergency-tip {
+ padding: 4px 10px;
+ margin-bottom: 6px;
+
+ :deep(.el-alert__title) {
+ padding: 0;
+ font-size: 13px;
+ line-height: 20px;
+ }
+
+ &__text {
+ color: var(--el-color-warning-dark-2);
+ }
+
+ /* 鍏抽敭瀛楁/鎸夐敭鍋氬己璋冿紝鏂逛究涓�鐪肩湅鎳傝杈撲粈涔堛�佹寜浠�涔� */
+ &__key {
+ font-weight: 600;
+ color: var(--el-color-danger);
+ }
+
+ &__enter {
+ padding: 0 4px;
+ margin: 0 2px;
+ border: 1px solid var(--el-color-danger);
+ border-radius: 3px;
+ font-weight: 600;
+ color: var(--el-color-danger);
+ background-color: var(--el-color-danger-light-9);
+ }
+}
+/* 銆愭湰闇�姹傘�戠揣鎬ュ姞鍋氾細棰勭害閫夋嫨妗嗙殑銆岄�変腑琛屻�嶈瓒冲鏄庢樉
+ 锛堝師鏉ュ彧鏈夐粯璁ょ殑娴呰壊 current-row 鑳屾櫙锛岀幇鍦哄弽棣�"鍙槸鍙樻繁涓�鐐癸紝鐪嬩笉娓�"锛� */
+.emergency-table {
+ :deep(.el-table__row) {
+ cursor: pointer;
+ }
+ :deep(.el-table__row:hover > td) {
+ background-color: var(--el-color-primary-light-9) !important;
+ }
+ /* 閫変腑琛岋細涓昏壊鑳屾櫙 + 鍔犵矖 + 宸︿晶 4px 涓昏壊鏉� */
+ :deep(.el-table__row.is-selected > td) {
+ background-color: var(--el-color-primary-light-6) !important;
+ color: var(--el-color-primary-dark-2);
+ font-weight: 600;
+ }
+ :deep(.el-table__row.is-selected > td:first-child) {
+ box-shadow: inset 4px 0 0 var(--el-color-primary);
+ }
+}
+
+/* 閫夋嫨妗嗗簳閮ㄣ�屽凡閫夈�嶅洖鏄� */
+.emergency-selected-hint {
+ float: left;
+ line-height: 32px;
+ font-size: 13px;
+ color: var(--el-color-primary);
+ font-weight: 600;
+}
+/* 銆愭湰闇�姹傘�戝氨璇婂彿涓嬫柟鐨勬潯鐮佽锛氭潯鐮� + [闅愯棌|鏉$爜] + [澶嶅埗] 鍚屼竴琛岋紝绱у噾涓嶆拺楂� */
+.barcode-row {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ margin-top: 4px;
+ flex-wrap: wrap;
+}
.records-title {
display: flex;
align-items: center;
diff --git a/src/views/ecg/room/RoomLoginSelect.vue b/src/views/ecg/room/RoomLoginSelect.vue
index 9d0755e..5996cbd 100644
--- a/src/views/ecg/room/RoomLoginSelect.vue
+++ b/src/views/ecg/room/RoomLoginSelect.vue
@@ -33,7 +33,7 @@
<div class="room-select__scroll">
<div class="room-select__list">
<div class="room-select__item" v-for="(bed, index) in bedList" :key="`${bed.roomId}-${bed.bedNo}-${index}`">
- <RoomBedSelect :bed="bed" :curBed="curSel" :curUser='curUser' @event-haveseat="haveSeat" @event-leaveseat="leaveSeat" @event-setcurseat="setCurSeat"/>
+ <RoomBedSelect :bed="bed" :curBed="curSel" :curUser='curUser' @event-haveseat="haveSeat" @event-leaveseat="leaveSeat" @event-setcurseat="setCurSeat" @event-takeover="takeOverConfirm"/>
</div>
<el-empty v-if="isEmptyOpeningBed" class="room-select__empty" description="宸ヤ綅娌℃湁寮�鏀�"/>
</div>
@@ -397,8 +397,8 @@
tempRoomVO.docId = curUser.id
tempRoomVO.docName = curUser.nickname
- // 銆愭湰娆¢渶姹傘�戣蛋 store 鐨勫叆搴у姩浣滐細鏈嶅姟绔叆搴ф垚鍔熷悗浼�**鑷姩閲婃斁鎴戣繖涓处鍙风殑鍏跺畠宸ヤ綅**
- // 锛堜竴浜轰竴宸ヤ綅锛夛紝骞舵妸宸ヤ綅淇℃伅鍐欒繘浼氳瘽缂撳瓨銆�
+ // 銆愭湰闇�姹偮蜂竴浜哄宸ヤ綅銆戣蛋 store 鐨勫叆搴у姩浣滐細鏈嶅姟绔�**涓嶅啀閲婃斁**鎴戣处鍙蜂笅鐨勫叾瀹冨伐浣嶏紝
+ // 鍥犳杩欓噷鏄�"鏂板涓�涓垜鐨勫伐浣�"锛堝�肩彮澶氬矖浣嶏級锛屽苟鎶婂伐浣嶄俊鎭啓杩涗細璇濈紦瀛樸��
const seated = await roomStore.seatRoom(tempRoomVO)
if (!seated) {
// 澶辫触鏃惰嚜鍔ㄨ皟璇婃柇鎺ュ彛锛屾妸搴撻噷鐪熷疄琛屼笌缁撹涓�璧风粰鍑猴紙渚夸簬鐜板満涓�閿畾浣嶏級
@@ -425,6 +425,39 @@
gotoAfterSeat(newRoomVO.opType, false)
}
+/**
+ * 銆愭湰闇�姹偮锋帴鐝嚜鍔╂帴绠°�戝"鍒汉鍗犵敤"鐨勫伐浣嶆墽琛屾帴绠°��
+ *
+ * 鍦烘櫙锛氫笂涓�鐝尰鐢熶笅鐝病鐐广�岀搴с�嶏紝涓嬩竴鐝尰鐢熷湪鍚屼竴宸ヤ綅鎺ョ彮 鈥斺�� 鍘熸潵鍙兘鎵剧鐞嗗憳娓呯┖銆�
+ * 鐜板湪锛氫簩娆$‘璁� 鈫� 鍚庣寮哄埗鍘熷崰鐢ㄤ汉绂诲骇骞舵妸宸ヤ綅缁欐垜 鈫� 鍒锋柊鍒楄〃/鎴戠殑宸ヤ綅銆�
+ */
+const takeOverConfirm = async (roomVO: RoomVO) => {
+ const bedText = `${roomVO.roomName || '璇婂' + roomVO.roomId} 路 ${roomVO.bedNo}`
+ const owner = roomVO.docName || '鍏朵粬鍖荤敓'
+ try {
+ await ElMessageBox.confirm(
+ `宸ヤ綅銆�${bedText}銆嶅綋鍓嶇敱銆�${owner}銆嶅崰鐢ㄣ�俓n` +
+ `纭鎺ョ锛熸帴绠″悗銆�${owner}銆嶅皢琚己鍒剁搴э紙鍏堕〉闈細鎻愮ず閲嶆柊灏卞潗锛夛紝宸ヤ綅绔嬪嵆褰掍綘浣跨敤銆俙,
+ '鎺ョ宸ヤ綅',
+ { confirmButtonText: '纭鎺ョ', cancelButtonText: '鍙栨秷', type: 'warning' }
+ )
+ } catch {
+ return
+ }
+ const ok = await roomStore.takeOverBed(roomVO.roomId, roomVO.bedNo)
+ if (!ok) {
+ ElMessage({ message: '鎺ョ澶辫触锛岃绋嶅悗閲嶈瘯鎴栬仈绯荤鐞嗗憳', type: 'error', duration: 4000 })
+ return
+ }
+ ElMessage.success(`宸叉帴绠″伐浣嶏細${bedText}`)
+ resetCurSel()
+ curSel.value = { ...roomVO, docId: curUser.id, docName: curUser.nickname }
+ await roomStore.fetchMySeat()
+ await getList()
+ // 鎺ョ鍚庤繘鍏ヨ宀椾綅瀵瑰簲鐨勫伐浣滃彴锛堟帴绠′細甯︿笂璇ュ伐浣�"灏辫瘖涓�"鎮h�咃級
+ gotoAfterSeat(roomVO.opType, true)
+}
+
const leaveSeatConfirm = async (roomVO: RoomVO) => {
// 銆愭湰娆¢渶姹傘�戠搴у彧鑳芥竻**鑷繁鐨�** doc_id锛堟湇鍔$ setBedDoctorOff 宸插姞 doc_id 鏉′欢锛夛紝
// 杩欓噷鍏堟嫤涓�閬擄紝閬垮厤"鏃佽/鍏朵粬鍖荤敓"鐐圭搴ф妸姝e湪鎿嶄綔鐨勪汉韪㈡帀銆�
diff --git a/src/views/ecg/room/RoomSetting.vue b/src/views/ecg/room/RoomSetting.vue
index a7d041f..5858fed 100644
--- a/src/views/ecg/room/RoomSetting.vue
+++ b/src/views/ecg/room/RoomSetting.vue
@@ -41,7 +41,11 @@
{{ monitorInfo?.openingFlag === 1 ? '寮�璇婁腑锛堜細鑷姩琛ヤ汉锛�' : '宸查棴璇婏紙涓嶄細鑷姩琛ヤ汉锛�' }}
</el-tag>
</div>
- <div>宸ヤ綅姒傚喌锛� {{monitorInfo?.openingBedNum}} {{monitorInfo?.docBedNum}} {{monitorInfo?.routingBedNum}} </div>
+ <div>
+ 宸ヤ綅姒傚喌锛� 寮�閫� {{ monitorInfo?.openingBedNum }} 路
+ 鍦ㄥ骇宸ヤ綅 {{ monitorInfo?.docBedNum }}锛堝尰鐢� {{ monitorInfo?.docNum ?? 0 }} 浜猴級路
+ 鍙備笌鍒嗘祦 {{ monitorInfo?.routingBedNum }}
+ </div>
<div v-for="(value, key) in monitorInfo.checkTypeBedInfo" :key="key">
{{ getCheckTypeName(Number(key)) }} {{ value }}
</div>
--
Gitblit v1.9.3