门诊号码管理维护界面前后端

This commit is contained in:
2025-11-27 13:08:42 +08:00
parent 88d79729fe
commit a0e52da437
7 changed files with 1096 additions and 316 deletions

View File

@@ -0,0 +1,56 @@
package com.openhis.administration.domain;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.core.common.core.domain.HisBaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 门诊号码段管理Entity实体
*
* @author system
* @date 2025-01-XX
*/
@Data
@TableName("adm_outpatient_no_segment")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
public class OutpatientNoSegment extends HisBaseEntity {
/** ID */
@TableId(type = IdType.ASSIGN_ID)
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/** 操作员ID */
private Long operatorId;
/** 操作员姓名 */
private String operatorName;
/** 员工工号 */
private String staffNo;
/** 领用日期 */
@JsonFormat(pattern = "yyyy-MM-dd")
private Date receiveDate;
/** 起始号码 */
private String startNo;
/** 终止号码 */
private String endNo;
/** 使用号码 */
private String usedNo;
}

View File

@@ -0,0 +1,18 @@
package com.openhis.administration.mapper;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.openhis.administration.domain.OutpatientNoSegment;
/**
* 门诊号码段管理Mapper接口
*
* @author system
* @date 2025-01-XX
*/
@Repository
public interface OutpatientNoSegmentMapper extends BaseMapper<OutpatientNoSegment> {
}

View File

@@ -0,0 +1,66 @@
package com.openhis.administration.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.openhis.administration.domain.OutpatientNoSegment;
/**
* 门诊号码段管理Service接口
*
* @author system
* @date 2025-01-XX
*/
public interface IOutpatientNoSegmentService {
/**
* 分页查询门诊号码段列表
*
* @param page 分页对象
* @param onlySelf 是否只查询自己的true=只查询自己的false=查询所有)
* @param userId 用户ID
* @return 分页结果
*/
Page<OutpatientNoSegment> selectOutpatientNoSegmentPage(Page<OutpatientNoSegment> page, boolean onlySelf, Long userId);
/**
* 新增门诊号码段
*
* @param outpatientNoSegment 门诊号码段信息
* @return 结果
*/
int insertOutpatientNoSegment(OutpatientNoSegment outpatientNoSegment);
/**
* 修改门诊号码段
*
* @param outpatientNoSegment 门诊号码段信息
* @return 结果
*/
int updateOutpatientNoSegment(OutpatientNoSegment outpatientNoSegment);
/**
* 删除门诊号码段
*
* @param ids 门诊号码段ID列表
* @return 结果
*/
int deleteOutpatientNoSegmentByIds(Long[] ids);
/**
* 根据ID查询门诊号码段
*
* @param id 门诊号码段ID
* @return 门诊号码段信息
*/
OutpatientNoSegment getById(Long id);
/**
* 检查号码段是否重复(全系统范围)
*
* @param startNo 起始号码
* @param endNo 终止号码
* @param excludeId 排除的ID用于更新时排除自身
* @return true=重复false=不重复
*/
boolean checkNumberSegmentOverlap(String startNo, String endNo, Long excludeId);
}

View File

