| | |
| | | "vue-grid-layout": "^3.0.0-beta1", |
| | | "vue-i18n": "^9.10.2", |
| | | "vue-router": "^4.3.0", |
| | | "vue3-print-nb": "^0.1.4" |
| | | "vue3-print-nb": "^0.1.4", |
| | | "xlsx": "^0.18.5" |
| | | }, |
| | | "devDependencies": { |
| | | "@types/node": "^20.11.28", |
| | |
| | | "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" |
| | | } |
| | | }, |
| | | "node_modules/adler-32": { |
| | | "version": "1.3.1", |
| | | "resolved": "https://registry.npmmirror.com/adler-32/-/adler-32-1.3.1.tgz", |
| | | "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==", |
| | | "license": "Apache-2.0", |
| | | "engines": { |
| | | "node": ">=0.8" |
| | | } |
| | | }, |
| | | "node_modules/ajv": { |
| | | "version": "6.12.6", |
| | | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", |
| | |
| | | "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", |
| | | "optional": true |
| | | }, |
| | | "node_modules/cfb": { |
| | | "version": "1.2.2", |
| | | "resolved": "https://registry.npmmirror.com/cfb/-/cfb-1.2.2.tgz", |
| | | "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==", |
| | | "license": "Apache-2.0", |
| | | "dependencies": { |
| | | "adler-32": "~1.3.0", |
| | | "crc-32": "~1.2.0" |
| | | }, |
| | | "engines": { |
| | | "node": ">=0.8" |
| | | } |
| | | }, |
| | | "node_modules/chalk": { |
| | | "version": "4.1.2", |
| | | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", |
| | |
| | | "tiny-emitter": "^2.0.0" |
| | | } |
| | | }, |
| | | "node_modules/codepage": { |
| | | "version": "1.15.0", |
| | | "resolved": "https://registry.npmmirror.com/codepage/-/codepage-1.15.0.tgz", |
| | | "integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==", |
| | | "license": "Apache-2.0", |
| | | "engines": { |
| | | "node": ">=0.8" |
| | | } |
| | | }, |
| | | "node_modules/color-convert": { |
| | | "version": "2.0.1", |
| | | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", |
| | |
| | | "version": "2.8.0", |
| | | "resolved": "https://registry.npmjs.org/countup.js/-/countup.js-2.8.0.tgz", |
| | | "integrity": "sha512-f7xEhX0awl4NOElHulrl4XRfKoNH3rB+qfNSZZyjSZhaAoUk6elvhH+MNxMmlmuUJ2/QNTWPSA7U4mNtIAKljQ==" |
| | | }, |
| | | "node_modules/crc-32": { |
| | | "version": "1.2.2", |
| | | "resolved": "https://registry.npmmirror.com/crc-32/-/crc-32-1.2.2.tgz", |
| | | "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", |
| | | "license": "Apache-2.0", |
| | | "bin": { |
| | | "crc32": "bin/crc32.njs" |
| | | }, |
| | | "engines": { |
| | | "node": ">=0.8" |
| | | } |
| | | }, |
| | | "node_modules/cropperjs": { |
| | | "version": "1.6.1", |
| | |
| | | }, |
| | | "engines": { |
| | | "node": ">= 6" |
| | | } |
| | | }, |
| | | "node_modules/frac": { |
| | | "version": "1.1.2", |
| | | "resolved": "https://registry.npmmirror.com/frac/-/frac-1.1.2.tgz", |
| | | "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==", |
| | | "license": "Apache-2.0", |
| | | "engines": { |
| | | "node": ">=0.8" |
| | | } |
| | | }, |
| | | "node_modules/fs-extra": { |
| | |
| | | "url": "https://github.com/sponsors/antoniandre" |
| | | } |
| | | }, |
| | | "node_modules/ssf": { |
| | | "version": "0.11.2", |
| | | "resolved": "https://registry.npmmirror.com/ssf/-/ssf-0.11.2.tgz", |
| | | "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==", |
| | | "license": "Apache-2.0", |
| | | "dependencies": { |
| | | "frac": "~1.1.2" |
| | | }, |
| | | "engines": { |
| | | "node": ">=0.8" |
| | | } |
| | | }, |
| | | "node_modules/ssr-window": { |
| | | "version": "3.0.0", |
| | | "resolved": "https://registry.npmjs.org/ssr-window/-/ssr-window-3.0.0.tgz", |
| | |
| | | "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-1.1.2.tgz", |
| | | "integrity": "sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng==" |
| | | }, |
| | | "node_modules/wmf": { |
| | | "version": "1.0.2", |
| | | "resolved": "https://registry.npmmirror.com/wmf/-/wmf-1.0.2.tgz", |
| | | "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==", |
| | | "license": "Apache-2.0", |
| | | "engines": { |
| | | "node": ">=0.8" |
| | | } |
| | | }, |
| | | "node_modules/word": { |
| | | "version": "0.3.0", |
| | | "resolved": "https://registry.npmmirror.com/word/-/word-0.3.0.tgz", |
| | | "integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==", |
| | | "license": "Apache-2.0", |
| | | "engines": { |
| | | "node": ">=0.8" |
| | | } |
| | | }, |
| | | "node_modules/wrappy": { |
| | | "version": "1.0.2", |
| | | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", |
| | | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", |
| | | "dev": true |
| | | }, |
| | | "node_modules/xlsx": { |
| | | "version": "0.18.5", |
| | | "resolved": "https://registry.npmmirror.com/xlsx/-/xlsx-0.18.5.tgz", |
| | | "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==", |
| | | "license": "Apache-2.0", |
| | | "dependencies": { |
| | | "adler-32": "~1.3.0", |
| | | "cfb": "~1.2.1", |
| | | "codepage": "~1.15.0", |
| | | "crc-32": "~1.2.1", |
| | | "ssf": "~0.11.2", |
| | | "wmf": "~1.0.1", |
| | | "word": "~0.3.0" |
| | | }, |
| | | "bin": { |
| | | "xlsx": "bin/xlsx.njs" |
| | | }, |
| | | "engines": { |
| | | "node": ">=0.8" |
| | | } |
| | | }, |
| | | "node_modules/xml-name-validator": { |
| | | "version": "4.0.0", |
| | |
| | | "dev": true, |
| | | "requires": {} |
| | | }, |
| | | "adler-32": { |
| | | "version": "1.3.1", |
| | | "resolved": "https://registry.npmmirror.com/adler-32/-/adler-32-1.3.1.tgz", |
| | | "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==" |
| | | }, |
| | | "ajv": { |
| | | "version": "6.12.6", |
| | | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", |
| | |
| | | } |
| | | } |
| | | }, |
| | | "cfb": { |
| | | "version": "1.2.2", |
| | | "resolved": "https://registry.npmmirror.com/cfb/-/cfb-1.2.2.tgz", |
| | | "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==", |
| | | "requires": { |
| | | "adler-32": "~1.3.0", |
| | | "crc-32": "~1.2.0" |
| | | } |
| | | }, |
| | | "chalk": { |
| | | "version": "4.1.2", |
| | | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", |
| | |
| | | "tiny-emitter": "^2.0.0" |
| | | } |
| | | }, |
| | | "codepage": { |
| | | "version": "1.15.0", |
| | | "resolved": "https://registry.npmmirror.com/codepage/-/codepage-1.15.0.tgz", |
| | | "integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==" |
| | | }, |
| | | "color-convert": { |
| | | "version": "2.0.1", |
| | | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", |
| | |
| | | "version": "2.8.0", |
| | | "resolved": "https://registry.npmjs.org/countup.js/-/countup.js-2.8.0.tgz", |
| | | "integrity": "sha512-f7xEhX0awl4NOElHulrl4XRfKoNH3rB+qfNSZZyjSZhaAoUk6elvhH+MNxMmlmuUJ2/QNTWPSA7U4mNtIAKljQ==" |
| | | }, |
| | | "crc-32": { |
| | | "version": "1.2.2", |
| | | "resolved": "https://registry.npmmirror.com/crc-32/-/crc-32-1.2.2.tgz", |
| | | "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==" |
| | | }, |
| | | "cropperjs": { |
| | | "version": "1.6.1", |
| | |
| | | "combined-stream": "^1.0.8", |
| | | "mime-types": "^2.1.12" |
| | | } |
| | | }, |
| | | "frac": { |
| | | "version": "1.1.2", |
| | | "resolved": "https://registry.npmmirror.com/frac/-/frac-1.1.2.tgz", |
| | | "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==" |
| | | }, |
| | | "fs-extra": { |
| | | "version": "10.1.0", |
| | |
| | | "resolved": "https://registry.npmjs.org/splitpanes/-/splitpanes-3.1.5.tgz", |
| | | "integrity": "sha512-r3Mq2ITFQ5a2VXLOy4/Sb2Ptp7OfEO8YIbhVJqJXoFc9hc5nTXXkCvtVDjIGbvC0vdE7tse+xTM9BMjsszP6bw==" |
| | | }, |
| | | "ssf": { |
| | | "version": "0.11.2", |
| | | "resolved": "https://registry.npmmirror.com/ssf/-/ssf-0.11.2.tgz", |
| | | "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==", |
| | | "requires": { |
| | | "frac": "~1.1.2" |
| | | } |
| | | }, |
| | | "ssr-window": { |
| | | "version": "3.0.0", |
| | | "resolved": "https://registry.npmjs.org/ssr-window/-/ssr-window-3.0.0.tgz", |
| | |
| | | "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-1.1.2.tgz", |
| | | "integrity": "sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng==" |
| | | }, |
| | | "wmf": { |
| | | "version": "1.0.2", |
| | | "resolved": "https://registry.npmmirror.com/wmf/-/wmf-1.0.2.tgz", |
| | | "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==" |
| | | }, |
| | | "word": { |
| | | "version": "0.3.0", |
| | | "resolved": "https://registry.npmmirror.com/word/-/word-0.3.0.tgz", |
| | | "integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==" |
| | | }, |
| | | "wrappy": { |
| | | "version": "1.0.2", |
| | | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", |
| | | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", |
| | | "dev": true |
| | | }, |
| | | "xlsx": { |
| | | "version": "0.18.5", |
| | | "resolved": "https://registry.npmmirror.com/xlsx/-/xlsx-0.18.5.tgz", |
| | | "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==", |
| | | "requires": { |
| | | "adler-32": "~1.3.0", |
| | | "cfb": "~1.2.1", |
| | | "codepage": "~1.15.0", |
| | | "crc-32": "~1.2.1", |
| | | "ssf": "~0.11.2", |
| | | "wmf": "~1.0.1", |
| | | "word": "~0.3.0" |
| | | } |
| | | }, |
| | | "xml-name-validator": { |
| | | "version": "4.0.0", |
| | | "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", |
| | |
| | | "vue-grid-layout": "^3.0.0-beta1", |
| | | "vue-i18n": "^9.10.2", |
| | | "vue-router": "^4.3.0", |
| | | "vue3-print-nb": "^0.1.4" |
| | | "vue3-print-nb": "^0.1.4", |
| | | "xlsx": "^0.18.5" |
| | | }, |
| | | "devDependencies": { |
| | | "@types/node": "^20.11.28", |
| New file |
| | |
| | | import request from "/@/utils/request"; |
| | | import type { IPatientDialysisFrequencyCountRes, IPatientDialysisFrequencyCountParams, ItKtvAndUrrListByCondition, IGetKtvAndUrrListByCondition, IWypertensionStatistics, IWypertensionStatisticsParams, IQualityControlReportParams, IQualityControlReportReponse, WeightControlRateDetail, WeightControlRateByYearParams, WeightControlRateByYear, WeightControlRateDetailstParams } from './types' |
| | | import { AxiosPromise } from 'axios'; |
| | | |
| | | |
| | | export function listWorkStats(params: object) { |
| | | return request({ |
| | | url: '/patient/hemo/med/record/listWorkStats', |
| | | method: 'post', |
| | | data: params, |
| | | }); |
| | | } |
| | | |
| | | export function listHemoNurseWorkStats(params: object) { |
| | | return request({ |
| | | url: '/patient/hemo/med/record/listHemoNurseWorkStats', |
| | | method: 'post', |
| | | data: params, |
| | | }); |
| | | } |
| | | export function listRecordsByToolUsage(params: object) { |
| | | return request({ |
| | | url: '/patient/hemo/med/record/listRecordsByToolUsage', |
| | | method: 'post', |
| | | data: params, |
| | | }); |
| | | } |
| | | export function listRecordsByMedicineUsage(params: object) { |
| | | return request({ |
| | | url: '/patient/hemo/med/record/listRecordsByMedicineUsage', |
| | | method: 'post', |
| | | data: params, |
| | | }); |
| | | } |
| | | |
| | | export function listDetailsOfMedicineUsage(params: object) { |
| | | return request({ |
| | | url: '/patient/hemo/med/record/listDetailsOfMedicineUsage', |
| | | method: 'post', |
| | | data: params, |
| | | }); |
| | | } |
| | | export function doStatByResult(params: object) { |
| | | return request({ |
| | | url: '/lis/stat/doStatByResult', |
| | | method: 'post', |
| | | data: params, |
| | | }); |
| | | } |
| | | export function doClientStat4(params: object) { |
| | | return request({ |
| | | url: '/lis/stat/doClientStat4', |
| | | method: 'post', |
| | | data: params, |
| | | }); |
| | | } |
| | | export function doListResultsGroupByMonth(params: object) { |
| | | return request({ |
| | | url: '/lis/stat/doListResultsGroupByMonth', |
| | | method: 'post', |
| | | data: params, |
| | | }); |
| | | } |
| | | export function doListTestItems() { |
| | | return request({ |
| | | url: '/lis/stat/doListTestItems', |
| | | method: 'post', |
| | | }); |
| | | } |
| | | export function doTestItemPassedCount(params: object) { |
| | | return request({ |
| | | url: '/lis/stat/doTestItemPassedCount', |
| | | method: 'post', |
| | | data: params, |
| | | }); |
| | | } |
| | | export function listGroups() { |
| | | return request({ |
| | | url: '/client/group/info/listGroups', |
| | | method: 'post', |
| | | }); |
| | | } |
| | | export function listDetailsEachOne(params) { |
| | | return request({ |
| | | url: '/client/group/info/listDetailsEachOne', |
| | | method: 'post', |
| | | // headers: { |
| | | // 'Content-Type': 'application/x-www-form-urlencoded' |
| | | // }, |
| | | params, |
| | | }); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 重新计算KTV与URR |
| | | * @param params |
| | | * @returns |
| | | */ |
| | | export function doCalcKtvOrUrrApi(params) { |
| | | return request({ |
| | | url: '/lis/stat/doCalcKtvOrUrr', |
| | | method: 'post', |
| | | params |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * 统计体重增长控制率 |
| | | * @param params |
| | | * @returns |
| | | */ |
| | | export function weightControlRateByYearApi(params: WeightControlRateByYearParams): AxiosPromise<WeightControlRateByYear> { |
| | | return request({ |
| | | url: '/patient/stat/weight/increase/range/weightControlRateByYear', |
| | | method: 'post', |
| | | params |
| | | }) |
| | | } |
| | | |
| | | /** 统计体重增长控制率详情 */ |
| | | export function weightControlRateDetailsApi(data: WeightControlRateDetailstParams): AxiosPromise<{ list: WeightControlRateDetail[]; total: number }> { |
| | | return request({ |
| | | url: '/patient/stat/weight/increase/range/weightControlRateDetails', |
| | | method: 'post', |
| | | data |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * 查询KTV Or URR接口 |
| | | * @param data |
| | | * @returns |
| | | */ |
| | | // export function getKtvAndUrrListByConditionsApi(data: IGetKtvAndUrrListByCondition) :AxiosPromise<{ list: ItKtvAndUrrListByCondition[]; total: number; }> { |
| | | // return request({ |
| | | // url: '/patient/ktv/listByConditions', |
| | | // method: 'post', |
| | | // data |
| | | // }) |
| | | // } |
| | | |
| | | /** |
| | | * 查询KTV Or URR接口 |
| | | * @param data |
| | | * @returns |
| | | */ |
| | | export function getKtvAndUrrListByConditionsApi(data: IGetKtvAndUrrListByCondition) :AxiosPromise<{ list: ItKtvAndUrrListByCondition[]; total: number; }> { |
| | | return request({ |
| | | url: '/patient/ktv/listByConditions', |
| | | method: 'post', |
| | | data |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * 药物用量统计页面 |
| | | */ |
| | | |
| | | export function listGroupByDrug(param) { |
| | | return request({ |
| | | url: '/patient/drug/order/vs/patient/listGroupByDrug', |
| | | method: 'post', |
| | | params:param |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * 获取高血压控制率 |
| | | * @param params |
| | | * @returns |
| | | */ |
| | | export function hypertensionStatisticsApi(params: IWypertensionStatisticsParams) :AxiosPromise<IWypertensionStatistics> { |
| | | return request({ |
| | | url: '/patient/hemo/med/body/state/pre/hypertensionStatistics', |
| | | method: 'post', |
| | | params |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * 获取质控报表 |
| | | * @param params |
| | | * @returns |
| | | */ |
| | | export function qualityControlReportApi(params: IQualityControlReportParams): AxiosPromise<IQualityControlReportReponse> { |
| | | return request({ |
| | | url: '/patient/info/qualityControlReport', |
| | | method: 'post', |
| | | params |
| | | }) |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 月度患者透析次数统计接口 |
| | | * @param data |
| | | * @returns |
| | | */ |
| | | export function patientDialysisFrequencyCountApi(data: IPatientDialysisFrequencyCountParams) :AxiosPromise<IPatientDialysisFrequencyCountRes> { |
| | | return request({ |
| | | url: '/patient/hemo/med/record/patientDialysisFrequencyCount', |
| | | method: 'post', |
| | | data |
| | | }) |
| | | } |
| New file |
| | |
| | | import { IComminList } from '../common.type'; |
| | | |
| | | export interface WeightControlRateByYearParams { |
| | | clientCode: string; |
| | | year: number; |
| | | quarter: number; |
| | | maxValue: number; |
| | | minValue: number; |
| | | } |
| | | |
| | | export interface WeightControlRateByYear { |
| | | allcount: number; |
| | | conditionCount: number; |
| | | } |
| | | |
| | | export interface WeightControlRateDetailstParams { |
| | | year: number; |
| | | quarter: number; |
| | | weightControlRateDetailsCondition: { |
| | | page: number; |
| | | size: number; |
| | | clientCode: string; |
| | | maxValue: number; |
| | | minValue: number; |
| | | }; |
| | | } |
| | | |
| | | export interface WeightControlRateDetail { |
| | | age: string; |
| | | code: string; |
| | | patientGender: number; |
| | | patientName: string; |
| | | } |
| | | |
| | | export interface IGetKtvAndUrrListByCondition { |
| | | page: number; |
| | | size: number; |
| | | clientCode: string; |
| | | startTime: string; |
| | | endTime: string; |
| | | patientName: string; |
| | | patientCodes: string[]; |
| | | } |
| | | |
| | | export interface ItKtvAndUrrListByCondition { |
| | | code: string; //数据代码 |
| | | dataKtv: number; //KTV |
| | | dataMedPeriod: number; //透析时间(小时) |
| | | dataNiaosu1: number; //透前尿素 |
| | | dataNiaosu2: number; //透后尿素 |
| | | dataUrr: number; //URR |
| | | dataWeight1: number; //透前体重 |
| | | dataWeight2: number; //透后体重 |
| | | id: number; //记录ID |
| | | patientCode: string; //患者编号 |
| | | patientName: string; //患者姓名 |
| | | recordCode: string; //透析单 |
| | | sampleDate: string; //采样日期 |
| | | } |
| | | |
| | | |
| | | export interface IPatientDialysisFrequencyCountParams { |
| | | page: number; |
| | | size: number; |
| | | clientCode: string; |
| | | patientCodes: string[]; |
| | | scheduleTimeSlots: string[]; |
| | | recordsStatus: string; |
| | | startTime: string; |
| | | endTime: string; |
| | | } |
| | | |
| | | |
| | | export interface IPatientDialysisFrequencyCount { |
| | | allCount: string; |
| | | patientCode: string; |
| | | patientName: string; |
| | | typeCounts: IPatientDialysisFrequencyCountTypeCount[]; |
| | | } |
| | | |
| | | export interface IPatientDialysisFrequencyCountTypeCount { |
| | | schemeName: string; |
| | | typeCount: string; |
| | | } |
| | | |
| | | |
| | | export interface IPatientDialysisFrequencyCountRes extends Omit<IComminList, 'list'> { |
| | | list: IPatientDialysisFrequencyCount[]; |
| | | } |
| | | |
| | | export interface IWypertensionStatisticsParams { |
| | | clientCode: string; |
| | | beginTime: string; |
| | | endTime: string; |
| | | } |
| | | |
| | | export interface IQualityControlReportLisResults { |
| | | client_code: string; |
| | | item_name: string; |
| | | item_result: string; |
| | | item_result_flag: string; |
| | | item_result_ref: string; |
| | | item_result_unit: string; |
| | | patient_name: string; |
| | | sample_date: string; |
| | | sample_date_str: string; |
| | | 最新报告日期: string; |
| | | } |
| | | |
| | | |
| | | export interface IWypertensionStatistics { |
| | | 大于60岁患者: IWypertensionStatisticsObj; |
| | | 小于等于60岁患者: IWypertensionStatisticsObj; |
| | | 没有年龄的患者: IWypertensionStatisticsItem[]; |
| | | 透析总人数: number; |
| | | } |
| | | |
| | | export interface IWypertensionStatisticsItem { |
| | | patientCode: string; |
| | | patientName: string; |
| | | preMbpH: string; |
| | | preMbpL: string; |
| | | signTime: string; |
| | | } |
| | | |
| | | export interface IWypertensionStatisticsObj { |
| | | count: number; |
| | | eligiblePatientCount: number; |
| | | eligiblePatients: IWypertensionStatisticsItem[]; |
| | | noEligiblePatientCount: number; |
| | | noEligiblePatients: IWypertensionStatisticsItem[]; |
| | | } |
| | | |
| | | export interface IQualityControlReportParams { |
| | | clientCode: string; |
| | | beginTime: string; |
| | | endTime: string; |
| | | page: number; |
| | | size: number; |
| | | systemItemNames: string; |
| | | } |
| | | |
| | | export interface IQualityControlReport { |
| | | accessFirstUseDate: string; |
| | | age: number; |
| | | code: string; |
| | | dictText: string; |
| | | patientDiagnose: string; |
| | | patientName: string; |
| | | sex: string; |
| | | survivalTime: string; |
| | | lisResults: IQualityControlReportLisResults[]; |
| | | } |
| | | |
| | | export interface IQualityControlReportReponse { |
| | | total: number; |
| | | list: IQualityControlReport[]; |
| | | [key: string]: any; |
| | | } |
| | |
| | | visualizingLinkDemo2: '数据可视化演示2', |
| | | personal: '个人中心', |
| | | tongji:'患者健康服务统计', |
| | | xueqingdanbai:'质控-血清蛋白控制率', |
| | | tools: '工具类集合', |
| | | layoutLinkView: '外链', |
| | | layoutIframeViewOne: '内嵌 iframe1', |
| | |
| | | <el-avatar shape="square" style="width: 48px; height: 35px;background-color: #ffffff;margin-right: 10px;margin-left: 10px;" fit="contain" :src="logo" /> |
| | | |
| | | <div class="titleHome">营养管理系统</div> |
| | | <div style="margin-left: 20px;"> |
| | | <el-dropdown @command="onHandleCommandClick"> |
| | | <span class="el-dropdown-link"> |
| | | 统计帮助 |
| | | <el-icon class="el-icon--right"> |
| | | <arrow-down /> |
| | | </el-icon> |
| | | </span> |
| | | <template #dropdown> |
| | | <el-dropdown-menu> |
| | | <el-dropdown-item command="/tongji">患者健康服务统计</el-dropdown-item> |
| | | <el-dropdown-item command="/zhikong/xueqingdanbai">质控-血清蛋白控制率</el-dropdown-item> |
| | | <!-- <el-dropdown-item>Action 3</el-dropdown-item> |
| | | <el-dropdown-item disabled>Action 4</el-dropdown-item> |
| | | <el-dropdown-item divided>Action 5</el-dropdown-item> --> |
| | | </el-dropdown-menu> |
| | | </template> |
| | | </el-dropdown> |
| | | </div> |
| | | |
| | | |
| | | </div> |
| | | |
| | | </template> |
| | | |
| | | <script setup lang="ts" name="layoutBreadcrumb"> |
| | | import { ArrowDown } from '@element-plus/icons-vue' |
| | | import { reactive, computed, onMounted } from 'vue'; |
| | | import { onBeforeRouteUpdate, useRoute, useRouter } from 'vue-router'; |
| | | import { Local } from '/@/utils/storage'; |
| | |
| | | if (state.breadcrumbList.length > 0) |
| | | state.breadcrumbList[state.breadcrumbList.length - 1].meta.tagsViewName = other.setTagsViewNameI18n(<RouteToFrom>route); |
| | | }; |
| | | // 下拉菜单点击时 |
| | | const onHandleCommandClick = (path: string) => { |
| | | router.push(path); |
| | | }; |
| | | // 页面加载时 |
| | | onMounted(() => { |
| | | initRouteSplit(route.path); |
| | |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .example-showcase .el-dropdown-link { |
| | | cursor: pointer; |
| | | color: var(--el-color-primary); |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | .layout-navbars-breadcrumb { |
| | | flex: 1; |
| | | height: inherit; |
| | |
| | | |
| | | <Horizontal :menuList="state.menuList" v-if="isLayoutTransverse" /> |
| | | <User /> |
| | | |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | const User = defineAsyncComponent(() => import('/@/layout/navBars/topBar/user.vue')); |
| | | const Logo = defineAsyncComponent(() => import('/@/layout/logo/index.vue')); |
| | | const Horizontal = defineAsyncComponent(() => import('/@/layout/navMenu/horizontal.vue')); |
| | | const setings = defineAsyncComponent(() => import('/@/layout/navBars/topBar/setings.vue')); |
| | | |
| | | // 定义变量内容 |
| | | const stores = useRoutesList(); |
| | |
| | | }, |
| | | }, |
| | | { |
| | | path: '/zhikong/xueqingdanbai', |
| | | name: 'xueqingdanbai', |
| | | component: () => import('/@/views/zhikong/xueqingdanbai.vue'), |
| | | meta: { |
| | | title: 'message.router.xueqingdanbai', |
| | | isLink: '', |
| | | isHide: false, |
| | | isKeepAlive: true, |
| | | isAffix: false, |
| | | isIframe: false, |
| | | roles: ['admin', 'common'], |
| | | icon: 'iconfont icon-gerenzhongxin', |
| | | }, |
| | | }, |
| | | { |
| | | path: '/tools', |
| | | name: 'tools', |
| | | component: () => import('/@/views/tools/index.vue'), |
| New file |
| | |
| | | import FileSaver from 'file-saver' |
| | | import * as XLSX from 'xlsx' |
| | | // 自动计算col列宽 |
| | | function auto_width(ws, data) { |
| | | /*set worksheet max width per col*/ |
| | | const colWidth = data.map(row => row.map(val => { |
| | | /*if null/undefined*/ |
| | | if (val == null) { |
| | | return { 'wch': 10 } |
| | | } |
| | | /*if chinese*/ |
| | | else if (val.toString().charCodeAt(0) > 255) { |
| | | return { 'wch': val.toString().length * 2 } |
| | | } else { |
| | | return { 'wch': val.toString().length } |
| | | } |
| | | })) |
| | | /*start in the first row*/ |
| | | let result = colWidth[0] |
| | | for (let i = 1; i < colWidth.length; i++) { |
| | | for (let j = 0; j < colWidth[i].length; j++) { |
| | | if (result[j]['wch'] < colWidth[i][j]['wch']) { |
| | | result[j]['wch'] = colWidth[i][j]['wch'] |
| | | } |
| | | } |
| | | } |
| | | ws['!cols'] = result |
| | | } |
| | | // 将json数据转换成数组 |
| | | function json_to_array(key, jsonData) { |
| | | return jsonData.map(v => key.map(j => { |
| | | return v[j] |
| | | })) |
| | | } |
| | | /** |
| | | * @param header Object,表头 |
| | | * @param data Array,表体数据 |
| | | * @param key Array,字段名 |
| | | * @param title String,标题(会居中显示),即excel表格第一行 |
| | | * @param filename String,文件名 |
| | | * @param autoWidth Boolean,是否自动根据key自定义列宽度 |
| | | */ |
| | | export const exportJsonToExcel = ({ |
| | | header, |
| | | data, |
| | | key, |
| | | title, |
| | | filename, |
| | | autoWidth |
| | | }) => { |
| | | const wb = XLSX.utils.book_new() |
| | | if (header) { |
| | | data.unshift(header) |
| | | } |
| | | if (title) { |
| | | data.unshift(title) |
| | | } |
| | | const ws = XLSX.utils.json_to_sheet(data, { |
| | | header: key, |
| | | skipHeader: true |
| | | }) |
| | | // 合并单元格以覆盖整个第一行 |
| | | // ws['!merges'] = [{ s: {r:0, c:0}, e: {r:0, c:header.length - 1} }]; |
| | | if (autoWidth) { |
| | | const arr = json_to_array(key, data) |
| | | auto_width(ws, arr) |
| | | } |
| | | XLSX.utils.book_append_sheet(wb, ws, filename) |
| | | XLSX.writeFile(wb, filename + '.xlsx') |
| | | } |
| | | |
| | | /** |
| | | * 自动计算并设置列宽 |
| | | * @param {Object} ws - 工作表对象 |
| | | * @param {Array} data - 表格数据(二维数组) |
| | | */ |
| | | function autoWidth(ws, data) { |
| | | // 初始化每列宽度为默认值10 |
| | | const colWidths = Array(data[0].length).fill(10); |
| | | |
| | | // 遍历数据以计算最大宽度 |
| | | data.forEach(row => { |
| | | row.forEach((val, index) => { |
| | | let length = val ? (typeof val === 'string' ? getStrLen(val) : String(val).length) : 10; |
| | | if (colWidths[index] < length) { |
| | | colWidths[index] = length; // 更新最大宽度 |
| | | }else{ |
| | | colWidths[index] = 20; // 更新最大宽度 |
| | | } |
| | | }); |
| | | }); |
| | | |
| | | // 设置列宽 |
| | | ws['!cols'] = colWidths.map(width => ({ wch: width })); |
| | | } |
| | | /** |
| | | * 计算字符串长度,考虑多字节字符(如中文) |
| | | * @param {string} str - 输入字符串 |
| | | * @returns {number} 字符串长度 |
| | | */ |
| | | function getStrLen(str) { |
| | | return [...str].reduce((len, char) => len + (char.charCodeAt(0) > 255 ? 2 : 1), 0); |
| | | } |
| | | export const exportTableToExcel=(divId:string,name:string)=>{ |
| | | var wb = XLSX.utils.table_to_book(document.querySelector(divId));//关联dom节点 |
| | | console.log(wb) |
| | | // 获取第一个工作表 |
| | | const ws = wb.Sheets[wb.SheetNames[0]]; |
| | | |
| | | // 获取表格数据作为二维数组 |
| | | const data = XLSX.utils.sheet_to_json(ws, { header: 1 }); |
| | | |
| | | // 设置列宽 |
| | | autoWidth(ws, data); |
| | | var wbout = XLSX.write(wb, { |
| | | bookType: 'xlsx', |
| | | bookSST: true, |
| | | type: 'array' |
| | | }) |
| | | try { |
| | | FileSaver.saveAs(new Blob([wbout], { |
| | | type: 'application/octet-stream' |
| | | }), `${name}.xlsx`)//自定义文件名 |
| | | } catch (e) { |
| | | if (typeof console !== 'undefined') console.log(e, wbout); |
| | | } |
| | | return wbout |
| | | } |
| | | |
| | | export const exportTableToExcel2 = async (divId: string, name: string): Promise<Uint8Array | null> => { |
| | | try { |
| | | // 关联 DOM 节点 |
| | | const tableElement = document.querySelector(divId); |
| | | if (!tableElement) { |
| | | console.error("Table element not found"); |
| | | return null; |
| | | } |
| | | |
| | | // 转换表格为工作簿 |
| | | const wb = XLSX.utils.table_to_book(tableElement); |
| | | console.log(wb); |
| | | |
| | | // 将工作簿写入文件 |
| | | const wbout = XLSX.write(wb, { |
| | | bookType: 'xlsx', |
| | | bookSST: true, |
| | | type: 'array', |
| | | }); |
| | | |
| | | // 保存文件 |
| | | await new Promise<void>((resolve, reject) => { |
| | | try { |
| | | FileSaver.saveAs( |
| | | new Blob([wbout], { type: 'application/octet-stream' }), |
| | | `${name}.xlsx` |
| | | ); |
| | | resolve(); |
| | | } catch (e) { |
| | | console.error("Error saving file:", e); |
| | | reject(e); |
| | | } |
| | | }); |
| | | |
| | | // 返回生成的二进制数组 |
| | | return wbout; |
| | | } catch (error) { |
| | | console.error("Error exporting table to Excel:", error); |
| | | return null; |
| | | } |
| | | }; |
| | | export default { |
| | | exportJsonToExcel, |
| | | exportTableToExcel |
| | | } |
| | |
| | | <el-form-item> |
| | | <el-button type="primary" @click="onSubmit">查询</el-button> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="success" @click="daochuExcel">导出</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <div class="scrollable-table" :style="{maxHeight:tableHe}"> |
| | |
| | | import {nutritionalSummary} from '/@/api/Patients' |
| | | import {editUserInfo} from '/@/api/login' |
| | | import { ElLoading } from 'element-plus'; |
| | | import * as XLSX from 'xlsx'; |
| | | import {formatDate} from '/@/utils/formatTime' |
| | | const stores = useUserInfo(); |
| | | const { userInfos } = storeToRefs(stores); |
| | |
| | | }, |
| | | dialogTableVisible:false |
| | | }) |
| | | const daochuExcel=()=>{ |
| | | let table = document.getElementById('tabledome'); |
| | | if (table) { |
| | | const wb = XLSX.utils.table_to_book(table, { sheet: "Sheet1" }); |
| | | XLSX.writeFile(wb, "患者健康服务统计.xlsx"); // 文件名和扩展名可以根据需要更改 |
| | | } else { |
| | | console.error("找不到指定的表格"); |
| | | } |
| | | } |
| | | const onSubmit=()=>{ |
| | | const pasm={ |
| | | startTime:state.formInline.date[0]+ ' 00:00:00', |
| | |
| | | queryValue:'' |
| | | } |
| | | console.log(pasm) |
| | | const loading = ElLoading.service({ |
| | | lock: true, |
| | | text: 'Loading', |
| | | background: 'rgba(0, 0, 0, 0.7)', |
| | | }) |
| | | nutritionalSummary(pasm).then(re=>{ |
| | | console.log(re.data) |
| | | state.tableData=re.data |
| | | }).finally(()=>{ |
| | | loading.close() |
| | | }) |
| | | |
| | | } |
| New file |
| | |
| | | <template> |
| | | <el-row class="control_rate_container"> |
| | | <el-col :span="24" class="card_box card_box_search"> |
| | | <el-form :model="searchForm" size="small" inline> |
| | | <el-form-item label="查询日期"> |
| | | <el-date-picker |
| | | v-model="searchForm.dates" |
| | | type="daterange" |
| | | unlink-panels |
| | | range-separator="至" |
| | | start-placeholder="开始日期" |
| | | end-placeholder="结束日期" |
| | | :clearable="false" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="透析龄"> |
| | | <el-select v-model="searchForm.medMonth" placeholder="透析龄"> |
| | | <el-option label="全部" :value="0" /> |
| | | <el-option label=">=三个月" :value="1" /> |
| | | <el-option label="<三个月" :value="2" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="转归状态"> |
| | | <el-select v-model="searchForm.isInState" placeholder="转归状态"> |
| | | <el-option label="不限" :value="0" /> |
| | | <el-option label="在院" :value="1" /> |
| | | <el-option label="转出" :value="2" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item v-if="!isBloodPressure" label="标准值设定" prop=""> |
| | | <el-row> |
| | | <span :span="8"> |
| | | <el-input style="width: 150px" v-model="searchForm.limitBottom" @input="limitBottomInp"></el-input> |
| | | </span> |
| | | <span :span="8">≤标准值≤</span> |
| | | <span :span="8"> |
| | | <el-input style="width: 150px" v-model="searchForm.limitTop" @input="limitTopInp"></el-input> |
| | | </span> |
| | | </el-row> |
| | | </el-form-item> |
| | | <template v-else> |
| | | <el-form-item label="收缩压标准值设定" prop=""> |
| | | <el-row> |
| | | <span :span="8"> |
| | | <el-input style="width: 150px" v-model="searchForm.limitBottom" @input="limitBottomInp"></el-input> |
| | | </span> |
| | | <span :span="8">≤标准值≤</span> |
| | | <span :span="8"> |
| | | <el-input style="width: 150px" v-model="searchForm.limitTop" @input="limitTopInp"></el-input> |
| | | </span> |
| | | </el-row> |
| | | </el-form-item> |
| | | <el-form-item label="舒张压标准值设定" prop=""> |
| | | <el-row> |
| | | <span :span="8"> |
| | | <el-input style="width: 150px" v-model="searchForm.limitBplBottom" @input="limitBottomInp2"></el-input> |
| | | </span> |
| | | <span :span="8">≤标准值≤</span> |
| | | <span :span="8"> |
| | | <el-input style="width: 150px" v-model="searchForm.limitBplTop" @input="limitTopInp2"></el-input> |
| | | </span> |
| | | </el-row> |
| | | </el-form-item> |
| | | </template> |
| | | <el-form-item label="年龄标准值设定" prop=""> |
| | | <el-row> |
| | | <span :span="8"> |
| | | <el-input style="width: 150px" v-model="searchForm.limitAgeBottom" type="number"></el-input> |
| | | </span> |
| | | <span :span="8">≤标准值≤</span> |
| | | <span :span="8"> |
| | | <el-input style="width: 150px" v-model="searchForm.limitAgeTop" type="number"></el-input> |
| | | </span> |
| | | </el-row> |
| | | </el-form-item> |
| | | <el-form-item label="是否只展示最后一次结果"> |
| | | <el-switch v-model="searchForm.是否只展示最后一次结果" :active-value="1" :inactive-value="0" /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button size="small" :loading="loading" @click="onClickSearch" type="success"> |
| | | <el-icon><Search /></el-icon> |
| | | 查询</el-button |
| | | > |
| | | <slot name="right"></slot> |
| | | </el-form-item> |
| | | <el-form-item></el-form-item> |
| | | </el-form> |
| | | </el-col> |
| | | <el-col :span="24" v-loading="loading"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <div class="container_l" :style="{ height: tableHeight + 'px', 'min-height': '520px' }"> |
| | | <div v-loading="loading" ref="myEchartsRef" style="height: 500px; width: 100%; padding-top: 10px"></div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <div class="container_r" :style="{ height: tableHeight + 'px', 'min-height': '520px' }"> |
| | | <div class="untested_patients_box" v-if="untestedPatients.length > 0"> |
| | | <div class="untested_patients_header">未检测人员</div> |
| | | <div class="untested_patients_conter"> |
| | | {{ untestedPatients.join('、') }} |
| | | </div> |
| | | </div> |
| | | <div class="status_type_nav"> |
| | | <span |
| | | v-for="(item, index) in statusTypeOptions" |
| | | :key="index" |
| | | :class="[statusType === item.value ? 'select_type' : '']" |
| | | @click="onClickByStatusChange(item)" |
| | | > |
| | | {{ item.label }} |
| | | </span> |
| | | </div> |
| | | <el-table |
| | | v-if="tableHeight > 0" |
| | | v-loading="loading" |
| | | id="exportTbale" |
| | | :row-class-name="rowClassName" |
| | | :data="patTableData" |
| | | :height="untestedPatients.length > 0 ? tableHeight - 210 : tableHeight" |
| | | border |
| | | style="width: 100%" |
| | | > |
| | | <el-table-column prop="sampleDate" label="检验日期"> |
| | | <template #default="scope"> |
| | | {{ scope.row.sampleDate.substring(0, 11) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="patientName" label="患者姓名" /> |
| | | <el-table-column prop="itemResult" :label="defaultNameAndUnit" /> |
| | | </el-table> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | </el-col> |
| | | </el-row> |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | | import { ElMessage } from 'element-plus'; |
| | | import { defineComponent, reactive, toRefs, ref, onMounted, getCurrentInstance, watch } from 'vue'; |
| | | import { storeToRefs } from 'pinia'; |
| | | import { useUserInfo } from '/@/stores/userInfo'; |
| | | import { formatDate } from '/@/utils/formatTime'; |
| | | import { doStatByResult } from '/@/api/QC'; |
| | | import * as echarts from 'echarts'; |
| | | const stores = useUserInfo(); |
| | | const { userInfos } = storeToRefs(stores); |
| | | const end = new Date(); |
| | | const start = new Date(); |
| | | start.setTime(start.getTime() - 3600 * 1000 * 24 * 30); |
| | | |
| | | interface IDefDatas { |
| | | title: string; |
| | | itemName: string; |
| | | defaultNameAndUnit: string; |
| | | subTit: string; |
| | | whereFrom?: Partial<{ |
| | | itemName: string; |
| | | medMonth: number; |
| | | isInState: number; |
| | | statType: number; |
| | | limitBottom: string | number; |
| | | limitTop: string | number; |
| | | filterStyle: number; |
| | | dates: [Date, Date]; |
| | | attendingDoctor: ''; |
| | | 是否只展示最后一次结果: 0 | 1; |
| | | }>; |
| | | isBloodPressure?: boolean; |
| | | } |
| | | export default defineComponent({ |
| | | name: 'ControlRate', |
| | | setup() { |
| | | const { proxy } = getCurrentInstance() as any; |
| | | const myEchartsRef = ref(); |
| | | |
| | | const state = reactive({ |
| | | loading: false, |
| | | tableHeight: 0, |
| | | title: '', |
| | | itemName: '', |
| | | defaultNameAndUnit: '', |
| | | subTit: '', |
| | | patList: [], |
| | | untestedPatients: [], |
| | | dabaio: true, |
| | | budabaio: false, |
| | | searchForm: { |
| | | itemName: '', |
| | | medMonth: 0, |
| | | isInState: 1, |
| | | statType: 0, |
| | | limitBottom: '', |
| | | limitTop: '', |
| | | // filterStyle: 0, |
| | | dates: [start, end], |
| | | attendingDoctor: '', // 主治医师 |
| | | 是否只展示最后一次结果: 0, |
| | | limitBplBottom: null, |
| | | limitBplTop: null, |
| | | limitAgeBottom: null, |
| | | limitAgeTop: null, |
| | | }, |
| | | patTableData: [], |
| | | statusType: 0, |
| | | statusTypeOptions: [ |
| | | { label: '全部', value: 0 }, |
| | | { label: '达标', value: 1 }, |
| | | { label: '不达标', value: 2 }, |
| | | ], |
| | | doctorOptions: [], |
| | | isBloodPressure: false, // 是否是血压 |
| | | }); |
| | | |
| | | // 监听 searchForm.limitBottom 的变化,确保 Vue 的双向绑定正常工作 |
| | | // watch(() => state.searchForm.limitBottom, (newValue) => { |
| | | // if (newValue === '' || Number(newValue) < 0) { |
| | | // state.searchForm.limitBottom = ''; |
| | | // } else { |
| | | // // @ts-ignore |
| | | // state.searchForm.limitBottom = Number(newValue); |
| | | // } |
| | | // }); |
| | | |
| | | const onClickByStatusChange = (item: { label: string; value: number }) => { |
| | | state.statusType = item.value; |
| | | if (item.value === 0) { |
| | | state.patTableData = [...state.patList]; |
| | | } else if (item.value === 1) { |
| | | state.patTableData = state.patList.filter((e) => e.是否达标); |
| | | } else if (item.value === 2) { |
| | | state.patTableData = state.patList.filter((e) => !e.是否达标); |
| | | } |
| | | }; |
| | | |
| | | /** 查询 */ |
| | | const onClickSearch = async () => { |
| | | if (isNaN(+state.searchForm.limitBottom) || isNaN(+state.searchForm.limitTop)) return ElMessage.warning('标准值仅可为大于等于0的数值'); |
| | | if (+state.searchForm.limitBottom < 0 || +state.searchForm.limitTop < 0) return ElMessage.warning('标准值不能小于0'); |
| | | state.loading = true; |
| | | try { |
| | | await getDatas(); |
| | | } finally { |
| | | state.loading = false; |
| | | } |
| | | }; |
| | | |
| | | // /** 导出 */ |
| | | // const onClickExportExcel = () => { |
| | | // exportTableToExcel('#exportTbale', state.title); |
| | | // }; |
| | | |
| | | const setTableHeight = () => { |
| | | let height = document.documentElement.clientHeight; |
| | | |
| | | const navDom = document.querySelector('.layout-header'); |
| | | if (navDom) { |
| | | height -= navDom.scrollHeight; |
| | | } |
| | | |
| | | const demoFormDom = document.querySelector('.card_box_search'); |
| | | |
| | | if (demoFormDom) { |
| | | height -= demoFormDom.scrollHeight; |
| | | } |
| | | |
| | | height = height - 40; |
| | | state.tableHeight = height; |
| | | }; |
| | | |
| | | const initCompData = async (objData: IDefDatas) => { |
| | | state.loading = true; |
| | | try { |
| | | const { title, itemName, defaultNameAndUnit, subTit, whereFrom, isBloodPressure } = objData; |
| | | state.title = title; |
| | | state.itemName = itemName; |
| | | state.defaultNameAndUnit = defaultNameAndUnit; |
| | | state.subTit = subTit; |
| | | state.isBloodPressure = !!isBloodPressure; |
| | | if (whereFrom) { |
| | | Object.keys(whereFrom).forEach((k) => { |
| | | state.searchForm[k] = whereFrom[k]; |
| | | }); |
| | | } |
| | | const primaseFuns = [getDatas()]; |
| | | await Promise.all(primaseFuns); |
| | | await getDatas(); |
| | | } catch (error) { |
| | | // ElMessage.error('系统异常,请联系管理员:' + error); |
| | | console.error('xxxxxxxxxxx:', error); |
| | | } finally { |
| | | state.loading = false; |
| | | } |
| | | }; |
| | | |
| | | const getDatas = async () => { |
| | | const params = { |
| | | clientCode: userInfos.value.clientCode, |
| | | dateBegin: formatDate(state.searchForm.dates[0], 'YYYY-mm-dd') + ' 00:00:00', |
| | | dateEnd: formatDate(state.searchForm.dates[1], 'YYYY-mm-dd') + ' 23:59:59', |
| | | itemName: state.itemName, |
| | | medMonth: state.searchForm.medMonth, |
| | | isInState: state.searchForm.isInState, |
| | | statType: state.searchForm.statType, |
| | | limitBottom: state.searchForm.limitBottom, |
| | | limitTop: state.searchForm.limitTop, |
| | | // filterStyle: state.searchForm.filterStyle, |
| | | attendingDoctor: state.searchForm.attendingDoctor, |
| | | 是否只展示最后一次结果: state.searchForm.是否只展示最后一次结果, |
| | | limitBplBottom: state.searchForm.limitBplBottom, |
| | | limitBplTop: state.searchForm.limitBplTop, |
| | | limitAgeBottom: state.searchForm.limitAgeBottom, |
| | | limitAgeTop: state.searchForm.limitAgeTop, |
| | | }; |
| | | const { data } = await doStatByResult(params); |
| | | state.defaultNameAndUnit = data.itemUnit ? `${state.subTit}(${data.itemUnit})` : state.defaultNameAndUnit; |
| | | state.patList = data.statItemResults.slice().sort(compareDates); |
| | | if (state.statusType === 0) { |
| | | state.patTableData = [...state.patList]; |
| | | } else if (state.statusType === 1) { |
| | | state.patTableData = state.patList.filter((e) => e.是否达标); |
| | | } else if (state.statusType === 2) { |
| | | state.patTableData = state.patList.filter((e) => !e.是否达标); |
| | | } |
| | | state.untestedPatients = data.未检测患者列表; |
| | | initEcharts( |
| | | data.statDetail.map((v) => { |
| | | v.tooltip = { |
| | | formatter: '{a}<br />{b}: ({c})({d}%)', |
| | | }; |
| | | return v; |
| | | }) |
| | | ); |
| | | }; |
| | | |
| | | const initEcharts = (listdata: any) => { |
| | | //先获取Dom上的实例 |
| | | if (echarts) { |
| | | let myChart = echarts?.getInstanceByDom(proxy.$refs.myEchartsRef as HTMLDivElement); |
| | | //然后判断实例是否存在,如果不存在,就创建新实例 |
| | | if (myChart == null) { |
| | | myChart = echarts.init(proxy.$refs.myEchartsRef as HTMLDivElement); |
| | | } |
| | | const option = { |
| | | title: { |
| | | text: state.title, |
| | | subtext: `${formatDate(state.searchForm.dates[0], 'YYYY-mm-dd')}-${formatDate(state.searchForm.dates[1], 'YYYY-mm-dd')}`, |
| | | left: 'center', |
| | | }, |
| | | tooltip: { |
| | | trigger: 'item', |
| | | }, |
| | | legend: { |
| | | orient: 'vertical', |
| | | left: 'top', |
| | | }, |
| | | color: ['#5470c6', '#fc8251', '#91cd77', '#ef6567', '#f9c956', '#75bedc'], |
| | | series: [ |
| | | { |
| | | name: state.subTit, |
| | | type: 'pie', |
| | | radius: '70%', |
| | | // avoidLabelOverlap: false, |
| | | label: { |
| | | show: true, |
| | | overflow: 'break', |
| | | position: 'outer', |
| | | alignTo: 'none', |
| | | edgeDistance: '25%', |
| | | bleedMargin: 10, |
| | | distanceToLabelLine: 5, |
| | | formatter(param) { |
| | | return param.name + ' (' + param.value + ')' + ' (' + param.percent * 1 + '%)'; |
| | | }, |
| | | }, |
| | | emphasis: { |
| | | itemStyle: { |
| | | shadowBlur: 10, |
| | | shadowOffsetX: 0, |
| | | shadowColor: 'rgba(0, 0, 0, 0.5)', |
| | | }, |
| | | }, |
| | | labelLine: { |
| | | show: false, |
| | | }, |
| | | data: listdata, |
| | | }, |
| | | ], |
| | | }; |
| | | myChart.setOption(option); |
| | | myChart.on('legendselectchanged', function (event) { |
| | | // @ts-ignore |
| | | if (event.name === '不达标的患者人数') { |
| | | state.dabaio = !state.dabaio; |
| | | // @ts-ignore |
| | | } else if (event.name === '达标患者人数') { |
| | | state.budabaio = !state.budabaio; |
| | | } |
| | | // 在这里可以根据需要处理点击图例的逻辑 |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | const compareDates = (a, b) => { |
| | | const dateA = new Date(a.sampleDate); |
| | | const dateB = new Date(b.sampleDate); |
| | | // @ts-ignore |
| | | return dateA - dateB; // 升序排序 |
| | | }; |
| | | |
| | | const rowClassName = ({ row }) => { |
| | | if (row.是否达标 === state.dabaio && row.是否达标 === state.budabaio) { |
| | | return 'hidden-row'; |
| | | } |
| | | return ''; |
| | | }; |
| | | |
| | | const limitBottomInp = () => { |
| | | let newValue = state.searchForm.limitBottom; |
| | | |
| | | // 过滤掉非法字符,允许数字和小数点 |
| | | newValue = newValue.replace(/[^0-9.]/g, ''); |
| | | |
| | | // 确保第一个字符不是小数点 |
| | | if (newValue.startsWith('.')) { |
| | | newValue = '0' + newValue; |
| | | } |
| | | |
| | | // 确保只有一个小数点 |
| | | newValue = newValue.replace(/(\..*)\./g, '$1'); |
| | | |
| | | // 如果值为空或小于等于0,清空输入框 |
| | | if (newValue !== '' && parseFloat(newValue) < 0) { |
| | | newValue = ''; |
| | | } |
| | | state.searchForm.limitBottom = newValue; |
| | | }; |
| | | |
| | | const limitTopInp = () => { |
| | | let newValue = state.searchForm.limitTop; |
| | | |
| | | // 过滤掉非法字符,允许数字和小数点 |
| | | newValue = newValue.replace(/[^0-9.]/g, ''); |
| | | |
| | | // 确保第一个字符不是小数点 |
| | | if (newValue.startsWith('.')) { |
| | | newValue = '0' + newValue; |
| | | } |
| | | |
| | | // 确保只有一个小数点 |
| | | newValue = newValue.replace(/(\..*)\./g, '$1'); |
| | | |
| | | // 如果值为空或小于等于0,清空输入框 |
| | | if (newValue !== '' && parseFloat(newValue) < 0) { |
| | | newValue = ''; |
| | | } |
| | | state.searchForm.limitTop = newValue; |
| | | }; |
| | | |
| | | const limitBottomInp2 = () => { |
| | | let newValue = state.searchForm.limitBplBottom; |
| | | |
| | | // 过滤掉非法字符,允许数字和小数点 |
| | | newValue = newValue.replace(/[^0-9.]/g, ''); |
| | | |
| | | // 确保第一个字符不是小数点 |
| | | if (newValue.startsWith('.')) { |
| | | newValue = '0' + newValue; |
| | | } |
| | | |
| | | // 确保只有一个小数点 |
| | | newValue = newValue.replace(/(\..*)\./g, '$1'); |
| | | |
| | | // 如果值为空或小于等于0,清空输入框 |
| | | if (newValue !== '' && parseFloat(newValue) < 0) { |
| | | newValue = ''; |
| | | } |
| | | state.searchForm.limitBplBottom = newValue; |
| | | }; |
| | | |
| | | const limitTopInp2 = () => { |
| | | let newValue = state.searchForm.limitBplTop; |
| | | |
| | | // 过滤掉非法字符,允许数字和小数点 |
| | | newValue = newValue.replace(/[^0-9.]/g, ''); |
| | | |
| | | // 确保第一个字符不是小数点 |
| | | if (newValue.startsWith('.')) { |
| | | newValue = '0' + newValue; |
| | | } |
| | | |
| | | // 确保只有一个小数点 |
| | | newValue = newValue.replace(/(\..*)\./g, '$1'); |
| | | |
| | | // 如果值为空或小于等于0,清空输入框 |
| | | if (newValue !== '' && parseFloat(newValue) < 0) { |
| | | newValue = ''; |
| | | } |
| | | state.searchForm.limitBplTop = newValue; |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | setTableHeight(); |
| | | }); |
| | | |
| | | return { |
| | | ...toRefs(state), |
| | | myEchartsRef, |
| | | rowClassName, |
| | | onClickSearch, |
| | | initCompData, |
| | | onClickByStatusChange, |
| | | limitBottomInp, |
| | | limitTopInp, |
| | | limitBottomInp2, |
| | | limitTopInp2, |
| | | }; |
| | | }, |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .control_rate_container { |
| | | .card_box { |
| | | padding: 15px; |
| | | background: #fff; |
| | | padding-bottom: 0; |
| | | &.card_box_search { |
| | | padding-bottom: 0; |
| | | margin-bottom: 10px; |
| | | } |
| | | } |
| | | .sum_count { |
| | | padding-right: 20px; |
| | | line-height: 40px; |
| | | font-size: 14px; |
| | | font-weight: bold; |
| | | text-align: right; |
| | | color: #67c23a; |
| | | } |
| | | |
| | | .container_l, |
| | | .container_r { |
| | | background: #fff; |
| | | overflow-y: auto; |
| | | .untested_patients_box { |
| | | background-color: #fff; |
| | | padding: 10px; |
| | | .untested_patients_header { |
| | | text-align: center; |
| | | font-weight: bold; |
| | | background: #409eff; |
| | | color: #fff; |
| | | line-height: 40px; |
| | | } |
| | | .untested_patients_conter { |
| | | padding: 20px; |
| | | max-height: 200px; |
| | | overflow: hidden; |
| | | overflow-y: auto; |
| | | } |
| | | } |
| | | } |
| | | .status_type_nav { |
| | | display: flex; |
| | | align-items: center; |
| | | padding-top: 20px; |
| | | span { |
| | | background: #fff; |
| | | color: #333; |
| | | padding: 8px 14px; |
| | | font-size: 14px; |
| | | border-radius: 5px 5px 0 0; |
| | | box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.12); |
| | | transition: 0.3s; |
| | | &:hover { |
| | | cursor: pointer; |
| | | background: #92c3f5; |
| | | color: #fff; |
| | | } |
| | | &.select_type { |
| | | background-color: #409eff; |
| | | color: #fff; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .xuedanbai { |
| | | .el-table .hidden-row { |
| | | display: none; |
| | | } |
| | | .chaxun { |
| | | padding-left: 10px; |
| | | padding-top: 10px; |
| | | padding-bottom: -10px; |
| | | background: #ffffff; |
| | | box-shadow: -1px 1px 6px 1px rgba(207, 212, 218, 0.5); |
| | | border-radius: 0px 4px 4px 4px; |
| | | } |
| | | .bodyclass { |
| | | background: #ffffff; |
| | | box-shadow: -1px 1px 6px 1px rgba(207, 212, 218, 0.5); |
| | | border-radius: 0px 4px 4px 4px; |
| | | } |
| | | /*在谷歌下移除input[number]的上下箭头*/ |
| | | .inputNumber input[type='number']::-webkit-outer-spin-button, |
| | | .inputNumber input[type='number']::-webkit-inner-spin-button { |
| | | -webkit-appearance: none !important; |
| | | margin: 0; |
| | | } |
| | | /*在firefox下移除input[number]的上下箭头*/ |
| | | .inputNumber input[type='number'] { |
| | | -moz-appearance: textfield; |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | <template> |
| | | <ControlRate ref="controlRateRef" /> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { ref, onMounted } from 'vue'; |
| | | import ControlRate from './components/components.vue'; |
| | | |
| | | const controlRateRef = ref(); |
| | | |
| | | onMounted(() => { |
| | | const end = new Date(); |
| | | const start = new Date(); |
| | | start.setTime(start.getTime() - 3600 * 1000 * 24 * 30); |
| | | controlRateRef.value && |
| | | controlRateRef.value.initCompData({ |
| | | title: '血清白蛋白控制率', |
| | | itemName: '白蛋白', |
| | | defaultNameAndUnit: '血清白蛋白(g/L)', |
| | | subTit: '血清白蛋白', |
| | | whereFrom: { |
| | | itemName: '', |
| | | medMonth: 0, |
| | | isInState: 1, |
| | | statType: 0, |
| | | limitBottom: 35, |
| | | // filterStyle: 0, |
| | | limitTop: '', |
| | | dates: [start, end], |
| | | }, |
| | | }); |
| | | }); |
| | | </script> |
| | | |
| | | <style> |
| | | </style> |