feat(menu): 优化菜单路径唯一性校验并更新前端界面
- 在SysLoginController中添加optionMap数据返回 - 添加JSQLParser依赖支持MyBatis Plus功能 - 实现selectMenuByPathExcludeId方法用于排除当前菜单的路径唯一性校验 - 在SysMenuServiceImpl中添加日志记录并优化路径唯一性判断逻辑 - 在SysMenuMapper.xml中添加LIMIT 1限制并实现排除ID查询 - 在前端路由中注释患者管理相关路由配置 - 在用户store中添加optionMap配置项并优先从optionMap获取医院名称 - 重构检查项目设置页面的操作按钮样式为统一的圆形按钮设计 - 更新检查项目设置页面的导航栏样式和交互体验 - 优化门诊记录页面的搜索条件和表格展示功能 - 添加性别和状态筛选条件并改进数据加载逻辑
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
package com.openhis.web.administration.controller;
|
||||
|
||||
import com.core.common.annotation.Log;
|
||||
import com.core.common.core.controller.BaseController;
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
import com.core.common.core.page.TableDataInfo;
|
||||
import com.core.common.enums.BusinessType;
|
||||
import com.core.common.utils.poi.ExcelUtil;
|
||||
import com.openhis.administration.domain.PractitionerPatient;
|
||||
import com.openhis.administration.service.IPractitionerPatientService;
|
||||
import com.openhis.administration.dto.PractitionerPatientDto;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 医生患者关系管理Controller
|
||||
*
|
||||
* @author system
|
||||
* @date 2026-01-02
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/administration/practitioner-patient")
|
||||
public class PractitionerPatientController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private IPractitionerPatientService practitionerPatientService;
|
||||
|
||||
/**
|
||||
* 查询医生患者关系列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('administration:practitionerPatient:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(PractitionerPatient practitionerPatient) {
|
||||
startPage();
|
||||
List<PractitionerPatient> list = practitionerPatientService.list();
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出医生患者关系列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('administration:practitionerPatient:export')")
|
||||
@Log(title = "医生患者关系", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, PractitionerPatient practitionerPatient) {
|
||||
List<PractitionerPatient> list = practitionerPatientService.list();
|
||||
ExcelUtil<PractitionerPatient> util = new ExcelUtil<>(PractitionerPatient.class);
|
||||
util.exportExcel(response, list, "医生患者关系数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取医生患者关系详细信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('administration:practitionerPatient:query')")
|
||||
@GetMapping(value = "/{id}")
|
||||
public AjaxResult getInfo(@PathVariable("id") Long id) {
|
||||
return AjaxResult.success(practitionerPatientService.getById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取医生的所有有效患者
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('administration:practitionerPatient:query')")
|
||||
@GetMapping("/practitioner/{practitionerId}/patients")
|
||||
public AjaxResult getPatientsByPractitioner(@PathVariable Long practitionerId) {
|
||||
return AjaxResult.success(practitionerPatientService.getValidPatientsByPractitioner(practitionerId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取患者的所有有效医生
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('administration:practitionerPatient:query')")
|
||||
@GetMapping("/patient/{patientId}/practitioners")
|
||||
public AjaxResult getPractitionersByPatient(@PathVariable Long patientId) {
|
||||
return AjaxResult.success(practitionerPatientService.getValidPractitionersByPatient(patientId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增医生患者关系
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('administration:practitionerPatient:add')")
|
||||
@Log(title = "医生患者关系", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody PractitionerPatientDto dto) {
|
||||
PractitionerPatient relationship = new PractitionerPatient();
|
||||
relationship.setPractitionerId(dto.getPractitionerId());
|
||||
relationship.setPatientId(dto.getPatientId());
|
||||
relationship.setRelationshipType(dto.getRelationshipType());
|
||||
relationship.setOrganizationId(dto.getOrganizationId());
|
||||
relationship.setStartDate(dto.getStartDate());
|
||||
relationship.setRemark(dto.getRemark());
|
||||
|
||||
return toAjax(practitionerPatientService.createRelationship(relationship));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改医生患者关系
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('administration:practitionerPatient:edit')")
|
||||
@Log(title = "医生患者关系", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody PractitionerPatient practitionerPatient) {
|
||||
return toAjax(practitionerPatientService.updateById(practitionerPatient));
|
||||
}
|
||||
|
||||
/**
|
||||
* 终止医生患者关系
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('administration:practitionerPatient:remove')")
|
||||
@Log(title = "医生患者关系", businessType = BusinessType.DELETE)
|
||||
@PostMapping("/terminate/{id}")
|
||||
public AjaxResult terminate(@PathVariable Long id) {
|
||||
return toAjax(practitionerPatientService.terminateRelationship(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除医生患者关系
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('administration:practitionerPatient:remove')")
|
||||
@Log(title = "医生患者关系", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
public AjaxResult remove(@PathVariable Long[] ids) {
|
||||
return toAjax(practitionerPatientService.removeByIds(List.of(ids)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量创建医生患者关系
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('administration:practitionerPatient:add')")
|
||||
@Log(title = "批量创建医生患者关系", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/batch")
|
||||
public AjaxResult batchAdd(@RequestBody List<PractitionerPatientDto> dtos) {
|
||||
List<PractitionerPatient> relationships = dtos.stream().map(dto -> {
|
||||
PractitionerPatient relationship = new PractitionerPatient();
|
||||
relationship.setPractitionerId(dto.getPractitionerId());
|
||||
relationship.setPatientId(dto.getPatientId());
|
||||
relationship.setRelationshipType(dto.getRelationshipType());
|
||||
relationship.setOrganizationId(dto.getOrganizationId());
|
||||
relationship.setStartDate(dto.getStartDate());
|
||||
relationship.setRemark(dto.getRemark());
|
||||
return relationship;
|
||||
}).toList();
|
||||
|
||||
return toAjax(practitionerPatientService.batchCreateRelationships(relationships));
|
||||
}
|
||||
}
|
||||
@@ -407,8 +407,12 @@ public class PractitionerAppServiceImpl implements IPractitionerAppService {
|
||||
// iBizUserService.remove(new LambdaQueryWrapper<BizUser>().eq(BizUser::getUserId, userId));
|
||||
practitionerAppAppMapper.delUser(userId);
|
||||
practitionerAppAppMapper.delUserRole(userId);
|
||||
Practitioner one =
|
||||
iPractitionerService.getOne(new LambdaQueryWrapper<Practitioner>().eq(Practitioner::getUserId, userId));
|
||||
// 使用list()避免TooManyResultsException异常,然后取第一个记录
|
||||
List<Practitioner> practitionerList = iPractitionerService.list(new LambdaQueryWrapper<Practitioner>().eq(Practitioner::getUserId, userId));
|
||||
Practitioner one = practitionerList != null && !practitionerList.isEmpty() ? practitionerList.get(0) : null;
|
||||
if (one == null) {
|
||||
return R.fail(null, "未找到对应的医生信息");
|
||||
}
|
||||
Long practitionerId = one.getId();// 参与者id
|
||||
iPractitionerService.removeById(practitionerId);
|
||||
iPractitionerRoleService
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.openhis.web.controller;
|
||||
|
||||
import com.core.common.core.controller.BaseController;
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
import com.openhis.administration.domain.Encounter;
|
||||
import com.openhis.web.dto.HomeStatisticsDto;
|
||||
import com.openhis.web.service.IHomeStatisticsService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 首页统计Controller
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-12-31
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/home")
|
||||
public class HomeStatisticsController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private IHomeStatisticsService homeStatisticsService;
|
||||
|
||||
/**
|
||||
* 获取首页统计数据
|
||||
*
|
||||
* @return 首页统计数据
|
||||
*/
|
||||
@GetMapping("/statistics")
|
||||
public AjaxResult getHomeStatistics() {
|
||||
HomeStatisticsDto statistics = homeStatisticsService.getHomeStatistics();
|
||||
return AjaxResult.success(statistics);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.openhis.web.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 首页统计数据DTO
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-12-31
|
||||
*/
|
||||
@Data
|
||||
public class HomeStatisticsDto {
|
||||
/**
|
||||
* 在院患者数量
|
||||
*/
|
||||
private Integer totalPatients;
|
||||
|
||||
/**
|
||||
* 昨日在院患者数量
|
||||
*/
|
||||
private Integer yesterdayPatients;
|
||||
|
||||
/**
|
||||
* 相对前日变化百分比
|
||||
*/
|
||||
private Double patientTrend;
|
||||
|
||||
/**
|
||||
* 今日收入
|
||||
*/
|
||||
private String todayRevenue;
|
||||
|
||||
/**
|
||||
* 昨日收入
|
||||
*/
|
||||
private String yesterdayRevenue;
|
||||
|
||||
/**
|
||||
* 相对前日变化百分比
|
||||
*/
|
||||
private Double revenueTrend;
|
||||
|
||||
/**
|
||||
* 今日预约数量
|
||||
*/
|
||||
private Integer todayAppointments;
|
||||
|
||||
/**
|
||||
* 昨日预约数量
|
||||
*/
|
||||
private Integer yesterdayAppointments;
|
||||
|
||||
/**
|
||||
* 相对前日变化百分比
|
||||
*/
|
||||
private Double appointmentTrend;
|
||||
|
||||
/**
|
||||
* 待审核数量
|
||||
*/
|
||||
private Integer pendingApprovals;
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
// 使用接诊医生(ADMITTER,code="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()));
|
||||
|
||||
@@ -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()));
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
// 其他可能需要的字段
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
// 其他可能需要的查询参数
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.openhis.web.service;
|
||||
|
||||
import com.openhis.web.dto.HomeStatisticsDto;
|
||||
|
||||
/**
|
||||
* 首页统计Service接口
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-12-31
|
||||
*/
|
||||
public interface IHomeStatisticsService {
|
||||
/**
|
||||
* 获取首页统计数据
|
||||
*
|
||||
* @return 首页统计数据
|
||||
*/
|
||||
HomeStatisticsDto getHomeStatistics();
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package com.openhis.web.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.core.common.utils.DateUtils;
|
||||
import com.core.common.utils.SecurityUtils;
|
||||
import com.openhis.administration.domain.Encounter;
|
||||
import com.openhis.administration.domain.EncounterParticipant;
|
||||
import com.openhis.administration.domain.Patient;
|
||||
import com.openhis.administration.domain.Practitioner;
|
||||
import com.openhis.administration.service.IEncounterParticipantService;
|
||||
import com.openhis.administration.service.IEncounterService;
|
||||
import com.openhis.administration.service.IPatientService;
|
||||
import com.openhis.administration.service.IPractitionerService;
|
||||
import com.openhis.common.enums.ParticipantType;
|
||||
import com.openhis.web.dto.HomeStatisticsDto;
|
||||
import com.openhis.web.service.IHomeStatisticsService;
|
||||
import com.openhis.web.patientmanage.mapper.PatientManageMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 首页统计Service业务层处理
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-12-31
|
||||
*/
|
||||
@Service
|
||||
public class HomeStatisticsServiceImpl implements IHomeStatisticsService {
|
||||
|
||||
@Autowired
|
||||
private IEncounterService encounterService;
|
||||
|
||||
@Autowired
|
||||
private IEncounterParticipantService encounterParticipantService;
|
||||
|
||||
@Autowired
|
||||
private IPractitionerService practitionerService;
|
||||
|
||||
@Autowired
|
||||
private PatientManageMapper patientManageMapper;
|
||||
|
||||
@Autowired
|
||||
private IPatientService patientService;
|
||||
|
||||
/**
|
||||
* 获取首页统计数据
|
||||
*
|
||||
* @return 首页统计数据
|
||||
*/
|
||||
@Override
|
||||
public HomeStatisticsDto getHomeStatistics() {
|
||||
HomeStatisticsDto statistics = new HomeStatisticsDto();
|
||||
|
||||
// 获取当前登录用户ID
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
|
||||
// 查询当前用户对应的医生信息
|
||||
LambdaQueryWrapper<Practitioner> practitionerQuery = new LambdaQueryWrapper<>();
|
||||
practitionerQuery.eq(Practitioner::getUserId, userId);
|
||||
// 使用list()避免TooManyResultsException异常,然后取第一个记录
|
||||
List<Practitioner> practitionerList = practitionerService.list(practitionerQuery);
|
||||
Practitioner practitioner = practitionerList != null && !practitionerList.isEmpty() ? practitionerList.get(0) : null;
|
||||
|
||||
int totalPatients = 0;
|
||||
|
||||
// 如果当前用户是医生,查询该医生接诊和被挂号的所有患者
|
||||
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()));
|
||||
|
||||
totalPatients = doctorPatientIds != null ? doctorPatientIds.size() : 0;
|
||||
} else {
|
||||
// 如果不是医生,查询所有患者(与患者管理页面逻辑保持一致)
|
||||
LambdaQueryWrapper<Patient> patientQuery = new LambdaQueryWrapper<>();
|
||||
patientQuery.eq(Patient::getDeleteFlag, "0");
|
||||
List<Patient> patientList = patientService.list(patientQuery);
|
||||
totalPatients = patientList != null ? patientList.size() : 0;
|
||||
}
|
||||
|
||||
statistics.setTotalPatients(totalPatients);
|
||||
|
||||
// 查询昨日在院患者数量(暂时简化处理)
|
||||
// TODO: 应该从历史记录表中查询昨天的实际在院患者数
|
||||
int yesterdayPatients = totalPatients; // 这里应该是从历史表中查询昨天的数据
|
||||
statistics.setYesterdayPatients(yesterdayPatients);
|
||||
|
||||
// 计算相对前日的百分比
|
||||
double patientTrend = calculateTrend(totalPatients, yesterdayPatients);
|
||||
statistics.setPatientTrend(patientTrend);
|
||||
|
||||
// 今日收入和预约等其他统计(暂时设为0,后续从相应表查询)
|
||||
statistics.setTodayRevenue("¥ 0");
|
||||
statistics.setYesterdayRevenue("¥ 0");
|
||||
statistics.setRevenueTrend(0.0);
|
||||
statistics.setTodayAppointments(0);
|
||||
statistics.setYesterdayAppointments(0);
|
||||
statistics.setAppointmentTrend(0.0);
|
||||
statistics.setPendingApprovals(0);
|
||||
|
||||
return statistics;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算相对前日的百分比变化
|
||||
*
|
||||
* @param todayValue 今天的值
|
||||
* @param yesterdayValue 昨天的值
|
||||
* @return 百分比变化(正数表示增长,负数表示下降)
|
||||
*/
|
||||
private double calculateTrend(double todayValue, double yesterdayValue) {
|
||||
if (yesterdayValue == 0) {
|
||||
return todayValue > 0 ? 100.0 : 0.0;
|
||||
}
|
||||
return ((todayValue - yesterdayValue) / yesterdayValue) * 100;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user