258 预约管理-》医生排班管理:点【预约设置】界面编辑内容【确定】提示”保存成功“但是刷新重新进入未显示最后一次更新的数据

This commit is contained in:
HuangXinQuan
2026-03-27 15:42:26 +08:00
parent 112ec2e4a3
commit e2e5999276
15 changed files with 419 additions and 38 deletions

View File

@@ -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);
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -0,0 +1,45 @@
package com.openhis.appointmentmanage.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
/**
* 预约配置Entity
*
* @date 2026-03-23
*/
@Data
@TableName(value = "appointment_config")
@Accessors(chain = true)
public class AppointmentConfig {
/** 主键ID */
@TableId(type = IdType.AUTO)
private Long id;
/** 机构ID关联 sys_tenant */
private Integer tenantId;
/** 取消预约时间类型YEAR/MONTH/DAY */
private String cancelAppointmentType;
/** 取消预约次数限制 */
private Integer cancelAppointmentCount;
/** 有效标志1=有效0=无效 */
private Integer validFlag;
/** 创建人 */
private String createBy;
/** 创建时间 */
private LocalDateTime createTime;
/** 更新时间 */
private LocalDateTime updateTime;
}

View File

@@ -0,0 +1,15 @@
package com.openhis.appointmentmanage.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.openhis.appointmentmanage.domain.AppointmentConfig;
import org.apache.ibatis.annotations.Mapper;
/**
* 预约配置Mapper接口
*
* @author openhis
* @date 2026-03-23
*/
@Mapper
public interface AppointmentConfigMapper extends BaseMapper<AppointmentConfig> {
}

View File

@@ -0,0 +1,29 @@
package com.openhis.appointmentmanage.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.openhis.appointmentmanage.domain.AppointmentConfig;
/**
* 预约配置Service接口
*
* @author openhis
* @date 2026-03-23
*/
public interface IAppointmentConfigService extends IService<AppointmentConfig> {
/**
* 根据机构ID获取预约配置
*
* @param tenantId 机构ID
* @return 预约配置
*/
AppointmentConfig getConfigByTenantId(Integer tenantId);
/**
* 保存或更新预约配置
*
* @param appointmentConfig 预约配置
* @return 结果
*/
int saveOrUpdateConfig(AppointmentConfig appointmentConfig);
}

View File

@@ -0,0 +1,44 @@
package com.openhis.appointmentmanage.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.openhis.appointmentmanage.domain.AppointmentConfig;
import com.openhis.appointmentmanage.mapper.AppointmentConfigMapper;
import com.openhis.appointmentmanage.service.IAppointmentConfigService;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
/**
* 预约配置Service实现类
*
* @author openhis
* @date 2026-03-23
*/
@Service
public class AppointmentConfigServiceImpl
extends ServiceImpl<AppointmentConfigMapper, AppointmentConfig>
implements IAppointmentConfigService {
@Override
public AppointmentConfig getConfigByTenantId(Integer tenantId) {
LambdaQueryWrapper<AppointmentConfig> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(AppointmentConfig::getTenantId, tenantId)
.eq(AppointmentConfig::getValidFlag, 1);
return this.getOne(wrapper);
}
@Override
public int saveOrUpdateConfig(AppointmentConfig appointmentConfig) {
if (appointmentConfig.getId() == null) {
// 新增
appointmentConfig.setCreateTime(LocalDateTime.now());
appointmentConfig.setUpdateTime(LocalDateTime.now());
return this.baseMapper.insert(appointmentConfig) > 0 ? 1 : 0;
} else {
// 更新
appointmentConfig.setUpdateTime(LocalDateTime.now());
return this.baseMapper.updateById(appointmentConfig) > 0 ? 1 : 0;
}
}
}

View File

@@ -33,4 +33,14 @@ public interface IOrderService extends IService<Order> {
Order createAppointmentOrder(Map<String, Object> params);
int cancelAppointmentOrder(Long orderId, String cancelReason);
/**
* 统计患者在指定机构、指定起始时间后的取消预约次数
*
* @param patientId 患者ID
* @param tenantId 机构ID
* @param startTime 起始时间
* @return 取消次数
*/
long countPatientCancellations(Long patientId, Integer tenantId, java.time.LocalDateTime startTime);
}

View File

@@ -178,4 +178,16 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
Date cancelTime = new Date();
return orderMapper.updateOrderCancelInfoById(orderId, cancelTime, cancelReason);
}
@Override
public long countPatientCancellations(Long patientId, Integer tenantId, java.time.LocalDateTime startTime) {
if (patientId == null || tenantId == null || startTime == null) {
return 0;
}
return this.count(new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Order>()
.eq(Order::getPatientId, patientId)
.eq(Order::getTenantId, tenantId)
.ge(Order::getCancelTime, startTime)
.eq(Order::getStatus, AppointmentOrderStatus.CANCELLED));
}
}

