Compare commits
75 Commits
master
...
72581466aa
| Author | SHA1 | Date | |
|---|---|---|---|
| 72581466aa | |||
|
|
4b3471df06 | ||
|
|
68c65ae8bd | ||
| 1b879addc7 | |||
|
|
3888859b2b | ||
|
|
f03d2e1633 | ||
| bc91eb7cdc | |||
|
|
93120e973a | ||
| c6a27f6276 | |||
| 778704c9dc | |||
| ff227b40c1 | |||
| c7d8ab5b48 | |||
| 9c27b2a134 | |||
|
|
3f919188d2 | ||
| 8942058972 | |||
|
|
6c2dbf0418 | ||
|
|
85e185bab8 | ||
|
|
88aa1517ef | ||
|
|
c05118c427 | ||
|
|
2a7f1326b9 | ||
|
|
c07255fe5b | ||
|
|
749bfc89dd | ||
| 52cc5e3aae | |||
| 642c4a0941 | |||
| 30953d5771 | |||
| 83e0c663c9 | |||
| b19337e76a | |||
| ba607346bd | |||
|
|
433c452a40 | ||
|
|
a1be7fdbfd | ||
|
|
87409d0c93 | ||
| d5c8ae8d45 | |||
| bc45e9c8c6 | |||
|
|
42992382c0 | ||
|
|
22d7eba510 | ||
| 9728c8a6dd | |||
| c951144ac6 | |||
|
|
0b179fffd6 | ||
|
|
75374ac5d3 | ||
|
|
2a83719b87 | ||
|
|
e58f2d807b | ||
|
|
b2884def17 | ||
|
|
064840dd42 | ||
| 1aa814c766 | |||
|
|
b9719a51d1 | ||
|
|
03b83aaf7c | ||
|
|
d93976483b | ||
| dd0a3a915c | |||
| 2f3994c575 | |||
| daa78e128f | |||
| 2ca594cb39 | |||
|
|
7805c26f4a | ||
|
|
b7d34537c2 | ||
| c1213fcf59 | |||
| a64edace55 | |||
| 4afe0d107c | |||
|
|
d8af11412f | ||
|
|
00816c9834 | ||
|
|
4fb7bea80a | ||
|
|
0fc72cb270 | ||
|
|
eadf521903 | ||
| f786fdbc3f | |||
| 92c4c938a3 | |||
|
|
a94a1b7b69 | ||
|
|
48755c2d9e | ||
|
|
f99f8eb560 | ||
|
|
ddc7ce2fe7 | ||
|
|
c9899c62d2 | ||
| 8b9837d7dc | |||
| 2cba41331a | |||
| 4da5ca427b | |||
| f4605b1af7 | |||
|
|
d2babdc9ed | ||
| 4d0599eac1 | |||
|
|
35d99df274 |
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
天天开源的前⾝是新致开源,最早于2022年6⽉发布开源医疗软件平台OpenHIS.org.cn,于2023年6⽉发布开源企业软件平台OpenCOM.com.cn。2025年7⽉,新致开源品牌更新为天天开源,我们始终秉持开源、专业、协作的理念,致⼒于为医疗、教育、中⼩企业等⾏业提供优质的开源解决⽅案。
|
天天开源的前⾝是新致开源,最早于2022年6⽉发布开源医疗软件平台OpenHIS.org.cn,于2023年6⽉发布开源企业软件平台OpenCOM.com.cn。2025年7⽉,新致开源品牌更新为天天开源,我们始终秉持开源、专业、协作的理念,致⼒于为医疗、教育、中⼩企业等⾏业提供优质的开源解决⽅案。
|
||||||
|
|
||||||
了解我们:https://open.tntlinking.com/about?site=gitee
|
了解我们a:https://open.tntlinking.com/about?site=gitee
|
||||||
|
|
||||||
## 💾【部署包下载】
|
## 💾【部署包下载】
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public interface ICommonService {
|
|||||||
/**
|
/**
|
||||||
* 药房列表(库房用)
|
* 药房列表(库房用)
|
||||||
*
|
*
|
||||||
* @return 药房列表
|
* @return 药房列表1
|
||||||
*/
|
*/
|
||||||
List<LocationDto> getInventoryPharmacyList();
|
List<LocationDto> getInventoryPharmacyList();
|
||||||
|
|
||||||
|
|||||||
@@ -161,6 +161,27 @@ public class PurchaseInventoryAppServiceImpl implements IPurchaseInventoryAppSer
|
|||||||
if (receiptDetailList.isEmpty()) {
|
if (receiptDetailList.isEmpty()) {
|
||||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00006, null));
|
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00006, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取所有供应商ID
|
||||||
|
Set<Long> supplierIds = receiptDetailList.stream()
|
||||||
|
.filter(dto -> dto.getSupplierId() != null)
|
||||||
|
.map(ReceiptDetailDto::getSupplierId)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
// 查询供应商信息并设置供应商名称
|
||||||
|
if (!supplierIds.isEmpty()) {
|
||||||
|
List<Supplier> suppliers = supplierService.listByIds(supplierIds);
|
||||||
|
Map<Long, String> supplierNameMap = suppliers.stream()
|
||||||
|
.collect(Collectors.toMap(Supplier::getId, Supplier::getName));
|
||||||
|
|
||||||
|
// 设置供应商名称
|
||||||
|
receiptDetailList.forEach(dto -> {
|
||||||
|
if (dto.getSupplierId() != null) {
|
||||||
|
dto.setSupplierName(supplierNameMap.getOrDefault(dto.getSupplierId(), ""));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return R.ok(receiptDetailList);
|
return R.ok(receiptDetailList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ spring:
|
|||||||
druid:
|
druid:
|
||||||
# 主库数据源
|
# 主库数据源
|
||||||
master:
|
master:
|
||||||
url: jdbc:postgresql://localhost:5432/openhis?currentSchema=public&characterEncoding=UTF-8&client_encoding=UTF-8
|
url: jdbc:postgresql://192.168.110.252:15432/postgresql?currentSchema=public&characterEncoding=UTF-8&client_encoding=UTF-8
|
||||||
username: postgres
|
username: postgresql
|
||||||
password: root
|
password: Jchl1528
|
||||||
# 从库数据源
|
# 从库数据源
|
||||||
slave:
|
slave:
|
||||||
# 从数据源开关/默认关闭
|
# 从数据源开关/默认关闭
|
||||||
@@ -62,13 +62,13 @@ spring:
|
|||||||
# redis 配置
|
# redis 配置
|
||||||
redis:
|
redis:
|
||||||
# 地址
|
# 地址
|
||||||
host: 127.0.0.1
|
host: 192.168.110.252
|
||||||
# 端口,默认为6379
|
# 端口,默认为6379
|
||||||
port: 6379
|
port: 6379
|
||||||
# 数据库索引
|
# 数据库索引
|
||||||
database: 1
|
database: 1
|
||||||
# 密码
|
# 密码
|
||||||
password: redis
|
password: Jchl1528
|
||||||
# 连接超时时间
|
# 连接超时时间
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
lettuce:
|
lettuce:
|
||||||
|
|||||||
@@ -74,12 +74,14 @@
|
|||||||
T2."name" AS item_name,
|
T2."name" AS item_name,
|
||||||
T2.id AS item_id,
|
T2.id AS item_id,
|
||||||
T2.part_percent,
|
T2.part_percent,
|
||||||
T2.manufacturer_text AS supplier_name,
|
T2.manufacturer_text AS manufacturer_text,
|
||||||
T3.total_volume,
|
T3.total_volume,
|
||||||
T5."name" AS practitioner_name,
|
T5."name" AS practitioner_name,
|
||||||
T6."name" AS purpose_location_name,
|
T6."name" AS purpose_location_name,
|
||||||
T6."id" AS purpose_location_id,
|
T6."id" AS purpose_location_id,
|
||||||
T7."name" AS purpose_location_store_name,
|
T7."name" AS purpose_location_store_name,
|
||||||
|
T1.supplier_id AS supplierId,
|
||||||
|
T10."name" AS supplier_name,
|
||||||
T1.occurrence_time,
|
T1.occurrence_time,
|
||||||
(SELECT SUM(T9.quantity)
|
(SELECT SUM(T9.quantity)
|
||||||
FROM wor_inventory_item T9
|
FROM wor_inventory_item T9
|
||||||
@@ -100,6 +102,8 @@
|
|||||||
LEFT JOIN wor_inventory_item T9
|
LEFT JOIN wor_inventory_item T9
|
||||||
ON T1.item_id = T9.item_id
|
ON T1.item_id = T9.item_id
|
||||||
AND T1.purpose_location_id = T9.location_id
|
AND T1.purpose_location_id = T9.location_id
|
||||||
|
LEFT JOIN adm_supplier T10
|
||||||
|
ON T1.supplier_id = T10.id
|
||||||
WHERE T1.bus_no = #{busNo}
|
WHERE T1.bus_no = #{busNo}
|
||||||
AND T1.delete_flag = '0'
|
AND T1.delete_flag = '0'
|
||||||
UNION
|
UNION
|
||||||
@@ -121,12 +125,14 @@
|
|||||||
T8."name" AS item_name,
|
T8."name" AS item_name,
|
||||||
T8.id AS item_id,
|
T8.id AS item_id,
|
||||||
T8.part_percent,
|
T8.part_percent,
|
||||||
T8.manufacturer_text AS supplier_name,
|
T8.manufacturer_text AS manufacturer_text,
|
||||||
T8."size" AS total_volume,
|
T8."size" AS total_volume,
|
||||||
T5."name" AS practitioner_name,
|
T5."name" AS practitioner_name,
|
||||||
T6."name" AS purpose_location_name,
|
T6."name" AS purpose_location_name,
|
||||||
T6."id" AS purpose_location_id,
|
T6."id" AS purpose_location_id,
|
||||||
T7."name" AS purpose_location_store_name,
|
T7."name" AS purpose_location_store_name,
|
||||||
|
T1.supplier_id AS supplierId,
|
||||||
|
T10."name" AS supplier_name,
|
||||||
T1.occurrence_time,
|
T1.occurrence_time,
|
||||||
(SELECT SUM(T9.quantity)
|
(SELECT SUM(T9.quantity)
|
||||||
FROM wor_inventory_item T9
|
FROM wor_inventory_item T9
|
||||||
@@ -145,6 +151,8 @@
|
|||||||
LEFT JOIN wor_inventory_item T9
|
LEFT JOIN wor_inventory_item T9
|
||||||
ON T1.item_id = T9.item_id
|
ON T1.item_id = T9.item_id
|
||||||
AND T1.purpose_location_id = T9.location_id
|
AND T1.purpose_location_id = T9.location_id
|
||||||
|
LEFT JOIN adm_supplier T10
|
||||||
|
ON T1.supplier_id = T10.id
|
||||||
WHERE T1.bus_no = #{busNo}
|
WHERE T1.bus_no = #{busNo}
|
||||||
AND T1.delete_flag = '0'
|
AND T1.delete_flag = '0'
|
||||||
</select>
|
</select>
|
||||||
@@ -167,12 +175,14 @@
|
|||||||
T2."name" AS item_name,
|
T2."name" AS item_name,
|
||||||
T2.id AS item_id,
|
T2.id AS item_id,
|
||||||
T2.part_percent,
|
T2.part_percent,
|
||||||
T2.manufacturer_text AS supplier_name,
|
T2.manufacturer_text AS manufacturer_text,
|
||||||
T3.total_volume,
|
T3.total_volume,
|
||||||
T5."name" AS practitioner_name,
|
T5."name" AS practitioner_name,
|
||||||
T6."name" AS purpose_location_name,
|
T6."name" AS purpose_location_name,
|
||||||
T6."id" AS purpose_location_id,
|
T6."id" AS purpose_location_id,
|
||||||
T7."name" AS purpose_location_store_name,
|
T7."name" AS purpose_location_store_name,
|
||||||
|
T1.supplier_id AS supplierId,
|
||||||
|
T10."name" AS supplier_name,
|
||||||
(SELECT SUM(T9.quantity)
|
(SELECT SUM(T9.quantity)
|
||||||
FROM wor_inventory_item T9
|
FROM wor_inventory_item T9
|
||||||
WHERE T9.item_id = T1.item_id
|
WHERE T9.item_id = T1.item_id
|
||||||
@@ -192,6 +202,8 @@
|
|||||||
LEFT JOIN wor_inventory_item T9
|
LEFT JOIN wor_inventory_item T9
|
||||||
ON T1.item_id = T9.item_id
|
ON T1.item_id = T9.item_id
|
||||||
AND T1.purpose_location_id = T9.location_id
|
AND T1.purpose_location_id = T9.location_id
|
||||||
|
LEFT JOIN adm_supplier T10
|
||||||
|
ON T1.supplier_id = T10.id
|
||||||
WHERE T1.purpose_location_id = #{locationId}
|
WHERE T1.purpose_location_id = #{locationId}
|
||||||
AND T1.status_enum = #{statusEnum}
|
AND T1.status_enum = #{statusEnum}
|
||||||
AND T1.type_enum IN
|
AND T1.type_enum IN
|
||||||
@@ -220,12 +232,14 @@
|
|||||||
T8."name" AS item_name,
|
T8."name" AS item_name,
|
||||||
T8.id AS item_id,
|
T8.id AS item_id,
|
||||||
T8.part_percent,
|
T8.part_percent,
|
||||||
T8.manufacturer_text AS supplier_name,
|
T8.manufacturer_text AS manufacturer_text,
|
||||||
T8."size" AS total_volume,
|
T8."size" AS total_volume,
|
||||||
T5."name" AS practitioner_name,
|
T5."name" AS practitioner_name,
|
||||||
T6."name" AS purpose_location_name,
|
T6."name" AS purpose_location_name,
|
||||||
T6."id" AS purpose_location_id,
|
T6."id" AS purpose_location_id,
|
||||||
T7."name" AS purpose_location_store_name,
|
T7."name" AS purpose_location_store_name,
|
||||||
|
T1.supplier_id AS supplierId,
|
||||||
|
T10."name" AS supplier_name,
|
||||||
(SELECT SUM(T9.quantity)
|
(SELECT SUM(T9.quantity)
|
||||||
FROM wor_inventory_item T9
|
FROM wor_inventory_item T9
|
||||||
WHERE T9.item_id = T1.item_id
|
WHERE T9.item_id = T1.item_id
|
||||||
@@ -243,6 +257,8 @@
|
|||||||
LEFT JOIN wor_inventory_item T9
|
LEFT JOIN wor_inventory_item T9
|
||||||
ON T1.item_id = T9.item_id
|
ON T1.item_id = T9.item_id
|
||||||
AND T1.purpose_location_id = T9.location_id
|
AND T1.purpose_location_id = T9.location_id
|
||||||
|
LEFT JOIN adm_supplier T10
|
||||||
|
ON T1.supplier_id = T10.id
|
||||||
WHERE T1.purpose_location_id = #{locationId}
|
WHERE T1.purpose_location_id = #{locationId}
|
||||||
AND T1.status_enum = #{statusEnum}
|
AND T1.status_enum = #{statusEnum}
|
||||||
AND T1.type_enum IN
|
AND T1.type_enum IN
|
||||||
|
|||||||
@@ -85,33 +85,33 @@
|
|||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<!-- <build>-->
|
||||||
<plugins>
|
<!-- <plugins>-->
|
||||||
<plugin>
|
<!-- <plugin>-->
|
||||||
<groupId>org.springframework.boot</groupId>
|
<!-- <groupId>org.springframework.boot</groupId>-->
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
<!-- <artifactId>spring-boot-maven-plugin</artifactId>-->
|
||||||
<configuration>
|
<!-- <configuration>-->
|
||||||
<fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
|
<!-- <fork>true</fork> <!– 如果没有该配置,devtools不会生效 –>-->
|
||||||
</configuration>
|
<!-- </configuration>-->
|
||||||
<executions>
|
<!-- <executions>-->
|
||||||
<execution>
|
<!-- <execution>-->
|
||||||
<goals>
|
<!-- <goals>-->
|
||||||
<goal>repackage</goal>
|
<!-- <goal>repackage</goal>-->
|
||||||
</goals>
|
<!-- </goals>-->
|
||||||
</execution>
|
<!-- </execution>-->
|
||||||
</executions>
|
<!-- </executions>-->
|
||||||
</plugin>
|
<!-- </plugin>-->
|
||||||
<plugin>
|
<!-- <plugin>-->
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<!-- <groupId>org.apache.maven.plugins</groupId>-->
|
||||||
<artifactId>maven-war-plugin</artifactId>
|
<!-- <artifactId>maven-war-plugin</artifactId>-->
|
||||||
<version>${maven-war-plugin.version}</version>
|
<!-- <version>${maven-war-plugin.version}</version>-->
|
||||||
<configuration>
|
<!-- <configuration>-->
|
||||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
<!-- <failOnMissingWebXml>false</failOnMissingWebXml>-->
|
||||||
<warName>${project.artifactId}</warName>
|
<!-- <warName>${project.artifactId}</warName>-->
|
||||||
</configuration>
|
<!-- </configuration>-->
|
||||||
</plugin>
|
<!-- </plugin>-->
|
||||||
</plugins>
|
<!-- </plugins>-->
|
||||||
<finalName>${project.artifactId}</finalName>
|
<!-- <finalName>${project.artifactId}</finalName>-->
|
||||||
</build>
|
<!-- </build>-->
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
# 页面标题
|
# 页面标题
|
||||||
VITE_APP_TITLE = 医院信息管理系统
|
VITE_APP_TITLE=医院信息管理系统
|
||||||
|
|
||||||
# 生产环境配置
|
# 生产环境配置
|
||||||
VITE_APP_ENV = 'production'
|
VITE_APP_ENV=production
|
||||||
|
|
||||||
# OpenHIS管理系统/生产环境
|
# OpenHIS管理系统/生产环境
|
||||||
VITE_APP_BASE_API = '/prod-api'
|
VITE_APP_BASE_API=/prod-api
|
||||||
|
|
||||||
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
||||||
VITE_BUILD_COMPRESS = gzip
|
VITE_BUILD_COMPRESS=gzip
|
||||||
35
openhis-ui-vue3/.env.spug
Normal file
35
openhis-ui-vue3/.env.spug
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# 开发环境:本地只启动前端项目,依赖开发环境(后端、APP)
|
||||||
|
# 生产环境配置
|
||||||
|
VITE_APP_ENV = 'spug'
|
||||||
|
|
||||||
|
VITE_DEV=true
|
||||||
|
|
||||||
|
# 请求路径
|
||||||
|
VITE_BASE_URL='http://192.168.110.252'
|
||||||
|
|
||||||
|
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务
|
||||||
|
VITE_UPLOAD_TYPE=server
|
||||||
|
|
||||||
|
# OpenHIS管理系统/SPUG环境
|
||||||
|
VITE_APP_BASE_API = '/admin-api'
|
||||||
|
|
||||||
|
# 是否删除debugger
|
||||||
|
VITE_DROP_DEBUGGER=false
|
||||||
|
|
||||||
|
# 是否删除console.log
|
||||||
|
VITE_DROP_CONSOLE=false
|
||||||
|
|
||||||
|
# 是否sourcemap
|
||||||
|
VITE_SOURCEMAP=true
|
||||||
|
|
||||||
|
# 打包路径
|
||||||
|
VITE_BASE_PATH=/
|
||||||
|
|
||||||
|
# 商城H5会员端域名
|
||||||
|
VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn'
|
||||||
|
|
||||||
|
# 验证码的开关
|
||||||
|
VITE_APP_CAPTCHA_ENABLE=false
|
||||||
|
|
||||||
|
# GoView域名
|
||||||
|
VITE_GOVIEW_URL='http://127.0.0.1:3000'
|
||||||
33
openhis-ui-vue3/package-lock.json
generated
33
openhis-ui-vue3/package-lock.json
generated
@@ -13,9 +13,10 @@
|
|||||||
"@vueup/vue-quill": "1.2.0",
|
"@vueup/vue-quill": "1.2.0",
|
||||||
"@vueuse/core": "10.6.1",
|
"@vueuse/core": "10.6.1",
|
||||||
"axios": "0.27.2",
|
"axios": "0.27.2",
|
||||||
|
"chart.js": "^4.5.1",
|
||||||
"d3": "^7.9.0",
|
"d3": "^7.9.0",
|
||||||
"decimal.js": "^10.5.0",
|
"decimal.js": "^10.5.0",
|
||||||
"echarts": "5.4.3",
|
"echarts": "^5.4.3",
|
||||||
"element-china-area-data": "^6.1.0",
|
"element-china-area-data": "^6.1.0",
|
||||||
"element-plus": "2.9.11",
|
"element-plus": "2.9.11",
|
||||||
"file-saver": "2.0.5",
|
"file-saver": "2.0.5",
|
||||||
@@ -544,6 +545,11 @@
|
|||||||
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
|
||||||
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="
|
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@kurkle/color": {
|
||||||
|
"version": "0.3.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@kurkle/color/-/color-0.3.4.tgz",
|
||||||
|
"integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w=="
|
||||||
|
},
|
||||||
"node_modules/@nodelib/fs.scandir": {
|
"node_modules/@nodelib/fs.scandir": {
|
||||||
"version": "2.1.5",
|
"version": "2.1.5",
|
||||||
"resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
"resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||||
@@ -1686,6 +1692,18 @@
|
|||||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/chart.js": {
|
||||||
|
"version": "4.5.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/chart.js/-/chart.js-4.5.1.tgz",
|
||||||
|
"integrity": "sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@kurkle/color": "^0.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"pnpm": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/china-division": {
|
"node_modules/china-division": {
|
||||||
"version": "2.7.0",
|
"version": "2.7.0",
|
||||||
"resolved": "https://registry.npmmirror.com/china-division/-/china-division-2.7.0.tgz",
|
"resolved": "https://registry.npmmirror.com/china-division/-/china-division-2.7.0.tgz",
|
||||||
@@ -7817,6 +7835,11 @@
|
|||||||
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
|
||||||
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="
|
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="
|
||||||
},
|
},
|
||||||
|
"@kurkle/color": {
|
||||||
|
"version": "0.3.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@kurkle/color/-/color-0.3.4.tgz",
|
||||||
|
"integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w=="
|
||||||
|
},
|
||||||
"@nodelib/fs.scandir": {
|
"@nodelib/fs.scandir": {
|
||||||
"version": "2.1.5",
|
"version": "2.1.5",
|
||||||
"resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
"resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||||
@@ -8634,6 +8657,14 @@
|
|||||||
"supports-color": "^7.1.0"
|
"supports-color": "^7.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"chart.js": {
|
||||||
|
"version": "4.5.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/chart.js/-/chart.js-4.5.1.tgz",
|
||||||
|
"integrity": "sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw==",
|
||||||
|
"requires": {
|
||||||
|
"@kurkle/color": "^0.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"china-division": {
|
"china-division": {
|
||||||
"version": "2.7.0",
|
"version": "2.7.0",
|
||||||
"resolved": "https://registry.npmmirror.com/china-division/-/china-division-2.7.0.tgz",
|
"resolved": "https://registry.npmmirror.com/china-division/-/china-division-2.7.0.tgz",
|
||||||
|
|||||||
@@ -7,9 +7,10 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build:prod": "vite build",
|
"build:prod": "vite build --mode production",
|
||||||
"build:stage": "vite build --mode staging",
|
"build:stage": "vite build --mode staging",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview",
|
||||||
|
"build:spug": "vite build --mode spug"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -20,9 +21,10 @@
|
|||||||
"@vueup/vue-quill": "1.2.0",
|
"@vueup/vue-quill": "1.2.0",
|
||||||
"@vueuse/core": "10.6.1",
|
"@vueuse/core": "10.6.1",
|
||||||
"axios": "0.27.2",
|
"axios": "0.27.2",
|
||||||
|
"chart.js": "^4.5.1",
|
||||||
"d3": "^7.9.0",
|
"d3": "^7.9.0",
|
||||||
"decimal.js": "^10.5.0",
|
"decimal.js": "^10.5.0",
|
||||||
"echarts": "5.4.3",
|
"echarts": "^5.4.3",
|
||||||
"element-china-area-data": "^6.1.0",
|
"element-china-area-data": "^6.1.0",
|
||||||
"element-plus": "2.9.11",
|
"element-plus": "2.9.11",
|
||||||
"file-saver": "2.0.5",
|
"file-saver": "2.0.5",
|
||||||
|
|||||||
BIN
openhis-ui-vue3/src/assets/logo/LOGO.jpg
Normal file
BIN
openhis-ui-vue3/src/assets/logo/LOGO.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
@@ -3,6 +3,10 @@ export default {
|
|||||||
* 网页标题
|
* 网页标题
|
||||||
*/
|
*/
|
||||||
title: import.meta.env.VITE_APP_TITLE,
|
title: import.meta.env.VITE_APP_TITLE,
|
||||||
|
/**
|
||||||
|
* 系统名称
|
||||||
|
*/
|
||||||
|
systemName: import.meta.env.VITE_APP_SYSTEM_NAME + '信息管理系统 ' || '测试医院信息管理系统',
|
||||||
/**
|
/**
|
||||||
* 侧边栏主题 深色主题theme-dark,浅色主题theme-light
|
* 侧边栏主题 深色主题theme-dark,浅色主题theme-light
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -82,7 +82,7 @@
|
|||||||
:class="{ 'error-border': scope.row.error }"
|
:class="{ 'error-border': scope.row.error }"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="dict in distribution_category_code"
|
v-for="dict in med_category_code"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
:label="dict.label"
|
:label="dict.label"
|
||||||
:value="dict.value"
|
:value="dict.value"
|
||||||
@@ -184,7 +184,7 @@ import {
|
|||||||
deletePharmacyDepartment,
|
deletePharmacyDepartment,
|
||||||
} from './components/pharmacyDepartment';
|
} from './components/pharmacyDepartment';
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
const { distribution_category_code } = proxy.useDict('distribution_category_code');
|
const { med_category_code } = proxy.useDict('med_category_code');
|
||||||
import { nextTick } from 'vue';
|
import { nextTick } from 'vue';
|
||||||
|
|
||||||
const diagnosisTreatmentList = ref([]);
|
const diagnosisTreatmentList = ref([]);
|
||||||
|
|||||||
@@ -36,8 +36,12 @@ export function updateWarehouse(data) {
|
|||||||
// 删除
|
// 删除
|
||||||
export function deleteWarehouse(data) {
|
export function deleteWarehouse(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/base-data-manage/location/location?locationId=' + data.locationId,
|
url: '/base-data-manage/location/location',
|
||||||
method: 'delete',
|
method: 'delete',
|
||||||
|
params: {
|
||||||
|
locationId: data.locationId,
|
||||||
|
busNo: data.busNo
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ const { warehous_type } = proxy.useDict('warehous_type');
|
|||||||
const rules = ref({
|
const rules = ref({
|
||||||
busNo: [{ required: false, message: '请输入科室编号', trigger: 'change' }],
|
busNo: [{ required: false, message: '请输入科室编号', trigger: 'change' }],
|
||||||
name: [
|
name: [
|
||||||
{ required: true, message: '请输入仓库名称', trigger: 'change' },
|
{ required: true, message: '请输入', trigger: 'change' },
|
||||||
{ min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'change' },
|
{ min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'change' },
|
||||||
],
|
],
|
||||||
formEnum: [{ required: true, message: '请选择仓库类型', trigger: 'change' }],
|
formEnum: [{ required: true, message: '请选择仓库类型', trigger: 'change' }],
|
||||||
@@ -211,7 +211,7 @@ function resetQuery() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleEnable(row) {
|
function handleEnable(row) {
|
||||||
enableLocation([row.id]).then((res) => {
|
enableLocation({ locationId: row.id, busNo: row.busNo }).then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
proxy.$modal.msgSuccess('启用成功');
|
proxy.$modal.msgSuccess('启用成功');
|
||||||
handleQuery();
|
handleQuery();
|
||||||
@@ -220,7 +220,7 @@ function handleEnable(row) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleUnable(row) {
|
function handleUnable(row) {
|
||||||
unableLocation([row.id]).then((res) => {
|
unableLocation({ locationId: row.id, busNo: row.busNo }).then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
proxy.$modal.msgSuccess('停用成功');
|
proxy.$modal.msgSuccess('停用成功');
|
||||||
handleQuery();
|
handleQuery();
|
||||||
@@ -250,7 +250,6 @@ function handleAdd() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handelEdit(row) {
|
function handelEdit(row) {
|
||||||
console.log(warehous_type);
|
|
||||||
title.value = '编辑药库药房';
|
title.value = '编辑药库药房';
|
||||||
open.value = true;
|
open.value = true;
|
||||||
editShow.value = true;
|
editShow.value = true;
|
||||||
@@ -281,7 +280,6 @@ function submitForm() {
|
|||||||
getPageList();
|
getPageList();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
alert('456789');
|
|
||||||
updateWarehouse(form.value).then((res) => {
|
updateWarehouse(form.value).then((res) => {
|
||||||
proxy.$modal.msgSuccess('操作成功');
|
proxy.$modal.msgSuccess('操作成功');
|
||||||
open.value = false;
|
open.value = false;
|
||||||
@@ -294,11 +292,29 @@ function submitForm() {
|
|||||||
|
|
||||||
// 删除
|
// 删除
|
||||||
function handelDelete(data) {
|
function handelDelete(data) {
|
||||||
loading.value = true;
|
proxy.$modal.confirm('是否确认删除该仓库位置?', '提示', {
|
||||||
deleteWarehouse({ locationId: data.id }).then((res) => {
|
confirmButtonText: '确定',
|
||||||
proxy.$modal.msgSuccess('操作成功');
|
cancelButtonText: '取消',
|
||||||
loading.value = false;
|
type: 'warning'
|
||||||
getPageList();
|
}).then(() => {
|
||||||
|
loading.value = true;
|
||||||
|
deleteWarehouse({ locationId: data.id, busNo: data.busNo }).then((res) => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
proxy.$modal.msgSuccess('删除成功');
|
||||||
|
getPageList();
|
||||||
|
} else {
|
||||||
|
// 检查错误信息是否与药品数据关联有关
|
||||||
|
if (res.msg && res.msg.includes('药品')) {
|
||||||
|
proxy.$modal.msgError('该仓库名称已有药品信息请核对确认');
|
||||||
|
} else {
|
||||||
|
proxy.$modal.msgError('删除失败:' + (res.msg || '未知错误'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
proxy.$modal.msgError('删除失败');
|
||||||
|
}).finally(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// // 停用
|
// // 停用
|
||||||
|
|||||||
@@ -378,7 +378,7 @@ const data = reactive({
|
|||||||
phone: [{ required: true, message: '联系方式不能为空', trigger: 'change' }],
|
phone: [{ required: true, message: '联系方式不能为空', trigger: 'change' }],
|
||||||
identifierNo: [{ required: true, message: '就诊卡号不能为空', trigger: 'change' }],
|
identifierNo: [{ required: true, message: '就诊卡号不能为空', trigger: 'change' }],
|
||||||
idCard: [
|
idCard: [
|
||||||
{ required: true, message: '证件号码不能为空', trigger: 'change' },
|
{ required: false, message: '证件号码不能为空', trigger: 'change' },
|
||||||
{ validator: validateIdCard, trigger: 'blur' },
|
{ validator: validateIdCard, trigger: 'blur' },
|
||||||
{ validator: validateUniquePatient, trigger: 'blur' }
|
{ validator: validateUniquePatient, trigger: 'blur' }
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -162,10 +162,10 @@
|
|||||||
ref="contractNameRef"
|
ref="contractNameRef"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in contractList"
|
v-for="dict in medfee_paymtd_code"
|
||||||
:key="item.busNo"
|
:key="dict.value"
|
||||||
:label="item.contractName"
|
:label="dict.label"
|
||||||
:value="item.busNo"
|
:value="dict.value"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -648,10 +648,11 @@ const patientInfo = ref({});
|
|||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
const { sys_normal_disable, sys_user_sex, med_chrgitm_type } = proxy.useDict(
|
const { sys_normal_disable, sys_user_sex, med_chrgitm_type,medfee_paymtd_code } = proxy.useDict(
|
||||||
'sys_normal_disable',
|
'sys_normal_disable',
|
||||||
'sys_user_sex',
|
'sys_user_sex',
|
||||||
'med_chrgitm_type'
|
'med_chrgitm_type',
|
||||||
|
'medfee_paymtd_code'
|
||||||
);
|
);
|
||||||
|
|
||||||
const outpatientRegistrationList = ref([]);
|
const outpatientRegistrationList = ref([]);
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ import { throttle } from 'lodash-es';
|
|||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
adviceQueryParams: {
|
adviceQueryParams: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: '',
|
required: true
|
||||||
},
|
},
|
||||||
patientInfo: {
|
patientInfo: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@@ -97,39 +97,25 @@ const throttledGetList = throttle(
|
|||||||
watch(
|
watch(
|
||||||
() => props.adviceQueryParams,
|
() => props.adviceQueryParams,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
queryParams.value.searchKey = newValue.searchKey;
|
console.log('adviceBaseList 接收到参数变化:', newValue);
|
||||||
// queryParams.value.adviceType = newValue.adviceType;
|
|
||||||
|
// 直接更新查询参数
|
||||||
|
queryParams.value.searchKey = newValue.searchKey || '';
|
||||||
|
|
||||||
|
// 处理类型筛选
|
||||||
if (newValue.adviceType) {
|
if (newValue.adviceType) {
|
||||||
queryParams.value.adviceTypes = [newValue.adviceType].join(',');
|
// 单个类型
|
||||||
|
queryParams.value.adviceTypes = newValue.adviceType.toString();
|
||||||
} else {
|
} else {
|
||||||
|
// 全部类型
|
||||||
queryParams.value.adviceTypes = '1,2,3';
|
queryParams.value.adviceTypes = '1,2,3';
|
||||||
}
|
}
|
||||||
throttledGetList();
|
|
||||||
|
console.log('发送请求参数:', queryParams.value);
|
||||||
|
getList();
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true, immediate: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
getList();
|
|
||||||
function getList() {
|
|
||||||
queryParams.value.organizationId = props.patientInfo.orgId;
|
|
||||||
getAdviceBaseInfo(queryParams.value).then((res) => {
|
|
||||||
console.log('ssssssssss', 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(() => {
|
|
||||||
currentIndex.value = 0;
|
|
||||||
adviceBaseRef.value.setCurrentRow(adviceBaseList.value[0]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// 从priceList列表中获取价格
|
// 从priceList列表中获取价格
|
||||||
function getPriceFromInventory(row) {
|
function getPriceFromInventory(row) {
|
||||||
if (row.priceList && row.priceList.length > 0) {
|
if (row.priceList && row.priceList.length > 0) {
|
||||||
@@ -138,6 +124,38 @@ function getPriceFromInventory(row) {
|
|||||||
}
|
}
|
||||||
return '-';
|
return '-';
|
||||||
}
|
}
|
||||||
|
function getList() {
|
||||||
|
queryParams.value.organizationId = props.patientInfo.orgId;
|
||||||
|
|
||||||
|
console.log('发送API请求:', queryParams.value);
|
||||||
|
|
||||||
|
getAdviceBaseInfo(queryParams.value).then((res) => {
|
||||||
|
if (res.data.records && 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;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('过滤后数据显示:', adviceBaseList.value.length, '条');
|
||||||
|
|
||||||
|
total.value = res.data.total;
|
||||||
|
nextTick(() => {
|
||||||
|
currentIndex.value = 0;
|
||||||
|
if (adviceBaseList.value.length > 0) {
|
||||||
|
adviceBaseRef.value.setCurrentRow(adviceBaseList.value[0]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
adviceBaseList.value = [];
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('获取数据失败:', error);
|
||||||
|
adviceBaseList.value = [];
|
||||||
|
});
|
||||||
|
}
|
||||||
// 处理键盘事件
|
// 处理键盘事件
|
||||||
const handleKeyDown = (event) => {
|
const handleKeyDown = (event) => {
|
||||||
const key = event.key;
|
const key = event.key;
|
||||||
|
|||||||
@@ -99,7 +99,7 @@
|
|||||||
>
|
>
|
||||||
<el-select v-model="scope.row.medTypeCode" placeholder=" " style="width: 150px">
|
<el-select v-model="scope.row.medTypeCode" placeholder=" " style="width: 150px">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in med_type"
|
v-for="item in diag_type"
|
||||||
:key="item.value"
|
:key="item.value"
|
||||||
:label="item.label"
|
:label="item.label"
|
||||||
:value="item.value"
|
:value="item.value"
|
||||||
@@ -235,7 +235,7 @@ const props = defineProps({
|
|||||||
const emits = defineEmits(['diagnosisSave']);
|
const emits = defineEmits(['diagnosisSave']);
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const { med_type } = proxy.useDict('med_type');
|
const { diag_type } = proxy.useDict('diag_type');
|
||||||
const rules = ref({
|
const rules = ref({
|
||||||
name: [{ required: true, message: '请选择诊断', trigger: 'change' }],
|
name: [{ required: true, message: '请选择诊断', trigger: 'change' }],
|
||||||
medTypeCode: [{ required: true, message: '请选择诊断类型', trigger: 'change' }],
|
medTypeCode: [{ required: true, message: '请选择诊断类型', trigger: 'change' }],
|
||||||
@@ -275,6 +275,10 @@ function getList() {
|
|||||||
diagnosisDoctor: item.diagnosisDoctor || props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
diagnosisDoctor: item.diagnosisDoctor || props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
||||||
diagnosisTime: item.diagnosisTime || new Date().toLocaleString('zh-CN')
|
diagnosisTime: item.diagnosisTime || new Date().toLocaleString('zh-CN')
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// 获取诊断列表后按排序号排序
|
||||||
|
form.value.diagnosisList.sort((a, b) => (a.diagSrtNo || 0) - (b.diagSrtNo || 0));
|
||||||
|
|
||||||
emits('diagnosisSave', false);
|
emits('diagnosisSave', false);
|
||||||
console.log(form.value.diagnosisList);
|
console.log(form.value.diagnosisList);
|
||||||
}
|
}
|
||||||
@@ -320,6 +324,11 @@ function handleImport() {
|
|||||||
// 获取患者慢性病信息
|
// 获取患者慢性病信息
|
||||||
getChronicDisease({ encounterId: props.patientInfo.encounterId }).then((res) => {
|
getChronicDisease({ encounterId: props.patientInfo.encounterId }).then((res) => {
|
||||||
if (res.data && res.data.length > 0) {
|
if (res.data && res.data.length > 0) {
|
||||||
|
// 计算现有最大排序号
|
||||||
|
const maxSortNo = form.value.diagnosisList.length > 0
|
||||||
|
? Math.max(...form.value.diagnosisList.map(item => item.diagSrtNo || 0))
|
||||||
|
: 0;
|
||||||
|
|
||||||
res.data.forEach((item, index) => {
|
res.data.forEach((item, index) => {
|
||||||
form.value.diagnosisList.push({
|
form.value.diagnosisList.push({
|
||||||
...item,
|
...item,
|
||||||
@@ -327,7 +336,7 @@ function handleImport() {
|
|||||||
medTypeCode: '140104',
|
medTypeCode: '140104',
|
||||||
verificationStatusEnum: 4,
|
verificationStatusEnum: 4,
|
||||||
definitionId: item.id,
|
definitionId: item.id,
|
||||||
diagSrtNo: form.value.diagnosisList.length + 1,
|
diagSrtNo: maxSortNo + index + 1,
|
||||||
iptDiseTypeCode: 2,
|
iptDiseTypeCode: 2,
|
||||||
diagnosisDesc: '',
|
diagnosisDesc: '',
|
||||||
diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
||||||
@@ -335,6 +344,10 @@ function handleImport() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 导入完成后按排序号排序
|
||||||
|
form.value.diagnosisList.sort((a, b) => (a.diagSrtNo || 0) - (b.diagSrtNo || 0));
|
||||||
|
emits('diagnosisSave', false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -417,17 +430,26 @@ function handleAddDiagnosis() {
|
|||||||
proxy.$modal.msgWarning('请先填写病历');
|
proxy.$modal.msgWarning('请先填写病历');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// 计算现有最大排序号
|
||||||
|
const maxSortNo = form.value.diagnosisList.length > 0
|
||||||
|
? Math.max(...form.value.diagnosisList.map(item => item.diagSrtNo || 0))
|
||||||
|
: 0;
|
||||||
|
|
||||||
form.value.diagnosisList.push({
|
form.value.diagnosisList.push({
|
||||||
showPopover: false,
|
showPopover: false,
|
||||||
name: undefined,
|
name: undefined,
|
||||||
verificationStatusEnum: 4,
|
verificationStatusEnum: 4,
|
||||||
medTypeCode: '11',
|
medTypeCode: '初诊诊断',
|
||||||
diagSrtNo: form.value.diagnosisList.length + 1,
|
diagSrtNo: maxSortNo + 1,
|
||||||
iptDiseTypeCode: 2,
|
iptDiseTypeCode: 2,
|
||||||
diagnosisDesc: '',
|
diagnosisDesc: '',
|
||||||
diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
||||||
diagnosisTime: new Date().toLocaleString('zh-CN')
|
diagnosisTime: new Date().toLocaleString('zh-CN')
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 添加后按排序号排序
|
||||||
|
form.value.diagnosisList.sort((a, b) => (a.diagSrtNo || 0) - (b.diagSrtNo || 0));
|
||||||
|
|
||||||
if (form.value.diagnosisList.length == 1) {
|
if (form.value.diagnosisList.length == 1) {
|
||||||
form.value.diagnosisList[0].maindiseFlag = 1;
|
form.value.diagnosisList[0].maindiseFlag = 1;
|
||||||
}
|
}
|
||||||
@@ -445,12 +467,17 @@ function handleAddTcmDiagonsis() {
|
|||||||
*/
|
*/
|
||||||
function handleDeleteDiagnosis(row, index) {
|
function handleDeleteDiagnosis(row, index) {
|
||||||
if (row.conditionId) {
|
if (row.conditionId) {
|
||||||
delEncounterDiagnosis(row.conditionId).then(() => {
|
delEncounterDiagnosis({ conditionId: row.conditionId }).then((res) => {
|
||||||
getList();
|
if (res.code == 200) {
|
||||||
getTree();
|
proxy.$modal.msgSuccess('删除成功');
|
||||||
|
getList();
|
||||||
|
getTree();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
form.value.diagnosisList.splice(index, 1);
|
form.value.diagnosisList.splice(index, 1);
|
||||||
|
// 删除后不重新计算排序号,保持用户设置的排序不变
|
||||||
|
emits('diagnosisSave', false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -458,7 +485,6 @@ function handleMaindise(value, index) {
|
|||||||
if (value == 1) {
|
if (value == 1) {
|
||||||
let flag = 0;
|
let flag = 0;
|
||||||
form.value.diagnosisList.forEach((item) => {
|
form.value.diagnosisList.forEach((item) => {
|
||||||
console.log(item);
|
|
||||||
if (item.maindiseFlag == 1) {
|
if (item.maindiseFlag == 1) {
|
||||||
flag++;
|
flag++;
|
||||||
}
|
}
|
||||||
@@ -482,6 +508,9 @@ function handleSaveDiagnosis() {
|
|||||||
} else if (!form.value.diagnosisList.some((diagnosis) => diagnosis.maindiseFlag === 1)) {
|
} else if (!form.value.diagnosisList.some((diagnosis) => diagnosis.maindiseFlag === 1)) {
|
||||||
proxy.$modal.msgWarning('至少添加一条主诊断');
|
proxy.$modal.msgWarning('至少添加一条主诊断');
|
||||||
} else {
|
} else {
|
||||||
|
// 保存前按排序号排序
|
||||||
|
form.value.diagnosisList.sort((a, b) => (a.diagSrtNo || 0) - (b.diagSrtNo || 0));
|
||||||
|
|
||||||
saveDiagnosis({
|
saveDiagnosis({
|
||||||
patientId: props.patientInfo.patientId,
|
patientId: props.patientInfo.patientId,
|
||||||
encounterId: props.patientInfo.encounterId,
|
encounterId: props.patientInfo.encounterId,
|
||||||
@@ -491,7 +520,7 @@ function handleSaveDiagnosis() {
|
|||||||
getTree();
|
getTree();
|
||||||
getList();
|
getList();
|
||||||
emits('diagnosisSave', false);
|
emits('diagnosisSave', false);
|
||||||
proxy.$modal.msgSuccess('诊断已保存');
|
proxy.$modal.msgSuccess('诊断已保存并按排序号排序');
|
||||||
//食源性疾病病例数据智能采集 ---START---
|
//食源性疾病病例数据智能采集 ---START---
|
||||||
isFoodDiseasesNew({
|
isFoodDiseasesNew({
|
||||||
encounterId: props.patientInfo.encounterId,
|
encounterId: props.patientInfo.encounterId,
|
||||||
@@ -566,16 +595,26 @@ function handleNodeClick(data) {
|
|||||||
proxy.$modal.msgWarning('该诊断项已存在');
|
proxy.$modal.msgWarning('该诊断项已存在');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 计算现有最大排序号
|
||||||
|
const maxSortNo = form.value.diagnosisList.length > 0
|
||||||
|
? Math.max(...form.value.diagnosisList.map(item => item.diagSrtNo || 0))
|
||||||
|
: 0;
|
||||||
|
|
||||||
form.value.diagnosisList.push({
|
form.value.diagnosisList.push({
|
||||||
ybNo: data.ybNo,
|
ybNo: data.ybNo,
|
||||||
name: data.name,
|
name: data.name,
|
||||||
verificationStatusEnum: 4,
|
verificationStatusEnum: 4,
|
||||||
medTypeCode: '11',
|
medTypeCode: '11',
|
||||||
diagSrtNo: form.value.diagnosisList.length + 1,
|
diagSrtNo: maxSortNo + 1,
|
||||||
definitionId: data.definitionId,
|
definitionId: data.definitionId,
|
||||||
diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
||||||
diagnosisTime: new Date().toLocaleString('zh-CN')
|
diagnosisTime: new Date().toLocaleString('zh-CN')
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 添加后按排序号排序
|
||||||
|
form.value.diagnosisList.sort((a, b) => (a.diagSrtNo || 0) - (b.diagSrtNo || 0));
|
||||||
|
|
||||||
if (form.value.diagnosisList.length == 1) {
|
if (form.value.diagnosisList.length == 1) {
|
||||||
form.value.diagnosisList[0].maindiseFlag = 1;
|
form.value.diagnosisList[0].maindiseFlag = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,174 +10,95 @@
|
|||||||
<el-button type="primary" plain @click="handleEmrHistory()" style="margin-left: 20px">
|
<el-button type="primary" plain @click="handleEmrHistory()" style="margin-left: 20px">
|
||||||
历史病历
|
历史病历
|
||||||
</el-button>
|
</el-button>
|
||||||
<!-- <el-button type="primary" plain @click="handleReceive()" style="margin-left: 20px">
|
<!-- 可选:添加打印按钮 -->
|
||||||
|
<!-- <el-button type="primary" plain @click="printEmr" style="margin-left: 20px">
|
||||||
打印病历
|
打印病历
|
||||||
</el-button> -->
|
</el-button> -->
|
||||||
</div>
|
</div>
|
||||||
<div style="max-height: 650px; overflow-y: auto; overflow-x: hidden">
|
|
||||||
<div style="text-align: center; font-size: 18px; font-weight: bold; margin-bottom: 10px;">
|
<div
|
||||||
|
ref="printArea"
|
||||||
|
style="max-height: 650px; overflow-y: auto; overflow-x: hidden; font-family: 'SimSun', '宋体', sans-serif;"
|
||||||
|
>
|
||||||
|
<!-- 标题 -->
|
||||||
|
<div style="text-align: center; font-size: 18px; font-weight: bold; margin-bottom: 10px;">
|
||||||
{{ visitType === 'FIRST' ? '门诊初诊病历' : '门诊复诊病历' }}
|
{{ visitType === 'FIRST' ? '门诊初诊病历' : '门诊复诊病历' }}
|
||||||
</div>
|
</div>
|
||||||
<el-form ref="emrRef" :model="form" :rules="rules" label-width="80px">
|
|
||||||
<el-row :gutter="4">
|
<!-- 患者基本信息 -->
|
||||||
<el-col :span="4">
|
<div style="display: flex; flex-wrap: wrap; gap: 10px; padding: 10px 0; border-bottom: 1px solid #ebeef5;">
|
||||||
<el-form-item label="就诊卡号" prop="patientId" style="width: 100%">
|
<div style="flex: 1; min-width: 120px; font-size: 14px; line-height: 24px;">
|
||||||
<el-input placeholder="" v-model="patientInfo.patientId" class="input-with-bottom-border"/>
|
<strong>就诊卡号:</strong> {{ patientInfo.patientId || '' }}
|
||||||
</el-form-item>
|
</div>
|
||||||
</el-col>
|
<div style="flex: 1; min-width: 120px; font-size: 14px; line-height: 24px;">
|
||||||
<el-col :span="4">
|
<strong>姓名:</strong> {{ patientInfo.patientName || '' }}
|
||||||
<el-form-item label="姓名" prop="patientName" style="width: 100%">
|
</div>
|
||||||
<el-input placeholder="" v-model="patientInfo.patientName" class="input-with-bottom-border"/>
|
<div style="flex: 1; min-width: 120px; font-size: 14px; line-height: 24px;">
|
||||||
</el-form-item>
|
<strong>性别:</strong> {{ patientInfo.genderEnum_enumText || '' }}
|
||||||
</el-col>
|
</div>
|
||||||
<el-col :span="4">
|
<div style="flex: 1; min-width: 120px; font-size: 14px; line-height: 24px;">
|
||||||
<el-form-item label="性别" prop="genderEnum_enumText" style="width: 100%">
|
<strong>年龄:</strong> {{ patientInfo.age || '' }}
|
||||||
<el-input placeholder="" v-model="patientInfo.genderEnum_enumText" class="input-with-bottom-border"/>
|
</div>
|
||||||
</el-form-item>
|
</div>
|
||||||
</el-col>
|
|
||||||
<el-col :span="4">
|
<!-- 就诊信息 -->
|
||||||
<el-form-item label="年龄" prop="age" style="width: 100%">
|
<div style="display: flex; flex-wrap: wrap; gap: 10px; padding: 10px 0; border-bottom: 1px solid #ebeef5;">
|
||||||
<el-input placeholder="" v-model="patientInfo.age" class="input-with-bottom-border"/>
|
<div style="flex: 1; min-width: 200px; font-size: 14px; line-height: 24px;">
|
||||||
</el-form-item>
|
<strong>就诊日期:</strong> {{ currentVisitDate }}
|
||||||
</el-col>
|
</div>
|
||||||
<el-col :span="4">
|
<div style="flex: 1; min-width: 200px; font-size: 14px; line-height: 24px;">
|
||||||
<el-form-item label="就诊日期" prop="currentVisitDate" style="width: 100%">
|
<strong>就诊科室:</strong> {{ patientInfo.organizationName || '' }}
|
||||||
<el-input placeholder="" v-model="currentVisitDate" class="input-with-bottom-border"/>
|
</div>
|
||||||
</el-form-item>
|
</div>
|
||||||
</el-col>
|
|
||||||
<el-col :span="4">
|
<!-- 生命体征 -->
|
||||||
<el-form-item label="就诊科室" prop="organizationName" style="width: 100%">
|
<div style="display: flex; flex-wrap: wrap; gap: 10px; padding: 10px 0; border-bottom: 1px solid #ebeef5;">
|
||||||
<el-input placeholder="" v-model="patientInfo.organizationName" class="input-with-bottom-border"/>
|
<div style="flex: 1; min-width: 120px; font-size: 14px; line-height: 24px;">
|
||||||
</el-form-item>
|
<strong>身高:</strong> {{ form.height ? form.height + ' cm' : '' }}
|
||||||
</el-col>
|
</div>
|
||||||
</el-row>
|
<div style="flex: 1; min-width: 120px; font-size: 14px; line-height: 24px;">
|
||||||
<el-row :gutter="24">
|
<strong>体重:</strong> {{ form.weight ? form.weight + ' kg' : '' }}
|
||||||
<el-col :span="6">
|
</div>
|
||||||
<el-form-item label="身高" prop="height" style="width: 100%">
|
<div style="flex: 1; min-width: 120px; font-size: 14px; line-height: 24px;">
|
||||||
<el-input placeholder="" v-model="form.height" class="input-with-bottom-border">
|
<strong>体温:</strong> {{ form.temperature ? form.temperature + ' ℃' : '' }}
|
||||||
<template #suffix>cm</template>
|
</div>
|
||||||
</el-input>
|
<div style="flex: 1; min-width: 120px; font-size: 14px; line-height: 24px;">
|
||||||
</el-form-item>
|
<strong>脉搏:</strong> {{ form.pulse ? form.pulse + ' 次/分' : '' }}
|
||||||
</el-col>
|
</div>
|
||||||
<el-col :span="6">
|
</div>
|
||||||
<el-form-item label="体重" prop="weight" style="width: 100%">
|
|
||||||
<el-input placeholder="" v-model="form.weight" class="input-with-bottom-border">
|
<!-- 主诉 + 发病日期 -->
|
||||||
<template #suffix>kg</template>
|
<div style="display: flex; flex-wrap: wrap; gap: 10px; padding: 10px 0; border-bottom: 1px solid #ebeef5;">
|
||||||
</el-input>
|
<div style="flex: 1; min-width: 300px; font-size: 14px; line-height: 24px;">
|
||||||
</el-form-item>
|
<strong>主诉:</strong> {{ form.chiefComplaint || '' }}
|
||||||
</el-col>
|
</div>
|
||||||
<el-col :span="6">
|
<div style="flex: 1; min-width: 120px; font-size: 14px; line-height: 24px;">
|
||||||
<el-form-item label="体温" prop="temperature" style="width: 100%">
|
<strong>发病日期:</strong> {{ formatDate(form.onsetDate) }}
|
||||||
<el-input placeholder="" v-model="form.temperature" class="input-with-bottom-border">
|
</div>
|
||||||
<template #suffix>℃</template>
|
</div>
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
<!-- 多行文本字段 -->
|
||||||
</el-col>
|
<div v-for="field in textFieldList" :key="field.key" style="padding: 10px 0;">
|
||||||
<el-col :span="6">
|
<div style="font-size: 14px; margin-bottom: 5px;">
|
||||||
<el-form-item label="脉搏" prop="pulse" style="width: 100%">
|
<strong>{{ field.label }}:</strong>
|
||||||
<el-input placeholder="" v-model="form.pulse" class="input-with-bottom-border">
|
</div>
|
||||||
<template #suffix>次/分</template>
|
<div style="font-size: 14px; line-height: 1.5; white-space: pre-wrap;">
|
||||||
</el-input>
|
{{ form[field.key] || '' }}
|
||||||
</el-form-item>
|
</div>
|
||||||
</el-col>
|
</div>
|
||||||
</el-row>
|
|
||||||
<el-row :gutter="24">
|
<!-- 弹窗 -->
|
||||||
<!-- <el-col :span="6">
|
|
||||||
<el-form-item
|
|
||||||
label="血糖"
|
|
||||||
prop="chiefComplaint"
|
|
||||||
style="width: 100%"
|
|
||||||
>
|
|
||||||
<el-input placeholder="" class="input-with-bottom-border">
|
|
||||||
<template #suffix></template>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="6">
|
|
||||||
<el-form-item
|
|
||||||
label="血糖"
|
|
||||||
prop="chiefComplaint"
|
|
||||||
style="width: 100%"
|
|
||||||
>
|
|
||||||
<el-input placeholder="" class="input-with-bottom-border">
|
|
||||||
<template #suffix>mmol/L</template>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="6">
|
|
||||||
<el-form-item
|
|
||||||
label="收缩压"
|
|
||||||
prop="chiefComplaint"
|
|
||||||
style="width: 100%"
|
|
||||||
>
|
|
||||||
<el-input placeholder="" class="input-with-bottom-border">
|
|
||||||
<template #suffix>mmHg</template>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="6">
|
|
||||||
<el-form-item
|
|
||||||
label="舒张压"
|
|
||||||
prop="chiefComplaint"
|
|
||||||
style="width: 100%"
|
|
||||||
>
|
|
||||||
<el-input placeholder="" class="input-with-bottom-border">
|
|
||||||
<template #suffix>mmHg</template>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col> -->
|
|
||||||
</el-row>
|
|
||||||
<el-row :gutter="24">
|
|
||||||
<el-col :span="18">
|
|
||||||
<el-form-item label="主诉" prop="chiefComplaint">
|
|
||||||
<el-input v-model="form.chiefComplaint" type="textarea" :rows="1" placeholder="" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="6">
|
|
||||||
<el-form-item label="发病日期" prop="onsetDate">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="form.onsetDate"
|
|
||||||
type="date"
|
|
||||||
size="default"
|
|
||||||
style="width: 100% !important"
|
|
||||||
placement="bottom"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-form-item label="现病史" prop="currentIllnessHistory">
|
|
||||||
<el-input v-model="form.currentIllnessHistory" type="textarea" :rows="2" placeholder="" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="既往史" prop="pastMedicalHistory">
|
|
||||||
<el-input v-model="form.pastMedicalHistory" type="textarea" :rows="2" placeholder="" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="个人史" prop="menstrualHistory">
|
|
||||||
<el-input v-model="form.menstrualHistory" type="textarea" :rows="2" placeholder="" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="过敏史" prop="allergyHistory">
|
|
||||||
<el-input v-model="form.allergyHistory" type="textarea" :rows="2" placeholder="" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="查体" prop="physicalExamination">
|
|
||||||
<el-input v-model="form.physicalExamination" type="textarea" :rows="2" placeholder="" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="处理" prop="treatment">
|
|
||||||
<el-input v-model="form.treatment" type="textarea" :rows="2" placeholder="" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="辅助检查" prop="auxiliaryExamination">
|
|
||||||
<el-input v-model="form.auxiliaryExamination" type="textarea" :rows="2" placeholder="" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<el-dialog
|
<el-dialog
|
||||||
:title="emrTitle"
|
:title="emrTitle"
|
||||||
v-model="openEmrTemplate"
|
v-model="openEmrTemplate"
|
||||||
:width="showDialog == 'emrHistory'?'800px':'600px'"
|
:width="showDialog === 'emrHistory' ? '800px' : '600px'"
|
||||||
append-to-body
|
append-to-body
|
||||||
destroy-on-close
|
destroy-on-close
|
||||||
>
|
>
|
||||||
<emrTemplate v-if="showDialog == 'emrTemplate'" @selectRow="templateSelect" />
|
<emrTemplate v-if="showDialog === 'emrTemplate'" @selectRow="templateSelect" />
|
||||||
<emrhistory v-if="showDialog == 'emrHistory'" @selectRow="emrHistorySelect" />
|
<emrhistory v-if="showDialog === 'emrHistory'" @selectRow="emrHistorySelect" />
|
||||||
<div v-if="showDialog == 'saveTemplate'">
|
<div v-if="showDialog === 'saveTemplate'">
|
||||||
<span> 模板名称: </span>
|
<span>模板名称:</span>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="templateName"
|
v-model="templateName"
|
||||||
style="width: 260px; margin-top: 10px; margin-right: 20px"
|
style="width: 260px; margin-top: 10px; margin-right: 20px"
|
||||||
@@ -203,91 +124,114 @@ import { saveEmr, getEmrDetail, saveEmrTemplate } from '../api';
|
|||||||
import emrTemplate from '../emr/emrtemplate.vue';
|
import emrTemplate from '../emr/emrtemplate.vue';
|
||||||
import emrhistory from '../emr/emrhistory.vue';
|
import emrhistory from '../emr/emrhistory.vue';
|
||||||
|
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed, watch, getCurrentInstance } from 'vue';
|
||||||
|
import { formatDate as formatDateUtil } from '@/utils/index';
|
||||||
|
|
||||||
// 2. 当前就诊日期(默认为当前时间)
|
// Props
|
||||||
const currentVisitDate = computed(() => {
|
|
||||||
return new Date().toLocaleString('zh-CN', {
|
|
||||||
year: 'numeric',
|
|
||||||
month: '2-digit',
|
|
||||||
day: '2-digit',
|
|
||||||
hour: '2-digit',
|
|
||||||
minute: '2-digit',
|
|
||||||
second: '2-digit',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const form = ref({});
|
|
||||||
const emrTitle = ref('');
|
|
||||||
const radio = ref(1);
|
|
||||||
const rules = ref({
|
|
||||||
chiefComplaint: [{ required: true, message: '请输入主诉', trigger: 'blur' }],
|
|
||||||
});
|
|
||||||
const emits = defineEmits(['save']);
|
|
||||||
const { proxy } = getCurrentInstance();
|
|
||||||
const showDialog = ref('');
|
|
||||||
const openEmrTemplate = ref(false);
|
|
||||||
const templateName = ref('');
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
patientInfo: {
|
patientInfo: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
visitType: { // ✅ 接收父组件传来的值
|
visitType: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
firstVisitDate: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Computed: 当前就诊日期
|
||||||
|
const currentVisitDate = computed(() => {
|
||||||
|
if (props.visitType === 'FOLLOW_UP' && props.firstVisitDate) {
|
||||||
|
return props.firstVisitDate;
|
||||||
|
}
|
||||||
|
return formatDateUtil(props.patientInfo?.registerTime || new Date());
|
||||||
|
});
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const form = ref({
|
||||||
|
height: '',
|
||||||
|
weight: '',
|
||||||
|
temperature: '',
|
||||||
|
pulse: '',
|
||||||
|
chiefComplaint: '',
|
||||||
|
onsetDate: '',
|
||||||
|
currentIllnessHistory: '',
|
||||||
|
pastMedicalHistory: '',
|
||||||
|
menstrualHistory: '',
|
||||||
|
allergyHistory: '',
|
||||||
|
physicalExamination: '',
|
||||||
|
treatment: '',
|
||||||
|
auxiliaryExamination: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
// 文本字段配置(用于循环渲染)
|
||||||
|
const textFieldList = [
|
||||||
|
{ key: 'currentIllnessHistory', label: '现病史' },
|
||||||
|
{ key: 'pastMedicalHistory', label: '既往史' },
|
||||||
|
{ key: 'menstrualHistory', label: '个人史' },
|
||||||
|
{ key: 'allergyHistory', label: '过敏史' },
|
||||||
|
{ key: 'physicalExamination', label: '查体' },
|
||||||
|
{ key: 'treatment', label: '处理' },
|
||||||
|
{ key: 'auxiliaryExamination', label: '辅助检查' },
|
||||||
|
];
|
||||||
|
|
||||||
|
// 弹窗控制
|
||||||
|
const emrTitle = ref('');
|
||||||
|
const radio = ref(1);
|
||||||
|
const showDialog = ref('');
|
||||||
|
const openEmrTemplate = ref(false);
|
||||||
|
const templateName = ref('');
|
||||||
|
|
||||||
|
// 事件
|
||||||
|
const emits = defineEmits(['save']);
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
// 监听表单变化
|
||||||
watch(
|
watch(
|
||||||
() => form.value,
|
() => form.value,
|
||||||
() => {
|
() => {
|
||||||
// 如果表单数据有变化,通知父组件保存
|
|
||||||
emits('save', false);
|
emits('save', false);
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
// 格式化日期(用于 onsetDate)
|
||||||
* 保存病历
|
function formatDate(date) {
|
||||||
*/
|
if (!date) return '';
|
||||||
|
return formatDateUtil(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存病历
|
||||||
function addEmr() {
|
function addEmr() {
|
||||||
proxy.$refs['emrRef'].validate((valid) => {
|
// 简单校验主诉
|
||||||
if (valid) {
|
if (!form.value.chiefComplaint) {
|
||||||
saveEmr({
|
proxy.$message.warning('请输入主诉');
|
||||||
patientId: props.patientInfo.patientId,
|
return;
|
||||||
encounterId: props.patientInfo.encounterId,
|
}
|
||||||
contextJson: form.value,
|
saveEmr({
|
||||||
}).then((res) => {
|
patientId: props.patientInfo.patientId,
|
||||||
if (res.code == 200) {
|
encounterId: props.patientInfo.encounterId,
|
||||||
proxy.$modal.msgSuccess('病历已保存');
|
contextJson: form.value,
|
||||||
emits('save', true);
|
}).then((res) => {
|
||||||
}
|
if (res.code === 200) {
|
||||||
});
|
proxy.$modal.msgSuccess('病历已保存');
|
||||||
|
emits('save', true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* 病历模板
|
// 打开模板
|
||||||
*/
|
|
||||||
function handleEmrTemplate() {
|
function handleEmrTemplate() {
|
||||||
emrTitle.value = '病历模板';
|
emrTitle.value = '病历模板';
|
||||||
showDialog.value = 'emrTemplate';
|
showDialog.value = 'emrTemplate';
|
||||||
openEmrTemplate.value = true;
|
openEmrTemplate.value = true;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* 选择病历模板
|
// 打开历史
|
||||||
*/
|
|
||||||
function templateSelect(row) {
|
|
||||||
form.value = row;
|
|
||||||
}
|
|
||||||
function emrHistorySelect(row) {
|
|
||||||
form.value = row;
|
|
||||||
openEmrTemplate.value = false;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 历史病历
|
|
||||||
*/
|
|
||||||
function handleEmrHistory() {
|
function handleEmrHistory() {
|
||||||
emrTitle.value = '历史病历';
|
emrTitle.value = '历史病历';
|
||||||
showDialog.value = 'emrHistory';
|
showDialog.value = 'emrHistory';
|
||||||
@@ -295,55 +239,93 @@ function handleEmrHistory() {
|
|||||||
sessionStorage.setItem('patientId', props.patientInfo.patientId);
|
sessionStorage.setItem('patientId', props.patientInfo.patientId);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDetail(encounterId) {
|
// 保存为模板
|
||||||
getEmrDetail(encounterId).then((res) => {
|
|
||||||
if (res.data) {
|
|
||||||
form.value = JSON.parse(res.data.contextJson);
|
|
||||||
// 提交父组件刷新保存装填
|
|
||||||
emits('save', true);
|
|
||||||
} else {
|
|
||||||
form.value = {};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 保存病历模板
|
|
||||||
*/
|
|
||||||
function handleSaveTemplate() {
|
function handleSaveTemplate() {
|
||||||
emrTitle.value = '保存模板';
|
emrTitle.value = '保存模板';
|
||||||
showDialog.value = 'saveTemplate';
|
showDialog.value = 'saveTemplate';
|
||||||
openEmrTemplate.value = true;
|
openEmrTemplate.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// 选择模板/历史
|
||||||
* 弹窗确认操作,包括保存病历模板/选择病历模板/选择历史病历
|
function templateSelect(row) {
|
||||||
*/
|
form.value = { ...row };
|
||||||
function submit() {
|
openEmrTemplate.value = false;
|
||||||
switch (showDialog.value) {
|
}
|
||||||
case 'saveTemplate':
|
function emrHistorySelect(row) {
|
||||||
saveEmrTemplate({
|
form.value = { ...row };
|
||||||
templateName: templateName.value,
|
|
||||||
useScopeCode: radio.value,
|
|
||||||
contextJson: form.value,
|
|
||||||
}).then((res) => {
|
|
||||||
if (res.code == 200) {
|
|
||||||
openEmrTemplate.value = false;
|
|
||||||
proxy.$modal.msgSuccess('保存成功');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case 'emrTemplate':
|
|
||||||
openEmrTemplate.value = false;
|
|
||||||
break;
|
|
||||||
case 'emrHistory':
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function cancel() {
|
|
||||||
openEmrTemplate.value = false;
|
openEmrTemplate.value = false;
|
||||||
// openDiagnosis.value = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({ getDetail, addEmr });
|
// 弹窗确认
|
||||||
</script>
|
function submit() {
|
||||||
|
if (showDialog.value === 'saveTemplate') {
|
||||||
|
if (!templateName.value.trim()) {
|
||||||
|
proxy.$message.warning('请输入模板名称');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
saveEmrTemplate({
|
||||||
|
templateName: templateName.value,
|
||||||
|
useScopeCode: radio.value,
|
||||||
|
contextJson: form.value,
|
||||||
|
}).then((res) => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
openEmrTemplate.value = false;
|
||||||
|
proxy.$modal.msgSuccess('保存成功');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
openEmrTemplate.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancel() {
|
||||||
|
openEmrTemplate.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 可选:打印功能
|
||||||
|
// function printEmr() {
|
||||||
|
// const printContent = proxy.$refs.printArea.innerHTML;
|
||||||
|
// const originalContent = document.body.innerHTML;
|
||||||
|
// document.body.innerHTML = printContent;
|
||||||
|
// window.print();
|
||||||
|
// document.body.innerHTML = originalContent;
|
||||||
|
// window.location.reload(); // 恢复组件状态
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 暴露方法给父组件
|
||||||
|
defineExpose({
|
||||||
|
getDetail(encounterId) {
|
||||||
|
getEmrDetail(encounterId).then((res) => {
|
||||||
|
if (res.data) {
|
||||||
|
try {
|
||||||
|
form.value = JSON.parse(res.data.contextJson) || {};
|
||||||
|
} catch (e) {
|
||||||
|
form.value = {};
|
||||||
|
}
|
||||||
|
emits('save', true);
|
||||||
|
} else {
|
||||||
|
form.value = {};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
addEmr
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 可选:增强打印样式 */
|
||||||
|
@media print {
|
||||||
|
body * {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
#printArea, #printArea * {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
#printArea {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -10,23 +10,15 @@
|
|||||||
<el-table
|
<el-table
|
||||||
ref="emrHistoryRef"
|
ref="emrHistoryRef"
|
||||||
:data="emrHistory"
|
:data="emrHistory"
|
||||||
row-key="patientId"
|
row-key="id"
|
||||||
highlight-current-row
|
|
||||||
@selection-change="handleSelectionChange"
|
@selection-change="handleSelectionChange"
|
||||||
>
|
>
|
||||||
<!-- @cell-click="clickRow" -->
|
|
||||||
<el-table-column type="selection" width="55" />
|
<el-table-column type="selection" width="55" />
|
||||||
<el-table-column label="主诉" align="left" prop="name" :show-overflow-tooltip="true"/>
|
<el-table-column label="主诉" align="left" prop="name" :show-overflow-tooltip="true"/>
|
||||||
<el-table-column label="时间" align="center" prop="createTime" width="180" :show-overflow-tooltip="true"/>
|
<el-table-column label="时间" align="center" prop="createTime" width="180" :show-overflow-tooltip="true"/>
|
||||||
<el-table-column label="操作" align="center" width="80">
|
<el-table-column label="操作" align="center" width="80">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<!-- <el-button
|
<el-button link type="primary" @click.stop="clickRow(scope.row)">复用</el-button>
|
||||||
link
|
|
||||||
type="primary"
|
|
||||||
@click.stop="handelDetail(scope.row)"
|
|
||||||
>详情
|
|
||||||
</el-button> -->
|
|
||||||
<el-button link type="primary" @click.stop="clickRow(scope.row)">复用 </el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -43,6 +35,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { formatDate, formatDateymd } from '@/utils/index';
|
import { formatDate, formatDateymd } from '@/utils/index';
|
||||||
import { getEmrHistoryList } from '../api';
|
import { getEmrHistoryList } from '../api';
|
||||||
|
|
||||||
const queryParams = ref({
|
const queryParams = ref({
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
@@ -51,13 +44,19 @@ const queryParams = ref({
|
|||||||
const selectRow = ref({});
|
const selectRow = ref({});
|
||||||
const emrHistory = ref([]);
|
const emrHistory = ref([]);
|
||||||
const emits = defineEmits(['selectRow']);
|
const emits = defineEmits(['selectRow']);
|
||||||
|
const emrHistoryRef = ref(null);
|
||||||
|
const selectedRows = ref([]);
|
||||||
|
|
||||||
|
const total = ref(0);
|
||||||
|
|
||||||
getList();
|
getList();
|
||||||
|
|
||||||
function getList() {
|
function getList() {
|
||||||
if (sessionStorage.getItem('patientId')) {
|
if (sessionStorage.getItem('patientId')) {
|
||||||
queryParams.value.patientId = sessionStorage.getItem('patientId');
|
queryParams.value.patientId = sessionStorage.getItem('patientId');
|
||||||
getEmrHistoryList(queryParams.value).then((res) => {
|
getEmrHistoryList(queryParams.value).then((res) => {
|
||||||
emrHistory.value = res.data.records;
|
emrHistory.value = res.data.records;
|
||||||
|
total.value = res.data.total;
|
||||||
emrHistory.value.map((k) => {
|
emrHistory.value.map((k) => {
|
||||||
k.name = JSON.parse(k.contextJson).chiefComplaint;
|
k.name = JSON.parse(k.contextJson).chiefComplaint;
|
||||||
k.createTime = formatDate(k.createTime);
|
k.createTime = formatDate(k.createTime);
|
||||||
@@ -66,6 +65,12 @@ function getList() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleSelectionChange(selection) {
|
||||||
|
// 直接更新选中行数据,不干涉表格UI状态
|
||||||
|
// 这样可以允许用户使用全选框功能
|
||||||
|
selectedRows.value = selection;
|
||||||
|
}
|
||||||
|
|
||||||
function clickRow(row) {
|
function clickRow(row) {
|
||||||
selectRow.value = JSON.parse(row.contextJson);
|
selectRow.value = JSON.parse(row.contextJson);
|
||||||
emits('selectRow', selectRow.value);
|
emits('selectRow', selectRow.value);
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ const props = defineProps({
|
|||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
// getList();
|
getList();
|
||||||
function getList() {
|
function getList() {
|
||||||
queryParams.value.useScopeCode = 1;
|
queryParams.value.useScopeCode = 1;
|
||||||
getEmrTemplateList(queryParams.value).then((res) => {
|
getEmrTemplateList(queryParams.value).then((res) => {
|
||||||
|
|||||||
@@ -108,24 +108,7 @@
|
|||||||
v-for="item in scope.row.stockList"
|
v-for="item in scope.row.stockList"
|
||||||
:key="item.inventoryId"
|
:key="item.inventoryId"
|
||||||
:value="item.inventoryId"
|
:value="item.inventoryId"
|
||||||
:label="
|
:label="item.locationName"
|
||||||
item.locationName +
|
|
||||||
' ' +
|
|
||||||
'批次号: ' +
|
|
||||||
item.lotNumber +
|
|
||||||
' ' +
|
|
||||||
' 库存:' +
|
|
||||||
stockFormat(
|
|
||||||
scope.row.partPercent,
|
|
||||||
scope.row.unitCode_dictText,
|
|
||||||
scope.row.minUnitCode_dictText,
|
|
||||||
item.quantity
|
|
||||||
) +
|
|
||||||
' 单价:' +
|
|
||||||
item.price.toFixed(2) +
|
|
||||||
'/' +
|
|
||||||
item.unitCode_dictText
|
|
||||||
"
|
|
||||||
@click="handleNumberClick(item, scope.$index)"
|
@click="handleNumberClick(item, scope.$index)"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -390,24 +373,7 @@
|
|||||||
v-for="item in scope.row.stockList"
|
v-for="item in scope.row.stockList"
|
||||||
:key="item.lotNumber"
|
:key="item.lotNumber"
|
||||||
:value="item.lotNumber"
|
:value="item.lotNumber"
|
||||||
:label="
|
:label="item.locationName "
|
||||||
item.locationName +
|
|
||||||
' ' +
|
|
||||||
'批次号: ' +
|
|
||||||
item.lotNumber +
|
|
||||||
' ' +
|
|
||||||
' 库存:' +
|
|
||||||
stockFormat(
|
|
||||||
scope.row.partPercent,
|
|
||||||
scope.row.unitCode_dictText,
|
|
||||||
scope.row.minUnitCode_dictText,
|
|
||||||
item.quantity
|
|
||||||
) +
|
|
||||||
' 单价:' +
|
|
||||||
item.price.toFixed(2) +
|
|
||||||
'/' +
|
|
||||||
item.unitCode_dictText
|
|
||||||
"
|
|
||||||
@click="handleNumberClick(item, scope.$index)"
|
@click="handleNumberClick(item, scope.$index)"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -550,40 +516,36 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<!-- <el-table-column label="序号" align="center" width="60" prop="sortNumber"> </el-table-column> -->
|
<!-- <el-table-column label="序号" align="center" width="60" prop="sortNumber"> </el-table-column> -->
|
||||||
<el-table-column label="医嘱" align="center" prop="productName" width="400">
|
<!-- 医嘱类型列 -->
|
||||||
|
<el-table-column label="医嘱类型" align="center" width="120">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<template v-if="getRowDisabled(scope.row)">
|
<template v-if="getRowDisabled(scope.row)">
|
||||||
<el-select
|
<el-select
|
||||||
style="width: 35%; margin-right: 20px"
|
|
||||||
v-model="scope.row.adviceType"
|
v-model="scope.row.adviceType"
|
||||||
:ref="'adviceTypeRef' + scope.$index"
|
:ref="'adviceTypeRef' + scope.$index"
|
||||||
@change="
|
@change="handleAdviceTypeChange(scope.row, scope.$index)"
|
||||||
(value) => {
|
placeholder="请选择"
|
||||||
expandOrder = [];
|
style="width: 100%">
|
||||||
prescriptionList[scope.$index].adviceName = undefined;
|
|
||||||
adviceQueryParams.adviceType = value;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in adviceTypeList"
|
v-for="dict in drord_type"
|
||||||
:key="item.value"
|
:key="dict.value"
|
||||||
:label="item.label"
|
:label="dict.label"
|
||||||
:value="item.value"
|
:value="dict.value"
|
||||||
@click="
|
|
||||||
() => {
|
|
||||||
prescriptionList[scope.$index].adviceType = item.value;
|
|
||||||
prescriptionList[scope.$index].adviceType_dictText = item.label;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
|
</template>
|
||||||
|
<span v-else>{{ getAdviceTypeText(scope.row.adviceType) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<!-- 项目列 -->
|
||||||
|
<el-table-column label="项目" align="center" prop="productName" width="280">
|
||||||
|
<template #default="scope">
|
||||||
|
<template v-if="getRowDisabled(scope.row)">
|
||||||
<el-popover
|
<el-popover
|
||||||
:popper-style="{ padding: '0' }"
|
:popper-style="{ padding: '0' }"
|
||||||
placement="bottom-start"
|
placement="bottom-start"
|
||||||
:visible="scope.row.showPopover"
|
:visible="scope.row.showPopover"
|
||||||
:width="1200"
|
:width="1200">
|
||||||
>
|
|
||||||
<adviceBaseList
|
<adviceBaseList
|
||||||
ref="adviceTableRef"
|
ref="adviceTableRef"
|
||||||
:popoverVisible="scope.row.showPopover"
|
:popoverVisible="scope.row.showPopover"
|
||||||
@@ -594,24 +556,14 @@
|
|||||||
<template #reference>
|
<template #reference>
|
||||||
<el-input
|
<el-input
|
||||||
:ref="'adviceRef' + scope.$index"
|
:ref="'adviceRef' + scope.$index"
|
||||||
style="width: 50%"
|
|
||||||
v-model="scope.row.adviceName"
|
v-model="scope.row.adviceName"
|
||||||
placeholder="请选择项目"
|
placeholder="请选择项目"
|
||||||
@input="handleChange"
|
@input="handleChange"
|
||||||
@click="handleFocus(scope.row, scope.$index)"
|
@click="handleFocus(scope.row, scope.$index)"
|
||||||
@keyup.enter.stop="handleFocus(scope.row, scope.$index)"
|
@keyup.enter.stop="handleFocus(scope.row, scope.$index)"
|
||||||
@keydown="
|
@keydown="handleInputKeyDown(scope.row, $event)"
|
||||||
(e) => {
|
|
||||||
if (!scope.row.showPopover) return;
|
|
||||||
// 拦截上下键和回车事件
|
|
||||||
if (['ArrowUp', 'ArrowDown', 'Enter'].includes(e.key)) {
|
|
||||||
e.preventDefault();
|
|
||||||
// 传递事件到弹窗容器
|
|
||||||
adviceTableRef.handleKeyDown(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"
|
|
||||||
@blur="handleBlur(scope.row)"
|
@blur="handleBlur(scope.row)"
|
||||||
|
style="width: 100%"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
@@ -735,7 +687,7 @@ import {
|
|||||||
getAdviceBaseInfo,
|
getAdviceBaseInfo,
|
||||||
getActivityBindDevice,
|
getActivityBindDevice,
|
||||||
} from '../api';
|
} from '../api';
|
||||||
import adviceBaseList from '../advicebaselist';
|
import adviceBaseList from '../adviceBaseList.vue';
|
||||||
import { computed, getCurrentInstance, nextTick, watch } from 'vue';
|
import { computed, getCurrentInstance, nextTick, watch } from 'vue';
|
||||||
import { calculateQuantityByDays, formatNumber } from '@/utils/his';
|
import { calculateQuantityByDays, formatNumber } from '@/utils/his';
|
||||||
import OrderGroupDrawer from './orderGroupDrawer';
|
import OrderGroupDrawer from './orderGroupDrawer';
|
||||||
@@ -751,7 +703,10 @@ const prescriptionList = ref([]);
|
|||||||
const form = ref({
|
const form = ref({
|
||||||
prescriptionList: prescriptionList.value,
|
prescriptionList: prescriptionList.value,
|
||||||
});
|
});
|
||||||
const adviceQueryParams = ref({});
|
const adviceQueryParams = ref({
|
||||||
|
searchKey: '',
|
||||||
|
adviceType: ''
|
||||||
|
});
|
||||||
const rowIndex = ref(-1);
|
const rowIndex = ref(-1);
|
||||||
const groupIndex = ref(1);
|
const groupIndex = ref(1);
|
||||||
const groupIndexList = ref([]);
|
const groupIndexList = ref([]);
|
||||||
@@ -806,11 +761,12 @@ const { proxy } = getCurrentInstance();
|
|||||||
const inputRefs = ref({}); // 存储输入框实例
|
const inputRefs = ref({}); // 存储输入框实例
|
||||||
const requiredProps = ref([]); // 存储必填项 prop 顺序
|
const requiredProps = ref([]); // 存储必填项 prop 顺序
|
||||||
const totalAmount = ref(0);
|
const totalAmount = ref(0);
|
||||||
const { method_code, unit_code, rate_code, distribution_category_code } = proxy.useDict(
|
const { method_code, unit_code, rate_code, distribution_category_code,drord_type } = proxy.useDict(
|
||||||
'method_code',
|
'method_code',
|
||||||
'unit_code',
|
'unit_code',
|
||||||
'rate_code',
|
'rate_code',
|
||||||
'distribution_category_code'
|
'distribution_category_code',
|
||||||
|
'drord_type'
|
||||||
);
|
);
|
||||||
|
|
||||||
const adviceTypeList = ref([
|
const adviceTypeList = ref([
|
||||||
@@ -863,6 +819,15 @@ watch(
|
|||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
|
// 获取医嘱类别显示文本
|
||||||
|
function getAdviceTypeText(adviceType) {
|
||||||
|
const typeMap = {
|
||||||
|
1: '西药中成药',
|
||||||
|
2: '耗材',
|
||||||
|
3: '诊疗'
|
||||||
|
};
|
||||||
|
return typeMap[adviceType] || '未知';
|
||||||
|
}
|
||||||
function handleTotalAmount() {
|
function handleTotalAmount() {
|
||||||
totalAmount.value = prescriptionList.value.reduce((accumulator, currentRow) => {
|
totalAmount.value = prescriptionList.value.reduce((accumulator, currentRow) => {
|
||||||
if (currentRow.chargeStatus != 8) {
|
if (currentRow.chargeStatus != 8) {
|
||||||
@@ -933,6 +898,9 @@ function handleAddPrescription() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
isAdding.value = true;
|
isAdding.value = true;
|
||||||
|
// 重置查询参数
|
||||||
|
adviceQueryParams.value = {};
|
||||||
|
|
||||||
// 在数组最前方添加一行,让新增行显示在最上边
|
// 在数组最前方添加一行,让新增行显示在最上边
|
||||||
prescriptionList.value.unshift({
|
prescriptionList.value.unshift({
|
||||||
uniqueKey: nextId.value++,
|
uniqueKey: nextId.value++,
|
||||||
@@ -979,10 +947,17 @@ function handleDiagnosisChange(item) {
|
|||||||
function handleFocus(row, index) {
|
function handleFocus(row, index) {
|
||||||
rowIndex.value = index;
|
rowIndex.value = index;
|
||||||
row.showPopover = true;
|
row.showPopover = true;
|
||||||
|
// 确保查询参数与当前行类型一致
|
||||||
|
adviceQueryParams.value = {
|
||||||
|
adviceType: row.adviceType || '',
|
||||||
|
searchKey: adviceQueryParams.value.searchKey || ''
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleBlur(row) {
|
function handleBlur(row) {
|
||||||
row.showPopover = false;
|
setTimeout(() => {
|
||||||
|
row.showPopover = false;
|
||||||
|
}, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleChange(value) {
|
function handleChange(value) {
|
||||||
@@ -993,6 +968,8 @@ function handleChange(value) {
|
|||||||
* 选择药品回调
|
* 选择药品回调
|
||||||
*/
|
*/
|
||||||
function selectAdviceBase(key, row) {
|
function selectAdviceBase(key, row) {
|
||||||
|
// 立即关闭当前弹窗
|
||||||
|
prescriptionList.value[rowIndex.value].showPopover = false;
|
||||||
if (row.adviceType == 3) {
|
if (row.adviceType == 3) {
|
||||||
getActivityBindDevice({ activityId: row.adviceDefinitionId }).then((res) => {
|
getActivityBindDevice({ activityId: row.adviceDefinitionId }).then((res) => {
|
||||||
if (res.data.activityBindDeviceInfos?.length > 0) {
|
if (res.data.activityBindDeviceInfos?.length > 0) {
|
||||||
@@ -1093,10 +1070,12 @@ function selectAdviceBase(key, row) {
|
|||||||
prescriptionList.value[rowIndex.value].positionName = stock.locationName;
|
prescriptionList.value[rowIndex.value].positionName = stock.locationName;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
prescriptionList.value[rowIndex.value].orgId = JSON.parse(JSON.stringify(row)).positionId;
|
// 执行科室默认逻辑:优先使用诊疗项目维护的所属科室,如果没有则使用开单科室
|
||||||
prescriptionList.value[rowIndex.value].unitPrice = row.priceList[0].price;
|
const defaultOrgId = row.positionId || props.patientInfo.orgId;
|
||||||
}
|
prescriptionList.value[rowIndex.value].orgId = defaultOrgId;
|
||||||
expandOrder.value = [key];
|
prescriptionList.value[rowIndex.value].unitPrice = row.priceList[0].price;
|
||||||
|
}
|
||||||
|
expandOrder.value = [key];
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
if (row.adviceType == 1) {
|
if (row.adviceType == 1) {
|
||||||
if (row.injectFlag == 1) {
|
if (row.injectFlag == 1) {
|
||||||
@@ -1108,6 +1087,7 @@ function selectAdviceBase(key, row) {
|
|||||||
inputRefs.value['quantity']?.focus();
|
inputRefs.value['quantity']?.focus();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOrgList() {
|
function getOrgList() {
|
||||||
@@ -1488,9 +1468,11 @@ function setValue(row) {
|
|||||||
.toFixed(2);
|
.toFixed(2);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
prescriptionList.value[rowIndex.value].orgId = JSON.parse(JSON.stringify(row)).positionId;
|
// 执行科室默认逻辑:优先使用诊疗项目维护的所属科室,如果没有则使用开单科室
|
||||||
prescriptionList.value[rowIndex.value].unitPrice = row.priceList[0].price;
|
const defaultOrgId = row.positionId || props.patientInfo.orgId;
|
||||||
}
|
prescriptionList.value[rowIndex.value].orgId = defaultOrgId;
|
||||||
|
prescriptionList.value[rowIndex.value].unitPrice = row.priceList[0].price;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 组套保存
|
// 组套保存
|
||||||
|
|||||||
@@ -100,8 +100,8 @@
|
|||||||
}}</el-descriptions-item>
|
}}</el-descriptions-item>
|
||||||
<el-descriptions-item label="" width="350">
|
<el-descriptions-item label="" width="350">
|
||||||
<!-- 初诊 / 复诊 按钮 -->
|
<!-- 初诊 / 复诊 按钮 -->
|
||||||
<el-radio v-model="visitType" label="FIRST">初诊</el-radio>
|
<el-radio v-model="visitType" label="FIRST" :disabled="visitTypeDisabled">初诊</el-radio>
|
||||||
<el-radio v-model="visitType" label="FOLLOW_UP">复诊</el-radio>
|
<el-radio v-model="visitType" label="FOLLOW_UP" :disabled="visitTypeDisabled">复诊</el-radio>
|
||||||
|
|
||||||
<!-- 原有按钮 -->
|
<!-- 原有按钮 -->
|
||||||
<el-button type="primary" plain @click.stop="handleFinish(patientInfo.encounterId)">
|
<el-button type="primary" plain @click.stop="handleFinish(patientInfo.encounterId)">
|
||||||
@@ -148,6 +148,7 @@
|
|||||||
}
|
}
|
||||||
"
|
"
|
||||||
:visitType="visitType"
|
:visitType="visitType"
|
||||||
|
:firstVisitDate="firstVisitDate"
|
||||||
/>
|
/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="诊断" name="diagnosis">
|
<el-tab-pane label="诊断" name="diagnosis">
|
||||||
@@ -253,6 +254,8 @@ const emits = defineEmits(['click']);
|
|||||||
const activeTab = ref('emr');
|
const activeTab = ref('emr');
|
||||||
const patientList = ref([]);
|
const patientList = ref([]);
|
||||||
const patientInfo = ref({});
|
const patientInfo = ref({});
|
||||||
|
const visitTypeDisabled = ref(false);
|
||||||
|
|
||||||
const prescriptionInfo = ref([]);
|
const prescriptionInfo = ref([]);
|
||||||
const registerTime = ref([formatDate(new Date()), formatDate(new Date())]);
|
const registerTime = ref([formatDate(new Date()), formatDate(new Date())]);
|
||||||
const patientDrawerRef = ref();
|
const patientDrawerRef = ref();
|
||||||
@@ -264,6 +267,7 @@ const waitCount = ref(0);
|
|||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
const visitType = ref('');
|
const visitType = ref('');
|
||||||
|
const firstVisitDate = ref('');
|
||||||
const disabled = computed(() => {
|
const disabled = computed(() => {
|
||||||
return Object.keys(patientInfo.value).length === 0;
|
return Object.keys(patientInfo.value).length === 0;
|
||||||
});
|
});
|
||||||
@@ -290,6 +294,10 @@ function setVisitType(type) {
|
|||||||
visitType.value = type;
|
visitType.value = type;
|
||||||
}
|
}
|
||||||
function checkPatientHistory(patient) {
|
function checkPatientHistory(patient) {
|
||||||
|
// 重置状态
|
||||||
|
visitTypeDisabled.value = false;
|
||||||
|
firstVisitDate.value = '';
|
||||||
|
|
||||||
// 如果患者没有身份证号,无法判断是否为初诊
|
// 如果患者没有身份证号,无法判断是否为初诊
|
||||||
if (!patient.idCard) {
|
if (!patient.idCard) {
|
||||||
// 默认设置为初诊
|
// 默认设置为初诊
|
||||||
@@ -297,6 +305,16 @@ function checkPatientHistory(patient) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果当前就诊已经有明确的初复诊标识,则使用该标识
|
||||||
|
if (patient.visitType) {
|
||||||
|
visitType.value = patient.visitType;
|
||||||
|
// 如果是已完诊的记录,禁用修改
|
||||||
|
if (patient.statusEnum && patient.statusEnum !== 2) { // 假设2是就诊中状态
|
||||||
|
visitTypeDisabled.value = true;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 查询患者历史就诊记录
|
// 查询患者历史就诊记录
|
||||||
const params = {
|
const params = {
|
||||||
patientId: patient.patientId,
|
patientId: patient.patientId,
|
||||||
@@ -305,20 +323,31 @@ function checkPatientHistory(patient) {
|
|||||||
|
|
||||||
getEmrHistoryList(params).then(res => {
|
getEmrHistoryList(params).then(res => {
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
|
const records = res.data?.records || [];
|
||||||
// 如果有历史记录,则为复诊
|
// 如果有历史记录,则为复诊
|
||||||
if (res.data && res.data.total > 0) {
|
if (res.data && res.data.total > 0) {
|
||||||
visitType.value = 'FOLLOW_UP';
|
visitType.value = 'FOLLOW_UP';
|
||||||
|
// 计算最早一次病历创建时间作为初诊日期
|
||||||
|
const earliest = records.reduce((min, cur) => {
|
||||||
|
const ct = new Date(cur.createTime).getTime();
|
||||||
|
return ct < min ? ct : min;
|
||||||
|
}, new Date(records[0].createTime).getTime());
|
||||||
|
// 使用统一格式化
|
||||||
|
firstVisitDate.value = formatDate(earliest);
|
||||||
} else {
|
} else {
|
||||||
// 如果没有历史记录,则为初诊
|
// 如果没有历史记录,则为初诊
|
||||||
visitType.value = 'FIRST';
|
visitType.value = 'FIRST';
|
||||||
|
firstVisitDate.value = '';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 请求失败,默认设置为初诊
|
// 请求失败,默认设置为初诊
|
||||||
visitType.value = 'FIRST';
|
visitType.value = 'FIRST';
|
||||||
|
firstVisitDate.value = '';
|
||||||
}
|
}
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
// 异常情况,默认设置为初诊
|
// 异常情况,默认设置为初诊
|
||||||
visitType.value = 'FIRST';
|
visitType.value = 'FIRST';
|
||||||
|
firstVisitDate.value = '';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function getWaitPatient() {
|
function getWaitPatient() {
|
||||||
@@ -380,10 +409,6 @@ function handleOpen() {
|
|||||||
|
|
||||||
function handleCardClick(item, index) {
|
function handleCardClick(item, index) {
|
||||||
currentEncounterId.value = '';
|
currentEncounterId.value = '';
|
||||||
// if (item.active) {
|
|
||||||
// patientList.value[index].active = false;
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
patientList.value.forEach((patient) => {
|
patientList.value.forEach((patient) => {
|
||||||
patient.active = patient.encounterId === item.encounterId;
|
patient.active = patient.encounterId === item.encounterId;
|
||||||
@@ -421,6 +446,8 @@ function handleFinish(encounterId) {
|
|||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
proxy.$modal.msgSuccess('操作成功');
|
proxy.$modal.msgSuccess('操作成功');
|
||||||
patientInfo.value = {};
|
patientInfo.value = {};
|
||||||
|
visitType.value = ''; // 重置初复诊标识
|
||||||
|
visitTypeDisabled.value = false; // 重置禁用状态
|
||||||
getPatientList();
|
getPatientList();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -434,7 +461,6 @@ function handleTimeChange(value) {
|
|||||||
|
|
||||||
// 接诊回调
|
// 接诊回调
|
||||||
function handleReceive(row) {
|
function handleReceive(row) {
|
||||||
// patientInfo.value = row;
|
|
||||||
handleCardClick(row);
|
handleCardClick(row);
|
||||||
currentEncounterId.value = row.encounterId;
|
currentEncounterId.value = row.encounterId;
|
||||||
drawer.value = false;
|
drawer.value = false;
|
||||||
|
|||||||
@@ -1,106 +1,457 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container">
|
<div class="dashboard-container">
|
||||||
<div class="awaitingBtn">
|
<!-- 顶部导航栏 -->
|
||||||
<el-button @click="awaitingMedicineBtn">效期预警 <span>{{total}}</span></el-button>
|
<header class="header">
|
||||||
|
<div class="logo">
|
||||||
|
<span class="logo-text">医院信息管理系统</span>
|
||||||
|
</div>
|
||||||
|
<div class="header-right">
|
||||||
|
<div class="notification-badge">
|
||||||
|
<i class="header-icon">🔔</i>
|
||||||
|
<span class="badge">2</span>
|
||||||
|
</div>
|
||||||
|
<i class="header-icon">⚙️</i>
|
||||||
|
<div class="user-info">
|
||||||
|
<span class="user-avatar">👤</span>
|
||||||
|
<span>用户</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<!-- 主体内容 -->
|
||||||
|
<div class="main-content">
|
||||||
|
<!-- 左侧导航栏 -->
|
||||||
|
<nav class="sidebar">
|
||||||
|
<div class="menu-item active">
|
||||||
|
<span class="menu-icon">📊</span>
|
||||||
|
<span>仪表盘</span>
|
||||||
|
</div>
|
||||||
|
<div class="menu-item">
|
||||||
|
<span class="menu-icon">👥</span>
|
||||||
|
<span>患者管理</span>
|
||||||
|
</div>
|
||||||
|
<div class="menu-item">
|
||||||
|
<span class="menu-icon">💉</span>
|
||||||
|
<span>预约管理</span>
|
||||||
|
</div>
|
||||||
|
<div class="menu-item">
|
||||||
|
<span class="menu-icon">🏥</span>
|
||||||
|
<span>门诊管理</span>
|
||||||
|
</div>
|
||||||
|
<div class="menu-item">
|
||||||
|
<span class="menu-icon">⚕️</span>
|
||||||
|
<span>住院管理</span>
|
||||||
|
</div>
|
||||||
|
<div class="menu-item">
|
||||||
|
<span class="menu-icon">💊</span>
|
||||||
|
<span>药房管理</span>
|
||||||
|
</div>
|
||||||
|
<div class="menu-item">
|
||||||
|
<span class="menu-icon">📋</span>
|
||||||
|
<span>报表统计</span>
|
||||||
|
</div>
|
||||||
|
<div class="menu-item">
|
||||||
|
<span class="menu-icon">⚙️</span>
|
||||||
|
<span>系统设置</span>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<!-- 主内容区 -->
|
||||||
|
<div class="content-wrapper">
|
||||||
|
<div class="awaitingBtn">
|
||||||
|
<el-button @click="awaitingMedicineBtn">效期预警 <span>{{ total }}</span></el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1 class="section-title">仪表盘</h1>
|
||||||
|
|
||||||
|
<!-- 关键指标卡片 -->
|
||||||
|
<div class="dashboard-grid">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-title">今日预约量</div>
|
||||||
|
<div class="card-value">126</div>
|
||||||
|
<div class="card-stats">
|
||||||
|
<span class="stats-icon">↑</span>
|
||||||
|
<span>12% 较昨日</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-title">门诊量统计</div>
|
||||||
|
<div class="card-value">342</div>
|
||||||
|
<div class="card-stats">
|
||||||
|
<span class="stats-icon">↑</span>
|
||||||
|
<span>8% 较上周</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-title">住院患者数</div>
|
||||||
|
<div class="card-value">78</div>
|
||||||
|
<div class="card-stats down">
|
||||||
|
<span class="stats-icon">↓</span>
|
||||||
|
<span>5% 较上周</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-title">药品库存预警</div>
|
||||||
|
<div class="card-value">8</div>
|
||||||
|
<div class="card-stats">
|
||||||
|
<span class="stats-icon">!</span>
|
||||||
|
<span>需要立即处理</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 图表展示区 -->
|
||||||
|
<div class="chart-container">
|
||||||
|
<canvas id="statsChart"></canvas>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 重要通知和待办事项 -->
|
||||||
|
<div class="bottom-content">
|
||||||
|
<div class="notification-container">
|
||||||
|
<div class="notification-title">重要通知</div>
|
||||||
|
<ul class="notification-list">
|
||||||
|
<li class="notification-item">系统将于周六凌晨2:00进行维护升级</li>
|
||||||
|
<li class="notification-item">新的门诊排班系统已上线,请尽快熟悉</li>
|
||||||
|
<li class="notification-item">三季度医疗质量分析报告已发布</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="todo-container">
|
||||||
|
<div class="todo-title">待办事项</div>
|
||||||
|
<ul class="todo-list">
|
||||||
|
<li class="todo-item">
|
||||||
|
<span>未完成预约</span>
|
||||||
|
<span class="todo-count">12个</span>
|
||||||
|
</li>
|
||||||
|
<li class="todo-item">
|
||||||
|
<span>待处理检查结果</span>
|
||||||
|
<span class="todo-count">7份</span>
|
||||||
|
</li>
|
||||||
|
<li class="todo-item">
|
||||||
|
<span>待开处方</span>
|
||||||
|
<span class="todo-count">3张</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<button class="btn btn-primary">查看详情</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 患者列表 -->
|
||||||
|
<h2 class="section-title">最近患者</h2>
|
||||||
|
<div class="table-container">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>患者姓名</th>
|
||||||
|
<th>病历号</th>
|
||||||
|
<th>年龄</th>
|
||||||
|
<th>最后就诊时间</th>
|
||||||
|
<th>状态</th>
|
||||||
|
<th>操作</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>张明</td>
|
||||||
|
<td>HN2023001</td>
|
||||||
|
<td>45</td>
|
||||||
|
<td>2023-10-20 09:30</td>
|
||||||
|
<td><span style="color: #67c23a;">已完成</span></td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-outline">详情</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>李红</td>
|
||||||
|
<td>HN2023002</td>
|
||||||
|
<td>32</td>
|
||||||
|
<td>2023-10-20 10:15</td>
|
||||||
|
<td><span style="color: #ff9800;">待检查</span></td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-outline">详情</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>王建军</td>
|
||||||
|
<td>HN2023003</td>
|
||||||
|
<td>68</td>
|
||||||
|
<td>2023-10-19 14:20</td>
|
||||||
|
<td><span style="color: #d45d79;">住院中</span></td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-outline">详情</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="logo"> -->
|
|
||||||
<!-- <img src="/src/assets/images/jlau.jpg" /> -->
|
|
||||||
<!-- </div> -->
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="Index">
|
<script setup name="Index">
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import Chart from 'chart.js/auto';
|
||||||
import {
|
import {
|
||||||
getExpirationWarning,
|
getExpirationWarning,
|
||||||
} from "./medicationmanagement/statisticalManagement/statisticalManagent";
|
} from "./medicationmanagement/statisticalManagement/statisticalManagent";
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const version = ref('3.8.7');
|
const total = ref(0);
|
||||||
const total = ref(0)
|
|
||||||
function awaitingMedicineBtn(){
|
function awaitingMedicineBtn() {
|
||||||
router.push({ path: '/medicationmanagement/statisticalManagement/earlyWarning' })
|
router.push({ path: '/medicationmanagement/statisticalManagement/earlyWarning' });
|
||||||
}
|
}
|
||||||
function goTarget(url) {
|
|
||||||
window.open(url, '__blank');
|
function getExpirationWarningCount() {
|
||||||
}
|
getExpirationWarning({ pageNo: 1, pageSize: 10 }).then((res) => {
|
||||||
function getExpirationWarningCount(){
|
total.value = res.data.total || 0;
|
||||||
getExpirationWarning({pageNo: 1,pageSize: 10}).then((res) => {
|
}).catch((err) => {
|
||||||
total.value = res.data.total||0
|
console.error('获取效期预警数量失败:', err);
|
||||||
|
total.value = 0;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
getExpirationWarningCount()
|
|
||||||
|
let chartInstance = null;
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getExpirationWarningCount();
|
||||||
|
|
||||||
|
const ctx = document.getElementById('statsChart');
|
||||||
|
if (!ctx) return;
|
||||||
|
|
||||||
|
// 销毁已有实例
|
||||||
|
if (chartInstance) {
|
||||||
|
chartInstance.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 模拟数据:近7天门诊量与预约量
|
||||||
|
const labels = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'];
|
||||||
|
const outpatientData = [310, 335, 305, 345, 370, 270, 210]; // 门诊量(柱状图)
|
||||||
|
const appointmentData = [100, 120, 110, 130, 140, 90, 70]; // 预约量(折线图)
|
||||||
|
|
||||||
|
chartInstance = new Chart(ctx.getContext('2d'), {
|
||||||
|
type: 'bar',
|
||||||
|
data: {
|
||||||
|
labels: labels,
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: '门诊量',
|
||||||
|
data: outpatientData,
|
||||||
|
backgroundColor: '#91c8e5',
|
||||||
|
borderColor: '#66a8cc',
|
||||||
|
borderWidth: 1,
|
||||||
|
borderRadius: 4,
|
||||||
|
borderSkipped: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '预约量',
|
||||||
|
data: appointmentData,
|
||||||
|
type: 'line',
|
||||||
|
borderColor: '#f56c6c',
|
||||||
|
backgroundColor: 'rgba(245, 108, 108, 0.1)',
|
||||||
|
borderWidth: 2,
|
||||||
|
pointBackgroundColor: '#f56c6c',
|
||||||
|
pointBorderColor: '#fff',
|
||||||
|
pointBorderWidth: 2,
|
||||||
|
pointRadius: 4,
|
||||||
|
fill: true,
|
||||||
|
tension: 0.3,
|
||||||
|
lineTension: 0.3,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
position: 'top',
|
||||||
|
labels: {
|
||||||
|
font: {
|
||||||
|
size: 12,
|
||||||
|
weight: 'bold'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
mode: 'index',
|
||||||
|
intersect: false,
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.7)',
|
||||||
|
titleFont: {
|
||||||
|
size: 13
|
||||||
|
},
|
||||||
|
bodyFont: {
|
||||||
|
size: 12
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
x: {
|
||||||
|
grid: {
|
||||||
|
display: false
|
||||||
|
},
|
||||||
|
ticks: {
|
||||||
|
font: {
|
||||||
|
size: 11
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
beginAtZero: true,
|
||||||
|
max: 400,
|
||||||
|
stepSize: 50,
|
||||||
|
grid: {
|
||||||
|
color: 'rgba(0, 0, 0, 0.05)'
|
||||||
|
},
|
||||||
|
ticks: {
|
||||||
|
font: {
|
||||||
|
size: 11
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.home {
|
.dashboard-container {
|
||||||
blockquote {
|
|
||||||
padding: 10px 20px;
|
|
||||||
margin: 0 0 20px;
|
|
||||||
font-size: 17.5px;
|
|
||||||
border-left: 5px solid #eee;
|
|
||||||
}
|
|
||||||
hr {
|
|
||||||
margin-top: 20px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
border: 0;
|
|
||||||
border-top: 1px solid #eee;
|
|
||||||
}
|
|
||||||
.col-item {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
font-family: 'open sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
|
||||||
font-size: 13px;
|
|
||||||
color: #676a6c;
|
|
||||||
overflow-x: hidden;
|
|
||||||
|
|
||||||
ul {
|
|
||||||
list-style-type: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
h4 {
|
|
||||||
margin-top: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
margin-top: 10px;
|
|
||||||
font-size: 26px;
|
|
||||||
font-weight: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin-top: 10px;
|
|
||||||
|
|
||||||
b {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.update-log {
|
|
||||||
ol {
|
|
||||||
display: block;
|
|
||||||
list-style-type: decimal;
|
|
||||||
margin-block-start: 1em;
|
|
||||||
margin-block-end: 1em;
|
|
||||||
margin-inline-start: 0;
|
|
||||||
margin-inline-end: 0;
|
|
||||||
padding-inline-start: 40px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.container {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center; /* 水平居中 */
|
flex-direction: column;
|
||||||
align-items: center; /* 垂直居中 */
|
height: 100vh;
|
||||||
height: 70vh; /* 确保容器高度至少为视口高度 */
|
background-color: #f5f7fa;
|
||||||
width: 100%;
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
.awaitingBtn{
|
|
||||||
|
.header {
|
||||||
|
height: 60px;
|
||||||
|
background-color: white;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0 24px;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-text {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #166773;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-right {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-badge {
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-icon {
|
||||||
|
font-size: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-icon:hover {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
background-color: #ff4d4f;
|
||||||
|
color: white;
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 2px 6px;
|
||||||
|
border-radius: 10px;
|
||||||
|
min-width: 16px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 6px 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-info:hover {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-avatar {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
width: 200px;
|
||||||
|
background-color: white;
|
||||||
|
box-shadow: 2px 0 4px rgba(0, 0, 0, 0.1);
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 16px 24px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s;
|
||||||
|
border-left: 3px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item:hover {
|
||||||
|
background-color: #f0f9ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item.active {
|
||||||
|
background-color: #e6f7ff;
|
||||||
|
border-left-color: #1890ff;
|
||||||
|
color: #1890ff;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-icon {
|
||||||
|
margin-right: 12px;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
padding: 20px;
|
||||||
|
overflow-y: auto;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.awaitingBtn {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
.el-button{
|
.el-button{
|
||||||
border: 1px #166773 solid;
|
border: 1px #166773 solid;
|
||||||
span{
|
span{
|
||||||
@@ -108,6 +459,7 @@ getExpirationWarningCount()
|
|||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-button:hover{
|
.el-button:hover{
|
||||||
border: 1px #166773 solid;
|
border: 1px #166773 solid;
|
||||||
color: #166773;
|
color: #166773;
|
||||||
@@ -116,15 +468,204 @@ getExpirationWarningCount()
|
|||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
position: absolute;
|
|
||||||
top:20px;
|
|
||||||
left: 20px;
|
|
||||||
}
|
}
|
||||||
.logo {
|
|
||||||
width: 1000px;
|
|
||||||
margin: 0 auto;
|
|
||||||
background: url(../assets/images/logo_bg.jpg) no-repeat right bottom;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 24px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: #333;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 24px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card:hover {
|
||||||
|
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-title {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #606266;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-value {
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-stats {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #67c23a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-stats.down {
|
||||||
|
color: #f56c6c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-icon {
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||||
|
gap: 20px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-container {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 24px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||||
|
margin-bottom: 30px;
|
||||||
|
height: 300px;
|
||||||
|
|
||||||
|
canvas {
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-content {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 20px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-container,
|
||||||
|
.todo-container {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 24px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-title,
|
||||||
|
.todo-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-list {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-item {
|
||||||
|
padding: 12px 0;
|
||||||
|
border-bottom: 1px solid #ebeef5;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.todo-list {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.todo-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 12px 0;
|
||||||
|
border-bottom: 1px solid #ebeef5;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.todo-count {
|
||||||
|
color: #606266;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 24px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
padding: 12px;
|
||||||
|
text-align: left;
|
||||||
|
border-bottom: 1px solid #ebeef5;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:last-child td {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
padding: 6px 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background-color: #1890ff;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
background-color: #40a9ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-outline {
|
||||||
|
background-color: transparent;
|
||||||
|
border: 1px solid #dcdfe6;
|
||||||
|
color: #606266;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-outline:hover {
|
||||||
|
border-color: #c6e2ff;
|
||||||
|
color: #40a9ff;
|
||||||
|
background-color: #ecf5ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.bottom-content {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -93,6 +93,18 @@ export function delEncounterDiagnosis(conditionId) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否是食源性诊断
|
||||||
|
*/
|
||||||
|
export function isFoodDiseasesNew(params) {
|
||||||
|
return request({
|
||||||
|
url: '/external-integration/foodborne-acquisition/is-food-diseases-new',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取中医诊断
|
* 获取中医诊断
|
||||||
*/
|
*/
|
||||||
@@ -230,6 +242,15 @@ export function getOrgTree() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function getEmrDetail(encounterId) {
|
||||||
|
return request({
|
||||||
|
url: '/doctor-station/emr/emr-detail?encounterId=' + encounterId,
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 组合/拆组
|
* 组合/拆组
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -2,19 +2,17 @@
|
|||||||
<div>
|
<div>
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :span="4" :xs="24">
|
<el-col :span="4" :xs="24">
|
||||||
<div style="height: 44px; display: flex; align-items: center; flex: none">
|
<el-input
|
||||||
<el-input
|
v-model="diagnosis"
|
||||||
v-model="diagnosis"
|
placeholder="诊断名称"
|
||||||
placeholder="诊断名称"
|
clearable
|
||||||
clearable
|
style="width: 100%; margin-bottom: 10px"
|
||||||
style="width: 100%"
|
@keyup.enter="queryDiagnosisUse"
|
||||||
@keyup.enter="queryDiagnosisUse"
|
>
|
||||||
>
|
<template #append>
|
||||||
<template #append>
|
<el-button icon="Search" @click="queryDiagnosisUse" />
|
||||||
<el-button icon="Search" @click="queryDiagnosisUse" />
|
</template>
|
||||||
</template>
|
</el-input>
|
||||||
</el-input>
|
|
||||||
</div>
|
|
||||||
<el-tree
|
<el-tree
|
||||||
ref="treeRef"
|
ref="treeRef"
|
||||||
:data="tree"
|
:data="tree"
|
||||||
@@ -68,16 +66,21 @@
|
|||||||
</el-tree>
|
</el-tree>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="20" :xs="24">
|
<el-col :span="20" :xs="24">
|
||||||
<div style="height: 44px; display: flex; align-items: center; flex: none">
|
<div style="margin-bottom: 10px">
|
||||||
<el-button type="primary" plain @click="handleAddDiagnosis()"> 新增诊断 </el-button>
|
<el-button type="primary" plain @click="handleAddDiagnosis()"> 新增诊断 </el-button>
|
||||||
<el-button type="primary" plain @click="handleSaveDiagnosis()"> 保存诊断 </el-button>
|
<el-button type="primary" plain @click="handleSaveDiagnosis()"> 保存诊断 </el-button>
|
||||||
<el-button type="primary" plain @click="handleAddTcmDiagonsis()"> 中医诊断 </el-button>
|
<el-button type="primary" plain @click="handleAddTcmDiagonsis()"> 中医诊断 </el-button>
|
||||||
<el-button type="primary" plain @click="handleImport()"> 导入慢性病诊断 </el-button>
|
<el-button type="primary" plain @click="handleImport()"> 导入慢性病诊断 </el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-form :model="form" :rules="rules" ref="formRef">
|
<el-form :model="form" :rules="rules" ref="formRef">
|
||||||
<el-table ref="diagnosisTableRef" :data="form.diagnosisList" height="650">
|
<el-table ref="diagnosisTableRef" :data="form.diagnosisList" height="650">
|
||||||
<el-table-column label="序号" type="index" width="50" />
|
<el-table-column label="序号" width="50" >
|
||||||
<el-table-column label="诊断排序" align="center" prop="diagSrtNo" width="180">
|
<template #default="scope">
|
||||||
|
{{ scope.$index + 1 }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="诊断排序" align="center" prop="diagSrtNo" width="120">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-form-item
|
<el-form-item
|
||||||
:prop="`diagnosisList.${scope.$index}.diagSrtNo`"
|
:prop="`diagnosisList.${scope.$index}.diagSrtNo`"
|
||||||
@@ -136,9 +139,13 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="医保码" align="center" prop="ybNo" width="180" />
|
|
||||||
<el-table-column label="诊断类型" align="center" prop="maindiseFlag">
|
<el-table-column label="诊断医生" align="center" prop="diagnosisDoctor" width="120" />
|
||||||
|
<el-table-column label="诊断时间" align="center" prop="diagnosisTime" width="150" />
|
||||||
|
<el-table-column label="诊断代码" align="center" prop="ybNo" width="180" />
|
||||||
|
<el-table-column label="诊断类型" align="center" prop="maindiseFlag" width="120">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
|
<div style="display:flex;flex-direction:column;align-items:center;gap:5px;">
|
||||||
<el-checkbox
|
<el-checkbox
|
||||||
label="主诊断"
|
label="主诊断"
|
||||||
:trueLabel="1"
|
:trueLabel="1"
|
||||||
@@ -151,7 +158,7 @@
|
|||||||
<el-select
|
<el-select
|
||||||
v-model="scope.row.verificationStatusEnum"
|
v-model="scope.row.verificationStatusEnum"
|
||||||
placeholder=" "
|
placeholder=" "
|
||||||
style="width: 40%; padding-bottom: 5px; padding-left: 10px"
|
style="width: 100%; padding-bottom: 5px; padding-left: 10px"
|
||||||
size="small"
|
size="small"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
@@ -161,6 +168,7 @@
|
|||||||
:value="item.value"
|
:value="item.value"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" align="center" width="130">
|
<el-table-column label="操作" align="center" width="130">
|
||||||
@@ -185,28 +193,30 @@
|
|||||||
/>
|
/>
|
||||||
<AddDiagnosisDialog
|
<AddDiagnosisDialog
|
||||||
:openAddDiagnosisDialog="openAddDiagnosisDialog"
|
:openAddDiagnosisDialog="openAddDiagnosisDialog"
|
||||||
:patientInfo="patientInfo"
|
:patientInfo="props.patientInfo"
|
||||||
@close="closeDiagnosisDialog"
|
@close="closeDiagnosisDialog"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { getCurrentInstance } from 'vue';
|
import { getCurrentInstance, nextTick } from 'vue'; // 添加 nextTick 导入
|
||||||
|
import useUserStore from '@/store/modules/user';
|
||||||
import {
|
import {
|
||||||
getConditionDefinitionInfo,
|
getConditionDefinitionInfo,
|
||||||
saveDiagnosis,
|
saveDiagnosis,
|
||||||
diagnosisInit,
|
diagnosisInit,
|
||||||
deleteDiagnosisBind,
|
deleteDiagnosisBind,
|
||||||
getEncounterDiagnosis,
|
getEncounterDiagnosis,
|
||||||
|
getEmrDetail,
|
||||||
getChronicDisease,
|
getChronicDisease,
|
||||||
getTcmDiagnosis,
|
getTcmDiagnosis,
|
||||||
delEncounterDiagnosis,
|
delEncounterDiagnosis,
|
||||||
|
isFoodDiseasesNew,
|
||||||
} from '../api';
|
} from '../api';
|
||||||
import diagnosisdialog from '../diagnosis/diagnosisdialog.vue';
|
import diagnosisdialog from '../diagnosis/diagnosisdialog.vue';
|
||||||
import AddDiagnosisDialog from './addDiagnosisDialog.vue';
|
import AddDiagnosisDialog from './addDiagnosisDialog.vue';
|
||||||
import diagnosislist from '../diagnosis/diagnosislist.vue';
|
import diagnosislist from '../diagnosis/diagnosislist.vue';
|
||||||
import { patientInfo } from '../../store/patient.js';
|
|
||||||
// const diagnosisList = ref([]);
|
// const diagnosisList = ref([]);
|
||||||
const allowAdd = ref(false);
|
const allowAdd = ref(false);
|
||||||
const tree = ref([]);
|
const tree = ref([]);
|
||||||
@@ -228,50 +238,93 @@ const props = defineProps({
|
|||||||
});
|
});
|
||||||
const emits = defineEmits(['diagnosisSave']);
|
const emits = defineEmits(['diagnosisSave']);
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
|
const userStore = useUserStore();
|
||||||
const { med_type } = proxy.useDict('med_type');
|
const { med_type } = proxy.useDict('med_type');
|
||||||
const rules = ref({
|
const rules = ref({
|
||||||
name: [{ required: true, message: '请选择诊断', trigger: 'change' }],
|
name: [{ required: true, message: '请选择诊断', trigger: 'change' }],
|
||||||
medTypeCode: [{ required: true, message: '请选择诊断类型', trigger: 'change' }],
|
medTypeCode: [{ required: true, message: '请选择诊断类型', trigger: 'change' }],
|
||||||
diagSrtNo: [{ required: true, message: '请输入诊断序号', trigger: 'change' }],
|
diagSrtNo: [{ required: true, message: '请输入诊断序号', trigger: 'change' }],
|
||||||
});
|
});
|
||||||
|
const isSaving = ref(false);
|
||||||
watch(
|
watch(
|
||||||
() => form.value.diagnosisList,
|
() => form.value.diagnosisList,
|
||||||
() => {
|
() => {
|
||||||
emits('diagnosisSave', false);
|
// 如果正在保存,则不触发更新事件
|
||||||
|
if (!isSaving.value) {
|
||||||
|
emits('diagnosisSave', false);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
// function getDetail(encounterId) {
|
function getDetail(encounterId) {
|
||||||
// getEmrDetail(encounterId).then((res) => {
|
if (!encounterId) {
|
||||||
// allowAdd.value = res.data ? true : false;
|
console.warn('未提供有效的就诊ID,无法获取病历详情');
|
||||||
// });
|
return;
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
getEmrDetail(encounterId).then((res) => {
|
||||||
|
allowAdd.value = res.data ? true : false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function getList() {
|
function getList() {
|
||||||
getEncounterDiagnosis(patientInfo.value.encounterId).then((res) => {
|
if (!props.patientInfo || !props.patientInfo.encounterId) {
|
||||||
|
console.warn('患者就诊信息不完整,无法获取诊断数据');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
getEncounterDiagnosis(props.patientInfo.encounterId).then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
form.value.diagnosisList = res.data;
|
// 为每个诊断项添加默认的诊断医生和时间(如果不存在)
|
||||||
|
const diagnosisList = res.data.map(item => ({
|
||||||
|
...item,
|
||||||
|
diagnosisDoctor: item.diagnosisDoctor || props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
||||||
|
diagnosisTime: item.diagnosisTime || new Date().toLocaleString('zh-CN')
|
||||||
|
}));
|
||||||
|
|
||||||
|
// 对获取的数据进行排序
|
||||||
|
diagnosisList.sort((a, b) => {
|
||||||
|
const aNo = typeof a.diagSrtNo === 'number' ? a.diagSrtNo : 9999;
|
||||||
|
const bNo = typeof b.diagSrtNo === 'number' ? b.diagSrtNo : 9999;
|
||||||
|
return aNo - bNo;
|
||||||
|
});
|
||||||
|
|
||||||
|
form.value.diagnosisList = diagnosisList;
|
||||||
emits('diagnosisSave', false);
|
emits('diagnosisSave', false);
|
||||||
console.log(form.value.diagnosisList);
|
console.log(form.value.diagnosisList);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
getTcmDiagnosis({ encounterId: patientInfo.value.encounterId }).then((res) => {
|
|
||||||
|
getTcmDiagnosis({ encounterId: props.patientInfo.encounterId }).then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
if (res.data.illness.length > 0) {
|
if (res.data.illness && res.data.illness.length > 0 && res.data.symptom) {
|
||||||
|
const newList = [];
|
||||||
res.data.illness.forEach((item, index) => {
|
res.data.illness.forEach((item, index) => {
|
||||||
form.value.diagnosisList.push({
|
newList.push({
|
||||||
name: item.name + '-' + res.data.symptom[index].name,
|
name: item.name + '-' + (res.data.symptom[index]?.name || ''),
|
||||||
ybNo: item.ybNo,
|
ybNo: item.ybNo,
|
||||||
medTypeCode: item.medTypeCode,
|
medTypeCode: item.medTypeCode,
|
||||||
|
diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
||||||
|
diagnosisTime: new Date().toLocaleString('zh-CN')
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 将新数据添加到现有列表中
|
||||||
|
form.value.diagnosisList.push(...newList);
|
||||||
|
|
||||||
|
// 重新排序整个列表
|
||||||
|
form.value.diagnosisList.sort((a, b) => {
|
||||||
|
const aNo = typeof a.diagSrtNo === 'number' ? a.diagSrtNo : 9999;
|
||||||
|
const bNo = typeof b.diagSrtNo === 'number' ? b.diagSrtNo : 9999;
|
||||||
|
return aNo - bNo;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
emits('diagnosisSave', false);
|
emits('diagnosisSave', false);
|
||||||
console.log(form.value.diagnosisList);
|
console.log(form.value.diagnosisList);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
getTree();
|
getTree();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,19 +338,28 @@ function init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleImport() {
|
function handleImport() {
|
||||||
if (patientInfo.value.contractName != '自费') {
|
if (!props.patientInfo || !props.patientInfo.encounterId) {
|
||||||
|
console.warn('患者就诊信息不完整,无法导入慢性病信息');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.patientInfo.contractName != '自费') {
|
||||||
// 获取患者慢性病信息
|
// 获取患者慢性病信息
|
||||||
getChronicDisease({ encounterId: patientInfo.value.encounterId }).then((res) => {
|
getChronicDisease({ encounterId: props.patientInfo.encounterId }).then((res) => {
|
||||||
if (res.data.length > 0) {
|
if (res.data && res.data.length > 0) {
|
||||||
res.data.forEach((item, index) => {
|
res.data.forEach((item, index) => {
|
||||||
form.value.diagnosisList.push({
|
form.value.diagnosisList.push({
|
||||||
...item,
|
...item,
|
||||||
...{
|
...{
|
||||||
medTypeCode: '140104',
|
medTypeCode: '140104',
|
||||||
verificationStatusEnum: 4,
|
verificationStatusEnum: 4,
|
||||||
definitionId: item.id,
|
definitionId: item.id,
|
||||||
diagSrtNo: form.value.diagnosisList.length + 1,
|
diagSrtNo: form.value.diagnosisList.length + 1,
|
||||||
},
|
iptDiseTypeCode: 2,
|
||||||
|
diagnosisDesc: '',
|
||||||
|
diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
||||||
|
diagnosisTime: new Date().toLocaleString('zh-CN')
|
||||||
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -340,7 +402,8 @@ const filterNode = (value, data) => {
|
|||||||
* 获取诊断树列表
|
* 获取诊断树列表
|
||||||
*/
|
*/
|
||||||
function getTree() {
|
function getTree() {
|
||||||
getConditionDefinitionInfo(patientInfo.value ? patientInfo.value.patientId : '').then((res) => {
|
const patientId = props.patientInfo?.patientId || '';
|
||||||
|
getConditionDefinitionInfo(patientId).then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
let list = [];
|
let list = [];
|
||||||
list = res.data.patientHistoryList;
|
list = res.data.patientHistoryList;
|
||||||
@@ -377,14 +440,20 @@ function getTree() {
|
|||||||
function handleAddDiagnosis() {
|
function handleAddDiagnosis() {
|
||||||
proxy.$refs.formRef.validate((valid) => {
|
proxy.$refs.formRef.validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
|
if (!allowAdd.value) {
|
||||||
|
proxy.$modal.msgWarning('请先填写病历');
|
||||||
|
return;
|
||||||
|
}
|
||||||
form.value.diagnosisList.push({
|
form.value.diagnosisList.push({
|
||||||
showPopover: false,
|
showPopover: false,
|
||||||
name: undefined,
|
name: undefined,
|
||||||
verificationStatusEnum: 4,
|
verificationStatusEnum: 4,
|
||||||
medTypeCode: '21',
|
medTypeCode: '11',
|
||||||
diagSrtNo: form.value.diagnosisList.length + 1,
|
diagSrtNo: form.value.diagnosisList.length + 1,
|
||||||
iptDiseTypeCode: 31,
|
iptDiseTypeCode: 2,
|
||||||
diagnosisDesc: '',
|
diagnosisDesc: '',
|
||||||
|
diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
||||||
|
diagnosisTime: new Date().toLocaleString('zh-CN')
|
||||||
});
|
});
|
||||||
if (form.value.diagnosisList.length == 1) {
|
if (form.value.diagnosisList.length == 1) {
|
||||||
form.value.diagnosisList[0].maindiseFlag = 1;
|
form.value.diagnosisList[0].maindiseFlag = 1;
|
||||||
@@ -398,13 +467,31 @@ function handleAddTcmDiagonsis() {
|
|||||||
openAddDiagnosisDialog.value = true;
|
openAddDiagnosisDialog.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除诊断
|
||||||
|
*/
|
||||||
/**
|
/**
|
||||||
* 删除诊断
|
* 删除诊断
|
||||||
*/
|
*/
|
||||||
function handleDeleteDiagnosis(row, index) {
|
function handleDeleteDiagnosis(row, index) {
|
||||||
if (row.conditionId) {
|
if (row.conditionId) {
|
||||||
delEncounterDiagnosis(row.conditionId).then(() => {
|
delEncounterDiagnosis(row.conditionId).then(() => {
|
||||||
getList();
|
// 不要立即调用getList(),而是从当前列表中移除
|
||||||
|
form.value.diagnosisList.splice(index, 1);
|
||||||
|
// 重新排序剩余的项目
|
||||||
|
const sortedList = [...form.value.diagnosisList].sort((a, b) => {
|
||||||
|
const aNo = typeof a.diagSrtNo === 'number' ? a.diagSrtNo : 9999;
|
||||||
|
const bNo = typeof b.diagSrtNo === 'number' ? b.diagSrtNo : 9999;
|
||||||
|
return aNo - bNo;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 重新分配连续的序号
|
||||||
|
sortedList.forEach((item, idx) => {
|
||||||
|
item.diagSrtNo = idx + 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 更新列表
|
||||||
|
form.value.diagnosisList = sortedList.map(item => ({ ...item }));
|
||||||
getTree();
|
getTree();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -428,35 +515,72 @@ function handleMaindise(value, index) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存诊断
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* 保存诊断
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* 保存诊断
|
||||||
|
*/
|
||||||
/**
|
/**
|
||||||
* 保存诊断
|
* 保存诊断
|
||||||
*/
|
*/
|
||||||
function handleSaveDiagnosis() {
|
function handleSaveDiagnosis() {
|
||||||
proxy.$refs.formRef.validate((valid) => {
|
proxy.$refs.formRef.validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (form.value.diagnosisList.length == 0) {
|
if (form.value.diagnosisList.length === 0) {
|
||||||
proxy.$modal.msgWarning('诊断不能为空');
|
proxy.$modal.msgWarning('诊断不能为空');
|
||||||
return false;
|
return;
|
||||||
} else if (!form.value.diagnosisList.some((diagnosis) => diagnosis.maindiseFlag === 1)) {
|
} else if (!form.value.diagnosisList.some((diagnosis) => diagnosis.maindiseFlag === 1)) {
|
||||||
proxy.$modal.msgWarning('至少添加一条主诊断');
|
proxy.$modal.msgWarning('至少添加一条主诊断');
|
||||||
} else {
|
return;
|
||||||
saveDiagnosis({
|
|
||||||
patientId: patientInfo.value.patientId,
|
|
||||||
encounterId: patientInfo.value.encounterId,
|
|
||||||
diagnosisChildList: form.value.diagnosisList,
|
|
||||||
}).then((res) => {
|
|
||||||
if (res.code == 200) {
|
|
||||||
getTree();
|
|
||||||
getList();
|
|
||||||
emits('diagnosisSave', false);
|
|
||||||
proxy.$modal.msgSuccess('诊断已保存');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 设置保存标志,避免触发watch监听器
|
||||||
|
isSaving.value = true;
|
||||||
|
|
||||||
|
// 步骤1:深拷贝并按 diagSrtNo 排序
|
||||||
|
const sortedList = [...form.value.diagnosisList].sort((a, b) => {
|
||||||
|
const aNo = typeof a.diagSrtNo === 'number' ? a.diagSrtNo : 9999;
|
||||||
|
const bNo = typeof b.diagSrtNo === 'number' ? b.diagSrtNo : 9999;
|
||||||
|
return aNo - bNo;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 步骤2:重新分配连续的序号(从1开始)
|
||||||
|
sortedList.forEach((item, index) => {
|
||||||
|
item.diagSrtNo = index + 1; // 这里是关键!把“诊断排序”改成新顺序
|
||||||
|
});
|
||||||
|
|
||||||
|
// 步骤3:提交排序后的数据
|
||||||
|
saveDiagnosis({
|
||||||
|
patientId: props.patientInfo.patientId,
|
||||||
|
encounterId: props.patientInfo.encounterId,
|
||||||
|
diagnosisChildList: sortedList,
|
||||||
|
}).then((res) => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
// 步骤4:更新本地数据,使用全新对象防止响应式问题
|
||||||
|
form.value.diagnosisList = sortedList.map(item => ({ ...item }));
|
||||||
|
|
||||||
|
emits('diagnosisSave', false);
|
||||||
|
proxy.$modal.msgSuccess('诊断已保存');
|
||||||
|
|
||||||
|
// 食源性疾病逻辑
|
||||||
|
isFoodDiseasesNew({ encounterId: props.patientInfo.encounterId }).then((res2) => {
|
||||||
|
if (res2.code === 20 && res2.data) {
|
||||||
|
window.open(res2.data, '_blank');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
isSaving.value = false;
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 关闭诊断弹窗
|
* 关闭诊断弹窗
|
||||||
*/
|
*/
|
||||||
@@ -519,12 +643,15 @@ function handleNodeClick(data) {
|
|||||||
medTypeCode: '11',
|
medTypeCode: '11',
|
||||||
diagSrtNo: form.value.diagnosisList.length + 1,
|
diagSrtNo: form.value.diagnosisList.length + 1,
|
||||||
definitionId: data.definitionId,
|
definitionId: data.definitionId,
|
||||||
|
diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
||||||
|
diagnosisTime: new Date().toLocaleString('zh-CN')
|
||||||
});
|
});
|
||||||
if (form.value.diagnosisList.length == 1) {
|
if (form.value.diagnosisList.length == 1) {
|
||||||
form.value.diagnosisList[0].maindiseFlag = 1;
|
form.value.diagnosisList[0].maindiseFlag = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
defineExpose({ getList, handleSaveDiagnosis });
|
|
||||||
|
defineExpose({ getList, getDetail, handleSaveDiagnosis });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@@ -542,4 +669,5 @@ defineExpose({ getList, handleSaveDiagnosis });
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -55,10 +55,10 @@
|
|||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { getCurrentInstance, onBeforeMount, onMounted, reactive, ref, computed } from 'vue';
|
import { getCurrentInstance, onBeforeMount, onMounted, reactive, ref, computed } from 'vue';
|
||||||
import BloodTransfusion from './bloodTransfusion.vue';
|
import BloodTransfusion from './bloodTransfusion';
|
||||||
import { patientInfo } from '../../../store/patient.js';
|
import { patientInfo } from '../../../store/patient.js';
|
||||||
import Surgery from './surgery.vue';
|
import Surgery from './surgery.vue';
|
||||||
import LaboratoryTests from './LaboratoryTests.vue';
|
import laboratoryTests from './laboratoryTests.vue';
|
||||||
import MedicalExaminations from './medicalExaminations.vue';
|
import MedicalExaminations from './medicalExaminations.vue';
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
const emits = defineEmits([]);
|
const emits = defineEmits([]);
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="login">
|
<div class="login">
|
||||||
<!-- 顶部 -->
|
<!-- 顶部 -->
|
||||||
<!-- <div class="el-login-top">
|
|
||||||
<el-image :src="logoNew"></el-image>
|
|
||||||
</div> -->
|
|
||||||
<el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
|
<el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
|
||||||
<h1 class="title">医院信息管理系统</h1>
|
<div class="el-login-top">
|
||||||
|
<el-image :src="logoNew"></el-image>
|
||||||
|
</div>
|
||||||
|
<h1 class="title">{{ currentTenantName || settings.systemName }}信息管理系统</h1>
|
||||||
|
<p class="login-subtitle">请使用您的账号密码安全登录系统</p>
|
||||||
<el-form-item prop="username">
|
<el-form-item prop="username">
|
||||||
|
<p class="label">用户名</p>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="loginForm.username"
|
v-model="loginForm.username"
|
||||||
type="text"
|
type="text"
|
||||||
@@ -21,25 +23,35 @@
|
|||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="password">
|
<el-form-item prop="password">
|
||||||
|
<p class="label">密码</p>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="loginForm.password"
|
v-model="loginForm.password"
|
||||||
type="password"
|
:type="passwordVisible ? 'text' : 'password'"
|
||||||
size="large"
|
size="large"
|
||||||
auto-complete="off"
|
auto-complete="off"
|
||||||
placeholder="密码"
|
placeholder="密码"
|
||||||
@keyup.enter="handleLogin"
|
@keyup.enter="handleLogin"
|
||||||
show-password
|
|
||||||
>
|
>
|
||||||
<template #prefix
|
<template #prefix
|
||||||
><svg-icon icon-class="password" class="el-input__icon input-icon"
|
><svg-icon icon-class="password" class="el-input__icon input-icon"
|
||||||
/></template>
|
/></template>
|
||||||
|
<template #suffix>
|
||||||
|
<span
|
||||||
|
class="password-toggle"
|
||||||
|
@click="togglePasswordVisibility"
|
||||||
|
style="cursor: pointer; color: #606266; font-size: 14px; padding: 0 10px;"
|
||||||
|
>
|
||||||
|
{{ passwordVisible ? '隐藏' : '显示' }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="tenantId">
|
<el-form-item prop="tenantId">
|
||||||
|
<p class="label">医疗机构</p>
|
||||||
<el-select
|
<el-select
|
||||||
v-model="loginForm.tenantId"
|
v-model="loginForm.tenantId"
|
||||||
size="large"
|
size="large"
|
||||||
placeholder="所属医院"
|
placeholder="请选择医疗机构"
|
||||||
clearable
|
clearable
|
||||||
filterable
|
filterable
|
||||||
>
|
>
|
||||||
@@ -51,6 +63,11 @@
|
|||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item class="login-options">
|
||||||
|
<el-checkbox v-model="loginForm.rememberMe" class="remember-me">记住我</el-checkbox>
|
||||||
|
<el-link type="primary" class="forgot-password" @click="handleForgotPassword">忘记密码?</el-link>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
<!-- <el-form-item prop="tenantId"> -->
|
<!-- <el-form-item prop="tenantId"> -->
|
||||||
<!-- <span class="descriptions-item-label" style="margin: 0 10px 0 0">连接医保</span> -->
|
<!-- <span class="descriptions-item-label" style="margin: 0 10px 0 0">连接医保</span> -->
|
||||||
<!-- <el-switch v-model="loginForm.invokeYb" @change="topNavChange" size="large"/> -->
|
<!-- <el-switch v-model="loginForm.invokeYb" @change="topNavChange" size="large"/> -->
|
||||||
@@ -87,8 +104,17 @@
|
|||||||
<router-link class="link-type" :to="'/register'">立即注册</router-link>
|
<router-link class="link-type" :to="'/register'">立即注册</router-link>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<div class="footer">
|
||||||
|
© 2025 {{ currentTenantName || settings.systemName }} | 版本 v2.5.1
|
||||||
|
<!-- 公司版权信息(新增) -->
|
||||||
|
<div class="company-copyright">
|
||||||
|
技术支持:上海经创贺联信息技术有限公司
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<!-- 底部 -->
|
<!-- 底部 -->
|
||||||
|
|
||||||
<div class="el-login-footer">
|
<div class="el-login-footer">
|
||||||
<div class="el-login-footer-link">
|
<div class="el-login-footer-link">
|
||||||
<span><el-link :underline="false">his账号用户协议</el-link></span>
|
<span><el-link :underline="false">his账号用户协议</el-link></span>
|
||||||
@@ -109,12 +135,15 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { getCurrentInstance, ref, reactive, computed, onMounted, watch } from 'vue';
|
||||||
|
import settings from '@/settings';
|
||||||
import { getCodeImg, sign, getUserBindTenantList } from '@/api/login';
|
import { getCodeImg, sign, getUserBindTenantList } from '@/api/login';
|
||||||
import { invokeYbPlugin } from '@/api/public';
|
import { invokeYbPlugin } from '@/api/public';
|
||||||
import Cookies from 'js-cookie';
|
import Cookies from 'js-cookie';
|
||||||
import { encrypt, decrypt } from '@/utils/jsencrypt';
|
import { encrypt, decrypt } from '@/utils/jsencrypt';
|
||||||
import useUserStore from '@/store/modules/user';
|
import useUserStore from '@/store/modules/user';
|
||||||
import logoNew from '@/assets/logo/logoBlack.png';
|
import { ElMessage } from 'element-plus';
|
||||||
|
import logoNew from '@/assets/logo/LOGO.jpg';
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -131,6 +160,7 @@ const loginForm = ref({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const tenantOptions = ref([]);
|
const tenantOptions = ref([]);
|
||||||
|
const currentTenantName = ref('');
|
||||||
|
|
||||||
const loginRules = {
|
const loginRules = {
|
||||||
username: [{ required: true, trigger: 'blur', message: '请输入您的账号' }],
|
username: [{ required: true, trigger: 'blur', message: '请输入您的账号' }],
|
||||||
@@ -146,6 +176,21 @@ const captchaEnabled = ref(true);
|
|||||||
// 注册开关
|
// 注册开关
|
||||||
const register = ref(false);
|
const register = ref(false);
|
||||||
const redirect = ref(undefined);
|
const redirect = ref(undefined);
|
||||||
|
const passwordVisible = ref(false);
|
||||||
|
|
||||||
|
function togglePasswordVisibility() {
|
||||||
|
passwordVisible.value = !passwordVisible.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理忘记密码功能
|
||||||
|
function handleForgotPassword() {
|
||||||
|
// 这里可以添加忘记密码的逻辑,例如跳转到忘记密码页面或显示忘记密码弹窗
|
||||||
|
// 目前先显示一个提示
|
||||||
|
ElMessage({
|
||||||
|
message: '忘记密码功能正在开发中',
|
||||||
|
type: 'info'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
route,
|
route,
|
||||||
@@ -155,7 +200,7 @@ watch(
|
|||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
// 页面加载时从 localStorage 获取 invokeYb 的值
|
// 页面加载时从 localStorage 获取 invokeYb 的值和从 Cookies 获取记住的登录信息
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const storedInvokeYb = localStorage.getItem('invokeYb');
|
const storedInvokeYb = localStorage.getItem('invokeYb');
|
||||||
if (storedInvokeYb !== null) {
|
if (storedInvokeYb !== null) {
|
||||||
@@ -164,6 +209,38 @@ onMounted(() => {
|
|||||||
// 如果 localStorage 中没有值,则设置默认值并保存
|
// 如果 localStorage 中没有值,则设置默认值并保存
|
||||||
localStorage.setItem('invokeYb', 'true');
|
localStorage.setItem('invokeYb', 'true');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 从 Cookies 中恢复记住的登录信息
|
||||||
|
const rememberMe = Cookies.get('rememberMe');
|
||||||
|
if (rememberMe && rememberMe === 'true') {
|
||||||
|
const username = Cookies.get('username');
|
||||||
|
const password = Cookies.get('password');
|
||||||
|
if (username) {
|
||||||
|
loginForm.value.username = username;
|
||||||
|
loginForm.value.rememberMe = true;
|
||||||
|
// 解密密码
|
||||||
|
if (password) {
|
||||||
|
try {
|
||||||
|
loginForm.value.password = decrypt(password);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('密码解密失败:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取医疗机构列表
|
||||||
|
getUserBindTenantList().then((res) => {
|
||||||
|
tenantOptions.value = res.data.map(item => ({
|
||||||
|
label: item.tenantName,
|
||||||
|
value: item.id
|
||||||
|
}));
|
||||||
|
// 如果只有一个医疗机构,自动选中
|
||||||
|
if (tenantOptions.value.length === 1) {
|
||||||
|
loginForm.value.tenantId = tenantOptions.value[0].value;
|
||||||
|
currentTenantName.value = tenantOptions.value[0].label;
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function handleLogin() {
|
function handleLogin() {
|
||||||
@@ -279,6 +356,14 @@ function getCode() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 监听租户选择变化
|
||||||
|
watch(() => loginForm.value.tenantId, (newTenantId) => {
|
||||||
|
const selectedTenant = tenantOptions.value.find(item => item.value === newTenantId);
|
||||||
|
if (selectedTenant) {
|
||||||
|
currentTenantName.value = selectedTenant.label;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// 切换医保连接开关时更新 localStorage
|
// 切换医保连接开关时更新 localStorage
|
||||||
function topNavChange(value) {
|
function topNavChange(value) {
|
||||||
localStorage.setItem('invokeYb', value.toString());
|
localStorage.setItem('invokeYb', value.toString());
|
||||||
@@ -303,6 +388,7 @@ function getTenantList(username) {
|
|||||||
label: item.tenantName,
|
label: item.tenantName,
|
||||||
}));
|
}));
|
||||||
loginForm.value.tenantId = tenantOptions.value[0].value; //默认选中第一个
|
loginForm.value.tenantId = tenantOptions.value[0].value; //默认选中第一个
|
||||||
|
currentTenantName.value = tenantOptions.value[0].label;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -389,31 +475,85 @@ getCookie();
|
|||||||
getTenantList(loginForm.value.username);
|
getTenantList(loginForm.value.username);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
height: auto;
|
||||||
|
min-height: 100vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.login {
|
.login {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
background: #f8f9fa;
|
||||||
height: 100%;
|
min-height: 100vh;
|
||||||
|
padding-bottom: 100px; /* 为底部固定footer留出空间 */
|
||||||
//background-image: url("../assets/images/login-background.jpg");
|
//background-image: url("../assets/images/login-background.jpg");
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
}
|
}
|
||||||
.title {
|
.title {
|
||||||
margin: 0px auto 30px auto;
|
margin: 10px auto 15px auto;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #000;
|
color: #000;
|
||||||
font-family: 'Microsoft Yahei,STHeiti,Simsun,STSong,Helvetica Neue,Helvetica,Arial,sans-serif';
|
font-family: 'Microsoft Yahei,STHeiti,Simsun,STSong,Helvetica Neue,Helvetica,Arial,sans-serif';
|
||||||
}
|
}
|
||||||
|
.label{
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-options {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin: 8px 0 10px 0;
|
||||||
|
width: 100%; /* 确保容器占满宽度 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.remember-me {
|
||||||
|
margin: 0;
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.forgot-password {
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--primary);
|
||||||
|
cursor: pointer;
|
||||||
|
text-align: right; /* 确保文本右对齐 */
|
||||||
|
margin-left: auto; /* 确保元素右对齐 */
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
margin-top: 32px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-subtitle {
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
.login-form {
|
.login-form {
|
||||||
border-radius: 6px;
|
border-radius: 16px;
|
||||||
|
box-shadow: 0 4px 12px var(--shadow);
|
||||||
|
border: 1px solid var(--border);
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
width: 400px;
|
width: 100%;
|
||||||
|
max-width: 400px;
|
||||||
|
padding: 40px;
|
||||||
padding: 25px 25px 5px 25px;
|
padding: 25px 25px 5px 25px;
|
||||||
|
text-align: center;
|
||||||
.el-input {
|
.el-input {
|
||||||
height: 50px; // 修改输入框高度
|
height: 50px; // 修改输入框高度
|
||||||
input {
|
input {
|
||||||
height: 50px; // 修改输入框高度
|
height: 50px; // 修改输入框高度
|
||||||
font-size: 18px; // 修改输入框内文字大小
|
font-size: 18px; // 修改输入框内文字大小
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -438,24 +578,20 @@ getTenantList(loginForm.value.username);
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.el-login-top {
|
.el-login-top {
|
||||||
height: 80px;
|
text-align: center;
|
||||||
line-height: 40px;
|
margin: 0 auto 10px;
|
||||||
position: fixed;
|
.el-image {
|
||||||
top: 0;
|
max-width: 120px;
|
||||||
width: 100%;
|
max-height: 120px;
|
||||||
text-align: left;
|
}
|
||||||
color: #000;
|
|
||||||
font-family: Arial;
|
|
||||||
font-size: 12px;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
background-color: #f1f1f1;
|
|
||||||
padding: 20px;
|
|
||||||
}
|
}
|
||||||
.el-login-footer {
|
.el-login-footer {
|
||||||
height: 100px;
|
height: 80px;
|
||||||
line-height: 40px;
|
line-height: 30px;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #000;
|
color: #000;
|
||||||
@@ -463,8 +599,7 @@ getTenantList(loginForm.value.username);
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
background-color: #f1f1f1;
|
background-color: #f1f1f1;
|
||||||
|
z-index: 100; /* 确保footer在最上层 */
|
||||||
color: #000;
|
|
||||||
span {
|
span {
|
||||||
margin: 0 10px;
|
margin: 0 10px;
|
||||||
}
|
}
|
||||||
@@ -490,6 +625,13 @@ getTenantList(loginForm.value.username);
|
|||||||
width: 24px !important; // 调整图标的宽度
|
width: 24px !important; // 调整图标的宽度
|
||||||
height: 24px !important; // 调整图标的高度
|
height: 24px !important; // 调整图标的高度
|
||||||
font-size: 24px !important; // 调整图标的字体大小
|
font-size: 24px !important; // 调整图标的字体大小
|
||||||
|
color: #606266 !important; // 确保图标颜色可见
|
||||||
|
cursor: pointer !important; // 确保鼠标悬停时显示指针
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.password-toggle) {
|
||||||
|
line-height: 50px !important; // 确保文字垂直居中
|
||||||
|
user-select: none; // 禁止选中文字
|
||||||
}
|
}
|
||||||
:deep(.el-select__wrapper) {
|
:deep(.el-select__wrapper) {
|
||||||
background-color: #f5f7fa !important;
|
background-color: #f5f7fa !important;
|
||||||
@@ -498,4 +640,8 @@ getTenantList(loginForm.value.username);
|
|||||||
font-size: 18px !important;
|
font-size: 18px !important;
|
||||||
height: 50px !important; // 修改输入框高度
|
height: 50px !important; // 修改输入框高度
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:deep(.el-form-item) {
|
||||||
|
margin-bottom: 15px !important; // 减小输入框之间的距离
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -185,6 +185,7 @@ import {
|
|||||||
getpurchaseInventoryDetail,
|
getpurchaseInventoryDetail,
|
||||||
getpurchaseInventoryDetailReturn
|
getpurchaseInventoryDetailReturn
|
||||||
} from "./components/api";
|
} from "./components/api";
|
||||||
|
import { purchaseInventoryApproved as purchaseReturnApproved } from '../returnedPurchase/components/api';
|
||||||
import { useStore } from '@/store/store';
|
import { useStore } from '@/store/store';
|
||||||
import { formatDate } from "@/utils/index";
|
import { formatDate } from "@/utils/index";
|
||||||
import useTagsViewStore from '@/store/modules/tagsView';
|
import useTagsViewStore from '@/store/modules/tagsView';
|
||||||
@@ -260,6 +261,21 @@ function handelApply(row) {
|
|||||||
getList();
|
getList();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
}else if(row.typeEnum == 5){ // 采购退货审批通过
|
||||||
|
console.log("采购退货审批通过,typeEnum:", row.typeEnum);
|
||||||
|
console.log("供应单据号:", row.supplyBusNo);
|
||||||
|
purchaseReturnApproved(row.supplyBusNo).then((res) => {
|
||||||
|
console.log("采购退货审批结果:", res);
|
||||||
|
if (res.code == 200) {
|
||||||
|
proxy.$modal.msgSuccess("操作成功");
|
||||||
|
getList();
|
||||||
|
} else {
|
||||||
|
proxy.$modal.msgError("操作失败: " + (res.msg || "未知错误"));
|
||||||
|
}
|
||||||
|
}).catch((error) => {
|
||||||
|
console.error("采购退货审批错误:", error);
|
||||||
|
proxy.$modal.msgError("操作异常: " + error.message);
|
||||||
|
});
|
||||||
}else{
|
}else{
|
||||||
purchaseInventoryApproved(row.supplyBusNo).then((res) => {
|
purchaseInventoryApproved(row.supplyBusNo).then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
|
|||||||
@@ -87,23 +87,38 @@ export function getCount(queryParams) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取药房列表
|
// 获取药房列表(权限过滤)
|
||||||
export function getPharmacyList() {
|
export function getPharmacyList() {
|
||||||
return request({
|
return request({
|
||||||
url: '/app-common/inventory-pharmacy-list',
|
url: '/app-common/inventory-pharmacy-list',
|
||||||
// '/app-common/pharmacy-list',
|
|
||||||
method: 'get',
|
method: 'get',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取药库列表
|
// 获取药库列表(权限过滤)
|
||||||
export function getDispensaryList() {
|
export function getDispensaryList() {
|
||||||
return request({
|
return request({
|
||||||
url: '/app-common/inventory-cabinet-list',
|
url: '/app-common/inventory-cabinet-list',
|
||||||
// '/app-common/cabinet-list',
|
|
||||||
method: 'get',
|
method: 'get',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取药房列表(不受权限过滤,作为回退)
|
||||||
|
export function getPharmacyListAll() {
|
||||||
|
return request({
|
||||||
|
url: '/app-common/pharmacy-list',
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取药库列表(不受权限过滤,作为回退)
|
||||||
|
export function getDispensaryListAll() {
|
||||||
|
return request({
|
||||||
|
url: '/app-common/cabinet-list',
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 审批驳回
|
* 审批驳回
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -30,7 +30,8 @@
|
|||||||
<el-button type="primary" plain icon="Plus" @click="handleSave">批量保存</el-button>
|
<el-button type="primary" plain icon="Plus" @click="handleSave">批量保存</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-button type="primary" plain icon="Printer" @click="handlePrint"> 打印单据 </el-button>
|
<el-button type="primary" icon="View" @click="handlePrintPreview"> 预览单据 </el-button>
|
||||||
|
<el-button type="success" plain icon="Printer" @click="handlePrint"> 打印单据 </el-button>
|
||||||
<el-form
|
<el-form
|
||||||
:model="receiptHeaderForm"
|
:model="receiptHeaderForm"
|
||||||
ref="receiptHeaderRef"
|
ref="receiptHeaderRef"
|
||||||
@@ -130,8 +131,8 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<el-tabs type="border-card">
|
<el-tabs type="border-card">
|
||||||
<el-tab-pane label="入库单明细">
|
<el-tab-pane label="入库单明细">
|
||||||
<el-row :gutter="10" class="mb8" v-if="!viewStatus">
|
<el-row :gutter="10" class="mb8" v-if="!viewStatus">
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="primary" plain icon="Plus" @click="addNewRow">添加行</el-button>
|
<el-button type="primary" plain icon="Plus" @click="addNewRow">添加行</el-button>
|
||||||
@@ -635,6 +636,8 @@ import {
|
|||||||
getInitBusNo,
|
getInitBusNo,
|
||||||
purchaseInventoryApproved,
|
purchaseInventoryApproved,
|
||||||
reject,
|
reject,
|
||||||
|
getPharmacyListAll,
|
||||||
|
getDispensaryListAll,
|
||||||
} from './components/api';
|
} from './components/api';
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
import PopoverList from '@/components/OpenHis/popoverList/index.vue';
|
import PopoverList from '@/components/OpenHis/popoverList/index.vue';
|
||||||
@@ -643,6 +646,7 @@ import TraceNoDialog from '@/components/OpenHis/TraceNoDialog/index.vue';
|
|||||||
import { formatDate, formatDateymd } from '@/utils/index';
|
import { formatDate, formatDateymd } from '@/utils/index';
|
||||||
import { useStore } from '@/store/store';
|
import { useStore } from '@/store/store';
|
||||||
import useUserStore from '@/store/modules/user';
|
import useUserStore from '@/store/modules/user';
|
||||||
|
import { ElMessage } from 'element-plus';
|
||||||
import { nextTick, ref, watch } from 'vue';
|
import { nextTick, ref, watch } from 'vue';
|
||||||
import useTagsViewStore from '@/store/modules/tagsView';
|
import useTagsViewStore from '@/store/modules/tagsView';
|
||||||
import _, { isEqual } from 'lodash';
|
import _, { isEqual } from 'lodash';
|
||||||
@@ -793,6 +797,25 @@ watch(
|
|||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
document.addEventListener("click", handleClickOutside);
|
||||||
|
|
||||||
|
// 获取源仓库列表(假设 getPharmacyList 返回仓库数据)
|
||||||
|
getPharmacyList({ type: 'source' }).then(res => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
sourceTypeListOptions.value = res.data; // 格式需为 [{id, name}, ...]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 获取目的仓库列表
|
||||||
|
getPharmacyList({ type: 'purpose' }).then(res => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
purposeTypeListOptions.value = res.data;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 初始化默认仓库数据,使用药房类型(16)
|
||||||
|
handleChangeLocationType(16);
|
||||||
|
|
||||||
console.log(route, '!1212');
|
console.log(route, '!1212');
|
||||||
if (route.query.view) {
|
if (route.query.view) {
|
||||||
viewStatus.value = route.query.view;
|
viewStatus.value = route.query.view;
|
||||||
@@ -821,7 +844,8 @@ function addNewRow() {
|
|||||||
remake: '',
|
remake: '',
|
||||||
supplierId: '',
|
supplierId: '',
|
||||||
purposeTypeEnum: '',
|
purposeTypeEnum: '',
|
||||||
purposeLocationId: null,
|
// 使用表头的仓库作为新增行默认值,减少重复选择
|
||||||
|
purposeLocationId: receiptHeaderForm.purposeLocationId || null,
|
||||||
purposeLocationStoreId: null,
|
purposeLocationStoreId: null,
|
||||||
practitionerId: '',
|
practitionerId: '',
|
||||||
traceNo: '',
|
traceNo: '',
|
||||||
@@ -1124,11 +1148,25 @@ function changeValEnd(val, index) {
|
|||||||
function handleChangeLocationType(value) {
|
function handleChangeLocationType(value) {
|
||||||
if (value == 16) {
|
if (value == 16) {
|
||||||
getPharmacyList().then((res) => {
|
getPharmacyList().then((res) => {
|
||||||
locationList.value = res.data;
|
const list = res?.data || [];
|
||||||
|
if (!list.length) {
|
||||||
|
getPharmacyListAll().then((res2) => {
|
||||||
|
locationList.value = res2?.data || [];
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
locationList.value = list;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else if (value == 11) {
|
} else if (value == 17) {
|
||||||
getDispensaryList().then((res) => {
|
getDispensaryList().then((res) => {
|
||||||
locationList.value = res.data;
|
const list = res?.data || [];
|
||||||
|
if (!list.length) {
|
||||||
|
getDispensaryListAll().then((res2) => {
|
||||||
|
locationList.value = res2?.data || [];
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
locationList.value = list;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1303,27 +1341,193 @@ function handleSelectionChange(selection) {
|
|||||||
multiple.value = !selection.length;
|
multiple.value = !selection.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handlePrint() {
|
// 预览单据函数 - 简化实现,避免复杂嵌套数据结构
|
||||||
const result = [];
|
function handlePrintPreview() {
|
||||||
let supplierName = supplierListOptions.value.filter((item) => {
|
console.log('开始执行预览功能');
|
||||||
return item.value == receiptHeaderForm.supplierId;
|
|
||||||
})[0].label;
|
// 检查是否存在数据
|
||||||
|
if (!form.purchaseinventoryList || form.purchaseinventoryList.length === 0) {
|
||||||
|
ElMessage.warning('没有数据可预览');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否所有必填字段都已填写
|
||||||
|
const hasEmptyFields = form.purchaseinventoryList.some(row => {
|
||||||
|
return !row.name || !row.itemQuantity || !row.price || !row.totalPrice;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hasEmptyFields) {
|
||||||
|
ElMessage.warning('请确保所有药品信息完整后再预览');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查templateJson是否已正确导入
|
||||||
|
if (!templateJson) {
|
||||||
|
console.error('错误:templateJson未定义,请检查导入');
|
||||||
|
ElMessage.error('打印模板未加载,请刷新页面重试');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 安全获取供应商名称
|
||||||
|
let supplierName = '';
|
||||||
|
if (supplierListOptions.value && receiptHeaderForm.supplierId) {
|
||||||
|
const filteredSuppliers = supplierListOptions.value.filter((item) => {
|
||||||
|
return item.value == receiptHeaderForm.supplierId;
|
||||||
|
});
|
||||||
|
supplierName = filteredSuppliers.length > 0 ? filteredSuppliers[0].label : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算总金额
|
||||||
const totalAmount = form.purchaseinventoryList.reduce((accumulator, currentRow) => {
|
const totalAmount = form.purchaseinventoryList.reduce((accumulator, currentRow) => {
|
||||||
return accumulator + (Number(currentRow.totalPrice) || 0);
|
return accumulator + (Number(currentRow.totalPrice) || 0);
|
||||||
}, 0);
|
}, 0);
|
||||||
result.push({
|
|
||||||
supplierName: supplierName,
|
// 重新构建包含药品清单的数据结构
|
||||||
|
const simpleData = {
|
||||||
|
supplierName: supplierName || '',
|
||||||
totalAmount: totalAmount.toFixed(2),
|
totalAmount: totalAmount.toFixed(2),
|
||||||
...receiptHeaderForm,
|
receiptNumber: receiptHeaderForm.receiptNumber || '',
|
||||||
purchaseinventoryList: form.purchaseinventoryList,
|
receiptDate: receiptHeaderForm.receiptDate || '',
|
||||||
|
organizationName: receiptHeaderForm.organizationName || '',
|
||||||
|
// 重新添加药品清单数组,但确保格式安全
|
||||||
|
purchaseinventoryList: Array.isArray(form.purchaseinventoryList) ? form.purchaseinventoryList.map(item => ({
|
||||||
|
id: item.id || '',
|
||||||
|
name: item.name || '',
|
||||||
|
itemQuantity: item.itemQuantity || 0,
|
||||||
|
price: item.price || 0,
|
||||||
|
totalPrice: item.totalPrice || 0,
|
||||||
|
// 保留其他可能需要的字段
|
||||||
|
...item
|
||||||
|
})) : []
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('简化后的预览数据:', simpleData);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 直接使用templateJson创建打印
|
||||||
|
// 避免复杂的模板创建和数据处理逻辑
|
||||||
|
setTimeout(() => {
|
||||||
|
try {
|
||||||
|
// 最简单的方式使用hiprint - 直接调用print2方法
|
||||||
|
// 只传递必要的数据,不传递复杂嵌套的数组
|
||||||
|
const printOptions = {
|
||||||
|
preview: true,
|
||||||
|
title: '药品采购入库清单',
|
||||||
|
printer: ''
|
||||||
|
};
|
||||||
|
|
||||||
|
// 方法1: 尝试直接使用templateJson
|
||||||
|
console.log('尝试直接使用templateJson');
|
||||||
|
if (typeof hiprint.template !== 'undefined' && typeof hiprint.template.print === 'function') {
|
||||||
|
hiprint.template.print(templateJson, simpleData, printOptions);
|
||||||
|
}
|
||||||
|
// 方法2: 尝试创建简单模板
|
||||||
|
else if (typeof hiprint.PrintTemplate === 'function') {
|
||||||
|
console.log('尝试使用PrintTemplate');
|
||||||
|
const template = new hiprint.PrintTemplate({template: templateJson});
|
||||||
|
template.print(simpleData, printOptions);
|
||||||
|
}
|
||||||
|
// 方法3: 最直接的方式
|
||||||
|
else {
|
||||||
|
console.log('尝试最直接的打印方式');
|
||||||
|
hiprint.print(templateJson, simpleData, printOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
ElMessage.success('正在生成单据预览,请等待...');
|
||||||
|
} catch (e) {
|
||||||
|
console.error('预览执行失败:', e);
|
||||||
|
ElMessage.error('预览功能执行失败,请稍后重试');
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('预览准备失败:', error);
|
||||||
|
ElMessage.error('预览失败,请检查配置');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打印单据函数 - 简化实现,与预览函数保持一致
|
||||||
|
function handlePrint() {
|
||||||
|
// 检查是否存在数据
|
||||||
|
if (!form.purchaseinventoryList || form.purchaseinventoryList.length === 0) {
|
||||||
|
ElMessage.warning('没有数据可打印');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否所有必填字段都已填写
|
||||||
|
const hasEmptyFields = form.purchaseinventoryList.some(row => {
|
||||||
|
return !row.name || !row.itemQuantity || !row.price || !row.totalPrice;
|
||||||
});
|
});
|
||||||
console.log(result, '345678987654');
|
|
||||||
const printElements = templateJson;
|
if (hasEmptyFields) {
|
||||||
var hiprintTemplate = new hiprint.PrintTemplate({ template: printElements }); // 定义模板
|
ElMessage.warning('请确保所有药品信息完整后再打印');
|
||||||
hiprintTemplate.print2(result, {
|
return;
|
||||||
printer: 'EPSON LQ-80KFII',
|
}
|
||||||
title: '打印标题',
|
|
||||||
}); //开始打印
|
// 安全获取供应商名称
|
||||||
|
let supplierName = '';
|
||||||
|
if (supplierListOptions.value && receiptHeaderForm.supplierId) {
|
||||||
|
const filteredSuppliers = supplierListOptions.value.filter((item) => {
|
||||||
|
return item.value == receiptHeaderForm.supplierId;
|
||||||
|
});
|
||||||
|
supplierName = filteredSuppliers.length > 0 ? filteredSuppliers[0].label : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算总金额
|
||||||
|
const totalAmount = form.purchaseinventoryList.reduce((accumulator, currentRow) => {
|
||||||
|
return accumulator + (Number(currentRow.totalPrice) || 0);
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
// 重新构建包含药品清单的数据结构
|
||||||
|
const simpleData = {
|
||||||
|
supplierName: supplierName || '',
|
||||||
|
totalAmount: totalAmount.toFixed(2),
|
||||||
|
receiptNumber: receiptHeaderForm.receiptNumber || '',
|
||||||
|
receiptDate: receiptHeaderForm.receiptDate || '',
|
||||||
|
organizationName: receiptHeaderForm.organizationName || '',
|
||||||
|
// 重新添加药品清单数组,但确保格式安全
|
||||||
|
purchaseinventoryList: Array.isArray(form.purchaseinventoryList) ? form.purchaseinventoryList.map(item => ({
|
||||||
|
id: item.id || '',
|
||||||
|
name: item.name || '',
|
||||||
|
itemQuantity: item.itemQuantity || 0,
|
||||||
|
price: item.price || 0,
|
||||||
|
totalPrice: item.totalPrice || 0,
|
||||||
|
// 保留其他可能需要的字段
|
||||||
|
...item
|
||||||
|
})) : []
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 使用与预览函数相同的简化打印逻辑
|
||||||
|
setTimeout(() => {
|
||||||
|
try {
|
||||||
|
const printOptions = {
|
||||||
|
preview: false, // 直接打印模式
|
||||||
|
title: '药品采购入库清单',
|
||||||
|
printer: ''
|
||||||
|
};
|
||||||
|
|
||||||
|
// 尝试多种可能的API调用方式
|
||||||
|
if (typeof hiprint.template !== 'undefined' && typeof hiprint.template.print === 'function') {
|
||||||
|
hiprint.template.print(templateJson, simpleData, printOptions);
|
||||||
|
}
|
||||||
|
else if (typeof hiprint.PrintTemplate === 'function') {
|
||||||
|
const template = new hiprint.PrintTemplate({template: templateJson});
|
||||||
|
template.print(simpleData, printOptions);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hiprint.print(templateJson, simpleData, printOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
ElMessage.success('打印请求已发送');
|
||||||
|
} catch (e) {
|
||||||
|
console.error('打印执行失败:', e);
|
||||||
|
ElMessage.error('打印执行失败,请稍后重试');
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('打印失败:', error);
|
||||||
|
ElMessage.error('打印失败,请检查配置');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteSelectedRows() {
|
function deleteSelectedRows() {
|
||||||
@@ -1406,7 +1610,9 @@ function show() {
|
|||||||
visible.value = true;
|
visible.value = true;
|
||||||
getPurchaseinventoryTypeList();
|
getPurchaseinventoryTypeList();
|
||||||
getInitBusNo().then((res) => {
|
getInitBusNo().then((res) => {
|
||||||
receiptHeaderForm.busNo = res.data.busNo;
|
if (res.data && res.data.busNo) {
|
||||||
|
receiptHeaderForm.busNo = res.data.busNo;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// supplierListOptions.value = props.supplierListOptions;
|
// supplierListOptions.value = props.supplierListOptions;
|
||||||
// itemTypeOptions.value = props.itemTypeOptions;
|
// itemTypeOptions.value = props.itemTypeOptions;
|
||||||
@@ -1428,9 +1634,15 @@ function edit() {
|
|||||||
// itemTypeOptions.value = props.itemTypeOptions;
|
// itemTypeOptions.value = props.itemTypeOptions;
|
||||||
// practitionerListOptions.value = props.practitionerListOptions;
|
// practitionerListOptions.value = props.practitionerListOptions;
|
||||||
// receiptHeaderForm.busNo = props.busNoAdd;
|
// receiptHeaderForm.busNo = props.busNoAdd;
|
||||||
|
// 确保数据存在
|
||||||
|
if (!editData.value.item || editData.value.item.length === 0) {
|
||||||
|
proxy.$message.warning('没有可编辑的数据');
|
||||||
|
return;
|
||||||
|
}
|
||||||
receiptHeaderForm.value = editData.value.item.length > 0 ? editData.value.item[0] : {};
|
receiptHeaderForm.value = editData.value.item.length > 0 ? editData.value.item[0] : {};
|
||||||
receiptHeaderForm.busNo = editData.value.editRow.supplyBusNo;
|
receiptHeaderForm.busNo = editData.value.editRow.supplyBusNo;
|
||||||
receiptHeaderForm.supplierId = editData.value.editRow.supplierId;
|
// 修改这里:优先从详情数据中获取供应商ID,如果不存在则从列表数据中获取
|
||||||
|
receiptHeaderForm.supplierId = (editData.value.item[0] && editData.value.item[0].supplierId) || editData.value.editRow.supplierId;
|
||||||
receiptHeaderForm.practitionerId = editData.value.editRow.practitionerId;
|
receiptHeaderForm.practitionerId = editData.value.editRow.practitionerId;
|
||||||
console.log(editData.value.editRow, editData.value, 'editData.value.editRow');
|
console.log(editData.value.editRow, editData.value, 'editData.value.editRow');
|
||||||
receiptHeaderForm.occurrenceTime = editData.value.item[0].occurrenceTime
|
receiptHeaderForm.occurrenceTime = editData.value.item[0].occurrenceTime
|
||||||
@@ -1463,6 +1675,10 @@ function edit() {
|
|||||||
volume: item.totalVolume,
|
volume: item.totalVolume,
|
||||||
manufacturer: item.supplierName,
|
manufacturer: item.supplierName,
|
||||||
quantity: item.totalQuantity,
|
quantity: item.totalQuantity,
|
||||||
|
// 确保仓库字段回显
|
||||||
|
purposeLocationId: item.purposeLocationId || editData.value.editRow?.purposeLocationId || null,
|
||||||
|
locationStoreName: item.locationStoreName || '',
|
||||||
|
purposeLocationStoreId: item.purposeLocationStoreId || null,
|
||||||
// locationInventoryList: locationList.value,
|
// locationInventoryList: locationList.value,
|
||||||
startTime: formatDateymd(item.startTime),
|
startTime: formatDateymd(item.startTime),
|
||||||
endTime: formatDateymd(item.endTime),
|
endTime: formatDateymd(item.endTime),
|
||||||
@@ -1475,6 +1691,27 @@ function edit() {
|
|||||||
console.log(form.purchaseinventoryList, 'purchaseinventoryList.value');
|
console.log(form.purchaseinventoryList, 'purchaseinventoryList.value');
|
||||||
console.log(receiptHeaderForm, 'receiptHeaderForm');
|
console.log(receiptHeaderForm, 'receiptHeaderForm');
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
|
// 使用 Promise 确保数据加载完成
|
||||||
|
Promise.resolve().then(() => {
|
||||||
|
form.purchaseinventoryList = editData.value.item.map((item) => {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
name: item.itemName,
|
||||||
|
volume: item.totalVolume,
|
||||||
|
manufacturer: item.supplierName,
|
||||||
|
quantity: item.totalQuantity,
|
||||||
|
// 仓库字段回显(Promise 阶段再保障一次)
|
||||||
|
purposeLocationId: item.purposeLocationId || editData.value.editRow?.purposeLocationId || null,
|
||||||
|
locationStoreName: item.locationStoreName || '',
|
||||||
|
purposeLocationStoreId: item.purposeLocationStoreId || null,
|
||||||
|
startTime: formatDateymd(item.startTime),
|
||||||
|
endTime: formatDateymd(item.endTime),
|
||||||
|
applyTime: formatDate(item.applyTime),
|
||||||
|
isSave: true,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPurchaseinventoryTypeList() {
|
function getPurchaseinventoryTypeList() {
|
||||||
@@ -1485,7 +1722,7 @@ function getPurchaseinventoryTypeList() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 驳回
|
// reject
|
||||||
function handleReject() {
|
function handleReject() {
|
||||||
reject(route.query.supplyBusNo).then((res) => {
|
reject(route.query.supplyBusNo).then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
|
|||||||
@@ -693,6 +693,7 @@ const multiple = ref(true);
|
|||||||
const total = ref(0);
|
const total = ref(0);
|
||||||
const title = ref("");
|
const title = ref("");
|
||||||
const visible = ref(false);
|
const visible = ref(false);
|
||||||
|
const pageLoading = ref(false);
|
||||||
const row = ref({});
|
const row = ref({});
|
||||||
const rowIndex = ref(-1);
|
const rowIndex = ref(-1);
|
||||||
const totalAmount = ref(0);
|
const totalAmount = ref(0);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-container" v-loading="pageLoading" loading-text="审批中...">
|
<div class="app-container" v-loading="pageLoading" loading-text="审批中...">
|
||||||
|
|
||||||
<el-row :gutter="10" class="mb8" v-if="viewStatus">
|
<el-row :gutter="10" class="mb8" v-if="viewStatus">
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button
|
<el-button
|
||||||
@@ -144,7 +145,6 @@
|
|||||||
style="width: 150px"
|
style="width: 150px"
|
||||||
:disabled="data.isEdit"
|
:disabled="data.isEdit"
|
||||||
>
|
>
|
||||||
<!-- purchase_type -->
|
|
||||||
<el-option
|
<el-option
|
||||||
v-for="supplier in sourceTypeListOptions"
|
v-for="supplier in sourceTypeListOptions"
|
||||||
:key="supplier.id"
|
:key="supplier.id"
|
||||||
@@ -198,7 +198,6 @@
|
|||||||
style="width: 150px"
|
style="width: 150px"
|
||||||
:disabled="data.isEdit"
|
:disabled="data.isEdit"
|
||||||
>
|
>
|
||||||
<!-- purchase_type -->
|
|
||||||
<el-option
|
<el-option
|
||||||
v-for="supplier in purposeTypeListOptions"
|
v-for="supplier in purposeTypeListOptions"
|
||||||
:key="supplier.id"
|
:key="supplier.id"
|
||||||
@@ -208,6 +207,21 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- purposeLocationStoreName -->
|
<!-- purposeLocationStoreName -->
|
||||||
|
<el-form-item label="目的货位:" prop="purposeLocationStoreId">
|
||||||
|
<el-select
|
||||||
|
v-model="receiptHeaderForm.purposeLocationStoreId"
|
||||||
|
placeholder="请选择目的货位"
|
||||||
|
style="width: 150px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="supplier in purposeLocationStoreIdListOptions"
|
||||||
|
:key="supplier.value"
|
||||||
|
:label="supplier.label"
|
||||||
|
:value="supplier.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<!-- purposeLocationStoreName -->
|
||||||
<el-form-item label="目的货位:" prop="purposeLocationStoreId">
|
<el-form-item label="目的货位:" prop="purposeLocationStoreId">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="receiptHeaderForm.purposeLocationStoreId"
|
v-model="receiptHeaderForm.purposeLocationStoreId"
|
||||||
@@ -769,6 +783,7 @@ import useUserStore from "@/store/modules/user";
|
|||||||
import { useStore } from '@/store/store';
|
import { useStore } from '@/store/store';
|
||||||
import useTagsViewStore from '@/store/modules/tagsView';
|
import useTagsViewStore from '@/store/modules/tagsView';
|
||||||
import TraceNoDialog from '@/components/OpenHis/TraceNoDialog/index.vue'
|
import TraceNoDialog from '@/components/OpenHis/TraceNoDialog/index.vue'
|
||||||
|
import { nextTick } from 'vue';
|
||||||
const tagsViewStore = useTagsViewStore();
|
const tagsViewStore = useTagsViewStore();
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -831,6 +846,11 @@ const forms = reactive({
|
|||||||
const receiptHeaderForm = reactive({
|
const receiptHeaderForm = reactive({
|
||||||
busNo: undefined,
|
busNo: undefined,
|
||||||
occurrence_time: formatDate(new Date()),
|
occurrence_time: formatDate(new Date()),
|
||||||
|
sourceTypeEnum: 16, // 默认药房类型
|
||||||
|
purposeTypeEnum: 16, // 默认药房类型
|
||||||
|
sourceLocationId: '',
|
||||||
|
purposeLocationId: '',
|
||||||
|
medicationType: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
@@ -886,8 +906,18 @@ const data = reactive({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const { queryParams, rules, tableRules } = toRefs(data);
|
const { queryParams, rules, tableRules } = toRefs(data);
|
||||||
const purposeTypeListOptions = ref(undefined);
|
const purposeTypeListOptions = ref([]);
|
||||||
const sourceTypeListOptions = ref(undefined);
|
const sourceTypeListOptions = ref([]);
|
||||||
|
// 立即初始化模拟仓库数据
|
||||||
|
const mockWarehouses = [
|
||||||
|
{ id: '1', name: '药房1号' },
|
||||||
|
{ id: '2', name: '药房2号' },
|
||||||
|
{ id: '3', name: '药房3号' },
|
||||||
|
{ id: '4', name: '中心药房' },
|
||||||
|
{ id: '5', name: '门诊药房' }
|
||||||
|
];
|
||||||
|
// 设置模拟数据到仓库列表选项
|
||||||
|
// 通过onMounted中调用的handleChangeSourceTypeEnum和handleChangePurposeTypeEnum函数动态获取仓库数据
|
||||||
const sourceLocationStoreIdListOptions = ref(undefined);
|
const sourceLocationStoreIdListOptions = ref(undefined);
|
||||||
const purposeLocationStoreIdListOptions = ref(undefined);
|
const purposeLocationStoreIdListOptions = ref(undefined);
|
||||||
const categoryListOptions = ref(undefined);
|
const categoryListOptions = ref(undefined);
|
||||||
@@ -941,6 +971,9 @@ watch(
|
|||||||
// 挂载时绑定事件
|
// 挂载时绑定事件
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
document.addEventListener("click", handleClickOutside);
|
document.addEventListener("click", handleClickOutside);
|
||||||
|
// 初始化仓库数据,默认加载药房类型(16)的仓库
|
||||||
|
handleChangeSourceTypeEnum(receiptHeaderForm.sourceTypeEnum, 1);
|
||||||
|
handleChangePurposeTypeEnum(receiptHeaderForm.purposeTypeEnum, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 卸载时移除事件
|
// 卸载时移除事件
|
||||||
@@ -975,11 +1008,11 @@ function addNewRow() {
|
|||||||
itemId: "",
|
itemId: "",
|
||||||
unitCode: "",
|
unitCode: "",
|
||||||
remake: "",
|
remake: "",
|
||||||
// supplierId: "",
|
supplierId: "",
|
||||||
purposeTypeEnum: "",
|
purposeTypeEnum: "",
|
||||||
purposeLocationId: null,
|
purposeLocationId: null,
|
||||||
purposeLocationStoreId: null,
|
purposeLocationStoreId: null,
|
||||||
// practitionerId: "",
|
practitionerId: "",
|
||||||
traceNo: "",
|
traceNo: "",
|
||||||
invoiceNo: "",
|
invoiceNo: "",
|
||||||
startTime: "",
|
startTime: "",
|
||||||
@@ -1018,6 +1051,7 @@ function handleBlur(row, index) {
|
|||||||
if (receiptHeaderForm.medicationType == 1) {
|
if (receiptHeaderForm.medicationType == 1) {
|
||||||
row.itemTable = "med_medication_definition";
|
row.itemTable = "med_medication_definition";
|
||||||
} else {
|
} else {
|
||||||
|
console.log('Unknown warehouse type:', value);
|
||||||
row.itemTable = "adm_device_definition";
|
row.itemTable = "adm_device_definition";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1206,42 +1240,66 @@ function handleLocationClick(id,purposeLocationId,itemId, index) {
|
|||||||
}
|
}
|
||||||
// 切换仓库类型获取药房/药库列表 目的仓库切换
|
// 切换仓库类型获取药房/药库列表 目的仓库切换
|
||||||
function handleChangePurposeTypeEnum(value,type) {
|
function handleChangePurposeTypeEnum(value,type) {
|
||||||
if (value == 16) {
|
console.log('handleChangePurposeTypeEnum called with value:', value, 'type:', type);
|
||||||
getPharmacyList().then((res) => {
|
receiptHeaderForm.purposeLocationId = '';
|
||||||
purposeTypeListOptions.value = res.data;
|
if(value === 16){ // 药房类型
|
||||||
if(!route.query.supplyBusNo&&!type){
|
getPharmacyList().then(res => {
|
||||||
receiptHeaderForm.purposeLocationId = ''
|
console.log('getPharmacyList response:', res);
|
||||||
receiptHeaderForm.purposeLocationId1 = ''
|
if (res && res.data) {
|
||||||
|
purposeTypeListOptions.value = res.data;
|
||||||
|
if(!type && res.data.length > 0) {
|
||||||
|
receiptHeaderForm.purposeLocationId = res.data[0].id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('Error fetching pharmacy list:', error);
|
||||||
});
|
});
|
||||||
} else if (value == 11) {
|
} else if(value === 17){ // 药库类型
|
||||||
getDispensaryList().then((res) => {
|
getDispensaryList().then(res => {
|
||||||
purposeTypeListOptions.value = res.data;
|
console.log('getDispensaryList response:', res);
|
||||||
if(!route.query.supplyBusNo&&!type){
|
if (res && res.data) {
|
||||||
receiptHeaderForm.purposeLocationId = ''
|
purposeTypeListOptions.value = res.data;
|
||||||
receiptHeaderForm.purposeLocationId1 = ''
|
if(!type && res.data.length > 0) {
|
||||||
|
receiptHeaderForm.purposeLocationId = res.data[0].id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('Error fetching dispensary list:', error);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
purposeTypeListOptions.value = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 源仓库切换
|
// 源仓库切换
|
||||||
function handleChangeSourceTypeEnum(value,type) {
|
function handleChangeSourceTypeEnum(value,type) {
|
||||||
if (value == 16) {
|
console.log('handleChangeSourceTypeEnum called with value:', value, 'type:', type);
|
||||||
getPharmacyList().then((res) => {
|
receiptHeaderForm.sourceLocationId = '';
|
||||||
sourceTypeListOptions.value = res.data;
|
if(value === 16){ // 药房类型
|
||||||
if(!route.query.supplyBusNo&&!type){
|
getPharmacyList().then(res => {
|
||||||
receiptHeaderForm.sourceLocationId = ''
|
console.log('getPharmacyList response:', res);
|
||||||
receiptHeaderForm.sourceLocationId1 = ''
|
if (res && res.data) {
|
||||||
|
sourceTypeListOptions.value = res.data;
|
||||||
|
if(!type && res.data.length > 0) {
|
||||||
|
receiptHeaderForm.sourceLocationId = res.data[0].id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('Error fetching pharmacy list:', error);
|
||||||
});
|
});
|
||||||
} else if (value == 11) {
|
} else if(value === 17){ // 药库类型
|
||||||
getDispensaryList().then((res) => {
|
getDispensaryList().then(res => {
|
||||||
sourceTypeListOptions.value = res.data;
|
console.log('getDispensaryList response:', res);
|
||||||
if(!route.query.supplyBusNo&&!type){
|
if (res && res.data) {
|
||||||
receiptHeaderForm.sourceLocationId = ''
|
sourceTypeListOptions.value = res.data;
|
||||||
receiptHeaderForm.sourceLocationId1 = ''
|
if(!type && res.data.length > 0) {
|
||||||
|
receiptHeaderForm.sourceLocationId = res.data[0].id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('Error fetching dispensary list:', error);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
sourceTypeListOptions.value = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function editBatchTransfer(index){
|
function editBatchTransfer(index){
|
||||||
@@ -1857,8 +1915,19 @@ function getBusNoInitList() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getTransferProductTypeList();
|
// 初始化函数
|
||||||
getBusNoInitList()
|
function initComponent() {
|
||||||
|
console.log('initComponent called');
|
||||||
|
getTransferProductTypeList();
|
||||||
|
getBusNoInitList();
|
||||||
|
|
||||||
|
console.log('组件初始化完成,仓库列表数据已预先设置');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 调用初始化函数
|
||||||
|
initComponent();
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.custom-tree-node {
|
.custom-tree-node {
|
||||||
|
|||||||
@@ -110,8 +110,7 @@ export function getCount(queryParams) {
|
|||||||
// 获取药房列表
|
// 获取药房列表
|
||||||
export function getPharmacyList() {
|
export function getPharmacyList() {
|
||||||
return request({
|
return request({
|
||||||
url: '/app-common/inventory-pharmacy-list',
|
url: '/app-common/pharmacy-list',
|
||||||
// '/app-common/pharmacy-list',
|
|
||||||
method: 'get',
|
method: 'get',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -119,8 +118,7 @@ export function getPharmacyList() {
|
|||||||
// 获取药库列表
|
// 获取药库列表
|
||||||
export function getDispensaryList() {
|
export function getDispensaryList() {
|
||||||
return request({
|
return request({
|
||||||
url:'/app-common/inventory-cabinet-list',
|
url: '/app-common/cabinet-list',
|
||||||
// '/app-common/cabinet-list',
|
|
||||||
method: 'get',
|
method: 'get',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -360,7 +360,7 @@
|
|||||||
"tableQRCodeLevel": 0,
|
"tableQRCodeLevel": 0,
|
||||||
"tableSummaryTitle": true,
|
"tableSummaryTitle": true,
|
||||||
"tableSummary": "",
|
"tableSummary": "",
|
||||||
"renderFormatter": "function(value,row,colIndex,options,rowIndex){ return value + '<br/>' + '用法用量'; }",
|
"renderFormatter": "function(value,row,colIndex,options,rowIndex){ return value + '<br/>' + (row.totalVolume || '') + '<br/>' + '用法用量'; }",
|
||||||
"styler2": "function(value,row,index,options){ return {padding: '5px 5px' }; }",
|
"styler2": "function(value,row,index,options){ return {padding: '5px 5px' }; }",
|
||||||
"width": 86.5148548770295,
|
"width": 86.5148548770295,
|
||||||
"field": "itemName",
|
"field": "itemName",
|
||||||
@@ -462,7 +462,7 @@
|
|||||||
"tableQRCodeLevel": 0,
|
"tableQRCodeLevel": 0,
|
||||||
"tableSummaryTitle": true,
|
"tableSummaryTitle": true,
|
||||||
"tableSummary": "",
|
"tableSummary": "",
|
||||||
"renderFormatter": "function(value,row,colIndex,options,rowIndex){ return value + '<br/>' + '用法用量'; }",
|
"renderFormatter": "function(value,row,colIndex,options,rowIndex){ return value + '<br/>' + (row.totalVolume || '') + '<br/>' + (row.methodCode_dictText || '用法用量'); }",
|
||||||
"styler2": "function(value,row,index,options){ return {padding: '5px 5px' }; }",
|
"styler2": "function(value,row,index,options){ return {padding: '5px 5px' }; }",
|
||||||
"width": 86.5148548770295,
|
"width": 86.5148548770295,
|
||||||
"field": "medicineName",
|
"field": "medicineName",
|
||||||
|
|||||||
@@ -196,7 +196,7 @@
|
|||||||
批量发药
|
批量发药
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button type="primary" @click="handleScan()" style="margin-left: 30px"> 扫码 </el-button>
|
<el-button type="primary" @click="handleScan()" style="margin-left: 30px"> 扫码 </el-button>
|
||||||
<el-button type="primary" @click="printPrescription()" style="margin-left: 30px">
|
<el-button type="primary" @click="previewAndPrint()" style="margin-left: 30px">
|
||||||
处方打印
|
处方打印
|
||||||
</el-button>
|
</el-button>
|
||||||
<div style="position: absolute; top: 30px; right: 25px">
|
<div style="position: absolute; top: 30px; right: 25px">
|
||||||
@@ -398,7 +398,7 @@ import { advicePrint } from '@/api/public';
|
|||||||
import { formatDate, formatDateStr } from '@/utils/index';
|
import { formatDate, formatDateStr } from '@/utils/index';
|
||||||
import { debounce } from 'lodash-es';
|
import { debounce } from 'lodash-es';
|
||||||
import TraceNoDialog from '@/components/OpenHis/TraceNoDialog/index.vue';
|
import TraceNoDialog from '@/components/OpenHis/TraceNoDialog/index.vue';
|
||||||
import { hiprint } from 'vue-plugin-hiprint';
|
// 使用window.hiprint,不再从vue-plugin-hiprint导入
|
||||||
import templateJson from './components/templateJson.json';
|
import templateJson from './components/templateJson.json';
|
||||||
// import disposalTemplate from './components/disposalTemplate.json';
|
// import disposalTemplate from './components/disposalTemplate.json';
|
||||||
import {
|
import {
|
||||||
@@ -655,91 +655,373 @@ function getList() {
|
|||||||
const printerList = ref([]); // 打印机列表
|
const printerList = ref([]); // 打印机列表
|
||||||
const selectedPrinter = ref(''); // 选中的打印机
|
const selectedPrinter = ref(''); // 选中的打印机
|
||||||
const showPrinterDialog = ref(false); // 显示打印机选择对话框
|
const showPrinterDialog = ref(false); // 显示打印机选择对话框
|
||||||
|
const previewData = ref(null); // 预览数据
|
||||||
|
|
||||||
// 修改printPrescription方法,强制显示打印机选择弹窗
|
// 抽取获取打印数据的公共函数
|
||||||
async function printPrescription() {
|
async function getPrintData() {
|
||||||
const selectedRows = tableRef.value.getSelectionRows();
|
const selectedRows = tableRef.value.getSelectionRows();
|
||||||
if (selectedRows.length === 0) {
|
if (selectedRows.length === 0) {
|
||||||
proxy.$modal.msgWarning('未选择要打印的项目,请重新选择,打印失败');
|
proxy.$modal.msgWarning('未选择要打印的项目,请重新选择');
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 获取打印数据
|
// 获取打印数据
|
||||||
let requestIds = selectedRows.map((item) => item.requestId).join(',');
|
let requestIds = selectedRows.map((item) => item.requestId).join(',');
|
||||||
|
console.log('打印请求ID:', requestIds);
|
||||||
|
|
||||||
advicePrint({ requestIds: requestIds, isPrescription: '1' }).then((res) => {
|
const res = await advicePrint({ requestIds: requestIds, isPrescription: '1' });
|
||||||
const groupedRows = {};
|
console.log('打印数据获取结果:', res);
|
||||||
res.data.adviceItemList.forEach((row) => {
|
|
||||||
const prescriptionNo = row.prescriptionNo;
|
if (!res || !res.data || !res.data.adviceItemList) {
|
||||||
if (!groupedRows[prescriptionNo]) {
|
proxy.$modal.msgError('获取打印数据失败:数据格式不正确');
|
||||||
groupedRows[prescriptionNo] = [];
|
return null;
|
||||||
}
|
}
|
||||||
row.contractName = res.data.contractName;
|
|
||||||
groupedRows[prescriptionNo].push(row);
|
const groupedRows = {};
|
||||||
});
|
res.data.adviceItemList.forEach((row) => {
|
||||||
|
const prescriptionNo = row.prescriptionNo;
|
||||||
|
if (!groupedRows[prescriptionNo]) {
|
||||||
|
groupedRows[prescriptionNo] = [];
|
||||||
|
}
|
||||||
|
row.contractName = res.data.contractName;
|
||||||
|
groupedRows[prescriptionNo].push(row);
|
||||||
|
});
|
||||||
|
|
||||||
const groupedArray = Object.values(groupedRows);
|
const groupedArray = Object.values(groupedRows);
|
||||||
const result = [];
|
const result = [];
|
||||||
|
|
||||||
groupedArray.forEach((item) => {
|
groupedArray.forEach((item) => {
|
||||||
|
if (item && item.length > 0) {
|
||||||
|
// 从处方列表的第一个条目提取处方信息
|
||||||
|
const firstItem = item[0];
|
||||||
const total = item.reduce((sum, item) => {
|
const total = item.reduce((sum, item) => {
|
||||||
return sum + (item.totalPrice || 0);
|
return sum + (item.totalPrice || 0);
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
|
// 转换药品列表字段,确保与打印模板匹配
|
||||||
|
const transformedPrescriptionList = item.map(medItem => ({
|
||||||
|
...medItem,
|
||||||
|
// 添加模板需要的字段映射
|
||||||
|
medicineName: medItem.itemName, // 用于模板中的medicineName字段
|
||||||
|
totalVolume: medItem.totalVolume || medItem.spec || '', // 后端返回的规格字段是totalVolume
|
||||||
|
unitPrice: medItem.unitPrice || medItem.price || 0, // 使用后端返回的unitPrice
|
||||||
|
unitCode_dictText: medItem.unitCode_dictText || medItem.unit || '', // 使用后端返回的unitCode_dictText
|
||||||
|
// 添加其他可能需要的字段
|
||||||
|
dose: medItem.dose || '',
|
||||||
|
doseUnitCode_dictText: medItem.doseUnitCode_dictText || '',
|
||||||
|
methodCode_dictText: medItem.methodCode_dictText || medItem.usage || '',
|
||||||
|
rateCode_dictText: medItem.rateCode_dictText || medItem.rateCode || ''
|
||||||
|
}));
|
||||||
|
|
||||||
result.push({
|
result.push({
|
||||||
...res.data,
|
...res.data,
|
||||||
|
// 确保处方号、患者信息等关键数据正确提取,并添加模板需要的字段映射
|
||||||
|
prescriptionNo: firstItem.prescriptionNo,
|
||||||
|
patientName: res.data.patientName || firstItem.patientName,
|
||||||
|
gender: res.data.genderEnum || firstItem.gender,
|
||||||
|
genderEnum_enumText: res.data.genderEnum_enumText || firstItem.gender || '', // 使用后端返回的性别文本
|
||||||
|
age: res.data.age || firstItem.age,
|
||||||
|
adviceDate: res.data.reqTime || firstItem.adviceDate || firstItem.createTime || new Date().toLocaleDateString(),
|
||||||
|
reqTime: res.data.reqTime || firstItem.adviceDate || firstItem.createTime || new Date().toLocaleDateString(), // 开具日期字段映射
|
||||||
|
doctorName: res.data.doctorName || firstItem.doctorName,
|
||||||
medTotalAmount: total,
|
medTotalAmount: total,
|
||||||
prescriptionList: item,
|
// 添加模板需要的其他字段
|
||||||
|
encounterNo: res.data.encounterNo || firstItem.encounterNo || '', // 门诊号
|
||||||
|
departmentName: res.data.departmentName || firstItem.departmentName || '', // 科室
|
||||||
|
conditionName: res.data.conditionName || firstItem.conditionName || '', // 临床诊断
|
||||||
|
phone: res.data.phone || firstItem.phone || '', // 电话
|
||||||
|
contractName: res.data.contractName || firstItem.contractName || '', // 医疗机构
|
||||||
|
prescriptionList: transformedPrescriptionList, // 使用转换后的药品列表
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
// 获取打印机列表
|
|
||||||
const printers = getPrinterList();
|
|
||||||
|
|
||||||
if (printers.length === 0) {
|
|
||||||
proxy.$modal.msgWarning('未检测到可用打印机');
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 强制显示打印机选择对话框,无论是否有缓存
|
|
||||||
// 设置打印机列表
|
|
||||||
printerList.value = printers;
|
|
||||||
// 显示对话框
|
|
||||||
showPrinterDialog.value = true;
|
|
||||||
// 保存当前打印数据到临时变量
|
|
||||||
window.currentPrintData = result;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log('打印数据准备完成:', result);
|
||||||
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('打印过程出错:', error);
|
console.error('获取打印数据失败:', error);
|
||||||
proxy.$modal.msgError('打印失败: ' + error.message);
|
proxy.$modal.msgError('获取打印数据失败: ' + error.message);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 合并预览和打印功能的主函数
|
||||||
|
async function previewAndPrint() {
|
||||||
|
try {
|
||||||
|
const result = await getPrintData();
|
||||||
|
if (!result) return;
|
||||||
|
|
||||||
|
// 保存预览数据
|
||||||
|
previewData.value = result;
|
||||||
|
|
||||||
|
console.log('执行处方预览和打印');
|
||||||
|
|
||||||
|
// 构建预览HTML
|
||||||
|
let previewHtml = '';
|
||||||
|
|
||||||
|
// 为每个处方生成预览内容
|
||||||
|
result.forEach((prescription, index) => {
|
||||||
|
// 确保处方数据存在
|
||||||
|
if (!prescription) return;
|
||||||
|
|
||||||
|
// 从处方获取药品列表,确保是数组
|
||||||
|
const prescriptionList = Array.isArray(prescription.prescriptionList) ? prescription.prescriptionList : [];
|
||||||
|
|
||||||
|
previewHtml += '<div class="prescription-container">';
|
||||||
|
previewHtml += '<h3>处方 ' + (index + 1) + '</h3>';
|
||||||
|
previewHtml += '<div class="prescription-info">';
|
||||||
|
previewHtml += '<p><strong>处方号:</strong> ' + (prescription.prescriptionNo || 'N/A') + '</p>';
|
||||||
|
previewHtml += '<p><strong>患者姓名:</strong> ' + (prescription.patientName || 'N/A') + '</p>';
|
||||||
|
previewHtml += '<p><strong>性别:</strong> ' + (prescription.genderEnum_enumText || prescription.gender || 'N/A') + '</p>';
|
||||||
|
previewHtml += '<p><strong>年龄:</strong> ' + (prescription.age || 'N/A') + '</p>';
|
||||||
|
previewHtml += '<p><strong>开具日期:</strong> ' + (prescription.reqTime || prescription.adviceDate || prescription.createTime || new Date().toLocaleDateString()) + '</p>';
|
||||||
|
previewHtml += '<p><strong>医生:</strong> ' + (prescription.doctorName || 'N/A') + '</p>';
|
||||||
|
// 添加额外的处方信息
|
||||||
|
if (prescription.encounterNo) previewHtml += '<p><strong>门诊号:</strong> ' + prescription.encounterNo + '</p>';
|
||||||
|
if (prescription.departmentName) previewHtml += '<p><strong>科室:</strong> ' + prescription.departmentName + '</p>';
|
||||||
|
if (prescription.conditionName) previewHtml += '<p><strong>临床诊断:</strong> ' + prescription.conditionName + '</p>';
|
||||||
|
if (prescription.phone) previewHtml += '<p><strong>电话:</strong> ' + prescription.phone + '</p>';
|
||||||
|
previewHtml += '</div>';
|
||||||
|
|
||||||
|
previewHtml += '<table class="prescription-table">';
|
||||||
|
previewHtml += '<thead>';
|
||||||
|
previewHtml += '<tr>';
|
||||||
|
previewHtml += '<th>药品名称</th>';
|
||||||
|
previewHtml += '<th>规格</th>';
|
||||||
|
previewHtml += '<th>单价</th>';
|
||||||
|
previewHtml += '<th>数量</th>';
|
||||||
|
previewHtml += '<th>金额</th>';
|
||||||
|
previewHtml += '<th>费用等级</th>';
|
||||||
|
previewHtml += '<th>用法用量</th>';
|
||||||
|
previewHtml += '</tr>';
|
||||||
|
previewHtml += '</thead>';
|
||||||
|
previewHtml += '<tbody>';
|
||||||
|
|
||||||
|
// 添加药品列表
|
||||||
|
if (prescriptionList.length > 0) {
|
||||||
|
prescriptionList.forEach((item) => {
|
||||||
|
previewHtml += '<tr>';
|
||||||
|
// 使用映射后的字段名,确保与打印模板一致
|
||||||
|
previewHtml += '<td>' + (item.medicineName || item.itemName || 'N/A') + '</td>';
|
||||||
|
previewHtml += '<td>' + (item.totalVolume || item.spec || '') + '</td>';
|
||||||
|
previewHtml += '<td>' + (item.unitPrice || item.price || '0.00') + '</td>';
|
||||||
|
previewHtml += '<td>' + (item.quantity || 'N/A') + ' ' + (item.unitCode_dictText || item.unit || '') + '</td>';
|
||||||
|
previewHtml += '<td>' + (item.totalPrice || '0.00') + '</td>';
|
||||||
|
previewHtml += '<td>' + (item.contractName || 'N/A') + '</td>';
|
||||||
|
// 组合用法用量信息
|
||||||
|
const usageInfo = [];
|
||||||
|
if (item.dose && item.doseUnitCode_dictText) usageInfo.push(item.dose + item.doseUnitCode_dictText);
|
||||||
|
if (item.methodCode_dictText || item.usage) usageInfo.push(item.methodCode_dictText || item.usage);
|
||||||
|
if (item.frequency) usageInfo.push(item.frequency);
|
||||||
|
previewHtml += '<td>' + usageInfo.join('<br/>') + '</td>';
|
||||||
|
previewHtml += '</tr>';
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
previewHtml += '<tr><td colspan="7" style="text-align: center;">暂无药品信息</td></tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
previewHtml += '</tbody>';
|
||||||
|
previewHtml += '<tfoot>';
|
||||||
|
previewHtml += '<tr>';
|
||||||
|
previewHtml += '<td colspan="6" style="text-align: right; font-weight: bold;">总计:</td>';
|
||||||
|
previewHtml += '<td style="font-weight: bold;">' + (prescription.medTotalAmount || '0.00') + '</td>';
|
||||||
|
previewHtml += '</tr>';
|
||||||
|
previewHtml += '</tfoot>';
|
||||||
|
previewHtml += '</table>';
|
||||||
|
|
||||||
|
previewHtml += '<div class="prescription-footer">';
|
||||||
|
previewHtml += '<p><strong>医疗机构:</strong> ' + (prescription.contractName || 'N/A') + '</p>';
|
||||||
|
previewHtml += '</div>';
|
||||||
|
previewHtml += '</div>';
|
||||||
|
previewHtml += '<hr class="prescription-separator">';
|
||||||
|
});
|
||||||
|
|
||||||
|
// 将打印数据序列化,以便在预览窗口中访问
|
||||||
|
const serializedData = encodeURIComponent(JSON.stringify(result));
|
||||||
|
|
||||||
|
// 创建预览窗口
|
||||||
|
const previewWindow = window.open('', '_blank');
|
||||||
|
if (!previewWindow) {
|
||||||
|
throw new Error('无法打开预览窗口,请检查浏览器弹窗设置');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用更安全的方式生成HTML内容,避免Vue编译错误
|
||||||
|
const createPreviewHtml = (prescriptionData) => {
|
||||||
|
// 简单的HTML结构,避免复杂标签嵌套
|
||||||
|
let html = '<!DOCTYPE html><html><head><meta charset="utf-8"><title>处方预览</title>';
|
||||||
|
|
||||||
|
// 简化的样式
|
||||||
|
html += '<style>';
|
||||||
|
html += 'body{font-family:Arial,sans-serif;margin:20px;}';
|
||||||
|
html += '.content{max-width:800px;margin:0 auto;}';
|
||||||
|
html += '.header{text-align:center;margin-bottom:20px;}';
|
||||||
|
html += '.print-btn{background:#1890ff;color:white;border:none;padding:10px 20px;margin-bottom:20px;cursor:pointer;}';
|
||||||
|
html += 'table{width:100%;border-collapse:collapse;margin-bottom:20px;}';
|
||||||
|
html += 'th,td{border:1px solid #ddd;padding:8px;}';
|
||||||
|
html += 'th{background:#f2f2f2;}';
|
||||||
|
html += '.prescription{margin-bottom:40px;padding-bottom:20px;border-bottom:1px solid #ddd;}';
|
||||||
|
html += '@media print{.print-btn{display:none;}}';
|
||||||
|
html += '</style>';
|
||||||
|
|
||||||
|
html += '</head><body><div class="content">';
|
||||||
|
html += '<div class="header"><h2>处方预览</h2></div>';
|
||||||
|
html += '<button class="print-btn" onclick="window.print()">打印</button>';
|
||||||
|
|
||||||
|
// 添加处方内容
|
||||||
|
html += prescriptionData;
|
||||||
|
|
||||||
|
html += '</div></body></html>';
|
||||||
|
return html;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 使用创建的函数生成HTML并写入
|
||||||
|
previewWindow.document.write(createPreviewHtml(previewHtml));
|
||||||
|
previewWindow.document.close();
|
||||||
|
|
||||||
|
proxy.$modal.msgSuccess('预览成功,请在新窗口中查看并点击打印按钮');
|
||||||
|
|
||||||
|
// 同时处理后台打印逻辑(使用原来的打印功能)
|
||||||
|
setTimeout(() => {
|
||||||
|
handleBackgroundPrint(result);
|
||||||
|
}, 1000);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('预览和打印过程出错:', error);
|
||||||
|
proxy.$modal.msgError('操作失败: ' + error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 后台打印逻辑,复用原有的打印功能
|
||||||
|
function handleBackgroundPrint(result) {
|
||||||
|
try {
|
||||||
|
// 获取打印机列表
|
||||||
|
const printers = getPrinterList();
|
||||||
|
console.log('获取到的打印机列表:', printers);
|
||||||
|
|
||||||
|
if (printers.length === 0) {
|
||||||
|
console.log('未检测到可用打印机,仅提供预览功能');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置打印机列表
|
||||||
|
printerList.value = printers;
|
||||||
|
|
||||||
|
// 检查是否有缓存的打印机
|
||||||
|
const cachedPrinter = getCachedPrinter();
|
||||||
|
console.log('缓存的打印机:', cachedPrinter);
|
||||||
|
|
||||||
|
if (cachedPrinter && printers.some(printer => printer.name === cachedPrinter)) {
|
||||||
|
// 如果有缓存的打印机,直接使用
|
||||||
|
selectedPrinter.value = cachedPrinter;
|
||||||
|
confirmPrinter(result);
|
||||||
|
} else {
|
||||||
|
// 否则不自动显示打印机选择对话框,让用户在预览页面手动选择打印
|
||||||
|
console.log('无缓存打印机,用户可在预览页面手动打印');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('后台打印过程出错:', error);
|
||||||
|
// 不显示错误提示,以免干扰用户在预览页面的操作
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用保存的打印数据执行打印
|
// 使用保存的打印数据执行打印
|
||||||
function confirmPrinter() {
|
function confirmPrinter(printData) {
|
||||||
|
console.log('开始打印,传入数据:', printData);
|
||||||
|
console.log('window临时数据:', window.currentPrintData);
|
||||||
|
|
||||||
|
// 如果没有传入数据,尝试从window临时变量获取
|
||||||
|
let data = printData || window.currentPrintData;
|
||||||
|
|
||||||
if (!selectedPrinter.value) {
|
if (!selectedPrinter.value) {
|
||||||
proxy.$modal.msgWarning('请选择打印机');
|
proxy.$modal.msgWarning('请选择打印机');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!data || !Array.isArray(data) || data.length === 0) {
|
||||||
|
proxy.$modal.msgError('没有找到有效的打印数据');
|
||||||
|
showPrinterDialog.value = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!templateJson) {
|
||||||
|
proxy.$modal.msgError('打印模板加载失败');
|
||||||
|
showPrinterDialog.value = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确保数据字段映射正确,特别是规格字段
|
||||||
|
data = data.map(prescription => {
|
||||||
|
const mappedPrescription = { ...prescription };
|
||||||
|
// 确保药品列表字段映射正确
|
||||||
|
if (Array.isArray(prescription.prescriptionList)) {
|
||||||
|
mappedPrescription.prescriptionList = prescription.prescriptionList.map(med => ({
|
||||||
|
...med,
|
||||||
|
// 确保规格字段正确映射,优先使用totalVolume
|
||||||
|
totalVolume: med.totalVolume || med.spec || '',
|
||||||
|
// 确保其他关键字段存在
|
||||||
|
medicineName: med.medicineName || med.itemName || '',
|
||||||
|
unitPrice: med.unitPrice || med.price || 0,
|
||||||
|
unitCode_dictText: med.unitCode_dictText || med.unit || '',
|
||||||
|
methodCode_dictText: med.methodCode_dictText || med.usage || ''
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
return mappedPrescription;
|
||||||
|
});
|
||||||
|
console.log('处理后的打印数据:', data);
|
||||||
|
|
||||||
|
console.log('准备执行打印,打印机:', selectedPrinter.value);
|
||||||
|
|
||||||
// 使用his.js中的savePrinterToCache保存选择
|
// 使用his.js中的savePrinterToCache保存选择
|
||||||
savePrinterToCache(selectedPrinter.value);
|
savePrinterToCache(selectedPrinter.value);
|
||||||
|
|
||||||
// 使用his.js中的executePrint方法执行打印
|
try {
|
||||||
if (window.currentPrintData) {
|
// 检查hiprint是否可用
|
||||||
executePrint(window.currentPrintData, templateJson, selectedPrinter.value)
|
if (!window.hiprint) {
|
||||||
.then(() => {
|
throw new Error('打印插件未正确加载');
|
||||||
showPrinterDialog.value = false;
|
}
|
||||||
// 清除临时数据
|
|
||||||
window.currentPrintData = null;
|
// 直接使用hiprint执行打印,确保功能正常
|
||||||
})
|
const hiprintTemplate = new window.hiprint.PrintTemplate({ template: templateJson });
|
||||||
.catch((error) => {
|
const printOptions = {
|
||||||
proxy.$modal.msgError(error.message || '打印失败');
|
title: '处方打印',
|
||||||
showPrinterDialog.value = false;
|
height: 210,
|
||||||
window.currentPrintData = null;
|
width: 148,
|
||||||
});
|
printer: selectedPrinter.value
|
||||||
|
};
|
||||||
|
|
||||||
|
// 打印成功回调
|
||||||
|
hiprintTemplate.on('printSuccess', function (e) {
|
||||||
|
console.log('打印成功:', e);
|
||||||
|
proxy.$modal.msgSuccess('打印成功');
|
||||||
|
showPrinterDialog.value = false;
|
||||||
|
// 清除临时数据
|
||||||
|
window.currentPrintData = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 打印失败回调
|
||||||
|
hiprintTemplate.on('printError', function (e) {
|
||||||
|
console.error('打印失败:', e);
|
||||||
|
proxy.$modal.msgError('打印失败,请检查打印机连接');
|
||||||
|
showPrinterDialog.value = false;
|
||||||
|
window.currentPrintData = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 执行打印
|
||||||
|
console.log('调用hiprint.print2方法');
|
||||||
|
hiprintTemplate.print2(data, printOptions);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('打印执行出错:', error);
|
||||||
|
proxy.$modal.msgError('打印执行失败: ' + error.message);
|
||||||
|
showPrinterDialog.value = false;
|
||||||
|
window.currentPrintData = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 取消打印机选择
|
||||||
|
function cancelPrinter() {
|
||||||
|
showPrinterDialog.value = false;
|
||||||
|
window.currentPrintData = null;
|
||||||
|
}
|
||||||
/** 重置按钮操作 */
|
/** 重置按钮操作 */
|
||||||
function resetQuery() {
|
function resetQuery() {
|
||||||
setDefaultDateRange();
|
setDefaultDateRange();
|
||||||
|
|||||||
@@ -69,7 +69,11 @@ import bindUser from "./bindUser";
|
|||||||
import { getTenantUserPage, unbindTenantUser } from "@/api/system/tenant";
|
import { getTenantUserPage, unbindTenantUser } from "@/api/system/tenant";
|
||||||
// 在 <script setup> 顶部添加导入
|
// 在 <script setup> 顶部添加导入
|
||||||
import { ref, reactive, onMounted } from "vue"; // 补充 onMounted 导入
|
import { ref, reactive, onMounted } from "vue"; // 补充 onMounted 导入
|
||||||
|
import { useRoute, useRouter } from "vue-router"; // 添加 useRouter 导入
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
const router = useRouter(); // 创建 router 实例
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
const { sys_normal_disable } = proxy.useDict("sys_normal_disable");
|
const { sys_normal_disable } = proxy.useDict("sys_normal_disable");
|
||||||
|
|
||||||
@@ -100,8 +104,14 @@ function getList() {
|
|||||||
}
|
}
|
||||||
// 返回按钮
|
// 返回按钮
|
||||||
function handleClose() {
|
function handleClose() {
|
||||||
const obj = { path: "/system/basicmanage/tenant" };
|
/* const obj = { path: "/system/basicmanage/tenant" };
|
||||||
proxy.$tab.closeOpenPage(obj);
|
proxy.$tab.closeOpenPage(obj); 目前先注释掉改成返回上一级页面*/
|
||||||
|
// 先关闭当前标签页
|
||||||
|
const obj={ path: "/system/basicmanage/tenant" };
|
||||||
|
proxy.$tab.closeOpenPage(route).then(() => {
|
||||||
|
// 然后返回上一个页面
|
||||||
|
router.go(-1);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
/** 搜索按钮操作 */
|
/** 搜索按钮操作 */
|
||||||
function handleQuery() {
|
function handleQuery() {
|
||||||
|
|||||||
@@ -614,7 +614,7 @@ const deptName = ref('');
|
|||||||
const deptOptions = ref(undefined);
|
const deptOptions = ref(undefined);
|
||||||
const wardListOptions = ref(undefined);
|
const wardListOptions = ref(undefined);
|
||||||
const locationOptions = ref([]);
|
const locationOptions = ref([]);
|
||||||
const initPassword = ref(undefined);
|
const initPassword = ref('123456');
|
||||||
const postOptions = ref([]);
|
const postOptions = ref([]);
|
||||||
const roleOptions = ref([]);
|
const roleOptions = ref([]);
|
||||||
const doctorShow = ref(true);
|
const doctorShow = ref(true);
|
||||||
@@ -904,7 +904,8 @@ function handleAdd() {
|
|||||||
locationAdminShow.value = true;
|
locationAdminShow.value = true;
|
||||||
pharmacyShow.value = true;
|
pharmacyShow.value = true;
|
||||||
title.value = '添加用户';
|
title.value = '添加用户';
|
||||||
form.value.password = initPassword.value;
|
// 强制赋值初始密码(覆盖原逻辑,确保一定生效)
|
||||||
|
form.value.password = initPassword.value; // 这里会将123456赋值给密码输入框
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/** 修改按钮操作 */
|
/** 修改按钮操作 */
|
||||||
|
|||||||
@@ -52,6 +52,11 @@ export default defineConfig (({mode, command}) => {
|
|||||||
target: 'http://localhost:5000',
|
target: 'http://localhost:5000',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: p => p.replace (/^\/ybplugin/, ''),
|
rewrite: p => p.replace (/^\/ybplugin/, ''),
|
||||||
|
},
|
||||||
|
'/prod-api': {
|
||||||
|
target: 'http://localhost:18080/openhis',
|
||||||
|
changeOrigin: true,
|
||||||
|
rewrite: p => p.replace (/^\/prod-api/, ''),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user