Compare commits
212 Commits
effcdfbbe6
...
bug/334
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c5353cf8b | ||
|
|
8a84b40ee5 | ||
| f6b39a4815 | |||
|
|
1b3d4e3dc0 | ||
|
|
cb46461ede | ||
| 3b0a359412 | |||
| 6fa26e895d | |||
| 8ab8691c17 | |||
|
|
35b8a7d10a | ||
| 22de02f132 | |||
| 11244aa48f | |||
| 0a5f26e9c0 | |||
| 4a8e9b5a22 | |||
| bfb2491842 | |||
|
|
b747f80507 | ||
| ced931a280 | |||
| b497eb853c | |||
| 7a2342ea2e | |||
|
|
09fdfa294a | ||
|
|
4ef9aa07d2 | ||
| 08085403b3 | |||
| 2d7dcb4aeb | |||
| ad29502488 | |||
| 5b0acede89 | |||
| ac1cd3afc8 | |||
|
|
8a863b4ecb | ||
|
|
882d63249c | ||
|
|
6315ca5658 | ||
|
|
9f802b67f0 | ||
| 6694ae52ba | |||
| 9491ceaa5d | |||
| db9a70a99d | |||
|
|
9105e687d6 | ||
| b1d6c6008e | |||
| 6b9f9a107e | |||
| 11a7f49162 | |||
| b4e5061b73 | |||
| f5a1ad7f3f | |||
| eeac88b1d1 | |||
| 1ab9b020c1 | |||
| 3055518d2b | |||
| 9f619ccdd4 | |||
| df78ff29bd | |||
| 4d13acacc2 | |||
| 67573c1d9d | |||
| b27d8a6703 | |||
| 6f3d4272e6 | |||
| 6e5315fdd6 | |||
| 544d7ee95c | |||
| 7f7f7d69f7 | |||
|
|
ae9a96822e | ||
| bbef0322a3 | |||
| a8a205aa48 | |||
| c052ea7c39 | |||
| 6accaa35c9 | |||
| 466e7296fa | |||
|
|
5678535d88 | ||
| b7993885bb | |||
| 3b8ef380ae | |||
|
|
2334a27467 | ||
|
|
92511c2777 | ||
| 64b02466b1 | |||
| 2ffbe73305 | |||
| 48d3941701 | |||
| 0ad1889029 | |||
| 7dc98dcf84 | |||
| 681fb695bd | |||
| 518d8385e6 | |||
|
|
7073ef0be0 | ||
| 2288162ad7 | |||
| 6f701d7fa6 | |||
| 34253f88b2 | |||
|
|
488c311788 | ||
|
|
b5527cc07f | ||
| 6d23d36a9c | |||
|
|
e2e5999276 | ||
|
|
112ec2e4a3 | ||
| 4b92be10b4 | |||
| 0b361df0a4 | |||
| 3a242074ff | |||
|
|
353f267488 | ||
|
|
2d705d2f81 | ||
| 184871e84f | |||
| ffcdaed087 | |||
| 91a0b48662 | |||
| c509a804ec | |||
| 1a7b6c0cd4 | |||
|
|
11cf88fd49 | ||
| 3f0fa3bbb3 | |||
| d7c15848f0 | |||
|
|
188b907907 | ||
| 71e3601d51 | |||
| f04c3d112c | |||
| 8739959be0 | |||
| 24bc049fa0 | |||
| b42cffdd8a | |||
| 927691a27b | |||
| 6c36ae5340 | |||
| 5473a21418 | |||
| b14c19a887 | |||
| 979dc0a34c | |||
| c2fa13de82 | |||
|
|
77b054a86c | ||
|
|
20eb020071 | ||
|
|
d3deb244c0 | ||
| d20a95c3c4 | |||
| 1f84a641ea | |||
| c542b057b5 | |||
|
|
03d980e0cf | ||
| b03f563df4 | |||
| 8fa0a239b5 | |||
| ee51ab2960 | |||
|
|
22d73e5b44 | ||
| b31cacd930 | |||
| 1440cd45a0 | |||
|
|
07829b93c7 | ||
| c2b1d7d9d9 | |||
| 9f6e94da4b | |||
| e0b9081649 | |||
| e1dc5c895f | |||
|
|
4e58601b2c | ||
| 4060be4de7 | |||
|
|
059078c264 | ||
| cc51d0b345 | |||
| bedad38ca3 | |||
| c15c091718 | |||
| e90e541af3 | |||
|
|
88088c01ac | ||
| 251cf263ff | |||
| f1a4fc87c8 | |||
| d28ac34ae0 | |||
| 4d2a321999 | |||
| b5cf685b13 | |||
|
|
316c1478fc | ||
|
|
24e8a3cfdf | ||
| 888ac1fee3 | |||
| 427d567337 | |||
| 5d73de3072 | |||
| 1fdaafb1e8 | |||
| dbdaba5a6a | |||
| 4210f32a05 | |||
|
|
dc2e4098ae | ||
|
|
83747d8626 | ||
| 68c0c098c8 | |||
| dc1366890f | |||
| f1087b04f0 | |||
|
|
0b4b4f7283 | ||
| d41d3066b3 | |||
| 3bfe25c2f2 | |||
|
|
266b06114a | ||
|
|
6ed41eb513 | ||
|
|
0a8428a4ca | ||
|
|
d058b30872 | ||
| 0c06b05764 | |||
|
|
557f626c05 | ||
| 32bfef6686 | |||
|
|
5795d9eb74 | ||
| 7c29c6359f | |||
|
|
40c5d26dfd | ||
|
|
81c97de170 | ||
| 0cdf332ee7 | |||
| b4e13e1305 | |||
| dd1cd17801 | |||
| 6d87b7c445 | |||
| 0d1710f201 | |||
| a3650aa386 | |||
| 0f9ef726bf | |||
| 8f2405ee34 | |||
|
|
6d59c6491c | ||
| 1e7e0453e6 | |||
| 257ea42db7 | |||
| 872a5308ef | |||
| 32f7077fc1 | |||
| 4f917b0121 | |||
| 8a7d2abb4a | |||
| 03939fb232 | |||
|
|
16f6fbb8cf | ||
| 28f85ceb05 | |||
|
|
b43688e483 | ||
|
|
0bf29a53a4 | ||
|
|
0c70b224f9 | ||
|
|
449209a79b | ||
|
|
d6663c9667 | ||
|
|
53d29cbe14 | ||
|
|
e16a70dd50 | ||
|
|
bba63d2f1b | ||
|
|
f3d011951b | ||
| 7dc76d7b59 | |||
| b2dec2667a | |||
|
|
879d31b51d | ||
|
|
473a5f7f06 | ||
| 2eec988c56 | |||
| 8820048d55 | |||
| 6af7720470 | |||
|
|
5f134945ab | ||
| bc12cc1b08 | |||
| 17b8ea7192 | |||
|
|
2bfdd686c7 | ||
|
|
066cfaba46 | ||
| e8850e85fc | |||
| d083a3123a | |||
| 96c1927f8d | |||
| bdac9d0709 | |||
| 8faba1ea21 | |||
| dd9b77f6bb | |||
| d45955f6de | |||
| f905915f34 | |||
|
|
52951d7296 | ||
| 3c47979913 | |||
| 9aad809322 | |||
| b7850e5b8a | |||
| 4277a369d2 |
@@ -2,5 +2,5 @@
|
||||
"tools": {
|
||||
"approvalMode": "yolo"
|
||||
},
|
||||
"$version": 2
|
||||
"$version": 3
|
||||
}
|
||||
6
.qwen/settings.json.orig
Normal file
6
.qwen/settings.json.orig
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"tools": {
|
||||
"approvalMode": "yolo"
|
||||
},
|
||||
"$version": 2
|
||||
}
|
||||
@@ -1,11 +1,15 @@
|
||||
package com.core.framework.config;
|
||||
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
@@ -24,6 +28,14 @@ public class ApplicationConfig {
|
||||
*/
|
||||
@Bean
|
||||
public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() {
|
||||
return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault());
|
||||
return builder -> {
|
||||
// 设置默认时区
|
||||
builder.timeZone(TimeZone.getDefault());
|
||||
// 设置日期格式为 yyyy/M/d HH:mm:ss,支持多种格式反序列化
|
||||
builder.simpleDateFormat("yyyy/M/d HH:mm:ss");
|
||||
// 添加JavaTimeModule支持,用于LocalDateTime
|
||||
builder.modules(new JavaTimeModule());
|
||||
builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy/M/d HH:mm:ss")));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,9 +54,17 @@ public interface SysUserRoleMapper {
|
||||
/**
|
||||
* 批量取消授权用户角色
|
||||
*
|
||||
* @param roleId 角色ID
|
||||
* @param userIds 需要删除的用户数据ID
|
||||
* @param roleId 角色 ID
|
||||
* @param userIds 需要删除的用户数据 ID
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteUserRoleInfos(@Param("roleId") Long roleId, @Param("userIds") Long[] userIds);
|
||||
|
||||
/**
|
||||
* 通过角色 ID 查询用户 ID 列表
|
||||
*
|
||||
* @param roleId 角色 ID
|
||||
* @return 用户 ID 列表
|
||||
*/
|
||||
public List<Long> selectUserIdsByRoleId(Long roleId);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import com.core.system.mapper.SysRoleDeptMapper;
|
||||
import com.core.system.mapper.SysRoleMapper;
|
||||
import com.core.system.mapper.SysRoleMenuMapper;
|
||||
import com.core.system.mapper.SysUserRoleMapper;
|
||||
import com.core.system.service.ISysMenuService;
|
||||
import com.core.system.service.ISysRoleService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -41,6 +42,9 @@ public class SysRoleServiceImpl implements ISysRoleService {
|
||||
@Autowired
|
||||
private SysRoleDeptMapper roleDeptMapper;
|
||||
|
||||
@Autowired
|
||||
private ISysMenuService menuService;
|
||||
|
||||
/**
|
||||
* 根据条件分页查询角色数据
|
||||
*
|
||||
@@ -221,11 +225,23 @@ public class SysRoleServiceImpl implements ISysRoleService {
|
||||
@Override
|
||||
@Transactional
|
||||
public int updateRole(SysRole role) {
|
||||
// 修改角色信息
|
||||
// 1. 获取该角色下的所有用户 ID(在修改权限前查询)
|
||||
List<Long> userIds = userRoleMapper.selectUserIdsByRoleId(role.getRoleId());
|
||||
|
||||
// 2. 修改角色信息
|
||||
roleMapper.updateRole(role);
|
||||
// 删除角色与菜单关联
|
||||
// 3. 删除角色与菜单关联
|
||||
roleMenuMapper.deleteRoleMenuByRoleId(role.getRoleId());
|
||||
return insertRoleMenu(role);
|
||||
int result = insertRoleMenu(role);
|
||||
|
||||
// 4. 清除该角色下所有用户的菜单树缓存
|
||||
if (userIds != null && !userIds.isEmpty()) {
|
||||
for (Long userId : userIds) {
|
||||
menuService.clearMenuCacheByUserId(userId);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -48,4 +48,10 @@
|
||||
#{userId}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<select id="selectUserIdsByRoleId" resultType="Long">
|
||||
select user_id
|
||||
from sys_user_role
|
||||
where role_id = #{roleId}
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.openhis.web.appointmentmanage.appservice;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.appointmentmanage.domain.AppointmentConfig;
|
||||
|
||||
/**
|
||||
* 预约配置AppService接口
|
||||
*
|
||||
* @author openhis
|
||||
* @date 2026-03-23
|
||||
*/
|
||||
public interface IAppointmentConfigAppService {
|
||||
|
||||
/**
|
||||
* 获取当前机构的预约配置
|
||||
*
|
||||
* @return 预约配置
|
||||
*/
|
||||
R<?> getAppointmentConfig();
|
||||
|
||||
/**
|
||||
* 保存预约配置
|
||||
*
|
||||
* @param appointmentConfig 预约配置
|
||||
* @return 结果
|
||||
*/
|
||||
R<?> saveAppointmentConfig(AppointmentConfig appointmentConfig);
|
||||
}
|
||||
@@ -2,7 +2,9 @@ package com.openhis.web.appointmentmanage.appservice;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.appointmentmanage.dto.TicketQueryDTO;
|
||||
import com.openhis.web.appointmentmanage.dto.TicketDto;
|
||||
import com.openhis.appointmentmanage.dto.TicketQueryDTO;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -14,36 +16,52 @@ import java.util.Map;
|
||||
public interface ITicketAppService {
|
||||
|
||||
/**
|
||||
* 预约号源
|
||||
* 分页查询门诊号源列表(真分页)
|
||||
*
|
||||
* @param params 预约参数
|
||||
* @param query 查询参数
|
||||
* @return 结果
|
||||
*/
|
||||
R<?> bookTicket(Map<String, Object> params);
|
||||
R<?> listTicket(TicketQueryDTO query);
|
||||
|
||||
/**
|
||||
* 查询医生余号汇总(基于号源池,不受分页影响)
|
||||
*
|
||||
* @param query 查询参数
|
||||
* @return 结果
|
||||
*/
|
||||
R<?> listDoctorAvailability(TicketQueryDTO query);
|
||||
|
||||
/**
|
||||
* 预约号源
|
||||
*
|
||||
* @param dto 预约参数
|
||||
* @return 结果
|
||||
*/
|
||||
R<?> bookTicket(com.openhis.appointmentmanage.domain.AppointmentBookDTO dto);
|
||||
|
||||
/**
|
||||
* 取消预约
|
||||
*
|
||||
* @param ticketId 号源ID
|
||||
* @param slotId 槽位ID
|
||||
* @return 结果
|
||||
*/
|
||||
R<?> cancelTicket(Long ticketId);
|
||||
R<?> cancelTicket(Long slotId);
|
||||
|
||||
/**
|
||||
* 取号
|
||||
*
|
||||
* @param ticketId 号源ID
|
||||
* @param slotId 槽位ID
|
||||
* @return 结果
|
||||
*/
|
||||
R<?> checkInTicket(Long ticketId);
|
||||
R<?> checkInTicket(Long slotId);
|
||||
|
||||
/**
|
||||
* 停诊
|
||||
*
|
||||
* @param ticketId 号源ID
|
||||
* @param slotId 槽位ID
|
||||
* @return 结果
|
||||
*/
|
||||
R<?> cancelConsultation(Long ticketId);
|
||||
R<?> cancelConsultation(Long slotId);
|
||||
|
||||
/**
|
||||
* 查询所有号源(用于测试)
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.openhis.web.appointmentmanage.appservice.impl;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.core.common.utils.SecurityUtils;
|
||||
import com.openhis.appointmentmanage.domain.AppointmentConfig;
|
||||
import com.openhis.appointmentmanage.service.IAppointmentConfigService;
|
||||
import com.openhis.web.appointmentmanage.appservice.IAppointmentConfigAppService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 预约配置AppService实现类
|
||||
*
|
||||
* @author openhis
|
||||
* @date 2026-03-23
|
||||
*/
|
||||
@Service
|
||||
public class AppointmentConfigAppServiceImpl implements IAppointmentConfigAppService {
|
||||
|
||||
@Resource
|
||||
private IAppointmentConfigService appointmentConfigService;
|
||||
|
||||
@Override
|
||||
public R<?> getAppointmentConfig() {
|
||||
// 获取当前登录用户的机构ID
|
||||
Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
|
||||
if (tenantId == null) {
|
||||
return R.fail("获取机构信息失败");
|
||||
}
|
||||
|
||||
AppointmentConfig config = appointmentConfigService.getConfigByTenantId(tenantId);
|
||||
return R.ok(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> saveAppointmentConfig(AppointmentConfig appointmentConfig) {
|
||||
// 获取当前登录用户的机构ID
|
||||
Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
|
||||
if (tenantId == null) {
|
||||
return R.fail("获取机构信息失败");
|
||||
}
|
||||
|
||||
// 查询是否已存在配置
|
||||
AppointmentConfig existingConfig = appointmentConfigService.getConfigByTenantId(tenantId);
|
||||
|
||||
if (existingConfig != null) {
|
||||
// 更新现有配置
|
||||
existingConfig.setCancelAppointmentType(appointmentConfig.getCancelAppointmentType());
|
||||
existingConfig.setCancelAppointmentCount(appointmentConfig.getCancelAppointmentCount());
|
||||
existingConfig.setValidFlag(appointmentConfig.getValidFlag());
|
||||
appointmentConfigService.saveOrUpdate(existingConfig);
|
||||
return R.ok(existingConfig);
|
||||
} else {
|
||||
// 新增配置
|
||||
appointmentConfig.setTenantId(tenantId);
|
||||
appointmentConfig.setValidFlag(1);
|
||||
appointmentConfigService.saveOrUpdateConfig(appointmentConfig);
|
||||
return R.ok(appointmentConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -118,6 +118,7 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
|
||||
newSchedule.setIsStopped(doctorSchedule.getIsStopped() != null ? doctorSchedule.getIsStopped() : false);
|
||||
newSchedule.setStopReason(doctorSchedule.getStopReason() != null ? doctorSchedule.getStopReason() : "");
|
||||
newSchedule.setDeptId(doctorSchedule.getDeptId());
|
||||
newSchedule.setRegType(doctorSchedule.getRegType() != null ? doctorSchedule.getRegType() : 0);
|
||||
newSchedule.setDoctorId(doctorSchedule.getDoctorId());
|
||||
|
||||
// 不设置id字段,让数据库自动生成
|
||||
@@ -162,6 +163,30 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
|
||||
return R.fail("限号数量必须大于0");
|
||||
}
|
||||
|
||||
// 检查结束时间必须大于开始时间
|
||||
if (doctorSchedule.getStartTime() != null && doctorSchedule.getEndTime() != null) {
|
||||
if (!doctorSchedule.getStartTime().isBefore(doctorSchedule.getEndTime())) {
|
||||
return R.fail("结束时间必须大于开始时间");
|
||||
}
|
||||
}
|
||||
|
||||
// 检查时间重叠(同一医生、同一天时间段有重叠)
|
||||
if (doctorSchedule.getDoctorId() != null && scheduledDate != null
|
||||
&& doctorSchedule.getStartTime() != null && doctorSchedule.getEndTime() != null) {
|
||||
LocalDate scheduleDate = LocalDate.parse(scheduledDate);
|
||||
boolean hasOverlap = checkTimeOverlap(
|
||||
doctorSchedule.getDoctorId(),
|
||||
scheduleDate,
|
||||
doctorSchedule.getStartTime(),
|
||||
doctorSchedule.getEndTime()
|
||||
);
|
||||
if (hasOverlap) {
|
||||
return R.fail("该医生在 " + scheduledDate + " 的 "
|
||||
+ doctorSchedule.getStartTime() + "-" + doctorSchedule.getEndTime()
|
||||
+ " 时间段与已有排班重叠,不能重复添加");
|
||||
}
|
||||
}
|
||||
|
||||
// 创建新对象,排除id字段(数据库id列是GENERATED ALWAYS,由数据库自动生成)
|
||||
DoctorSchedule newSchedule = new DoctorSchedule();
|
||||
newSchedule.setWeekday(doctorSchedule.getWeekday());
|
||||
@@ -183,6 +208,7 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
|
||||
newSchedule.setIsStopped(doctorSchedule.getIsStopped() != null ? doctorSchedule.getIsStopped() : false);
|
||||
newSchedule.setStopReason(doctorSchedule.getStopReason() != null ? doctorSchedule.getStopReason() : "");
|
||||
newSchedule.setDeptId(doctorSchedule.getDeptId());
|
||||
newSchedule.setRegType(doctorSchedule.getRegType() != null ? doctorSchedule.getRegType() : 0);
|
||||
newSchedule.setDoctorId(doctorSchedule.getDoctorId());
|
||||
|
||||
// 不设置id字段,让数据库自动生成
|
||||
@@ -213,14 +239,51 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public R<?> updateDoctorSchedule(DoctorSchedule doctorSchedule) {
|
||||
if (ObjectUtil.isEmpty(doctorSchedule) || ObjectUtil.isEmpty(doctorSchedule.getId())) {
|
||||
return R.fail("医生排班ID不能为空");
|
||||
}
|
||||
// 注意:此为核心更新,暂未处理号源池和号源槽的同步更新
|
||||
|
||||
int result = doctorScheduleMapper.updateDoctorSchedule(doctorSchedule);
|
||||
return result > 0 ? R.ok(result) : R.fail("更新排班信息失败");
|
||||
if (result <= 0) {
|
||||
return R.fail("更新排班信息失败");
|
||||
}
|
||||
|
||||
// 同步更新号源池,避免查询联表时医生/诊室等字段看起来“未更新”
|
||||
boolean needSyncPool = doctorSchedule.getDoctorId() != null
|
||||
|| doctorSchedule.getDoctor() != null
|
||||
|| doctorSchedule.getClinic() != null
|
||||
|| doctorSchedule.getStartTime() != null
|
||||
|| doctorSchedule.getEndTime() != null
|
||||
|| doctorSchedule.getLimitNumber() != null
|
||||
|| doctorSchedule.getStopReason() != null
|
||||
|| doctorSchedule.getRegType() != null
|
||||
|| doctorSchedule.getRegisterFee() != null
|
||||
|| doctorSchedule.getRegisterItem() != null
|
||||
|| doctorSchedule.getDiagnosisItem() != null
|
||||
|| doctorSchedule.getDiagnosisFee() != null;
|
||||
|
||||
if (needSyncPool) {
|
||||
schedulePoolService.lambdaUpdate()
|
||||
.eq(SchedulePool::getScheduleId, doctorSchedule.getId())
|
||||
.set(doctorSchedule.getDoctorId() != null, SchedulePool::getDoctorId, doctorSchedule.getDoctorId())
|
||||
.set(doctorSchedule.getDoctor() != null, SchedulePool::getDoctorName, doctorSchedule.getDoctor())
|
||||
.set(doctorSchedule.getClinic() != null, SchedulePool::getClinicRoom, doctorSchedule.getClinic())
|
||||
.set(doctorSchedule.getStartTime() != null, SchedulePool::getStartTime, doctorSchedule.getStartTime())
|
||||
.set(doctorSchedule.getEndTime() != null, SchedulePool::getEndTime, doctorSchedule.getEndTime())
|
||||
.set(doctorSchedule.getLimitNumber() != null, SchedulePool::getTotalQuota,
|
||||
doctorSchedule.getLimitNumber())
|
||||
.set(doctorSchedule.getStopReason() != null, SchedulePool::getStopReason, doctorSchedule.getStopReason())
|
||||
.set(doctorSchedule.getRegType() != null, SchedulePool::getRegType, String.valueOf(doctorSchedule.getRegType()))
|
||||
.set(doctorSchedule.getRegisterFee() != null, SchedulePool::getFee, Double.valueOf(doctorSchedule.getRegisterFee().toString()))
|
||||
.set(doctorSchedule.getRegisterFee() != null, SchedulePool::getInsurancePrice,
|
||||
Double.valueOf(doctorSchedule.getRegisterFee().toString()))
|
||||
.update();
|
||||
}
|
||||
|
||||
return R.ok(result);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -246,7 +309,7 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
|
||||
// 不设置available_num,因为它是数据库生成列
|
||||
// pool.setAvailableNum(0); // 初始为0,稍后更新
|
||||
pool.setRegType(schedule.getRegisterItem() != null ? schedule.getRegisterItem() : "普通");
|
||||
pool.setFee(schedule.getRegisterFee() != null ? schedule.getRegisterFee() / 100.0 : 0.0); // 假设数据库中以分为单位存储
|
||||
pool.setFee(schedule.getRegisterFee() != null ? Double.valueOf(schedule.getRegisterFee().toString()) : 0.0); // 直接使用原始价格
|
||||
pool.setInsurancePrice(pool.getFee()); // 医保价格暂时与原价相同
|
||||
// 暂时设置support_channel为空字符串,避免JSON类型问题
|
||||
pool.setSupportChannel("");
|
||||
@@ -299,7 +362,7 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
|
||||
// 不设置available_num,因为它是数据库生成列
|
||||
// pool.setAvailableNum(0); // 初始为0,稍后更新
|
||||
pool.setRegType(schedule.getRegisterItem() != null ? schedule.getRegisterItem() : "普通");
|
||||
pool.setFee(schedule.getRegisterFee() != null ? schedule.getRegisterFee() / 100.0 : 0.0); // 假设数据库中以分为单位存储
|
||||
pool.setFee(schedule.getRegisterFee() != null ? Double.valueOf(schedule.getRegisterFee().toString()) : 0.0); // 直接使用原始价格
|
||||
pool.setInsurancePrice(pool.getFee()); // 医保价格暂时与原价相同
|
||||
// 暂时设置support_channel为空字符串,避免JSON类型问题
|
||||
pool.setSupportChannel("");
|
||||
@@ -345,6 +408,42 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
|
||||
return slots;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查同一医生、同一天、同时段是否已存在排班
|
||||
*
|
||||
* @param doctorId 医生ID
|
||||
* @param scheduleDate 出诊日期
|
||||
* @param timePeriod 时段(上午/下午)
|
||||
* @return true表示存在重复排班,false表示不存在
|
||||
*/
|
||||
// private boolean checkDuplicateSchedule(Long doctorId, LocalDate scheduleDate, String timePeriod) {
|
||||
// return schedulePoolService.lambdaQuery()
|
||||
// .eq(SchedulePool::getDoctorId, doctorId)
|
||||
// .eq(SchedulePool::getScheduleDate, scheduleDate)
|
||||
// .eq(SchedulePool::getShift, timePeriod)
|
||||
// .exists();
|
||||
// }
|
||||
|
||||
/**
|
||||
* 检查同一医生、同一天是否有时间重叠的排班
|
||||
* 重叠判断:startA < endB AND startB < endA(即时间段有交集)
|
||||
*
|
||||
* @param doctorId 医生ID
|
||||
* @param scheduleDate 出诊日期
|
||||
* @param startTime 开始时间
|
||||
* @param endTime 结束时间
|
||||
* @return true表示存在时间重叠,false表示不重叠
|
||||
*/
|
||||
private boolean checkTimeOverlap(Long doctorId, LocalDate scheduleDate,
|
||||
LocalTime startTime, LocalTime endTime) {
|
||||
return schedulePoolService.lambdaQuery()
|
||||
.eq(SchedulePool::getDoctorId, doctorId)
|
||||
.eq(SchedulePool::getScheduleDate, scheduleDate)
|
||||
.lt(SchedulePool::getStartTime, endTime) // 已有开始时间 < 新结束时间
|
||||
.gt(SchedulePool::getEndTime, startTime) // 已有结束时间 > 新开始时间
|
||||
.exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据星期几计算具体日期(下周的对应星期)
|
||||
*/
|
||||
|
||||
@@ -4,28 +4,22 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.administration.domain.Patient;
|
||||
import com.openhis.administration.service.IPatientService;
|
||||
import com.openhis.appointmentmanage.domain.DoctorSchedule;
|
||||
import com.openhis.appointmentmanage.mapper.DoctorScheduleMapper;
|
||||
import com.openhis.appointmentmanage.service.IDoctorScheduleService;
|
||||
import com.openhis.clinical.domain.Order;
|
||||
import com.openhis.appointmentmanage.mapper.ScheduleSlotMapper;
|
||||
import com.openhis.clinical.domain.Ticket;
|
||||
import com.openhis.clinical.mapper.OrderMapper;
|
||||
import com.openhis.clinical.service.ITicketService;
|
||||
import com.openhis.web.appointmentmanage.appservice.IDoctorScheduleAppService;
|
||||
import com.openhis.web.appointmentmanage.appservice.ITicketAppService;
|
||||
import com.openhis.web.appointmentmanage.dto.TicketDto;
|
||||
import com.openhis.common.constant.CommonConstants.SlotStatus;
|
||||
import com.openhis.common.constant.CommonConstants.AppointmentOrderStatus;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Locale;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* 号源管理应用服务实现类
|
||||
*
|
||||
@@ -36,73 +30,41 @@ public class TicketAppServiceImpl implements ITicketAppService {
|
||||
|
||||
@Resource
|
||||
private ITicketService ticketService;
|
||||
|
||||
@Resource
|
||||
private ScheduleSlotMapper scheduleSlotMapper;
|
||||
@Resource
|
||||
private IPatientService patientService;
|
||||
@Resource
|
||||
private IDoctorScheduleAppService doctorScheduleAppService;
|
||||
@Resource
|
||||
private DoctorScheduleMapper doctorScheduleMapper;
|
||||
@Resource
|
||||
private OrderMapper orderMapper;
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(TicketAppServiceImpl.class);
|
||||
|
||||
/**
|
||||
* 预约号源
|
||||
* 预约号源 (重构版:精准锁定单一槽位)
|
||||
*
|
||||
* @param params 预约参数
|
||||
* @param dto 预约参数
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> bookTicket(Map<String, Object> params) {
|
||||
// 1. 获取 ticketId 和 slotId
|
||||
Long ticketId = null;
|
||||
Long slotId = null;
|
||||
if (params.get("ticketId") != null) {
|
||||
ticketId = Long.valueOf(params.get("ticketId").toString());
|
||||
public R<?> bookTicket(com.openhis.appointmentmanage.domain.AppointmentBookDTO dto) {
|
||||
Long slotId = dto.getSlotId();
|
||||
if (slotId == null) {
|
||||
return R.fail("参数校验失败:缺少排班槽位唯一标识");
|
||||
}
|
||||
if (params.get("slotId") != null) {
|
||||
slotId = Long.valueOf(params.get("slotId").toString());
|
||||
}
|
||||
// 2. 参数校验
|
||||
if (ticketId == null || slotId == null) {
|
||||
return R.fail("参数错误:ticketId 或 slotId 不能为空");
|
||||
}
|
||||
|
||||
try {
|
||||
// 3. 执行原有的预约逻辑
|
||||
int result = ticketService.bookTicket(params);
|
||||
int result = ticketService.bookTicket(dto);
|
||||
if (result > 0) {
|
||||
// 4. 预约成功后,更新排班表状态
|
||||
DoctorSchedule schedule = new DoctorSchedule();
|
||||
schedule.setId(slotId); // 对应 XML 中的 WHERE id = #{id}
|
||||
schedule.setIsStopped(true); // 设置为已预约
|
||||
schedule.setStopReason("booked"); // 设置停用原因
|
||||
|
||||
// 执行更新
|
||||
int updateCount = doctorScheduleMapper.updateDoctorSchedule(schedule);
|
||||
|
||||
if (updateCount > 0) {
|
||||
return R.ok("预约成功并已更新排班状态");
|
||||
} else {
|
||||
// 如果更新失败,可能需要根据业务逻辑决定是否回滚预约
|
||||
return R.ok("预约成功,但排班状态更新失败");
|
||||
}
|
||||
} else {
|
||||
return R.fail("预约失败");
|
||||
return R.ok("预约成功!号源已安全锁定。");
|
||||
}
|
||||
return R.fail("预约挂单核发失败");
|
||||
} catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
log.error(e.getMessage());
|
||||
log.error("大厅挂号捕获系统异常", e);
|
||||
return R.fail("系统异常:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消预约
|
||||
* 取消预约 (重构版:精准释放单一槽位)
|
||||
*
|
||||
* @param slotId 医生排班ID
|
||||
* @param slotId 医生槽位排班ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@@ -111,18 +73,8 @@ public class TicketAppServiceImpl implements ITicketAppService {
|
||||
return R.fail("参数错误");
|
||||
}
|
||||
try {
|
||||
ticketService.cancelTicket(slotId);
|
||||
DoctorSchedule schedule = new DoctorSchedule();
|
||||
schedule.setId(slotId); // 对应 WHERE id = #{id}
|
||||
schedule.setIsStopped(false); // 设置为 false
|
||||
schedule.setStopReason(""); // 将原因清空 (设为空字符串)
|
||||
// 3. 调用自定义更新方法
|
||||
int updateCount = doctorScheduleMapper.updateDoctorSchedule(schedule);
|
||||
if (updateCount > 0) {
|
||||
return R.ok("取消成功");
|
||||
} else {
|
||||
return R.ok("取消成功");
|
||||
}
|
||||
int result = ticketService.cancelTicket(slotId);
|
||||
return R.ok(result > 0 ? "取消成功,号源已重新释放回市场" : "取消失败");
|
||||
} catch (Exception e) {
|
||||
return R.fail(e.getMessage());
|
||||
}
|
||||
@@ -131,16 +83,16 @@ public class TicketAppServiceImpl implements ITicketAppService {
|
||||
/**
|
||||
* 取号
|
||||
*
|
||||
* @param ticketId 号源ID
|
||||
* @param slotId 槽位ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> checkInTicket(Long ticketId) {
|
||||
if (ticketId == null) {
|
||||
public R<?> checkInTicket(Long slotId) {
|
||||
if (slotId == null) {
|
||||
return R.fail("参数错误");
|
||||
}
|
||||
try {
|
||||
int result = ticketService.checkInTicket(ticketId);
|
||||
int result = ticketService.checkInTicket(slotId);
|
||||
return R.ok(result > 0 ? "取号成功" : "取号失败");
|
||||
} catch (Exception e) {
|
||||
return R.fail(e.getMessage());
|
||||
@@ -150,16 +102,16 @@ public class TicketAppServiceImpl implements ITicketAppService {
|
||||
/**
|
||||
* 停诊
|
||||
*
|
||||
* @param ticketId 号源ID
|
||||
* @param slotId 槽位ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> cancelConsultation(Long ticketId) {
|
||||
if (ticketId == null) {
|
||||
public R<?> cancelConsultation(Long slotId) {
|
||||
if (slotId == null) {
|
||||
return R.fail("参数错误");
|
||||
}
|
||||
try {
|
||||
int result = ticketService.cancelConsultation(ticketId);
|
||||
int result = ticketService.cancelConsultation(slotId);
|
||||
return R.ok(result > 0 ? "停诊成功" : "停诊失败");
|
||||
} catch (Exception e) {
|
||||
return R.fail(e.getMessage());
|
||||
@@ -167,92 +119,283 @@ public class TicketAppServiceImpl implements ITicketAppService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> listAllTickets() {
|
||||
// 1. 从 AppService 获取排班数据
|
||||
R<?> response = doctorScheduleAppService.getDoctorScheduleList();
|
||||
// 获取返回的 List 数据 (假设 R.ok 里的数据是 List<DoctorSchedule>)
|
||||
List<DoctorSchedule> scheduleList = (List<DoctorSchedule>) response.getData();
|
||||
public R<?> listTicket(com.openhis.appointmentmanage.dto.TicketQueryDTO query) {
|
||||
// 1. 防空指针处理
|
||||
if (query == null) {
|
||||
query = new com.openhis.appointmentmanage.dto.TicketQueryDTO();
|
||||
}
|
||||
normalizeQueryStatus(query);
|
||||
|
||||
// 2. 转换数据为 TicketDto
|
||||
List<TicketDto> tickets = new ArrayList<>();
|
||||
// 2. 构造 MyBatis 的分页对象 (传入前端给的当前页和每页条数)
|
||||
com.baomidou.mybatisplus.extension.plugins.pagination.Page<com.openhis.appointmentmanage.domain.TicketSlotDTO> pageParam = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(
|
||||
query.getPage(), query.getLimit());
|
||||
|
||||
if (scheduleList != null) {
|
||||
for (DoctorSchedule schedule : scheduleList) {
|
||||
// 3. 调用刚才写的底层动态 SQL 查询!
|
||||
com.baomidou.mybatisplus.extension.plugins.pagination.Page<com.openhis.appointmentmanage.domain.TicketSlotDTO> rawPage = scheduleSlotMapper
|
||||
.selectTicketSlotsPage(pageParam, query);
|
||||
|
||||
// 4. 将查出来的数据翻译为前端可以直接渲染的结构
|
||||
java.util.List<TicketDto> tickets = new java.util.ArrayList<>();
|
||||
if (rawPage.getRecords() != null) {
|
||||
for (com.openhis.appointmentmanage.domain.TicketSlotDTO raw : rawPage.getRecords()) {
|
||||
TicketDto dto = new TicketDto();
|
||||
|
||||
// 基础信息映射
|
||||
dto.setSlot_id(Long.valueOf(schedule.getId())); // Integer 转 Long
|
||||
dto.setBusNo(String.valueOf(schedule.getId())); // 生成一个业务编号
|
||||
dto.setDepartment(String.valueOf(schedule.getDeptId())); // 如果有科室名建议关联查询,这里暂填ID
|
||||
dto.setDoctor(schedule.getDoctor());
|
||||
// 基础字段映射
|
||||
dto.setSlot_id(raw.getSlotId());
|
||||
dto.setSeqNo(raw.getSeqNo());
|
||||
dto.setBusNo(String.valueOf(raw.getSlotId()));
|
||||
dto.setDoctor(raw.getDoctor());
|
||||
dto.setDepartment(raw.getDepartmentName()); // 注意:以前这里传成了ID,导致前端出Bug,现在修复成了真正的科室名
|
||||
dto.setFee(raw.getFee());
|
||||
dto.setPatientName(raw.getPatientName());
|
||||
dto.setPatientId(raw.getMedicalCard());
|
||||
dto.setPhone(raw.getPhone());
|
||||
dto.setIdCard(raw.getIdCard());
|
||||
dto.setDoctorId(raw.getDoctorId());
|
||||
dto.setDepartmentId(raw.getDepartmentId());
|
||||
dto.setRealPatientId(raw.getPatientId());
|
||||
|
||||
// 号源类型处理:根据挂号项目判断是普通号还是专家号
|
||||
String registerItem = schedule.getRegisterItem();
|
||||
if (registerItem != null && registerItem.contains("专家")) {
|
||||
// 性别处理:直接读取优先级最高的订单性别字段 (SQL 已处理优先级)
|
||||
if (raw.getPatientGender() != null) {
|
||||
String pg = raw.getPatientGender().trim();
|
||||
dto.setGender("1".equals(pg) ? "男" : ("2".equals(pg) ? "女" : "未知"));
|
||||
} else {
|
||||
dto.setGender("未知");
|
||||
}
|
||||
|
||||
if (raw.getRegType() != null && raw.getRegType() == 1) {
|
||||
dto.setTicketType("expert");
|
||||
} else {
|
||||
dto.setTicketType("general");
|
||||
}
|
||||
// 时间处理:格式化为日期+时间范围,如 "2025-12-01 08:00-12:00"
|
||||
String currentDate = LocalDate.now().toString(); // 或者从schedule中获取具体日期
|
||||
String timeRange = schedule.getStartTime() + "-" + schedule.getEndTime();
|
||||
dto.setDateTime(currentDate + " " + timeRange);
|
||||
LocalTime nowTime = LocalTime.now();
|
||||
LocalTime endTime = schedule.getEndTime();
|
||||
String stopReason1 = schedule.getStopReason();
|
||||
if ("cancelled".equals(stopReason1)||(endTime != null && nowTime.isAfter(endTime))) {
|
||||
dto.setStatus("已停诊");
|
||||
}else if (Boolean.TRUE.equals(schedule.getIsStopped())) {
|
||||
// 获取原因并处理可能的空值
|
||||
String stopReason = schedule.getStopReason();
|
||||
// 使用 .equals() 比较内容,并将常量放在前面防止空指针
|
||||
if ("booked".equals(stopReason)) {
|
||||
dto.setStatus("已预约");
|
||||
// --- 新增:获取患者信息 ---
|
||||
List<Order> Order = orderMapper.selectOrderBySlotId(Long.valueOf(schedule.getId()));
|
||||
Order latestOrder=Order.get(0);
|
||||
|
||||
if (latestOrder != null) {
|
||||
dto.setPatientName(latestOrder.getPatientName());
|
||||
dto.setPatientId(String.valueOf(latestOrder.getPatientId()));
|
||||
dto.setPhone(latestOrder.getPhone());
|
||||
if (raw.getScheduleDate() != null && raw.getExpectTime() != null) {
|
||||
dto.setDateTime(raw.getScheduleDate().toString() + " " + raw.getExpectTime().toString());
|
||||
try {
|
||||
String timeStr = raw.getAppointmentTime() != null ? raw.getAppointmentTime() : (raw.getScheduleDate().toString() + " " + raw.getExpectTime().toString());
|
||||
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(timeStr.length() > 10 ? "yyyy-MM-dd HH:mm" : "yyyy-MM-dd");
|
||||
java.util.Date date = sdf.parse(timeStr);
|
||||
dto.setAppointmentDate(date);
|
||||
dto.setAppointmentTime(date);
|
||||
} catch (Exception e) {
|
||||
dto.setAppointmentDate(new java.util.Date());
|
||||
}
|
||||
// -----------------------
|
||||
} else if ("checked".equals(stopReason)) {
|
||||
}
|
||||
|
||||
if (Boolean.TRUE.equals(raw.getIsStopped())) {
|
||||
dto.setStatus("已停诊");
|
||||
} else {
|
||||
Integer slotStatus = raw.getSlotStatus();
|
||||
if (slotStatus != null) {
|
||||
if (SlotStatus.CHECKED_IN.equals(slotStatus)) {
|
||||
dto.setStatus("已取号");
|
||||
} else if (SlotStatus.BOOKED.equals(slotStatus)) {
|
||||
if (AppointmentOrderStatus.CHECKED_IN.equals(raw.getOrderStatus())) {
|
||||
dto.setStatus("已取号");
|
||||
} else if (AppointmentOrderStatus.RETURNED.equals(raw.getOrderStatus())) {
|
||||
dto.setStatus("已退号");
|
||||
} else {
|
||||
// 兜底逻辑:如果 is_stopped 为 true 但没有匹配到原因
|
||||
dto.setStatus("不可预约");
|
||||
dto.setStatus("已预约");
|
||||
}
|
||||
} else if (SlotStatus.RETURNED.equals(slotStatus)) {
|
||||
dto.setStatus("已退号");
|
||||
} else if (SlotStatus.CANCELLED.equals(slotStatus)) {
|
||||
dto.setStatus("已停诊");
|
||||
} else if (SlotStatus.LOCKED.equals(slotStatus)) {
|
||||
dto.setStatus("已锁定");
|
||||
} else {
|
||||
dto.setStatus("未预约");
|
||||
}
|
||||
} else {
|
||||
// is_stopped 为 false 或 null 时
|
||||
dto.setStatus("未预约");
|
||||
}
|
||||
|
||||
// 费用处理 (挂号费 + 诊疗费)
|
||||
int totalFee = schedule.getRegisterFee() + schedule.getDiagnosisFee();
|
||||
dto.setFee(String.valueOf(totalFee));
|
||||
|
||||
// 日期处理:LocalDateTime 转 Date
|
||||
if (schedule.getCreateTime() != null) {
|
||||
// 1. 先转成 Instant
|
||||
Instant instant = schedule.getCreateTime().toInstant();
|
||||
// 2. 结合时区转成 ZonedDateTime
|
||||
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
|
||||
// 3. 再转回 Date (如果 DTO 需要的是 Date)
|
||||
dto.setAppointmentDate(Date.from(zdt.toInstant()));
|
||||
}
|
||||
|
||||
tickets.add(dto);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 封装分页响应结构
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
// 5. 按照前端组件需要的【真分页】格式进行包装,并返回
|
||||
java.util.Map<String, Object> result = new java.util.HashMap<>();
|
||||
result.put("list", tickets);
|
||||
result.put("total", rawPage.getTotal()); // 这个 total 就是底层用 COUNT(*) 算出来的真实总条数!
|
||||
result.put("page", query.getPage());
|
||||
result.put("limit", query.getLimit());
|
||||
|
||||
return R.ok(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一状态入参,避免前端状态值大小写/中文/数字差异导致 SQL 条件失效后回全量数据
|
||||
*/
|
||||
private void normalizeQueryStatus(com.openhis.appointmentmanage.dto.TicketQueryDTO query) {
|
||||
String rawStatus = query.getStatus();
|
||||
if (rawStatus == null) {
|
||||
return;
|
||||
}
|
||||
String normalized = rawStatus.trim();
|
||||
if (normalized.isEmpty()) {
|
||||
query.setStatus(null);
|
||||
return;
|
||||
}
|
||||
String lower = normalized.toLowerCase(Locale.ROOT);
|
||||
switch (lower) {
|
||||
case "all":
|
||||
case "全部":
|
||||
query.setStatus("all");
|
||||
break;
|
||||
case "unbooked":
|
||||
case "0":
|
||||
case "未预约":
|
||||
query.setStatus("unbooked");
|
||||
break;
|
||||
case "booked":
|
||||
case "1":
|
||||
case "已预约":
|
||||
query.setStatus("booked");
|
||||
break;
|
||||
case "checked":
|
||||
case "checkin":
|
||||
case "checkedin":
|
||||
case "2":
|
||||
case "已取号":
|
||||
query.setStatus("checked");
|
||||
break;
|
||||
case "cancelled":
|
||||
case "canceled":
|
||||
case "3":
|
||||
case "已停诊":
|
||||
case "已取消":
|
||||
query.setStatus("cancelled");
|
||||
break;
|
||||
case "returned":
|
||||
case "4":
|
||||
case "5":
|
||||
case "已退号":
|
||||
query.setStatus("returned");
|
||||
break;
|
||||
default:
|
||||
// 设置为 impossible 值,配合 mapper 的 otherwise 分支直接返回空
|
||||
query.setStatus("__invalid__");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> listDoctorAvailability(com.openhis.appointmentmanage.dto.TicketQueryDTO query) {
|
||||
if (query == null) {
|
||||
query = new com.openhis.appointmentmanage.dto.TicketQueryDTO();
|
||||
}
|
||||
|
||||
java.util.List<com.openhis.appointmentmanage.domain.DoctorAvailabilityDTO> rawList = scheduleSlotMapper
|
||||
.selectDoctorAvailabilitySummary(query);
|
||||
java.util.List<java.util.Map<String, Object>> doctors = new java.util.ArrayList<>();
|
||||
if (rawList != null) {
|
||||
for (com.openhis.appointmentmanage.domain.DoctorAvailabilityDTO item : rawList) {
|
||||
java.util.Map<String, Object> row = new java.util.HashMap<>();
|
||||
String doctorName = item.getDoctorName();
|
||||
Long doctorId = item.getDoctorId();
|
||||
row.put("id", doctorId != null ? String.valueOf(doctorId) : doctorName);
|
||||
row.put("name", doctorName);
|
||||
row.put("available", item.getAvailable() == null ? 0 : item.getAvailable());
|
||||
row.put("type", item.getTicketType() == null ? "general" : item.getTicketType());
|
||||
doctors.add(row);
|
||||
}
|
||||
}
|
||||
return R.ok(doctors);
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> listAllTickets() {
|
||||
// 1. 调用最新的 Mapper,直接从数据库抽出我们半成品的 DTO(强类型!)
|
||||
List<com.openhis.appointmentmanage.domain.TicketSlotDTO> rawDtos = scheduleSlotMapper.selectAllTicketSlots();
|
||||
|
||||
// 这是真正要发给前端展示的包裹外卖盒
|
||||
List<TicketDto> tickets = new ArrayList<>();
|
||||
|
||||
if (rawDtos != null) {
|
||||
for (com.openhis.appointmentmanage.domain.TicketSlotDTO raw : rawDtos) {
|
||||
TicketDto dto = new TicketDto();
|
||||
|
||||
// --- 基础字段处理 ---
|
||||
// 注意:这里已经变成了极其舒服的 .getSlotId() 方法调用,告别魔鬼字符串!
|
||||
dto.setSlot_id(raw.getSlotId());
|
||||
dto.setSeqNo(raw.getSeqNo());
|
||||
dto.setBusNo(String.valueOf(raw.getSlotId())); // 暂时借用真实槽位ID做唯一流水号
|
||||
dto.setDoctor(raw.getDoctor());
|
||||
dto.setDepartment(raw.getDepartmentName());
|
||||
dto.setFee(raw.getFee());
|
||||
dto.setPatientName(raw.getPatientName());
|
||||
dto.setPatientId(raw.getMedicalCard());
|
||||
dto.setPhone(raw.getPhone());
|
||||
|
||||
// --- 号源类型处理 (普通/专家) ---
|
||||
// 改用底层 adm_doctor_schedule 传来的标准数字字典:0=普通,1=专家
|
||||
if (raw.getRegType() != null && raw.getRegType() == 1) {
|
||||
dto.setTicketType("expert");
|
||||
} else {
|
||||
dto.setTicketType("general");
|
||||
}
|
||||
|
||||
// --- 就诊时间严谨拼接 ---
|
||||
// 拼接出来给前端展示的,如 "2026-03-20 08:30"
|
||||
if (raw.getScheduleDate() != null && raw.getExpectTime() != null) {
|
||||
dto.setDateTime(raw.getScheduleDate().toString() + " " + raw.getExpectTime().toString());
|
||||
try {
|
||||
String timeStr = raw.getAppointmentTime() != null ? raw.getAppointmentTime() : (raw.getScheduleDate().toString() + " " + raw.getExpectTime().toString());
|
||||
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(timeStr.length() > 10 ? "yyyy-MM-dd HH:mm" : "yyyy-MM-dd");
|
||||
java.util.Date date = sdf.parse(timeStr);
|
||||
dto.setAppointmentDate(date);
|
||||
dto.setAppointmentTime(date);
|
||||
} catch (Exception e) {
|
||||
log.error("时间解析失败", e);
|
||||
dto.setAppointmentDate(new java.util.Date());
|
||||
}
|
||||
}
|
||||
|
||||
// --- 核心逻辑:精准状态分类 ---
|
||||
// 第一关:底层硬性停诊拦截
|
||||
if (Boolean.TRUE.equals(raw.getIsStopped())) {
|
||||
dto.setStatus("已停诊");
|
||||
} else {
|
||||
// 第二关:看独立的细分槽位状态 (0: 可用, 1: 已预约, 2: 已取消...)
|
||||
Integer slotStatus = raw.getSlotStatus();
|
||||
if (slotStatus != null) {
|
||||
if (SlotStatus.CHECKED_IN.equals(slotStatus)) {
|
||||
dto.setStatus("已取号");
|
||||
} else if (SlotStatus.BOOKED.equals(slotStatus)) {
|
||||
if (AppointmentOrderStatus.CHECKED_IN.equals(raw.getOrderStatus())) {
|
||||
dto.setStatus("已取号");
|
||||
} else if (AppointmentOrderStatus.RETURNED.equals(raw.getOrderStatus())) {
|
||||
dto.setStatus("已退号");
|
||||
} else {
|
||||
dto.setStatus("已预约");
|
||||
}
|
||||
} else if (SlotStatus.RETURNED.equals(slotStatus)) {
|
||||
dto.setStatus("已退号");
|
||||
} else if (SlotStatus.CANCELLED.equals(slotStatus)) {
|
||||
dto.setStatus("已停诊");
|
||||
} else if (SlotStatus.LOCKED.equals(slotStatus)) {
|
||||
dto.setStatus("已锁定");
|
||||
} else {
|
||||
dto.setStatus("未预约");
|
||||
}
|
||||
} else {
|
||||
dto.setStatus("未预约");
|
||||
}
|
||||
}
|
||||
|
||||
tickets.add(dto);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 封装分页响应结构并吐给前端
|
||||
java.util.Map<String, Object> result = new java.util.HashMap<>();
|
||||
result.put("list", tickets);
|
||||
result.put("total", tickets.size());
|
||||
result.put("page", 1);
|
||||
result.put("limit", 20);
|
||||
|
||||
return R.ok(result);
|
||||
}
|
||||
|
||||
@@ -312,14 +455,11 @@ public class TicketAppServiceImpl implements ITicketAppService {
|
||||
if (patient != null) {
|
||||
Integer genderEnum = patient.getGenderEnum();
|
||||
if (genderEnum != null) {
|
||||
switch (genderEnum) {
|
||||
case 1:
|
||||
if (Integer.valueOf(1).equals(genderEnum)) {
|
||||
dto.setGender("男");
|
||||
break;
|
||||
case 2:
|
||||
} else if (Integer.valueOf(2).equals(genderEnum)) {
|
||||
dto.setGender("女");
|
||||
break;
|
||||
default:
|
||||
} else {
|
||||
dto.setGender("未知");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package com.openhis.web.appointmentmanage.controller;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.appointmentmanage.domain.AppointmentConfig;
|
||||
import com.openhis.web.appointmentmanage.appservice.IAppointmentConfigAppService;
|
||||
import com.openhis.web.appointmentmanage.appservice.IDeptAppService;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@@ -16,6 +15,9 @@ public class DeptController {
|
||||
@Resource
|
||||
private IDeptAppService deptAppService;
|
||||
|
||||
@Resource
|
||||
private IAppointmentConfigAppService appointmentConfigAppService;
|
||||
|
||||
/*
|
||||
* 获取科室列表
|
||||
*
|
||||
@@ -38,4 +40,22 @@ public class DeptController {
|
||||
){
|
||||
return R.ok(deptAppService.searchDept(pageNo,pageSize,orgName,deptName));
|
||||
}
|
||||
|
||||
/*
|
||||
* 获取预约配置
|
||||
*
|
||||
* */
|
||||
@GetMapping("/config")
|
||||
public R<?> getAppointmentConfig(){
|
||||
return appointmentConfigAppService.getAppointmentConfig();
|
||||
}
|
||||
|
||||
/*
|
||||
* 保存预约配置
|
||||
*
|
||||
* */
|
||||
@PostMapping("/config")
|
||||
public R<?> saveAppointmentConfig(@RequestBody AppointmentConfig appointmentConfig){
|
||||
return appointmentConfigAppService.saveAppointmentConfig(appointmentConfig);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,6 @@ public class DoctorScheduleController {
|
||||
|
||||
/*
|
||||
* 新增医生排班(带具体日期)
|
||||
*
|
||||
* */
|
||||
@PostMapping("/add-with-date")
|
||||
public R<?> addDoctorScheduleWithDate(@RequestBody DoctorSchedule doctorSchedule) {
|
||||
@@ -77,7 +76,7 @@ public class DoctorScheduleController {
|
||||
* */
|
||||
@DeleteMapping("/delete/{doctorScheduleId}")
|
||||
public R<?> removeDoctorSchedule(@PathVariable Integer doctorScheduleId){
|
||||
return R.ok(doctorScheduleAppService.removeDoctorSchedule(doctorScheduleId));
|
||||
return doctorScheduleAppService.removeDoctorSchedule(doctorScheduleId);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -3,8 +3,12 @@ package com.openhis.web.appointmentmanage.controller;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.core.common.annotation.Anonymous;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.appointmentmanage.domain.AppointmentBookDTO;
|
||||
import com.openhis.appointmentmanage.dto.TicketQueryDTO;
|
||||
import com.openhis.web.appointmentmanage.appservice.ITicketAppService;
|
||||
import com.openhis.web.appointmentmanage.dto.TicketDto;
|
||||
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
@@ -19,11 +23,35 @@ import java.util.Map;
|
||||
@RequestMapping("/appointment/ticket")
|
||||
public class TicketController {
|
||||
|
||||
/**
|
||||
* 分页查询门诊号源列表 (带多条件过滤)
|
||||
*
|
||||
* @param query 查询条件
|
||||
* @return 分页号源列表
|
||||
*/
|
||||
@Anonymous
|
||||
@PostMapping("/list")
|
||||
public R<?> listTicket(@RequestBody @Validated TicketQueryDTO query) {
|
||||
return ticketAppService.listTicket(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询医生余号汇总(基于号源池,不受分页影响)
|
||||
*
|
||||
* @param query 查询条件
|
||||
* @return 医生余号列表
|
||||
*/
|
||||
@Anonymous
|
||||
@PostMapping("/doctorSummary")
|
||||
public R<?> listDoctorAvailability(@RequestBody @Validated TicketQueryDTO query) {
|
||||
return ticketAppService.listDoctorAvailability(query);
|
||||
}
|
||||
|
||||
@Resource
|
||||
private ITicketAppService ticketAppService;
|
||||
|
||||
/**
|
||||
* 查询所有号源(用于测试)
|
||||
* 查询所有号源
|
||||
*
|
||||
* @return 所有号源列表
|
||||
*/
|
||||
@@ -36,44 +64,44 @@ public class TicketController {
|
||||
/**
|
||||
* 预约号源
|
||||
*
|
||||
* @param params 预约参数
|
||||
* @param dto 预约参数
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping("/book")
|
||||
public R<?> bookTicket(@RequestBody Map<String, Object> params) {
|
||||
return ticketAppService.bookTicket(params);
|
||||
public R<?> bookTicket(@RequestBody @Validated AppointmentBookDTO dto) {
|
||||
return ticketAppService.bookTicket(dto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消预约
|
||||
*
|
||||
* @param ticketId 号源ID
|
||||
* @param slotId 槽位ID
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping("/cancel")
|
||||
public R<?> cancelTicket(@RequestParam Long ticketId) {
|
||||
return ticketAppService.cancelTicket(ticketId);
|
||||
public R<?> cancelTicket(@RequestParam Long slotId) {
|
||||
return ticketAppService.cancelTicket(slotId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取号
|
||||
*
|
||||
* @param ticketId 号源ID
|
||||
* @param slotId 槽位ID
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping("/checkin")
|
||||
public R<?> checkInTicket(@RequestParam Long ticketId) {
|
||||
return ticketAppService.checkInTicket(ticketId);
|
||||
public R<?> checkInTicket(@RequestParam Long slotId) {
|
||||
return ticketAppService.checkInTicket(slotId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 停诊
|
||||
*
|
||||
* @param ticketId 号源ID
|
||||
* @param slotId 槽位ID
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping("/cancelConsultation")
|
||||
public R<?> cancelConsultation(@RequestParam Long ticketId) {
|
||||
return ticketAppService.cancelConsultation(ticketId);
|
||||
public R<?> cancelConsultation(@RequestParam Long slotId) {
|
||||
return ticketAppService.cancelConsultation(slotId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,11 @@ public class TicketDto {
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long slot_id;
|
||||
|
||||
/**
|
||||
* 号源序号(对应 adm_schedule_slot.seq_no)
|
||||
*/
|
||||
private Integer seqNo;
|
||||
|
||||
/**
|
||||
* 号源编码
|
||||
*/
|
||||
@@ -49,7 +54,7 @@ public class TicketDto {
|
||||
private String dateTime;
|
||||
|
||||
/**
|
||||
* 状态 (unbooked:未预约, booked:已预约, checked:已取号, cancelled:已取消, locked:已锁定)
|
||||
* 状态
|
||||
*/
|
||||
private String status;
|
||||
|
||||
@@ -99,4 +104,15 @@ public class TicketDto {
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long doctorId;
|
||||
|
||||
/**
|
||||
* 真实患者ID(数据库主键,区别于 patientId 存的就诊卡号)
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long realPatientId;
|
||||
|
||||
/**
|
||||
* 身份证号
|
||||
*/
|
||||
private String idCard;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package com.openhis.web.basedatamanage.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.core.common.core.domain.R;
|
||||
import com.core.common.utils.AssignSeqUtil;
|
||||
import com.core.common.utils.MessageUtils;
|
||||
import com.core.common.utils.StringUtils;
|
||||
import com.openhis.administration.domain.Organization;
|
||||
import com.openhis.administration.mapper.OrganizationMapper;
|
||||
import com.openhis.administration.service.IOrganizationService;
|
||||
import com.openhis.common.constant.CommonConstants;
|
||||
import com.openhis.common.constant.PromptMsgConstant;
|
||||
@@ -35,12 +37,15 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
|
||||
@Resource
|
||||
private AssignSeqUtil assignSeqUtil;
|
||||
|
||||
@Resource
|
||||
private OrganizationMapper organizationMapper;
|
||||
|
||||
@Override
|
||||
public Page<OrganizationDto> getOrganizationTree(Integer pageNo, Integer pageSize, String name, Integer typeEnum,
|
||||
List<String> classEnumList,
|
||||
String sortField, String sortOrder, HttpServletRequest request) {
|
||||
|
||||
// 使用Page对象进行分页查询
|
||||
// 使用 Page 对象进行分页查询
|
||||
Page<Organization> page = new Page<>(pageNo, pageSize);
|
||||
|
||||
// 创建查询条件
|
||||
@@ -54,7 +59,7 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
|
||||
queryWrapper.eq(Organization::getTypeEnum, typeEnum);
|
||||
}
|
||||
if (classEnumList != null && !classEnumList.isEmpty()) {
|
||||
// 使用OR条件来匹配class_enum字段中包含任一值的记录
|
||||
// 使用 OR 条件来匹配 class_enum 字段中包含任一值的记录
|
||||
queryWrapper.and(wrapper -> {
|
||||
for (int i = 0; i < classEnumList.size(); i++) {
|
||||
String classEnum = classEnumList.get(i);
|
||||
@@ -63,18 +68,18 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
|
||||
wrapper.and(subWrapper -> {
|
||||
subWrapper.eq(Organization::getClassEnum, classEnum) // 精确匹配
|
||||
.or() // 或者
|
||||
.likeRight(Organization::getClassEnum, classEnum + ",") // 以"值,"开头
|
||||
.likeRight(Organization::getClassEnum, classEnum + ",") // 以"值,"开头
|
||||
.or() // 或者
|
||||
.likeLeft(Organization::getClassEnum, "," + classEnum) // 以",值"结尾
|
||||
.or() // 或者
|
||||
.like(Organization::getClassEnum, "," + classEnum + ","); // 在中间,被逗号包围
|
||||
});
|
||||
} else {
|
||||
// 后续条件使用OR连接
|
||||
// 后续条件使用 OR 连接
|
||||
wrapper.or(subWrapper -> {
|
||||
subWrapper.eq(Organization::getClassEnum, classEnum) // 精确匹配
|
||||
.or() // 或者
|
||||
.likeRight(Organization::getClassEnum, classEnum + ",") // 以"值,"开头
|
||||
.likeRight(Organization::getClassEnum, classEnum + ",") // 以"值,"开头
|
||||
.or() // 或者
|
||||
.likeLeft(Organization::getClassEnum, "," + classEnum) // 以",值"结尾
|
||||
.or() // 或者
|
||||
@@ -88,7 +93,7 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
|
||||
// 执行分页查询
|
||||
Page<Organization> resultPage = organizationService.page(page, queryWrapper);
|
||||
|
||||
// 将查询结果转为DTO并构建树结构
|
||||
// 将查询结果转为 DTO 并构建树结构
|
||||
List<Organization> organizationList = resultPage.getRecords();
|
||||
List<OrganizationDto> orgTree = buildTree(organizationList);
|
||||
|
||||
@@ -109,7 +114,7 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
|
||||
* @return tree
|
||||
*/
|
||||
private List<OrganizationDto> buildTree(List<Organization> records) {
|
||||
// 按b_no的层级排序,确保父节点先处理
|
||||
// 按 b_no 的层级排序,确保父节点先处理
|
||||
List<Organization> sortedRecords = records.stream()
|
||||
.sorted(Comparator.comparingInt(r -> r.getBusNo().split("\\.").length)).collect(Collectors.toList());
|
||||
|
||||
@@ -131,7 +136,7 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
|
||||
// 根节点
|
||||
tree.add(node);
|
||||
} else {
|
||||
// 获取父节点的b_no(去掉最后一部分)
|
||||
// 获取父节点的 b_no(去掉最后一部分)
|
||||
String parentBNo = String.join(".", Arrays.copyOf(parts, parts.length - 1));
|
||||
OrganizationDto parent = nodeMap.get(parentBNo);
|
||||
|
||||
@@ -149,7 +154,7 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
|
||||
/**
|
||||
* 机构信息详情
|
||||
*
|
||||
* @param orgId 机构信息id
|
||||
* @param orgId 机构信息 id
|
||||
* @return 机构信息详情
|
||||
*/
|
||||
@Override
|
||||
@@ -159,7 +164,7 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00006, new Object[] { "机构信息" }));
|
||||
}
|
||||
|
||||
// 转换为DTO对象,确保数据格式一致
|
||||
// 转换为 DTO 对象,确保数据格式一致
|
||||
OrganizationDto organizationDto = new OrganizationDto();
|
||||
BeanUtils.copyProperties(organization, organizationDto);
|
||||
organizationDto
|
||||
@@ -181,7 +186,7 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
|
||||
@Override
|
||||
public R<?> addOrEditOrganization(OrganizationDto organizationDto) {
|
||||
|
||||
// 新增organization信息
|
||||
// 新增 organization 信息
|
||||
Organization organization = new Organization();
|
||||
BeanUtils.copyProperties(organizationDto, organization);
|
||||
|
||||
@@ -191,9 +196,9 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
|
||||
} else {
|
||||
// 活动标识:有效
|
||||
organization.setActiveFlag(AccountStatus.ACTIVE.getValue());
|
||||
// 采番bus_no三位
|
||||
// 采番 bus_no 三位
|
||||
String code = assignSeqUtil.getSeq(AssignSeqEnum.ORGANIZATION_BUS_NO.getPrefix(), 3);
|
||||
// 如果传了上级科室 把当前的code拼到后边
|
||||
// 如果传了上级科室 把当前的 code 拼到后边
|
||||
if (StringUtils.isNotEmpty(organization.getBusNo())) {
|
||||
organization.setBusNo(String.format(CommonConstants.Common.MONTAGE_FORMAT, organization.getBusNo(),
|
||||
CommonConstants.Common.POINT, code));
|
||||
@@ -203,7 +208,7 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
|
||||
// 生成待发送的机构信息
|
||||
organizationService.save(organization);
|
||||
}
|
||||
// 返回机构id
|
||||
// 返回机构 id
|
||||
return R.ok(organization.getId(),
|
||||
MessageUtils.createMessage(PromptMsgConstant.Common.M00004, new Object[] { "机构信息更新添加" }));
|
||||
}
|
||||
@@ -211,7 +216,7 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
|
||||
/**
|
||||
* 删除机构
|
||||
*
|
||||
* @param orgIds 机构信息id
|
||||
* @param orgIds 机构信息 id
|
||||
* @return 操作结果
|
||||
*/
|
||||
@Override
|
||||
@@ -232,7 +237,7 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
|
||||
/**
|
||||
* 机构启用
|
||||
*
|
||||
* @param orgId 机构信息id
|
||||
* @param orgId 机构信息 id
|
||||
* @return 操作结果
|
||||
*/
|
||||
@Override
|
||||
@@ -247,7 +252,7 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
|
||||
/**
|
||||
* 机构停用
|
||||
*
|
||||
* @param orgId 机构信息id
|
||||
* @param orgId 机构信息 id
|
||||
* @return 操作结果
|
||||
*/
|
||||
@Override
|
||||
@@ -299,38 +304,27 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
|
||||
*/
|
||||
@Override
|
||||
public R<?> getRegisterOrganizations(Integer pageNo, Integer pageSize, String name, String orgName) {
|
||||
// 使用Page对象进行分页查询
|
||||
// 使用 Page 对象进行分页查询
|
||||
Page<Organization> page = new Page<>(pageNo != null ? pageNo : 1, pageSize != null ? pageSize : 10);
|
||||
|
||||
// 创建查询条件,只查询register_flag为1的组织机构
|
||||
LambdaQueryWrapper<Organization> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(Organization::getRegisterFlag, 1); // 只获取挂号科室
|
||||
queryWrapper.eq(Organization::getDeleteFlag, "0"); // 确保未删除
|
||||
// 使用 Mapper 方法关联查询 sys_tenant 表获取租户名称
|
||||
IPage<Organization> resultPage = organizationMapper.selectRegisterOrganizationsWithTenant(
|
||||
page,
|
||||
1, // register_flag = 1
|
||||
"0", // delete_flag = '0'
|
||||
name,
|
||||
orgName
|
||||
);
|
||||
|
||||
// 添加名称过滤条件
|
||||
if (StringUtils.isNotEmpty(name)) {
|
||||
queryWrapper.like(Organization::getName, name);
|
||||
}
|
||||
|
||||
// 如果有机构名称筛选
|
||||
if (StringUtils.isNotEmpty(orgName)) {
|
||||
// 这里假设 orgName 是父机构名称,如果需要更复杂的关联查询可在此扩展
|
||||
// 当前逻辑暂保持与原逻辑一致的过滤方式或根据需求调整
|
||||
}
|
||||
|
||||
// 按编码排序
|
||||
queryWrapper.orderByAsc(Organization::getBusNo);
|
||||
|
||||
// 执行分页查询
|
||||
Page<Organization> resultPage = organizationService.page(page, queryWrapper);
|
||||
|
||||
// 转换为DTO对象并设置字典文本
|
||||
// 转换为 DTO 对象并设置字典文本
|
||||
List<OrganizationDto> organizationDtoList = resultPage.getRecords().stream().map(org -> {
|
||||
OrganizationDto dto = new OrganizationDto();
|
||||
BeanUtils.copyProperties(org, dto);
|
||||
dto.setTypeEnum_dictText(EnumUtils.getInfoByValue(OrganizationType.class, dto.getTypeEnum()));
|
||||
dto.setClassEnum_dictText(formatClassEnumDictText(dto.getClassEnum()));
|
||||
dto.setActiveFlag_dictText(EnumUtils.getInfoByValue(AccountStatus.class, dto.getActiveFlag()));
|
||||
// 设置租户名称
|
||||
dto.setOrgName(org.getTenantName());
|
||||
return dto;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -60,7 +59,6 @@ public class OrganizationDto {
|
||||
private Integer displayOrder;
|
||||
|
||||
/** 子集合 */
|
||||
@ToString.Exclude
|
||||
private List<OrganizationDto> children = new ArrayList<>();
|
||||
|
||||
/** 挂号科室标记 */
|
||||
@@ -74,4 +72,7 @@ public class OrganizationDto {
|
||||
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
|
||||
/** 租户名称 */
|
||||
private String orgName;
|
||||
}
|
||||
|
||||
@@ -119,9 +119,11 @@ public class OutpatientChargeAppServiceImpl implements IOutpatientChargeAppServi
|
||||
= outpatientChargeAppMapper.selectEncounterPatientPrescription(encounterId,
|
||||
ChargeItemContext.ACTIVITY.getValue(), ChargeItemContext.MEDICATION.getValue(),
|
||||
ChargeItemContext.DEVICE.getValue(), ChargeItemContext.REGISTER.getValue(),
|
||||
ChargeItemContext.WESTERN_MEDICINE.getValue(), ChargeItemContext.CHINESE_PATENT_MEDICINE.getValue(),
|
||||
ChargeItemStatus.PLANNED.getValue(), ChargeItemStatus.BILLABLE.getValue(),
|
||||
ChargeItemStatus.BILLED.getValue(), ChargeItemStatus.REFUNDING.getValue(),
|
||||
ChargeItemStatus.REFUNDED.getValue(), ChargeItemStatus.PART_REFUND.getValue());
|
||||
ChargeItemStatus.REFUNDED.getValue(), ChargeItemStatus.PART_REFUND.getValue(),
|
||||
CommonConstants.TableName.WOR_DEVICE_REQUEST);
|
||||
prescriptionDtoList.forEach(e -> {
|
||||
// 收费状态枚举
|
||||
e.setStatusEnum_enumText(EnumUtils.getInfoByValue(ChargeItemStatus.class, e.getStatusEnum()));
|
||||
@@ -229,7 +231,8 @@ public class OutpatientChargeAppServiceImpl implements IOutpatientChargeAppServi
|
||||
ChargeItemStatus.REFUNDING.getValue(), ChargeItemStatus.REFUNDED.getValue(),
|
||||
ChargeItemStatus.PART_REFUND.getValue(), YbPayment.DISCOUNT_PAY.getValue(),
|
||||
YbPayment.SELF_CASH_VALUE.getValue(), YbPayment.SELF_CASH_VX_VALUE.getValue(),
|
||||
YbPayment.SELF_CASH_ALI_VALUE.getValue(), YbPayment.SELF_CASH_UNION_VALUE.getValue());
|
||||
YbPayment.SELF_CASH_ALI_VALUE.getValue(), YbPayment.SELF_CASH_UNION_VALUE.getValue(),
|
||||
CommonConstants.TableName.WOR_DEVICE_REQUEST);
|
||||
prescriptionDtoList.forEach(e -> {
|
||||
// 应收金额
|
||||
BigDecimal receivableAmount = e.getReceivableAmount();
|
||||
|
||||
@@ -73,10 +73,10 @@ public class OutpatientPricingAppServiceImpl implements IOutpatientPricingAppSer
|
||||
} else {
|
||||
adviceTypes = List.of(1, 2, 3);
|
||||
}
|
||||
// 门诊划价:不要强制 pricingFlag=1 参与过滤(wor_activity_definition.pricing_flag 可能为 0),
|
||||
// 否则会导致诊疗项目(adviceType=3)查询结果为空 records=[]
|
||||
String categoryCode = adviceBaseDto != null ? adviceBaseDto.getCategoryCode() : null;
|
||||
// 门诊划价:仅返回划价标记为“是”的项目
|
||||
return iDoctorStationAdviceAppService.getAdviceBaseInfo(adviceBaseDto, searchKey, locationId, null,
|
||||
organizationId, pageNo, pageSize, null, adviceTypes, null);
|
||||
organizationId, pageNo, pageSize, Whether.YES.getValue(), adviceTypes, null, categoryCode);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ import com.openhis.common.enums.ybenums.YbPayment;
|
||||
import com.openhis.common.utils.EnumUtils;
|
||||
import com.openhis.common.utils.HisPageUtils;
|
||||
import com.openhis.common.utils.HisQueryUtils;
|
||||
import com.openhis.appointmentmanage.mapper.SchedulePoolMapper;
|
||||
import com.openhis.appointmentmanage.mapper.ScheduleSlotMapper;
|
||||
import com.openhis.clinical.domain.Order;
|
||||
import com.openhis.clinical.service.IOrderService;
|
||||
import com.openhis.financial.domain.PaymentReconciliation;
|
||||
import com.openhis.financial.domain.RefundLog;
|
||||
import com.openhis.financial.service.IRefundLogService;
|
||||
@@ -48,6 +52,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -97,6 +102,15 @@ public class OutpatientRegistrationAppServiceImpl implements IOutpatientRegistra
|
||||
@Resource
|
||||
IRefundLogService iRefundLogService;
|
||||
|
||||
@Resource
|
||||
IOrderService orderService;
|
||||
|
||||
@Resource
|
||||
ScheduleSlotMapper scheduleSlotMapper;
|
||||
|
||||
@Resource
|
||||
SchedulePoolMapper schedulePoolMapper;
|
||||
|
||||
/**
|
||||
* 门诊挂号 - 查询患者信息
|
||||
*
|
||||
@@ -291,6 +305,11 @@ public class OutpatientRegistrationAppServiceImpl implements IOutpatientRegistra
|
||||
}
|
||||
}
|
||||
|
||||
// 如果本次门诊挂号来自预约签到,同步把预约订单与号源槽位状态改为已退号
|
||||
if (result != null && result.getCode() == 200) {
|
||||
syncAppointmentReturnStatus(byId, cancelRegPaymentDto.getReason());
|
||||
}
|
||||
|
||||
// 记录退号日志
|
||||
recordRefundLog(cancelRegPaymentDto, byId, result, paymentRecon);
|
||||
|
||||
@@ -399,6 +418,74 @@ public class OutpatientRegistrationAppServiceImpl implements IOutpatientRegistra
|
||||
return R.ok("已取消挂号");
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步预约号源状态为已退号。
|
||||
* 说明:
|
||||
* 1) 门诊退号主流程不依赖该步骤成功与否,因此此方法内部异常仅记录日志,不向上抛出。
|
||||
* 2) 通过患者、科室、日期以及状态筛选最近一条预约订单,尽量避免误匹配。
|
||||
*/
|
||||
private void syncAppointmentReturnStatus(Encounter encounter, String reason) {
|
||||
if (encounter == null || encounter.getPatientId() == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<Order>()
|
||||
.eq(Order::getPatientId, encounter.getPatientId())
|
||||
.in(Order::getStatus, CommonConstants.AppointmentOrderStatus.BOOKED,
|
||||
CommonConstants.AppointmentOrderStatus.CHECKED_IN)
|
||||
.orderByDesc(Order::getUpdateTime)
|
||||
.orderByDesc(Order::getCreateTime)
|
||||
.last("LIMIT 1");
|
||||
|
||||
if (encounter.getOrganizationId() != null) {
|
||||
queryWrapper.eq(Order::getDepartmentId, encounter.getOrganizationId());
|
||||
}
|
||||
if (encounter.getTenantId() != null) {
|
||||
queryWrapper.eq(Order::getTenantId, encounter.getTenantId());
|
||||
}
|
||||
if (encounter.getCreateTime() != null) {
|
||||
LocalDate encounterDate = encounter.getCreateTime().toInstant()
|
||||
.atZone(ZoneId.systemDefault()).toLocalDate();
|
||||
Date startOfDay = Date.from(encounterDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
|
||||
Date nextDayStart = Date.from(encounterDate.plusDays(1).atStartOfDay(ZoneId.systemDefault()).toInstant());
|
||||
queryWrapper.ge(Order::getAppointmentDate, startOfDay)
|
||||
.lt(Order::getAppointmentDate, nextDayStart);
|
||||
}
|
||||
|
||||
Order appointmentOrder = orderService.getOne(queryWrapper, false);
|
||||
if (appointmentOrder == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Date now = new Date();
|
||||
if (!CommonConstants.AppointmentOrderStatus.RETURNED.equals(appointmentOrder.getStatus())) {
|
||||
Order updateOrder = new Order();
|
||||
updateOrder.setId(appointmentOrder.getId());
|
||||
updateOrder.setStatus(CommonConstants.AppointmentOrderStatus.RETURNED);
|
||||
updateOrder.setCancelTime(now);
|
||||
updateOrder.setCancelReason(
|
||||
StringUtils.isNotEmpty(reason) ? reason : "门诊退号");
|
||||
updateOrder.setUpdateTime(now);
|
||||
orderService.updateById(updateOrder);
|
||||
}
|
||||
|
||||
Long slotId = appointmentOrder.getSlotId();
|
||||
if (slotId == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int slotRows = scheduleSlotMapper.updateSlotStatus(slotId, CommonConstants.SlotStatus.RETURNED);
|
||||
if (slotRows > 0) {
|
||||
Long poolId = scheduleSlotMapper.selectPoolIdBySlotId(slotId);
|
||||
if (poolId != null) {
|
||||
schedulePoolMapper.refreshPoolStats(poolId);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("同步预约号源已退号状态失败, encounterId={}", encounter.getId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 补打挂号
|
||||
* 补打挂号不需要修改数据库,只需要返回成功即可,前端已有所有需要的数据用于打印
|
||||
|
||||
@@ -61,7 +61,12 @@ public class OutpatientPricingController {
|
||||
@RequestParam(value = "locationId", required = false) Long locationId,
|
||||
@RequestParam(value = "organizationId") Long organizationId,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(value = "categoryCode", required = false) String categoryCode) {
|
||||
// 将 categoryCode 设置到 adviceBaseDto 中
|
||||
if (categoryCode != null && !categoryCode.isEmpty()) {
|
||||
adviceBaseDto.setCategoryCode(categoryCode);
|
||||
}
|
||||
return R.ok(iOutpatientPricingAppService.getAdviceBaseInfo(adviceBaseDto, searchKey, locationId, organizationId,
|
||||
pageNo, pageSize));
|
||||
}
|
||||
|
||||
@@ -42,19 +42,24 @@ public interface OutpatientChargeAppMapper {
|
||||
* @param medication 药品
|
||||
* @param device 耗材
|
||||
* @param register 挂号费
|
||||
* @param westernMedicine 西药
|
||||
* @param chinesePatentMedicine 中成药
|
||||
* @param planned 收费状态:待收费
|
||||
* @param billable 收费状态:待结算
|
||||
* @param billed 收费状态:已结算
|
||||
* @param refunding 收费状态:退费中
|
||||
* @param refunded 收费状态:全部退费
|
||||
* @param partRefund 收费状态:部分退费
|
||||
* @param worDeviceRequest 耗材请求表名常量
|
||||
* @return 患者处方列表
|
||||
*/
|
||||
List<EncounterPatientPrescriptionDto> selectEncounterPatientPrescription(@Param("encounterId") Long encounterId,
|
||||
@Param("activity") Integer activity, @Param("medication") Integer medication, @Param("device") Integer device,
|
||||
@Param("register") Integer register, @Param("planned") Integer planned, @Param("billable") Integer billable,
|
||||
@Param("register") Integer register, @Param("westernMedicine") Integer westernMedicine,
|
||||
@Param("chinesePatentMedicine") Integer chinesePatentMedicine,
|
||||
@Param("planned") Integer planned, @Param("billable") Integer billable,
|
||||
@Param("billed") Integer billed, @Param("refunding") Integer refunding, @Param("refunded") Integer refunded,
|
||||
@Param("partRefund") Integer partRefund);
|
||||
@Param("partRefund") Integer partRefund, @Param("worDeviceRequest") String worDeviceRequest);
|
||||
|
||||
/**
|
||||
* 根据就诊id查询患者处方列表并新增字段:应收金额,实收金额,优惠金额,折扣率
|
||||
@@ -75,6 +80,7 @@ public interface OutpatientChargeAppMapper {
|
||||
* @param selfVxCode 微信枚举码
|
||||
* @param selfAliCode 支付宝枚举码
|
||||
* @param selfUnionCode 银联枚举码
|
||||
* @param worDeviceRequest 耗材请求表名常量
|
||||
* @return 患者处方列表
|
||||
*/
|
||||
List<EncounterPatientPrescriptionDto> selectEncounterPatientPrescriptionWithPrice(
|
||||
@@ -84,5 +90,5 @@ public interface OutpatientChargeAppMapper {
|
||||
@Param("refunding") Integer refunding, @Param("refunded") Integer refunded,
|
||||
@Param("partRefund") Integer partRefund, @Param("discountCode") Integer discountCode,
|
||||
@Param("self") Integer selfCode, @Param("selfVx") Integer selfVxCode, @Param("selfAli") Integer selfAliCode,
|
||||
@Param("selfUnion") Integer selfUnionCode);
|
||||
@Param("selfUnion") Integer selfUnionCode, @Param("worDeviceRequest") String worDeviceRequest);
|
||||
}
|
||||
|
||||
@@ -58,4 +58,15 @@ public interface OutpatientRegistrationAppMapper {
|
||||
*/
|
||||
List<ActivityDeviceDto> getTmpActivityList(@Param("itemId") String itemId, @Param("devActable") String devActable);
|
||||
|
||||
/**
|
||||
* 根据用法代码查询绑定的耗材
|
||||
*
|
||||
* @param methodCode 用法代码
|
||||
* @param devActTable 绑定的表名(耗材)
|
||||
* @param typeCode 类型代码(1-用法绑定)
|
||||
* @return 绑定的耗材列表
|
||||
*/
|
||||
List<ActivityDeviceDto> getBoundDevicesByUsage(@Param("methodCode") String methodCode,
|
||||
@Param("devActTable") String devActTable, @Param("typeCode") String typeCode);
|
||||
|
||||
}
|
||||
|
||||
@@ -24,5 +24,5 @@ public interface ICheckMethodAppService{
|
||||
|
||||
R<?> searchCheckMethodList(Integer pageNo, Integer pageSize, String checkType, String name, String packageName);
|
||||
|
||||
R<?> exportCheckMethod(String checkType, String name, String packageName, HttpServletResponse response);
|
||||
void exportCheckMethod(String checkType, String name, String packageName, HttpServletResponse response);
|
||||
}
|
||||
|
||||
@@ -16,5 +16,5 @@ public interface ICheckPartAppService {
|
||||
|
||||
R<?> searchCheckPartList(Integer pageNo, Integer pageSize, String checkType, String name, String packageName);
|
||||
|
||||
R<?> exportCheckPart(String checkType, String name, String packageName, HttpServletResponse response);
|
||||
void exportCheckPart(String checkType, String name, String packageName, HttpServletResponse response);
|
||||
}
|
||||
|
||||
@@ -59,8 +59,10 @@ public class CheckMethodAppServiceImpl implements ICheckMethodAppService {
|
||||
return R.fail("检查方法的检查类型不能为空!");
|
||||
}
|
||||
//2.保存
|
||||
boolean save = checkMethodService.save(checkMethod);
|
||||
return R.ok(save);
|
||||
checkMethodService.save(checkMethod);
|
||||
java.util.Map<String, Object> result = new java.util.HashMap<>();
|
||||
result.put("id", checkMethod.getId());
|
||||
return R.ok(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -87,7 +89,7 @@ public class CheckMethodAppServiceImpl implements ICheckMethodAppService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> exportCheckMethod(String checkType, String name, String packageName, HttpServletResponse response) {
|
||||
public void exportCheckMethod(String checkType, String name, String packageName, HttpServletResponse response) {
|
||||
LambdaQueryWrapper<CheckMethod> wrapper = new LambdaQueryWrapper<>();
|
||||
if (checkType != null && ObjectUtil.isNotEmpty(checkType)) {
|
||||
wrapper.eq(CheckMethod::getCheckType, checkType);
|
||||
@@ -101,7 +103,13 @@ public class CheckMethodAppServiceImpl implements ICheckMethodAppService {
|
||||
List<CheckMethod> list = checkMethodService.list(wrapper);
|
||||
|
||||
if (list.isEmpty()) {
|
||||
return R.fail("导出Excel失败,无数据。");
|
||||
try {
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.getWriter().write("{\"code\":500,\"msg\":\"导出Excel失败,无数据。\"}");
|
||||
} catch (IOException e) {
|
||||
log.error("写入响应失败", e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -121,9 +129,12 @@ public class CheckMethodAppServiceImpl implements ICheckMethodAppService {
|
||||
ExcelFillerUtil.makeExcelFile(response, list, headers, excelName, null);
|
||||
} catch (IOException | IllegalAccessException e) {
|
||||
log.error("导出Excel失败", e);
|
||||
return R.fail("导出Excel失败:" + e.getMessage());
|
||||
try {
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.getWriter().write("{\"code\":500,\"msg\":\"导出Excel失败:" + e.getMessage() + "\"}");
|
||||
} catch (IOException ex) {
|
||||
log.error("写入响应失败", ex);
|
||||
}
|
||||
}
|
||||
|
||||
return R.ok(null, "导出Excel成功");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 检查套餐AppService实现
|
||||
* 检查套餐 AppService 实现
|
||||
*
|
||||
* @author system
|
||||
* @date 2025-11-26
|
||||
@@ -35,6 +35,32 @@ public class CheckPackageAppServiceImpl implements ICheckPackageAppService {
|
||||
private final ICheckPackageService checkPackageService;
|
||||
private final ICheckPackageDetailService checkPackageDetailService;
|
||||
|
||||
/**
|
||||
* 转换明细 DTO 列表为实体列表
|
||||
* @param detailDtos 明细 DTO 列表
|
||||
* @param packageId 套餐 ID
|
||||
* @param orderNumStart 起始序号
|
||||
* @return 明细实体列表
|
||||
*/
|
||||
private List<CheckPackageDetail> convertToDetails(List<CheckPackageDetailDto> detailDtos, Long packageId, int orderNumStart) {
|
||||
if (detailDtos == null || detailDtos.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
List<CheckPackageDetail> details = new ArrayList<>();
|
||||
int orderNum = orderNumStart;
|
||||
for (CheckPackageDetailDto detailDto : detailDtos) {
|
||||
CheckPackageDetail detail = new CheckPackageDetail();
|
||||
BeanUtils.copyProperties(detailDto, detail);
|
||||
detail.setPackageId(packageId);
|
||||
detail.setOrderNum(orderNum++);
|
||||
detail.setCreateTime(LocalDateTime.now());
|
||||
detail.setUpdateTime(LocalDateTime.now());
|
||||
details.add(detail);
|
||||
}
|
||||
return details;
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> getCheckPackageList() {
|
||||
try {
|
||||
@@ -61,7 +87,7 @@ public class CheckPackageAppServiceImpl implements ICheckPackageAppService {
|
||||
.orderByAsc(CheckPackageDetail::getOrderNum)
|
||||
);
|
||||
|
||||
// 转换为DTO
|
||||
// 转换为 DTO
|
||||
CheckPackageDto dto = new CheckPackageDto();
|
||||
BeanUtils.copyProperties(checkPackage, dto);
|
||||
|
||||
@@ -101,28 +127,21 @@ public class CheckPackageAppServiceImpl implements ICheckPackageAppService {
|
||||
|
||||
// 保存套餐明细
|
||||
if (checkPackageDto.getItems() != null && !checkPackageDto.getItems().isEmpty()) {
|
||||
List<CheckPackageDetail> details = new ArrayList<>();
|
||||
int orderNum = 1;
|
||||
for (CheckPackageDetailDto detailDto : checkPackageDto.getItems()) {
|
||||
CheckPackageDetail detail = new CheckPackageDetail();
|
||||
BeanUtils.copyProperties(detailDto, detail);
|
||||
detail.setPackageId(checkPackage.getId());
|
||||
detail.setOrderNum(orderNum++);
|
||||
detail.setCreateTime(LocalDateTime.now());
|
||||
detail.setUpdateTime(LocalDateTime.now());
|
||||
details.add(detail);
|
||||
List<CheckPackageDetail> details = convertToDetails(checkPackageDto.getItems(), checkPackage.getId(), 1);
|
||||
boolean detailSaveResult = checkPackageDetailService.saveBatch(details);
|
||||
if (!detailSaveResult) {
|
||||
throw new RuntimeException("保存套餐明细失败");
|
||||
}
|
||||
checkPackageDetailService.saveBatch(details);
|
||||
}
|
||||
|
||||
return R.ok(checkPackage.getId(), "保存成功");
|
||||
} catch (Exception e) {
|
||||
log.error("新增检查套餐失败", e);
|
||||
|
||||
// 捕获PostgreSQL唯一约束冲突异常
|
||||
// 捕获 PostgreSQL 唯一约束冲突异常
|
||||
String errorMessage = e.getMessage();
|
||||
if (errorMessage != null) {
|
||||
// PostgreSQL唯一约束错误通常包含 "duplicate key value" 或约束名称
|
||||
// PostgreSQL 唯一约束错误通常包含 "duplicate key value" 或约束名称
|
||||
if (errorMessage.contains("duplicate key value") ||
|
||||
errorMessage.contains("违反唯一约束") ||
|
||||
errorMessage.contains("unique constraint")) {
|
||||
@@ -135,7 +154,7 @@ public class CheckPackageAppServiceImpl implements ICheckPackageAppService {
|
||||
}
|
||||
}
|
||||
|
||||
return R.fail("新增检查套餐失败: " + errorMessage);
|
||||
return R.fail("新增检查套餐失败:" + errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,24 +189,14 @@ public class CheckPackageAppServiceImpl implements ICheckPackageAppService {
|
||||
|
||||
// 保存新的套餐明细
|
||||
if (checkPackageDto.getItems() != null && !checkPackageDto.getItems().isEmpty()) {
|
||||
List<CheckPackageDetail> details = new ArrayList<>();
|
||||
int orderNum = 1;
|
||||
for (CheckPackageDetailDto detailDto : checkPackageDto.getItems()) {
|
||||
CheckPackageDetail detail = new CheckPackageDetail();
|
||||
BeanUtils.copyProperties(detailDto, detail);
|
||||
detail.setPackageId(checkPackage.getId());
|
||||
detail.setOrderNum(orderNum++);
|
||||
detail.setCreateTime(LocalDateTime.now());
|
||||
detail.setUpdateTime(LocalDateTime.now());
|
||||
details.add(detail);
|
||||
}
|
||||
List<CheckPackageDetail> details = convertToDetails(checkPackageDto.getItems(), checkPackage.getId(), 1);
|
||||
checkPackageDetailService.saveBatch(details);
|
||||
}
|
||||
|
||||
return R.ok("更新成功");
|
||||
} catch (Exception e) {
|
||||
log.error("更新检查套餐失败", e);
|
||||
return R.fail("更新检查套餐失败: " + e.getMessage());
|
||||
return R.fail("更新检查套餐失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,11 +210,14 @@ public class CheckPackageAppServiceImpl implements ICheckPackageAppService {
|
||||
return R.fail("套餐不存在");
|
||||
}
|
||||
|
||||
// 删除套餐明细
|
||||
checkPackageDetailService.remove(
|
||||
// 删除套餐明细 - 先删除子表数据
|
||||
boolean removeDetailsResult = checkPackageDetailService.remove(
|
||||
new LambdaQueryWrapper<CheckPackageDetail>()
|
||||
.eq(CheckPackageDetail::getPackageId, id)
|
||||
);
|
||||
if (!removeDetailsResult) {
|
||||
log.warn("删除套餐明细失败,套餐 ID: {}", id);
|
||||
}
|
||||
|
||||
// 删除套餐主表
|
||||
boolean deleteResult = checkPackageService.removeById(id);
|
||||
@@ -213,11 +225,11 @@ public class CheckPackageAppServiceImpl implements ICheckPackageAppService {
|
||||
return R.fail("删除套餐失败");
|
||||
}
|
||||
|
||||
log.info("删除检查套餐成功,套餐 ID: {}", id);
|
||||
return R.ok("删除成功");
|
||||
} catch (Exception e) {
|
||||
log.error("删除检查套餐失败", e);
|
||||
return R.fail("删除检查套餐失败: " + e.getMessage());
|
||||
return R.fail("删除检查套餐失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ public class CheckPartAppServiceImpl implements ICheckPartAppService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> exportCheckPart(String checkType, String name, String packageName, HttpServletResponse response) {
|
||||
public void exportCheckPart(String checkType, String name, String packageName, HttpServletResponse response) {
|
||||
LambdaQueryWrapper<CheckPart> wrapper = new LambdaQueryWrapper<>();
|
||||
if (checkType != null && ObjectUtil.isNotEmpty(checkType)) {
|
||||
wrapper.eq(CheckPart::getCheckType, checkType);
|
||||
@@ -79,7 +79,13 @@ public class CheckPartAppServiceImpl implements ICheckPartAppService {
|
||||
List<CheckPart> list = checkPartService.list(wrapper);
|
||||
|
||||
if (list.isEmpty()) {
|
||||
return R.fail("导出Excel失败,无数据。");
|
||||
try {
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.getWriter().write("{\"code\":500,\"msg\":\"导出Excel失败,无数据。\"}");
|
||||
} catch (IOException e) {
|
||||
log.error("写入响应失败", e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -102,8 +108,12 @@ public class CheckPartAppServiceImpl implements ICheckPartAppService {
|
||||
ExcelFillerUtil.makeExcelFile(response, list, headers, excelName, null);
|
||||
} catch (IOException | IllegalAccessException e) {
|
||||
log.error("导出Excel失败", e);
|
||||
return R.fail("导出Excel失败:" + e.getMessage());
|
||||
try {
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.getWriter().write("{\"code\":500,\"msg\":\"导出Excel失败:" + e.getMessage() + "\"}");
|
||||
} catch (IOException ex) {
|
||||
log.error("写入响应失败", ex);
|
||||
}
|
||||
}
|
||||
return R.ok(null, "导出Excel成功");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,9 @@ public class CheckPackageDetailDto {
|
||||
@NotNull(message = "数量不能为空")
|
||||
private Integer quantity;
|
||||
|
||||
/** 单位 */
|
||||
private String unit;
|
||||
|
||||
/** 单价 */
|
||||
@NotNull(message = "单价不能为空")
|
||||
private BigDecimal unitPrice;
|
||||
|
||||
@@ -343,11 +343,28 @@ public class SurgeryAppServiceImpl implements ISurgeryAppService {
|
||||
serviceRequest.setEncounterId(surgeryDto.getEncounterId()); // 就诊id
|
||||
serviceRequest.setAuthoredTime(curDate); // 请求签发时间
|
||||
serviceRequest.setOrgId(orgId); // 执行科室
|
||||
// 🔧 BugFix#318: 设置 contentJson,包含手术名称
|
||||
Map<String, String> serviceContentMap = new HashMap<>();
|
||||
String surgeryNameFromDto = surgeryDto.getSurgeryName();
|
||||
String surgeryCodeFromDto = surgeryDto.getSurgeryCode();
|
||||
log.info("【DEBUG】surgeryName from DTO: {}", surgeryNameFromDto);
|
||||
log.info("【DEBUG】surgeryCode from DTO: {}", surgeryCodeFromDto);
|
||||
serviceContentMap.put("surgeryName", surgeryNameFromDto != null ? surgeryNameFromDto : "");
|
||||
serviceContentMap.put("surgeryCode", surgeryCodeFromDto != null ? surgeryCodeFromDto : "");
|
||||
try {
|
||||
String contentJson = new ObjectMapper().writeValueAsString(serviceContentMap);
|
||||
log.info("【DEBUG】Setting contentJson: {}", contentJson);
|
||||
serviceRequest.setContentJson(contentJson);
|
||||
} catch (JsonProcessingException e) {
|
||||
log.error("【DEBUG】设置手术医嘱 contentJson 失败", e);
|
||||
}
|
||||
serviceRequestService.save(serviceRequest);
|
||||
log.info("【DEBUG】Saved serviceRequest with ID: {}, contentJson: {}",
|
||||
serviceRequest.getId(), serviceRequest.getContentJson());
|
||||
|
||||
// 生成收费项目
|
||||
ChargeItem chargeItem = new ChargeItem();
|
||||
chargeItem.setStatusEnum(ChargeItemStatus.DRAFT.getValue()); // 收费状态
|
||||
chargeItem.setStatusEnum(ChargeItemStatus.PLANNED.getValue()); // 收费状态:待收费
|
||||
chargeItem.setBusNo("CI" + serviceRequest.getBusNo());
|
||||
chargeItem.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue()); // 生成来源
|
||||
chargeItem.setPatientId(surgeryDto.getPatientId()); // 患者
|
||||
@@ -541,15 +558,33 @@ public class SurgeryAppServiceImpl implements ISurgeryAppService {
|
||||
// 收集所有需要查询的ID
|
||||
Set<Long> practitionerIds = new HashSet<>();
|
||||
Set<Long> orgIds = new HashSet<>();
|
||||
Set<Long> otherIds = new HashSet<>();
|
||||
Set<Long> userIds = new HashSet<>(); // 用于查询sys_user表
|
||||
|
||||
// 收集Practitioner IDs
|
||||
if (surgery.getMainSurgeonId() != null) practitionerIds.add(surgery.getMainSurgeonId());
|
||||
if (surgery.getAnesthetistId() != null) practitionerIds.add(surgery.getAnesthetistId());
|
||||
if (surgery.getAssistant1Id() != null) practitionerIds.add(surgery.getAssistant1Id());
|
||||
if (surgery.getAssistant2Id() != null) practitionerIds.add(surgery.getAssistant2Id());
|
||||
if (surgery.getScrubNurseId() != null) practitionerIds.add(surgery.getScrubNurseId());
|
||||
if (surgery.getApplyDoctorId() != null) practitionerIds.add(surgery.getApplyDoctorId());
|
||||
// 收集Practitioner IDs (医生相关)
|
||||
if (surgery.getMainSurgeonId() != null) {
|
||||
practitionerIds.add(surgery.getMainSurgeonId());
|
||||
userIds.add(surgery.getMainSurgeonId());
|
||||
}
|
||||
if (surgery.getAnesthetistId() != null) {
|
||||
practitionerIds.add(surgery.getAnesthetistId());
|
||||
userIds.add(surgery.getAnesthetistId());
|
||||
}
|
||||
if (surgery.getAssistant1Id() != null) {
|
||||
practitionerIds.add(surgery.getAssistant1Id());
|
||||
userIds.add(surgery.getAssistant1Id());
|
||||
}
|
||||
if (surgery.getAssistant2Id() != null) {
|
||||
practitionerIds.add(surgery.getAssistant2Id());
|
||||
userIds.add(surgery.getAssistant2Id());
|
||||
}
|
||||
if (surgery.getScrubNurseId() != null) {
|
||||
practitionerIds.add(surgery.getScrubNurseId());
|
||||
userIds.add(surgery.getScrubNurseId());
|
||||
}
|
||||
if (surgery.getApplyDoctorId() != null) {
|
||||
practitionerIds.add(surgery.getApplyDoctorId());
|
||||
userIds.add(surgery.getApplyDoctorId());
|
||||
}
|
||||
|
||||
// 收集Organization IDs
|
||||
if (surgery.getOrgId() != null) orgIds.add(surgery.getOrgId());
|
||||
@@ -558,69 +593,151 @@ public class SurgeryAppServiceImpl implements ISurgeryAppService {
|
||||
// 批量查询并缓存结果
|
||||
Map<Long, String> practitionerNameMap = new HashMap<>();
|
||||
Map<Long, String> orgNameMap = new HashMap<>();
|
||||
Map<Long, String> userNameMap = new HashMap<>(); // 从sys_user查询的名称
|
||||
|
||||
// 批量查询Practitioner
|
||||
if (!practitionerIds.isEmpty()) {
|
||||
try {
|
||||
List<com.openhis.administration.domain.Practitioner> practitioners = practitionerService.listByIds(practitionerIds);
|
||||
for (com.openhis.administration.domain.Practitioner p : practitioners) {
|
||||
if (p.getName() != null && !p.getName().isEmpty()) {
|
||||
practitionerNameMap.put(p.getId(), p.getName());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("查询Practitioner名称失败: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 批量查询SysUser (作为备选) - 使用逐个查询
|
||||
if (!userIds.isEmpty()) {
|
||||
try {
|
||||
for (Long userId : userIds) {
|
||||
SysUser u = sysUserService.selectUserById(userId);
|
||||
if (u != null) {
|
||||
String userName = u.getNickName() != null && !u.getNickName().isEmpty()
|
||||
? u.getNickName()
|
||||
: u.getUserName();
|
||||
if (userName != null && !userName.isEmpty()) {
|
||||
userNameMap.put(u.getUserId(), userName);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("查询SysUser名称失败: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 批量查询Organization
|
||||
if (!orgIds.isEmpty()) {
|
||||
try {
|
||||
List<Organization> orgs = organizationService.listByIds(orgIds);
|
||||
for (Organization o : orgs) {
|
||||
if (o.getName() != null && !o.getName().isEmpty()) {
|
||||
orgNameMap.put(o.getId(), o.getName());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("查询Organization名称失败: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 填充患者姓名
|
||||
if (surgery.getPatientId() != null && surgery.getPatientName() == null) {
|
||||
try {
|
||||
Patient patient = patientService.getById(surgery.getPatientId());
|
||||
if (patient != null) {
|
||||
surgery.setPatientName(patient.getName());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("查询患者名称失败: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 使用缓存填充名称
|
||||
// 填充医生名称 - 优先使用practitioner,如果不存在则使用sys_user
|
||||
if (surgery.getMainSurgeonId() != null && surgery.getMainSurgeonName() == null) {
|
||||
surgery.setMainSurgeonName(practitionerNameMap.get(surgery.getMainSurgeonId()));
|
||||
String name = practitionerNameMap.get(surgery.getMainSurgeonId());
|
||||
if (name == null || name.isEmpty()) {
|
||||
name = userNameMap.get(surgery.getMainSurgeonId());
|
||||
}
|
||||
if (name != null && !name.isEmpty()) {
|
||||
surgery.setMainSurgeonName(name);
|
||||
}
|
||||
}
|
||||
if (surgery.getAnesthetistId() != null && surgery.getAnesthetistName() == null) {
|
||||
surgery.setAnesthetistName(practitionerNameMap.get(surgery.getAnesthetistId()));
|
||||
String name = practitionerNameMap.get(surgery.getAnesthetistId());
|
||||
if (name == null || name.isEmpty()) {
|
||||
name = userNameMap.get(surgery.getAnesthetistId());
|
||||
}
|
||||
if (name != null && !name.isEmpty()) {
|
||||
surgery.setAnesthetistName(name);
|
||||
}
|
||||
}
|
||||
if (surgery.getAssistant1Id() != null && surgery.getAssistant1Name() == null) {
|
||||
surgery.setAssistant1Name(practitionerNameMap.get(surgery.getAssistant1Id()));
|
||||
String name = practitionerNameMap.get(surgery.getAssistant1Id());
|
||||
if (name == null || name.isEmpty()) {
|
||||
name = userNameMap.get(surgery.getAssistant1Id());
|
||||
}
|
||||
if (name != null && !name.isEmpty()) {
|
||||
surgery.setAssistant1Name(name);
|
||||
}
|
||||
}
|
||||
if (surgery.getAssistant2Id() != null && surgery.getAssistant2Name() == null) {
|
||||
surgery.setAssistant2Name(practitionerNameMap.get(surgery.getAssistant2Id()));
|
||||
String name = practitionerNameMap.get(surgery.getAssistant2Id());
|
||||
if (name == null || name.isEmpty()) {
|
||||
name = userNameMap.get(surgery.getAssistant2Id());
|
||||
}
|
||||
if (name != null && !name.isEmpty()) {
|
||||
surgery.setAssistant2Name(name);
|
||||
}
|
||||
}
|
||||
if (surgery.getScrubNurseId() != null && surgery.getScrubNurseName() == null) {
|
||||
surgery.setScrubNurseName(practitionerNameMap.get(surgery.getScrubNurseId()));
|
||||
String name = practitionerNameMap.get(surgery.getScrubNurseId());
|
||||
if (name == null || name.isEmpty()) {
|
||||
name = userNameMap.get(surgery.getScrubNurseId());
|
||||
}
|
||||
if (name != null && !name.isEmpty()) {
|
||||
surgery.setScrubNurseName(name);
|
||||
}
|
||||
}
|
||||
if (surgery.getApplyDoctorId() != null && surgery.getApplyDoctorName() == null) {
|
||||
surgery.setApplyDoctorName(practitionerNameMap.get(surgery.getApplyDoctorId()));
|
||||
String name = practitionerNameMap.get(surgery.getApplyDoctorId());
|
||||
if (name == null || name.isEmpty()) {
|
||||
name = userNameMap.get(surgery.getApplyDoctorId());
|
||||
}
|
||||
if (name != null && !name.isEmpty()) {
|
||||
surgery.setApplyDoctorName(name);
|
||||
}
|
||||
}
|
||||
|
||||
// 填充手术室名称
|
||||
if (surgery.getOperatingRoomId() != null && surgery.getOperatingRoomName() == null) {
|
||||
try {
|
||||
OperatingRoom operatingRoom = operatingRoomService.getById(surgery.getOperatingRoomId());
|
||||
if (operatingRoom != null) {
|
||||
surgery.setOperatingRoomName(operatingRoom.getName());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("查询手术室名称失败: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 使用缓存填充组织名称
|
||||
if (surgery.getOrgId() != null && surgery.getOrgName() == null) {
|
||||
surgery.setOrgName(orgNameMap.get(surgery.getOrgId()));
|
||||
String name = orgNameMap.get(surgery.getOrgId());
|
||||
if (name != null && !name.isEmpty()) {
|
||||
surgery.setOrgName(name);
|
||||
}
|
||||
}
|
||||
if (surgery.getApplyDeptId() != null && surgery.getApplyDeptName() == null) {
|
||||
surgery.setApplyDeptName(orgNameMap.get(surgery.getApplyDeptId()));
|
||||
String name = orgNameMap.get(surgery.getApplyDeptId());
|
||||
if (name != null && !name.isEmpty()) {
|
||||
surgery.setApplyDeptName(name);
|
||||
}
|
||||
}
|
||||
|
||||
log.debug("填充手术名称字段完成 - patientName: {}, mainSurgeonName: {}, orgName: {}",
|
||||
surgery.getPatientName(), surgery.getMainSurgeonName(), surgery.getOrgName());
|
||||
log.debug("填充手术名称字段完成 - patientName: {}, mainSurgeonName: {}, applyDeptName: {}",
|
||||
surgery.getPatientName(), surgery.getMainSurgeonName(), surgery.getApplyDeptName());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
package com.openhis.web.clinicalmanage.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.core.common.core.domain.R;
|
||||
import com.core.common.core.domain.model.LoginUser;
|
||||
import com.core.common.utils.SecurityUtils;
|
||||
import com.openhis.administration.domain.Patient;
|
||||
import com.openhis.administration.service.IOrganizationService;
|
||||
import com.openhis.administration.service.IPatientService;
|
||||
import com.openhis.clinical.domain.Surgery;
|
||||
import com.openhis.clinical.service.ISurgeryService;
|
||||
import com.openhis.surgicalschedule.domain.OpSchedule;
|
||||
import com.openhis.surgicalschedule.service.IOpScheduleService;
|
||||
import com.openhis.web.clinicalmanage.appservice.ISurgicalScheduleAppService;
|
||||
@@ -29,6 +33,8 @@ import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import static com.core.framework.datasource.DynamicDataSourceContextHolder.log;
|
||||
|
||||
/**
|
||||
* 手术安排业务层实现类
|
||||
*
|
||||
@@ -47,6 +53,15 @@ public class SurgicalScheduleAppServiceImpl implements ISurgicalScheduleAppServi
|
||||
@Resource
|
||||
private SurgicalScheduleAppMapper surgicalScheduleAppMapper;
|
||||
|
||||
@Resource
|
||||
private ISurgeryService surgeryService;
|
||||
|
||||
@Resource
|
||||
private com.openhis.administration.service.IOrganizationService organizationService;
|
||||
|
||||
@Resource
|
||||
private com.core.system.service.ISysUserService sysUserService;
|
||||
|
||||
|
||||
@Resource
|
||||
private RequestFormManageAppMapper requestFormManageAppMapper;
|
||||
@@ -94,14 +109,32 @@ public class SurgicalScheduleAppServiceImpl implements ISurgicalScheduleAppServi
|
||||
return R.fail("患者信息不存在");
|
||||
}
|
||||
}
|
||||
//校验该时段内手术间是否被占用
|
||||
LocalDateTime scheduleDate = opCreateScheduleDto.getEntryTime();//入室时间
|
||||
String roomCode = opCreateScheduleDto.getRoomCode();//手术室编号
|
||||
|
||||
// 校验是否重复手术安排(必须在校验手术间占用之前执行,确保能正确返回重复错误)
|
||||
// 同一患者 + 同一手术单号 + 同一手术名称 只能有一条有效安排记录
|
||||
if (opCreateScheduleDto.getPatientId() != null
|
||||
&& opCreateScheduleDto.getOperCode() != null && !opCreateScheduleDto.getOperCode().isEmpty()
|
||||
&& opCreateScheduleDto.getOperName() != null && !opCreateScheduleDto.getOperName().isEmpty()) {
|
||||
Boolean existsDuplicate = surgicalScheduleAppMapper.existsDuplicateSchedule(
|
||||
opCreateScheduleDto.getPatientId(),
|
||||
opCreateScheduleDto.getOperCode(),
|
||||
opCreateScheduleDto.getOperName()
|
||||
);
|
||||
if (existsDuplicate != null && existsDuplicate) {
|
||||
return R.fail("该患者此手术单号已存在手术安排,请勿重复提交");
|
||||
}
|
||||
}
|
||||
|
||||
// 校验该时段内手术间是否被占用
|
||||
LocalDateTime startTime = opCreateScheduleDto.getEntryTime();//入室时间
|
||||
LocalDateTime endTime = opCreateScheduleDto.getEndTime();//手术结束时间
|
||||
Boolean scheduleConflict = surgicalScheduleAppMapper.isScheduleConflict(scheduleDate, endTime, roomCode);
|
||||
if (scheduleConflict) {
|
||||
String roomCode = opCreateScheduleDto.getRoomCode();//手术室编号
|
||||
if (startTime != null && endTime != null && roomCode != null && !roomCode.isEmpty()) {
|
||||
Boolean scheduleConflict = surgicalScheduleAppMapper.isScheduleConflict(startTime, endTime, roomCode);
|
||||
if (scheduleConflict != null && scheduleConflict) {
|
||||
return R.fail("该时段内手术间被占用");
|
||||
}
|
||||
}
|
||||
|
||||
LoginUser loginUser = new LoginUser();
|
||||
//获取当前登录用户信息
|
||||
@@ -113,6 +146,44 @@ public class SurgicalScheduleAppServiceImpl implements ISurgicalScheduleAppServi
|
||||
OpSchedule opSchedule = new OpSchedule();
|
||||
BeanUtils.copyProperties(opCreateScheduleDto, opSchedule);
|
||||
|
||||
// 处理可能为null的字符串字段,设置默认值为空字符串
|
||||
if (opSchedule.getPreoperativeDiagnosis() == null) {
|
||||
opSchedule.setPreoperativeDiagnosis("");
|
||||
}
|
||||
if (opSchedule.getPostoperativeDiagnosis() == null) {
|
||||
opSchedule.setPostoperativeDiagnosis("");
|
||||
}
|
||||
if (opSchedule.getAnesMethod() == null) {
|
||||
opSchedule.setAnesMethod("");
|
||||
}
|
||||
if (opSchedule.getAnesDoctor1Code() == null) {
|
||||
opSchedule.setAnesDoctor1Code("");
|
||||
}
|
||||
if (opSchedule.getAnesDoctor2Code() == null) {
|
||||
opSchedule.setAnesDoctor2Code("");
|
||||
}
|
||||
if (opSchedule.getAnesDoctor3Code() == null) {
|
||||
opSchedule.setAnesDoctor3Code("");
|
||||
}
|
||||
if (opSchedule.getScrubNurseCode() == null) {
|
||||
opSchedule.setScrubNurseCode("");
|
||||
}
|
||||
if (opSchedule.getCircuNurse1Code() == null) {
|
||||
opSchedule.setCircuNurse1Code("");
|
||||
}
|
||||
if (opSchedule.getCircuNurse2Code() == null) {
|
||||
opSchedule.setCircuNurse2Code("");
|
||||
}
|
||||
if (opSchedule.getScrubNurse1Code() == null) {
|
||||
opSchedule.setScrubNurse1Code("");
|
||||
}
|
||||
if (opSchedule.getScrubNurse2Code() == null) {
|
||||
opSchedule.setScrubNurse2Code("");
|
||||
}
|
||||
if (opSchedule.getSurgeonCode() == null) {
|
||||
opSchedule.setSurgeonCode("");
|
||||
}
|
||||
|
||||
// 设置创建者ID
|
||||
opSchedule.setCreatorId(userId);
|
||||
//设置创建人名称
|
||||
@@ -127,12 +198,34 @@ public class SurgicalScheduleAppServiceImpl implements ISurgicalScheduleAppServi
|
||||
|
||||
// 保存手术安排
|
||||
boolean saved = opScheduleService.save(opSchedule);
|
||||
//修改申请单状态为已排期
|
||||
|
||||
if (!saved) {
|
||||
return R.fail("新增手术安排失败");
|
||||
}
|
||||
|
||||
// Bug #247 修复:更新手术申请单状态为已排期 (1)
|
||||
if (opCreateScheduleDto.getApplyId() != null) {
|
||||
try {
|
||||
// 通过手术单号查找手术申请记录并更新状态
|
||||
LambdaQueryWrapper<com.openhis.clinical.domain.Surgery> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(com.openhis.clinical.domain.Surgery::getSurgeryNo, opSchedule.getOperCode())
|
||||
.eq(com.openhis.clinical.domain.Surgery::getDeleteFlag, "0");
|
||||
com.openhis.clinical.domain.Surgery surgery = surgeryService.getOne(queryWrapper);
|
||||
if (surgery != null) {
|
||||
surgery.setStatusEnum(1); // 1 = 已排期
|
||||
surgery.setUpdateTime(new Date());
|
||||
|
||||
// 填充缺失的申请科室和主刀医生名称
|
||||
fillSurgeryMissingNames(surgery);
|
||||
|
||||
surgeryService.updateById(surgery);
|
||||
log.info("更新手术申请单状态为已排期 - surgeryNo: {}, surgeryId: {}", opSchedule.getOperCode(), surgery.getId());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("更新手术申请单状态失败 - operCode: {}", opSchedule.getOperCode(), e);
|
||||
// 状态更新失败不影响主流程,只记录日志
|
||||
}
|
||||
}
|
||||
|
||||
return R.ok("新增手术安排成功");
|
||||
}
|
||||
|
||||
@@ -158,6 +251,44 @@ public class SurgicalScheduleAppServiceImpl implements ISurgicalScheduleAppServi
|
||||
OpSchedule opSchedule = new OpSchedule();
|
||||
BeanUtils.copyProperties(opScheduleDto, opSchedule);
|
||||
|
||||
// 处理可能为null的字符串字段,设置默认值为空字符串
|
||||
if (opSchedule.getPreoperativeDiagnosis() == null) {
|
||||
opSchedule.setPreoperativeDiagnosis("");
|
||||
}
|
||||
if (opSchedule.getPostoperativeDiagnosis() == null) {
|
||||
opSchedule.setPostoperativeDiagnosis("");
|
||||
}
|
||||
if (opSchedule.getAnesMethod() == null) {
|
||||
opSchedule.setAnesMethod("");
|
||||
}
|
||||
if (opSchedule.getAnesDoctor1Code() == null) {
|
||||
opSchedule.setAnesDoctor1Code("");
|
||||
}
|
||||
if (opSchedule.getAnesDoctor2Code() == null) {
|
||||
opSchedule.setAnesDoctor2Code("");
|
||||
}
|
||||
if (opSchedule.getAnesDoctor3Code() == null) {
|
||||
opSchedule.setAnesDoctor3Code("");
|
||||
}
|
||||
if (opSchedule.getScrubNurseCode() == null) {
|
||||
opSchedule.setScrubNurseCode("");
|
||||
}
|
||||
if (opSchedule.getCircuNurse1Code() == null) {
|
||||
opSchedule.setCircuNurse1Code("");
|
||||
}
|
||||
if (opSchedule.getCircuNurse2Code() == null) {
|
||||
opSchedule.setCircuNurse2Code("");
|
||||
}
|
||||
if (opSchedule.getScrubNurse1Code() == null) {
|
||||
opSchedule.setScrubNurse1Code("");
|
||||
}
|
||||
if (opSchedule.getScrubNurse2Code() == null) {
|
||||
opSchedule.setScrubNurse2Code("");
|
||||
}
|
||||
if (opSchedule.getSurgeonCode() == null) {
|
||||
opSchedule.setSurgeonCode("");
|
||||
}
|
||||
|
||||
// 更新时间
|
||||
opSchedule.setUpdateTime(new Date());
|
||||
|
||||
@@ -240,7 +371,7 @@ public class SurgicalScheduleAppServiceImpl implements ISurgicalScheduleAppServi
|
||||
index, // 序号从1开始
|
||||
schedule.getOrgName() != null ? schedule.getOrgName() : "",
|
||||
schedule.getPatientName() != null ? schedule.getPatientName() : "",
|
||||
schedule.getVisitId() != null ? schedule.getVisitId().toString() : "",
|
||||
schedule.getIdentifierNo() != null ? schedule.getIdentifierNo() : "",
|
||||
schedule.getOperCode() != null ? schedule.getOperCode() : "",
|
||||
schedule.getOperName() != null ? schedule.getOperName() : "",
|
||||
schedule.getApplyDeptName() != null ? schedule.getApplyDeptName() : "",
|
||||
@@ -293,10 +424,84 @@ public class SurgicalScheduleAppServiceImpl implements ISurgicalScheduleAppServi
|
||||
/**
|
||||
* 格式化安排时间
|
||||
*/
|
||||
private String formatScheduleDate(LocalDate scheduleDate) {
|
||||
private String formatScheduleDate(LocalDateTime scheduleDate) {
|
||||
if (scheduleDate == null) return "";
|
||||
|
||||
// 格式化为 yyyy-MM-dd
|
||||
return scheduleDate.format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||
// 格式化为 yyyy-MM-dd HH:mm:ss
|
||||
return scheduleDate.format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 填充手术申请中缺失的名称字段
|
||||
* 在创建手术安排时调用,确保关联的cli_surgery表中的名称字段有值
|
||||
*
|
||||
* @param surgery 手术申请对象
|
||||
*/
|
||||
private void fillSurgeryMissingNames(com.openhis.clinical.domain.Surgery surgery) {
|
||||
// 填充申请科室名称
|
||||
if ((surgery.getApplyDeptName() == null || surgery.getApplyDeptName().isEmpty())
|
||||
&& surgery.getApplyDeptId() != null) {
|
||||
try {
|
||||
com.openhis.administration.domain.Organization org = organizationService.getById(surgery.getApplyDeptId());
|
||||
if (org != null && org.getName() != null) {
|
||||
surgery.setApplyDeptName(org.getName());
|
||||
log.info("填充申请科室名称 - surgeryId: {}, deptId: {}, deptName: {}",
|
||||
surgery.getId(), surgery.getApplyDeptId(), org.getName());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("查询申请科室名称失败 - deptId: {}, error: {}", surgery.getApplyDeptId(), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 填充主刀医生名称
|
||||
if ((surgery.getMainSurgeonName() == null || surgery.getMainSurgeonName().isEmpty())
|
||||
&& surgery.getMainSurgeonId() != null) {
|
||||
try {
|
||||
com.core.common.core.domain.entity.SysUser user = sysUserService.selectUserById(surgery.getMainSurgeonId());
|
||||
if (user != null) {
|
||||
String surgeonName = user.getNickName() != null && !user.getNickName().isEmpty()
|
||||
? user.getNickName()
|
||||
: user.getUserName();
|
||||
if (surgeonName != null) {
|
||||
surgery.setMainSurgeonName(surgeonName);
|
||||
log.info("填充主刀医生名称 - surgeryId: {}, surgeonId: {}, surgeonName: {}",
|
||||
surgery.getId(), surgery.getMainSurgeonId(), surgeonName);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("查询主刀医生名称失败 - surgeonId: {}, error: {}", surgery.getMainSurgeonId(), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 填充麻醉医生名称
|
||||
if ((surgery.getAnesthetistName() == null || surgery.getAnesthetistName().isEmpty())
|
||||
&& surgery.getAnesthetistId() != null) {
|
||||
try {
|
||||
com.core.common.core.domain.entity.SysUser user = sysUserService.selectUserById(surgery.getAnesthetistId());
|
||||
if (user != null) {
|
||||
String anesthetistName = user.getNickName() != null && !user.getNickName().isEmpty()
|
||||
? user.getNickName()
|
||||
: user.getUserName();
|
||||
if (anesthetistName != null) {
|
||||
surgery.setAnesthetistName(anesthetistName);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("查询麻醉医生名称失败 - anesthetistId: {}, error: {}", surgery.getAnesthetistId(), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 填充执行科室名称
|
||||
if ((surgery.getOrgName() == null || surgery.getOrgName().isEmpty())
|
||||
&& surgery.getOrgId() != null) {
|
||||
try {
|
||||
com.openhis.administration.domain.Organization org = organizationService.getById(surgery.getOrgId());
|
||||
if (org != null && org.getName() != null) {
|
||||
surgery.setOrgName(org.getName());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("查询执行科室名称失败 - orgId: {}, error: {}", surgery.getOrgId(), e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,11 @@ public class OpCreateScheduleDto {
|
||||
*/
|
||||
private Long visitId;
|
||||
|
||||
/**
|
||||
* 就诊卡号
|
||||
*/
|
||||
private String identifierNo;
|
||||
|
||||
/**
|
||||
* 手术编码
|
||||
*/
|
||||
@@ -45,9 +50,10 @@ public class OpCreateScheduleDto {
|
||||
private String postoperativeDiagnosis;
|
||||
|
||||
/**
|
||||
* 手术安排日期
|
||||
* 手术安排日期时间
|
||||
*/
|
||||
private LocalDate scheduleDate;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime scheduleDate;
|
||||
|
||||
/**
|
||||
* 手术台次序号
|
||||
@@ -82,11 +88,13 @@ public class OpCreateScheduleDto {
|
||||
/**
|
||||
* 入院时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime admissionTime;
|
||||
|
||||
/**
|
||||
* 入手术室时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime entryTime;
|
||||
|
||||
/**
|
||||
@@ -167,21 +175,25 @@ public class OpCreateScheduleDto {
|
||||
/**
|
||||
* 手术开始时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime startTime;
|
||||
|
||||
/**
|
||||
* 手术结束时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime endTime;
|
||||
|
||||
/**
|
||||
* 麻醉开始时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime anesStart;
|
||||
|
||||
/**
|
||||
* 麻醉结束时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime anesEnd;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.openhis.web.clinicalmanage.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.openhis.surgicalschedule.domain.OpSchedule;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
@@ -17,6 +19,20 @@ import java.time.LocalDate;
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class OpScheduleDto extends OpSchedule {
|
||||
|
||||
/**
|
||||
* 手术安排日期开始(查询用)
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
private LocalDate scheduleDateStart;
|
||||
|
||||
/**
|
||||
* 手术安排日期结束(查询用)
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
private LocalDate scheduleDateEnd;
|
||||
|
||||
/**
|
||||
* 患者姓名
|
||||
*/
|
||||
@@ -27,6 +43,11 @@ public class OpScheduleDto extends OpSchedule {
|
||||
*/
|
||||
private Long encounterId;
|
||||
|
||||
/**
|
||||
* 就诊卡号
|
||||
*/
|
||||
private String patientCardNo;
|
||||
|
||||
/**
|
||||
* 性别
|
||||
*/
|
||||
@@ -55,6 +76,7 @@ public class OpScheduleDto extends OpSchedule {
|
||||
/**
|
||||
* 申请时间开始
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
|
||||
private String applyTime;
|
||||
|
||||
/**
|
||||
|
||||
@@ -45,6 +45,9 @@ public class SurgeryDto {
|
||||
/** 就诊流水号 */
|
||||
private String encounterNo;
|
||||
|
||||
/** 就诊卡号 */
|
||||
private String patientCardNo;
|
||||
|
||||
/** 申请医生ID */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long applyDoctorId;
|
||||
|
||||
@@ -58,4 +58,14 @@ public interface SurgicalScheduleAppMapper {
|
||||
* @return 是否存在冲突的手术安排
|
||||
*/
|
||||
Boolean isScheduleConflict(LocalDateTime startTime, LocalDateTime endTime, String surgeryRoomId);
|
||||
|
||||
/**
|
||||
* 检查是否存在重复的手术安排
|
||||
*
|
||||
* @param patientId 患者ID
|
||||
* @param operCode 手术单号
|
||||
* @param operName 手术名称
|
||||
* @return 是否存在重复记录
|
||||
*/
|
||||
Boolean existsDuplicateSchedule(@Param("patientId") Long patientId, @Param("operCode") String operCode, @Param("operName") String operName);
|
||||
}
|
||||
|
||||
@@ -464,17 +464,86 @@ public class CommonServiceImpl implements ICommonService {
|
||||
*/
|
||||
@Override
|
||||
public List<LocationDto> getPractitionerWard() {
|
||||
// 查询当前登录者管理的病区
|
||||
// 获取当前登录用户信息
|
||||
Long practitionerId = SecurityUtils.getLoginUser().getPractitionerId();
|
||||
Long currentOrgId = SecurityUtils.getLoginUser().getOrgId();
|
||||
|
||||
log.info("getPractitionerWard - practitionerId: {}, currentOrgId: {}", practitionerId, currentOrgId);
|
||||
|
||||
// 获取用户配置的位置 ID 列表(可能包含科室、病区等)
|
||||
List<Long> locationIds = practitionerRoleService.getLocationIdsByPractitionerId(practitionerId);
|
||||
// 获取用户配置的科室 ID 列表
|
||||
List<Long> orgIds = practitionerRoleService.getOrgIdsByPractitionerId(practitionerId);
|
||||
|
||||
log.info("getPractitionerWard - locationIds: {}, orgIds: {}", locationIds, orgIds);
|
||||
|
||||
List<Location> wardList = new ArrayList<>();
|
||||
|
||||
// 方式 1:从 locationIds 中过滤出病区
|
||||
if (locationIds != null && !locationIds.isEmpty()) {
|
||||
// 过滤掉 null 值
|
||||
locationIds = locationIds.stream().filter(id -> id != null).collect(java.util.stream.Collectors.toList());
|
||||
if (!locationIds.isEmpty()) {
|
||||
List<Location> locationList
|
||||
= locationService.getLocationList(locationIds, Collections.singletonList(LocationStatus.ACTIVE.getValue()));
|
||||
List<Location> wardList = new ArrayList<>();
|
||||
for (Location ward : locationList) {
|
||||
if (LocationForm.WARD.getValue().equals(ward.getFormEnum())) {
|
||||
wardList.add(ward);
|
||||
log.info("getPractitionerWard - 从 locationIds 查询到的位置总数:{}", locationList != null ? locationList.size() : 0);
|
||||
|
||||
for (Location location : locationList) {
|
||||
log.info("getPractitionerWard - 位置:id={}, name={}, formEnum={}, organizationId={}",
|
||||
location.getId(), location.getName(), location.getFormEnum(), location.getOrganizationId());
|
||||
if (LocationForm.WARD.getValue().equals(location.getFormEnum())) {
|
||||
// 如果当前有选择科室,只添加当前科室的病区
|
||||
if (currentOrgId == null || currentOrgId.equals(location.getOrganizationId())) {
|
||||
wardList.add(location);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 方式 2:从 orgIds 查询病区(补充查询,确保能获取到病区)
|
||||
if (orgIds != null && !orgIds.isEmpty()) {
|
||||
// 过滤掉 null 值并去重
|
||||
orgIds = orgIds.stream().filter(id -> id != null).distinct().collect(java.util.stream.Collectors.toList());
|
||||
if (!orgIds.isEmpty()) {
|
||||
log.info("getPractitionerWard - 从 orgIds 查询病区,orgIds: {}", orgIds);
|
||||
for (Long orgId : orgIds) {
|
||||
// 如果当前有选择科室,只查询当前科室的病区
|
||||
if (currentOrgId != null && !currentOrgId.equals(orgId)) {
|
||||
continue;
|
||||
}
|
||||
List<Location> orgWards = locationService.getWardList(orgId);
|
||||
log.info("getPractitionerWard - orgId: {} 查询到病区数:{}", orgId, orgWards != null ? orgWards.size() : 0);
|
||||
if (orgWards != null && !orgWards.isEmpty()) {
|
||||
wardList.addAll(orgWards);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 方式 3:如果仍然没有病区,且 currentOrgId 为空,尝试获取所有病区
|
||||
if (wardList.isEmpty() && currentOrgId == null) {
|
||||
log.info("getPractitionerWard - 尝试获取所有病区");
|
||||
List<Location> allWards = locationService.getWardList(null);
|
||||
log.info("getPractitionerWard - 所有病区数:{}", allWards != null ? allWards.size() : 0);
|
||||
if (allWards != null && !allWards.isEmpty()) {
|
||||
wardList.addAll(allWards);
|
||||
}
|
||||
}
|
||||
|
||||
// 去重:根据病区 ID 去重(因为方式 1 和方式 2 可能会查询到相同的病区)
|
||||
if (!wardList.isEmpty()) {
|
||||
wardList = wardList.stream()
|
||||
.collect(java.util.stream.Collectors.collectingAndThen(
|
||||
java.util.stream.Collectors.toCollection(() ->
|
||||
new java.util.TreeSet<>(java.util.Comparator.comparing(Location::getId))),
|
||||
ArrayList::new
|
||||
));
|
||||
}
|
||||
|
||||
log.info("getPractitionerWard - 最终病区数:{}", wardList.size());
|
||||
|
||||
// 转换为 DTO
|
||||
List<LocationDto> locationDtoList = new ArrayList<>();
|
||||
LocationDto locationDto;
|
||||
for (Location ward : wardList) {
|
||||
@@ -482,6 +551,31 @@ public class CommonServiceImpl implements ICommonService {
|
||||
BeanUtils.copyProperties(ward, locationDto);
|
||||
locationDtoList.add(locationDto);
|
||||
}
|
||||
|
||||
return locationDtoList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将Location列表转换为LocationDto列表
|
||||
*
|
||||
* @param locationList Location列表
|
||||
* @return LocationDto列表
|
||||
*/
|
||||
private List<LocationDto> convertToLocationDtoList(List<Location> locationList) {
|
||||
List<LocationDto> locationDtoList = new ArrayList<>();
|
||||
if (locationList == null || locationList.isEmpty()) {
|
||||
return locationDtoList;
|
||||
}
|
||||
|
||||
LocationDto locationDto;
|
||||
for (Location location : locationList) {
|
||||
// 只返回病区类型的位置
|
||||
if (LocationForm.WARD.getValue().equals(location.getFormEnum())) {
|
||||
locationDto = new LocationDto();
|
||||
BeanUtils.copyProperties(location, locationDto);
|
||||
locationDtoList.add(locationDto);
|
||||
}
|
||||
}
|
||||
return locationDtoList;
|
||||
}
|
||||
|
||||
|
||||
@@ -202,8 +202,8 @@ public class CommonAppController {
|
||||
* @return 病区列表
|
||||
*/
|
||||
@GetMapping(value = "/practitioner-ward")
|
||||
public List<LocationDto> getPractitionerWard() {
|
||||
return commonService.getPractitionerWard();
|
||||
public R<?> getPractitionerWard() {
|
||||
return R.ok(commonService.getPractitionerWard());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -149,6 +149,14 @@ public interface IConsultationAppService {
|
||||
* @return 会诊意见列表
|
||||
*/
|
||||
List<ConsultationOpinionDto> getConsultationOpinions(String consultationId);
|
||||
|
||||
/**
|
||||
* 根据ID查询会诊申请详情
|
||||
*
|
||||
* @param id 会诊申请ID
|
||||
* @return 会诊申请详情
|
||||
*/
|
||||
ConsultationRequestDto getConsultationById(Long id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -61,6 +61,8 @@ import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.openhis.web.consultation.enums.ConsultationStatusEnum.CANCELLED;
|
||||
|
||||
/**
|
||||
* 会诊管理AppService实现类
|
||||
*
|
||||
@@ -134,6 +136,8 @@ public class ConsultationAppServiceImpl implements IConsultationAppService {
|
||||
|
||||
// 根据就诊ID,查询该患者的会诊申请
|
||||
wrapper.eq(ConsultationRequest::getEncounterId, encounterId);
|
||||
// 过滤已作废的数据
|
||||
wrapper.ne(ConsultationRequest::getConsultationStatus, CANCELLED.getCode());
|
||||
wrapper.orderByDesc(ConsultationRequest::getCreateTime);
|
||||
|
||||
List<ConsultationRequest> list = consultationRequestMapper.selectList(wrapper);
|
||||
@@ -182,6 +186,11 @@ public class ConsultationAppServiceImpl implements IConsultationAppService {
|
||||
wrapper.like(ConsultationRequest::getPatientName, dto.getPatientName());
|
||||
}
|
||||
|
||||
// 会诊ID查询(支持模糊匹配)
|
||||
if (StringUtils.hasText(dto.getConsultationId())) {
|
||||
wrapper.like(ConsultationRequest::getConsultationId, dto.getConsultationId());
|
||||
}
|
||||
|
||||
// 按创建时间倒序排列
|
||||
wrapper.orderByDesc(ConsultationRequest::getConsultationRequestDate);
|
||||
|
||||
@@ -236,6 +245,11 @@ public class ConsultationAppServiceImpl implements IConsultationAppService {
|
||||
wrapper.like(ConsultationRequest::getPatientName, dto.getPatientName());
|
||||
}
|
||||
|
||||
// 会诊ID查询(支持模糊匹配)
|
||||
if (StringUtils.hasText(dto.getConsultationId())) {
|
||||
wrapper.like(ConsultationRequest::getConsultationId, dto.getConsultationId());
|
||||
}
|
||||
|
||||
// 按创建时间倒序排列
|
||||
wrapper.orderByDesc(ConsultationRequest::getConsultationRequestDate);
|
||||
|
||||
@@ -282,11 +296,15 @@ public class ConsultationAppServiceImpl implements IConsultationAppService {
|
||||
entity = new ConsultationRequest();
|
||||
entity.setConsultationId(generateConsultationId());
|
||||
entity.setTenantId(SecurityUtils.getLoginUser().getTenantId().longValue());
|
||||
entity.setConsultationRequestDate(new Date());
|
||||
}
|
||||
|
||||
// 复制基本属性(现在字段名已统一,可以直接复制)
|
||||
BeanUtils.copyProperties(dto, entity, "id", "consultationId", "invitedList", "submitFlag", "provisionalDiagnosis", "consultationRequestDate");
|
||||
BeanUtils.copyProperties(dto, entity, "id", "consultationId", "invitedList", "submitFlag", "provisionalDiagnosis");
|
||||
|
||||
// 新增时:如果前端没有传递申请时间,使用服务器时间
|
||||
if (!isUpdate && entity.getConsultationRequestDate() == null) {
|
||||
entity.setConsultationRequestDate(new Date());
|
||||
}
|
||||
|
||||
// 如果前端没有传递申请医生ID,使用当前登录用户
|
||||
if (entity.getRequestingPhysicianId() == null) {
|
||||
@@ -427,7 +445,15 @@ public class ConsultationAppServiceImpl implements IConsultationAppService {
|
||||
}
|
||||
|
||||
// 判断是"取消提交"还是"作废"
|
||||
if ("取消提交".equals(cancelReason) && ConsultationStatusEnum.SUBMITTED.getCode().equals(entity.getConsultationStatus())) {
|
||||
if ("取消提交".equals(cancelReason)) {
|
||||
// 状态校验:禁止已确认 (20)、已签名 (30)、已完成 (40) 的会诊申请取消提交
|
||||
if (entity.getConsultationStatus() >= ConsultationStatusEnum.CONFIRMED.getCode()) {
|
||||
throw new IllegalArgumentException("当前状态不允许取消提交,只有已提交状态的会诊申请才能取消提交");
|
||||
}
|
||||
// 只有状态为 10(已提交) 才允许取消提交
|
||||
if (!ConsultationStatusEnum.SUBMITTED.getCode().equals(entity.getConsultationStatus())) {
|
||||
throw new IllegalArgumentException("只有已提交状态的会诊申请才能取消提交");
|
||||
}
|
||||
// 取消提交:将状态从"已提交"改回"新开"
|
||||
entity.setConsultationStatus(ConsultationStatusEnum.NEW.getCode());
|
||||
entity.setConfirmingPhysician(null);
|
||||
@@ -439,8 +465,14 @@ public class ConsultationAppServiceImpl implements IConsultationAppService {
|
||||
updateServiceRequestStatus(entity.getOrderId(), RequestStatus.DRAFT.getValue());
|
||||
|
||||
} else {
|
||||
// 作废:将状态改为"已取消"
|
||||
entity.setConsultationStatus(ConsultationStatusEnum.CANCELLED.getCode());
|
||||
// 作废:状态校验 - 已确认(20)、已签名(30)、已完成(40) 状态禁止作废
|
||||
ConsultationStatusEnum currentStatus = ConsultationStatusEnum.getByCode(entity.getConsultationStatus());
|
||||
if (currentStatus != null && !currentStatus.canCancel()) {
|
||||
throw new IllegalArgumentException("当前状态【" + currentStatus.getDescription() + "】不允许作废,只有新开或已提交状态的会诊申请才能作废");
|
||||
}
|
||||
|
||||
// 将状态改为"已取消"
|
||||
entity.setConsultationStatus(CANCELLED.getCode());
|
||||
entity.setCancelReason(cancelReason);
|
||||
entity.setCancelNatureDate(new Date());
|
||||
consultationRequestMapper.updateById(entity);
|
||||
@@ -709,38 +741,64 @@ public class ConsultationAppServiceImpl implements IConsultationAppService {
|
||||
|
||||
dto.setInvitedList(invitedDtoList);
|
||||
|
||||
// 🎯 如果会诊已完成或已签名,填充会诊记录信息(从已签名的医生中获取)
|
||||
|
||||
// 🎯 如果会诊已确认、已签名或已完成,填充会诊记录信息(从会诊确认表中获取)
|
||||
// 会诊状态:20=已确认,30=已签名,40=已完成
|
||||
if (entity.getConsultationStatus() != null &&
|
||||
(entity.getConsultationStatus() == ConsultationStatusEnum.SIGNED.getCode() ||
|
||||
entity.getConsultationStatus() == ConsultationStatusEnum.COMPLETED.getCode())) {
|
||||
entity.getConsultationStatus() >= ConsultationStatusEnum.CONFIRMED.getCode()) {
|
||||
|
||||
// 查询会诊确认记录
|
||||
LambdaQueryWrapper<ConsultationConfirmation> confirmWrapper = new LambdaQueryWrapper<>();
|
||||
confirmWrapper.eq(ConsultationConfirmation::getConsultationRequestId, entity.getId());
|
||||
ConsultationConfirmation confirmation = consultationConfirmationMapper.selectOne(confirmWrapper);
|
||||
|
||||
// 查询所有已确认和已签名的医生(invited_status >= 2)
|
||||
List<ConsultationInvited> confirmedAndSignedPhysicians = invitedList.stream()
|
||||
.filter(inv -> inv.getInvitedStatus() != null && inv.getInvitedStatus() >= 2)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 查询所有已签名的医生(invited_status >= 3)
|
||||
List<ConsultationInvited> signedPhysicians = invitedList.stream()
|
||||
.filter(inv -> inv.getInvitedStatus() != null && inv.getInvitedStatus() >= 3)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (!signedPhysicians.isEmpty()) {
|
||||
// 1. 会诊邀请参加医师:拼接所有已签名医生的"科室-姓名"
|
||||
String invitedPhysiciansText = signedPhysicians.stream()
|
||||
if (confirmation != null) {
|
||||
// 1. 会诊确认参加医师:优先从确认表的confirming_physicians字段取值
|
||||
if (StringUtils.hasText(confirmation.getConfirmingPhysicians())) {
|
||||
dto.setInvitedPhysiciansText(confirmation.getConfirmingPhysicians());
|
||||
} else if (!confirmedAndSignedPhysicians.isEmpty()) {
|
||||
// 备用:从invitedList拼接
|
||||
String invitedPhysiciansText = confirmedAndSignedPhysicians.stream()
|
||||
.map(inv -> inv.getInvitedDepartmentName() + "-" + inv.getInvitedPhysicianName())
|
||||
.collect(Collectors.joining("、"));
|
||||
dto.setInvitedPhysiciansText(invitedPhysiciansText);
|
||||
}
|
||||
|
||||
// 2. 会诊意见:汇总所有已签名医生的意见
|
||||
String consultationOpinion = signedPhysicians.stream()
|
||||
// 2. 会诊意见:优先从确认表取值
|
||||
if (StringUtils.hasText(confirmation.getConsultationOpinion())) {
|
||||
dto.setConsultationOpinion(confirmation.getConsultationOpinion());
|
||||
} else if (!confirmedAndSignedPhysicians.isEmpty()) {
|
||||
// 备用:从invitedList汇总
|
||||
String consultationOpinion = confirmedAndSignedPhysicians.stream()
|
||||
.filter(inv -> StringUtils.hasText(inv.getConfirmOpinion()))
|
||||
.map(ConsultationInvited::getConfirmOpinion)
|
||||
.collect(Collectors.joining("\n"));
|
||||
dto.setConsultationOpinion(consultationOpinion);
|
||||
}
|
||||
|
||||
// 3. 所属医生、代表科室、签名医生、签名时间:使用第一个签名的医生
|
||||
ConsultationInvited firstSigned = signedPhysicians.get(0);
|
||||
dto.setAttendingPhysician(firstSigned.getInvitedPhysicianName());
|
||||
dto.setRepresentDepartment(firstSigned.getInvitedDepartmentName());
|
||||
dto.setSignPhysician(firstSigned.getInvitedPhysicianName());
|
||||
dto.setSignTime(firstSigned.getSignatureTime());
|
||||
// 3. 签名医生、签名时间:从确认表取值
|
||||
dto.setSignPhysician(confirmation.getSignature());
|
||||
dto.setSignTime(confirmation.getSignatureDate());
|
||||
}
|
||||
|
||||
log.info("填充会诊记录信息,已签名医生数:{}", signedPhysicians.size());
|
||||
// 4. 所属医生、代表科室:使用第一个确认的医生(向后兼容)
|
||||
if (!confirmedAndSignedPhysicians.isEmpty()) {
|
||||
ConsultationInvited firstConfirmed = confirmedAndSignedPhysicians.get(0);
|
||||
dto.setAttendingPhysician(firstConfirmed.getInvitedPhysicianName());
|
||||
dto.setRepresentDepartment(firstConfirmed.getInvitedDepartmentName());
|
||||
|
||||
log.info("填充会诊记录信息,已确认和已签名医生数:{},已签名医生数:{}",
|
||||
confirmedAndSignedPhysicians.size(), signedPhysicians.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1775,5 +1833,26 @@ public class ConsultationAppServiceImpl implements IConsultationAppService {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConsultationRequestDto getConsultationById(Long id) {
|
||||
try {
|
||||
if (id == null) {
|
||||
throw new IllegalArgumentException("会诊申请ID不能为空");
|
||||
}
|
||||
|
||||
// 1. 查询会诊申请
|
||||
ConsultationRequest request = consultationRequestMapper.selectById(id);
|
||||
if (request == null) {
|
||||
throw new IllegalArgumentException("会诊申请不存在,ID: " + id);
|
||||
}
|
||||
|
||||
// 2. 转换为DTO并返回
|
||||
return convertToDto(request);
|
||||
} catch (Exception e) {
|
||||
log.error("查询会诊申请详情失败", e);
|
||||
throw new RuntimeException("查询会诊申请详情失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -302,5 +302,21 @@ public class ConsultationController {
|
||||
return R.fail("获取会诊意见列表失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ID查询会诊申请详情
|
||||
*/
|
||||
@ApiOperation("根据ID查询会诊申请详情")
|
||||
@GetMapping("/detail/{id}")
|
||||
public R<ConsultationRequestDto> getConsultationById(
|
||||
@ApiParam("会诊申请ID") @PathVariable Long id) {
|
||||
try {
|
||||
ConsultationRequestDto detail = consultationAppService.getConsultationById(id);
|
||||
return R.ok(detail);
|
||||
} catch (Exception e) {
|
||||
log.error("查询会诊申请详情失败", e);
|
||||
return R.fail("查询会诊申请详情失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ public enum ConsultationStatusEnum {
|
||||
/**
|
||||
* 已取消
|
||||
*/
|
||||
CANCELLED(50, "已取消");
|
||||
CANCELLED(50, "已取消/作废");
|
||||
|
||||
/**
|
||||
* 状态码
|
||||
@@ -76,10 +76,12 @@ public enum ConsultationStatusEnum {
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否可以取消
|
||||
* 判断是否可以取消/作废
|
||||
* 只有新开(0)和已提交(10)状态可以作废
|
||||
* 已确认(20)、已签名(30)、已完成(40)状态禁止作废
|
||||
*/
|
||||
public boolean canCancel() {
|
||||
return this == NEW || this == SUBMITTED || this == CONFIRMED;
|
||||
return this == NEW || this == SUBMITTED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -130,4 +130,13 @@ public interface IDiagTreatMAppService {
|
||||
* @return 结果
|
||||
*/
|
||||
R<?> updatePricingFlag(List<Long> ids, Integer pricingFlag);
|
||||
|
||||
/**
|
||||
* 诊疗目录下拉列表(轻量级,用于套餐设置)
|
||||
*
|
||||
* @param statusEnum 状态(2=启用)
|
||||
* @param searchKey 搜索关键词(可选)
|
||||
* @return 只包含 id, name, busNo, retailPrice
|
||||
*/
|
||||
R<?> getDiagnosisTreatmentSimpleList(Integer statusEnum, String searchKey);
|
||||
}
|
||||
@@ -78,7 +78,6 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
|
||||
private IOperationRecordService operationRecordService;
|
||||
@Resource
|
||||
private IServiceRequestService serviceRequestService;
|
||||
|
||||
/**
|
||||
* 诊疗目录初期查询
|
||||
*
|
||||
@@ -186,6 +185,14 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
|
||||
public R<?> getDiseaseTreatmentPage(DiagnosisTreatmentSelParam DiagnosisTreatmentSelParam, String searchKey,
|
||||
Integer pageNo, Integer pageSize, HttpServletRequest request) {
|
||||
|
||||
// 如果没有指定状态,默认只查询启用状态(status_enum=2),避免显示未启用的项目导致保存失败
|
||||
if (DiagnosisTreatmentSelParam == null) {
|
||||
DiagnosisTreatmentSelParam = new DiagnosisTreatmentSelParam();
|
||||
}
|
||||
if (DiagnosisTreatmentSelParam.getStatusEnum() == null) {
|
||||
DiagnosisTreatmentSelParam.setStatusEnum(PublicationStatus.ACTIVE.getValue());
|
||||
}
|
||||
|
||||
// 临时保存ybType值并从参数对象中移除,避免HisQueryUtils构建yb_type条件
|
||||
String ybTypeValue = null;
|
||||
if (DiagnosisTreatmentSelParam != null && StringUtils.isNotEmpty(DiagnosisTreatmentSelParam.getYbType())) {
|
||||
@@ -193,9 +200,23 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
|
||||
DiagnosisTreatmentSelParam.setYbType(null); // 临时移除,防止HisQueryUtils处理
|
||||
}
|
||||
|
||||
// 临时保存inspectionTypeId值,手动添加带表别名的条件
|
||||
Long inspectionTypeIdValue = null;
|
||||
if (DiagnosisTreatmentSelParam != null && DiagnosisTreatmentSelParam.getInspectionTypeId() != null) {
|
||||
inspectionTypeIdValue = DiagnosisTreatmentSelParam.getInspectionTypeId();
|
||||
DiagnosisTreatmentSelParam.setInspectionTypeId(null); // 临时移除,防止HisQueryUtils处理
|
||||
}
|
||||
|
||||
// 临时保存pricingFlag值,手动添加带表别名的条件
|
||||
Integer pricingFlagValue = null;
|
||||
if (DiagnosisTreatmentSelParam != null && DiagnosisTreatmentSelParam.getPricingFlag() != null) {
|
||||
pricingFlagValue = DiagnosisTreatmentSelParam.getPricingFlag();
|
||||
DiagnosisTreatmentSelParam.setPricingFlag(null); // 临时移除,防止HisQueryUtils处理
|
||||
}
|
||||
|
||||
// 构建查询条件
|
||||
QueryWrapper<DiagnosisTreatmentDto> queryWrapper = HisQueryUtils.buildQueryWrapper(DiagnosisTreatmentSelParam,
|
||||
searchKey, new HashSet<>(Arrays.asList("bus_no", "name", "py_str", "wb_str")), request);
|
||||
searchKey, new HashSet<>(Arrays.asList("T1.bus_no", "T1.name", "T1.py_str", "T1.wb_str")), request);
|
||||
|
||||
// 如果需要按医保类型过滤(如挂号费类型13),添加带表别名的条件
|
||||
if (ybTypeValue != null) {
|
||||
@@ -204,9 +225,22 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
|
||||
DiagnosisTreatmentSelParam.setYbType(ybTypeValue);
|
||||
}
|
||||
|
||||
// 分页查询
|
||||
// 如果需要按检验类型过滤,添加带表别名的条件
|
||||
if (inspectionTypeIdValue != null) {
|
||||
queryWrapper.eq("T1.inspection_type_id", inspectionTypeIdValue);
|
||||
// 恢复参数对象中的值
|
||||
DiagnosisTreatmentSelParam.setInspectionTypeId(inspectionTypeIdValue);
|
||||
}
|
||||
|
||||
// 如果需要按划价标记过滤,添加带表别名的条件
|
||||
if (pricingFlagValue != null) {
|
||||
queryWrapper.eq("T1.pricing_flag", pricingFlagValue);
|
||||
// 恢复参数对象中的值
|
||||
DiagnosisTreatmentSelParam.setPricingFlag(pricingFlagValue);
|
||||
}
|
||||
|
||||
IPage<DiagnosisTreatmentDto> diseaseTreatmentPage
|
||||
= activityDefinitionManageMapper.getDiseaseTreatmentPage(new Page<DiagnosisTreatmentDto>(pageNo, pageSize), queryWrapper);
|
||||
= activityDefinitionManageMapper.getDiseaseTreatmentPage(new Page<>(pageNo, pageSize), queryWrapper);
|
||||
|
||||
diseaseTreatmentPage.getRecords().forEach(e -> {
|
||||
// 医保标记枚举类回显赋值
|
||||
@@ -266,24 +300,19 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取诊查项目列表(医保类型为02)
|
||||
* 获取诊查项目列表(医保类型为02,返回全量数据)
|
||||
*
|
||||
* @param orgId 科室ID
|
||||
* @param orgId 科室ID(兼容保留,不参与过滤)
|
||||
* @return 诊查项目列表
|
||||
*/
|
||||
@Override
|
||||
public R<?> getClinicItems(Long orgId) {
|
||||
// 构建查询条件,只查询医保类型为02(诊查费)的项目
|
||||
// 构建查询条件,只查询医保类型为02(诊察费)的项目,不按科室过滤
|
||||
QueryWrapper<DiagnosisTreatmentDto> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("T2.yb_type", "02"); // 使用T2表的yb_type字段,避免歧义
|
||||
queryWrapper.eq("T1.delete_flag", "0"); // 只查询未删除的记录
|
||||
queryWrapper.eq("T2.instance_table", "wor_activity_definition"); // 确保关联正确
|
||||
|
||||
// 如果提供了科室ID,则过滤该科室的项目
|
||||
if (orgId != null) {
|
||||
queryWrapper.eq("T1.org_id", orgId); // 使用机构ID进行过滤
|
||||
}
|
||||
|
||||
// 分页查询,设置一个较大的页大小以获取所有诊查项目
|
||||
IPage<DiagnosisTreatmentDto> diseaseTreatmentPage
|
||||
= activityDefinitionManageMapper.getDiseaseTreatmentPage(new Page<DiagnosisTreatmentDto>(1, 100), queryWrapper);
|
||||
@@ -336,6 +365,8 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
|
||||
// 显式设置新增的字段
|
||||
activityDefinition.setSortOrder(diagnosisTreatmentUpDto.getSortOrder());
|
||||
activityDefinition.setServiceRange(diagnosisTreatmentUpDto.getServiceRange());
|
||||
// 显式设置检验类型ID
|
||||
activityDefinition.setInspectionTypeId(diagnosisTreatmentUpDto.getInspectionTypeId());
|
||||
// 显式设置划价标记(避免前端字段/类型差异导致 copyProperties 后仍为默认值)
|
||||
activityDefinition.setPricingFlag(diagnosisTreatmentUpDto.getPricingFlag());
|
||||
|
||||
@@ -414,24 +445,17 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
|
||||
*/
|
||||
@Override
|
||||
public R<?> editDiseaseTreatmentStop(List<Long> ids) {
|
||||
|
||||
List<ActivityDefinition> ActivityDefinitionList = new CopyOnWriteArrayList<>();
|
||||
|
||||
// 取得更新值
|
||||
for (Long detail : ids) {
|
||||
ActivityDefinition ActivityDefinition = new ActivityDefinition();
|
||||
ActivityDefinition.setId(detail);
|
||||
ActivityDefinition.setStatusEnum(PublicationStatus.RETIRED.getValue());
|
||||
ActivityDefinitionList.add(ActivityDefinition);
|
||||
List<ActivityDefinition> actList = new CopyOnWriteArrayList<>();
|
||||
for (Long id : ids) {
|
||||
ActivityDefinition act = new ActivityDefinition();
|
||||
act.setId(id);
|
||||
act.setStatusEnum(PublicationStatus.RETIRED.getValue());
|
||||
actList.add(act);
|
||||
}
|
||||
// 插入操作记录
|
||||
operationRecordService.addIdsOperationRecord(DbOpType.STOP.getCode(),
|
||||
CommonConstants.TableName.WOR_ACTIVITY_DEFINITION, ids);
|
||||
// 更新诊疗信息
|
||||
return activityDefinitionService.updateBatchById(ActivityDefinitionList)
|
||||
? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"诊疗目录"}))
|
||||
: R.fail(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
|
||||
activityDefinitionService.updateBatchById(actList);
|
||||
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"\u8bca\u7597\u76ee\u5f55"}));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -442,24 +466,17 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
|
||||
*/
|
||||
@Override
|
||||
public R<?> editDiseaseTreatmentStart(List<Long> ids) {
|
||||
|
||||
List<ActivityDefinition> ActivityDefinitionList = new CopyOnWriteArrayList<>();
|
||||
|
||||
// 取得更新值
|
||||
for (Long detail : ids) {
|
||||
ActivityDefinition ActivityDefinition = new ActivityDefinition();
|
||||
ActivityDefinition.setId(detail);
|
||||
ActivityDefinition.setStatusEnum(PublicationStatus.ACTIVE.getValue());
|
||||
ActivityDefinitionList.add(ActivityDefinition);
|
||||
List<ActivityDefinition> actList = new CopyOnWriteArrayList<>();
|
||||
for (Long id : ids) {
|
||||
ActivityDefinition act = new ActivityDefinition();
|
||||
act.setId(id);
|
||||
act.setStatusEnum(PublicationStatus.ACTIVE.getValue());
|
||||
actList.add(act);
|
||||
}
|
||||
// 插入操作记录
|
||||
operationRecordService.addIdsOperationRecord(DbOpType.START.getCode(),
|
||||
CommonConstants.TableName.WOR_ACTIVITY_DEFINITION, ids);
|
||||
// 更新诊疗信息
|
||||
return activityDefinitionService.updateBatchById(ActivityDefinitionList)
|
||||
? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"诊疗目录"}))
|
||||
: R.fail(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
|
||||
activityDefinitionService.updateBatchById(actList);
|
||||
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"诊疗目录"}));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -483,6 +500,8 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
|
||||
// 显式设置新增的字段
|
||||
activityDefinition.setSortOrder(diagnosisTreatmentUpDto.getSortOrder());
|
||||
activityDefinition.setServiceRange(diagnosisTreatmentUpDto.getServiceRange());
|
||||
// 显式设置检验类型ID
|
||||
activityDefinition.setInspectionTypeId(diagnosisTreatmentUpDto.getInspectionTypeId());
|
||||
|
||||
// 如果前端没有传入编码,则使用10位数基础采番
|
||||
if (StringUtils.isEmpty(activityDefinition.getBusNo())) {
|
||||
@@ -795,4 +814,20 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
|
||||
}
|
||||
return activityDefinition;
|
||||
}
|
||||
|
||||
/**
|
||||
* 诊疗目录下拉列表(轻量级,用于套餐设置)
|
||||
* 只查询必要字段,减少JOIN,提高查询速度
|
||||
* 支持搜索关键词过滤
|
||||
*
|
||||
* @param statusEnum 状态(2=启用)
|
||||
* @param searchKey 搜索关键词
|
||||
* @return 只包含 id, name, busNo, retailPrice
|
||||
*/
|
||||
@Override
|
||||
public R<?> getDiagnosisTreatmentSimpleList(Integer statusEnum, String searchKey) {
|
||||
Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
|
||||
List<DiagnosisTreatmentDto> list = activityDefinitionManageMapper.getDiagnosisTreatmentSimpleList(statusEnum, tenantId, searchKey);
|
||||
return R.ok(list);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package com.openhis.web.datadictionary.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.lab.domain.InspectionType;
|
||||
import com.openhis.lab.service.IInspectionTypeService;
|
||||
import com.openhis.web.datadictionary.appservice.IDiagTreatMAppService;
|
||||
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentSelParam;
|
||||
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentUpDto;
|
||||
@@ -30,6 +33,9 @@ public class DiagnosisTreatmentController {
|
||||
@Resource
|
||||
private IDiagTreatMAppService diagTreatMAppService;
|
||||
|
||||
@Resource
|
||||
private IInspectionTypeService inspectionTypeService;
|
||||
|
||||
/**
|
||||
* 诊疗目录初期查询
|
||||
*
|
||||
@@ -188,4 +194,34 @@ public class DiagnosisTreatmentController {
|
||||
public R<?> updatePricingFlag(@RequestBody List<Long> ids, @RequestParam Integer pricingFlag) {
|
||||
return diagTreatMAppService.updatePricingFlag(ids, pricingFlag);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取检验类型列表(用于下拉框)
|
||||
*
|
||||
* @return 检验类型列表
|
||||
*/
|
||||
@GetMapping("/inspection-types")
|
||||
public R<?> getInspectionTypes() {
|
||||
LambdaQueryWrapper<InspectionType> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(InspectionType::getValidFlag, 1)
|
||||
.orderByAsc(InspectionType::getSortOrder);
|
||||
return R.ok(inspectionTypeService.list(queryWrapper));
|
||||
}
|
||||
|
||||
/**
|
||||
* 诊疗目录下拉列表(轻量级,用于套餐设置)
|
||||
* 只查询必要字段,减少JOIN,提高查询速度
|
||||
* 支持搜索关键词过滤
|
||||
*
|
||||
* @param statusEnum 状态(2=启用)
|
||||
* @param searchKey 搜索关键词
|
||||
* @return 只包含 id, name, busNo, retailPrice
|
||||
*/
|
||||
@GetMapping("/simple-list")
|
||||
public R<?> getDiagnosisTreatmentSimpleList(@RequestParam(required = false) Integer statusEnum, @RequestParam(required = false) String searchKey) {
|
||||
if (statusEnum == null) {
|
||||
statusEnum = 2;
|
||||
}
|
||||
return diagTreatMAppService.getDiagnosisTreatmentSimpleList(statusEnum, searchKey);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,4 +130,27 @@ public class DiagnosisTreatmentDto {
|
||||
|
||||
/** 服务范围 */
|
||||
private String serviceRange;
|
||||
|
||||
/** 检验类型ID */
|
||||
@Dict(dictTable = "inspection_type", dictCode = "id", dictText = "name", deleteFlag = "valid_flag")
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long inspectionTypeId;
|
||||
private String inspectionTypeId_dictText;
|
||||
|
||||
/** 检验类型名称(用于前端 testType 字段) */
|
||||
private String testType;
|
||||
|
||||
/** 费用套餐ID(关联 inspection_basic_information) */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long feePackageId;
|
||||
|
||||
/** 费用套餐名称(JOIN inspection_basic_information.package_name) */
|
||||
private String packageName;
|
||||
|
||||
/** 下级医技类型ID(关联 inspection_type 子类) */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long subItemId;
|
||||
|
||||
/** 下级医技类型名称(JOIN inspection_type.name) */
|
||||
private String subItemName;
|
||||
}
|
||||
|
||||
@@ -30,4 +30,10 @@ public class DiagnosisTreatmentSelParam {
|
||||
|
||||
/** 状态 */
|
||||
private Integer statusEnum;
|
||||
|
||||
/** 检验类型ID */
|
||||
private Long inspectionTypeId;
|
||||
|
||||
/** 划价标记 */
|
||||
private Integer pricingFlag;
|
||||
}
|
||||
|
||||
@@ -128,4 +128,16 @@ public class DiagnosisTreatmentUpDto {
|
||||
|
||||
/** 服务范围 */
|
||||
private String serviceRange;
|
||||
|
||||
/** 检验类型ID(关联 inspection_type 大类,parent_id 为空) */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long inspectionTypeId;
|
||||
|
||||
/** 费用套餐ID(关联 inspection_basic_information) */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long feePackageId;
|
||||
|
||||
/** 下级医技类型ID(关联 inspection_type 子类,parent_id 不为空) */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long subItemId;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import com.openhis.web.datadictionary.dto.DiagnosisTreatmentDto;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 诊疗定义管理
|
||||
*
|
||||
@@ -36,4 +38,14 @@ public interface ActivityDefinitionManageMapper {
|
||||
*/
|
||||
DiagnosisTreatmentDto getDiseaseTreatmentOne(@Param("id") Long id, @Param("tenantId") Integer tenantId);
|
||||
|
||||
/**
|
||||
* 诊疗目录下拉列表(轻量级,只查4个字段)
|
||||
*
|
||||
* @param statusEnum 状态
|
||||
* @param tenantId 租户ID
|
||||
* @param searchKey 搜索关键词(可选)
|
||||
* @return id, name, busNo, retailPrice
|
||||
*/
|
||||
List<DiagnosisTreatmentDto> getDiagnosisTreatmentSimpleList(@Param("statusEnum") Integer statusEnum, @Param("tenantId") Integer tenantId, @Param("searchKey") String searchKey);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.openhis.web.datadictionary.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentDto;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 检验项目定义管理 Mapper(操作 lab_activity_definition 表)
|
||||
*/
|
||||
@Repository
|
||||
public interface LabActivityDefinitionManageMapper {
|
||||
|
||||
/**
|
||||
* 检验项目分页查询
|
||||
*
|
||||
* @param page 分页参数
|
||||
* @param queryWrapper 查询条件
|
||||
* @return 分页结果
|
||||
*/
|
||||
IPage<DiagnosisTreatmentDto> getLabActivityDefinitionPage(
|
||||
@Param("page") Page<DiagnosisTreatmentDto> page,
|
||||
@Param(Constants.WRAPPER) QueryWrapper<DiagnosisTreatmentDto> queryWrapper);
|
||||
|
||||
/**
|
||||
* 检验项目详情
|
||||
*
|
||||
* @param id 项目ID
|
||||
* @param tenantId 租户ID
|
||||
* @return 详情
|
||||
*/
|
||||
DiagnosisTreatmentDto getLabActivityDefinitionOne(@Param("id") Long id, @Param("tenantId") Integer tenantId);
|
||||
|
||||
/**
|
||||
* 检验项目下拉列表(轻量级)
|
||||
*
|
||||
* @param statusEnum 状态
|
||||
* @param tenantId 租户ID
|
||||
* @param searchKey 搜索关键词(可选)
|
||||
* @return 列表
|
||||
*/
|
||||
List<DiagnosisTreatmentDto> getLabActivityDefinitionSimpleList(
|
||||
@Param("statusEnum") Integer statusEnum,
|
||||
@Param("tenantId") Integer tenantId,
|
||||
@Param("searchKey") String searchKey);
|
||||
}
|
||||
@@ -31,7 +31,7 @@ public interface IDoctorStationAdviceAppService {
|
||||
*/
|
||||
IPage<AdviceBaseDto> getAdviceBaseInfo(AdviceBaseDto adviceBaseDto, String searchKey, Long locationId,
|
||||
List<Long> adviceDefinitionIdParamList, Long organizationId, Integer pageNo, Integer pageSize,
|
||||
Integer pricingFlag, List<Integer> adviceTypes, String orderPricing);
|
||||
Integer pricingFlag, List<Integer> adviceTypes, String orderPricing, String categoryCode);
|
||||
|
||||
/**
|
||||
* 查询医嘱绑定信息
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,8 +10,10 @@ import com.core.common.utils.AssignSeqUtil;
|
||||
import com.core.common.utils.MessageUtils;
|
||||
import com.core.common.utils.SecurityUtils;
|
||||
import com.core.common.utils.StringUtils;
|
||||
import com.openhis.administration.domain.Account;
|
||||
import com.openhis.administration.domain.ChargeItem;
|
||||
import com.openhis.administration.domain.EncounterDiagnosis;
|
||||
import com.openhis.administration.service.IAccountService;
|
||||
import com.openhis.administration.service.IChargeItemService;
|
||||
import com.openhis.administration.service.IEncounterDiagnosisService;
|
||||
import com.openhis.clinical.domain.Condition;
|
||||
@@ -80,6 +82,9 @@ public class DoctorStationChineseMedicalAppServiceImpl implements IDoctorStation
|
||||
@Resource
|
||||
AdviceUtils adviceUtils;
|
||||
|
||||
@Resource
|
||||
IAccountService iAccountService;
|
||||
|
||||
/**
|
||||
* 查询中医诊断数据
|
||||
*
|
||||
@@ -364,7 +369,7 @@ public class DoctorStationChineseMedicalAppServiceImpl implements IDoctorStation
|
||||
adviceBaseDto.setAdviceType(1); // 医嘱类型为药品
|
||||
adviceBaseDto.setCategoryCode(MedCategoryCode.CHINESE_HERBAL_MEDICINE.getValue());// 中草药
|
||||
return iDoctorStationAdviceAppService.getAdviceBaseInfo(adviceBaseDto, searchKey, locationId,
|
||||
adviceDefinitionIdParamList, organizationId, pageNo, pageSize, pricingFlag, List.of(1, 2, 3), null);
|
||||
adviceDefinitionIdParamList, organizationId, pageNo, pageSize, pricingFlag, List.of(1, 2, 3), null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -475,6 +480,28 @@ public class DoctorStationChineseMedicalAppServiceImpl implements IDoctorStation
|
||||
// 医嘱签发编码
|
||||
String signCode = assignSeqUtil.getSeq(AssignSeqEnum.ADVICE_SIGN.getPrefix(), 10);
|
||||
for (AdviceSaveDto adviceSaveDto : insertOrUpdateList) {
|
||||
// 🔧 Bug Fix: 确保accountId不为null
|
||||
if (adviceSaveDto.getAccountId() == null) {
|
||||
// 尝试从患者就诊中获取默认账户ID(自费账户)
|
||||
Account selfAccount = iAccountService.getSelfAccount(adviceSaveDto.getEncounterId());
|
||||
if (selfAccount != null) {
|
||||
adviceSaveDto.setAccountId(selfAccount.getId());
|
||||
} else {
|
||||
// 自动创建自费账户
|
||||
Account newAccount = new Account();
|
||||
newAccount.setPatientId(adviceSaveDto.getPatientId());
|
||||
newAccount.setEncounterId(adviceSaveDto.getEncounterId());
|
||||
newAccount.setContractNo(CommonConstants.BusinessName.DEFAULT_CONTRACT_NO);
|
||||
newAccount.setTypeCode(AccountType.PERSONAL_CASH_ACCOUNT.getCode());
|
||||
newAccount.setBalanceAmount(BigDecimal.ZERO);
|
||||
newAccount.setStatusEnum(AccountStatus.ACTIVE.getValue());
|
||||
newAccount.setEncounterFlag(Whether.YES.getValue());
|
||||
newAccount.setName(AccountType.PERSONAL_CASH_ACCOUNT.getInfo());
|
||||
Long newAccountId = iAccountService.saveAccountByRegister(newAccount);
|
||||
adviceSaveDto.setAccountId(newAccountId);
|
||||
}
|
||||
}
|
||||
|
||||
// 中药付数
|
||||
BigDecimal chineseHerbsDoseQuantity = adviceSaveDto.getChineseHerbsDoseQuantity();
|
||||
medicationRequest = new MedicationRequest();
|
||||
@@ -586,7 +613,7 @@ public class DoctorStationChineseMedicalAppServiceImpl implements IDoctorStation
|
||||
|
||||
// 对应的诊疗医嘱信息
|
||||
AdviceBaseDto activityAdviceBaseDto = iDoctorStationAdviceAppService.getAdviceBaseInfo(adviceBaseDto, null,
|
||||
null, null, organizationId, 1, 1, Whether.NO.getValue(), List.of(3), null).getRecords().get(0);
|
||||
null, null, organizationId, 1, 1, Whether.NO.getValue(), List.of(3), null, null).getRecords().get(0);
|
||||
if (activityAdviceBaseDto != null) {
|
||||
// 费用定价
|
||||
AdvicePriceDto advicePriceDto = activityAdviceBaseDto.getPriceList().get(0);
|
||||
|
||||
@@ -36,10 +36,11 @@ import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Date;
|
||||
import java.util.*;
|
||||
|
||||
import static com.openhis.common.constant.CommonConstants.FieldName.DeleteFlag;
|
||||
import static com.openhis.common.enums.ReportCardStatus.SUBMITTED;
|
||||
import static java.time.LocalDateTime.now;
|
||||
|
||||
/**
|
||||
@@ -272,12 +273,28 @@ public class DoctorStationDiagnosisAppServiceImpl implements IDoctorStationDiagn
|
||||
*/
|
||||
@Override
|
||||
public R<?> saveDoctorDiagnosisNew(SaveDiagnosisParam saveDiagnosisParam) {
|
||||
// 参数校验:确保诊断列表不为空
|
||||
if (saveDiagnosisParam == null) {
|
||||
return R.fail(MessageUtils.message(PromptMsgConstant.Common.M00009, new Object[] { "保存诊断参数" }));
|
||||
}
|
||||
|
||||
// 患者id
|
||||
Long patientId = saveDiagnosisParam.getPatientId();
|
||||
// 就诊ID
|
||||
Long encounterId = saveDiagnosisParam.getEncounterId();
|
||||
// 诊断定义集合
|
||||
List<SaveDiagnosisChildParam> diagnosisChildList = saveDiagnosisParam.getDiagnosisChildList();
|
||||
|
||||
// 校验患者ID和就诊ID
|
||||
if (patientId == null || encounterId == null) {
|
||||
return R.fail(MessageUtils.message(PromptMsgConstant.Common.M00009, new Object[] { "患者ID或就诊ID" }));
|
||||
}
|
||||
|
||||
// 校验诊断列表不为空
|
||||
if (diagnosisChildList == null || diagnosisChildList.isEmpty()) {
|
||||
return R.fail(MessageUtils.message(PromptMsgConstant.Common.M00009, new Object[] { "诊断列表" }));
|
||||
}
|
||||
|
||||
// 先删除再保存
|
||||
// iEncounterDiagnosisService.deleteEncounterDiagnosisInfos(encounterId);
|
||||
|
||||
@@ -353,8 +370,6 @@ public class DoctorStationDiagnosisAppServiceImpl implements IDoctorStationDiagn
|
||||
encounterDiagnosis.setLongTermFlag(saveDiagnosisChildParam.getLongTermFlag());
|
||||
encounterDiagnosis.setOnsetDate(saveDiagnosisChildParam.getOnsetDate());
|
||||
encounterDiagnosis.setDiagnosisTime(saveDiagnosisChildParam.getDiagnosisTime());
|
||||
encounterDiagnosis.setOnsetDate(saveDiagnosisChildParam.getOnsetDate());
|
||||
encounterDiagnosis.setDiagnosisTime(saveDiagnosisChildParam.getDiagnosisTime());
|
||||
if(encounterDiagnosis.getCreateBy() == null){
|
||||
encounterDiagnosis.setCreateBy(username);
|
||||
}
|
||||
@@ -383,8 +398,6 @@ public class DoctorStationDiagnosisAppServiceImpl implements IDoctorStationDiagn
|
||||
encounterDiagnosis.setLongTermFlag(saveDiagnosisChildParam.getLongTermFlag());
|
||||
encounterDiagnosis.setOnsetDate(saveDiagnosisChildParam.getOnsetDate());
|
||||
encounterDiagnosis.setDiagnosisTime(saveDiagnosisChildParam.getDiagnosisTime());
|
||||
encounterDiagnosis.setOnsetDate(saveDiagnosisChildParam.getOnsetDate());
|
||||
encounterDiagnosis.setDiagnosisTime(saveDiagnosisChildParam.getDiagnosisTime());
|
||||
if(encounterDiagnosis.getCreateBy() == null){
|
||||
encounterDiagnosis.setCreateBy(username);
|
||||
}
|
||||
@@ -607,15 +620,16 @@ public class DoctorStationDiagnosisAppServiceImpl implements IDoctorStationDiagn
|
||||
* 报告单位,报告医生,报告日期
|
||||
*/
|
||||
infectiousDiseaseReport.setReportOrg(null);
|
||||
infectiousDiseaseReport.setReportDate(LocalDate.now());
|
||||
infectiousDiseaseReport.setReportDate(new Date());
|
||||
|
||||
// 如果状态为空,设置为草稿状态
|
||||
if (infectiousDiseaseReport.getStatus() == null) {
|
||||
infectiousDiseaseReport.setStatus(0); // 0-草稿
|
||||
infectiousDiseaseReport.setStatus(SUBMITTED.getValue()); //已提交。草稿状态
|
||||
}
|
||||
log.debug("保存传染病报告卡数据getReportOrg:{}", infectiousDiseaseReport.getReportOrg());
|
||||
log.debug("保存传染病报告卡数据:{}", infectiousDiseaseReport.getDeleteFlag());
|
||||
log.debug("保存传染病报告卡数据,更新日期:{}",infectiousDiseaseReport.getUpdateTime());
|
||||
log.debug("保存传染病报告卡数据getStatus:{}",infectiousDiseaseReport.getStatus());
|
||||
// 保存到数据库
|
||||
boolean success = iInfectiousDiseaseReportService.save(infectiousDiseaseReport);
|
||||
|
||||
|
||||
@@ -16,10 +16,12 @@ import java.util.Date;
|
||||
import java.sql.Timestamp;
|
||||
import com.openhis.common.enums.BindingType;
|
||||
import com.openhis.common.enums.EncounterStatus;
|
||||
import com.openhis.document.domain.DocRecord;
|
||||
import com.openhis.document.domain.Emr;
|
||||
import com.openhis.document.domain.EmrDetail;
|
||||
import com.openhis.document.domain.EmrDict;
|
||||
import com.openhis.document.domain.EmrTemplate;
|
||||
import com.openhis.document.service.IDocRecordService;
|
||||
import com.openhis.document.service.IEmrDetailService;
|
||||
import com.openhis.document.service.IEmrDictService;
|
||||
import com.openhis.document.service.IEmrService;
|
||||
@@ -54,6 +56,9 @@ public class DoctorStationEmrAppServiceImpl implements IDoctorStationEmrAppServi
|
||||
@Resource
|
||||
IEmrDictService emrDictService;
|
||||
|
||||
@Resource
|
||||
IDocRecordService docRecordService;
|
||||
|
||||
@Resource
|
||||
private EncounterMapper encounterMapper;
|
||||
|
||||
@@ -128,16 +133,35 @@ public class DoctorStationEmrAppServiceImpl implements IDoctorStationEmrAppServi
|
||||
|
||||
/**
|
||||
* 获取病历详情
|
||||
* 同时检查门诊病历(emr表)和住院病历(doc_record表)
|
||||
*
|
||||
* @param encounterId 就诊id
|
||||
* @return 病历详情
|
||||
*/
|
||||
@Override
|
||||
public R<?> getEmrDetail(Long encounterId) {
|
||||
// 先查询门诊病历(emr表)
|
||||
Emr emrDetail = emrService.getOne(new LambdaQueryWrapper<Emr>().eq(Emr::getEncounterId, encounterId));
|
||||
if (emrDetail != null) {
|
||||
return R.ok(emrDetail);
|
||||
}
|
||||
|
||||
// 如果门诊病历为空,检查住院病历(doc_record表)
|
||||
DocRecord docRecord = docRecordService.getOne(
|
||||
new LambdaQueryWrapper<DocRecord>()
|
||||
.eq(DocRecord::getEncounterId, encounterId)
|
||||
.orderByDesc(DocRecord::getCreateTime)
|
||||
.last("LIMIT 1")
|
||||
);
|
||||
if (docRecord != null) {
|
||||
// 住院病历存在,也返回数据
|
||||
return R.ok(docRecord);
|
||||
}
|
||||
|
||||
// 都没有病历
|
||||
return R.ok(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存病历模板
|
||||
*
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.openhis.web.doctorstation.appservice.impl;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.core.common.core.redis.RedisCache;
|
||||
import com.core.common.enums.DelFlag;
|
||||
import com.core.common.utils.SecurityUtils;
|
||||
import com.openhis.common.enums.DbOpType;
|
||||
@@ -35,6 +36,8 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
@@ -76,6 +79,9 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
|
||||
@Autowired
|
||||
private IServiceRequestService serviceRequestService;
|
||||
|
||||
@Autowired
|
||||
private RedisCache redisCache;
|
||||
|
||||
/**
|
||||
* 保存检验申请单信息
|
||||
* @param doctorStationLabApplyDto
|
||||
@@ -88,8 +94,39 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
|
||||
* 保存检验申请单信息逻辑
|
||||
* 保存检验申请单信息同时根据检验申请单检验项目数据保存检验申请单明细信息
|
||||
*/
|
||||
log.debug("保存检验申请单信息:{}", doctorStationLabApplyDto);
|
||||
log.debug("保存申请单明细信息:{}",doctorStationLabApplyDto.getLabApplyItemList());
|
||||
|
||||
// 申请单号为空或"待生成"时,由后端生成新单号
|
||||
String applyNo = doctorStationLabApplyDto.getApplyNo();
|
||||
boolean isNewApplyNo = false;
|
||||
if (applyNo == null || applyNo.trim().isEmpty() || "待生成".equals(applyNo) || "自动生成".equals(applyNo)) {
|
||||
applyNo = generateApplyNo();
|
||||
isNewApplyNo = true;
|
||||
}
|
||||
// 将生成的单号设置回 DTO
|
||||
doctorStationLabApplyDto.setApplyNo(applyNo);
|
||||
|
||||
try {
|
||||
// 执行保存逻辑
|
||||
doSaveInspectionLabApply(doctorStationLabApplyDto, applyNo);
|
||||
} catch (Exception e) {
|
||||
// 记录废号日志(申请单号已生成但保存失败)
|
||||
if (isNewApplyNo) {
|
||||
log.error("申请单号 {} 因保存失败成为废号,原因:{}", applyNo, e.getMessage());
|
||||
}
|
||||
throw e; // 重新抛出异常,让事务回滚
|
||||
}
|
||||
|
||||
// 返回生成的申请单号
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("applyNo", applyNo);
|
||||
return R.ok(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行保存检验申请单的实际逻辑
|
||||
*/
|
||||
private void doSaveInspectionLabApply(DoctorStationLabApplyDto doctorStationLabApplyDto, String applyNo) {
|
||||
|
||||
//获取当前登陆用户 ID
|
||||
String userId = String.valueOf(SecurityUtils.getLoginUser().getUserId());
|
||||
InspectionLabApply inspectionLabApply = new InspectionLabApply();
|
||||
@@ -102,22 +139,34 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
|
||||
inspectionLabApply.setOperatorId(userId);
|
||||
inspectionLabApply.setCreateTime(new Date());
|
||||
inspectionLabApply.setDeleteFlag(DelFlag.NO.getCode());
|
||||
// 申请日期使用服务器当前系统时间
|
||||
inspectionLabApply.setApplyTime(new Date());
|
||||
|
||||
log.debug("保存检验申请单信息:{}", inspectionLabApply);
|
||||
inspectionLabApplyService.saveOrUpdate(inspectionLabApply);
|
||||
|
||||
// 金额校验和重算:后端重新计算金额,防止前端篡改
|
||||
java.math.BigDecimal totalAmount = java.math.BigDecimal.ZERO;
|
||||
int index = 0;
|
||||
|
||||
//遍历 doctorStationLabApplyDto.getLabApplyItemList()
|
||||
int index = 0;
|
||||
for (DoctorStationLabApplyItemDto doctorStationLabApplyItemDto : doctorStationLabApplyDto.getLabApplyItemList()) {
|
||||
//将 dto 数据复制到 InspectionLabApplyItem 对象中
|
||||
InspectionLabApplyItem inspectionLabApplyItem = new InspectionLabApplyItem();
|
||||
BeanUtils.copyProperties(doctorStationLabApplyItemDto, inspectionLabApplyItem);
|
||||
|
||||
// 后端重新计算金额:金额 = 单价 × 数量
|
||||
java.math.BigDecimal itemPrice = doctorStationLabApplyItemDto.getItemPrice();
|
||||
java.math.BigDecimal itemQty = doctorStationLabApplyItemDto.getItemQty();
|
||||
if (itemPrice != null && itemQty != null) {
|
||||
java.math.BigDecimal calculatedAmount = itemPrice.multiply(itemQty).setScale(2, java.math.RoundingMode.HALF_UP);
|
||||
inspectionLabApplyItem.setItemAmount(calculatedAmount);
|
||||
totalAmount = totalAmount.add(calculatedAmount);
|
||||
}
|
||||
|
||||
//设置从表申请单明细的申请单号
|
||||
inspectionLabApplyItem.setApplyNo(doctorStationLabApplyDto.getApplyNo());
|
||||
//检验科代码,取值于检验申请单
|
||||
inspectionLabApplyItem.setPerformDeptCode(doctorStationLabApplyDto.getApplyDeptCode());
|
||||
//执行科室代码,取值于检验申请单明细(前端传递的字典值)
|
||||
inspectionLabApplyItem.setPerformDeptCode(doctorStationLabApplyItemDto.getPerformDeptCode());
|
||||
//同主表状态,可单独回写
|
||||
inspectionLabApplyItem.setItemStatus(doctorStationLabApplyDto.getApplyStatus());
|
||||
// 设置项目序号 (打印顺序),按照遍历序号进行排序
|
||||
@@ -125,7 +174,6 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
|
||||
index++;
|
||||
|
||||
inspectionLabApplyItem.setDeleteFlag(DelFlag.NO.getCode());
|
||||
log.debug("保存申请单明细信息:{}", inspectionLabApplyItem);
|
||||
inspectionLabApplyItemService.saveOrUpdate(inspectionLabApplyItem);
|
||||
|
||||
//创建条码对象
|
||||
@@ -141,8 +189,6 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
|
||||
barCode.setCreateTime(new Date());
|
||||
barCode.setDeleteFlag(DelFlag.NO.getCode());
|
||||
|
||||
|
||||
log.debug("插入条码数据前,barCode:{}",barCode);
|
||||
inspectionLabBarCodeService.saveOrUpdate(barCode);
|
||||
}
|
||||
|
||||
@@ -189,11 +235,14 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
|
||||
);
|
||||
if (organization != null) {
|
||||
positionId = organization.getId();
|
||||
} else {
|
||||
log.warn("未找到执行科室代码对应的科室:{}", performDeptCode);
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有指定执行科室,使用当前医生所在的科室作为默认执行科室
|
||||
if (positionId == null) {
|
||||
positionId = SecurityUtils.getDeptId();
|
||||
}
|
||||
|
||||
// 4. 创建医嘱保存对象
|
||||
AdviceSaveDto adviceSaveDto = new AdviceSaveDto();
|
||||
// 设置医嘱操作类型
|
||||
@@ -270,23 +319,45 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
|
||||
adviceSaveParam.setAdviceSaveList(adviceSaveList);
|
||||
|
||||
// 调用门诊医嘱保存接口,创建关联的医嘱记录
|
||||
try {
|
||||
iDoctorStationAdviceAppService.saveAdvice(adviceSaveParam, "1"); // "1"表示保存操作
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("创建关联医嘱记录失败", e);
|
||||
}
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据申请单号查询检验申请单
|
||||
* 根据申请单号查询检验申请单(包含检验项目明细)
|
||||
*
|
||||
* @param applyNo
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Object getInspectionApplyByApplyNo(String applyNo) {
|
||||
return doctorStationLabApplyMapper.getInspectionApplyByApplyNo(applyNo);
|
||||
// 查询主表数据
|
||||
DoctorStationLabApplyDto applyDto = (DoctorStationLabApplyDto) doctorStationLabApplyMapper.getInspectionApplyByApplyNo(applyNo);
|
||||
if (applyDto == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 查询检验项目明细
|
||||
List<InspectionLabApplyItem> itemList = inspectionLabApplyItemService.list(
|
||||
new QueryWrapper<InspectionLabApplyItem>()
|
||||
.eq("apply_no", applyNo)
|
||||
.eq("delete_flag", "0")
|
||||
.orderByAsc("item_seq")
|
||||
);
|
||||
|
||||
// 转换为 DTO 列表
|
||||
List<DoctorStationLabApplyItemDto> itemDtoList = new ArrayList<>();
|
||||
if (itemList != null && !itemList.isEmpty()) {
|
||||
for (InspectionLabApplyItem item : itemList) {
|
||||
DoctorStationLabApplyItemDto itemDto = new DoctorStationLabApplyItemDto();
|
||||
BeanUtils.copyProperties(item, itemDto);
|
||||
itemDtoList.add(itemDto);
|
||||
}
|
||||
// 从第一个明细项获取执行科室代码
|
||||
applyDto.setExecuteDepartment(itemList.get(0).getPerformDeptCode());
|
||||
}
|
||||
applyDto.setLabApplyItemList(itemDtoList);
|
||||
|
||||
return applyDto;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -303,11 +374,11 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
|
||||
|
||||
// 查询检验申请单列表
|
||||
log.debug("查询申请单数据前");
|
||||
List<InspectionLabApply> list = doctorStationLabApplyMapper.getInspectionApplyListPage(encounterId);
|
||||
List<DoctorStationLabApplyDto> list = doctorStationLabApplyMapper.getInspectionApplyListPage(encounterId);
|
||||
log.debug("查询申请单数据后");
|
||||
|
||||
// 使用 PageInfo 包装查询结果
|
||||
PageInfo<InspectionLabApply> pageInfo = new PageInfo<>(list);
|
||||
PageInfo<DoctorStationLabApplyDto> pageInfo = new PageInfo<>(list);
|
||||
|
||||
// 构建返回结果
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
@@ -514,4 +585,36 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成检验申请单号
|
||||
* 规则:LS + YYYYMMDD + 5位流水号(每日从1开始递增)
|
||||
* 支持并发安全:使用 Redis 原子递增保证唯一性
|
||||
* @return 申请单号
|
||||
*/
|
||||
private String generateApplyNo() {
|
||||
// 获取当前日期
|
||||
LocalDate today = LocalDate.now();
|
||||
String dateStr = today.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
|
||||
|
||||
// 生成前缀:LS + 日期
|
||||
String prefix = "LS" + dateStr;
|
||||
|
||||
// Redis key 用于存储当天的流水号
|
||||
String redisKey = "lab_apply_no:" + dateStr;
|
||||
|
||||
// 使用 Redis 原子递增获取流水号(并发安全)
|
||||
long sequence = redisCache.incr(redisKey, 1);
|
||||
|
||||
// 设置 Redis key 过期时间(每天的 key 按日期独立,隔天不再使用,25小时确保跨午夜场景安全)
|
||||
redisCache.expire(redisKey, 25 * 60 * 60);
|
||||
|
||||
// 格式化流水号为5位,不足前补0
|
||||
String sequenceStr = String.format("%05d", sequence);
|
||||
|
||||
// 生成完整的申请单号
|
||||
String applyNo = prefix + sequenceStr;
|
||||
|
||||
return applyNo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.openhis.web.doctorstation.appservice.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
@@ -16,21 +17,23 @@ import com.openhis.common.constant.CommonConstants;
|
||||
import com.openhis.common.enums.*;
|
||||
import com.openhis.common.utils.EnumUtils;
|
||||
import com.openhis.common.utils.HisQueryUtils;
|
||||
import com.openhis.triageandqueuemanage.domain.TriageQueueItem;
|
||||
import com.openhis.triageandqueuemanage.service.TriageQueueItemService;
|
||||
import com.openhis.web.doctorstation.appservice.*;
|
||||
import com.openhis.web.doctorstation.dto.PatientInfoDto;
|
||||
import com.openhis.web.doctorstation.dto.PrescriptionInfoBaseDto;
|
||||
import com.openhis.web.doctorstation.dto.PrescriptionInfoDetailDto;
|
||||
import com.openhis.web.doctorstation.dto.ReceptionStatisticsDto;
|
||||
import com.openhis.web.doctorstation.mapper.DoctorStationMainAppMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -64,6 +67,9 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
|
||||
|
||||
@Resource
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
||||
@Resource
|
||||
private TriageQueueItemService triageQueueItemService;
|
||||
/**
|
||||
* 查询就诊患者信息
|
||||
*
|
||||
@@ -124,14 +130,40 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> receiveEncounter(Long encounterId) {
|
||||
Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
|
||||
String currentUsername = SecurityUtils.getUsername();
|
||||
|
||||
// 检查就诊记录是否存在
|
||||
Encounter encounter = encounterMapper.selectById(encounterId);
|
||||
if (encounter == null) {
|
||||
return R.fail("就诊记录不存在");
|
||||
}
|
||||
|
||||
// 检查患者状态,防止重复接诊
|
||||
Integer currentStatus = encounter.getStatusEnum();
|
||||
if (EncounterStatus.IN_PROGRESS.getValue().equals(currentStatus)) {
|
||||
return R.fail("已接诊,请勿重复点击,已为您刷新");
|
||||
}
|
||||
|
||||
int update = encounterMapper.update(null,
|
||||
new LambdaUpdateWrapper<Encounter>().eq(Encounter::getId, encounterId)
|
||||
.eq(Encounter::getStatusEnum, EncounterStatus.PLANNED.getValue()) // 只更新待诊状态的患者
|
||||
.set(Encounter::getReceptionTime, new Date())
|
||||
.set(Encounter::getStatusEnum, EncounterStatus.IN_PROGRESS.getValue())
|
||||
.set(Encounter::getSubjectStatusEnum, EncounterSubjectStatus.RECEIVING_CARE.getValue()));
|
||||
|
||||
// 如果更新失败,说明状态已被其他医生修改
|
||||
if (update <= 0) {
|
||||
// 重新查询当前状态
|
||||
encounter = encounterMapper.selectById(encounterId);
|
||||
if (EncounterStatus.IN_PROGRESS.getValue().equals(encounter.getStatusEnum())) {
|
||||
return R.fail("已接诊,请勿重复接诊");
|
||||
}
|
||||
return R.fail("接诊失败,请刷新后重试");
|
||||
}
|
||||
|
||||
// 先把之前的接诊记录更新为已完成
|
||||
iEncounterParticipantService.update(new LambdaUpdateWrapper<EncounterParticipant>()
|
||||
.eq(EncounterParticipant::getTypeCode, ParticipantType.ADMITTER.getCode())
|
||||
@@ -148,7 +180,28 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
|
||||
encounterParticipant.setCreateBy(currentUsername);
|
||||
encounterParticipant.setCreateTime(new Date());
|
||||
iEncounterParticipantService.save(encounterParticipant);
|
||||
return update > 0 ? R.ok() : R.fail();
|
||||
|
||||
// 更新 triage_queue_item 队列记录状态为 CALLING
|
||||
try {
|
||||
TriageQueueItem queueItem = triageQueueItemService.getOne(
|
||||
new LambdaQueryWrapper<TriageQueueItem>()
|
||||
.eq(TriageQueueItem::getTenantId, tenantId)
|
||||
.eq(TriageQueueItem::getEncounterId, encounterId)
|
||||
.eq(TriageQueueItem::getDeleteFlag, "0")
|
||||
);
|
||||
if (queueItem != null) {
|
||||
queueItem.setStatus("CALLING");
|
||||
queueItem.setUpdateTime(LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS));
|
||||
triageQueueItemService.updateById(queueItem);
|
||||
log.info("接诊时更新队列状态为CALLING,encounterId={}, queueItemId={}", encounterId, queueItem.getId());
|
||||
} else {
|
||||
log.warn("接诊时未找到队列记录,encounterId={}", encounterId);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("接诊时更新队列状态失败,encounterId={}", encounterId, e);
|
||||
}
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -181,11 +234,54 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
|
||||
return R.fail("就诊记录不存在");
|
||||
}
|
||||
|
||||
if (!EncounterStatus.IN_PROGRESS.getValue().equals(encounter.getStatusEnum())) {
|
||||
return R.fail("当前患者不在就诊中状态");
|
||||
// 检查患者状态,防止重复完诊
|
||||
Integer currentStatus = encounter.getStatusEnum();
|
||||
if (EncounterStatus.DISCHARGED.getValue().equals(currentStatus) ||
|
||||
EncounterStatus.COMPLETED.getValue().equals(currentStatus)) {
|
||||
// 患者已完成就诊,返回特定提示
|
||||
return R.fail("患者已完成就诊,已为您自动刷新患者列表");
|
||||
}
|
||||
|
||||
// 2. 更新状态、完成时间以及初复诊标识
|
||||
if (!EncounterStatus.IN_PROGRESS.getValue().equals(currentStatus)) {
|
||||
return R.fail("非就诊中患者不能完诊");
|
||||
}
|
||||
|
||||
// 2. 查找队列项
|
||||
Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
|
||||
TriageQueueItem queueItem = triageQueueItemService.getOne(
|
||||
new LambdaQueryWrapper<TriageQueueItem>()
|
||||
.eq(TriageQueueItem::getTenantId, tenantId)
|
||||
.eq(TriageQueueItem::getEncounterId, encounterId)
|
||||
.eq(TriageQueueItem::getDeleteFlag, "0")
|
||||
);
|
||||
|
||||
// 如果队列项存在,检查状态并更新
|
||||
if (queueItem != null && "CALLING".equals(queueItem.getStatus())) {
|
||||
// 更新队列状态为已完成
|
||||
java.time.LocalDateTime nowLocal = java.time.LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS);
|
||||
queueItem.setStatus("COMPLETED");
|
||||
queueItem.setUpdateTime(nowLocal);
|
||||
triageQueueItemService.updateById(queueItem);
|
||||
|
||||
// 写入 div_log 审计日志
|
||||
try {
|
||||
Long userId = SecurityUtils.getLoginUser().getUserId();
|
||||
String divLogSql = "INSERT INTO hisdev.div_log "
|
||||
+ "(pool_id, slot_id, queue_no, op_user_id, action, create_time) "
|
||||
+ "VALUES (?, ?, ?, ?, 'COMPLETE', NOW()::timestamp(0))";
|
||||
|
||||
jdbcTemplate.update(divLogSql,
|
||||
queueItem.getOrganizationId(), // pool_id: 候选池ID(科室)
|
||||
queueItem.getPractitionerId(), // slot_id: 槽位ID(医生)
|
||||
queueItem.getQueueOrder(), // queue_no: 队列号
|
||||
userId); // op_user_id: 操作用户ID
|
||||
} catch (Exception e) {
|
||||
log.error("写入div_log审计日志失败", e);
|
||||
// 审计日志失败不影响主流程
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 更新状态、完成时间以及初复诊标识
|
||||
Date now = new Date();
|
||||
int update = encounterMapper.update(null,
|
||||
new LambdaUpdateWrapper<Encounter>()
|
||||
@@ -198,7 +294,7 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
|
||||
|
||||
if (update <= 0) return R.fail("完诊失败");
|
||||
|
||||
// 3. 审计日志
|
||||
// 4. 审计日志(sys_oper_log)
|
||||
try {
|
||||
String username = SecurityUtils.getUsernameSafe();
|
||||
String sql = "INSERT INTO sys_oper_log "
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
*/
|
||||
package com.openhis.web.doctorstation.controller;
|
||||
|
||||
import com.core.common.annotation.RepeatSubmit;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.common.enums.AdviceOpType;
|
||||
import com.openhis.common.enums.Whether;
|
||||
@@ -15,6 +16,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 医生站-医嘱/处方 controller
|
||||
@@ -50,7 +52,7 @@ public class DoctorStationAdviceController {
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
|
||||
return R.ok(iDoctorStationAdviceAppService.getAdviceBaseInfo(adviceBaseDto, searchKey, locationId,
|
||||
adviceDefinitionIdParamList, organizationId, pageNo, pageSize, Whether.NO.getValue(), adviceTypes, null));
|
||||
adviceDefinitionIdParamList, organizationId, pageNo, pageSize, Whether.NO.getValue(), adviceTypes, null, null));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,6 +86,7 @@ public class DoctorStationAdviceController {
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping(value = "/sign-advice")
|
||||
@RepeatSubmit(interval = 5000, message = "请勿重复签发医嘱,请稍候再试")
|
||||
public R<?> signAdvice(@RequestBody AdviceSaveParam adviceSaveParam) {
|
||||
return iDoctorStationAdviceAppService.saveAdvice(adviceSaveParam, AdviceOpType.SIGN_ADVICE.getCode());
|
||||
}
|
||||
@@ -91,12 +94,16 @@ public class DoctorStationAdviceController {
|
||||
/**
|
||||
* 门诊签退医嘱
|
||||
*
|
||||
* @param requestIdList 请求id列表
|
||||
* @param requestIdList 请求id列表(字符串类型,避免前端大整数精度丢失)
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping(value = "/sign-off")
|
||||
public R<?> signOffAdvice(@RequestBody List<Long> requestIdList) {
|
||||
return iDoctorStationAdviceAppService.signOffAdvice(requestIdList);
|
||||
public R<?> signOffAdvice(@RequestBody List<String> requestIdList) {
|
||||
// 🔧 BugFix: 将字符串转换为Long
|
||||
List<Long> ids = requestIdList.stream()
|
||||
.map(Long::parseLong)
|
||||
.collect(Collectors.toList());
|
||||
return iDoctorStationAdviceAppService.signOffAdvice(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package com.openhis.web.doctorstation.controller;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.core.common.utils.SecurityUtils;
|
||||
import com.openhis.common.enums.AdviceOpType;
|
||||
import com.openhis.common.enums.Whether;
|
||||
import com.openhis.web.doctorstation.appservice.IDoctorStationAdviceAppService;
|
||||
@@ -109,9 +110,13 @@ public class DoctorStationChineseMedicalController {
|
||||
@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
|
||||
@RequestParam(value = "locationId", required = false) Long locationId,
|
||||
@RequestParam(value = "adviceDefinitionIdParamList", required = false) List<Long> adviceDefinitionIdParamList,
|
||||
@RequestParam(value = "organizationId") Long organizationId,
|
||||
@RequestParam(value = "organizationId", required = false) Long organizationId,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
|
||||
// 从当前登录用户获取科室 ID 作为默认值
|
||||
if (organizationId == null) {
|
||||
organizationId = SecurityUtils.getLoginUser().getOrgId();
|
||||
}
|
||||
return R.ok(iDoctorStationChineseMedicalAppService.getTcmAdviceBaseInfo(adviceBaseDto, searchKey, locationId,
|
||||
adviceDefinitionIdParamList, organizationId, pageNo, pageSize, Whether.NO.getValue()));
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 门诊医生站-检验控制器
|
||||
|
||||
@@ -8,6 +8,8 @@ import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import com.fasterxml.jackson.annotation.JsonSetter;
|
||||
import com.fasterxml.jackson.annotation.Nulls;
|
||||
|
||||
/**
|
||||
* 医嘱保存 dto
|
||||
@@ -48,10 +50,32 @@ public class AdviceSaveDto {
|
||||
|
||||
/**
|
||||
* 物理位置id | 可能是 发药药房id,耗材房id,执行科室id
|
||||
* 前端字段名:orgId(诊疗项目)
|
||||
* 对应数据库:org_id / perform_location
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long positionId;
|
||||
|
||||
/**
|
||||
* 执行科室ID | 诊疗项目使用
|
||||
* 前端传来字段名:orgId
|
||||
* 对应数据库:org_id
|
||||
* 🔧 Bug Fix #238: 添加此字段以支持前端orgId传参
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long orgId;
|
||||
|
||||
/**
|
||||
* 获取有效的执行科室ID(兼容处理)
|
||||
* 优先使用orgId,如果不存在则使用positionId
|
||||
* 🔧 Bug Fix #238: 统一获取执行科室ID的方法
|
||||
*
|
||||
* @return 有效的科室ID,如果都为null则返回null
|
||||
*/
|
||||
public Long getEffectiveOrgId() {
|
||||
return orgId != null ? orgId : positionId;
|
||||
}
|
||||
|
||||
/** 药品性质 | 分方使用 */
|
||||
private String pharmacologyCategoryCode;
|
||||
|
||||
@@ -80,6 +104,7 @@ public class AdviceSaveDto {
|
||||
private BigDecimal unitPrice;
|
||||
|
||||
/** 总价 */
|
||||
@JsonSetter(nulls = Nulls.AS_EMPTY)
|
||||
private BigDecimal totalPrice;
|
||||
|
||||
/** 费用定价主表ID */
|
||||
@@ -250,9 +275,22 @@ public class AdviceSaveDto {
|
||||
*/
|
||||
public AdviceSaveDto() {
|
||||
this.chineseHerbsDoseQuantity = new BigDecimal("1");
|
||||
this.therapyEnum = TherapyTimeType.TEMPORARY.getValue();
|
||||
// 默认设置为长期医嘱,但前端应该明确传递正确的值
|
||||
this.therapyEnum = TherapyTimeType.LONG_TERM.getValue();
|
||||
this.practitionerId = SecurityUtils.getLoginUser().getPractitionerId();
|
||||
this.founderOrgId = SecurityUtils.getLoginUser().getOrgId(); // 开方人科室
|
||||
}
|
||||
|
||||
/**
|
||||
* 🔧 Bug Fix: Custom setter for totalPrice to handle NaN and invalid values
|
||||
* Prevents JSON parse errors when frontend sends NaN or invalid BigDecimal values
|
||||
*/
|
||||
public void setTotalPrice(BigDecimal totalPrice) {
|
||||
if (totalPrice == null || totalPrice.compareTo(BigDecimal.ZERO) < 0) {
|
||||
this.totalPrice = BigDecimal.ZERO;
|
||||
} else {
|
||||
this.totalPrice = totalPrice;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,6 +17,10 @@ import java.util.List;
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class DoctorStationLabApplyDto {
|
||||
/**
|
||||
* 申请单ID(数据库自增主键)
|
||||
*/
|
||||
private Long applicationId;
|
||||
/**
|
||||
* 申请单编号
|
||||
*/
|
||||
@@ -135,6 +139,10 @@ public class DoctorStationLabApplyDto {
|
||||
* 就诊id
|
||||
*/
|
||||
private Long encounterId;
|
||||
/**
|
||||
* 执行科室代码(从明细项获取)
|
||||
*/
|
||||
private String executeDepartment;
|
||||
/**
|
||||
* 检验项目数据列表
|
||||
*/
|
||||
|
||||
@@ -79,6 +79,11 @@ public class RequestBaseDto {
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long chargeItemId;
|
||||
|
||||
/**
|
||||
* 医嘱定义对应表名
|
||||
*/
|
||||
private String adviceTableName;
|
||||
|
||||
/**
|
||||
* 医嘱名称
|
||||
*/
|
||||
@@ -156,6 +161,11 @@ public class RequestBaseDto {
|
||||
private String doseUnitCode;
|
||||
private String doseUnitCode_dictText;
|
||||
|
||||
/**
|
||||
* 单价
|
||||
*/
|
||||
private BigDecimal unitPrice;
|
||||
|
||||
/**
|
||||
* 总价
|
||||
*/
|
||||
@@ -210,4 +220,16 @@ public class RequestBaseDto {
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long basedOnId;
|
||||
|
||||
/**
|
||||
* 就诊id
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long encounterId;
|
||||
|
||||
/**
|
||||
* 患者id
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long patientId;
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.openhis.web.doctorstation.dto;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@@ -73,12 +74,16 @@ public class SaveDiagnosisChildParam {
|
||||
|
||||
/**
|
||||
* 诊断时间
|
||||
* 添加 pattern 以支持前端传来的 "yyyy/M/d HH:mm:ss" 格式
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy/M/d HH:mm:ss", timezone = "GMT+8")
|
||||
private Date diagnosisTime;
|
||||
|
||||
/**
|
||||
* 发病时间
|
||||
* 同样添加 pattern 以防前端传来相同格式的发病时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy/M/d HH:mm:ss", timezone = "GMT+8")
|
||||
private Date onsetDate;
|
||||
|
||||
/** 患者疾病诊断类型代码 */
|
||||
|
||||
@@ -37,6 +37,8 @@ public interface DoctorStationAdviceAppMapper {
|
||||
@Param("activityTableName") String activityTableName, @Param("pricingFlag") Integer pricingFlag,
|
||||
@Param("adviceDefinitionIdParamList") List<Long> adviceDefinitionIdParamList,
|
||||
@Param("adviceTypes") List<Integer> adviceTypes,
|
||||
@Param("searchKey") String searchKey,
|
||||
@Param("categoryCode") String categoryCode,
|
||||
@Param(Constants.WRAPPER) QueryWrapper<AdviceBaseDto> queryWrapper);
|
||||
|
||||
/**
|
||||
@@ -174,4 +176,12 @@ public interface DoctorStationAdviceAppMapper {
|
||||
List<ProofAndTestResultDto> getProofAndTestResult(@Param("encounterId") Long encounterId,
|
||||
@Param("status") Integer status, @Param("typeEnum") Integer typeEnum);
|
||||
|
||||
/**
|
||||
* 获取就诊的默认账户ID
|
||||
*
|
||||
* @param encounterId 就诊ID
|
||||
* @return 默认账户ID,如果没有则返回null
|
||||
*/
|
||||
Long getDefaultAccountId(@Param("encounterId") Long encounterId);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.openhis.web.doctorstation.mapper;
|
||||
|
||||
import com.openhis.lab.domain.InspectionLabApply;
|
||||
import com.openhis.web.doctorstation.dto.DoctorStationLabApplyDto;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@@ -11,6 +11,11 @@ import java.util.List;
|
||||
*/
|
||||
@Repository
|
||||
public interface DoctorStationLabApplyMapper {
|
||||
/**
|
||||
* 根据申请单号查询检验申请单
|
||||
* @param applyNo 申请单号
|
||||
* @return 检验申请单DTO
|
||||
*/
|
||||
Object getInspectionApplyByApplyNo(String applyNo);
|
||||
|
||||
/**
|
||||
@@ -18,5 +23,5 @@ public interface DoctorStationLabApplyMapper {
|
||||
* @param encounterId 就诊 ID
|
||||
* @return 检验申请单列表
|
||||
*/
|
||||
List<InspectionLabApply> getInspectionApplyListPage(@Param("encounterId") Long encounterId);
|
||||
List<DoctorStationLabApplyDto> getInspectionApplyListPage(@Param("encounterId") Long encounterId);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import com.openhis.administration.domain.ChargeItem;
|
||||
import com.openhis.administration.domain.Account;
|
||||
import com.openhis.administration.service.IAccountService;
|
||||
import com.openhis.administration.service.IChargeItemService;
|
||||
import com.openhis.common.constant.CommonConstants;
|
||||
import com.openhis.common.enums.*;
|
||||
@@ -71,6 +73,9 @@ public class AdviceUtils {
|
||||
@Resource
|
||||
IDoctorStationAdviceAppService iDoctorStationAdviceAppService;
|
||||
|
||||
@Resource
|
||||
IAccountService iAccountService;
|
||||
|
||||
/**
|
||||
* 校验库存
|
||||
*
|
||||
@@ -98,15 +103,27 @@ public class AdviceUtils {
|
||||
for (AdviceInventoryDto inventoryDto : adviceInventory) {
|
||||
// 匹配条件:adviceDefinitionId, adviceTableName, locationId, lotNumber 同时相等
|
||||
// 如果选择了具体的批次号,校验库存时需要加上批次号的匹配条件
|
||||
// 🔧 Bug #177 修复:添加容错处理,如果 adviceTableName 为空则跳过该项匹配
|
||||
boolean lotNumberMatch = StringUtils.isEmpty(saveDto.getLotNumber())
|
||||
|| saveDto.getLotNumber().equals(inventoryDto.getLotNumber());
|
||||
boolean tableNameMatch = StringUtils.isEmpty(saveDto.getAdviceTableName())
|
||||
|| inventoryDto.getItemTable().equals(saveDto.getAdviceTableName());
|
||||
// if (saveDto.)
|
||||
if (inventoryDto.getItemId().equals(saveDto.getAdviceDefinitionId())
|
||||
&& inventoryDto.getItemTable().equals(saveDto.getAdviceTableName())
|
||||
&& tableNameMatch
|
||||
&& inventoryDto.getLocationId().equals(saveDto.getLocationId()) && lotNumberMatch) {
|
||||
matched = true;
|
||||
// 检查库存是否充足
|
||||
BigDecimal minUnitQuantity = saveDto.getMinUnitQuantity();
|
||||
// 🔧 Bug Fix: 对于耗材类型,如果没有设置minUnitQuantity,则使用quantity作为默认值
|
||||
if (minUnitQuantity == null) {
|
||||
if (CommonConstants.TableName.ADM_DEVICE_DEFINITION.equals(inventoryDto.getItemTable())) {
|
||||
// 耗材只有一个单位,minUnitQuantity等于quantity
|
||||
minUnitQuantity = saveDto.getQuantity();
|
||||
} else {
|
||||
return saveDto.getAdviceName() + "的小单位数量不能为空";
|
||||
}
|
||||
}
|
||||
BigDecimal chineseHerbsDoseQuantity = saveDto.getChineseHerbsDoseQuantity(); // 中药付数
|
||||
// 中草药医嘱的情况
|
||||
if (chineseHerbsDoseQuantity != null && chineseHerbsDoseQuantity.compareTo(BigDecimal.ZERO) > 0) {
|
||||
@@ -302,6 +319,28 @@ public class AdviceUtils {
|
||||
*/
|
||||
public void handleActivityChild(String childrenJson, Long organizationId,
|
||||
ActivityChildrenJsonParams activityChildrenJsonParams) {
|
||||
// 🔧 Bug Fix: 确保accountId不为null
|
||||
if (activityChildrenJsonParams.getAccountId() == null) {
|
||||
// 尝试从患者就诊中获取默认账户ID(自费账户)
|
||||
Account selfAccount = iAccountService.getSelfAccount(activityChildrenJsonParams.getEncounterId());
|
||||
if (selfAccount != null) {
|
||||
activityChildrenJsonParams.setAccountId(selfAccount.getId());
|
||||
} else {
|
||||
// 自动创建自费账户
|
||||
Account newAccount = new Account();
|
||||
newAccount.setPatientId(activityChildrenJsonParams.getPatientId());
|
||||
newAccount.setEncounterId(activityChildrenJsonParams.getEncounterId());
|
||||
newAccount.setContractNo(CommonConstants.BusinessName.DEFAULT_CONTRACT_NO);
|
||||
newAccount.setTypeCode(AccountType.PERSONAL_CASH_ACCOUNT.getCode());
|
||||
newAccount.setBalanceAmount(BigDecimal.ZERO);
|
||||
newAccount.setStatusEnum(AccountStatus.ACTIVE.getValue());
|
||||
newAccount.setEncounterFlag(Whether.YES.getValue());
|
||||
newAccount.setName(AccountType.PERSONAL_CASH_ACCOUNT.getInfo());
|
||||
Long newAccountId = iAccountService.saveAccountByRegister(newAccount);
|
||||
activityChildrenJsonParams.setAccountId(newAccountId);
|
||||
}
|
||||
}
|
||||
|
||||
// 治疗类型 (长期/临时)
|
||||
Integer therapyEnum = activityChildrenJsonParams.getTherapyEnum();
|
||||
// 当前登录账号的科室id
|
||||
@@ -334,7 +373,7 @@ public class AdviceUtils {
|
||||
// 对应的子项诊疗医嘱信息
|
||||
AdviceBaseDto activityAdviceBaseDto
|
||||
= iDoctorStationAdviceAppService.getAdviceBaseInfo(adviceBaseDto, null, null, null, organizationId, 1,
|
||||
1, Whether.NO.getValue(), List.of(1, 2, 3), null).getRecords().get(0);
|
||||
1, Whether.NO.getValue(), List.of(1, 2, 3), null, null).getRecords().get(0);
|
||||
if (activityAdviceBaseDto != null) {
|
||||
// 费用定价
|
||||
AdvicePriceDto advicePriceDto = activityAdviceBaseDto.getPriceList().get(0);
|
||||
|
||||
@@ -32,9 +32,11 @@ public class PrescriptionUtils {
|
||||
if (medicineList == null || medicineList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// 1. 按诊断ID分组(不同诊断必须分开)
|
||||
// 1. 按诊断ID分组(不同诊断必须分开,null值归为一组)
|
||||
Map<Long, List<AdviceSaveDto>> diagnosisGroups =
|
||||
medicineList.stream().collect(Collectors.groupingBy(AdviceSaveDto::getConditionDefinitionId));
|
||||
medicineList.stream().collect(Collectors.groupingBy(dto ->
|
||||
dto.getConditionDefinitionId() != null ? dto.getConditionDefinitionId() : 0L
|
||||
));
|
||||
// 2. 处理每个诊断组
|
||||
diagnosisGroups.values().forEach(this::processDiagnosisGroup);
|
||||
}
|
||||
@@ -46,9 +48,11 @@ public class PrescriptionUtils {
|
||||
if (diagnosisGroup.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// 1. 按药品性质分组
|
||||
// 1. 按药品性质分组(null值归为普通药品)
|
||||
Map<String, List<AdviceSaveDto>> pharmacologyGroups =
|
||||
diagnosisGroup.stream().collect(Collectors.groupingBy(AdviceSaveDto::getPharmacologyCategoryCode));
|
||||
diagnosisGroup.stream().collect(Collectors.groupingBy(dto ->
|
||||
dto.getPharmacologyCategoryCode() != null ? dto.getPharmacologyCategoryCode() : "0"
|
||||
));
|
||||
// 2. 处理每个药品性质组
|
||||
pharmacologyGroups.values().forEach(pharmaGroup -> {
|
||||
// 2.1 先处理有分组ID的药品(确保它们不会被拆分)
|
||||
|
||||
@@ -245,15 +245,37 @@ public class DocDefinitionAppServiceImpl implements IDocDefinitionAppService {
|
||||
public R<?> getTreeList(DocDefinitonParam param) {
|
||||
// 1. 获取当前登录用户的医院ID(避免跨医院查询)
|
||||
Long hospitalId = SecurityUtils.getLoginUser().getHospitalId();
|
||||
Long organizationId = param.getOrganizationId();
|
||||
List<Integer> useRanges = param.getUseRanges();
|
||||
|
||||
log.info("获取文书定义树形列表 - 请求参数: hospitalId={}, organizationId={}, useRanges={}, name={}, primaryMenuEnum={}",
|
||||
hospitalId, organizationId, useRanges, param.getName(), param.getPrimaryMenuEnum());
|
||||
|
||||
if (hospitalId == null) {
|
||||
log.warn("当前登录用户未关联医院ID,将使用默认值");
|
||||
// 设置默认医院ID为1(或其他合适的默认值)
|
||||
hospitalId = 1L;
|
||||
}
|
||||
|
||||
if (organizationId == null || organizationId == 0) {
|
||||
log.warn("organizationId为空或0,将跳过医院过滤和使用范围过滤");
|
||||
}
|
||||
|
||||
if (useRanges == null || useRanges.isEmpty()) {
|
||||
log.warn("useRanges为空,可能返回所有使用范围的文书");
|
||||
}
|
||||
|
||||
// 2. 数据库查询文书定义列表
|
||||
List<DocDefinitionDto> docList = docDefinitionAppMapper.getDefinationList(param.getUseRanges(),
|
||||
param.getOrganizationId(), hospitalId, param.getName(), param.getPrimaryMenuEnum());
|
||||
List<DocDefinitionDto> docList = docDefinitionAppMapper.getDefinationList(useRanges,
|
||||
organizationId, hospitalId, param.getName(), param.getPrimaryMenuEnum());
|
||||
|
||||
log.info("获取文书定义树形列表 - 查询结果: 记录数={}", docList != null ? docList.size() : 0);
|
||||
if (docList != null && !docList.isEmpty()) {
|
||||
for (DocDefinitionDto doc : docList) {
|
||||
log.debug("文书: id={}, name={}, useRangeEnum={}, hospitalId={}",
|
||||
doc.getId(), doc.getName(), doc.getUseRangeEnum(), doc.getHospitalId());
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 构建树形结构(空列表时返回空树,避免空指针)
|
||||
List<DirectoryNode> treeNodes = new ArrayList<>();
|
||||
|
||||
@@ -59,7 +59,7 @@ public class DocTemplateAppServiceImpl implements IDocTemplateAppService {
|
||||
docTemplateDto.setUserId(SecurityUtils.getLoginUser().getUserId());
|
||||
}
|
||||
docTemplate.setOrganizationId(docTemplateDto.getOrganizationId());
|
||||
docTemplate.setId(docTemplateDto.getUserId());
|
||||
docTemplate.setUserId(docTemplateDto.getUserId());
|
||||
docTemplate.setUseRange(docTemplateDto.getUseRange());
|
||||
docTemplate.setRemark(docTemplateDto.getRemark());
|
||||
docTemplateService.save(docTemplate);
|
||||
@@ -140,7 +140,7 @@ public class DocTemplateAppServiceImpl implements IDocTemplateAppService {
|
||||
docTemplate.setOrganizationId(docTemplateDto.getOrganizationId());
|
||||
docTemplate.setUserId(docTemplateDto.getUserId());
|
||||
docTemplate.setRemark(docTemplateDto.getRemark());
|
||||
docTemplateService.save(docTemplate);
|
||||
docTemplateService.updateById(docTemplate);
|
||||
return R.ok("更新成功");
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +106,9 @@ public class DocDefinitionController {
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/treeList")
|
||||
public R<?> getTreeList(DocDefinitonParam docDefinitonParam) {
|
||||
public R<?> getTreeList(DocDefinitonParam docDefinitonParam,
|
||||
@RequestParam(value = "useRanges", required = false) List<Integer> useRanges) {
|
||||
docDefinitonParam.setUseRanges(useRanges);
|
||||
return iDocDefinitionAppService.getTreeList(docDefinitonParam);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,10 +14,13 @@ import com.core.common.utils.SecurityUtils;
|
||||
import com.core.common.utils.StringUtils;
|
||||
import com.openhis.administration.domain.Encounter;
|
||||
import com.openhis.administration.domain.EncounterLocation;
|
||||
import com.openhis.administration.domain.EncounterParticipant;
|
||||
import com.openhis.administration.domain.Practitioner;
|
||||
import com.openhis.administration.service.IEncounterLocationService;
|
||||
import com.openhis.administration.service.IEncounterParticipantService;
|
||||
import com.openhis.administration.service.IEncounterService;
|
||||
import com.openhis.administration.service.ILocationService;
|
||||
import com.openhis.administration.service.IPractitionerService;
|
||||
import com.openhis.common.constant.CommonConstants;
|
||||
import com.openhis.common.enums.*;
|
||||
import com.openhis.common.utils.EnumUtils;
|
||||
@@ -40,8 +43,10 @@ import com.openhis.web.inhospitalnursestation.mapper.ATDManageAppMapper;
|
||||
import com.openhis.workflow.domain.ServiceRequest;
|
||||
import com.openhis.workflow.service.IServiceRequestService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -53,6 +58,7 @@ import java.util.stream.Stream;
|
||||
* @author zwh
|
||||
* @date 2025-07-28
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ATDManageAppServiceImpl implements IATDManageAppService {
|
||||
|
||||
@@ -92,6 +98,9 @@ public class ATDManageAppServiceImpl implements IATDManageAppService {
|
||||
@Resource
|
||||
private IServiceRequestService serviceRequestService;
|
||||
|
||||
@Resource
|
||||
private IPractitionerService practitionerService;
|
||||
|
||||
/**
|
||||
* 入出转管理页面初始化
|
||||
*
|
||||
@@ -212,12 +221,131 @@ public class ATDManageAppServiceImpl implements IATDManageAppService {
|
||||
*/
|
||||
@Override
|
||||
public R<?> getAdmissionPatientInfo(Long encounterId) {
|
||||
// 查询住院患者详细信息
|
||||
log.info("========== 查询患者信息 - encounterId: {} ==========", encounterId);
|
||||
Integer active = EncounterActivityStatus.ACTIVE.getValue();
|
||||
String primaryNurse = ParticipantType.PRIMARY_NURSE.getCode();
|
||||
String attendingDoctor = ParticipantType.ATTENDING_DOCTOR.getCode();
|
||||
String admittingDoctor = ParticipantType.ADMITTING_DOCTOR.getCode();
|
||||
String chiefDoctor = ParticipantType.CHIEF_DOCTOR.getCode();
|
||||
log.info("查询参数 - encounterId: {}, active: {} (type: {}), primaryNurse: {} (type: {}), attendingDoctor: {} (type: {}), admittingDoctor: {} (type: {}), chiefDoctor: {} (type: {})",
|
||||
encounterId, active, active.getClass().getSimpleName(),
|
||||
primaryNurse, primaryNurse.getClass().getSimpleName(),
|
||||
attendingDoctor, attendingDoctor.getClass().getSimpleName(),
|
||||
admittingDoctor, admittingDoctor.getClass().getSimpleName(),
|
||||
chiefDoctor, chiefDoctor.getClass().getSimpleName());
|
||||
|
||||
// 先通过简单的 SQL 查询患者基本信息
|
||||
AdmissionPatientInfoDto admissionPatientInfoDto
|
||||
= atdManageAppMapper.selectAdmissionPatientInfo(encounterId, EncounterActivityStatus.ACTIVE.getValue(),
|
||||
= atdManageAppMapper.selectAdmissionPatientInfo(encounterId, active,
|
||||
LocationForm.WARD.getValue(), LocationForm.HOUSE.getValue(), LocationForm.BED.getValue(),
|
||||
ParticipantType.PRIMARY_NURSE.getCode(), ParticipantType.ATTENDING_DOCTOR.getCode(),
|
||||
ParticipantType.ADMITTING_DOCTOR.getCode(), ParticipantType.CHIEF_DOCTOR.getCode());
|
||||
primaryNurse, attendingDoctor, admittingDoctor, chiefDoctor);
|
||||
|
||||
// 从 EncounterParticipant 表手动获取医生护士信息
|
||||
List<EncounterParticipant> participantList = encounterParticipantService.getEncounterParticipantList(encounterId);
|
||||
log.info("从 EncounterParticipant 获取到 {} 条记录", participantList.size());
|
||||
|
||||
// 调试:打印所有 participant 的详细信息
|
||||
for (EncounterParticipant ep : participantList) {
|
||||
log.info("调试 - typeCode: '{}', practitionerId: {}, statusEnum: {}, deleteFlag: '{}'",
|
||||
ep.getTypeCode(), ep.getPractitionerId(), ep.getStatusEnum(), ep.getDeleteFlag());
|
||||
}
|
||||
|
||||
// 查找各个角色 - 使用 Integer 类型进行比较
|
||||
Integer primaryNurseValue = ParticipantType.PRIMARY_NURSE.getValue();
|
||||
Integer attendingDoctorValue = ParticipantType.ATTENDING_DOCTOR.getValue();
|
||||
Integer admittingDoctorValue = ParticipantType.ADMITTING_DOCTOR.getValue();
|
||||
Integer chiefDoctorValue = ParticipantType.CHIEF_DOCTOR.getValue();
|
||||
|
||||
log.info("枚举值 - primaryNurse: {} ({})", primaryNurseValue, primaryNurse);
|
||||
log.info("枚举值 - attendingDoctor: {} ({})", attendingDoctorValue, attendingDoctor);
|
||||
log.info("枚举值 - admittingDoctor: {} ({})", admittingDoctorValue, admittingDoctor);
|
||||
log.info("枚举值 - chiefDoctor: {} ({})", chiefDoctorValue, chiefDoctor);
|
||||
|
||||
// 查找各个角色
|
||||
Long primaryNurseId = null;
|
||||
String primaryNurseName = null;
|
||||
Long attendingDoctorId = null;
|
||||
String attendingDoctorName = null;
|
||||
Long admittingDoctorId = null;
|
||||
String admittingDoctorName = null;
|
||||
Long chiefDoctorId = null;
|
||||
String chiefDoctorName = null;
|
||||
|
||||
for (EncounterParticipant ep : participantList) {
|
||||
if (ep.getStatusEnum() == null || !ep.getStatusEnum().equals(active)) {
|
||||
log.info("跳过 - statusEnum: {} vs active: {}", ep.getStatusEnum(), active);
|
||||
continue;
|
||||
}
|
||||
if (ep.getTypeCode() == null) {
|
||||
log.info("跳过 - typeCode 为空");
|
||||
continue;
|
||||
}
|
||||
|
||||
// 尝试将 typeCode 转换为 Integer 进行比较
|
||||
Integer typeCodeValue = null;
|
||||
try {
|
||||
typeCodeValue = Integer.parseInt(ep.getTypeCode().trim());
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("typeCode 无法转换为 Integer: {}", ep.getTypeCode());
|
||||
}
|
||||
|
||||
log.info("检查 typeCode: {} (Integer: {}) vs primaryNurseValue: {}, attendingDoctorValue: {}, admittingDoctorValue: {}, chiefDoctorValue: {}",
|
||||
ep.getTypeCode(), typeCodeValue, primaryNurseValue, attendingDoctorValue, admittingDoctorValue, chiefDoctorValue);
|
||||
|
||||
// 根据 typeCode 的 Integer 值匹配并获取 practitioner 名称
|
||||
if (typeCodeValue != null && typeCodeValue.equals(primaryNurseValue)) {
|
||||
primaryNurseId = ep.getPractitionerId();
|
||||
// 查询 practitioner 名称
|
||||
if (primaryNurseId != null) {
|
||||
Practitioner practitioner = practitionerService.getById(primaryNurseId);
|
||||
if (practitioner != null) {
|
||||
primaryNurseName = practitioner.getName();
|
||||
}
|
||||
}
|
||||
log.info("找到责任护士 - id: {}, name: {}", primaryNurseId, primaryNurseName);
|
||||
} else if (typeCodeValue != null && typeCodeValue.equals(attendingDoctorValue)) {
|
||||
attendingDoctorId = ep.getPractitionerId();
|
||||
if (attendingDoctorId != null) {
|
||||
Practitioner practitioner = practitionerService.getById(attendingDoctorId);
|
||||
if (practitioner != null) {
|
||||
attendingDoctorName = practitioner.getName();
|
||||
}
|
||||
}
|
||||
log.info("找到主治医生 - id: {}, name: {}", attendingDoctorId, attendingDoctorName);
|
||||
} else if (typeCodeValue != null && typeCodeValue.equals(admittingDoctorValue)) {
|
||||
admittingDoctorId = ep.getPractitionerId();
|
||||
if (admittingDoctorId != null) {
|
||||
Practitioner practitioner = practitionerService.getById(admittingDoctorId);
|
||||
if (practitioner != null) {
|
||||
admittingDoctorName = practitioner.getName();
|
||||
}
|
||||
}
|
||||
log.info("找到入院医生 - id: {}, name: {}", admittingDoctorId, admittingDoctorName);
|
||||
} else if (typeCodeValue != null && typeCodeValue.equals(chiefDoctorValue)) {
|
||||
chiefDoctorId = ep.getPractitionerId();
|
||||
if (chiefDoctorId != null) {
|
||||
Practitioner practitioner = practitionerService.getById(chiefDoctorId);
|
||||
if (practitioner != null) {
|
||||
chiefDoctorName = practitioner.getName();
|
||||
}
|
||||
}
|
||||
log.info("找到主任医生 - id: {}, name: {}", chiefDoctorId, chiefDoctorName);
|
||||
} else {
|
||||
log.info("未匹配到任何角色 typeCode: {} (value: {})", ep.getTypeCode(), typeCodeValue);
|
||||
}
|
||||
}
|
||||
|
||||
// 手动设置医生护士信息到 DTO
|
||||
if (admissionPatientInfoDto != null) {
|
||||
admissionPatientInfoDto.setPrimaryNurseId(primaryNurseId);
|
||||
admissionPatientInfoDto.setPrimaryNurseName(primaryNurseName);
|
||||
admissionPatientInfoDto.setAttendingDoctorId(attendingDoctorId);
|
||||
admissionPatientInfoDto.setAttendingDoctorName(attendingDoctorName);
|
||||
admissionPatientInfoDto.setAdmittingDoctorId(admittingDoctorId);
|
||||
admissionPatientInfoDto.setAdmittingDoctorName(admittingDoctorName);
|
||||
admissionPatientInfoDto.setChiefDoctorId(chiefDoctorId);
|
||||
admissionPatientInfoDto.setChiefDoctorName(chiefDoctorName);
|
||||
|
||||
// 年龄
|
||||
if (admissionPatientInfoDto.getBirthDate() != null) {
|
||||
admissionPatientInfoDto.setAge(AgeCalculatorUtil.getAge(admissionPatientInfoDto.getBirthDate()));
|
||||
@@ -230,6 +358,13 @@ public class ATDManageAppServiceImpl implements IATDManageAppService {
|
||||
EnumUtils.getInfoByValue(PriorityLevel.class, admissionPatientInfoDto.getPriorityEnum()));
|
||||
// 获取入院体征
|
||||
getAdmissionSigns(encounterId, admissionPatientInfoDto);
|
||||
}
|
||||
|
||||
log.info("查询结果 - admittingDoctorId: {}, attendingDoctorId: {}, chiefDoctorId: {}, primaryNurseId: {}",
|
||||
admissionPatientInfoDto != null ? admissionPatientInfoDto.getAdmittingDoctorId() : "null",
|
||||
admissionPatientInfoDto != null ? admissionPatientInfoDto.getAttendingDoctorId() : "null",
|
||||
admissionPatientInfoDto != null ? admissionPatientInfoDto.getChiefDoctorId() : "null",
|
||||
admissionPatientInfoDto != null ? admissionPatientInfoDto.getPrimaryNurseId() : "null");
|
||||
return R.ok(admissionPatientInfoDto);
|
||||
}
|
||||
|
||||
@@ -283,7 +418,9 @@ public class ATDManageAppServiceImpl implements IATDManageAppService {
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> admissionBedAssignment(AdmissionPatientInfoDto admissionPatientInfoDto) {
|
||||
log.info("===== admissionBedAssignment 开始 =====");
|
||||
|
||||
// 住院id
|
||||
Long encounterId = admissionPatientInfoDto.getEncounterId();
|
||||
@@ -297,35 +434,58 @@ public class ATDManageAppServiceImpl implements IATDManageAppService {
|
||||
Long targetBedId = admissionPatientInfoDto.getTargetBedId();
|
||||
|
||||
// 进入编辑患者信息,不更换床位
|
||||
if (Whether.YES.getCode().equals(admissionPatientInfoDto.getEditFlag())) {
|
||||
if ("1".equals(admissionPatientInfoDto.getEditFlag())) {
|
||||
log.info("编辑模式 - encounterId: {}, admittingDoctorId: {}, attendingDoctorId: {}, chiefDoctorId: {}, primaryNurseId: {}",
|
||||
encounterId, admissionPatientInfoDto.getAdmittingDoctorId(), admissionPatientInfoDto.getAttendingDoctorId(),
|
||||
admissionPatientInfoDto.getChiefDoctorId(), admissionPatientInfoDto.getPrimaryNurseId());
|
||||
// 更新患者病情(如果提供了)
|
||||
if (admissionPatientInfoDto.getPriorityEnum() != null) {
|
||||
// 更新患者病情
|
||||
encounterService.updatePriorityEnumById(encounterId, admissionPatientInfoDto.getPriorityEnum());
|
||||
}
|
||||
// 将之前的住院参与者更新为已完成(如果存在的话)
|
||||
encounterParticipantService.updateEncounterParticipantsStatus(encounterId);
|
||||
// 更新住院参与者
|
||||
// 住院医生
|
||||
// 住院医生(必须填写)
|
||||
if (admissionPatientInfoDto.getAdmittingDoctorId() != null) {
|
||||
encounterParticipantService.creatEncounterParticipants(encounterId, startTime,
|
||||
admissionPatientInfoDto.getAdmittingDoctorId(), ParticipantType.ADMITTING_DOCTOR.getCode());
|
||||
// 责任护士
|
||||
}
|
||||
// 责任护士(必须填写)
|
||||
if (admissionPatientInfoDto.getPrimaryNurseId() != null) {
|
||||
encounterParticipantService.creatEncounterParticipants(encounterId, startTime,
|
||||
admissionPatientInfoDto.getPrimaryNurseId(), ParticipantType.PRIMARY_NURSE.getCode());
|
||||
}
|
||||
// 主治医生(可选)
|
||||
if (admissionPatientInfoDto.getAttendingDoctorId() != null) {
|
||||
// 主治医生
|
||||
encounterParticipantService.creatEncounterParticipants(encounterId, startTime,
|
||||
admissionPatientInfoDto.getAttendingDoctorId(), ParticipantType.ATTENDING_DOCTOR.getCode());
|
||||
}
|
||||
// 主任医生(可选)
|
||||
if (admissionPatientInfoDto.getChiefDoctorId() != null) {
|
||||
// 主任医生
|
||||
encounterParticipantService.creatEncounterParticipants(encounterId, startTime,
|
||||
admissionPatientInfoDto.getChiefDoctorId(), ParticipantType.CHIEF_DOCTOR.getCode());
|
||||
}
|
||||
// 保存后立即查询确认数据
|
||||
List<EncounterParticipant> savedParticipants = encounterParticipantService.getEncounterParticipantList(encounterId);
|
||||
log.info("保存后查询参与者 - encounterId: {}, 数量: {}", encounterId, savedParticipants.size());
|
||||
for (EncounterParticipant ep : savedParticipants) {
|
||||
log.info("参与者详情 - typeCode: {}, practitionerId: {}, statusEnum: {}",
|
||||
ep.getTypeCode(), ep.getPractitionerId(), ep.getStatusEnum());
|
||||
}
|
||||
// 更新入院体征
|
||||
// 更新入院体征(在事务外执行,避免影响参与者数据保存)
|
||||
try {
|
||||
saveOrUpdateAdmissionSigns(encounterId, admissionPatientInfoDto, startTime);
|
||||
} catch (Exception e) {
|
||||
log.error("保存入院体征失败,但不影响参与者数据", e);
|
||||
}
|
||||
return R.ok("患者信息更新成功");
|
||||
}
|
||||
|
||||
// 新分配床位时,校验床位信息
|
||||
if (targetBedId == null || admissionPatientInfoDto.getTargetHouseId() == null) {
|
||||
return R.fail("床位分配失败,请选择有效的床位");
|
||||
}
|
||||
|
||||
// 判断患者是否已经在床
|
||||
if (oldBedId != null) {
|
||||
// 判断目标床位是否已经被占用
|
||||
@@ -421,8 +581,12 @@ public class ATDManageAppServiceImpl implements IATDManageAppService {
|
||||
if (result == 0) {
|
||||
return R.fail("床位分配失败,请联系管理员");
|
||||
}
|
||||
// 保存入院体征
|
||||
// 保存入院体征(在事务外执行,避免影响参与者数据保存)
|
||||
try {
|
||||
saveOrUpdateAdmissionSigns(encounterId, admissionPatientInfoDto, startTime);
|
||||
} catch (Exception e) {
|
||||
log.error("保存入院体征失败,但不影响参与者数据", e);
|
||||
}
|
||||
return R.ok("床位分配成功");
|
||||
}
|
||||
|
||||
@@ -616,20 +780,33 @@ public class ATDManageAppServiceImpl implements IATDManageAppService {
|
||||
map.put(e.getStatisticDefinitionCode(), e.getValue());
|
||||
}
|
||||
});
|
||||
// 入院体征赋值
|
||||
// 入院体征赋值 - 带fallback处理,兼容heartRate/hertRate等历史数据
|
||||
dto.setHeight(map.get(TemperatureChartEnum.HEIGHT.getTypeCode()));
|
||||
dto.setWeight(map.get(TemperatureChartEnum.WEIGHT.getTypeCode()));
|
||||
dto.setTemperature(map.get(TemperatureChartEnum.TEMPERATURE.getTypeCode()));
|
||||
dto.setPulse(map.get(TemperatureChartEnum.PULSE.getTypeCode()));
|
||||
dto.setHertRate(map.get(TemperatureChartEnum.HEART_RATE.getTypeCode()));
|
||||
// 心率字段兼容性处理:尝试heartRate,如果不存在尝试hertRate
|
||||
String heartRateValue = map.get(TemperatureChartEnum.HEART_RATE.getTypeCode());
|
||||
if (heartRateValue == null) {
|
||||
heartRateValue = map.get("hertRate"); // 兼容历史数据中的拼写错误
|
||||
}
|
||||
dto.setHertRate(heartRateValue);
|
||||
String bloodPressure = map.get(TemperatureChartEnum.BLOOD_PRESSURE.getTypeCode());
|
||||
if (!StringUtils.isEmpty(bloodPressure)) {
|
||||
if (!StringUtils.isEmpty(bloodPressure) && bloodPressure.contains("/")) {
|
||||
String[] split = bloodPressure.split("/");
|
||||
// 安全检查:确保分割后有2个元素
|
||||
if (split.length >= 2) {
|
||||
String endBloodPressure = split[0].strip();
|
||||
String highBloodPressure = split[1].strip();
|
||||
// 进一步检查值不为空
|
||||
if (!endBloodPressure.isEmpty()) {
|
||||
dto.setEndBloodPressure(endBloodPressure);
|
||||
}
|
||||
if (!highBloodPressure.isEmpty()) {
|
||||
dto.setHighBloodPressure(highBloodPressure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -669,12 +846,36 @@ public class ATDManageAppServiceImpl implements IATDManageAppService {
|
||||
= ((List<DocStatisticsDto>) docStatisticsAppService.queryByEncounterId(encounterId).getData()).stream()
|
||||
.filter(item -> DocDefinitionEnum.ADMISSION_VITAL_SIGNS.getValue().equals(item.getSource())).toList();
|
||||
List<DocStatisticsDto> list = new ArrayList<>(data);
|
||||
|
||||
// 先删除所有已有的入院体征记录(重新保存最新数据)
|
||||
for (DocStatisticsDto existingItem : data) {
|
||||
if (existingItem.getId() != null) {
|
||||
docStatisticsMapper.deleteById(existingItem.getId());
|
||||
}
|
||||
}
|
||||
list.clear();
|
||||
|
||||
map.keySet().forEach(key -> {
|
||||
if (map.get(key) != null && !map.get(key).isEmpty()) {
|
||||
String value = map.get(key);
|
||||
// 只保存非空值
|
||||
if (value != null && !value.isEmpty() && !" ".equals(value)) {
|
||||
DocStatisticsDefinitionDto docStatisticsDefinitionDto = definitionDtoHashMap.get(key);
|
||||
// 如果找不到定义,尝试使用code作为fallback(兼容历史数据)
|
||||
if (docStatisticsDefinitionDto == null) {
|
||||
log.warn("DocStatisticsDefinition not found for key: {}, trying fallback lookup", key);
|
||||
// 尝试查找任意匹配的定义(兼容heartRate/hertRate等差异)
|
||||
docStatisticsDefinitionDto = definitionList.stream()
|
||||
.filter(d -> key.equalsIgnoreCase(d.getCode()) || key.equalsIgnoreCase(d.getTypeCode()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
if (docStatisticsDefinitionDto == null) {
|
||||
log.error("无法找到DocStatisticsDefinition,跳过保存 - key: {}, value: {}", key, value);
|
||||
return; // 跳过这个字段
|
||||
}
|
||||
DocStatisticsDto statistics = new DocStatisticsDto();
|
||||
statistics.setStatisticDefinitionCode(key);
|
||||
statistics.setValue(map.get(key));
|
||||
statistics.setValue(value);
|
||||
statistics.setEncounterId(encounterId);
|
||||
statistics.setPatientId(encounter.getPatientId());
|
||||
statistics.setStatisticDefinitionId(docStatisticsDefinitionDto.getId());
|
||||
|
||||
@@ -702,7 +702,7 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
= medUseExeList.stream().map(MedicationRequestUseExe::getMedicationId).collect(Collectors.toList());
|
||||
// 医嘱详细信息
|
||||
List<AdviceBaseDto> medicationInfos = doctorStationAdviceAppService.getAdviceBaseInfo(null, null, null,
|
||||
medicationDefinitionIdList, 0L, 1, 500, Whether.NO.getValue(), List.of(1), null).getRecords();
|
||||
medicationDefinitionIdList, 0L, 1, 500, Whether.NO.getValue(), List.of(1), null, null).getRecords();
|
||||
|
||||
// 当前时间
|
||||
Date curDate = new Date();
|
||||
@@ -979,7 +979,7 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
= actUseExeList.stream().map(ServiceRequestUseExe::getActivityId).collect(Collectors.toList());
|
||||
// 医嘱详细信息
|
||||
List<AdviceBaseDto> activityInfos = doctorStationAdviceAppService.getAdviceBaseInfo(null, null, null,
|
||||
activityDefinitionIdList, 0L, 1, 500, Whether.NO.getValue(), List.of(3), null).getRecords();
|
||||
activityDefinitionIdList, 0L, 1, 500, Whether.NO.getValue(), List.of(3), null, null).getRecords();
|
||||
|
||||
// 当前时间
|
||||
Date curDate = new Date();
|
||||
@@ -1146,7 +1146,7 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
|
||||
// 耗材医嘱详细信息
|
||||
List<AdviceBaseDto> deviceInfos = doctorStationAdviceAppService
|
||||
.getAdviceBaseInfo(null, null, null, deviceIds, 0L, 1, 500, Whether.NO.getValue(), List.of(2), null)
|
||||
.getAdviceBaseInfo(null, null, null, deviceIds, 0L, 1, 500, Whether.NO.getValue(), List.of(2), null, null)
|
||||
.getRecords();
|
||||
|
||||
DeviceRequest deviceRequest;
|
||||
|
||||
@@ -201,7 +201,7 @@ public class EncounterAutoRollAppServiceImpl implements IEncounterAutoRollAppSer
|
||||
.map(AutoRollNursingDto::getActivityDefinitionId).collect(Collectors.toList());
|
||||
// 诊疗医嘱信息
|
||||
List<AdviceBaseDto> activityInfos = doctorStationAdviceAppService.getAdviceBaseInfo(null, null, null,
|
||||
activityDefinitionIdList, 0L, 1, 500, Whether.NO.getValue(), List.of(3), orderPricing).getRecords();
|
||||
activityDefinitionIdList, 0L, 1, 500, Whether.NO.getValue(), List.of(3), orderPricing, null).getRecords();
|
||||
|
||||
// 计费
|
||||
ChargeItem chargeItem;
|
||||
@@ -295,7 +295,7 @@ public class EncounterAutoRollAppServiceImpl implements IEncounterAutoRollAppSer
|
||||
.map(AutoRollBasicServiceDto::getActivityDefinitionId).collect(Collectors.toList());
|
||||
// 诊疗医嘱信息
|
||||
List<AdviceBaseDto> activityInfos = doctorStationAdviceAppService.getAdviceBaseInfo(null, null, null,
|
||||
activityDefinitionIdList, 0L, 1, 500, Whether.NO.getValue(), List.of(3), orderPricing).getRecords();
|
||||
activityDefinitionIdList, 0L, 1, 500, Whether.NO.getValue(), List.of(3), orderPricing, null).getRecords();
|
||||
// 计费
|
||||
ChargeItem chargeItem;
|
||||
for (AutoRollBasicServiceDto autoRollBasicServiceDto : autoRollBasicService) {
|
||||
|
||||
@@ -69,7 +69,8 @@ public class PatientHomeAppServiceImpl implements IPatientHomeAppService {
|
||||
|
||||
// 分页查询,查询患者信息
|
||||
IPage<PatientHomeDto> patientHomeInfoPage = patientHomeAppMapper.getPage(new Page<>(pageNo, pageSize),
|
||||
patientHomeSearchParam.getStatusEnum(), patientHomeSearchParam.getPatientId(), searchKey, queryWrapper);
|
||||
patientHomeSearchParam.getStatusEnum(), patientHomeSearchParam.getPatientId(), searchKey,
|
||||
patientHomeSearchParam.getNursingLevelList(), queryWrapper);
|
||||
|
||||
patientHomeInfoPage.getRecords().forEach(e -> {
|
||||
// 护理级别
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 患者首页 应用实现
|
||||
@@ -36,7 +37,11 @@ public class PatientHomeController {
|
||||
public R<?> getPatientInfoInit(PatientHomeSearchParam patientHomeSearchParam,
|
||||
@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request) {
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(value = "nursingLevelList", required = false) List<Integer> nursingLevelList,
|
||||
HttpServletRequest request) {
|
||||
// 将护理级别列表设置到查询参数中
|
||||
patientHomeSearchParam.setNursingLevelList(nursingLevelList);
|
||||
return patientHomeAppService.getPatientInfoInit(patientHomeSearchParam, searchKey, pageNo, pageSize, request);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.openhis.web.inpatientmanage.dto;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 患者首页查询参数
|
||||
*
|
||||
@@ -19,4 +21,7 @@ public class PatientHomeSearchParam {
|
||||
/** 患者ID */
|
||||
private Long patientId;
|
||||
|
||||
/** 护理级别列表(多选) */
|
||||
private List<Integer> nursingLevelList;
|
||||
|
||||
}
|
||||
|
||||
@@ -27,10 +27,13 @@ public interface PatientHomeAppMapper {
|
||||
* @param statusEnum 状态编码
|
||||
* @param patientId 患者ID
|
||||
* @param searchKey 查询条件
|
||||
* @param nursingLevelList 护理级别列表
|
||||
* @param queryWrapper 查询wrapper
|
||||
* @return 住院登记信息
|
||||
*/
|
||||
IPage<PatientHomeDto> getPage(@Param("page") Page<PatientHomeDto> page, @Param("statusEnum") Integer statusEnum,
|
||||
@Param("patientId") Long patientId, @Param("searchKey") String searchKey,
|
||||
@Param("nursingLevelList") List<Integer> nursingLevelList,
|
||||
@Param(Constants.WRAPPER) QueryWrapper<PatientHomeDto> queryWrapper);
|
||||
|
||||
/**
|
||||
|
||||
@@ -100,10 +100,12 @@ public class IssueDto {
|
||||
|
||||
/** 开始时间 */
|
||||
@NotNull
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date startTime;
|
||||
|
||||
/** 结束时间 */
|
||||
@NotNull
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date endTime;
|
||||
|
||||
/** 单价 */
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package com.openhis.web.inventorymanage.dto;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.core.common.annotation.Excel;
|
||||
import com.core.common.annotation.ExcelExtra;
|
||||
@@ -248,7 +249,8 @@ public class ProductTransferDetailDto {
|
||||
private Date occurrenceTime;
|
||||
|
||||
/**
|
||||
* 单位列表
|
||||
* 单位列表(非数据库字段,业务逻辑填充)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private List<UnitDto> unitList;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.openhis.web.lab.appservice;
|
||||
|
||||
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentSelParam;
|
||||
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentUpDto;
|
||||
import com.core.common.core.domain.R;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 检验项目 AppService 接口(独立操作 lab_activity_definition 表)
|
||||
*/
|
||||
public interface ILabActivityDefinitionAppService {
|
||||
|
||||
/**
|
||||
* 分页查询检验项目列表
|
||||
*/
|
||||
R<?> getLabActivityDefinitionPage(DiagnosisTreatmentSelParam selParam, String searchKey,
|
||||
Integer pageNo, Integer pageSize, HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* 根据id查询检验项目详情
|
||||
*/
|
||||
R<?> getLabActivityDefinitionOne(Long id);
|
||||
|
||||
/**
|
||||
* 新增检验项目
|
||||
*/
|
||||
R<?> addLabActivityDefinition(DiagnosisTreatmentUpDto dto);
|
||||
|
||||
/**
|
||||
* 编辑检验项目
|
||||
*/
|
||||
R<?> editLabActivityDefinition(DiagnosisTreatmentUpDto dto);
|
||||
|
||||
/**
|
||||
* 停用检验项目
|
||||
*/
|
||||
R<?> stopLabActivityDefinition(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 启用检验项目
|
||||
*/
|
||||
R<?> startLabActivityDefinition(List<Long> ids);
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
package com.openhis.web.lab.appservice.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.core.common.core.domain.model.LoginUser;
|
||||
import com.core.common.utils.*;
|
||||
import com.core.common.utils.bean.BeanUtils;
|
||||
import com.openhis.common.constant.PromptMsgConstant;
|
||||
import com.openhis.common.enums.ActivityType;
|
||||
import com.openhis.common.enums.PublicationStatus;
|
||||
import com.openhis.common.enums.Whether;
|
||||
import com.core.common.utils.ChineseConvertUtils;
|
||||
import com.openhis.common.utils.EnumUtils;
|
||||
import com.openhis.common.utils.HisQueryUtils;
|
||||
import com.openhis.common.enums.AssignSeqEnum;
|
||||
import com.openhis.lab.domain.LabActivityDefinition;
|
||||
import com.openhis.lab.service.ILabActivityDefinitionService;
|
||||
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentDto;
|
||||
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentSelParam;
|
||||
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentUpDto;
|
||||
import com.openhis.web.lab.appservice.ILabActivityDefinitionAppService;
|
||||
import com.openhis.web.datadictionary.mapper.LabActivityDefinitionManageMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
* 检验项目 AppService 实现(独立操作 lab_activity_definition 表)
|
||||
*/
|
||||
@Service
|
||||
public class LabActivityDefinitionAppServiceImpl implements ILabActivityDefinitionAppService {
|
||||
|
||||
@Resource
|
||||
private ILabActivityDefinitionService labActivityDefinitionService;
|
||||
|
||||
@Resource
|
||||
private LabActivityDefinitionManageMapper labActivityDefinitionManageMapper;
|
||||
|
||||
@Resource
|
||||
private AssignSeqUtil assignSeqUtil;
|
||||
|
||||
@Override
|
||||
public R<?> getLabActivityDefinitionPage(DiagnosisTreatmentSelParam selParam, String searchKey,
|
||||
Integer pageNo, Integer pageSize, HttpServletRequest request) {
|
||||
if (selParam == null) {
|
||||
selParam = new DiagnosisTreatmentSelParam();
|
||||
}
|
||||
if (selParam.getStatusEnum() == null) {
|
||||
selParam.setStatusEnum(PublicationStatus.ACTIVE.getValue());
|
||||
}
|
||||
|
||||
// 临时移除需要手动拼别名条件的字段
|
||||
Long inspectionTypeIdValue = null;
|
||||
if (selParam.getInspectionTypeId() != null) {
|
||||
inspectionTypeIdValue = selParam.getInspectionTypeId();
|
||||
selParam.setInspectionTypeId(null);
|
||||
}
|
||||
Integer pricingFlagValue = null;
|
||||
if (selParam.getPricingFlag() != null) {
|
||||
pricingFlagValue = selParam.getPricingFlag();
|
||||
selParam.setPricingFlag(null);
|
||||
}
|
||||
|
||||
QueryWrapper<DiagnosisTreatmentDto> queryWrapper = HisQueryUtils.buildQueryWrapper(selParam,
|
||||
searchKey, new HashSet<>(Arrays.asList("T1.bus_no", "T1.name", "T1.py_str", "T1.wb_str")), request);
|
||||
|
||||
if (inspectionTypeIdValue != null) {
|
||||
queryWrapper.eq("T1.inspection_type_id", inspectionTypeIdValue);
|
||||
selParam.setInspectionTypeId(inspectionTypeIdValue);
|
||||
}
|
||||
if (pricingFlagValue != null) {
|
||||
queryWrapper.eq("T1.pricing_flag", pricingFlagValue);
|
||||
selParam.setPricingFlag(pricingFlagValue);
|
||||
}
|
||||
|
||||
IPage<DiagnosisTreatmentDto> page = labActivityDefinitionManageMapper
|
||||
.getLabActivityDefinitionPage(new Page<>(pageNo, pageSize), queryWrapper);
|
||||
|
||||
page.getRecords().forEach(e -> {
|
||||
e.setYbFlag_enumText(EnumUtils.getInfoByValue(Whether.class, e.getYbFlag()));
|
||||
e.setYbMatchFlag_enumText(EnumUtils.getInfoByValue(Whether.class, e.getYbMatchFlag()));
|
||||
e.setTypeEnum_enumText(EnumUtils.getInfoByValue(ActivityType.class, e.getTypeEnum()));
|
||||
e.setStatusEnum_enumText(EnumUtils.getInfoByValue(PublicationStatus.class, e.getStatusEnum()));
|
||||
e.setPricingFlag_enumText(EnumUtils.getInfoByValue(Whether.class, e.getPricingFlag()));
|
||||
});
|
||||
|
||||
return R.ok(page);
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> getLabActivityDefinitionOne(Long id) {
|
||||
Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
|
||||
DiagnosisTreatmentDto dto = labActivityDefinitionManageMapper.getLabActivityDefinitionOne(id, tenantId);
|
||||
return R.ok(dto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> addLabActivityDefinition(DiagnosisTreatmentUpDto dto) {
|
||||
if (dto.getOrgId() == null) {
|
||||
dto.setOrgId(SecurityUtils.getLoginUser().getHospitalId());
|
||||
}
|
||||
|
||||
LabActivityDefinition lab = new LabActivityDefinition();
|
||||
BeanUtils.copyProperties(dto, lab);
|
||||
lab.setSortOrder(dto.getSortOrder())
|
||||
.setServiceRange(dto.getServiceRange())
|
||||
.setInspectionTypeId(dto.getInspectionTypeId())
|
||||
.setFeePackageId(dto.getFeePackageId())
|
||||
.setSubItemId(dto.getSubItemId());
|
||||
|
||||
if (StringUtils.isEmpty(lab.getBusNo())) {
|
||||
lab.setBusNo(assignSeqUtil.getSeq(AssignSeqEnum.ACTIVITY_DEFINITION_NUM.getPrefix(), 10));
|
||||
}
|
||||
lab.setPyStr(ChineseConvertUtils.toPinyinFirstLetter(lab.getName()));
|
||||
lab.setWbStr(ChineseConvertUtils.toWBFirstLetter(lab.getName()));
|
||||
lab.setStatusEnum(PublicationStatus.ACTIVE.getValue());
|
||||
|
||||
// 设置创建者和租户ID
|
||||
String createBy = "system";
|
||||
Integer tenantId = null;
|
||||
try {
|
||||
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||
if (loginUser != null) {
|
||||
createBy = loginUser.getUsername();
|
||||
tenantId = loginUser.getTenantId();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 使用默认值
|
||||
}
|
||||
lab.setCreateBy(createBy);
|
||||
lab.setTenantId(tenantId != null ? tenantId : 1);
|
||||
if (lab.getCreateTime() == null) {
|
||||
lab.setCreateTime(new java.util.Date());
|
||||
}
|
||||
|
||||
return labActivityDefinitionService.addLabActivityDefinition(lab)
|
||||
? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"检验项目"}))
|
||||
: R.fail(null, "检验编码已存在:" + lab.getBusNo());
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> editLabActivityDefinition(DiagnosisTreatmentUpDto dto) {
|
||||
LabActivityDefinition lab = new LabActivityDefinition();
|
||||
BeanUtils.copyProperties(dto, lab);
|
||||
lab.setSortOrder(dto.getSortOrder())
|
||||
.setServiceRange(dto.getServiceRange())
|
||||
.setInspectionTypeId(dto.getInspectionTypeId())
|
||||
.setFeePackageId(dto.getFeePackageId())
|
||||
.setSubItemId(dto.getSubItemId())
|
||||
.setPricingFlag(dto.getPricingFlag());
|
||||
lab.setPyStr(ChineseConvertUtils.toPinyinFirstLetter(lab.getName()));
|
||||
lab.setWbStr(ChineseConvertUtils.toWBFirstLetter(lab.getName()));
|
||||
|
||||
return labActivityDefinitionService.updateById(lab)
|
||||
? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"检验项目"}))
|
||||
: R.fail(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> stopLabActivityDefinition(List<Long> ids) {
|
||||
List<LabActivityDefinition> labList = new CopyOnWriteArrayList<>();
|
||||
for (Long id : ids) {
|
||||
LabActivityDefinition lab = new LabActivityDefinition();
|
||||
lab.setId(id).setStatusEnum(PublicationStatus.RETIRED.getValue());
|
||||
labList.add(lab);
|
||||
}
|
||||
labActivityDefinitionService.updateBatchById(labList);
|
||||
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"检验项目"}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> startLabActivityDefinition(List<Long> ids) {
|
||||
List<LabActivityDefinition> labList = new CopyOnWriteArrayList<>();
|
||||
for (Long id : ids) {
|
||||
LabActivityDefinition lab = new LabActivityDefinition();
|
||||
lab.setId(id).setStatusEnum(PublicationStatus.ACTIVE.getValue());
|
||||
labList.add(lab);
|
||||
}
|
||||
labActivityDefinitionService.updateBatchById(labList);
|
||||
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"检验项目"}));
|
||||
}
|
||||
}
|
||||
@@ -146,6 +146,9 @@ public class InspectionPackageController extends BaseController {
|
||||
if (inspectionPackage.getIsDisabled() != null) {
|
||||
queryWrapper.eq("is_disabled", inspectionPackage.getIsDisabled());
|
||||
}
|
||||
if (inspectionPackage.getUserId() != null && !inspectionPackage.getUserId().isEmpty()) {
|
||||
queryWrapper.like("user_id", inspectionPackage.getUserId());
|
||||
}
|
||||
}
|
||||
|
||||
// 默认只查询未删除的记录
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.openhis.web.lab.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.core.common.core.controller.BaseController;
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
import com.openhis.lab.domain.InspectionType;
|
||||
@@ -29,7 +30,25 @@ public class InspectionTypeController extends BaseController {
|
||||
private final TransactionTemplate transactionTemplate;
|
||||
|
||||
/**
|
||||
* 获取检验类型列表
|
||||
* 分页获取检验类型列表
|
||||
*
|
||||
* @param pageNo 页码
|
||||
* @param pageSize 每页数量
|
||||
* @param searchKey 搜索关键词
|
||||
*/
|
||||
@GetMapping("/page")
|
||||
public AjaxResult getPage(
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "100") Integer pageSize,
|
||||
@RequestParam(value = "searchKey", required = false) String searchKey) {
|
||||
log.info("【检验类型】分页查询请求 - pageNo: {}, pageSize: {}, searchKey: {}", pageNo, pageSize, searchKey);
|
||||
IPage<InspectionType> result = inspectionTypeService.getPage(pageNo, pageSize, searchKey);
|
||||
log.info("【检验类型】分页查询完成 - 总记录数: {}, 当前页记录数: {}", result.getTotal(), result.getRecords().size());
|
||||
return AjaxResult.success(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取检验类型列表(不分页,兼容旧接口)
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public AjaxResult list(InspectionType inspectionType) {
|
||||
@@ -75,7 +94,6 @@ public class InspectionTypeController extends BaseController {
|
||||
|
||||
// 查询是否存在相同编码的记录
|
||||
List<InspectionType> existingRecords = inspectionTypeService.list(queryWrapper);
|
||||
log.debug("检查编码唯一性:code={}, 数据库中存在记录数={}", inspectionType.getCode(), existingRecords.size());
|
||||
|
||||
if (!existingRecords.isEmpty()) {
|
||||
return AjaxResult.error("检验类型编码已存在");
|
||||
@@ -100,8 +118,6 @@ public class InspectionTypeController extends BaseController {
|
||||
return toAjax(result);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
log.error("新增检验类型失败:code={}, 错误信息:{}", inspectionType.getCode(), e.getMessage(), e);
|
||||
|
||||
// 捕获唯一性约束冲突异常
|
||||
if (e.getMessage().contains("uk_inspection_type_code") ||
|
||||
e.getMessage().contains("duplicate key value") ||
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.openhis.web.lab.controller;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentSelParam;
|
||||
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentUpDto;
|
||||
import com.openhis.web.lab.appservice.ILabActivityDefinitionAppService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 检验项目维护 Controller(独立操作 lab_activity_definition 表)
|
||||
* 路径前缀:/lab/activity-definition
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/lab/activity-definition")
|
||||
@Slf4j
|
||||
public class LabActivityDefinitionController {
|
||||
|
||||
@Resource
|
||||
private ILabActivityDefinitionAppService labActivityDefinitionAppService;
|
||||
|
||||
/**
|
||||
* 分页查询检验项目列表
|
||||
*/
|
||||
@GetMapping("/page")
|
||||
public R<?> getPage(DiagnosisTreatmentSelParam selParam,
|
||||
@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
HttpServletRequest request) {
|
||||
return labActivityDefinitionAppService.getLabActivityDefinitionPage(selParam, searchKey, pageNo, pageSize, request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id查询检验项目详情
|
||||
*/
|
||||
@GetMapping("/one")
|
||||
public R<?> getOne(@RequestParam Long id) {
|
||||
return labActivityDefinitionAppService.getLabActivityDefinitionOne(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增检验项目
|
||||
*/
|
||||
@PostMapping("/add")
|
||||
public R<?> add(@Validated @RequestBody DiagnosisTreatmentUpDto dto) {
|
||||
return labActivityDefinitionAppService.addLabActivityDefinition(dto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑检验项目
|
||||
*/
|
||||
@PutMapping("/edit")
|
||||
public R<?> edit(@RequestBody DiagnosisTreatmentUpDto dto) {
|
||||
return labActivityDefinitionAppService.editLabActivityDefinition(dto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 停用检验项目
|
||||
*/
|
||||
@PutMapping("/stop")
|
||||
public R<?> stop(@RequestBody List<Long> ids) {
|
||||
return labActivityDefinitionAppService.stopLabActivityDefinition(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用检验项目
|
||||
*/
|
||||
@PutMapping("/start")
|
||||
public R<?> start(@RequestBody List<Long> ids) {
|
||||
return labActivityDefinitionAppService.startLabActivityDefinition(ids);
|
||||
}
|
||||
}
|
||||
@@ -62,10 +62,10 @@ public class OutpatientInfusionAppServiceImpl implements IOutpatientInfusionAppS
|
||||
OutpatientStationInitDto initDto = new OutpatientStationInitDto();
|
||||
// 执行状态
|
||||
List<OutpatientStationInitDto.ServiceStatus> serviceStatusOptions = new ArrayList<>();
|
||||
serviceStatusOptions.add(new OutpatientStationInitDto.ServiceStatus(RequestStatus.ACTIVE.getValue(),
|
||||
"待执行"));
|
||||
serviceStatusOptions.add(new OutpatientStationInitDto.ServiceStatus(RequestStatus.COMPLETED.getValue(),
|
||||
RequestStatus.COMPLETED.getInfo()));
|
||||
// serviceStatusOptions.add(new OutpatientStationInitDto.ServiceStatus(RequestStatus.IN_PROGRESS.getValue(),
|
||||
// RequestStatus.IN_PROGRESS.getInfo()));
|
||||
serviceStatusOptions.add(new OutpatientStationInitDto.ServiceStatus(RequestStatus.CANCELLED.getValue(),
|
||||
RequestStatus.CANCELLED.getInfo()));
|
||||
initDto.setServiceStatusOptions(serviceStatusOptions);
|
||||
|
||||
@@ -55,6 +55,8 @@ import com.openhis.web.paymentmanage.dto.CancelPaymentDto;
|
||||
import com.openhis.web.paymentmanage.dto.Clinic2207OrderResultDto;
|
||||
import com.openhis.web.paymentmanage.mapper.PaymentMapper;
|
||||
import com.openhis.web.personalization.dto.ActivityDeviceDto;
|
||||
import com.openhis.triageandqueuemanage.domain.TriageQueueItem;
|
||||
import com.openhis.triageandqueuemanage.service.TriageQueueItemService;
|
||||
import com.openhis.workflow.domain.ServiceRequest;
|
||||
import com.openhis.workflow.service.IDeviceDispenseService;
|
||||
import com.openhis.workflow.service.IDeviceRequestService;
|
||||
@@ -81,9 +83,11 @@ import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -149,6 +153,8 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
||||
@Resource
|
||||
private OutpatientRegistrationAppMapper outpatientRegistrationAppMapper;
|
||||
@Resource
|
||||
private TriageQueueItemService triageQueueItemService;
|
||||
@Resource
|
||||
private IRegService iRegService;
|
||||
@Resource
|
||||
private IPatientService iPatientService;
|
||||
@@ -199,13 +205,19 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
||||
// 此次chargeItem的就诊诊断id集合
|
||||
List<Long> diagIdList
|
||||
= chargeItemList.stream().map(ChargeItem::getEncounterDiagnosisId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
|
||||
if (diagIdList.isEmpty()) {
|
||||
throw new ServiceException("收费项的就诊诊断查询为空");
|
||||
}
|
||||
// 此次就诊的医疗类型列表
|
||||
List<EncounterDiagnosis> diagList = iEncounterDiagnosisService.getDiagnosisList(diagIdList);
|
||||
List<EncounterDiagnosis> diagList;
|
||||
if (diagIdList.isEmpty()) {
|
||||
// 收费项未关联就诊诊断(如挂号费、自动诊疗费等),则直接从就诊维度查询诊断
|
||||
diagList = iEncounterDiagnosisService.getDiagnosisList(prePaymentDto.getEncounterId());
|
||||
if (diagList.isEmpty()) {
|
||||
throw new ServiceException("就诊诊断查询为空,错误信息:EncounterDiagnosis");
|
||||
throw new ServiceException("当前就诊暂无诊断记录,请先由医生录入诊断后再进行收费");
|
||||
}
|
||||
} else {
|
||||
diagList = iEncounterDiagnosisService.getDiagnosisList(diagIdList);
|
||||
if (diagList.isEmpty()) {
|
||||
throw new ServiceException("就诊诊断查询为空");
|
||||
}
|
||||
}
|
||||
List<String> medTypeList
|
||||
= diagList.stream().map(EncounterDiagnosis::getMedTypeCode).distinct().collect(Collectors.toList());
|
||||
@@ -231,15 +243,27 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
||||
if (distinctAccountIdList.isEmpty()) {
|
||||
throw new ServiceException("未找到有效的账户信息");
|
||||
}
|
||||
// 只按账户ID查询,不再追加 encounter_id 条件
|
||||
// 原因:收费项上的 accountId 已能唯一定位账户,额外的 encounter_id 条件
|
||||
// 在挂号费等场景下可能因数据不一致导致查不到,引发误报
|
||||
List<Account> accountList = iAccountService.list(new LambdaQueryWrapper<Account>()
|
||||
.in(Account::getId, distinctAccountIdList).eq(Account::getEncounterId, prePaymentDto.getEncounterId()));
|
||||
.in(Account::getId, distinctAccountIdList));
|
||||
if (accountList.size() != distinctAccountIdList.size()) {
|
||||
throw new ServiceException("未查询到账户信息");
|
||||
// 部分账户查不到时,记录警告日志,并校验是否每个收费项都能找到对应账户
|
||||
Set<Long> foundAccountIds = accountList.stream().map(Account::getId).collect(Collectors.toSet());
|
||||
List<Long> missingAccountIds = distinctAccountIdList.stream()
|
||||
.filter(id -> !foundAccountIds.contains(id)).collect(Collectors.toList());
|
||||
if (accountList.isEmpty()) {
|
||||
throw new ServiceException("未查询到任何账户信息,encounterId:" + prePaymentDto.getEncounterId()
|
||||
+ ",期望accountId列表:" + distinctAccountIdList);
|
||||
}
|
||||
}
|
||||
|
||||
// 账户id,对应的账单列表
|
||||
Map<Long, List<ChargeItem>> chargeItemMapByAccountId
|
||||
= chargeItemList.stream().collect(Collectors.groupingBy(ChargeItem::getAccountId));
|
||||
= chargeItemList.stream()
|
||||
.filter(item -> item.getAccountId() != null)
|
||||
.collect(Collectors.groupingBy(ChargeItem::getAccountId));
|
||||
// 查询合同信息
|
||||
List<Contract> contractList = contractService.list();
|
||||
|
||||
@@ -622,6 +646,37 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
||||
});
|
||||
|
||||
if (!medicationRequestIdList.isEmpty()) {
|
||||
// 获取药品请求信息,为输液类药品生成服务请求
|
||||
List<MedicationRequest> medicationRequests = medicationRequestService.listByIds(medicationRequestIdList);
|
||||
|
||||
// 为输液类药品生成 wor_service_request 记录
|
||||
for (MedicationRequest medReq : medicationRequests) {
|
||||
if (medReq.getInfusionFlag() != null && medReq.getInfusionFlag() == 1) {
|
||||
ServiceRequest serviceRequest = new ServiceRequest();
|
||||
serviceRequest.setBasedOnId(medReq.getId())
|
||||
.setBasedOnTable(CommonConstants.TableName.MED_MEDICATION_REQUEST)
|
||||
.setEncounterId(medReq.getEncounterId())
|
||||
.setPatientId(medReq.getPatientId())
|
||||
.setActivityId(medReq.getMedicationId())
|
||||
.setStatusEnum(RequestStatus.ACTIVE.getValue()) // 状态设为已发送 (2),这样门诊输液页面才能查到
|
||||
.setGroupId(medReq.getGroupId())
|
||||
.setOrgId(medReq.getOrgId())
|
||||
.setRequesterId(medReq.getPractitionerId())
|
||||
.setAuthoredTime(new Date())
|
||||
.setEncounterDiagnosisId(medReq.getEncounterDiagnosisId())
|
||||
.setConditionId(medReq.getConditionId())
|
||||
.setQuantity(medReq.getQuantity())
|
||||
.setUnitCode(medReq.getUnitCode())
|
||||
.setPriorityEnum(medReq.getPriorityEnum())
|
||||
.setPerformFlag(Whether.NO.getValue())
|
||||
.setIntentEnum(medReq.getIntentEnum())
|
||||
.setCategoryEnum(medReq.getCategoryEnum())
|
||||
.setYbClassEnum(medReq.getYbClassEnum())
|
||||
.setBusNo(assignSeqUtil.getSeqByDay(AssignSeqEnum.SERVICE_RES_NO.getPrefix(), 4));
|
||||
serviceRequestService.save(serviceRequest);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新请求状态为已完成
|
||||
medicationRequestService.updateCompletedStatusBatch(medicationRequestIdList, null, null);
|
||||
// 更新药品发放状态为待配药
|
||||
@@ -1881,6 +1936,80 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
||||
|
||||
// 就诊ID
|
||||
Long encounterId = iEncounterService.saveEncounterByRegister(encounter);
|
||||
|
||||
// 创建 triage_queue_item 队列记录
|
||||
try {
|
||||
Integer tenantId = encounter.getTenantId() != null ? encounter.getTenantId() : SecurityUtils.getLoginUser().getTenantId();
|
||||
LocalDate queueDate = LocalDate.now();
|
||||
|
||||
// 查询当前科室当天的最大排队序号
|
||||
Integer maxOrder = triageQueueItemService.list(
|
||||
new LambdaQueryWrapper<TriageQueueItem>()
|
||||
.eq(TriageQueueItem::getTenantId, tenantId)
|
||||
.eq(TriageQueueItem::getOrganizationId, encounter.getOrganizationId())
|
||||
.eq(TriageQueueItem::getQueueDate, queueDate)
|
||||
.eq(TriageQueueItem::getDeleteFlag, "0")
|
||||
.ne(TriageQueueItem::getStatus, "COMPLETED")
|
||||
).stream()
|
||||
.map(TriageQueueItem::getQueueOrder)
|
||||
.filter(Objects::nonNull)
|
||||
.max(Integer::compareTo)
|
||||
.orElse(0);
|
||||
|
||||
// 获取患者信息
|
||||
Patient patient = iPatientService.getById(encounter.getPatientId());
|
||||
String patientName = patient != null ? patient.getName() : null;
|
||||
|
||||
// 获取挂号医生信息
|
||||
String practitionerName = null;
|
||||
Long queuePractitionerId = null;
|
||||
if (encounterParticipantFormData.getPractitionerId() != null) {
|
||||
Practitioner practitioner = iPractitionerService.getById(encounterParticipantFormData.getPractitionerId());
|
||||
if (practitioner != null) {
|
||||
practitionerName = practitioner.getName();
|
||||
queuePractitionerId = practitioner.getId();
|
||||
}
|
||||
}
|
||||
|
||||
// 获取科室信息
|
||||
Organization organization = iOrganizationService.getById(encounter.getOrganizationId());
|
||||
String organizationName = organization != null ? organization.getName() : null;
|
||||
|
||||
// 获取服务项目信息(挂号类型)
|
||||
String healthcareName = null;
|
||||
if (encounter.getServiceTypeId() != null) {
|
||||
HealthcareService healthcareService = healthcareServiceService.getById(encounter.getServiceTypeId());
|
||||
if (healthcareService != null) {
|
||||
healthcareName = healthcareService.getName();
|
||||
}
|
||||
}
|
||||
|
||||
// 创建队列项
|
||||
TriageQueueItem queueItem = new TriageQueueItem()
|
||||
.setTenantId(tenantId)
|
||||
.setQueueDate(queueDate)
|
||||
.setOrganizationId(encounter.getOrganizationId())
|
||||
.setOrganizationName(organizationName)
|
||||
.setEncounterId(encounterId)
|
||||
.setPatientId(encounter.getPatientId())
|
||||
.setPatientName(patientName)
|
||||
.setHealthcareName(healthcareName)
|
||||
.setPractitionerId(queuePractitionerId)
|
||||
.setPractitionerName(practitionerName)
|
||||
.setRoomNo(null)
|
||||
.setStatus("WAITING")
|
||||
.setQueueOrder(maxOrder + 1)
|
||||
.setDeleteFlag("0")
|
||||
.setCreateTime(LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS))
|
||||
.setUpdateTime(LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS));
|
||||
|
||||
triageQueueItemService.save(queueItem);
|
||||
logger.info("挂号时创建队列记录成功,encounterId={}, queueItemId={}", encounterId, queueItem.getId());
|
||||
} catch (Exception e) {
|
||||
logger.error("挂号时创建队列记录失败,encounterId={}", encounterId, e);
|
||||
// 队列记录创建失败不影响挂号流程
|
||||
}
|
||||
|
||||
// 保存就诊位置信息
|
||||
// 挂号时不选Location了
|
||||
// encounterLocationFormData.setEncounterId(encounterId);
|
||||
@@ -2048,7 +2177,7 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
||||
adviceBaseDto.setAdviceDefinitionId(activityDeviceDto.getDevActId());
|
||||
// 对应的诊疗医嘱信息
|
||||
AdviceBaseDto activityAdviceBaseDto = iDoctorStationAdviceAppService.getAdviceBaseInfo(adviceBaseDto, null,
|
||||
null, null, organizationId, 1, 1, Whether.NO.getValue(), List.of(1, 2, 3), null).getRecords().get(0);
|
||||
null, null, organizationId, 1, 1, Whether.NO.getValue(), List.of(1, 2, 3), null, null).getRecords().get(0);
|
||||
// 价格信息
|
||||
if (activityAdviceBaseDto != null) {
|
||||
// 费用定价
|
||||
@@ -2125,14 +2254,18 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
||||
piModel.setBusNo(chargeItem.getBusNo());
|
||||
|
||||
EncounterDiagnosis encounterDiagnosis;
|
||||
if (chargeItem.getEncounterDiagnosisId() == null) {
|
||||
// 收费项未关联就诊诊断(如挂号费、自动诊疗费等),取诊断列表第一条作为兜底
|
||||
encounterDiagnosis = diagList.get(0);
|
||||
} else {
|
||||
Optional<EncounterDiagnosis> optional
|
||||
= diagList.stream().filter(e -> e.getId().equals(chargeItem.getEncounterDiagnosisId())).findFirst();
|
||||
|
||||
if (optional.isPresent()) {
|
||||
encounterDiagnosis = optional.get();
|
||||
} else {
|
||||
throw new ServiceException(
|
||||
"诊断信息与收费项的诊断信息未对应,错误信息:费用项" + chargeItem.getBusNo() + chargeItem.getEncounterDiagnosisId());
|
||||
// 收费项关联的诊断ID在diagList中找不到,也取第一条兜底
|
||||
encounterDiagnosis = diagList.get(0);
|
||||
}
|
||||
}
|
||||
piModel.setMedType(encounterDiagnosis.getMedTypeCode());
|
||||
piModel.setTotalPrice(chargeItem.getTotalPrice());
|
||||
@@ -2200,7 +2333,9 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
||||
= iChargeItemService.getChargeItemBaseInfoByIds(prePaymentDto.getChargeItemIds());
|
||||
|
||||
Map<String, List<ChargeItemBaseInfoDto>> chargeItemKVByContractNo
|
||||
= chargeItemBaseInfoByIds.stream().collect(Collectors.groupingBy(ChargeItemBaseInfoDto::getContractNo));
|
||||
= chargeItemBaseInfoByIds.stream()
|
||||
.filter(dto -> dto.getContractNo() != null && !dto.getContractNo().isEmpty())
|
||||
.collect(Collectors.groupingBy(ChargeItemBaseInfoDto::getContractNo));
|
||||
|
||||
List<InpatientPreSettleDto> yb2303OutputSetInfos = new ArrayList<>();
|
||||
Yb2303OutputSetInfo yb2303OutputSetInfo;
|
||||
@@ -2328,13 +2463,17 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
||||
List<ChargeItemBaseInfoDto> chargeItemBaseInfoByIds
|
||||
= iChargeItemService.getChargeItemBaseInfoByIds(paymentDto.getChargeItemIds());
|
||||
Map<String, List<ChargeItemBaseInfoDto>> chargeItemKVByContractNo
|
||||
= chargeItemBaseInfoByIds.stream().collect(Collectors.groupingBy(ChargeItemBaseInfoDto::getContractNo));
|
||||
= chargeItemBaseInfoByIds.stream()
|
||||
.filter(dto -> dto.getContractNo() != null && !dto.getContractNo().isEmpty())
|
||||
.collect(Collectors.groupingBy(ChargeItemBaseInfoDto::getContractNo));
|
||||
|
||||
List<Account> accountList = iAccountService.getAccountListByEncounter(paymentDto.getEncounterId());
|
||||
if (accountList.isEmpty()) {
|
||||
throw new ServiceException("未查询到账户信息");
|
||||
}
|
||||
Map<Long, List<Account>> accountKVById = accountList.stream().collect(Collectors.groupingBy(Account::getId));
|
||||
Map<Long, List<Account>> accountKVById = accountList.stream()
|
||||
.filter(acc -> acc.getId() != null)
|
||||
.collect(Collectors.groupingBy(Account::getId));
|
||||
|
||||
com.openhis.financial.model.PaymentResult paymentResult;
|
||||
List<com.openhis.financial.model.PaymentResult> paymentResultList = new ArrayList<>();
|
||||
@@ -2344,7 +2483,9 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
||||
|
||||
// <3>收费详情按照收费批次进行分组后结算
|
||||
Map<Long, List<PaymentRecDetail>> payTransNoMap
|
||||
= paymentRecDetails.stream().collect(Collectors.groupingBy(PaymentRecDetail::getAccountId));
|
||||
= paymentRecDetails.stream()
|
||||
.filter(detail -> detail.getAccountId() != null)
|
||||
.collect(Collectors.groupingBy(PaymentRecDetail::getAccountId));
|
||||
|
||||
for (Map.Entry<Long, List<PaymentRecDetail>> stringListEntry : payTransNoMap.entrySet()) {
|
||||
// paymentResult = new PaymentResult();
|
||||
|
||||
@@ -30,9 +30,10 @@ public interface IOrdersGroupPackageAppService {
|
||||
*
|
||||
* @param packageTypeEnum 类型枚举
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param tcmFlag 中医标识:0-西医 1-中医
|
||||
* @return 组合套餐
|
||||
*/
|
||||
List<OrdersGroupPackageQueryDto> getGroupPackage(Integer packageTypeEnum, String searchKey);
|
||||
List<OrdersGroupPackageQueryDto> getGroupPackage(Integer packageTypeEnum, String searchKey, Integer tcmFlag);
|
||||
|
||||
/**
|
||||
* 查询组合套餐明细
|
||||
@@ -54,8 +55,9 @@ public interface IOrdersGroupPackageAppService {
|
||||
* 查询组合套餐,供开立医嘱使用
|
||||
*
|
||||
* @param organizationId 患者挂号对应的科室id
|
||||
* @param tcmFlag 中医标识:0-西医 1-中医
|
||||
* @return 组合套餐
|
||||
*/
|
||||
OrdersGroupPackageUseDto getGroupPackageForOrder(Long organizationId);
|
||||
OrdersGroupPackageUseDto getGroupPackageForOrder(Long organizationId, Integer tcmFlag);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
package com.openhis.web.personalization.appservice.impl;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.core.common.exception.ServiceException;
|
||||
import com.core.common.utils.MessageUtils;
|
||||
import com.core.common.utils.SecurityUtils;
|
||||
import com.openhis.common.constant.PromptMsgConstant;
|
||||
@@ -18,13 +26,8 @@ import com.openhis.web.doctorstation.dto.AdviceBaseDto;
|
||||
import com.openhis.web.personalization.appservice.IOrdersGroupPackageAppService;
|
||||
import com.openhis.web.personalization.dto.*;
|
||||
import com.openhis.web.personalization.mapper.OrdersGroupPackageAppMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import static com.core.framework.datasource.DynamicDataSourceContextHolder.log;
|
||||
|
||||
/**
|
||||
* 组合套餐 实现类
|
||||
@@ -61,10 +64,12 @@ public class OrdersGroupPackageAppServiceImpl implements IOrdersGroupPackageAppS
|
||||
|
||||
if (BindingType.PERSONAL.getValue().equals(packageTypeEnum)
|
||||
&& ordersGroupPackageSaveDto.getPractitionerId() == null) {
|
||||
throw new ServiceException("个人组套需选择人员");
|
||||
// throw new ServiceException("个人组套需选择人员");
|
||||
ordersGroupPackageSaveDto.setPractitionerId(SecurityUtils.getLoginUser().getPractitionerId());
|
||||
} else if (BindingType.ORGANIZATION.getValue().equals(packageTypeEnum)
|
||||
&& ordersGroupPackageSaveDto.getOrganizationId() == null) {
|
||||
throw new ServiceException("科室组套需选择科室");
|
||||
// throw new ServiceException("科室组套需选择科室");
|
||||
ordersGroupPackageSaveDto.setOrganizationId(SecurityUtils.getLoginUser().getOrgId());
|
||||
}
|
||||
// 保存主表
|
||||
OrdersGroupPackage ordersGroupPackage = new OrdersGroupPackage();
|
||||
@@ -73,6 +78,7 @@ public class OrdersGroupPackageAppServiceImpl implements IOrdersGroupPackageAppS
|
||||
ordersGroupPackage.setPackageTypeEnum(packageTypeEnum);// 组套包类型
|
||||
ordersGroupPackage.setOrganizationId(ordersGroupPackageSaveDto.getOrganizationId()); // 科室id
|
||||
ordersGroupPackage.setPractitionerId(ordersGroupPackageSaveDto.getPractitionerId()); // 参与者id
|
||||
ordersGroupPackage.setTcmFlag(ordersGroupPackageSaveDto.getTcmFlag()); // 中医标识
|
||||
ordersGroupPackageService.saveOrUpdate(ordersGroupPackage);
|
||||
|
||||
// 编辑场景时,先删除原有的明细再新增
|
||||
@@ -96,6 +102,7 @@ public class OrdersGroupPackageAppServiceImpl implements IOrdersGroupPackageAppS
|
||||
ordersGroupPackageDetail.setMethodCode(ordersGroupPackageDetailSaveDto.getMethodCode()); // 给药途径
|
||||
ordersGroupPackageDetail.setDoseQuantity(ordersGroupPackageDetailSaveDto.getDoseQuantity()); // 小单位单次剂量
|
||||
ordersGroupPackageDetail.setGroupId(ordersGroupPackageDetailSaveDto.getGroupId()); // 组号
|
||||
ordersGroupPackageDetail.setTherapyEnum(ordersGroupPackageDetailSaveDto.getTherapyEnum()); // 治疗类型
|
||||
ordersGroupPackageDetailService.save(ordersGroupPackageDetail);
|
||||
}
|
||||
|
||||
@@ -107,12 +114,14 @@ public class OrdersGroupPackageAppServiceImpl implements IOrdersGroupPackageAppS
|
||||
*
|
||||
* @param packageTypeEnum 类型枚举
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param tcmFlag 中医标识
|
||||
* @return 组合套餐
|
||||
*/
|
||||
@Override
|
||||
public List<OrdersGroupPackageQueryDto> getGroupPackage(Integer packageTypeEnum, String searchKey) {
|
||||
public List<OrdersGroupPackageQueryDto> getGroupPackage(Integer packageTypeEnum, String searchKey,
|
||||
Integer tcmFlag) {
|
||||
List<OrdersGroupPackageQueryDto> groupPackage =
|
||||
ordersGroupPackageAppMapper.getGroupPackage(packageTypeEnum, null, null, searchKey);
|
||||
ordersGroupPackageAppMapper.getGroupPackage(packageTypeEnum, null, null, searchKey, tcmFlag);
|
||||
for (OrdersGroupPackageQueryDto ordersGroupPackageQueryDto : groupPackage) {
|
||||
ordersGroupPackageQueryDto.setPackageTypeEnum_enumText(
|
||||
EnumUtils.getInfoByValue(BindingType.class, ordersGroupPackageQueryDto.getPackageTypeEnum()));
|
||||
@@ -151,19 +160,23 @@ public class OrdersGroupPackageAppServiceImpl implements IOrdersGroupPackageAppS
|
||||
* 查询组合套餐,供开立医嘱使用
|
||||
*
|
||||
* @param organizationId 患者挂号对应的科室id
|
||||
* @param tcmFlag 中医标识
|
||||
* @return 组合套餐
|
||||
*/
|
||||
@Override
|
||||
public OrdersGroupPackageUseDto getGroupPackageForOrder(Long organizationId) {
|
||||
public OrdersGroupPackageUseDto getGroupPackageForOrder(Long organizationId, Integer tcmFlag) {
|
||||
OrdersGroupPackageUseDto ordersGroupPackageUseDto = new OrdersGroupPackageUseDto();
|
||||
// 当前参参与者id
|
||||
Long practitionerId = SecurityUtils.getLoginUser().getPractitionerId();
|
||||
// 当前登录账号的科室id
|
||||
Long orgId = SecurityUtils.getLoginUser().getOrgId();
|
||||
|
||||
log.info("[getGroupPackageForOrder] 当前登录用户 practitionerId: {}, orgId: {}", practitionerId, orgId);
|
||||
|
||||
// 个人组套
|
||||
List<OrdersGroupPackageQueryDto> personalGroupPackage =
|
||||
ordersGroupPackageAppMapper.getGroupPackage(BindingType.PERSONAL.getValue(), null, practitionerId, null);
|
||||
List<OrdersGroupPackageQueryDto> personalGroupPackage = ordersGroupPackageAppMapper
|
||||
.getGroupPackage(BindingType.PERSONAL.getValue(), null, practitionerId, null, tcmFlag);
|
||||
log.info("[getGroupPackageForOrder] 个人组套查询结果数: {}", personalGroupPackage.size());
|
||||
if (!personalGroupPackage.isEmpty()) {
|
||||
List<OrdersGroupPackageDto> personalList = personalGroupPackage.stream().map(queryDto -> {
|
||||
OrdersGroupPackageDto dto = new OrdersGroupPackageDto();
|
||||
@@ -184,7 +197,7 @@ public class OrdersGroupPackageAppServiceImpl implements IOrdersGroupPackageAppS
|
||||
// 医嘱下拉详细信息
|
||||
List<AdviceBaseDto> personalRecords =
|
||||
iDoctorStationAdviceAppService.getAdviceBaseInfo(null, null, null, orderDefinitionIdParamList,
|
||||
organizationId, 1, 100, Whether.NO.getValue(), List.of(1, 2, 3), null).getRecords();
|
||||
organizationId, 1, 100, Whether.NO.getValue(), List.of(1, 2, 3), null, null).getRecords();
|
||||
// 创建AdviceBaseDto的映射,以adviceDefinitionId为key
|
||||
Map<Long, AdviceBaseDto> adviceMap = personalRecords.stream().collect(Collectors
|
||||
.toMap(AdviceBaseDto::getAdviceDefinitionId, advice -> advice, (existing, replacement) -> existing // 如果有重复key,保留第一个
|
||||
@@ -208,10 +221,13 @@ public class OrdersGroupPackageAppServiceImpl implements IOrdersGroupPackageAppS
|
||||
});
|
||||
}
|
||||
ordersGroupPackageUseDto.setPersonalList(personalList);
|
||||
log.info("[getGroupPackageForOrder] 个人组套已设置,数量: {}", personalList.size());
|
||||
} else {
|
||||
log.info("[getGroupPackageForOrder] 个人组套查询结果为空");
|
||||
}
|
||||
// 科室组套
|
||||
List<OrdersGroupPackageQueryDto> organizationGroupPackage =
|
||||
ordersGroupPackageAppMapper.getGroupPackage(BindingType.ORGANIZATION.getValue(), orgId, null, null);
|
||||
List<OrdersGroupPackageQueryDto> organizationGroupPackage = ordersGroupPackageAppMapper
|
||||
.getGroupPackage(BindingType.ORGANIZATION.getValue(), orgId, null, null, tcmFlag);
|
||||
if (!organizationGroupPackage.isEmpty()) {
|
||||
List<OrdersGroupPackageDto> organizationList = organizationGroupPackage.stream().map(queryDto -> {
|
||||
OrdersGroupPackageDto dto = new OrdersGroupPackageDto();
|
||||
@@ -232,7 +248,7 @@ public class OrdersGroupPackageAppServiceImpl implements IOrdersGroupPackageAppS
|
||||
// 医嘱下拉详细信息
|
||||
List<AdviceBaseDto> personalRecords =
|
||||
iDoctorStationAdviceAppService.getAdviceBaseInfo(null, null, null, orderDefinitionIdParamList,
|
||||
organizationId, 1, 100, Whether.NO.getValue(), List.of(1, 2, 3), null).getRecords();
|
||||
organizationId, 1, 100, Whether.NO.getValue(), List.of(1, 2, 3), null, null).getRecords();
|
||||
// 创建AdviceBaseDto的映射,以adviceDefinitionId为key
|
||||
Map<Long, AdviceBaseDto> adviceMap = personalRecords.stream().collect(Collectors
|
||||
.toMap(AdviceBaseDto::getAdviceDefinitionId, advice -> advice, (existing, replacement) -> existing // 如果有重复key,保留第一个
|
||||
@@ -260,7 +276,7 @@ public class OrdersGroupPackageAppServiceImpl implements IOrdersGroupPackageAppS
|
||||
|
||||
// 全院组套
|
||||
List<OrdersGroupPackageQueryDto> hospitalGroupPackage =
|
||||
ordersGroupPackageAppMapper.getGroupPackage(BindingType.HOSPITAL.getValue(), null, null, null);
|
||||
ordersGroupPackageAppMapper.getGroupPackage(BindingType.HOSPITAL.getValue(), null, null, null, tcmFlag);
|
||||
if (!hospitalGroupPackage.isEmpty()) {
|
||||
List<OrdersGroupPackageDto> hospitalList = hospitalGroupPackage.stream().map(queryDto -> {
|
||||
OrdersGroupPackageDto dto = new OrdersGroupPackageDto();
|
||||
@@ -281,7 +297,7 @@ public class OrdersGroupPackageAppServiceImpl implements IOrdersGroupPackageAppS
|
||||
// 医嘱下拉详细信息
|
||||
List<AdviceBaseDto> personalRecords =
|
||||
iDoctorStationAdviceAppService.getAdviceBaseInfo(null, null, null, orderDefinitionIdParamList,
|
||||
organizationId, 1, 100, Whether.NO.getValue(), List.of(1, 2, 3), null).getRecords();
|
||||
organizationId, 1, 100, Whether.NO.getValue(), List.of(1, 2, 3), null, null).getRecords();
|
||||
// 创建AdviceBaseDto的映射,以adviceDefinitionId为key
|
||||
Map<Long, AdviceBaseDto> adviceMap = personalRecords.stream().collect(Collectors
|
||||
.toMap(AdviceBaseDto::getAdviceDefinitionId, advice -> advice, (existing, replacement) -> existing // 如果有重复key,保留第一个
|
||||
|
||||
@@ -0,0 +1,321 @@
|
||||
package com.openhis.web.personalization.appservice.impl;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.core.common.utils.MessageUtils;
|
||||
import com.core.common.utils.SecurityUtils;
|
||||
import com.openhis.common.constant.PromptMsgConstant;
|
||||
import com.openhis.common.enums.BindingType;
|
||||
import com.openhis.common.enums.Whether;
|
||||
import com.openhis.common.utils.EnumUtils;
|
||||
import com.openhis.template.domain.OrdersGroupPackage;
|
||||
import com.openhis.template.domain.OrdersGroupPackageDetail;
|
||||
import com.openhis.template.service.IOrdersGroupPackageDetailService;
|
||||
import com.openhis.template.service.IOrdersGroupPackageService;
|
||||
import com.openhis.web.doctorstation.appservice.IDoctorStationAdviceAppService;
|
||||
import com.openhis.web.doctorstation.dto.AdviceBaseDto;
|
||||
import com.openhis.web.personalization.appservice.IOrdersGroupPackageAppService;
|
||||
import com.openhis.web.personalization.dto.*;
|
||||
import com.openhis.web.personalization.mapper.OrdersGroupPackageAppMapper;
|
||||
|
||||
/**
|
||||
* 组合套餐 实现类
|
||||
*
|
||||
* @author yangmo
|
||||
* @date 2025-04-10
|
||||
*/
|
||||
@Service
|
||||
public class OrdersGroupPackageAppServiceImpl implements IOrdersGroupPackageAppService {
|
||||
|
||||
@Resource
|
||||
OrdersGroupPackageAppMapper ordersGroupPackageAppMapper;
|
||||
|
||||
@Resource
|
||||
IOrdersGroupPackageService ordersGroupPackageService;
|
||||
|
||||
@Resource
|
||||
IOrdersGroupPackageDetailService ordersGroupPackageDetailService;
|
||||
|
||||
@Resource
|
||||
IDoctorStationAdviceAppService iDoctorStationAdviceAppService;
|
||||
|
||||
/**
|
||||
* 保存组合套餐
|
||||
*
|
||||
* @param ordersGroupPackageSaveDto 保存组合套餐dto
|
||||
* @param packageTypeEnum 类型枚举
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> saveGroupPackage(OrdersGroupPackageSaveDto ordersGroupPackageSaveDto, Integer packageTypeEnum) {
|
||||
// 组合套餐id
|
||||
Long groupPackageId = ordersGroupPackageSaveDto.getGroupPackageId();
|
||||
|
||||
if (BindingType.PERSONAL.getValue().equals(packageTypeEnum)
|
||||
&& ordersGroupPackageSaveDto.getPractitionerId() == null) {
|
||||
// throw new ServiceException("个人组套需选择人员");
|
||||
ordersGroupPackageSaveDto.setPractitionerId(SecurityUtils.getLoginUser().getPractitionerId());
|
||||
} else if (BindingType.ORGANIZATION.getValue().equals(packageTypeEnum)
|
||||
&& ordersGroupPackageSaveDto.getOrganizationId() == null) {
|
||||
// throw new ServiceException("科室组套需选择科室");
|
||||
ordersGroupPackageSaveDto.setOrganizationId(SecurityUtils.getLoginUser().getOrgId());
|
||||
}
|
||||
// 保存主表
|
||||
OrdersGroupPackage ordersGroupPackage = new OrdersGroupPackage();
|
||||
ordersGroupPackage.setId(groupPackageId);
|
||||
ordersGroupPackage.setName(ordersGroupPackageSaveDto.getName());// 名称
|
||||
ordersGroupPackage.setPackageTypeEnum(packageTypeEnum);// 组套包类型
|
||||
ordersGroupPackage.setOrganizationId(ordersGroupPackageSaveDto.getOrganizationId()); // 科室id
|
||||
ordersGroupPackage.setPractitionerId(ordersGroupPackageSaveDto.getPractitionerId()); // 参与者id
|
||||
ordersGroupPackage.setTcmFlag(ordersGroupPackageSaveDto.getTcmFlag()); // 中医标识
|
||||
ordersGroupPackageService.saveOrUpdate(ordersGroupPackage);
|
||||
|
||||
// 编辑场景时,先删除原有的明细再新增
|
||||
if (groupPackageId != null) {
|
||||
ordersGroupPackageDetailService.remove(new LambdaQueryWrapper<OrdersGroupPackageDetail>()
|
||||
.eq(OrdersGroupPackageDetail::getGroupPackageId, groupPackageId));
|
||||
}
|
||||
// 保存明细表
|
||||
List<OrdersGroupPackageDetailSaveDto> detailList = ordersGroupPackageSaveDto.getDetailList();
|
||||
OrdersGroupPackageDetail ordersGroupPackageDetail;
|
||||
for (OrdersGroupPackageDetailSaveDto ordersGroupPackageDetailSaveDto : detailList) {
|
||||
ordersGroupPackageDetail = new OrdersGroupPackageDetail();
|
||||
ordersGroupPackageDetail.setGroupPackageId(ordersGroupPackage.getId()); // 组合套餐id
|
||||
ordersGroupPackageDetail.setOrderDefinitionId(ordersGroupPackageDetailSaveDto.getOrderDefinitionId()); // 医嘱定义id
|
||||
ordersGroupPackageDetail.setOrderDefinitionTable(ordersGroupPackageDetailSaveDto.getOrderDefinitionTable());// 医嘱定义表名
|
||||
ordersGroupPackageDetail.setQuantity(ordersGroupPackageDetailSaveDto.getQuantity()); // 数量
|
||||
ordersGroupPackageDetail.setUnitCode(ordersGroupPackageDetailSaveDto.getUnitCode()); // 单位
|
||||
ordersGroupPackageDetail.setDose(ordersGroupPackageDetailSaveDto.getDose()); // 单次剂量
|
||||
ordersGroupPackageDetail.setRateCode(ordersGroupPackageDetailSaveDto.getRateCode()); // 用药频次
|
||||
ordersGroupPackageDetail.setDispensePerDuration(ordersGroupPackageDetailSaveDto.getDispensePerDuration()); // 用药天数
|
||||
ordersGroupPackageDetail.setMethodCode(ordersGroupPackageDetailSaveDto.getMethodCode()); // 给药途径
|
||||
ordersGroupPackageDetail.setDoseQuantity(ordersGroupPackageDetailSaveDto.getDoseQuantity()); // 小单位单次剂量
|
||||
ordersGroupPackageDetail.setGroupId(ordersGroupPackageDetailSaveDto.getGroupId()); // 组号
|
||||
ordersGroupPackageDetail.setTherapyEnum(ordersGroupPackageDetailSaveDto.getTherapyEnum()); // 治疗类型
|
||||
ordersGroupPackageDetailService.save(ordersGroupPackageDetail);
|
||||
}
|
||||
|
||||
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[] {"组合套餐"}));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询组合套餐
|
||||
*
|
||||
* @param packageTypeEnum 类型枚举
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param tcmFlag 中医标识
|
||||
* @return 组合套餐
|
||||
*/
|
||||
@Override
|
||||
public List<OrdersGroupPackageQueryDto> getGroupPackage(Integer packageTypeEnum, String searchKey,
|
||||
Integer tcmFlag) {
|
||||
List<OrdersGroupPackageQueryDto> groupPackage =
|
||||
ordersGroupPackageAppMapper.getGroupPackage(packageTypeEnum, null, null, searchKey, tcmFlag);
|
||||
for (OrdersGroupPackageQueryDto ordersGroupPackageQueryDto : groupPackage) {
|
||||
ordersGroupPackageQueryDto.setPackageTypeEnum_enumText(
|
||||
EnumUtils.getInfoByValue(BindingType.class, ordersGroupPackageQueryDto.getPackageTypeEnum()));
|
||||
}
|
||||
return groupPackage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询组合套餐明细
|
||||
*
|
||||
* @param groupPackageId 组合套餐id
|
||||
* @return 组合套餐明细
|
||||
*/
|
||||
@Override
|
||||
public List<OrdersGroupPackageDetailQueryDto> getGroupPackageDetail(Long groupPackageId) {
|
||||
return ordersGroupPackageAppMapper.getGroupPackageDetail(List.of(groupPackageId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除组合套餐
|
||||
*
|
||||
* @param groupPackageId 组合套餐id
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> delGroupPackage(Long groupPackageId) {
|
||||
// 删除主表
|
||||
ordersGroupPackageService.removeById(groupPackageId);
|
||||
// 删除明细
|
||||
ordersGroupPackageDetailService.remove(new LambdaQueryWrapper<OrdersGroupPackageDetail>()
|
||||
.eq(OrdersGroupPackageDetail::getGroupPackageId, groupPackageId));
|
||||
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00005, new Object[] {"组合套餐"}));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询组合套餐,供开立医嘱使用
|
||||
*
|
||||
* @param organizationId 患者挂号对应的科室id
|
||||
* @param tcmFlag 中医标识
|
||||
* @return 组合套餐
|
||||
*/
|
||||
@Override
|
||||
public OrdersGroupPackageUseDto getGroupPackageForOrder(Long organizationId, Integer tcmFlag) {
|
||||
OrdersGroupPackageUseDto ordersGroupPackageUseDto = new OrdersGroupPackageUseDto();
|
||||
// 当前参参与者id
|
||||
Long practitionerId = SecurityUtils.getLoginUser().getPractitionerId();
|
||||
// 当前登录账号的科室id
|
||||
Long orgId = SecurityUtils.getLoginUser().getOrgId();
|
||||
|
||||
// 个人组套
|
||||
List<OrdersGroupPackageQueryDto> personalGroupPackage = ordersGroupPackageAppMapper
|
||||
.getGroupPackage(BindingType.PERSONAL.getValue(), null, practitionerId, null, tcmFlag);
|
||||
if (!personalGroupPackage.isEmpty()) {
|
||||
List<OrdersGroupPackageDto> personalList = personalGroupPackage.stream().map(queryDto -> {
|
||||
OrdersGroupPackageDto dto = new OrdersGroupPackageDto();
|
||||
dto.setGroupPackageId(queryDto.getGroupPackageId());
|
||||
dto.setName(queryDto.getName());
|
||||
return dto;
|
||||
}).collect(Collectors.toList());
|
||||
List<Long> groupPackageIds =
|
||||
personalList.stream().map(OrdersGroupPackageDto::getGroupPackageId).collect(Collectors.toList());
|
||||
// 明细项
|
||||
List<OrdersGroupPackageDetailQueryDto> personalGroupPackageDetail =
|
||||
ordersGroupPackageAppMapper.getGroupPackageDetail(groupPackageIds);
|
||||
// 明细项赋值
|
||||
if (!personalGroupPackageDetail.isEmpty()) {
|
||||
// 医嘱定义id集合
|
||||
List<Long> orderDefinitionIdParamList = personalGroupPackageDetail.stream()
|
||||
.map(OrdersGroupPackageDetailQueryDto::getOrderDefinitionId).collect(Collectors.toList());
|
||||
// 医嘱下拉详细信息
|
||||
List<AdviceBaseDto> personalRecords =
|
||||
iDoctorStationAdviceAppService.getAdviceBaseInfo(null, null, null, orderDefinitionIdParamList,
|
||||
organizationId, 1, 100, Whether.NO.getValue(), List.of(1, 2, 3), null).getRecords();
|
||||
// 创建AdviceBaseDto的映射,以adviceDefinitionId为key
|
||||
Map<Long, AdviceBaseDto> adviceMap = personalRecords.stream().collect(Collectors
|
||||
.toMap(AdviceBaseDto::getAdviceDefinitionId, advice -> advice, (existing, replacement) -> existing // 如果有重复key,保留第一个
|
||||
));
|
||||
// 遍历personalGroupPackageDetail,进行匹配赋值
|
||||
for (OrdersGroupPackageDetailQueryDto detail : personalGroupPackageDetail) {
|
||||
Long orderDefinitionId = detail.getOrderDefinitionId();
|
||||
if (orderDefinitionId != null) {
|
||||
AdviceBaseDto matchedAdvice = adviceMap.get(orderDefinitionId);
|
||||
if (matchedAdvice != null) {
|
||||
detail.setOrderDetailInfos(matchedAdvice);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 将明细数据按groupPackageId分组
|
||||
Map<Long, List<OrdersGroupPackageDetailQueryDto>> detailMap = personalGroupPackageDetail.stream()
|
||||
.collect(Collectors.groupingBy(OrdersGroupPackageDetailQueryDto::getGroupPackageId));
|
||||
personalList.forEach(dto -> {
|
||||
List<OrdersGroupPackageDetailQueryDto> details = detailMap.get(dto.getGroupPackageId());
|
||||
dto.setDetailList(details != null ? details : Collections.emptyList());
|
||||
});
|
||||
}
|
||||
ordersGroupPackageUseDto.setPersonalList(personalList);
|
||||
}
|
||||
// 科室组套
|
||||
List<OrdersGroupPackageQueryDto> organizationGroupPackage = ordersGroupPackageAppMapper
|
||||
.getGroupPackage(BindingType.ORGANIZATION.getValue(), orgId, null, null, tcmFlag);
|
||||
if (!organizationGroupPackage.isEmpty()) {
|
||||
List<OrdersGroupPackageDto> organizationList = organizationGroupPackage.stream().map(queryDto -> {
|
||||
OrdersGroupPackageDto dto = new OrdersGroupPackageDto();
|
||||
dto.setGroupPackageId(queryDto.getGroupPackageId());
|
||||
dto.setName(queryDto.getName());
|
||||
return dto;
|
||||
}).collect(Collectors.toList());
|
||||
List<Long> groupPackageIds =
|
||||
organizationList.stream().map(OrdersGroupPackageDto::getGroupPackageId).collect(Collectors.toList());
|
||||
// 明细项
|
||||
List<OrdersGroupPackageDetailQueryDto> organizationGroupPackageDetail =
|
||||
ordersGroupPackageAppMapper.getGroupPackageDetail(groupPackageIds);
|
||||
// 明细项赋值
|
||||
if (!organizationGroupPackageDetail.isEmpty()) {
|
||||
// 医嘱定义id集合
|
||||
List<Long> orderDefinitionIdParamList = organizationGroupPackageDetail.stream()
|
||||
.map(OrdersGroupPackageDetailQueryDto::getOrderDefinitionId).collect(Collectors.toList());
|
||||
// 医嘱下拉详细信息
|
||||
List<AdviceBaseDto> personalRecords =
|
||||
iDoctorStationAdviceAppService.getAdviceBaseInfo(null, null, null, orderDefinitionIdParamList,
|
||||
organizationId, 1, 100, Whether.NO.getValue(), List.of(1, 2, 3), null).getRecords();
|
||||
// 创建AdviceBaseDto的映射,以adviceDefinitionId为key
|
||||
Map<Long, AdviceBaseDto> adviceMap = personalRecords.stream().collect(Collectors
|
||||
.toMap(AdviceBaseDto::getAdviceDefinitionId, advice -> advice, (existing, replacement) -> existing // 如果有重复key,保留第一个
|
||||
));
|
||||
// 遍历personalGroupPackageDetail,进行匹配赋值
|
||||
for (OrdersGroupPackageDetailQueryDto detail : organizationGroupPackageDetail) {
|
||||
Long orderDefinitionId = detail.getOrderDefinitionId();
|
||||
if (orderDefinitionId != null) {
|
||||
AdviceBaseDto matchedAdvice = adviceMap.get(orderDefinitionId);
|
||||
if (matchedAdvice != null) {
|
||||
detail.setOrderDetailInfos(matchedAdvice);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 将明细数据按groupPackageId分组
|
||||
Map<Long, List<OrdersGroupPackageDetailQueryDto>> detailMap = organizationGroupPackageDetail.stream()
|
||||
.collect(Collectors.groupingBy(OrdersGroupPackageDetailQueryDto::getGroupPackageId));
|
||||
organizationList.forEach(dto -> {
|
||||
List<OrdersGroupPackageDetailQueryDto> details = detailMap.get(dto.getGroupPackageId());
|
||||
dto.setDetailList(details != null ? details : Collections.emptyList());
|
||||
});
|
||||
}
|
||||
ordersGroupPackageUseDto.setOrganizationList(organizationList);
|
||||
}
|
||||
|
||||
// 全院组套
|
||||
List<OrdersGroupPackageQueryDto> hospitalGroupPackage =
|
||||
ordersGroupPackageAppMapper.getGroupPackage(BindingType.HOSPITAL.getValue(), null, null, null, tcmFlag);
|
||||
if (!hospitalGroupPackage.isEmpty()) {
|
||||
List<OrdersGroupPackageDto> hospitalList = hospitalGroupPackage.stream().map(queryDto -> {
|
||||
OrdersGroupPackageDto dto = new OrdersGroupPackageDto();
|
||||
dto.setGroupPackageId(queryDto.getGroupPackageId());
|
||||
dto.setName(queryDto.getName());
|
||||
return dto;
|
||||
}).collect(Collectors.toList());
|
||||
List<Long> groupPackageIds =
|
||||
hospitalList.stream().map(OrdersGroupPackageDto::getGroupPackageId).collect(Collectors.toList());
|
||||
// 明细项
|
||||
List<OrdersGroupPackageDetailQueryDto> hospitalGroupPackageDetail =
|
||||
ordersGroupPackageAppMapper.getGroupPackageDetail(groupPackageIds);
|
||||
// 明细项赋值
|
||||
if (!hospitalGroupPackageDetail.isEmpty()) {
|
||||
// 医嘱定义id集合
|
||||
List<Long> orderDefinitionIdParamList = hospitalGroupPackageDetail.stream()
|
||||
.map(OrdersGroupPackageDetailQueryDto::getOrderDefinitionId).collect(Collectors.toList());
|
||||
// 医嘱下拉详细信息
|
||||
List<AdviceBaseDto> personalRecords =
|
||||
iDoctorStationAdviceAppService.getAdviceBaseInfo(null, null, null, orderDefinitionIdParamList,
|
||||
organizationId, 1, 100, Whether.NO.getValue(), List.of(1, 2, 3), null).getRecords();
|
||||
// 创建AdviceBaseDto的映射,以adviceDefinitionId为key
|
||||
Map<Long, AdviceBaseDto> adviceMap = personalRecords.stream().collect(Collectors
|
||||
.toMap(AdviceBaseDto::getAdviceDefinitionId, advice -> advice, (existing, replacement) -> existing // 如果有重复key,保留第一个
|
||||
));
|
||||
// 遍历personalGroupPackageDetail,进行匹配赋值
|
||||
for (OrdersGroupPackageDetailQueryDto detail : hospitalGroupPackageDetail) {
|
||||
Long orderDefinitionId = detail.getOrderDefinitionId();
|
||||
if (orderDefinitionId != null) {
|
||||
AdviceBaseDto matchedAdvice = adviceMap.get(orderDefinitionId);
|
||||
if (matchedAdvice != null) {
|
||||
detail.setOrderDetailInfos(matchedAdvice);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 将明细数据按groupPackageId分组
|
||||
Map<Long, List<OrdersGroupPackageDetailQueryDto>> detailMap = hospitalGroupPackageDetail.stream()
|
||||
.collect(Collectors.groupingBy(OrdersGroupPackageDetailQueryDto::getGroupPackageId));
|
||||
hospitalList.forEach(dto -> {
|
||||
List<OrdersGroupPackageDetailQueryDto> details = detailMap.get(dto.getGroupPackageId());
|
||||
dto.setDetailList(details != null ? details : Collections.emptyList());
|
||||
});
|
||||
}
|
||||
ordersGroupPackageUseDto.setHospitalList(hospitalList);
|
||||
}
|
||||
|
||||
return ordersGroupPackageUseDto;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -65,33 +65,39 @@ public class OrdersGroupPackageController {
|
||||
* 查询个人组套
|
||||
*
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param tcmFlag 中医标识:0-西医 1-中医
|
||||
* @return 个人组套
|
||||
*/
|
||||
@GetMapping(value = "/get-personal")
|
||||
public R<?> getPersonal(@RequestParam(value = "searchKey", defaultValue = "") String searchKey) {
|
||||
return R.ok(ordersGroupPackageAppService.getGroupPackage(BindingType.PERSONAL.getValue(), searchKey));
|
||||
public R<?> getPersonal(@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
|
||||
@RequestParam(value = "tcmFlag", defaultValue = "0") Integer tcmFlag) {
|
||||
return R.ok(ordersGroupPackageAppService.getGroupPackage(BindingType.PERSONAL.getValue(), searchKey, tcmFlag));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询科室组套
|
||||
*
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param tcmFlag 中医标识:0-西医 1-中医
|
||||
* @return 科室组套
|
||||
*/
|
||||
@GetMapping(value = "/get-organization")
|
||||
public R<?> getOrganization(@RequestParam(value = "searchKey", defaultValue = "") String searchKey) {
|
||||
return R.ok(ordersGroupPackageAppService.getGroupPackage(BindingType.ORGANIZATION.getValue(), searchKey));
|
||||
public R<?> getOrganization(@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
|
||||
@RequestParam(value = "tcmFlag", defaultValue = "0") Integer tcmFlag) {
|
||||
return R.ok(ordersGroupPackageAppService.getGroupPackage(BindingType.ORGANIZATION.getValue(), searchKey, tcmFlag));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询全院组套
|
||||
*
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param tcmFlag 中医标识:0-西医 1-中医
|
||||
* @return 全院组套
|
||||
*/
|
||||
@GetMapping(value = "/get-hospital")
|
||||
public R<?> getHospital(@RequestParam(value = "searchKey", defaultValue = "") String searchKey) {
|
||||
return R.ok(ordersGroupPackageAppService.getGroupPackage(BindingType.HOSPITAL.getValue(), searchKey));
|
||||
public R<?> getHospital(@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
|
||||
@RequestParam(value = "tcmFlag", defaultValue = "0") Integer tcmFlag) {
|
||||
return R.ok(ordersGroupPackageAppService.getGroupPackage(BindingType.HOSPITAL.getValue(), searchKey, tcmFlag));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,12 +126,13 @@ public class OrdersGroupPackageController {
|
||||
* 查询组合套餐,供开立医嘱使用
|
||||
*
|
||||
* @param organizationId 患者挂号对应的科室id
|
||||
* @param tcmFlag 中医标识:0-西医 1-中医,不传则不过滤
|
||||
* @return 组合套餐
|
||||
*/
|
||||
@GetMapping(value = "/group-package-for-order")
|
||||
public R<?>
|
||||
getGroupPackageForOrder(@RequestParam(value = "organizationId", defaultValue = "0") Long organizationId) {
|
||||
return R.ok(ordersGroupPackageAppService.getGroupPackageForOrder(organizationId));
|
||||
public R<?> getGroupPackageForOrder(@RequestParam(value = "organizationId", required = false) Long organizationId,
|
||||
@RequestParam(value = "tcmFlag", required = false) Integer tcmFlag) {
|
||||
return R.ok(ordersGroupPackageAppService.getGroupPackageForOrder(organizationId, tcmFlag));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -63,4 +63,9 @@ public class OrdersGroupPackageDetailSaveDto {
|
||||
*/
|
||||
private Long groupId;
|
||||
|
||||
/**
|
||||
* 治疗类型:1-长期 2-临时
|
||||
*/
|
||||
private Integer therapyEnum;
|
||||
|
||||
}
|
||||
|
||||
@@ -48,6 +48,11 @@ public class OrdersGroupPackageSaveDto {
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long practitionerId;
|
||||
|
||||
/**
|
||||
* 中医标识:0-西医 1-中医
|
||||
*/
|
||||
private Integer tcmFlag;
|
||||
|
||||
/**
|
||||
* 明细集合
|
||||
*/
|
||||
|
||||
@@ -26,11 +26,12 @@ public interface OrdersGroupPackageAppMapper {
|
||||
* @param organizationId 科室id
|
||||
* @param practitionerId 参与者id
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param tcmFlag 中医标识:0-西医 1-中医
|
||||
* @return 组合套餐
|
||||
*/
|
||||
List<OrdersGroupPackageQueryDto> getGroupPackage(@Param("packageTypeEnum") Integer packageTypeEnum,
|
||||
@Param("organizationId") Long organizationId, @Param("practitionerId") Long practitionerId,
|
||||
@Param("searchKey") String searchKey);
|
||||
@Param("searchKey") String searchKey, @Param("tcmFlag") Integer tcmFlag);
|
||||
|
||||
/**
|
||||
* 查询组合套餐明细
|
||||
|
||||
@@ -394,7 +394,7 @@ public class MedicalDeviceDispenseAppServiceImpl implements IMedicalDeviceDispen
|
||||
}
|
||||
List<ChargeItem> chargeItemList = chargeItemService.listByIds(chargeItemIds);
|
||||
if (chargeItemList == null || chargeItemList.isEmpty()) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
return R.fail("未查询到耗材收费项目信息");
|
||||
}
|
||||
|
||||
// 获取发申请id列表
|
||||
|
||||
@@ -236,6 +236,11 @@ public class WesternMedicineDispenseAppServiceImpl implements IWesternMedicineDi
|
||||
EnumUtils.getInfoByValue(DispenseStatus.class, medicineDispenseOrder.getStatusEnum()));
|
||||
// 设置所在表名
|
||||
medicineDispenseOrder.setItemTable(CommonConstants.TableName.MED_MEDICATION_DEFINITION);
|
||||
// 处方类型(发药类型:门诊/住院等)
|
||||
if (medicineDispenseOrder.getDispenseEnum() != null) {
|
||||
medicineDispenseOrder.setDispenseEnum_enumText(
|
||||
EnumUtils.getInfoByValue(EncounterClass.class, medicineDispenseOrder.getDispenseEnum()));
|
||||
}
|
||||
});
|
||||
return R.ok(medicineDispenseOrderPage);
|
||||
}
|
||||
|
||||
@@ -271,6 +271,12 @@ public class ItemDispenseOrderDto {
|
||||
private String medTypeCode;
|
||||
private String medTypeCode_dictText;
|
||||
|
||||
/**
|
||||
* 发药类型(处方类型:门诊/住院等)
|
||||
*/
|
||||
private Integer dispenseEnum;
|
||||
private String dispenseEnum_enumText;
|
||||
|
||||
/**
|
||||
* 输液标志
|
||||
*/
|
||||
|
||||
@@ -29,9 +29,12 @@ import com.openhis.web.regdoctorstation.appservice.IAdviceManageAppService;
|
||||
import com.openhis.web.regdoctorstation.dto.*;
|
||||
import com.openhis.web.regdoctorstation.mapper.AdviceManageAppMapper;
|
||||
import com.openhis.web.regdoctorstation.utils.RegPrescriptionUtils;
|
||||
import com.openhis.workflow.domain.ActivityDefinition;
|
||||
import com.openhis.workflow.domain.DeviceRequest;
|
||||
import com.openhis.workflow.domain.ServiceRequest;
|
||||
import com.openhis.workflow.service.IActivityDefinitionService;
|
||||
import com.openhis.workflow.domain.ActivityDefinition;
|
||||
import com.openhis.workflow.service.IDeviceDispenseService;
|
||||
import com.openhis.workflow.service.IDeviceRequestService;
|
||||
import com.openhis.workflow.service.IServiceRequestService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -76,6 +79,12 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService {
|
||||
@Resource
|
||||
IActivityDefinitionService iActivityDefinitionService;
|
||||
|
||||
@Resource
|
||||
IDeviceRequestService iDeviceRequestService;
|
||||
|
||||
@Resource
|
||||
IDeviceDispenseService iDeviceDispenseService;
|
||||
|
||||
/**
|
||||
* 查询住院患者信息
|
||||
*
|
||||
@@ -167,12 +176,16 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService {
|
||||
Long organizationId = regAdviceSaveParam.getOrganizationId();
|
||||
// 医嘱分类信息
|
||||
List<RegAdviceSaveDto> regAdviceSaveList = regAdviceSaveParam.getRegAdviceSaveList();
|
||||
|
||||
// 药品
|
||||
List<RegAdviceSaveDto> medicineList = regAdviceSaveList.stream()
|
||||
.filter(e -> ItemType.MEDICINE.getValue().equals(e.getAdviceType())).collect(Collectors.toList());
|
||||
// 诊疗活动
|
||||
List<RegAdviceSaveDto> activityList = regAdviceSaveList.stream()
|
||||
.filter(e -> ItemType.ACTIVITY.getValue().equals(e.getAdviceType())).collect(Collectors.toList());
|
||||
// 耗材 🔧 Bug #147 修复
|
||||
List<RegAdviceSaveDto> deviceList = regAdviceSaveList.stream()
|
||||
.filter(e -> ItemType.DEVICE.getValue().equals(e.getAdviceType())).collect(Collectors.toList());
|
||||
|
||||
// 保存时,校验临时医嘱库存
|
||||
if (AdviceOpType.SAVE_ADVICE.getCode().equals(adviceOpType)) {
|
||||
@@ -209,6 +222,11 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService {
|
||||
*/
|
||||
this.handService(activityList, startTime, authoredTime, curDate, adviceOpType, organizationId, signCode);
|
||||
|
||||
/**
|
||||
* 🔧 Bug #147 修复:处理耗材请求
|
||||
*/
|
||||
this.handDevice(deviceList, startTime, authoredTime, curDate, adviceOpType, organizationId, signCode);
|
||||
|
||||
// 签发时,把草稿状态的账单更新为待收费
|
||||
if (AdviceOpType.SIGN_ADVICE.getCode().equals(adviceOpType) && !regAdviceSaveList.isEmpty()) {
|
||||
// 签发的医嘱id集合
|
||||
@@ -593,6 +611,150 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 🔧 Bug #147 修复:处理耗材
|
||||
*/
|
||||
private void handDevice(List<RegAdviceSaveDto> deviceList, Date startTime, Date authoredTime, Date curDate,
|
||||
String adviceOpType, Long organizationId, String signCode) {
|
||||
// 当前登录账号的科室id
|
||||
Long orgId = SecurityUtils.getLoginUser().getOrgId();
|
||||
// 获取当前登录用户的tenantId
|
||||
Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
|
||||
// 保存操作
|
||||
boolean is_save = AdviceOpType.SAVE_ADVICE.getCode().equals(adviceOpType);
|
||||
// 签发操作
|
||||
boolean is_sign = AdviceOpType.SIGN_ADVICE.getCode().equals(adviceOpType);
|
||||
|
||||
// 删除
|
||||
List<RegAdviceSaveDto> deleteList = deviceList.stream()
|
||||
.filter(e -> DbOpType.DELETE.getCode().equals(e.getDbOpType())).collect(Collectors.toList());
|
||||
for (RegAdviceSaveDto regAdviceSaveDto : deleteList) {
|
||||
iDeviceRequestService.removeById(regAdviceSaveDto.getRequestId());
|
||||
// 删除已经产生的耗材发放信息
|
||||
iDeviceDispenseService.deleteDeviceDispense(regAdviceSaveDto.getRequestId());
|
||||
// 删除费用项
|
||||
iChargeItemService.deleteByServiceTableAndId(CommonConstants.TableName.WOR_DEVICE_REQUEST,
|
||||
regAdviceSaveDto.getRequestId());
|
||||
}
|
||||
|
||||
// 声明耗材请求
|
||||
DeviceRequest deviceRequest;
|
||||
// 声明费用项
|
||||
ChargeItem chargeItem;
|
||||
|
||||
// 新增 + 修改 (长期医嘱)
|
||||
List<RegAdviceSaveDto> longInsertOrUpdateList = deviceList.stream().filter(e -> TherapyTimeType.LONG_TERM
|
||||
.getValue().equals(e.getTherapyEnum())
|
||||
&& (DbOpType.INSERT.getCode().equals(e.getDbOpType()) || DbOpType.UPDATE.getCode().equals(e.getDbOpType())))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (RegAdviceSaveDto regAdviceSaveDto : longInsertOrUpdateList) {
|
||||
deviceRequest = new DeviceRequest();
|
||||
deviceRequest.setId(regAdviceSaveDto.getRequestId()); // 主键id
|
||||
deviceRequest.setStatusEnum(is_save ? RequestStatus.DRAFT.getValue() : RequestStatus.ACTIVE.getValue()); // 请求状态
|
||||
deviceRequest.setTenantId(SecurityUtils.getLoginUser().getTenantId()); // 显式设置租户ID
|
||||
if (is_sign) {
|
||||
deviceRequest.setReqAuthoredTime(authoredTime); // 医嘱签发时间
|
||||
}
|
||||
// 保存时处理的字段属性
|
||||
if (is_save) {
|
||||
deviceRequest.setBusNo(assignSeqUtil.getSeqByDay(AssignSeqEnum.DEVICE_RES_NO.getPrefix(), 4));
|
||||
deviceRequest.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue()); // 生成来源
|
||||
deviceRequest.setQuantity(regAdviceSaveDto.getQuantity()); // 请求数量
|
||||
deviceRequest.setUnitCode(regAdviceSaveDto.getUnitCode()); // 请求单位编码
|
||||
deviceRequest.setLotNumber(regAdviceSaveDto.getLotNumber()); // 产品批号
|
||||
deviceRequest.setCategoryEnum(regAdviceSaveDto.getCategoryEnum()); // 请求类型
|
||||
deviceRequest.setDeviceDefId(regAdviceSaveDto.getAdviceDefinitionId());// 耗材定义id
|
||||
deviceRequest.setPatientId(regAdviceSaveDto.getPatientId()); // 患者
|
||||
deviceRequest.setRequesterId(regAdviceSaveDto.getPractitionerId()); // 开方医生
|
||||
deviceRequest.setOrgId(regAdviceSaveDto.getFounderOrgId()); // 开方人科室
|
||||
deviceRequest.setReqAuthoredTime(startTime); // 医嘱开始时间
|
||||
deviceRequest.setPerformLocation(regAdviceSaveDto.getLocationId()); // 发放科室
|
||||
deviceRequest.setEncounterId(regAdviceSaveDto.getEncounterId()); // 就诊id
|
||||
deviceRequest.setPackageId(regAdviceSaveDto.getPackageId()); // 组套id
|
||||
deviceRequest.setContentJson(regAdviceSaveDto.getContentJson()); // 请求内容json
|
||||
deviceRequest.setYbClassEnum(regAdviceSaveDto.getYbClassEnum());// 类别医保编码
|
||||
deviceRequest.setConditionId(regAdviceSaveDto.getConditionId()); // 诊断id
|
||||
deviceRequest.setEncounterDiagnosisId(regAdviceSaveDto.getEncounterDiagnosisId()); // 就诊诊断id
|
||||
}
|
||||
iDeviceRequestService.saveOrUpdate(deviceRequest);
|
||||
}
|
||||
|
||||
// 新增 + 修改 (临时医嘱)
|
||||
List<RegAdviceSaveDto> tempInsertOrUpdateList = deviceList.stream().filter(e -> TherapyTimeType.TEMPORARY
|
||||
.getValue().equals(e.getTherapyEnum())
|
||||
&& (DbOpType.INSERT.getCode().equals(e.getDbOpType()) || DbOpType.UPDATE.getCode().equals(e.getDbOpType())))
|
||||
.collect(Collectors.toList());
|
||||
for (RegAdviceSaveDto regAdviceSaveDto : tempInsertOrUpdateList) {
|
||||
deviceRequest = new DeviceRequest();
|
||||
deviceRequest.setId(regAdviceSaveDto.getRequestId()); // 主键id
|
||||
deviceRequest.setStatusEnum(is_save ? RequestStatus.DRAFT.getValue() : RequestStatus.ACTIVE.getValue()); // 请求状态
|
||||
deviceRequest.setTenantId(SecurityUtils.getLoginUser().getTenantId()); // 显式设置租户ID
|
||||
if (is_sign) {
|
||||
deviceRequest.setReqAuthoredTime(authoredTime); // 医嘱签发时间
|
||||
}
|
||||
// 保存时处理的字段属性
|
||||
if (is_save) {
|
||||
deviceRequest.setBusNo(assignSeqUtil.getSeqByDay(AssignSeqEnum.DEVICE_RES_NO.getPrefix(), 4));
|
||||
deviceRequest.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue()); // 生成来源
|
||||
deviceRequest.setQuantity(regAdviceSaveDto.getQuantity()); // 请求数量
|
||||
deviceRequest.setUnitCode(regAdviceSaveDto.getUnitCode()); // 请求单位编码
|
||||
deviceRequest.setLotNumber(regAdviceSaveDto.getLotNumber()); // 产品批号
|
||||
deviceRequest.setCategoryEnum(regAdviceSaveDto.getCategoryEnum()); // 请求类型
|
||||
deviceRequest.setDeviceDefId(regAdviceSaveDto.getAdviceDefinitionId());// 耗材定义id
|
||||
deviceRequest.setPatientId(regAdviceSaveDto.getPatientId()); // 患者
|
||||
deviceRequest.setRequesterId(regAdviceSaveDto.getPractitionerId()); // 开方医生
|
||||
deviceRequest.setOrgId(regAdviceSaveDto.getFounderOrgId()); // 开方人科室
|
||||
deviceRequest.setReqAuthoredTime(startTime); // 医嘱开始时间
|
||||
deviceRequest.setPerformLocation(regAdviceSaveDto.getLocationId()); // 发放科室
|
||||
deviceRequest.setEncounterId(regAdviceSaveDto.getEncounterId()); // 就诊id
|
||||
deviceRequest.setPackageId(regAdviceSaveDto.getPackageId()); // 组套id
|
||||
deviceRequest.setContentJson(regAdviceSaveDto.getContentJson()); // 请求内容json
|
||||
deviceRequest.setYbClassEnum(regAdviceSaveDto.getYbClassEnum());// 类别医保编码
|
||||
deviceRequest.setConditionId(regAdviceSaveDto.getConditionId()); // 诊断id
|
||||
deviceRequest.setEncounterDiagnosisId(regAdviceSaveDto.getEncounterDiagnosisId()); // 就诊诊断id
|
||||
}
|
||||
iDeviceRequestService.saveOrUpdate(deviceRequest);
|
||||
|
||||
// 保存时,保存耗材费用项
|
||||
if (is_save) {
|
||||
// 处理耗材发放
|
||||
Long dispenseId = iDeviceDispenseService.handleDeviceDispense(deviceRequest,
|
||||
regAdviceSaveDto.getDbOpType());
|
||||
|
||||
// 保存耗材费用项
|
||||
chargeItem = new ChargeItem();
|
||||
chargeItem.setId(regAdviceSaveDto.getChargeItemId()); // 费用项id
|
||||
chargeItem.setStatusEnum(ChargeItemStatus.DRAFT.getValue()); // 收费状态
|
||||
chargeItem.setBusNo(AssignSeqEnum.CHARGE_ITEM_NO.getPrefix().concat(deviceRequest.getBusNo()));
|
||||
chargeItem.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue()); // 生成来源
|
||||
chargeItem.setPatientId(regAdviceSaveDto.getPatientId()); // 患者
|
||||
chargeItem.setContextEnum(regAdviceSaveDto.getAdviceType()); // 类型
|
||||
chargeItem.setEncounterId(regAdviceSaveDto.getEncounterId()); // 就诊id
|
||||
chargeItem.setDefinitionId(regAdviceSaveDto.getDefinitionId()); // 费用定价ID
|
||||
chargeItem.setDefDetailId(regAdviceSaveDto.getDefinitionDetailId()); // 定价子表主键
|
||||
chargeItem.setEntererId(regAdviceSaveDto.getPractitionerId());// 开立人ID
|
||||
chargeItem.setEnteredDate(curDate); // 开立时间
|
||||
chargeItem.setServiceTable(CommonConstants.TableName.WOR_DEVICE_REQUEST);// 医疗服务类型
|
||||
chargeItem.setServiceId(deviceRequest.getId()); // 医疗服务ID
|
||||
chargeItem.setProductTable(regAdviceSaveDto.getAdviceTableName());// 产品所在表
|
||||
chargeItem.setProductId(regAdviceSaveDto.getAdviceDefinitionId());// 收费项id
|
||||
chargeItem.setAccountId(regAdviceSaveDto.getAccountId());// 关联账户ID
|
||||
chargeItem.setRequestingOrgId(orgId); // 开立科室
|
||||
chargeItem.setConditionId(regAdviceSaveDto.getConditionId()); // 诊断id
|
||||
chargeItem.setEncounterDiagnosisId(regAdviceSaveDto.getEncounterDiagnosisId()); // 就诊诊断id
|
||||
chargeItem.setDispenseId(dispenseId); // 发放ID
|
||||
|
||||
chargeItem.setQuantityValue(regAdviceSaveDto.getQuantity()); // 数量
|
||||
chargeItem.setQuantityUnit(regAdviceSaveDto.getUnitCode()); // 单位
|
||||
chargeItem.setUnitPrice(regAdviceSaveDto.getUnitPrice()); // 单价
|
||||
chargeItem.setTotalPrice(regAdviceSaveDto.getTotalPrice()); // 总价
|
||||
|
||||
iChargeItemService.saveOrUpdate(chargeItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询住院医嘱请求数据
|
||||
*
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.core.common.exception.ServiceException;
|
||||
import com.core.common.utils.AssignSeqUtil;
|
||||
import com.core.common.utils.MessageUtils;
|
||||
import com.core.common.utils.SecurityUtils;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.openhis.administration.domain.ChargeItem;
|
||||
import com.openhis.administration.service.IChargeItemService;
|
||||
import com.openhis.common.constant.CommonConstants;
|
||||
@@ -28,8 +29,10 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -132,6 +135,7 @@ public class RequestFormManageAppServiceImpl implements IRequestFormManageAppSer
|
||||
ChargeItem chargeItem;
|
||||
// 诊疗集合
|
||||
List<ActivitySaveDto> activityList = requestFormSaveDto.getActivityList();
|
||||
log.info("保存申请单,typeCode={}, activityListSize={}, encounterId={}", typeCode, activityList != null ? activityList.size() : 0, encounterId);
|
||||
// 诊疗执行科室配置
|
||||
List<ActivityOrganizationConfigDto> activityOrganizationConfig =
|
||||
requestFormManageAppMapper.getActivityOrganizationConfig(typeCode);
|
||||
@@ -211,6 +215,189 @@ public class RequestFormManageAppServiceImpl implements IRequestFormManageAppSer
|
||||
}
|
||||
}
|
||||
|
||||
// 如果是手术申请单,需要额外生成手术医嘱
|
||||
log.info("【调试】判断手术医嘱生成条件: typeCode={}, PROCEDURE.code={}, typeCode类型={}, PROCEDURE.code类型={}",
|
||||
typeCode, ActivityDefCategory.PROCEDURE.getCode(),
|
||||
typeCode != null ? typeCode.getClass().getName() : "null",
|
||||
ActivityDefCategory.PROCEDURE.getCode().getClass().getName());
|
||||
boolean isProcedure = ActivityDefCategory.PROCEDURE.getCode().equals(typeCode);
|
||||
log.info("【调试】判断结果: isProcedure={}, typeCode字符串={}, PROCEDURE.code字符串={}",
|
||||
isProcedure,
|
||||
typeCode != null ? "'" + typeCode + "'" : "null",
|
||||
"'" + ActivityDefCategory.PROCEDURE.getCode() + "'");
|
||||
if (isProcedure) {
|
||||
log.info("开始生成手术医嘱,encounterId={}, patientId={}, typeCode={}, activityListSize={}",
|
||||
encounterId, patientId, typeCode, activityList != null ? activityList.size() : 0);
|
||||
try {
|
||||
// 从 descJson 中解析手术信息
|
||||
String descJson = requestFormSaveDto.getDescJson();
|
||||
Map<String, Object> descMap = null;
|
||||
if (descJson != null && !descJson.isEmpty()) {
|
||||
try {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
descMap = objectMapper.readValue(descJson, Map.class);
|
||||
log.info("解析手术申请单 descJson 成功: {}", descMap);
|
||||
} catch (Exception e) {
|
||||
log.error("解析手术申请单 descJson 失败: {}", descJson, e);
|
||||
}
|
||||
} else {
|
||||
log.warn("手术申请单 descJson 为空");
|
||||
}
|
||||
|
||||
// 获取手术信息
|
||||
String surgeryName = descMap != null ? (String) descMap.get("surgeryName") : null;
|
||||
String surgeryCode = descMap != null ? (String) descMap.get("surgeryCode") : null;
|
||||
String surgeryFee = descMap != null ? (String) descMap.get("surgeryFee") : null;
|
||||
String anesthesiaFee = descMap != null ? (String) descMap.get("anesthesiaFee") : null;
|
||||
String plannedTime = descMap != null ? (String) descMap.get("plannedTime") : null;
|
||||
String surgeryIndication = descMap != null ? (String) descMap.get("surgeryIndication") : null;
|
||||
String preoperativeDiagnosis = descMap != null ? (String) descMap.get("preoperativeDiagnosis") : null;
|
||||
|
||||
// 🔧 BugFix#318: 从 activityList 获取手术项目名称
|
||||
String adviceDefinitionName = null;
|
||||
if (activityList != null && !activityList.isEmpty()) {
|
||||
adviceDefinitionName = activityList.get(0).getAdviceDefinitionName();
|
||||
log.info("从 activityList 获取手术项目名称: {}", adviceDefinitionName);
|
||||
}
|
||||
|
||||
log.info("手术信息: surgeryName={}, surgeryCode={}, surgeryFee={}, anesthesiaFee={}, adviceDefinitionName={}",
|
||||
surgeryName, surgeryCode, surgeryFee, anesthesiaFee, adviceDefinitionName);
|
||||
|
||||
// 生成手术医嘱
|
||||
ServiceRequest surgeryServiceRequest = new ServiceRequest();
|
||||
surgeryServiceRequest.setStatusEnum(RequestStatus.DRAFT.getValue());
|
||||
surgeryServiceRequest.setBusNo(String.format("%04d", (int) (Math.random() * 10000)));
|
||||
surgeryServiceRequest.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue());
|
||||
surgeryServiceRequest.setPrescriptionNo(prescriptionNo);
|
||||
surgeryServiceRequest.setTherapyEnum(TherapyTimeType.TEMPORARY.getValue());
|
||||
surgeryServiceRequest.setQuantity(BigDecimal.valueOf(1));
|
||||
surgeryServiceRequest.setUnitCode("次");
|
||||
surgeryServiceRequest.setCategoryEnum(4); // 4-手术
|
||||
// 优先从 activityList 获取手术 ID
|
||||
if (activityList != null && !activityList.isEmpty()) {
|
||||
Long activityId = activityList.get(0).getAdviceDefinitionId();
|
||||
surgeryServiceRequest.setActivityId(activityId);
|
||||
log.info("从 activityList 获取手术ID: {}", activityId);
|
||||
} else {
|
||||
log.warn("activityList 为空,无法获取手术ID");
|
||||
}
|
||||
surgeryServiceRequest.setPatientId(patientId);
|
||||
surgeryServiceRequest.setRequesterId(practitionerId);
|
||||
surgeryServiceRequest.setEncounterId(encounterId);
|
||||
surgeryServiceRequest.setAuthoredTime(curDate);
|
||||
surgeryServiceRequest.setOrgId(orgId);
|
||||
|
||||
// 设置手术相关信息到 contentJson 字段
|
||||
Map<String, String> contentMap = new java.util.HashMap<>();
|
||||
// 🔧 BugFix#318: 优先使用 activityList 中的手术项目名称
|
||||
if (adviceDefinitionName != null && !adviceDefinitionName.isEmpty()) {
|
||||
contentMap.put("surgeryName", adviceDefinitionName);
|
||||
} else if (surgeryName != null && !surgeryName.isEmpty()) {
|
||||
contentMap.put("surgeryName", surgeryName);
|
||||
}
|
||||
if (surgeryCode != null && !surgeryCode.isEmpty()) {
|
||||
contentMap.put("surgeryCode", surgeryCode);
|
||||
}
|
||||
if (plannedTime != null && !plannedTime.isEmpty()) {
|
||||
contentMap.put("plannedTime", plannedTime);
|
||||
}
|
||||
if (surgeryIndication != null && !surgeryIndication.isEmpty()) {
|
||||
contentMap.put("surgeryIndication", surgeryIndication);
|
||||
}
|
||||
if (preoperativeDiagnosis != null && !preoperativeDiagnosis.isEmpty()) {
|
||||
contentMap.put("preoperativeDiagnosis", preoperativeDiagnosis);
|
||||
}
|
||||
if (!contentMap.isEmpty()) {
|
||||
try {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
surgeryServiceRequest.setContentJson(objectMapper.writeValueAsString(contentMap));
|
||||
} catch (Exception e) {
|
||||
log.error("序列化手术信息失败", e);
|
||||
}
|
||||
}
|
||||
try {
|
||||
iServiceRequestService.save(surgeryServiceRequest);
|
||||
log.info("手术医嘱生成成功,serviceRequestId={}, prescriptionNo={}", surgeryServiceRequest.getId(), prescriptionNo);
|
||||
} catch (Exception e) {
|
||||
log.error("保存手术医嘱失败", e);
|
||||
throw new ServiceException("保存手术医嘱失败: " + e.getMessage());
|
||||
}
|
||||
|
||||
// 生成手术收费项目
|
||||
try {
|
||||
ChargeItem surgeryChargeItem = new ChargeItem();
|
||||
surgeryChargeItem.setStatusEnum(ChargeItemStatus.DRAFT.getValue());
|
||||
surgeryChargeItem.setBusNo(AssignSeqEnum.CHARGE_ITEM_NO.getPrefix().concat(surgeryServiceRequest.getBusNo()));
|
||||
surgeryChargeItem.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue());
|
||||
surgeryChargeItem.setPatientId(patientId);
|
||||
surgeryChargeItem.setContextEnum(6); // 6-手术
|
||||
surgeryChargeItem.setEncounterId(encounterId);
|
||||
surgeryChargeItem.setEntererId(practitionerId);
|
||||
surgeryChargeItem.setEnteredDate(curDate);
|
||||
surgeryChargeItem.setServiceTable(CommonConstants.TableName.WOR_SERVICE_REQUEST);
|
||||
surgeryChargeItem.setServiceId(surgeryServiceRequest.getId());
|
||||
surgeryChargeItem.setProductTable(CommonConstants.TableName.WOR_ACTIVITY_DEFINITION);
|
||||
// 优先从 activityList 获取 productId
|
||||
if (activityList != null && !activityList.isEmpty()) {
|
||||
surgeryChargeItem.setProductId(activityList.get(0).getAdviceDefinitionId());
|
||||
surgeryChargeItem.setAccountId(activityList.get(0).getAccountId());
|
||||
}
|
||||
surgeryChargeItem.setRequestingOrgId(orgId);
|
||||
surgeryChargeItem.setQuantityValue(BigDecimal.valueOf(1));
|
||||
surgeryChargeItem.setQuantityUnit("次");
|
||||
// 设置手术费用
|
||||
if (surgeryFee != null && !surgeryFee.isEmpty()) {
|
||||
try {
|
||||
surgeryChargeItem.setUnitPrice(new BigDecimal(surgeryFee));
|
||||
surgeryChargeItem.setTotalPrice(new BigDecimal(surgeryFee));
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("手术费用格式不正确:{}", surgeryFee);
|
||||
}
|
||||
}
|
||||
iChargeItemService.save(surgeryChargeItem);
|
||||
log.info("手术收费项目生成成功,chargeItemId={}", surgeryChargeItem.getId());
|
||||
} catch (Exception e) {
|
||||
log.error("生成手术收费项目失败", e);
|
||||
throw new ServiceException("生成手术收费项目失败: " + e.getMessage());
|
||||
}
|
||||
|
||||
// 如果存在麻醉费用,生成麻醉收费项目
|
||||
if (anesthesiaFee != null && !anesthesiaFee.isEmpty()) {
|
||||
try {
|
||||
BigDecimal anesthesiaFeeAmount = new BigDecimal(anesthesiaFee);
|
||||
if (anesthesiaFeeAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
ChargeItem anesthesiaChargeItem = new ChargeItem();
|
||||
anesthesiaChargeItem.setStatusEnum(ChargeItemStatus.DRAFT.getValue());
|
||||
anesthesiaChargeItem.setBusNo(AssignSeqEnum.CHARGE_ITEM_NO.getPrefix().concat(surgeryServiceRequest.getBusNo()));
|
||||
anesthesiaChargeItem.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue());
|
||||
anesthesiaChargeItem.setPatientId(patientId);
|
||||
anesthesiaChargeItem.setContextEnum(3); // 3-诊疗
|
||||
anesthesiaChargeItem.setEncounterId(encounterId);
|
||||
anesthesiaChargeItem.setEntererId(practitionerId);
|
||||
anesthesiaChargeItem.setEnteredDate(curDate);
|
||||
anesthesiaChargeItem.setServiceTable(CommonConstants.TableName.WOR_SERVICE_REQUEST);
|
||||
anesthesiaChargeItem.setServiceId(surgeryServiceRequest.getId());
|
||||
anesthesiaChargeItem.setProductTable(CommonConstants.TableName.WOR_ACTIVITY_DEFINITION);
|
||||
anesthesiaChargeItem.setRequestingOrgId(orgId);
|
||||
anesthesiaChargeItem.setQuantityValue(BigDecimal.valueOf(1));
|
||||
anesthesiaChargeItem.setQuantityUnit("次");
|
||||
anesthesiaChargeItem.setUnitPrice(anesthesiaFeeAmount);
|
||||
anesthesiaChargeItem.setTotalPrice(anesthesiaFeeAmount);
|
||||
iChargeItemService.save(anesthesiaChargeItem);
|
||||
log.info("麻醉收费项目生成成功");
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("麻醉费用格式不正确:{}", anesthesiaFee);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("生成手术医嘱过程中发生异常", e);
|
||||
throw e;
|
||||
}
|
||||
} else {
|
||||
log.info("不是手术申请单,跳过手术医嘱生成,typeCode={}", typeCode);
|
||||
}
|
||||
|
||||
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[] {"申请单"}));
|
||||
}
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ public class SpecialAdviceAppServiceImpl implements ISpecialAdviceAppService {
|
||||
adviceBaseDto.setAdviceDefinitionId(definitionId); // 医嘱定义id
|
||||
// 对应的诊疗医嘱信息
|
||||
activityAdviceBaseDto = iDoctorStationAdviceAppService.getAdviceBaseInfo(adviceBaseDto, null, null,
|
||||
null, null, 1, 1, Whether.NO.getValue(), List.of(3), null).getRecords().get(0);
|
||||
null, null, 1, 1, Whether.NO.getValue(), List.of(3), null, null).getRecords().get(0);
|
||||
// 逻辑1---------------------直接新增
|
||||
longServiceRequest.setStatusEnum(RequestStatus.DRAFT.getValue());// 请求状态
|
||||
longServiceRequest.setOccurrenceStartTime(startTime); // 医嘱开始时间
|
||||
@@ -208,7 +208,7 @@ public class SpecialAdviceAppServiceImpl implements ISpecialAdviceAppService {
|
||||
adviceBaseDto.setAdviceDefinitionId(definitionId); // 医嘱定义id
|
||||
// 对应的诊疗医嘱信息
|
||||
activityAdviceBaseDto = iDoctorStationAdviceAppService
|
||||
.getAdviceBaseInfo(adviceBaseDto, null, null, null, null, 1, 1, Whether.NO.getValue(), List.of(3), null)
|
||||
.getAdviceBaseInfo(adviceBaseDto, null, null, null, null, 1, 1, Whether.NO.getValue(), List.of(3), null, null)
|
||||
.getRecords().get(0);
|
||||
|
||||
longServiceRequest.setStatusEnum(RequestStatus.DRAFT.getValue());// 请求状态
|
||||
@@ -348,7 +348,7 @@ public class SpecialAdviceAppServiceImpl implements ISpecialAdviceAppService {
|
||||
adviceBaseDto.setAdviceDefinitionId(transferOrganizationDefinitionId); // 医嘱定义id
|
||||
// 转科的医嘱信息
|
||||
AdviceBaseDto activityAdviceBaseDto = iDoctorStationAdviceAppService
|
||||
.getAdviceBaseInfo(adviceBaseDto, null, null, null, null, 1, 1, Whether.NO.getValue(), List.of(3), null)
|
||||
.getAdviceBaseInfo(adviceBaseDto, null, null, null, null, 1, 1, Whether.NO.getValue(), List.of(3), null, null)
|
||||
.getRecords().get(0);
|
||||
// 保存转科医嘱请求
|
||||
ServiceRequest serviceRequest = new ServiceRequest();
|
||||
@@ -430,7 +430,7 @@ public class SpecialAdviceAppServiceImpl implements ISpecialAdviceAppService {
|
||||
|
||||
// 出院的医嘱信息
|
||||
AdviceBaseDto activityAdviceBaseDto = iDoctorStationAdviceAppService.getAdviceBaseInfo(null, null, null,
|
||||
List.of(transferOrganizationDefinitionId), null, 1, 1, Whether.NO.getValue(), List.of(3), null).getRecords()
|
||||
List.of(transferOrganizationDefinitionId), null, 1, 1, Whether.NO.getValue(), List.of(3), null, null).getRecords()
|
||||
.get(0);
|
||||
// 保存出院医嘱请求
|
||||
ServiceRequest serviceRequest = new ServiceRequest();
|
||||
|
||||
@@ -72,6 +72,7 @@ public class RequestFormManageController {
|
||||
*/
|
||||
@PostMapping(value = "/save-surgery")
|
||||
public R<?> saveSurgeryRequestForm(@RequestBody RequestFormSaveDto requestFormSaveDto) {
|
||||
log.info("【Controller】保存手术申请单,typeCode={}", ActivityDefCategory.PROCEDURE.getCode());
|
||||
return iRequestFormManageAppService.saveRequestForm(requestFormSaveDto,
|
||||
ActivityDefCategory.PROCEDURE.getCode());
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user