| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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": { |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | }, |
| | | minPixelValue: 2, |
| | | } |
| | | } |
| | | } |
| | |
| | | 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') |
| New file |
| | |
| | | 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 |
| | | }; |
| | | } |
| | | ); |
| New file |
| | |
| | | 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() |
| | |
| | | </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"; |
| | |
| | | } |
| | | const props = defineProps<Props>(); |
| | | |
| | | const settingDeviceDialogRef = ref<any>(null); |
| | | |
| | | const formTypeNoText = computed(() => { |
| | | if (props.formNo) { |
| | | let result = props?.formType === 1 ? "住院号" : "门诊号"; |
| | |
| | | } |
| | | 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; |
| New file |
| | |
| | | <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> |
| | |
| | | </template> |
| | | |
| | | <script lang="ts" setup name="UnplannedSchedule"> |
| | | interface Props { |
| | | height: number; |
| | | } |
| | | const props = defineProps<Props>(); |
| | | |
| | | // @ts-ignore |
| | | import Card from './Card.vue'; |
| | | </script> |
| | |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { defineAsyncComponent } from 'vue'; |
| | | // @ts-ignore |
| | | import Header from './components/Header.vue'; |
| | | |
| | | |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | |
| | | "moduleResolution": "node", |
| | | "baseUrl": ".", |
| | | "paths": { |
| | | "@/*": ["src/*"], |
| | | "*": ["node_modules/*", "src/types/*"] |
| | | }, |
| | | "esModuleInterop": true, |
| | |
| | | }, |
| | | resolve: { |
| | | alias: { |
| | | '@': '/src' |
| | | '@': path.resolve(__dirname, 'src') |
| | | } |
| | | } |
| | | }); |