2025-12-24 发版,具体内容见发版日志
This commit is contained in:
1
openhis-ui-vue3/.gitignore
vendored
1
openhis-ui-vue3/.gitignore
vendored
@@ -21,4 +21,3 @@ selenium-debug.log
|
||||
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
vite.config.js
|
||||
|
||||
564
openhis-ui-vue3/package-lock.json
generated
564
openhis-ui-vue3/package-lock.json
generated
@@ -13,7 +13,9 @@
|
||||
"@vueup/vue-quill": "1.2.0",
|
||||
"@vueuse/core": "10.6.1",
|
||||
"axios": "0.27.2",
|
||||
"china-division": "^2.7.0",
|
||||
"d3": "^7.9.0",
|
||||
"dayjs": "^1.11.19",
|
||||
"decimal.js": "^10.5.0",
|
||||
"echarts": "5.4.3",
|
||||
"element-china-area-data": "^6.1.0",
|
||||
@@ -24,6 +26,7 @@
|
||||
"js-cookie": "3.0.5",
|
||||
"jsencrypt": "3.3.2",
|
||||
"lodash": "^4.17.21",
|
||||
"lodash-es": "^4.17.21",
|
||||
"moment": "^2.30.1",
|
||||
"nprogress": "0.2.0",
|
||||
"pinia": "2.1.7",
|
||||
@@ -38,14 +41,17 @@
|
||||
"vue-router": "4.2.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^25.0.1",
|
||||
"@vitejs/plugin-vue": "4.5.0",
|
||||
"@vue/compiler-sfc": "3.3.9",
|
||||
"sass": "1.69.5",
|
||||
"typescript": "^5.9.3",
|
||||
"unplugin-auto-import": "0.17.1",
|
||||
"unplugin-vue-setup-extend-plus": "1.0.0",
|
||||
"vite": "5.0.4",
|
||||
"vite-plugin-compression": "0.5.1",
|
||||
"vite-plugin-svg-icons": "2.0.1"
|
||||
"vite-plugin-svg-icons": "2.0.1",
|
||||
"vue-tsc": "^3.1.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@antfu/utils": {
|
||||
@@ -668,9 +674,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.2.tgz",
|
||||
"integrity": "sha512-yDPzwsgiFO26RJA4nZo8I+xqzh7sJTZIWQOxn+/XOdPE31lAvLIYCKqjV+lNH/vxE2L2iH3plKxDCRK6i+CwhA==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz",
|
||||
"integrity": "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -682,9 +688,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm64": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.2.tgz",
|
||||
"integrity": "sha512-k8FontTxIE7b0/OGKeSN5B6j25EuppBcWM33Z19JoVT7UTXFSo3D9CdU39wGTeb29NO3XxpMNauh09B+Ibw+9g==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.3.tgz",
|
||||
"integrity": "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -696,9 +702,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.2.tgz",
|
||||
"integrity": "sha512-A6s4gJpomNBtJ2yioj8bflM2oogDwzUiMl2yNJ2v9E7++sHrSrsQ29fOfn5DM/iCzpWcebNYEdXpaK4tr2RhfQ==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz",
|
||||
"integrity": "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -710,9 +716,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-x64": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.2.tgz",
|
||||
"integrity": "sha512-e6XqVmXlHrBlG56obu9gDRPW3O3hLxpwHpLsBJvuI8qqnsrtSZ9ERoWUXtPOkY8c78WghyPHZdmPhHLWNdAGEw==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.3.tgz",
|
||||
"integrity": "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -724,9 +730,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-freebsd-arm64": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.2.tgz",
|
||||
"integrity": "sha512-v0E9lJW8VsrwPux5Qe5CwmH/CF/2mQs6xU1MF3nmUxmZUCHazCjLgYvToOk+YuuUqLQBio1qkkREhxhc656ViA==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.3.tgz",
|
||||
"integrity": "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -738,9 +744,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-freebsd-x64": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.2.tgz",
|
||||
"integrity": "sha512-ClAmAPx3ZCHtp6ysl4XEhWU69GUB1D+s7G9YjHGhIGCSrsg00nEGRRZHmINYxkdoJehde8VIsDC5t9C0gb6yqA==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.3.tgz",
|
||||
"integrity": "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -752,9 +758,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.2.tgz",
|
||||
"integrity": "sha512-EPlb95nUsz6Dd9Qy13fI5kUPXNSljaG9FiJ4YUGU1O/Q77i5DYFW5KR8g1OzTcdZUqQQ1KdDqsTohdFVwCwjqg==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.3.tgz",
|
||||
"integrity": "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -766,9 +772,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.2.tgz",
|
||||
"integrity": "sha512-BOmnVW+khAUX+YZvNfa0tGTEMVVEerOxN0pDk2E6N6DsEIa2Ctj48FOMfNDdrwinocKaC7YXUZ1pHlKpnkja/Q==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.3.tgz",
|
||||
"integrity": "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -780,9 +786,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.2.tgz",
|
||||
"integrity": "sha512-Xt2byDZ+6OVNuREgBXr4+CZDJtrVso5woFtpKdGPhpTPHcNG7D8YXeQzpNbFRxzTVqJf7kvPMCub/pcGUWgBjA==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.3.tgz",
|
||||
"integrity": "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -794,9 +800,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.2.tgz",
|
||||
"integrity": "sha512-+LdZSldy/I9N8+klim/Y1HsKbJ3BbInHav5qE9Iy77dtHC/pibw1SR/fXlWyAk0ThnpRKoODwnAuSjqxFRDHUQ==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.3.tgz",
|
||||
"integrity": "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -808,9 +814,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-loong64-gnu": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.2.tgz",
|
||||
"integrity": "sha512-8ms8sjmyc1jWJS6WdNSA23rEfdjWB30LH8Wqj0Cqvv7qSHnvw6kgMMXRdop6hkmGPlyYBdRPkjJnj3KCUHV/uQ==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.3.tgz",
|
||||
"integrity": "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
@@ -822,9 +828,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.2.tgz",
|
||||
"integrity": "sha512-3HRQLUQbpBDMmzoxPJYd3W6vrVHOo2cVW8RUo87Xz0JPJcBLBr5kZ1pGcQAhdZgX9VV7NbGNipah1omKKe23/g==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.3.tgz",
|
||||
"integrity": "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
@@ -836,9 +842,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.2.tgz",
|
||||
"integrity": "sha512-fMjKi+ojnmIvhk34gZP94vjogXNNUKMEYs+EDaB/5TG/wUkoeua7p7VCHnE6T2Tx+iaghAqQX8teQzcvrYpaQA==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.3.tgz",
|
||||
"integrity": "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
@@ -850,9 +856,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-musl": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.2.tgz",
|
||||
"integrity": "sha512-XuGFGU+VwUUV5kLvoAdi0Wz5Xbh2SrjIxCtZj6Wq8MDp4bflb/+ThZsVxokM7n0pcbkEr2h5/pzqzDYI7cCgLQ==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.3.tgz",
|
||||
"integrity": "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
@@ -864,9 +870,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.2.tgz",
|
||||
"integrity": "sha512-w6yjZF0P+NGzWR3AXWX9zc0DNEGdtvykB03uhonSHMRa+oWA6novflo2WaJr6JZakG2ucsyb+rvhrKac6NIy+w==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.3.tgz",
|
||||
"integrity": "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
@@ -878,9 +884,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.2.tgz",
|
||||
"integrity": "sha512-yo8d6tdfdeBArzC7T/PnHd7OypfI9cbuZzPnzLJIyKYFhAQ8SvlkKtKBMbXDxe1h03Rcr7u++nFS7tqXz87Gtw==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz",
|
||||
"integrity": "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -892,9 +898,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.2.tgz",
|
||||
"integrity": "sha512-ah59c1YkCxKExPP8O9PwOvs+XRLKwh/mV+3YdKqQ5AMQ0r4M4ZDuOrpWkUaqO7fzAHdINzV9tEVu8vNw48z0lA==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz",
|
||||
"integrity": "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -906,9 +912,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-openharmony-arm64": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.2.tgz",
|
||||
"integrity": "sha512-4VEd19Wmhr+Zy7hbUsFZ6YXEiP48hE//KPLCSVNY5RMGX2/7HZ+QkN55a3atM1C/BZCGIgqN+xrVgtdak2S9+A==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.3.tgz",
|
||||
"integrity": "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -920,9 +926,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.2.tgz",
|
||||
"integrity": "sha512-IlbHFYc/pQCgew/d5fslcy1KEaYVCJ44G8pajugd8VoOEI8ODhtb/j8XMhLpwHCMB3yk2J07ctup10gpw2nyMA==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.3.tgz",
|
||||
"integrity": "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -934,9 +940,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.2.tgz",
|
||||
"integrity": "sha512-lNlPEGgdUfSzdCWU176ku/dQRnA7W+Gp8d+cWv73jYrb8uT7HTVVxq62DUYxjbaByuf1Yk0RIIAbDzp+CnOTFg==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.3.tgz",
|
||||
"integrity": "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@@ -948,9 +954,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-gnu": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.2.tgz",
|
||||
"integrity": "sha512-S6YojNVrHybQis2lYov1sd+uj7K0Q05NxHcGktuMMdIQ2VixGwAfbJ23NnlvvVV1bdpR2m5MsNBViHJKcA4ADw==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz",
|
||||
"integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -962,9 +968,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.2.tgz",
|
||||
"integrity": "sha512-k+/Rkcyx//P6fetPoLMb8pBeqJBNGx81uuf7iljX9++yNBVRDQgD04L+SVXmXmh5ZP4/WOp4mWF0kmi06PW2tA==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz",
|
||||
"integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -999,9 +1005,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/lodash": {
|
||||
"version": "4.17.20",
|
||||
"resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.17.20.tgz",
|
||||
"integrity": "sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==",
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-FOvQ0YPD5NOfPgMzJihoT+Za5pdkDJWcbpuj1DjaKZIr/gxodQjY/uWEFlTNqW2ugXHUiL8lRQgw63dzKHZdeQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/lodash-es": {
|
||||
@@ -1014,9 +1020,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "24.10.0",
|
||||
"resolved": "https://registry.npmmirror.com/@types/node/-/node-24.10.0.tgz",
|
||||
"integrity": "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==",
|
||||
"version": "25.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/@types/node/-/node-25.0.2.tgz",
|
||||
"integrity": "sha512-gWEkeiyYE4vqjON/+Obqcoeffmk0NF15WSBwSs7zwVA2bAbTaE0SJ7P0WNGoJn8uE7fiaV5a7dKYIJriEqOrmA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -1078,6 +1084,35 @@
|
||||
"vue": "^3.2.25"
|
||||
}
|
||||
},
|
||||
"node_modules/@volar/language-core": {
|
||||
"version": "2.4.26",
|
||||
"resolved": "https://registry.npmmirror.com/@volar/language-core/-/language-core-2.4.26.tgz",
|
||||
"integrity": "sha512-hH0SMitMxnB43OZpyF1IFPS9bgb2I3bpCh76m2WEK7BE0A0EzpYsRp0CCH2xNKshr7kacU5TQBLYn4zj7CG60A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@volar/source-map": "2.4.26"
|
||||
}
|
||||
},
|
||||
"node_modules/@volar/source-map": {
|
||||
"version": "2.4.26",
|
||||
"resolved": "https://registry.npmmirror.com/@volar/source-map/-/source-map-2.4.26.tgz",
|
||||
"integrity": "sha512-JJw0Tt/kSFsIRmgTQF4JSt81AUSI1aEye5Zl65EeZ8H35JHnTvFGmpDOBn5iOxd48fyGE+ZvZBp5FcgAy/1Qhw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@volar/typescript": {
|
||||
"version": "2.4.26",
|
||||
"resolved": "https://registry.npmmirror.com/@volar/typescript/-/typescript-2.4.26.tgz",
|
||||
"integrity": "sha512-N87ecLD48Sp6zV9zID/5yuS1+5foj0DfuYGdQ6KHj/IbKvyKv1zNX6VCmnKYwtmHadEO6mFc2EKISiu3RDPAvA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@volar/language-core": "2.4.26",
|
||||
"path-browserify": "^1.0.1",
|
||||
"vscode-uri": "^3.0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-core": {
|
||||
"version": "3.3.9",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.3.9.tgz",
|
||||
@@ -1138,13 +1173,95 @@
|
||||
"integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@vue/reactivity": {
|
||||
"version": "3.5.24",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.24.tgz",
|
||||
"integrity": "sha512-BM8kBhtlkkbnyl4q+HiF5R5BL0ycDPfihowulm02q3WYp2vxgPcJuZO866qa/0u3idbMntKEtVNuAUp5bw4teg==",
|
||||
"node_modules/@vue/language-core": {
|
||||
"version": "3.1.8",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/language-core/-/language-core-3.1.8.tgz",
|
||||
"integrity": "sha512-PfwAW7BLopqaJbneChNL6cUOTL3GL+0l8paYP5shhgY5toBNidWnMXWM+qDwL7MC9+zDtzCF2enT8r6VPu64iw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/shared": "3.5.24"
|
||||
"@volar/language-core": "2.4.26",
|
||||
"@vue/compiler-dom": "^3.5.0",
|
||||
"@vue/shared": "^3.5.0",
|
||||
"alien-signals": "^3.0.0",
|
||||
"muggle-string": "^0.4.1",
|
||||
"path-browserify": "^1.0.1",
|
||||
"picomatch": "^4.0.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/language-core/node_modules/@vue/compiler-core": {
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.25.tgz",
|
||||
"integrity": "sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.28.5",
|
||||
"@vue/shared": "3.5.25",
|
||||
"entities": "^4.5.0",
|
||||
"estree-walker": "^2.0.2",
|
||||
"source-map-js": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/language-core/node_modules/@vue/compiler-dom": {
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.25.tgz",
|
||||
"integrity": "sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/compiler-core": "3.5.25",
|
||||
"@vue/shared": "3.5.25"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/language-core/node_modules/@vue/shared": {
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.25.tgz",
|
||||
"integrity": "sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@vue/language-core/node_modules/entities": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz",
|
||||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/language-core/node_modules/picomatch": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz",
|
||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/reactivity": {
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.25.tgz",
|
||||
"integrity": "sha512-5xfAypCQepv4Jog1U4zn8cZIcbKKFka3AgWHEFQeK65OW+Ys4XybP6z2kKgws4YB43KGpqp5D/K3go2UPPunLA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/shared": "3.5.25"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/reactivity-transform": {
|
||||
@@ -1162,95 +1279,95 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/reactivity/node_modules/@vue/shared": {
|
||||
"version": "3.5.24",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.24.tgz",
|
||||
"integrity": "sha512-9cwHL2EsJBdi8NY22pngYYWzkTDhld6fAD6jlaeloNGciNSJL6bLpbxVgXl96X00Jtc6YWQv96YA/0sxex/k1A==",
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.25.tgz",
|
||||
"integrity": "sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@vue/runtime-core": {
|
||||
"version": "3.5.24",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.24.tgz",
|
||||
"integrity": "sha512-RYP/byyKDgNIqfX/gNb2PB55dJmM97jc9wyF3jK7QUInYKypK2exmZMNwnjueWwGceEkP6NChd3D2ZVEp9undQ==",
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.25.tgz",
|
||||
"integrity": "sha512-Z751v203YWwYzy460bzsYQISDfPjHTl+6Zzwo/a3CsAf+0ccEjQ8c+0CdX1WsumRTHeywvyUFtW6KvNukT/smA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/reactivity": "3.5.24",
|
||||
"@vue/shared": "3.5.24"
|
||||
"@vue/reactivity": "3.5.25",
|
||||
"@vue/shared": "3.5.25"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/runtime-core/node_modules/@vue/shared": {
|
||||
"version": "3.5.24",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.24.tgz",
|
||||
"integrity": "sha512-9cwHL2EsJBdi8NY22pngYYWzkTDhld6fAD6jlaeloNGciNSJL6bLpbxVgXl96X00Jtc6YWQv96YA/0sxex/k1A==",
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.25.tgz",
|
||||
"integrity": "sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@vue/runtime-dom": {
|
||||
"version": "3.5.24",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.24.tgz",
|
||||
"integrity": "sha512-Z8ANhr/i0XIluonHVjbUkjvn+CyrxbXRIxR7wn7+X7xlcb7dJsfITZbkVOeJZdP8VZwfrWRsWdShH6pngMxRjw==",
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.25.tgz",
|
||||
"integrity": "sha512-a4WrkYFbb19i9pjkz38zJBg8wa/rboNERq3+hRRb0dHiJh13c+6kAbgqCPfMaJ2gg4weWD3APZswASOfmKwamA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/reactivity": "3.5.24",
|
||||
"@vue/runtime-core": "3.5.24",
|
||||
"@vue/shared": "3.5.24",
|
||||
"@vue/reactivity": "3.5.25",
|
||||
"@vue/runtime-core": "3.5.25",
|
||||
"@vue/shared": "3.5.25",
|
||||
"csstype": "^3.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/runtime-dom/node_modules/@vue/shared": {
|
||||
"version": "3.5.24",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.24.tgz",
|
||||
"integrity": "sha512-9cwHL2EsJBdi8NY22pngYYWzkTDhld6fAD6jlaeloNGciNSJL6bLpbxVgXl96X00Jtc6YWQv96YA/0sxex/k1A==",
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.25.tgz",
|
||||
"integrity": "sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@vue/server-renderer": {
|
||||
"version": "3.5.24",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.24.tgz",
|
||||
"integrity": "sha512-Yh2j2Y4G/0/4z/xJ1Bad4mxaAk++C2v4kaa8oSYTMJBJ00/ndPuxCnWeot0/7/qafQFLh5pr6xeV6SdMcE/G1w==",
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.25.tgz",
|
||||
"integrity": "sha512-UJaXR54vMG61i8XNIzTSf2Q7MOqZHpp8+x3XLGtE3+fL+nQd+k7O5+X3D/uWrnQXOdMw5VPih+Uremcw+u1woQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/compiler-ssr": "3.5.24",
|
||||
"@vue/shared": "3.5.24"
|
||||
"@vue/compiler-ssr": "3.5.25",
|
||||
"@vue/shared": "3.5.25"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "3.5.24"
|
||||
"vue": "3.5.25"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/server-renderer/node_modules/@vue/compiler-core": {
|
||||
"version": "3.5.24",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.24.tgz",
|
||||
"integrity": "sha512-eDl5H57AOpNakGNAkFDH+y7kTqrQpJkZFXhWZQGyx/5Wh7B1uQYvcWkvZi11BDhscPgj8N7XV3oRwiPnx1Vrig==",
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.25.tgz",
|
||||
"integrity": "sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.28.5",
|
||||
"@vue/shared": "3.5.24",
|
||||
"@vue/shared": "3.5.25",
|
||||
"entities": "^4.5.0",
|
||||
"estree-walker": "^2.0.2",
|
||||
"source-map-js": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/server-renderer/node_modules/@vue/compiler-dom": {
|
||||
"version": "3.5.24",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.24.tgz",
|
||||
"integrity": "sha512-1QHGAvs53gXkWdd3ZMGYuvQFXHW4ksKWPG8HP8/2BscrbZ0brw183q2oNWjMrSWImYLHxHrx1ItBQr50I/q2zw==",
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.25.tgz",
|
||||
"integrity": "sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/compiler-core": "3.5.24",
|
||||
"@vue/shared": "3.5.24"
|
||||
"@vue/compiler-core": "3.5.25",
|
||||
"@vue/shared": "3.5.25"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/server-renderer/node_modules/@vue/compiler-ssr": {
|
||||
"version": "3.5.24",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.24.tgz",
|
||||
"integrity": "sha512-trOvMWNBMQ/odMRHW7Ae1CdfYx+7MuiQu62Jtu36gMLXcaoqKvAyh+P73sYG9ll+6jLB6QPovqoKGGZROzkFFg==",
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.25.tgz",
|
||||
"integrity": "sha512-ritPSKLBcParnsKYi+GNtbdbrIE1mtuFEJ4U1sWeuOMlIziK5GtOL85t5RhsNy4uWIXPgk+OUdpnXiTdzn8o3A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/compiler-dom": "3.5.24",
|
||||
"@vue/shared": "3.5.24"
|
||||
"@vue/compiler-dom": "3.5.25",
|
||||
"@vue/shared": "3.5.25"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/server-renderer/node_modules/@vue/shared": {
|
||||
"version": "3.5.24",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.24.tgz",
|
||||
"integrity": "sha512-9cwHL2EsJBdi8NY22pngYYWzkTDhld6fAD6jlaeloNGciNSJL6bLpbxVgXl96X00Jtc6YWQv96YA/0sxex/k1A==",
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.25.tgz",
|
||||
"integrity": "sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@vue/server-renderer/node_modules/entities": {
|
||||
@@ -1399,6 +1516,13 @@
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/alien-signals": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/alien-signals/-/alien-signals-3.1.1.tgz",
|
||||
"integrity": "sha512-ogkIWbVrLwKtHY6oOAXaYkAxP+cTH7V5FZ5+Tm4NZFd8VDZ6uNMDrfzqctTZ42eTMCSR3ne3otpcxmqSnFfPYA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
@@ -1739,9 +1863,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/bwip-js": {
|
||||
"version": "4.7.0",
|
||||
"resolved": "https://registry.npmmirror.com/bwip-js/-/bwip-js-4.7.0.tgz",
|
||||
"integrity": "sha512-b7oQcgbWUl8rpcZayQ32SQrBCNteiZFuLkimKKBRlPwIHCeUN2VNeUE3HCMYShe04Evxd+ucS9uUAOsvNKjQbA==",
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmmirror.com/bwip-js/-/bwip-js-4.8.0.tgz",
|
||||
"integrity": "sha512-gUDkDHSTv8/DJhomSIbO0fX/Dx0MO/sgllLxJyJfu4WixCQe9nfGJzmHm64ZCbxo+gUYQEsQcRmqcwcwPRwUkg==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"bwip-js": "bin/bwip-js.js"
|
||||
@@ -2046,9 +2170,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/core-js": {
|
||||
"version": "3.46.0",
|
||||
"resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.46.0.tgz",
|
||||
"integrity": "sha512-vDMm9B0xnqqZ8uSBpZ8sNtRtOdmfShrvT6h2TuQGLs0Is+cR0DYbj/KWP6ALVNbWPpqA/qPLoOuppJN07humpA==",
|
||||
"version": "3.47.0",
|
||||
"resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.47.0.tgz",
|
||||
"integrity": "sha512-c3Q2VVkGAUyupsjRnaNX6u8Dq2vAdzm9iuPj5FW0fRxzlxgq9Q39MDq10IvmQSpLgHQNyQzQmOo6bgGHmH3NNg==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
@@ -2222,9 +2346,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/csstype": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz",
|
||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.2.3.tgz",
|
||||
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/d3": {
|
||||
@@ -3540,9 +3664,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.4.tgz",
|
||||
"integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.5.tgz",
|
||||
"integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
@@ -4702,12 +4826,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/jspdf": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/jspdf/-/jspdf-3.0.3.tgz",
|
||||
"integrity": "sha512-eURjAyz5iX1H8BOYAfzvdPfIKK53V7mCpBTe7Kb16PaM8JSXEcUQNBQaiWMI8wY5RvNOPj4GccMjTlfwRBd+oQ==",
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmmirror.com/jspdf/-/jspdf-3.0.4.tgz",
|
||||
"integrity": "sha512-dc6oQ8y37rRcHn316s4ngz/nOjayLF/FFxBF4V9zamQKRqXxyiH1zagkCdktdWhtoQId5K20xt1lB90XzkB+hQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.26.9",
|
||||
"@babel/runtime": "^7.28.4",
|
||||
"fast-png": "^6.2.0",
|
||||
"fflate": "^0.8.1"
|
||||
},
|
||||
@@ -5007,6 +5131,13 @@
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/muggle-string": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmmirror.com/muggle-string/-/muggle-string-0.4.1.tgz",
|
||||
"integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.11",
|
||||
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz",
|
||||
@@ -5390,6 +5521,13 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/path-browserify": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/path-browserify/-/path-browserify-1.0.1.tgz",
|
||||
"integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/path-parse": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz",
|
||||
@@ -6014,9 +6152,9 @@
|
||||
"license": "Unlicense"
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "4.53.2",
|
||||
"resolved": "https://registry.npmmirror.com/rollup/-/rollup-4.53.2.tgz",
|
||||
"integrity": "sha512-MHngMYwGJVi6Fmnk6ISmnk7JAHRNF0UkuucA0CUW3N3a4KnONPEZz+vUanQP/ZC/iY1Qkf3bwPWzyY84wEks1g==",
|
||||
"version": "4.53.3",
|
||||
"resolved": "https://registry.npmmirror.com/rollup/-/rollup-4.53.3.tgz",
|
||||
"integrity": "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -6030,28 +6168,28 @@
|
||||
"npm": ">=8.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rollup/rollup-android-arm-eabi": "4.53.2",
|
||||
"@rollup/rollup-android-arm64": "4.53.2",
|
||||
"@rollup/rollup-darwin-arm64": "4.53.2",
|
||||
"@rollup/rollup-darwin-x64": "4.53.2",
|
||||
"@rollup/rollup-freebsd-arm64": "4.53.2",
|
||||
"@rollup/rollup-freebsd-x64": "4.53.2",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.53.2",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.53.2",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.53.2",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.53.2",
|
||||
"@rollup/rollup-linux-loong64-gnu": "4.53.2",
|
||||
"@rollup/rollup-linux-ppc64-gnu": "4.53.2",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.53.2",
|
||||
"@rollup/rollup-linux-riscv64-musl": "4.53.2",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.53.2",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.53.2",
|
||||
"@rollup/rollup-linux-x64-musl": "4.53.2",
|
||||
"@rollup/rollup-openharmony-arm64": "4.53.2",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.53.2",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.53.2",
|
||||
"@rollup/rollup-win32-x64-gnu": "4.53.2",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.53.2",
|
||||
"@rollup/rollup-android-arm-eabi": "4.53.3",
|
||||
"@rollup/rollup-android-arm64": "4.53.3",
|
||||
"@rollup/rollup-darwin-arm64": "4.53.3",
|
||||
"@rollup/rollup-darwin-x64": "4.53.3",
|
||||
"@rollup/rollup-freebsd-arm64": "4.53.3",
|
||||
"@rollup/rollup-freebsd-x64": "4.53.3",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.53.3",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.53.3",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.53.3",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.53.3",
|
||||
"@rollup/rollup-linux-loong64-gnu": "4.53.3",
|
||||
"@rollup/rollup-linux-ppc64-gnu": "4.53.3",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.53.3",
|
||||
"@rollup/rollup-linux-riscv64-musl": "4.53.3",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.53.3",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.53.3",
|
||||
"@rollup/rollup-linux-x64-musl": "4.53.3",
|
||||
"@rollup/rollup-openharmony-arm64": "4.53.3",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.53.3",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.53.3",
|
||||
"@rollup/rollup-win32-x64-gnu": "4.53.3",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.53.3",
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
@@ -7351,6 +7489,20 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.9.3",
|
||||
"resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.9.3.tgz",
|
||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||
"devOptional": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/ufo": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npmmirror.com/ufo/-/ufo-1.6.1.tgz",
|
||||
@@ -7796,17 +7948,24 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/vscode-uri": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/vscode-uri/-/vscode-uri-3.1.0.tgz",
|
||||
"integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/vue": {
|
||||
"version": "3.5.24",
|
||||
"resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.24.tgz",
|
||||
"integrity": "sha512-uTHDOpVQTMjcGgrqFPSb8iO2m1DUvo+WbGqoXQz8Y1CeBYQ0FXf2z1gLRaBtHjlRz7zZUBHxjVB5VTLzYkvftg==",
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.25.tgz",
|
||||
"integrity": "sha512-YLVdgv2K13WJ6n+kD5owehKtEXwdwXuj2TTyJMsO7pSeKw2bfRNZGjhB7YzrpbMYj5b5QsUebHpOqR3R3ziy/g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/compiler-dom": "3.5.24",
|
||||
"@vue/compiler-sfc": "3.5.24",
|
||||
"@vue/runtime-dom": "3.5.24",
|
||||
"@vue/server-renderer": "3.5.24",
|
||||
"@vue/shared": "3.5.24"
|
||||
"@vue/compiler-dom": "3.5.25",
|
||||
"@vue/compiler-sfc": "3.5.25",
|
||||
"@vue/runtime-dom": "3.5.25",
|
||||
"@vue/server-renderer": "3.5.25",
|
||||
"@vue/shared": "3.5.25"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "*"
|
||||
@@ -7901,40 +8060,57 @@
|
||||
"vue": "^3.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-tsc": {
|
||||
"version": "3.1.8",
|
||||
"resolved": "https://registry.npmmirror.com/vue-tsc/-/vue-tsc-3.1.8.tgz",
|
||||
"integrity": "sha512-deKgwx6exIHeZwF601P1ktZKNF0bepaSN4jBU3AsbldPx9gylUc1JDxYppl82yxgkAgaz0Y0LCLOi+cXe9HMYA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@volar/typescript": "2.4.26",
|
||||
"@vue/language-core": "3.1.8"
|
||||
},
|
||||
"bin": {
|
||||
"vue-tsc": "bin/vue-tsc.js"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vue/node_modules/@vue/compiler-core": {
|
||||
"version": "3.5.24",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.24.tgz",
|
||||
"integrity": "sha512-eDl5H57AOpNakGNAkFDH+y7kTqrQpJkZFXhWZQGyx/5Wh7B1uQYvcWkvZi11BDhscPgj8N7XV3oRwiPnx1Vrig==",
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.25.tgz",
|
||||
"integrity": "sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.28.5",
|
||||
"@vue/shared": "3.5.24",
|
||||
"@vue/shared": "3.5.25",
|
||||
"entities": "^4.5.0",
|
||||
"estree-walker": "^2.0.2",
|
||||
"source-map-js": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/vue/node_modules/@vue/compiler-dom": {
|
||||
"version": "3.5.24",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.24.tgz",
|
||||
"integrity": "sha512-1QHGAvs53gXkWdd3ZMGYuvQFXHW4ksKWPG8HP8/2BscrbZ0brw183q2oNWjMrSWImYLHxHrx1ItBQr50I/q2zw==",
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.25.tgz",
|
||||
"integrity": "sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/compiler-core": "3.5.24",
|
||||
"@vue/shared": "3.5.24"
|
||||
"@vue/compiler-core": "3.5.25",
|
||||
"@vue/shared": "3.5.25"
|
||||
}
|
||||
},
|
||||
"node_modules/vue/node_modules/@vue/compiler-sfc": {
|
||||
"version": "3.5.24",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.24.tgz",
|
||||
"integrity": "sha512-8EG5YPRgmTB+YxYBM3VXy8zHD9SWHUJLIGPhDovo3Z8VOgvP+O7UP5vl0J4BBPWYD9vxtBabzW1EuEZ+Cqs14g==",
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.25.tgz",
|
||||
"integrity": "sha512-PUgKp2rn8fFsI++lF2sO7gwO2d9Yj57Utr5yEsDf3GNaQcowCLKL7sf+LvVFvtJDXUp/03+dC6f2+LCv5aK1ag==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.28.5",
|
||||
"@vue/compiler-core": "3.5.24",
|
||||
"@vue/compiler-dom": "3.5.24",
|
||||
"@vue/compiler-ssr": "3.5.24",
|
||||
"@vue/shared": "3.5.24",
|
||||
"@vue/compiler-core": "3.5.25",
|
||||
"@vue/compiler-dom": "3.5.25",
|
||||
"@vue/compiler-ssr": "3.5.25",
|
||||
"@vue/shared": "3.5.25",
|
||||
"estree-walker": "^2.0.2",
|
||||
"magic-string": "^0.30.21",
|
||||
"postcss": "^8.5.6",
|
||||
@@ -7942,19 +8118,19 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vue/node_modules/@vue/compiler-ssr": {
|
||||
"version": "3.5.24",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.24.tgz",
|
||||
"integrity": "sha512-trOvMWNBMQ/odMRHW7Ae1CdfYx+7MuiQu62Jtu36gMLXcaoqKvAyh+P73sYG9ll+6jLB6QPovqoKGGZROzkFFg==",
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.25.tgz",
|
||||
"integrity": "sha512-ritPSKLBcParnsKYi+GNtbdbrIE1mtuFEJ4U1sWeuOMlIziK5GtOL85t5RhsNy4uWIXPgk+OUdpnXiTdzn8o3A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/compiler-dom": "3.5.24",
|
||||
"@vue/shared": "3.5.24"
|
||||
"@vue/compiler-dom": "3.5.25",
|
||||
"@vue/shared": "3.5.25"
|
||||
}
|
||||
},
|
||||
"node_modules/vue/node_modules/@vue/shared": {
|
||||
"version": "3.5.24",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.24.tgz",
|
||||
"integrity": "sha512-9cwHL2EsJBdi8NY22pngYYWzkTDhld6fAD6jlaeloNGciNSJL6bLpbxVgXl96X00Jtc6YWQv96YA/0sxex/k1A==",
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.25.tgz",
|
||||
"integrity": "sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/vue/node_modules/entities": {
|
||||
|
||||
@@ -48,13 +48,16 @@
|
||||
"vue-router": "4.2.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^25.0.1",
|
||||
"@vitejs/plugin-vue": "4.5.0",
|
||||
"@vue/compiler-sfc": "3.3.9",
|
||||
"sass": "1.69.5",
|
||||
"typescript": "^5.9.3",
|
||||
"unplugin-auto-import": "0.17.1",
|
||||
"unplugin-vue-setup-extend-plus": "1.0.0",
|
||||
"vite": "5.0.4",
|
||||
"vite-plugin-compression": "0.5.1",
|
||||
"vite-plugin-svg-icons": "2.0.1"
|
||||
"vite-plugin-svg-icons": "2.0.1",
|
||||
"vue-tsc": "^3.1.8"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,48 +1,48 @@
|
||||
import request from '@/utils/request'
|
||||
import request from '@/utils/request';
|
||||
|
||||
// 获取追溯码
|
||||
export function searchTraceNo(data) {
|
||||
return request({
|
||||
url:'/app-common/search-trace-no',
|
||||
url: '/app-common/search-trace-no',
|
||||
method: 'get',
|
||||
params: data,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 获取处方打印数据
|
||||
export function advicePrint(data) {
|
||||
return request({
|
||||
url:'/app-common/advice-print',
|
||||
url: '/app-common/advice-print',
|
||||
method: 'get',
|
||||
params: data,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 获取全部科室列表
|
||||
export function getOrgList(data) {
|
||||
return request({
|
||||
url:'/app-common/department-list',
|
||||
url: '/app-common/department-list',
|
||||
method: 'get',
|
||||
params: data,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 获取全部病区列表
|
||||
export function getWardList(data) {
|
||||
return request({
|
||||
url:'/app-common/ward-list',
|
||||
url: '/app-common/ward-list',
|
||||
method: 'get',
|
||||
params: data,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 获取全部供应商列表
|
||||
export function getSupplierList(data) {
|
||||
return request({
|
||||
url:'/app-common/supplier',
|
||||
url: '/app-common/supplier',
|
||||
method: 'get',
|
||||
params: data,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,8 +52,8 @@ export function getAdjustPriceSwitchState(params) {
|
||||
return request({
|
||||
url: '/change/price/getAdjustPriceSwitchState',
|
||||
method: 'get',
|
||||
params: params
|
||||
})
|
||||
params: params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,34 +63,33 @@ export function lotNumberMatch(params) {
|
||||
return request({
|
||||
url: '/app-common/lot-number-match',
|
||||
method: 'get',
|
||||
params: params
|
||||
})
|
||||
params: params,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
const env = import.meta.env.MODE;
|
||||
export function invokeYbPlugin(data) {
|
||||
export function invokeYbPlugin5001(data) {
|
||||
|
||||
// if(env == 'development'){
|
||||
// return axios.create(
|
||||
// {
|
||||
// // axios中请求配置有baseURL选项,表示请求URL公共部分
|
||||
// baseURL: '/ybplugin',//ybplugin
|
||||
// // 超时
|
||||
// timeout: 60000
|
||||
// }
|
||||
// ).post('/api/data/', data);
|
||||
return axios
|
||||
.create({
|
||||
// axios中请求配置有baseURL选项,表示请求URL公共部分
|
||||
baseURL: '',
|
||||
// 超时
|
||||
timeout: 60000,
|
||||
})
|
||||
.post('http://localhost:5001/api/data/', data);
|
||||
}
|
||||
// }
|
||||
|
||||
// } else {
|
||||
return axios.create(
|
||||
{
|
||||
export function invokeYbPlugin5000(data) {
|
||||
return axios
|
||||
.create({
|
||||
// axios中请求配置有baseURL选项,表示请求URL公共部分
|
||||
baseURL: '',
|
||||
// 超时
|
||||
timeout: 60000
|
||||
}
|
||||
).post('http://localhost:5000/api/data/', data);
|
||||
}
|
||||
// }
|
||||
timeout: 60000,
|
||||
})
|
||||
.post('http://localhost:5000/api/data/', data);
|
||||
}
|
||||
BIN
openhis-ui-vue3/src/assets/images/weixinzhifu.png
Normal file
BIN
openhis-ui-vue3/src/assets/images/weixinzhifu.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.0 KiB |
BIN
openhis-ui-vue3/src/assets/images/zhifubaozhifu.png
Normal file
BIN
openhis-ui-vue3/src/assets/images/zhifubaozhifu.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
51
openhis-ui-vue3/src/components/Layout/index.vue
Normal file
51
openhis-ui-vue3/src/components/Layout/index.vue
Normal file
@@ -0,0 +1,51 @@
|
||||
<template>
|
||||
<div class="page-container">
|
||||
<div v-if="$slots.header" class="page-header">
|
||||
<slot name="header" />
|
||||
</div>
|
||||
<div class="page-content">
|
||||
<slot />
|
||||
</div>
|
||||
<div v-if="$slots.footer" class="page-footer">
|
||||
<slot name="footer" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped lang="scss">
|
||||
.page-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
padding: 16px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.page-content {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.page-footer {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 16px;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid #ebeef5;
|
||||
}
|
||||
</style>
|
||||
12
openhis-ui-vue3/src/components/PatientList/api.js
Normal file
12
openhis-ui-vue3/src/components/PatientList/api.js
Normal file
@@ -0,0 +1,12 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
/**
|
||||
* 获取住院患者列表
|
||||
*/
|
||||
export function getPatientList(queryParams) {
|
||||
return request({
|
||||
url: '/reg-doctorstation/advice-manage/reg-patient-zk',
|
||||
method: 'get',
|
||||
params: queryParams,
|
||||
});
|
||||
}
|
||||
695
openhis-ui-vue3/src/components/PatientList/index.vue
Normal file
695
openhis-ui-vue3/src/components/PatientList/index.vue
Normal file
@@ -0,0 +1,695 @@
|
||||
<template>
|
||||
<div class="patientList-container" :class="{ 'patientList-container-unexpand': !currentExpand }">
|
||||
<div
|
||||
class="patientList-operate"
|
||||
:class="{ 'patientList-operate-unexpand': !currentExpand }"
|
||||
v-if="currentExpand"
|
||||
>
|
||||
<el-input
|
||||
class="patientList-search-input"
|
||||
placeholder="床号/住院号/姓名"
|
||||
v-model="searchKeyword"
|
||||
@keyup.enter="handleSearch"
|
||||
:prefix-icon="Search"
|
||||
/>
|
||||
<el-button class="icon-btn" circle @click="handleRefresh" type="text" plain>
|
||||
<el-icon icon-class="Refresh" size="24" :class="{ 'is-rotating': refreshing }">
|
||||
<Refresh />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<transition name="patient-list-toggle" mode="out-in">
|
||||
<div key="expanded" class="patientList-list" v-if="currentExpand">
|
||||
<div class="patient-cards" v-loading="isLoading">
|
||||
<template v-if="filteredCardData && filteredCardData.length > 0">
|
||||
<el-scrollbar ref="expandScrollbarRef" class="patient-cards-scrollbar">
|
||||
<div
|
||||
class="patient-card"
|
||||
v-for="item in filteredCardData"
|
||||
:key="item.encounterId"
|
||||
:id="item.encounterId"
|
||||
@click="handleItemClick(item)"
|
||||
:class="{ actived: activeCardId === item.encounterId }"
|
||||
>
|
||||
<div class="patient-card-header">
|
||||
<div class="header-top">
|
||||
<div class="bed-container">
|
||||
<div class="bed">
|
||||
<div class="bed-info">
|
||||
<div v-if="item.houseName" class="house-name">{{ item.houseName }}</div>
|
||||
<div class="bed-name">{{ item.bedName || '未分床' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-space>
|
||||
<el-tag
|
||||
v-if="item.statusEnum_enumText"
|
||||
size="small"
|
||||
class="payer-tag-status"
|
||||
effect="light"
|
||||
:style="getStatusStyle(item.statusEnum)"
|
||||
>
|
||||
{{ item.statusEnum_enumText }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="item.contractName"
|
||||
size="small"
|
||||
class="payer-tag"
|
||||
effect="light"
|
||||
>
|
||||
{{ item.contractName }}
|
||||
</el-tag>
|
||||
</el-space>
|
||||
</div>
|
||||
|
||||
<div class="header-bottom">
|
||||
<span class="bus-no">住院号:{{ item.busNo || '-' }}</span>
|
||||
<span class="insurance-type" v-if="item.insutype_dictText">
|
||||
险种类型:{{ item.insutype_dictText }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="doctor-parent-line" />
|
||||
|
||||
<div class="patient-card-body">
|
||||
<div class="personal-info-container">
|
||||
<div class="name-container">
|
||||
<div class="name">
|
||||
<el-text :text="item.patientName" tclass="name" width="auto">
|
||||
{{ item.patientName || '-' }}
|
||||
</el-text>
|
||||
</div>
|
||||
<div class="age">
|
||||
<el-tag
|
||||
size="small"
|
||||
class="age-tag"
|
||||
effect="plain"
|
||||
:class="{ 'age-tag-female': item.genderEnum_enumText === '女性' }"
|
||||
>
|
||||
{{ item.genderEnum_enumText || '-' }}
|
||||
<span v-if="item.age"> · {{ item.age }}</span>
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</template>
|
||||
<el-empty v-else description="暂无数据" />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
key="collapsed"
|
||||
class="patientList-list"
|
||||
v-else
|
||||
v-loading="isLoading"
|
||||
:class="{ 'patientList-list-unexpand': !currentExpand }"
|
||||
>
|
||||
<el-scrollbar ref="contractScrollbarRef" class="patient-cards-scrollbar">
|
||||
<template v-if="filteredCardData && filteredCardData.length > 0">
|
||||
<el-tooltip
|
||||
v-for="item in filteredCardData"
|
||||
:show-after="200"
|
||||
:key="item.encounterId"
|
||||
:show-arrow="true"
|
||||
placement="right"
|
||||
effect="light"
|
||||
:offset="4"
|
||||
>
|
||||
<template #content>
|
||||
<div class="card-tooltip">
|
||||
<div class="card-tooltip-main">
|
||||
<span class="card-tooltip-bed">{{ item.bedName }}</span>
|
||||
<span class="card-tooltip-name">{{ item.patientName }}</span>
|
||||
</div>
|
||||
<div class="card-tooltip-sex">
|
||||
<span class="card-tooltip-sex-text">
|
||||
{{ item.genderEnum_enumText || '-' }}
|
||||
<span v-if="item.age"> · {{ item.age }}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div>
|
||||
<div
|
||||
class="card-small"
|
||||
:class="{ 'patient-active': activeCardId === item.encounterId }"
|
||||
@click="handleSmallCardClick(item)"
|
||||
:key="item.encounterId"
|
||||
>
|
||||
{{ item.bedName }}
|
||||
</div>
|
||||
<div class="patient-card-small-border"></div>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-empty v-else description="暂无数据" :image-size="50" />
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<div
|
||||
class="patientList-toggle-btn-wrap"
|
||||
:class="{ 'patientList-toggle-btn-wrap-unexpand': !currentExpand }"
|
||||
>
|
||||
<el-button class="icon-btn" circle @click="updateExpand">
|
||||
<el-icon class="svg-sty-menu" size="24">
|
||||
<Expand v-if="!currentExpand" />
|
||||
<Fold v-if="currentExpand" />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch } from 'vue';
|
||||
import { Search, Refresh, Expand, Fold } from '@element-plus/icons-vue';
|
||||
import type { ElScrollbar } from 'element-plus';
|
||||
|
||||
interface PatientCardItem {
|
||||
encounterId: string;
|
||||
bedName?: string;
|
||||
busNo?: string;
|
||||
patientName?: string;
|
||||
genderEnum_enumText?: string;
|
||||
age?: number | string;
|
||||
contractName?: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
// 过滤后的卡片数据
|
||||
filteredCardData?: PatientCardItem[];
|
||||
// 当前激活的卡片ID
|
||||
activeCardId?: string;
|
||||
// 是否展开(不传则为不受控模式,组件内部自己管理)
|
||||
expand?: boolean;
|
||||
// 加载状态
|
||||
loading?: boolean;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
filteredCardData: () => [],
|
||||
activeCardId: '',
|
||||
expand: undefined,
|
||||
loading: false,
|
||||
});
|
||||
|
||||
interface Emits {
|
||||
(e: 'item-click', item: PatientCardItem): void;
|
||||
(e: 'search', keyword: string): void;
|
||||
(e: 'refresh'): void;
|
||||
(e: 'update:expand', value: boolean): void;
|
||||
}
|
||||
|
||||
const emit = defineEmits<Emits>();
|
||||
|
||||
const searchKeyword = ref<string>('');
|
||||
const refreshing = ref<boolean>(false);
|
||||
const refreshLoading = ref<boolean>(false);
|
||||
|
||||
const internalExpand = ref<boolean>(true);
|
||||
|
||||
const isControlled = computed<boolean>(() => props.expand !== undefined);
|
||||
|
||||
const currentExpand = computed<boolean>(() => {
|
||||
return isControlled.value ? props.expand! : internalExpand.value;
|
||||
});
|
||||
|
||||
const isLoading = computed<boolean>(() => {
|
||||
return props.loading || refreshLoading.value;
|
||||
});
|
||||
|
||||
const handleItemClick = (item: PatientCardItem): void => {
|
||||
emit('item-click', item);
|
||||
};
|
||||
|
||||
const handleSmallCardClick = (item: PatientCardItem): void => {
|
||||
emit('item-click', item);
|
||||
};
|
||||
|
||||
const handleSearch = (): void => {
|
||||
emit('search', searchKeyword.value);
|
||||
};
|
||||
|
||||
const handleRefresh = (): void => {
|
||||
if (refreshing.value) return;
|
||||
refreshing.value = true;
|
||||
refreshLoading.value = true;
|
||||
emit('refresh');
|
||||
setTimeout(() => {
|
||||
refreshing.value = false;
|
||||
}, 600);
|
||||
|
||||
setTimeout(() => {
|
||||
if (!props.loading) {
|
||||
refreshLoading.value = false;
|
||||
}
|
||||
}, 500);
|
||||
};
|
||||
|
||||
const updateExpand = (): void => {
|
||||
const newValue = !currentExpand.value;
|
||||
if (isControlled.value) {
|
||||
emit('update:expand', newValue);
|
||||
} else {
|
||||
internalExpand.value = newValue;
|
||||
}
|
||||
};
|
||||
|
||||
// 根据状态枚举值返回文本颜色
|
||||
const getStatusColor = (statusEnum?: number): string => {
|
||||
if (statusEnum === undefined || statusEnum === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
switch (statusEnum) {
|
||||
case 2: // REGISTERED - 待入科
|
||||
return '#E6A23C'; // 橙色
|
||||
case 3: // AWAITING_DISCHARGE - 待出院
|
||||
return '#F56C6C'; // 红色
|
||||
case 4: // DISCHARGED_FROM_HOSPITAL - 待出院结算
|
||||
return '#909399'; // 灰色
|
||||
case 5: // ADMITTED_TO_THE_HOSPITAL - 已入院
|
||||
return '#67C23A'; // 绿色
|
||||
case 6: // PENDING_TRANSFER - 待转科
|
||||
return '#409EFF'; // 蓝色
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
// 根据状态枚举值返回带透明背景的样式
|
||||
const getStatusStyle = (statusEnum?: number): Record<string, string> => {
|
||||
const color = getStatusColor(statusEnum);
|
||||
if (!color) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// 不同状态对应的半透明背景色
|
||||
let backgroundColor = '';
|
||||
switch (statusEnum) {
|
||||
case 2: // 橙色
|
||||
backgroundColor = 'rgba(230, 162, 60, 0.12)';
|
||||
break;
|
||||
case 3: // 红色
|
||||
backgroundColor = 'rgba(245, 108, 108, 0.12)';
|
||||
break;
|
||||
case 4: // 灰色
|
||||
backgroundColor = 'rgba(144, 147, 153, 0.12)';
|
||||
break;
|
||||
case 5: // 绿色
|
||||
backgroundColor = 'rgba(103, 194, 58, 0.12)';
|
||||
break;
|
||||
case 6: // 蓝色
|
||||
backgroundColor = 'rgba(64, 158, 255, 0.12)';
|
||||
break;
|
||||
default:
|
||||
backgroundColor = 'rgba(148, 163, 184, 0.12)';
|
||||
}
|
||||
|
||||
return {
|
||||
color,
|
||||
backgroundColor,
|
||||
borderColor: 'transparent',
|
||||
};
|
||||
};
|
||||
|
||||
// 保险类型映射表
|
||||
const insuranceTypeMap: Record<number, string> = {
|
||||
310: '职工基本医疗保险',
|
||||
320: '公务员医疗补助',
|
||||
330: '大额医疗费用补助',
|
||||
340: '离休人员医疗保障',
|
||||
350: '一至六级残废军人医疗补助',
|
||||
360: '老红军医疗保障',
|
||||
370: '企业补充医疗保险',
|
||||
380: '新型农村合作医疗',
|
||||
390: '城乡居民基本医疗保险',
|
||||
391: '城镇居民基本医疗保险',
|
||||
392: '城乡居民大病医疗保险',
|
||||
399: '其他特殊人员医疗保障',
|
||||
410: '长期照护保险',
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.loading,
|
||||
(newLoading) => {
|
||||
if (!newLoading && refreshLoading.value) {
|
||||
refreshLoading.value = false;
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.patient-card {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
background-color: #fff;
|
||||
border-radius: 6px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.04);
|
||||
box-shadow: 0 2px 6px 0 rgba(15, 35, 52, 0.12);
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 4px 12px rgba(15, 35, 52, 0.18);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
&.actived {
|
||||
background-color: rgba(7, 155, 140, 0.06);
|
||||
border-color: var(--el-color-primary);
|
||||
box-shadow: 0 0 0 1px rgba(7, 155, 140, 0.3), 0 4px 14px rgba(7, 155, 140, 0.25);
|
||||
}
|
||||
|
||||
.patient-card-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 10px 12px 4px;
|
||||
|
||||
.header-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
|
||||
.bed-container {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
|
||||
.bed {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 1;
|
||||
min-width: 0;
|
||||
|
||||
.bed-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
line-height: 1.4;
|
||||
|
||||
.house-name {
|
||||
color: #1f2933;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
white-space: normal;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.bed-name {
|
||||
color: #1f2933;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
white-space: normal;
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.payer-tag {
|
||||
max-width: 120px;
|
||||
font-size: 12px;
|
||||
border-radius: 999px;
|
||||
font-weight: bolder;
|
||||
}
|
||||
.payer-tag-status {
|
||||
font-weight: bolder;
|
||||
border-radius: 999px;
|
||||
}
|
||||
}
|
||||
|
||||
.header-bottom {
|
||||
margin-top: 4px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 2px;
|
||||
color: #6b7280;
|
||||
font-size: 12px;
|
||||
|
||||
.bus-no {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.insurance-type {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.doctor-parent-line {
|
||||
margin: 6px 12px 0;
|
||||
border-bottom: 1px dashed #e5e7eb;
|
||||
}
|
||||
|
||||
.patient-card-body {
|
||||
padding: 8px 12px 10px;
|
||||
|
||||
.personal-info-container {
|
||||
display: block;
|
||||
|
||||
.name-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
|
||||
.name {
|
||||
color: #111827;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.age {
|
||||
flex-shrink: 0;
|
||||
|
||||
.age-tag {
|
||||
border-radius: 999px;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.age-tag-female {
|
||||
border-color: rgb(255, 55, 158);
|
||||
color: rgb(255, 126, 184);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.patientList-container {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
border-right: 1px solid #ebeef5;
|
||||
background-color: #ffffff;
|
||||
width: 240px;
|
||||
min-width: 240px;
|
||||
&-unexpand {
|
||||
width: 84px;
|
||||
min-width: 84px;
|
||||
}
|
||||
.patientList-operate {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
min-height: 44px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
flex: none;
|
||||
padding: 0 0 0 8px;
|
||||
|
||||
&-unexpand {
|
||||
justify-content: space-around;
|
||||
}
|
||||
}
|
||||
|
||||
.patientList-list {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
height: 0;
|
||||
width: 240px;
|
||||
&-unexpand {
|
||||
width: 84px;
|
||||
}
|
||||
|
||||
.search-operate {
|
||||
padding: 0 8px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.patient-cards {
|
||||
flex: 1;
|
||||
padding: 0 8px;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
:deep(.patient-cards-scrollbar) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.el-scrollbar__bar {
|
||||
width: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-small {
|
||||
height: 44px;
|
||||
padding: 0 10px 0 12px;
|
||||
overflow: hidden;
|
||||
font-size: 14px;
|
||||
line-height: 44px;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
border-right: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.patient-active {
|
||||
background-color: #e6f7ff;
|
||||
font-weight: 600;
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
.patient-card-small-border {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
background-color: #f1faff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.patientList-toggle-btn-wrap {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 4px 16px 8px;
|
||||
&-unexpand {
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.patient-list-toggle-enter-active,
|
||||
.patient-list-toggle-leave-active {
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.patient-list-toggle-enter-from,
|
||||
.patient-list-toggle-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(-8px);
|
||||
}
|
||||
|
||||
.card-tooltip {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
min-width: 140px;
|
||||
max-width: 220px;
|
||||
padding: 6px 10px;
|
||||
border-radius: 6px;
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
.card-tooltip-main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.card-tooltip-bed {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #111827;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.card-tooltip-name {
|
||||
font-size: 13px;
|
||||
color: #4b5563;
|
||||
}
|
||||
|
||||
.card-tooltip-sex {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.card-tooltip-sex-text {
|
||||
font-size: 12px;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.svg-gray {
|
||||
fill: var(--hip-color-text-unit);
|
||||
}
|
||||
|
||||
.icon-btn {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
box-shadow: none;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.is-rotating {
|
||||
animation: patient-refresh-rotate 0.6s linear;
|
||||
}
|
||||
|
||||
@keyframes patient-refresh-rotate {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.scrollbar) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.el-scrollbar__bar {
|
||||
width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.f-16 {
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.f-14 {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.empty-wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
|
||||
.empty-text-sty {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
110
openhis-ui-vue3/src/components/PatientList/patient-list.vue
Normal file
110
openhis-ui-vue3/src/components/PatientList/patient-list.vue
Normal file
@@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<BasePatientList
|
||||
:filtered-card-data="filteredCardData"
|
||||
:active-card-id="cardId"
|
||||
:loading="queryloading"
|
||||
@item-click="handleItemClick"
|
||||
@search="handleSearch"
|
||||
@refresh="getList"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, onMounted, reactive, ref, watch } from 'vue';
|
||||
import BasePatientList from './index.vue';
|
||||
import { getPatientList } from '@/views/inpatientDoctor/home/components/api';
|
||||
|
||||
defineOptions({
|
||||
name: 'PatientListWithData',
|
||||
});
|
||||
|
||||
const props = defineProps({
|
||||
/** 接口 status 参数,默认 5(在院) */
|
||||
status: {
|
||||
type: [String, Number],
|
||||
default: undefined,
|
||||
},
|
||||
/** 首次加载自动选中第一条 */
|
||||
autoSelectFirst: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
/** 外部已选中的患者信息(用于避免重复自动选中) */
|
||||
selectedPatient: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
/**
|
||||
* 选中患者时回调(给你外部写 store 用)
|
||||
* (patient) => void
|
||||
*/
|
||||
onSelect: {
|
||||
type: Function,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['item-click']);
|
||||
|
||||
// 这段逻辑就是你说的 “@index.vue (4-11) 那套带数据的”
|
||||
const searchData = reactive({
|
||||
keyword: '',
|
||||
patientType: 1,
|
||||
type: 1,
|
||||
timeLimit: 3,
|
||||
});
|
||||
|
||||
const cardId = ref('');
|
||||
const cardAllData = ref([]);
|
||||
const isFirstLoad = ref(true);
|
||||
const queryloading = ref(false);
|
||||
|
||||
const filteredCardData = computed(() => cardAllData.value);
|
||||
|
||||
const getList = () => {
|
||||
queryloading.value = true;
|
||||
getPatientList({ status: props.status, searchKey: searchData.keyword })
|
||||
.then((res) => {
|
||||
cardAllData.value = res?.data?.records || [];
|
||||
})
|
||||
.finally(() => {
|
||||
queryloading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
watch(
|
||||
() => filteredCardData.value,
|
||||
(newData) => {
|
||||
if (!props.autoSelectFirst) return;
|
||||
if (
|
||||
newData &&
|
||||
newData.length > 0 &&
|
||||
!cardId.value &&
|
||||
isFirstLoad.value &&
|
||||
!props.selectedPatient?.encounterId
|
||||
) {
|
||||
const firstPatient = newData[0];
|
||||
if (firstPatient?.encounterId) {
|
||||
handleItemClick(firstPatient);
|
||||
isFirstLoad.value = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
const handleItemClick = (node) => {
|
||||
cardId.value = node.encounterId;
|
||||
props.onSelect?.(node);
|
||||
emit('item-click', node);
|
||||
};
|
||||
|
||||
const handleSearch = (keyword) => {
|
||||
searchData.keyword = keyword;
|
||||
getList();
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
318
openhis-ui-vue3/src/components/PendingPatientList/index.vue
Normal file
318
openhis-ui-vue3/src/components/PendingPatientList/index.vue
Normal file
@@ -0,0 +1,318 @@
|
||||
<template>
|
||||
<div class="pending-patient-list">
|
||||
<div class="patient-cards" v-loading="loading">
|
||||
<template v-if="list && list.length > 0">
|
||||
<el-scrollbar class="patient-cards-scrollbar">
|
||||
<div
|
||||
class="patient-card"
|
||||
v-for="(item, index) in list"
|
||||
:key="item[idKey] ?? index"
|
||||
:class="{ actived: !!item.active || activeId === item[idKey] }"
|
||||
draggable="true"
|
||||
@click="emit('item-click', item, index)"
|
||||
@dblclick="emit('item-dblclick', item)"
|
||||
@dragstart="(e) => emit('dragstart', e, item)"
|
||||
@dragend="(e) => emit('dragend', e)"
|
||||
>
|
||||
<div class="patient-card-header">
|
||||
<div class="header-top">
|
||||
<div class="bed-container">
|
||||
<div class="bed">
|
||||
<el-text truncated tclass="bed-font" width="auto">
|
||||
{{ item.bedName || '-' }}
|
||||
</el-text>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-tags">
|
||||
<el-tag v-if="item.contractName" size="small" class="payer-tag" effect="light">
|
||||
{{ item.contractName }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="item.encounterStatus_enumText"
|
||||
size="small"
|
||||
class="status-tag"
|
||||
effect="light"
|
||||
:class="getStatusClass(item)"
|
||||
>
|
||||
{{ item.encounterStatus_enumText }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="header-bottom">
|
||||
<span class="bus-no">住院号:{{ item.busNo || '-' }}</span>
|
||||
</div>
|
||||
<div class="meta">
|
||||
<div class="meta-row">
|
||||
<span class="meta-label">入院时间:</span>
|
||||
<span class="meta-value">{{
|
||||
item.startTime ? formatDate(item.startTime) : '-'
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="meta-row">
|
||||
<span class="meta-label">入科时间:</span>
|
||||
<span class="meta-value">{{
|
||||
item.admissionTime ? formatDate(item.admissionTime) : '-'
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="doctor-parent-line" />
|
||||
|
||||
<div class="patient-card-body">
|
||||
<div class="personal-info-container">
|
||||
<div class="name-container">
|
||||
<div class="name">
|
||||
<el-text :text="item.patientName" tclass="name" width="auto">
|
||||
{{ item.patientName || '-' }}
|
||||
</el-text>
|
||||
</div>
|
||||
<div class="age">
|
||||
<el-tag
|
||||
size="small"
|
||||
class="age-tag"
|
||||
effect="plain"
|
||||
:class="{
|
||||
'age-tag-female': item.genderEnum_enumText === '女性',
|
||||
'age-tag-male': item.genderEnum_enumText === '男性',
|
||||
}"
|
||||
>
|
||||
{{ item.genderEnum_enumText || '-' }}
|
||||
<span v-if="item.age"> · {{ item.age }}</span>
|
||||
<span v-if="item.priorityEnum_enumText">
|
||||
· {{ item.priorityEnum_enumText }}</span
|
||||
>
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="meta"></div>
|
||||
</div>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</template>
|
||||
<el-empty v-else description="暂无数据" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { formatDate } from '@/utils/index';
|
||||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
list: any[];
|
||||
activeId?: string | number;
|
||||
idKey?: string;
|
||||
loading?: boolean;
|
||||
}>(),
|
||||
{
|
||||
list: () => [],
|
||||
activeId: '',
|
||||
idKey: 'id',
|
||||
loading: false,
|
||||
}
|
||||
);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'item-click', item: any, index: number): void;
|
||||
(e: 'item-dblclick', item: any): void;
|
||||
(e: 'dragstart', event: DragEvent, item: any): void;
|
||||
(e: 'dragend', event: DragEvent): void;
|
||||
}>();
|
||||
|
||||
const getStatusClass = (item: any) => {
|
||||
if (item?.encounterStatus == 2) return 'status-tag--blue';
|
||||
if (item?.encounterStatus == 5) return 'status-tag--green';
|
||||
return '';
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss" name="PendingPatientList">
|
||||
.pending-patient-list {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
min-width: 240px;
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
.patient-cards {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
|
||||
:deep(.patient-cards-scrollbar) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.el-scrollbar__bar {
|
||||
width: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.patient-card {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
background-color: #fff;
|
||||
border-radius: 6px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.04);
|
||||
box-shadow: 0 2px 6px 0 rgba(15, 35, 52, 0.12);
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 4px 12px rgba(15, 35, 52, 0.18);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
&.actived {
|
||||
background-color: rgba(7, 155, 140, 0.06);
|
||||
border-color: var(--el-color-primary);
|
||||
box-shadow: 0 0 0 1px rgba(7, 155, 140, 0.3), 0 4px 14px rgba(7, 155, 140, 0.25);
|
||||
}
|
||||
}
|
||||
|
||||
.patient-card-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 10px 12px 4px;
|
||||
|
||||
.header-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
|
||||
.bed-container {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
|
||||
.bed {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 1;
|
||||
min-width: 0;
|
||||
|
||||
:deep(.bed-font) {
|
||||
color: #1f2933;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.payer-tag {
|
||||
max-width: 120px;
|
||||
font-size: 12px;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.header-tags {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: flex-end;
|
||||
gap: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.header-bottom {
|
||||
margin-top: 4px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
color: #6b7280;
|
||||
font-size: 12px;
|
||||
|
||||
.bus-no {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.doctor-parent-line {
|
||||
margin: 6px 12px 0;
|
||||
border-bottom: 1px dashed #e5e7eb;
|
||||
}
|
||||
|
||||
.patient-card-body {
|
||||
padding: 8px 12px 10px;
|
||||
}
|
||||
|
||||
.personal-info-container {
|
||||
display: block;
|
||||
|
||||
.name-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
|
||||
.name {
|
||||
color: #111827;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.age {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.age-tag {
|
||||
border-radius: 999px;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.age-tag-female {
|
||||
border-color: rgb(255, 55, 158);
|
||||
color: rgb(255, 126, 184);
|
||||
}
|
||||
|
||||
.age-tag-male {
|
||||
border-color: #91d5ff;
|
||||
color: #1677ff;
|
||||
}
|
||||
|
||||
.status-tag {
|
||||
border-radius: 999px;
|
||||
padding: 0 8px;
|
||||
flex-shrink: 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.status-tag--blue {
|
||||
border-color: #91d5ff;
|
||||
background-color: #1677ff;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.status-tag--green {
|
||||
border-color: #b7eb8f;
|
||||
background-color: #389e0d;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.meta {
|
||||
margin-top: 6px;
|
||||
color: #6b7280;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.meta-row {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.meta-label {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -240,7 +240,8 @@
|
||||
"columnId": "totalPrice",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
"colspan": 1,
|
||||
"formatter2": "function(value, row, index, options, rowIndex, column) {\n if (!value) return '';\n return `<span>${value}元</span>`;\n}"
|
||||
},
|
||||
{
|
||||
"title": "类别",
|
||||
|
||||
@@ -1,239 +0,0 @@
|
||||
{
|
||||
"panels": [
|
||||
{
|
||||
"index": 1,
|
||||
"name": 2,
|
||||
"paperType": "自定义",
|
||||
"height": 50,
|
||||
"width": 70,
|
||||
"paperList": {
|
||||
"type": "自定义",
|
||||
"width": 70,
|
||||
"height": 50
|
||||
},
|
||||
"paperHeader": 0,
|
||||
"paperFooter": 138.8976377952756,
|
||||
"paperNumberDisabled": true,
|
||||
"paperNumberContinue": true,
|
||||
"panelAngle": 0,
|
||||
"overPrintOptions": {
|
||||
"content": "",
|
||||
"opacity": 0.01,
|
||||
"type": 1
|
||||
},
|
||||
"watermarkOptions": {
|
||||
"content": "",
|
||||
"fillStyle": "rgba(87, 13, 248, 0.5)",
|
||||
"fontSize": "10px",
|
||||
"rotate": 0,
|
||||
"width": 100,
|
||||
"height": 100,
|
||||
"timestamp": false,
|
||||
"format": "YYYY-MM-DD HH:mm"
|
||||
},
|
||||
"panelLayoutOptions": {
|
||||
"layoutType": "column",
|
||||
"layoutRowGap": 0,
|
||||
"layoutColumnGap": 0
|
||||
},
|
||||
"printElements": [
|
||||
{
|
||||
"options": {
|
||||
"left": 6,
|
||||
"top": 7.5,
|
||||
"height": 15,
|
||||
"width": 51,
|
||||
"title": "文本",
|
||||
"field": "patientName",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"hideTitle": true,
|
||||
"fontSize": 10.5,
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 90,
|
||||
"top": 7.5,
|
||||
"height": 15,
|
||||
"width": 33,
|
||||
"title": "文本",
|
||||
"field": "genderEnum_enumText",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"hideTitle": true,
|
||||
"fontSize": 10.5,
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 147,
|
||||
"top": 7.5,
|
||||
"height": 15,
|
||||
"width": 45,
|
||||
"title": "文本",
|
||||
"field": "age",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"hideTitle": true,
|
||||
"fontSize": 10.5,
|
||||
"fontWeight": "bold",
|
||||
"textAlign": "right"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 6,
|
||||
"top": 33,
|
||||
"height": 15,
|
||||
"width": 81,
|
||||
"title": "频次 qd",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"fontSize": 10.5,
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 122,
|
||||
"top": 33,
|
||||
"height": 15,
|
||||
"width": 70.5,
|
||||
"title": "文本",
|
||||
"field": "date",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"hideTitle": true,
|
||||
"fontSize": 10.5,
|
||||
"fontWeight": "bold",
|
||||
"textAlign": "right"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 4.5,
|
||||
"top": 52.5,
|
||||
"height": 36,
|
||||
"width": 189,
|
||||
"title": "undefined+beforeDragIn",
|
||||
"field": "infuseData",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"tableHeaderBackground": "#ffffff",
|
||||
"tableBodyCellBorder": "noBorder",
|
||||
"rowsColumnsMerge": "function(data, col, colIndex, rowIndex, tableData, printData){ \n // 合并前三列 (columnIndex 0-2)\n if (colIndex >= 0 && colIndex <= 2) {\n // 第一列显示合并后的单元格\n if (colIndex === 0) {\n return [1, 3]; // rowspan=1, colspan=3\n } \n // 其他两列不显示(被合并)\n else {\n return [0, 0]; // rowspan=0, colspan=0\n }\n }\n // 其他列正常显示\n return [1, 1]; // rowspan=1, colspan=1\n}",
|
||||
"tableBodyRowBorder": "topBottomBorder",
|
||||
"columns": [
|
||||
[
|
||||
{
|
||||
"title": "用法",
|
||||
"titleSync": false,
|
||||
"halign": "center",
|
||||
"tableQRCodeLevel": 0,
|
||||
"tableSummaryTitle": true,
|
||||
"tableSummary": "",
|
||||
"width": 45.48982644423766,
|
||||
"field": "data",
|
||||
"checked": true,
|
||||
"columnId": "data",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "剂量",
|
||||
"titleSync": false,
|
||||
"align": "center",
|
||||
"tableQRCodeLevel": 0,
|
||||
"tableSummaryTitle": true,
|
||||
"tableSummary": "",
|
||||
"width": 47.79422504530706,
|
||||
"checked": true,
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "速度",
|
||||
"titleSync": false,
|
||||
"align": "center",
|
||||
"tableQRCodeLevel": 0,
|
||||
"tableSummaryTitle": true,
|
||||
"tableSummary": "",
|
||||
"width": 48.74985321589121,
|
||||
"checked": true,
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "数量",
|
||||
"titleSync": false,
|
||||
"align": "center",
|
||||
"tableQRCodeLevel": 0,
|
||||
"tableSummaryTitle": true,
|
||||
"tableSummary": "",
|
||||
"formatter2": "function(value,row,index,options,rowIndex,column){ return value + ' ' + row.unitCode_dictText; }",
|
||||
"width": 46.96609529456407,
|
||||
"field": "quantity",
|
||||
"checked": true,
|
||||
"columnId": "quantity",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "表格",
|
||||
"type": "table",
|
||||
"editable": true,
|
||||
"columnDisplayEditable": true,
|
||||
"columnDisplayIndexEditable": true,
|
||||
"columnTitleEditable": true,
|
||||
"columnResizable": true,
|
||||
"columnAlignEditable": true,
|
||||
"isEnableEditField": true,
|
||||
"isEnableContextMenu": true,
|
||||
"isEnableInsertRow": true,
|
||||
"isEnableDeleteRow": true,
|
||||
"isEnableInsertColumn": true,
|
||||
"isEnableDeleteColumn": true,
|
||||
"isEnableMergeCell": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"paperNumberLeft": 151.5,
|
||||
"paperNumberTop": 91
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -4,32 +4,31 @@
|
||||
"index": 1,
|
||||
"name": 2,
|
||||
"paperType": "自定义",
|
||||
"height": 34,
|
||||
"width": 58,
|
||||
"height": 60,
|
||||
"width": 80,
|
||||
"paperList": {
|
||||
"type": "自定义",
|
||||
"width": 60,
|
||||
"height": 40
|
||||
"width": 80,
|
||||
"height": 60
|
||||
},
|
||||
"paperHeader": 0,
|
||||
"paperFooter": 91.5,
|
||||
"paperFooter": 166.5,
|
||||
"paperNumberDisabled": true,
|
||||
"paperNumberContinue": true,
|
||||
"expandCss": "",
|
||||
"panelAngle": 0,
|
||||
"overPrintOptions": {
|
||||
"content": "",
|
||||
"opacity": 0.01,
|
||||
"opacity": 0.7,
|
||||
"type": 1
|
||||
},
|
||||
"watermarkOptions": {
|
||||
"content": "",
|
||||
"fillStyle": "rgba(87, 13, 248, 0.5)",
|
||||
"fontSize": "10px",
|
||||
"fontSize": "36px",
|
||||
"rotate": 25,
|
||||
"width": 100,
|
||||
"height": 100,
|
||||
"timestamp": false,
|
||||
"width": 413,
|
||||
"height": 310,
|
||||
"timestamp": true,
|
||||
"format": "YYYY-MM-DD HH:mm"
|
||||
},
|
||||
"panelLayoutOptions": {
|
||||
@@ -43,13 +42,12 @@
|
||||
"left": 6,
|
||||
"top": 7.5,
|
||||
"height": 10,
|
||||
"width": 51,
|
||||
"title": "文本",
|
||||
"width": 69,
|
||||
"title": "病区",
|
||||
"field": "patientName",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"hideTitle": true,
|
||||
"fontSize": 7.5,
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
@@ -60,16 +58,15 @@
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 70,
|
||||
"left": 81,
|
||||
"top": 7.5,
|
||||
"height": 10,
|
||||
"width": 33,
|
||||
"title": "文本",
|
||||
"field": "genderEnum_enumText",
|
||||
"width": 52.5,
|
||||
"title": "姓名",
|
||||
"field": "patientName",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"hideTitle": true,
|
||||
"fontSize": 7.5,
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
@@ -80,19 +77,17 @@
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 119,
|
||||
"left": 147,
|
||||
"top": 7.5,
|
||||
"height": 10,
|
||||
"width": 45,
|
||||
"title": "文本",
|
||||
"field": "age",
|
||||
"width": 72,
|
||||
"title": "床位号",
|
||||
"field": "bedNo",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"hideTitle": true,
|
||||
"fontSize": 7.5,
|
||||
"fontWeight": "bold",
|
||||
"textAlign": "right"
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
@@ -102,7 +97,7 @@
|
||||
{
|
||||
"options": {
|
||||
"left": 6,
|
||||
"top": 19.5,
|
||||
"top": 22,
|
||||
"height": 12,
|
||||
"width": 81,
|
||||
"title": "频次 qd",
|
||||
@@ -119,19 +114,17 @@
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 93,
|
||||
"top": 19.5,
|
||||
"left": 147,
|
||||
"top": 24,
|
||||
"height": 10,
|
||||
"width": 70.5,
|
||||
"title": "文本",
|
||||
"title": "日期",
|
||||
"field": "date",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"hideTitle": true,
|
||||
"fontSize": 7.5,
|
||||
"fontWeight": "bold",
|
||||
"textAlign": "right"
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
@@ -141,9 +134,9 @@
|
||||
{
|
||||
"options": {
|
||||
"left": 4.5,
|
||||
"top": 36,
|
||||
"top": 45,
|
||||
"height": 30,
|
||||
"width": 156,
|
||||
"width": 216,
|
||||
"title": "undefined+beforeDragIn",
|
||||
"field": "infuseData",
|
||||
"coordinateSync": false,
|
||||
@@ -166,7 +159,7 @@
|
||||
"tableQRCodeLevel": 0,
|
||||
"tableSummaryTitle": true,
|
||||
"tableSummary": "",
|
||||
"width": 37.54715833492632,
|
||||
"width": 51.988373079128756,
|
||||
"field": "data",
|
||||
"checked": true,
|
||||
"columnId": "data",
|
||||
@@ -181,21 +174,23 @@
|
||||
"tableQRCodeLevel": 0,
|
||||
"tableSummaryTitle": true,
|
||||
"tableSummary": "",
|
||||
"width": 39.4492016246979,
|
||||
"width": 55.016471480350916,
|
||||
"checked": true,
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "速度",
|
||||
"title": "滴速",
|
||||
"titleSync": false,
|
||||
"align": "center",
|
||||
"tableQRCodeLevel": 0,
|
||||
"tableSummaryTitle": true,
|
||||
"tableSummary": "",
|
||||
"width": 40.23797408295783,
|
||||
"width": 55.31961796101854,
|
||||
"field": "",
|
||||
"checked": true,
|
||||
"columnId": "",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
@@ -208,7 +203,7 @@
|
||||
"tableSummaryTitle": true,
|
||||
"tableSummary": "",
|
||||
"formatter2": "function(value,row,index,options,rowIndex,column){ return value + ' ' + row.unitCode_dictText; }",
|
||||
"width": 38.765665957417966,
|
||||
"width": 53.6755374795018,
|
||||
"field": "quantity",
|
||||
"checked": true,
|
||||
"columnId": "quantity",
|
||||
@@ -236,6 +231,56 @@
|
||||
"isEnableDeleteColumn": true,
|
||||
"isEnableMergeCell": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 10,
|
||||
"top": 144,
|
||||
"height": 9,
|
||||
"width": 210,
|
||||
"borderWidth": "0.75",
|
||||
"title": "undefined+beforeDragIn",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "横线",
|
||||
"type": "hline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 10,
|
||||
"top": 153,
|
||||
"height": 9.75,
|
||||
"width": 82.5,
|
||||
"title": "执行人",
|
||||
"field": "prepareName",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 111,
|
||||
"top": 153,
|
||||
"height": 9.75,
|
||||
"width": 82.5,
|
||||
"title": "时间",
|
||||
"field": "date",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
],
|
||||
"paperNumberLeft": 151.5,
|
||||
|
||||
@@ -4,31 +4,32 @@
|
||||
"index": 1,
|
||||
"name": 2,
|
||||
"paperType": "自定义",
|
||||
"height": 60,
|
||||
"width": 80,
|
||||
"height": 34,
|
||||
"width": 58,
|
||||
"paperList": {
|
||||
"type": "自定义",
|
||||
"width": 80,
|
||||
"height": 60
|
||||
"width": 60,
|
||||
"height": 40
|
||||
},
|
||||
"paperHeader": 0,
|
||||
"paperFooter": 166.5,
|
||||
"paperFooter": 91.5,
|
||||
"paperNumberDisabled": true,
|
||||
"paperNumberContinue": true,
|
||||
"expandCss": "",
|
||||
"panelAngle": 0,
|
||||
"overPrintOptions": {
|
||||
"content": "",
|
||||
"opacity": 0.7,
|
||||
"opacity": 0.01,
|
||||
"type": 1
|
||||
},
|
||||
"watermarkOptions": {
|
||||
"content": "",
|
||||
"fillStyle": "rgba(87, 13, 248, 0.5)",
|
||||
"fontSize": "36px",
|
||||
"fontSize": "10px",
|
||||
"rotate": 25,
|
||||
"width": 413,
|
||||
"height": 310,
|
||||
"timestamp": true,
|
||||
"width": 100,
|
||||
"height": 100,
|
||||
"timestamp": false,
|
||||
"format": "YYYY-MM-DD HH:mm"
|
||||
},
|
||||
"panelLayoutOptions": {
|
||||
@@ -42,12 +43,13 @@
|
||||
"left": 6,
|
||||
"top": 7.5,
|
||||
"height": 10,
|
||||
"width": 69,
|
||||
"title": "病区",
|
||||
"width": 51,
|
||||
"title": "文本",
|
||||
"field": "patientName",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"hideTitle": true,
|
||||
"fontSize": 7.5,
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
@@ -58,15 +60,16 @@
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 81,
|
||||
"left": 70,
|
||||
"top": 7.5,
|
||||
"height": 10,
|
||||
"width": 52.5,
|
||||
"title": "姓名",
|
||||
"field": "patientName",
|
||||
"width": 33,
|
||||
"title": "文本",
|
||||
"field": "genderEnum_enumText",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"hideTitle": true,
|
||||
"fontSize": 7.5,
|
||||
"fontWeight": "bold"
|
||||
},
|
||||
@@ -77,17 +80,19 @@
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 147,
|
||||
"left": 119,
|
||||
"top": 7.5,
|
||||
"height": 10,
|
||||
"width": 72,
|
||||
"title": "床位号",
|
||||
"field": "bedNo",
|
||||
"width": 45,
|
||||
"title": "文本",
|
||||
"field": "age",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"hideTitle": true,
|
||||
"fontSize": 7.5,
|
||||
"fontWeight": "bold"
|
||||
"fontWeight": "bold",
|
||||
"textAlign": "right"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
@@ -97,7 +102,7 @@
|
||||
{
|
||||
"options": {
|
||||
"left": 6,
|
||||
"top": 22,
|
||||
"top": 19.5,
|
||||
"height": 12,
|
||||
"width": 81,
|
||||
"title": "频次 qd",
|
||||
@@ -114,17 +119,19 @@
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 147,
|
||||
"top": 24,
|
||||
"left": 93,
|
||||
"top": 19.5,
|
||||
"height": 10,
|
||||
"width": 70.5,
|
||||
"title": "日期",
|
||||
"title": "文本",
|
||||
"field": "date",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0,
|
||||
"hideTitle": true,
|
||||
"fontSize": 7.5,
|
||||
"fontWeight": "bold"
|
||||
"fontWeight": "bold",
|
||||
"textAlign": "right"
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
@@ -134,9 +141,9 @@
|
||||
{
|
||||
"options": {
|
||||
"left": 4.5,
|
||||
"top": 45,
|
||||
"top": 36,
|
||||
"height": 30,
|
||||
"width": 216,
|
||||
"width": 156,
|
||||
"title": "undefined+beforeDragIn",
|
||||
"field": "infuseData",
|
||||
"coordinateSync": false,
|
||||
@@ -159,7 +166,7 @@
|
||||
"tableQRCodeLevel": 0,
|
||||
"tableSummaryTitle": true,
|
||||
"tableSummary": "",
|
||||
"width": 51.988373079128756,
|
||||
"width": 37.54715833492632,
|
||||
"field": "data",
|
||||
"checked": true,
|
||||
"columnId": "data",
|
||||
@@ -174,23 +181,21 @@
|
||||
"tableQRCodeLevel": 0,
|
||||
"tableSummaryTitle": true,
|
||||
"tableSummary": "",
|
||||
"width": 55.016471480350916,
|
||||
"width": 39.4492016246979,
|
||||
"checked": true,
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
},
|
||||
{
|
||||
"title": "滴速",
|
||||
"title": "速度",
|
||||
"titleSync": false,
|
||||
"align": "center",
|
||||
"tableQRCodeLevel": 0,
|
||||
"tableSummaryTitle": true,
|
||||
"tableSummary": "",
|
||||
"width": 55.31961796101854,
|
||||
"field": "",
|
||||
"width": 40.23797408295783,
|
||||
"checked": true,
|
||||
"columnId": "",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
@@ -203,7 +208,7 @@
|
||||
"tableSummaryTitle": true,
|
||||
"tableSummary": "",
|
||||
"formatter2": "function(value,row,index,options,rowIndex,column){ return value + ' ' + row.unitCode_dictText; }",
|
||||
"width": 53.6755374795018,
|
||||
"width": 38.765665957417966,
|
||||
"field": "quantity",
|
||||
"checked": true,
|
||||
"columnId": "quantity",
|
||||
@@ -231,56 +236,6 @@
|
||||
"isEnableDeleteColumn": true,
|
||||
"isEnableMergeCell": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 10,
|
||||
"top": 144,
|
||||
"height": 9,
|
||||
"width": 210,
|
||||
"borderWidth": "0.75",
|
||||
"title": "undefined+beforeDragIn",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "横线",
|
||||
"type": "hline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 10,
|
||||
"top": 153,
|
||||
"height": 9.75,
|
||||
"width": 82.5,
|
||||
"title": "执行人",
|
||||
"field": "prepareName",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"left": 111,
|
||||
"top": 153,
|
||||
"height": 9.75,
|
||||
"width": 82.5,
|
||||
"title": "时间",
|
||||
"field": "date",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"qrCodeLevel": 0
|
||||
},
|
||||
"printElementType": {
|
||||
"title": "文本",
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
],
|
||||
"paperNumberLeft": 151.5,
|
||||
|
||||
@@ -225,7 +225,8 @@
|
||||
"columnId": "totalPrice",
|
||||
"fixed": false,
|
||||
"rowspan": 1,
|
||||
"colspan": 1
|
||||
"colspan": 1,
|
||||
"formatter2": "function(value, row, index, options, rowIndex, column) {\n if (!value) return '';\n return `<span>${value}元</span>`;\n}"
|
||||
},
|
||||
{
|
||||
"title": "类别",
|
||||
|
||||
60
openhis-ui-vue3/src/components/TableLayout/EditTable.vue
Normal file
60
openhis-ui-vue3/src/components/TableLayout/EditTable.vue
Normal file
@@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<div class="table-section" v-loading="loading">
|
||||
<EditableTable ref="editableTableRef" v-bind="$attrs" class="editable-table">
|
||||
<template v-for="(_, slotName) in $slots" :key="slotName" #[slotName]="slotProps">
|
||||
<slot :name="slotName" v-bind="slotProps" />
|
||||
</template>
|
||||
</EditableTable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import EditableTable from './EditableTable.vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'EditTable',
|
||||
inheritAttrs: false,
|
||||
});
|
||||
|
||||
const props = defineProps({
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const editableTableRef = ref(null);
|
||||
|
||||
defineExpose({
|
||||
get formRef() {
|
||||
return editableTableRef.value?.formRef;
|
||||
},
|
||||
get tableRef() {
|
||||
return editableTableRef.value?.tableRef;
|
||||
},
|
||||
validate: (...args) => editableTableRef.value?.validate(...args),
|
||||
validateField: (...args) => editableTableRef.value?.validateField(...args),
|
||||
resetFields: (...args) => editableTableRef.value?.resetFields(...args),
|
||||
clearValidate: (...args) => editableTableRef.value?.clearValidate(...args),
|
||||
get tableData() {
|
||||
return editableTableRef.value?.tableData;
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.table-section {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.editable-table {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
567
openhis-ui-vue3/src/components/TableLayout/EditableTable.vue
Normal file
567
openhis-ui-vue3/src/components/TableLayout/EditableTable.vue
Normal file
@@ -0,0 +1,567 @@
|
||||
<template>
|
||||
<el-form ref="formRef" :model="{ tableData }" :rules="rules" class="editable-table-form">
|
||||
<div
|
||||
v-if="showAddButton || showDeleteButton || searchFields.length > 0"
|
||||
class="editable-table-toolbar"
|
||||
>
|
||||
<div class="toolbar-left">
|
||||
<el-button v-if="showAddButton" type="primary" icon="Plus" @click="handleToolbarAdd">
|
||||
添加行
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="showDeleteButton"
|
||||
type="danger"
|
||||
icon="Delete"
|
||||
:disabled="selectedRows.length === 0"
|
||||
@click="handleToolbarDelete"
|
||||
>
|
||||
删除行
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="toolbar-right">
|
||||
<el-input
|
||||
v-if="searchFields.length > 0"
|
||||
v-model="searchKeyword"
|
||||
:placeholder="searchPlaceholder"
|
||||
clearable
|
||||
style="width: 300px"
|
||||
@input="handleSearch"
|
||||
>
|
||||
<template #prefix>
|
||||
<el-icon><Search /></el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="filteredTableData"
|
||||
:border="border"
|
||||
:stripe="stripe"
|
||||
:max-height="maxHeight || undefined"
|
||||
:min-height="minHeight || undefined"
|
||||
:height="!maxHeight && !minHeight ? '100%' : undefined"
|
||||
:row-key="getRowKey"
|
||||
:virtualized="useVirtualized"
|
||||
v-bind="$attrs"
|
||||
@selection-change="handleSelectionChange"
|
||||
class="editable-table-inner"
|
||||
>
|
||||
<el-table-column v-if="showSelection" type="selection" width="55" align="center" />
|
||||
<el-table-column
|
||||
v-if="showRowActions"
|
||||
:width="rowActionsColumnWidth"
|
||||
align="center"
|
||||
fixed="left"
|
||||
>
|
||||
<template #header>
|
||||
<div
|
||||
v-if="showSelection && selectedRows.length > 0 && !showDeleteButton"
|
||||
style="display: flex; align-items: center; justify-content: center; gap: 4px"
|
||||
>
|
||||
<el-button type="danger" size="small" icon="Delete" link @click="handleDeleteSelected">
|
||||
删除选中({{ selectedRows.length }})
|
||||
</el-button>
|
||||
</div>
|
||||
<span v-else></span>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="showRowAddButton"
|
||||
type="primary"
|
||||
link
|
||||
icon="CirclePlus"
|
||||
class="action-btn"
|
||||
@click="handleAdd(scope.$index)"
|
||||
title="增加"
|
||||
/>
|
||||
<el-button
|
||||
v-if="showRowDeleteButton"
|
||||
type="danger"
|
||||
link
|
||||
icon="Delete"
|
||||
class="action-btn"
|
||||
@click="handleDelete(scope.$index)"
|
||||
title="删除"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
v-for="col in filteredColumns"
|
||||
:key="col.prop"
|
||||
:prop="col.prop"
|
||||
:label="col.label"
|
||||
:width="col.width"
|
||||
:min-width="col.minWidth"
|
||||
:fixed="col.fixed"
|
||||
:align="col.align || 'center'"
|
||||
:formatter="col.formatter"
|
||||
>
|
||||
<template #default="scope">
|
||||
<template v-if="col.type === 'input'">
|
||||
<el-form-item
|
||||
:prop="`tableData.${scope.$index}.${col.prop}`"
|
||||
:rules="col.rules"
|
||||
style="margin-bottom: 0"
|
||||
>
|
||||
<el-input
|
||||
v-model="scope.row[col.prop]"
|
||||
:placeholder="col.placeholder || `请输入${col.label}`"
|
||||
:disabled="col.disabled"
|
||||
:clearable="col.clearable !== false"
|
||||
@blur="col.onBlur && col.onBlur(scope.row, scope.$index)"
|
||||
@input="col.onInput && col.onInput(scope.row, scope.$index)"
|
||||
@change="col.onChange && col.onChange(scope.row, scope.$index)"
|
||||
>
|
||||
<template v-if="col.suffix" #suffix>{{ col.suffix }}</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<template v-else-if="col.type === 'number'">
|
||||
<el-form-item
|
||||
:prop="`tableData.${scope.$index}.${col.prop}`"
|
||||
:rules="col.rules"
|
||||
style="margin-bottom: 0"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="scope.row[col.prop]"
|
||||
:placeholder="col.placeholder || `请输入${col.label}`"
|
||||
:disabled="col.disabled"
|
||||
:min="col.min"
|
||||
:max="col.max"
|
||||
:precision="col.precision"
|
||||
:controls="false"
|
||||
style="width: 100%"
|
||||
@change="col.onChange && col.onChange(scope.row, scope.$index)"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<template v-else-if="col.type === 'select'">
|
||||
<el-form-item
|
||||
:prop="`tableData.${scope.$index}.${col.prop}`"
|
||||
:rules="col.rules"
|
||||
style="margin-bottom: 0"
|
||||
>
|
||||
<el-select
|
||||
v-model="scope.row[col.prop]"
|
||||
:placeholder="col.placeholder || `请选择${col.label}`"
|
||||
:disabled="col.disabled"
|
||||
:clearable="col.clearable !== false"
|
||||
:filterable="col.filterable"
|
||||
:multiple="col.multiple"
|
||||
style="width: 100%"
|
||||
:class="scope.row.error ? 'error-border' : ''"
|
||||
@change="
|
||||
async (value) => {
|
||||
const checkBeforeChange = col.extraprops?.checkBeforeChange;
|
||||
if (checkBeforeChange && typeof checkBeforeChange === 'function') {
|
||||
const result = await checkBeforeChange(scope.row, scope.$index, value);
|
||||
if (result === false) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (col.onChange) {
|
||||
col.onChange(scope.row, scope.$index, value);
|
||||
}
|
||||
}
|
||||
"
|
||||
>
|
||||
<el-option
|
||||
v-for="option in typeof col.options === 'function'
|
||||
? col.options(scope.row, scope.$index)
|
||||
: col.options || []"
|
||||
:key="option.value"
|
||||
:label="option.label"
|
||||
:value="option.value"
|
||||
@click="option.onClick && option.onClick(scope.row, option)"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<template v-else-if="col.type === 'date'">
|
||||
<el-form-item
|
||||
:prop="`tableData.${scope.$index}.${col.prop}`"
|
||||
:rules="col.rules"
|
||||
style="margin-bottom: 0"
|
||||
>
|
||||
<el-date-picker
|
||||
v-model="scope.row[col.prop]"
|
||||
:type="col.dateType || 'date'"
|
||||
:placeholder="col.placeholder || `请选择${col.label}`"
|
||||
:disabled="col.disabled"
|
||||
:clearable="col.clearable !== false"
|
||||
:value-format="col.valueFormat || 'YYYY-MM-DD'"
|
||||
style="width: 100%"
|
||||
@change="col.onChange && col.onChange(scope.row, scope.$index)"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<template v-else-if="col.type === 'slot'">
|
||||
<el-form-item
|
||||
:prop="`tableData.${scope.$index}.${col.prop}`"
|
||||
:rules="col.rules"
|
||||
style="margin-bottom: 0"
|
||||
>
|
||||
<slot :name="col.slot || col.prop" :row="scope.row" :index="scope.$index" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<span>{{
|
||||
col.formatter
|
||||
? col.formatter(scope.row, scope.column, scope.row[col.prop])
|
||||
: scope.row[col.prop]
|
||||
}}</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div v-if="$slots.footer" class="editable-table-footer">
|
||||
<slot name="footer" :tableData="tableData" />
|
||||
</div>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, nextTick, computed } from 'vue';
|
||||
import { Search } from '@element-plus/icons-vue';
|
||||
import type { EditableTableProps } from '../types/EditableTable.d';
|
||||
|
||||
defineOptions({
|
||||
name: 'EditableTable',
|
||||
});
|
||||
|
||||
const props = withDefaults(defineProps<EditableTableProps>(), {
|
||||
modelValue: () => [],
|
||||
rules: () => ({}),
|
||||
defaultRow: () => ({}),
|
||||
border: true,
|
||||
stripe: false,
|
||||
showSelection: false,
|
||||
showAddButton: false,
|
||||
showDeleteButton: false,
|
||||
showRowActions: true,
|
||||
showRowAddButton: true,
|
||||
showRowDeleteButton: true,
|
||||
searchFields: () => [],
|
||||
virtualizedThreshold: 100,
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: Record<string, any>[]];
|
||||
add: [row: Record<string, any>, index: number];
|
||||
delete: [row: Record<string, any>, index: number, isClear: boolean];
|
||||
'selection-change': [selection: Record<string, any>[]];
|
||||
'toolbar-add': [];
|
||||
'toolbar-delete': [rows: Record<string, any>[]];
|
||||
}>();
|
||||
|
||||
const formRef = ref<InstanceType<typeof import('element-plus').ElForm> | null>(null);
|
||||
const tableRef = ref<InstanceType<typeof import('element-plus').ElTable> | null>(null);
|
||||
const selectedRows = ref<Record<string, any>[]>([]);
|
||||
const searchKeyword = ref('');
|
||||
|
||||
const tableData = ref([...props.modelValue]);
|
||||
|
||||
// 行唯一 key(用于虚拟滚动等)
|
||||
const autoRowId = ref(0);
|
||||
const getRowKey = (row: Record<string, any>) => {
|
||||
if (row.rowKey !== undefined && row.rowKey !== null) return row.rowKey;
|
||||
if (row.id !== undefined && row.id !== null) return row.id;
|
||||
if (!row._etKey) {
|
||||
row._etKey = `et-${autoRowId.value++}`;
|
||||
}
|
||||
return row._etKey;
|
||||
};
|
||||
|
||||
// 是否开启虚拟滚动:优先使用外部传入,其次根据数据量自动开启
|
||||
const useVirtualized = computed(() => {
|
||||
if (typeof props.virtualized === 'boolean') {
|
||||
return props.virtualized;
|
||||
}
|
||||
const threshold = props.virtualizedThreshold ?? 100;
|
||||
return tableData.value.length > threshold;
|
||||
});
|
||||
|
||||
// 过滤列(支持条件显示)
|
||||
const filteredColumns = computed(() => {
|
||||
return props.columns.filter((col) => !col.vIf || col.vIf());
|
||||
});
|
||||
|
||||
// 行操作列宽度:同时显示“增加+删除”则宽一点;只显示一个则缩窄
|
||||
const rowActionsColumnWidth = computed(() => {
|
||||
const showAdd = !!props.showRowAddButton;
|
||||
const showDel = !!props.showRowDeleteButton;
|
||||
if (showAdd && showDel) return 100;
|
||||
if (showAdd || showDel) return 60;
|
||||
// 如果两者都不显示,列也不会渲染;这里给个兜底
|
||||
return 0;
|
||||
});
|
||||
|
||||
const searchPlaceholder = computed(() => {
|
||||
if (props.searchFields.length === 0) {
|
||||
return '请输入搜索关键词';
|
||||
}
|
||||
|
||||
const fieldLabels = props.searchFields
|
||||
.map((field) => {
|
||||
const column = props.columns.find((col) => col.prop === field);
|
||||
return column?.label || field;
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
if (fieldLabels.length === 0) {
|
||||
return '请输入搜索关键词';
|
||||
}
|
||||
|
||||
if (fieldLabels.length === 1) {
|
||||
return `请输入${fieldLabels[0]}`;
|
||||
}
|
||||
|
||||
return `请输入${fieldLabels.join('|')}`;
|
||||
});
|
||||
|
||||
// 根据搜索关键词过滤表格数据
|
||||
const filteredTableData = computed(() => {
|
||||
if (!searchKeyword.value || props.searchFields.length === 0) {
|
||||
return tableData.value;
|
||||
}
|
||||
|
||||
const keyword = searchKeyword.value.toLowerCase();
|
||||
return tableData.value.filter((row) => {
|
||||
return props.searchFields.some((field) => {
|
||||
const value = row[field];
|
||||
if (value === null || value === undefined) {
|
||||
return false;
|
||||
}
|
||||
return String(value).toLowerCase().includes(keyword);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(newVal) => {
|
||||
if (newVal !== tableData.value) {
|
||||
tableData.value = [...newVal];
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
watch(
|
||||
tableData,
|
||||
(newVal) => {
|
||||
emit('update:modelValue', newVal);
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
const handleAdd = (index) => {
|
||||
const newRow = { ...props.defaultRow };
|
||||
tableData.value.splice(index + 1, 0, newRow);
|
||||
nextTick(() => {
|
||||
emit('add', newRow, index + 1);
|
||||
});
|
||||
};
|
||||
|
||||
const handleDelete = (index) => {
|
||||
if (tableData.value.length === 1) {
|
||||
Object.keys(tableData.value[0]).forEach((key) => {
|
||||
tableData.value[0][key] = '';
|
||||
});
|
||||
Object.assign(tableData.value[0], { ...props.defaultRow });
|
||||
emit('delete', tableData.value[0], index, true);
|
||||
} else {
|
||||
const deletedRow = tableData.value.splice(index, 1)[0];
|
||||
emit('delete', deletedRow, index, false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelectionChange = (selection) => {
|
||||
selectedRows.value = selection;
|
||||
emit('selection-change', selection);
|
||||
};
|
||||
|
||||
// 删除所有选中的行
|
||||
const handleDeleteSelected = () => {
|
||||
if (selectedRows.value.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取选中行的索引
|
||||
const selectedIndexes = selectedRows.value.map((row) => tableData.value.indexOf(row));
|
||||
// 从后往前删除,避免索引变化问题
|
||||
selectedIndexes.sort((a, b) => b - a);
|
||||
|
||||
// 如果选中了所有行且只剩一行,清空数据而不是删除
|
||||
if (tableData.value.length === selectedRows.value.length && tableData.value.length === 1) {
|
||||
Object.keys(tableData.value[0]).forEach((key) => {
|
||||
tableData.value[0][key] = '';
|
||||
});
|
||||
Object.assign(tableData.value[0], { ...props.defaultRow });
|
||||
emit('delete', tableData.value[0], 0, true);
|
||||
} else {
|
||||
// 删除选中的行
|
||||
selectedIndexes.forEach((index) => {
|
||||
if (index !== -1 && tableData.value.length > 1) {
|
||||
const deletedRow = tableData.value.splice(index, 1)[0];
|
||||
emit('delete', deletedRow, index, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 清空选中状态
|
||||
if (tableRef.value) {
|
||||
tableRef.value.clearSelection();
|
||||
}
|
||||
selectedRows.value = [];
|
||||
};
|
||||
|
||||
// 工具栏新增按钮
|
||||
const handleToolbarAdd = () => {
|
||||
const newRow = { ...props.defaultRow };
|
||||
tableData.value.push(newRow);
|
||||
nextTick(() => {
|
||||
emit('toolbar-add');
|
||||
emit('add', newRow, tableData.value.length - 1);
|
||||
});
|
||||
};
|
||||
|
||||
// 工具栏删除按钮
|
||||
const handleToolbarDelete = () => {
|
||||
if (selectedRows.value.length === 0) {
|
||||
return;
|
||||
}
|
||||
emit('toolbar-delete', selectedRows.value);
|
||||
handleDeleteSelected();
|
||||
};
|
||||
|
||||
// 搜索处理
|
||||
const handleSearch = () => {
|
||||
// 搜索逻辑已在 computed 中处理
|
||||
};
|
||||
|
||||
const validate = (callback) => {
|
||||
if (formRef.value) {
|
||||
return formRef.value.validate(callback);
|
||||
}
|
||||
};
|
||||
|
||||
const validateField = (props, callback) => {
|
||||
if (formRef.value) {
|
||||
return formRef.value.validateField(props, callback);
|
||||
}
|
||||
};
|
||||
|
||||
const resetFields = () => {
|
||||
if (formRef.value) {
|
||||
formRef.value.resetFields();
|
||||
}
|
||||
};
|
||||
|
||||
const clearValidate = (props) => {
|
||||
if (formRef.value) {
|
||||
formRef.value.clearValidate(props);
|
||||
}
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
formRef,
|
||||
tableRef,
|
||||
validate,
|
||||
validateField,
|
||||
resetFields,
|
||||
clearValidate,
|
||||
tableData,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.editable-table-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
.editable-table-toolbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
padding: 0 4px;
|
||||
|
||||
.toolbar-left {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.toolbar-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-table.editable-table-inner) {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.el-table__body-wrapper {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.el-table__cell {
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
vertical-align: top;
|
||||
|
||||
.cell {
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-table__cell) {
|
||||
overflow: visible;
|
||||
vertical-align: top;
|
||||
|
||||
.cell {
|
||||
overflow: visible;
|
||||
}
|
||||
}
|
||||
|
||||
// 错误信息往下撑开行高,不影响上面布局
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 0;
|
||||
|
||||
.el-form-item__error {
|
||||
position: static;
|
||||
line-height: 1.5;
|
||||
padding-top: 4px;
|
||||
font-size: 12px;
|
||||
color: var(--el-color-danger);
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
margin: 4px;
|
||||
:deep(.el-icon) {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.editable-table-footer {
|
||||
flex-shrink: 0;
|
||||
margin-top: 16px;
|
||||
}
|
||||
</style>
|
||||
157
openhis-ui-vue3/src/components/TableLayout/Filter.vue
Normal file
157
openhis-ui-vue3/src/components/TableLayout/Filter.vue
Normal file
@@ -0,0 +1,157 @@
|
||||
<template>
|
||||
<div v-if="show" class="query-form-wrapper">
|
||||
<el-form
|
||||
ref="queryFormRef"
|
||||
:model="queryParams"
|
||||
:inline="true"
|
||||
class="query-form"
|
||||
:label-width="labelWidth"
|
||||
>
|
||||
<template v-for="item in displayedFormItems" :key="item.prop">
|
||||
<FormItem
|
||||
:item="item"
|
||||
:model-value="queryParams[item.prop]"
|
||||
:on-enter="handleQuery"
|
||||
@update:model-value="(value) => (queryParams[item.prop] = value)"
|
||||
@change="(value) => item.onChange && item.onChange(value)"
|
||||
>
|
||||
<template v-for="(_, slotName) in $slots" :key="slotName" #[slotName]="slotProps">
|
||||
<slot :name="slotName" v-bind="slotProps" />
|
||||
</template>
|
||||
</FormItem>
|
||||
</template>
|
||||
<el-form-item v-if="showDefaultButtons" style="margin-left: 20px">
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
<el-button v-if="needCollapse" type="text" @click="toggleExpand" style="margin-left: 16px">
|
||||
{{ isExpanded ? '收起' : '展开' }}
|
||||
<el-icon class="el-icon--right">
|
||||
<DArrowLeft v-if="isExpanded" class="collapse-arrow collapse-arrow--up" />
|
||||
<DArrowRight v-else class="collapse-arrow collapse-arrow--down" />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue';
|
||||
import FormItem from './FormItem.vue';
|
||||
import type { FilterProps } from '../types/Filter.d';
|
||||
|
||||
defineOptions({
|
||||
name: 'Filter'
|
||||
});
|
||||
|
||||
const props = withDefaults(defineProps<FilterProps>(), {
|
||||
formItems: () => [],
|
||||
show: true,
|
||||
showDefaultButtons: true,
|
||||
labelWidth: '120px',
|
||||
showLabelColon: true,
|
||||
});
|
||||
|
||||
|
||||
const emit = defineEmits<{
|
||||
query: [queryParams: Record<string, any>];
|
||||
reset: [];
|
||||
}>();
|
||||
|
||||
const queryFormRef = ref<InstanceType<typeof import('element-plus').ElForm> | null>(null);
|
||||
const isExpanded = ref(true);
|
||||
|
||||
const itemsPerRow = 4;
|
||||
|
||||
const normalizedFormItems = computed(() =>
|
||||
(props.formItems || []).map((item) => ({
|
||||
...item,
|
||||
labelSuffix: item.labelSuffix ?? (props.showLabelColon ? ':' : ''),
|
||||
}))
|
||||
);
|
||||
|
||||
const needCollapse = computed(() => {
|
||||
if (!normalizedFormItems.value || normalizedFormItems.value.length === 0) return false;
|
||||
|
||||
let totalWidth = 0;
|
||||
normalizedFormItems.value.forEach((item) => {
|
||||
if (item.type === 'custom' || item.type === 'daterange') {
|
||||
totalWidth += 2;
|
||||
} else {
|
||||
totalWidth += 1;
|
||||
}
|
||||
});
|
||||
|
||||
return totalWidth > itemsPerRow * 2;
|
||||
});
|
||||
|
||||
const displayedFormItems = computed(() => {
|
||||
if (!needCollapse.value || isExpanded.value) {
|
||||
return normalizedFormItems.value;
|
||||
}
|
||||
|
||||
const maxItems = itemsPerRow * 2;
|
||||
let count = 0;
|
||||
const result: any[] = [];
|
||||
|
||||
for (const item of normalizedFormItems.value) {
|
||||
const itemWidth = item.type === 'custom' || item.type === 'daterange' ? 2 : 1;
|
||||
|
||||
if (count + itemWidth > maxItems) {
|
||||
break;
|
||||
}
|
||||
|
||||
result.push(item);
|
||||
count += itemWidth;
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
const toggleExpand = () => {
|
||||
isExpanded.value = !isExpanded.value;
|
||||
};
|
||||
|
||||
const handleQuery = () => {
|
||||
emit('query', props.queryParams);
|
||||
};
|
||||
|
||||
const resetQuery = () => {
|
||||
if (queryFormRef.value) {
|
||||
queryFormRef.value.resetFields();
|
||||
}
|
||||
if (props.queryParams && Object.prototype.hasOwnProperty.call(props.queryParams, 'pageNum')) {
|
||||
props.queryParams.pageNum = 1;
|
||||
}
|
||||
emit('reset');
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
queryFormRef,
|
||||
handleQuery,
|
||||
resetQuery,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.query-form-wrapper {
|
||||
flex-shrink: 0;
|
||||
width: 100%;
|
||||
|
||||
.query-form {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.collapse-arrow {
|
||||
transition: transform 0.2s ease;
|
||||
|
||||
&.collapse-arrow--up {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
&.collapse-arrow--down {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
115
openhis-ui-vue3/src/components/TableLayout/Form.vue
Normal file
115
openhis-ui-vue3/src/components/TableLayout/Form.vue
Normal file
@@ -0,0 +1,115 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="model"
|
||||
:rules="rules"
|
||||
:label-width="labelWidth"
|
||||
:inline="inline"
|
||||
:label-position="labelPosition"
|
||||
class="table-layout-form"
|
||||
>
|
||||
<template v-for="item in normalizedFormItems" :key="item.prop">
|
||||
<FormItem
|
||||
:item="item"
|
||||
:model-value="model[item.prop]"
|
||||
@update:model-value="(value) => (model[item.prop] = value)"
|
||||
@change="(value) => item.onChange && item.onChange(value)"
|
||||
>
|
||||
<template v-for="(_, slotName) in $slots" :key="slotName" #[slotName]="slotProps">
|
||||
<slot :name="slotName" v-bind="slotProps" />
|
||||
</template>
|
||||
</FormItem>
|
||||
</template>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue';
|
||||
import FormItem from './FormItem.vue';
|
||||
import type { FormProps } from '../types/Form.d';
|
||||
|
||||
defineOptions({
|
||||
name: 'Form'
|
||||
});
|
||||
|
||||
const props = withDefaults(defineProps<FormProps>(), {
|
||||
formItems: () => [],
|
||||
rules: () => ({}),
|
||||
labelWidth: '120px',
|
||||
inline: false,
|
||||
labelPosition: 'right',
|
||||
showLabelColon: true,
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
validate: [callback?: (valid: boolean) => void];
|
||||
}>();
|
||||
|
||||
const formRef = ref<InstanceType<typeof import('element-plus').ElForm> | null>(null);
|
||||
|
||||
const normalizedFormItems = computed(() =>
|
||||
(props.formItems || []).map((item) => ({
|
||||
...item,
|
||||
labelSuffix: item.labelSuffix ?? (props.showLabelColon ? ':' : ''),
|
||||
}))
|
||||
);
|
||||
|
||||
// 表单验证
|
||||
const validate = (callback) => {
|
||||
if (formRef.value) {
|
||||
return formRef.value.validate(callback);
|
||||
}
|
||||
};
|
||||
|
||||
// 验证指定字段
|
||||
const validateField = (props, callback) => {
|
||||
if (formRef.value) {
|
||||
return formRef.value.validateField(props, callback);
|
||||
}
|
||||
};
|
||||
|
||||
// 重置表单
|
||||
const resetFields = () => {
|
||||
if (formRef.value) {
|
||||
formRef.value.resetFields();
|
||||
}
|
||||
};
|
||||
|
||||
// 清除验证
|
||||
const clearValidate = (props) => {
|
||||
if (formRef.value) {
|
||||
formRef.value.clearValidate(props);
|
||||
}
|
||||
};
|
||||
|
||||
// 滚动到指定字段
|
||||
const scrollToField = (prop) => {
|
||||
if (formRef.value) {
|
||||
formRef.value.scrollToField(prop);
|
||||
}
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
formRef,
|
||||
validate,
|
||||
validateField,
|
||||
resetFields,
|
||||
clearValidate,
|
||||
scrollToField,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.table-layout-form {
|
||||
width: 100%;
|
||||
|
||||
// 非内联表单样式
|
||||
&:not(.el-form--inline) {
|
||||
:deep(.el-form-item) {
|
||||
display: flex;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
196
openhis-ui-vue3/src/components/TableLayout/FormItem.vue
Normal file
196
openhis-ui-vue3/src/components/TableLayout/FormItem.vue
Normal file
@@ -0,0 +1,196 @@
|
||||
<template>
|
||||
<el-form-item
|
||||
:label="labelWithSuffix"
|
||||
:prop="item.prop"
|
||||
:required="item.required"
|
||||
:class="{ 'form-item-double': item.type === 'custom' || item.type === 'daterange' }"
|
||||
>
|
||||
<el-input
|
||||
v-if="item.type === 'input'"
|
||||
:model-value="modelValue"
|
||||
:placeholder="item.placeholder || `请输入${item.label}`"
|
||||
:clearable="item.clearable !== false"
|
||||
:style="item.style || { width: item.width || '200px' }"
|
||||
v-bind="item.extraprops || {}"
|
||||
@keyup.enter="handleEnter"
|
||||
@update:model-value="handleUpdate"
|
||||
/>
|
||||
<el-select
|
||||
v-else-if="item.type === 'select'"
|
||||
:model-value="modelValue"
|
||||
:placeholder="item.placeholder || `请选择${item.label}`"
|
||||
:clearable="item.clearable !== false"
|
||||
:style="item.style || { width: item.width || '200px' }"
|
||||
:disabled="item.disabled"
|
||||
v-bind="item.extraprops || {}"
|
||||
:multiple="item.multiple !== false"
|
||||
:filterable="item.filterable !== false"
|
||||
:collapse-tags="item.collapseTags !== false"
|
||||
@change="handleChange"
|
||||
@update:model-value="(value) => handleUpdateWithCheck(value, item.checkBeforeChange)"
|
||||
>
|
||||
<el-option
|
||||
v-for="option in item.options || []"
|
||||
:key="option.value"
|
||||
:label="option.label"
|
||||
:value="option.value"
|
||||
/>
|
||||
</el-select>
|
||||
<el-radio-group
|
||||
v-else-if="item.type === 'radio'"
|
||||
:model-value="modelValue"
|
||||
v-bind="item.extraprops || {}"
|
||||
@change="handleChange"
|
||||
@update:model-value="handleUpdate"
|
||||
>
|
||||
<el-radio v-for="option in item.options || []" :key="option.value" :label="option.value">
|
||||
{{ option.label }}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
<!-- 单独日期 -->
|
||||
<el-date-picker
|
||||
v-else-if="item.type === 'date'"
|
||||
:model-value="modelValue"
|
||||
type="date"
|
||||
:placeholder="item.placeholder || `请选择${item.label}`"
|
||||
:clearable="item.clearable !== false"
|
||||
:value-format="item.valueFormat || 'YYYY-MM-DD'"
|
||||
:style="item.style || { width: item.width || '200px' }"
|
||||
:disabled="item.disabled"
|
||||
v-bind="item.extraprops || {}"
|
||||
@change="handleChange"
|
||||
@update:model-value="handleUpdate"
|
||||
/>
|
||||
<!-- 日期区间 -->
|
||||
<QuickDateRange
|
||||
v-else-if="item.type === 'daterange'"
|
||||
:model-value="daterangeValue"
|
||||
:start-placeholder="item.startPlaceholder || '开始日期'"
|
||||
:end-placeholder="item.endPlaceholder || '结束日期'"
|
||||
:value-format="item.valueFormat || 'YYYY-MM-DD'"
|
||||
:clearable="item.clearable !== false"
|
||||
:date-picker-style="daterangeStyle"
|
||||
:attrs="item.extraprops || {}"
|
||||
@change="handleChange"
|
||||
@update:model-value="handleUpdate"
|
||||
/>
|
||||
<!-- 纯文本展示 -->
|
||||
<span
|
||||
v-else-if="item.type === 'text'"
|
||||
:style="item.style || { width: item.width || '200px' }"
|
||||
class="form-item-text"
|
||||
>
|
||||
{{ item.formatter ? item.formatter(modelValue) : modelValue ?? '' }}
|
||||
</span>
|
||||
<slot
|
||||
v-else-if="item.type === 'custom'"
|
||||
:name="item.slot || item.prop"
|
||||
:item="item"
|
||||
:modelValue="modelValue"
|
||||
:updateModelValue="handleUpdate"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import type { FormItemProps } from '../types/FormItem.d';
|
||||
import QuickDateRange from './QuickDateRange.vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'FormItem',
|
||||
});
|
||||
|
||||
const props = defineProps<FormItemProps>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: any];
|
||||
change: [value: any];
|
||||
}>();
|
||||
|
||||
const labelWithSuffix = computed(() => {
|
||||
const suffix = props.item.labelSuffix || '';
|
||||
return `${props.item.label || ''}${suffix}`;
|
||||
});
|
||||
|
||||
// 日期区间组件的值处理
|
||||
const daterangeValue = computed<string[]>(() => {
|
||||
if (props.item.type === 'daterange') {
|
||||
if (Array.isArray(props.modelValue)) {
|
||||
return props.modelValue.map((v: any) => String(v));
|
||||
}
|
||||
return [];
|
||||
}
|
||||
return [];
|
||||
});
|
||||
|
||||
// 日期区间组件的样式处理
|
||||
const daterangeStyle = computed(() => {
|
||||
if (props.item.type === 'daterange') {
|
||||
if (
|
||||
typeof props.item.style === 'object' &&
|
||||
props.item.style !== null &&
|
||||
!Array.isArray(props.item.style)
|
||||
) {
|
||||
return props.item.style;
|
||||
}
|
||||
return { width: props.item.width || 'calc(316px + 7em)' };
|
||||
}
|
||||
return {};
|
||||
});
|
||||
|
||||
const handleUpdate = (value: any) => {
|
||||
emit('update:modelValue', value);
|
||||
};
|
||||
|
||||
const handleUpdateWithCheck = async (value: any, shouldCheck = false) => {
|
||||
if (shouldCheck) {
|
||||
if (props.item.onChange && typeof props.item.onChange === 'function') {
|
||||
const result = await props.item.onChange(value);
|
||||
if (result === false) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
handleUpdate(value);
|
||||
};
|
||||
|
||||
const handleChange = (value: any) => {
|
||||
emit('change', value);
|
||||
};
|
||||
|
||||
const handleEnter = () => {
|
||||
if (props.onEnter && typeof props.onEnter === 'function') {
|
||||
props.onEnter();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 16px;
|
||||
display: inline-flex;
|
||||
align-items: flex-start;
|
||||
vertical-align: top;
|
||||
margin-right: 16px;
|
||||
|
||||
.el-form-item__label {
|
||||
width: 7em !important;
|
||||
min-width: 7em;
|
||||
white-space: normal;
|
||||
word-break: break-all;
|
||||
line-height: 1.5;
|
||||
padding-right: 8px;
|
||||
text-align: right;
|
||||
padding-top: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.el-form-item__content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
143
openhis-ui-vue3/src/components/TableLayout/FormLayout.vue
Normal file
143
openhis-ui-vue3/src/components/TableLayout/FormLayout.vue
Normal file
@@ -0,0 +1,143 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="model"
|
||||
:rules="rules"
|
||||
:label-width="labelWidth"
|
||||
:label-position="labelPosition"
|
||||
class="form-layout-form"
|
||||
>
|
||||
<div class="form-items-container" :class="columns > 0 ? `form-layout-${columns}col` : ''">
|
||||
<template v-for="(item, index) in normalizedFormItems" :key="item.prop">
|
||||
<FormItem
|
||||
:item="item"
|
||||
:model-value="model[item.prop]"
|
||||
@update:model-value="
|
||||
async (value) => {
|
||||
if (item.onChange && typeof item.onChange === 'function') {
|
||||
const result = await item.onChange(value);
|
||||
if (result === false) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
model[item.prop] = value;
|
||||
}
|
||||
"
|
||||
>
|
||||
<template v-for="(_, slotName) in $slots" :key="slotName" #[slotName]="slotProps">
|
||||
<slot :name="slotName" v-bind="slotProps" />
|
||||
</template>
|
||||
</FormItem>
|
||||
<span
|
||||
v-if="
|
||||
columns > 0 &&
|
||||
index > 0 &&
|
||||
(index + 1) % columns === 0 &&
|
||||
index < normalizedFormItems.length - 1
|
||||
"
|
||||
class="form-item-break"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue';
|
||||
import FormItem from './FormItem.vue';
|
||||
import type { FormLayoutProps } from '../types/FormLayout.d';
|
||||
|
||||
defineOptions({
|
||||
name: 'FormLayout',
|
||||
});
|
||||
|
||||
const props = withDefaults(defineProps<FormLayoutProps>(), {
|
||||
formItems: () => [],
|
||||
rules: () => ({}),
|
||||
labelWidth: '120px',
|
||||
labelPosition: 'right',
|
||||
showLabelColon: true,
|
||||
columns: 0,
|
||||
});
|
||||
|
||||
const formRef = ref<InstanceType<typeof import('element-plus').ElForm> | null>(null);
|
||||
|
||||
const normalizedFormItems = computed(() =>
|
||||
(props.formItems || []).map((item) => ({
|
||||
...item,
|
||||
labelSuffix: item.labelSuffix ?? (props.showLabelColon ? ':' : ''),
|
||||
}))
|
||||
);
|
||||
|
||||
const validate = (callback) => {
|
||||
if (formRef.value) {
|
||||
return formRef.value.validate(callback);
|
||||
}
|
||||
};
|
||||
|
||||
const validateField = (props, callback) => {
|
||||
if (formRef.value) {
|
||||
return formRef.value.validateField(props, callback);
|
||||
}
|
||||
};
|
||||
|
||||
const resetFields = () => {
|
||||
if (formRef.value) {
|
||||
formRef.value.resetFields();
|
||||
}
|
||||
};
|
||||
|
||||
const clearValidate = (props) => {
|
||||
if (formRef.value) {
|
||||
formRef.value.clearValidate(props);
|
||||
}
|
||||
};
|
||||
|
||||
const scrollToField = (prop) => {
|
||||
if (formRef.value) {
|
||||
formRef.value.scrollToField(prop);
|
||||
}
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
formRef,
|
||||
validate,
|
||||
validateField,
|
||||
resetFields,
|
||||
clearValidate,
|
||||
scrollToField,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.form-layout-form {
|
||||
width: 100%;
|
||||
|
||||
.form-items-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
column-gap: 16px;
|
||||
row-gap: 16px;
|
||||
|
||||
.form-item-break {
|
||||
flex-basis: 100%;
|
||||
width: 0;
|
||||
height: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 0;
|
||||
justify-content: flex-start;
|
||||
flex: 0 0 auto;
|
||||
|
||||
.el-form-item__content {
|
||||
justify-content: flex-start;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
18
openhis-ui-vue3/src/components/TableLayout/FormSection.vue
Normal file
18
openhis-ui-vue3/src/components/TableLayout/FormSection.vue
Normal file
@@ -0,0 +1,18 @@
|
||||
<template>
|
||||
<div class="form-section">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineOptions({
|
||||
name: 'FormSection',
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.form-section {
|
||||
flex-shrink: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<div class="form-section">
|
||||
<FormLayout ref="formLayoutRef" v-bind="$attrs">
|
||||
<template v-for="(_, slotName) in $slots" :key="slotName" #[slotName]="slotProps">
|
||||
<slot :name="slotName" v-bind="slotProps" />
|
||||
</template>
|
||||
</FormLayout>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import FormLayout from './FormLayout.vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'FormSectionLayout',
|
||||
inheritAttrs: false,
|
||||
});
|
||||
|
||||
const formLayoutRef = ref(null);
|
||||
|
||||
defineExpose({
|
||||
get formRef() {
|
||||
return formLayoutRef.value?.formRef;
|
||||
},
|
||||
validate: (...args) => formLayoutRef.value?.validate(...args),
|
||||
validateField: (...args) => formLayoutRef.value?.validateField(...args),
|
||||
resetFields: (...args) => formLayoutRef.value?.resetFields(...args),
|
||||
clearValidate: (...args) => formLayoutRef.value?.clearValidate(...args),
|
||||
scrollToField: (...args) => formLayoutRef.value?.scrollToField(...args),
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.form-section {
|
||||
flex-shrink: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
</style>
|
||||
136
openhis-ui-vue3/src/components/TableLayout/NumberInput.vue
Normal file
136
openhis-ui-vue3/src/components/TableLayout/NumberInput.vue
Normal file
@@ -0,0 +1,136 @@
|
||||
<template>
|
||||
<el-input
|
||||
:model-value="displayValue"
|
||||
:placeholder="placeholder"
|
||||
:disabled="disabled"
|
||||
:clearable="clearable"
|
||||
@input="handleInput"
|
||||
@blur="handleBlur"
|
||||
@change="handleChange"
|
||||
>
|
||||
<template v-if="suffix" #suffix>{{ suffix }}</template>
|
||||
</el-input>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: [Number, String],
|
||||
placeholder: String,
|
||||
disabled: Boolean,
|
||||
clearable: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
suffix: String,
|
||||
precision: Number, // 小数位数
|
||||
min: Number,
|
||||
max: Number,
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:modelValue', 'blur', 'change']);
|
||||
|
||||
const displayValue = computed(() => {
|
||||
if (props.modelValue === null || props.modelValue === undefined || props.modelValue === '') {
|
||||
return '';
|
||||
}
|
||||
return String(props.modelValue);
|
||||
});
|
||||
|
||||
const handleInput = (value) => {
|
||||
// 只允许数字、小数点和负号
|
||||
let newValue = value.replace(/[^\d.-]/g, '');
|
||||
|
||||
// 只允许一个小数点
|
||||
const parts = newValue.split('.');
|
||||
if (parts.length > 2) {
|
||||
newValue = parts[0] + '.' + parts.slice(1).join('');
|
||||
}
|
||||
|
||||
// 只允许一个负号,且必须在开头
|
||||
if (newValue.indexOf('-') > 0) {
|
||||
newValue = newValue.replace(/-/g, '');
|
||||
}
|
||||
if (newValue.startsWith('-') && newValue.split('-').length > 2) {
|
||||
newValue = '-' + newValue.replace(/-/g, '');
|
||||
}
|
||||
|
||||
// 如果为空,直接返回空字符串
|
||||
if (newValue === '' || newValue === '-') {
|
||||
emit('update:modelValue', '');
|
||||
return;
|
||||
}
|
||||
|
||||
// 转换为数字
|
||||
const numValue = parseFloat(newValue);
|
||||
if (isNaN(numValue)) {
|
||||
emit('update:modelValue', '');
|
||||
return;
|
||||
}
|
||||
|
||||
// 限制最小值
|
||||
if (props.min !== undefined && numValue < props.min) {
|
||||
newValue = String(props.min);
|
||||
}
|
||||
|
||||
// 限制最大值
|
||||
if (props.max !== undefined && numValue > props.max) {
|
||||
newValue = String(props.max);
|
||||
}
|
||||
|
||||
// 处理精度
|
||||
if (props.precision !== undefined && newValue.includes('.')) {
|
||||
const parts = newValue.split('.');
|
||||
if (parts[1] && parts[1].length > props.precision) {
|
||||
parts[1] = parts[1].substring(0, props.precision);
|
||||
newValue = parts.join('.');
|
||||
}
|
||||
}
|
||||
|
||||
emit('update:modelValue', newValue);
|
||||
};
|
||||
|
||||
const handleBlur = (event) => {
|
||||
const value = event.target.value;
|
||||
if (value === '' || value === '-') {
|
||||
emit('update:modelValue', '');
|
||||
emit('blur', event);
|
||||
return;
|
||||
}
|
||||
|
||||
const numValue = parseFloat(value);
|
||||
if (isNaN(numValue)) {
|
||||
emit('update:modelValue', '');
|
||||
emit('blur', event);
|
||||
return;
|
||||
}
|
||||
|
||||
// 应用精度
|
||||
let finalValue = numValue;
|
||||
if (props.precision !== undefined) {
|
||||
finalValue = parseFloat(numValue.toFixed(props.precision));
|
||||
}
|
||||
|
||||
// 限制范围
|
||||
if (props.min !== undefined && finalValue < props.min) {
|
||||
finalValue = props.min;
|
||||
}
|
||||
if (props.max !== undefined && finalValue > props.max) {
|
||||
finalValue = props.max;
|
||||
}
|
||||
|
||||
emit('update:modelValue', String(finalValue));
|
||||
emit('blur', event);
|
||||
};
|
||||
|
||||
const handleChange = (value) => {
|
||||
emit('change', value);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
:deep(.el-input__inner) {
|
||||
text-align: left;
|
||||
}
|
||||
</style>
|
||||
29
openhis-ui-vue3/src/components/TableLayout/PageLayout.vue
Normal file
29
openhis-ui-vue3/src/components/TableLayout/PageLayout.vue
Normal file
@@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<Layout>
|
||||
<template #default>
|
||||
<div class="page-wrapper">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="$slots.footer" #footer>
|
||||
<slot name="footer" />
|
||||
</template>
|
||||
</Layout>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Layout from '@/components/Layout/index.vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'PageLayout',
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.page-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
20
openhis-ui-vue3/src/components/TableLayout/PageWrapper.vue
Normal file
20
openhis-ui-vue3/src/components/TableLayout/PageWrapper.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<div class="page-wrapper">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineOptions({
|
||||
name: 'PageWrapper',
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.page-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
171
openhis-ui-vue3/src/components/TableLayout/QuickDateRange.vue
Normal file
171
openhis-ui-vue3/src/components/TableLayout/QuickDateRange.vue
Normal file
@@ -0,0 +1,171 @@
|
||||
<template>
|
||||
<div class="quick-date-range">
|
||||
<el-select v-model="quickType" class="quick-select" @change="handleQuickChange">
|
||||
<el-option label="自定义时间段" value="custom" />
|
||||
<el-option label="今天" value="today" />
|
||||
<el-option label="昨天" value="yesterday" />
|
||||
<el-option label="本周" value="thisWeek" />
|
||||
<el-option label="上周" value="lastWeek" />
|
||||
<el-option label="最近30日" value="last30Days" />
|
||||
</el-select>
|
||||
<el-date-picker
|
||||
v-model="innerValue"
|
||||
type="daterange"
|
||||
range-separator="-"
|
||||
:start-placeholder="startPlaceholder || '开始日期'"
|
||||
:end-placeholder="endPlaceholder || '结束日期'"
|
||||
:value-format="valueFormat"
|
||||
:clearable="clearable"
|
||||
:style="datePickerStyle"
|
||||
v-bind="attrs"
|
||||
@change="handleDateChange"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, computed } from 'vue';
|
||||
import type { QuickDateRangeProps } from '../types/QuickDateRange.d';
|
||||
|
||||
defineOptions({
|
||||
name: 'QuickDateRange'
|
||||
});
|
||||
|
||||
const props = withDefaults(defineProps<QuickDateRangeProps>(), {
|
||||
modelValue: () => [],
|
||||
startPlaceholder: '',
|
||||
endPlaceholder: '',
|
||||
valueFormat: 'YYYY-MM-DD',
|
||||
clearable: true,
|
||||
datePickerStyle: () => ({}),
|
||||
attrs: () => ({}),
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: string[]];
|
||||
change: [value: string[]];
|
||||
}>();
|
||||
|
||||
const innerValue = ref<string[]>(props.modelValue && props.modelValue.length ? [...props.modelValue] : []);
|
||||
const quickType = ref<string>('custom');
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val) => {
|
||||
if (!val || !val.length) {
|
||||
innerValue.value = [];
|
||||
quickType.value = 'custom';
|
||||
} else {
|
||||
innerValue.value = [...val];
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
const datePickerStyle = computed(() => {
|
||||
return Object.assign({ width: '300px' }, props.datePickerStyle || {});
|
||||
});
|
||||
|
||||
function formatDate(date) {
|
||||
const y = date.getFullYear();
|
||||
const m = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const d = String(date.getDate()).padStart(2, '0');
|
||||
return `${y}-${m}-${d}`;
|
||||
}
|
||||
|
||||
function getToday() {
|
||||
const today = new Date();
|
||||
const d = new Date(today.getFullYear(), today.getMonth(), today.getDate());
|
||||
const s = formatDate(d);
|
||||
return [s, s];
|
||||
}
|
||||
|
||||
function getYesterday() {
|
||||
const today = new Date();
|
||||
const d = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1);
|
||||
const s = formatDate(d);
|
||||
return [s, s];
|
||||
}
|
||||
|
||||
function getThisWeek() {
|
||||
const today = new Date();
|
||||
const day = today.getDay() || 7; // 周日返回 7
|
||||
const monday = new Date(today);
|
||||
monday.setDate(today.getDate() - day + 1);
|
||||
const sunday = new Date(monday);
|
||||
sunday.setDate(monday.getDate() + 6);
|
||||
return [formatDate(monday), formatDate(sunday)];
|
||||
}
|
||||
|
||||
function getLastWeek() {
|
||||
const today = new Date();
|
||||
const day = today.getDay() || 7;
|
||||
const lastMonday = new Date(today);
|
||||
lastMonday.setDate(today.getDate() - day - 6);
|
||||
const lastSunday = new Date(lastMonday);
|
||||
lastSunday.setDate(lastMonday.getDate() + 6);
|
||||
return [formatDate(lastMonday), formatDate(lastSunday)];
|
||||
}
|
||||
|
||||
function getLast30Days() {
|
||||
const today = new Date();
|
||||
const end = new Date(today.getFullYear(), today.getMonth(), today.getDate());
|
||||
const start = new Date(end);
|
||||
start.setDate(end.getDate() - 29);
|
||||
return [formatDate(start), formatDate(end)];
|
||||
}
|
||||
|
||||
function handleQuickChange(val: string) {
|
||||
if (val === 'custom') {
|
||||
// 自定义时间段,清空日期值
|
||||
innerValue.value = [];
|
||||
emit('update:modelValue', []);
|
||||
emit('change', []);
|
||||
return;
|
||||
}
|
||||
let range: string[] = [];
|
||||
switch (val) {
|
||||
case 'today':
|
||||
range = getToday();
|
||||
break;
|
||||
case 'yesterday':
|
||||
range = getYesterday();
|
||||
break;
|
||||
case 'thisWeek':
|
||||
range = getThisWeek();
|
||||
break;
|
||||
case 'lastWeek':
|
||||
range = getLastWeek();
|
||||
break;
|
||||
case 'last30Days':
|
||||
range = getLast30Days();
|
||||
break;
|
||||
default:
|
||||
range = [];
|
||||
}
|
||||
innerValue.value = range;
|
||||
emit('update:modelValue', range);
|
||||
emit('change', range);
|
||||
}
|
||||
|
||||
function handleDateChange(val: string[] | null) {
|
||||
// 用户手动选择时间段时,将预设切换为自定义
|
||||
quickType.value = 'custom';
|
||||
innerValue.value = val || [];
|
||||
emit('update:modelValue', innerValue.value);
|
||||
emit('change', innerValue.value);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.quick-date-range {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
.quick-select {
|
||||
width: 130px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
373
openhis-ui-vue3/src/components/TableLayout/Table.vue
Normal file
373
openhis-ui-vue3/src/components/TableLayout/Table.vue
Normal file
@@ -0,0 +1,373 @@
|
||||
<template>
|
||||
<div class="table-container">
|
||||
<div ref="tableWrapperRef" class="table-wrapper">
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
v-loading="loading"
|
||||
:data="computedTableData"
|
||||
:border="border"
|
||||
:stripe="stripe"
|
||||
:size="size"
|
||||
:height="computedTableHeight"
|
||||
:row-key="rowKey"
|
||||
:highlight-current-row="highlightCurrentRow"
|
||||
@row-click="handleRowClick"
|
||||
@selection-change="handleSelectionChange"
|
||||
@sort-change="handleSortChange"
|
||||
style="width: 100%; height: 100%"
|
||||
>
|
||||
<!-- 通过配置数组生成的列 -->
|
||||
<template v-for="column in tableColumns" :key="column.prop || column.type">
|
||||
<el-table-column
|
||||
v-if="column.type && column.type !== 'expand'"
|
||||
:type="column.type"
|
||||
:width="column.width"
|
||||
:min-width="column.minWidth"
|
||||
:align="column.align || 'center'"
|
||||
:fixed="
|
||||
column.type === 'selection'
|
||||
? column.fixed !== undefined
|
||||
? column.fixed
|
||||
: 'left'
|
||||
: column.fixed
|
||||
"
|
||||
:selectable="column.selectable"
|
||||
/>
|
||||
<!-- 展开列,支持自定义插槽内容 -->
|
||||
<el-table-column
|
||||
v-else-if="column.type === 'expand'"
|
||||
type="expand"
|
||||
:width="column.width"
|
||||
:min-width="column.minWidth"
|
||||
:fixed="column.fixed"
|
||||
>
|
||||
<template #default="scope">
|
||||
<slot :name="column.slot || 'expand'" :row="scope.row" :scope="scope" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- 普通数据列 -->
|
||||
<el-table-column
|
||||
v-else
|
||||
:prop="column.prop"
|
||||
:label="column.label"
|
||||
:width="column.width"
|
||||
:min-width="column.minWidth"
|
||||
:align="column.align || 'left'"
|
||||
:fixed="column.fixed"
|
||||
:show-overflow-tooltip="column.showOverflowTooltip !== false"
|
||||
>
|
||||
<template v-if="column.slot" #default="scope">
|
||||
<slot :name="column.slot" :row="scope.row" :scope="scope" />
|
||||
</template>
|
||||
<template v-else-if="column.formatter" #default="scope">
|
||||
{{
|
||||
column.formatter(
|
||||
scope.row,
|
||||
scope.column,
|
||||
column.prop ? scope.row[column.prop] : undefined,
|
||||
scope.$index
|
||||
)
|
||||
}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
<!-- 通过插槽自定义的列 -->
|
||||
<slot name="table" />
|
||||
</el-table>
|
||||
</div>
|
||||
<div v-if="showPagination" ref="paginationWrapperRef" class="pagination-wrapper">
|
||||
<div
|
||||
class="pagination-content"
|
||||
:class="{ 'has-left-content': paginationLeftText || $slots.paginationLeft }"
|
||||
>
|
||||
<div v-if="paginationLeftText || $slots.paginationLeft" class="pagination-left">
|
||||
<slot name="paginationLeft">
|
||||
{{ paginationLeftText }}
|
||||
</slot>
|
||||
</div>
|
||||
<pagination
|
||||
v-show="computedTotal > 0"
|
||||
:total="computedTotal"
|
||||
:page="computedPageNo"
|
||||
:limit="computedPageSize"
|
||||
v-bind="paginationProps"
|
||||
@pagination="handlePagination"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch, onMounted, onUnmounted, nextTick } from 'vue';
|
||||
import Pagination from '@/components/Pagination/index.vue';
|
||||
import type { TableProps } from '../types/Table.d';
|
||||
|
||||
defineOptions({
|
||||
name: 'Table',
|
||||
});
|
||||
|
||||
const props = withDefaults(defineProps<TableProps>(), {
|
||||
tableData: () => [],
|
||||
loading: false,
|
||||
border: true,
|
||||
stripe: false,
|
||||
size: 'default',
|
||||
highlightCurrentRow: false,
|
||||
tableColumns: () => [],
|
||||
showPagination: false,
|
||||
total: 0,
|
||||
pageNo: 1,
|
||||
pageSize: 20,
|
||||
isAllData: false,
|
||||
paginationLeftText: '',
|
||||
paginationProps: () => ({}),
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
'row-click': [row: Record<string, any>, column: any, event: Event];
|
||||
'selection-change': [selection: Record<string, any>[]];
|
||||
'sort-change': [sortInfo: { column: any; prop: string; order: string }];
|
||||
pagination: [pagination: { page: number; limit: number }];
|
||||
}>();
|
||||
|
||||
const internalPageNo = ref(props.pageNo);
|
||||
const internalPageSize = ref(props.pageSize);
|
||||
|
||||
watch(
|
||||
() => [props.pageNo, props.pageSize],
|
||||
([newPageNo, newPageSize]) => {
|
||||
if (!props.isAllData) {
|
||||
internalPageNo.value = newPageNo;
|
||||
internalPageSize.value = newPageSize;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.isAllData,
|
||||
(isAllData) => {
|
||||
if (isAllData) {
|
||||
internalPageNo.value = props.pageNo;
|
||||
internalPageSize.value = props.pageSize;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const computedPageNo = computed(() => {
|
||||
return props.isAllData ? internalPageNo.value : props.pageNo;
|
||||
});
|
||||
|
||||
const computedPageSize = computed(() => {
|
||||
return props.isAllData ? internalPageSize.value : props.pageSize;
|
||||
});
|
||||
|
||||
const computedTotal = computed(() => {
|
||||
return props.isAllData ? props.tableData.length : props.total;
|
||||
});
|
||||
|
||||
const computedTableData = computed(() => {
|
||||
if (!props.isAllData) {
|
||||
return props.tableData;
|
||||
}
|
||||
const start = (computedPageNo.value - 1) * computedPageSize.value;
|
||||
const end = start + computedPageSize.value;
|
||||
return props.tableData.slice(start, end);
|
||||
});
|
||||
|
||||
const handlePagination = (pagination: { page: number; limit: number }) => {
|
||||
if (props.isAllData) {
|
||||
internalPageNo.value = pagination.page;
|
||||
internalPageSize.value = pagination.limit;
|
||||
} else {
|
||||
emit('pagination', pagination);
|
||||
}
|
||||
nextTick(() => {
|
||||
calculateTableHeight();
|
||||
});
|
||||
};
|
||||
|
||||
const tableRef = ref<InstanceType<typeof import('element-plus').ElTable> | null>(null);
|
||||
const tableWrapperRef = ref<HTMLDivElement | null>(null);
|
||||
const paginationWrapperRef = ref<HTMLDivElement | null>(null);
|
||||
const dynamicTableHeight = ref<number | null>(null);
|
||||
const paginationHeight = ref<number>(0);
|
||||
|
||||
const computedTableHeight = computed(() => {
|
||||
if (props.tableHeight) {
|
||||
return props.tableHeight;
|
||||
}
|
||||
if (props.maxHeight) {
|
||||
return props.maxHeight;
|
||||
}
|
||||
if (dynamicTableHeight.value) {
|
||||
const height = dynamicTableHeight.value - paginationHeight.value;
|
||||
return height > 0 ? height : dynamicTableHeight.value;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
const calculateTableHeight = () => {
|
||||
nextTick(() => {
|
||||
if (tableWrapperRef.value) {
|
||||
const tableContainer = tableWrapperRef.value.parentElement;
|
||||
if (tableContainer) {
|
||||
const containerRect = tableContainer.getBoundingClientRect();
|
||||
let height = containerRect.height;
|
||||
|
||||
if (props.showPagination && paginationWrapperRef.value && computedTotal.value > 0) {
|
||||
const paginationRect = paginationWrapperRef.value.getBoundingClientRect();
|
||||
paginationHeight.value = paginationRect.height;
|
||||
height -= paginationRect.height;
|
||||
} else {
|
||||
paginationHeight.value = 0;
|
||||
}
|
||||
|
||||
if (height > 0) {
|
||||
dynamicTableHeight.value = height;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
let resizeObserver: ResizeObserver | null = null;
|
||||
let paginationObserver: ResizeObserver | null = null;
|
||||
|
||||
onMounted(() => {
|
||||
calculateTableHeight();
|
||||
const tableContainer = tableWrapperRef.value?.parentElement;
|
||||
if (tableContainer && window.ResizeObserver) {
|
||||
resizeObserver = new ResizeObserver(() => {
|
||||
calculateTableHeight();
|
||||
});
|
||||
resizeObserver.observe(tableContainer);
|
||||
} else {
|
||||
window.addEventListener('resize', calculateTableHeight);
|
||||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.showPagination && computedTotal.value > 0 && paginationWrapperRef.value,
|
||||
(shouldObserve) => {
|
||||
if (shouldObserve && paginationWrapperRef.value && window.ResizeObserver) {
|
||||
if (!paginationObserver) {
|
||||
paginationObserver = new ResizeObserver(() => {
|
||||
calculateTableHeight();
|
||||
});
|
||||
}
|
||||
paginationObserver.observe(paginationWrapperRef.value);
|
||||
} else if (paginationObserver && paginationWrapperRef.value) {
|
||||
paginationObserver.unobserve(paginationWrapperRef.value);
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
onUnmounted(() => {
|
||||
if (resizeObserver) {
|
||||
resizeObserver.disconnect();
|
||||
}
|
||||
if (paginationObserver) {
|
||||
paginationObserver.disconnect();
|
||||
}
|
||||
if (!resizeObserver) {
|
||||
window.removeEventListener('resize', calculateTableHeight);
|
||||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.tableData,
|
||||
() => {
|
||||
calculateTableHeight();
|
||||
if (props.isAllData && internalPageNo.value !== 1) {
|
||||
internalPageNo.value = 1;
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
watch(
|
||||
() => [props.showPagination, computedTotal.value],
|
||||
() => {
|
||||
calculateTableHeight();
|
||||
}
|
||||
);
|
||||
|
||||
const handleRowClick = (row: Record<string, any>, column: any, event: Event) => {
|
||||
emit('row-click', row, column, event);
|
||||
};
|
||||
|
||||
const handleSelectionChange = (selection: Record<string, any>[]) => {
|
||||
emit('selection-change', selection);
|
||||
};
|
||||
|
||||
const handleSortChange = ({
|
||||
column,
|
||||
prop,
|
||||
order,
|
||||
}: {
|
||||
column: any;
|
||||
prop: string;
|
||||
order: string;
|
||||
}) => {
|
||||
emit('sort-change', { column, prop, order });
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
tableRef,
|
||||
tableWrapperRef,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.table-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.table-wrapper {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.pagination-wrapper {
|
||||
flex-shrink: 0;
|
||||
margin-top: 8px;
|
||||
padding-bottom: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.pagination-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 16px;
|
||||
|
||||
&.has-left-content {
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
|
||||
.pagination-left {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
color: var(--el-text-color-regular);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.pagination-content :deep(.pagination-container) {
|
||||
.el-pagination {
|
||||
margin-right: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
27
openhis-ui-vue3/src/components/TableLayout/TableSection.vue
Normal file
27
openhis-ui-vue3/src/components/TableLayout/TableSection.vue
Normal file
@@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<div class="table-section">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineOptions({
|
||||
name: 'TableSection',
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.table-section {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
:deep(.editable-table) {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
411
openhis-ui-vue3/src/components/TableLayout/index.vue
Normal file
411
openhis-ui-vue3/src/components/TableLayout/index.vue
Normal file
@@ -0,0 +1,411 @@
|
||||
<template>
|
||||
<div class="table-layout-container">
|
||||
<div class="card-content-wrapper">
|
||||
<div
|
||||
v-if="showSideQuery"
|
||||
class="side-query-wrapper"
|
||||
:class="{ collapsed: sideQueryCollapsed }"
|
||||
>
|
||||
<div v-if="!sideQueryCollapsed" class="side-query-header">
|
||||
<el-input v-model="sideSearchKeyword" placeholder="搜索树节点" clearable size="small">
|
||||
<template #prefix>
|
||||
<el-icon><Search /></el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
<div v-if="!sideQueryCollapsed" class="side-query-content">
|
||||
<el-tree
|
||||
ref="treeRef"
|
||||
:data="treeDataWithAll"
|
||||
:props="defaultProps"
|
||||
:node-key="treeNodeKey"
|
||||
:expand-on-click-node="false"
|
||||
default-expand-all
|
||||
highlight-current
|
||||
@node-click="handleNodeClick"
|
||||
@current-change="handleCurrentChange"
|
||||
></el-tree>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="showSideQuery" class="collapse-divider">
|
||||
<el-button
|
||||
circle
|
||||
size="small"
|
||||
class="collapse-btn"
|
||||
@click="sideQueryCollapsed = !sideQueryCollapsed"
|
||||
>
|
||||
<el-icon>
|
||||
<ArrowRight v-if="sideQueryCollapsed" />
|
||||
<ArrowLeft v-else />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 主内容区域 -->
|
||||
<div
|
||||
class="main-content-wrapper"
|
||||
:class="{ 'with-side-query': showSideQuery && !sideQueryCollapsed }"
|
||||
>
|
||||
<Filter
|
||||
v-if="showTopQuery"
|
||||
ref="queryFormComponentRef"
|
||||
:query-params="queryParams"
|
||||
:form-items="formItems"
|
||||
:show-default-buttons="showDefaultButtons"
|
||||
@query="handleQuery"
|
||||
@reset="resetQuery"
|
||||
>
|
||||
<template
|
||||
v-for="item in customFormItems"
|
||||
:key="item.prop"
|
||||
v-slot:[item.slotName]="slotProps"
|
||||
>
|
||||
<slot :name="item.slotName" :item="slotProps.item" :queryParams="props.queryParams" />
|
||||
</template>
|
||||
<template #default="{ queryParams, handleQuery, resetQuery }">
|
||||
<slot
|
||||
name="topQuery"
|
||||
:queryParams="queryParams"
|
||||
:handleQuery="handleQuery"
|
||||
:resetQuery="resetQuery"
|
||||
/>
|
||||
</template>
|
||||
</Filter>
|
||||
|
||||
<!-- 操作按钮区域 -->
|
||||
<div class="table-operation-bar">
|
||||
<slot name="operations" />
|
||||
</div>
|
||||
|
||||
<!-- 表格区域 -->
|
||||
<Table
|
||||
:table-data="tableData"
|
||||
:loading="loading"
|
||||
:border="border"
|
||||
:stripe="stripe"
|
||||
:size="size"
|
||||
:table-height="tableHeight"
|
||||
:max-height="maxHeight"
|
||||
:row-key="rowKey"
|
||||
:highlight-current-row="highlightCurrentRow"
|
||||
:table-columns="tableColumns"
|
||||
:show-pagination="showPagination"
|
||||
:total="total"
|
||||
:page-no="props.queryParams.pageNo"
|
||||
:page-size="props.queryParams.pageSize"
|
||||
@row-click="handleRowClick"
|
||||
@selection-change="handleSelectionChange"
|
||||
@sort-change="handleSortChange"
|
||||
@pagination="handlePagination"
|
||||
>
|
||||
<template v-for="(_, slotName) in $slots" :key="slotName" #[slotName]="slotProps">
|
||||
<slot :name="slotName" v-bind="slotProps" />
|
||||
</template>
|
||||
</Table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue';
|
||||
import Filter from './Filter.vue';
|
||||
import Table from './Table.vue';
|
||||
import type { TableLayoutProps, TreeNodeData } from '../types/TableLayout.d';
|
||||
|
||||
defineOptions({
|
||||
name: 'TableLayout',
|
||||
});
|
||||
|
||||
const props = withDefaults(defineProps<TableLayoutProps>(), {
|
||||
tableData: () => [],
|
||||
loading: false,
|
||||
total: 0,
|
||||
queryParams: () => ({
|
||||
pageNo: 1,
|
||||
pageSize: 20,
|
||||
}),
|
||||
sideQueryParams: () => ({}),
|
||||
formItems: () => [],
|
||||
showTopQuery: true,
|
||||
showSideQuery: false,
|
||||
showPagination: true,
|
||||
showDefaultButtons: true,
|
||||
sideWidth: 6,
|
||||
border: true,
|
||||
stripe: false,
|
||||
size: 'default',
|
||||
highlightCurrentRow: false,
|
||||
siderData: () => [],
|
||||
treeNodeKey: 'id',
|
||||
tableColumns: () => [],
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
query: [queryParams: Record<string, any>];
|
||||
reset: [];
|
||||
pagination: [pagination: { page: number; limit: number }];
|
||||
'row-click': [row: Record<string, any>, column: any, event: Event];
|
||||
'selection-change': [selection: Record<string, any>[]];
|
||||
'sort-change': [sortInfo: { column: any; prop: string; order: string }];
|
||||
'side-query': [node: TreeNodeData];
|
||||
'reset-side-query': [];
|
||||
}>();
|
||||
|
||||
const queryFormRef = ref<InstanceType<typeof import('element-plus').ElForm> | null>(null);
|
||||
import type { FilterExpose } from '../types/Filter.d';
|
||||
const queryFormComponentRef = ref<FilterExpose | null>(null);
|
||||
const sideSearchKeyword = ref<string>('');
|
||||
const treeRef = ref<InstanceType<typeof import('element-plus').ElTree> | null>(null);
|
||||
const currentTreeNode = ref<TreeNodeData | null>(null);
|
||||
const sideQueryCollapsed = ref<boolean>(false);
|
||||
|
||||
const customFormItems = computed(() => {
|
||||
return props.formItems
|
||||
.filter((item) => item.type === 'custom')
|
||||
.map((item) => ({
|
||||
...item,
|
||||
slotName: item.slot || item.prop,
|
||||
}));
|
||||
});
|
||||
|
||||
const defaultProps = {
|
||||
children: 'children',
|
||||
label: 'label',
|
||||
};
|
||||
|
||||
const filteredSiderData = computed(() => {
|
||||
if (!sideSearchKeyword.value || !props.siderData || props.siderData.length === 0) {
|
||||
return props.siderData;
|
||||
}
|
||||
|
||||
const keyword = sideSearchKeyword.value.toLowerCase();
|
||||
|
||||
const filterTree = (nodes: TreeNodeData[]): TreeNodeData[] => {
|
||||
if (!nodes || nodes.length === 0) return [];
|
||||
|
||||
return nodes
|
||||
.map((node: TreeNodeData) => {
|
||||
const label = (node[defaultProps.label] || '').toLowerCase();
|
||||
const match = label.includes(keyword);
|
||||
const children = node[defaultProps.children];
|
||||
|
||||
let filteredChildren: TreeNodeData[] | null = null;
|
||||
if (children && children.length > 0) {
|
||||
filteredChildren = filterTree(children);
|
||||
}
|
||||
|
||||
if (match || (filteredChildren && filteredChildren.length > 0)) {
|
||||
return {
|
||||
...node,
|
||||
[defaultProps.children]: filteredChildren,
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
})
|
||||
.filter(Boolean) as TreeNodeData[];
|
||||
};
|
||||
|
||||
return filterTree(props.siderData);
|
||||
});
|
||||
|
||||
const treeDataWithAll = computed(() => {
|
||||
const children = filteredSiderData.value || [];
|
||||
return [
|
||||
{
|
||||
[props.treeNodeKey]: '__ALL__',
|
||||
[defaultProps.label]: '全部',
|
||||
[defaultProps.children]: children || [],
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
const handleQuery = () => {
|
||||
props.queryParams.pageNo = 1;
|
||||
emit('query', props.queryParams);
|
||||
if (currentTreeNode.value) {
|
||||
emit('side-query', currentTreeNode.value);
|
||||
}
|
||||
};
|
||||
|
||||
const handleNodeClick = (data: TreeNodeData, node: any) => {
|
||||
currentTreeNode.value = data;
|
||||
if (treeRef.value && data && data[props.treeNodeKey]) {
|
||||
treeRef.value.setCurrentKey(data[props.treeNodeKey]);
|
||||
}
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
const handleCurrentChange = (data: TreeNodeData, node: any) => {
|
||||
currentTreeNode.value = data;
|
||||
};
|
||||
|
||||
const resetQuery = () => {
|
||||
if (queryFormComponentRef.value?.queryFormRef) {
|
||||
queryFormComponentRef.value.queryFormRef.resetFields();
|
||||
}
|
||||
if (props.queryParams) {
|
||||
Object.keys(props.queryParams).forEach((key) => {
|
||||
if (key !== 'pageNo' && key !== 'pageSize') {
|
||||
if (Array.isArray(props.queryParams[key])) {
|
||||
props.queryParams[key] = [];
|
||||
} else if (typeof props.queryParams[key] === 'object' && props.queryParams[key] !== null) {
|
||||
props.queryParams[key] = null;
|
||||
} else {
|
||||
props.queryParams[key] = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
if (Object.prototype.hasOwnProperty.call(props.queryParams, 'pageNo')) {
|
||||
props.queryParams.pageNo = 1;
|
||||
}
|
||||
}
|
||||
emit('reset');
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
const handlePagination = (pagination) => {
|
||||
if (props.queryParams) {
|
||||
props.queryParams.pageNo = pagination.page;
|
||||
props.queryParams.pageSize = pagination.limit;
|
||||
}
|
||||
emit('pagination', pagination);
|
||||
emit('query', props.queryParams);
|
||||
if (currentTreeNode.value) {
|
||||
emit('side-query', currentTreeNode.value);
|
||||
}
|
||||
};
|
||||
|
||||
const handleRowClick = (row, column, event) => {
|
||||
emit('row-click', row, column, event);
|
||||
};
|
||||
|
||||
const handleSelectionChange = (selection) => {
|
||||
emit('selection-change', selection);
|
||||
};
|
||||
|
||||
const handleSortChange = ({ column, prop, order }) => {
|
||||
emit('sort-change', { column, prop, order });
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
queryFormRef: computed(() => queryFormComponentRef.value?.queryFormRef),
|
||||
handleQuery,
|
||||
resetQuery,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.table-layout-container {
|
||||
height: 100%;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
|
||||
.main-content-card {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
overflow: visible;
|
||||
|
||||
:deep(.el-card__body) {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 16px 16px 8px 16px;
|
||||
min-height: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
}
|
||||
|
||||
.card-content-wrapper {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
gap: 0;
|
||||
min-height: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.collapse-divider {
|
||||
flex-shrink: 0;
|
||||
width: 1px;
|
||||
background-color: #ebeef5;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
margin: 0 12px;
|
||||
|
||||
.collapse-btn {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 18px;
|
||||
transform: translateX(-50%);
|
||||
background-color: #fff;
|
||||
border: 1px solid #ebeef5;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
|
||||
z-index: 10;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
|
||||
&:hover {
|
||||
background-color: #409eff;
|
||||
color: #fff;
|
||||
border-color: #409eff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.side-query-wrapper {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
transition: width 0.3s, opacity 0.3s;
|
||||
overflow: hidden;
|
||||
|
||||
&.collapsed {
|
||||
width: 0;
|
||||
opacity: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.side-query-header {
|
||||
flex-shrink: 0;
|
||||
margin-bottom: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.side-query-content {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
|
||||
:deep(.el-tree--highlight-current) {
|
||||
background-color: #fff !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.main-content-wrapper {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.table-operation-bar {
|
||||
flex-shrink: 0;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,188 +1,125 @@
|
||||
<!--
|
||||
* @Author: sjjh
|
||||
* @Date: 2025-04-07 20:42:45
|
||||
* @Description:住院患者信息,给医生用,带折叠
|
||||
-->
|
||||
<template>
|
||||
<div class="inPatientBarDoctorFold-container">
|
||||
<div class="basic_info">
|
||||
<div class="patient-header white-bg">
|
||||
<div class="select_wrapper_div">
|
||||
<b class="bedNumber" style="margin-left: 12px">{{ patientInfo?.bedName }}</b>
|
||||
<label class="content-text-color" style="margin-left: 12px; color: #a15209">
|
||||
{{ patientInfo?.patientName }}
|
||||
<span class="sex-age"> {{ patientInfo?.sexName }}/{{ patientInfo?.age }} </span>
|
||||
<b class="bedNumber">{{ patientInfo?.bedName || '未分床' }}</b>
|
||||
<label class="patient-name">
|
||||
{{ patientInfo?.patientName || '-' }}
|
||||
<span class="sex-age">
|
||||
{{ formatSexAge(patientInfo?.sexName, patientInfo?.age) }}
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<div style="display: flex; margin-left: 8px">
|
||||
<!-- 状态展示// TODO 后端给状态,前段 -->
|
||||
<div class="tag-list" v-if="patientInfo?.list && patientInfo.list.length > 0">
|
||||
<ball-tag
|
||||
style="margin-right: 4px"
|
||||
v-for="item in patientInfo?.list"
|
||||
v-for="item in patientInfo.list"
|
||||
:key="item"
|
||||
:tagId="item"
|
||||
class="tag-item"
|
||||
></ball-tag>
|
||||
</div>
|
||||
<div
|
||||
class="gray-border"
|
||||
v-show="patientInfo?.feeTypeName && patientInfo?.feeTypeName !== ''"
|
||||
>
|
||||
{{ patientInfo?.feeTypeName }}
|
||||
<div class="gray-border" v-if="patientInfo?.feeTypeName">
|
||||
{{ patientInfo.feeTypeName }}
|
||||
</div>
|
||||
<label style="margin-left: 24px">
|
||||
<label class="info-label">
|
||||
<span class="label-text-color">住院:</span>
|
||||
<span class="content-text-color">{{ patientInfo?.inHospitalDays + '天' }}</span>
|
||||
<span class="content-text-color">{{ formatDays(patientInfo?.inHospitalDays) }}</span>
|
||||
</label>
|
||||
<label style="margin-left: 24px">
|
||||
<label class="info-label" v-if="patientInfo?.inOrgTime">
|
||||
<span class="label-text-color">入科:</span>
|
||||
<span class="content-text-color">{{ patientInfo?.inDeptDate }}</span>
|
||||
<span class="content-text-color">{{ patientInfo.inOrgTime }}</span>
|
||||
</label>
|
||||
<label style="margin-left: 24px">
|
||||
<label class="info-label" v-if="patientInfo?.inHospitalTime">
|
||||
<span class="label-text-color">入院时间:</span>
|
||||
<span class="content-text-color">{{ patientInfo?.inHospitalTime }}</span>
|
||||
<span class="content-text-color">{{ patientInfo.inHospitalTime }}</span>
|
||||
</label>
|
||||
<label style="margin-left: 24px">
|
||||
<span class="label-text-color">住院号:{{ patientInfo?.busNo }}</span>
|
||||
<label class="info-label" v-if="patientInfo?.busNo">
|
||||
<span class="label-text-color">住院号:</span>
|
||||
<span class="content-text-color">{{ patientInfo.busNo }}</span>
|
||||
</label>
|
||||
<svg-icon icon-class="hipCopy" height="20px" width="20px" class="copy-svg" />
|
||||
<label style="margin-left: 30px">
|
||||
<label class="info-label diagnosis-label" v-if="patientInfo?.regDiagnosisName">
|
||||
<span class="label-text-color">诊断:</span>
|
||||
<span class="content-text-color">{{ patientInfo?.regDiagnosisName }}</span>
|
||||
<span class="content-text-color">{{ patientInfo.regDiagnosisName }}</span>
|
||||
</label>
|
||||
<label class="info-label">
|
||||
<span class="label-text-color">费用:</span>
|
||||
<span class="content-text-color">{{ formatMoney(patientInfo?.totalAmount) }}</span>
|
||||
</label>
|
||||
<label class="info-label">
|
||||
<span class="label-text-color">余额:</span>
|
||||
<span class="content-text-color">{{ formatMoney(patientInfo?.balanceAmount) }}</span>
|
||||
</label>
|
||||
<!-- <div style="margin-left: auto">
|
||||
<el-icon v-if="expand" @click="toggleExpand"><ArrowUpBold /></el-icon>
|
||||
<el-icon v-else @click="toggleExpand"><ArrowDownBold /></el-icon>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="expand" class="expand_more">
|
||||
<div style="background-color: #ffffff">
|
||||
<div style="margin-top: -10px">
|
||||
<label style="font-size: 14px">
|
||||
<div class="expand-content">
|
||||
<div class="expand-section">
|
||||
<label class="expand-label">
|
||||
<span class="primary-text">过敏:</span>
|
||||
<span class="primary-text">{{ patientInfo?.allergies || '无过敏史' }}</span>
|
||||
</label>
|
||||
<label style="font-size: 14px; margin-left: 32px" v-show="patientInfo?.insuplcAdmdvsName">
|
||||
<span class="primary-text">医保统筹区:</span>
|
||||
<span class="primary-text">{{ patientInfo?.insuplcAdmdvsName }}</span>
|
||||
<label class="expand-label" v-if="patientInfo?.insuplcAdmdvsName">
|
||||
<span class="primary-text">医保统筹区:</span>
|
||||
<span class="primary-text">{{ patientInfo.insuplcAdmdvsName }}</span>
|
||||
</label>
|
||||
|
||||
<label style="font-size: 14px; margin-left: 32px" v-show="patientInfo?.ciType">
|
||||
<label class="expand-label" v-if="patientInfo?.ciType">
|
||||
<span class="primary-text">商保信息:</span>
|
||||
<span class="primary-text">{{ patientInfo?.ciType }}</span>
|
||||
<span class="primary-text">{{ patientInfo.ciType }}</span>
|
||||
</label>
|
||||
<div style="display: flex; flex-wrap: nowrap; margin-top: 8px; white-space: nowrap">
|
||||
<div
|
||||
class="blue-bg"
|
||||
style="background-color: #f1faff; flex-shrink: 0; min-width: fit-content"
|
||||
>
|
||||
<div class="info-tags">
|
||||
<div class="blue-bg">
|
||||
<span class="content-text-color">
|
||||
{{
|
||||
patientInfo?.height && patientInfo?.weight
|
||||
? `${patientInfo?.height}cm/${patientInfo?.weight}kg`
|
||||
: '身高/体重'
|
||||
}}
|
||||
{{ formatHeightWeight(patientInfo?.height, patientInfo?.weight) }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="blue-bg"
|
||||
style="
|
||||
margin-left: 24px;
|
||||
background-color: #f1faff;
|
||||
flex-shrink: 0;
|
||||
min-width: fit-content;
|
||||
"
|
||||
v-show="patientInfo?.postoperativeDays"
|
||||
>
|
||||
<span class="content-text-color">术后{{ patientInfo?.postoperativeDays }}天</span>
|
||||
<div class="blue-bg" v-if="patientInfo?.postoperativeDays">
|
||||
<span class="content-text-color">术后{{ patientInfo.postoperativeDays }}天</span>
|
||||
</div>
|
||||
<div
|
||||
class="blue-bg"
|
||||
style="
|
||||
margin-left: 16px;
|
||||
background-color: #f1faff;
|
||||
flex-shrink: 0;
|
||||
min-width: fit-content;
|
||||
"
|
||||
v-show="patientInfo?.poorTypeName"
|
||||
>
|
||||
<span class="label-text-color">贫困类型:</span>
|
||||
<span class="content-text-color" style="margin-left: 4px">{{
|
||||
patientInfo?.poorTypeName
|
||||
}}</span>
|
||||
<div class="blue-bg" v-if="patientInfo?.poorTypeName">
|
||||
<span class="label-text-color">贫困类型:</span>
|
||||
<span class="content-text-color">{{ patientInfo.poorTypeName }}</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="blue-bg"
|
||||
style="
|
||||
margin-left: 16px;
|
||||
background-color: #f1faff;
|
||||
flex-shrink: 0;
|
||||
min-width: fit-content;
|
||||
"
|
||||
v-show="patientInfo?.pathwayName"
|
||||
>
|
||||
<span class="label-text-color">路径情况:</span>
|
||||
<span class="content-text-color" style="margin-left: 4px">{{
|
||||
patientInfo?.pathwayName
|
||||
}}</span>
|
||||
<div class="blue-bg" v-if="patientInfo?.pathwayName">
|
||||
<span class="label-text-color">路径情况:</span>
|
||||
<span class="content-text-color">{{ patientInfo.pathwayName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="background-color: #ffffff">
|
||||
<div style="margin-top: -10px">
|
||||
<div class="expand-content">
|
||||
<div class="expand-section">
|
||||
<div class="patient-board">
|
||||
<div class="item-center">
|
||||
<div class="line-block">
|
||||
<div class="line-block-top">
|
||||
<span class="label-text-color">科室:</span>
|
||||
<span class="content-text-color">{{ patientInfo?.admissionDeptName }}</span>
|
||||
<span class="content-text-color">{{
|
||||
patientInfo?.admissionDeptName || '-'
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="line-block-bottom">
|
||||
<span class="label-text-color">病区:</span>
|
||||
<span class="content-text-color">{{ patientInfo?.deptNurseName }}</span>
|
||||
<span class="content-text-color">{{ patientInfo?.deptNurseName || '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="line-block">
|
||||
<div class="line-block-top">
|
||||
<span class="label-text-color">主治医生:</span>
|
||||
<span class="content-text-color">{{ patientInfo?.masterDoctorName }}</span>
|
||||
<span class="content-text-color">{{ patientInfo?.masterDoctorName || '-' }}</span>
|
||||
</div>
|
||||
<div class="line-block-bottom">
|
||||
<span class="label-text-color">责任护士:</span>
|
||||
<span class="content-text-color">{{ patientInfo?.masterNurseName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="line-blockMoney">
|
||||
<div class="line-blockMoney-top">
|
||||
<span class="label-text-color">费用</span>
|
||||
</div>
|
||||
<div class="line-blockMoney-bottom">
|
||||
<b class="money-content size-15">{{
|
||||
patientInfo?.totalAmount ? patientInfo?.totalAmount : 0
|
||||
}}</b>
|
||||
<span class="content-text-color">{{ patientInfo?.masterNurseName || '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="line-blockMoney">
|
||||
<div class="line-blockMoney-top">
|
||||
<span class="label-text-color">预交金</span>
|
||||
</div>
|
||||
<div class="line-blockMoney-bottom">
|
||||
<b class="money-content size-15">{{
|
||||
patientInfo?.prepayAmount ? patientInfo?.prepayAmount : 0
|
||||
}}</b>
|
||||
</div>
|
||||
</div>
|
||||
<div class="line-blockMoney">
|
||||
<div class="line-blockMoney-top">
|
||||
<span class="label-text-color">余额</span>
|
||||
</div>
|
||||
<div class="line-blockMoney-bottom">
|
||||
<b class="money-content size-15">{{
|
||||
patientInfo?.balance ? patientInfo?.balance : 0
|
||||
}}</b>
|
||||
<b class="money-content size-15">{{ formatMoney(patientInfo?.prepayAmount) }}</b>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -192,45 +129,57 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { computed, onMounted, ref, watch } from 'vue';
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue';
|
||||
import BallTag from './components/BallTag.vue';
|
||||
import { patientInfo } from '@/views/inpatientDoctor/home/store/patient.js';
|
||||
// import { ElMessage } from 'element-plus'
|
||||
|
||||
const expand = ref(false);
|
||||
|
||||
const showDividers = ref(true);
|
||||
|
||||
// 示例方法:切换显示状态
|
||||
const toggleDividers = () => {
|
||||
showDividers.value = !showDividers.value;
|
||||
};
|
||||
const iconClass = ref('hipBarDown');
|
||||
|
||||
// 切换展开状态的方法
|
||||
function toggleExpand() {
|
||||
expand.value = !expand.value;
|
||||
iconClass.value = expand.value ? 'hipBarUp' : 'hipBarDown';
|
||||
toggleDividers();
|
||||
interface Props {
|
||||
visitCode?: string;
|
||||
}
|
||||
|
||||
const fetchPatientInfoById = async (patientId) => {
|
||||
// 查询患者信息
|
||||
console.log(patientId);
|
||||
};
|
||||
|
||||
const props = defineProps({
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
visitCode: '',
|
||||
});
|
||||
watch(
|
||||
() => props.visitCode,
|
||||
(val) => {
|
||||
if (val !== null && val !== '') {
|
||||
fetchPatientInfoById(val);
|
||||
}
|
||||
|
||||
const expand = ref<boolean>(false);
|
||||
|
||||
// 格式化性别和年龄
|
||||
const formatSexAge = (sexName?: string, age?: number | string): string => {
|
||||
const sex = sexName || '';
|
||||
const ageStr = age !== undefined && age !== null ? String(age) : '';
|
||||
if (sex && ageStr) {
|
||||
return `${sex}/${ageStr}`;
|
||||
} else if (sex) {
|
||||
return sex;
|
||||
} else if (ageStr) {
|
||||
return ageStr;
|
||||
}
|
||||
);
|
||||
return '-';
|
||||
};
|
||||
|
||||
// 格式化天数
|
||||
const formatDays = (days?: number | string): string => {
|
||||
if (days === undefined || days === null || days === '') {
|
||||
return '-';
|
||||
}
|
||||
return `${days}天`;
|
||||
};
|
||||
|
||||
// 格式化身高体重
|
||||
const formatHeightWeight = (height?: number | string, weight?: number | string): string => {
|
||||
if (height && weight) {
|
||||
return `${height}cm/${weight}kg`;
|
||||
}
|
||||
return '身高/体重';
|
||||
};
|
||||
|
||||
// 格式化金额
|
||||
const formatMoney = (amount?: number | string): number => {
|
||||
if (amount === undefined || amount === null || amount === '') {
|
||||
return 0;
|
||||
}
|
||||
return Number(amount) || 0;
|
||||
};
|
||||
|
||||
defineOptions({
|
||||
name: 'NurserDoctorPatientBarminimal',
|
||||
@@ -240,27 +189,77 @@ defineOptions({
|
||||
<style lang="scss" scoped>
|
||||
.inPatientBarDoctorFold-container {
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
background-color: #ffffff;
|
||||
align-items: center;
|
||||
.basic_info {
|
||||
height: 43px;
|
||||
min-height: 44px;
|
||||
padding: 0 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
/* expand_more */
|
||||
|
||||
.expand_more {
|
||||
width: 100%;
|
||||
height: 56px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-direction: column;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.expand-content {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.expand-section {
|
||||
margin-top: -10px;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.patient-header {
|
||||
width: 100%;
|
||||
padding: 6px 0;
|
||||
font-size: 13px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
|
||||
.select_wrapper_div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.bedNumber {
|
||||
font-weight: bold;
|
||||
font-size: 18px;
|
||||
margin-left: 12px;
|
||||
color: #1f2933;
|
||||
}
|
||||
|
||||
.patient-name {
|
||||
margin-left: 12px;
|
||||
color: #a15209;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.sex-age {
|
||||
margin-left: 20px;
|
||||
margin-left: 8px;
|
||||
color: var(--hip-color-text-description);
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.tag-list {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: 8px;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.tag-item {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.gray-border {
|
||||
@@ -270,43 +269,66 @@ defineOptions({
|
||||
align-items: center;
|
||||
border: 1px solid var(--hip-color-text-description);
|
||||
border-radius: 20px;
|
||||
padding: 0px 8px;
|
||||
padding: 0 8px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
margin-left: 24px;
|
||||
white-space: nowrap;
|
||||
|
||||
&:first-of-type {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.diagnosis-label {
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
.copy-svg {
|
||||
fill: var(--hip-color-primary);
|
||||
cursor: pointer;
|
||||
margin-left: 4px;
|
||||
transition: opacity 0.2s;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.expand-label {
|
||||
font-size: 14px;
|
||||
margin-right: 32px;
|
||||
white-space: nowrap;
|
||||
|
||||
&:first-child {
|
||||
margin-right: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.info-tags {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
margin-top: 8px;
|
||||
white-space: nowrap;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.size-15 {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.bedNumber {
|
||||
font-weight: bold;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.primary-text {
|
||||
color: var(--hip-color-primary);
|
||||
}
|
||||
|
||||
.flex-between {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.item-center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.patient-board {
|
||||
margin-left: 20px;
|
||||
|
||||
@@ -330,10 +352,8 @@ defineOptions({
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.money-content {
|
||||
color: #ff8616;
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
&-bottom {
|
||||
margin-top: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -354,7 +374,7 @@ defineOptions({
|
||||
}
|
||||
|
||||
&-top {
|
||||
margin-bottom: 0px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.money-content {
|
||||
@@ -378,13 +398,24 @@ defineOptions({
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #f1faff;
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
border-radius: 4px; /*圆角*/
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
flex-shrink: 0;
|
||||
min-width: fit-content;
|
||||
white-space: nowrap;
|
||||
|
||||
.content-text-color {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.label-text-color {
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.label-text-color {
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.content-text-color {
|
||||
|
||||
42
openhis-ui-vue3/src/components/types/Dialog.d.ts
vendored
Normal file
42
openhis-ui-vue3/src/components/types/Dialog.d.ts
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Dialog 尺寸类型
|
||||
*/
|
||||
export type DialogSize = 'small' | 'medium' | 'large';
|
||||
|
||||
/**
|
||||
* Dialog 组件的 Props 类型
|
||||
*/
|
||||
export interface DialogProps {
|
||||
/** 对话框标题 */
|
||||
title?: string;
|
||||
/** 对话框尺寸 */
|
||||
size?: DialogSize;
|
||||
/** 自定义宽度 */
|
||||
width?: string | number;
|
||||
/** 自定义高度 */
|
||||
height?: string | number;
|
||||
/** 是否显示对话框 */
|
||||
modelValue?: boolean;
|
||||
/** 是否在关闭时销毁子元素 */
|
||||
destroyOnClose?: boolean;
|
||||
/** 是否将对话框追加到 body 上 */
|
||||
appendToBody?: boolean;
|
||||
/** 是否可以通过点击遮罩层关闭对话框 */
|
||||
closeOnClickModal?: boolean;
|
||||
/** 是否可以通过按下 ESC 关闭对话框 */
|
||||
closeOnPressEscape?: boolean;
|
||||
/** 是否显示关闭按钮 */
|
||||
showClose?: boolean;
|
||||
/** 是否在对话框出现时将 body 滚动锁定 */
|
||||
lockScroll?: boolean;
|
||||
/** 自定义类名 */
|
||||
customClass?: string;
|
||||
/** 是否可拖拽 */
|
||||
draggable?: boolean;
|
||||
/** 是否全屏 */
|
||||
fullscreen?: boolean;
|
||||
/** 是否显示加载状态 */
|
||||
loading?: boolean;
|
||||
/** 对话框打开前的回调 */
|
||||
beforeClose?: (done: () => void) => void;
|
||||
}
|
||||
99
openhis-ui-vue3/src/components/types/EditableTable.d.ts
vendored
Normal file
99
openhis-ui-vue3/src/components/types/EditableTable.d.ts
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
import type { FormItemOption } from './FormItem.d';
|
||||
|
||||
/**
|
||||
* 可编辑表格列配置类型
|
||||
*/
|
||||
export interface EditableTableColumn {
|
||||
/** 列字段名 */
|
||||
prop: string;
|
||||
/** 列标签 */
|
||||
label: string;
|
||||
/** 列宽度 */
|
||||
width?: string | number;
|
||||
/** 最小宽度 */
|
||||
minWidth?: string | number;
|
||||
/** 是否固定列 */
|
||||
fixed?: boolean | 'left' | 'right';
|
||||
/** 对齐方式 */
|
||||
align?: 'left' | 'center' | 'right';
|
||||
/** 列类型 */
|
||||
type?: 'input' | 'number' | 'select' | 'date' | 'slot';
|
||||
/** 占位符 */
|
||||
placeholder?: string;
|
||||
/** 是否禁用 */
|
||||
disabled?: boolean | ((row: Record<string, any>, index: number) => boolean);
|
||||
/** 是否可清空 */
|
||||
clearable?: boolean;
|
||||
/** 是否可搜索(select 类型) */
|
||||
filterable?: boolean;
|
||||
/** 是否多选(select 类型) */
|
||||
multiple?: boolean;
|
||||
/** 最小值(number 类型) */
|
||||
min?: number;
|
||||
/** 最大值(number 类型) */
|
||||
max?: number;
|
||||
/** 精度(number 类型) */
|
||||
precision?: number;
|
||||
/** 日期类型(date 类型) */
|
||||
dateType?: 'date' | 'datetime' | 'daterange';
|
||||
/** 日期格式 */
|
||||
valueFormat?: string;
|
||||
/** 选项列表(select 类型) */
|
||||
options?: FormItemOption[] | ((row: Record<string, any>, index: number) => FormItemOption[]);
|
||||
/** 自定义插槽名称(slot 类型) */
|
||||
slot?: string;
|
||||
/** 格式化函数 */
|
||||
formatter?: (row: Record<string, any>, column: any, cellValue: any) => string;
|
||||
/** 验证规则 */
|
||||
rules?: any;
|
||||
/** 后缀文本(input 类型) */
|
||||
suffix?: string;
|
||||
/** 条件显示 */
|
||||
vIf?: () => boolean;
|
||||
/** 失焦回调 */
|
||||
onBlur?: (row: Record<string, any>, index: number) => void;
|
||||
/** 输入回调 */
|
||||
onInput?: (row: Record<string, any>, index: number) => void;
|
||||
/** 变更回调 */
|
||||
onChange?: (row: Record<string, any>, index: number, value?: any) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* EditableTable 组件的 Props 类型
|
||||
*/
|
||||
export interface EditableTableProps {
|
||||
/** 表格数据 */
|
||||
modelValue: Record<string, any>[];
|
||||
/** 列配置 */
|
||||
columns: EditableTableColumn[];
|
||||
/** 表单验证规则 */
|
||||
rules?: Record<string, any>;
|
||||
/** 默认行数据 */
|
||||
defaultRow?: Record<string, any>;
|
||||
/** 是否显示边框 */
|
||||
border?: boolean;
|
||||
/** 是否显示斑马纹 */
|
||||
stripe?: boolean;
|
||||
/** 最大高度 */
|
||||
maxHeight?: string | number;
|
||||
/** 最小高度 */
|
||||
minHeight?: string | number;
|
||||
/** 是否开启虚拟滚动(不传则根据数据量自动开启) */
|
||||
virtualized?: boolean;
|
||||
/** 自动开启虚拟滚动的行数阈值,默认 100 */
|
||||
virtualizedThreshold?: number;
|
||||
/** 是否显示选择列 */
|
||||
showSelection?: boolean;
|
||||
/** 是否显示新增按钮 */
|
||||
showAddButton?: boolean;
|
||||
/** 是否显示删除按钮 */
|
||||
showDeleteButton?: boolean;
|
||||
/** 是否显示行级增删按钮 */
|
||||
showRowActions?: boolean;
|
||||
/** 是否显示行级“增加”按钮 */
|
||||
showRowAddButton?: boolean;
|
||||
/** 是否显示行级“删除”按钮 */
|
||||
showRowDeleteButton?: boolean;
|
||||
/** 搜索字段列表(用于筛选,不为空时自动显示搜索框) */
|
||||
searchFields?: string[];
|
||||
}
|
||||
30
openhis-ui-vue3/src/components/types/Filter.d.ts
vendored
Normal file
30
openhis-ui-vue3/src/components/types/Filter.d.ts
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
import type { FormItemConfig } from './FormItem.d';
|
||||
import type { DefineComponent } from 'vue';
|
||||
|
||||
/**
|
||||
* Filter 组件的 Props 类型
|
||||
*/
|
||||
export interface FilterProps {
|
||||
/** 查询参数对象 */
|
||||
queryParams: Record<string, any>;
|
||||
/** 表单项配置数组 */
|
||||
formItems: FormItemConfig[];
|
||||
/** 是否显示 */
|
||||
show?: boolean;
|
||||
/** 是否显示默认按钮 */
|
||||
showDefaultButtons?: boolean;
|
||||
/** 标签宽度 */
|
||||
labelWidth?: string;
|
||||
/** 标签后是否添加冒号 */
|
||||
showLabelColon?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter 组件暴露的方法
|
||||
*/
|
||||
export interface FilterExpose {
|
||||
queryFormRef: InstanceType<typeof import('element-plus').ElForm> | null;
|
||||
handleQuery: () => void;
|
||||
resetQuery: () => void;
|
||||
}
|
||||
|
||||
21
openhis-ui-vue3/src/components/types/Form.d.ts
vendored
Normal file
21
openhis-ui-vue3/src/components/types/Form.d.ts
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
import type { FormItemConfig } from './FormItem.d';
|
||||
|
||||
/**
|
||||
* Form 组件的 Props 类型
|
||||
*/
|
||||
export interface FormProps {
|
||||
/** 表单数据对象 */
|
||||
model: Record<string, any>;
|
||||
/** 表单项配置数组 */
|
||||
formItems: FormItemConfig[];
|
||||
/** 表单验证规则 */
|
||||
rules?: Record<string, any>;
|
||||
/** 标签宽度 */
|
||||
labelWidth?: string;
|
||||
/** 是否内联表单 */
|
||||
inline?: boolean;
|
||||
/** 标签位置 */
|
||||
labelPosition?: 'left' | 'right' | 'top';
|
||||
/** 标签后是否添加冒号 */
|
||||
showLabelColon?: boolean;
|
||||
}
|
||||
82
openhis-ui-vue3/src/components/types/FormItem.d.ts
vendored
Normal file
82
openhis-ui-vue3/src/components/types/FormItem.d.ts
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
import type { CSSProperties } from 'vue';
|
||||
|
||||
/**
|
||||
* 表单项选项类型
|
||||
*/
|
||||
export interface FormItemOption {
|
||||
/** 选项标签 */
|
||||
label: string;
|
||||
/** 选项值 */
|
||||
value: string | number | boolean | null | undefined;
|
||||
/** 是否禁用该选项 */
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* onChange 回调函数类型
|
||||
* @param value - 新的值
|
||||
* @returns 返回 false 时阻止更新,返回其他值或 undefined 时允许更新
|
||||
*/
|
||||
export type OnChangeCallback = (
|
||||
value: string | number | Array<string | number> | Date | null | undefined
|
||||
) => Promise<boolean | void> | boolean | void;
|
||||
|
||||
/**
|
||||
* 表单项配置类型
|
||||
*/
|
||||
export interface FormItemConfig {
|
||||
/** 表单项类型 */
|
||||
type: 'input' | 'select' | 'radio' | 'date' | 'daterange' | 'custom' | 'text';
|
||||
/** 表单项标签 */
|
||||
label: string;
|
||||
/** 表单项字段名(对应 queryParams 的 key) */
|
||||
prop: string;
|
||||
/** 占位符文本 */
|
||||
placeholder?: string;
|
||||
/** 开始日期占位符(仅 daterange 类型) */
|
||||
startPlaceholder?: string;
|
||||
/** 结束日期占位符(仅 daterange 类型) */
|
||||
endPlaceholder?: string;
|
||||
/** 是否可清空 */
|
||||
clearable?: boolean;
|
||||
/** 自定义样式对象或字符串 */
|
||||
style?: CSSProperties | string | { width?: string; [key: string]: any };
|
||||
/** 表单项宽度(字符串,如 '200px') */
|
||||
width?: string;
|
||||
/** 额外的属性(会通过 v-bind 传递给组件) */
|
||||
extraprops?: Record<string, any>;
|
||||
/** 是否多选(仅 select 类型) */
|
||||
multiple?: boolean;
|
||||
/** 是否可搜索(仅 select 类型) */
|
||||
filterable?: boolean;
|
||||
/** 多选时是否折叠标签(仅 select 类型) */
|
||||
collapseTags?: boolean;
|
||||
/** 选项列表(select 和 radio 类型) */
|
||||
options?: FormItemOption[];
|
||||
/** 日期格式(date 和 daterange 类型) */
|
||||
valueFormat?: string;
|
||||
/** 自定义插槽名称(custom 类型) */
|
||||
slot?: string;
|
||||
/** 是否必填 */
|
||||
required?: boolean;
|
||||
/** 标签后缀 */
|
||||
labelSuffix?: string;
|
||||
/** 值变更时的回调函数 */
|
||||
onChange?: OnChangeCallback;
|
||||
/** 是否在变更前进行检查(仅 select 类型,为 true 时会执行 onChange 回调) */
|
||||
checkBeforeChange?: boolean;
|
||||
/** 格式化函数(text 类型,用于格式化显示的文本) */
|
||||
formatter?: (value: any) => string;
|
||||
}
|
||||
|
||||
/**
|
||||
* FormItem 组件的 Props 类型
|
||||
*/
|
||||
export interface FormItemProps {
|
||||
/** 表单项配置对象 */
|
||||
item: FormItemConfig;
|
||||
/** 表单项的值 */
|
||||
modelValue?: string | number | Array<string | number> | Date | null;
|
||||
/** 回车键按下时的回调函数 */
|
||||
onEnter?: () => void;
|
||||
}
|
||||
21
openhis-ui-vue3/src/components/types/FormLayout.d.ts
vendored
Normal file
21
openhis-ui-vue3/src/components/types/FormLayout.d.ts
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
import type { FormItemConfig } from './FormItem.d';
|
||||
|
||||
/**
|
||||
* FormLayout 组件的 Props 类型
|
||||
*/
|
||||
export interface FormLayoutProps {
|
||||
/** 表单数据对象 */
|
||||
model: Record<string, any>;
|
||||
/** 表单项配置数组 */
|
||||
formItems: FormItemConfig[];
|
||||
/** 表单验证规则 */
|
||||
rules?: Record<string, any>;
|
||||
/** 标签宽度 */
|
||||
labelWidth?: string;
|
||||
/** 标签位置 */
|
||||
labelPosition?: 'left' | 'right' | 'top';
|
||||
/** 标签后是否添加冒号 */
|
||||
showLabelColon?: boolean;
|
||||
/** 列数(0 表示不限制) */
|
||||
columns?: number;
|
||||
}
|
||||
21
openhis-ui-vue3/src/components/types/Pagination.d.ts
vendored
Normal file
21
openhis-ui-vue3/src/components/types/Pagination.d.ts
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
import type { DefineComponent } from 'vue';
|
||||
|
||||
/**
|
||||
* Pagination 组件的 Props 类型
|
||||
*/
|
||||
export interface PaginationProps {
|
||||
/** 总记录数 */
|
||||
total: number;
|
||||
/** 当前页码 */
|
||||
page: number;
|
||||
/** 每页条数 */
|
||||
limit: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 为 Pagination.vue 组件提供类型声明
|
||||
*/
|
||||
declare module '@/components/Pagination/index.vue' {
|
||||
const component: DefineComponent<PaginationProps>;
|
||||
export default component;
|
||||
}
|
||||
21
openhis-ui-vue3/src/components/types/QuickDateRange.d.ts
vendored
Normal file
21
openhis-ui-vue3/src/components/types/QuickDateRange.d.ts
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
import type { DefineComponent } from 'vue';
|
||||
|
||||
/**
|
||||
* QuickDateRange 组件的 Props 类型
|
||||
*/
|
||||
export interface QuickDateRangeProps {
|
||||
/** 日期范围值(字符串数组,如 ['2024-01-01', '2024-01-31']) */
|
||||
modelValue?: string[];
|
||||
/** 开始日期占位符 */
|
||||
startPlaceholder?: string;
|
||||
/** 结束日期占位符 */
|
||||
endPlaceholder?: string;
|
||||
/** 日期格式 */
|
||||
valueFormat?: string;
|
||||
/** 是否可清空 */
|
||||
clearable?: boolean;
|
||||
/** 日期选择器的样式 */
|
||||
datePickerStyle?: Record<string, any>;
|
||||
/** 透传给日期选择器的其他属性 */
|
||||
attrs?: Record<string, any>;
|
||||
}
|
||||
48
openhis-ui-vue3/src/components/types/Table.d.ts
vendored
Normal file
48
openhis-ui-vue3/src/components/types/Table.d.ts
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
import type { TableColumn } from './TableLayout.d';
|
||||
|
||||
/**
|
||||
* Table 组件的 Props 类型
|
||||
*/
|
||||
export interface TableProps {
|
||||
/** 表格数据 */
|
||||
tableData: Record<string, any>[];
|
||||
/** 加载状态 */
|
||||
loading?: boolean;
|
||||
/** 是否显示边框 */
|
||||
border?: boolean;
|
||||
/** 是否显示斑马纹 */
|
||||
stripe?: boolean;
|
||||
/** 表格尺寸 */
|
||||
size?: 'large' | 'default' | 'small';
|
||||
/** 表格高度 */
|
||||
tableHeight?: string | number;
|
||||
/** 最大高度 */
|
||||
maxHeight?: string | number;
|
||||
/** 行键 */
|
||||
rowKey?: string | ((row: Record<string, any>) => string);
|
||||
/** 是否高亮当前行 */
|
||||
highlightCurrentRow?: boolean;
|
||||
/** 表格列配置 */
|
||||
tableColumns?: TableColumn[];
|
||||
/** 是否显示分页 */
|
||||
showPagination?: boolean;
|
||||
/** 总记录数 */
|
||||
total?: number;
|
||||
/** 当前页码 */
|
||||
pageNo?: number;
|
||||
/** 每页条数 */
|
||||
pageSize?: number;
|
||||
/** 是否所有数据都在客户端,如果是则在组件内部进行分页 */
|
||||
isAllData?: boolean;
|
||||
/** 分页左侧自定义文案 */
|
||||
paginationLeftText?: string;
|
||||
/** 分页组件自定义属性 */
|
||||
paginationProps?: {
|
||||
pageSizes?: number[];
|
||||
pagerCount?: number;
|
||||
layout?: string;
|
||||
background?: boolean;
|
||||
autoScroll?: boolean;
|
||||
hidden?: boolean;
|
||||
};
|
||||
}
|
||||
89
openhis-ui-vue3/src/components/types/TableLayout.d.ts
vendored
Normal file
89
openhis-ui-vue3/src/components/types/TableLayout.d.ts
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
import type { FormItemConfig } from './FormItem.d';
|
||||
|
||||
/**
|
||||
* 表格列配置类型
|
||||
*/
|
||||
export interface TableColumn {
|
||||
/** 列类型 */
|
||||
type?: 'selection' | 'index' | 'expand';
|
||||
/** 列字段名 */
|
||||
prop?: string;
|
||||
/** 列标签 */
|
||||
label?: string;
|
||||
/** 列宽度 */
|
||||
width?: string | number;
|
||||
/** 最小宽度 */
|
||||
minWidth?: string | number;
|
||||
/** 是否固定列 */
|
||||
fixed?: boolean | 'left' | 'right';
|
||||
/** 对齐方式 */
|
||||
align?: 'left' | 'center' | 'right';
|
||||
/** 是否显示溢出提示 */
|
||||
showOverflowTooltip?: boolean;
|
||||
/** 自定义插槽名称 */
|
||||
slot?: string;
|
||||
/** 格式化函数 */
|
||||
formatter?: (row: Record<string, any>, column: any, cellValue: any, index?: number) => string;
|
||||
/** 是否可选(selection 类型) */
|
||||
selectable?: (row: Record<string, any>, index: number) => boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 树节点数据类型
|
||||
*/
|
||||
export interface TreeNodeData {
|
||||
[key: string]: any;
|
||||
children?: TreeNodeData[];
|
||||
}
|
||||
|
||||
/**
|
||||
* TableLayout 组件的 Props 类型
|
||||
*/
|
||||
export interface TableLayoutProps {
|
||||
/** 表格数据 */
|
||||
tableData: Record<string, any>[];
|
||||
/** 加载状态 */
|
||||
loading?: boolean;
|
||||
/** 总记录数 */
|
||||
total?: number;
|
||||
/** 查询参数对象 */
|
||||
queryParams: {
|
||||
pageNo: number;
|
||||
pageSize: number;
|
||||
[key: string]: any;
|
||||
};
|
||||
/** 侧边查询参数 */
|
||||
sideQueryParams?: Record<string, any>;
|
||||
/** 表单项配置数组 */
|
||||
formItems?: FormItemConfig[];
|
||||
/** 是否显示顶部查询 */
|
||||
showTopQuery?: boolean;
|
||||
/** 是否显示侧边查询 */
|
||||
showSideQuery?: boolean;
|
||||
/** 是否显示分页 */
|
||||
showPagination?: boolean;
|
||||
/** 是否显示默认按钮 */
|
||||
showDefaultButtons?: boolean;
|
||||
/** 侧边栏宽度 */
|
||||
sideWidth?: number;
|
||||
/** 是否显示边框 */
|
||||
border?: boolean;
|
||||
/** 是否显示斑马纹 */
|
||||
stripe?: boolean;
|
||||
/** 表格尺寸 */
|
||||
size?: 'large' | 'default' | 'small';
|
||||
/** 表格高度 */
|
||||
tableHeight?: string | number;
|
||||
/** 最大高度 */
|
||||
maxHeight?: string | number;
|
||||
/** 行键 */
|
||||
rowKey?: string | ((row: Record<string, any>) => string);
|
||||
/** 是否高亮当前行 */
|
||||
highlightCurrentRow?: boolean;
|
||||
/** 侧边栏数据 */
|
||||
siderData?: TreeNodeData[];
|
||||
/** 树节点键名 */
|
||||
treeNodeKey?: string;
|
||||
/** 表格列配置 */
|
||||
tableColumns?: TableColumn[];
|
||||
}
|
||||
13
openhis-ui-vue3/src/components/types/index.d.ts
vendored
Normal file
13
openhis-ui-vue3/src/components/types/index.d.ts
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* TableLayout 组件相关的类型定义
|
||||
*/
|
||||
|
||||
export * from './FormItem.d';
|
||||
export * from './QuickDateRange.d';
|
||||
export * from './EditableTable.d';
|
||||
export * from './Filter.d';
|
||||
export * from './FormLayout.d';
|
||||
export * from './Form.d';
|
||||
export * from './Table.d';
|
||||
export * from './TableLayout.d';
|
||||
export * from './Dialog.d';
|
||||
@@ -1,51 +1,70 @@
|
||||
<template>
|
||||
<div class="navbar">
|
||||
<!-- <hamburger id="hamburger-container" :is-active="appStore.sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" /> -->
|
||||
<!-- <breadcrumb id="breadcrumb-container" class="breadcrumb-container" v-if="!settingsStore.topNav" /> -->
|
||||
<!-- <top-nav id="topmenu-container" class="topmenu-container" style="border: 1px solid blue;"/> -->
|
||||
|
||||
<div class="right-menu">
|
||||
<template v-if="appStore.device !== 'mobile'">
|
||||
<header-search id="header-search" class="right-menu-item" />
|
||||
|
||||
<!-- <el-tooltip content="源码地址" effect="dark" placement="bottom">
|
||||
<ruo-yi-git id="openhis-git" class="right-menu-item hover-effect" />
|
||||
</el-tooltip> -->
|
||||
|
||||
<!-- <el-tooltip content="文档地址" effect="dark" placement="bottom">
|
||||
<ruo-yi-doc id="openhis-doc" class="right-menu-item hover-effect" />
|
||||
</el-tooltip> -->
|
||||
|
||||
<!-- <screenfull id="screenfull" class="right-menu-item hover-effect" /> -->
|
||||
|
||||
<el-tooltip content="布局大小" effect="dark" placement="bottom">
|
||||
<size-select id="size-select" class="right-menu-item hover-effect" />
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<div class="avatar-container">
|
||||
<el-dropdown @command="handleCommand" class="right-menu-item hover-effect" trigger="click">
|
||||
<div class="avatar-wrapper">
|
||||
<img :src="userStore.avatar" class="user-avatar" />
|
||||
<span class="nick-name">{{ userStore.nickName }}</span>
|
||||
<!-- <el-icon><caret-bottom /></el-icon> -->
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<router-link to="/user/profile">
|
||||
<el-dropdown-item>个人中心</el-dropdown-item>
|
||||
</router-link>
|
||||
<el-dropdown-item command="switch">
|
||||
<span>切换科室</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="setLayout" v-if="settingsStore.showSettings">
|
||||
<span>布局设置</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item divided command="logout">
|
||||
<span>退出登录</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<div class="avatar-wrapper">
|
||||
<el-dropdown
|
||||
@command="handleCommand"
|
||||
class="user-info-dropdown hover-effect"
|
||||
trigger="click"
|
||||
teleported
|
||||
popper-class="navbar-dropdown"
|
||||
:popper-options="{
|
||||
modifiers: [
|
||||
{
|
||||
name: 'offset',
|
||||
options: {
|
||||
offset: [0, 12],
|
||||
},
|
||||
},
|
||||
],
|
||||
}"
|
||||
>
|
||||
<div class="user-info">
|
||||
<img :src="userStore.avatar" class="user-avatar" />
|
||||
<span class="nick-name">{{ userStore.nickName }}</span>
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<router-link to="/user/profile">
|
||||
<el-dropdown-item>个人中心</el-dropdown-item>
|
||||
</router-link>
|
||||
<!-- <el-dropdown-item command="setLayout" v-if="settingsStore.showSettings">
|
||||
<span>布局设置</span>
|
||||
</el-dropdown-item> -->
|
||||
<el-dropdown-item divided command="logout">
|
||||
<span>退出登录</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<span class="divider">|</span>
|
||||
<el-dropdown
|
||||
@command="handleOrgSwitch"
|
||||
trigger="click"
|
||||
teleported
|
||||
popper-class="navbar-dropdown"
|
||||
:placement="'bottom-start'"
|
||||
>
|
||||
<span class="org-name">{{ userStore.orgName }}</span>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item
|
||||
v-for="item in orgOptions"
|
||||
:key="item.orgId"
|
||||
:command="item.orgId"
|
||||
:class="{ 'is-active': item.orgId === userStore.orgId }"
|
||||
>
|
||||
{{ item.orgName }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<span class="divider" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog title="切换科室" v-model="showDialog" width="400px" append-to-body destroy-on-close>
|
||||
@@ -68,6 +87,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted } from 'vue';
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import Breadcrumb from '@/components/Breadcrumb';
|
||||
import TopNav from '@/components/TopNav';
|
||||
@@ -86,8 +106,39 @@ const settingsStore = useSettingsStore();
|
||||
const orgOptions = ref([]);
|
||||
const showDialog = ref(false);
|
||||
const orgId = ref('');
|
||||
function toggleSideBar() {
|
||||
appStore.toggleSideBar();
|
||||
|
||||
function loadOrgList() {
|
||||
getOrg().then((res) => {
|
||||
orgOptions.value = res.data;
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadOrgList();
|
||||
});
|
||||
|
||||
function handleOrgSwitch(selectedOrgId) {
|
||||
if (selectedOrgId === userStore.orgId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const selectedOrg = orgOptions.value.find((item) => item.orgId === selectedOrgId);
|
||||
const orgName = selectedOrg ? selectedOrg.orgName : '该科室';
|
||||
|
||||
ElMessageBox.confirm(`确定要切换到科室"${orgName}"吗?`, '切换科室', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}).then(() => {
|
||||
orgId.value = selectedOrgId;
|
||||
switchOrg(selectedOrgId).then((res) => {
|
||||
if (res.code === 200) {
|
||||
userStore.logOut().then(() => {
|
||||
location.href = '/index';
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function handleCommand(command) {
|
||||
@@ -98,13 +149,6 @@ function handleCommand(command) {
|
||||
case 'logout':
|
||||
logout();
|
||||
break;
|
||||
case 'switch':
|
||||
orgId.value = userStore.orgId;
|
||||
getOrg().then((res) => {
|
||||
orgOptions.value = res.data;
|
||||
showDialog.value = true;
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -143,29 +187,35 @@ function setLayout() {
|
||||
<style lang='scss' scoped>
|
||||
.navbar {
|
||||
height: 50px;
|
||||
overflow: hidden;
|
||||
overflow: visible;
|
||||
position: relative;
|
||||
background-color: transparent;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding-right: 10px;
|
||||
flex-shrink: 0;
|
||||
min-width: 200px;
|
||||
z-index: 1002;
|
||||
|
||||
.right-menu {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
white-space: nowrap;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.right-menu-item {
|
||||
display: inline-block;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 6px;
|
||||
height: 100%;
|
||||
font-size: 16px;
|
||||
color: #606266;
|
||||
vertical-align: text-bottom;
|
||||
flex-shrink: 0;
|
||||
|
||||
&.hover-effect {
|
||||
cursor: pointer;
|
||||
@@ -180,25 +230,70 @@ function setLayout() {
|
||||
.avatar-container {
|
||||
margin-right: 0;
|
||||
margin-left: 5px;
|
||||
flex-shrink: 0;
|
||||
position: relative;
|
||||
z-index: 1003;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.avatar-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 5px;
|
||||
gap: 8px;
|
||||
position: relative;
|
||||
|
||||
.user-info-dropdown {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
cursor: pointer;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 6px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.nick-name {
|
||||
font-weight: 500;
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
width: 80px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 100px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.divider {
|
||||
color: #dcdfe6;
|
||||
font-size: 14px;
|
||||
margin: 0 8px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.org-name {
|
||||
font-weight: 500;
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 120px;
|
||||
flex-shrink: 0;
|
||||
cursor: pointer;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
|
||||
.el-icon {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
@@ -210,5 +305,99 @@ function setLayout() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
min-width: 150px;
|
||||
padding-right: 5px;
|
||||
|
||||
.right-menu {
|
||||
.avatar-container {
|
||||
.avatar-wrapper {
|
||||
gap: 4px;
|
||||
|
||||
.nick-name {
|
||||
max-width: 60px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.org-name {
|
||||
max-width: 80px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.divider {
|
||||
margin: 0 4px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
min-width: 120px;
|
||||
padding-right: 5px;
|
||||
|
||||
.right-menu {
|
||||
.avatar-container {
|
||||
.avatar-wrapper {
|
||||
.nick-name {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.divider {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.org-name {
|
||||
max-width: 80px;
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
.navbar-dropdown {
|
||||
margin-bottom: 8px !important;
|
||||
z-index: 10010 !important;
|
||||
|
||||
.el-dropdown-menu {
|
||||
margin-bottom: 0 !important;
|
||||
z-index: 10010 !important;
|
||||
max-height: 300px !important;
|
||||
overflow-y: auto !important;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 3px;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.el-dropdown-menu__item.is-active {
|
||||
color: #409eff !important;
|
||||
font-weight: 500 !important;
|
||||
background-color: #ecf5ff !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,33 +1,36 @@
|
||||
<template>
|
||||
<div
|
||||
:class="{ 'has-logo': showLogo }"
|
||||
class="sidebar-wrapper"
|
||||
:style="{
|
||||
backgroundColor:
|
||||
sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground,
|
||||
}"
|
||||
>
|
||||
<!-- <logo v-if="showLogo" :collapse="isCollapse" /> -->
|
||||
<!-- <el-scrollbar :class="sideTheme" wrap-class="scrollbar-wrapper"> -->
|
||||
<el-menu
|
||||
:default-active="activeMenu"
|
||||
:collapse="isCollapse"
|
||||
:background-color="
|
||||
sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground
|
||||
"
|
||||
:text-color="sideTheme === 'theme-dark' ? variables.menuColor : variables.menuLightColor"
|
||||
:unique-opened="true"
|
||||
:active-text-color="theme"
|
||||
:collapse-transition="false"
|
||||
mode="horizontal"
|
||||
>
|
||||
<sidebar-item
|
||||
v-for="(route, index) in sidebarRouters"
|
||||
:key="route.path + index"
|
||||
:item="route"
|
||||
:base-path="route.path"
|
||||
/>
|
||||
</el-menu>
|
||||
<!-- </el-scrollbar> -->
|
||||
<div class="menu-container">
|
||||
<div class="menu-scrollbar">
|
||||
<el-menu
|
||||
:default-active="activeMenu"
|
||||
:collapse="isCollapse"
|
||||
:background-color="
|
||||
sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground
|
||||
"
|
||||
:text-color="sideTheme === 'theme-dark' ? variables.menuColor : variables.menuLightColor"
|
||||
:unique-opened="true"
|
||||
:active-text-color="theme"
|
||||
:collapse-transition="false"
|
||||
mode="horizontal"
|
||||
>
|
||||
<sidebar-item
|
||||
v-for="(route, index) in sidebarRouters"
|
||||
:key="route.path + index"
|
||||
:item="route"
|
||||
:base-path="route.path"
|
||||
/>
|
||||
</el-menu>
|
||||
</div>
|
||||
</div>
|
||||
<navbar @setLayout="setLayout" class="navbar-container" />
|
||||
<settings ref="settingRef" />
|
||||
</div>
|
||||
@@ -71,17 +74,61 @@ function setLayout() {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.scrollbar-wrapper {
|
||||
overflow-x: auto !important;
|
||||
.sidebar-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
height: 50px;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.menu-container {
|
||||
flex: 1;
|
||||
height: 50px;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.menu-scrollbar {
|
||||
height: 50px;
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
height: 4px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar:vertical {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.el-menu--horizontal {
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
border-bottom: none !important;
|
||||
background-color: transparent !important;
|
||||
min-width: auto;
|
||||
flex-wrap: nowrap;
|
||||
height: 50px;
|
||||
|
||||
& > .el-menu-item,
|
||||
& > .el-sub-menu {
|
||||
@@ -91,7 +138,10 @@ function setLayout() {
|
||||
padding: 0 20px !important;
|
||||
font-size: 14px;
|
||||
min-width: 120px !important;
|
||||
border: 1px solid red !important;
|
||||
flex-shrink: 0;
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
:deep(.svg-icon) {
|
||||
@@ -101,6 +151,9 @@ function setLayout() {
|
||||
|
||||
:deep(.el-sub-menu__title) {
|
||||
padding-right: 25px !important;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
:deep(.el-sub-menu__icon-arrow) {
|
||||
@@ -112,20 +165,36 @@ function setLayout() {
|
||||
}
|
||||
}
|
||||
|
||||
/* 水平布局,并与 Navbar 正确配合 */
|
||||
div {
|
||||
&.has-logo {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
height: 50px;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
.navbar-container {
|
||||
flex-shrink: 0;
|
||||
height: 50px;
|
||||
z-index: 1002;
|
||||
}
|
||||
|
||||
& > .el-scrollbar {
|
||||
flex: 1;
|
||||
height: 50px;
|
||||
min-width: 0;
|
||||
/* 响应式处理 */
|
||||
@media (max-width: 768px) {
|
||||
.menu-container {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.el-menu--horizontal {
|
||||
& > .el-menu-item,
|
||||
& > .el-sub-menu {
|
||||
padding: 0 12px !important;
|
||||
min-width: 80px !important;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.el-menu--horizontal {
|
||||
& > .el-menu-item,
|
||||
& > .el-sub-menu {
|
||||
padding: 0 8px !important;
|
||||
min-width: 60px !important;
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,6 +105,7 @@ function setLayout() {
|
||||
left: 0;
|
||||
z-index: 1001;
|
||||
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.35);
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.sidebar-container {
|
||||
|
||||
@@ -24,12 +24,17 @@
|
||||
<div class="single-row-layout">
|
||||
<el-form-item label="姓名" prop="patientName" class="row-item">
|
||||
<div class="input-with-unit">
|
||||
<el-input v-model="formData.patientName" type="text" placeholder="请输入" />
|
||||
<el-input
|
||||
disabled
|
||||
v-model="formData.patientName"
|
||||
type="text"
|
||||
placeholder="请输入"
|
||||
/>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="年龄" prop="age" class="row-item">
|
||||
<div class="input-with-unit">
|
||||
<el-input v-model="formData.age" type="text" placeholder="请输入" />
|
||||
<el-input disabled v-model="formData.age" type="text" placeholder="请输入" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="性别" prop="gender" class="row-item">
|
||||
@@ -40,7 +45,7 @@
|
||||
|
||||
<el-form-item label="住院号" prop="busNo" class="row-item">
|
||||
<div class="input-with-unit">
|
||||
<el-input v-model="formData.busNo" type="text" placeholder="请输入" />
|
||||
<el-input disabled v-model="formData.busNo" type="text" placeholder="请输入" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="职业" prop="temperature" class="row-item">
|
||||
@@ -68,7 +73,7 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="住院天数" prop="hospitalDays" class="row-item">
|
||||
<div class="input-with-unit">
|
||||
<el-input v-model="formData.hospitalDays" type="number" placeholder="请输入" />
|
||||
<el-input disabled v-model="formData.hospitalDays" placeholder="请输入" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
</div>
|
||||
@@ -81,7 +86,7 @@
|
||||
v-model="formData.DischargeDiagnosis"
|
||||
type="textarea"
|
||||
placeholder="请输入出院诊断"
|
||||
:rows="4"
|
||||
:autosize="{ minRows: 1 }"
|
||||
style="resize: none; padding-right: 10px"
|
||||
/>
|
||||
</el-form-item>
|
||||
@@ -95,7 +100,7 @@
|
||||
v-model="formData.SummaryAndDiagnosisAndTreatmentProcess"
|
||||
type="textarea"
|
||||
placeholder="请输入出院病情摘要及诊疗经过"
|
||||
:rows="4"
|
||||
:autosize="{ minRows: 1 }"
|
||||
style="resize: none; padding-right: 10px"
|
||||
/>
|
||||
</el-form-item>
|
||||
@@ -109,7 +114,7 @@
|
||||
v-model="formData.RequirementsAndPrecautionsAfterDischarge"
|
||||
type="textarea"
|
||||
placeholder="请输入出院后要求及注意事项"
|
||||
:rows="4"
|
||||
:autosize="{ minRows: 1 }"
|
||||
style="resize: none; padding-right: 10px"
|
||||
/>
|
||||
</el-form-item>
|
||||
@@ -123,19 +128,21 @@
|
||||
v-model="formData.TraditionalChineseMedicineNursing"
|
||||
type="textarea"
|
||||
placeholder="请输入中医调护"
|
||||
:rows="4"
|
||||
:autosize="{ minRows: 1 }"
|
||||
style="resize: none; padding-right: 10px"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
<DisDiagnMedicalRecord v-if="isShowprintDom" ref="recordPrintRef"></DisDiagnMedicalRecord>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref, onMounted, watch } from 'vue';
|
||||
import { reactive, ref, onMounted, watch, nextTick } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { patientInfo } from '../views/doctorstation/components/store/patient';
|
||||
import { previewPrint } from '../utils/printUtils';
|
||||
import DisDiagnMedicalRecord from '../views/hospitalRecord/components/disDiagnMedicalRecord.vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'DischargeDiagnosisCertificate',
|
||||
@@ -149,6 +156,9 @@ const props = defineProps({
|
||||
},
|
||||
});
|
||||
|
||||
const recordPrintRef = ref();
|
||||
const isShowprintDom = ref(false);
|
||||
|
||||
const patient = props.patientInfo;
|
||||
|
||||
// const props = defineProps({});
|
||||
@@ -220,6 +230,10 @@ onMounted(() => {
|
||||
if (!formData.admissionDate) {
|
||||
formData.admissionDate = patient?.inHospitalTime || '';
|
||||
}
|
||||
if (!formData.hospitalDays) {
|
||||
formData.hospitalDays = patient?.inHospitalDays;
|
||||
}
|
||||
console.log('patientInfo========>', JSON.stringify(props.patientInfo));
|
||||
});
|
||||
|
||||
// 监听患者信息变化,实现联动显示和自动填充
|
||||
@@ -246,14 +260,27 @@ const fillPatientInfo = (patientData) => {
|
||||
formData.age = patientData.age || '';
|
||||
formData.gender = patientData.genderEnum_enumText || '';
|
||||
formData.busNo = patientData.busNo || '';
|
||||
formData.hospitalDays = patientData.inHospitalDays || '';
|
||||
} catch (error) {
|
||||
console.error('填充患者信息时发生错误:', error);
|
||||
ElMessage.error('自动填充患者信息失败,请检查数据源格式');
|
||||
}
|
||||
};
|
||||
|
||||
// 打印方法
|
||||
const printFun = () => {
|
||||
isShowprintDom.value = true;
|
||||
nextTick(() => {
|
||||
recordPrintRef?.value.setData(formData);
|
||||
nextTick(() => {
|
||||
previewPrint(recordPrintRef?.value.getDom());
|
||||
isShowprintDom.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 暴露接口
|
||||
defineExpose({ formData, submit, setFormData, fillPatientInfo });
|
||||
defineExpose({ formData, submit, setFormData, fillPatientInfo, printFun });
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
@onCaseSecond="updateCaseFirstDatas"
|
||||
></medicalRecordSecond>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="病案附页(一)" name="third">
|
||||
<el-tab-pane label="病案附页(三)" name="third">
|
||||
<medicalRecordThird
|
||||
:formData="formData"
|
||||
@onCaseThird="updateCaseFirstDatas"
|
||||
@@ -23,9 +23,13 @@
|
||||
</el-tabs>
|
||||
|
||||
<div class="form-footer">
|
||||
<button @click="printForm" class="print-btn">打印表单</button>
|
||||
<!-- <button @click="printForm" class="print-btn">打印表单</button> -->
|
||||
<button @click="resetForm" class="reset-btn">重置表单</button>
|
||||
</div>
|
||||
<medicalRecordPrint v-if="isShowprintDom" ref="recordPrintRef"></medicalRecordPrint>
|
||||
<!-- <el-drawer v-model="drawer" size="100%">
|
||||
<medicalRecordPrint ref="recordPrintRef"></medicalRecordPrint>
|
||||
</el-drawer> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -33,7 +37,7 @@
|
||||
defineOptions({
|
||||
name: 'HospitalRecordForm',
|
||||
});
|
||||
import { ref, reactive } from 'vue';
|
||||
import { ref, reactive, nextTick } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
// import medicalRecordFirst from './components/medicalRecordFirst.vue';
|
||||
import medicalRecordFirst from '@/views/hospitalRecord/components/medicalRecordFirst.vue';
|
||||
@@ -43,10 +47,17 @@ import medicalRecordFirstPrint from '@/views/hospitalRecord/components/medicalRe
|
||||
import medicalRecordSecondPrint from '@/views/hospitalRecord/components/medicalRecordSecondPrint.json';
|
||||
import medicalRecordThirdPrint from '@/views/hospitalRecord/components/medicalRecordThirdPrint.json';
|
||||
import formDataJs from '../views/doctorstation/components/store/medicalpage';
|
||||
import medicalRecordPrint from '../views/hospitalRecord/components/medicalRecordPrint.vue';
|
||||
import { previewPrint } from '../utils/printUtils';
|
||||
import {
|
||||
getEncounterDiagnosis,
|
||||
getTcmDiagnosis,
|
||||
} from '../views/inpatientDoctor/home/components/api';
|
||||
import { cloneDeep } from 'lodash';
|
||||
const firstRef = ref();
|
||||
const commpoentType = 'medicalRecord';
|
||||
const emit = defineEmits(['submitOk']);
|
||||
const drawer = ref(false);
|
||||
// 表单数据
|
||||
const formData = reactive({
|
||||
//医院信息
|
||||
@@ -304,29 +315,40 @@ const formData = reactive({
|
||||
tableData_top: [],
|
||||
});
|
||||
|
||||
// Props与事件
|
||||
const props = defineProps({
|
||||
patientInfo: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const activeName = ref('first');
|
||||
const recordPrintRef = ref();
|
||||
const isShowprintDom = ref(false);
|
||||
|
||||
// 打印表单
|
||||
const printForm = () => {
|
||||
// 创建一个新的打印窗口
|
||||
const printWindow = window.open('', '_blank');
|
||||
let printContent;
|
||||
// 获取模板字符串并替换转义的插值标记
|
||||
if (activeName.value == 'first') {
|
||||
printContent = medicalRecordFirstPrint.printContent;
|
||||
} else if (activeName.value == 'second') {
|
||||
printContent = medicalRecordSecondPrint.printContent;
|
||||
} else {
|
||||
printContent = medicalRecordThirdPrint.printContent;
|
||||
}
|
||||
// 这里可以进行实际的数据替换操作
|
||||
printContent = printContent.replace(/\$\{([^}]+)\}/g, (match, expr) => {
|
||||
// 简单示例:实际应根据expr内容进行数据提取
|
||||
return eval(expr); // 注意:实际使用中应避免eval,这里仅为示例
|
||||
});
|
||||
// 将内容写入打印窗口并打印
|
||||
printWindow.document.write(printContent);
|
||||
printWindow.document.close();
|
||||
drawer.value = true;
|
||||
// // 创建一个新的打印窗口
|
||||
// const printWindow = window.open('', '_blank');
|
||||
// let printContent;
|
||||
// // 获取模板字符串并替换转义的插值标记
|
||||
// if (activeName.value == 'first') {
|
||||
// printContent = medicalRecordFirstPrint.printContent;
|
||||
// } else if (activeName.value == 'second') {
|
||||
// printContent = medicalRecordSecondPrint.printContent;
|
||||
// } else {
|
||||
// printContent = medicalRecordThirdPrint.printContent;
|
||||
// }
|
||||
// // 这里可以进行实际的数据替换操作
|
||||
// printContent = printContent.replace(/\$\{([^}]+)\}/g, (match, expr) => {
|
||||
// // 简单示例:实际应根据expr内容进行数据提取
|
||||
// return eval(expr); // 注意:实际使用中应避免eval,这里仅为示例
|
||||
// });
|
||||
// // 将内容写入打印窗口并打印
|
||||
// printWindow.document.write(printContent);
|
||||
// printWindow.document.close();
|
||||
};
|
||||
|
||||
function handleClick() {
|
||||
@@ -345,8 +367,16 @@ const resetFun = (data) => {
|
||||
// 重置表单
|
||||
const resetForm = () => {
|
||||
if (activeName.value == 'first') {
|
||||
resetFun(firstRef.value.formData.hospitalInfo);
|
||||
resetFun(firstRef.value.formData.patientInfo);
|
||||
// resetFun(firstRef.value.formData.hospitalInfo);
|
||||
// resetFun(firstRef.value.formData.patientInfo);
|
||||
firstRef.value.formData.patientInfo.napl = ''; //籍贯
|
||||
firstRef.value.formData.patientInfo.certno = ''; //身份证号
|
||||
firstRef.value.formData.patientInfo.resd_addr = ''; //户口地址
|
||||
firstRef.value.formData.patientInfo.empr_addr = ''; //工作单位
|
||||
firstRef.value.formData.patientInfo.coner_name = ''; //联系人
|
||||
firstRef.value.formData.patientInfo.coner_rlts_code = ''; //关系
|
||||
firstRef.value.formData.patientInfo.coner_addr = ''; //联系人地址
|
||||
firstRef.value.formData.patientInfo.coner_tel = ''; //联系人电话
|
||||
resetFun(firstRef.value.formData.admission);
|
||||
resetFun(firstRef.value.formData.diagnosis);
|
||||
resetFun(firstRef.value.formData.medicalInfo);
|
||||
@@ -373,9 +403,37 @@ const resetForm = () => {
|
||||
const updateCaseFirstDatas = (newDatas) => {
|
||||
Object.assign(formData, newDatas);
|
||||
};
|
||||
|
||||
const getList = () => {
|
||||
getEncounterDiagnosis(props.patientInfo.encounterId).then((res) => {
|
||||
if (res.code == 200) {
|
||||
console.log('getEncounterDiagnosis=======>', JSON.stringify(res.data));
|
||||
formDataJs.diagnosisList = res.data;
|
||||
}
|
||||
});
|
||||
getTcmDiagnosis({ encounterId: props.patientInfo.encounterId }).then((res) => {
|
||||
if (res.code == 200) {
|
||||
// if (res.data.illness.length > 0) {
|
||||
// diagnosisNetDatas.value = res.data.illness;
|
||||
// res.data.illness.forEach((item, index) => {
|
||||
// form.value.diagnosisList.push({
|
||||
// name: item.name + '-' + res.data.symptom[index].name,
|
||||
// ybNo: item.ybNo,
|
||||
// medTypeCode: item.medTypeCode,
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
}
|
||||
});
|
||||
};
|
||||
// 点击历史数据回传布局
|
||||
const setFormData = (data) => {
|
||||
Object.assign(firstRef.value.formData, data);
|
||||
if (Object.keys(data).length > 0) {
|
||||
Object.assign(firstRef.value.formData, data);
|
||||
} else {
|
||||
resetForm();
|
||||
}
|
||||
getList();
|
||||
};
|
||||
//保存数据方法
|
||||
const submit = () => {
|
||||
@@ -581,11 +639,21 @@ const verifyMethod = (data) => {
|
||||
}
|
||||
return true;
|
||||
};
|
||||
// 打印方法
|
||||
const printFun = () => {
|
||||
isShowprintDom.value = true;
|
||||
nextTick(() => {
|
||||
recordPrintRef?.value.setData();
|
||||
previewPrint(recordPrintRef?.value.getDom());
|
||||
isShowprintDom.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
submit,
|
||||
commpoentType,
|
||||
setFormData,
|
||||
printFun,
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -7,177 +7,133 @@
|
||||
<span class="hospital-text">长春市朝阳区中医院</span>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<!-- 页面标题 -->
|
||||
<h2 class="form-title">住院病人风险评估表</h2>
|
||||
|
||||
<!-- 表单卡片 -->
|
||||
<el-card class="form-card">
|
||||
<el-form :model="formData" label-width="100px">
|
||||
<!-- 第一行:科室、床号、住院号 -->
|
||||
<el-row :gutter="16">
|
||||
<el-col :xs="24" :sm="12" :md="8">
|
||||
<el-form-item label="科室">
|
||||
<el-input
|
||||
v-model="formData.department"
|
||||
readonly="true"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 1 }"
|
||||
class="auto-resize-input"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="8">
|
||||
<el-form-item label="床号">
|
||||
<el-input
|
||||
v-model="formData.bedNo"
|
||||
readonly="true"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 1 }"
|
||||
class="auto-resize-input"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="8">
|
||||
<el-form-item label="住院号">
|
||||
<el-input
|
||||
v-model="formData.busNo"
|
||||
readonly="true"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 1 }"
|
||||
class="auto-resize-input"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 第二行:姓名、性别、年龄 -->
|
||||
<el-row :gutter="16">
|
||||
<el-col :xs="24" :sm="12" :md="8">
|
||||
<el-form-item label="姓名">
|
||||
<el-input
|
||||
v-model="formData.patientName"
|
||||
readonly="true"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 1 }"
|
||||
class="auto-resize-input"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="8">
|
||||
<el-form-item label="性别">
|
||||
<el-input
|
||||
v-model="formData.gender"
|
||||
readonly="true"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 1 }"
|
||||
class="auto-resize-input"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="8">
|
||||
<el-form-item label="年龄">
|
||||
<el-input
|
||||
v-model="formData.age"
|
||||
readonly="true"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 1 }"
|
||||
class="auto-resize-input"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 病情简介 -->
|
||||
<el-form-item label="病情简介">
|
||||
<el-input
|
||||
type="textarea"
|
||||
v-model="formData.adm_cond"
|
||||
:autosize="{ minRows: 4, maxRows: 10 }"
|
||||
class="full-width-textarea"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 不良后果及预后 -->
|
||||
<el-form-item label="可能发生的不良后果及预后">
|
||||
<el-input
|
||||
type="textarea"
|
||||
v-model="formData.effectless"
|
||||
:autosize="{ minRows: 1, maxRows: 5 }"
|
||||
class="full-width-textarea"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 评估等级 -->
|
||||
<el-form-item label="评估等级">
|
||||
<el-radio-group v-model="formData.evalLevel">
|
||||
<el-radio label="一般">一般</el-radio>
|
||||
<el-radio label="病重">病重</el-radio>
|
||||
<el-radio label="病危">病危</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 护理等级 -->
|
||||
<el-form-item label="护理等级">
|
||||
<el-radio-group v-model="formData.nurseLevel">
|
||||
<el-radio label="特级护理">特级护理</el-radio>
|
||||
<el-radio label="一级护理">一级护理</el-radio>
|
||||
<el-radio label="二级护理">二级护理</el-radio>
|
||||
<el-radio label="三级护理">三级护理</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 收集资料时间 -->
|
||||
<el-form-item label="收集资料时间">
|
||||
<span class="date-display">{{ currentDate }}</span>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 医师签名 -->
|
||||
<el-row :gutter="16">
|
||||
<el-col :xs="24" :sm="12" :md="8">
|
||||
<el-form-item label="评估医师签名">
|
||||
<el-input
|
||||
v-model="formData.sign_doc"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 1 }"
|
||||
class="auto-resize-input"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="8">
|
||||
<el-form-item label="主治医师签名">
|
||||
<el-input
|
||||
v-model="formData.sign_maindoc"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 1 }"
|
||||
class="auto-resize-input"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="8">
|
||||
<el-form-item label="科主任签名">
|
||||
<el-input
|
||||
v-model="formData.sign_leader"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 1 }"
|
||||
class="auto-resize-input"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<el-form :model="formData" label-width="100px">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="科室" label-position="top">
|
||||
<el-input v-model="formData.department" readonly="true"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="床号" label-position="top" class="comment-padding">
|
||||
<el-input v-model="formData.bedNo" readonly="true"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="住院号" label-position="top" class="comment-padding">
|
||||
<el-input v-model="formData.busNo" readonly="true"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="姓名" label-position="top">
|
||||
<el-input
|
||||
v-model="formData.patientName"
|
||||
readonly="true"
|
||||
class="auto-resize-input"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="性别" label-position="top" class="comment-padding">
|
||||
<el-input
|
||||
v-model="formData.gender"
|
||||
readonly="true"
|
||||
class="auto-resize-input"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="年龄" label-position="top" class="comment-padding">
|
||||
<el-input v-model="formData.age" readonly="true" class="auto-resize-input"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="病情简介" label-position="top">
|
||||
<el-input
|
||||
type="textarea"
|
||||
v-model="formData.adm_cond"
|
||||
:autosize="{ minRows: 1, maxRows: 100 }"
|
||||
class="full-width-textarea"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="可能发生的不良后果及预后" label-position="top">
|
||||
<el-input
|
||||
type="textarea"
|
||||
v-model="formData.effectless"
|
||||
:autosize="{ minRows: 1, maxRows: 100 }"
|
||||
class="full-width-textarea"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="评估等级" label-position="top">
|
||||
<el-radio-group v-model="formData.evalLevel">
|
||||
<el-radio label="一般">一般</el-radio>
|
||||
<el-radio label="病重">病重</el-radio>
|
||||
<el-radio label="病危">病危</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="护理等级" label-position="top">
|
||||
<el-radio-group v-model="formData.nurseLevel">
|
||||
<el-radio label="特级护理">特级护理</el-radio>
|
||||
<el-radio label="一级护理">一级护理</el-radio>
|
||||
<el-radio label="二级护理">二级护理</el-radio>
|
||||
<el-radio label="三级护理">三级护理</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="收集资料时间:">
|
||||
<span class="date-display">{{ currentDate }}</span>
|
||||
</el-form-item>
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="评估医师签名:">
|
||||
<el-input
|
||||
disabled
|
||||
v-model="formData.sign_doc"
|
||||
:autosize="{ minRows: 1 }"
|
||||
class="auto-resize-input"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="主治医师签名:" class="comment-padding">
|
||||
<el-input
|
||||
v-model="formData.sign_maindoc"
|
||||
:autosize="{ minRows: 1 }"
|
||||
class="auto-resize-input"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="科主任签名:" class="comment-padding">
|
||||
<el-input
|
||||
v-model="formData.sign_leader"
|
||||
:autosize="{ minRows: 1 }"
|
||||
class="auto-resize-input"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
<inAssessmentForm v-if="isShowprintDom" ref="recordPrintRef"></inAssessmentForm>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, onMounted, nextTick, reactive, ref } from 'vue';
|
||||
|
||||
import inAssessmentForm from '../views/hospitalRecord/components/inAssessmentForm.vue';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import { previewPrint } from '../utils/printUtils';
|
||||
defineOptions({
|
||||
name: 'InHospitalCaseForm',
|
||||
});
|
||||
|
||||
const isShowprintDom = ref(false);
|
||||
const recordPrintRef = ref();
|
||||
const props = defineProps({
|
||||
patientInfo: {
|
||||
type: Object,
|
||||
@@ -186,20 +142,21 @@ const props = defineProps({
|
||||
});
|
||||
|
||||
const patient = props.patientInfo;
|
||||
const userStore = useUserStore();
|
||||
|
||||
// 表单数据 - 修复:将 formData 定义移到 patient 之后
|
||||
const formData = reactive({
|
||||
department: patient?.department || '',
|
||||
bedNo: patient?.bedNo || '',
|
||||
department: patient?.inHospitalOrgName || '',
|
||||
bedNo: patient?.bedName || '',
|
||||
busNo: patient?.busNo || '',
|
||||
patientName: patient?.patientName || '',
|
||||
gender: patient?.sex || '',
|
||||
gender: patient?.genderEnum_enumText || '',
|
||||
age: patient?.age || '',
|
||||
adm_cond: '',
|
||||
effectless: '',
|
||||
evalLevel: '',
|
||||
nurseLevel: '',
|
||||
sign_doc: '',
|
||||
sign_doc: userStore.nickName || '',
|
||||
sign_maindoc: '',
|
||||
sign_leader: '',
|
||||
});
|
||||
@@ -220,9 +177,9 @@ const formRef = ref(null);
|
||||
const submit = () => {
|
||||
// 如果需要表单验证,可以使用以下代码
|
||||
// formRef.value.validate((valid) => {
|
||||
// if (valid) {
|
||||
// emits('submitOk', formData);
|
||||
// }
|
||||
// if (valid) {
|
||||
// emits('submitOk', formData);
|
||||
// }
|
||||
// });
|
||||
// 简化版本:
|
||||
emits('submitOk', formData);
|
||||
@@ -243,28 +200,36 @@ onMounted(() => {
|
||||
setTimeout(() => {
|
||||
window.dispatchEvent(new Event('resize'));
|
||||
}, 100);
|
||||
console.log('@@@@@=======>', JSON.stringify(props.patientInfo));
|
||||
});
|
||||
|
||||
// 打印方法
|
||||
const printFun = () => {
|
||||
console.log('入院记录打印');
|
||||
isShowprintDom.value = true;
|
||||
nextTick(() => {
|
||||
recordPrintRef?.value.setData(formData);
|
||||
nextTick(() => {
|
||||
previewPrint(recordPrintRef?.value.getDom());
|
||||
isShowprintDom.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
//暴露接口
|
||||
defineExpose({ formData, submit, setFormData });
|
||||
defineExpose({ formData, submit, setFormData, printFun });
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* ===== 页面容器与背景 ===== */
|
||||
.comment-padding {
|
||||
padding-left: 10px;
|
||||
}
|
||||
.assessment-page {
|
||||
font-family: 'Microsoft YaHei', 宋体, sans-serif;
|
||||
background-color: #f3f4f6;
|
||||
padding: 1.25rem;
|
||||
min-height: 100vh;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.page-container {
|
||||
max-width: 48rem;
|
||||
margin: 0 auto;
|
||||
background-color: #ffffff;
|
||||
padding: 1.5rem;
|
||||
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
||||
border-radius: 4px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* ===== 医院头部 ===== */
|
||||
@@ -272,8 +237,7 @@ defineExpose({ formData, submit, setFormData });
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.hospital-name {
|
||||
@@ -292,6 +256,7 @@ defineExpose({ formData, submit, setFormData });
|
||||
|
||||
/* ===== 表单标题与操作 ===== */
|
||||
.form-title {
|
||||
margin-top: 10px;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
@@ -305,22 +270,6 @@ defineExpose({ formData, submit, setFormData });
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
:deep(.el-card.form-card) {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
/* ===== 自动调整大小的输入框样式 ===== */
|
||||
.auto-resize-input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.auto-resize-input .el-textarea__inner) {
|
||||
overflow: hidden;
|
||||
resize: none;
|
||||
min-height: 32px !important;
|
||||
padding: 5px 12px;
|
||||
}
|
||||
|
||||
/* ===== Textarea 自动扩展样式 ===== */
|
||||
.full-width-textarea {
|
||||
width: 100%;
|
||||
@@ -337,15 +286,4 @@ defineExpose({ formData, submit, setFormData });
|
||||
font-size: 0.95rem;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* ===== 响应式调整 ===== */
|
||||
@media (max-width: 768px) {
|
||||
.page-container {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.hospital-name {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<template>
|
||||
<div class="medical-form">
|
||||
<h2 style="text-align: center;">{{ userStore.hospitalName || '长春市朝阳区中医院' }} -入院记录</h2>
|
||||
|
||||
<h2 style="text-align: center">
|
||||
{{ userStore.hospitalName || '长春市朝阳区中医院' }} -入院记录
|
||||
</h2>
|
||||
|
||||
<!-- 滚动内容区域 -->
|
||||
<div class="form-scroll-container">
|
||||
<el-form
|
||||
@@ -16,90 +18,67 @@
|
||||
<h4 class="section-title">基础信息</h4>
|
||||
<div class="adaptive-grid form-section">
|
||||
<el-form-item label="姓名" prop="patientName" class="grid-item required">
|
||||
<el-input
|
||||
v-model="formData.patientName"
|
||||
placeholder="请输入姓名"
|
||||
clearable
|
||||
/>
|
||||
<el-input v-model="formData.patientName" placeholder="请输入姓名" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="住院号" prop="hospitalNo" class="grid-item required">
|
||||
<el-input
|
||||
v-model="formData.hospitalNo"
|
||||
placeholder="请输入住院号"
|
||||
clearable
|
||||
/>
|
||||
<el-input v-model="formData.hospitalNo" placeholder="请输入住院号" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="性别" prop="gender" class="grid-item required">
|
||||
<el-select v-model="formData.gender" placeholder="请选择" style="width: 100%;">
|
||||
<el-select v-model="formData.gender" placeholder="请选择" style="width: 100%">
|
||||
<el-option label="男" value="男"></el-option>
|
||||
<el-option label="女" value="女"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="年龄" prop="age" class="grid-item required">
|
||||
<div class="input-with-unit">
|
||||
<el-input
|
||||
v-model.number="formData.age"
|
||||
placeholder="请输入年龄"
|
||||
clearable
|
||||
/>
|
||||
<el-input v-model.number="formData.age" placeholder="请输入年龄" clearable />
|
||||
<span class="unit">岁</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="民族" prop="nation" class="grid-item">
|
||||
<el-input
|
||||
v-model="formData.nation"
|
||||
placeholder="请输入民族"
|
||||
clearable
|
||||
/>
|
||||
<el-input v-model="formData.nation" placeholder="请输入民族" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="职业" prop="occupation" class="grid-item">
|
||||
<el-input
|
||||
v-model="formData.occupation"
|
||||
placeholder="请输入职业"
|
||||
clearable
|
||||
/>
|
||||
<el-input v-model="formData.occupation" placeholder="请输入职业" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="婚姻状况" prop="marriage" class="grid-item">
|
||||
<el-select v-model="formData.marriage" placeholder="请选择" clearable style="width: 100%;">
|
||||
<el-select
|
||||
v-model="formData.marriage"
|
||||
placeholder="请选择"
|
||||
clearable
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option label="已婚" value="已婚"></el-option>
|
||||
<el-option label="未婚" value="未婚"></el-option>
|
||||
<el-option label="离异" value="离异"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="出生地" prop="birthplace" class="grid-item">
|
||||
<el-input
|
||||
v-model="formData.birthplace"
|
||||
placeholder="请输入出生地"
|
||||
clearable
|
||||
/>
|
||||
<el-input v-model="formData.birthplace" placeholder="请输入出生地" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="入院时间" prop="admissionTime" class="grid-item required">
|
||||
<el-date-picker
|
||||
v-model="formData.admissionTime"
|
||||
type="datetime"
|
||||
placeholder="选择入院时间"
|
||||
<el-date-picker
|
||||
v-model="formData.admissionTime"
|
||||
type="datetime"
|
||||
placeholder="选择入院时间"
|
||||
value-format="YYYY-MM-DD HH:mm"
|
||||
style="width: 100%;"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="记录时间" prop="recordTime" class="grid-item required">
|
||||
<el-date-picker
|
||||
v-model="formData.recordTime"
|
||||
type="datetime"
|
||||
placeholder="选择记录时间"
|
||||
<el-date-picker
|
||||
v-model="formData.recordTime"
|
||||
type="datetime"
|
||||
placeholder="选择记录时间"
|
||||
value-format="YYYY-MM-DD HH:mm"
|
||||
style="width: 100%;"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="病史陈述者" prop="historyReporter" class="grid-item">
|
||||
<el-input
|
||||
v-model="formData.historyReporter"
|
||||
placeholder="请输入陈述者"
|
||||
clearable
|
||||
/>
|
||||
<el-input v-model="formData.historyReporter" placeholder="请输入陈述者" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="可靠程度" prop="reliability" class="grid-item">
|
||||
<el-select v-model="formData.reliability" placeholder="请选择" style="width: 100%;">
|
||||
<el-select v-model="formData.reliability" placeholder="请选择" style="width: 100%">
|
||||
<el-option label="可靠" value="可靠"></el-option>
|
||||
<el-option label="基本可靠" value="基本可靠"></el-option>
|
||||
<el-option label="不可靠" value="不可靠"></el-option>
|
||||
@@ -111,76 +90,76 @@
|
||||
<h4 class="section-title">病史信息</h4>
|
||||
<div class="form-section">
|
||||
<el-form-item label="主诉" prop="complaint" class="history-item required">
|
||||
<el-input
|
||||
v-model="formData.complaint"
|
||||
type="textarea"
|
||||
placeholder="请输入主诉"
|
||||
<el-input
|
||||
v-model="formData.complaint"
|
||||
type="textarea"
|
||||
placeholder="请输入主诉"
|
||||
autosize
|
||||
maxlength="200"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="现病史" prop="presentIllness" class="history-item">
|
||||
<el-input
|
||||
v-model="formData.presentIllness"
|
||||
type="textarea"
|
||||
placeholder="请详细描述现病史"
|
||||
<el-input
|
||||
v-model="formData.presentIllness"
|
||||
type="textarea"
|
||||
placeholder="请详细描述现病史"
|
||||
autosize
|
||||
maxlength="1000"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="既往史" prop="pastHistory" class="history-item">
|
||||
<el-input
|
||||
v-model="formData.pastHistory"
|
||||
type="textarea"
|
||||
placeholder="请输入既往史"
|
||||
<el-input
|
||||
v-model="formData.pastHistory"
|
||||
type="textarea"
|
||||
placeholder="请输入既往史"
|
||||
autosize
|
||||
maxlength="800"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="个人史" prop="personalHistory" class="history-item">
|
||||
<el-input
|
||||
v-model="formData.personalHistory"
|
||||
type="textarea"
|
||||
placeholder="请输入个人史"
|
||||
<el-input
|
||||
v-model="formData.personalHistory"
|
||||
type="textarea"
|
||||
placeholder="请输入个人史"
|
||||
autosize
|
||||
maxlength="500"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="婚育史" prop="maritalHistory" class="history-item">
|
||||
<el-input
|
||||
v-model="formData.maritalHistory"
|
||||
type="textarea"
|
||||
placeholder="请输入婚育史"
|
||||
<el-input
|
||||
v-model="formData.maritalHistory"
|
||||
type="textarea"
|
||||
placeholder="请输入婚育史"
|
||||
autosize
|
||||
maxlength="500"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="月经史" prop="menstrualHistory" class="history-item">
|
||||
<el-input
|
||||
v-model="formData.menstrualHistory"
|
||||
type="textarea"
|
||||
placeholder="请输入月经史"
|
||||
<el-input
|
||||
v-model="formData.menstrualHistory"
|
||||
type="textarea"
|
||||
placeholder="请输入月经史"
|
||||
autosize
|
||||
maxlength="500"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="家族史" prop="familyHistory" class="history-item">
|
||||
<el-input
|
||||
v-model="formData.familyHistory"
|
||||
type="textarea"
|
||||
placeholder="请输入家族史"
|
||||
<el-input
|
||||
v-model="formData.familyHistory"
|
||||
type="textarea"
|
||||
placeholder="请输入家族史"
|
||||
autosize
|
||||
maxlength="500"
|
||||
show-word-limit
|
||||
@@ -192,10 +171,10 @@
|
||||
<h4 class="section-title">中医望闻问切</h4>
|
||||
<div class="form-section">
|
||||
<el-form-item label="望闻问切" prop="tcmInfo" class="history-item">
|
||||
<el-input
|
||||
v-model="formData.tcmInfo"
|
||||
type="textarea"
|
||||
placeholder="请输入中医望闻问切结果"
|
||||
<el-input
|
||||
v-model="formData.tcmInfo"
|
||||
type="textarea"
|
||||
placeholder="请输入中医望闻问切结果"
|
||||
autosize
|
||||
maxlength="600"
|
||||
show-word-limit
|
||||
@@ -209,138 +188,134 @@
|
||||
<div class="adaptive-grid">
|
||||
<el-form-item label="体温" prop="temp" class="grid-item">
|
||||
<div class="input-with-unit">
|
||||
<el-input
|
||||
v-model.number="formData.temp"
|
||||
type="number"
|
||||
step="0.1"
|
||||
placeholder="如36.0"
|
||||
<el-input
|
||||
v-model.number="formData.temp"
|
||||
type="number"
|
||||
step="0.1"
|
||||
placeholder="如36.0"
|
||||
clearable
|
||||
/>
|
||||
<span class="unit">℃</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="脉搏" prop="pulse" class="grid-item">
|
||||
<div class="input-with-unit">
|
||||
<el-input
|
||||
v-model.number="formData.pulse"
|
||||
type="number"
|
||||
placeholder="如76"
|
||||
<el-input
|
||||
v-model.number="formData.pulse"
|
||||
type="number"
|
||||
placeholder="如76"
|
||||
clearable
|
||||
/>
|
||||
<span class="unit">次/分</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="呼吸" prop="respiration" class="grid-item">
|
||||
<div class="input-with-unit">
|
||||
<el-input
|
||||
v-model.number="formData.respiration"
|
||||
type="number"
|
||||
placeholder="如16"
|
||||
<el-input
|
||||
v-model.number="formData.respiration"
|
||||
type="number"
|
||||
placeholder="如16"
|
||||
clearable
|
||||
/>
|
||||
<span class="unit">次/分</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="血压" prop="bp" class="grid-item">
|
||||
<div class="input-with-unit">
|
||||
<el-input
|
||||
v-model="formData.bp"
|
||||
placeholder="如188/94"
|
||||
<el-input
|
||||
v-model="formData.bp"
|
||||
placeholder="如188/94"
|
||||
clearable
|
||||
@blur="validateBloodPressure"
|
||||
/>
|
||||
<span class="unit">mmHg</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="身高" prop="height" class="grid-item">
|
||||
<div class="input-with-unit">
|
||||
<el-input
|
||||
v-model.number="formData.height"
|
||||
type="number"
|
||||
placeholder="如165"
|
||||
<el-input
|
||||
v-model.number="formData.height"
|
||||
type="number"
|
||||
placeholder="如165"
|
||||
clearable
|
||||
/>
|
||||
<span class="unit">cm</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="体重" prop="weight" class="grid-item">
|
||||
<div class="input-with-unit">
|
||||
<el-input
|
||||
v-model.number="formData.weight"
|
||||
type="number"
|
||||
placeholder="如79"
|
||||
<el-input
|
||||
v-model.number="formData.weight"
|
||||
type="number"
|
||||
placeholder="如79"
|
||||
clearable
|
||||
/>
|
||||
<span class="unit">kg</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="BMI" prop="bmi" class="grid-item">
|
||||
<div class="input-with-unit">
|
||||
<el-input
|
||||
v-model="formData.bmi"
|
||||
placeholder="如29.02"
|
||||
readonly
|
||||
/>
|
||||
<el-input v-model="formData.bmi" placeholder="如29.02" readonly />
|
||||
<span class="unit">kg/m²</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<el-form-item label="一般情况" prop="general" class="history-item">
|
||||
<el-input
|
||||
v-model="formData.general"
|
||||
type="textarea"
|
||||
placeholder="请输入一般情况"
|
||||
<el-input
|
||||
v-model="formData.general"
|
||||
type="textarea"
|
||||
placeholder="请输入一般情况"
|
||||
autosize
|
||||
maxlength="300"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="皮肤粘膜" prop="skin" class="history-item">
|
||||
<el-input
|
||||
v-model="formData.skin"
|
||||
type="textarea"
|
||||
placeholder="请输入皮肤粘膜情况"
|
||||
<el-input
|
||||
v-model="formData.skin"
|
||||
type="textarea"
|
||||
placeholder="请输入皮肤粘膜情况"
|
||||
autosize
|
||||
maxlength="300"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="胸部(心、肺)" prop="chest" class="history-item">
|
||||
<el-input
|
||||
v-model="formData.chest"
|
||||
type="textarea"
|
||||
placeholder="请输入胸部检查结果"
|
||||
<el-input
|
||||
v-model="formData.chest"
|
||||
type="textarea"
|
||||
placeholder="请输入胸部检查结果"
|
||||
autosize
|
||||
maxlength="500"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="腹部" prop="abdomen" class="history-item">
|
||||
<el-input
|
||||
v-model="formData.abdomen"
|
||||
type="textarea"
|
||||
placeholder="请输入腹部检查结果"
|
||||
<el-input
|
||||
v-model="formData.abdomen"
|
||||
type="textarea"
|
||||
placeholder="请输入腹部检查结果"
|
||||
autosize
|
||||
maxlength="500"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="四肢/神经系统" prop="limbsNervous" class="history-item">
|
||||
<el-input
|
||||
v-model="formData.limbsNervous"
|
||||
type="textarea"
|
||||
placeholder="请输入四肢及神经系统检查结果"
|
||||
<el-input
|
||||
v-model="formData.limbsNervous"
|
||||
type="textarea"
|
||||
placeholder="请输入四肢及神经系统检查结果"
|
||||
autosize
|
||||
maxlength="500"
|
||||
show-word-limit
|
||||
@@ -352,10 +327,10 @@
|
||||
<h4 class="section-title">辅助检查</h4>
|
||||
<div class="form-section">
|
||||
<el-form-item label="检查结果" prop="auxExam" class="history-item">
|
||||
<el-input
|
||||
v-model="formData.auxExam"
|
||||
type="textarea"
|
||||
placeholder="请输入辅助检查结果"
|
||||
<el-input
|
||||
v-model="formData.auxExam"
|
||||
type="textarea"
|
||||
placeholder="请输入辅助检查结果"
|
||||
autosize
|
||||
maxlength="1000"
|
||||
show-word-limit
|
||||
@@ -367,21 +342,21 @@
|
||||
<h4 class="section-title">初步诊断</h4>
|
||||
<div class="form-section">
|
||||
<el-form-item label="中医诊断" prop="tcmDiagnosis" class="history-item">
|
||||
<el-input
|
||||
v-model="formData.tcmDiagnosis"
|
||||
type="textarea"
|
||||
placeholder="如:胸痹心痛(气阴两虚证)"
|
||||
<el-input
|
||||
v-model="formData.tcmDiagnosis"
|
||||
type="textarea"
|
||||
placeholder="如:胸痹心痛(气阴两虚证)"
|
||||
autosize
|
||||
maxlength="500"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="西医诊断" prop="westernDiagnosis" class="history-item">
|
||||
<el-input
|
||||
v-model="formData.westernDiagnosis"
|
||||
type="textarea"
|
||||
placeholder="如:1.冠状动脉粥样硬化性心脏病"
|
||||
<el-input
|
||||
v-model="formData.westernDiagnosis"
|
||||
type="textarea"
|
||||
placeholder="如:1.冠状动脉粥样硬化性心脏病"
|
||||
autosize
|
||||
maxlength="800"
|
||||
show-word-limit
|
||||
@@ -391,30 +366,22 @@
|
||||
|
||||
<!-- 7. 签名信息(三列布局) -->
|
||||
<h4 class="section-title">签名信息</h4>
|
||||
<div class="adaptive-grid form-section" style="grid-template-columns: repeat(3, 1fr);">
|
||||
<div class="adaptive-grid form-section" style="grid-template-columns: repeat(3, 1fr)">
|
||||
<el-form-item label="医师签名" prop="doctorSign" class="grid-item">
|
||||
<el-input
|
||||
v-model="formData.doctorSign"
|
||||
placeholder="请签名"
|
||||
clearable
|
||||
/>
|
||||
<el-input v-model="formData.doctorSign" placeholder="请签名" clearable />
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="上级医师签名" prop="superiorSign" class="grid-item">
|
||||
<el-input
|
||||
v-model="formData.superiorSign"
|
||||
placeholder="请签名"
|
||||
clearable
|
||||
/>
|
||||
<el-input v-model="formData.superiorSign" placeholder="请签名" clearable />
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="记录日期" prop="signDate" class="grid-item">
|
||||
<el-date-picker
|
||||
v-model="formData.signDate"
|
||||
type="datetime"
|
||||
placeholder="选择日期"
|
||||
<el-date-picker
|
||||
v-model="formData.signDate"
|
||||
type="datetime"
|
||||
placeholder="选择日期"
|
||||
value-format="YYYY-MM-DD HH:mm"
|
||||
style="width: 100%;"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
@@ -426,16 +393,30 @@
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
<admissionRecord v-if="isShowprintDom" ref="recordPrintRef"></admissionRecord>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch, onMounted } from 'vue';
|
||||
import { ElInput, ElSelect, ElOption, ElDatePicker, ElButton, ElMessage, ElMessageBox, ElForm, ElFormItem } from 'element-plus';
|
||||
import { previewPrint } from '../utils/printUtils';
|
||||
import admissionRecord from '../views/hospitalRecord/components/admissionRecord.vue';
|
||||
import {
|
||||
ElInput,
|
||||
ElSelect,
|
||||
ElOption,
|
||||
ElDatePicker,
|
||||
ElButton,
|
||||
ElMessage,
|
||||
ElMessageBox,
|
||||
ElForm,
|
||||
ElFormItem,
|
||||
} from 'element-plus';
|
||||
import useUserStore from '../store/modules/user';
|
||||
|
||||
const isShowprintDom = ref(false);
|
||||
const recordPrintRef = ref();
|
||||
defineOptions({
|
||||
name: 'InHospitalRecord',
|
||||
components: { ElInput, ElSelect, ElOption, ElDatePicker, ElButton, ElForm, ElFormItem }
|
||||
components: { ElInput, ElSelect, ElOption, ElDatePicker, ElButton, ElForm, ElFormItem },
|
||||
});
|
||||
|
||||
// Props与事件
|
||||
@@ -461,26 +442,26 @@ const formData = reactive({
|
||||
gender: patient?.genderEnum_enumText || '',
|
||||
age: patient?.age || '',
|
||||
nation: '',
|
||||
occupation: '',// 职业
|
||||
marriage: '',// 婚姻状况
|
||||
birthplace: '',// 出生地
|
||||
admissionTime: '',// 入院时间
|
||||
recordTime: '',// 记录时间
|
||||
historyReporter: '',// 病史陈述者
|
||||
reliability: '可靠',// 可靠程度
|
||||
occupation: '', // 职业
|
||||
marriage: '', // 婚姻状况
|
||||
birthplace: '', // 出生地
|
||||
admissionTime: '', // 入院时间
|
||||
recordTime: '', // 记录时间
|
||||
historyReporter: '', // 病史陈述者
|
||||
reliability: '可靠', // 可靠程度
|
||||
// 病史信息
|
||||
complaint: '',// 主诉
|
||||
presentIllness: '',// 现病史
|
||||
pastIllness: '',// 既往史
|
||||
personalHistory: '',// 个人史
|
||||
allergyHistory: '',// 过敏史
|
||||
pastHistory: '',// 既往史
|
||||
familyHistory: '',// 家族史
|
||||
maritalHistory: '',// 婚姻史
|
||||
menstrualHistory: '',// 月经史
|
||||
complaint: '', // 主诉
|
||||
presentIllness: '', // 现病史
|
||||
pastIllness: '', // 既往史
|
||||
personalHistory: '', // 个人史
|
||||
allergyHistory: '', // 过敏史
|
||||
pastHistory: '', // 既往史
|
||||
familyHistory: '', // 家族史
|
||||
maritalHistory: '', // 婚姻史
|
||||
menstrualHistory: '', // 月经史
|
||||
// 中医信息
|
||||
tcmInfo: '',
|
||||
|
||||
|
||||
// 体格检查
|
||||
temp: '',
|
||||
pulse: '',
|
||||
@@ -494,44 +475,38 @@ const formData = reactive({
|
||||
chest: '',
|
||||
abdomen: '',
|
||||
limbsNervous: '',
|
||||
|
||||
|
||||
// 辅助检查
|
||||
auxExam: '',
|
||||
|
||||
|
||||
// 诊断信息
|
||||
tcmDiagnosis: '',
|
||||
westernDiagnosis: '',
|
||||
|
||||
|
||||
// 签名信息
|
||||
doctorSign: '',
|
||||
superiorSign: '',
|
||||
signDate: ''
|
||||
signDate: '',
|
||||
});
|
||||
|
||||
// 表单校验规则
|
||||
const rules = reactive({
|
||||
name: [
|
||||
{ required: true, message: '请填写姓名', trigger: ['blur', 'submit'] }
|
||||
],
|
||||
hospitalNo: [
|
||||
{ required: true, message: '请填写住院号', trigger: ['blur', 'submit'] }
|
||||
],
|
||||
gender: [
|
||||
{ required: true, message: '请选择性别', trigger: ['change', 'submit'] }
|
||||
],
|
||||
name: [{ required: true, message: '请填写姓名', trigger: ['blur', 'submit'] }],
|
||||
hospitalNo: [{ required: true, message: '请填写住院号', trigger: ['blur', 'submit'] }],
|
||||
gender: [{ required: true, message: '请选择性别', trigger: ['change', 'submit'] }],
|
||||
age: [
|
||||
{ required: true, message: '请填写年龄', trigger: ['blur', 'submit'] },
|
||||
{ type: 'number', min: 1, max: 120, message: '年龄需在1-120岁之间', trigger: ['blur', 'submit'] }
|
||||
{
|
||||
type: 'number',
|
||||
min: 1,
|
||||
max: 120,
|
||||
message: '年龄需在1-120岁之间',
|
||||
trigger: ['blur', 'submit'],
|
||||
},
|
||||
],
|
||||
admissionTime: [
|
||||
{ required: true, message: '请选择入院时间', trigger: ['change', 'submit'] }
|
||||
],
|
||||
recordTime: [
|
||||
{ required: true, message: '请选择记录时间', trigger: ['change', 'submit'] }
|
||||
],
|
||||
chiefComplaint: [
|
||||
{ required: true, message: '请填写主诉', trigger: ['blur', 'submit'] }
|
||||
]
|
||||
admissionTime: [{ required: true, message: '请选择入院时间', trigger: ['change', 'submit'] }],
|
||||
recordTime: [{ required: true, message: '请选择记录时间', trigger: ['change', 'submit'] }],
|
||||
chiefComplaint: [{ required: true, message: '请填写主诉', trigger: ['blur', 'submit'] }],
|
||||
});
|
||||
|
||||
// 生命周期
|
||||
@@ -548,11 +523,11 @@ onMounted(() => {
|
||||
}
|
||||
if (!formData.patientName) {
|
||||
formData.patientName = patient?.patientName || '';
|
||||
}
|
||||
if (!formData.gender) {
|
||||
}
|
||||
if (!formData.gender) {
|
||||
formData.gender = patient?.genderEnum_enumText || '';
|
||||
}
|
||||
if (!formData.age) {
|
||||
}
|
||||
if (!formData.age) {
|
||||
formData.age = patient?.age || '';
|
||||
}
|
||||
if (!formData.hospitalNo) {
|
||||
@@ -571,21 +546,22 @@ watch([() => formData.height, () => formData.weight], ([newHeight, newWeight]) =
|
||||
});
|
||||
|
||||
// 入院时间变化处理
|
||||
watch(() => formData.admissionTime, (val) => {
|
||||
if (val && !formData.recordTime) {
|
||||
ElMessageBox.confirm(
|
||||
'是否将记录时间同步为入院时间?',
|
||||
'时间同步提示',
|
||||
{
|
||||
watch(
|
||||
() => formData.admissionTime,
|
||||
(val) => {
|
||||
if (val && !formData.recordTime) {
|
||||
ElMessageBox.confirm('是否将记录时间同步为入院时间?', '时间同步提示', {
|
||||
confirmButtonText: '同步',
|
||||
cancelButtonText: '手动设置',
|
||||
type: 'info'
|
||||
}
|
||||
).then(() => {
|
||||
formData.recordTime = val;
|
||||
}).catch(() => {});
|
||||
type: 'info',
|
||||
})
|
||||
.then(() => {
|
||||
formData.recordTime = val;
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
|
||||
// 血压格式校验
|
||||
const validateBloodPressure = () => {
|
||||
@@ -607,7 +583,7 @@ const submit = () => {
|
||||
validateBloodPressure();
|
||||
if (!formData.bp) return; // 格式错误时终止提交
|
||||
}
|
||||
|
||||
|
||||
emits('submitOk', formData);
|
||||
ElMessage.success('记录保存成功!');
|
||||
}
|
||||
@@ -616,35 +592,33 @@ const submit = () => {
|
||||
|
||||
// 新增:重置表单方法(带确认提示)
|
||||
const handleReset = () => {
|
||||
ElMessageBox.confirm(
|
||||
'确定要重置表单吗?所有已填写内容将被清空,且不可恢复',
|
||||
'重置确认',
|
||||
{
|
||||
confirmButtonText: '确认重置',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
center: true
|
||||
}
|
||||
).then(() => {
|
||||
// 执行表单重置
|
||||
formRef.value.resetFields();
|
||||
// 保留患者基础信息和默认值(避免清空关键基础数据)
|
||||
formData.patientName = patient?.name || '';
|
||||
formData.hospitalNo = patient?.busNo || '';
|
||||
formData.gender = patient?.genderEnum_enumText || '';
|
||||
formData.age = patient?.age || '';
|
||||
formData.reliability = '可靠';
|
||||
// 重置时间为当前时间
|
||||
const today = new Date();
|
||||
formData.admissionTime = formatDateTime(today);
|
||||
formData.recordTime = formatDateTime(today);
|
||||
formData.signDate = formatDateTime(today);
|
||||
// 重置成功提示
|
||||
ElMessage.success('表单已成功重置');
|
||||
}).catch(() => {
|
||||
// 取消重置提示
|
||||
ElMessage.info('已取消表单重置');
|
||||
});
|
||||
ElMessageBox.confirm('确定要重置表单吗?所有已填写内容将被清空,且不可恢复', '重置确认', {
|
||||
confirmButtonText: '确认重置',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
center: true,
|
||||
})
|
||||
.then(() => {
|
||||
// 执行表单重置
|
||||
formRef.value.resetFields();
|
||||
// 保留患者基础信息和默认值(避免清空关键基础数据)
|
||||
formData.patientName = patient?.name || '';
|
||||
formData.hospitalNo = patient?.busNo || '';
|
||||
formData.gender = patient?.genderEnum_enumText || '';
|
||||
formData.age = patient?.age || '';
|
||||
formData.reliability = '可靠';
|
||||
// 重置时间为当前时间
|
||||
const today = new Date();
|
||||
formData.admissionTime = formatDateTime(today);
|
||||
formData.recordTime = formatDateTime(today);
|
||||
formData.signDate = formatDateTime(today);
|
||||
// 重置成功提示
|
||||
ElMessage.success('表单已成功重置');
|
||||
})
|
||||
.catch(() => {
|
||||
// 取消重置提示
|
||||
ElMessage.info('已取消表单重置');
|
||||
});
|
||||
};
|
||||
|
||||
// 表单数据赋值
|
||||
@@ -664,8 +638,21 @@ const formatDateTime = (date) => {
|
||||
return `${year}-${month}-${day} ${hour}:${minute}`;
|
||||
};
|
||||
|
||||
// 打印方法
|
||||
const printFun = () => {
|
||||
console.log('入院记录打印');
|
||||
isShowprintDom.value = true;
|
||||
nextTick(() => {
|
||||
recordPrintRef?.value.setData(formData);
|
||||
nextTick(() => {
|
||||
previewPrint(recordPrintRef?.value.getDom());
|
||||
isShowprintDom.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 暴露接口
|
||||
defineExpose({ formData, submit, setFormData, handleReset });
|
||||
defineExpose({ formData, submit, setFormData, handleReset, printFun });
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@@ -673,8 +660,7 @@ defineExpose({ formData, submit, setFormData, handleReset });
|
||||
.medical-form {
|
||||
max-width: 1200px;
|
||||
width: 100%;
|
||||
height: 700px;
|
||||
margin: 15px auto;
|
||||
height: 28000px;
|
||||
padding: 15px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
@@ -810,7 +796,8 @@ defineExpose({ formData, submit, setFormData, handleReset });
|
||||
.adaptive-grid {
|
||||
grid-template-columns: 1fr; /* 小屏幕下单列显示 */
|
||||
}
|
||||
.grid-item, .history-item {
|
||||
.grid-item,
|
||||
.history-item {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
/* 小屏幕按钮居中 */
|
||||
@@ -825,4 +812,4 @@ defineExpose({ formData, submit, setFormData, handleReset });
|
||||
grid-template-columns: repeat(2, 1fr); /* 中等屏幕下两列显示 */
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -231,10 +231,12 @@
|
||||
<el-button type="warning" @click="handleReset">重置表单</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<intOperRecordSheet v-if="isShowprintDom" ref="recordPrintRef"></intOperRecordSheet>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import intOperRecordSheet from '../views/hospitalRecord/components/intOperRecordSheet.vue';
|
||||
import {
|
||||
ElMessage,
|
||||
ElMessageBox,
|
||||
@@ -246,6 +248,9 @@ import {
|
||||
ElDatePicker,
|
||||
ElButton,
|
||||
} from 'element-plus';
|
||||
import { previewPrint } from '../utils/printUtils';
|
||||
const isShowprintDom = ref(false);
|
||||
const recordPrintRef = ref();
|
||||
// 医院名称
|
||||
const hospitalName = '长春市朝阳区中医院';
|
||||
defineOptions({
|
||||
@@ -374,6 +379,9 @@ onMounted(() => {
|
||||
if (!formData.bedNo) {
|
||||
formData.bedNo = patient?.houseName + '-' + patient?.bedName;
|
||||
}
|
||||
if (!formData.busNo) {
|
||||
formData.busNo = patient?.busNo || '';
|
||||
}
|
||||
});
|
||||
|
||||
const emits = defineEmits(['submitOk']);
|
||||
@@ -393,6 +401,9 @@ const submit = () => {
|
||||
const setFormData = (data) => {
|
||||
if (data) {
|
||||
Object.assign(formData, data);
|
||||
if (!formData.busNo) {
|
||||
formData.busNo = patient?.busNo || '';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -439,18 +450,31 @@ const formatDateTime = (date) => {
|
||||
const minute = String(date.getMinutes()).padStart(2, '0');
|
||||
return `${year}-${month}-${day} ${hour}:${minute}`;
|
||||
};
|
||||
defineExpose({ submit, setFormData });
|
||||
const printFun = () => {
|
||||
console.log('入院记录打印');
|
||||
isShowprintDom.value = true;
|
||||
nextTick(() => {
|
||||
recordPrintRef?.value.setData(formData);
|
||||
nextTick(() => {
|
||||
previewPrint(recordPrintRef?.value.getDom());
|
||||
isShowprintDom.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
defineExpose({ submit, setFormData, printFun });
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 样式与原代码保持一致,无需修改 */
|
||||
/* 核心容器:PC端限制合理最大宽度,避免超宽屏内容过散 */
|
||||
.medical-document {
|
||||
max-width: 1200px;
|
||||
max-width: 1440px; /* PC端最优宽度,兼顾大屏和常规屏 */
|
||||
width: 98%; /* 占满父容器98%,保留少量边距 */
|
||||
margin: 20px auto;
|
||||
padding: 30px;
|
||||
background: #fff;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
font-family: 'SimSun', '宋体', serif;
|
||||
box-sizing: border-box; /* 确保内边距不撑大容器 */
|
||||
}
|
||||
|
||||
.doc-header {
|
||||
@@ -489,11 +513,14 @@ defineExpose({ submit, setFormData });
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* 自适应网格:PC端优先展示多列,优化列宽比例 */
|
||||
.adaptive-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
/* PC端最小列宽220px,保证每列内容不拥挤,自动适配列数 */
|
||||
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||||
gap: 15px 20px;
|
||||
margin-bottom: 15px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.grid-item {
|
||||
@@ -547,13 +574,15 @@ defineExpose({ submit, setFormData });
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
/* 仅针对小屏设备做基础适配,优先保证PC端体验 */
|
||||
@media (max-width: 768px) {
|
||||
.medical-document {
|
||||
max-width: 100%;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.adaptive-grid {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-columns: 1fr; /* 移动端强制单列 */
|
||||
}
|
||||
|
||||
.doc-title {
|
||||
@@ -565,6 +594,18 @@ defineExpose({ submit, setFormData });
|
||||
}
|
||||
}
|
||||
|
||||
/* 超宽屏(≥1920px)优化:适度增大间距,提升视觉体验 */
|
||||
@media (min-width: 1920px) {
|
||||
.medical-document {
|
||||
max-width: 1600px;
|
||||
padding: 40px;
|
||||
}
|
||||
.adaptive-grid {
|
||||
gap: 20px 25px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 打印样式保留 */
|
||||
@media print {
|
||||
.btn-group {
|
||||
display: none;
|
||||
@@ -574,6 +615,7 @@ defineExpose({ submit, setFormData });
|
||||
box-shadow: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.el-input__inner,
|
||||
|
||||
@@ -163,6 +163,7 @@ export function getPrinterList() {
|
||||
}
|
||||
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
/**
|
||||
* 获取当前登录用户ID
|
||||
@@ -315,6 +316,22 @@ export async function selectPrinterAndPrint(
|
||||
}
|
||||
}
|
||||
|
||||
// 预览打印
|
||||
export function previewPrint(elementDom) {
|
||||
if (elementDom) {
|
||||
//初始化
|
||||
window.hiprint.init();
|
||||
const hiprintTemplate = new window.hiprint.PrintTemplate();
|
||||
// printByHtml为预览打印
|
||||
hiprintTemplate.printByHtml(elementDom, {});
|
||||
} else {
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: '加载模版失败',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 默认导出简化的打印方法
|
||||
export default {
|
||||
print: simplePrint,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/**
|
||||
* 判断url是否是http或https
|
||||
* 判断url是否是http或https
|
||||
* @param {string} path
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function isHttp(url) {
|
||||
return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1
|
||||
export function isHttp(url) {
|
||||
return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -12,8 +12,8 @@
|
||||
* @param {string} path
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function isExternal(path) {
|
||||
return /^(https?:|mailto:|tel:)/.test(path)
|
||||
export function isExternal(path) {
|
||||
return /^(https?:|mailto:|tel:)/.test(path);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -21,8 +21,8 @@
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function validUsername(str) {
|
||||
const valid_map = ['admin', 'editor']
|
||||
return valid_map.indexOf(str.trim()) >= 0
|
||||
const valid_map = ['admin', 'editor'];
|
||||
return valid_map.indexOf(str.trim()) >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -30,8 +30,9 @@ export function validUsername(str) {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function validURL(url) {
|
||||
const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
|
||||
return reg.test(url)
|
||||
const reg =
|
||||
/^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/;
|
||||
return reg.test(url);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,8 +40,8 @@ export function validURL(url) {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function validLowerCase(str) {
|
||||
const reg = /^[a-z]+$/
|
||||
return reg.test(str)
|
||||
const reg = /^[a-z]+$/;
|
||||
return reg.test(str);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,8 +49,8 @@ export function validLowerCase(str) {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function validUpperCase(str) {
|
||||
const reg = /^[A-Z]+$/
|
||||
return reg.test(str)
|
||||
const reg = /^[A-Z]+$/;
|
||||
return reg.test(str);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,8 +58,8 @@ export function validUpperCase(str) {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function validAlphabets(str) {
|
||||
const reg = /^[A-Za-z]+$/
|
||||
return reg.test(str)
|
||||
const reg = /^[A-Za-z]+$/;
|
||||
return reg.test(str);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,8 +67,9 @@ export function validAlphabets(str) {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function validEmail(email) {
|
||||
const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
||||
return reg.test(email)
|
||||
const reg =
|
||||
/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||
return reg.test(email);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,9 +78,9 @@ export function validEmail(email) {
|
||||
*/
|
||||
export function isString(str) {
|
||||
if (typeof str === 'string' || str instanceof String) {
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,7 +89,39 @@ export function isString(str) {
|
||||
*/
|
||||
export function isArray(arg) {
|
||||
if (typeof Array.isArray === 'undefined') {
|
||||
return Object.prototype.toString.call(arg) === '[object Array]'
|
||||
return Object.prototype.toString.call(arg) === '[object Array]';
|
||||
}
|
||||
return Array.isArray(arg)
|
||||
return Array.isArray(arg);
|
||||
}
|
||||
// 手机号正则
|
||||
export function isValidCNPhoneNumber(phone) {
|
||||
const regex = /^1[3-9]\d{9}$/;
|
||||
return regex.test(phone);
|
||||
}
|
||||
// 身份证号正则
|
||||
export function isValidCNidCardNumber(idCard) {
|
||||
const regex = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
|
||||
return regex.test(idCard);
|
||||
}
|
||||
// 根据身份证号获取性别和年龄
|
||||
export function getGenderAndAge(idCard) {
|
||||
// 确保身份证号码是18位
|
||||
if (idCard.length !== 18) {
|
||||
return { error: '身份证号码必须是18位' };
|
||||
}
|
||||
// 提取出生年月日
|
||||
const birthDate = idCard.substr(6, 8); // YYYYMMDD
|
||||
const year = birthDate.substr(0, 4);
|
||||
const month = birthDate.substr(4, 2);
|
||||
const day = birthDate.substr(6, 2);
|
||||
const dateOfBirth = new Date(`${year}-${month}-${day}`);
|
||||
// 计算年龄
|
||||
const age = new Date().getFullYear() - dateOfBirth.getFullYear();
|
||||
const m = new Date().getMonth() - dateOfBirth.getMonth();
|
||||
if (m < 0 || (m === 0 && new Date().getDate() < dateOfBirth.getDate())) {
|
||||
age--;
|
||||
}
|
||||
// 提取性别
|
||||
const gender = idCard.charAt(16) % 2 === 0 ? 1 : 0;
|
||||
return { age, gender };
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<PopoverList @search="handleSearch" :width="800" :modelValue="scope.row.name">
|
||||
<template #popover-content="{}">
|
||||
<DeviceList
|
||||
v-if="scope.row.type == '2' || props.tab == 2 "
|
||||
v-if="scope.row.type == '2' || props.tab == 2"
|
||||
@selectRow="(row) => selectRow(row, scope.$index)"
|
||||
:searchKey="searchKey"
|
||||
/>
|
||||
@@ -171,7 +171,7 @@
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script setup>
|
||||
import { reactive, watch } from 'vue';
|
||||
import { bind, deleteBind, init } from './api';
|
||||
@@ -345,6 +345,5 @@ function selectRow(row, index) {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
|
||||
<style scoped></style>
|
||||
|
||||
@@ -79,8 +79,12 @@ import { getActivityList, getBindList, getRegistrationfeeList } from './componen
|
||||
import ConsumablesList from './components/consumablesList.vue';
|
||||
|
||||
const activityList = ref([]);
|
||||
const queryParams = ref({});
|
||||
const queryParamsRegistration = ref({});
|
||||
const queryParams = ref({
|
||||
statusEnum: 2,
|
||||
});
|
||||
const queryParamsRegistration = ref({
|
||||
activeFlag: 1,
|
||||
});
|
||||
const bindList = ref([]);
|
||||
const bindInfo = ref({});
|
||||
const activeTab = ref(1);
|
||||
@@ -91,19 +95,18 @@ const { proxy } = getCurrentInstance();
|
||||
const { method_code } = proxy.useDict('method_code');
|
||||
|
||||
getList();
|
||||
getRegistrationList()
|
||||
getRegistrationList();
|
||||
function getList() {
|
||||
// queryParams.value.typeEnum = activeTab.value;
|
||||
getActivityList(queryParams.value).then((res) => {
|
||||
activityList.value = res.data.records;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function getRegistrationList() {
|
||||
getRegistrationfeeList(queryParamsRegistration.value).then(res => {
|
||||
getRegistrationfeeList(queryParamsRegistration.value).then((res) => {
|
||||
RegistrationfeeList.value = res.data.records;
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 点击诊疗列表 获取绑定的耗材
|
||||
@@ -119,5 +122,4 @@ function clickRow(row) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<span style="vertical-align: middle">病区</span>
|
||||
</template>
|
||||
<div style="width: 100%">
|
||||
<el-button type="primary" @click="open = true" class="mb8"> 新增 </el-button>
|
||||
<el-button type="primary" @click="onIncrease" class="mb8"> 新增 </el-button>
|
||||
<el-button type="success" plain @click="handleEnableBatch('wardRef')" class="mb8">
|
||||
批量启用
|
||||
</el-button>
|
||||
@@ -16,7 +16,7 @@
|
||||
<el-table
|
||||
max-height="630"
|
||||
:data="wardList"
|
||||
@cell-click="(row) => clickRow(row, 10)"
|
||||
@cell-click="(row) => clickRow(row, 10, 0)"
|
||||
highlight-current-row
|
||||
ref="wardRef"
|
||||
>
|
||||
@@ -95,7 +95,7 @@
|
||||
<el-table
|
||||
height="280"
|
||||
:data="houseList"
|
||||
@cell-click="(row) => clickRow(row, 8)"
|
||||
@cell-click="(row) => clickRow(row, 8, 0, 1)"
|
||||
highlight-current-row
|
||||
v-loading="loading"
|
||||
ref="hourseRef"
|
||||
@@ -134,7 +134,7 @@
|
||||
@click.stop="
|
||||
() => {
|
||||
handleUnable(scope.row).then(() => {
|
||||
clickRow(houseRow, 10);
|
||||
getHouseList();
|
||||
});
|
||||
}
|
||||
"
|
||||
@@ -153,7 +153,7 @@
|
||||
@click.stop="
|
||||
() => {
|
||||
handleEnable(scope.row).then(() => {
|
||||
clickRow(houseRow, 10);
|
||||
getHouseList();
|
||||
});
|
||||
}
|
||||
"
|
||||
@@ -206,7 +206,7 @@
|
||||
@click.stop="
|
||||
() => {
|
||||
handleUnable(scope.row, 10).then(() => {
|
||||
clickRow(bedRow, 8);
|
||||
getBedList();
|
||||
});
|
||||
}
|
||||
"
|
||||
@@ -225,7 +225,7 @@
|
||||
@click.stop="
|
||||
() => {
|
||||
handleEnable(scope.row, 10).then(() => {
|
||||
clickRow(bedRow, 8);
|
||||
getBedList();
|
||||
});
|
||||
}
|
||||
"
|
||||
@@ -255,7 +255,7 @@
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="type + '名称'" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入科室名称" />
|
||||
<el-input v-model="form.name" :placeholder="'请输入' + type + '名称'" />
|
||||
</el-form-item>
|
||||
<el-col>
|
||||
<el-form-item :label="upLabel" prop="busNoParent">
|
||||
@@ -304,8 +304,9 @@
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script setup name="Ward">
|
||||
import { onMounted, ref } from 'vue';
|
||||
import {
|
||||
getList,
|
||||
addLocation,
|
||||
@@ -315,33 +316,65 @@ import {
|
||||
unableLocation,
|
||||
enableLocation,
|
||||
} from './components/api';
|
||||
import { ElMessage } from 'element-plus';
|
||||
const { proxy } = getCurrentInstance();
|
||||
// 病区参数
|
||||
const queryParams = ref({
|
||||
pageNum: 1,
|
||||
pageSize: 50,
|
||||
formEnum: 4,
|
||||
formEnum: 4, //4 病区 10 病房 8床位
|
||||
// locationFormList: [4],
|
||||
});
|
||||
// 病房参数
|
||||
const queryHouseParams = ref({
|
||||
pageNum: 1,
|
||||
pageSize: 50,
|
||||
formEnum: 10, //4 病区 10 病房 8床位
|
||||
// locationFormList: [4],
|
||||
});
|
||||
// 病床参数
|
||||
const querybedParams = ref({
|
||||
pageNum: 1,
|
||||
pageSize: 50,
|
||||
formEnum: 8, //4 病区 10 病房 8床位
|
||||
// locationFormList: [4],
|
||||
});
|
||||
// 病区、病房、病床类型
|
||||
const type = ref('病区');
|
||||
// 病区列表
|
||||
const wardList = ref([]);
|
||||
// 床位列表
|
||||
const bedList = ref([]);
|
||||
// 病房列表
|
||||
const houseList = ref([]);
|
||||
const wardListOption = ref([]);
|
||||
const organization = ref([]);
|
||||
const loading = ref(false);
|
||||
const isEdit = ref(false);
|
||||
const open = ref(false);
|
||||
// 病区row
|
||||
const wardRow = ref({});
|
||||
// 床位row
|
||||
const bedRow = ref({});
|
||||
// 病房row
|
||||
const houseRow = ref({});
|
||||
// 记录点击的是启用
|
||||
const clickType = ref(0);
|
||||
const orgRef = ref();
|
||||
// 新增数据参数
|
||||
const form = reactive({
|
||||
formEnum: 4,
|
||||
busNoParent: '',
|
||||
organizationId: '',
|
||||
name: '',
|
||||
busNo: '',
|
||||
});
|
||||
const upLabel = ref('关联科室');
|
||||
const title = ref('新增');
|
||||
const rules = ref({
|
||||
name: [
|
||||
{ required: true, message: '请输入科室名称', trigger: 'blur' },
|
||||
{ min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' },
|
||||
{ required: true, message: '请输入名称', trigger: 'blur' },
|
||||
{ required: true, min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' },
|
||||
],
|
||||
busNoParent: [
|
||||
{
|
||||
@@ -351,23 +384,76 @@ const rules = ref({
|
||||
},
|
||||
],
|
||||
});
|
||||
/**
|
||||
* 病区列表
|
||||
*/
|
||||
function getWardList() {
|
||||
queryParams.value.formEnum = 4;
|
||||
getList(queryParams.value).then((res) => {
|
||||
wardList.value = res.data.records;
|
||||
});
|
||||
}
|
||||
|
||||
// 获取科室下啦树
|
||||
function init() {
|
||||
getOrgList().then((res) => {
|
||||
organization.value = res.data.records;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 病区列表
|
||||
*/
|
||||
function getWardList() {
|
||||
houseList.value = [];
|
||||
bedList.value = [];
|
||||
getList(queryParams.value).then((res) => {
|
||||
wardList.value = res.data.records;
|
||||
});
|
||||
}
|
||||
// 获取病房列表
|
||||
const getHouseList = () => {
|
||||
// 4病区 10病房 8床位
|
||||
loading.value = true;
|
||||
// 病区号
|
||||
queryHouseParams.value.busNo = wardRow.value.busNo;
|
||||
bedList.value = [];
|
||||
getList(queryHouseParams.value).then((res) => {
|
||||
houseList.value = res.data.records;
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
// 获取床位列表
|
||||
const getBedList = () => {
|
||||
// 4病区 10病房 8床位
|
||||
loading.value = true;
|
||||
querybedParams.value.busNo = houseRow.value.busNo;
|
||||
bedList.value = [];
|
||||
getList(querybedParams.value).then((res) => {
|
||||
bedList.value = res.data.records;
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
// 点击新增按钮
|
||||
const onIncrease = () => {
|
||||
open.value = true;
|
||||
};
|
||||
|
||||
// 查询病房和病区的下拉选
|
||||
const getHomeOrBed = (formEnum) => {
|
||||
const params = {
|
||||
formEnum,
|
||||
pageNum: 1,
|
||||
pageSize: 50,
|
||||
};
|
||||
getList(params).then((res) => {
|
||||
if (formEnum == 10) {
|
||||
const datas = res.data?.records || [];
|
||||
const optionsList = datas.map((item) => {
|
||||
let obj = {
|
||||
...item,
|
||||
};
|
||||
obj.name = item.parentName + '-' + item.name;
|
||||
return obj;
|
||||
});
|
||||
wardListOption.value = optionsList;
|
||||
} else {
|
||||
wardListOption.value = res.data?.records || [];
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function handleRadioChange(val) {
|
||||
let formEnum = 4;
|
||||
if (val == 4) {
|
||||
type.value = '病区';
|
||||
upLabel.value = '关联科室';
|
||||
@@ -375,38 +461,56 @@ function handleRadioChange(val) {
|
||||
} else if (val == 10) {
|
||||
type.value = '病房';
|
||||
upLabel.value = '所属病区';
|
||||
queryParams.value.formEnum = 4;
|
||||
formEnum = 4;
|
||||
// queryParams.value.formEnum = 4;
|
||||
} else {
|
||||
type.value = '床位';
|
||||
upLabel.value = '所属病房';
|
||||
queryParams.value.formEnum = 10;
|
||||
formEnum = 10;
|
||||
// queryParams.value.formEnum = 10;
|
||||
}
|
||||
getList(queryParams.value).then((res) => {
|
||||
wardListOption.value = res.data.records;
|
||||
});
|
||||
form.organizationId = '';
|
||||
form.busNo = '';
|
||||
form.busNoParent = '';
|
||||
form.name = '';
|
||||
getHomeOrBed(formEnum);
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击患者列表行 获取处方列表
|
||||
*/
|
||||
function clickRow(row, val) {
|
||||
loading.value = true;
|
||||
queryParams.value.formEnum = val;
|
||||
queryParams.value.busNo = row.busNo;
|
||||
bedList.value = [];
|
||||
getList(queryParams.value).then((res) => {
|
||||
if (val == 10) {
|
||||
houseList.value = res.data.records;
|
||||
houseRow.value = row;
|
||||
} else if (val == 8) {
|
||||
bedRow.value = row;
|
||||
bedList.value = res.data.records;
|
||||
}
|
||||
setTimeout(() => {
|
||||
queryParams.value.busNo = undefined;
|
||||
loading.value = false;
|
||||
}, 100);
|
||||
});
|
||||
function clickRow(row, val, type) {
|
||||
// 1点击了启用
|
||||
clickType.value = type;
|
||||
console.log('val=====>', JSON.stringify(row));
|
||||
console.log('type=====>', JSON.stringify(type));
|
||||
console.log('val=====>', JSON.stringify(val));
|
||||
// if (type !== 1) {
|
||||
// if (val == 10) {
|
||||
// wardRow.value = row;
|
||||
// getHouseList();
|
||||
// } else if (val == 8) {
|
||||
// houseRow.value = row;
|
||||
// getBedList();
|
||||
// }
|
||||
// } else {
|
||||
// if (val == 10) {
|
||||
// houseRow.value = row;
|
||||
// getHouseList();
|
||||
// } else if (val == 8) {
|
||||
// bedRow.value = row;
|
||||
// getBedList();
|
||||
// }
|
||||
// }
|
||||
if (val == 10) {
|
||||
wardRow.value = row;
|
||||
getHouseList();
|
||||
} else if (val == 8) {
|
||||
houseRow.value = row;
|
||||
console.log('houseRow=====>', houseRow.value);
|
||||
|
||||
getBedList();
|
||||
}
|
||||
}
|
||||
|
||||
function checkSelectable(row, index) {
|
||||
@@ -459,38 +563,113 @@ function handleUnableBatch(tableRef) {
|
||||
});
|
||||
}
|
||||
|
||||
// 新增病床拆分"busNo": "LOC055.LOC056",
|
||||
const splitBusNo = (busNo) => {
|
||||
const busNoArr = busNo.split('.') || [];
|
||||
let busNoParent = '';
|
||||
if (busNoArr.length > 1) {
|
||||
busNoParent = busNoArr[0];
|
||||
}
|
||||
return busNoParent;
|
||||
};
|
||||
function submitForm() {
|
||||
if (form.busNoParent) {
|
||||
if (form.formEnum == 4) {
|
||||
form.organizationId = form.busNoParent;
|
||||
} else {
|
||||
form.busNo = form.busNoParent;
|
||||
if (!orgRef) return;
|
||||
const params = {
|
||||
...form,
|
||||
};
|
||||
console.log('form========>', JSON.stringify(form));
|
||||
console.log('params11========>', JSON.stringify(params));
|
||||
orgRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
console.log('99999999');
|
||||
|
||||
if (form.busNoParent) {
|
||||
if (form.formEnum == 4) {
|
||||
params.organizationId = form.busNoParent;
|
||||
} else {
|
||||
if (!isEdit.value) {
|
||||
params.busNo = form.busNoParent;
|
||||
// params.busNoParent = splitBusNo(form.busNoParent);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (form.formEnum == 4) {
|
||||
if (!(params.organizationId && params.organizationId.length > 0)) {
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: '请选择关联科室!',
|
||||
});
|
||||
return;
|
||||
}
|
||||
} else if (form.formEnum == 10) {
|
||||
if (!(params.busNo && params.busNo.length > 0)) {
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: '请选择所属病区!',
|
||||
});
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!(params.busNo && params.busNo.length > 8)) {
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: '请选择所属病房!',
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// console.log('params========>', JSON.stringify(form));
|
||||
console.log('params========>', JSON.stringify(params));
|
||||
// console.log('params========>', isEdit.value);
|
||||
if (!isEdit.value) {
|
||||
addLocation(params).then((res) => {
|
||||
if (res.code == 200) {
|
||||
proxy.$modal.msgSuccess('操作成功');
|
||||
if (params.formEnum == 4) {
|
||||
cancel();
|
||||
getWardList();
|
||||
} else if (params.formEnum == 10) {
|
||||
getHouseList();
|
||||
open.value = false;
|
||||
} else if (params.formEnum == 8) {
|
||||
getBedList();
|
||||
open.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
editLocation(params).then((res) => {
|
||||
if (res.code == 200) {
|
||||
proxy.$modal.msgSuccess('操作成功');
|
||||
if (params.formEnum == 4) {
|
||||
cancel();
|
||||
getWardList();
|
||||
} else if (params.formEnum == 10) {
|
||||
getHouseList();
|
||||
open.value = false;
|
||||
} else if (params.formEnum == 8) {
|
||||
getBedList();
|
||||
open.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(form);
|
||||
if (!isEdit.value) {
|
||||
addLocation(form).then((res) => {
|
||||
if (res.code == 200) {
|
||||
proxy.$modal.msgSuccess('操作成功');
|
||||
cancel();
|
||||
getWardList();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
editLocation(form).then((res) => {
|
||||
if (res.code == 200) {
|
||||
proxy.$modal.msgSuccess('操作成功');
|
||||
cancel();
|
||||
getWardList();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handleDelete(row) {
|
||||
deleteLocation(row.busNo).then((res) => {
|
||||
if (res.code == 200) {
|
||||
proxy.$modal.msgSuccess('删除成功');
|
||||
if (row.formEnum == 4) {
|
||||
getWardList();
|
||||
} else if (row.formEnum == 10) {
|
||||
getHouseList();
|
||||
} else {
|
||||
getBedList();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -501,24 +680,27 @@ function getLastPartOfString(str) {
|
||||
}
|
||||
|
||||
function handleEdit(row, val) {
|
||||
console.log('editRow=========>', JSON.stringify(row));
|
||||
|
||||
form.id = row.id;
|
||||
form.name = row.name;
|
||||
form.formEnum = row.formEnum;
|
||||
form.busNo = row.busNo;
|
||||
if (row.organizationId) {
|
||||
form.busNoParent = row.organizationId;
|
||||
form.organizationId = row.organizationId;
|
||||
} else {
|
||||
form.busNoParent = row.busNo.split('.').slice(0, -1).join('.');
|
||||
}
|
||||
isEdit.value = true;
|
||||
title.value = '编辑';
|
||||
if (val) {
|
||||
queryParams.value.formEnum = val;
|
||||
getList(queryParams.value).then((res) => {
|
||||
wardListOption.value = res.data.records;
|
||||
});
|
||||
}
|
||||
open.value = true;
|
||||
console.log('editRow1=========>', JSON.stringify(form));
|
||||
if (val == 4) {
|
||||
getHomeOrBed(4);
|
||||
} else if (val == 10) {
|
||||
getHomeOrBed(10);
|
||||
}
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
@@ -532,10 +714,13 @@ function cancel() {
|
||||
isEdit.value = false;
|
||||
title.value = '新增';
|
||||
}
|
||||
|
||||
init();
|
||||
getWardList();
|
||||
// 页面挂在成功
|
||||
onMounted(() => {
|
||||
// 获取所有科室
|
||||
init();
|
||||
// 获取病区列表
|
||||
getWardList();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -98,6 +98,13 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="69码" prop="drug69Code">
|
||||
<el-input v-model="form.drug69Code" placeholder="" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div class="title">临床信息</div>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="6">
|
||||
@@ -610,14 +617,15 @@
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="DDD值" prop="dddCode">
|
||||
<el-select v-model="antibioticForm.dddCode" clearable>
|
||||
<!-- <el-select v-model="antibioticForm.dddCode" clearable>
|
||||
<el-option
|
||||
v-for="category in ddd_code"
|
||||
:key="category.value"
|
||||
:label="category.label"
|
||||
:value="category.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-select> -->
|
||||
<el-input v-model="antibioticForm.dddCode" placeholder="请输入dddCode"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
|
||||
@@ -219,6 +219,13 @@
|
||||
prop="ybMatchFlag_enumText"
|
||||
:show-overflow-tooltip="true"
|
||||
/>
|
||||
<el-table-column
|
||||
label="69码"
|
||||
align="center"
|
||||
key="drug69Code"
|
||||
prop="drug69Code"
|
||||
:show-overflow-tooltip="true"
|
||||
/>
|
||||
<!-- <el-table-column
|
||||
label="医保上传"
|
||||
align="center"
|
||||
@@ -592,11 +599,10 @@ getMedicationCategoryList();
|
||||
getList();
|
||||
|
||||
// 药品名称按照第一个汉字首字母排序
|
||||
function getPinyinFirstLetter(row){
|
||||
function getPinyinFirstLetter(row) {
|
||||
const firstChar = row.merchandisePyStr.charAt(0);
|
||||
return firstChar.toUpperCase();
|
||||
};
|
||||
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.el-form--inline .el-form-item {
|
||||
|
||||
@@ -31,6 +31,11 @@
|
||||
<template v-for="(item, index) in formData.selfPay" :key="index">
|
||||
<div v-show="item.payEnum != 220500" class="payment-item">
|
||||
<span>支付方式:</span>
|
||||
<img
|
||||
v-if="item.payEnum == 220100 || item.payEnum == 220200"
|
||||
:src="imgs[item.payEnum == 220100 ? 0 : 1]"
|
||||
style="width: 20px; height: 20px"
|
||||
/>
|
||||
<el-select
|
||||
v-model="item.payEnum"
|
||||
placeholder="选择支付方式"
|
||||
@@ -164,7 +169,9 @@ import { hiprint } from 'vue-plugin-hiprint';
|
||||
import templateJson from './template.json';
|
||||
import { pa } from 'element-plus/es/locales.mjs';
|
||||
import printUtils, { PRINT_TEMPLATE } from '@/utils/printUtils';
|
||||
|
||||
import image1 from '../../../../assets/images/weixinzhifu.png';
|
||||
import image2 from '../../../../assets/images/zhifubaozhifu.png';
|
||||
const imgs = ref([image1, image2]);
|
||||
const props = defineProps({
|
||||
open: {
|
||||
type: Boolean,
|
||||
|
||||
@@ -241,7 +241,7 @@ import {
|
||||
changeStudentPayTosStudentSelf,
|
||||
changeStudentSelfToStudentPay,
|
||||
} from './components/api';
|
||||
import { invokeYbPlugin } from '@/api/public';
|
||||
import { invokeYbPlugin5000, invokeYbPlugin5001 } from '@/api/public';
|
||||
import ChargeDialog from './components/chargeDialog.vue';
|
||||
import { formatDateStr } from '@/utils';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
@@ -446,7 +446,7 @@ async function handleReadCard(value) {
|
||||
switch (value) {
|
||||
case '01': // 电子凭证
|
||||
// readCardLoading.value = true;
|
||||
await invokeYbPlugin({
|
||||
await invokeYbPlugin5000({
|
||||
FunctionId: 3,
|
||||
url: 'http://10.47.0.67:8089/localcfc/api/hsecfc/localQrCodeQuery',
|
||||
orgId: 'H22010200672',
|
||||
@@ -468,7 +468,7 @@ async function handleReadCard(value) {
|
||||
readCardLoading.value = false;
|
||||
});
|
||||
cardInfo = JSON.parse(JSON.stringify(jsonResult));
|
||||
let message = JSON.parse(cardInfo.message);
|
||||
let message = JSON.parse(cardInfo.data);
|
||||
userMessage = {
|
||||
certType: '02', // 证件类型
|
||||
certNo: message.data.idNo, // 身份证号
|
||||
@@ -488,7 +488,7 @@ async function handleReadCard(value) {
|
||||
case '03': // 社保卡
|
||||
readCardLoading.value = true;
|
||||
loadingText.value = '正在读取...';
|
||||
await invokeYbPlugin(
|
||||
await invokeYbPlugin5001(
|
||||
JSON.stringify({
|
||||
FunctionId: 1,
|
||||
IP: 'ddjk.jlhs.gov.cn',
|
||||
|
||||
@@ -360,6 +360,8 @@ async function printReceipt(param) {
|
||||
|
||||
// 收费时间
|
||||
chargeTime: new Date().toLocaleString(),
|
||||
//电子收据二维码
|
||||
pictureUrl: param.pictureUrl || 'https://chinaebill.com/img/xiaochengxu.png',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -71,6 +71,15 @@ export function getHealthcareMetadata(query) {
|
||||
});
|
||||
}
|
||||
|
||||
// 更新患者手机号
|
||||
export function updatePatientPhone(data) {
|
||||
return request({
|
||||
url: '/patient-manage/information/update-patient-phone',
|
||||
method: 'post',
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
|
||||
// 门诊挂号查询
|
||||
export function getOutpatientRegistrationCurrent(query) {
|
||||
return request({
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<!-- <el-col :span="8">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="活动标识" prop="tempFlag">
|
||||
<el-radio-group v-model="form.tempFlag" :disabled="isViewMode">
|
||||
<el-radio v-for="dict in patient_temp_flag" :key="dict.value" :label="dict.value">
|
||||
@@ -30,15 +30,33 @@
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col> -->
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="联系方式" prop="phone">
|
||||
<el-input v-model="form.phone" clearable :disabled="isViewMode" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<!-- <el-col :span="8">
|
||||
<el-form-item label="证件类型" prop="typeCode">
|
||||
<el-select
|
||||
v-model="form.typeCode"
|
||||
placeholder="证件类型"
|
||||
clearable
|
||||
:disabled="isViewMode"
|
||||
@change="typeChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in sys_idtype"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col> -->
|
||||
<el-col :span="8">
|
||||
<el-form-item label="证件号码" prop="idCard">
|
||||
<el-input v-model="form.idCard" clearable :disabled="isViewMode" />
|
||||
<el-form-item label="身份证号码" prop="idCard">
|
||||
<el-input v-model="form.idCard" clearable :disabled="isViewMode" @blur="onBlur" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
@@ -53,33 +71,16 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="卡类别" prop="typeCode">
|
||||
<el-select
|
||||
v-model="form.typeCode"
|
||||
placeholder="卡类别"
|
||||
clearable
|
||||
:disabled="isViewMode"
|
||||
>
|
||||
<el-option
|
||||
v-for="dict in sys_idtype"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="就诊卡号" prop="identifierNo">
|
||||
<el-input v-model="form.identifierNo" clearable :disabled="isViewMode" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<!-- <el-col :span="8">
|
||||
<el-form-item label="国家编码" prop="countryCode">
|
||||
<el-input v-model="form.countryCode" clearable :disabled="isViewMode" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-col> -->
|
||||
</el-row>
|
||||
<!-- <el-col :span="6">
|
||||
<el-form-item label="年龄" prop="age">
|
||||
@@ -243,7 +244,13 @@
|
||||
import { watch } from 'vue';
|
||||
import pcas from 'china-division/dist/pcas-code.json';
|
||||
import { addPatient, patientlLists, getOutpatientRegistrationList } from './outpatientregistration';
|
||||
import {
|
||||
isValidCNPhoneNumber,
|
||||
isValidCNidCardNumber,
|
||||
getGenderAndAge,
|
||||
} from '../../../../utils/validate';
|
||||
import { fromPairs } from 'lodash';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
const router = useRouter();
|
||||
const { proxy } = getCurrentInstance();
|
||||
@@ -289,13 +296,16 @@ const emits = defineEmits(['submit']); // 声明自定义事件
|
||||
const data = reactive({
|
||||
isViewMode: false,
|
||||
form: {
|
||||
typeCode: '08',
|
||||
typeCode: '01',
|
||||
tempFlag: '1',
|
||||
// genderEnum: 0,
|
||||
},
|
||||
rules: {
|
||||
name: [{ required: true, message: '姓名不能为空', trigger: 'change' }],
|
||||
genderEnum: [{ required: true, message: '请选择性别', trigger: 'change' }],
|
||||
age: [{ required: true, message: '年龄不能为空', trigger: 'change' }],
|
||||
phone: [{ required: true, message: '联系方式不能为空', trigger: 'change' }],
|
||||
idCard: [{ required: true, message: '证件号不能为空', trigger: 'change' }],
|
||||
},
|
||||
});
|
||||
|
||||
@@ -308,30 +318,30 @@ const props = defineProps({
|
||||
},
|
||||
});
|
||||
|
||||
watch(
|
||||
() => form.value.idCard,
|
||||
(newIdCard) => {
|
||||
if (newIdCard && newIdCard.length === 18) {
|
||||
const birthYear = parseInt(newIdCard.substring(6, 10));
|
||||
const birthMonth = parseInt(newIdCard.substring(10, 12));
|
||||
const birthDay = parseInt(newIdCard.substring(12, 14));
|
||||
// watch(
|
||||
// () => form.value.idCard,
|
||||
// (newIdCard) => {
|
||||
// if (newIdCard && newIdCard.length === 18) {
|
||||
// const birthYear = parseInt(newIdCard.substring(6, 10));
|
||||
// const birthMonth = parseInt(newIdCard.substring(10, 12));
|
||||
// const birthDay = parseInt(newIdCard.substring(12, 14));
|
||||
|
||||
const today = new Date();
|
||||
const currentYear = today.getFullYear();
|
||||
const currentMonth = today.getMonth() + 1;
|
||||
const currentDay = today.getDate();
|
||||
// const today = new Date();
|
||||
// const currentYear = today.getFullYear();
|
||||
// const currentMonth = today.getMonth() + 1;
|
||||
// const currentDay = today.getDate();
|
||||
|
||||
let age = currentYear - birthYear;
|
||||
// let age = currentYear - birthYear;
|
||||
|
||||
// 如果当前月份小于出生月份,或者月份相同但当前日期小于出生日期,则年龄减1
|
||||
if (currentMonth < birthMonth || (currentMonth === birthMonth && currentDay < birthDay)) {
|
||||
age--;
|
||||
}
|
||||
// // 如果当前月份小于出生月份,或者月份相同但当前日期小于出生日期,则年龄减1
|
||||
// if (currentMonth < birthMonth || (currentMonth === birthMonth && currentDay < birthDay)) {
|
||||
// age--;
|
||||
// }
|
||||
|
||||
form.value.age = age;
|
||||
}
|
||||
}
|
||||
);
|
||||
// form.value.age = age;
|
||||
// }
|
||||
// }
|
||||
// );
|
||||
/** 查询菜单列表 */
|
||||
function getList() {
|
||||
patientlLists().then((response) => {
|
||||
@@ -342,6 +352,7 @@ function getList() {
|
||||
bloodtypearhList.value = response.data.bloodTypeRH;
|
||||
familyrelationshiptypeList.value = response.data.familyRelationshipType;
|
||||
maritalstatusList.value = response.data.maritalStatus;
|
||||
console.log('administrativegenderList======>', JSON.stringify(administrativegenderList.value));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -399,7 +410,7 @@ function reset() {
|
||||
menuName: undefined,
|
||||
age: undefined,
|
||||
genderEnum: undefined,
|
||||
typeCode: '08',
|
||||
typeCode: '01',
|
||||
idCard: undefined,
|
||||
phone: undefined,
|
||||
prfsEnum: undefined,
|
||||
@@ -426,14 +437,45 @@ function reset() {
|
||||
}
|
||||
/** 提交按钮 */
|
||||
function submitForm() {
|
||||
if (!isValidCNPhoneNumber(form.value.phone)) {
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: '手机号有误,请重新输入',
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (form.value.typeCode === '01') {
|
||||
if (!isValidCNidCardNumber(form.value.idCard)) {
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: '身份证号有误,请重新输入',
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 活动标识 2 启用 3 停用
|
||||
if (form.value.tempFlag == '1') {
|
||||
form.value.activeFlag = 2;
|
||||
} else {
|
||||
form.value.activeFlag = 3;
|
||||
}
|
||||
form.value.patientIdInfoList = [
|
||||
{
|
||||
typeCode: form.value.typeCode,
|
||||
},
|
||||
];
|
||||
if (form.value.idCard) {
|
||||
form.value.birthDate =
|
||||
form.value.idCard.toString().substring(6, 10) +
|
||||
'-' +
|
||||
form.value.idCard.toString().substring(10, 12) +
|
||||
'-' +
|
||||
form.value.idCard.toString().substring(12, 14);
|
||||
console.log(form.value.birthDate, 123);
|
||||
if (form.value.typeCode === '01') {
|
||||
form.value.birthDate =
|
||||
form.value.idCard.toString().substring(6, 10) +
|
||||
'-' +
|
||||
form.value.idCard.toString().substring(10, 12) +
|
||||
'-' +
|
||||
form.value.idCard.toString().substring(12, 14);
|
||||
console.log(form.value.birthDate, 123);
|
||||
} else {
|
||||
form.value.birthDate = undefined;
|
||||
}
|
||||
}
|
||||
proxy.$refs['patientRef'].validate((valid) => {
|
||||
if (valid) {
|
||||
@@ -471,6 +513,22 @@ function cancel() {
|
||||
visible.value = false;
|
||||
reset();
|
||||
}
|
||||
// 身份证号失去焦点获取年龄和性别
|
||||
const onBlur = () => {
|
||||
if (form.value.typeCode === '01') {
|
||||
const info = getGenderAndAge(form.value.idCard || '');
|
||||
form.value.age = info.age;
|
||||
form.value.genderEnum = info.gender;
|
||||
}
|
||||
};
|
||||
//切换证件类型
|
||||
const typeChange = () => {
|
||||
if (form.value.typeCode === '01') {
|
||||
const info = getGenderAndAge(form.value.idCard || '');
|
||||
form.value.age = info.age;
|
||||
form.value.genderEnum = info.gender;
|
||||
}
|
||||
};
|
||||
defineExpose({
|
||||
show,
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
title="确认退费"
|
||||
:title="eventType == '1' ? '确认退费' : '挂号详情'"
|
||||
v-model="props.open"
|
||||
width="700px"
|
||||
append-to-body
|
||||
@@ -50,6 +50,7 @@
|
||||
v-model="reason"
|
||||
placeholder="退费原因"
|
||||
class="reason-textarea"
|
||||
:disabled="eventType == '1' ? false : true"
|
||||
/>
|
||||
</div>
|
||||
<!-- 添加退费方式功能暂时注释 -->
|
||||
@@ -102,7 +103,7 @@
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submit">确 定</el-button>
|
||||
<el-button v-if="eventType == 1" type="primary" @click="submit">确 定</el-button>
|
||||
<el-button @click="close">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
@@ -137,6 +138,10 @@ const props = defineProps({
|
||||
type: [],
|
||||
default: [],
|
||||
},
|
||||
eventType: {
|
||||
type: String,
|
||||
default: 1,
|
||||
},
|
||||
});
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
@@ -44,13 +44,7 @@
|
||||
<el-button type="primary" plain @click="handleReadCard('01')" style="width: 65px">
|
||||
电子凭证
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
@click="handleReadCard('02')"
|
||||
style="width: 65px"
|
||||
:disabled="true"
|
||||
>
|
||||
<el-button type="primary" plain @click="handleReadCard('02')" style="width: 65px">
|
||||
身份证
|
||||
</el-button>
|
||||
<el-button type="primary" plain @click="handleReadCard('03')" style="width: 65px">
|
||||
@@ -547,7 +541,7 @@
|
||||
<span>{{ parseTime(scope.row.registerTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" key="registerTime" prop="registerTime">
|
||||
<el-table-column label="操作" align="center" key="registerTime" prop="registerTime" do>
|
||||
<template #default="scope">
|
||||
<!-- <el-tooltip
|
||||
:content="
|
||||
@@ -560,14 +554,19 @@
|
||||
placement="top"
|
||||
:disabled="scope.row.statusEnum != 6"
|
||||
> -->
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="handleReturn(scope.row)"
|
||||
:disabled="scope.row.statusEnum == 6"
|
||||
>
|
||||
退号
|
||||
</el-button>
|
||||
<div style="display: flex">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="handleReturn(scope.row, 1)"
|
||||
:disabled="scope.row.statusEnum == 6"
|
||||
>
|
||||
退号
|
||||
</el-button>
|
||||
<el-button link type="primary" @click="handleReturn(scope.row, 0)">
|
||||
详情
|
||||
</el-button>
|
||||
</div>
|
||||
<!-- </el-tooltip> -->
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -616,6 +615,7 @@
|
||||
:patientInfo="patientInfo"
|
||||
:paymentId="paymentId"
|
||||
:chargeItemIds="chargeItemIdList"
|
||||
:eventType="eventType"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -635,8 +635,9 @@ import {
|
||||
precharge,
|
||||
cancelRegister,
|
||||
gerPreInfo,
|
||||
updatePatientPhone,
|
||||
} from './components/outpatientregistration';
|
||||
import { invokeYbPlugin } from '@/api/public';
|
||||
import { invokeYbPlugin5000, invokeYbPlugin5001 } from '@/api/public';
|
||||
import patientInfoDialog from './components/patientInfoDialog';
|
||||
import PatientAddDialog from './components/patientAddDialog';
|
||||
import patientList from './components/patientList';
|
||||
@@ -646,9 +647,11 @@ import RefundDialog from './components/refundDialog.vue';
|
||||
import { handleColor } from '@/utils/his';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import { formatDate, formatDateStr } from '@/utils/index';
|
||||
import { isValidCNPhoneNumber } from '../../../utils/validate';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
const patientInfo = ref({});
|
||||
|
||||
const eventType = ref(0);
|
||||
const router = useRouter();
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { sys_normal_disable, sys_user_sex, med_chrgitm_type } = proxy.useDict(
|
||||
@@ -730,11 +733,10 @@ const data = reactive({
|
||||
serviceTypeId: [{ required: true, message: '挂号类型不能为空', trigger: 'blur' }],
|
||||
organizationId: [{ required: true, message: '优先级不能为空', trigger: 'blur' }],
|
||||
orgId: [{ required: true, message: '就诊科室不能为空', trigger: 'blur' }],
|
||||
practitionerId: [
|
||||
{ required: true, message: "医生不能为空", trigger: "blur" },
|
||||
],
|
||||
practitionerId: [{ required: true, message: '医生不能为空', trigger: 'blur' }],
|
||||
typeCode: [{ required: true, message: '账户类型不能为空', trigger: 'blur' }],
|
||||
definitionId: [{ required: true, message: '费用定价不能为空', trigger: 'blur' }],
|
||||
phone: [{ required: true, message: '联系电话不能为空', trigger: 'blur' }],
|
||||
// totalPrice: [{ required: true, message: "总价不能为空", trigger: "blur" }],
|
||||
},
|
||||
});
|
||||
@@ -852,10 +854,10 @@ async function handleReadCard(value) {
|
||||
// .getInfoByQrCodeAsync(
|
||||
|
||||
// )
|
||||
await invokeYbPlugin({
|
||||
await invokeYbPlugin5000({
|
||||
FunctionId: 3,
|
||||
url: 'http://10.47.0.67:8089/localcfc/api/hsecfc/localQrCodeQuery',
|
||||
orgId: 'H22010200672',
|
||||
orgId: 'H22010402403',
|
||||
businessType: '01101',
|
||||
operatorId: userStore.id.toString(),
|
||||
operatorName: userStore.name,
|
||||
@@ -872,7 +874,7 @@ async function handleReadCard(value) {
|
||||
readCardLoading.value = false;
|
||||
});
|
||||
cardInfo = JSON.parse(JSON.stringify(jsonResult));
|
||||
let message = JSON.parse(cardInfo.message);
|
||||
let message = JSON.parse(cardInfo.data);
|
||||
userMessage = {
|
||||
certType: '02', // 证件类型
|
||||
certNo: message.data.idNo, // 身份证号
|
||||
@@ -892,7 +894,7 @@ async function handleReadCard(value) {
|
||||
case '03': // 社保卡
|
||||
readCardLoading.value = true;
|
||||
loadingText.value = '正在读取...';
|
||||
await invokeYbPlugin(
|
||||
await invokeYbPlugin5001(
|
||||
JSON.stringify({
|
||||
FunctionId: 1,
|
||||
IP: 'ddjk.jlhs.gov.cn',
|
||||
@@ -1143,6 +1145,8 @@ function reset() {
|
||||
|
||||
/** 新增按钮操作 */
|
||||
function handleAdd() {
|
||||
console.log('isValidCNPhoneNumber=======>', isValidCNPhoneNumber(form.value.phone));
|
||||
|
||||
transformedData.value = transformFormData(form.value);
|
||||
console.log(transformedData, 'transformedData门诊挂号');
|
||||
chargeItemIdList.value = [];
|
||||
@@ -1165,6 +1169,13 @@ function handleAdd() {
|
||||
};
|
||||
proxy.$refs['outpatientRegistrationRef'].validate((valid) => {
|
||||
if (valid) {
|
||||
if (!isValidCNPhoneNumber(patientInfo.value.phone)) {
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: '手机号格式不正确,请重新输入!',
|
||||
});
|
||||
return;
|
||||
}
|
||||
readCardLoading.value = true;
|
||||
transformedData.value.busiCardInfo = userCardInfo.busiCardInfo;
|
||||
transformedData.value.certType = userCardInfo.certType;
|
||||
@@ -1231,13 +1242,14 @@ function handleSearchPatient(value) {
|
||||
patientSearchKey.value = value;
|
||||
}
|
||||
|
||||
function handleReturn(row) {
|
||||
function handleReturn(row, type = '1') {
|
||||
openRefundDialog.value = true;
|
||||
patientInfo.value.patientId = row.patientId;
|
||||
patientInfo.value.encounterId = row.encounterId;
|
||||
totalAmount.value = row.totalPrice;
|
||||
chargeItemIdList.value = row.chargeItemIds.split(',');
|
||||
paymentId.value = row.paymentId;
|
||||
eventType.value = type;
|
||||
console.log(paymentId.value);
|
||||
}
|
||||
|
||||
@@ -1298,13 +1310,31 @@ function transformFormData(form) {
|
||||
},
|
||||
};
|
||||
}
|
||||
// 更新患者手机号
|
||||
async function updatePhone() {
|
||||
const params = {
|
||||
id: patientInfo.value.patientId,
|
||||
phone: patientInfo.value.phone,
|
||||
};
|
||||
console.log('params========>', JSON.stringify(params));
|
||||
|
||||
try {
|
||||
await updatePatientPhone(params);
|
||||
getList();
|
||||
reset();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
function handleClose(value) {
|
||||
openDialog.value = false;
|
||||
if (value == 'success') {
|
||||
proxy.$modal.msgSuccess('操作成功');
|
||||
getList();
|
||||
reset();
|
||||
// 更新患者手机号
|
||||
updatePhone();
|
||||
// getList();
|
||||
// reset();
|
||||
// addOutpatientRegistration(transformedData.value).then((response) => {
|
||||
// reset();
|
||||
// proxy.$modal.msgSuccess('新增成功');
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
"top": 22.5,
|
||||
"height": 12,
|
||||
"width": 420,
|
||||
"title": "长春市朝阳区中医院医院",
|
||||
"title": "长春市朝阳区中医院",
|
||||
"coordinateSync": false,
|
||||
"widthHeightSync": false,
|
||||
"fontSize": 13.5,
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
<el-table-column prop="patientName" label="姓名" align="center" />
|
||||
<el-table-column prop="genderEnum_enumText" label="性别" align="center" />
|
||||
<el-table-column prop="age" label="年龄" align="center" />
|
||||
<el-table-column prop="receptionTime" label="挂号时间" align="center" />
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
@@ -97,13 +98,7 @@
|
||||
>
|
||||
打印处置单
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
@click.stop="getEnPrescription()"
|
||||
>
|
||||
处方单
|
||||
</el-button>
|
||||
<el-button type="primary" plain @click.stop="getEnPrescription()"> 处方单 </el-button>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<el-form
|
||||
@@ -290,16 +285,16 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" header-align="center" prop="unitPrice" label="单价">
|
||||
<template #default="scope">
|
||||
<template #default="{ row }">
|
||||
<span>
|
||||
{{ scope.unitPrice ? scope.unitPrice.toFixed(2) : '0.00' + ' 元' }}
|
||||
{{ row.unitPrice ? row.unitPrice.toFixed(2) : '0.00' + ' 元' }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" header-align="center" prop="totalPrice" label="总价">
|
||||
<template #default="scope">
|
||||
<template #default="{ row }">
|
||||
<span>
|
||||
{{ scope.totalPrice ? scope.totalPrice.toFixed(2) : '0.00' + ' 元' }}
|
||||
{{ row.totalPrice ? row.totalPrice.toFixed(2) : '0.00' + ' 元' }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -309,7 +304,7 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
<PerformRecordDialog :open="openDialog" :recordList="recordList" @close="openDialog = false" />
|
||||
<PrescriptionInfo
|
||||
<PrescriptionInfo
|
||||
:open="openPrescriptionDialog"
|
||||
:precriptionInfo="prescriptionInfo"
|
||||
@close="openPrescriptionDialog = false"
|
||||
@@ -429,6 +424,7 @@ function handleServiceCategoryChange(value) {
|
||||
deviceList.value = res.data.records.filter((item) => {
|
||||
return item.requestTable == 'wor_device_request';
|
||||
});
|
||||
|
||||
activityList.value = res.data.records.filter((item) => {
|
||||
return (
|
||||
item.requestTable == 'wor_service_request' ||
|
||||
@@ -461,6 +457,7 @@ function getAllList(row) {
|
||||
deviceList.value = res.data.records.filter((item) => {
|
||||
return item.requestTable == 'wor_device_request';
|
||||
});
|
||||
console.log('耗材列表=====>', JSON.stringify(deviceList.value));
|
||||
activityList.value = res.data.records.filter((item) => {
|
||||
return (
|
||||
item.requestTable == 'wor_service_request' || item.requestTable == 'med_medication_request'
|
||||
|
||||
@@ -451,6 +451,8 @@ const templateRef = ref(null);
|
||||
const handleTemplateClick = (data) => {
|
||||
newEmr();
|
||||
editForm.value = data;
|
||||
editForm.value.id = '';
|
||||
editForm.value.recordTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
|
||||
nextTick(() => {
|
||||
emrComponentRef.value?.setFormData(JSON.parse(editForm.value.contextJson));
|
||||
});
|
||||
|
||||
@@ -868,6 +868,8 @@ watch(
|
||||
watch(
|
||||
() => prescriptionList.value,
|
||||
(newValue) => {
|
||||
// 每次进来重置总合计,存在医嘱会重新计算金额
|
||||
totalAmount.value = 0;
|
||||
if (newValue && newValue.length > 0) {
|
||||
handleTotalAmount();
|
||||
}
|
||||
|
||||
@@ -2,16 +2,16 @@ const formData = reactive({
|
||||
//医院信息
|
||||
hospitalInfo: {
|
||||
//组织机构代码
|
||||
orgCode: '',
|
||||
medins_orgcode: '',
|
||||
//医疗付款方式
|
||||
medicalPaymentCode: '',
|
||||
medfee_paymtd_code: '',
|
||||
},
|
||||
//患者信息
|
||||
patientInfo: {
|
||||
// 健康卡号
|
||||
healthCardNo: '',
|
||||
// 患者姓名
|
||||
patientName: '',
|
||||
patient_name: '',
|
||||
// 患者性别
|
||||
gend: '',
|
||||
// 出生日期
|
||||
@@ -19,11 +19,11 @@ const formData = reactive({
|
||||
// 年龄
|
||||
age: '',
|
||||
// 国籍
|
||||
nationality: '中国',
|
||||
ntly: '中国',
|
||||
// 籍贯
|
||||
napl: '',
|
||||
// 民族
|
||||
naty: '',
|
||||
naty: '1',
|
||||
// 身份证号
|
||||
certno: '',
|
||||
// 户口住址
|
||||
@@ -50,9 +50,9 @@ const formData = reactive({
|
||||
// 入院途径
|
||||
adm_way_code: '',
|
||||
// 入院时间
|
||||
admitTime: '',
|
||||
adm_time: '',
|
||||
// 入院科室
|
||||
adm_caty: '',
|
||||
adm_dept_name: '',
|
||||
// 病房
|
||||
adm_ward: '',
|
||||
// 确诊日期
|
||||
@@ -64,7 +64,7 @@ const formData = reactive({
|
||||
// 病房
|
||||
dscg_ward: '',
|
||||
// 实际住院天数
|
||||
ipt_days: '',
|
||||
act_ipt_days: '',
|
||||
},
|
||||
// 诊断信息
|
||||
diagnosis: {
|
||||
@@ -73,6 +73,8 @@ const formData = reactive({
|
||||
// 其他诊断
|
||||
otherDiagnosis: '',
|
||||
},
|
||||
// 诊断信息
|
||||
diagnosisList: [],
|
||||
// 医疗信息
|
||||
medicalInfo: {
|
||||
// 是否输血
|
||||
@@ -116,7 +118,7 @@ const formData = reactive({
|
||||
// 31天是否计划出院
|
||||
dscg_31days_rinp_flag: '',
|
||||
// 目的
|
||||
purpose: '',
|
||||
dscg_31days_rinp_pup: '',
|
||||
//昏迷时间---入院前
|
||||
brn_damg_bfadm_coma_dura: '',
|
||||
//昏迷时间---入院后
|
||||
@@ -132,7 +134,7 @@ const formData = reactive({
|
||||
// 判断依据
|
||||
judgmentBase: '',
|
||||
// 分化程度
|
||||
degreeDifferentiation: '',
|
||||
bkup_deg_code: '',
|
||||
// 临床路径
|
||||
enterPath: '',
|
||||
// 变异
|
||||
@@ -148,7 +150,7 @@ const formData = reactive({
|
||||
// 3级护理
|
||||
nursingLevel_3: '',
|
||||
// 呼吸机使用
|
||||
ventilatorUse: '',
|
||||
use_vent_flag: '',
|
||||
// 有创呼吸机使用小时
|
||||
vent_used_dura: '',
|
||||
// 手术表
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
' / ' +
|
||||
patientInfo.genderEnum_enumText +
|
||||
' / ' +
|
||||
patientInfo.contractName +
|
||||
(patientInfo?.contractName ? patientInfo.contractName : '') +
|
||||
'/' +
|
||||
patientInfo.phone +
|
||||
'/' +
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="就诊日期">
|
||||
<el-form-item label="入院日期">
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
type="daterange"
|
||||
@@ -60,14 +60,15 @@
|
||||
highlight-current-row
|
||||
@row-click="handleCurrentChange"
|
||||
>
|
||||
<el-table-column prop="encounterNo" label="住院号" width="150" align="center" />
|
||||
<el-table-column prop="patientName" label="姓名" width="130" align="center" />
|
||||
<el-table-column prop="genderEnum_enumText" label="性别" width="80" align="center" />
|
||||
<el-table-column prop="age" label="年龄" width="80" align="center" />
|
||||
<el-table-column prop="receptionTime" label="就诊日期" align="center">
|
||||
<!-- <el-table-column prop="receptionTime" label="就诊日期" align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row.receptionTime ? formatDate(scope.row.receptionTime) : '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table-column> -->
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
@@ -392,8 +393,8 @@ function submit(value) {
|
||||
}
|
||||
|
||||
function getList() {
|
||||
queryParams.value.receptionTimeSTime = dateRange.value[0] + ' 00:00:00';
|
||||
queryParams.value.receptionTimeETime = dateRange.value[1] + ' 23:59:59';
|
||||
queryParams.value.startTimeSTime = dateRange.value[0] + ' 00:00:00';
|
||||
queryParams.value.startTimeETime = dateRange.value[1] + ' 23:59:59';
|
||||
if (projectTypeCode.value == 2) {
|
||||
listPatient(queryParams.value).then((response) => {
|
||||
patientList.value = response.data.records;
|
||||
@@ -504,11 +505,11 @@ function resetQuery() {
|
||||
/** 搜索按钮操作 */
|
||||
function handleQuery() {
|
||||
if (dateRange.value) {
|
||||
queryParams.value.receptionTimeSTime = dateRange.value[0] + ' 00:00:00';
|
||||
queryParams.value.receptionTimeETime = dateRange.value[1] + ' 23:59:59';
|
||||
queryParams.value.startTimeSTime = dateRange.value[0] + ' 00:00:00';
|
||||
queryParams.value.startTimeETime = dateRange.value[1] + ' 23:59:59';
|
||||
} else {
|
||||
queryParams.value.receptionTimeSTime = null;
|
||||
queryParams.value.receptionTimeETime = null;
|
||||
queryParams.value.startTimeSTime = null;
|
||||
queryParams.value.startTimeETime = null;
|
||||
}
|
||||
queryParams.value.pageNo = 1;
|
||||
getList();
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<el-select
|
||||
placeholder="发放状态"
|
||||
style="width: 250px; margin-left: 10px"
|
||||
v-model="queryParams.therapyEnum"
|
||||
v-model="queryParams.statusEnum"
|
||||
@change="getSummaryList"
|
||||
>
|
||||
<el-option
|
||||
@@ -135,10 +135,16 @@
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { totalSendDrug, getFromSummaryList, getFromSummaryDetails } from './api.js';
|
||||
import {
|
||||
totalSendDrug,
|
||||
getFromSummaryList,
|
||||
getFromSummaryDetails,
|
||||
getFromSummaryInit,
|
||||
} from './api.js';
|
||||
import { getCurrentInstance } from 'vue';
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const statusEnumOptions = ref([]);
|
||||
const summaryList = ref([]);
|
||||
const queryParams = ref({
|
||||
applyTime: [
|
||||
@@ -206,6 +212,15 @@ function handleSend(row) {
|
||||
});
|
||||
}
|
||||
|
||||
// 获取发药状态
|
||||
const getStatusOption = async () => {
|
||||
try {
|
||||
const res = await getFromSummaryInit();
|
||||
statusEnumOptions.value = res.data.dispenseStatusOptions;
|
||||
} catch (error) {}
|
||||
};
|
||||
getStatusOption();
|
||||
|
||||
// 定义暴露给父组件的数据和方法
|
||||
defineExpose({
|
||||
selectedRows,
|
||||
|
||||
@@ -217,8 +217,8 @@ const ypName = ref('');
|
||||
const { proxy } = getCurrentInstance();
|
||||
getEncounterList();
|
||||
function getEncounterList() {
|
||||
queryParams.value.receptionTimeSTime = dateRange.value[0] + ' 00:00:00';
|
||||
queryParams.value.receptionTimeETime = dateRange.value[1] + ' 23:59:59';
|
||||
queryParams.value.startTimeSTime = dateRange.value[0] + ' 00:00:00';
|
||||
queryParams.value.startTimeETime = dateRange.value[1] + ' 23:59:59';
|
||||
getList(queryParams.value).then((res) => {
|
||||
encounterList.value = res.data.records;
|
||||
});
|
||||
@@ -478,4 +478,4 @@ function handelSpanMethod({ row, column, rowIndex, columnIndex }) {
|
||||
:deep(.no-hover-table) .el-table__body tr:hover > td {
|
||||
background: inherit !important;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -18,6 +18,15 @@ export function getFromSummaryList(queryParams) {
|
||||
});
|
||||
}
|
||||
|
||||
// 发药汇总发放状态
|
||||
export function getFromSummaryInit(queryParams) {
|
||||
return request({
|
||||
url: '/nurse-station/medicine-summary/summary-init',
|
||||
method: 'get',
|
||||
params: queryParams,
|
||||
});
|
||||
}
|
||||
|
||||
// 汇总发药单详情
|
||||
export function getFromSummaryDetails(queryParams) {
|
||||
return request({
|
||||
@@ -111,7 +120,7 @@ export function adviceCancel(data) {
|
||||
|
||||
/**
|
||||
* 明细发药
|
||||
*
|
||||
*
|
||||
*/
|
||||
export function totalSendDrug(data) {
|
||||
return request({
|
||||
@@ -131,69 +140,67 @@ export function totalReturnDrug(data) {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------门诊发药接口------------------------------------------------------------
|
||||
export function listPatient(query) {
|
||||
return request({
|
||||
url: '/pharmacy-manage/western-medicine-dispense/encounter-list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
export function devicePatientList(query) {
|
||||
return request({
|
||||
url: '/pharmacy-manage/device-dispense/encounter-list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
export function listInit(query) {
|
||||
return request({
|
||||
url: '/pharmacy-manage/western-medicine-dispense/init',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
export function listWesternmedicine(query) {
|
||||
return request({
|
||||
url: '/pharmacy-manage/western-medicine-dispense/medicine-order',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
export function updateMedicion(prescriptionList) {
|
||||
return request({
|
||||
url: '/pharmacy-manage/western-medicine-dispense/medicine-dispense',
|
||||
method: 'put',
|
||||
data: prescriptionList
|
||||
})
|
||||
}
|
||||
return request({
|
||||
url: '/pharmacy-manage/western-medicine-dispense/medicine-dispense',
|
||||
method: 'put',
|
||||
data: prescriptionList,
|
||||
});
|
||||
}
|
||||
export function prepareMedicion(data) {
|
||||
return request({
|
||||
url: '/pharmacy-manage/western-medicine-dispense/prepare',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
return request({
|
||||
url: '/pharmacy-manage/western-medicine-dispense/prepare',
|
||||
method: 'put',
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
export function backMedicion(data) {
|
||||
return request({
|
||||
url: '/pharmacy-manage/western-medicine-dispense/medicine-cancel',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
//扫码枪返回追溯码筛选
|
||||
export function itemTraceNo(params) {
|
||||
return request({
|
||||
url: '/app-common/item-trace-no?traceNoList=' + params,
|
||||
method: 'get',
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -203,8 +210,8 @@ export function getReportRegisterInit(query) {
|
||||
return request({
|
||||
url: '/pharmacy-manage/device-dispense/device-order',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -214,8 +221,8 @@ export function deviceDispense(params) {
|
||||
return request({
|
||||
url: '/pharmacy-manage/device-dispense/device-dispense',
|
||||
method: 'put',
|
||||
data: params
|
||||
})
|
||||
data: params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -225,8 +232,8 @@ export function deviceInvalid(data) {
|
||||
return request({
|
||||
url: '/pharmacy-manage/device-dispense/device-cancel',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -236,8 +243,8 @@ export function medicineMatch(data) {
|
||||
return request({
|
||||
url: '/pharmacy-manage/western-medicine-dispense/medicine-match',
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
params: data,
|
||||
});
|
||||
}
|
||||
|
||||
// ----------------------------------------------门诊退药接口----------------------------------------------------------------------
|
||||
@@ -248,8 +255,8 @@ export function getList(queryParams) {
|
||||
return request({
|
||||
url: '/pharmacy-manage/return-medicine/return-patient-page',
|
||||
method: 'get',
|
||||
params: queryParams
|
||||
})
|
||||
params: queryParams,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -259,8 +266,8 @@ export function getReturnDrugList(params) {
|
||||
return request({
|
||||
url: '/pharmacy-manage/return-medicine/medicine-return-list',
|
||||
method: 'get',
|
||||
params: params
|
||||
})
|
||||
params: params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -270,8 +277,8 @@ export function returnDrug(data) {
|
||||
return request({
|
||||
url: '/pharmacy-manage/return-medicine/medicine-return',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -281,7 +288,7 @@ export function init() {
|
||||
return request({
|
||||
url: '/pharmacy-manage/return-medicine/init',
|
||||
method: 'get',
|
||||
})
|
||||
});
|
||||
}
|
||||
// //扫码枪返回追溯码筛选
|
||||
// export function itemTraceNo(params) {
|
||||
|
||||
@@ -0,0 +1,725 @@
|
||||
<template>
|
||||
<div style="padding: 20px; max-width: 1200px; margin: 0 auto" ref="bodyRef">
|
||||
<!-- 标题区域 - 居中加粗,增加层次感 -->
|
||||
<div style="text-align: center; margin-bottom: 30px">
|
||||
<div style="font-size: 22px; color: #333; letter-spacing: 1px">长春市朝阳区中医院</div>
|
||||
<div
|
||||
style="
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: #222;
|
||||
padding: 12px 0;
|
||||
border-bottom: 2px solid #333;
|
||||
display: inline-block;
|
||||
"
|
||||
>
|
||||
入院记录
|
||||
</div>
|
||||
<div style="margin-top: 8px; font-size: 14px; color: #666">(第 1 页,共 1 页)</div>
|
||||
</div>
|
||||
|
||||
<!-- 基本信息模块 - 卡片式布局,优化间距和对齐 -->
|
||||
<div
|
||||
style="
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
padding: 25px;
|
||||
margin-bottom: 25px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.03);
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #eee;
|
||||
"
|
||||
>
|
||||
基本信息
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||
gap: 18px;
|
||||
"
|
||||
>
|
||||
<!-- 第一列 -->
|
||||
<div>
|
||||
<div style="display: flex; align-items: flex-start; margin-bottom: 16px">
|
||||
<span style="font-weight: 500; color: #333; min-width: 80px; font-size: 15px"
|
||||
>姓名:</span
|
||||
>
|
||||
<span style="font-size: 14px; color: #666; line-height: 1.5">{{
|
||||
formData.patientName
|
||||
}}</span>
|
||||
</div>
|
||||
<div style="display: flex; align-items: flex-start; margin-bottom: 16px">
|
||||
<span style="font-weight: 500; color: #333; min-width: 80px; font-size: 15px"
|
||||
>性别:</span
|
||||
>
|
||||
<span style="font-size: 14px; color: #666; line-height: 1.5">{{
|
||||
formData.gender
|
||||
}}</span>
|
||||
</div>
|
||||
<div style="display: flex; align-items: flex-start; margin-bottom: 16px">
|
||||
<span style="font-weight: 500; color: #333; min-width: 80px; font-size: 15px"
|
||||
>民族:</span
|
||||
>
|
||||
<span style="font-size: 14px; color: #666; line-height: 1.5">{{
|
||||
formData.nation || '汉族'
|
||||
}}</span>
|
||||
</div>
|
||||
<div style="display: flex; align-items: flex-start; margin-bottom: 16px">
|
||||
<span style="font-weight: 500; color: #333; min-width: 80px; font-size: 15px"
|
||||
>婚姻状况:</span
|
||||
>
|
||||
<span style="font-size: 14px; color: #666; line-height: 1.5">{{
|
||||
formData.marriage || ''
|
||||
}}</span>
|
||||
</div>
|
||||
<div style="display: flex; align-items: flex-start; margin-bottom: 16px">
|
||||
<span style="font-weight: 500; color: #333; min-width: 80px; font-size: 15px"
|
||||
>入院时间:</span
|
||||
>
|
||||
<span style="font-size: 14px; color: #666; line-height: 1.5">{{
|
||||
formData.admissionTime || ''
|
||||
}}</span>
|
||||
</div>
|
||||
<div style="display: flex; align-items: flex-start">
|
||||
<span style="font-weight: 500; color: #333; min-width: 80px; font-size: 15px"
|
||||
>病史陈述:</span
|
||||
>
|
||||
<span style="font-size: 14px; color: #666; line-height: 1.5">{{
|
||||
formData.historyReporter || ''
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 第二列 -->
|
||||
<div>
|
||||
<div style="display: flex; align-items: flex-start; margin-bottom: 16px">
|
||||
<span style="font-weight: 500; color: #333; min-width: 80px; font-size: 15px"
|
||||
>住院号:</span
|
||||
>
|
||||
<span style="font-size: 14px; color: #666; line-height: 1.5">{{
|
||||
formData.hospitalNo || '123456'
|
||||
}}</span>
|
||||
</div>
|
||||
<div style="display: flex; align-items: flex-start; margin-bottom: 16px">
|
||||
<span style="font-weight: 500; color: #333; min-width: 80px; font-size: 15px"
|
||||
>年龄:</span
|
||||
>
|
||||
<span style="font-size: 14px; color: #666; line-height: 1.5">{{
|
||||
formData.age || '16 岁'
|
||||
}}</span>
|
||||
</div>
|
||||
<div style="display: flex; align-items: flex-start; margin-bottom: 16px">
|
||||
<span style="font-weight: 500; color: #333; min-width: 80px; font-size: 15px"
|
||||
>职业:</span
|
||||
>
|
||||
<span style="font-size: 14px; color: #666; line-height: 1.5">{{
|
||||
formData.occupation || '中医'
|
||||
}}</span>
|
||||
</div>
|
||||
<div style="display: flex; align-items: flex-start; margin-bottom: 16px">
|
||||
<span style="font-weight: 500; color: #333; min-width: 80px; font-size: 15px"
|
||||
>出生地:</span
|
||||
>
|
||||
<span style="font-size: 14px; color: #666; line-height: 1.5">{{
|
||||
formData.birthplace || '阿拉善'
|
||||
}}</span>
|
||||
</div>
|
||||
<div style="display: flex; align-items: flex-start; margin-bottom: 16px">
|
||||
<span style="font-weight: 500; color: #333; min-width: 80px; font-size: 15px"
|
||||
>记录时间:</span
|
||||
>
|
||||
<span style="font-size: 14px; color: #666; line-height: 1.5">{{
|
||||
formData.recordTime || '2025-12-18 14:04:00'
|
||||
}}</span>
|
||||
</div>
|
||||
<div style="display: flex; align-items: flex-start">
|
||||
<span style="font-weight: 500; color: #333; min-width: 80px; font-size: 15px"
|
||||
>可靠程度:</span
|
||||
>
|
||||
<span style="font-size: 14px; color: #666; line-height: 1.5">{{
|
||||
formData.reliability
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 病史信息模块 - 优化布局,内容可换行 -->
|
||||
<div
|
||||
style="
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
padding: 25px;
|
||||
margin-bottom: 25px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.03);
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #eee;
|
||||
"
|
||||
>
|
||||
病史信息
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||
gap: 18px;
|
||||
"
|
||||
>
|
||||
<!-- 第一列 -->
|
||||
<div>
|
||||
<div style="display: flex; align-items: flex-start; margin-bottom: 16px">
|
||||
<span style="font-weight: 500; color: #333; min-width: 80px; font-size: 15px"
|
||||
>家族史:</span
|
||||
>
|
||||
<span style="font-size: 14px; color: #666; line-height: 1.6">{{
|
||||
formData.familyHistory || ''
|
||||
}}</span>
|
||||
</div>
|
||||
<div style="display: flex; align-items: flex-start; margin-bottom: 16px">
|
||||
<span style="font-weight: 500; color: #333; min-width: 80px; font-size: 15px"
|
||||
>现病史:</span
|
||||
>
|
||||
<span style="font-size: 14px; color: #666; line-height: 1.6">{{
|
||||
formData.presentIllness || ''
|
||||
}}</span>
|
||||
</div>
|
||||
<div style="display: flex; align-items: flex-start; margin-bottom: 16px">
|
||||
<span style="font-weight: 500; color: #333; min-width: 80px; font-size: 15px"
|
||||
>既往史:</span
|
||||
>
|
||||
<span style="font-size: 14px; color: #666; line-height: 1.6">{{
|
||||
formData.pastIllness || formData.pastHistory || ''
|
||||
}}</span>
|
||||
</div>
|
||||
<div style="display: flex; align-items: flex-start">
|
||||
<span style="font-weight: 500; color: #333; min-width: 80px; font-size: 15px"
|
||||
>主诉:</span
|
||||
>
|
||||
<span style="font-size: 14px; color: #666; line-height: 1.6">{{
|
||||
formData.complaint || ''
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 第二列 -->
|
||||
<div>
|
||||
<div style="display: flex; align-items: flex-start; margin-bottom: 16px">
|
||||
<span style="font-weight: 500; color: #333; min-width: 80px; font-size: 15px"
|
||||
>婚育史:</span
|
||||
>
|
||||
<span style="font-size: 14px; color: #666; line-height: 1.6">{{
|
||||
formData.maritalHistory || ''
|
||||
}}</span>
|
||||
</div>
|
||||
<div style="display: flex; align-items: flex-start; margin-bottom: 16px">
|
||||
<span style="font-weight: 500; color: #333; min-width: 80px; font-size: 15px"
|
||||
>月经史:</span
|
||||
>
|
||||
<span style="font-size: 14px; color: #666; line-height: 1.6">{{
|
||||
formData.menstrualHistory || ''
|
||||
}}</span>
|
||||
</div>
|
||||
<div style="display: flex; align-items: flex-start">
|
||||
<span style="font-weight: 500; color: #333; min-width: 80px; font-size: 15px"
|
||||
>个人史:</span
|
||||
>
|
||||
<span style="font-size: 14px; color: #666; line-height: 1.6">{{
|
||||
formData.personalHistory || ''
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 中医望闻问切模块 -->
|
||||
<div
|
||||
style="
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
padding: 25px;
|
||||
margin-bottom: 25px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.03);
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #eee;
|
||||
"
|
||||
>
|
||||
中医望闻问切
|
||||
</div>
|
||||
<div style="display: flex; align-items: flex-start">
|
||||
<span style="font-weight: 500; color: #333; min-width: 120px; font-size: 15px"
|
||||
>详细记录:</span
|
||||
>
|
||||
<span style="font-size: 14px; color: #666; line-height: 1.8">{{
|
||||
formData.tcmInfo || ''
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 体格检查模块 - 优化两列布局,信息对齐 -->
|
||||
<div
|
||||
style="
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
padding: 25px;
|
||||
margin-bottom: 25px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.03);
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #eee;
|
||||
"
|
||||
>
|
||||
体格检查
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||
gap: 25px;
|
||||
"
|
||||
>
|
||||
<!-- 第一列:生命体征 -->
|
||||
<div>
|
||||
<div
|
||||
style="
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
margin-bottom: 15px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
"
|
||||
>
|
||||
生命体征
|
||||
</div>
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 12px">
|
||||
<div style="padding: 10px; background: #f8f8f8; border-radius: 4px; text-align: center">
|
||||
<div style="font-size: 13px; color: #666; margin-bottom: 4px">体温</div>
|
||||
<div style="font-size: 14px; color: #333; font-weight: 500">
|
||||
{{ formData.temp || '' }}
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding: 10px; background: #f8f8f8; border-radius: 4px; text-align: center">
|
||||
<div style="font-size: 13px; color: #666; margin-bottom: 4px">脉搏</div>
|
||||
<div style="font-size: 14px; color: #333; font-weight: 500">
|
||||
{{ formData.pulse || '' }}
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding: 10px; background: #f8f8f8; border-radius: 4px; text-align: center">
|
||||
<div style="font-size: 13px; color: #666; margin-bottom: 4px">呼吸</div>
|
||||
<div style="font-size: 14px; color: #333; font-weight: 500">
|
||||
{{ formData.respiration || '' }}
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding: 10px; background: #f8f8f8; border-radius: 4px; text-align: center">
|
||||
<div style="font-size: 13px; color: #666; margin-bottom: 4px">血压</div>
|
||||
<div style="font-size: 14px; color: #333; font-weight: 500">
|
||||
{{ formData.bp || '' }}
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding: 10px; background: #f8f8f8; border-radius: 4px; text-align: center">
|
||||
<div style="font-size: 13px; color: #666; margin-bottom: 4px">身高</div>
|
||||
<div style="font-size: 14px; color: #333; font-weight: 500">
|
||||
{{ formData.height || '' }}
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding: 10px; background: #f8f8f8; border-radius: 4px; text-align: center">
|
||||
<div style="font-size: 13px; color: #666; margin-bottom: 4px">体重</div>
|
||||
<div style="font-size: 14px; color: #333; font-weight: 500">
|
||||
{{ formData.weight || '' }}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
padding: 10px;
|
||||
background: #f8f8f8;
|
||||
border-radius: 4px;
|
||||
text-align: center;
|
||||
grid-column: 1/3;
|
||||
"
|
||||
>
|
||||
<div style="font-size: 13px; color: #666; margin-bottom: 4px">BMI</div>
|
||||
<div style="font-size: 14px; color: #333; font-weight: 500">
|
||||
{{ formData.bmi || '' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 第二列:检查详情 -->
|
||||
<div>
|
||||
<div
|
||||
style="
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
margin-bottom: 15px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
"
|
||||
>
|
||||
检查详情
|
||||
</div>
|
||||
<div style="display: flex; align-items: flex-start; margin-bottom: 14px">
|
||||
<span style="font-weight: 500; color: #333; min-width: 100px; font-size: 14px"
|
||||
>皮肤粘膜:</span
|
||||
>
|
||||
<span style="font-size: 13px; color: #666; line-height: 1.5">{{
|
||||
formData.skin || ''
|
||||
}}</span>
|
||||
</div>
|
||||
<div style="display: flex; align-items: flex-start; margin-bottom: 14px">
|
||||
<span style="font-weight: 500; color: #333; min-width: 100px; font-size: 14px"
|
||||
>胸部:</span
|
||||
>
|
||||
<span style="font-size: 13px; color: #666; line-height: 1.5">{{
|
||||
formData.chest || ''
|
||||
}}</span>
|
||||
</div>
|
||||
<div style="display: flex; align-items: flex-start; margin-bottom: 14px">
|
||||
<span style="font-weight: 500; color: #333; min-width: 100px; font-size: 14px"
|
||||
>腹部:</span
|
||||
>
|
||||
<span style="font-size: 13px; color: #666; line-height: 1.5">{{
|
||||
formData.abdomen || ''
|
||||
}}</span>
|
||||
</div>
|
||||
<div style="display: flex; align-items: flex-start; margin-bottom: 14px">
|
||||
<span style="font-weight: 500; color: #333; min-width: 100px; font-size: 14px"
|
||||
>一般情况:</span
|
||||
>
|
||||
<span style="font-size: 13px; color: #666; line-height: 1.5">{{
|
||||
formData.general || ''
|
||||
}}</span>
|
||||
</div>
|
||||
<div style="display: flex; align-items: flex-start">
|
||||
<span style="font-weight: 500; color: #333; min-width: 100px; font-size: 14px"
|
||||
>四肢/神经:</span
|
||||
>
|
||||
<span style="font-size: 13px; color: #666; line-height: 1.5">{{
|
||||
formData.limbsNervous || ''
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 辅助检查模块 - 合并重复模块,优化显示 -->
|
||||
<div
|
||||
style="
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
padding: 25px;
|
||||
margin-bottom: 25px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.03);
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #eee;
|
||||
"
|
||||
>
|
||||
辅助检查
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
|
||||
gap: 20px;
|
||||
"
|
||||
>
|
||||
<div style="padding: 15px; background: #f8f8f8; border-radius: 6px">
|
||||
<div style="font-weight: 500; color: #333; font-size: 15px; margin-bottom: 8px">
|
||||
检查结果:
|
||||
</div>
|
||||
<div style="font-size: 14px; color: #666; line-height: 1.6">
|
||||
{{ formData.auxExam || '' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 诊断信息模块 - 修正分类,优化布局 -->
|
||||
<div
|
||||
style="
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
padding: 25px;
|
||||
margin-bottom: 25px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.03);
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #eee;
|
||||
"
|
||||
>
|
||||
诊断信息
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
|
||||
gap: 20px;
|
||||
"
|
||||
>
|
||||
<div style="padding: 18px; background: #f8f8f8; border-radius: 6px">
|
||||
<div style="font-weight: 500; color: #333; font-size: 15px; margin-bottom: 10px">
|
||||
中医诊断:
|
||||
</div>
|
||||
<div style="font-size: 14px; color: #666; line-height: 1.8">
|
||||
{{ formData.tcmDiagnosis || '' }}
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding: 18px; background: #f8f8f8; border-radius: 6px">
|
||||
<div style="font-weight: 500; color: #333; font-size: 15px; margin-bottom: 10px">
|
||||
西医诊断:
|
||||
</div>
|
||||
<div style="font-size: 14px; color: #666; line-height: 1.8">
|
||||
{{ formData.westernDiagnosis || '' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 签名信息模块 -->
|
||||
<div
|
||||
style="
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
padding: 25px;
|
||||
margin-bottom: 30px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.03);
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #eee;
|
||||
"
|
||||
>
|
||||
签名信息
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 30px;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
"
|
||||
>
|
||||
<div style="text-align: center">
|
||||
<div
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
font-size: 15px;
|
||||
margin-bottom: 40px;
|
||||
border-bottom: 1px solid #333;
|
||||
padding-bottom: 2px;
|
||||
display: inline-block;
|
||||
"
|
||||
>
|
||||
医师签名
|
||||
</div>
|
||||
<div style="font-size: 14px; color: #666">{{ formData.doctorSign || '' }}</div>
|
||||
</div>
|
||||
<div style="text-align: center">
|
||||
<div
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
font-size: 15px;
|
||||
margin-bottom: 40px;
|
||||
border-bottom: 1px solid #333;
|
||||
padding-bottom: 2px;
|
||||
display: inline-block;
|
||||
"
|
||||
>
|
||||
上级医师
|
||||
</div>
|
||||
<div style="font-size: 14px; color: #666">{{ formData.superiorSign || '' }}</div>
|
||||
</div>
|
||||
<div style="text-align: center">
|
||||
<div
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
font-size: 15px;
|
||||
margin-bottom: 40px;
|
||||
border-bottom: 1px solid #333;
|
||||
padding-bottom: 2px;
|
||||
display: inline-block;
|
||||
"
|
||||
>
|
||||
记录日期
|
||||
</div>
|
||||
<div style="font-size: 14px; color: #666">{{ formData.signDate || '' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部备注 -->
|
||||
<div
|
||||
style="
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
color: #888;
|
||||
margin-bottom: 20px;
|
||||
padding-top: 10px;
|
||||
border-top: 1px solid #eee;
|
||||
"
|
||||
>
|
||||
本记录由长春市朝阳区中医院医师根据患者病情如实记录,仅供临床诊疗参考 |
|
||||
地址:长春市朝阳区XX街XX号 | 联系电话:0431-XXXXXXX
|
||||
</div>
|
||||
|
||||
<!-- 打印按钮 - 优化样式,居中显示 -->
|
||||
<!-- <div style="text-align: center; margin-bottom: 30px">
|
||||
<el-button type="primary" @click="onPrint" style="padding: 10px 30px; font-size: 15px"
|
||||
>打印预览</el-button
|
||||
>
|
||||
</div> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from 'vue';
|
||||
import { previewPrint } from '../../../utils/printUtils';
|
||||
|
||||
const bodyRef = ref();
|
||||
|
||||
// 响应式表单数据
|
||||
const formData = reactive({
|
||||
// 基础信息
|
||||
patientName: '', // 原patient?.name
|
||||
hospitalNo: '', // 原patient?.busNo
|
||||
gender: '', // 原patient?.genderEnum_enumText
|
||||
age: '',
|
||||
nation: '',
|
||||
occupation: '', // 职业
|
||||
marriage: '', // 婚姻状况
|
||||
birthplace: '', // 出生地
|
||||
admissionTime: '', // 入院时间
|
||||
recordTime: '', // 记录时间
|
||||
historyReporter: '', // 病史陈述者
|
||||
reliability: '可靠', // 可靠程度
|
||||
// 病史信息
|
||||
complaint: '', // 主诉
|
||||
presentIllness: '', // 现病史
|
||||
pastIllness: '', // 既往史
|
||||
personalHistory: '', // 个人史
|
||||
allergyHistory: '', // 过敏史
|
||||
pastHistory: '', // 既往史(重复字段,保留兼容)
|
||||
familyHistory: '', // 家族史
|
||||
maritalHistory: '', // 婚姻史
|
||||
menstrualHistory: '', // 月经史
|
||||
// 中医信息
|
||||
tcmInfo: '',
|
||||
|
||||
// 体格检查
|
||||
temp: '',
|
||||
pulse: '',
|
||||
respiration: '',
|
||||
bp: '',
|
||||
height: '',
|
||||
weight: '',
|
||||
bmi: '',
|
||||
general: '',
|
||||
skin: '',
|
||||
chest: '',
|
||||
abdomen: '',
|
||||
limbsNervous: '',
|
||||
|
||||
// 辅助检查
|
||||
auxExam: '',
|
||||
|
||||
// 诊断信息
|
||||
tcmDiagnosis: '',
|
||||
westernDiagnosis: '',
|
||||
|
||||
// 签名信息
|
||||
doctorSign: '',
|
||||
superiorSign: '',
|
||||
signDate: '',
|
||||
});
|
||||
|
||||
// 打印方法
|
||||
const onPrint = () => {
|
||||
// previewPrint(bodyRef.value);
|
||||
};
|
||||
|
||||
const getDom = () => {
|
||||
return bodyRef.value;
|
||||
};
|
||||
const setData = (data) => {
|
||||
console.log('设置数据=========>', JSON.stringify(data));
|
||||
Object.assign(formData, data);
|
||||
};
|
||||
defineExpose({
|
||||
setData,
|
||||
getDom,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 打印样式优化,隐藏不必要元素 */
|
||||
@media print {
|
||||
.el-button {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
body {
|
||||
print-color-adjust: exact;
|
||||
-webkit-print-color-adjust: exact;
|
||||
}
|
||||
|
||||
div[style*='box-shadow'] {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,543 @@
|
||||
<template>
|
||||
<div
|
||||
ref="bodyRef"
|
||||
style="
|
||||
padding: 30px 20px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
min-height: 100vh;
|
||||
background: #f8f9fa;
|
||||
font-family: 'Microsoft YaHei', 'PingFang SC', sans-serif;
|
||||
"
|
||||
>
|
||||
<!-- 标题区域 - 强化正式感与层次感 -->
|
||||
<div style="text-align: center; margin-bottom: 35px; padding: 20px 0">
|
||||
<div
|
||||
style="
|
||||
font-size: 24px;
|
||||
color: #2c3e50;
|
||||
letter-spacing: 2px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 8px;
|
||||
"
|
||||
>
|
||||
长春市朝阳区中医院
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: #1a2b48;
|
||||
padding: 12px 0;
|
||||
border-bottom: 2px solid #2c3e50;
|
||||
display: inline-block;
|
||||
letter-spacing: 1px;
|
||||
"
|
||||
>
|
||||
出院诊断病历
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 基础信息卡片 -->
|
||||
<div
|
||||
style="
|
||||
border: 1px solid #e5e8eb;
|
||||
border-radius: 12px;
|
||||
padding: 25px;
|
||||
margin-bottom: 25px;
|
||||
background: #ffffff;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #f0f2f5;
|
||||
position: relative;
|
||||
"
|
||||
>
|
||||
基础信息
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||
gap: 18px;
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 16px;
|
||||
line-height: 1.6;
|
||||
word-wrap: break-word;
|
||||
"
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #34495e;
|
||||
min-width: 80px;
|
||||
font-size: 15px;
|
||||
flex-shrink: 0;
|
||||
word-wrap: break-word;
|
||||
"
|
||||
>姓名:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
flex: 1;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
white-space: normal;
|
||||
"
|
||||
>{{ formData.patientName }}</span
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 16px;
|
||||
line-height: 1.6;
|
||||
word-wrap: break-word;
|
||||
"
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #34495e;
|
||||
min-width: 80px;
|
||||
font-size: 15px;
|
||||
flex-shrink: 0;
|
||||
word-wrap: break-word;
|
||||
"
|
||||
>性别:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
flex: 1;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
white-space: normal;
|
||||
"
|
||||
>{{ formData.gender }}</span
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 16px;
|
||||
line-height: 1.6;
|
||||
word-wrap: break-word;
|
||||
"
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #34495e;
|
||||
min-width: 80px;
|
||||
font-size: 15px;
|
||||
flex-shrink: 0;
|
||||
word-wrap: break-word;
|
||||
"
|
||||
>年龄:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
flex: 1;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
white-space: normal;
|
||||
"
|
||||
>{{ formData.age }}</span
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 16px;
|
||||
line-height: 1.6;
|
||||
word-wrap: break-word;
|
||||
"
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #34495e;
|
||||
min-width: 80px;
|
||||
font-size: 15px;
|
||||
flex-shrink: 0;
|
||||
word-wrap: break-word;
|
||||
"
|
||||
>住院号:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
flex: 1;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
white-space: normal;
|
||||
"
|
||||
>{{ formData.busNo }}</span
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 16px;
|
||||
line-height: 1.6;
|
||||
word-wrap: break-word;
|
||||
"
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #34495e;
|
||||
min-width: 80px;
|
||||
font-size: 15px;
|
||||
flex-shrink: 0;
|
||||
word-wrap: break-word;
|
||||
"
|
||||
>职业:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
flex: 1;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
white-space: normal;
|
||||
"
|
||||
>{{ formData.temperature }}</span
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 16px;
|
||||
line-height: 1.6;
|
||||
word-wrap: break-word;
|
||||
"
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #34495e;
|
||||
min-width: 80px;
|
||||
font-size: 15px;
|
||||
flex-shrink: 0;
|
||||
word-wrap: break-word;
|
||||
"
|
||||
>入院时间:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
flex: 1;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
white-space: normal;
|
||||
"
|
||||
>{{ formData.admissionDate }}</span
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 16px;
|
||||
line-height: 1.6;
|
||||
word-wrap: break-word;
|
||||
"
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #34495e;
|
||||
min-width: 80px;
|
||||
font-size: 15px;
|
||||
flex-shrink: 0;
|
||||
word-wrap: break-word;
|
||||
"
|
||||
>出院时间:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
flex: 1;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
white-space: normal;
|
||||
"
|
||||
>{{ formData.dischargeDate }}</span
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 16px;
|
||||
line-height: 1.6;
|
||||
word-wrap: break-word;
|
||||
"
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #34495e;
|
||||
min-width: 80px;
|
||||
font-size: 15px;
|
||||
flex-shrink: 0;
|
||||
word-wrap: break-word;
|
||||
"
|
||||
>住院天数:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
flex: 1;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
white-space: normal;
|
||||
"
|
||||
>{{ formData.hospitalDays }}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 诊断信息卡片 -->
|
||||
<div
|
||||
style="
|
||||
border: 1px solid #e5e8eb;
|
||||
border-radius: 12px;
|
||||
padding: 25px;
|
||||
margin-bottom: 25px;
|
||||
background: #ffffff;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #f0f2f5;
|
||||
position: relative;
|
||||
"
|
||||
>
|
||||
诊断
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||
gap: 18px;
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 16px;
|
||||
line-height: 1.6;
|
||||
word-wrap: break-word;
|
||||
"
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #34495e;
|
||||
min-width: 80px;
|
||||
font-size: 15px;
|
||||
flex-shrink: 0;
|
||||
word-wrap: break-word;
|
||||
"
|
||||
>出诊诊断:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
flex: 1;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
white-space: normal;
|
||||
"
|
||||
>{{ formData.DischargeDiagnosis }}</span
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 16px;
|
||||
line-height: 1.6;
|
||||
word-wrap: break-word;
|
||||
grid-column: 1 / -1;
|
||||
padding: 4px 0;
|
||||
"
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #34495e;
|
||||
min-width: 80px;
|
||||
font-size: 15px;
|
||||
flex-shrink: 0;
|
||||
word-wrap: break-word;
|
||||
"
|
||||
>出院病情摘要:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
flex: 1;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
white-space: normal;
|
||||
"
|
||||
>{{ formData.SummaryAndDiagnosisAndTreatmentProcess }}</span
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 16px;
|
||||
line-height: 1.6;
|
||||
word-wrap: break-word;
|
||||
grid-column: 1 / -1;
|
||||
padding: 4px 0;
|
||||
"
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #34495e;
|
||||
min-width: 80px;
|
||||
font-size: 15px;
|
||||
flex-shrink: 0;
|
||||
word-wrap: break-word;
|
||||
"
|
||||
>出院后要求及注意事项:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
flex: 1;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
white-space: normal;
|
||||
"
|
||||
>{{ formData.RequirementsAndPrecautionsAfterDischarge }}</span
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 16px;
|
||||
line-height: 1.6;
|
||||
word-wrap: break-word;
|
||||
grid-column: 1 / -1;
|
||||
padding: 4px 0;
|
||||
"
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #34495e;
|
||||
min-width: 80px;
|
||||
font-size: 15px;
|
||||
flex-shrink: 0;
|
||||
word-wrap: break-word;
|
||||
"
|
||||
>中医调护:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
flex: 1;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
white-space: normal;
|
||||
"
|
||||
>{{ formData.TraditionalChineseMedicineNursing }}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from 'vue'; // 补充缺失的reactive导入
|
||||
|
||||
const bodyRef = ref(null);
|
||||
const showPrintPreview = ref(false); // 控制弹窗显隐
|
||||
|
||||
// 表单数据
|
||||
const formData = reactive({
|
||||
patientName: '', // 姓名
|
||||
age: '', // 年龄
|
||||
gender: '', // 性别
|
||||
busNo: '', // 住院号
|
||||
admissionDate: '', // 入院日期
|
||||
dischargeDate: '', // 出院日期
|
||||
hospitalDays: '', // 住院天数
|
||||
DischargeDiagnosis: '', // 出院诊断
|
||||
SummaryAndDiagnosisAndTreatmentProcess: '', // 出院病情摘要及诊疗经过
|
||||
RequirementsAndPrecautionsAfterDischarge: '', // 出院后要求及注意事项
|
||||
TraditionalChineseMedicineNursing: '', // 中医调护
|
||||
});
|
||||
|
||||
const getDom = () => {
|
||||
return bodyRef.value;
|
||||
};
|
||||
|
||||
const setData = (data) => {
|
||||
console.log('设置数据=========>', JSON.stringify(data));
|
||||
Object.assign(formData, data);
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
setData,
|
||||
getDom,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 以下是内联样式无法实现的样式(保留说明) */
|
||||
/* 1. 伪元素样式(card-title::after):内联样式不支持伪元素 */
|
||||
/* 2. hover效果:内联样式不支持:hover伪类 */
|
||||
/* 3. 媒体查询响应式:内联样式无法编写@media规则 */
|
||||
/* 4. 打印预览相关样式:若需要打印功能,需单独处理 */
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,347 @@
|
||||
<template>
|
||||
<div style="padding: 20px; background: #f8f9fa; min-height: 100vh;" ref="bodyRef">
|
||||
<!-- 标题区域 - 强化正式感 -->
|
||||
<div
|
||||
style="text-align: center; margin-bottom: 30px; padding: 20px; background: #fff; border-radius: 12px; box-shadow: 0 2px 6px rgba(0,0,0,0.03);">
|
||||
<div style="font-size: 22px; color: #2d3748; letter-spacing: 1px;">长春市朝阳区中医院</div>
|
||||
<div
|
||||
style="font-size: 28px; font-weight: 700; margin: 12px 0; padding: 8px 0; border-bottom: 2px solid #e8f4f8; display: inline-block;">
|
||||
住院患者入院沟通记录单</div>
|
||||
<div style="display: flex; justify-content: center; align-items: center; gap: 10px; font-size: 15px; ">
|
||||
<span style="font-weight: 500;">住院号:</span>
|
||||
<span style="font-weight: 600; text-decoration: underline;">20210001</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 基本信息模块 -->
|
||||
<div class="card-container">
|
||||
<div class="card-header">
|
||||
<span class="card-title">基本信息</span>
|
||||
</div>
|
||||
<div class="card-content grid-2col">
|
||||
<div class="info-item">
|
||||
<span class="info-label">姓名:</span>
|
||||
<span class="info-value">张三</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">性别:</span>
|
||||
<span class="info-value">男</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">年龄:</span>
|
||||
<span class="info-value">34 岁</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">科室/病区:</span>
|
||||
<span class="info-value">中医科</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">病房/床号:</span>
|
||||
<span class="info-value">305-2</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">入院日期:</span>
|
||||
<span class="info-value">2025-02-14</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 团队信息模块 -->
|
||||
<div class="card-container">
|
||||
<div class="card-header">
|
||||
<span class="card-title">团队信息</span>
|
||||
</div>
|
||||
<div class="card-content grid-2col">
|
||||
<div class="info-item">
|
||||
<span class="info-label">经治医生:</span>
|
||||
<span class="info-value">华佗</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">主治医生:</span>
|
||||
<span class="info-value">王海明</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">科主任:</span>
|
||||
<span class="info-value">特斯拉</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 病情与诊断模块 -->
|
||||
<div class="card-container">
|
||||
<div class="card-header">
|
||||
<span class="card-title">病情与诊断</span>
|
||||
</div>
|
||||
<div class="card-content grid-2col">
|
||||
<div class="info-item">
|
||||
<span class="info-label">病情状况:</span>
|
||||
<div class="info-value multi-line">
|
||||
1111111111111111111111111111111111111111111111111111111111111111111111111111</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">中医诊断:</span>
|
||||
<div class="info-value multi-line">
|
||||
1111111111111111111111111111111111111111111111111111111111111111111111111111</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">西医诊断:</span>
|
||||
<div class="info-value multi-line">
|
||||
1111111111111111111111111111111111111111111111111111111111111111111111111111</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 治疗与检查计划模块 -->
|
||||
<div class="card-container">
|
||||
<div class="card-header">
|
||||
<span class="card-title">治疗与检查计划</span>
|
||||
</div>
|
||||
<div class="card-content grid-2col">
|
||||
<div class="info-item">
|
||||
<span class="info-label">治疗方案:</span>
|
||||
<div class="info-value multi-line">
|
||||
1111111111111111111111111111111111111111111111111111111111111111111111111111</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">进一步检查项目:</span>
|
||||
<div class="info-value multi-line">血常规、肝肾功能、腹部B超、心电图、中医辨证分型检查、肿瘤标志物筛查</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 风险告知模块 -->
|
||||
<div class="card-container">
|
||||
<div class="card-header">
|
||||
<span class="card-title">风险告知</span>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div class="info-item full-width">
|
||||
<span class="info-label">告知内容:</span>
|
||||
<div class="info-value multi-line">
|
||||
1. 治疗过程中可能出现药物不良反应(如过敏、胃肠道不适等),若出现不适需及时告知医护人员;<br />
|
||||
2. 检查项目存在一定的操作风险(如穿刺出血、感染等),医护人员将严格按照规范操作;<br />
|
||||
3. 病情可能因个体差异出现变化,需根据实际情况调整治疗方案;<br />
|
||||
4. 若患者存在隐瞒病史、不配合治疗等情况,可能影响治疗效果,相关风险由患者自行承担。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 签署确认模块 -->
|
||||
<div class="card-container">
|
||||
<div class="card-header">
|
||||
<span class="card-title">签署确认</span>
|
||||
</div>
|
||||
<div class="card-content grid-2col">
|
||||
<div class="info-item">
|
||||
<span class="info-label">患者或家属:</span>
|
||||
<span class="info-value">张三</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">与患者关系:</span>
|
||||
<span class="info-value">妻子</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">签字日期:</span>
|
||||
<span class="info-value">2025-02-14</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">沟通医师签字:</span>
|
||||
<span class="info-value">华佗</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">沟通日期:</span>
|
||||
<span class="info-value">2025-02-14</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* 全局卡片容器统一样式 */
|
||||
.card-container {
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
|
||||
margin-bottom: 20px;
|
||||
background: #fff;
|
||||
transition: box-shadow 0.3s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
/* 卡片hover效果 */
|
||||
.card-container:hover {
|
||||
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.08);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
/* 卡片头部样式 */
|
||||
.card-header {
|
||||
padding: 14px 20px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
background-color: #f5fafe;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 卡片标题样式 */
|
||||
.card-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
/* 卡片内容区统一样式 */
|
||||
.card-content {
|
||||
padding: 22px;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
/* 2列网格布局(桌面端) */
|
||||
.grid-2col {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
/* 信息项统一样式 */
|
||||
.info-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
/* 改为顶端对齐,适配多行文本 */
|
||||
padding: 9px 0;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
/* 信息标签样式 */
|
||||
.info-label {
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 110px;
|
||||
font-size: 15px;
|
||||
padding-top: 5px;
|
||||
/* 对齐多行文本的顶部 */
|
||||
}
|
||||
|
||||
/* 信息值样式(单行) */
|
||||
.info-value {
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
min-height: 28px;
|
||||
/* 确保单行和多行高度一致 */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 多行文本样式(适配长内容) */
|
||||
.info-value.multi-line {
|
||||
align-items: flex-start;
|
||||
padding: 10px 12px;
|
||||
line-height: 1.6;
|
||||
min-height: 80px;
|
||||
/* 最小高度,避免内容过少时显得空旷 */
|
||||
white-space: pre-line;
|
||||
/* 支持换行符和空格 */
|
||||
}
|
||||
|
||||
/* 全屏宽度信息项(如风险告知) */
|
||||
.info-item.full-width {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 信息值hover效果 */
|
||||
.info-value:hover {
|
||||
background: #f2f2f2;
|
||||
border-color: #e0e0e0;
|
||||
}
|
||||
|
||||
/* 响应式适配(移动端1列布局) */
|
||||
@media (max-width: 768px) {
|
||||
.grid-2col {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.card-content {
|
||||
padding: 16px;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
padding: 12px 16px;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
min-width: 90px;
|
||||
font-size: 14px;
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 14px;
|
||||
padding: 4px 10px;
|
||||
min-height: 24px;
|
||||
}
|
||||
|
||||
.info-value.multi-line {
|
||||
padding: 8px 10px;
|
||||
min-height: 60px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* 标题区域适配移动端 */
|
||||
div[style*="font-size: 28px"] {
|
||||
font-size: 24px !important;
|
||||
}
|
||||
|
||||
div[style*="font-size: 22px"] {
|
||||
font-size: 20px !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 打印样式优化 */
|
||||
@media print {
|
||||
body {
|
||||
print-color-adjust: exact;
|
||||
-webkit-print-color-adjust: exact;
|
||||
background: #fff !important;
|
||||
}
|
||||
|
||||
.card-container {
|
||||
box-shadow: none !important;
|
||||
border: 1px solid #ddd !important;
|
||||
margin-bottom: 15px !important;
|
||||
transform: none !important;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
background: #f8f8f8 !important;
|
||||
border-bottom: 1px solid #ddd !important;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
background: #fff !important;
|
||||
border: 1px dashed #eee !important;
|
||||
}
|
||||
|
||||
.card-container:hover {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script setup>
|
||||
|
||||
</script>
|
||||
@@ -0,0 +1,877 @@
|
||||
<template>
|
||||
<div style="padding: 20px; background: #f8f9fa; min-height: 100vh" ref="bodyRef">
|
||||
<!-- 标题区域 - 强化正式感 -->
|
||||
<div
|
||||
style="
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
padding: 20px;
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.03);
|
||||
"
|
||||
>
|
||||
<div style="font-size: 22px; color: #2d3748; letter-spacing: 1px">长春市朝阳区中医院</div>
|
||||
<div
|
||||
style="
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
margin: 12px 0;
|
||||
padding: 8px 0;
|
||||
border-bottom: 2px solid #e8f4f8;
|
||||
display: inline-block;
|
||||
"
|
||||
>
|
||||
患者与手术基础信息
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
font-size: 15px;
|
||||
color: #4a5568;
|
||||
"
|
||||
>
|
||||
<span style="font-weight: 500">住院号:</span>
|
||||
<span style="font-weight: 600; text-decoration: underline">{{ formData.busNo }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 基本信息模块(统一为card样式) -->
|
||||
<div
|
||||
style="
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
|
||||
margin-bottom: 20px;
|
||||
background: #fff;
|
||||
transition: box-shadow 0.3s ease, transform 0.2s ease;
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
padding: 14px 20px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
"
|
||||
>
|
||||
<span style="font-size: 18px; font-weight: 600; letter-spacing: 0.5px">基本信息</span>
|
||||
</div>
|
||||
<div style="padding: 22px; gap: 20px; display: grid; grid-template-columns: repeat(2, 1fr)">
|
||||
<div style="display: flex; align-items: center; padding: 9px 0">
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 100px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
"
|
||||
>姓名:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
"
|
||||
>{{ formData.patientName }}</span
|
||||
>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; padding: 9px 0">
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 100px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
"
|
||||
>性别:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
"
|
||||
>{{ formData.gender }}</span
|
||||
>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; padding: 9px 0">
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 100px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
"
|
||||
>年龄:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
"
|
||||
>{{ formData.age }}岁</span
|
||||
>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; padding: 9px 0">
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 100px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
"
|
||||
>科室:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
"
|
||||
>{{ formData.department }}</span
|
||||
>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; padding: 9px 0">
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 100px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
"
|
||||
>病房/床号:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
"
|
||||
>{{ formData.bedNo }}</span
|
||||
>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; padding: 9px 0">
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 100px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
"
|
||||
>手术日期:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
"
|
||||
>{{ formData.operationDateTime }}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 手术团队信息模块 -->
|
||||
<div
|
||||
style="
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
|
||||
margin-bottom: 20px;
|
||||
background: #fff;
|
||||
transition: box-shadow 0.3s ease, transform 0.2s ease;
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
padding: 14px 20px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
"
|
||||
>
|
||||
<span style="font-size: 18px; font-weight: 600; letter-spacing: 0.5px">手术团队信息</span>
|
||||
</div>
|
||||
<div style="padding: 22px; gap: 20px; display: grid; grid-template-columns: repeat(2, 1fr)">
|
||||
<div style="display: flex; align-items: center; padding: 9px 0">
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 100px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
"
|
||||
>手术者:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
"
|
||||
>{{ formData.surgeon }}</span
|
||||
>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; padding: 9px 0">
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 100px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
"
|
||||
>第一助手:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
"
|
||||
>{{ formData.firstAssistant }}</span
|
||||
>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; padding: 9px 0">
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 100px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
"
|
||||
>第二助手:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
"
|
||||
>{{ formData.secondAssistant }}</span
|
||||
>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; padding: 9px 0">
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 100px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
"
|
||||
>器械护士:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
"
|
||||
>{{ formData.scrubNurse }}</span
|
||||
>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; padding: 9px 0">
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 100px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
"
|
||||
>麻醉医师:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
"
|
||||
>{{ formData.anesthesiologist }}</span
|
||||
>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; padding: 9px 0">
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 100px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
"
|
||||
>巡逻护士:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
"
|
||||
>{{ formData.circulatingNurse }}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 手术详情模块 -->
|
||||
<div
|
||||
style="
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
|
||||
margin-bottom: 20px;
|
||||
background: #fff;
|
||||
transition: box-shadow 0.3s ease, transform 0.2s ease;
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
padding: 14px 20px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
"
|
||||
>
|
||||
<span style="font-size: 18px; font-weight: 600; letter-spacing: 0.5px">手术详情</span>
|
||||
</div>
|
||||
<div style="padding: 22px; gap: 20px; display: grid; grid-template-columns: repeat(2, 1fr)">
|
||||
<div style="display: flex; align-items: center; padding: 9px 0">
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 100px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
"
|
||||
>手术名称:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
"
|
||||
>{{ formData.operationName }}</span
|
||||
>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; padding: 9px 0">
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 100px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
"
|
||||
>手术方式:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
"
|
||||
>{{ formData.operationMethod }}</span
|
||||
>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; padding: 9px 0">
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 100px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
"
|
||||
>手术入路:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
"
|
||||
>{{ formData.surgicalApproach }}</span
|
||||
>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; padding: 9px 0">
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 100px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
"
|
||||
>术中发现:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
"
|
||||
>{{ formData.intraoperativeFindings }}</span
|
||||
>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; padding: 9px 0">
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 100px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
"
|
||||
>手术过程:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
"
|
||||
>{{ formData.operationProcess }}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 术后情况模块 -->
|
||||
<div
|
||||
style="
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
|
||||
margin-bottom: 20px;
|
||||
background: #fff;
|
||||
transition: box-shadow 0.3s ease, transform 0.2s ease;
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
padding: 14px 20px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
"
|
||||
>
|
||||
<span style="font-size: 18px; font-weight: 600; letter-spacing: 0.5px">术后情况</span>
|
||||
</div>
|
||||
<div style="padding: 22px; gap: 20px; display: grid; grid-template-columns: repeat(2, 1fr)">
|
||||
<div style="display: flex; align-items: center; padding: 9px 0">
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 100px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
"
|
||||
>术中出血量:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
"
|
||||
>{{ formData.bloodLoss }}ml</span
|
||||
>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; padding: 9px 0">
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 100px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
"
|
||||
>输血情况:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
"
|
||||
>{{ formData.bloodTransfusion }}</span
|
||||
>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; padding: 9px 0">
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 100px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
"
|
||||
>引流管放置:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
"
|
||||
>{{ formData.drainageTube }}</span
|
||||
>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; padding: 9px 0">
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 100px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
"
|
||||
>标本处理:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
"
|
||||
>{{ formData.specimenDisposal }}</span
|
||||
>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; padding: 9px 0">
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 100px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
"
|
||||
>手术结束时间:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
"
|
||||
>{{ formData.operationEndTime }}</span
|
||||
>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; padding: 9px 0">
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 100px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
"
|
||||
>患者去向:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
"
|
||||
>{{ formData.patientDestination }}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 签署确认模块 -->
|
||||
<div
|
||||
style="
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
|
||||
margin-bottom: 20px;
|
||||
background: #fff;
|
||||
transition: box-shadow 0.3s ease, transform 0.2s ease;
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
padding: 14px 20px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
"
|
||||
>
|
||||
<span style="font-size: 18px; font-weight: 600; letter-spacing: 0.5px">签署确认</span>
|
||||
</div>
|
||||
<div style="padding: 22px; gap: 20px; display: grid; grid-template-columns: repeat(2, 1fr)">
|
||||
<div style="display: flex; align-items: center; padding: 9px 0">
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 100px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
"
|
||||
>手术者签名:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
"
|
||||
>{{ formData.surgeonSignature }}</span
|
||||
>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; padding: 9px 0">
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 100px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
"
|
||||
>记录者签名:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
"
|
||||
>{{ formData.recorderSignature }}</span
|
||||
>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; padding: 9px 0">
|
||||
<span
|
||||
style="
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
min-width: 100px;
|
||||
font-size: 15px;
|
||||
margin-right: 10px;
|
||||
"
|
||||
>记录日期:</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
font-size: 15px;
|
||||
color: #222;
|
||||
padding: 5px 12px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
border: 1px solid #f0f0f0;
|
||||
transition: all 0.2s ease;
|
||||
"
|
||||
>{{ formData.recordDate }}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, defineExpose } from 'vue';
|
||||
const bodyRef = ref();
|
||||
// 响应式表单数据
|
||||
const formData = reactive({
|
||||
// 患者与手术基础信息
|
||||
busNo: '',
|
||||
patientName: '',
|
||||
gender: '',
|
||||
age: '',
|
||||
department: '',
|
||||
bedNo: '',
|
||||
operationDateTime: '', // 手术日期时间
|
||||
|
||||
// 手术团队信息
|
||||
surgeon: '', // 主刀医师
|
||||
firstAssistant: '', // 第一助手
|
||||
secondAssistant: '', // 第二助手
|
||||
anesthesiologist: '', // 麻醉医师
|
||||
circulatingNurse: '', // 巡回护士
|
||||
scrubNurse: '', // 器械护士
|
||||
|
||||
// 手术详情
|
||||
operationName: '', // 规范手术名称
|
||||
operationMethod: '', // 手术方式
|
||||
surgicalApproach: '', // 手术入路
|
||||
intraoperativeFindings: '', // 术中发现
|
||||
operationProcess: '', // 手术过程
|
||||
|
||||
// 术后情况
|
||||
bloodLoss: '', // 术中出血量
|
||||
bloodTransfusion: '', // 输血情况
|
||||
drainageTube: '', // 引流管放置
|
||||
specimenDisposal: '', // 标本处理
|
||||
operationEndTime: '', // 手术结束时间
|
||||
patientDestination: '', // 患者去向
|
||||
|
||||
// 签署信息
|
||||
surgeonSignature: '', // 手术者签名
|
||||
recorderSignature: '', // 记录者签名
|
||||
recordDate: '', // 记录日期
|
||||
});
|
||||
const getDom = () => {
|
||||
return bodyRef.value;
|
||||
};
|
||||
const setData = (data) => {
|
||||
console.log('设置数据=========>', JSON.stringify(data));
|
||||
Object.assign(formData, data);
|
||||
};
|
||||
defineExpose({
|
||||
setData,
|
||||
getDom,
|
||||
});
|
||||
</script>
|
||||
@@ -12,13 +12,13 @@
|
||||
<label>组织机构代码:</label>
|
||||
<el-input
|
||||
type="text"
|
||||
v-model="formData.hospitalInfo.orgCode"
|
||||
v-model="formData.hospitalInfo.medins_orgcode"
|
||||
placeholder="请填写组织机构代码"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<label>医疗付费方式:</label>
|
||||
<el-select placeholder="请选择" v-model="formData.hospitalInfo.medicalPaymentCode">
|
||||
<el-select placeholder="请选择" v-model="formData.hospitalInfo.medfee_paymtd_code">
|
||||
<el-option
|
||||
v-for="item in medicalSelectOptions"
|
||||
:key="item.id"
|
||||
@@ -60,6 +60,7 @@
|
||||
:label="item.label"
|
||||
></el-option>
|
||||
</el-select>
|
||||
<!-- <el-input v-model="formData.patientInfo.gend" placeholder="请输入"></el-input> -->
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<label>出生日期:</label>
|
||||
@@ -67,21 +68,11 @@
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<label>年龄:</label>
|
||||
<el-input
|
||||
type="number"
|
||||
max="120"
|
||||
min="0"
|
||||
v-model="formData.patientInfo.age"
|
||||
placeholder="请填写年龄"
|
||||
/>
|
||||
<el-input max="120" min="0" v-model="formData.patientInfo.age" placeholder="请填写年龄" />
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<label>国籍:</label>
|
||||
<el-input
|
||||
type="text"
|
||||
v-model="formData.patientInfo.nationality"
|
||||
placeholder="请填写国籍"
|
||||
/>
|
||||
<el-input type="text" v-model="formData.patientInfo.ntly" placeholder="请填写国籍" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -211,13 +202,13 @@
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<label>入院时间:</label>
|
||||
<el-input type="date" v-model="formData.admission.admitTime" />
|
||||
<el-input type="date" v-model="formData.admission.adm_time" />
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<label>入院科室:</label>
|
||||
<el-input
|
||||
type="text"
|
||||
v-model="formData.admission.adm_caty"
|
||||
v-model="formData.admission.adm_dept_name"
|
||||
placeholder="请填写入院科室"
|
||||
/>
|
||||
</div>
|
||||
@@ -252,7 +243,7 @@
|
||||
<label>实际住院天数:</label>
|
||||
<el-input
|
||||
type="number"
|
||||
v-model="formData.admission.ipt_days"
|
||||
v-model="formData.admission.act_ipt_days"
|
||||
placeholder="请填写实际住院天数"
|
||||
/>
|
||||
</div>
|
||||
@@ -262,26 +253,99 @@
|
||||
<!-- 诊断信息 -->
|
||||
<div class="section">
|
||||
<div class="section-title">诊断信息</div>
|
||||
<div class="form-row">
|
||||
<div class="form-item full-width">
|
||||
<label>主要诊断:</label>
|
||||
<el-input
|
||||
type="text"
|
||||
v-model="formData.diagnosis.mainDiagnosis"
|
||||
placeholder="腰椎间盘突出症(L4-5)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-item full-width">
|
||||
<label>其他诊断:</label>
|
||||
<el-input
|
||||
type="textarea"
|
||||
v-model="formData.diagnosis.otherDiagnosis"
|
||||
placeholder="腰椎管狭窄(L4-5)\n右下肢不全瘫"
|
||||
></el-input>
|
||||
</div>
|
||||
</div>
|
||||
<el-col :span="23" :xs="24">
|
||||
<el-form disabled :model="formData" :rules="rules" ref="formRef">
|
||||
<el-table ref="diagnosisTableRef" :data="formData?.diagnosisList" width="100px">
|
||||
<el-table-column label="序号" type="index" width="50" />
|
||||
<el-table-column label="诊断排序" align="center" prop="diagSrtNo">
|
||||
<template #default="scope">
|
||||
<el-input-number
|
||||
v-model="scope.row.diagSrtNo"
|
||||
controls-position="right"
|
||||
:controls="false"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="诊断类别" align="center" prop="diagSrtNo">
|
||||
<template #default="scope">
|
||||
<el-form-item
|
||||
:prop="`diagnosisList.${scope.$index}.medTypeCode`"
|
||||
:rules="rules.medTypeCode"
|
||||
>
|
||||
<el-select
|
||||
v-model="scope.row.medTypeCode"
|
||||
placeholder=" "
|
||||
style="margin-top: 15px"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in med_type"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="诊断名称" align="center" prop="name">
|
||||
<template #default="scope">
|
||||
<el-form-item :prop="`diagnosisList.${scope.$index}.name`" :rules="rules.name">
|
||||
<el-popover
|
||||
:popper-style="{ padding: '0' }"
|
||||
placement="bottom-start"
|
||||
:visible="scope.row.showPopover"
|
||||
trigger="manual"
|
||||
>
|
||||
<diagnosislist
|
||||
:diagnosisSearchkey="diagnosisSearchkey"
|
||||
@selectDiagnosis="handleSelsectDiagnosis"
|
||||
/>
|
||||
<template #reference>
|
||||
<el-input
|
||||
v-model="scope.row.name"
|
||||
placeholder="请选择诊断"
|
||||
@input="handleChange"
|
||||
@focus="handleFocus(scope.row, scope.$index)"
|
||||
@blur="handleBlur(scope.row)"
|
||||
style="margin-top: 15px"
|
||||
/>
|
||||
</template>
|
||||
</el-popover>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="医保码" align="center" prop="ybNo" />
|
||||
<el-table-column label="诊断类型" align="center" prop="maindiseFlag">
|
||||
<template #default="scope">
|
||||
<div style="display: flex">
|
||||
<el-checkbox
|
||||
label="主诊断"
|
||||
:trueLabel="1"
|
||||
:falseLabel="0"
|
||||
v-model="scope.row.maindiseFlag"
|
||||
border
|
||||
size="small"
|
||||
@change="(value) => handleMaindise(value, scope.$index)"
|
||||
/>
|
||||
<el-select
|
||||
v-model="scope.row.verificationStatusEnum"
|
||||
placeholder=" "
|
||||
style="padding-bottom: 5px; padding-left: 10px"
|
||||
size="small"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in diagnosisOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-form>
|
||||
</el-col>
|
||||
</div>
|
||||
|
||||
<!-- 医疗信息 -->
|
||||
@@ -433,11 +497,14 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, watch } from 'vue';
|
||||
import { reactive, watch, ref } from 'vue';
|
||||
import formDataJs from '../../doctorstation/components/store/medicalpage';
|
||||
import { patientInfo } from '../../inpatientDoctor/home/store/patient';
|
||||
import diagnosislist from '../../inpatientDoctor/home/components/diagnosis/diagnosislist.vue';
|
||||
import { diagnosisInit } from '../../doctorstation/components/api';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { med_type } = proxy.useDict('med_type');
|
||||
const {
|
||||
medfee_paymtd_code,
|
||||
blotype_abo,
|
||||
@@ -461,9 +528,13 @@ const {
|
||||
'naty',
|
||||
'patn_rlts'
|
||||
);
|
||||
const formRef = ref();
|
||||
const diagnosisTableRef = ref();
|
||||
// 诊断类型下拉选
|
||||
const diagnosisOptions = ref([]);
|
||||
const userStore = useUserStore();
|
||||
const fixmedinsCode = userStore.fixmedinsCode;
|
||||
formDataJs.hospitalInfo.orgCode = fixmedinsCode;
|
||||
formDataJs.hospitalInfo.medins_orgcode = fixmedinsCode;
|
||||
// 医疗付费方式
|
||||
const medicalSelectOptions = medfee_paymtd_code;
|
||||
// 性别
|
||||
@@ -490,23 +561,48 @@ const formData = reactive(formDataJs);
|
||||
defineExpose({
|
||||
formData,
|
||||
});
|
||||
// 映射性别
|
||||
const mapSex = (data = '') => {
|
||||
let code = '0';
|
||||
if (data.indexOf('男') !== -1) {
|
||||
code = '1';
|
||||
}
|
||||
if (data.indexOf('女') !== -1) {
|
||||
code = '2';
|
||||
}
|
||||
return code;
|
||||
};
|
||||
watch(
|
||||
patientInfo,
|
||||
(newValue) => {
|
||||
if (newValue) {
|
||||
console.log('21321212132321=====>', newValue.age);
|
||||
|
||||
const birthDate = newValue.birthDate.split(' ');
|
||||
formData.patientInfo.patientName = newValue.patientName ?? '';
|
||||
formData.patientInfo.healthCardNo = newValue.busNo ?? '';
|
||||
// formData.patientInfo.gender = newValue.genderEnum ?? '';
|
||||
formData.patientInfo.gend = mapSex(newValue.genderEnum_enumText) ?? '';
|
||||
formData.patientInfo.brdy = birthDate.length > 0 ? birthDate[0] : '';
|
||||
formData.patientInfo.age = newValue.age ?? '';
|
||||
formData.admission.patn_ipt_cnt = newValue.inHospitalDays ?? '';
|
||||
formData.admission.dscg_ward = newValue.houseName ?? '';
|
||||
formData.admission.adm_ward = newValue.houseName ?? '';
|
||||
formData.admission.ipt_no = newValue.contractNo ?? '';
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
init();
|
||||
function init() {
|
||||
diagnosisInit().then((res) => {
|
||||
if (res.code == 200) {
|
||||
diagnosisOptions.value = res.data.verificationStatusOptions;
|
||||
}
|
||||
});
|
||||
}
|
||||
const rules = ref({
|
||||
name: [{ required: true, message: '请选择诊断', trigger: 'change' }],
|
||||
medTypeCode: [{ required: true, message: '请选择诊断类型', trigger: 'change' }],
|
||||
diagSrtNo: [{ required: true, message: '请输入诊断序号', trigger: 'change' }],
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -158,7 +158,10 @@
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<label>目的:</label>
|
||||
<el-input v-model="formData.medicalSecond.purpose" placeholder="请填写目的"></el-input>
|
||||
<el-input
|
||||
v-model="formData.medicalSecond.dscg_31days_rinp_pup"
|
||||
placeholder="请填写目的"
|
||||
></el-input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
@@ -223,21 +226,30 @@
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<label>分化程度:</label>
|
||||
<el-input type="date" v-model="formData.medicalSecond.degreeDifferentiation" />
|
||||
<!-- <el-input type="date" v-model="formData.medicalSecond.bkup_deg" /> -->
|
||||
<el-select v-model="formData.medicalSecond.bkup_deg_code" placeholder="请选择分化程度">
|
||||
<el-option
|
||||
v-for="item in bkup_deg_codeOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-item">
|
||||
<label>临床路径-进入路径:</label>
|
||||
<el-select v-model="formData.medicalSecond.enterPath">
|
||||
<!-- <el-select v-model="formData.medicalSecond.enterPath">
|
||||
<el-option
|
||||
v-for="item in enterPathOptions"
|
||||
:key="item.id"
|
||||
:value="item.value"
|
||||
:label="item.label"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-select> -->
|
||||
<el-input v-model="formData.medicalSecond.enterPath" placeholder="请输入"></el-input>
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<label>变异:</label>
|
||||
@@ -254,14 +266,15 @@
|
||||
<div class="form-row">
|
||||
<div class="form-item">
|
||||
<label>退出路径:</label>
|
||||
<el-select v-model="formData.medicalSecond.outPath">
|
||||
<!-- <el-select v-model="formData.medicalSecond.outPath">
|
||||
<el-option
|
||||
v-for="item in outPathOptions"
|
||||
:key="item.id"
|
||||
:value="item.value"
|
||||
:label="item.label"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-select> -->
|
||||
<el-input v-model="formData.medicalSecond.outPath" placeholder="请输入"></el-input>
|
||||
</div>
|
||||
<div class="form-item"></div>
|
||||
</div>
|
||||
@@ -311,7 +324,7 @@
|
||||
<div class="form-row">
|
||||
<div class="form-item">
|
||||
<label>呼吸机使用:</label>
|
||||
<el-select v-model="formData.medicalSecond.ventilatorUse">
|
||||
<el-select v-model="formData.medicalSecond.use_vent_flag">
|
||||
<el-option
|
||||
v-for="item in ventilatorUseOptions"
|
||||
:key="item.id"
|
||||
@@ -356,6 +369,7 @@ const {
|
||||
sys_yes_no,
|
||||
sys_exit_path,
|
||||
oprn_patn_type_code,
|
||||
bkup_deg_code,
|
||||
} = proxy.useDict(
|
||||
'dscg_way',
|
||||
'days_rinp_flag_31',
|
||||
@@ -369,7 +383,8 @@ const {
|
||||
'sys_entry_path',
|
||||
'sys_yes_no',
|
||||
'sys_exit_path',
|
||||
'oprn_patn_type_code'
|
||||
'oprn_patn_type_code',
|
||||
'bkup_deg_code'
|
||||
);
|
||||
|
||||
// 手术类型
|
||||
@@ -398,6 +413,8 @@ const cutLevelOptions = sinc_heal_lv_code;
|
||||
const anesthesiaTypeOptions = anst_mtd_code;
|
||||
// 麻醉分级
|
||||
const anesthesiaLevelOptions = anst_lv_code;
|
||||
// 分化程度
|
||||
const bkup_deg_codeOptions = bkup_deg_code;
|
||||
watch(
|
||||
() => formData.medicalSecond.surgery_tableData,
|
||||
(newValue) => {
|
||||
|
||||
@@ -153,7 +153,7 @@ function viewPatient(patient) {
|
||||
console.log('View patient:', patient);
|
||||
selectedPatient.value = patient; // 选中患者
|
||||
emits('patientSelected', selectedPatient.value); // 发送选中的患者数据
|
||||
emits('triggerSearch', patient.busNo);// 触发预交金查询事件
|
||||
emits('triggerSearch', patient.busNo); // 触发预交金查询事件
|
||||
drawerVisible.value = false;
|
||||
reset(); // 重置筛选条件
|
||||
// 可以在这里做一些操作,比如高亮行,或者如果“查看”是选择并关闭,则触发confirm
|
||||
@@ -185,18 +185,20 @@ function show() {
|
||||
console.log('show', props);
|
||||
wardListOptions.value = props.wardListOptions;
|
||||
drawerVisible.value = props.drawerVisible;
|
||||
getWardList().then((res) => {
|
||||
if (res.length > 0) {
|
||||
wardListOptions.value = res.map(ward => ({
|
||||
label: ward.name,
|
||||
value: ward.id
|
||||
}));
|
||||
}
|
||||
getList();
|
||||
}).catch((error) => {
|
||||
console.error('获取病区列表失败:', error);
|
||||
getList();
|
||||
});
|
||||
getWardList()
|
||||
.then((res) => {
|
||||
if (res.length > 0) {
|
||||
wardListOptions.value = res.map((ward) => ({
|
||||
label: ward.name,
|
||||
value: ward.id,
|
||||
}));
|
||||
}
|
||||
getList();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('获取病区列表失败:', error);
|
||||
getList();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -205,7 +207,7 @@ function show() {
|
||||
function getList() {
|
||||
console.log('queryParams', queryParams.value);
|
||||
getDepositInfo(queryParams.value).then((res) => {
|
||||
patientData.value = res.data.records;
|
||||
patientData.value = res.data?.records || [];
|
||||
total.value = res.data.total;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -31,6 +31,11 @@
|
||||
<template v-for="(item, index) in formData.selfPay" :key="index">
|
||||
<div v-show="item.payEnum != 220500" class="payment-item">
|
||||
<span>支付方式:</span>
|
||||
<img
|
||||
v-if="item.payEnum == 220100 || item.payEnum == 220200"
|
||||
:src="imgs[item.payEnum == 220100 ? 0 : 1]"
|
||||
style="width: 20px; height: 20px"
|
||||
/>
|
||||
<el-select
|
||||
v-model="item.payEnum"
|
||||
placeholder="选择支付方式"
|
||||
@@ -163,7 +168,9 @@ import useUserStore from '@/store/modules/user';
|
||||
import { hiprint } from 'vue-plugin-hiprint';
|
||||
import templateJson from './template.json';
|
||||
import { pa } from 'element-plus/es/locales.mjs';
|
||||
|
||||
import image1 from '../../../../../assets/images/weixinzhifu.png';
|
||||
import image2 from '../../../../../assets/images/zhifubaozhifu.png';
|
||||
const imgs = ref([image1, image2]);
|
||||
const props = defineProps({
|
||||
open: {
|
||||
type: Boolean,
|
||||
@@ -206,6 +213,14 @@ const props = defineProps({
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
newId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
oldId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
@@ -216,7 +231,6 @@ const userStore = useUserStore();
|
||||
const discountRadio = ref();
|
||||
const discountAmount = ref(0);
|
||||
const txtCode = ref('');
|
||||
|
||||
const formData = reactive({
|
||||
totalAmount: 0,
|
||||
selfPay: [{ payEnum: 220100, amount: 0.0, payLevelEnum: 2 }],
|
||||
@@ -398,6 +412,7 @@ async function submit() {
|
||||
return;
|
||||
}
|
||||
dialogLoading.value = true;
|
||||
console.log(props.newId, props.oldId);
|
||||
savePayment({
|
||||
chargeItemIds: props.chargeItemIds,
|
||||
encounterId: props.patientInfo.encounterId,
|
||||
@@ -405,6 +420,8 @@ async function submit() {
|
||||
paymentDetails: formData.selfPay,
|
||||
ybMdtrtCertType: props.userCardInfo.psnCertType,
|
||||
busiCardInfo: props.userCardInfo.busiCardInfo,
|
||||
newId: props.newId,
|
||||
oldId: props.oldId,
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.code == 200) {
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
@cell-click="clickRow"
|
||||
highlight-current-row
|
||||
>
|
||||
<el-table-column label="住院号" align="center" prop="patientBusNo" />
|
||||
<el-table-column label="住院号" align="center" prop="encounterBusNo" />
|
||||
<!-- <el-table-column label="床号" align="center" prop="bedNo" /> -->
|
||||
<el-table-column label="姓名" align="center" prop="patientName" />
|
||||
<el-table-column label="账户余额" align="center" prop="balanceAmount" />
|
||||
@@ -86,15 +86,30 @@
|
||||
<!-- <el-descriptions-item label="科室:">
|
||||
{{ patientInfo.organizationName }}
|
||||
</el-descriptions-item> -->
|
||||
<el-descriptions-item label="床号:">
|
||||
<!-- <el-descriptions-item label="床号:">
|
||||
{{ patientInfo.bedNo }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="就诊时间:">
|
||||
{{ formatDateStr(patientInfo.receptionTime, 'YYYY-MM-DD HH:mm:ss') }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions-item> -->
|
||||
</el-descriptions>
|
||||
</el-card>
|
||||
<el-card style="min-width: 1100px">
|
||||
<el-card>
|
||||
<el-date-picker
|
||||
v-model="costSearchTime"
|
||||
type="daterange"
|
||||
range-separator="~"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
placement="bottom"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 40%; margin-bottom: 10px; margin-right: 10px"
|
||||
@change="getPatientList"
|
||||
/>
|
||||
<el-button type="primary" style="margin-bottom: 10px" @click="costSearch"> 搜索 </el-button>
|
||||
</el-card>
|
||||
|
||||
<el-card style="min-width: 1100px; margin-top: 20px">
|
||||
<template #header>
|
||||
<span style="vertical-align: middle">收费项目</span>
|
||||
</template>
|
||||
@@ -156,7 +171,7 @@
|
||||
<el-table
|
||||
ref="chargeListRef"
|
||||
height="530"
|
||||
:data="chargeList"
|
||||
:data="chargeFilterList"
|
||||
row-key="id"
|
||||
@selection-change="handleSelectionChange"
|
||||
v-loading="chargeLoading"
|
||||
@@ -174,17 +189,14 @@
|
||||
<el-table-column label="费用性质" align="center" prop="contractName" />
|
||||
<el-table-column label="结算状态" align="center" prop="statusEnum_enumText" width="150">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.encounterStatus === 1" disable-transitions>
|
||||
<!-- 1代收费 2代结算 5已收费 8已退费 -->
|
||||
<el-tag v-if="scope.row.statusEnum === 1" disable-transitions>
|
||||
{{ scope.row.statusEnum_enumText }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-else-if="scope.row.encounterStatus === 5"
|
||||
type="success"
|
||||
disable-transitions
|
||||
>
|
||||
<el-tag v-else-if="scope.row.statusEnum === 5" type="success" disable-transitions>
|
||||
{{ scope.row.statusEnum_enumText }}
|
||||
</el-tag>
|
||||
<el-tag v-else-if="scope.row.encounterStatus === 8" type="danger" disable-transitions>
|
||||
<el-tag v-else-if="scope.row.statusEnum === 8" type="danger" disable-transitions>
|
||||
{{ scope.row.statusEnum_enumText }}
|
||||
</el-tag>
|
||||
<el-tag v-else type="warning" disable-transitions>
|
||||
@@ -231,7 +243,8 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="折扣率" align="right" prop="discountRate" header-align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row.discountRate.toFixed(2) + '%' || '0.00' + '%' }}
|
||||
<!-- discountRate是一个字符串类型的 -->
|
||||
{{ Number(scope.row.discountRate).toFixed(2) + '%' || '0.00' + '%' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
@@ -270,6 +283,8 @@
|
||||
:details="details"
|
||||
:chargedItems="chargedItems"
|
||||
@refresh="getPatientList"
|
||||
:newId="newId"
|
||||
:oldId="oldId"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -286,11 +301,13 @@ import {
|
||||
changeStudentPayTosStudentSelf,
|
||||
changeStudentSelfToStudentPay,
|
||||
} from './components/api';
|
||||
import { invokeYbPlugin } from '@/api/public';
|
||||
import { invokeYbPlugin5001 } from '@/api/public';
|
||||
import ChargeDialog from './components/chargeDialog.vue';
|
||||
import { formatDateStr } from '@/utils';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import Decimal from 'decimal.js';
|
||||
import moment from 'moment';
|
||||
import { onMounted } from 'vue';
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const userStore = useUserStore();
|
||||
@@ -302,12 +319,17 @@ const queryParams = ref({
|
||||
const totalAmounts = ref(0);
|
||||
const selectedRows = ref([]);
|
||||
const patientList = ref([]);
|
||||
// 收费项目列表
|
||||
const chargeList = ref([]);
|
||||
// 根据时间过滤的收费项目列表
|
||||
const chargeFilterList = ref([]);
|
||||
const chargeItemIdList = ref([]);
|
||||
const chrgBchnoList = ref([]);
|
||||
const chargeLoading = ref(false);
|
||||
const encounterId = ref('');
|
||||
const paymentId = ref('');
|
||||
const newId = ref('');
|
||||
const oldId = ref('');
|
||||
const patientInfo = ref({});
|
||||
const openDialog = ref(false);
|
||||
const totalAmount = ref(0);
|
||||
@@ -318,6 +340,40 @@ const receptionTime = ref([
|
||||
formatDateStr(new Date(), 'YYYY-MM-DD'),
|
||||
formatDateStr(new Date(), 'YYYY-MM-DD'),
|
||||
]);
|
||||
// 计算当前时间+6天
|
||||
const accumulateDay = () => {
|
||||
// 获取当前时间
|
||||
let now = moment();
|
||||
// 在当前时间上加一天
|
||||
let tomorrow = now.add(6, 'days');
|
||||
// 格式化为年-月-日的格式
|
||||
let formattedDate = tomorrow.format('YYYY-MM-DD');
|
||||
return formattedDate;
|
||||
};
|
||||
// 收费项目时间段搜索
|
||||
const costSearchTime = ref([formatDateStr(new Date(), 'YYYY-MM-DD'), accumulateDay()]);
|
||||
// 测试数据
|
||||
const items = [
|
||||
{ id: 1, name: 'Item 1', date: '2025-12-15' },
|
||||
{ id: 2, name: 'Item 2', date: '2025-12-18' },
|
||||
{ id: 3, name: 'Item 3', date: '2025-12-20' },
|
||||
];
|
||||
// 根据时间短搜索
|
||||
const costSearch = () => {
|
||||
console.log(costSearchTime.value === null);
|
||||
|
||||
if (costSearchTime.value === null) {
|
||||
chargeFilterList.value = chargeList.value;
|
||||
} else {
|
||||
const startTime = moment(costSearchTime.value[0], 'YYYY-MM-DD');
|
||||
const endTime = moment(costSearchTime.value[1], 'YYYY-MM-DD');
|
||||
const filterData = chargeList.value.filter((item) => {
|
||||
const itemDate = moment(item.billDate || '', 'YYYY-MM-DD'); // 将数据项的日期也格式化为moment对象
|
||||
return itemDate.isBetween(startTime, endTime, null, '[]'); // 使用isBetween方法进行范围判断,'[]'表示包含边界值
|
||||
});
|
||||
chargeFilterList.value = filterData;
|
||||
}
|
||||
};
|
||||
const buttonDisabled = computed(() => {
|
||||
return Object.keys(patientInfo.value).length === 0;
|
||||
});
|
||||
@@ -339,9 +395,7 @@ watch(
|
||||
() => chargeList.value,
|
||||
(newVlaue) => {
|
||||
if (newVlaue && newVlaue.length > 0) {
|
||||
handleTotalAmount();
|
||||
} else {
|
||||
totalAmounts.value = 0;
|
||||
chargeFilterList.value = newVlaue;
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
@@ -350,15 +404,9 @@ function handleSelectionChange(selection) {
|
||||
selectedRows.value = selection;
|
||||
}
|
||||
function handleTotalAmount() {
|
||||
if (selectedRows.value.length == 0) {
|
||||
totalAmounts.value = chargeList.value.reduce((accumulator, currentRow) => {
|
||||
return new Decimal(accumulator).add(currentRow.totalPrice.toFixed(2) || 0);
|
||||
}, new Decimal(0));
|
||||
} else {
|
||||
totalAmounts.value = selectedRows.value.reduce((accumulator, currentRow) => {
|
||||
return new Decimal(accumulator).add(currentRow.totalPrice.toFixed(2) || 0);
|
||||
}, 0);
|
||||
}
|
||||
totalAmounts.value = selectedRows.value.reduce((accumulator, currentRow) => {
|
||||
return new Decimal(accumulator).add(currentRow.totalPrice.toFixed(2) || 0);
|
||||
}, 0);
|
||||
}
|
||||
getPatientList();
|
||||
initOption();
|
||||
@@ -375,7 +423,7 @@ function getPatientList() {
|
||||
}
|
||||
getList1(queryParams.value).then((res) => {
|
||||
console.log('患者列表', res);
|
||||
patientList.value = res.data.data.records;
|
||||
patientList.value = res.data.records;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -389,7 +437,7 @@ function initOption() {
|
||||
|
||||
function checkSelectable(row, index) {
|
||||
// 已结算时禁用选择框
|
||||
return row.encounterStatus === 1;
|
||||
return row.statusEnum == 1 || row.statusEnum == 2;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -433,6 +481,7 @@ function confirmCharge() {
|
||||
chargeItemIdList.value = selectRows.map((item) => {
|
||||
return item.id;
|
||||
});
|
||||
//wor_device_request 器材
|
||||
consumablesIdList.value = selectRows
|
||||
.filter((item) => {
|
||||
return item.serviceTable == 'wor_device_request';
|
||||
@@ -451,11 +500,15 @@ function confirmCharge() {
|
||||
chargeItemIds: chargeItemIdList.value,
|
||||
}).then((res) => {
|
||||
if (res.code == 200) {
|
||||
// totalAmount.value = res.data.psnCashPay;
|
||||
paymentId.value = res.data.paymentId;
|
||||
const item = res.data.paymentRecDetailDtoList.find((i) => {
|
||||
return i.payEnum == 220000;
|
||||
});
|
||||
totalAmount.value = item?.amount;
|
||||
paymentId.value = res.data.id;
|
||||
newId.value = res.data.newId;
|
||||
oldId.value = res.data.oldId;
|
||||
chrgBchnoList.value = res.data.chrgBchnoList;
|
||||
totalAmount.value = res.data.details.find((item) => item.payEnum == 220000).amount;
|
||||
details.value = res.data.details.filter((item) => {
|
||||
details.value = res.data.paymentRecDetailDtoList?.filter((item) => {
|
||||
return item.amount > 0;
|
||||
});
|
||||
openDialog.value = true;
|
||||
@@ -491,7 +544,7 @@ async function handleReadCard(value) {
|
||||
switch (value) {
|
||||
case '01': // 电子凭证
|
||||
// readCardLoading.value = true;
|
||||
await invokeYbPlugin({
|
||||
await invokeYbPlugin5001({
|
||||
FunctionId: 3,
|
||||
url: 'http://10.47.0.67:8089/localcfc/api/hsecfc/localQrCodeQuery',
|
||||
orgId: 'H22010200672',
|
||||
@@ -533,7 +586,7 @@ async function handleReadCard(value) {
|
||||
case '03': // 社保卡
|
||||
readCardLoading.value = true;
|
||||
loadingText.value = '正在读取...';
|
||||
await invokeYbPlugin(
|
||||
await invokeYbPlugin5001(
|
||||
JSON.stringify({
|
||||
FunctionId: 1,
|
||||
IP: 'ddjk.jlhs.gov.cn',
|
||||
@@ -605,16 +658,19 @@ async function handleReadCard(value) {
|
||||
busiCardInfo: userCardInfo.busiCardInfo,
|
||||
}).then((res) => {
|
||||
if (res.code == 200) {
|
||||
// totalAmount.value = res.data.psnCashPay;
|
||||
paymentId.value = res.data.paymentId;
|
||||
totalAmount.value = res.data.details.find((item) => item.payEnum == 220000).amount;
|
||||
details.value = res.data.details;
|
||||
paymentId.value = res.data.id;
|
||||
totalAmount.value = res.data.paymentRecDetailDtoList.find(
|
||||
(item) => item.payEnum == 220000
|
||||
).amount;
|
||||
details.value = res.data.paymentRecDetailDtoList;
|
||||
// chrgBchnoList.value = res.data.chrgBchnoList;
|
||||
chargeItemIdList.value = selectRows.map((item) => {
|
||||
return item.id;
|
||||
});
|
||||
// 打印项目赋值
|
||||
chargedItems.value = selectRows;
|
||||
newId.value = res.data.newId;
|
||||
oldId.value = res.data.oldId;
|
||||
consumablesIdList.value = selectRows
|
||||
.filter((item) => {
|
||||
return item.serviceTable == 'wor_device_request';
|
||||
@@ -622,6 +678,7 @@ async function handleReadCard(value) {
|
||||
.map((item) => {
|
||||
return item.id;
|
||||
});
|
||||
|
||||
openDialog.value = true;
|
||||
} else {
|
||||
proxy.$modal.msgError(res.msg);
|
||||
|
||||
@@ -23,8 +23,14 @@
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="入院日期" prop="admissionDate">
|
||||
<el-date-picker v-model="formData.admissionDate" type="date" format="yyyy-MM-dd" value-format="yyyy-MM-dd"
|
||||
style="width: 100%" placeholder="请选择日期" />
|
||||
<el-date-picker
|
||||
v-model="formData.admissionDate"
|
||||
type="date"
|
||||
format="yyyy-MM-dd"
|
||||
value-format="yyyy-MM-dd"
|
||||
style="width: 100%"
|
||||
placeholder="请选择日期"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -46,7 +52,12 @@
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="重复住院">
|
||||
<el-switch inline-prompt v-model="formData.isRepeatHospitalization" active-text="是" inactive-text="否" />
|
||||
<el-switch
|
||||
inline-prompt
|
||||
v-model="formData.isRepeatHospitalization"
|
||||
active-text="是"
|
||||
inactive-text="否"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
@@ -75,7 +86,12 @@
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="急诊标志">
|
||||
<el-switch inline-prompt v-model="formData.isEmergency" active-text="是" inactive-text="否" />
|
||||
<el-switch
|
||||
inline-prompt
|
||||
v-model="formData.isEmergency"
|
||||
active-text="是"
|
||||
inactive-text="否"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
@@ -97,9 +113,11 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup >
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'YbregisterEdit',
|
||||
});
|
||||
// interface FormData {
|
||||
// medicalType: string;
|
||||
// diseaseName: string;
|
||||
@@ -141,7 +159,6 @@ import { ref } from 'vue';
|
||||
|
||||
const handleSubmit = () => {
|
||||
// 处理表单提交
|
||||
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -79,9 +79,12 @@
|
||||
@cancelAct="cancelAct"
|
||||
/>
|
||||
</template>
|
||||
<script setup >
|
||||
<script setup>
|
||||
import PatientRegister from './patientRegister.vue';
|
||||
import { getAdmissionPage, getPatientBasicInfo, getInHospitalInfo } from './api';
|
||||
import { getContractList } from './api';
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { admit_source_code } = proxy.useDict('admit_source_code');
|
||||
//const { proxy } = getCurrentInstance();
|
||||
const emits = defineEmits([]);
|
||||
// const props = defineProps({});
|
||||
@@ -105,6 +108,7 @@ const patientRegisterVisible = ref(false);
|
||||
const noFile = ref(false);
|
||||
const registrationType = ref(true);
|
||||
const patient = ref({});
|
||||
const priceTypeList = ref({});
|
||||
const doEdit = (row) => {
|
||||
getPatientBasicInfo(row.patientId).then((res) => {
|
||||
patient.value = res.data;
|
||||
@@ -116,6 +120,7 @@ const doEdit = (row) => {
|
||||
});
|
||||
};
|
||||
onBeforeMount(() => {});
|
||||
getContract();
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
@@ -149,9 +154,47 @@ function resetQuery() {
|
||||
getList();
|
||||
}
|
||||
|
||||
// 入院登记
|
||||
const mapHospitalization = (admitSourceCode = '') => {
|
||||
console.log('admit_source_code=======>', admitSourceCode);
|
||||
const findObj = admit_source_code.value.find((item) => {
|
||||
return item.value == admitSourceCode;
|
||||
});
|
||||
return findObj?.label;
|
||||
};
|
||||
/** 查询费用性质 */
|
||||
function getContract() {
|
||||
getContractList().then((response) => {
|
||||
priceTypeList.value = response.data;
|
||||
});
|
||||
}
|
||||
// 映射费用性质
|
||||
const priceTypeDic = (contractNo) => {
|
||||
const findObj = priceTypeList.value.find((item) => {
|
||||
return item.busNo == contractNo;
|
||||
});
|
||||
return findObj?.contractName;
|
||||
};
|
||||
|
||||
const getList = () => {
|
||||
getAdmissionPage(queryParams.value).then((res) => {
|
||||
treatHospitalizedData.value = res.data.records;
|
||||
console.log('priceTypeList=======>', JSON.stringify(priceTypeList.value));
|
||||
let dataList = [];
|
||||
for (let index = 0; index < (res.data.records || []).length; index++) {
|
||||
const obj = (res.data.records || [])[index];
|
||||
const newObj = {
|
||||
...obj,
|
||||
};
|
||||
newObj.admitSourceCode = mapHospitalization(obj.admitSourceCode);
|
||||
dataList.push(newObj);
|
||||
}
|
||||
for (let index = 0; index < dataList.length; index++) {
|
||||
const obj = dataList[index];
|
||||
obj.contractNo = priceTypeDic(obj.contractNo);
|
||||
}
|
||||
|
||||
treatHospitalizedData.value = dataList;
|
||||
// treatHospitalizedData.value = res.data.records;
|
||||
total.value = res.data.total;
|
||||
});
|
||||
};
|
||||
|
||||
@@ -124,10 +124,12 @@ const patientYbRegisterVisible = ref(false);
|
||||
const patientRegisterOK = () => {
|
||||
patientRegisterVisible.value = false;
|
||||
queryParams.value.searchKey = '';
|
||||
getList();
|
||||
emits('okList');
|
||||
};
|
||||
|
||||
const cancelAct = () => {
|
||||
getList();
|
||||
patientRegisterVisible.value = false;
|
||||
};
|
||||
|
||||
|
||||
@@ -166,7 +166,7 @@
|
||||
import { ref, reactive, watch, onMounted } from 'vue';
|
||||
import PatientInfoForm from './patientInfoForm.vue';
|
||||
import { patientlLists, getOrgList, gerPreInfo } from './api';
|
||||
import { invokeYbPlugin } from '@/api/public';
|
||||
import { invokeYbPlugin5001 } from '@/api/public';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
@@ -212,7 +212,7 @@ const props = defineProps({
|
||||
required: false,
|
||||
},
|
||||
});
|
||||
const emits = defineEmits(['onChangFeeType']);
|
||||
const emits = defineEmits(['onChangFeeType', 'carReading']);
|
||||
const registerRef = ref();
|
||||
const typeCode = ref('01');
|
||||
const organization = ref([]);
|
||||
@@ -282,9 +282,6 @@ const getDictLabel = (dictList, value) => {
|
||||
return item ? item.label : value;
|
||||
};
|
||||
async function handleReadCard(value) {
|
||||
// if (window.CefSharp === undefined) {
|
||||
// alert('请在医保版本中调用读卡功能!');
|
||||
// } else {
|
||||
try {
|
||||
// await CefSharp.BindObjectAsync('boundAsync');
|
||||
// string url,
|
||||
@@ -312,7 +309,7 @@ async function handleReadCard(value) {
|
||||
// .getInfoByQrCodeAsync(
|
||||
|
||||
// )
|
||||
await invokeYbPlugin({
|
||||
await invokeYbPlugin5001({
|
||||
FunctionId: 3,
|
||||
url: 'http://10.47.0.67:8089/localcfc/api/hsecfc/localQrCodeQuery',
|
||||
orgId: 'H22010200672',
|
||||
@@ -327,38 +324,41 @@ async function handleReadCard(value) {
|
||||
loadingText.value = '正在读取...';
|
||||
console.log(res);
|
||||
jsonResult = res.data;
|
||||
|
||||
cardInfo = JSON.parse(JSON.stringify(jsonResult));
|
||||
let message = JSON.parse(cardInfo.message);
|
||||
console.log('patientInfo中的encounterId:', props.patientInfo);
|
||||
const encounterId = props.inHospitalInfo.encounterId || '1993854019030441985';
|
||||
console.log('1111111111111111111准备使用的encounterId:', encounterId);
|
||||
|
||||
userMessage = {
|
||||
certType: '02', // 证件类型
|
||||
certNo: message.data.idNo, // 身份证号
|
||||
psnCertType: '02', // 居民身份证
|
||||
encounterId: encounterId || '1993854019030441985',
|
||||
};
|
||||
userCardInfo = {
|
||||
certType: '01', // 证件类型
|
||||
certNo: message.data.idNo, // 身份证号
|
||||
psnCertType: '01', // 居民身份证
|
||||
busiCardInfo: message.data.ecToken, // 令牌
|
||||
encounterId: encounterId || '1993854019030441985',
|
||||
};
|
||||
BusiCardInfo.value = message.data.ecToken;
|
||||
console.log(BusiCardInfo.value);
|
||||
|
||||
emits('carReading', jsonResult);
|
||||
})
|
||||
.catch(() => {
|
||||
readCardLoading.value = false;
|
||||
});
|
||||
cardInfo = JSON.parse(JSON.stringify(jsonResult));
|
||||
let message = JSON.parse(cardInfo.message);
|
||||
console.log('patientInfo中的encounterId:', props.patientInfo);
|
||||
const encounterId = props.inHospitalInfo.encounterId || '1993854019030441985';
|
||||
console.log('1111111111111111111准备使用的encounterId:', encounterId);
|
||||
|
||||
userMessage = {
|
||||
certType: '02', // 证件类型
|
||||
certNo: message.data.idNo, // 身份证号
|
||||
psnCertType: '02', // 居民身份证
|
||||
encounterId: encounterId || '1993854019030441985',
|
||||
};
|
||||
userCardInfo = {
|
||||
certType: '01', // 证件类型
|
||||
certNo: message.data.idNo, // 身份证号
|
||||
psnCertType: '01', // 居民身份证
|
||||
busiCardInfo: message.data.ecToken, // 令牌
|
||||
encounterId: encounterId || '1993854019030441985',
|
||||
};
|
||||
BusiCardInfo.value = message.data.ecToken;
|
||||
console.log(BusiCardInfo.value);
|
||||
break;
|
||||
case '02':
|
||||
break;
|
||||
case '03': // 社保卡
|
||||
readCardLoading.value = true;
|
||||
loadingText.value = '正在读取...';
|
||||
await invokeYbPlugin(
|
||||
await invokeYbPlugin5001(
|
||||
JSON.stringify({
|
||||
FunctionId: 1,
|
||||
IP: 'ddjk.jlhs.gov.cn',
|
||||
@@ -369,32 +369,34 @@ async function handleReadCard(value) {
|
||||
)
|
||||
.then((res) => {
|
||||
jsonResult = JSON.stringify(res.data);
|
||||
|
||||
let message1 = JSON.parse(jsonResult);
|
||||
// 从patientInfo中获取encounterId,如果没有则尝试从住院号中获取
|
||||
// const encounterId =
|
||||
// props.patientInfo?.encounterId || props.patientInfo?.visitNo || props.patientInfo?.busNo;
|
||||
// console.log('准备使用的encounterId:', encounterId);
|
||||
|
||||
userMessage = {
|
||||
certType: '02', // 证件类型
|
||||
certNo: message1.SocialSecurityNumber, // 身份证号
|
||||
psnCertType: '02', // 居民身份证
|
||||
encounterId: encounterId || '1993854019030441985',
|
||||
};
|
||||
userCardInfo = {
|
||||
certType: '02', // 证件类型
|
||||
certNo: message1.SocialSecurityNumber, // 身份证号
|
||||
psnCertType: '02', // 居民身份证
|
||||
busiCardInfo: message1.BusiCardInfo, //卡号
|
||||
encounterId: encounterId || '1993854019030441985',
|
||||
};
|
||||
BusiCardInfo.value = message1.BusiCardInfo;
|
||||
console.log(message1.BusiCardInfo);
|
||||
|
||||
emits('carReading', res.data);
|
||||
})
|
||||
.finally(() => {
|
||||
readCardLoading.value = false;
|
||||
});
|
||||
|
||||
let message1 = JSON.parse(jsonResult);
|
||||
// 从patientInfo中获取encounterId,如果没有则尝试从住院号中获取
|
||||
// const encounterId =
|
||||
// props.patientInfo?.encounterId || props.patientInfo?.visitNo || props.patientInfo?.busNo;
|
||||
// console.log('准备使用的encounterId:', encounterId);
|
||||
|
||||
userMessage = {
|
||||
certType: '02', // 证件类型
|
||||
certNo: message1.SocialSecurityNumber, // 身份证号
|
||||
psnCertType: '02', // 居民身份证
|
||||
encounterId: encounterId || '1993854019030441985',
|
||||
};
|
||||
userCardInfo = {
|
||||
certType: '02', // 证件类型
|
||||
certNo: message1.SocialSecurityNumber, // 身份证号
|
||||
psnCertType: '02', // 居民身份证
|
||||
busiCardInfo: message1.BusiCardInfo, //卡号
|
||||
encounterId: encounterId || '1993854019030441985',
|
||||
};
|
||||
BusiCardInfo.value = message1.BusiCardInfo;
|
||||
console.log(message1.BusiCardInfo);
|
||||
break;
|
||||
case '99':
|
||||
break;
|
||||
@@ -448,7 +450,12 @@ async function handleReadCard(value) {
|
||||
const changFeeType = () => {
|
||||
emits('onChangFeeType');
|
||||
};
|
||||
defineExpose({ submitForm, form, isEditing });
|
||||
|
||||
// 无档登记收集信息
|
||||
const getPatientForm = () => {
|
||||
return patientInfoFormRef?.value?.form;
|
||||
};
|
||||
defineExpose({ submitForm, form, isEditing, getPatientForm });
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -262,6 +262,7 @@ const data = reactive({
|
||||
isViewMode: false,
|
||||
form: {
|
||||
typeCode: '01',
|
||||
genderEnum: 0,
|
||||
},
|
||||
rules: {
|
||||
name: [{ required: true, message: '姓名不能为空', trigger: 'change' }],
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
ref="patientInfoRef"
|
||||
:is-registered="props.isRegistered"
|
||||
@onChangFeeType="onChangFeeType"
|
||||
@carReading="onCarRead"
|
||||
/>
|
||||
<!-- <PatientRelationList
|
||||
class="relationList"
|
||||
@@ -39,6 +40,19 @@
|
||||
</el-scrollbar>
|
||||
<template v-slot:footer>
|
||||
<div class="advance-container">
|
||||
<div v-if="currentFeeType !== 'hipCash'" class="payment-item">
|
||||
<span>{{ payType() }}支付:</span>
|
||||
<el-input
|
||||
ref="txtCodeRef"
|
||||
v-model="txtCode"
|
||||
style="width: 300px; margin-left: 10px"
|
||||
:placeholder="payType() + '支付码'"
|
||||
/>
|
||||
<el-button link type="primary" @click="handleWxPay()" style="margin-left: 10px"
|
||||
>扫码支付</el-button
|
||||
>
|
||||
<el-button link type="primary" @click="getWxPayResult()">查看结果</el-button>
|
||||
</div>
|
||||
<el-space>
|
||||
<div>缴费预交金</div>
|
||||
<el-input
|
||||
@@ -86,9 +100,12 @@ const { proxy } = getCurrentInstance();
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import PatientInfoComp from './patientInfo.vue';
|
||||
import RegisterForm from './registerForm.vue';
|
||||
import { noFilesRegister, registerInHospital, getInit, getProvincesAndCities } from './api';
|
||||
import { noFilesRegister, registerInHospital, getProvincesAndCities } from './api';
|
||||
import { getInit } from '../../../../doctorstation/components/api';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { wxPay, WxPayResult } from '../../../../charge/cliniccharge/components/api';
|
||||
import printUtils from '@/utils/printUtils';
|
||||
const txtCode = ref('');
|
||||
const router = useRouter();
|
||||
const emits = defineEmits(['okAct', 'cancelAct']);
|
||||
|
||||
@@ -165,12 +182,58 @@ const handleSubmit = () => {
|
||||
};
|
||||
params.inHospitalInfo.payEnum = payEnum.value;
|
||||
params.payEnum = payEnum.value;
|
||||
debugger;
|
||||
console.log('params==========>', JSON.stringify(patientInfoRef?.value.getPatientForm()));
|
||||
if (props.noFile) {
|
||||
const paramsDic = patientInfoRef?.value.getPatientForm();
|
||||
const paramsDic1 = RegisterFormRef.value.submitForm;
|
||||
if (!paramsDic?.name) {
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: '请输入患者姓名',
|
||||
});
|
||||
return;
|
||||
} else if (!paramsDic?.phone) {
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: '请输入联系方式',
|
||||
});
|
||||
return;
|
||||
} else if (!paramsDic?.age) {
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: '请输入年龄',
|
||||
});
|
||||
return;
|
||||
} else if (!paramsDic1?.inHospitalOrgId) {
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: '请选择入院科室',
|
||||
});
|
||||
return;
|
||||
} else if (!paramsDic1?.wardLocationId) {
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: '请选择入院病区',
|
||||
});
|
||||
return;
|
||||
} else if (!paramsDic1?.diagnosisDefinitionId) {
|
||||
ElMessage({
|
||||
type: 'error',
|
||||
message: '请选择入院诊断',
|
||||
});
|
||||
return;
|
||||
}
|
||||
// else if (!paramsDic1?.diagnosisDesc) {
|
||||
// ElMessage({
|
||||
// type: 'error',
|
||||
// message: '请输入诊断描述',
|
||||
// });
|
||||
// return;
|
||||
// }
|
||||
RegisterFormRef.value.validateData(async () => {
|
||||
params.inHospitalInfo = RegisterFormRef.value.submitForm;
|
||||
params.inHospitalInfo.payEnum = payEnum.value;
|
||||
params.patientInformation = patientInfoRef.value.getPatientForm();
|
||||
params.patientInformation = patientInfoRef?.value.getPatientForm();
|
||||
if (params.patientInformation.idCard) {
|
||||
// 验证身份证号长度是否为18位
|
||||
const idCard = params.patientInformation.idCard.toString();
|
||||
@@ -184,7 +247,6 @@ const handleSubmit = () => {
|
||||
}
|
||||
}
|
||||
console.log('params', params);
|
||||
debugger;
|
||||
params.inHospitalInfo.balanceAmount = advance.value;
|
||||
const performRegistration = () => {
|
||||
noFilesRegister(params).then((res) => {
|
||||
@@ -194,47 +256,48 @@ const handleSubmit = () => {
|
||||
ElMessage.success(res.msg);
|
||||
// 打印预交金收据
|
||||
printDepositReceipt(props.patientInfo, params.inHospitalInfo);
|
||||
cancelAct();
|
||||
// 询问是否需要医保登记
|
||||
ElMessageBox.confirm('是否需要进行医保登记?', '医保登记确认', {
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
type: 'info',
|
||||
})
|
||||
.then(() => {
|
||||
// 准备传递的数据
|
||||
const cardData = {
|
||||
patientInfo: params.patientInformation,
|
||||
inHospitalInfo: params.inHospitalInfo,
|
||||
encounterId: params.inHospitalInfo.encounterId,
|
||||
};
|
||||
// ElMessageBox.confirm('是否需要进行医保登记?', '医保登记确认', {
|
||||
// confirmButtonText: '确认',
|
||||
// cancelButtonText: '取消',
|
||||
// type: 'info',
|
||||
// })
|
||||
// .then(() => {
|
||||
// // 准备传递的数据
|
||||
// const cardData = {
|
||||
// patientInfo: params.patientInformation,
|
||||
// inHospitalInfo: params.inHospitalInfo,
|
||||
// encounterId: params.inHospitalInfo.encounterId,
|
||||
// };
|
||||
|
||||
// 跳转到医保登记页面
|
||||
try {
|
||||
router
|
||||
.push({
|
||||
path: '/ybmanagement/ybInhospital/ybregisterEdit',
|
||||
query: {
|
||||
encounterId: props.patientInfo.encounterId,
|
||||
cardData: encodeURIComponent(JSON.stringify(cardData)),
|
||||
cardType: 'inHospital',
|
||||
operationType: 'HospitalizationRegistration',
|
||||
},
|
||||
})
|
||||
.then(() => {
|
||||
console.log('路由跳转成功');
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('路由跳转失败:', error);
|
||||
ElMessage.error('跳转到医保登记页面失败');
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('跳转异常:', error);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// 用户取消医保登记,关闭当前弹窗
|
||||
emits('okAct');
|
||||
});
|
||||
// // 跳转到医保登记页面
|
||||
// try {
|
||||
// router
|
||||
// .push({
|
||||
// path: '/ybmanagement/ybInhospital/ybregisterEdit',
|
||||
// query: {
|
||||
// encounterId: props.patientInfo.encounterId,
|
||||
// cardData: encodeURIComponent(JSON.stringify(cardData)),
|
||||
// cardType: 'inHospital',
|
||||
// operationType: 'HospitalizationRegistration',
|
||||
// },
|
||||
// })
|
||||
// .then(() => {
|
||||
// console.log('路由跳转成功');
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// console.error('路由跳转失败:', error);
|
||||
// ElMessage.error('跳转到医保登记页面失败');
|
||||
// });
|
||||
// } catch (error) {
|
||||
// console.error('跳转异常:', error);
|
||||
// }
|
||||
// })
|
||||
// .catch(() => {
|
||||
// // 用户取消医保登记,关闭当前弹窗
|
||||
// emits('okAct');
|
||||
// });
|
||||
} else {
|
||||
ElMessage.error(res.msg);
|
||||
}
|
||||
@@ -259,7 +322,6 @@ const handleSubmit = () => {
|
||||
params.patientId = props.patientInfo.patientId;
|
||||
RegisterFormRef.value.validateData(async () => {
|
||||
params = { ...params, ...RegisterFormRef.value.submitForm };
|
||||
console.log('params', params);
|
||||
const performRegistration = () => {
|
||||
console.log('params', params);
|
||||
registerInHospital(params).then((res) => {
|
||||
@@ -273,48 +335,51 @@ const handleSubmit = () => {
|
||||
params,
|
||||
RegisterFormRef.value.medicalInsuranceTitle
|
||||
);
|
||||
|
||||
// 询问是否需要医保登记
|
||||
ElMessageBox.confirm('是否需要进行医保登记?', '医保登记确认', {
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
type: 'info',
|
||||
})
|
||||
.then(() => {
|
||||
// 准备传递的数据
|
||||
const cardData = {
|
||||
patientInfo: props.patientInfo,
|
||||
inHospitalInfo: params,
|
||||
};
|
||||
|
||||
// 跳转到医保登记页面
|
||||
try {
|
||||
router
|
||||
.push({
|
||||
path: '/ybmanagement/ybInhospital/ybregisterEdit',
|
||||
query: {
|
||||
encounterId: props.patientInfo.encounterId,
|
||||
cardData: encodeURIComponent(JSON.stringify(cardData)),
|
||||
cardType: 'inHospital',
|
||||
operationType: 'HospitalizationRegistration',
|
||||
certType: props.patientInfo.certType,
|
||||
},
|
||||
})
|
||||
.then(() => {
|
||||
console.log('路由跳转成功');
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('路由跳转失败:', error);
|
||||
ElMessage.error('跳转到医保登记页面失败');
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('跳转异常:', error);
|
||||
}
|
||||
// 自费不需要弹医保
|
||||
if (params.contractNo != '0000') {
|
||||
// 询问是否需要医保登记
|
||||
ElMessageBox.confirm('是否需要进行医保登记?', '医保登记确认', {
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
type: 'info',
|
||||
})
|
||||
.catch(() => {
|
||||
// 用户取消医保登记,关闭当前弹窗
|
||||
emits('okAct');
|
||||
});
|
||||
.then(() => {
|
||||
// 准备传递的数据
|
||||
const cardData = {
|
||||
patientInfo: props.patientInfo,
|
||||
inHospitalInfo: params,
|
||||
};
|
||||
|
||||
// 跳转到医保登记页面
|
||||
try {
|
||||
router
|
||||
.push({
|
||||
path: '/ybmanagement/ybInhospital/ybregisterEdit',
|
||||
query: {
|
||||
encounterId: props.patientInfo.encounterId,
|
||||
cardData: encodeURIComponent(JSON.stringify(cardData)),
|
||||
cardType: 'inHospital',
|
||||
operationType: 'HospitalizationRegistration',
|
||||
certType: props.patientInfo.certType,
|
||||
},
|
||||
})
|
||||
.then(() => {
|
||||
console.log('路由跳转成功');
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('路由跳转失败:', error);
|
||||
ElMessage.error('跳转到医保登记页面失败');
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('跳转异常:', error);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// 用户取消医保登记,关闭当前弹窗
|
||||
emits('okAct');
|
||||
});
|
||||
}
|
||||
cancelAct();
|
||||
} else {
|
||||
ElMessage.error(res.msg);
|
||||
}
|
||||
@@ -355,6 +420,8 @@ const closedAct = () => {
|
||||
|
||||
onMounted(() => {
|
||||
getInit().then((res) => {
|
||||
console.log('getInit=========>', JSON.stringify(res.data));
|
||||
|
||||
initOptions.value = res.data;
|
||||
});
|
||||
});
|
||||
@@ -522,6 +589,55 @@ const convertToChineseNumber = (amount) => {
|
||||
/* 导入用户信息 */
|
||||
import useUserStore from '@/store/modules/user';
|
||||
const userStore = useUserStore();
|
||||
function handleWxPay() {
|
||||
wxPay({
|
||||
// 支付码
|
||||
txtCode: txtCode.value,
|
||||
// 收费项id 住院怎么给
|
||||
chargeItemIds: props.chargeItemIds,
|
||||
encounterId: props.patientInfo.encounterId,
|
||||
// 支付id 住院怎么给
|
||||
id: props.paymentId,
|
||||
// 支付详情 住院怎么给 格式[{ payEnum: 220100, amount: 0.0, payLevelEnum: 2 }]
|
||||
paymentDetails: formData.selfPay,
|
||||
// 读卡的时候获取的
|
||||
ybMdtrtCertType: props.userCardInfo.psnCertType,
|
||||
// 读卡获取
|
||||
busiCardInfo: props.userCardInfo.busiCardInfo,
|
||||
});
|
||||
}
|
||||
|
||||
function getWxPayResult() {
|
||||
WxPayResult({
|
||||
txtCode: txtCode.value,
|
||||
chargeItemIds: props.chargeItemIds,
|
||||
encounterId: props.patientInfo.encounterId,
|
||||
id: props.paymentId,
|
||||
paymentDetails: formData.selfPay,
|
||||
ybMdtrtCertType: props.userCardInfo.psnCertType,
|
||||
busiCardInfo: props.userCardInfo.busiCardInfo,
|
||||
});
|
||||
}
|
||||
|
||||
// 根据不同支付方式,显示不同的支付方式详情
|
||||
const payType = () => {
|
||||
switch (currentFeeType.value) {
|
||||
case 'hipCash':
|
||||
return '现金';
|
||||
case 'hipAlipay':
|
||||
return '支付宝';
|
||||
case 'wechat':
|
||||
return '微信卡';
|
||||
case 'hipPayCard':
|
||||
return '银行卡';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
};
|
||||
// 读卡操作
|
||||
const onCarRead = (a) => {
|
||||
console.log('读卡操作:', a);
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.patientRegister-container {
|
||||
@@ -532,7 +648,12 @@ const userStore = useUserStore();
|
||||
.advance-container {
|
||||
width: 660px;
|
||||
display: flex;
|
||||
|
||||
flex-direction: column;
|
||||
.payment-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.feeType {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -134,9 +134,9 @@
|
||||
<el-form-item label="患者病情">
|
||||
<el-select v-model="submitForm.priorityEnum" :disabled="props.isRegistered">
|
||||
<el-option
|
||||
v-for="item in props.initOptions.priorityEnumList"
|
||||
v-for="item in props.initOptions.priorityLevelOptionOptions"
|
||||
:key="item.value"
|
||||
:label="item.info"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
@@ -280,13 +280,13 @@ const rules = reactive({
|
||||
trigger: ['blur', 'change'],
|
||||
},
|
||||
],
|
||||
diagnosisDesc: [
|
||||
{
|
||||
required: true,
|
||||
message: '诊断描述未填写',
|
||||
trigger: ['blur', 'change'],
|
||||
},
|
||||
],
|
||||
// diagnosisDesc: [
|
||||
// {
|
||||
// required: true,
|
||||
// message: '诊断描述未填写',
|
||||
// trigger: ['blur', 'change'],
|
||||
// },
|
||||
// ],
|
||||
});
|
||||
|
||||
//获取省市医保字符串
|
||||
@@ -298,11 +298,13 @@ const medicalInsuranceTitle = ref('');
|
||||
// });
|
||||
const getProvincesAndCitiesInfo = async () => {
|
||||
try {
|
||||
const res = await getProvincesAndCities(props.inHospitalInfo.encounterId);
|
||||
// console.log('获取省市医保字符串', res);
|
||||
if (res && res.code == 200) {
|
||||
// 确保有数据时才更新
|
||||
medicalInsuranceTitle.value = res.data?.insutype || res.data || '';
|
||||
if (inHospitalInfo.encounterId) {
|
||||
const res = await getProvincesAndCities(props.inHospitalInfo.encounterId);
|
||||
// console.log('获取省市医保字符串', res);
|
||||
if (res && res.code == 200) {
|
||||
// 确保有数据时才更新
|
||||
medicalInsuranceTitle.value = res.data?.insutype || res.data || '';
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// 静默处理错误,确保页面不会显示错误信息
|
||||
|
||||
@@ -22,7 +22,6 @@ const props = defineProps({});
|
||||
const state = reactive({});
|
||||
defineExpose({ state });
|
||||
const activeName = ref('first');
|
||||
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.sds {
|
||||
|
||||
@@ -1,72 +1,89 @@
|
||||
<template>
|
||||
<div @keyup="handleKeyDown" tabindex="0" ref="tableWrapper">
|
||||
<el-table
|
||||
<div @keyup="handleKeyDown" tabindex="0" ref="tableWrapper" class="advice-base-list-wrapper">
|
||||
<Table
|
||||
ref="adviceBaseRef"
|
||||
height="400"
|
||||
:data="adviceBaseList"
|
||||
highlight-current-row
|
||||
@current-change="handleCurrentChange"
|
||||
:table-data="adviceBaseList"
|
||||
:table-columns="tableColumns"
|
||||
:highlight-current-row="true"
|
||||
:table-height="400"
|
||||
:max-height="400"
|
||||
:loading="loading"
|
||||
row-key="patientId"
|
||||
@cell-click="clickRow"
|
||||
@row-click="handleRowClick"
|
||||
>
|
||||
<el-table-column label="名称" align="center" prop="adviceName" />
|
||||
<el-table-column label="类型" align="center" prop="activityType_enumText" />
|
||||
<el-table-column label="包装单位" align="center" prop="unitCode_dictText" />
|
||||
<el-table-column label="最小单位" align="center" prop="minUnitCode_dictText" />
|
||||
<el-table-column label="规格" align="center" prop="volume" />
|
||||
<el-table-column label="用法" align="center" prop="methodCode_dictText" />
|
||||
<el-table-column label="库存数量" align="center">
|
||||
<template #default="scope">{{ handleQuantity(scope.row) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="频次" align="center" prop="rateCode_dictText" />
|
||||
<!-- <el-table-column label="单次剂量" align="center" prop="dose" /> -->
|
||||
<!-- <el-table-column label="剂量单位" align="center" prop="doseUnitCode_dictText" /> -->
|
||||
<el-table-column label="注射药品" align="center" prop="injectFlag_enumText" />
|
||||
<el-table-column label="皮试" align="center" prop="skinTestFlag_enumText" />
|
||||
<el-table-column label="医保码" align="center" prop="ybNo" />
|
||||
<!-- <el-table-column label="限制使用标志" align="center" prop="useLimitFlag" /> -->
|
||||
<el-table-column
|
||||
label="限制使用范围"
|
||||
align="center"
|
||||
:show-overflow-tooltip="true"
|
||||
prop="useScope"
|
||||
>
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.useLimitFlag === 1">{{ scope.row.useScope }}</span>
|
||||
<span v-else>{{ '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<template #quantity="{ row }">
|
||||
{{ handleQuantity(row) }}
|
||||
</template>
|
||||
<template #useScope="{ row }">
|
||||
<span v-if="row.useLimitFlag === 1">{{ row.useScope }}</span>
|
||||
<span v-else>{{ '-' }}</span>
|
||||
</template>
|
||||
</Table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { nextTick } from 'vue';
|
||||
import { getAdviceBaseInfo } from './api';
|
||||
<script setup lang="ts">
|
||||
import { ref, nextTick, watch, computed } from 'vue';
|
||||
import { throttle } from 'lodash-es';
|
||||
import Table from '@/components/TableLayout/Table.vue';
|
||||
import { getAdviceBaseInfo } from './api';
|
||||
import type { TableColumn } from '@/components/types/TableLayout.d';
|
||||
|
||||
const props = defineProps({
|
||||
adviceQueryParams: {
|
||||
type: Object,
|
||||
default: '',
|
||||
},
|
||||
interface Props {
|
||||
adviceQueryParams?: {
|
||||
searchKey?: string;
|
||||
adviceType?: string;
|
||||
};
|
||||
patientInfo: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
inHospitalOrgId?: string;
|
||||
[key: string]: any;
|
||||
};
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
adviceQueryParams: () => ({}),
|
||||
});
|
||||
const emit = defineEmits(['selectAdviceBase']);
|
||||
const total = ref(0);
|
||||
const adviceBaseRef = ref();
|
||||
const tableWrapper = ref();
|
||||
const currentIndex = ref(0); // 当前选中行索引
|
||||
const currentSelectRow = ref({});
|
||||
|
||||
const emit = defineEmits<{
|
||||
selectAdviceBase: [row: any];
|
||||
}>();
|
||||
|
||||
const total = ref<number>(0);
|
||||
const loading = ref<boolean>(false);
|
||||
const adviceBaseRef = ref<InstanceType<typeof Table> | null>(null);
|
||||
const tableWrapper = ref<HTMLDivElement | null>(null);
|
||||
const currentIndex = ref<number>(0);
|
||||
const currentSelectRow = ref<any>({});
|
||||
const queryParams = ref({
|
||||
pageSize: 100,
|
||||
pageNum: 1,
|
||||
adviceTypes: '1,3'
|
||||
adviceTypes: '1,3',
|
||||
searchKey: '',
|
||||
organizationId: '',
|
||||
});
|
||||
const adviceBaseList = ref([]);
|
||||
const adviceBaseList = ref<any[]>([]);
|
||||
|
||||
// 表格列配置
|
||||
const tableColumns = computed<TableColumn[]>(() => [
|
||||
{ label: '名称', prop: 'adviceName', align: 'center', width: 200 },
|
||||
{ label: '类型', prop: 'activityType_enumText', align: 'center' },
|
||||
{ label: '包装单位', prop: 'unitCode_dictText', align: 'center' },
|
||||
{ label: '最小单位', prop: 'minUnitCode_dictText', align: 'center' },
|
||||
{ label: '规格', prop: 'volume', align: 'center' },
|
||||
{ label: '用法', prop: 'methodCode_dictText', align: 'center' },
|
||||
{ label: '库存数量', prop: 'quantity', align: 'center', slot: 'quantity' },
|
||||
{ label: '频次', prop: 'rateCode_dictText', align: 'center' },
|
||||
{ label: '注射药品', prop: 'injectFlag_enumText', align: 'center' },
|
||||
{ label: '皮试', prop: 'skinTestFlag_enumText', align: 'center' },
|
||||
{ label: '医保码', prop: 'ybNo', align: 'center' },
|
||||
{
|
||||
label: '限制使用范围',
|
||||
prop: 'useScope',
|
||||
align: 'center',
|
||||
showOverflowTooltip: true,
|
||||
slot: 'useScope',
|
||||
},
|
||||
]);
|
||||
// 节流函数
|
||||
const throttledGetList = throttle(
|
||||
() => {
|
||||
@@ -88,39 +105,52 @@ watch(
|
||||
|
||||
getList();
|
||||
function getList() {
|
||||
loading.value = true;
|
||||
queryParams.value.organizationId = props.patientInfo.inHospitalOrgId;
|
||||
getAdviceBaseInfo(queryParams.value).then((res) => {
|
||||
if (res.data.records.length > 0) {
|
||||
adviceBaseList.value = res.data.records.filter((item) => {
|
||||
if (item.adviceType == 1 || item.adviceType == 2) {
|
||||
return handleQuantity(item) != 0;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
total.value = res.data.total;
|
||||
nextTick(() => {
|
||||
currentIndex.value = 0;
|
||||
adviceBaseRef.value.setCurrentRow(adviceBaseList.value[0]);
|
||||
});
|
||||
}
|
||||
});
|
||||
getAdviceBaseInfo(queryParams.value)
|
||||
.then((res) => {
|
||||
console.log(res.data.records);
|
||||
if (res.data.records.length > 0) {
|
||||
adviceBaseList.value = res.data.records.filter((item) => {
|
||||
if (item.adviceType == 1 || item.adviceType == 2) {
|
||||
return handleQuantity(item) != 0;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
total.value = res.data.total;
|
||||
nextTick(() => {
|
||||
if (adviceBaseList.value.length > 0) {
|
||||
currentIndex.value = 0;
|
||||
setCurrentRow(adviceBaseList.value[0]);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
adviceBaseList.value = [];
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
adviceBaseList.value = [];
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
// 处理键盘事件
|
||||
const handleKeyDown = (event) => {
|
||||
const handleKeyDown = (event: KeyboardEvent): void => {
|
||||
const key = event.key;
|
||||
const data = adviceBaseList.value;
|
||||
|
||||
switch (key) {
|
||||
case 'ArrowUp': // 上箭头
|
||||
event.preventDefault(); // 阻止默认滚动行为
|
||||
event.preventDefault();
|
||||
if (currentIndex.value > 0) {
|
||||
currentIndex.value--;
|
||||
setCurrentRow(data[currentIndex.value]);
|
||||
}
|
||||
break;
|
||||
case 'ArrowDown': // 下箭头`
|
||||
case 'ArrowDown': // 下箭头
|
||||
event.preventDefault();
|
||||
if (currentIndex.value < data.length - 1) {
|
||||
currentIndex.value++;
|
||||
@@ -128,52 +158,84 @@ const handleKeyDown = (event) => {
|
||||
}
|
||||
break;
|
||||
case 'Enter': // 回车键
|
||||
// const currentRow = adviceBaseRef.value.getSelectionRows();
|
||||
event.preventDefault();
|
||||
if (currentSelectRow.value) {
|
||||
// 这里可以触发自定义逻辑,如弹窗、跳转等
|
||||
if (currentSelectRow.value && Object.keys(currentSelectRow.value).length > 0) {
|
||||
emit('selectAdviceBase', currentSelectRow.value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
function handleQuantity(row) {
|
||||
function handleQuantity(row: any): string {
|
||||
if (row.inventoryList && row.inventoryList.length > 0) {
|
||||
const totalQuantity = row.inventoryList.reduce((sum, item) => sum + (item.quantity || 0), 0);
|
||||
return totalQuantity.toString() + row.minUnitCode_dictText;
|
||||
const totalQuantity = row.inventoryList.reduce(
|
||||
(sum: number, item: any) => sum + (item.quantity || 0),
|
||||
0
|
||||
);
|
||||
return totalQuantity.toString() + (row.minUnitCode_dictText || '');
|
||||
}
|
||||
return 0;
|
||||
return '0';
|
||||
}
|
||||
|
||||
// 设置选中行(带滚动)
|
||||
const setCurrentRow = (row) => {
|
||||
adviceBaseRef.value.setCurrentRow(row);
|
||||
// 滚动到选中行
|
||||
const tableBody = adviceBaseRef.value.$el.querySelector('.el-table__body-wrapper');
|
||||
const currentRowEl = adviceBaseRef.value.$el.querySelector('.current-row');
|
||||
if (tableBody && currentRowEl) {
|
||||
currentRowEl.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
||||
const setCurrentRow = (row: any) => {
|
||||
if (adviceBaseRef.value?.tableRef) {
|
||||
adviceBaseRef.value.tableRef.setCurrentRow(row);
|
||||
// 滚动到选中行
|
||||
nextTick(() => {
|
||||
const tableEl = adviceBaseRef.value?.tableRef?.$el;
|
||||
if (tableEl) {
|
||||
const tableBody = tableEl.querySelector('.el-table__body-wrapper');
|
||||
const currentRowEl = tableEl.querySelector('.current-row');
|
||||
if (tableBody && currentRowEl) {
|
||||
currentRowEl.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 当前行变化时更新索引
|
||||
const handleCurrentChange = (currentRow) => {
|
||||
currentIndex.value = adviceBaseList.value.findIndex((item) => item === currentRow);
|
||||
currentSelectRow.value = currentRow;
|
||||
// 行点击事件
|
||||
const handleRowClick = (row: any): void => {
|
||||
currentIndex.value = adviceBaseList.value.findIndex((item) => item === row);
|
||||
currentSelectRow.value = row;
|
||||
emit('selectAdviceBase', row);
|
||||
};
|
||||
|
||||
function clickRow(row) {
|
||||
emit('selectAdviceBase', row);
|
||||
}
|
||||
// 监听表格当前行变化(通过 el-table 的 current-change 事件)
|
||||
watch(
|
||||
() => adviceBaseRef.value?.tableRef,
|
||||
(tableRef) => {
|
||||
if (tableRef) {
|
||||
// 通过 $el 访问原生 el-table 并监听 current-change
|
||||
const elTable = tableRef.$el?.querySelector('.el-table');
|
||||
if (elTable) {
|
||||
// 使用 MutationObserver 或直接监听 DOM 变化来检测当前行变化
|
||||
// 或者通过 watch 监听 currentSelectRow 的变化
|
||||
}
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
defineExpose({
|
||||
handleKeyDown,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.popover-table-wrapper:focus {
|
||||
outline: 2px solid #409eff; /* 聚焦时的高亮效果 */
|
||||
|
||||
<style scoped lang="scss">
|
||||
.advice-base-list-wrapper {
|
||||
height: 400px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
&:focus {
|
||||
outline: 2px solid #409eff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
.popover-table-wrapper:focus {
|
||||
outline: 2px solid #409eff;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -110,6 +110,7 @@ import { getCurrentInstance, ref, watch, computed } from 'vue';
|
||||
import { Refresh } from '@element-plus/icons-vue';
|
||||
import { patientInfo } from '../../store/patient.js';
|
||||
import { getBloodTransfusion } from './api';
|
||||
import { getOrgList } from '../../../../doctorstation/components/api.js';
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
@@ -118,6 +119,7 @@ const loading = ref(false);
|
||||
const detailDialogVisible = ref(false);
|
||||
const currentDetail = ref(null);
|
||||
const descJsonData = ref(null);
|
||||
const orgOptions = ref([]);
|
||||
|
||||
const fetchData = async () => {
|
||||
if (!patientInfo.value?.encounterId) {
|
||||
@@ -172,12 +174,40 @@ const hasMatchedFields = computed(() => {
|
||||
return Object.keys(descJsonData.value).some((key) => isFieldMatched(key));
|
||||
});
|
||||
|
||||
/** 查询科室 */
|
||||
const getLocationInfo = () => {
|
||||
getOrgList().then((res) => {
|
||||
orgOptions.value = res.data.records;
|
||||
});
|
||||
};
|
||||
|
||||
const recursionFun = (targetDepartment) => {
|
||||
let name = '';
|
||||
for (let index = 0; index < orgOptions.value.length; index++) {
|
||||
const obj = orgOptions.value[index];
|
||||
if (obj.id == targetDepartment) {
|
||||
name = obj.name;
|
||||
}
|
||||
const subObjArray = obj['children'];
|
||||
for (let index = 0; index < subObjArray.length; index++) {
|
||||
const item = subObjArray[index];
|
||||
if (item.id == targetDepartment) {
|
||||
name = item.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
return name;
|
||||
};
|
||||
|
||||
const handleViewDetail = (row) => {
|
||||
currentDetail.value = row;
|
||||
// 解析 descJson
|
||||
if (row.descJson) {
|
||||
try {
|
||||
descJsonData.value = JSON.parse(row.descJson);
|
||||
// descJsonData.value = JSON.parse(row.descJson);
|
||||
const obj = JSON.parse(row.descJson);
|
||||
obj.targetDepartment = recursionFun(obj.targetDepartment);
|
||||
descJsonData.value = obj;
|
||||
} catch (e) {
|
||||
console.error('解析 descJson 失败:', e);
|
||||
descJsonData.value = null;
|
||||
@@ -193,6 +223,7 @@ watch(
|
||||
(val) => {
|
||||
if (val) {
|
||||
fetchData();
|
||||
getLocationInfo();
|
||||
} else {
|
||||
tableData.value = [];
|
||||
}
|
||||
|
||||
@@ -110,6 +110,7 @@ import { getCurrentInstance, ref, watch, computed } from 'vue';
|
||||
import { Refresh } from '@element-plus/icons-vue';
|
||||
import { patientInfo } from '../../store/patient.js';
|
||||
import { getCheck } from './api';
|
||||
import { getOrgList } from '../../../../doctorstation/components/api.js';
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
@@ -118,6 +119,7 @@ const loading = ref(false);
|
||||
const detailDialogVisible = ref(false);
|
||||
const currentDetail = ref(null);
|
||||
const descJsonData = ref(null);
|
||||
const orgOptions = ref([]);
|
||||
|
||||
const fetchData = async () => {
|
||||
if (!patientInfo.value?.encounterId) {
|
||||
@@ -172,12 +174,41 @@ const hasMatchedFields = computed(() => {
|
||||
return Object.keys(descJsonData.value).some((key) => isFieldMatched(key));
|
||||
});
|
||||
|
||||
/** 查询科室 */
|
||||
const getLocationInfo = () => {
|
||||
getOrgList().then((res) => {
|
||||
orgOptions.value = res.data.records;
|
||||
});
|
||||
};
|
||||
|
||||
const recursionFun = (targetDepartment) => {
|
||||
let name = '';
|
||||
for (let index = 0; index < orgOptions.value.length; index++) {
|
||||
const obj = orgOptions.value[index];
|
||||
if (obj.id == targetDepartment) {
|
||||
name = obj.name;
|
||||
}
|
||||
const subObjArray = obj['children'];
|
||||
for (let index = 0; index < subObjArray.length; index++) {
|
||||
const item = subObjArray[index];
|
||||
if (item.id == targetDepartment) {
|
||||
name = item.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
return name;
|
||||
};
|
||||
|
||||
const handleViewDetail = (row) => {
|
||||
console.log('targetDepartment========>', JSON.stringify(row));
|
||||
|
||||
currentDetail.value = row;
|
||||
// 解析 descJson
|
||||
if (row.descJson) {
|
||||
try {
|
||||
descJsonData.value = JSON.parse(row.descJson);
|
||||
const obj = JSON.parse(row.descJson);
|
||||
obj.targetDepartment = recursionFun(obj.targetDepartment);
|
||||
descJsonData.value = obj;
|
||||
} catch (e) {
|
||||
console.error('解析 descJson 失败:', e);
|
||||
descJsonData.value = null;
|
||||
@@ -193,6 +224,7 @@ watch(
|
||||
(val) => {
|
||||
if (val) {
|
||||
fetchData();
|
||||
getLocationInfo();
|
||||
} else {
|
||||
tableData.value = [];
|
||||
}
|
||||
|
||||
@@ -110,6 +110,7 @@ import { getCurrentInstance, ref, watch, computed } from 'vue';
|
||||
import { Refresh } from '@element-plus/icons-vue';
|
||||
import { patientInfo } from '../../store/patient.js';
|
||||
import { getSurgery } from './api';
|
||||
import { getOrgList } from '../../../../doctorstation/components/api.js';
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
@@ -118,6 +119,7 @@ const loading = ref(false);
|
||||
const detailDialogVisible = ref(false);
|
||||
const currentDetail = ref(null);
|
||||
const descJsonData = ref(null);
|
||||
const orgOptions = ref([]);
|
||||
|
||||
const fetchData = async () => {
|
||||
if (!patientInfo.value?.encounterId) {
|
||||
@@ -172,12 +174,40 @@ const hasMatchedFields = computed(() => {
|
||||
return Object.keys(descJsonData.value).some((key) => isFieldMatched(key));
|
||||
});
|
||||
|
||||
/** 查询科室 */
|
||||
const getLocationInfo = () => {
|
||||
getOrgList().then((res) => {
|
||||
orgOptions.value = res.data.records;
|
||||
});
|
||||
};
|
||||
|
||||
const recursionFun = (targetDepartment) => {
|
||||
let name = '';
|
||||
for (let index = 0; index < orgOptions.value.length; index++) {
|
||||
const obj = orgOptions.value[index];
|
||||
if (obj.id == targetDepartment) {
|
||||
name = obj.name;
|
||||
}
|
||||
const subObjArray = obj['children'];
|
||||
for (let index = 0; index < subObjArray.length; index++) {
|
||||
const item = subObjArray[index];
|
||||
if (item.id == targetDepartment) {
|
||||
name = item.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
return name;
|
||||
};
|
||||
|
||||
const handleViewDetail = (row) => {
|
||||
currentDetail.value = row;
|
||||
// 解析 descJson
|
||||
if (row.descJson) {
|
||||
try {
|
||||
descJsonData.value = JSON.parse(row.descJson);
|
||||
// descJsonData.value = JSON.parse(row.descJson);
|
||||
const obj = JSON.parse(row.descJson);
|
||||
obj.targetDepartment = recursionFun(obj.targetDepartment);
|
||||
descJsonData.value = obj;
|
||||
} catch (e) {
|
||||
console.error('解析 descJson 失败:', e);
|
||||
descJsonData.value = null;
|
||||
@@ -193,6 +223,7 @@ watch(
|
||||
(val) => {
|
||||
if (val) {
|
||||
fetchData();
|
||||
getLocationInfo();
|
||||
} else {
|
||||
tableData.value = [];
|
||||
}
|
||||
|
||||
@@ -110,6 +110,7 @@ import { getCurrentInstance, ref, watch, computed } from 'vue';
|
||||
import { Refresh } from '@element-plus/icons-vue';
|
||||
import { patientInfo } from '../../store/patient.js';
|
||||
import { getInspection } from './api';
|
||||
import { getOrgList } from '../../../../doctorstation/components/api.js';
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
@@ -118,6 +119,7 @@ const loading = ref(false);
|
||||
const detailDialogVisible = ref(false);
|
||||
const currentDetail = ref(null);
|
||||
const descJsonData = ref(null);
|
||||
const orgOptions = ref([]);
|
||||
|
||||
const fetchData = async () => {
|
||||
if (!patientInfo.value?.encounterId) {
|
||||
@@ -172,12 +174,40 @@ const hasMatchedFields = computed(() => {
|
||||
return Object.keys(descJsonData.value).some((key) => isFieldMatched(key));
|
||||
});
|
||||
|
||||
/** 查询科室 */
|
||||
const getLocationInfo = () => {
|
||||
getOrgList().then((res) => {
|
||||
orgOptions.value = res.data.records;
|
||||
});
|
||||
};
|
||||
|
||||
const recursionFun = (targetDepartment) => {
|
||||
let name = '';
|
||||
for (let index = 0; index < orgOptions.value.length; index++) {
|
||||
const obj = orgOptions.value[index];
|
||||
if (obj.id == targetDepartment) {
|
||||
name = obj.name;
|
||||
}
|
||||
const subObjArray = obj['children'];
|
||||
for (let index = 0; index < subObjArray.length; index++) {
|
||||
const item = subObjArray[index];
|
||||
if (item.id == targetDepartment) {
|
||||
name = item.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
return name;
|
||||
};
|
||||
|
||||
const handleViewDetail = (row) => {
|
||||
currentDetail.value = row;
|
||||
// 解析 descJson
|
||||
if (row.descJson) {
|
||||
try {
|
||||
descJsonData.value = JSON.parse(row.descJson);
|
||||
const obj = JSON.parse(row.descJson);
|
||||
obj.targetDepartment = recursionFun(obj.targetDepartment);
|
||||
descJsonData.value = obj;
|
||||
// descJsonData.value = JSON.parse(row.descJson);
|
||||
} catch (e) {
|
||||
console.error('解析 descJson 失败:', e);
|
||||
descJsonData.value = null;
|
||||
@@ -193,6 +223,7 @@ watch(
|
||||
(val) => {
|
||||
if (val) {
|
||||
fetchData();
|
||||
getLocationInfo();
|
||||
} else {
|
||||
tableData.value = [];
|
||||
}
|
||||
|
||||
@@ -259,7 +259,17 @@ watch(
|
||||
function getList() {
|
||||
getEncounterDiagnosis(patientInfo.value.encounterId).then((res) => {
|
||||
if (res.code == 200) {
|
||||
form.value.diagnosisList = res.data;
|
||||
const datas = (res.data || []).map((item) => {
|
||||
let obj = {
|
||||
...item,
|
||||
};
|
||||
if (obj.diagSrtNo == null) {
|
||||
obj.diagSrtNo = '1';
|
||||
}
|
||||
return obj;
|
||||
});
|
||||
form.value.diagnosisList = datas;
|
||||
// form.value.diagnosisList = res.data;
|
||||
emits('diagnosisSave', false);
|
||||
}
|
||||
});
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user