diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/drugtrace/controller/DrugTraceController.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/drugtrace/controller/DrugTraceController.java new file mode 100644 index 000000000..819e45bd4 --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/drugtrace/controller/DrugTraceController.java @@ -0,0 +1,270 @@ +package com.healthlink.his.web.drugtrace.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.drugtrace.domain.*; +import com.healthlink.his.drugtrace.service.*; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.*; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * 药品追溯码管理 Controller — 2026新规+三甲要求 + * + * 业务说明: + * 1. 追溯码注册: 药品入库时注册追溯码,关联药品基本信息 + * 2. 扫码出入库: 入库/出库/发药时扫码验证,确保药品来源可查 + * 3. 全流程追溯: 从采购→入库→调拨→发药→使用的全链路追踪 + * 4. 预警管理: 近效期/过期/批次召回/异常扫码自动预警 + * + * 调用关系: + * DrugTraceController → IDrugTraceCodeService → 追溯码CRUD+验证 + * → IDrugTraceBatchService → 批次管理 + * → IDrugTraceScanService → 扫码记录 + * → IDrugTraceAlertService → 预警管理 + */ +@RestController +@RequestMapping("/drugtrace") +@Slf4j +@AllArgsConstructor +public class DrugTraceController { + + private final IDrugTraceCodeService codeService; + private final IDrugTraceBatchService batchService; + private final IDrugTraceScanService scanService; + private final IDrugTraceAlertService alertService; + + // ==================== 1. 追溯码管理 ==================== + + @GetMapping("/code/page") + public R getCodePage( + @RequestParam(value = "drugName", required = false) String drugName, + @RequestParam(value = "batchNo", required = false) String batchNo, + @RequestParam(value = "status", required = false) String status, + @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize) { + LambdaQueryWrapper w = new LambdaQueryWrapper<>(); + w.like(StringUtils.hasText(drugName), DrugTraceCode::getDrugName, drugName) + .eq(StringUtils.hasText(batchNo), DrugTraceCode::getBatchNo, batchNo) + .eq(StringUtils.hasText(status), DrugTraceCode::getStatus, status) + .orderByDesc(DrugTraceCode::getCreateTime); + return R.ok(codeService.page(new Page<>(pageNo, pageSize), w)); + } + + @PostMapping("/code/add") + @Transactional(rollbackFor = Exception.class) + public R addCode(@RequestBody DrugTraceCode code) { + code.setCreateTime(new Date()); + code.setStatus("ACTIVE"); + codeService.save(code); + log.info("追溯码注册: {} {} {}", code.getDrugName(), code.getBatchNo(), code.getTraceCode()); + return R.ok(code); + } + + @PutMapping("/code/{id}") + @Transactional(rollbackFor = Exception.class) + public R updateCode(@PathVariable Long id, @RequestBody DrugTraceCode data) { + DrugTraceCode code = codeService.getById(id); + if (code != null) { + data.setId(id); + codeService.updateById(data); + } + return R.ok(); + } + + @DeleteMapping("/code/delete/{id}") + @Transactional(rollbackFor = Exception.class) + public R deleteCode(@PathVariable Long id) { + codeService.removeById(id); + return R.ok(); + } + + @GetMapping("/code/verify/{traceCode}") + public R verifyTraceCode(@PathVariable String traceCode) { + LambdaQueryWrapper w = new LambdaQueryWrapper<>(); + w.eq(DrugTraceCode::getTraceCode, traceCode); + DrugTraceCode code = codeService.getOne(w); + if (code == null) { + return R.ok(Map.of("valid", false, "message", "追溯码不存在")); + } + Map result = new HashMap<>(); + result.put("valid", true); + result.put("drugName", code.getDrugName()); + result.put("batchNo", code.getBatchNo()); + result.put("manufacturer", code.getManufacturer()); + result.put("expiryDate", code.getExpiryDate()); + result.put("status", code.getStatus()); + boolean expired = code.getExpiryDate() != null && code.getExpiryDate().before(new Date()); + result.put("expired", expired); + if (expired) { + result.put("warning", "该药品已过期!"); + } + return R.ok(result); + } + + // ==================== 2. 批次管理 ==================== + + @GetMapping("/batch/page") + public R getBatchPage( + @RequestParam(value = "batchNo", required = false) String batchNo, + @RequestParam(value = "drugName", required = false) String drugName, + @RequestParam(value = "status", required = false) String status, + @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize) { + LambdaQueryWrapper w = new LambdaQueryWrapper<>(); + w.eq(StringUtils.hasText(batchNo), DrugTraceBatch::getBatchNo, batchNo) + .like(StringUtils.hasText(drugName), DrugTraceBatch::getDrugName, drugName) + .eq(StringUtils.hasText(status), DrugTraceBatch::getStatus, status) + .orderByDesc(DrugTraceBatch::getCreateTime); + return R.ok(batchService.page(new Page<>(pageNo, pageSize), w)); + } + + @PostMapping("/batch/add") + @Transactional(rollbackFor = Exception.class) + public R addBatch(@RequestBody DrugTraceBatch batch) { + batch.setCreateTime(new Date()); + batch.setStatus("PENDING"); + batch.setReceivedQuantity(0); + batchService.save(batch); + log.info("追溯批次创建: {} 药品: {} 数量: {}", batch.getBatchNo(), batch.getDrugName(), batch.getQuantity()); + return R.ok(batch); + } + + @PutMapping("/batch/{id}/receive") + @Transactional(rollbackFor = Exception.class) + public R receiveBatch(@PathVariable Long id, @RequestBody Map data) { + DrugTraceBatch batch = batchService.getById(id); + if (batch == null) return R.ok(Map.of("success", false, "message", "批次不存在")); + Integer receivedQty = (Integer) data.get("receivedQuantity"); + batch.setReceivedQuantity(receivedQty != null ? receivedQty : batch.getQuantity()); + batch.setReceiveTime(new Date()); + batch.setReceiverId(Long.valueOf(String.valueOf(data.getOrDefault("receiverId", 0)))); + batch.setReceiverName((String) data.getOrDefault("receiverName", "")); + batch.setStatus("RECEIVED"); + batchService.updateById(batch); + log.info("批次收货: {} 实收: {}/{}", batch.getBatchNo(), batch.getReceivedQuantity(), batch.getQuantity()); + return R.ok(batch); + } + + @DeleteMapping("/batch/delete/{id}") + @Transactional(rollbackFor = Exception.class) + public R deleteBatch(@PathVariable Long id) { + batchService.removeById(id); + return R.ok(); + } + + // ==================== 3. 扫码记录 ==================== + + @GetMapping("/scan/page") + public R getScanPage( + @RequestParam(value = "scanType", required = false) String scanType, + @RequestParam(value = "drugName", required = false) String drugName, + @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize) { + LambdaQueryWrapper w = new LambdaQueryWrapper<>(); + w.eq(StringUtils.hasText(scanType), DrugTraceScan::getScanType, scanType) + .like(StringUtils.hasText(drugName), DrugTraceScan::getDrugName, drugName) + .orderByDesc(DrugTraceScan::getScanTime); + return R.ok(scanService.page(new Page<>(pageNo, pageSize), w)); + } + + @PostMapping("/scan/record") + @Transactional(rollbackFor = Exception.class) + public R recordScan(@RequestBody DrugTraceScan scan) { + scan.setScanTime(new Date()); + scan.setScanResult("SUCCESS"); + scanService.save(scan); + log.info("扫码记录: {} 类型: {} 结果: {}", scan.getTraceCode(), scan.getScanType(), scan.getScanResult()); + return R.ok(scan); + } + + @GetMapping("/scan/trace/{traceCode}") + public R traceByCode(@PathVariable String traceCode) { + LambdaQueryWrapper w = new LambdaQueryWrapper<>(); + w.eq(DrugTraceScan::getTraceCode, traceCode).orderByAsc(DrugTraceScan::getScanTime); + List scans = scanService.list(w); + Map result = new HashMap<>(); + result.put("traceCode", traceCode); + result.put("scanCount", scans.size()); + result.put("scans", scans); + result.put("firstScan", scans.isEmpty() ? null : scans.get(0)); + result.put("lastScan", scans.isEmpty() ? null : scans.get(scans.size() - 1)); + List locations = scans.stream().map(DrugTraceScan::getScanLocation).filter(Objects::nonNull).distinct().collect(Collectors.toList()); + result.put("locations", locations); + return R.ok(result); + } + + // ==================== 4. 预警管理 ==================== + + @GetMapping("/alert/page") + public R getAlertPage( + @RequestParam(value = "alertType", required = false) String alertType, + @RequestParam(value = "status", required = false) String status, + @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize) { + LambdaQueryWrapper w = new LambdaQueryWrapper<>(); + w.eq(StringUtils.hasText(alertType), DrugTraceAlert::getAlertType, alertType) + .eq(StringUtils.hasText(status), DrugTraceAlert::getStatus, status) + .orderByDesc(DrugTraceAlert::getAlertTime); + return R.ok(alertService.page(new Page<>(pageNo, pageSize), w)); + } + + @PostMapping("/alert/add") + @Transactional(rollbackFor = Exception.class) + public R addAlert(@RequestBody DrugTraceAlert alert) { + alert.setAlertTime(new Date()); + alert.setStatus("PENDING"); + alertService.save(alert); + log.info("追溯预警: {} 级别: {} 内容: {}", alert.getAlertType(), alert.getAlertLevel(), alert.getAlertContent()); + return R.ok(alert); + } + + @PutMapping("/alert/{id}/handle") + @Transactional(rollbackFor = Exception.class) + public R handleAlert(@PathVariable Long id, @RequestBody Map data) { + DrugTraceAlert alert = alertService.getById(id); + if (alert != null) { + alert.setHandlerName(data.get("handlerName")); + alert.setHandleTime(new Date()); + alert.setHandleResult(data.get("handleResult")); + alert.setStatus("HANDLED"); + alertService.updateById(alert); + } + return R.ok(); + } + + @DeleteMapping("/alert/delete/{id}") + @Transactional(rollbackFor = Exception.class) + public R deleteAlert(@PathVariable Long id) { + alertService.removeById(id); + return R.ok(); + } + + // ==================== 5. 统计 ==================== + + @GetMapping("/statistics") + public R getStatistics() { + Map stats = new HashMap<>(); + stats.put("totalCodes", codeService.count()); + stats.put("activeCodes", codeService.count(new LambdaQueryWrapper().eq(DrugTraceCode::getStatus, "ACTIVE"))); + stats.put("totalBatches", batchService.count()); + stats.put("pendingBatches", batchService.count(new LambdaQueryWrapper().eq(DrugTraceBatch::getStatus, "PENDING"))); + stats.put("totalScans", scanService.count()); + stats.put("pendingAlerts", alertService.count(new LambdaQueryWrapper().eq(DrugTraceAlert::getStatus, "PENDING"))); + // 近效期预警(30天内过期) + Date thirtyDaysLater = new Date(System.currentTimeMillis() + 30L * 24 * 60 * 60 * 1000); + Date now = new Date(); + stats.put("expiringSoon", codeService.count(new LambdaQueryWrapper() + .ge(DrugTraceCode::getExpiryDate, now) + .le(DrugTraceCode::getExpiryDate, thirtyDaysLater))); + stats.put("expired", codeService.count(new LambdaQueryWrapper() + .lt(DrugTraceCode::getExpiryDate, now))); + return R.ok(stats); + } +} diff --git a/healthlink-his-server/healthlink-his-application/src/main/resources/db/migration/V36__drug_traceability.sql b/healthlink-his-server/healthlink-his-application/src/main/resources/db/migration/V36__drug_traceability.sql new file mode 100644 index 000000000..2fcff1ea0 --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/resources/db/migration/V36__drug_traceability.sql @@ -0,0 +1,120 @@ +-- ========================================== +-- V36: 药品追溯码管理模块 +-- 三甲要求: 2026年新规,药品全流程追溯 +-- ========================================== + +-- 1. 药品追溯码主表 +CREATE TABLE IF NOT EXISTS drug_trace_code ( + id BIGSERIAL PRIMARY KEY, + drug_code VARCHAR(50) NOT NULL, + drug_name VARCHAR(200) NOT NULL, + generic_name VARCHAR(200), + specification VARCHAR(200), + manufacturer VARCHAR(200), + batch_no VARCHAR(100) NOT NULL, + trace_code VARCHAR(200) NOT NULL, + production_date TIMESTAMP, + expiry_date TIMESTAMP, + approval_number VARCHAR(100), + dosage_form VARCHAR(50), + unit VARCHAR(20), + barcode VARCHAR(200), + qr_code VARCHAR(500), + status VARCHAR(20) DEFAULT 'ACTIVE', + delete_flag VARCHAR(1) DEFAULT '0', + create_by VARCHAR(64), + create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + update_by VARCHAR(64), + update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + tenant_id BIGINT DEFAULT 0 +); + +CREATE INDEX IF NOT EXISTS idx_drug_trace_code_drug ON drug_trace_code(drug_code); +CREATE INDEX IF NOT EXISTS idx_drug_trace_code_batch ON drug_trace_code(batch_no); +CREATE INDEX IF NOT EXISTS idx_drug_trace_code_trace ON drug_trace_code(trace_code); + +-- 2. 药品追溯批次信息 +CREATE TABLE IF NOT EXISTS drug_trace_batch ( + id BIGSERIAL PRIMARY KEY, + batch_no VARCHAR(100) NOT NULL, + drug_code VARCHAR(50) NOT NULL, + drug_name VARCHAR(200), + supplier VARCHAR(200), + supplier_license VARCHAR(100), + purchase_order_no VARCHAR(100), + quantity INTEGER NOT NULL, + received_quantity INTEGER DEFAULT 0, + warehouse_id BIGINT, + warehouse_name VARCHAR(100), + receive_time TIMESTAMP, + receiver_id BIGINT, + receiver_name VARCHAR(64), + status VARCHAR(20) DEFAULT 'PENDING', + delete_flag VARCHAR(1) DEFAULT '0', + create_by VARCHAR(64), + create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + update_by VARCHAR(64), + update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + tenant_id BIGINT DEFAULT 0 +); + +CREATE INDEX IF NOT EXISTS idx_drug_trace_batch_no ON drug_trace_batch(batch_no); +CREATE INDEX IF NOT EXISTS idx_drug_trace_batch_drug ON drug_trace_batch(drug_code); + +-- 3. 药品追溯扫码记录 +CREATE TABLE IF NOT EXISTS drug_trace_scan ( + id BIGSERIAL PRIMARY KEY, + trace_code VARCHAR(200) NOT NULL, + drug_code VARCHAR(50), + drug_name VARCHAR(200), + batch_no VARCHAR(100), + scan_type VARCHAR(50) NOT NULL, + scan_location VARCHAR(200), + scan_person_id BIGINT, + scan_person_name VARCHAR(64), + scan_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + scan_result VARCHAR(20) DEFAULT 'SUCCESS', + related_order_no VARCHAR(100), + related_order_type VARCHAR(50), + ip_address VARCHAR(50), + device_info VARCHAR(200), + delete_flag VARCHAR(1) DEFAULT '0', + create_by VARCHAR(64), + create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + update_by VARCHAR(64), + update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + tenant_id BIGINT DEFAULT 0 +); + +CREATE INDEX IF NOT EXISTS idx_drug_trace_scan_code ON drug_trace_scan(trace_code); +CREATE INDEX IF NOT EXISTS idx_drug_trace_scan_time ON drug_trace_scan(scan_time); +CREATE INDEX IF NOT EXISTS idx_drug_trace_scan_type ON drug_trace_scan(scan_type); + +-- 4. 药品追溯预警 +CREATE TABLE IF NOT EXISTS drug_trace_alert ( + id BIGSERIAL PRIMARY KEY, + alert_type VARCHAR(50) NOT NULL, + alert_level VARCHAR(20) NOT NULL, + drug_code VARCHAR(50), + drug_name VARCHAR(200), + batch_no VARCHAR(100), + trace_code VARCHAR(200), + alert_content TEXT NOT NULL, + related_order_no VARCHAR(100), + alert_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + handler_id BIGINT, + handler_name VARCHAR(64), + handle_time TIMESTAMP, + handle_result TEXT, + status VARCHAR(20) DEFAULT 'PENDING', + delete_flag VARCHAR(1) DEFAULT '0', + create_by VARCHAR(64), + create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + update_by VARCHAR(64), + update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + tenant_id BIGINT DEFAULT 0 +); + +CREATE INDEX IF NOT EXISTS idx_drug_trace_alert_type ON drug_trace_alert(alert_type); +CREATE INDEX IF NOT EXISTS idx_drug_trace_alert_status ON drug_trace_alert(status); +CREATE INDEX IF NOT EXISTS idx_drug_trace_alert_time ON drug_trace_alert(alert_time); diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/domain/DrugTraceAlert.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/domain/DrugTraceAlert.java new file mode 100644 index 000000000..0c0a30e3b --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/domain/DrugTraceAlert.java @@ -0,0 +1,46 @@ +package com.healthlink.his.drugtrace.domain; + +import com.baomidou.mybatisplus.annotation.*; +import com.core.common.core.domain.HisBaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import lombok.EqualsAndHashCode; +import java.util.Date; + +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("drug_trace_alert") +public class DrugTraceAlert extends HisBaseEntity { + @TableId(type = IdType.ASSIGN_ID) + private Long id; + @TableField("alert_type") + private String alertType; + @TableField("alert_level") + private String alertLevel; + @TableField("drug_code") + private String drugCode; + @TableField("drug_name") + private String drugName; + @TableField("batch_no") + private String batchNo; + @TableField("trace_code") + private String traceCode; + @TableField("alert_content") + private String alertContent; + @TableField("related_order_no") + private String relatedOrderNo; + @TableField("alert_time") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date alertTime; + @TableField("handler_id") + private Long handlerId; + @TableField("handler_name") + private String handlerName; + @TableField("handle_time") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date handleTime; + @TableField("handle_result") + private String handleResult; + @TableField("status") + private String status; +} diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/domain/DrugTraceBatch.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/domain/DrugTraceBatch.java new file mode 100644 index 000000000..4278db577 --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/domain/DrugTraceBatch.java @@ -0,0 +1,45 @@ +package com.healthlink.his.drugtrace.domain; + +import com.baomidou.mybatisplus.annotation.*; +import com.core.common.core.domain.HisBaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import lombok.EqualsAndHashCode; +import java.util.Date; + +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("drug_trace_batch") +public class DrugTraceBatch extends HisBaseEntity { + @TableId(type = IdType.ASSIGN_ID) + private Long id; + @TableField("batch_no") + private String batchNo; + @TableField("drug_code") + private String drugCode; + @TableField("drug_name") + private String drugName; + @TableField("supplier") + private String supplier; + @TableField("supplier_license") + private String supplierLicense; + @TableField("purchase_order_no") + private String purchaseOrderNo; + @TableField("quantity") + private Integer quantity; + @TableField("received_quantity") + private Integer receivedQuantity; + @TableField("warehouse_id") + private Long warehouseId; + @TableField("warehouse_name") + private String warehouseName; + @TableField("receive_time") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date receiveTime; + @TableField("receiver_id") + private Long receiverId; + @TableField("receiver_name") + private String receiverName; + @TableField("status") + private String status; +} diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/domain/DrugTraceCode.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/domain/DrugTraceCode.java new file mode 100644 index 000000000..0185b5164 --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/domain/DrugTraceCode.java @@ -0,0 +1,48 @@ +package com.healthlink.his.drugtrace.domain; + +import com.baomidou.mybatisplus.annotation.*; +import com.core.common.core.domain.HisBaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import lombok.EqualsAndHashCode; +import java.util.Date; + +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("drug_trace_code") +public class DrugTraceCode extends HisBaseEntity { + @TableId(type = IdType.ASSIGN_ID) + private Long id; + @TableField("drug_code") + private String drugCode; + @TableField("drug_name") + private String drugName; + @TableField("generic_name") + private String genericName; + @TableField("specification") + private String specification; + @TableField("manufacturer") + private String manufacturer; + @TableField("batch_no") + private String batchNo; + @TableField("trace_code") + private String traceCode; + @TableField("production_date") + @JsonFormat(pattern = "yyyy-MM-dd") + private Date productionDate; + @TableField("expiry_date") + @JsonFormat(pattern = "yyyy-MM-dd") + private Date expiryDate; + @TableField("approval_number") + private String approvalNumber; + @TableField("dosage_form") + private String dosageForm; + @TableField("unit") + private String unit; + @TableField("barcode") + private String barcode; + @TableField("qr_code") + private String qrCode; + @TableField("status") + private String status; +} diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/domain/DrugTraceScan.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/domain/DrugTraceScan.java new file mode 100644 index 000000000..fcf1870e0 --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/domain/DrugTraceScan.java @@ -0,0 +1,45 @@ +package com.healthlink.his.drugtrace.domain; + +import com.baomidou.mybatisplus.annotation.*; +import com.core.common.core.domain.HisBaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import lombok.EqualsAndHashCode; +import java.util.Date; + +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("drug_trace_scan") +public class DrugTraceScan extends HisBaseEntity { + @TableId(type = IdType.ASSIGN_ID) + private Long id; + @TableField("trace_code") + private String traceCode; + @TableField("drug_code") + private String drugCode; + @TableField("drug_name") + private String drugName; + @TableField("batch_no") + private String batchNo; + @TableField("scan_type") + private String scanType; + @TableField("scan_location") + private String scanLocation; + @TableField("scan_person_id") + private Long scanPersonId; + @TableField("scan_person_name") + private String scanPersonName; + @TableField("scan_time") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date scanTime; + @TableField("scan_result") + private String scanResult; + @TableField("related_order_no") + private String relatedOrderNo; + @TableField("related_order_type") + private String relatedOrderType; + @TableField("ip_address") + private String ipAddress; + @TableField("device_info") + private String deviceInfo; +} diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/mapper/DrugTraceAlertMapper.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/mapper/DrugTraceAlertMapper.java new file mode 100644 index 000000000..69da96b53 --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/mapper/DrugTraceAlertMapper.java @@ -0,0 +1,9 @@ +package com.healthlink.his.drugtrace.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.healthlink.his.drugtrace.domain.DrugTraceAlert; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface DrugTraceAlertMapper extends BaseMapper { +} diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/mapper/DrugTraceBatchMapper.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/mapper/DrugTraceBatchMapper.java new file mode 100644 index 000000000..8cc2e03e6 --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/mapper/DrugTraceBatchMapper.java @@ -0,0 +1,9 @@ +package com.healthlink.his.drugtrace.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.healthlink.his.drugtrace.domain.DrugTraceBatch; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface DrugTraceBatchMapper extends BaseMapper { +} diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/mapper/DrugTraceCodeMapper.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/mapper/DrugTraceCodeMapper.java new file mode 100644 index 000000000..b2e719ab8 --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/mapper/DrugTraceCodeMapper.java @@ -0,0 +1,9 @@ +package com.healthlink.his.drugtrace.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.healthlink.his.drugtrace.domain.DrugTraceCode; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface DrugTraceCodeMapper extends BaseMapper { +} diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/mapper/DrugTraceScanMapper.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/mapper/DrugTraceScanMapper.java new file mode 100644 index 000000000..0f952dc6b --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/mapper/DrugTraceScanMapper.java @@ -0,0 +1,9 @@ +package com.healthlink.his.drugtrace.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.healthlink.his.drugtrace.domain.DrugTraceScan; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface DrugTraceScanMapper extends BaseMapper { +} diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/service/IDrugTraceAlertService.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/service/IDrugTraceAlertService.java new file mode 100644 index 000000000..0c097b1b3 --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/service/IDrugTraceAlertService.java @@ -0,0 +1,7 @@ +package com.healthlink.his.drugtrace.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.healthlink.his.drugtrace.domain.DrugTraceAlert; + +public interface IDrugTraceAlertService extends IService { +} diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/service/IDrugTraceBatchService.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/service/IDrugTraceBatchService.java new file mode 100644 index 000000000..eb4a6615b --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/service/IDrugTraceBatchService.java @@ -0,0 +1,7 @@ +package com.healthlink.his.drugtrace.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.healthlink.his.drugtrace.domain.DrugTraceBatch; + +public interface IDrugTraceBatchService extends IService { +} diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/service/IDrugTraceCodeService.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/service/IDrugTraceCodeService.java new file mode 100644 index 000000000..7846be530 --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/service/IDrugTraceCodeService.java @@ -0,0 +1,7 @@ +package com.healthlink.his.drugtrace.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.healthlink.his.drugtrace.domain.DrugTraceCode; + +public interface IDrugTraceCodeService extends IService { +} diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/service/IDrugTraceScanService.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/service/IDrugTraceScanService.java new file mode 100644 index 000000000..97c30940b --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/service/IDrugTraceScanService.java @@ -0,0 +1,7 @@ +package com.healthlink.his.drugtrace.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.healthlink.his.drugtrace.domain.DrugTraceScan; + +public interface IDrugTraceScanService extends IService { +} diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/service/impl/DrugTraceAlertServiceImpl.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/service/impl/DrugTraceAlertServiceImpl.java new file mode 100644 index 000000000..3dc1670c0 --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/service/impl/DrugTraceAlertServiceImpl.java @@ -0,0 +1,11 @@ +package com.healthlink.his.drugtrace.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.healthlink.his.drugtrace.domain.DrugTraceAlert; +import com.healthlink.his.drugtrace.mapper.DrugTraceAlertMapper; +import com.healthlink.his.drugtrace.service.IDrugTraceAlertService; +import org.springframework.stereotype.Service; + +@Service +public class DrugTraceAlertServiceImpl extends ServiceImpl implements IDrugTraceAlertService { +} diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/service/impl/DrugTraceBatchServiceImpl.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/service/impl/DrugTraceBatchServiceImpl.java new file mode 100644 index 000000000..dcb6858a6 --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/service/impl/DrugTraceBatchServiceImpl.java @@ -0,0 +1,11 @@ +package com.healthlink.his.drugtrace.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.healthlink.his.drugtrace.domain.DrugTraceBatch; +import com.healthlink.his.drugtrace.mapper.DrugTraceBatchMapper; +import com.healthlink.his.drugtrace.service.IDrugTraceBatchService; +import org.springframework.stereotype.Service; + +@Service +public class DrugTraceBatchServiceImpl extends ServiceImpl implements IDrugTraceBatchService { +} diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/service/impl/DrugTraceCodeServiceImpl.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/service/impl/DrugTraceCodeServiceImpl.java new file mode 100644 index 000000000..df2508c82 --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/service/impl/DrugTraceCodeServiceImpl.java @@ -0,0 +1,11 @@ +package com.healthlink.his.drugtrace.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.healthlink.his.drugtrace.domain.DrugTraceCode; +import com.healthlink.his.drugtrace.mapper.DrugTraceCodeMapper; +import com.healthlink.his.drugtrace.service.IDrugTraceCodeService; +import org.springframework.stereotype.Service; + +@Service +public class DrugTraceCodeServiceImpl extends ServiceImpl implements IDrugTraceCodeService { +} diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/service/impl/DrugTraceScanServiceImpl.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/service/impl/DrugTraceScanServiceImpl.java new file mode 100644 index 000000000..93a42d474 --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/drugtrace/service/impl/DrugTraceScanServiceImpl.java @@ -0,0 +1,11 @@ +package com.healthlink.his.drugtrace.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.healthlink.his.drugtrace.domain.DrugTraceScan; +import com.healthlink.his.drugtrace.mapper.DrugTraceScanMapper; +import com.healthlink.his.drugtrace.service.IDrugTraceScanService; +import org.springframework.stereotype.Service; + +@Service +public class DrugTraceScanServiceImpl extends ServiceImpl implements IDrugTraceScanService { +} diff --git a/healthlink-his-ui/src/views/drugtrace/alert/index.vue b/healthlink-his-ui/src/views/drugtrace/alert/index.vue new file mode 100644 index 000000000..beea1fe96 --- /dev/null +++ b/healthlink-his-ui/src/views/drugtrace/alert/index.vue @@ -0,0 +1,74 @@ + + + diff --git a/healthlink-his-ui/src/views/drugtrace/api.js b/healthlink-his-ui/src/views/drugtrace/api.js new file mode 100644 index 000000000..ea7d6a5e1 --- /dev/null +++ b/healthlink-his-ui/src/views/drugtrace/api.js @@ -0,0 +1,23 @@ +import request from '@/utils/request' + +export function getCodePage(params) { return request({ url: '/drugtrace/code/page', method: 'get', params }) } +export function addCode(data) { return request({ url: '/drugtrace/code/add', method: 'post', data }) } +export function updateCode(id, data) { return request({ url: '/drugtrace/code/' + id, method: 'put', data }) } +export function deleteCode(id) { return request({ url: '/drugtrace/code/delete/' + id, method: 'delete' }) } +export function verifyTraceCode(traceCode) { return request({ url: '/drugtrace/code/verify/' + traceCode, method: 'get' }) } + +export function getBatchPage(params) { return request({ url: '/drugtrace/batch/page', method: 'get', params }) } +export function addBatch(data) { return request({ url: '/drugtrace/batch/add', method: 'post', data }) } +export function receiveBatch(id, data) { return request({ url: '/drugtrace/batch/' + id + '/receive', method: 'put', data }) } +export function deleteBatch(id) { return request({ url: '/drugtrace/batch/delete/' + id, method: 'delete' }) } + +export function getScanPage(params) { return request({ url: '/drugtrace/scan/page', method: 'get', params }) } +export function recordScan(data) { return request({ url: '/drugtrace/scan/record', method: 'post', data }) } +export function traceByCode(traceCode) { return request({ url: '/drugtrace/scan/trace/' + traceCode, method: 'get' }) } + +export function getAlertPage(params) { return request({ url: '/drugtrace/alert/page', method: 'get', params }) } +export function addAlert(data) { return request({ url: '/drugtrace/alert/add', method: 'post', data }) } +export function handleAlert(id, data) { return request({ url: '/drugtrace/alert/' + id + '/handle', method: 'put', data }) } +export function deleteAlert(id) { return request({ url: '/drugtrace/alert/delete/' + id, method: 'delete' }) } + +export function getStatistics() { return request({ url: '/drugtrace/statistics', method: 'get' }) } diff --git a/healthlink-his-ui/src/views/drugtrace/batch/index.vue b/healthlink-his-ui/src/views/drugtrace/batch/index.vue new file mode 100644 index 000000000..6aadbd38c --- /dev/null +++ b/healthlink-his-ui/src/views/drugtrace/batch/index.vue @@ -0,0 +1,87 @@ + + + diff --git a/healthlink-his-ui/src/views/drugtrace/code/index.vue b/healthlink-his-ui/src/views/drugtrace/code/index.vue new file mode 100644 index 000000000..20c8e9895 --- /dev/null +++ b/healthlink-his-ui/src/views/drugtrace/code/index.vue @@ -0,0 +1,106 @@ + + + diff --git a/healthlink-his-ui/src/views/drugtrace/scan/index.vue b/healthlink-his-ui/src/views/drugtrace/scan/index.vue new file mode 100644 index 000000000..0318494a7 --- /dev/null +++ b/healthlink-his-ui/src/views/drugtrace/scan/index.vue @@ -0,0 +1,78 @@ + + +