From f3aac08c4e3139505084e9de26a98f7bc5480f04 Mon Sep 17 00:00:00 2001 From: chenqi Date: Thu, 18 Jun 2026 15:56:12 +0800 Subject: [PATCH] feat(ehcard): add electronic health card module (T13.3) --- .../ehcard/appservice/IEhcardAppService.java | 11 ++ .../appservice/impl/EhcardAppServiceImpl.java | 99 +++++++++++ .../ehcard/controller/EhcardController.java | 53 ++++++ .../resources/db/migration/V68__ehcard.sql | 42 +++++ .../his/ehcard/domain/EhcardCard.java | 39 +++++ .../his/ehcard/domain/EhcardUsageLog.java | 30 ++++ .../his/ehcard/mapper/EhcardCardMapper.java | 9 + .../ehcard/mapper/EhcardUsageLogMapper.java | 9 + .../ehcard/service/IEhcardCardService.java | 7 + .../service/IEhcardUsageLogService.java | 7 + .../service/impl/EhcardCardServiceImpl.java | 11 ++ .../impl/EhcardUsageLogServiceImpl.java | 11 ++ .../src/views/ehcard/EhcardManagement.vue | 160 ++++++++++++++++++ healthlink-his-ui/src/views/ehcard/api.js | 17 ++ 14 files changed, 505 insertions(+) create mode 100644 healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/ehcard/appservice/IEhcardAppService.java create mode 100644 healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/ehcard/appservice/impl/EhcardAppServiceImpl.java create mode 100644 healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/ehcard/controller/EhcardController.java create mode 100644 healthlink-his-server/healthlink-his-application/src/main/resources/db/migration/V68__ehcard.sql create mode 100644 healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/domain/EhcardCard.java create mode 100644 healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/domain/EhcardUsageLog.java create mode 100644 healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/mapper/EhcardCardMapper.java create mode 100644 healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/mapper/EhcardUsageLogMapper.java create mode 100644 healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/service/IEhcardCardService.java create mode 100644 healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/service/IEhcardUsageLogService.java create mode 100644 healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/service/impl/EhcardCardServiceImpl.java create mode 100644 healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/service/impl/EhcardUsageLogServiceImpl.java create mode 100644 healthlink-his-ui/src/views/ehcard/EhcardManagement.vue create mode 100644 healthlink-his-ui/src/views/ehcard/api.js diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/ehcard/appservice/IEhcardAppService.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/ehcard/appservice/IEhcardAppService.java new file mode 100644 index 000000000..dda588c4c --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/ehcard/appservice/IEhcardAppService.java @@ -0,0 +1,11 @@ +package com.healthlink.his.web.ehcard.appservice; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.healthlink.his.ehcard.domain.EhcardCard; + +public interface IEhcardAppService { + void apply(EhcardCard card); + IPage page(String status, String patientName, Integer pageNum, Integer pageSize); + void lock(Long id, String reason); + void unlock(Long id); +} diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/ehcard/appservice/impl/EhcardAppServiceImpl.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/ehcard/appservice/impl/EhcardAppServiceImpl.java new file mode 100644 index 000000000..ab540d12b --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/ehcard/appservice/impl/EhcardAppServiceImpl.java @@ -0,0 +1,99 @@ +package com.healthlink.his.web.ehcard.appservice.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.healthlink.his.ehcard.domain.EhcardCard; +import com.healthlink.his.ehcard.domain.EhcardUsageLog; +import com.healthlink.his.ehcard.service.IEhcardCardService; +import com.healthlink.his.ehcard.service.IEhcardUsageLogService; +import com.healthlink.his.web.ehcard.appservice.IEhcardAppService; +import com.core.common.utils.SecurityUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.util.Date; +import java.util.UUID; + +@Service +public class EhcardAppServiceImpl implements IEhcardAppService { + + @Autowired + private IEhcardCardService cardService; + + @Autowired + private IEhcardUsageLogService usageLogService; + + @Override + public void apply(EhcardCard card) { + card.setCardNo("EHC" + System.currentTimeMillis()); + card.setCardType("HEALTH"); + card.setStatus("ACTIVE"); + card.setApplyTime(new Date()); + cardService.save(card); + + EhcardUsageLog log = new EhcardUsageLog(); + log.setCardId(card.getId()); + log.setPatientId(card.getPatientId()); + log.setUsageType("APPLY"); + log.setUsageDesc("申请电子健康卡"); + log.setOperatorName(SecurityUtils.getUsername()); + log.setUsageTime(new Date()); + usageLogService.save(log); + } + + @Override + public IPage page(String status, String patientName, Integer pageNum, Integer pageSize) { + LambdaQueryWrapper w = new LambdaQueryWrapper<>(); + if (StringUtils.hasText(status)) { + w.eq(EhcardCard::getStatus, status); + } + if (StringUtils.hasText(patientName)) { + w.like(EhcardCard::getPatientName, patientName); + } + w.orderByDesc(EhcardCard::getCreateTime); + return cardService.page(new Page<>(pageNum, pageSize), w); + } + + @Override + public void lock(Long id, String reason) { + EhcardCard card = cardService.getById(id); + if (card == null) { + throw new RuntimeException("电子健康卡不存在"); + } + card.setStatus("LOCKED"); + card.setLockTime(new Date()); + card.setLockReason(reason); + cardService.updateById(card); + + EhcardUsageLog log = new EhcardUsageLog(); + log.setCardId(id); + log.setPatientId(card.getPatientId()); + log.setUsageType("LOCK"); + log.setUsageDesc("锁定: " + reason); + log.setOperatorName(SecurityUtils.getUsername()); + log.setUsageTime(new Date()); + usageLogService.save(log); + } + + @Override + public void unlock(Long id) { + EhcardCard card = cardService.getById(id); + if (card == null) { + throw new RuntimeException("电子健康卡不存在"); + } + card.setStatus("ACTIVE"); + card.setUnlockTime(new Date()); + cardService.updateById(card); + + EhcardUsageLog log = new EhcardUsageLog(); + log.setCardId(id); + log.setPatientId(card.getPatientId()); + log.setUsageType("UNLOCK"); + log.setUsageDesc("解锁"); + log.setOperatorName(SecurityUtils.getUsername()); + log.setUsageTime(new Date()); + usageLogService.save(log); + } +} diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/ehcard/controller/EhcardController.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/ehcard/controller/EhcardController.java new file mode 100644 index 000000000..65650ea13 --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/ehcard/controller/EhcardController.java @@ -0,0 +1,53 @@ +package com.healthlink.his.web.ehcard.controller; + +import com.core.common.core.domain.AjaxResult; +import com.healthlink.his.ehcard.domain.EhcardCard; +import com.healthlink.his.web.ehcard.appservice.IEhcardAppService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +@Tag(name = "电子健康卡管理") +@RestController +@RequestMapping("/api/v1/ehcard") +public class EhcardController { + + @Autowired + private IEhcardAppService ehcardAppService; + + @Operation(summary = "申请电子健康卡") + @PreAuthorize("@ss.hasPermi('basicmanage:ehcard:edit')") + @PostMapping("/apply") + public AjaxResult apply(@RequestBody EhcardCard card) { + ehcardAppService.apply(card); + return AjaxResult.success(); + } + + @Operation(summary = "电子健康卡分页") + @PreAuthorize("@ss.hasPermi('basicmanage:ehcard:list')") + @GetMapping("/page") + public AjaxResult page(@RequestParam(required = false) String status, + @RequestParam(required = false) String patientName, + @RequestParam(defaultValue = "1") Integer pageNum, + @RequestParam(defaultValue = "10") Integer pageSize) { + return AjaxResult.success(ehcardAppService.page(status, patientName, pageNum, pageSize)); + } + + @Operation(summary = "锁定电子健康卡") + @PreAuthorize("@ss.hasPermi('basicmanage:ehcard:edit')") + @PostMapping("/lock") + public AjaxResult lock(@RequestParam Long id, @RequestParam(required = false) String reason) { + ehcardAppService.lock(id, reason); + return AjaxResult.success(); + } + + @Operation(summary = "解锁电子健康卡") + @PreAuthorize("@ss.hasPermi('basicmanage:ehcard:edit')") + @PostMapping("/unlock") + public AjaxResult unlock(@RequestParam Long id) { + ehcardAppService.unlock(id); + return AjaxResult.success(); + } +} diff --git a/healthlink-his-server/healthlink-his-application/src/main/resources/db/migration/V68__ehcard.sql b/healthlink-his-server/healthlink-his-application/src/main/resources/db/migration/V68__ehcard.sql new file mode 100644 index 000000000..8ae307c2b --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/resources/db/migration/V68__ehcard.sql @@ -0,0 +1,42 @@ +CREATE TABLE IF NOT EXISTS ehcard_card ( + id BIGINT PRIMARY KEY, + patient_id BIGINT NOT NULL, + patient_name VARCHAR(64), + id_card VARCHAR(32), + phone VARCHAR(20), + card_no VARCHAR(64) NOT NULL, + card_type VARCHAR(20) NOT NULL DEFAULT 'HEALTH', + status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE', + qr_code TEXT, + apply_time TIMESTAMP, + lock_time TIMESTAMP, + unlock_time TIMESTAMP, + lock_reason VARCHAR(256), + create_by VARCHAR(64), + create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + update_by VARCHAR(64), + update_time TIMESTAMP, + tenant_id INT DEFAULT 1, + delete_flag VARCHAR(1) DEFAULT '0' +); + +CREATE TABLE IF NOT EXISTS ehcard_usage_log ( + id BIGINT PRIMARY KEY, + card_id BIGINT NOT NULL, + patient_id BIGINT, + usage_type VARCHAR(32) NOT NULL, + usage_desc VARCHAR(256), + operator_name VARCHAR(64), + usage_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + create_by VARCHAR(64), + create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + update_by VARCHAR(64), + update_time TIMESTAMP, + tenant_id INT DEFAULT 1, + delete_flag VARCHAR(1) DEFAULT '0' +); + +CREATE INDEX idx_ehcard_card_patient ON ehcard_card(patient_id); +CREATE INDEX idx_ehcard_card_no ON ehcard_card(card_no); +CREATE INDEX idx_ehcard_card_status ON ehcard_card(status); +CREATE INDEX idx_ehcard_log_card ON ehcard_usage_log(card_id); diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/domain/EhcardCard.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/domain/EhcardCard.java new file mode 100644 index 000000000..113f818d0 --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/domain/EhcardCard.java @@ -0,0 +1,39 @@ +package com.healthlink.his.ehcard.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.core.common.core.domain.HisBaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import lombok.EqualsAndHashCode; +import tools.jackson.databind.annotation.JsonSerialize; +import tools.jackson.databind.ser.std.ToStringSerializer; + +import java.util.Date; + +@Data +@TableName("ehcard_card") +@EqualsAndHashCode(callSuper = true) +public class EhcardCard extends HisBaseEntity { + @TableId(value = "id", type = IdType.ASSIGN_ID) + @JsonSerialize(using = ToStringSerializer.class) + private Long id; + + @JsonSerialize(using = ToStringSerializer.class) + private Long patientId; + private String patientName; + private String idCard; + private String phone; + private String cardNo; + private String cardType; + private String status; + private String qrCode; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date applyTime; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date lockTime; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date unlockTime; + private String lockReason; +} diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/domain/EhcardUsageLog.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/domain/EhcardUsageLog.java new file mode 100644 index 000000000..b8fcfa01a --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/domain/EhcardUsageLog.java @@ -0,0 +1,30 @@ +package com.healthlink.his.ehcard.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.core.common.core.domain.HisBaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; +import tools.jackson.databind.annotation.JsonSerialize; +import tools.jackson.databind.ser.std.ToStringSerializer; + +import java.util.Date; + +@Data +@TableName("ehcard_usage_log") +@EqualsAndHashCode(callSuper = true) +public class EhcardUsageLog extends HisBaseEntity { + @TableId(value = "id", type = IdType.ASSIGN_ID) + @JsonSerialize(using = ToStringSerializer.class) + private Long id; + + @JsonSerialize(using = ToStringSerializer.class) + private Long cardId; + @JsonSerialize(using = ToStringSerializer.class) + private Long patientId; + private String usageType; + private String usageDesc; + private String operatorName; + private Date usageTime; +} diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/mapper/EhcardCardMapper.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/mapper/EhcardCardMapper.java new file mode 100644 index 000000000..46238b993 --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/mapper/EhcardCardMapper.java @@ -0,0 +1,9 @@ +package com.healthlink.his.ehcard.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.healthlink.his.ehcard.domain.EhcardCard; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface EhcardCardMapper extends BaseMapper { +} diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/mapper/EhcardUsageLogMapper.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/mapper/EhcardUsageLogMapper.java new file mode 100644 index 000000000..8c350f0f9 --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/mapper/EhcardUsageLogMapper.java @@ -0,0 +1,9 @@ +package com.healthlink.his.ehcard.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.healthlink.his.ehcard.domain.EhcardUsageLog; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface EhcardUsageLogMapper extends BaseMapper { +} diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/service/IEhcardCardService.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/service/IEhcardCardService.java new file mode 100644 index 000000000..9c6b0d49c --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/service/IEhcardCardService.java @@ -0,0 +1,7 @@ +package com.healthlink.his.ehcard.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.healthlink.his.ehcard.domain.EhcardCard; + +public interface IEhcardCardService extends IService { +} diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/service/IEhcardUsageLogService.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/service/IEhcardUsageLogService.java new file mode 100644 index 000000000..3b278a288 --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/service/IEhcardUsageLogService.java @@ -0,0 +1,7 @@ +package com.healthlink.his.ehcard.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.healthlink.his.ehcard.domain.EhcardUsageLog; + +public interface IEhcardUsageLogService extends IService { +} diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/service/impl/EhcardCardServiceImpl.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/service/impl/EhcardCardServiceImpl.java new file mode 100644 index 000000000..36cdd136b --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/service/impl/EhcardCardServiceImpl.java @@ -0,0 +1,11 @@ +package com.healthlink.his.ehcard.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.healthlink.his.ehcard.domain.EhcardCard; +import com.healthlink.his.ehcard.mapper.EhcardCardMapper; +import com.healthlink.his.ehcard.service.IEhcardCardService; +import org.springframework.stereotype.Service; + +@Service +public class EhcardCardServiceImpl extends ServiceImpl implements IEhcardCardService { +} diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/service/impl/EhcardUsageLogServiceImpl.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/service/impl/EhcardUsageLogServiceImpl.java new file mode 100644 index 000000000..f0adbbf51 --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/ehcard/service/impl/EhcardUsageLogServiceImpl.java @@ -0,0 +1,11 @@ +package com.healthlink.his.ehcard.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.healthlink.his.ehcard.domain.EhcardUsageLog; +import com.healthlink.his.ehcard.mapper.EhcardUsageLogMapper; +import com.healthlink.his.ehcard.service.IEhcardUsageLogService; +import org.springframework.stereotype.Service; + +@Service +public class EhcardUsageLogServiceImpl extends ServiceImpl implements IEhcardUsageLogService { +} diff --git a/healthlink-his-ui/src/views/ehcard/EhcardManagement.vue b/healthlink-his-ui/src/views/ehcard/EhcardManagement.vue new file mode 100644 index 000000000..6efad5368 --- /dev/null +++ b/healthlink-his-ui/src/views/ehcard/EhcardManagement.vue @@ -0,0 +1,160 @@ + + + diff --git a/healthlink-his-ui/src/views/ehcard/api.js b/healthlink-his-ui/src/views/ehcard/api.js new file mode 100644 index 000000000..8059ff577 --- /dev/null +++ b/healthlink-his-ui/src/views/ehcard/api.js @@ -0,0 +1,17 @@ +import request from '@/utils/request' + +export function applyEhcard(data) { + return request({ url: '/api/v1/ehcard/apply', method: 'post', data }) +} + +export function getEhcardPage(params) { + return request({ url: '/api/v1/ehcard/page', method: 'get', params }) +} + +export function lockEhcard(params) { + return request({ url: '/api/v1/ehcard/lock', method: 'post', params }) +} + +export function unlockEhcard(params) { + return request({ url: '/api/v1/ehcard/unlock', method: 'post', params }) +}