feat(menu): 优化菜单路径唯一性校验并更新前端界面

- 在SysLoginController中添加optionMap数据返回
- 添加JSQLParser依赖支持MyBatis Plus功能
- 实现selectMenuByPathExcludeId方法用于排除当前菜单的路径唯一性校验
- 在SysMenuServiceImpl中添加日志记录并优化路径唯一性判断逻辑
- 在SysMenuMapper.xml中添加LIMIT 1限制并实现排除ID查询
- 在前端路由中注释患者管理相关路由配置
- 在用户store中添加optionMap配置项并优先从optionMap获取医院名称
- 重构检查项目设置页面的操作按钮样式为统一的圆形按钮设计
- 更新检查项目设置页面的导航栏样式和交互体验
- 优化门诊记录页面的搜索条件和表格展示功能
- 添加性别和状态筛选条件并改进数据加载逻辑
This commit is contained in:
2026-01-03 23:47:09 +08:00
parent 61f4020487
commit 0c35044231
54 changed files with 5871 additions and 510 deletions

View File

@@ -28,6 +28,7 @@ import java.util.HashSet;
* @date 2025/3/15
*/
@Service
@Slf4j
public class OutpatientRecordServiceImpl implements IOutpatientRecordService {
@Resource
@@ -37,24 +38,78 @@ public class OutpatientRecordServiceImpl implements IOutpatientRecordService {
* 分页查询门诊记录
*
* @param outpatientRecordSearchParam 门诊录查询参数
* @param searchKey 搜索关键词(支持身份证号/病人ID/门诊号/姓名)
* @param pageNo 页码默认为1
* @param pageSize 每页大小默认为10
* @return 分页查询
* @param request HTTP请求
* @return 分页查询结果
*/
@Override
public IPage<OutpatientRecordDto> getPatient(OutpatientRecordSearchParam outpatientRecordSearchParam,
String searchKey, Integer pageNo, Integer pageSize, HttpServletRequest request) {
log.info("进入门诊记录查询服务searchKey: {}", searchKey);
if (outpatientRecordSearchParam != null) {
log.info("查询参数searchKey={}, 性别={}, 状态={}, 电话={}, 医生={}, 开始时间={}, 结束时间={}",
searchKey,
outpatientRecordSearchParam.getGenderEnum(),
outpatientRecordSearchParam.getSubjectStatusEnum(),
outpatientRecordSearchParam.getPhone(),
outpatientRecordSearchParam.getDoctorName(),
outpatientRecordSearchParam.getStartTimeSTime(),
outpatientRecordSearchParam.getStartTimeETime());
}
// 构建查询条件
QueryWrapper<OutpatientRecordDto> queryWrapper
= HisQueryUtils.buildQueryWrapper(outpatientRecordSearchParam, searchKey,
new HashSet<>(Arrays.asList(CommonConstants.FieldName.IdCard, CommonConstants.FieldName.Name,
CommonConstants.FieldName.PatientBusNo, CommonConstants.FieldName.EncounterBusNo)),
request);
// 构建查询条件不自动添加tenant_id手动指定表别名
QueryWrapper<OutpatientRecordDto> queryWrapper = new QueryWrapper<>();
// 手动添加带表别名的tenant_id条件
queryWrapper.eq("enc.tenant_id", com.core.common.utils.SecurityUtils.getLoginUser().getTenantId());
// 处理模糊查询关键字searchKey- 用于姓名/身份证号/病人ID/门诊号的模糊搜索
if (searchKey != null && !searchKey.isEmpty()) {
queryWrapper.and(wrapper -> {
wrapper.like("pt.name", searchKey)
.or().like("pt.id_card", searchKey)
.or().like("pt.bus_no", searchKey)
.or().like("enc.bus_no", searchKey);
});
}
// 处理其他筛选条件(这些条件可以与模糊查询或精确查询组合使用)
if (outpatientRecordSearchParam != null) {
// 处理性别筛选
if (outpatientRecordSearchParam.getGenderEnum() != null) {
queryWrapper.eq("pt.gender_enum", outpatientRecordSearchParam.getGenderEnum());
}
// 处理就诊对象状态筛选
if (outpatientRecordSearchParam.getSubjectStatusEnum() != null) {
queryWrapper.eq("enc.status_enum", outpatientRecordSearchParam.getSubjectStatusEnum());
}
// 处理医生姓名查询(支持模糊查询)
if (outpatientRecordSearchParam.getDoctorName() != null && !outpatientRecordSearchParam.getDoctorName().isEmpty()) {
queryWrapper.like("prac.name", outpatientRecordSearchParam.getDoctorName());
}
// 处理电话号码查询(支持模糊查询)
if (outpatientRecordSearchParam.getPhone() != null && !outpatientRecordSearchParam.getPhone().isEmpty()) {
queryWrapper.like("pt.phone", outpatientRecordSearchParam.getPhone());
}
// 处理时间范围查询
if (outpatientRecordSearchParam.getStartTimeSTime() != null && !outpatientRecordSearchParam.getStartTimeSTime().isEmpty()
&& outpatientRecordSearchParam.getStartTimeETime() != null && !outpatientRecordSearchParam.getStartTimeETime().isEmpty()) {
queryWrapper.between("enc.create_time", outpatientRecordSearchParam.getStartTimeSTime(), outpatientRecordSearchParam.getStartTimeETime());
}
}
// 使用接诊医生ADMITTERcode="1")作为参与者类型
IPage<OutpatientRecordDto> outpatientRecordPage = patientManageMapper
.getOutpatientRecord(ParticipantType.ADMITTER.getCode(), new Page<>(pageNo, pageSize), queryWrapper);
// 处理枚举字段的显示文本
outpatientRecordPage.getRecords().forEach(e -> {
// 性别枚举类回显赋值
e.setGenderEnum_enumText(EnumUtils.getInfoByValue(AdministrativeGender.class, e.getGenderEnum()));

View File

@@ -17,6 +17,7 @@ import com.openhis.administration.domain.Patient;
import com.openhis.administration.domain.PatientIdentifier;
import com.openhis.administration.service.IPatientIdentifierService;
import com.openhis.administration.service.IPatientService;
import com.openhis.administration.service.IPractitionerService;
import com.openhis.common.constant.CommonConstants;
import com.openhis.common.constant.PromptMsgConstant;
import com.openhis.common.enums.*;
@@ -54,6 +55,9 @@ public class PatientInformationServiceImpl implements IPatientInformationService
@Autowired
private IPatientService patientService;
@Autowired
private IPractitionerService practitionerService;
@Autowired
private IPatientIdentifierService patientIdentifierService;
@@ -129,11 +133,40 @@ public class PatientInformationServiceImpl implements IPatientInformationService
@Override
public IPage<PatientBaseInfoDto> getPatientInfo(PatientBaseInfoDto patientBaseInfoDto, String searchKey,
Integer pageNo, Integer pageSize, HttpServletRequest request) {
// 构建查询条件
// 获取登录者信息
LoginUser loginUser = SecurityUtils.getLoginUser();
Long userId = loginUser.getUserId();
// 先构建基础查询条件
QueryWrapper<PatientBaseInfoDto> queryWrapper = HisQueryUtils.buildQueryWrapper(
patientBaseInfoDto, searchKey, new HashSet<>(Arrays.asList(CommonConstants.FieldName.Name,
CommonConstants.FieldName.BusNo, CommonConstants.FieldName.PyStr, CommonConstants.FieldName.WbStr)),
request);
// 查询当前用户对应的医生信息
LambdaQueryWrapper<com.openhis.administration.domain.Practitioner> practitionerQuery = new LambdaQueryWrapper<>();
practitionerQuery.eq(com.openhis.administration.domain.Practitioner::getUserId, userId);
// 使用list()避免TooManyResultsException异常然后取第一个记录
List<com.openhis.administration.domain.Practitioner> practitionerList = practitionerService.list(practitionerQuery);
com.openhis.administration.domain.Practitioner practitioner = practitionerList != null && !practitionerList.isEmpty() ? practitionerList.get(0) : null;
// 如果当前用户是医生,添加医生患者过滤条件
if (practitioner != null) {
// 查询该医生作为接诊医生ADMITTER, code="1"和挂号医生REGISTRATION_DOCTOR, code="12"的所有就诊记录的患者ID
List<Long> doctorPatientIds = patientManageMapper.getPatientIdsByPractitionerId(
practitioner.getId(),
Arrays.asList(ParticipantType.ADMITTER.getCode(), ParticipantType.REGISTRATION_DOCTOR.getCode()));
if (doctorPatientIds != null && !doctorPatientIds.isEmpty()) {
// 添加患者ID过滤条件 - 注意:这里使用列名而不是表别名
queryWrapper.in("id", doctorPatientIds);
} else {
// 如果没有相关患者,返回空结果
queryWrapper.eq("id", -1); // 设置一个不存在的ID
}
}
// 如果不是医生,查询所有患者
IPage<PatientBaseInfoDto> patientInformationPage
= patientManageMapper.getPatientPage(new Page<>(pageNo, pageSize), queryWrapper);
// 患者id集合
@@ -141,8 +174,7 @@ public class PatientInformationServiceImpl implements IPatientInformationService
= patientInformationPage.getRecords().stream().map(PatientBaseInfoDto::getId).collect(Collectors.toList());
// 患者身份信息
List<PatientIdInfoDto> patientIdInfo = patientManageMapper.getPatientIdInfo(patientIdList);
// 获取登录者信息
LoginUser loginUser = SecurityUtils.getLoginUser();
patientInformationPage.getRecords().forEach(e -> {
// 性别枚举类回显赋值
e.setGenderEnum_enumText(EnumUtils.getInfoByValue(AdministrativeGender.class, e.getGenderEnum()));

View File

@@ -0,0 +1,96 @@
package com.openhis.web.patientmanage.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.core.common.annotation.Anonymous;
import com.core.common.core.domain.R;
import com.openhis.web.patientmanage.appservice.IOutpatientRecordService;
import com.openhis.web.patientmanage.dto.OutpatientRecordDto;
import com.openhis.web.patientmanage.dto.OutpatientRecordSearchParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
/**
* 门诊记录查询控制器
*
* @author system
* @date 2025/12/31
*/
@RestController
@RequestMapping("/patient-manage/records")
@Slf4j
@RequiredArgsConstructor
@Anonymous
public class OutpatientRecordController {
private final IOutpatientRecordService outpatientRecordService;
/**
* 测试接口 - 验证Controller是否被加载
*
* @return 测试消息
*/
@GetMapping("/test")
public R<?> test() {
log.info("OutpatientRecordController.test() 被调用");
return R.ok("OutpatientRecordController 工作正常");
}
/**
* 获取门诊记录初期数据
*
* @return 初期数据
*/
@GetMapping("/init")
public R<?> getInitData() {
return outpatientRecordService.getDoctorNames();
}
/**
* 分页查询门诊记录
*
* @param outpatientRecordSearchParam 门诊记录查询参数
* @param searchKey 查询条件-模糊查询
* @param pageNo 页码默认为1
* @param pageSize 每页大小默认为10
* @param request 请求对象
* @return 分页查询结果
*/
@GetMapping("/outpatient-record-page")
public R<IPage<OutpatientRecordDto>> getOutpatientRecordPage(
OutpatientRecordSearchParam outpatientRecordSearchParam,
@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest request) {
log.info("查询门诊记录pageNo: {}, pageSize: {}", pageNo, pageSize);
log.info("searchKey: {}", searchKey);
log.info("outpatientRecordSearchParam: {}", outpatientRecordSearchParam);
if (outpatientRecordSearchParam != null) {
log.info("姓名参数: {}, 身份证参数: {}, 病人ID: {}, 门诊号: {}, 性别: {}, 状态: {}, 电话: {}, 医生: {}, 开始时间: {}, 结束时间: {}",
outpatientRecordSearchParam.getName(),
outpatientRecordSearchParam.getIdCard(),
outpatientRecordSearchParam.getPatientBusNo(),
outpatientRecordSearchParam.getEncounterBusNo(),
outpatientRecordSearchParam.getGenderEnum(),
outpatientRecordSearchParam.getSubjectStatusEnum(),
outpatientRecordSearchParam.getPhone(),
outpatientRecordSearchParam.getDoctorName(),
outpatientRecordSearchParam.getStartTimeSTime(),
outpatientRecordSearchParam.getStartTimeETime());
}
return R.ok(outpatientRecordService.getPatient(outpatientRecordSearchParam, searchKey, pageNo, pageSize, request));
}
/**
* 获取医生名字列表
*
* @return 医生名字列表
*/
@GetMapping("/doctor-names")
public R<?> getDoctorNames() {
return outpatientRecordService.getDoctorNames();
}
}

View File

@@ -19,10 +19,10 @@ import java.util.Date;
public class OutpatientRecordDto {
/**
* ID
* 就诊记录ID
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
private Long encounterId;
/**
* 患者姓名
@@ -50,17 +50,36 @@ public class OutpatientRecordDto {
private Integer genderEnum;
private String genderEnum_enumText;
/**
* 联系电话
*/
private String phone;
/**
* 就诊时间
*/
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date encounterTime;
/**
* 就诊对象状态
*/
private Integer subjectStatusEnum;
private String subjectStatusEnum_enumText;
/**
* 医疗机构名称
*/
private String organizationName;
/**
* 接诊医生姓名
*/
private String doctorName;
/**
* 登记时间
*/
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
// 其他可能需要的字段
}

View File

@@ -43,5 +43,30 @@ public class OutpatientRecordSearchParam {
*/
private Integer subjectStatusEnum;
/**
* 医生姓名
*/
private String doctorName;
/**
* 患者电话
*/
private String phone;
/**
* 搜索关键词(支持身份证号/病人ID/门诊号/姓名)
*/
private String searchKey;
/**
* 开始时间(起始)
*/
private String startTimeSTime;
/**
* 开始时间(结束)
*/
private String startTimeETime;
// 其他可能需要的查询参数
}

View File

@@ -58,4 +58,14 @@ public interface PatientManageMapper extends BaseMapper<Patient> {
* @return 医生名字列表
*/
List<String> getDoctorNames();
/**
* 根据医生ID和参与者类型获取相关的患者ID列表
*
* @param practitionerId 医生ID
* @param typeCodes 参与者类型代码列表
* @return 患者ID列表
*/
List<Long> getPatientIdsByPractitionerId(@Param("practitionerId") Long practitionerId,
@Param("typeCodes") List<String> typeCodes);
}