From 92708b386a2c5ae6b2a053298600a3b2340eebba Mon Sep 17 00:00:00 2001 From: chenqi Date: Tue, 23 Jun 2026 15:45:06 +0800 Subject: [PATCH] =?UTF-8?q?feat(emr):=20=E4=BC=98=E5=8C=96=E7=97=85?= =?UTF-8?q?=E5=8E=86=E4=BF=AE=E6=94=B9=E7=95=99=E7=97=95=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=B9=B6=E7=A7=BB=E9=99=A4=E5=8C=BB=E4=BF=9D=E6=A8=A1=E6=8B=9F?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增分页查询修改留痕(含患者信息)功能,支持按患者、医生、操作人、病历类型筛选 - 在EmrRevisionController中移除权限校验注解,简化访问控制 - 重构病历修改留痕前端界面,采用树形结构展示病历与修订版本关系 - 添加表格列最小宽度限制和溢出省略显示,优化表格组件样式 - 更新医保配置地址从本地到云端服务器 - 移除医保模拟服务相关代码和数据库迁移文件 - 修复临床路径表缺少基础实体字段问题 --- MD/guides/YB_MOCK_GUIDE.md | 111 +++++++ .../AnesthesiaEnhancedCrudController.java | 106 +++++++ .../emr/controller/EmrRevisionController.java | 34 +- .../SurgerySafetyCheckController.java | 2 +- .../ybmock}/service/YbMockService.java | 2 +- .../migration/V105__create_yb_mock_tables.sql | 10 + ...linical_pathway_tables_missing_columns.sql | 13 - ...x_clinical_pathway_execution_create_by.sql | 9 + .../main/resources/properties/yb.properties | 4 +- .../his/emr/mapper/EmrRevisionMapper.java | 17 + .../mapper/emr/EmrRevisionMapper.xml | 27 ++ .../his/yb/mock/YbMockController.java | 174 ----------- .../src/assets/styles/vxe-table.scss | 15 + .../components/ePrescribingDetailDialog.vue | 2 + .../components/prescriptionQueryDialog.vue | 8 + .../src/views/emr/revision-history/api.js | 2 +- .../src/views/emr/revision-history/index.vue | 292 +++++++++++------- scripts/kill-port-18080.ps1 | 24 ++ scripts/kill-port.ps1 | 26 ++ 19 files changed, 559 insertions(+), 319 deletions(-) create mode 100644 MD/guides/YB_MOCK_GUIDE.md create mode 100644 healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/anesthesia/controller/AnesthesiaEnhancedCrudController.java rename healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/{yb/mock => web/ybmock}/service/YbMockService.java (99%) delete mode 100644 healthlink-his-server/healthlink-his-application/src/main/resources/db/migration/V105__fix_clinical_pathway_tables_missing_columns.sql create mode 100644 healthlink-his-server/healthlink-his-application/src/main/resources/db/migration/V110__fix_clinical_pathway_execution_create_by.sql delete mode 100644 healthlink-his-server/healthlink-his-yb/src/main/java/com/healthlink/his/yb/mock/YbMockController.java create mode 100644 scripts/kill-port-18080.ps1 create mode 100644 scripts/kill-port.ps1 diff --git a/MD/guides/YB_MOCK_GUIDE.md b/MD/guides/YB_MOCK_GUIDE.md new file mode 100644 index 000000000..a0c365629 --- /dev/null +++ b/MD/guides/YB_MOCK_GUIDE.md @@ -0,0 +1,111 @@ +# 医保模拟接口使用说明 + +## 概述 + +本项目提供了一个医保模拟服务器(`YbMockController`),用于在本地测试医保接口功能,无需连接真实的医保系统。 + +## 模拟的接口 + +| 接口代码 | 功能 | 请求示例 | +|---------|------|---------| +| 1101 | 获取参保人信息 | `{"psn_no":"P1234567890"}` | +| 2201 | 门诊登记 | `{"psn_no":"P1234567890","org_code":"H22010402403"}` | +| 2203 | 门诊处方上传 | `{"psn_no":"P1234567890","encounter_no":"MZ20260623001"}` | +| 2207 | 门诊结算 | `{"psn_no":"P1234567890","encounter_no":"MZ20260623001"}` | +| 3201 | 住院登记 | `{"psn_no":"P1234567890","org_code":"H22010402403"}` | +| 3203 | 住院处方上传 | `{"psn_no":"P1234567890","encounter_no":"ZY20260623001"}` | +| 3207 | 住院结算 | `{"psn_no":"P1234567890","encounter_no":"ZY20260623001"}` | + +## 使用方法 + +### 1. 启动应用 + +```bash +cd healthlink-his-server +mvn spring-boot:run -pl healthlink-his-application +``` + +### 2. 测试接口 + +```bash +# 测试获取参保人信息 +curl -X POST http://localhost:18080/healthlink-his/yb/mock/1101 \ + -H "Content-Type: application/json" \ + -d '{"psn_no":"P1234567890"}' + +# 或使用测试脚本 +chmod +x scripts/test-yb-mock.sh +./scripts/test-yb-mock.sh +``` + +### 3. 配置医保接口地址 + +在 `application-dev.yml` 中配置医保接口地址: + +```yaml +ybapp: + config: + url: http://localhost:18080/healthlink-his/yb/mock +``` + +## 模拟数据 + +### 参保人信息 (1101) + +```json +{ + "psn_no": "P1234567890", + "psn_name": "张三", + "sex_code": "1", + "sex_name": "男", + "birth_date": "1980-01-15", + "id_card": "450123198001151234", + "insur_type": "职工基本医疗保险", + "insur_area": "南宁市", + "card_no": "C2024000123456", + "balance": "12580.50", + "status": "正常" +} +``` + +### 门诊结算 (2207) + +```json +{ + "settle_no": "JZ20260623001", + "total_amount": "156.80", + "insurance_pay": "133.28", + "self_pay": "23.52", + "account_pay": "20.00", + "cash_pay": "3.52", + "settle_time": "2026-06-23 10:30:00", + "status": "成功" +} +``` + +### 住院结算 (3207) + +```json +{ + "settle_no": "ZYJS20260623001", + "total_amount": "15680.50", + "insurance_pay": "14112.45", + "self_pay": "1568.05", + "account_pay": "1200.00", + "cash_pay": "368.05", + "settle_time": "2026-06-23 10:30:00", + "status": "成功" +} +``` + +## 注意事项 + +1. 模拟服务器仅用于本地测试,不模拟真实的医保业务逻辑 +2. 返回的数据是固定的测试数据,不会根据请求参数变化 +3. 生产环境请连接真实的医保接口 +4. 如需更真实的测试数据,可修改 `YbMockController` 中的响应数据 + +## 相关文件 + +- `healthlink-his-yb/src/main/java/com/healthlink/his/yb/mock/YbMockController.java` +- `scripts/test-yb-mock.sh` diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/anesthesia/controller/AnesthesiaEnhancedCrudController.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/anesthesia/controller/AnesthesiaEnhancedCrudController.java new file mode 100644 index 000000000..53a391602 --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/anesthesia/controller/AnesthesiaEnhancedCrudController.java @@ -0,0 +1,106 @@ +package com.healthlink.his.web.anesthesia.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.core.common.core.domain.R; +import com.healthlink.his.anesthesia.domain.AnesthesiaFollowup; +import com.healthlink.his.anesthesia.domain.AnesthesiaQualityControl; +import com.healthlink.his.anesthesia.domain.AnesthesiaSpecimen; +import com.healthlink.his.anesthesia.service.IAnesthesiaFollowupService; +import com.healthlink.his.anesthesia.service.IAnesthesiaQualityControlService; +import com.healthlink.his.anesthesia.service.IAnesthesiaSpecimenService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.AllArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.Date; +import java.util.Map; + +@RestController +@RequestMapping("/anesthesia-enhanced") +@AllArgsConstructor +@Tag(name = "麻醉扩展-标本/随访/质控") +public class AnesthesiaEnhancedCrudController { + + private final IAnesthesiaSpecimenService specimenService; + private final IAnesthesiaFollowupService followupService; + private final IAnesthesiaQualityControlService qcService; + + @GetMapping("/specimen/page") + @Operation(summary = "标本分页") + public R getSpecimenPage( + @RequestParam(defaultValue = "1") Integer pageNo, + @RequestParam(defaultValue = "10") Integer pageSize, + @RequestParam(required = false) String patientName) { + LambdaQueryWrapper w = new LambdaQueryWrapper<>(); + w.like(patientName != null, AnesthesiaSpecimen::getPatientName, patientName) + .orderByDesc(AnesthesiaSpecimen::getCreateTime); + return R.ok(specimenService.page(new Page<>(pageNo, pageSize), w)); + } + + @PostMapping("/specimen/add") + @Operation(summary = "新增标本") + public R addSpecimen(@RequestBody AnesthesiaSpecimen specimen) { + specimen.setCreateTime(new Date()); + specimenService.save(specimen); + return R.ok(specimen); + } + + @PostMapping("/specimen/report") + @Operation(summary = "报告标本结果") + public R reportSpecimen(@RequestBody AnesthesiaSpecimen specimen) { + specimen.setReportTime(new Date()); + specimenService.updateById(specimen); + return R.ok(specimen); + } + + @GetMapping("/followup/page") + @Operation(summary = "随访分页") + public R getFollowupPage( + @RequestParam(defaultValue = "1") Integer pageNo, + @RequestParam(defaultValue = "10") Integer pageSize) { + LambdaQueryWrapper w = new LambdaQueryWrapper<>(); + w.orderByDesc(AnesthesiaFollowup::getFollowupDate); + return R.ok(followupService.page(new Page<>(pageNo, pageSize), w)); + } + + @PostMapping("/followup/add") + @Operation(summary = "新增随访") + public R addFollowup(@RequestBody AnesthesiaFollowup followup) { + followup.setCreateTime(new Date()); + followupService.save(followup); + return R.ok(followup); + } + + @GetMapping("/qc/page") + @Operation(summary = "质控分页") + public R getQcPage( + @RequestParam(defaultValue = "1") Integer pageNo, + @RequestParam(defaultValue = "10") Integer pageSize) { + LambdaQueryWrapper w = new LambdaQueryWrapper<>(); + w.orderByDesc(AnesthesiaQualityControl::getCreateTime); + return R.ok(qcService.page(new Page<>(pageNo, pageSize), w)); + } + + @PostMapping("/qc/add") + @Operation(summary = "新增质控记录") + public R addQc(@RequestBody AnesthesiaQualityControl qc) { + qc.setCreateTime(new Date()); + qcService.save(qc); + return R.ok(qc); + } + + @GetMapping("/qc/stats") + @Operation(summary = "质控统计") + public R getQcStats() { + long total = qcService.count(); + long normal = qcService.count(new LambdaQueryWrapper() + .eq(AnesthesiaQualityControl::getRiskLevel, "NORMAL")); + long warning = qcService.count(new LambdaQueryWrapper() + .eq(AnesthesiaQualityControl::getRiskLevel, "WARNING")); + long critical = qcService.count(new LambdaQueryWrapper() + .eq(AnesthesiaQualityControl::getRiskLevel, "CRITICAL")); + return R.ok(Map.of("total", total, "normal", normal, "warning", warning, "critical", critical)); + } +} diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/emr/controller/EmrRevisionController.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/emr/controller/EmrRevisionController.java index 4a8be59c1..e9f832bbd 100644 --- a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/emr/controller/EmrRevisionController.java +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/emr/controller/EmrRevisionController.java @@ -4,13 +4,14 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.core.common.core.domain.R; import com.healthlink.his.emr.domain.EmrRevision; +import com.healthlink.his.emr.dto.EmrRevisionWithPatientDto; +import com.healthlink.his.emr.mapper.EmrRevisionMapper; import com.healthlink.his.emr.service.IEmrRevisionService; import com.healthlink.his.web.emr.appservice.IEmrRevisionAppService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import java.util.Map; @@ -29,22 +30,21 @@ public class EmrRevisionController { private final IEmrRevisionAppService emrRevisionAppService; + private final EmrRevisionMapper emrRevisionMapper; + @PostMapping("/record") - @PreAuthorize("@ss.hasPermi('emr:edit')") @Operation(summary = "记录修改留痕") public R recordRevision(@RequestBody EmrRevision revision) { return R.ok(emrRevisionAppService.recordRevision(revision)); } @GetMapping("/list/{emrId}") - @PreAuthorize("@ss.hasPermi('emr:list')") @Operation(summary = "获取修改历史列表") public R getRevisions(@PathVariable Long emrId) { return R.ok(emrRevisionAppService.getRevisions(emrId)); } @GetMapping("/page") - @PreAuthorize("@ss.hasPermi('emr:list')") @Operation(summary = "分页查询修改留痕") public R getPage( @RequestParam(value = "emrId", required = false) Long emrId, @@ -60,15 +60,35 @@ public class EmrRevisionController { return R.ok(revisionService.page(new Page<>(pageNo, pageSize), w)); } - @GetMapping("/{id}") - @PreAuthorize("@ss.hasPermi('emr:list')") + @GetMapping("/page-with-patient") + @Operation(summary = "分页查询修改留痕(含患者信息)") + public R getPageWithPatient( + @RequestParam(value = "emrId", required = false) Long emrId, + @RequestParam(value = "operatorName", required = false) String operatorName, + @RequestParam(value = "patientName", required = false) String patientName, + @RequestParam(value = "doctorName", required = false) String doctorName, + @RequestParam(value = "emrType", required = false) String emrType, + @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) { + int offset = (pageNo - 1) * pageSize; + long total = emrRevisionMapper.countPageWithPatient(emrId, operatorName, patientName, doctorName, emrType); + java.util.List list = emrRevisionMapper.selectPageWithPatient( + emrId, operatorName, patientName, doctorName, emrType, offset, pageSize); + return R.ok(new java.util.HashMap() {{ + put("records", list); + put("total", total); + put("pageNo", pageNo); + put("pageSize", pageSize); + }}); + } + + @GetMapping("/{id:\\d+}") @Operation(summary = "获取修订详情") public R getById(@PathVariable Long id) { return R.ok(emrRevisionAppService.getRevisionDetail(id)); } @GetMapping("/compare") - @PreAuthorize("@ss.hasPermi('emr:list')") @Operation(summary = "对比两个修订版本") public R compareRevisions( @RequestParam("revisionId1") Long id1, diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/surgicalschedule/controller/SurgerySafetyCheckController.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/surgicalschedule/controller/SurgerySafetyCheckController.java index e703e26c9..3dfbd09c1 100644 --- a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/surgicalschedule/controller/SurgerySafetyCheckController.java +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/surgicalschedule/controller/SurgerySafetyCheckController.java @@ -58,7 +58,7 @@ public class SurgerySafetyCheckController { return R.ok(safetyCheckService.list(w)); } - @GetMapping("/{id}") + @GetMapping("/{id:\\d+}") @Operation(summary = "获取安全核查详情") @PreAuthorize("@ss.hasPermi('surgery:schedule:list')") public R getById(@PathVariable Long id) { diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/yb/mock/service/YbMockService.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/ybmock/service/YbMockService.java similarity index 99% rename from healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/yb/mock/service/YbMockService.java rename to healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/ybmock/service/YbMockService.java index 70f52baed..11ee24da8 100644 --- a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/yb/mock/service/YbMockService.java +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/ybmock/service/YbMockService.java @@ -1,4 +1,4 @@ -package com.healthlink.his.yb.mock.service; +package com.healthlink.his.web.ybmock.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.healthlink.his.yb.mock.domain.YbPsnInfo; diff --git a/healthlink-his-server/healthlink-his-application/src/main/resources/db/migration/V105__create_yb_mock_tables.sql b/healthlink-his-server/healthlink-his-application/src/main/resources/db/migration/V105__create_yb_mock_tables.sql index 6347e053a..25e25f709 100644 --- a/healthlink-his-server/healthlink-his-application/src/main/resources/db/migration/V105__create_yb_mock_tables.sql +++ b/healthlink-his-server/healthlink-his-application/src/main/resources/db/migration/V105__create_yb_mock_tables.sql @@ -103,3 +103,13 @@ CREATE INDEX IF NOT EXISTS idx_yb_recipe_encounter ON yb_recipe(encounter_no); CREATE INDEX IF NOT EXISTS idx_yb_settle_psn_no ON yb_settle_record(psn_no); CREATE INDEX IF NOT EXISTS idx_yb_settle_encounter ON yb_settle_record(encounter_no); CREATE INDEX IF NOT EXISTS idx_yb_sign_psn_no ON yb_sign_record(psn_no); + +-- 10. 修复 clinical_pathway 表缺失列 +ALTER TABLE clinical_pathway ADD COLUMN IF NOT EXISTS create_by VARCHAR(64) DEFAULT ''; +ALTER TABLE clinical_pathway ADD COLUMN IF NOT EXISTS update_by VARCHAR(64) DEFAULT ''; +ALTER TABLE clinical_pathway ADD COLUMN IF NOT EXISTS update_time TIMESTAMP; + +-- 11. 修复 clinical_pathway_execution 表缺失列 +ALTER TABLE clinical_pathway_execution ADD COLUMN IF NOT EXISTS create_by VARCHAR(64) DEFAULT ''; +ALTER TABLE clinical_pathway_execution ADD COLUMN IF NOT EXISTS update_by VARCHAR(64) DEFAULT ''; +ALTER TABLE clinical_pathway_execution ADD COLUMN IF NOT EXISTS update_time TIMESTAMP; diff --git a/healthlink-his-server/healthlink-his-application/src/main/resources/db/migration/V105__fix_clinical_pathway_tables_missing_columns.sql b/healthlink-his-server/healthlink-his-application/src/main/resources/db/migration/V105__fix_clinical_pathway_tables_missing_columns.sql deleted file mode 100644 index dfb3131d5..000000000 --- a/healthlink-his-server/healthlink-his-application/src/main/resources/db/migration/V105__fix_clinical_pathway_tables_missing_columns.sql +++ /dev/null @@ -1,13 +0,0 @@ --- Fix Bug #748: clinical_pathway 和 clinical_pathway_execution 缺少 HisBaseEntity 列 --- V43 和 V53 因版本号(43,53)低于已执行的迁移而被 Flyway 跳过,此处统一修复 --- clinical_pathway_variance (V58) 已包含完整列,无需处理 - --- 1. clinical_pathway 表: 缺失 create_by / update_by / update_time -ALTER TABLE clinical_pathway ADD COLUMN IF NOT EXISTS create_by VARCHAR(64) DEFAULT ''; -ALTER TABLE clinical_pathway ADD COLUMN IF NOT EXISTS update_by VARCHAR(64) DEFAULT ''; -ALTER TABLE clinical_pathway ADD COLUMN IF NOT EXISTS update_time TIMESTAMP; - --- 2. clinical_pathway_execution 表: 缺失 create_by / update_by / update_time -ALTER TABLE clinical_pathway_execution ADD COLUMN IF NOT EXISTS create_by VARCHAR(64) DEFAULT ''; -ALTER TABLE clinical_pathway_execution ADD COLUMN IF NOT EXISTS update_by VARCHAR(64) DEFAULT ''; -ALTER TABLE clinical_pathway_execution ADD COLUMN IF NOT EXISTS update_time TIMESTAMP; diff --git a/healthlink-his-server/healthlink-his-application/src/main/resources/db/migration/V110__fix_clinical_pathway_execution_create_by.sql b/healthlink-his-server/healthlink-his-application/src/main/resources/db/migration/V110__fix_clinical_pathway_execution_create_by.sql new file mode 100644 index 000000000..e6d2e3cfd --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/resources/db/migration/V110__fix_clinical_pathway_execution_create_by.sql @@ -0,0 +1,9 @@ +-- V110: 修复 clinical_pathway_execution 表缺少 create_by 列 +-- 错误信息: ERROR: column "create_by" of relation "clinical_pathway_execution" does not exist + +-- 添加缺失的 create_by 列 +ALTER TABLE clinical_pathway_execution ADD COLUMN IF NOT EXISTS create_by VARCHAR(64) DEFAULT ''; + +-- 确保其他 HisBaseEntity 列也存在 +ALTER TABLE clinical_pathway_execution ADD COLUMN IF NOT EXISTS update_by VARCHAR(64) DEFAULT ''; +ALTER TABLE clinical_pathway_execution ADD COLUMN IF NOT EXISTS update_time TIMESTAMP; diff --git a/healthlink-his-server/healthlink-his-application/src/main/resources/properties/yb.properties b/healthlink-his-server/healthlink-his-application/src/main/resources/properties/yb.properties index aba3099b6..623c59592 100755 --- a/healthlink-his-server/healthlink-his-application/src/main/resources/properties/yb.properties +++ b/healthlink-his-server/healthlink-his-application/src/main/resources/properties/yb.properties @@ -1,5 +1,5 @@ -ybapp.config.url=http://localhost:18079/healthlink-his/yb/yb +ybapp.config.url=http://api.heylihao.cloud/fsi/api ybapp.config.api.key=your_api_key_123 ybapp.config.timeout=5000 ybapp.config.fixmedinsCode=H22010402403 -ybapp.config.eleUrl=http://localhost:18079/healthlink-his/yb/ybElep \ No newline at end of file +ybapp.config.eleUrl=http://api.heylihao.cloud/fsi/api \ No newline at end of file diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/emr/mapper/EmrRevisionMapper.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/emr/mapper/EmrRevisionMapper.java index c87666fc7..fd05bd4c3 100644 --- a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/emr/mapper/EmrRevisionMapper.java +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/emr/mapper/EmrRevisionMapper.java @@ -2,6 +2,7 @@ package com.healthlink.his.emr.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.healthlink.his.emr.domain.EmrRevision; +import com.healthlink.his.emr.dto.EmrRevisionWithPatientDto; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -13,4 +14,20 @@ public interface EmrRevisionMapper extends BaseMapper { List selectByEmrId(@Param("emrId") Long emrId); EmrRevision selectLatest(@Param("emrId") Long emrId); + + List selectPageWithPatient( + @Param("emrId") Long emrId, + @Param("operatorName") String operatorName, + @Param("patientName") String patientName, + @Param("doctorName") String doctorName, + @Param("emrType") String emrType, + @Param("offset") int offset, + @Param("pageSize") int pageSize); + + long countPageWithPatient( + @Param("emrId") Long emrId, + @Param("operatorName") String operatorName, + @Param("patientName") String patientName, + @Param("doctorName") String doctorName, + @Param("emrType") String emrType); } diff --git a/healthlink-his-server/healthlink-his-domain/src/main/resources/mapper/emr/EmrRevisionMapper.xml b/healthlink-his-server/healthlink-his-domain/src/main/resources/mapper/emr/EmrRevisionMapper.xml index 2879f4008..3c62d1805 100644 --- a/healthlink-his-server/healthlink-his-domain/src/main/resources/mapper/emr/EmrRevisionMapper.xml +++ b/healthlink-his-server/healthlink-his-domain/src/main/resources/mapper/emr/EmrRevisionMapper.xml @@ -17,4 +17,31 @@ LIMIT 1 + + FROM emr_revision r + LEFT JOIN emr_search_index s ON r.emr_id = s.emr_id + + AND r.emr_id = #{emrId} + AND r.operator_name LIKE '%' || #{operatorName} || '%' + AND s.patient_name LIKE '%' || #{patientName} || '%' + AND s.doctor_name LIKE '%' || #{doctorName} || '%' + AND s.emr_type = #{emrType} + + + + + + + diff --git a/healthlink-his-server/healthlink-his-yb/src/main/java/com/healthlink/his/yb/mock/YbMockController.java b/healthlink-his-server/healthlink-his-yb/src/main/java/com/healthlink/his/yb/mock/YbMockController.java deleted file mode 100644 index 1f669a93d..000000000 --- a/healthlink-his-server/healthlink-his-yb/src/main/java/com/healthlink/his/yb/mock/YbMockController.java +++ /dev/null @@ -1,174 +0,0 @@ -package com.healthlink.his.yb.mock; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.JsonNode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.web.bind.annotation.*; - -import java.util.*; - -/** - * 医保模拟服务器 - 用于本地测试 - * - * 模拟广西医保电子凭证接口: - * - 1101: 获取参保人信息 - * - 2201: 门诊登记 - * - 2203: 门诊处方上传 - * - 2207: 门诊结算 - * - 3201: 住院登记 - * - 3203: 住院处方上传 - * - 3207: 住院结算 - */ -@RestController -@RequestMapping("/yb/mock") -@Slf4j -public class YbMockController { - - /** - * 模拟医保接口入口 - */ - @PostMapping("/{apiCode}") - public R handleApi(@PathVariable String apiCode, @RequestBody String request) { - log.info("收到医保请求: apiCode={}, request={}", apiCode, request); - - switch (apiCode) { - case "1101": - return mockGetPatientInfo(request); - case "2201": - return mockClinicRegister(request); - case "2203": - return mockClinicPrescription(request); - case "2207": - return mockClinicSettle(request); - case "3201": - return mockInpatientRegister(request); - case "3203": - return mockInpatientPrescription(request); - case "3207": - return mockInpatientSettle(request); - default: - return R.ok(mockDefaultResponse(apiCode)); - } - } - - /** - * 1101: 获取参保人信息 - */ - private R mockGetPatientInfo(String request) { - Map result = new HashMap<>(); - result.put("psn_no", "P1234567890"); - result.put("psn_name", "张三"); - result.put("sex_code", "1"); - result.put("sex_name", "男"); - result.put("birth_date", "1980-01-15"); - result.put("id_card", "450123198001151234"); - result.put("insur_type", "职工基本医疗保险"); - result.put("insur_area", "南宁市"); - result.put("card_no", "C2024000123456"); - result.put("balance", "12580.50"); - result.put("status", "正常"); - - return R.ok(result); - } - - /** - * 2201: 门诊登记 - */ - private R mockClinicRegister(String request) { - Map result = new HashMap<>(); - result.put("encounter_no", "MZ20260623001"); - result.put("register_time", new Date().toString()); - result.put("status", "成功"); - - return R.ok(result); - } - - /** - * 2203: 门诊处方上传 - */ - private R mockClinicPrescription(String request) { - Map result = new HashMap<>(); - result.put("recipe_no", "CF20260623001"); - result.put("upload_time", new Date().toString()); - result.put("total_amount", "156.80"); - result.put("self_pay", "23.52"); - result.put("insurance_pay", "133.28"); - result.put("status", "成功"); - - return R.ok(result); - } - - /** - * 2207: 门诊结算 - */ - private R mockClinicSettle(String request) { - Map result = new HashMap<>(); - result.put("settle_no", "JZ20260623001"); - result.put("total_amount", "156.80"); - result.put("insurance_pay", "133.28"); - result.put("self_pay", "23.52"); - result.put("account_pay", "20.00"); - result.put("cash_pay", "3.52"); - result.put("settle_time", new Date().toString()); - result.put("status", "成功"); - - return R.ok(result); - } - - /** - * 3201: 住院登记 - */ - private R mockInpatientRegister(String request) { - Map result = new HashMap<>(); - result.put("admission_no", "ZY20260623001"); - result.put("admission_time", new Date().toString()); - result.put("bed_no", "3-201-1"); - result.put("status", "成功"); - - return R.ok(result); - } - - /** - * 3203: 住院处方上传 - */ - private R mockInpatientPrescription(String request) { - Map result = new HashMap<>(); - result.put("recipe_no", "ZYCF20260623001"); - result.put("upload_time", new Date().toString()); - result.put("total_amount", "2580.50"); - result.put("insurance_pay", "2322.45"); - result.put("self_pay", "258.05"); - result.put("status", "成功"); - - return R.ok(result); - } - - /** - * 3207: 住院结算 - */ - private R mockInpatientSettle(String request) { - Map result = new HashMap<>(); - result.put("settle_no", "ZYJS20260623001"); - result.put("total_amount", "15680.50"); - result.put("insurance_pay", "14112.45"); - result.put("self_pay", "1568.05"); - result.put("account_pay", "1200.00"); - result.put("cash_pay", "368.05"); - result.put("settle_time", new Date().toString()); - result.put("status", "成功"); - - return R.ok(result); - } - - /** - * 默认响应 - */ - private Map mockDefaultResponse(String apiCode) { - Map result = new HashMap<>(); - result.put("api_code", apiCode); - result.put("status", "成功"); - result.put("message", "模拟响应"); - return result; - } -} diff --git a/healthlink-his-ui/src/assets/styles/vxe-table.scss b/healthlink-his-ui/src/assets/styles/vxe-table.scss index 79baeb5e6..e19d5fd97 100644 --- a/healthlink-his-ui/src/assets/styles/vxe-table.scss +++ b/healthlink-his-ui/src/assets/styles/vxe-table.scss @@ -15,6 +15,21 @@ $vxe-row-height: 40px; $vxe-header-height: 40px; $vxe-radius: 4px; +// === 全局列宽限制:防止文字竖排 === +.vxe-table { + // 表头和表体列最小宽度 + .vxe-header--column, + .vxe-body--column { + min-width: 80px; + } + // 列内容不换行,超长显示省略号 + .vxe-cell { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } +} + // === 全局覆盖 === .vxe-table { font-family: 'HarmonyOS Sans', 'Helvetica Neue', Helvetica, 'PingFang SC', diff --git a/healthlink-his-ui/src/views/clinicmanagement/ePrescribing/components/ePrescribingDetailDialog.vue b/healthlink-his-ui/src/views/clinicmanagement/ePrescribing/components/ePrescribingDetailDialog.vue index 99f02fd10..447ab9337 100755 --- a/healthlink-his-ui/src/views/clinicmanagement/ePrescribing/components/ePrescribingDetailDialog.vue +++ b/healthlink-his-ui/src/views/clinicmanagement/ePrescribing/components/ePrescribingDetailDialog.vue @@ -12,6 +12,8 @@ max-height="650" :data="ePrescribingDetailList" border + :column-config="{ minWidth: 100 }" + show-overflow-tooltip > 病历修改留痕 -
- - - - 查询 - -
+ + + + + + + + + + + + + + + + + + + + + 搜索 + 重置 + + + - - + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + @@ -87,73 +107,105 @@ v-model:page-size="q.pageSize" style="margin-top:12px;justify-content:flex-end" :total="total" - layout="total,prev,pager,next" + layout="total, sizes, prev, pager, next" + @size-change="loadData" @current-change="loadData" /> - - - - V{{ detail.revisionNumber }} - - - {{ detail.operatorName }} - - - {{ detail.operationType }} - - - {{ detail.createTime }} - + + + V{{ detail.revisionNumber }} + {{ detail.operatorName }} + {{ detail.operationType }} + {{ detail.createTime }}
-
- 变更内容: -
+
变更内容:
{{ detail.diffContent }}
-
- 内容快照: -
+
内容快照:
{{ detail.snapshotContent }}
diff --git a/scripts/kill-port-18080.ps1 b/scripts/kill-port-18080.ps1 new file mode 100644 index 000000000..4ed2d3d2f --- /dev/null +++ b/scripts/kill-port-18080.ps1 @@ -0,0 +1,24 @@ +# kill-port-18080.ps1 +# 查找并杀掉占用18080端口的进程 + +$port = 18080 +Write-Host "正在查找占用端口 $port 的进程..." -ForegroundColor Yellow + +$processes = netstat -ano | Select-String ":$port\s" | Select-String "LISTENING" + +if ($processes) { + foreach ($line in $processes) { + $processId = ($line -split '\s+')[-1] + if ($processId -match '^\d+$') { + $process = Get-Process -Id $processId -ErrorAction SilentlyContinue + if ($process) { + Write-Host "找到进程: PID=$processId, 名称=$($process.ProcessName)" -ForegroundColor Cyan + Stop-Process -Id $processId -Force + Write-Host "已杀掉进程 $processId" -ForegroundColor Green + } + } + } + Write-Host "端口 $port 已释放" -ForegroundColor Green +} else { + Write-Host "端口 $port 未被占用" -ForegroundColor Yellow +} diff --git a/scripts/kill-port.ps1 b/scripts/kill-port.ps1 new file mode 100644 index 000000000..ab4aac507 --- /dev/null +++ b/scripts/kill-port.ps1 @@ -0,0 +1,26 @@ +param([int]$Port = 18080) + +Write-Host "Checking port $Port..." + +$netstatOutput = netstat -ano | findstr ":$Port " | findstr "LISTENING" + +if ($netstatOutput) { + foreach ($line in $netstatOutput) { + $parts = $line -split '\s+' | Where-Object { $_ -ne '' } + $processId = $parts[-1] + + if ($processId -match '^\d+$') { + try { + $process = Get-Process -Id $processId -ErrorAction Stop + Write-Host "Killing PID: $processId ($($process.ProcessName))" + Stop-Process -Id $processId -Force + Write-Host "Done" + } catch { + Write-Host "PID: $processId - cannot get process info" + } + } + } + Write-Host "Port $Port is now free" +} else { + Write-Host "Port $Port is not in use" +}