From 87a971f080881598bc2380d5f72252be88ab8982 Mon Sep 17 00:00:00 2001
From: zhangchen <1652267879@qq.com>
Date: 星期二, 08 七月 2025 17:39:08 +0800
Subject: [PATCH] ID1825-设备号弹窗修改完成
---
src/views/mobile/bedsideAuxiliaryScreen/components/UnplannedSchedule.vue | 5
package-lock.json | 229 +++++++++++++++++
src/views/mobile/bedsideAuxiliaryScreen/components/Header.vue | 21 +
src/store/bedsideAuxiliaryScreen.ts | 73 +++++
src/main.ts | 5
vite.config.ts | 2
src/views/mobile/bedsideAuxiliaryScreen/components/SettingDeviceDialog.vue | 317 ++++++++++++++++++++++++
tsconfig.json | 1
package.json | 1
src/img/upload.png | 0
src/views/mobile/bedsideAuxiliaryScreen/index.vue | 3
postcss.config.js | 3
src/utils/cache.ts | 69 +++++
src/img/close.png | 0
14 files changed, 722 insertions(+), 7 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 35c566b..5383b81 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,6 +14,7 @@
"echarts": "^5.6.0",
"element-plus": "^2.9.2",
"event-source-polyfill": "^1.0.31",
+ "pinia": "^3.0.3",
"qs": "^6.14.0",
"speak-tts": "^2.0.8",
"vant": "^3.4.3",
@@ -1013,6 +1014,30 @@
"integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==",
"license": "MIT"
},
+ "node_modules/@vue/devtools-kit": {
+ "version": "7.7.7",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.7.tgz",
+ "integrity": "sha512-wgoZtxcTta65cnZ1Q6MbAfePVFxfM+gq0saaeytoph7nEa7yMXoi6sCPy4ufO111B9msnw0VOWjPEFCXuAKRHA==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/devtools-shared": "^7.7.7",
+ "birpc": "^2.3.0",
+ "hookable": "^5.5.3",
+ "mitt": "^3.0.1",
+ "perfect-debounce": "^1.0.0",
+ "speakingurl": "^14.0.1",
+ "superjson": "^2.2.2"
+ }
+ },
+ "node_modules/@vue/devtools-shared": {
+ "version": "7.7.7",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.7.tgz",
+ "integrity": "sha512-+udSj47aRl5aKb0memBvcUG9koarqnxNM5yjuREvqwK6T3ap4mn3Zqqc17QrBFTqSMjr3HK1cvStEZpMDpfdyw==",
+ "license": "MIT",
+ "dependencies": {
+ "rfdc": "^1.4.1"
+ }
+ },
"node_modules/@vue/language-core": {
"version": "2.2.0",
"resolved": "https://registry.npmmirror.com/@vue/language-core/-/language-core-2.2.0.tgz",
@@ -1266,6 +1291,15 @@
"resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
+ },
+ "node_modules/birpc": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.4.0.tgz",
+ "integrity": "sha512-5IdNxTyhXHv2UlgnPHQ0h+5ypVmkrYHzL8QT+DwFZ//2N/oNV8Ch+BCRmTJ3x6/z9Axo/cXYBc9eprsUVK/Jsg==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
},
"node_modules/brace-expansion": {
"version": "2.0.1",
@@ -1737,6 +1771,12 @@
"he": "bin/he"
}
},
+ "node_modules/hookable": {
+ "version": "5.5.3",
+ "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
+ "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==",
+ "license": "MIT"
+ },
"node_modules/iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz",
@@ -1919,6 +1959,12 @@
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
+ },
+ "node_modules/mitt": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
+ "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",
+ "license": "MIT"
},
"node_modules/muggle-string": {
"version": "0.4.1",
@@ -4674,6 +4720,12 @@
"integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
"dev": true
},
+ "node_modules/perfect-debounce": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz",
+ "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==",
+ "license": "MIT"
+ },
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
@@ -4688,6 +4740,36 @@
"optional": true,
"engines": {
"node": ">=6"
+ }
+ },
+ "node_modules/pinia": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/pinia/-/pinia-3.0.3.tgz",
+ "integrity": "sha512-ttXO/InUULUXkMHpTdp9Fj4hLpD/2AoJdmAbAeW2yu1iy1k+pkFekQXw5VpC0/5p51IOR/jDaDRfRWRnMMsGOA==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/devtools-api": "^7.7.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/posva"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.4.4",
+ "vue": "^2.7.0 || ^3.5.11"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/pinia/node_modules/@vue/devtools-api": {
+ "version": "7.7.7",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.7.tgz",
+ "integrity": "sha512-lwOnNBH2e7x1fIIbVT7yF5D+YWhqELm55/4ZKf45R9T8r9dE2AIOy8HKjfqzGsoTHFbWbr337O4E0A0QADnjBg==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/devtools-kit": "^7.7.7"
}
},
"node_modules/postcss": {
@@ -4755,6 +4837,12 @@
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
+ },
+ "node_modules/rfdc": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
+ "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
+ "license": "MIT"
},
"node_modules/rollup": {
"version": "4.30.1",
@@ -4930,6 +5018,54 @@
"resolved": "https://registry.npmmirror.com/speak-tts/-/speak-tts-2.0.8.tgz",
"integrity": "sha512-VY6Q6mRjdou6bF+x0LspvM7GJhBxHx8CLyGPTNQQ7jrztiGutyI4QNZn0cA17c4uk0FnFbA4PaMI3skeZ6PiFg==",
"license": "MIT"
+ },
+ "node_modules/speakingurl": {
+ "version": "14.0.1",
+ "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz",
+ "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/superjson": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz",
+ "integrity": "sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==",
+ "license": "MIT",
+ "dependencies": {
+ "copy-anything": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/superjson/node_modules/copy-anything": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz",
+ "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==",
+ "license": "MIT",
+ "dependencies": {
+ "is-what": "^4.1.8"
+ },
+ "engines": {
+ "node": ">=12.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mesqueeb"
+ }
+ },
+ "node_modules/superjson/node_modules/is-what": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz",
+ "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mesqueeb"
+ }
},
"node_modules/terser": {
"version": "5.43.1",
@@ -5721,6 +5857,28 @@
"resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz",
"integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g=="
},
+ "@vue/devtools-kit": {
+ "version": "7.7.7",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.7.tgz",
+ "integrity": "sha512-wgoZtxcTta65cnZ1Q6MbAfePVFxfM+gq0saaeytoph7nEa7yMXoi6sCPy4ufO111B9msnw0VOWjPEFCXuAKRHA==",
+ "requires": {
+ "@vue/devtools-shared": "^7.7.7",
+ "birpc": "^2.3.0",
+ "hookable": "^5.5.3",
+ "mitt": "^3.0.1",
+ "perfect-debounce": "^1.0.0",
+ "speakingurl": "^14.0.1",
+ "superjson": "^2.2.2"
+ }
+ },
+ "@vue/devtools-shared": {
+ "version": "7.7.7",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.7.tgz",
+ "integrity": "sha512-+udSj47aRl5aKb0memBvcUG9koarqnxNM5yjuREvqwK6T3ap4mn3Zqqc17QrBFTqSMjr3HK1cvStEZpMDpfdyw==",
+ "requires": {
+ "rfdc": "^1.4.1"
+ }
+ },
"@vue/language-core": {
"version": "2.2.0",
"resolved": "https://registry.npmmirror.com/@vue/language-core/-/language-core-2.2.0.tgz",
@@ -5886,6 +6044,11 @@
"resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
+ },
+ "birpc": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.4.0.tgz",
+ "integrity": "sha512-5IdNxTyhXHv2UlgnPHQ0h+5ypVmkrYHzL8QT+DwFZ//2N/oNV8Ch+BCRmTJ3x6/z9Axo/cXYBc9eprsUVK/Jsg=="
},
"brace-expansion": {
"version": "2.0.1",
@@ -6204,6 +6367,11 @@
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
"dev": true
},
+ "hookable": {
+ "version": "5.5.3",
+ "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
+ "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="
+ },
"iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz",
@@ -6324,6 +6492,11 @@
"requires": {
"brace-expansion": "^2.0.1"
}
+ },
+ "mitt": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
+ "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="
},
"muggle-string": {
"version": "0.4.1",
@@ -8146,6 +8319,11 @@
"integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
"dev": true
},
+ "perfect-debounce": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz",
+ "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA=="
+ },
"picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
@@ -8157,6 +8335,24 @@
"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
"dev": true,
"optional": true
+ },
+ "pinia": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/pinia/-/pinia-3.0.3.tgz",
+ "integrity": "sha512-ttXO/InUULUXkMHpTdp9Fj4hLpD/2AoJdmAbAeW2yu1iy1k+pkFekQXw5VpC0/5p51IOR/jDaDRfRWRnMMsGOA==",
+ "requires": {
+ "@vue/devtools-api": "^7.7.2"
+ },
+ "dependencies": {
+ "@vue/devtools-api": {
+ "version": "7.7.7",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.7.tgz",
+ "integrity": "sha512-lwOnNBH2e7x1fIIbVT7yF5D+YWhqELm55/4ZKf45R9T8r9dE2AIOy8HKjfqzGsoTHFbWbr337O4E0A0QADnjBg==",
+ "requires": {
+ "@vue/devtools-kit": "^7.7.7"
+ }
+ }
+ }
},
"postcss": {
"version": "8.4.49",
@@ -8194,6 +8390,11 @@
"requires": {
"side-channel": "^1.1.0"
}
+ },
+ "rfdc": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
+ "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="
},
"rollup": {
"version": "4.30.1",
@@ -8318,6 +8519,34 @@
"resolved": "https://registry.npmmirror.com/speak-tts/-/speak-tts-2.0.8.tgz",
"integrity": "sha512-VY6Q6mRjdou6bF+x0LspvM7GJhBxHx8CLyGPTNQQ7jrztiGutyI4QNZn0cA17c4uk0FnFbA4PaMI3skeZ6PiFg=="
},
+ "speakingurl": {
+ "version": "14.0.1",
+ "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz",
+ "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ=="
+ },
+ "superjson": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz",
+ "integrity": "sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==",
+ "requires": {
+ "copy-anything": "^3.0.2"
+ },
+ "dependencies": {
+ "copy-anything": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz",
+ "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==",
+ "requires": {
+ "is-what": "^4.1.8"
+ }
+ },
+ "is-what": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz",
+ "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A=="
+ }
+ }
+ },
"terser": {
"version": "5.43.1",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz",
diff --git a/package.json b/package.json
index f6bb524..9eab2a0 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,7 @@
"echarts": "^5.6.0",
"element-plus": "^2.9.2",
"event-source-polyfill": "^1.0.31",
+ "pinia": "^3.0.3",
"qs": "^6.14.0",
"speak-tts": "^2.0.8",
"vant": "^3.4.3",
diff --git a/postcss.config.js b/postcss.config.js
index 3b8ce2d..b493b9a 100644
--- a/postcss.config.js
+++ b/postcss.config.js
@@ -18,7 +18,8 @@
return true;
}
return false;
- }
+ },
+ minPixelValue: 2,
}
}
}
diff --git a/src/img/close.png b/src/img/close.png
new file mode 100644
index 0000000..65a365d
--- /dev/null
+++ b/src/img/close.png
Binary files differ
diff --git a/src/img/upload.png b/src/img/upload.png
new file mode 100644
index 0000000..4a2b5b8
--- /dev/null
+++ b/src/img/upload.png
Binary files differ
diff --git a/src/main.ts b/src/main.ts
index 960ccbc..9147bbe 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -8,11 +8,12 @@
import router from './router';
import App from './App.vue'
import VConsole from 'vconsole'
+import { createPinia } from 'pinia'
if (import.meta.env.VITE_ENV === 'development') {
// 如果需要在手机平板上打开控制台,安装一个这个
const vConsole = new VConsole()
}
+const pinia = createPinia()
-
-createApp(App).use(router).use(ElementPlus).use(Vant).mount('#app')
+createApp(App).use(router).use(pinia).use(ElementPlus).use(Vant).mount('#app')
diff --git a/src/store/bedsideAuxiliaryScreen.ts b/src/store/bedsideAuxiliaryScreen.ts
new file mode 100644
index 0000000..5dbdc80
--- /dev/null
+++ b/src/store/bedsideAuxiliaryScreen.ts
@@ -0,0 +1,73 @@
+import { defineStore } from "pinia";
+import { ref } from "vue";
+import cache from "../utils/cache";
+import { EventSourcePolyfill } from "event-source-polyfill";
+
+export const useBedsideAuxiliaryScreenStore = defineStore(
+ "bedsideAuxiliaryScreen",
+ () => {
+ const deviceCode = ref<string>(cache.get("devcieCode") || ""); // 设备编号
+
+ /**
+ * 设置设备编号
+ * @param code
+ */
+ const setDeviceCode = (code: string) => {
+ deviceCode.value = code;
+ cache.set("devcieCode", code);
+ };
+
+ // SSE 相关状态
+ const source = ref<EventSource | null>(null);
+ const message = ref<string | null>(null);
+ const isConnected = ref(false);
+
+ /**
+ * 连接 SSE 服务
+ * @param url SSE 地址
+ */
+ const connect = (url: string) => {
+ if (source.value) return; // 已连接,避免重复连接
+
+ source.value = new EventSourcePolyfill(url, {
+ heartbeatTimeout: 60000,
+ });
+
+ source.value.onopen = () => {
+ console.log("[SSE] 连接成功");
+ isConnected.value = true;
+ };
+
+ source.value.onerror = (e) => {
+ console.warn("[SSE] 错误,等待重连中", e);
+ isConnected.value = false;
+ };
+
+ source.value.onmessage = (e) => {
+ console.log("[SSE] 消息:", e.data);
+ message.value = e.data;
+ };
+ };
+
+ /**
+ * 关闭 SSE 连接
+ */
+ const close = () => {
+ if (source.value) {
+ source.value.close();
+ source.value = null;
+ isConnected.value = false;
+ console.log("[SSE] 连接已关闭");
+ }
+ };
+ return {
+ deviceCode,
+ setDeviceCode,
+ source,
+ message,
+ isConnected,
+ connect,
+ close
+ };
+ }
+);
diff --git a/src/utils/cache.ts b/src/utils/cache.ts
new file mode 100644
index 0000000..d351a77
--- /dev/null
+++ b/src/utils/cache.ts
@@ -0,0 +1,69 @@
+class Cache {
+ /**
+ * 设置本地缓存
+ * @param key 键名
+ * @param value 值(会自动序列化为 JSON)
+ */
+ set<T = any>(key: string, value: T): void {
+ try {
+ const json = JSON.stringify(value)
+ localStorage.setItem(key, json)
+ } catch (e) {
+ console.error(`缓存写入失败(${key}):`, e)
+ }
+ }
+
+ /**
+ * 获取本地缓存
+ * @param key 键名
+ * @returns 反序列化后的值,失败返回 null
+ */
+ get<T = any>(key: string): T | null {
+ try {
+ const json = localStorage.getItem(key)
+ return json ? JSON.parse(json) as T : null
+ } catch (e) {
+ console.error(`缓存读取失败(${key}):`, e)
+ return null
+ }
+ }
+
+ /**
+ * 删除指定缓存项
+ * @param key 键名
+ */
+ delete(key: string): void {
+ try {
+ localStorage.removeItem(key)
+ } catch (e) {
+ console.error(`缓存删除失败(${key}):`, e)
+ }
+ }
+
+ /**
+ * 判断某项缓存是否存在
+ * @param key 键名
+ * @returns 是否存在
+ */
+ has(key: string): boolean {
+ try {
+ return localStorage.getItem(key) !== null
+ } catch (e) {
+ console.error(`缓存判断失败(${key}):`, e)
+ return false
+ }
+ }
+
+ /**
+ * 清空所有本地缓存
+ */
+ clear(): void {
+ try {
+ localStorage.clear()
+ } catch (e) {
+ console.error('缓存清空失败:', e)
+ }
+ }
+}
+
+export default new Cache()
diff --git a/src/views/mobile/bedsideAuxiliaryScreen/components/Header.vue b/src/views/mobile/bedsideAuxiliaryScreen/components/Header.vue
index 5f2b8f3..9b08031 100644
--- a/src/views/mobile/bedsideAuxiliaryScreen/components/Header.vue
+++ b/src/views/mobile/bedsideAuxiliaryScreen/components/Header.vue
@@ -19,14 +19,24 @@
</div>
<div class="header-right">
<img :src="atRegularTimeImg" class="btn-img" alt="" />
- <img :src="setUpImg" class="btn-img" alt="" />
+ <img
+ :src="setUpImg"
+ class="btn-img"
+ alt=""
+ @click="openSettingDeviceDialog"
+ />
<img :src="userImg" class="btn-img" alt="" />
</div>
</div>
+ <!-- 设置设备编号组件 -->
+ <SettingDeviceDialog ref="settingDeviceDialogRef" />
</template>
<script lang="ts" setup name="Header">
-import { computed } from "vue";
+import { ref, computed, defineAsyncComponent } from "vue";
+const SettingDeviceDialog = defineAsyncComponent(
+ () => import("./SettingDeviceDialog.vue")
+);
import atRegularTimeImg from "../../../../img/dingshi.png";
import setUpImg from "../../../../img/shezhi.png";
import userImg from "../../../../img/user.png";
@@ -45,6 +55,8 @@
}
const props = defineProps<Props>();
+const settingDeviceDialogRef = ref<any>(null);
+
const formTypeNoText = computed(() => {
if (props.formNo) {
let result = props?.formType === 1 ? "住院号" : "门诊号";
@@ -53,11 +65,14 @@
}
return "";
});
+
+const openSettingDeviceDialog = () => {
+ settingDeviceDialogRef.value?.openDialog();
+};
</script>
<style lang="less" scoped>
.bedside-auxiliary-screen-header {
- width: 100%;
height: 25px;
padding: 0 15px 0 12px;
display: flex;
diff --git a/src/views/mobile/bedsideAuxiliaryScreen/components/SettingDeviceDialog.vue b/src/views/mobile/bedsideAuxiliaryScreen/components/SettingDeviceDialog.vue
new file mode 100644
index 0000000..9d0a1cb
--- /dev/null
+++ b/src/views/mobile/bedsideAuxiliaryScreen/components/SettingDeviceDialog.vue
@@ -0,0 +1,317 @@
+<template>
+ <div class="setting-device-dialog-container">
+ <el-dialog
+ v-model="isShow"
+ center
+ title="设置编号"
+ width="80%"
+ :show-close="false"
+ >
+ <template #header>
+ <div class="setting-dialog-header">
+ <span class="header-title">设置编号</span>
+ <img
+ :src="closeImg"
+ class="header-close"
+ @click="handleCancel"
+ alt=""
+ />
+ </div>
+ </template>
+ <div class="setting-device-dialog-content">
+ <div class="content-row1">
+ <div class="row1-label">设备编号</div>
+ <div class="row1-inp-box">
+ <input
+ v-model="devcieCode"
+ type="text"
+ class="row1-inp"
+ placeholder="请输入设备编号或扫码二维码"
+ />
+ </div>
+ </div>
+ <div class="content-row2">
+ <el-upload
+ v-loading="isUploading"
+ class="upload-demo"
+ drag
+ :show-file-list="false"
+ accept="image/*"
+ :limit="1"
+ :before-upload="onBeforeUpload"
+ >
+ <div class="el-upload__text">
+ <img :src="uploadImg" class="upload-img" alt="" />
+ <p class="upload-text">点击虚线区域选择文件并识别二维码</p>
+ <div class="upload-btn">二维码上传</div>
+ </div>
+ </el-upload>
+ </div>
+ </div>
+ <template #footer>
+ <div class="my-button cancel" @click="handleCancel">取消</div>
+ <div class="my-button confirm" @click="handleConfirm">确认</div>
+ <div class="my-button refresh" @click="handleRefresh">刷新</div>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script lang="ts" setup>
+import { ElMessage, UploadRawFile } from "element-plus";
+import { ref } from "vue";
+import {
+ BrowserMultiFormatReader,
+ NotFoundException,
+ ChecksumException,
+ FormatException,
+} from "@zxing/library";
+import closeImg from "@/img/close.png";
+import uploadImg from "@/img/upload.png";
+import { useBedsideAuxiliaryScreenStore } from "@/store/bedsideAuxiliaryScreen";
+
+const bedsideAuxiliaryScreenStore = useBedsideAuxiliaryScreenStore();
+
+const isShow = ref(false);
+const isUploading = ref(false);
+const devcieCode = ref("");
+
+const openDialog = () => {
+ devcieCode.value = bedsideAuxiliaryScreenStore.deviceCode + "";
+ isShow.value = true;
+};
+
+const onBeforeUpload = async (uploadFile: UploadRawFile) => {
+ const file = uploadFile;
+ if (!file) return;
+
+ isUploading.value = true;
+ try {
+ const result = await decodeQRCodeFromFile(file);
+ devcieCode.value = result;
+ ElMessage.success("识别成功");
+ } catch (err) {
+ if (err instanceof NotFoundException) {
+ ElMessage.error("未找到二维码");
+ } else if (err instanceof ChecksumException) {
+ ElMessage.error("校验错误");
+ } else if (err instanceof FormatException) {
+ ElMessage.error("格式错误");
+ } else {
+ ElMessage.error("识别错误请重新识别");
+ console.error(err);
+ }
+ } finally {
+ isUploading.value = false;
+ }
+ return false;
+};
+
+const decodeQRCodeFromFile = async (file: File): Promise<string> => {
+ return new Promise((resolve, reject) => {
+ const reader = new FileReader();
+
+ reader.onload = async (e: any) => {
+ const imageBase64 = e.target.result;
+ const codeReader = new BrowserMultiFormatReader();
+
+ try {
+ const result = await codeReader.decodeFromImage(undefined, imageBase64);
+ resolve(result.getText());
+ } catch (err) {
+ reject(err);
+ }
+ };
+
+ reader.onerror = () => reject(new Error("读取文件失败"));
+ reader.readAsDataURL(file);
+ });
+};
+
+const handleCancel = () => {
+ isShow.value = false;
+};
+
+const handleConfirm = () => {
+ bedsideAuxiliaryScreenStore.setDeviceCode(devcieCode.value + "");
+ handleCancel();
+};
+
+const handleRefresh = () => {};
+
+defineExpose({
+ openDialog,
+});
+</script>
+
+<style lang="less" scoped>
+.setting-device-dialog-container {
+ ::v-deep(.el-dialog) {
+ padding: 0;
+ border-radius: 6px;
+ overflow: hidden;
+ }
+ ::v-deep(.el-dialog__footer) {
+ padding: 4px;
+ }
+ ::v-deep(.el-upload-dragger) {
+ height: 65px;
+ padding: 0 !important;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+ ::v-deep(.el-upload-dragger .el-icon--upload) {
+ display: none;
+ }
+ ::v-deep(.el-dialog__header) {
+ padding-bottom: 6px;
+ }
+ .setting-dialog-header {
+ position: relative;
+ height: 16px;
+ background: #769aff;
+ .header-title {
+ position: absolute;
+ left: 50%;
+ top: 50%;
+ transform: translateX(-50%) translateY(-50%);
+ font-family: AlibabaPuHuiTi, AlibabaPuHuiTi;
+ font-weight: 500;
+ font-size: 8px;
+ color: #ffffff;
+ line-height: 11px;
+ text-align: center;
+ }
+ .header-close {
+ position: absolute;
+ top: 50%;
+ transform: translateY(-50%);
+ right: 6px;
+ width: 15px;
+ height: 15px;
+ transition: transform 0.2s;
+
+ &:active {
+ opacity: 0.6;
+ transform: translateY(-50%) scale(0.95);
+ }
+ }
+ }
+ .setting-device-dialog-content {
+ padding: 0 12px 6px;
+ margin-bottom: 4px;
+ border-bottom: 1px solid #d8d8d8;
+ .content-row1 {
+ display: flex;
+ align-items: center;
+ margin-bottom: 6px;
+
+ .row1-label {
+ margin-right: 6px;
+ padding: 0 4px;
+ background: #769aff;
+ border-radius: 2px;
+ font-family: PingFangSC, PingFang SC;
+ font-weight: 600;
+ font-size: 8px;
+ line-height: 16px;
+ color: #ffffff;
+ font-style: normal;
+ }
+ .row1-inp-box {
+ flex: 1;
+ height: 16px;
+ border-radius: 2px;
+ border: 1px solid #979797;
+ overflow: hidden;
+
+ .row1-inp {
+ width: 100%;
+ height: 100%;
+ border: none;
+ outline: none;
+ padding: 0 4px; // 给一点水平 padding 更美观
+ line-height: 16px;
+ font-size: 9px;
+ font-family: PingFangSC, PingFang SC;
+ vertical-align: middle; // ✅ 关键设置
+ box-sizing: border-box; // 避免padding撑高
+
+ &::placeholder {
+ font-family: inherit;
+ font-size: inherit;
+ line-height: inherit;
+ color: #aaaaaa;
+ opacity: 1;
+ }
+ }
+ }
+ }
+
+ .el-upload__text {
+ display: flex;
+ align-items: center;
+ flex-direction: column;
+ justify-content: center;
+ .upload-img {
+ height: 8px;
+ }
+ .upload-text {
+ font-family: PingFangSC, PingFang SC;
+ font-weight: 500;
+ font-size: 5px;
+ color: #5a6470;
+ letter-spacing: 0px;
+ text-align: center;
+ font-style: normal;
+ }
+ .upload-btn {
+ padding: 0 2px;
+ background-color: #409eff;
+ border-radius: 1px;
+ font-family: PingFangSC, PingFang SC;
+ font-size: 4px;
+ color: #fff;
+ letter-spacing: 0px;
+ line-height: 8px;
+ text-align: center;
+ font-style: normal;
+ }
+ }
+ }
+
+ .my-button {
+ display: inline-block;
+ border-radius: 2px;
+ padding: 0px 10px;
+ font-family: PingFangSC, PingFang SC;
+ font-weight: 500;
+ font-size: 7px;
+ color: #ffffff;
+ line-height: 16px;
+ letter-spacing: 1px;
+ text-align: center;
+ font-style: normal;
+ transition: transform 0.1s ease, opacity 0.1s ease;
+ cursor: pointer;
+ &:active {
+ transform: scale(0.95);
+ opacity: 0.8;
+ }
+
+ &:not(:first-child) {
+ margin-left: 6px;
+ }
+ &.cancel {
+ background: #bbc6dd;
+ }
+ &.confirm {
+ background: #769aff;
+ }
+ &.refresh {
+ background: #e6a23c;
+ }
+ }
+}
+</style>
\ No newline at end of file
diff --git a/src/views/mobile/bedsideAuxiliaryScreen/components/UnplannedSchedule.vue b/src/views/mobile/bedsideAuxiliaryScreen/components/UnplannedSchedule.vue
index 5569c00..52d92bd 100644
--- a/src/views/mobile/bedsideAuxiliaryScreen/components/UnplannedSchedule.vue
+++ b/src/views/mobile/bedsideAuxiliaryScreen/components/UnplannedSchedule.vue
@@ -3,6 +3,11 @@
</template>
<script lang="ts" setup name="UnplannedSchedule">
+interface Props {
+ height: number;
+}
+const props = defineProps<Props>();
+
// @ts-ignore
import Card from './Card.vue';
</script>
diff --git a/src/views/mobile/bedsideAuxiliaryScreen/index.vue b/src/views/mobile/bedsideAuxiliaryScreen/index.vue
index f098537..54417c7 100644
--- a/src/views/mobile/bedsideAuxiliaryScreen/index.vue
+++ b/src/views/mobile/bedsideAuxiliaryScreen/index.vue
@@ -6,8 +6,11 @@
</template>
<script lang="ts" setup>
+import { defineAsyncComponent } from 'vue';
// @ts-ignore
import Header from './components/Header.vue';
+
+
</script>
<style lang="less" scoped>
diff --git a/tsconfig.json b/tsconfig.json
index cb5a989..3fb0cf2 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -5,6 +5,7 @@
"moduleResolution": "node",
"baseUrl": ".",
"paths": {
+ "@/*": ["src/*"],
"*": ["node_modules/*", "src/types/*"]
},
"esModuleInterop": true,
diff --git a/vite.config.ts b/vite.config.ts
index 08b537c..144989a 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -14,7 +14,7 @@
},
resolve: {
alias: {
- '@': '/src'
+ '@': path.resolve(__dirname, 'src')
}
}
});
\ No newline at end of file
--
Gitblit v1.8.0