@@ -0,0 +1,241 @@
package com.openhis.administration.service.impl;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.openhis.administration.domain.OutpatientNoSegment;
import com.openhis.administration.mapper.OutpatientNoSegmentMapper;
import com.openhis.administration.service.IOutpatientNoSegmentService;
/**
* 门诊号码段管理Service实现
*
* @author system
* @date 2025-01-XX
*/
@Service
public class OutpatientNoSegmentServiceImpl implements IOutpatientNoSegmentService {
@Autowired
private OutpatientNoSegmentMapper outpatientNoSegmentMapper;
/**
* 分页查询门诊号码段列表
*/
@Override
public Page<OutpatientNoSegment> selectOutpatientNoSegmentPage(Page<OutpatientNoSegment> page, boolean onlySelf, Long userId) {
LambdaQueryWrapper<OutpatientNoSegment> queryWrapper = new LambdaQueryWrapper<>();
// 如果不是管理员,只查询自己的号码段
if (onlySelf && userId != null) {
queryWrapper.eq(OutpatientNoSegment::getOperatorId, userId);
}
// 按创建时间正序排列(新记录排在后面)
queryWrapper.orderByAsc(OutpatientNoSegment::getCreateTime);
return outpatientNoSegmentMapper.selectPage(page, queryWrapper);
}
/**
* 新增门诊号码段
*/
@Override
public int insertOutpatientNoSegment(OutpatientNoSegment outpatientNoSegment) {
return outpatientNoSegmentMapper.insert(outpatientNoSegment);
}
/**
* 修改门诊号码段
*/
@Override
public int updateOutpatientNoSegment(OutpatientNoSegment outpatientNoSegment) {
return outpatientNoSegmentMapper.updateById(outpatientNoSegment);
}
/**
* 删除门诊号码段
*/
@Override
public int deleteOutpatientNoSegmentByIds(Long[] ids) {
if (ids == null || ids.length == 0) {
return 0;
}
return outpatientNoSegmentMapper.deleteBatchIds(java.util.Arrays.asList(ids));
}
/**
* 根据ID查询门诊号码段
* 注意:由于 @TableLogic 注解selectById 会自动过滤已删除的记录delete_flag = '1'
* 这意味着如果记录已经被软删除,此方法会返回 null
*/
@Override
public OutpatientNoSegment getById(Long id) {
System.out.println("=== 查询门诊号码段开始 ===");
System.out.println("查询ID: " + id);
System.out.println("ID类型: " + (id != null ? id.getClass().getName() : "null"));
System.out.println("ID值字符串: " + String.valueOf(id));
// 使用 selectById 查询(会自动过滤 delete_flag = '1' 的记录)
OutpatientNoSegment segment = outpatientNoSegmentMapper.selectById(id);
if (segment != null) {
System.out.println("查询成功 - 找到记录:");
System.out.println(" - 记录ID: " + segment.getId());
System.out.println(" - 操作员ID: " + segment.getOperatorId());
System.out.println(" - 起始号码: " + segment.getStartNo());
System.out.println(" - 终止号码: " + segment.getEndNo());
System.out.println(" - 使用号码: " + segment.getUsedNo());
} else {
System.out.println("查询失败 - 未找到记录");
System.out.println("可能原因:");
System.out.println(" 1. 记录不存在");
System.out.println(" 2. 记录已被软删除delete_flag = '1'");
System.out.println(" 3. ID 不匹配");
// 尝试直接查询数据库(包括已删除的记录)来验证记录是否存在
try {
LambdaQueryWrapper<OutpatientNoSegment> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(OutpatientNoSegment::getId, id);
// 注意:这里仍然会受到 @TableLogic 的影响,无法查询已删除的记录
// 如果需要查询已删除的记录,需要使用原生 SQL 或禁用逻辑删除
OutpatientNoSegment segmentWithDeleted = outpatientNoSegmentMapper.selectOne(queryWrapper);
if (segmentWithDeleted != null) {
System.out.println("使用 LambdaQueryWrapper 查询结果: 找到记录ID=" + segmentWithDeleted.getId());
} else {
System.out.println("使用 LambdaQueryWrapper 查询结果: 未找到记录");
}
} catch (Exception e) {
System.out.println("使用 LambdaQueryWrapper 查询时出错: " + e.getMessage());
}
// 尝试查询所有记录(不限制 delete_flag来验证 ID 是否存在
// 注意:由于 @TableLogic无法直接查询已删除的记录
// 但我们可以查询所有未删除的记录,看看是否有类似的 ID
try {
LambdaQueryWrapper<OutpatientNoSegment> allQuery = new LambdaQueryWrapper<>();
// 查询所有未删除的记录
List<OutpatientNoSegment> allSegments = outpatientNoSegmentMapper.selectList(allQuery);
System.out.println("数据库中所有未删除的记录数: " + allSegments.size());
System.out.println("所有记录的 ID 列表:");
for (OutpatientNoSegment seg : allSegments) {
System.out.println(" - ID: " + seg.getId() + " (类型: " + seg.getId().getClass().getName() + ")");
// 检查是否有接近的 ID可能是精度问题
if (seg.getId() != null) {
String segIdStr = String.valueOf(seg.getId());
String searchIdStr = String.valueOf(id);
if (segIdStr.length() == searchIdStr.length() &&
segIdStr.substring(0, Math.min(10, segIdStr.length())).equals(
searchIdStr.substring(0, Math.min(10, searchIdStr.length())))) {
System.out.println(" 警告:发现相似的 ID");
}
}
}
} catch (Exception e) {
System.out.println("查询所有记录时出错: " + e.getMessage());
}
}
System.out.println("=== 查询门诊号码段结束 ===");
return segment;
}
/**
* 检查号码段是否重复(全系统范围)
* 规则:从末位往前找到第一个字母作为前缀,比较前缀和数字范围
*/
@Override
public boolean checkNumberSegmentOverlap(String startNo, String endNo, Long excludeId) {
if (startNo == null || endNo == null) {
return false;
}
// 提取前缀(从末位往前找到第一个字母)
String prefix1 = extractPrefix(startNo);
String prefix2 = extractPrefix(endNo);
// 前缀必须一致
if (!prefix1.equals(prefix2)) {
return false;
}
// 提取尾部数字
Long num1 = extractTailNumber(startNo);
Long num2 = extractTailNumber(endNo);
if (num1 == null || num2 == null || num1 > num2) {
return false;
}
// 查询所有相同前缀的号码段
LambdaQueryWrapper<OutpatientNoSegment> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.likeRight(OutpatientNoSegment::getStartNo, prefix1);
if (excludeId != null) {
queryWrapper.ne(OutpatientNoSegment::getId, excludeId);
}
List<OutpatientNoSegment> segments = outpatientNoSegmentMapper.selectList(queryWrapper);
// 检查是否有重叠
for (OutpatientNoSegment segment : segments) {
String otherPrefix = extractPrefix(segment.getStartNo());
if (!prefix1.equals(otherPrefix)) {
continue;
}
Long otherNum1 = extractTailNumber(segment.getStartNo());
Long otherNum2 = extractTailNumber(segment.getEndNo());
if (otherNum1 != null && otherNum2 != null) {
// 检查范围是否重叠
if (Math.max(num1, otherNum1) <= Math.min(num2, otherNum2)) {
return true;
}
}
}
return false;
}
/**
* 从末位往前找到第一个字母,返回前缀(包含该字母)
*/
private String extractPrefix(String value) {
if (value == null || value.isEmpty()) {
return "";
}
char[] chars = value.toCharArray();
for (int i = chars.length - 1; i >= 0; i--) {
if (Character.isLetter(chars[i])) {
return value.substring(0, i + 1);
}
}
return "";
}
/**
* 提取尾部数字
*/
private Long extractTailNumber(String value) {
if (value == null || value.isEmpty()) {
return null;
}
Pattern pattern = Pattern.compile("(\\d+)$");
Matcher matcher = pattern.matcher(value);
if (matcher.find()) {
try {
return Long.parseLong(matcher.group(1));
} catch (NumberFormatException e) {
return null;
}
}
return null;
}
}