View File

@@ -2,6 +2,8 @@ package com.openhis.clinical.service.impl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.openhis.appointmentmanage.domain.AppointmentConfig;
import com.openhis.appointmentmanage.service.IAppointmentConfigService;
import com.openhis.appointmentmanage.domain.TicketSlotDTO;
import com.openhis.appointmentmanage.mapper.SchedulePoolMapper;
import com.openhis.appointmentmanage.mapper.ScheduleSlotMapper;
@@ -23,6 +25,7 @@ import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -49,6 +52,9 @@ public class TicketServiceImpl extends ServiceImpl<TicketMapper, Ticket> impleme
@Resource
private SchedulePoolMapper schedulePoolMapper;
@Resource
private IAppointmentConfigService appointmentConfigService;
/**
* 查询号源列表
*
@@ -235,6 +241,27 @@ public class TicketServiceImpl extends ServiceImpl<TicketMapper, Ticket> impleme
if (orders == null || orders.isEmpty()) {
throw new RuntimeException("当前号源没有可取消的预约订单");
}
// 核心逻辑:获取订单信息并检查机构取消限制
Order latestOrder = orders.get(0);
Integer tenantId = latestOrder.getTenantId();
Long patientId = latestOrder.getPatientId();
if (tenantId != null && patientId != null) {
AppointmentConfig config = appointmentConfigService.getConfigByTenantId(tenantId);
if (config != null && config.getCancelAppointmentCount() != null
&& config.getCancelAppointmentCount() > 0) {
// 计算当前周期的起始时间
LocalDateTime startTime = calculatePeriodStartTime(config.getCancelAppointmentType());
// 统计已取消次数
long cancelledCount = orderService.countPatientCancellations(patientId, tenantId, startTime);
if (cancelledCount >= config.getCancelAppointmentCount()) {
String periodName = getPeriodName(config.getCancelAppointmentType());
throw new RuntimeException("您在" + periodName + "内已达到该机构取消预约次数上限(" + config.getCancelAppointmentCount() + "次),禁止取消");
}
}
}
for (Order order : orders) {
orderService.cancelAppointmentOrder(order.getId(), "患者取消预约");
}
@@ -309,4 +336,35 @@ public class TicketServiceImpl extends ServiceImpl<TicketMapper, Ticket> impleme
throw new RuntimeException("挂号费格式错误: " + fee);
}
}
/**
* 根据类型获取周期名称
*/
private String getPeriodName(String type) {
if ("YEAR".equalsIgnoreCase(type)) {
return "年度";
} else if ("MONTH".equalsIgnoreCase(type)) {
return "月度";
} else {
return "当日";
}
}
/**
* 根据取消预约时间类型计算本周期的起始时间
*
* @param type YEAR/MONTH/DAY
* @return 起始时间
*/
private LocalDateTime calculatePeriodStartTime(String type) {
LocalDateTime now = LocalDateTime.now();
if ("YEAR".equalsIgnoreCase(type)) {
return now.with(TemporalAdjusters.firstDayOfYear()).with(LocalTime.MIN);
} else if ("MONTH".equalsIgnoreCase(type)) {
return now.with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
} else {
// 默认为 DAY
return now.with(LocalTime.MIN);
}
}
}

View File

@@ -239,32 +239,32 @@
<select id="countOrders" resultType="int">
select count(*) from order_main
<where>
<if test="orderNo != null and orderNo != ''">
and order_no = #{orderNo}
<if test="params.orderNo != null and params.orderNo != ''">
and order_no = #{params.orderNo}
</if>
<if test="patientId != null">
and patient_id = #{patientId}
<if test="params.patientId != null">
and patient_id = #{params.patientId}
</if>
<if test="scheduleId != null">
and schedule_id = #{scheduleId}
<if test="params.scheduleId != null">
and schedule_id = #{params.scheduleId}
</if>
<if test="slotId != null">
and slot_id = #{slotId}
<if test="params.slotId != null">
and slot_id = #{params.slotId}
</if>
<if test="departmentId != null">
and department_id = #{departmentId}
<if test="params.departmentId != null">
and department_id = #{params.departmentId}
</if>
<if test="doctorId != null">
and doctor_id = #{doctorId}
<if test="params.doctorId != null">
and doctor_id = #{params.doctorId}
</if>
<if test="status != null">
and status = #{status}
<if test="params.status != null">
and status = #{params.status}
</if>
<if test="payStatus != null">
and pay_status = #{payStatus}
<if test="params.payStatus != null">
and pay_status = #{params.payStatus}
</if>
<if test="appointmentDate != null">
and appointment_date = #{appointmentDate}
<if test="params.appointmentDate != null">
and appointment_date = #{params.appointmentDate}
</if>
</where>
</select>