Fix Bug #550: AI修复

This commit is contained in:
2026-05-27 03:00:08 +08:00
parent 8e6cb5c79f
commit 16c42ca108
5433 changed files with 171 additions and 778731 deletions

View File

@@ -1,44 +0,0 @@
package com.openhis;
import com.openhis.web.ybmanage.config.YbServiceConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.EnableAsync;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* 启动程序
*
* @author system 1234
*/
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}, scanBasePackages = {"com.core", "com.openhis"})
@EnableConfigurationProperties(YbServiceConfig.class)
@EnableAsync
public class OpenHisApplication {
public static void main(String[] args) throws UnknownHostException {
// System.setProperty("spring.devtools.restart.enabled", "false");
// 测试 Instrument 类加载
// try {
// Class.forName("com.openhis.administration.domain.Instrument");
// System.out.println("Instrument class loaded successfully");
// } catch (ClassNotFoundException e) {
// System.err.println("Failed to load Instrument class: " + e.getMessage());
// }
ConfigurableApplicationContext application = SpringApplication.run(OpenHisApplication.class, args);
Environment env = application.getEnvironment();
String ip = InetAddress.getLocalHost().getHostAddress();
String port = env.getProperty("server.port");
String path = env.getProperty("server.servlet.context-path");
System.out.println("\n----------------------------------------------------------\n\t"
+ "Application OpenHis is running! Access URLs:\n\t" + "Local: \t\thttp://localhost:" + port + path
+ "/\n\t" + "External: \thttp://" + ip + ":" + port + path + "/\n"
+ "----------------------------------------------------------");
}
}

View File

@@ -1,22 +0,0 @@
package com.openhis.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
/**
* http相关配置
*
* @author system
*/
@Data
@Component
@ConfigurationProperties(prefix = "http")
@PropertySource(value = {"classpath:http.yml"})
public class HttpConfig {
private String appId;
private String key;
private String url;
private String fixmedinsCode;
}

View File

@@ -1,152 +0,0 @@
package com.openhis.quartz.controller;
import com.core.common.annotation.Log;
import com.core.common.constant.Constants;
import com.core.common.core.controller.BaseController;
import com.core.common.core.domain.AjaxResult;
import com.core.common.core.page.TableDataInfo;
import com.core.common.enums.BusinessType;
import com.core.common.exception.job.TaskException;
import com.core.common.utils.StringUtils;
import com.core.common.utils.poi.ExcelUtil;
import com.core.quartz.domain.SysJob;
import com.core.quartz.util.CronUtils;
import com.openhis.quartz.service.ISysJobService;
import com.openhis.quartz.util.ScheduleUtils;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* 调度任务信息操作处理
*
* @author system
*/
@RestController
@RequestMapping("/monitor/job")
public class SysJobController extends BaseController {
@Autowired
private ISysJobService jobService;
/**
* 查询定时任务列表
*/
@PreAuthorize("@ss.hasPermi('monitor:job:list')")
@GetMapping("/list")
public TableDataInfo list(SysJob sysJob) {
startPage();
List<SysJob> list = jobService.selectJobList(sysJob);
return getDataTable(list);
}
/**
* 导出定时任务列表
*/
@PreAuthorize("@ss.hasPermi('monitor:job:export')")
@Log(title = "定时任务", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, SysJob sysJob) {
List<SysJob> list = jobService.selectJobList(sysJob);
ExcelUtil<SysJob> util = new ExcelUtil<SysJob>(SysJob.class);
util.exportExcel(response, list, "定时任务");
}
/**
* 获取定时任务详细信息
*/
@PreAuthorize("@ss.hasPermi('monitor:job:query')")
@GetMapping(value = "/{jobId}")
public AjaxResult getInfo(@PathVariable("jobId") Long jobId) {
return success(jobService.selectJobById(jobId));
}
/**
* 新增定时任务
*/
@PreAuthorize("@ss.hasPermi('monitor:job:add')")
@Log(title = "定时任务", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody SysJob job) throws SchedulerException, TaskException {
if (!CronUtils.isValid(job.getCronExpression())) {
return error("新增任务'" + job.getJobName() + "'失败Cron表达式不正确");
} else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI)) {
return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi'调用");
} else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(),
new String[] {Constants.LOOKUP_LDAP, Constants.LOOKUP_LDAPS})) {
return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap(s)'调用");
} else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(),
new String[] {Constants.HTTP, Constants.HTTPS})) {
return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)'调用");
} else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR)) {
return error("新增任务'" + job.getJobName() + "'失败,目标字符串存在违规");
} else if (!ScheduleUtils.whiteList(job.getInvokeTarget())) {
return error("新增任务'" + job.getJobName() + "'失败,目标字符串不在白名单内");
}
job.setCreateBy(getUsername());
return toAjax(jobService.insertJob(job));
}
/**
* 修改定时任务
*/
@PreAuthorize("@ss.hasPermi('monitor:job:edit')")
@Log(title = "定时任务", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody SysJob job) throws SchedulerException, TaskException {
if (!CronUtils.isValid(job.getCronExpression())) {
return error("修改任务'" + job.getJobName() + "'失败Cron表达式不正确");
} else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI)) {
return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi'调用");
} else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(),
new String[] {Constants.LOOKUP_LDAP, Constants.LOOKUP_LDAPS})) {
return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap(s)'调用");
} else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(),
new String[] {Constants.HTTP, Constants.HTTPS})) {
return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)'调用");
} else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR)) {
return error("修改任务'" + job.getJobName() + "'失败,目标字符串存在违规");
} else if (!ScheduleUtils.whiteList(job.getInvokeTarget())) {
return error("修改任务'" + job.getJobName() + "'失败,目标字符串不在白名单内");
}
job.setUpdateBy(getUsername());
return toAjax(jobService.updateJob(job));
}
/**
* 定时任务状态修改
*/
@PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')")
@Log(title = "定时任务", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus")
public AjaxResult changeStatus(@RequestBody SysJob job) throws SchedulerException {
SysJob newJob = jobService.selectJobById(job.getJobId());
newJob.setStatus(job.getStatus());
return toAjax(jobService.changeStatus(newJob));
}
/**
* 定时任务立即执行一次
*/
@PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')")
@Log(title = "定时任务", businessType = BusinessType.UPDATE)
@PutMapping("/run")
public AjaxResult run(@RequestBody SysJob job) throws SchedulerException {
boolean result = jobService.run(job);
return result ? success() : error("任务不存在或已过期!");
}
/**
* 删除定时任务
*/
@PreAuthorize("@ss.hasPermi('monitor:job:remove')")
@Log(title = "定时任务", businessType = BusinessType.DELETE)
@DeleteMapping("/{jobIds}")
public AjaxResult remove(@PathVariable Long[] jobIds) throws SchedulerException, TaskException {
jobService.deleteJobByIds(jobIds);
return success();
}
}

View File

@@ -1,81 +0,0 @@
package com.openhis.quartz.controller;
import com.core.common.annotation.Log;
import com.core.common.core.controller.BaseController;
import com.core.common.core.domain.AjaxResult;
import com.core.common.core.page.TableDataInfo;
import com.core.common.enums.BusinessType;
import com.core.common.utils.poi.ExcelUtil;
import com.core.quartz.domain.SysJobLog;
import com.openhis.quartz.service.ISysJobLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* 调度日志操作处理
*
* @author system
*/
@RestController
@RequestMapping("/monitor/jobLog")
public class SysJobLogController extends BaseController {
@Autowired
private ISysJobLogService jobLogService;
/**
* 查询定时任务调度日志列表
*/
@PreAuthorize("@ss.hasPermi('monitor:job:list')")
@GetMapping("/list")
public TableDataInfo list(SysJobLog sysJobLog) {
startPage();
List<SysJobLog> list = jobLogService.selectJobLogList(sysJobLog);
return getDataTable(list);
}
/**
* 导出定时任务调度日志列表
*/
@PreAuthorize("@ss.hasPermi('monitor:job:export')")
@Log(title = "任务调度日志", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, SysJobLog sysJobLog) {
List<SysJobLog> list = jobLogService.selectJobLogList(sysJobLog);
ExcelUtil<SysJobLog> util = new ExcelUtil<SysJobLog>(SysJobLog.class);
util.exportExcel(response, list, "调度日志");
}
/**
* 根据调度编号获取详细信息
*/
@PreAuthorize("@ss.hasPermi('monitor:job:query')")
@GetMapping(value = "/{jobLogId}")
public AjaxResult getInfo(@PathVariable Long jobLogId) {
return success(jobLogService.selectJobLogById(jobLogId));
}
/**
* 删除定时任务调度日志
*/
@PreAuthorize("@ss.hasPermi('monitor:job:remove')")
@Log(title = "定时任务调度日志", businessType = BusinessType.DELETE)
@DeleteMapping("/{jobLogIds}")
public AjaxResult remove(@PathVariable Long[] jobLogIds) {
return toAjax(jobLogService.deleteJobLogByIds(jobLogIds));
}
/**
* 清空定时任务调度日志
*/
@PreAuthorize("@ss.hasPermi('monitor:job:remove')")
@Log(title = "调度日志", businessType = BusinessType.CLEAN)
@DeleteMapping("/clean")
public AjaxResult clean() {
jobLogService.cleanJobLog();
return success();
}
}

View File

@@ -1,56 +0,0 @@
package com.openhis.quartz.service;
import com.core.quartz.domain.SysJobLog;
import java.util.List;
/**
* 定时任务调度日志信息信息 服务层
*
* @author system
*/
public interface ISysJobLogService {
/**
* 获取quartz调度器日志的计划任务
*
* @param jobLog 调度日志信息
* @return 调度任务日志集合
*/
public List<SysJobLog> selectJobLogList(SysJobLog jobLog);
/**
* 通过调度任务日志ID查询调度信息
*
* @param jobLogId 调度任务日志ID
* @return 调度任务日志对象信息
*/
public SysJobLog selectJobLogById(Long jobLogId);
/**
* 新增任务日志
*
* @param jobLog 调度日志信息
*/
public void addJobLog(SysJobLog jobLog);
/**
* 批量删除调度日志信息
*
* @param logIds 需要删除的日志ID
* @return 结果
*/
public int deleteJobLogByIds(Long[] logIds);
/**
* 删除任务日志
*
* @param jobId 调度日志ID
* @return 结果
*/
public int deleteJobLogById(Long jobId);
/**
* 清空任务日志
*/
public void cleanJobLog();
}

View File

@@ -1,102 +0,0 @@
package com.openhis.quartz.service;
import com.core.common.exception.job.TaskException;
import com.core.quartz.domain.SysJob;
import org.quartz.SchedulerException;
import java.util.List;
/**
* 定时任务调度信息信息 服务层
*
* @author system
*/
public interface ISysJobService {
/**
* 获取quartz调度器的计划任务
*
* @param job 调度信息
* @return 调度任务集合
*/
public List<SysJob> selectJobList(SysJob job);
/**
* 通过调度任务ID查询调度信息
*
* @param jobId 调度任务ID
* @return 调度任务对象信息
*/
public SysJob selectJobById(Long jobId);
/**
* 暂停任务
*
* @param job 调度信息
* @return 结果
*/
public int pauseJob(SysJob job) throws SchedulerException;
/**
* 恢复任务
*
* @param job 调度信息
* @return 结果
*/
public int resumeJob(SysJob job) throws SchedulerException;
/**
* 删除任务后所对应的trigger也将被删除
*
* @param job 调度信息
* @return 结果
*/
public int deleteJob(SysJob job) throws SchedulerException;
/**
* 批量删除调度信息
*
* @param jobIds 需要删除的任务ID
* @return 结果
*/
public void deleteJobByIds(Long[] jobIds) throws SchedulerException;
/**
* 任务调度状态修改
*
* @param job 调度信息
* @return 结果
*/
public int changeStatus(SysJob job) throws SchedulerException;
/**
* 立即运行任务
*
* @param job 调度信息
* @return 结果
*/
public boolean run(SysJob job) throws SchedulerException;
/**
* 新增任务
*
* @param job 调度信息
* @return 结果
*/
public int insertJob(SysJob job) throws SchedulerException, TaskException;
/**
* 更新任务
*
* @param job 调度信息
* @return 结果
*/
public int updateJob(SysJob job) throws SchedulerException, TaskException;
/**
* 校验cron表达式是否有效
*
* @param cronExpression 表达式
* @return 结果
*/
public boolean checkCronExpressionIsValid(String cronExpression);
}

View File

@@ -1,81 +0,0 @@
package com.openhis.quartz.service.impl;
import com.core.quartz.domain.SysJobLog;
import com.core.quartz.mapper.SysJobLogMapper;
import com.openhis.quartz.service.ISysJobLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 定时任务调度日志信息 服务层
*
* @author system
*/
@Service
public class SysJobLogServiceImpl implements ISysJobLogService {
@Autowired
private SysJobLogMapper jobLogMapper;
/**
* 获取quartz调度器日志的计划任务
*
* @param jobLog 调度日志信息
* @return 调度任务日志集合
*/
@Override
public List<SysJobLog> selectJobLogList(SysJobLog jobLog) {
return jobLogMapper.selectJobLogList(jobLog);
}
/**
* 通过调度任务日志ID查询调度信息
*
* @param jobLogId 调度任务日志ID
* @return 调度任务日志对象信息
*/
@Override
public SysJobLog selectJobLogById(Long jobLogId) {
return jobLogMapper.selectJobLogById(jobLogId);
}
/**
* 新增任务日志
*
* @param jobLog 调度日志信息
*/
@Override
public void addJobLog(SysJobLog jobLog) {
jobLogMapper.insertJobLog(jobLog);
}
/**
* 批量删除调度日志信息
*
* @param logIds 需要删除的数据ID
* @return 结果
*/
@Override
public int deleteJobLogByIds(Long[] logIds) {
return jobLogMapper.deleteJobLogByIds(logIds);
}
/**
* 删除任务日志
*
* @param jobId 调度日志ID
*/
@Override
public int deleteJobLogById(Long jobId) {
return jobLogMapper.deleteJobLogById(jobId);
}
/**
* 清空任务日志
*/
@Override
public void cleanJobLog() {
jobLogMapper.cleanJobLog();
}
}

View File

@@ -1,236 +0,0 @@
package com.openhis.quartz.service.impl;
import com.core.common.constant.ScheduleConstants;
import com.core.common.exception.job.TaskException;
import com.core.quartz.domain.SysJob;
import com.core.quartz.mapper.SysJobMapper;
import com.core.quartz.util.CronUtils;
import com.openhis.quartz.service.ISysJobService;
import com.openhis.quartz.util.ScheduleUtils;
import org.quartz.JobDataMap;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.PostConstruct;
import java.util.List;
/**
* 定时任务调度信息 服务层
*
* @author system
*/
@Service
public class SysJobServiceImpl implements ISysJobService {
@Autowired
private Scheduler scheduler;
@Autowired
private SysJobMapper jobMapper;
/**
* 项目启动时,初始化定时器 主要是防止手动修改数据库导致未同步到定时任务处理不能手动修改数据库ID和任务组名否则会导致脏数据
*/
@PostConstruct
public void init() throws SchedulerException, TaskException {
scheduler.clear();
List<SysJob> jobList = jobMapper.selectJobAll();
for (SysJob job : jobList) {
ScheduleUtils.createScheduleJob(scheduler, job);
}
}
/**
* 获取quartz调度器的计划任务列表
*
* @param job 调度信息
* @return
*/
@Override
public List<SysJob> selectJobList(SysJob job) {
return jobMapper.selectJobList(job);
}
/**
* 通过调度任务ID查询调度信息
*
* @param jobId 调度任务ID
* @return 调度任务对象信息
*/
@Override
public SysJob selectJobById(Long jobId) {
return jobMapper.selectJobById(jobId);
}
/**
* 暂停任务
*
* @param job 调度信息
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int pauseJob(SysJob job) throws SchedulerException {
Long jobId = job.getJobId();
String jobGroup = job.getJobGroup();
job.setStatus(ScheduleConstants.Status.PAUSE.getValue());
int rows = jobMapper.updateJob(job);
if (rows > 0) {
scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup));
}
return rows;
}
/**
* 恢复任务
*
* @param job 调度信息
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int resumeJob(SysJob job) throws SchedulerException {
Long jobId = job.getJobId();
String jobGroup = job.getJobGroup();
job.setStatus(ScheduleConstants.Status.NORMAL.getValue());
int rows = jobMapper.updateJob(job);
if (rows > 0) {
scheduler.resumeJob(ScheduleUtils.getJobKey(jobId, jobGroup));
}
return rows;
}
/**
* 删除任务后所对应的trigger也将被删除
*
* @param job 调度信息
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int deleteJob(SysJob job) throws SchedulerException {
Long jobId = job.getJobId();
String jobGroup = job.getJobGroup();
int rows = jobMapper.deleteJobById(jobId);
if (rows > 0) {
scheduler.deleteJob(ScheduleUtils.getJobKey(jobId, jobGroup));
}
return rows;
}
/**
* 批量删除调度信息
*
* @param jobIds 需要删除的任务ID
* @return 结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteJobByIds(Long[] jobIds) throws SchedulerException {
for (Long jobId : jobIds) {
SysJob job = jobMapper.selectJobById(jobId);
deleteJob(job);
}
}
/**
* 任务调度状态修改
*
* @param job 调度信息
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int changeStatus(SysJob job) throws SchedulerException {
int rows = 0;
String status = job.getStatus();
if (ScheduleConstants.Status.NORMAL.getValue().equals(status)) {
rows = resumeJob(job);
} else if (ScheduleConstants.Status.PAUSE.getValue().equals(status)) {
rows = pauseJob(job);
}
return rows;
}
/**
* 立即运行任务
*
* @param job 调度信息
*/
@Override
@Transactional(rollbackFor = Exception.class)
public boolean run(SysJob job) throws SchedulerException {
boolean result = false;
Long jobId = job.getJobId();
String jobGroup = job.getJobGroup();
SysJob properties = selectJobById(job.getJobId());
// 参数
JobDataMap dataMap = new JobDataMap();
dataMap.put(ScheduleConstants.TASK_PROPERTIES, properties);
JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup);
if (scheduler.checkExists(jobKey)) {
result = true;
scheduler.triggerJob(jobKey, dataMap);
}
return result;
}
/**
* 新增任务
*
* @param job 调度信息 调度信息
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int insertJob(SysJob job) throws SchedulerException, TaskException {
job.setStatus(ScheduleConstants.Status.PAUSE.getValue());
int rows = jobMapper.insertJob(job);
if (rows > 0) {
ScheduleUtils.createScheduleJob(scheduler, job);
}
return rows;
}
/**
* 更新任务的时间表达式
*
* @param job 调度信息
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int updateJob(SysJob job) throws SchedulerException, TaskException {
SysJob properties = selectJobById(job.getJobId());
int rows = jobMapper.updateJob(job);
if (rows > 0) {
updateSchedulerJob(job, properties.getJobGroup());
}
return rows;
}
/**
* 更新任务
*
* @param job 任务对象
* @param jobGroup 任务组名
*/
public void updateSchedulerJob(SysJob job, String jobGroup) throws SchedulerException, TaskException {
Long jobId = job.getJobId();
// 判断是否存在
JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup);
if (scheduler.checkExists(jobKey)) {
// 防止创建时存在数据问题 先移除,然后在执行创建操作
scheduler.deleteJob(jobKey);
}
ScheduleUtils.createScheduleJob(scheduler, job);
}
/**
* 校验cron表达式是否有效
*
* @param cronExpression 表达式
* @return 结果
*/
@Override
public boolean checkCronExpressionIsValid(String cronExpression) {
return CronUtils.isValid(cronExpression);
}
}

View File

@@ -1,48 +0,0 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.quartz.task;
import com.core.framework.config.TenantContext;
import com.openhis.web.inhospitalnursestation.appservice.IEncounterAutoRollAppService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* 自动滚方定时任务(每日执行)
*/
@Slf4j
@Component("AutoRollTask")
public class AutoRollTask {
@Resource
private IEncounterAutoRollAppService encounterAutoRollAppService;
/**
* 护理费
*
* @param tenantId 租户id
* @param orderPricing 医嘱定价来源 | 定时任务调用时传参
*/
public void autoRollNursingFee(Integer tenantId, String orderPricing) {
// 设置当前线程的租户ID
TenantContext.setCurrentTenant(tenantId);
// 滚护理费
encounterAutoRollAppService.autoRollNursingFee(tenantId, orderPricing);
}
/**
* 基础服务费 | 取暖费,床位费 等
*
* @param tenantId 租户id
* @param orderPricing 医嘱定价来源 | 定时任务调用时传参
*/
public void autoRollBasicService(Integer tenantId, String orderPricing) {
// 设置当前线程的租户ID
TenantContext.setCurrentTenant(tenantId);
// 滚基础服务费
encounterAutoRollAppService.autoRollBasicService(tenantId, orderPricing);
}
}

View File

@@ -1,33 +0,0 @@
package com.openhis.quartz.task;
import com.core.common.core.domain.R;
import com.core.common.utils.DateUtils;
import com.openhis.web.basedatamanage.appservice.IOrganizationAppService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 定时任务例子
*
* @author system
*/
@Slf4j
@Component("exampleTask")
public class ExampleTask {
@Autowired
private IOrganizationAppService organizationAppService;
/**
* 定时获取机构信息
*/
public void getOrgInfo() {
log.info("定时获取机构信息START时间{}", DateUtils.getDate());
// 处理部分
R<?> r = organizationAppService.getOrgInfo(1907249098877554689L);
log.info("定时获取机构信息END机构信息{},时间:{}", r.getData(), DateUtils.getDate());
}
}

View File

@@ -1,180 +0,0 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.quartz.task;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.enums.DelFlag;
import com.core.common.utils.AssignSeqUtil;
import com.core.common.utils.DateUtils;
import com.core.framework.config.TenantContext;
import com.openhis.common.enums.AssignSeqEnum;
import com.openhis.document.domain.DocInventoryItemStatic;
import com.openhis.document.service.IDocInventoryItemStaticService;
import com.openhis.web.inventorymanage.appservice.IProductDetailAppService;
import com.openhis.web.inventorymanage.dto.ProductDetailPageDto;
import com.openhis.web.inventorymanage.dto.ProductDetailSearchParam;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* 库存备份定时任务(每日执行)
*
* @author zwh
* @date 2025-11-12
*/
@Slf4j
@Component("InventoryBackupTask")
public class InventoryBackupTask {
Logger logger = LoggerFactory.getLogger(InventoryBackupTask.class);
@Resource
private IProductDetailAppService productDetailAppService;
@Resource
private IDocInventoryItemStaticService docInventoryItemStaticService;
@Resource
private AssignSeqUtil assignSeqUtil;
private static final AtomicBoolean isRunning = new AtomicBoolean(false);
/**
* 库存备份
*
* @param tenantId 租户id
*/
public void inventoryBackup(Integer tenantId) {
// 添加执行锁,防止重复执行
if (!isRunning.compareAndSet(false, true)) {
logger.warn("库存备份任务正在执行中,跳过本次执行");
return;
}
// 定时任务指定租户id
try {
logger.info("库存备份START{}", DateUtils.getNowDate());
// 设置当前线程的租户ID
TenantContext.setCurrentTenant(tenantId);
String now = DateUtils.dateTime();
// 查询当天是否已经执行过一次库存备份
List<DocInventoryItemStatic> hisDocInventoryItemStaticList = docInventoryItemStaticService
.list(new LambdaQueryWrapper<DocInventoryItemStatic>()
.eq(DocInventoryItemStatic::getDeleteFlag, DelFlag.NO.getCode())
.eq(DocInventoryItemStatic::getTenantId, tenantId))
.stream().filter(item -> item.getBusNo() != null && item.getBusNo().length() >= 11
&& now.equals(item.getBusNo().substring(3, 11)))
.toList();
if (!hisDocInventoryItemStaticList.isEmpty()) {
logger.warn("库存备份任务已执行过,跳过本次执行");
return;
}
// 生成备份编号
String busNo = assignSeqUtil.getSeqByDay(AssignSeqEnum.AUTO_BACKUP_NO.getPrefix(), 2);
// 获取库存商品明细
Page<ProductDetailPageDto> productDetailPage = productDetailAppService
.getProductDetailPage(new ProductDetailSearchParam(), 1, 9999, null, null).getData();
List<DocInventoryItemStatic> docInventoryItemStaticList = new ArrayList<>();
if (productDetailPage != null && productDetailPage.getTotal() > 0) {
List<ProductDetailPageDto> productDetailList = productDetailPage.getRecords();
for (ProductDetailPageDto productDetail : productDetailList) {
DocInventoryItemStatic docInventoryItemStatic = new DocInventoryItemStatic();
docInventoryItemStatic
// 库存状态枚举
.setInventoryStatusEnum(productDetail.getInventoryStatusEnum())
// 备份编号
.setBusNo(busNo)
// 库存id
.setInventoryId(productDetail.getInventoryId())
// 医保等级
.setChrgitmLv(productDetail.getChrgitmLv())
// 耗材类型
.setDevCategoryCode(productDetail.getDevCategoryCode())
// 项目id
.setItemId(productDetail.getItemId())
// 项目名称
.setName(productDetail.getItemName())
// 项目编号
.setItemNo(productDetail.getBusNo())
// 药品类别
.setMedCategoryCode(productDetail.getMedCategoryCode())
// 项目所在表
.setItemTable(productDetail.getItemTable())
// 所在位置
.setLocationId(productDetail.getLocationId())
// 位置名称
.setLocationName(productDetail.getLocationName())
// 所在货位
.setLocationStoreId(productDetail.getLocationStoreId())
// 货位名称
.setLocationStoreName(productDetail.getLocationStoreName())
// 厂家
.setManufacturerText(productDetail.getManufacturerText())
// 最小单位
.setMinUnitCode(productDetail.getMinUnitCode())
// 拆零比
.setPartPercent(productDetail.getPartPercent())
// 采购价
.setPrice(productDetail.getPurchasePrice())
// 生产日期
.setProductionDate(productDetail.getProductionDate())
// 到期日期
.setExpirationDate(productDetail.getExpirationDate())
// 库存数量
.setQuantity(productDetail.getQuantity())
// 销售价
.setSalePrice(productDetail.getSalePrice())
// 采购总价
.setTotalPrice(productDetail.getTotalPurchasePrice())
// 销售总价
.setTotalSalePrice(productDetail.getTotalSalePrice())
// 规格
.setTotalVolume(productDetail.getTotalVolume())
// 单位
.setUnitCode(productDetail.getUnitCode())
// 五笔码
.setWbStr(productDetail.getWbStr())
// 拼音码
.setPyStr(productDetail.getPyStr())
// 供应商id
.setSupplierId(productDetail.getSupplierId())
// 供应商名称
.setSupplierName(productDetail.getSupplierName())
// 剩余过期天数
.setRemainingDays(productDetail.getRemainingDays())
// 包装数量(整数)
.setNumber(productDetail.getNumber())
// 包装数量(小数)
.setRemainder(productDetail.getRemainder())
// 医保码
.setYbNo(productDetail.getYbNo())
// 批准文号
.setApprovalNumber(productDetail.getApprovalNumber())
// 批次号
.setLotNumber(productDetail.getLotNumber());
docInventoryItemStatic.setTenantId(tenantId);
docInventoryItemStaticList.add(docInventoryItemStatic);
}
docInventoryItemStaticService.saveBatch(docInventoryItemStaticList);
}
} catch (Exception e) {
logger.error("库存备份失败:", e);
} finally {
// 清除线程局部变量,防止内存泄漏
TenantContext.clear();
// 释放执行锁
isRunning.set(false);
logger.info("库存备份END{}", DateUtils.getNowDate());
}
}
}

View File

@@ -1,45 +0,0 @@
package com.openhis.quartz.task;
import com.core.common.utils.StringUtils;
import com.core.framework.config.TenantContext;
import com.openhis.administration.domain.Location;
import com.openhis.administration.service.ILocationService;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
/**
* 定时任务调度测试
*
* @author system
*/
@Component("ryTask")
public class RyTask {
@Resource
ILocationService locationService;
public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i) {
// 定时任务指定租户id,示例
try {
Integer tenantId = i;
// 设置当前线程的租户ID
TenantContext.setCurrentTenant(tenantId);
List<Location> pharmacyList = locationService.getPharmacyList();
System.out.println(StringUtils.format("执行多参方法: 字符串类型{},布尔类型{},长整型{},浮点型{},整形{}", s, b, l, d, i));
} finally {
// 清除线程局部变量,防止内存泄漏
TenantContext.clear();
}
}
public void ryParams(String params) {
System.out.println("执行有参方法:" + params);
}
public void ryNoParams() {
System.out.println("执行无参方法");
}
}

View File

@@ -1,97 +0,0 @@
package com.openhis.quartz.util;
import com.core.common.constant.Constants;
import com.core.common.constant.ScheduleConstants;
import com.core.common.utils.ExceptionUtil;
import com.core.common.utils.StringUtils;
import com.core.common.utils.bean.BeanUtils;
import com.core.common.utils.spring.SpringUtils;
import com.core.quartz.domain.SysJob;
import com.core.quartz.domain.SysJobLog;
import com.openhis.quartz.service.ISysJobLogService;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
/**
* 抽象quartz调用
*
* @author system
*/
public abstract class AbstractQuartzJob implements Job {
private static final Logger log = LoggerFactory.getLogger(AbstractQuartzJob.class);
/**
* 线程本地变量
*/
private static ThreadLocal<Date> threadLocal = new ThreadLocal<>();
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
SysJob sysJob = new SysJob();
BeanUtils.copyBeanProp(sysJob, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES));
try {
before(context, sysJob);
if (sysJob != null) {
doExecute(context, sysJob);
}
after(context, sysJob, null);
} catch (Exception e) {
log.error("任务执行异常 - ", e);
after(context, sysJob, e);
}
}
/**
* 执行前
*
* @param context 工作执行上下文对象
* @param sysJob 系统计划任务
*/
protected void before(JobExecutionContext context, SysJob sysJob) {
threadLocal.set(new Date());
}
/**
* 执行后
*
* @param context 工作执行上下文对象
* @param sysJob 系统计划任务
*/
protected void after(JobExecutionContext context, SysJob sysJob, Exception e) {
Date startTime = threadLocal.get();
threadLocal.remove();
final SysJobLog sysJobLog = new SysJobLog();
sysJobLog.setJobName(sysJob.getJobName());
sysJobLog.setJobGroup(sysJob.getJobGroup());
sysJobLog.setInvokeTarget(sysJob.getInvokeTarget());
sysJobLog.setStartTime(startTime);
sysJobLog.setStopTime(new Date());
long runMs = sysJobLog.getStopTime().getTime() - sysJobLog.getStartTime().getTime();
sysJobLog.setJobMessage(sysJobLog.getJobName() + " 总共耗时:" + runMs + "毫秒");
if (e != null) {
sysJobLog.setStatus(Constants.FAIL);
String errorMsg = StringUtils.substring(ExceptionUtil.getExceptionMessage(e), 0, 2000);
sysJobLog.setExceptionInfo(errorMsg);
} else {
sysJobLog.setStatus(Constants.SUCCESS);
}
// 写入数据库当中
SpringUtils.getBean(ISysJobLogService.class).addJobLog(sysJobLog);
}
/**
* 执行方法,由子类重载
*
* @param context 工作执行上下文对象
* @param sysJob 系统计划任务
* @throws Exception 执行过程中的异常
*/
protected abstract void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception;
}

View File

@@ -1,20 +0,0 @@
package com.openhis.quartz.util;
import com.core.quartz.domain.SysJob;
import com.core.quartz.util.JobInvokeUtil;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
/**
* 定时任务处理(禁止并发执行)
*
* @author system
*
*/
@DisallowConcurrentExecution
public class QuartzDisallowConcurrentExecution extends AbstractQuartzJob {
@Override
protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception {
JobInvokeUtil.invokeMethod(sysJob);
}
}

View File

@@ -1,18 +0,0 @@
package com.openhis.quartz.util;
import com.core.quartz.domain.SysJob;
import com.core.quartz.util.JobInvokeUtil;
import org.quartz.JobExecutionContext;
/**
* 定时任务处理(允许并发执行)
*
* @author system
*
*/
public class QuartzJobExecution extends AbstractQuartzJob {
@Override
protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception {
JobInvokeUtil.invokeMethod(sysJob);
}
}

View File

@@ -1,122 +0,0 @@
package com.openhis.quartz.util;
import com.core.common.constant.Constants;
import com.core.common.constant.ScheduleConstants;
import com.core.common.exception.job.TaskException;
import com.core.common.exception.job.TaskException.Code;
import com.core.common.utils.StringUtils;
import com.core.common.utils.spring.SpringUtils;
import com.core.quartz.domain.SysJob;
import com.core.quartz.util.CronUtils;
import org.quartz.*;
/**
* 定时任务工具类
*
* @author system
*
*/
public class ScheduleUtils {
/**
* 得到quartz任务类
*
* @param sysJob 执行计划
* @return 具体执行任务类
*/
private static Class<? extends Job> getQuartzJobClass(SysJob sysJob) {
boolean isConcurrent = "0".equals(sysJob.getConcurrent());
return isConcurrent ? QuartzJobExecution.class : QuartzDisallowConcurrentExecution.class;
}
/**
* 构建任务触发对象
*/
public static TriggerKey getTriggerKey(Long jobId, String jobGroup) {
return TriggerKey.triggerKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup);
}
/**
* 构建任务键对象
*/
public static JobKey getJobKey(Long jobId, String jobGroup) {
return JobKey.jobKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup);
}
/**
* 创建定时任务
*/
public static void createScheduleJob(Scheduler scheduler, SysJob job) throws SchedulerException, TaskException {
Class<? extends Job> jobClass = getQuartzJobClass(job);
// 构建job信息
Long jobId = job.getJobId();
String jobGroup = job.getJobGroup();
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(getJobKey(jobId, jobGroup)).build();
// 表达式调度构建器
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder);
// 按新的cronExpression表达式构建一个新的trigger
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(jobId, jobGroup))
.withSchedule(cronScheduleBuilder).build();
// 放入参数,运行时的方法可以获取
jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job);
// 判断是否存在
if (scheduler.checkExists(getJobKey(jobId, jobGroup))) {
// 防止创建时存在数据问题 先移除,然后在执行创建操作
scheduler.deleteJob(getJobKey(jobId, jobGroup));
}
// 判断任务是否过期
if (StringUtils.isNotNull(CronUtils.getNextExecution(job.getCronExpression()))) {
// 执行调度任务
scheduler.scheduleJob(jobDetail, trigger);
}
// 暂停任务
if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue())) {
scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup));
}
}
/**
* 设置定时任务策略
*/
public static CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob job, CronScheduleBuilder cb)
throws TaskException {
switch (job.getMisfirePolicy()) {
case ScheduleConstants.MISFIRE_DEFAULT:
return cb;
case ScheduleConstants.MISFIRE_IGNORE_MISFIRES:
return cb.withMisfireHandlingInstructionIgnoreMisfires();
case ScheduleConstants.MISFIRE_FIRE_AND_PROCEED:
return cb.withMisfireHandlingInstructionFireAndProceed();
case ScheduleConstants.MISFIRE_DO_NOTHING:
return cb.withMisfireHandlingInstructionDoNothing();
default:
throw new TaskException(
"The task misfire policy '" + job.getMisfirePolicy() + "' cannot be used in cron schedule tasks",
Code.CONFIG_ERROR);
}
}
/**
* 检查包名是否为白名单配置
*
* @param invokeTarget 目标字符串
* @return 结果
*/
public static boolean whiteList(String invokeTarget) {
String packageName = StringUtils.substringBefore(invokeTarget, "(");
int count = StringUtils.countMatches(packageName, ".");
if (count > 1) {
return StringUtils.containsAnyIgnoreCase(invokeTarget, Constants.JOB_WHITELIST_STR);
}
Object obj = SpringUtils.getBean(StringUtils.split(invokeTarget, ".")[0]);
String beanPackageName = obj.getClass().getPackage().getName();
return StringUtils.containsAnyIgnoreCase(beanPackageName, Constants.JOB_WHITELIST_STR)
&& !StringUtils.containsAnyIgnoreCase(beanPackageName, Constants.JOB_ERROR_STR);
}
}

View File

@@ -1,14 +0,0 @@
package com.openhis.rule.component;
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;
@Component("a")
public class ACmp extends NodeComponent {
@Override
public void process() {
// do your business
System.out.println("___aaa");
}
}

View File

@@ -1,14 +0,0 @@
package com.openhis.rule.component;
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;
@Component("b")
public class BCmp extends NodeComponent {
@Override
public void process() {
// do your business
System.out.println("___bbb");
}
}

View File

@@ -1,14 +0,0 @@
package com.openhis.rule.component;
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;
@Component("c")
public class CCmp extends NodeComponent {
@Override
public void process() {
// do your business
System.out.println("___ccc");
}
}

View File

@@ -1,38 +0,0 @@
# Web Layer - API Controllers
**Module**: `openhis-application/web`
**Role**: API endpoint layer - all REST controllers for frontend communication
## OVERVIEW
46 web modules serving REST APIs for all business functionality.
## STRUCTURE
```
web/
├── [module-name]/
│ ├── controller/ # REST endpoints (@RestController)
│ ├── dto/ # Data transfer objects
│ ├── mapper/ # MyBatis mappers (if module-specific)
│ └── appservice/ # Application service layer
│ └── impl/
```
## WHERE TO LOOK
| Task | Location |
|------|----------|
| API endpoints | `*/controller/*Controller.java` |
| Request/Response schemas | `*/dto/*.java` |
| Business logic orchestration | `*/appservice/*.java` |
## CONVENTIONS
- Controllers: `@RestController`, `@RequestMapping("/module-name")`
- Standard response: `AjaxResult` from core-common
- DTO naming: `XxxRequest`, `XxxResponse`, `XxxDTO`
- Service pattern: interface in `appservice/`, impl in `appservice/impl/`
- API naming: `listXxx()`, `getXxx()`, `addXxx()`, `updateXxx()`, `deleteXxx()`
## ANTI-PATTERNS
- Never put business logic in controllers - delegate to appservice
- Never return raw entities - use DTOs
- Never bypass `AjaxResult` wrapper
- Never create module-specific mappers without justification

View File

@@ -1,32 +0,0 @@
package com.openhis.web.Inspection.appservice;
import com.core.common.core.domain.R;
import com.openhis.administration.domain.Instrument;
import com.openhis.web.Inspection.dto.InstrumentSelParam;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
/**
* @Description TODO
* @Author
* @Date 2025/9/18 15:38
*/
public interface IInstrumentManageAppService {
R<?> getManageInit();
R<?> getInstrumentPage(InstrumentSelParam InstrumentSelParam, String searchKey, Integer pageNo, Integer pageSize,
HttpServletRequest request);
R<?> updateOrAddInstrument(Instrument instrument);
R<?> getInstrumentOne(Long id);
R<?> editInstrumentStatus(List<Long> ids, Integer status);
}

View File

@@ -1,19 +0,0 @@
package com.openhis.web.Inspection.appservice;
import com.core.common.core.domain.R;
import com.openhis.web.Inspection.dto.ReportResultManageDto;
import javax.servlet.http.HttpServletRequest;
/**
* @Description TODO
* @Author
* @Date 2025/10/16 15:36
*/
public interface ILaboratoryManageAppService {
R<?> getReportResultList(ReportResultManageDto reportResultManageDto, Integer pageNo, Integer pageSize, String searchKey, HttpServletRequest request);
R<?> getReportById(Long id);
}

View File

@@ -1,34 +0,0 @@
package com.openhis.web.Inspection.appservice;
import com.core.common.core.domain.R;
import com.openhis.web.Inspection.dto.LisConfigManageDto;
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentSelParam;
import javax.servlet.http.HttpServletRequest;
/**
* @Description TODO
* @Author
* @Date 2025/9/29 16:00
*/
public interface ILisConfigManageAppService {
R<?> getDiseaseTreatmentPage(DiagnosisTreatmentSelParam DiagnosisTreatmentSelParam, String searchKey,
Integer pageNo, Integer pageSize, HttpServletRequest request);
R<?> getInfoList(String searchKey,String type);
R<?> getInfoDetail(Long id);
R<?> saveAll(LisConfigManageDto manageDto);
/**
*
* @param patientId 患者id
* @param ServiceId 服务id
* @param itemId 检验项目id
* @return
*/
R<?>createAll(Long patientId,Long ServiceId, Long itemId);
}

View File

@@ -1,29 +0,0 @@
package com.openhis.web.Inspection.appservice;
import com.core.common.core.domain.R;
import com.openhis.administration.domain.ObservationDefinition;
import com.openhis.web.Inspection.dto.ObservationDefSelParam;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
/**
* @Description TODO
* @Author
* @Date 2025/9/23 16:32
*/
public interface IObservationManageAppService {
R<?> getManageInit();
R<?> getObservationDefPage(ObservationDefSelParam ObservationDefSelParam, String searchKey, Integer pageNo, Integer pageSize,
HttpServletRequest request);
R<?> updateOrAddObservationDef(ObservationDefinition Observation);
R<?> getObservationDefOne(Long id);
R<?> editObservationDefStatus(List<Long> ids, Integer status);
}

View File

@@ -1,20 +0,0 @@
package com.openhis.web.Inspection.appservice;
import com.core.common.core.domain.R;
import com.openhis.web.Inspection.dto.SampleCollectManageDto;
import com.openhis.web.Inspection.dto.SampleCollectStatusRequest;
import javax.servlet.http.HttpServletRequest;
/**
* @Description TODO
* @Author
* @Date 2025/10/16 15:36
*/
public interface ISampleCollectAppManageAppService {
R<?> getSampleCollectList(SampleCollectManageDto sampleCollectManageDto, Integer pageNo, Integer pageSize, String searchKey, HttpServletRequest request);
R<?>updateSampleStatus(SampleCollectStatusRequest statusRequest);
}

View File

@@ -1,33 +0,0 @@
package com.openhis.web.Inspection.appservice;
import com.core.common.core.domain.R;
import com.openhis.administration.domain.SpecimenDefinition;
import com.openhis.web.Inspection.dto.SpecimenDefSelParam;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
/**
* @Description TODO
* @Author
* @Date 2025/9/9 16:46
*/
public interface ISpecimenManageAppService {
R<?> getManageInit();
R<?> getSpecimenPage(SpecimenDefSelParam specimenDefSelParam, String searchKey, Integer pageNo, Integer pageSize,
HttpServletRequest request);
R<?> updateOrAddSpecimen(SpecimenDefinition specimenDefinition);
R<?> getSpecimenOne(Long id);
R<?> editSpecimenStatus(List<Long> ids,Integer status);
}

View File

@@ -1,107 +0,0 @@
package com.openhis.web.Inspection.appservice.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
import com.core.common.utils.MessageUtils;
import com.openhis.administration.domain.Instrument;
import com.openhis.administration.mapper.InstrumentMapper;
import com.openhis.administration.service.IInstrumentService;
import com.openhis.common.constant.PromptMsgConstant;
import com.openhis.common.enums.InstrumentCategory;
import com.openhis.common.enums.PublicationStatus;
import com.openhis.common.utils.EnumUtils;
import com.openhis.common.utils.HisPageUtils;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.web.Inspection.appservice.IInstrumentManageAppService;
import com.openhis.web.Inspection.dto.InstrumentManageDto;
import com.openhis.web.Inspection.dto.InstrumentManageInitDto;
import com.openhis.web.Inspection.dto.InstrumentSelParam;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @Description 仪器信息
* @Author
* @Date 2025/9/18
*/
@Service
@RequiredArgsConstructor
public class InstrumentManageAppServiceImpl implements IInstrumentManageAppService {
private final IInstrumentService instrumentService ;
private final InstrumentMapper instrumentMapper ;
@Override
public R<?> getManageInit() {
InstrumentManageInitDto instrumentManageInitDto = new InstrumentManageInitDto();
// 获取状态
List<InstrumentManageInitDto.statusEnumOption> statusEnumOptions = Stream.of(PublicationStatus.values())
.map(status -> new InstrumentManageInitDto.statusEnumOption(status.getValue(), status.getInfo()))
.collect(Collectors.toList());
instrumentManageInitDto.setStatusFlagOptions(statusEnumOptions);
// 获取仪器种类
List<InstrumentManageInitDto.InstrumentType> typeList = Stream.of(com.openhis.common.enums.InstrumentCategory.values())
.map(status -> new InstrumentManageInitDto.InstrumentType(status.getValue(), status.getInfo()))
.collect(Collectors.toList());
instrumentManageInitDto.setInstrumentTypeList(typeList);
// 获取仪器状态
List<InstrumentManageInitDto.InstrumentStatusEnumOption> InstrumentStatusEnumOptions = Stream.of(com.openhis.common.enums.InstrumentStatus.values())
.map(status -> new InstrumentManageInitDto.InstrumentStatusEnumOption(status.getValue(), status.getInfo()))
.collect(Collectors.toList());
instrumentManageInitDto.setInstrumentStatusEnumList(InstrumentStatusEnumOptions);
return R.ok(instrumentManageInitDto);
}
@Override
public R<?> getInstrumentPage(InstrumentSelParam InstrumentSelParam, String searchKey, Integer pageNo, Integer pageSize, HttpServletRequest request) {
QueryWrapper<Instrument> queryWrapper = HisQueryUtils.buildQueryWrapper(InstrumentSelParam,
searchKey, new HashSet<>(Arrays.asList( "instrument_name", "instrument_name")), request);
Page<InstrumentManageDto> instrumentPage = HisPageUtils.selectPage(instrumentMapper, queryWrapper, pageNo, pageSize,InstrumentManageDto.class);
instrumentPage.getRecords().forEach(instrumentManageDto -> {
instrumentManageDto.setInstrumentTypeEnumText(EnumUtils.getInfoByValue(InstrumentCategory.class, instrumentManageDto.getInstrumentTypeEnum())) ;
});
return R.ok(instrumentPage);
}
@Override
public R<?> updateOrAddInstrument(Instrument instrument) {
instrumentService.saveOrUpdate( instrument);
return R.ok();
}
@Override
public R<?> getInstrumentOne(Long id)
{
Instrument byId = instrumentService.getById(id);
InstrumentManageDto dto = new InstrumentManageDto();
BeanUtils.copyProperties(byId,dto);
return R.ok(dto);
}
@Override
public R<?> editInstrumentStatus(List<Long> ids, Integer status) {
List<Instrument> instrumentList = new CopyOnWriteArrayList<>();
for (Long detail : ids) {
Instrument instrument = new Instrument();
instrument.setId(detail);
instrument.setUsageStatusEnum(status);
instrumentList.add(instrument);
}
return instrumentService.updateBatchById(instrumentList) ? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"仪器信息"})) : R.fail(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
}
}

View File

@@ -1,58 +0,0 @@
package com.openhis.web.Inspection.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.openhis.common.enums.AdministrativeGender;
import com.openhis.common.utils.EnumUtils;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.web.Inspection.appservice.ILaboratoryManageAppService;
import com.openhis.web.Inspection.dto.ReportResultManageDto;
import com.openhis.web.Inspection.mapper.LisReportMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
/**
* @Description 样本采集
* @Author
* @Date 2025/10/16
*/
@RequiredArgsConstructor
@Service
public class LaboratoryManageAppService implements ILaboratoryManageAppService {
private final LisReportMapper reportMapper;
@Override
public R<?> getReportResultList(ReportResultManageDto reportResultManageDto, Integer pageNo, Integer pageSize, String searchKey, HttpServletRequest request) {
QueryWrapper<ReportResultManageDto> queryWrapper =
HisQueryUtils.buildQueryWrapper(reportResultManageDto,
searchKey, new HashSet<>(Arrays.asList( "patient_name", "charge_name")), request);
IPage<ReportResultManageDto> reportResultList = reportMapper.getReportResultList(new Page<>(pageNo, pageSize), queryWrapper);
Long total = reportMapper.getReportResultListTotal(new Page<>(pageNo, pageSize), queryWrapper);
reportResultList.getRecords().forEach(e -> {
// 性别
e.setGenderEnumText(EnumUtils.getInfoByValue(AdministrativeGender.class, e.getGenderEnum()));
});
if(total == null){
//总条数为null
total = 0L;
}
reportResultList.setTotal(total);
return R.ok(reportResultList);
}
@Override
public R<?> getReportById(Long id) {
//根据id查询所有观测值
List<ReportResultManageDto> list = reportMapper.getReportListById(new QueryWrapper<ReportResultManageDto>().eq("id", id));
//打印组件配置
return null;
}
}

View File

@@ -1,233 +0,0 @@
package com.openhis.web.Inspection.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.utils.SecurityUtils;
import com.openhis.administration.domain.Device;
import com.openhis.administration.domain.DeviceDefinition;
import com.openhis.administration.domain.ObservationDefinition;
import com.openhis.administration.domain.SpecimenDefinition;
import com.openhis.administration.service.IDeviceDefinitionService;
import com.openhis.administration.service.IDeviceService;
import com.openhis.administration.service.IObservationDefinitionService;
import com.openhis.administration.service.ISpecimenDefinitionService;
import com.openhis.common.enums.SpecCollectStatus;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.lab.domain.*;
import com.openhis.lab.mapper.ActivityDefDeviceDefMapper;
import com.openhis.lab.mapper.ActivityDefObservationDefMapper;
import com.openhis.lab.mapper.ActivityDefSpecimenDefMapper;
import com.openhis.lab.service.IObservationService;
import com.openhis.lab.service.ISpecimenService;
import com.openhis.web.Inspection.appservice.ILisConfigManageAppService;
import com.openhis.web.Inspection.dto.LisConfigManageDto;
import com.openhis.web.Inspection.dto.LisConfigManageInitDto;
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentDto;
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentSelParam;
import com.openhis.web.datadictionary.mapper.ActivityDefinitionManageMapper;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
/**
* @Description TODO
* @Author
* @Date 2025/9/29
*/
@RequiredArgsConstructor
@Service
public class LisConfigManageAppServiceImpl implements ILisConfigManageAppService {
private static final Logger log = LoggerFactory.getLogger(LisConfigManageAppServiceImpl.class);
@Resource
private ActivityDefinitionManageMapper activityDefinitionManageMapper;
@Resource
private ActivityDefDeviceDefMapper activityDefDeviceDefMapper;
@Resource
private ActivityDefObservationDefMapper activityDefObservationDefMapper;
@Resource
private ActivityDefSpecimenDefMapper activityDefSpecimenDefMapper;
@Resource
private IDeviceDefinitionService deviceDefinitionService;
@Resource
private ISpecimenDefinitionService specimenDefinitionService;
@Resource
private IObservationDefinitionService observationDefinitionService;
@Resource
private IObservationService observationService;
@Resource
private ISpecimenService specimenService;
@Resource
private IDeviceService deviceService;
@Override
public R<?> getDiseaseTreatmentPage(DiagnosisTreatmentSelParam DiagnosisTreatmentSelParam, String searchKey, Integer pageNo, Integer pageSize, HttpServletRequest request) {
// 构建查询条件
QueryWrapper<DiagnosisTreatmentDto> queryWrapper = HisQueryUtils.buildQueryWrapper(DiagnosisTreatmentSelParam,
searchKey, new HashSet<>(Arrays.asList("bus_no", "name", "py_str", "wb_str")), request);
// 分页查询
IPage<DiagnosisTreatmentDto> diseaseTreatmentPage =
activityDefinitionManageMapper.getDiseaseTreatmentPage(new Page<>(pageNo, pageSize), queryWrapper);
return R.ok(diseaseTreatmentPage);
}
public R<?> getInfoList(String searchKey, String type) {
LisConfigManageInitDto initDto = new LisConfigManageInitDto();
initDto.setDeviceDefs(deviceDefinitionService.list());
initDto.setObservationDefs(observationDefinitionService.list());
initDto.setSpecimenDefs(specimenDefinitionService.list());
if (searchKey == null || searchKey.isEmpty()) {
// 如果searchKey为空则查询所有
return switch (type) {
case "device" -> R.ok(deviceDefinitionService.list(new QueryWrapper<DeviceDefinition>().eq("status_enum",2)));
case "observation" -> R.ok(observationDefinitionService.list(new QueryWrapper<ObservationDefinition>().eq("status_enum",2) ));
case "specimen" -> R.ok(specimenDefinitionService.list(new QueryWrapper<SpecimenDefinition>().eq("status_enum",2)));
default -> R.ok(initDto);
};
} else {
// 如果searchKey不为空则根据name模糊查询
return switch (type) {
case "device" ->
R.ok(deviceDefinitionService.list((new QueryWrapper<DeviceDefinition>().like("name", searchKey).eq("status_enum",2))));
case "observation" ->
R.ok(observationDefinitionService.list((new QueryWrapper<ObservationDefinition>().like("name", searchKey).eq("status_enum",2))));
case "specimen" ->
R.ok(specimenDefinitionService.list((new QueryWrapper<SpecimenDefinition>().like("name", searchKey).eq("status_enum",2))));
default -> R.ok();
};
}
}
@Override
public R<?> getInfoDetail(Long id) {
LisConfigManageDto manageDto = new LisConfigManageDto();
manageDto.setActivityDefDeviceDefs(activityDefDeviceDefMapper.selectList(new QueryWrapper<ActivityDefDeviceDef>().eq("activity_definition_id", id)));
manageDto.setActivityDefObservationDefs(activityDefObservationDefMapper.selectList(new QueryWrapper<ActivityDefObservationDef>().eq("activity_definition_id", id)));
manageDto.setActivityDefSpecimenDefs(activityDefSpecimenDefMapper.selectList(new QueryWrapper<ActivityDefSpecimenDef>().eq("activity_definition_id", id)));
return R.ok(manageDto);
}
@Override
@Transactional
public R<?> saveAll(LisConfigManageDto manageDto) {
try {
// 先全部删除项目下详情
activityDefDeviceDefMapper.delete(new QueryWrapper<ActivityDefDeviceDef>().eq("activity_definition_id", manageDto.getId()));
activityDefObservationDefMapper.delete(new QueryWrapper<ActivityDefObservationDef>().eq("activity_definition_id", manageDto.getId()));
activityDefSpecimenDefMapper.delete(new QueryWrapper<ActivityDefSpecimenDef>().eq("activity_definition_id", manageDto.getId()));
// 获取租户ID并验证
Integer tenantId = null;
try {
tenantId = SecurityUtils.getLoginUser().getTenantId();
} catch (Exception e) {
log.warn("获取租户ID失败使用默认值", e);
}
// 根据ID查询【诊疗目录】详情
DiagnosisTreatmentDto diseaseTreatmentOne = activityDefinitionManageMapper.getDiseaseTreatmentOne(manageDto.getId(), tenantId);
if (diseaseTreatmentOne == null) {
log.warn("未找到诊疗目录id={}, tenantId={}", manageDto.getId(), tenantId);
// 即使未找到诊疗目录也继续保存使用ID作为名称
String activityDefinitionName = String.valueOf(manageDto.getId());
manageDto.getActivityDefDeviceDefs().forEach(activityDefDeviceDef -> {
activityDefDeviceDef.setActivityDefinitionId(manageDto.getId());
activityDefDeviceDef.setActivityDefinitionName(activityDefinitionName);
activityDefDeviceDefMapper.insert(activityDefDeviceDef);
});
manageDto.getActivityDefObservationDefs().forEach(activityDefObservationDef -> {
activityDefObservationDef.setActivityDefinitionId(manageDto.getId());
activityDefObservationDef.setActivityDefinitionName(activityDefinitionName);
activityDefObservationDefMapper.insert(activityDefObservationDef);
});
manageDto.getActivityDefSpecimenDefs().forEach(activityDefSpecimenDef -> {
activityDefSpecimenDef.setActivityDefinitionId(manageDto.getId());
activityDefSpecimenDef.setActivityDefinitionName(activityDefinitionName);
activityDefSpecimenDefMapper.insert(activityDefSpecimenDef);
});
} else {
// 正常保存
manageDto.getActivityDefDeviceDefs().forEach(activityDefDeviceDef -> {
activityDefDeviceDef.setActivityDefinitionId(manageDto.getId());
activityDefDeviceDef.setActivityDefinitionName(diseaseTreatmentOne.getName());
activityDefDeviceDefMapper.insert(activityDefDeviceDef);
});
manageDto.getActivityDefObservationDefs().forEach(activityDefObservationDef -> {
activityDefObservationDef.setActivityDefinitionId(manageDto.getId());
activityDefObservationDef.setActivityDefinitionName(diseaseTreatmentOne.getName());
activityDefObservationDefMapper.insert(activityDefObservationDef);
});
manageDto.getActivityDefSpecimenDefs().forEach(activityDefSpecimenDef -> {
activityDefSpecimenDef.setActivityDefinitionId(manageDto.getId());
activityDefSpecimenDef.setActivityDefinitionName(diseaseTreatmentOne.getName());
activityDefSpecimenDefMapper.insert(activityDefSpecimenDef);
});
}
log.info("保存检验项目设置成功id={}, deviceCount={}, observationCount={}, specimenCount={}",
manageDto.getId(),
manageDto.getActivityDefDeviceDefs().size(),
manageDto.getActivityDefObservationDefs().size(),
manageDto.getActivityDefSpecimenDefs().size());
return R.ok("保存成功");
} catch (Exception e) {
log.error("保存检验项目设置失败id={}, error={}", manageDto.getId(), e.getMessage(), e);
return R.fail("保存失败:" + e.getMessage());
}
}
@Override
public R<?> createAll(Long patientId,Long ServiceId, Long itemId) {
// 根据ID查询检查项目详情
List<ActivityDefDeviceDef> devices = activityDefDeviceDefMapper.selectList(new QueryWrapper<ActivityDefDeviceDef>().eq("activity_definition_id", itemId));
List<ActivityDefObservationDef> observations= activityDefObservationDefMapper.selectList(new QueryWrapper<ActivityDefObservationDef>().eq("activity_definition_id", itemId));
List<ActivityDefSpecimenDef> specimens = activityDefSpecimenDefMapper.selectList(new QueryWrapper<ActivityDefSpecimenDef>().eq("activity_definition_id", itemId));
devices.forEach(activityDefDeviceDef -> {
Device device = new Device();
device.setDeviceDefId(activityDefDeviceDef.getDeviceDefinitionId());
device.setName(activityDefDeviceDef.getDeviceDefinitionName());
//TODO 器材实体待完善,生成器材请求
});
observations.forEach(activityDefObservationDef -> {
Observation observation = new Observation();
//TODO 初始字段具体观测定义字段待完善
observation.setPatientId(patientId);
observation.setObservationDefinitionId(activityDefObservationDef.getObservationDefinitionId());
observationService.save(observation);
});
specimens.forEach(activityDefSpecimenDef -> {
Specimen specimen = new Specimen();
//TODO 初始字段具体标本定义字段待完善
specimen.setServiceId(ServiceId);
specimen.setSpecimenDefinitionId(activityDefSpecimenDef.getSpecimenDefinitionId());
specimen.setPatientId(patientId);
specimen.setCollectionStatusEnum(SpecCollectStatus.PENDING.getValue());
specimen.setSpecimenUnit(activityDefSpecimenDef.getSpecimenUnit());
specimen.setSpecimenVolume(activityDefSpecimenDef.getSpecimenVolume());
specimenService.save(specimen);
});
return R.ok();
}
}

View File

@@ -1,137 +0,0 @@
package com.openhis.web.Inspection.appservice.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
import com.core.common.enums.DelFlag;
import com.core.common.utils.MessageUtils;
import com.core.common.utils.bean.BeanUtils;
import com.openhis.administration.domain.ObservationDefinition;
import com.openhis.administration.mapper.ObservationDefinitionMapper;
import com.openhis.administration.service.IInstrumentService;
import com.openhis.administration.service.IObservationDefinitionService;
import com.openhis.common.constant.PromptMsgConstant;
import com.openhis.common.enums.ObservationType;
import com.openhis.common.enums.PublicationStatus;
import com.openhis.common.utils.EnumUtils;
import com.openhis.common.utils.HisPageUtils;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.web.Inspection.appservice.IObservationManageAppService;
import com.openhis.web.Inspection.dto.ObservationDefManageDto;
import com.openhis.web.Inspection.dto.ObservationDefManageInitDto;
import com.openhis.web.Inspection.dto.ObservationDefSelParam;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @Description TODO
* @Author
* @Date 2025/9/23
*/
@Service
@RequiredArgsConstructor
public class ObservationManageAppServiceImpl implements IObservationManageAppService
{
private static final Logger log = LoggerFactory.getLogger(ObservationManageAppServiceImpl.class);
private final ObservationDefinitionMapper observationDefinitionMapper;
private final IObservationDefinitionService observationDefinitionService;
private final IInstrumentService instrumentService;
@Override
public R<?> getManageInit() {
ObservationDefManageInitDto observationDefManageInitDto = new ObservationDefManageInitDto();
// 获取状态
List<ObservationDefManageInitDto.statusEnumOption> statusEnumOptions = Stream.of(PublicationStatus.values())
.map(status -> new ObservationDefManageInitDto.statusEnumOption(status.getValue(), status.getInfo()))
.collect(Collectors.toList());
observationDefManageInitDto.setStatusFlagOptions(statusEnumOptions);
//观测类型
List<ObservationDefManageInitDto.ObservationTypeEnumOption> ObservationTypeEnumOptions = Stream.of(com.openhis.common.enums.ObservationType.values())
.map(status -> new ObservationDefManageInitDto.ObservationTypeEnumOption(status.getValue(), status.getInfo()))
.collect(Collectors.toList());
observationDefManageInitDto.setObservationTypeList(ObservationTypeEnumOptions);
//仪器列表
List<ObservationDefManageInitDto.InstrumentEnumOption> InstrumentEnumOptions = instrumentService.list().stream()
.map(status -> new ObservationDefManageInitDto.InstrumentEnumOption(status.getId(), status.getInstrumentName()))
.collect(Collectors.toList());
observationDefManageInitDto.setInstrumentEnumOptionList(InstrumentEnumOptions);
return R.ok(observationDefManageInitDto);
}
@Override
public R<?> getObservationDefPage(ObservationDefSelParam ObservationDefSelParam, String searchKey, Integer pageNo, Integer pageSize, HttpServletRequest request) {
QueryWrapper<ObservationDefinition> queryWrapper = HisQueryUtils.buildQueryWrapper(ObservationDefSelParam,
searchKey, new HashSet<>(Arrays.asList( "name", "code")), request);
Page<ObservationDefManageDto> ObservationPage = HisPageUtils.selectPage(observationDefinitionMapper, queryWrapper, pageNo, pageSize, ObservationDefManageDto.class);
ObservationPage.getRecords().forEach(item -> {
item.setInstrumentId_dictText(instrumentService.getById(item.getInstrumentId()).getInstrumentName());
item.setStatusEnumText(EnumUtils.getInfoByValue(PublicationStatus.class, item.getStatusEnum()));
item.setObservationTypeEnumText(EnumUtils.getInfoByValue(ObservationType.class, item.getObservationTypeEnum()));
});
return R.ok(ObservationPage);
}
@Override
public R<?> updateOrAddObservationDef(ObservationDefinition Observation) {
try {
Observation.setDeleteFlag(DelFlag.NO.getCode());
boolean result = observationDefinitionService.saveOrUpdate(Observation);
if (result) {
log.info("保存检验项目成功name={}, code={}, id={}",
Observation.getName(), Observation.getCode(), Observation.getId());
return R.ok("添加成功");
} else {
log.warn("保存检验项目失败name={}, code={}",
Observation.getName(), Observation.getCode());
return R.fail("添加失败:保存操作未成功");
}
} catch (Exception e) {
log.error("保存检验项目异常name={}, code={}, error={}",
Observation.getName(), Observation.getCode(), e.getMessage(), e);
return R.fail("添加失败:" + e.getMessage());
}
}
@Override
public R<?> getObservationDefOne(Long id) {
ObservationDefinition observationDefinition = observationDefinitionService.getById(id);
ObservationDefManageDto dto = new ObservationDefManageDto();
BeanUtils.copyProperties(observationDefinition,dto);
return R.ok(dto);
}
@Override
public R<?> editObservationDefStatus(List<Long> ids, Integer status) {
List<ObservationDefinition> observationDefinitionList = new CopyOnWriteArrayList<>();
for (Long detail : ids) {
ObservationDefinition observationDefinition = new ObservationDefinition();
observationDefinition.setId(detail);
observationDefinition.setStatusEnum(status);
observationDefinitionList.add(observationDefinition);
}
return observationDefinitionService.updateBatchById(observationDefinitionList) ? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"观测信息"}))
: R.fail(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
}
}

View File

@@ -1,105 +0,0 @@
package com.openhis.web.Inspection.appservice.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
import com.openhis.common.enums.AdministrativeGender;
import com.openhis.common.enums.SpecCollectStatus;
import com.openhis.common.utils.EnumUtils;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.lab.domain.Specimen;
import com.openhis.lab.service.ISpecimenService;
import com.openhis.web.Inspection.appservice.ISampleCollectAppManageAppService;
import com.openhis.web.Inspection.dto.SampleCollectManageDto;
import com.openhis.web.Inspection.dto.SampleCollectStatusRequest;
import com.openhis.web.Inspection.mapper.SampleCollectMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.Objects;
/**
* @Description 样本采集
* @Author
* @Date 2025/10/16
*/
@RequiredArgsConstructor
@Service
public class SampleCollectManageAppService implements ISampleCollectAppManageAppService {
private final SampleCollectMapper sampleCollectMapper;
private final ISpecimenService specimenService;
@Override
public R<?> getSampleCollectList(SampleCollectManageDto sampleCollectManageDto, Integer pageNo, Integer pageSize, String searchKey, HttpServletRequest request) {
QueryWrapper<SampleCollectManageDto> queryWrapper =
HisQueryUtils.buildQueryWrapper(sampleCollectManageDto,
searchKey, new HashSet<>(Arrays.asList( "patient_name", "charge_name")), request);
IPage<SampleCollectManageDto> sampleCollectList = sampleCollectMapper.getSampleCollectList(new Page<>(pageNo, pageSize), queryWrapper);
Long total = sampleCollectMapper.getSampleCollectListTotal(new Page<>(pageNo, pageSize), queryWrapper);
sampleCollectList.getRecords().forEach(e -> {
// 性别
e.setGenderEnumText(EnumUtils.getInfoByValue(AdministrativeGender.class, e.getGenderEnum()));
// 采集状态
e.setCollectionStatusEnumText(EnumUtils.getInfoByValue(SpecCollectStatus.class, e.getCollectionStatusEnum()));
});
if(total == null){
//总条数为null
total = 0L;
}
sampleCollectList.setTotal(total);
return R.ok(sampleCollectList);
}
@Override
public R<?> updateSampleStatus(SampleCollectStatusRequest statusRequest) {
// 根据状态类型设置对应的状态值
Integer status = switch (statusRequest.getType()) {
case "待采集" -> SpecCollectStatus.PENDING.getValue();
case "已采集" -> SpecCollectStatus.COLLECTED.getValue();
case "已接收" -> SpecCollectStatus.RECEIVED.getValue();
default -> 0;
};
// 批量更新样本状态
specimenService.listByIds(statusRequest.getIds()).forEach(specimen -> {
Integer currentStatus = specimen.getCollectionStatusEnum(); // 获取当前样本状态
// 如果传入状态是已接收,但当前状态是待采集,跳过更新
if (Objects.equals(status, SpecCollectStatus.RECEIVED.getValue()) && Objects.equals(currentStatus, SpecCollectStatus.PENDING.getValue())) {
return;
}
// 构建更新条件
UpdateWrapper<Specimen> updateWrapper = new UpdateWrapper<>();
updateWrapper.in("id", statusRequest.getIds()) // 设置批量更新的条件
.set("collection_status_enum", status); // 设置更新的状态字段
// 如果状态为已采集,且采集日期不为空,跳过采集日期的更新,仅更新状态
if (Objects.equals(status, SpecCollectStatus.COLLECTED.getValue())) {
if (specimen.getCollectionDate() == null) {
// 如果采集日期为空,则设置当前日期
updateWrapper.set("collection_date", new Date());
}
updateWrapper.set("received_date", null);
} else if (Objects.equals(status, SpecCollectStatus.PENDING.getValue())) {
updateWrapper.set("collection_date", null); // 清空采集日期
} else if (Objects.equals(status, SpecCollectStatus.RECEIVED.getValue())) {
updateWrapper.set("received_date", new Date());
}
// 执行更新
specimenService.update(updateWrapper);
});
if (Objects.equals(status, SpecCollectStatus.RECEIVED.getValue())) {
// TODO 接收样本后续逻辑
System.err.println("接收样本后!!");
}
return R.ok();
}
}

View File

@@ -1,110 +0,0 @@
package com.openhis.web.Inspection.appservice.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
import com.core.common.utils.MessageUtils;
import com.openhis.administration.domain.SpecimenDefinition;
import com.openhis.administration.mapper.SpecimenDefinitionMapper;
import com.openhis.administration.service.ISpecimenDefinitionService;
import com.openhis.common.constant.PromptMsgConstant;
import com.openhis.common.enums.PublicationStatus;
import com.openhis.common.enums.SpecimenType;
import com.openhis.common.utils.EnumUtils;
import com.openhis.common.utils.HisPageUtils;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.web.Inspection.appservice.ISpecimenManageAppService;
import com.openhis.web.Inspection.dto.SpecimenDefManageDto;
import com.openhis.web.Inspection.dto.SpecimenDefManageInitDto;
import com.openhis.web.Inspection.dto.SpecimenDefSelParam;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @Description
* @Author
* @Date 2025/9/9
*/
@Service
@RequiredArgsConstructor
public class SpecimenManageAppServiceImpl implements ISpecimenManageAppService {
private final SpecimenDefinitionMapper specimenDefinitionMapper;
private final ISpecimenDefinitionService specimenDefinitionService;
@Override
public R<?> getManageInit() {
SpecimenDefManageInitDto specimenDefManageInitDto = new SpecimenDefManageInitDto();
// 获取状态
List<SpecimenDefManageInitDto.statusEnumOption> statusEnumOptions = Stream.of(PublicationStatus.values())
.map(status -> new SpecimenDefManageInitDto.statusEnumOption(status.getValue(), status.getInfo()))
.collect(Collectors.toList());
specimenDefManageInitDto.setStatusFlagOptions(statusEnumOptions);
// 获取录种类
List<SpecimenDefManageInitDto.SpecimenType> typeList = Stream.of(SpecimenType.values())
.map(status -> new SpecimenDefManageInitDto.SpecimenType(status.getValue(), status.getInfo()))
.collect(Collectors.toList());
specimenDefManageInitDto.setSpecimenTypeList(typeList);
return R.ok(specimenDefManageInitDto);
}
/**
* 样本目录查询
* @param SpecimenDefSelParam 查询条件
* @param searchKey 查询条件-模糊查询
* @param pageNo 查询条件
* @param pageSize 查询条件
* @param request
* @return
*/
@Override
public R<?> getSpecimenPage(SpecimenDefSelParam SpecimenDefSelParam, String searchKey, Integer pageNo, Integer pageSize, HttpServletRequest request) {
QueryWrapper<SpecimenDefinition> queryWrapper = HisQueryUtils.buildQueryWrapper(SpecimenDefSelParam,
searchKey, new HashSet<>(Arrays.asList("custom_code", "specimen_name", "py_str", "wb_str")), request);
Page<SpecimenDefManageDto> specimenPage = HisPageUtils.selectPage(specimenDefinitionMapper, queryWrapper, pageNo, pageSize, SpecimenDefManageDto.class);
specimenPage.getRecords().forEach(specimenDefManageDto -> {
specimenDefManageDto.setSpecimenTypeEnumText(EnumUtils.getInfoByValue(SpecimenType.class, specimenDefManageDto.getSpecimenTypeEnum())) ;
specimenDefManageDto.setStatusEnumText(EnumUtils.getInfoByValue(PublicationStatus.class, specimenDefManageDto.getStatusEnum()));
});
return R.ok(specimenPage);
}
@Override
public R<?> updateOrAddSpecimen(SpecimenDefinition specimenDefinition) {
specimenDefinitionService.saveOrUpdate(specimenDefinition);
return R.ok(" 添加成功");
}
@Override
public R<?> getSpecimenOne(Long id) {
SpecimenDefinition specimenDefinition = specimenDefinitionService.getById(id);
return R.ok(specimenDefinition);
}
@Override
public R<?> editSpecimenStatus(List<Long> ids, Integer status) {
List<SpecimenDefinition> specimenDefinitionList = new CopyOnWriteArrayList<>();
for (Long detail : ids) {
SpecimenDefinition specimenDefinition = new SpecimenDefinition();
specimenDefinition.setId(detail);
specimenDefinition.setStatusEnum(status);
specimenDefinitionList.add(specimenDefinition);
}
return specimenDefinitionService.updateBatchById(specimenDefinitionList) ? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"样本信息"}))
: R.fail(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
}
}

View File

@@ -1,78 +0,0 @@
package com.openhis.web.Inspection.controller;
import com.core.common.core.domain.R;
import com.core.common.enums.DelFlag;
import com.openhis.administration.domain.Instrument;
import com.openhis.common.enums.PublicationStatus;
import com.openhis.web.Inspection.appservice.IInstrumentManageAppService;
import com.openhis.web.Inspection.dto.InstrumentSelParam;
import com.openhis.web.Inspection.dto.InstrumentStatusRequest;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
/**
* @Description 仪器器材信息
* @Author
* @Date 2025/9/18
*/
@RestController
@RequestMapping("/inspection/instrument")
@Slf4j
@AllArgsConstructor
public class InstrumentController {
private final IInstrumentManageAppService appService;
@GetMapping("/init")
public R<?> getDiseaseTreatmentInit() {
return appService.getManageInit();
}
/**
* 查询样本类型分页列表
*
* @param pageNo 当前页码
* @param pageSize 查询条数
* @return
*/
@GetMapping("/information-page")
public R<?> getInstrumentPage(InstrumentSelParam InstrumentSelParam,
@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request) {
return appService.getInstrumentPage(InstrumentSelParam,searchKey, pageNo, pageSize, request);
}
@PostMapping("/information")
public R<?> editInstrument(@Validated @RequestBody Instrument instrument) {
instrument.setDeleteFlag(DelFlag.NO.getCode());
return appService.updateOrAddInstrument(instrument);
}
@GetMapping("/information-one")
public R<?> getInstrument(@RequestParam Long id) {
return appService.getInstrumentOne(id);
}
@PostMapping("/information-status")
public R<?> updateInstrumentStatus( @RequestBody InstrumentStatusRequest InstrumentStatusRequest ) {
//默认停用
Integer status = PublicationStatus.RETIRED.getValue();
if("启用".equals( InstrumentStatusRequest.getType())){
status = PublicationStatus.ACTIVE.getValue();
}
return appService.editInstrumentStatus(InstrumentStatusRequest.getIds(),status);
}
}

View File

@@ -1,39 +0,0 @@
package com.openhis.web.Inspection.controller;
import com.core.common.core.domain.R;
import com.openhis.web.Inspection.appservice.ILaboratoryManageAppService;
import com.openhis.web.Inspection.dto.ReportResultManageDto;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
/**
* @Description 检测中心相关
* @Author
* @Date 2025/10/24
*/
@RestController
@RequestMapping("/inspection/laboratory")
@Slf4j
@AllArgsConstructor
public class LaboratoryController {
private final ILaboratoryManageAppService appService;
@GetMapping("/information-page")
public R<?> getReportResultPage(ReportResultManageDto reportResultManageDto, @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request) {
return appService.getReportResultList( reportResultManageDto, pageNo, pageSize, searchKey, request);
}
@GetMapping("/{id}")
public R<?> getReportById(@PathVariable Long id) {
// 调用 ReportService 获取报告数据
return appService.getReportById(id);
}
}

View File

@@ -1,67 +0,0 @@
package com.openhis.web.Inspection.controller;
import com.core.common.core.domain.R;
import com.openhis.web.Inspection.appservice.ILisConfigManageAppService;
import com.openhis.web.Inspection.dto.LisConfigManageDto;
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentSelParam;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
/**
* @Description 检验定义配置
* @Author
* @Date 2025/9/29
*/
@RestController
@RequestMapping("/inspection/lisConfig")
@Slf4j
@AllArgsConstructor
public class LisConfigController {
private ILisConfigManageAppService lisConfigManageAppService;
/**
* @Description 获取检验项目列表
* @Author
* @Date 2025/9/29
*/
@RequestMapping("/init-page")
public R<?> getDiseaseTreatmentList(DiagnosisTreatmentSelParam DiagnosisTreatmentSelParam, String searchKey,
Integer pageNo, Integer pageSize, HttpServletRequest request) {
return lisConfigManageAppService.getDiseaseTreatmentPage(DiagnosisTreatmentSelParam, searchKey, pageNo, pageSize, request);
}
/**
* 根据项目id获取详细
* @return
*/
@GetMapping ("/info-detail")
public R<?> getInfoDetail(Long id) {
return lisConfigManageAppService.getInfoDetail(id);
}
@GetMapping ("/init-list")
public R<?> getInfoList(String searchKey,String type) {
return lisConfigManageAppService.getInfoList(searchKey, type);
}
/**
* 修改检验配置
* @param
* @param manageDto
* @return
*/
@PostMapping("/saveAll")
public R<?> saveInfo(@RequestBody LisConfigManageDto manageDto) {
return lisConfigManageAppService.saveAll(manageDto);
}
}

View File

@@ -1,78 +0,0 @@
package com.openhis.web.Inspection.controller;
import com.core.common.core.domain.R;
import com.core.common.enums.DelFlag;
import com.openhis.administration.domain.ObservationDefinition;
import com.openhis.common.enums.PublicationStatus;
import com.openhis.web.Inspection.appservice.IObservationManageAppService;
import com.openhis.web.Inspection.dto.ObservationDefSelParam;
import com.openhis.web.Inspection.dto.ObservationDefStatusRequest;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
/**
* @Description 仪器器材信息
* @Author
* @Date 2025/9/18
*/
@RestController
@RequestMapping("/inspection/observation")
@Slf4j
@AllArgsConstructor
public class ObservationDefController {
private final IObservationManageAppService appService;
@GetMapping("/init")
public R<?> getTreatmentInit() {
return appService.getManageInit();
}
/**
* 查询样本类型分页列表
*
* @param pageNo 当前页码
* @param pageSize 查询条数
* @return
*/
@GetMapping("/information-page")
public R<?> getObservationPage(ObservationDefSelParam observationDefSelParam,
@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request) {
return appService.getObservationDefPage(observationDefSelParam,searchKey, pageNo, pageSize, request);
}
@PostMapping("/information")
public R<?> editObservation(@Validated @RequestBody ObservationDefinition observation) {
observation.setDeleteFlag(DelFlag.NO.getCode());
return appService.updateOrAddObservationDef(observation);
}
@GetMapping("/information-one")
public R<?> getObservation(@RequestParam Long id) {
return appService.getObservationDefOne(id);
}
@PostMapping("/information-status")
public R<?> updateObservationStatus( @RequestBody ObservationDefStatusRequest observationDefStatusRequest) {
//默认停用
Integer status = PublicationStatus.RETIRED.getValue();
if("启用".equals( observationDefStatusRequest.getType())){
status = PublicationStatus.ACTIVE.getValue();
}
return appService.editObservationDefStatus(observationDefStatusRequest.getIds(),status);
}
}

View File

@@ -1,39 +0,0 @@
package com.openhis.web.Inspection.controller;
import com.core.common.core.domain.R;
import com.openhis.web.Inspection.appservice.ISampleCollectAppManageAppService;
import com.openhis.web.Inspection.dto.SampleCollectManageDto;
import com.openhis.web.Inspection.dto.SampleCollectStatusRequest;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
/**
* @Description 样本采集
* @Author
* @Date 2025/10/16
*/
@RestController
@RequestMapping("/inspection/collection")
@Slf4j
@AllArgsConstructor
public class SampleCollectController {
private final ISampleCollectAppManageAppService appService;
@GetMapping("/information-page")
public R<?> getSampleCollectPage(SampleCollectManageDto sampleCollectManageDto,@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request) {
return appService.getSampleCollectList( sampleCollectManageDto, pageNo, pageSize, searchKey, request);
}
@PostMapping("/information-status")
public R<?> editSampleCollectStatus(@RequestBody SampleCollectStatusRequest statusRequest) {
return appService.updateSampleStatus(statusRequest);
}
}

View File

@@ -1,76 +0,0 @@
package com.openhis.web.Inspection.controller;
import com.core.common.core.domain.R;
import com.core.common.enums.DelFlag;
import com.openhis.administration.domain.SpecimenDefinition;
import com.openhis.common.enums.PublicationStatus;
import com.openhis.web.Inspection.appservice.ISpecimenManageAppService;
import com.openhis.web.Inspection.dto.SpecimenDefSelParam;
import com.openhis.web.Inspection.dto.SpecimenDefStatusRequest;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
/**
* @Description 样本定义相关
* @Author
* @Date 2025/9/9
*/
@RestController
@RequestMapping("/inspection/specimen")
@Slf4j
@AllArgsConstructor
public class SpecimenDefController {
private final ISpecimenManageAppService specimenManageAppService;
@GetMapping("/init")
public R<?> getDiseaseTreatmentInit() {
return specimenManageAppService.getManageInit();
}
/**
* 查询样本类型分页列表
*
* @param pageNo 当前页码
* @param pageSize 查询条数
* @return
*/
@GetMapping("/information-page")
public R<?> getSpecimenPage(SpecimenDefSelParam specimenDefSelParam,
@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request) {
return specimenManageAppService.getSpecimenPage(specimenDefSelParam,searchKey, pageNo, pageSize, request);
}
@PostMapping("/information")
public R<?> editSpecimen(@Validated @RequestBody SpecimenDefinition specimenDefinition) {
specimenDefinition.setStatusEnum( PublicationStatus.ACTIVE.getValue());
specimenDefinition.setDeleteFlag(DelFlag.NO.getCode());
return specimenManageAppService.updateOrAddSpecimen(specimenDefinition);
}
@GetMapping("/information-one")
public R<?> getSpecimen(@RequestParam Long id) {
return specimenManageAppService.getSpecimenOne(id);
}
@PostMapping("/information-status")
public R<?> updateSpecimenStatus( @RequestBody SpecimenDefStatusRequest specimenDefStatusRequest) {
//默认停用
Integer status = PublicationStatus.RETIRED.getValue();
if("启用".equals( specimenDefStatusRequest.getType())){
status = PublicationStatus.ACTIVE.getValue();
}
return specimenManageAppService.editSpecimenStatus(specimenDefStatusRequest.getIds(),status);
}
}

View File

@@ -1,111 +0,0 @@
package com.openhis.web.Inspection.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.common.annotation.Dict;
import lombok.Data;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
import java.util.Date;
/**
* @Description 分页返回
* @Author
* @Date 2025/9/17
*/
@Data
@Accessors(chain = true)
public class InstrumentManageDto {
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/** 仪器编号,唯一且不能为空 */
private String instrumentCode;
/** 仪器名称,必填项 */
private String instrumentName;
/** 仪器主编号 */
private String instrumentMainCode;
/** 仪器类型,选择项 */
private Integer instrumentTypeEnum;
private String instrumentTypeEnumText;
/** 仪器型号 */
private String instrumentModel;
/** 生产厂家 */
private String manufacturer;
/** 仪器序列号 */
private String serialNumber;
/** 购买公司 */
private String purchasingCompany;
/** 联系人员 */
private String contactPerson;
/** 购买日期 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date purchaseDate;
/** 原价格 */
private BigDecimal originalPrice;
/** 成交价格 */
private BigDecimal transactionPrice;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
/** 安装日期 */
private Date installationDate;
/** 安装人员 */
private String installationPerson;
/** 维护人员 */
private String maintenancePerson;
/** 所属科室 */
@Dict(dictTable = "adm_organization", dictCode = "id", dictText = "name")
@JsonSerialize(using = ToStringSerializer.class)
private Long orgId;
private String orgId_dictText;
/** 鉴定人员 */
private String identificationPerson;
/** 记录温度 */
private String recordedTemperature;
/** 仪器附件 */
private String accessories;
/** 仪器状态 */
private Integer instrumentStatusEnum;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
/** 报损日期 */
private Date damageReportDate;
/** 可复查仪器 是否 */
private Integer recheckableInstrumentEnum;
/** 使用状态,是否 */
private Integer usageStatusEnum;
/** 停用原因 */
private String decommissionReason;
/** 备注 */
private String remarks;
// 手动添加 getter 方法
public Integer getInstrumentTypeEnum() {
return instrumentTypeEnum;
}
}

View File

@@ -1,68 +0,0 @@
package com.openhis.web.Inspection.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
/**
*
*
* @author
* @date
*/
@Data
@Accessors(chain = true)
public class InstrumentManageInitDto {
private List<statusEnumOption> statusFlagOptions;
private List<InstrumentType> InstrumentTypeList;
private List<InstrumentStatusEnumOption> InstrumentStatusEnumList;
// 手动添加 setter 方法
public void setStatusFlagOptions(List<statusEnumOption> statusFlagOptions) {
this.statusFlagOptions = statusFlagOptions;
}
public void setInstrumentTypeList(List<InstrumentType> InstrumentTypeList) {
this.InstrumentTypeList = InstrumentTypeList;
}
public void setInstrumentStatusEnumList(List<InstrumentStatusEnumOption> InstrumentStatusEnumList) {
this.InstrumentStatusEnumList = InstrumentStatusEnumList;
}
/**
* 状态
*/
@Data
public static class statusEnumOption {
private Integer value;
private String info;
public statusEnumOption(Integer value, String info) {
this.value = value;
this.info = info;
}
}
@Data
public static class InstrumentStatusEnumOption {
private Integer value;
private String info;
public InstrumentStatusEnumOption(Integer value, String info) {
this.value = value;
this.info = info;
}
}
@Data
public static class InstrumentType {
private Integer value;
private String info;
public InstrumentType(Integer value, String info) {
this.value = value;
this.info = info;
}
}
}

View File

@@ -1,22 +0,0 @@
package com.openhis.web.Inspection.dto;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 样本定义分页检索条件
*
* @author lpt
* @date 2025-02-25
*/
@Data
@Accessors(chain = true)
public class InstrumentSelParam {
/** 仪器类型 */
private Integer instrumentTypeEnum;
/** 状态 */
private Integer statusEnum;
}

View File

@@ -1,25 +0,0 @@
package com.openhis.web.Inspection.dto;
import lombok.Data;
import java.util.List;
/**
* @Description TODO
* @Author
* @Date 2025/9/18
*/
@Data
public class InstrumentStatusRequest {
private List<Long> ids;
private String type;
// 手动添加 getter 方法
public String getType() {
return type;
}
public List<Long> getIds() {
return ids;
}
}

View File

@@ -1,63 +0,0 @@
package com.openhis.web.Inspection.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.lab.domain.ActivityDefDeviceDef;
import com.openhis.lab.domain.ActivityDefObservationDef;
import com.openhis.lab.domain.ActivityDefSpecimenDef;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
/**
* @Description TODO
* @Author
* @Date 2025/9/30
*/
@Data
@Accessors(chain = true)
public class LisConfigManageDto {
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
private List<ActivityDefDeviceDef> activityDefDeviceDefs;
private List<ActivityDefObservationDef> activityDefObservationDefs;
private List<ActivityDefSpecimenDef> activityDefSpecimenDefs;
// 手动添加 getter 和 setter 方法
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public List<ActivityDefDeviceDef> getActivityDefDeviceDefs() {
return activityDefDeviceDefs;
}
public void setActivityDefDeviceDefs(List<ActivityDefDeviceDef> activityDefDeviceDefs) {
this.activityDefDeviceDefs = activityDefDeviceDefs;
}
public List<ActivityDefObservationDef> getActivityDefObservationDefs() {
return activityDefObservationDefs;
}
public void setActivityDefObservationDefs(List<ActivityDefObservationDef> activityDefObservationDefs) {
this.activityDefObservationDefs = activityDefObservationDefs;
}
public List<ActivityDefSpecimenDef> getActivityDefSpecimenDefs() {
return activityDefSpecimenDefs;
}
public void setActivityDefSpecimenDefs(List<ActivityDefSpecimenDef> activityDefSpecimenDefs) {
this.activityDefSpecimenDefs = activityDefSpecimenDefs;
}
}

View File

@@ -1,38 +0,0 @@
package com.openhis.web.Inspection.dto;
import com.openhis.administration.domain.DeviceDefinition;
import com.openhis.administration.domain.ObservationDefinition;
import com.openhis.administration.domain.SpecimenDefinition;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
/**
* @Description TODO
* @Author
* @Date 2025/10/10
*/
@Data
@Accessors(chain = true)
public class LisConfigManageInitDto {
private List <DeviceDefinition> deviceDefs;
private List<ObservationDefinition> observationDefs;
private List<SpecimenDefinition> specimenDefs;
// 手动添加 setter 方法
public void setDeviceDefs(List<DeviceDefinition> deviceDefs) {
this.deviceDefs = deviceDefs;
}
public void setObservationDefs(List<ObservationDefinition> observationDefs) {
this.observationDefs = observationDefs;
}
public void setSpecimenDefs(List<SpecimenDefinition> specimenDefs) {
this.specimenDefs = specimenDefs;
}
}

View File

@@ -1,59 +0,0 @@
package com.openhis.web.Inspection.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.common.annotation.Dict;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @Description 分页返回
* @Author
* @Date 2025/9/17
*/
@Data
@Accessors(chain = true)
public class ObservationDefManageDto {
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/** 观测名称,用于标识观测的具体名称 */
private String name;
/** 观测代码,用于唯一标识一个观测项 */
private String code;
/** 观测类型,例如:实验室、临床症状等 */
private Integer observationTypeEnum;
private String observationTypeEnumText;
/** 参考范围例如3.0-6.0 mg/dL用于指示正常范围 */
private String referenceRange;
@Dict(dictTable = "adm_instrument", dictCode = "id", dictText = "instrument_name")
/** 观测仪器id */
private Long instrumentId;
private String instrumentId_dictText;
/** 状态 */
private Integer statusEnum;
private String statusEnumText;
/** 删除状态) */
private String deleteFlag;
// 手动添加 getter 方法
public Long getInstrumentId() {
return instrumentId;
}
public Integer getStatusEnum() {
return statusEnum;
}
public Integer getObservationTypeEnum() {
return observationTypeEnum;
}
}

View File

@@ -1,66 +0,0 @@
package com.openhis.web.Inspection.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
/**
*
*
* @author
* @date
*/
@Data
@Accessors(chain = true)
public class ObservationDefManageInitDto {
private List<statusEnumOption> statusFlagOptions;
private List<ObservationTypeEnumOption> ObservationTypeList;
private List<InstrumentEnumOption> instrumentEnumOptionList;
// 手动添加 setter 方法
public void setStatusFlagOptions(List<statusEnumOption> statusFlagOptions) {
this.statusFlagOptions = statusFlagOptions;
}
public void setObservationTypeList(List<ObservationTypeEnumOption> ObservationTypeList) {
this.ObservationTypeList = ObservationTypeList;
}
public void setInstrumentEnumOptionList(List<InstrumentEnumOption> instrumentEnumOptionList) {
this.instrumentEnumOptionList = instrumentEnumOptionList;
}
/**
* 状态
*/
@Data
public static class statusEnumOption {
private Integer value;
private String info;
public statusEnumOption(Integer value, String info) {
this.value = value;
this.info = info;
}
}
@Data
public static class ObservationTypeEnumOption {
private Integer value;
private String info;
public ObservationTypeEnumOption(Integer value, String info) {
this.value = value;
this.info = info;
}
}
@Data
public static class InstrumentEnumOption {
private Long value;
private String info;
public InstrumentEnumOption(Long value, String info) {
this.value = value;
this.info = info;
}
}
}

View File

@@ -1,22 +0,0 @@
package com.openhis.web.Inspection.dto;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 样本定义分页检索条件
*
* @author lpt
* @date 2025-02-25
*/
@Data
@Accessors(chain = true)
public class ObservationDefSelParam {
/** 类型 */
private Integer observationTypeEnum;
/** 状态 */
private Integer statusEnum;
}

View File

@@ -1,25 +0,0 @@
package com.openhis.web.Inspection.dto;
import lombok.Data;
import java.util.List;
/**
* @Description TODO
* @Author
* @Date 2025/9/18
*/
@Data
public class ObservationDefStatusRequest {
private List<Long> ids;
private String type;
// 手动添加 getter 方法
public String getType() {
return type;
}
public List<Long> getIds() {
return ids;
}
}

View File

@@ -1,39 +0,0 @@
package com.openhis.web.Inspection.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
/**
* @Description TODO
* @Author
* @Date 2025/10/17
*/
@Data
public class ReportResultManageDto {
@JsonSerialize(using = ToStringSerializer.class)
private Long parentId;
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
private String patientName; // 患者名称
private String chargeName; // 项目名称
private String specimenName; // 样本名称
private String doctorName; // 开单医生
private String observationName;//观测定义名称
private String observationResult; // 观测结果
private String referenceRange; // 参考范围
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private String observationDate;//观测时间
private Integer genderEnum; // 性别
private String genderEnumText;// 性别文本
private String technicianName;// 检查人员
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private String authoredTime; // 开单时间
// 手动添加 getter 方法
public Integer getGenderEnum() {
return genderEnum;
}
}

View File

@@ -1,51 +0,0 @@
package com.openhis.web.Inspection.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import java.util.Date;
/**
* @Description TODO
* @Author
* @Date 2025/10/17
*/
@Data
public class SampleCollectManageDto {
@JsonSerialize(using = ToStringSerializer.class)
private Long parentId;
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
private String patientName; // 患者名称
private String chargeName; // 项目名称
private String specimenName; // 样本名称
private String doctorName; // 开单医生
private Integer specimenVolume; //样本量
private String specimenUnit; //样本单位
private Integer genderEnum; // 性别
private String genderEnumText;// 性别文本
private Integer collectionStatusEnum;//采集状态
private String collectionStatusEnumText; // 采集状态文本
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date collectionDate; // 采集时间
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date receivedDate; // 接收时间
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private String authoredTime; // 开单时间
// 手动添加 getter 方法
public Integer getGenderEnum() {
return genderEnum;
}
public Integer getCollectionStatusEnum() {
return collectionStatusEnum;
}
}

View File

@@ -1,25 +0,0 @@
package com.openhis.web.Inspection.dto;
import lombok.Data;
import java.util.List;
/**
* @Description TODO
* @Author
* @Date 2025/10/23
*/
@Data
public class SampleCollectStatusRequest {
private List<Long> ids;
private String type;
// 手动添加 getter 方法
public String getType() {
return type;
}
public List<Long> getIds() {
return ids;
}
}

View File

@@ -1,70 +0,0 @@
package com.openhis.web.Inspection.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @Description 分页返回
* @Author
* @Date 2025/9/17
*/
@Data
@Accessors(chain = true)
public class SpecimenDefManageDto {
/** $column.columnComment */
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/** 样本类型 */
private Integer specimenTypeEnum;
private String specimenTypeEnumText;
/** 样本名称 */
private String specimenName;
/** 自定义码 */
private String customCode;
/** 类型顺序 */
private Integer typeOrder;
/** 外部代码 */
private String externalCode;
/** 序号 */
private Integer serialNumber;
/** 全网型 */
private String globalType;
/** 拼音 */
private String pyStr;
/** 五笔 */
private String wbStr;
/** 样本类 */
private String specimenClass;
/** 扩展类型 */
private String extendedType;
/** WHONET代码 */
private String whonetCode;
/** 状态 */
private Integer statusEnum;
private String statusEnumText;
// 手动添加 getter 方法
public Integer getSpecimenTypeEnum() {
return specimenTypeEnum;
}
public Integer getStatusEnum() {
return statusEnum;
}
}

View File

@@ -1,54 +0,0 @@
package com.openhis.web.Inspection.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.ArrayList;
import java.util.List;
/**
*
*
* @author
* @date
*/
@Data
@Accessors(chain = true)
public class SpecimenDefManageInitDto {
private List<statusEnumOption> statusFlagOptions;
private List<SpecimenType> SpecimenTypeList;
// 手动添加 setter 方法
public void setStatusFlagOptions(List<statusEnumOption> statusFlagOptions) {
this.statusFlagOptions = statusFlagOptions;
}
public void setSpecimenTypeList(List<SpecimenType> SpecimenTypeList) {
this.SpecimenTypeList = SpecimenTypeList;
}
/**
* 状态
*/
@Data
public static class statusEnumOption {
private Integer value;
private String info;
public statusEnumOption(Integer value, String info) {
this.value = value;
this.info = info;
}
}
@Data
public static class SpecimenType {
private Integer value;
private String info;
List<SpecimenType> children = new ArrayList<>();
public SpecimenType(Integer value, String info) {
this.value = value;
this.info = info;
}
}
}

View File

@@ -1,22 +0,0 @@
package com.openhis.web.Inspection.dto;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 样本定义分页检索条件
*
* @author lpt
* @date 2025-02-25
*/
@Data
@Accessors(chain = true)
public class SpecimenDefSelParam {
/** 样本类型 */
private Integer specimenTypeEnum;
/** 状态 */
private Integer statusEnum;
}

View File

@@ -1,25 +0,0 @@
package com.openhis.web.Inspection.dto;
import lombok.Data;
import java.util.List;
/**
* @Description TODO
* @Author
* @Date 2025/9/18
*/
@Data
public class SpecimenDefStatusRequest {
private List<Long> ids;
private String type;
// 手动添加 getter 方法
public String getType() {
return type;
}
public List<Long> getIds() {
return ids;
}
}

View File

@@ -1,11 +0,0 @@
package com.openhis.web.Inspection.mapper;
/**
* @Description TODO
* @Author
* @Date 2025/10/24 16:40
*/
public interface GroupRecMapper {
}

View File

@@ -1,26 +0,0 @@
package com.openhis.web.Inspection.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.Inspection.dto.ReportResultManageDto;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @Description TODO
* @Author
* @Date 2025/11/5 9:36
*/
@Mapper
public interface LisReportMapper {
IPage<ReportResultManageDto> getReportResultList(@Param("page") Page<ReportResultManageDto> page, @Param(Constants.WRAPPER) QueryWrapper<ReportResultManageDto> queryWrapper);
Long getReportResultListTotal (@Param("page")Page<ReportResultManageDto> page, @Param(Constants.WRAPPER) QueryWrapper<ReportResultManageDto> queryWrapper);
List<ReportResultManageDto> getReportListById(@Param(Constants.WRAPPER) QueryWrapper<ReportResultManageDto> queryWrapper);
}

View File

@@ -1,23 +0,0 @@
package com.openhis.web.Inspection.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.Inspection.dto.SampleCollectManageDto;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* @Description TODO
* @Author
* @Date 2025/10/17 11:27
*/
@Mapper
public interface SampleCollectMapper {
IPage<SampleCollectManageDto> getSampleCollectList(@Param("page")Page<SampleCollectManageDto> page, @Param(Constants.WRAPPER) QueryWrapper<SampleCollectManageDto> queryWrapper);
Long getSampleCollectListTotal (@Param("page")Page<SampleCollectManageDto> page, @Param(Constants.WRAPPER) QueryWrapper<SampleCollectManageDto> queryWrapper);
}

View File

@@ -1,203 +0,0 @@
package com.openhis.web.adjustprice.appservice;
import com.core.common.core.domain.R;
import com.openhis.web.adjustprice.dto.AdjustPriceDataVo;
import com.openhis.web.adjustprice.dto.AdjustPriceManagerSearchParam;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
/**
* Desc: 调价业务接口
*
* @Author raymond
* @Date 08:42 2025/10/16
* @return
**/
public interface IAdjustPriceService {
/**
* Desc: 保存调价数据
*
* @param dataVoList 前端数据集合
* @Author raymond
* @Date 08:57 2025/10/16
* @return com.core.common.core.domain.R<?>
**/
R<?> submitChangePriceData(List<AdjustPriceDataVo> dataVoList);
/**
* Desc: 保存并提交审核调价数据
*
* @param dataVoList
* @Author raymond
* @Date 16:22 2025/10/23
* @return com.core.common.core.domain.R<?>
**/
R<?> submitExamineChangePriceData(List<AdjustPriceDataVo> dataVoList);
/**
* Desc: 根据关键词查询 药品|耗材|诊疗 集合的最后价格
*
* @param searchKey
* @Author raymond
* @Date 09:32 2025/10/20
* @return java.util.List<?>
**/
R<?> searchKeyWordDataListByMed(String searchKey);
/**
* Desc: 根据关键词查询 药品|耗材|诊疗 集合的最后价格
*
* @param searchKey
* @Author raymond
* @Date 09:32 2025/10/20
* @return java.util.List<?>
**/
R<?> searchKeyWordDataListByDevice(String searchKey);
/**
* Desc: 根据关键词查询 药品|耗材|诊疗 集合的最后价格
*
* @param searchKey
* @Author raymond
* @Date 09:32 2025/10/20
* @return java.util.List<?>
**/
R<?> searchKeyWordDataListByActivity(String searchKey);
/**
* Desc: 查询提交的改价数据
*
* @param adjustPriceManagerSearchParam
* @param pageNo
* @param pageSize
* @param searchKey
* @param request
* @Author raymond
* @Date 23:39 2025/11/1
* @return com.core.common.core.domain.R<?>
**/
R<?> searchChangePriceSubmitDataToPage(AdjustPriceManagerSearchParam adjustPriceManagerSearchParam, Integer pageNo,
Integer pageSize, String searchKey, HttpServletRequest request);
/**
* Desc: 根据busNo 查询调价单详情 med
*
* @param busNo
* @Author raymond
* @Date 13:15 2025/10/21
* @return com.core.common.core.domain.R<?>
**/
R<?> searchChangePriceDataByMed(String busNo);
/**
* Desc: 根据busNo 查询调价单详情 med
*
* @param busNo
* @Author raymond
* @Date 13:15 2025/10/21
* @return com.core.common.core.domain.R<?>
**/
R<?> searchChangePriceDataByDevice(String busNo);
/**
* Desc: 根据busNo 查询调价单详情 Activity
*
* @param busNo
* @Author raymond
* @Date 13:15 2025/10/21
* @return com.core.common.core.domain.R<?>
**/
R<?> searchChangePriceDataByActivity(String busNo);
/**
* Desc: 根据busNo 查询调价单详情 Health
*
* @param busNo
* @Author raymond
* @Date 13:15 2025/10/21
* @return com.core.common.core.domain.R<?>
**/
R<?> searchChangePriceDataByHealth(String busNo);
/**
* Desc: 修改调价原因 和 价格
*
* @param busNo
* @Author raymond
* @Date 15:21 2025/10/21
* @return com.core.common.core.domain.R<?>
**/
R<?> cancelChangePriceData(String busNo);
/**
* Desc: 查询有挂号信息的科室
*
* @param
* @Author raymond
* @Date 16:38 2025/10/22
* @return com.core.common.core.domain.R<?>
**/
R<?> searchAllOrgData();
/**
* Desc: 根据科室id 加载挂号数据
*
* @param orgId
* @Author raymond
* @Date 16:45 2025/10/22
* @return com.core.common.core.domain.R<?>
**/
R<?> searchHealthData(Long orgId);
/**
* Desc: 根据业务单据号 进行单据提交操作
*
* @param busNo
* @Author raymond
* @Date 09:25 2025/10/23
* @return com.core.common.core.domain.R<?>
**/
R<?> updateExamineByApproval(String busNo);
/**
* Desc: 根据药品ID 是否在审核中
*
* @param itemId
* @Author raymond
* @Date 17:48 2025/11/3
* @return com.core.common.core.domain.R<?>
**/
R<?> checkMedApprovalExist(Long itemId);
/**
* Desc: 根据耗材ID 是否在审核中
*
* @param itemId
* @Author raymond
* @Date 17:48 2025/11/3
* @return com.core.common.core.domain.R<?>
**/
R<?> checkDeviceApprovalExist(Long itemId);
/**
* Desc: 根据诊疗ID 是否在审核中
*
* @param itemId
* @Author raymond
* @Date 17:48 2025/11/3
* @return com.core.common.core.domain.R<?>
**/
R<?> checkActivityApprovalExist(Long itemId);
/**
* Desc: 根据挂号ID 是否在审核中
*
* @param itemId
* @Author raymond
* @Date 17:48 2025/11/3
* @return com.core.common.core.domain.R<?>
**/
R<?> checkHealthApprovalExist(Long itemId);
}

View File

@@ -1,592 +0,0 @@
package com.openhis.web.adjustprice.appservice.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
import com.core.common.core.domain.entity.SysDictData;
import com.core.common.enums.AdjustPriceEnum;
import com.core.common.utils.AssignSeqUtil;
import com.core.common.utils.MessageUtils;
import com.core.common.utils.SecurityUtils;
import com.core.system.service.ISysDictDataService;
import com.openhis.administration.domain.ChangePriceRecord;
import com.openhis.administration.dto.ChangePriceDataDto;
import com.openhis.administration.dto.ChargeItemDefDetailPriceDto;
import com.openhis.administration.dto.HealthcareDto;
import com.openhis.administration.dto.OrgDataDto;
import com.openhis.administration.service.*;
import com.openhis.common.constant.CommonConstants;
import com.openhis.common.constant.PromptMsgConstant;
import com.openhis.common.enums.*;
import com.openhis.common.utils.EnumUtils;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.common.utils.RedisKeys;
import com.openhis.common.utils.RedisUtil;
import com.openhis.medication.service.IMedicationService;
import com.openhis.web.adjustprice.appservice.IAdjustPriceService;
import com.openhis.web.adjustprice.dto.AdjustPriceDataVo;
import com.openhis.web.adjustprice.dto.AdjustPriceManagerSearchParam;
import com.openhis.web.adjustprice.dto.ChangePricePageDto;
import com.openhis.web.adjustprice.mapper.AdjustPriceMapper;
import com.openhis.web.inventorymanage.dto.InventorySearchParam;
import com.openhis.workflow.dto.ActivityDto;
import com.openhis.workflow.dto.AdjustPriceDto;
import com.openhis.workflow.service.IActivityDefinitionService;
import com.openhis.workflow.service.IInventoryItemService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* @ClassName AdjustPriceServiceImpl
* @Description 调价业务实现
* @Author raymond
* @Date 2025/10/15 16:10
* @Version 1.0
**/
@Service
public class AdjustPriceServiceImpl implements IAdjustPriceService {
@Resource
private IInventoryItemService inventoryItemService;
@Resource
private IActivityDefinitionService activityDefinitionService;
@Resource
private IHealthcareServiceService healthcareServiceService;
@Resource
private IMedicationService medicationService;
@Resource
private AdjustPriceMapper adjustPriceMapper;
@Resource
private IDeviceDefinitionService deviceDefinitionService;
@Resource
private IOrganizationService organizationService;
@Resource
private IChargeItemDefinitionService chargeItemDefinitionService;
@Resource
private IChangePriceRecordService changePriceRecordService;
@Resource
private ISysDictDataService sysDictDataService;
@Resource
private AssignSeqUtil assignSeqUtil;
@Resource
private RedisUtil redisUtil;
@Override
@Transactional(rollbackFor = Exception.class)
public R<?> submitChangePriceData(List<AdjustPriceDataVo> dataVoList) {
if (dataVoList.isEmpty()) {
return R.fail(MessageUtils.createMessage(PromptMsgConstant.AdjustPrice.M00001, null));
}
if (dataVoList.stream()
.anyMatch(data -> this.redisUtil.hasKey(RedisKeys.getProductsKey(data.getItemId().toString())))) {
return R.fail(MessageUtils.createMessage(PromptMsgConstant.AdjustPrice.M00002, null));
}
//获取数据中的类型
Integer categoryType = dataVoList.get(0).getCategoryType();
// 单据号
String busNo = assignSeqUtil.getSeqByDay(AssignSeqEnum.CHANGE_PRICE_BUZ.getPrefix());
// 当前人
Long practitionerId = SecurityUtils.getLoginUser().getPractitionerId();
// 根据表单提交的tab 进入不同的 execute
if (AdjustPriceEnum.MEDICINE.getCode().equals(categoryType)
|| AdjustPriceEnum.CONSUMABLES.getCode().equals(categoryType)) {
//如果是 药品或者是耗材 因为药品和耗材的价格取的是 charge_detail表
this.executeChangePriceForMedication(dataVoList, busNo, practitionerId, categoryType);
} else if (AdjustPriceEnum.DIAGNOSIS.getCode().equals(categoryType)) {
//如果是 如果是 诊疗, 取价格主表
this.executeChangePriceForActivity(dataVoList, busNo, practitionerId);
} else {
//如果是 如果是 挂号, 取价格主表
this.executeChangePriceForHealth(dataVoList, busNo, practitionerId);
}
return R.ok();
}
@Override
public R<?> submitExamineChangePriceData(List<AdjustPriceDataVo> dataVoList) {
if (dataVoList.isEmpty()) {
return R.fail(MessageUtils.createMessage(PromptMsgConstant.AdjustPrice.M00001, null));
}
if (dataVoList.stream()
.anyMatch(data -> this.redisUtil.hasKey(RedisKeys.getProductsKey(data.getItemId().toString())))) {
return R.fail(MessageUtils.createMessage(PromptMsgConstant.AdjustPrice.M00002, null));
}
//获取数据中的类型
Integer categoryType = dataVoList.get(0).getCategoryType();
// 单据号
String busNo = assignSeqUtil.getSeqByDay(AssignSeqEnum.CHANGE_PRICE_BUZ.getPrefix());
// 当前人
Long practitionerId = SecurityUtils.getLoginUser().getPractitionerId();
// 根据表单提交的tab 进入不同的 execute
if (AdjustPriceEnum.MEDICINE.getCode().equals(categoryType)
|| AdjustPriceEnum.CONSUMABLES.getCode().equals(categoryType)) {
this.executeChangePriceForMedicationExamine(dataVoList, busNo, practitionerId, categoryType);
} else if (AdjustPriceEnum.DIAGNOSIS.getCode().equals(categoryType)) {
this.executeChangePriceForActivityExamine(dataVoList, busNo, practitionerId);
} else {
this.executeChangePriceForHealthExamine(dataVoList, busNo, practitionerId);
}
return R.ok();
}
@Override
public R<?> searchKeyWordDataListByMed(String searchKey) {
//如果 searchKey == null 默认返回10条反则 查询所有
return R.ok(this.medicationService.searchMedListByKeyWord(searchKey));
}
@Override
public R<?> searchKeyWordDataListByDevice(String searchKey) {
//如果 searchKey == null 默认返回10条反则 查询所有
return R.ok(this.deviceDefinitionService.searchDeviceListByKeyWord(searchKey));
}
@Override
public R<?> searchKeyWordDataListByActivity(String searchKey) {
//如果 searchKey == null 默认返回10条反则 查询所有
return R.ok(this.activityDefinitionService.searchActivityListByKeyWord(searchKey));
}
@Override
public R<?> searchChangePriceSubmitDataToPage(AdjustPriceManagerSearchParam adjustPriceManagerSearchParam,
Integer pageNo, Integer pageSize, String searchKey, HttpServletRequest request) {
Long practitionerId = SecurityUtils.getLoginUser().getPractitionerId();
HashSet<String> searchFields = new HashSet<>();
searchFields.add(CommonConstants.FieldName.BusNo);
// 构建查询条件
QueryWrapper<InventorySearchParam> queryWrapper =
HisQueryUtils.buildQueryWrapper(adjustPriceManagerSearchParam, searchKey, searchFields, request);
// 查询入库单据分页列表
Page<ChangePricePageDto> changePricePageDtoPage = this.adjustPriceMapper.searchChangePriceDataToPage(
new Page<>(pageNo, pageSize), queryWrapper, SupplyType.REQUEST_MEDICATION_CHANGE_PRICE.getValue(),
SupplyType.REQUEST_DEVICE_CHANGE_PRICE.getValue(), SupplyType.REQUEST_ACTIVITY_CHANGE_PRICE.getValue(),
SupplyType.REQUEST_HEALTH_CHANGE_PRICE.getValue(), practitionerId);
changePricePageDtoPage.getRecords().forEach(e -> {
e.setStatusEnum_enumText(EnumUtils.getInfoByValue(SupplyStatus.class, e.getStatusEnum()));
e.setCategoryEnum_enumText(EnumUtils.getInfoByValue(SupplyType.class, e.getItemCategoryEnum()));
});
return R.ok(changePricePageDtoPage);
}
@Override
public R<?> searchChangePriceDataByMed(String busNo) {
// 根据 单据号 查询 药品详情
List<ChangePriceDataDto> dataList = this.changePriceRecordService.searchMedChangePriceByBusNo(busNo,
SupplyType.REQUEST_MEDICATION_CHANGE_PRICE.getValue(), null);
// 获取 药品的单位
for (ChangePriceDataDto changePriceDataDto : dataList) {
SysDictData sysDictData =
sysDictDataService.selectDictInfo(CommonConstants.FieldName.UnitCode, changePriceDataDto.getUnitCode());
changePriceDataDto.setLabel(sysDictData.getDictLabel());
}
return R.ok(dataList);
}
@Override
public R<?> searchChangePriceDataByDevice(String busNo) {
//根据 单据号 耗材调价单详情
return R.ok(this.changePriceRecordService.searchDeviceChangePriceByBusNo(busNo,
SupplyType.REQUEST_DEVICE_CHANGE_PRICE.getValue(), null));
}
@Override
public R<?> searchChangePriceDataByActivity(String busNo) {
//根据 单据号 查询 诊疗调价单详情
return R.ok(this.changePriceRecordService.searchActivityChangePriceByBusNo(busNo,
SupplyType.REQUEST_ACTIVITY_CHANGE_PRICE.getValue(), null));
}
@Override
public R<?> searchChangePriceDataByHealth(String busNo) {
//根据 单据号 挂号调价单详情
return R.ok(this.changePriceRecordService.searchHealthChangePriceByBusNo(busNo,
SupplyType.REQUEST_HEALTH_CHANGE_PRICE.getValue(), null));
}
@Override
public R<?> cancelChangePriceData(String busNo) {
//根据 单据号查询出 当前所有请求调价的数据集
List<ChangePriceRecord> changePriceRecordList =
this.changePriceRecordService.searchChangePriceDataForBusNo(busNo);
//循环数据集合,将状态修改为 无效状态
for (ChangePriceRecord data : changePriceRecordList) {
ChangePriceRecord changePriceRecord = this.changePriceRecordService.getById(data.getId());
changePriceRecord.setStatusEnum(SupplyStatus.EXPIRED_INVALIDATED.getValue());
this.changePriceRecordService.updateById(changePriceRecord);
}
return R.ok();
}
@Override
public R<?> searchAllOrgData() {
//查询所有科室
List<OrgDataDto> orgDataList = this.organizationService.searchOrgDataByHealth();
return R.ok(orgDataList);
}
@Override
public R<?> searchHealthData(Long orgId) {
//根据科室ID 查询所有号源
return R.ok(this.healthcareServiceService.searchAllHeathData(orgId,PublicationStatus.ACTIVE.getValue()));
}
@Override
public R<?> updateExamineByApproval(String busNo) {
//根据调价单编号 查询 分组后的 数据
List<ChangePriceRecord> changePriceRecordList =
this.changePriceRecordService.searchChangePriceDataGroupByBusNo(busNo);
if (!changePriceRecordList.isEmpty()) {
// 循环将数据进行填充
for (ChangePriceRecord data : changePriceRecordList) {
//提交 审批时,查看是否有正在审核中的 货品数据 。根据 货品ID 从redis中查询
if (this.redisUtil.hasKey(RedisKeys.getProductsKey(data.getItemId().toString()))) {
return R.fail(MessageUtils.createMessage(PromptMsgConstant.AdjustPrice.M00002, null));
}
//如果不存在向redis中插入 药品信息 = 给当前 货品上锁 。审批通过或驳回后 释放
this.redisUtil.set(RedisKeys.getProductsKey(data.getItemId().toString()), data.getItemId());
}
//根据 busNo 修改调价单状态
this.changePriceRecordService.submitApproval(busNo);
}
return R.ok();
}
@Override
public R<?> checkMedApprovalExist(Long itemId) {
//添加 货品调价时,先查询 当前货品是否在 审核中,如果在,不允许改价。
return this.changePriceRecordService.searchMedChangePriceByItemId(itemId,
SupplyType.REQUEST_MEDICATION_CHANGE_PRICE.getValue(), SupplyStatus.APPROVAL.getValue()).isEmpty() ? R.ok()
: R.fail(MessageUtils.createMessage(PromptMsgConstant.AdjustPrice.M00002, null));
}
@Override
public R<?> checkDeviceApprovalExist(Long itemId) {
//添加 货品调价时,先查询 当前货品是否在 审核中,如果在,不允许改价。
return this.changePriceRecordService.searchDeviceChangePriceByItemId(itemId,
SupplyType.REQUEST_DEVICE_CHANGE_PRICE.getValue(), SupplyStatus.APPROVAL.getValue()).isEmpty() ? R.ok()
: R.fail(MessageUtils.createMessage(PromptMsgConstant.AdjustPrice.M00002, null));
}
@Override
public R<?> checkActivityApprovalExist(Long itemId) {
//添加 货品调价时,先查询 当前货品是否在 审核中,如果在,不允许改价。
return this.changePriceRecordService.searchActivityChangePriceByItemId(itemId,
SupplyType.REQUEST_ACTIVITY_CHANGE_PRICE.getValue(), SupplyStatus.APPROVAL.getValue()).isEmpty() ? R.ok()
: R.fail(MessageUtils.createMessage(PromptMsgConstant.AdjustPrice.M00002, null));
}
@Override
public R<?> checkHealthApprovalExist(Long itemId) {
//添加 货品调价时,先查询 当前货品是否在 审核中,如果在,不允许改价。
return this.changePriceRecordService.searchHealthChangePriceByItemId(itemId,
SupplyType.REQUEST_HEALTH_CHANGE_PRICE.getValue(), SupplyStatus.APPROVAL.getValue()).isEmpty() ? R.ok()
: R.fail(MessageUtils.createMessage(PromptMsgConstant.AdjustPrice.M00002, null));
}
public boolean executeChangePriceForMedication(List<AdjustPriceDataVo> dataVoList, String busNo,
Long practitionerId, Integer categoryType) {
// 有库存的药品或耗材集合
List<AdjustPriceDataVo> resultList = new LinkedList<>();
// 从map中将表单集合取出
Map<Long, AdjustPriceDataVo> dataVoMap = this.executeMap(dataVoList);
//根据表单中的id数组 加载库存集合
List<AdjustPriceDto> inventoryItemList =
this.inventoryItemService.searchResultDataList(this.executeItemIds(dataVoList));
for (AdjustPriceDto data : inventoryItemList) {
AdjustPriceDataVo dataVo = new AdjustPriceDataVo();
dataVo.setTotalQuantity(data.getTotalCount());
dataVo.setItemTable(data.getItemTable());
dataVo.setItemId(data.getItemId());
dataVo.setNewBuyingPrice(dataVoMap.get(data.getItemId()).getNewBuyingPrice());
dataVo.setNewRetailPrice(dataVoMap.get(data.getItemId()).getNewRetailPrice());
dataVo.setReason(dataVoMap.get(data.getItemId()).getReason());
dataVo.setUnitCode(dataVoMap.get(data.getItemId()).getUnitCode());
dataVo.setLotNumber(data.getLotNumber());
dataVo.setLocationId(data.getLocationId());
resultList.add(dataVo);
}
//填充 ChangePriceRecord 对象返回list进行批量添加
List<ChangePriceRecord> changePriceRecords =
this.executeChangePriceData(busNo, practitionerId, resultList, SupplyStatus.PENDING_APPROVAL.getValue(),
AdjustPriceEnum.MEDICINE.getCode().equals(categoryType)
? SupplyType.REQUEST_MEDICATION_CHANGE_PRICE.getValue()
: SupplyType.REQUEST_DEVICE_CHANGE_PRICE.getValue());
return this.changePriceRecordService.saveOrUpdateBatch(changePriceRecords);
}
public boolean executeChangePriceForMedicationExamine(List<AdjustPriceDataVo> dataVoList, String busNo,
Long practitionerId, Integer categoryType) {
// 有库存的药品或耗材集合
List<AdjustPriceDataVo> resultList = new LinkedList<>();
Map<Long, AdjustPriceDataVo> dataVoMap = this.executeMap(dataVoList);
List<AdjustPriceDto> inventoryItemList =
this.inventoryItemService.searchResultDataList(this.executeItemIds(dataVoList));
for (AdjustPriceDto data : inventoryItemList) {
AdjustPriceDataVo dataVo = new AdjustPriceDataVo();
dataVo.setTotalQuantity(data.getTotalCount());
dataVo.setItemTable(data.getItemTable());
dataVo.setItemId(data.getItemId());
dataVo.setNewBuyingPrice(dataVoMap.get(data.getItemId()).getNewBuyingPrice());
dataVo.setNewRetailPrice(dataVoMap.get(data.getItemId()).getNewRetailPrice());
dataVo.setReason(dataVoMap.get(data.getItemId()).getReason());
dataVo.setUnitCode(dataVoMap.get(data.getItemId()).getUnitCode());
dataVo.setLotNumber(data.getLotNumber());
dataVo.setLocationId(data.getLocationId());
resultList.add(dataVo);
this.redisUtil.set(RedisKeys.getProductsKey(data.getItemId().toString()), data.getItemId());
}
//填充 ChangePriceRecord 对象返回list进行批量添加
List<ChangePriceRecord> changePriceRecords =
this.executeChangePriceData(busNo, practitionerId, resultList, SupplyStatus.APPROVAL.getValue(),
AdjustPriceEnum.MEDICINE.getCode().equals(categoryType)
? SupplyType.REQUEST_MEDICATION_CHANGE_PRICE.getValue()
: SupplyType.REQUEST_DEVICE_CHANGE_PRICE.getValue());
return this.changePriceRecordService.saveOrUpdateBatch(changePriceRecords);
}
public boolean executeChangePriceForActivity(List<AdjustPriceDataVo> dataVoList, String busNo,
Long practitionerId) {
List<ActivityDto> dataDtoList =
this.activityDefinitionService.searchActivityDefinitionByIds(this.executeItemIds(dataVoList));
Map<Long, AdjustPriceDataVo> dataVoMap = this.executeMap(dataVoList);
List<AdjustPriceDataVo> resultList = new LinkedList<>();
for (ActivityDto data : dataDtoList) {
AdjustPriceDataVo dataVo = new AdjustPriceDataVo();
dataVo.setItemTable(CommonConstants.TableName.WOR_ACTIVITY_DEFINITION);
dataVo.setName(data.getName());
dataVo.setItemId(data.getItemId());
dataVo.setNewBuyingPrice(dataVoMap.get(data.getItemId()).getNewBuyingPrice());
dataVo.setNewRetailPrice(dataVoMap.get(data.getItemId()).getNewRetailPrice());
dataVo.setReason(dataVoMap.get(data.getItemId()).getReason());
dataVo.setLotNumber(dataVoMap.get(data.getItemId()).getLotNumber());
resultList.add(dataVo);
}
//填充 ChangePriceRecord 对象返回list进行批量添加
List<ChangePriceRecord> changePriceRecords = this.executeChangePriceData(busNo, practitionerId, resultList,
SupplyStatus.PENDING_APPROVAL.getValue(), SupplyType.REQUEST_ACTIVITY_CHANGE_PRICE.getValue());
return this.changePriceRecordService.saveOrUpdateBatch(changePriceRecords);
}
/**
* Desc: 处理申请 诊疗改价业务申请
*
* @param dataVoList
* @Author raymond
* @Date 11:19 2025/10/18
* @return boolean
**/
public boolean executeChangePriceForActivityExamine(List<AdjustPriceDataVo> dataVoList, String busNo,
Long practitionerId) {
List<ActivityDto> dataDtoList =
this.activityDefinitionService.searchActivityDefinitionByIds(this.executeItemIds(dataVoList));
Map<Long, AdjustPriceDataVo> dataVoMap = this.executeMap(dataVoList);
List<AdjustPriceDataVo> resultList = new LinkedList<>();
for (ActivityDto data : dataDtoList) {
AdjustPriceDataVo dataVo = new AdjustPriceDataVo();
dataVo.setItemTable(CommonConstants.TableName.WOR_ACTIVITY_DEFINITION);
dataVo.setName(data.getName());
dataVo.setItemId(data.getItemId());
dataVo.setNewBuyingPrice(dataVoMap.get(data.getItemId()).getNewBuyingPrice());
dataVo.setNewRetailPrice(dataVoMap.get(data.getItemId()).getNewRetailPrice());
dataVo.setReason(dataVoMap.get(data.getItemId()).getReason());
dataVo.setLotNumber(dataVoMap.get(data.getItemId()).getLotNumber());
resultList.add(dataVo);
this.redisUtil.set(RedisKeys.getProductsKey(data.getItemId().toString()), data.getItemId());
}
//填充 ChangePriceRecord 对象返回list进行批量添加
List<ChangePriceRecord> changePriceRecords = this.executeChangePriceData(busNo, practitionerId, resultList,
SupplyStatus.APPROVAL.getValue(), SupplyType.REQUEST_ACTIVITY_CHANGE_PRICE.getValue());
return this.changePriceRecordService.saveOrUpdateBatch(changePriceRecords);
}
/**
* Desc: 处理申请 挂号改价业务
*
* @param dataVoList
* @Author raymond
* @Date 11:20 2025/10/18
* @return boolean
**/
public boolean executeChangePriceForHealth(List<AdjustPriceDataVo> dataVoList, String busNo, Long practitionerId) {
List<HealthcareDto> dataDtoList =
this.healthcareServiceService.searchHealthByIds(this.executeItemIds(dataVoList));
List<AdjustPriceDataVo> resultList = new LinkedList<>();
Map<Long, AdjustPriceDataVo> dataVoMap = this.executeMap(dataVoList);
for (HealthcareDto data : dataDtoList) {
AdjustPriceDataVo dataVo = new AdjustPriceDataVo();
dataVo.setItemTable(CommonConstants.TableName.ADM_HEALTHCARE_SERVICE);
dataVo.setItemId(data.getItemId());
dataVo.setName(data.getName());
dataVo.setNewBuyingPrice(dataVoMap.get(data.getItemId()).getNewBuyingPrice());
dataVo.setNewRetailPrice(dataVoMap.get(data.getItemId()).getNewRetailPrice());
dataVo.setReason(dataVoMap.get(data.getItemId()).getReason());
dataVo.setLotNumber(dataVoMap.get(data.getItemId()).getLotNumber());
resultList.add(dataVo);
}
//填充 ChangePriceRecord 对象返回list进行批量添加 supply_request表共享了 审核状态和 category 枚举
List<ChangePriceRecord> changePriceRecords = this.executeChangePriceData(busNo, practitionerId, resultList,
SupplyStatus.PENDING_APPROVAL.getValue(), SupplyType.REQUEST_HEALTH_CHANGE_PRICE.getValue());
return this.changePriceRecordService.saveOrUpdateBatch(changePriceRecords);
}
/**
* Desc: 处理申请 挂号改价业务
*
* @param dataVoList
* @Author raymond
* @Date 11:20 2025/10/18
* @return boolean
**/
public boolean executeChangePriceForHealthExamine(List<AdjustPriceDataVo> dataVoList, String busNo,
Long practitionerId) {
List<HealthcareDto> dataDtoList =
this.healthcareServiceService.searchHealthByIds(this.executeItemIds(dataVoList));
List<AdjustPriceDataVo> resultList = new LinkedList<>();
Map<Long, AdjustPriceDataVo> dataVoMap = this.executeMap(dataVoList);
for (HealthcareDto data : dataDtoList) {
AdjustPriceDataVo dataVo = new AdjustPriceDataVo();
dataVo.setItemTable(CommonConstants.TableName.ADM_HEALTHCARE_SERVICE);
dataVo.setItemId(data.getItemId());
dataVo.setName(data.getName());
dataVo.setNewBuyingPrice(dataVoMap.get(data.getItemId()).getNewBuyingPrice());
dataVo.setNewRetailPrice(dataVoMap.get(data.getItemId()).getNewRetailPrice());
dataVo.setReason(dataVoMap.get(data.getItemId()).getReason());
dataVo.setLotNumber(dataVoMap.get(data.getItemId()).getLotNumber());
resultList.add(dataVo);
this.redisUtil.set(RedisKeys.getProductsKey(data.getItemId().toString()), data.getItemId());
}
//填充 ChangePriceRecord 对象返回list进行批量添加 supply_request表共享了 审核状态和 category 枚举
List<ChangePriceRecord> changePriceRecords = this.executeChangePriceData(busNo, practitionerId, resultList,
SupplyStatus.APPROVAL.getValue(), SupplyType.REQUEST_HEALTH_CHANGE_PRICE.getValue());
return this.changePriceRecordService.saveOrUpdateBatch(changePriceRecords);
}
/**
* Desc: 封装对象数据
*
* @param busNo
* @param curUserId
* @param itemList
* @Author raymond
* @Date 09:35 2025/10/18
* @return java.util.List<com.openhis.workflow.domain.ChangePriceRecord>
**/
public List<ChangePriceRecord> executeChangePriceData(String busNo, Long curUserId,
List<AdjustPriceDataVo> itemList, Integer statusEnum, Integer categoryEnum) {
List<ChangePriceRecord> srList = new LinkedList<>();
for (AdjustPriceDataVo dataVo : itemList) {
ChangePriceRecord cpr = new ChangePriceRecord();
//如果是 药品调价
if (SupplyType.REQUEST_MEDICATION_CHANGE_PRICE.getValue().equals(categoryEnum)) {
// 获取当前进货价
ChargeItemDefDetailPriceDto buyingPriceDto = this.chargeItemDefinitionService
.getMedPriceByParam(ConditionCode.LOT_NUMBER_COST.getCode(), dataVo.getItemId());
// 获取当前零售价
ChargeItemDefDetailPriceDto retailPriceDto = this.chargeItemDefinitionService
.getMedPriceByParam(ConditionCode.LOT_NUMBER_PRICE.getCode(), dataVo.getItemId());
if (buyingPriceDto != null || retailPriceDto != null) {
// 库存 以最小单位存储,以货品最小单位进行计算
BigDecimal partPercent =
dataVo.getTotalQuantity().divide(buyingPriceDto.getPartPercent(), 6, RoundingMode.HALF_UP);
//进货价盈负差
BigDecimal buyingDiffPrice =
dataVo.getNewBuyingPrice().subtract(buyingPriceDto.getPrice()).multiply(partPercent);
// 零售价盈负差
BigDecimal retailDiffPrice =
dataVo.getNewRetailPrice().subtract(retailPriceDto.getPrice()).multiply(partPercent);
//填充 change_price_record表数据
cpr.setNewBuyingPrice(dataVo.getNewBuyingPrice()).setNewRetailPrice(dataVo.getNewRetailPrice())
.setItemQuantity(dataVo.getTotalQuantity()).setItemId(dataVo.getItemId())
.setItemTable(dataVo.getItemTable()).setReason(dataVo.getReason()).setBusNo(busNo)
.setApplicantId(curUserId).setStatusEnum(statusEnum).setItemCategoryEnum(categoryEnum)
.setLotNumber(dataVo.getLotNumber()).setUnitCode(dataVo.getUnitCode())
.setOriginBuyingPrice(buyingPriceDto.getPrice()).setOriginRetailPrice(retailPriceDto.getPrice())
.setDifferenceBuyingPrice(buyingDiffPrice).setDifferenceRetailPrice(retailDiffPrice)
.setApplicantTime(SupplyStatus.APPROVAL.getValue().equals(statusEnum) ? new Date() : null);
srList.add(cpr);
} //如果是 耗材调价
} else if (SupplyType.REQUEST_DEVICE_CHANGE_PRICE.getValue().equals(categoryEnum)) {
// 获取当前进货价
ChargeItemDefDetailPriceDto buyingPriceDto = this.chargeItemDefinitionService
.getDevicePriceByParam(ConditionCode.LOT_NUMBER_COST.getCode(), dataVo.getItemId());
// 获取当前零售价
ChargeItemDefDetailPriceDto retailPriceDto = this.chargeItemDefinitionService
.getDevicePriceByParam(ConditionCode.LOT_NUMBER_PRICE.getCode(), dataVo.getItemId());
if (buyingPriceDto != null || retailPriceDto != null) {
// 库存 以最小单位存储,以货品最小单位进行计算
BigDecimal partPercent =
dataVo.getTotalQuantity().divide(buyingPriceDto.getPartPercent(), 6, RoundingMode.HALF_UP);
//进货价盈负差
BigDecimal buyingDiffPrice =
dataVo.getNewBuyingPrice().subtract(buyingPriceDto.getPrice()).multiply(partPercent);
// 零售价盈负差
BigDecimal retailDiffPrice =
dataVo.getNewRetailPrice().subtract(retailPriceDto.getPrice()).multiply(partPercent);
//填充 change_price_record表数据
cpr.setNewBuyingPrice(dataVo.getNewBuyingPrice()).setNewRetailPrice(dataVo.getNewRetailPrice())
.setItemQuantity(dataVo.getTotalQuantity()).setItemId(dataVo.getItemId()).setLocationId(dataVo.getLocationId())
.setItemTable(dataVo.getItemTable()).setReason(dataVo.getReason()).setBusNo(busNo)
.setApplicantId(curUserId).setStatusEnum(statusEnum).setItemCategoryEnum(categoryEnum)
.setLotNumber(dataVo.getLotNumber()).setUnitCode(dataVo.getUnitCode())
.setOriginBuyingPrice(buyingPriceDto.getPrice()).setOriginRetailPrice(retailPriceDto.getPrice())
.setDifferenceBuyingPrice(buyingDiffPrice).setDifferenceRetailPrice(retailDiffPrice)
.setApplicantTime(SupplyStatus.APPROVAL.getValue().equals(statusEnum) ? new Date() : null);
srList.add(cpr);
}
} else {//如果是 诊疗或者挂号调价,诊疗和耗材 没有库存
ChargeItemDefDetailPriceDto retailPriceDto = this.chargeItemDefinitionService
.getProductPrice(PublicationStatus.ACTIVE.getValue(), dataVo.getItemId());
if (retailPriceDto != null) {
//新价格 - 原价格
BigDecimal retailDiffPrice = dataVo.getNewRetailPrice().subtract(retailPriceDto.getPrice());
//填充 change_price_record表数据
cpr.setNewBuyingPrice(dataVo.getNewBuyingPrice()).setNewRetailPrice(dataVo.getNewRetailPrice())
.setItemQuantity(dataVo.getTotalQuantity()).setItemId(dataVo.getItemId())
.setItemTable(dataVo.getItemTable()).setReason(dataVo.getReason()).setBusNo(busNo)
.setApplicantId(curUserId).setStatusEnum(statusEnum).setItemCategoryEnum(categoryEnum)
.setLotNumber(dataVo.getLotNumber()).setUnitCode(dataVo.getUnitCode())
.setOriginRetailPrice(retailPriceDto.getPrice()).setDifferenceRetailPrice(retailDiffPrice)
.setApplicantTime(SupplyStatus.APPROVAL.getValue().equals(statusEnum) ? new Date() : null);
srList.add(cpr);
}
}
}
return srList;
}
/**
* Desc: 封装获取药品和耗材的id数组
*
* @param dataVoList
* @Author raymond
* @Date 08:03 2025/10/18
* @return java.util.List<java.lang.Long>
**/
public List<Long> executeItemIds(List<AdjustPriceDataVo> dataVoList) {
List<Long> itemIds = new LinkedList<>();
for (AdjustPriceDataVo data : dataVoList) {
itemIds.add(data.getItemId());
}
return itemIds;
}
/**
* Desc: 存储表单数据
* @param dataVoList
* @Author raymond
* @Date 10:28 2025/11/5
* @return java.util.Map<java.lang.Long,com.openhis.web.adjustprice.dto.AdjustPriceDataVo>
**/
public Map<Long, AdjustPriceDataVo> executeMap(List<AdjustPriceDataVo> dataVoList) {
Map<Long, AdjustPriceDataVo> map = new ConcurrentHashMap<>();
for (AdjustPriceDataVo data : dataVoList) {
map.put(data.getItemId(), data);
}
return map;
}
}

View File

@@ -1,183 +0,0 @@
package com.openhis.web.adjustprice.controller;
import com.core.common.core.domain.R;
import com.core.common.enums.TenantOptionDict;
import com.core.web.util.TenantOptionUtil;
import com.openhis.common.enums.OrderPricingSource;
import com.openhis.web.adjustprice.appservice.IAdjustPriceService;
import com.openhis.web.adjustprice.dto.AdjustPriceDataVo;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* @ClassName ChargePriceController
* @Description 调价修改药品、耗材、诊疗、挂号接口类
* @Author raymond
* @Date 2025/10/14 16:56
* @Version 1.0
**/
@RestController
@RequestMapping("/change/price")
public class ChangePriceController {
@Resource
private IAdjustPriceService adjustPriceService;
/**
* Desc: 根据关键词搜索数据
*
* @param
* @return com.core.common.core.domain.R<?>
* @Author raymond
* @Date 09:26 2025/10/20
**/
@PostMapping(value = "searchKeyWordDataListByMed")
public R<?> searchKeyWordDataListByMed(@RequestParam(name = "searchKey", required = false) String searchKey) {
return R.ok(this.adjustPriceService.searchKeyWordDataListByMed(searchKey));
}
/**
* Desc: 根据关键词搜索数据
*
* @param
* @return com.core.common.core.domain.R<?>
* @Author raymond
* @Date 09:26 2025/10/20
**/
@PostMapping(value = "searchKeyWordDataListByDevice")
public R<?> searchKeyWordDataListByDevice(@RequestParam(name = "searchKey", required = false) String searchKey) {
return R.ok(this.adjustPriceService.searchKeyWordDataListByDevice(searchKey));
}
/**
* Desc: 根据关键词搜索数据
*
* @param
* @return com.core.common.core.domain.R<?>
* @Author raymond
* @Date 09:26 2025/10/20
**/
@PostMapping(value = "searchKeyWordDataListByActivity")
public R<?> searchKeyWordDataListByActivity(@RequestParam(name = "searchKey", required = false) String searchKey) {
return R.ok(this.adjustPriceService.searchKeyWordDataListByActivity(searchKey));
}
/**
* Desc: 查询所有 有挂号信息的科室
*
* @param
* @return com.core.common.core.domain.R<?>
* @Author raymond
* @Date 08:38 2025/10/22
**/
@PostMapping(value = "searchAllOrgData")
public R<?> searchAllOrgData() {
return this.adjustPriceService.searchAllOrgData();
}
/**
* Desc: 根据科室id 加载 挂号信息
*
* @param orgId
* @return com.core.common.core.domain.R<?>
* @Author raymond
* @Date 16:46 2025/10/22
**/
@PostMapping(value = "searchHealthData")
public R<?> searchHealthData(@RequestParam Long orgId) {
return this.adjustPriceService.searchHealthData(orgId);
}
/**
* Desc: 保存 改价数据
*
* @return com.core.common.core.domain.R<?>
* @Author raymond
* @Date 08:47 2025/10/15
**/
@PostMapping(value = "commitChangePriceData")
public R<?> commitChangePriceData(@RequestBody List<AdjustPriceDataVo> dataVoList) {
return adjustPriceService.submitChangePriceData(dataVoList);
}
/**
* Desc: 根据供应商和药品名称加载要修改的药品数据
*
* @return com.core.common.core.domain.R<?>
* @Author raymond
* @Date 08:47 2025/10/15
**/
@PostMapping(value = "submitExamineChangePriceData")
public R<?> submitExamineChangePriceData(@RequestBody List<AdjustPriceDataVo> dataVoList) {
return adjustPriceService.submitExamineChangePriceData(dataVoList);
}
/**
* Desc: 根据货品ID 查询是否有审核中的药品数据
*
* @param itemId
* @return com.core.common.core.domain.R<?>
* @Author raymond
* @Date 17:32 2025/11/3
**/
@PostMapping(value = "checkMedApprovalExist")
public R<?> checkMedApprovalExist(@RequestParam Long itemId) {
return this.adjustPriceService.checkMedApprovalExist(itemId);
}
/**
* Desc: 根据货品ID 查询是否有审核中的药品数据
*
* @param itemId
* @return com.core.common.core.domain.R<?>
* @Author raymond
* @Date 17:32 2025/11/3
**/
@PostMapping(value = "checkDeviceApprovalExist")
public R<?> checkDeviceApprovalExist(@RequestParam Long itemId) {
return this.adjustPriceService.checkDeviceApprovalExist(itemId);
}
/**
* Desc: 根据货品ID 查询是否有审核中的药品数据
*
* @param itemId
* @return com.core.common.core.domain.R<?>
* @Author raymond
* @Date 17:32 2025/11/3
**/
@PostMapping(value = "checkActivityApprovalExist")
public R<?> checkActivityApprovalExist(@RequestParam Long itemId) {
return this.adjustPriceService.checkActivityApprovalExist(itemId);
}
/**
* Desc: 根据货品ID 查询是否有审核中的药品数据
*
* @param itemId
* @return com.core.common.core.domain.R<?>
* @Author raymond
* @Date 17:32 2025/11/3
**/
@PostMapping(value = "checkHealthApprovalExist")
public R<?> checkHealthApprovalExist(@RequestParam Long itemId) {
return this.adjustPriceService.checkHealthApprovalExist(itemId);
}
/**
* Desc: 查询调价控制开关状态接口
*
* @return true:统一零售价 , false:按批次号售卖
**/
@GetMapping(value = "getAdjustPriceSwitchState")
public R<?> getAdjustPriceSwitchState() {
// 医嘱定价来源
String orderPricingSource = TenantOptionUtil.getOptionContent(TenantOptionDict.ORDER_PRICING_SOURCE);
if (OrderPricingSource.RETAIL_PRICE.getCode().equals(orderPricingSource)) {
return R.ok(true);
}
return R.ok(false);
}
}

View File

@@ -1,151 +0,0 @@
package com.openhis.web.adjustprice.controller;
import com.core.common.core.domain.R;
import com.core.common.utils.StringUtils;
import com.openhis.web.adjustprice.appservice.IAdjustPriceService;
import com.openhis.web.adjustprice.dto.AdjustPriceDataVo;
import com.openhis.web.adjustprice.dto.AdjustPriceManagerSearchParam;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
/**
* @ClassName ChangePriceListPageController
* @Description TODO
* @Author raymond
* @Date 2025/10/23 15:16
* @Version 1.0
**/
@RestController
@RequestMapping("/change/price/list")
public class ChangePriceDataListPageController {
@Resource
private IAdjustPriceService adjustPriceService;
/**
* Desc: 查询 调价管理列表页面 分页查询当前人 提交的调价单
*
* @param adjustPriceManagerSearchParam
* @param pageNo
* @param pageSize
* @param searchKey
* @param request
* @Author raymond
* @Date 15:47 2025/10/23
* @return com.core.common.core.domain.R<?>
**/
@GetMapping(value = "getPage")
public R<?> getPage(AdjustPriceManagerSearchParam adjustPriceManagerSearchParam,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request) {
return this.adjustPriceService.searchChangePriceSubmitDataToPage(adjustPriceManagerSearchParam, pageNo,
pageSize, searchKey, request);
}
/**
* Desc: 根据单据号 进行提交审核操作
*
* @param busNo
* @Author raymond
* @Date 09:38 2025/10/23
* @return com.core.common.core.domain.R<?>
**/
@PostMapping(value = "updateStatusByApproval")
public R<?> updateStatusByApproval(@RequestParam String busNo) {
return this.adjustPriceService.updateExamineByApproval(busNo);
}
/**
* Desc: 作废 调价单数据
*
* @param busNo
* @Author raymond
* @Date 14:47 2025/10/21
* @return com.core.common.core.domain.R<?>
**/
@PostMapping(value = "cancelChangePriceData")
public R<?> cancelChangePriceData(@RequestParam String busNo) {
return this.adjustPriceService.cancelChangePriceData(busNo);
}
/**
* Desc: 根据供应商和药品名称加载要修改的药品数据
*
*
* @Author raymond
* @Date 08:47 2025/10/15
* @return com.core.common.core.domain.R<?>
**/
@PostMapping(value = "submitChangePriceData")
public R<?> submitChangePriceData(@RequestBody List<AdjustPriceDataVo> dataVoList) {
return adjustPriceService.submitChangePriceData(dataVoList);
}
/**
* Desc: 根据 单据号 药品调价单 查询详情
*
* @param busNo
* @Author raymond
* @Date 12:01 2025/10/21
* @return com.core.common.core.domain.R<?>
**/
@PostMapping(value = "searchChangePriceDataByMed")
public R<?> searchChangePriceDataByMed(@RequestParam String busNo) {
if (StringUtils.isEmpty(busNo)) {
return R.fail();
}
return this.adjustPriceService.searchChangePriceDataByMed(busNo);
}
/**
* Desc: 根据 单据号 耗材调价单 查询详情
*
* @param busNo
* @Author raymond
* @Date 12:01 2025/10/21
* @return com.core.common.core.domain.R<?>
**/
@PostMapping(value = "searchChangePriceDataByDevice")
public R<?> searchChangePriceDataByDevice(@RequestParam String busNo) {
if (StringUtils.isEmpty(busNo)) {
return R.fail();
}
return this.adjustPriceService.searchChangePriceDataByDevice(busNo);
}
/**
* Desc: 根据 单据号 诊疗调价单 查询详情
*
* @param busNo
* @Author raymond
* @Date 12:01 2025/10/21
* @return com.core.common.core.domain.R<?>
**/
@PostMapping(value = "searchChangePriceDataByActivity")
public R<?> searchChangePriceDataByActivity(@RequestParam String busNo) {
if (StringUtils.isEmpty(busNo)) {
return R.fail();
}
return this.adjustPriceService.searchChangePriceDataByActivity(busNo);
}
/**
* Desc: 根据 单据号 挂号调价单 查询详情
*
* @param busNo
* @Author raymond
* @Date 12:01 2025/10/21
* @return com.core.common.core.domain.R<?>
**/
@PostMapping(value = "searchChangePriceDataByHealth")
public R<?> searchChangePriceDataByHealth(@RequestParam String busNo) {
if (StringUtils.isEmpty(busNo)) {
return R.fail();
}
return this.adjustPriceService.searchChangePriceDataByHealth(busNo);
}
}

View File

@@ -1,81 +0,0 @@
package com.openhis.web.adjustprice.dto;
import lombok.Data;
import java.math.BigDecimal;
/**
* @ClassName AdjustPriceDataVo
* @Description TODO
* @Author raymond
* @Date 2025/10/16 08:31
* @Version 1.0
**/
@Data
public class AdjustPriceDataVo {
/**
* 表ID
*/
private Long itemId;
/**
* 分类 0、药品1、耗材2、诊疗3、挂号
*/
private Integer categoryType;
/**
* 改价原因
*/
private String reason;
/**
* 新进货价
*/
private BigDecimal newBuyingPrice;
/**
* 新售价
*/
private BigDecimal newRetailPrice;
/**
* 经手人
*/
private Long practitionerId;
/**
* 每个批次影响数量
*/
private BigDecimal quantity;
/**
* 总数量
*/
private BigDecimal totalQuantity;
/**
* 表名
*/
private String itemTable;
/**
* 单据号
*/
private String busNo;
private String name;
/**
* 批次号
*/
private String lotNumber;
/**
* 单位
*/
private String unitCode;
/**
* 位置
*/
private Long locationId;
private BigDecimal finalTotalQuantity;
// 手动添加 getter 方法
public Long getItemId() {
return itemId;
}
public Integer getCategoryType() {
return categoryType;
}
}

View File

@@ -1,33 +0,0 @@
package com.openhis.web.adjustprice.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* @ClassName AdjustPriceManagerSearchParam
* @Description 改价管理 查询条件
* @Author raymond
* @Date 2025/10/24 16:23
* @Version 1.0
**/
@Data
@Accessors(chain = true)
public class AdjustPriceManagerSearchParam {
/** 审核状态 */
private Integer statusEnum;
/** 单据类型 */
private Integer itemCategoryEnum;
/**
* 单据时间
*/
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date applicantTime;
}

View File

@@ -1,95 +0,0 @@
package com.openhis.web.adjustprice.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* @ClassName ChangePricePageDto
* @Description TODO
* @Author raymond
* @Date 2025/10/31 17:35
* @Version 1.0
**/
@Data
public class ChangePriceDataDto {
/** 批次号 */
private String originLotNumber;
/** 改价申请人id */
private Long applicantId;
/** 目标枚举 药品、耗材、诊疗、挂号 */
private Integer itemCategoryEnum;
private String itemCategoryEnum_Text;
/** 药品ID、耗材ID、诊疗ID、挂号ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long itemId;
/**
* 获取名称
*/
private String itemName;
/** 原进货价 */
private BigDecimal originBuyingPrice;
/** 原零售价价格 */
private BigDecimal originRetailPrice;
/** 当前品库存量 */
private BigDecimal itemQuantity;
/** 当前业务批次号 */
private String busNo;
/** 改价申请时间 */
private Date applicantTime;
/** 新进货价 */
private BigDecimal newBuyingPrice;
/** 新零售价 */
private BigDecimal newRetailPrice;
/** 物品计量单位 */
private String unitCode;
/** 审批状态 */
private Integer statusEnum;
private Integer statusEnum_Text;
/** 批次号 */
private String lotNumber;
/** 条件理由 */
private String reason;
/** 零售价盈负差*/
private BigDecimal differenceRetailPrice;
/**进货价盈负差*/
private BigDecimal differenceBuyingPrice;
/**
* 科室名称
*/
private String orgName;
/**
* 价格主表ID
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long chargeId;
/**
* 调价表ID
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long changePriceRecordId;
private String label;
/**
* 规格
*/
private String totalVolume;
}

View File

@@ -1,65 +0,0 @@
package com.openhis.web.adjustprice.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.openhis.common.annotation.Dict;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.util.Date;
/**
* @ClassName ChangePricePageDto
* @Description 改价业务分页dto
* @Author raymond
* @Date 2025/11/1 22:53
* @Version 1.0
**/
@Data
public class ChangePricePageDto {
/** 单据号 */
private String busNo;
/** 状态 */
private Integer statusEnum;
private String statusEnum_enumText;
/** 审批人 */
@Dict(dictCode = "id", dictText = "name", dictTable = "adm_practitioner")
private Long approverId;
private String approverId_dictText;
/** 审批时间 */
private Date approvalTime;
/** 申请人 */
@Dict(dictCode = "id", dictText = "name", dictTable = "adm_practitioner")
private Long applicantId;
private String applicantId_dictText;
/** 申请时间 */
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date applicantTime;
/** 制单日期 */
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/** 备注 */
private String reason;
/**
* 24、药品
*/
private Integer itemCategoryEnum;
private String categoryEnum_enumText;
private BigDecimal originRetailPrice;
private BigDecimal originBuyingPrice;
private BigDecimal newBuyingPrice;
private BigDecimal newRetailPrice;
}

View File

@@ -1,154 +0,0 @@
package com.openhis.web.adjustprice.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.openhis.web.adjustprice.dto.ChangePriceDataDto;
import com.openhis.web.adjustprice.dto.ChangePricePageDto;
import com.openhis.web.inventorymanage.dto.InventorySearchParam;
import com.openhis.web.inventorymanage.dto.ReceiptPageDto;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* Desc:
*
* @Author raymond
* @Date 14:37 2025/10/15
* @return
**/
@Component
public interface AdjustPriceMapper {
/**
* Desc: 查询单据审批分页列表
*
* @param page
* @param queryWrapper
* @param medTypeEnum
* @param deviceTypeEnum
* @param activityTypeEnum
* @param healthTypeEnum
* @Author raymond
* @Date 16:01 2025/10/24
* @return com.baomidou.mybatisplus.extension.plugins.pagination.Page<com.openhis.web.inventorymanage.dto.ReceiptPageDto>
**/
Page<ReceiptPageDto> selectInventoryReceiptPage(@Param("page") Page<ReceiptPageDto> page,
@Param(Constants.WRAPPER) QueryWrapper<InventorySearchParam> queryWrapper,
@Param("medTypeEnum") Integer medTypeEnum, @Param("deviceTypeEnum") Integer deviceTypeEnum,
@Param("activityTypeEnum") Integer activityTypeEnum, @Param("healthTypeEnum") Integer healthTypeEnum);
/**
* Desc: 根据当前人 ID 查询提交的调价申请记录
*
* @param page
* @param queryWrapper
* @param medCategory
* @param deviceCategory
* @param activityCategory
* @param healthCategory
* @param applicantId
* @Author raymond
* @Date 00:59 2025/11/2
* @return com.baomidou.mybatisplus.extension.plugins.pagination.Page<com.openhis.web.adjustprice.dto.ChangePricePageDto>
**/
Page<ChangePricePageDto> searchChangePriceDataToPage(@Param("page") Page<ReceiptPageDto> page,
@Param(Constants.WRAPPER) QueryWrapper<InventorySearchParam> queryWrapper,
@Param("medCategory") Integer medCategory, @Param("deviceCategory") Integer deviceCategory,
@Param("activityCategory") Integer activityCategory, @Param("healthCategory") Integer healthCategory,
@Param("applicantId") Long applicantId);
/**
* Desc: 根据条件 查询 药品调价单
* @param busNo
* @param categoryEnum
* @param statusEnum
* @Author raymond
* @Date 09:46 2025/11/2
* @return java.util.List<com.openhis.administration.dto.ChangePriceDataDto>
**/
List<ChangePriceDataDto> searchMedChangePriceByBusNo(@Param("busNo") String busNo, @Param("categoryEnum") Integer categoryEnum, @Param("statusEnum") Integer statusEnum);
/**
* Desc: 根据条件 查询 药品调价单
* @param itemId
* @param categoryEnum
* @param statusEnum
* @Author raymond
* @Date 07:34 2025/11/4
* @return java.util.List<com.openhis.administration.dto.ChangePriceDataDto>
**/
List<ChangePriceDataDto> searchMedChangePriceByItemId(@Param("itemId") Long itemId,@Param("categoryEnum") Integer categoryEnum,@Param("statusEnum") Integer statusEnum);
/**
* Desc: 根据条件 查询 耗材调价单
* @param busNo
* @param categoryEnum
* @param statusEnum
* @Author raymond
* @Date 09:46 2025/11/2
* @return java.util.List<com.openhis.administration.dto.ChangePriceDataDto>
**/
List<ChangePriceDataDto> searchDeviceChangePriceByBusNo(@Param("busNo") String busNo,@Param("categoryEnum") Integer categoryEnum,@Param("statusEnum") Integer statusEnum);
/**
* Desc: 根据条件 查询 耗材调价单
* @param itemId
* @param categoryEnum
* @param statusEnum
* @Author raymond
* @Date 07:33 2025/11/4
* @return java.util.List<com.openhis.administration.dto.ChangePriceDataDto>
**/
List<ChangePriceDataDto> searchDeviceChangePriceByItemId(@Param("itemId") Long itemId,@Param("categoryEnum") Integer categoryEnum,@Param("statusEnum") Integer statusEnum);
/**
* Desc: 根据条件 查询 诊疗调价单
* @param busNo
* @param categoryEnum
* @param statusEnum
* @Author raymond
* @Date 09:46 2025/11/2
* @return java.util.List<com.openhis.administration.dto.ChangePriceDataDto>
**/
List<ChangePriceDataDto> searchActivityChangePriceByBusNo(@Param("busNo") String busNo,@Param("categoryEnum") Integer categoryEnum,@Param("statusEnum") Integer statusEnum);
/**
* Desc: 根据条件 查询 诊疗调价单
* @param itemId
* @param categoryEnum
* @param statusEnum
* @Author raymond
* @Date 07:32 2025/11/4
* @return java.util.List<com.openhis.administration.dto.ChangePriceDataDto>
**/
List<ChangePriceDataDto> searchActivityChangePriceByItemId(@Param("itemId") Long itemId,@Param("categoryEnum") Integer categoryEnum,@Param("statusEnum") Integer statusEnum);
/**
* Desc: 根据条件 查询 挂号调价单
* @param busNo
* @param categoryEnum
* @param statusEnum
* @Author raymond
* @Date 09:46 2025/11/2
* @return java.util.List<com.openhis.administration.dto.ChangePriceDataDto>
**/
List<ChangePriceDataDto> searchHealthChangePriceByBusNo(@Param("busNo") String busNo,@Param("categoryEnum") Integer categoryEnum,@Param("statusEnum") Integer statusEnum);
/**
* Desc: 根据条件 查询 挂号调价单
* @param itemId
* @param categoryEnum
* @param statusEnum
* @Author raymond
* @Date 07:31 2025/11/4
* @return java.util.List<com.openhis.administration.dto.ChangePriceDataDto>
**/
List<ChangePriceDataDto> searchHealthChangePriceByItemId(@Param("itemId") Long itemId,@Param("categoryEnum") Integer categoryEnum,@Param("statusEnum") Integer statusEnum);
/**
* Desc: 根据条件 查询 审批单 审核中的数据
* @param busNo
* @param statusEnum
* @Author raymond
* @Date 10:36 2025/11/2
* @return java.util.List<com.openhis.administration.dto.ChangePriceDataDto>
**/
List<ChangePriceDataDto> searchChangePriceRecordDataByBusNo(@Param("busNo") String busNo,@Param("statusEnum") Integer statusEnum);
}

View File

@@ -1,151 +0,0 @@
package com.openhis.web.administration.controller;
import com.core.common.annotation.Log;
import com.core.common.core.controller.BaseController;
import com.core.common.core.domain.AjaxResult;
import com.core.common.core.page.TableDataInfo;
import com.core.common.enums.BusinessType;
import com.core.common.utils.poi.ExcelUtil;
import com.openhis.administration.domain.PractitionerPatient;
import com.openhis.administration.service.IPractitionerPatientService;
import com.openhis.administration.dto.PractitionerPatientDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.List;
/**
* 医生患者关系管理Controller
*
* @author system
* @date 2026-01-02
*/
@RestController
@RequestMapping("/administration/practitioner-patient")
public class PractitionerPatientController extends BaseController {
@Autowired
private IPractitionerPatientService practitionerPatientService;
/**
* 查询医生患者关系列表
*/
@PreAuthorize("@ss.hasPermi('administration:practitionerPatient:list')")
@GetMapping("/list")
public TableDataInfo list(PractitionerPatient practitionerPatient) {
startPage();
List<PractitionerPatient> list = practitionerPatientService.list();
return getDataTable(list);
}
/**
* 导出医生患者关系列表
*/
@PreAuthorize("@ss.hasPermi('administration:practitionerPatient:export')")
@Log(title = "医生患者关系", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, PractitionerPatient practitionerPatient) {
List<PractitionerPatient> list = practitionerPatientService.list();
ExcelUtil<PractitionerPatient> util = new ExcelUtil<>(PractitionerPatient.class);
util.exportExcel(response, list, "医生患者关系数据");
}
/**
* 获取医生患者关系详细信息
*/
@PreAuthorize("@ss.hasPermi('administration:practitionerPatient:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id) {
return AjaxResult.success(practitionerPatientService.getById(id));
}
/**
* 获取医生的所有有效患者
*/
@PreAuthorize("@ss.hasPermi('administration:practitionerPatient:query')")
@GetMapping("/practitioner/{practitionerId}/patients")
public AjaxResult getPatientsByPractitioner(@PathVariable Long practitionerId) {
return AjaxResult.success(practitionerPatientService.getValidPatientsByPractitioner(practitionerId));
}
/**
* 获取患者的所有有效医生
*/
@PreAuthorize("@ss.hasPermi('administration:practitionerPatient:query')")
@GetMapping("/patient/{patientId}/practitioners")
public AjaxResult getPractitionersByPatient(@PathVariable Long patientId) {
return AjaxResult.success(practitionerPatientService.getValidPractitionersByPatient(patientId));
}
/**
* 新增医生患者关系
*/
@PreAuthorize("@ss.hasPermi('administration:practitionerPatient:add')")
@Log(title = "医生患者关系", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody PractitionerPatientDto dto) {
PractitionerPatient relationship = new PractitionerPatient();
relationship.setPractitionerId(dto.getPractitionerId());
relationship.setPatientId(dto.getPatientId());
relationship.setRelationshipType(dto.getRelationshipType());
relationship.setOrganizationId(dto.getOrganizationId());
relationship.setStartDate(dto.getStartDate());
relationship.setRemark(dto.getRemark());
return toAjax(practitionerPatientService.createRelationship(relationship));
}
/**
* 修改医生患者关系
*/
@PreAuthorize("@ss.hasPermi('administration:practitionerPatient:edit')")
@Log(title = "医生患者关系", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody PractitionerPatient practitionerPatient) {
return toAjax(practitionerPatientService.updateById(practitionerPatient));
}
/**
* 终止医生患者关系
*/
@PreAuthorize("@ss.hasPermi('administration:practitionerPatient:remove')")
@Log(title = "医生患者关系", businessType = BusinessType.DELETE)
@PostMapping("/terminate/{id}")
public AjaxResult terminate(@PathVariable Long id) {
return toAjax(practitionerPatientService.terminateRelationship(id));
}
/**
* 删除医生患者关系
*/
@PreAuthorize("@ss.hasPermi('administration:practitionerPatient:remove')")
@Log(title = "医生患者关系", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids) {
return toAjax(practitionerPatientService.removeByIds(List.of(ids)));
}
/**
* 批量创建医生患者关系
*/
@PreAuthorize("@ss.hasPermi('administration:practitionerPatient:add')")
@Log(title = "批量创建医生患者关系", businessType = BusinessType.INSERT)
@PostMapping("/batch")
public AjaxResult batchAdd(@RequestBody List<PractitionerPatientDto> dtos) {
List<PractitionerPatient> relationships = dtos.stream().map(dto -> {
PractitionerPatient relationship = new PractitionerPatient();
relationship.setPractitionerId(dto.getPractitionerId());
relationship.setPatientId(dto.getPatientId());
relationship.setRelationshipType(dto.getRelationshipType());
relationship.setOrganizationId(dto.getOrganizationId());
relationship.setStartDate(dto.getStartDate());
relationship.setRemark(dto.getRemark());
return relationship;
}).toList();
return toAjax(practitionerPatientService.batchCreateRelationships(relationships));
}
}

View File

@@ -1,28 +0,0 @@
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

@@ -1,45 +0,0 @@
package com.openhis.web.appointmentmanage.appservice;
import com.core.common.core.domain.R;
import com.openhis.appointmentmanage.domain.ClinicRoom;
public interface IClinicRoomAppService {
/**
* 分页查询诊室列表
* @param pageNum 页码
* @param pageSize 每页条数
* @param orgName 卫生机构名称
* @param roomName 诊室名称
* @return 分页查询结果
*/
R<?> selectClinicRoomPage(Integer pageNum, Integer pageSize, String orgName, String roomName);
/**
* 查询诊室详情
* @param id 诊室ID
* @return 诊室详情
*/
R<?> selectClinicRoomById(Long id);
/**
* 新增诊室
* @param clinicRoom 诊室信息
* @return 新增结果
*/
R<?> insertClinicRoom(ClinicRoom clinicRoom);
/**
* 更新诊室
* @param clinicRoom 诊室信息
* @return 更新结果
*/
R<?> updateClinicRoom(ClinicRoom clinicRoom);
/**
* 删除诊室
* @param id 诊室ID
* @return 删除结果
*/
R<?> deleteClinicRoomById(Long id);
}

View File

@@ -1,8 +0,0 @@
package com.openhis.web.appointmentmanage.appservice;
import com.core.common.core.domain.R;
public interface IDeptAppService {
R<?> getDeptList();
R<?> searchDept(Integer pageNo, Integer pageSize, String orgName, String deptName);
}

View File

@@ -1,17 +0,0 @@
package com.openhis.web.appointmentmanage.appservice;
import com.core.common.core.domain.R;
import com.openhis.appointmentmanage.domain.DeptAppointmentHours;
public interface IDeptAppointmentHoursAppService {
R<?> getDeptAppthoursList(DeptAppointmentHours deptAppointmentHours, Integer pageNum, Integer pageSize);
R<?> getDeptAppthoursDetail(Long id);
R<?> addDeptAppthours(DeptAppointmentHours deptAppointmentHours);
R<?> updateDeptAppthours(DeptAppointmentHours deptAppointmentHours);
R<?> deleteDeptAppthours(Long id);
}

View File

@@ -1,25 +0,0 @@
package com.openhis.web.appointmentmanage.appservice;
import com.core.common.core.domain.R;
import com.openhis.appointmentmanage.domain.DoctorSchedule;
public interface IDoctorScheduleAppService {
R<?> getDoctorScheduleList();
R<?> getTodayDoctorScheduleList();
R<?> getTodayMySchedule();
R<?> getDoctorScheduleListByDeptId(Long deptId);
R<?> getDoctorScheduleListByDeptIdAndDateRange(Long deptId, String startDate, String endDate);
R<?> addDoctorSchedule(DoctorSchedule doctorSchedule);
R<?> addDoctorScheduleWithDate(DoctorSchedule doctorSchedule, String scheduledDate);
R<?> updateDoctorSchedule(DoctorSchedule doctorSchedule);
R<?> removeDoctorSchedule(Integer doctorScheduleId);
}

View File

@@ -1,10 +0,0 @@
package com.openhis.web.appointmentmanage.appservice;
import com.core.common.core.domain.R;
import com.openhis.web.appointmentmanage.dto.SchedulePoolDto;
public interface ISchedulePoolAppService {
R<?> addSchedulePool(SchedulePoolDto schedulePoolDto);
R<?> list(SchedulePoolDto schedulePoolDto);
}

View File

@@ -1,4 +0,0 @@
package com.openhis.web.appointmentmanage.appservice;
public interface IScheduleSlotAppService {
}

View File

@@ -1,72 +0,0 @@
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;
/**
* 号源管理应用服务接口
*
* @author system
*/
public interface ITicketAppService {
/**
* 分页查询门诊号源列表(真分页)
*
* @param query 查询参数
* @return 结果
*/
R<?> listTicket(TicketQueryDTO query);
/**
* 查询医生余号汇总(基于号源池,不受分页影响)
*
* @param query 查询参数
* @return 结果
*/
R<?> listDoctorAvailability(TicketQueryDTO query);
/**
* 预约号源
*
* @param dto 预约参数
* @return 结果
*/
R<?> bookTicket(com.openhis.appointmentmanage.domain.AppointmentBookDTO dto);
/**
* 取消预约
*
* @param slotId 槽位ID
* @return 结果
*/
R<?> cancelTicket(Long slotId);
/**
* 取号
*
* @param slotId 槽位ID
* @return 结果
*/
R<?> checkInTicket(Long slotId);
/**
* 停诊
*
* @param slotId 槽位ID
* @return 结果
*/
R<?> cancelConsultation(Long slotId);
/**
* 查询所有号源(用于测试)
*
* @return 所有号源列表
*/
R<?> listAllTickets();
}

View File

@@ -1,62 +0,0 @@
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,121 +0,0 @@
package com.openhis.web.appointmentmanage.appservice.impl;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
import com.openhis.appointmentmanage.domain.ClinicRoom;
import com.openhis.appointmentmanage.service.IClinicRoomService;
import com.openhis.web.appointmentmanage.appservice.IClinicRoomAppService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class ClinicRoomAppServiceImpl implements IClinicRoomAppService {
@Resource
private IClinicRoomService clinicRoomService;
@Override
public R<?> selectClinicRoomPage(Integer pageNum, Integer pageSize, String orgName, String roomName) {
// 构建查询条件
ClinicRoom clinicRoom = new ClinicRoom();
if (orgName != null && ObjectUtil.isNotEmpty(orgName)) {
clinicRoom.setOrgName(orgName);
}
if (roomName != null && ObjectUtil.isNotEmpty(roomName)) {
clinicRoom.setRoomName(roomName);
}
// 分页查询
Page<ClinicRoom> page = new Page<>(pageNum, pageSize);
Page<ClinicRoom> result = clinicRoomService.selectClinicRoomPage(page, clinicRoom);
return R.ok(result);
}
@Override
public R<?> selectClinicRoomById(Long id) {
ClinicRoom clinicRoom = clinicRoomService.selectClinicRoomById(id);
if (clinicRoom == null) {
return R.fail(404, "诊室不存在");
}
return R.ok(clinicRoom);
}
@Override
public R<?> insertClinicRoom(ClinicRoom clinicRoom) {
// 数据校验
if (ObjectUtil.isEmpty(clinicRoom.getRoomName())) {
return R.fail(400, "诊室名称不能为空");
}
if (ObjectUtil.isEmpty(clinicRoom.getDepartment())) {
return R.fail(400, "科室名称不能为空");
}
if (clinicRoom.getRoomName().length() > 50) {
return R.fail(400, "诊室名称长度不能超过50个字符");
}
if (clinicRoom.getRemarks() != null && clinicRoom.getRemarks().length() > 500) {
return R.fail(400, "备注长度不能超过500个字符");
}
// 新增诊室
int result = clinicRoomService.insertClinicRoom(clinicRoom);
if (result > 0) {
return R.ok(null, "新增成功");
} else {
return R.fail("新增失败");
}
}
@Override
public R<?> updateClinicRoom(ClinicRoom clinicRoom) {
// 数据校验
if (ObjectUtil.isEmpty(clinicRoom.getId())) {
return R.fail(400, "诊室ID不能为空");
}
if (ObjectUtil.isEmpty(clinicRoom.getRoomName())) {
return R.fail(400, "诊室名称不能为空");
}
if (ObjectUtil.isEmpty(clinicRoom.getDepartment())) {
return R.fail(400, "科室名称不能为空");
}
if (clinicRoom.getRoomName().length() > 50) {
return R.fail(400, "诊室名称长度不能超过50个字符");
}
if (clinicRoom.getRemarks() != null && clinicRoom.getRemarks().length() > 500) {
return R.fail(400, "备注长度不能超过500个字符");
}
// 检查诊室是否存在
ClinicRoom existingClinicRoom = clinicRoomService.selectClinicRoomById(clinicRoom.getId());
if (existingClinicRoom == null) {
return R.fail(404, "诊室不存在");
}
// 更新诊室
int result = clinicRoomService.updateClinicRoom(clinicRoom);
if (result > 0) {
return R.ok(null, "修改成功");
} else {
return R.fail("修改失败");
}
}
@Override
public R<?> deleteClinicRoomById(Long id) {
// 检查诊室是否存在
ClinicRoom existingClinicRoom = clinicRoomService.selectClinicRoomById(id);
if (existingClinicRoom == null) {
return R.fail(404, "诊室不存在");
}
// 删除诊室
int result = clinicRoomService.deleteClinicRoomById(id);
if (result > 0) {
return R.ok(null, "删除成功");
} else {
return R.fail("删除失败");
}
}
}

View File

@@ -1,39 +0,0 @@
package com.openhis.web.appointmentmanage.appservice.impl;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.core.common.core.domain.R;
import com.openhis.appointmentmanage.domain.Dept;
import com.openhis.appointmentmanage.service.IDeptService;
import com.openhis.web.appointmentmanage.appservice.IDeptAppService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class DeptAppServiceImpl implements IDeptAppService {
@Resource
private IDeptService deptService;
@Override
public R<?> getDeptList() {
List<Dept> list = deptService.list();
return R.ok(list);
}
@Override
public R<?> searchDept(Integer pageNo, Integer pageSize, String orgName, String deptName) {
LambdaQueryWrapper<Dept> wrapper = new LambdaQueryWrapper<>();
if (orgName != null && ObjectUtil.isNotEmpty(orgName)) {
wrapper.eq(Dept::getOrgName, orgName);
}
if (deptName != null && ObjectUtil.isNotEmpty(deptName)) {
wrapper.eq(Dept::getDeptName, deptName);
}
List<Dept> list = deptService.list(wrapper);
return R.ok(list);
}
}

View File

@@ -1,103 +0,0 @@
package com.openhis.web.appointmentmanage.appservice.impl;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
import com.openhis.appointmentmanage.domain.DeptAppointmentHours;
import com.openhis.appointmentmanage.mapper.DeptAppointmentHoursMapper;
import com.openhis.appointmentmanage.service.IDeptAppointmentHoursService;
import com.openhis.web.appointmentmanage.appservice.IDeptAppointmentHoursAppService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class DeptAppointmentHoursAppServiceImpl implements IDeptAppointmentHoursAppService {
@Resource
private IDeptAppointmentHoursService deptAppointmentHoursService;
@Resource
private DeptAppointmentHoursMapper deptAppointmentHoursMapper;
@Override
public R<?> getDeptAppthoursList(DeptAppointmentHours deptAppointmentHours, Integer pageNum, Integer pageSize) {
LambdaQueryWrapper<DeptAppointmentHours> wrapper = new LambdaQueryWrapper<>();
if (StrUtil.isNotBlank(deptAppointmentHours.getInstitution())) {
wrapper.eq(DeptAppointmentHours::getInstitution, deptAppointmentHours.getInstitution());
}
if (StrUtil.isNotBlank(deptAppointmentHours.getDepartment())) {
wrapper.eq(DeptAppointmentHours::getDepartment, deptAppointmentHours.getDepartment());
}
wrapper.orderByDesc(DeptAppointmentHours::getCreatedTime);
Page<DeptAppointmentHours> page = new Page<>(pageNum, pageSize);
Page<DeptAppointmentHours> resultPage = deptAppointmentHoursMapper.selectPage(page, wrapper);
return R.ok(resultPage);
}
@Override
public R<?> getDeptAppthoursDetail(Long id) {
if (ObjectUtil.isNull(id)) {
return R.fail("ID不能为空");
}
DeptAppointmentHours deptAppointmentHours = deptAppointmentHoursService.getById(id);
if (ObjectUtil.isNull(deptAppointmentHours)) {
return R.fail("数据不存在");
}
return R.ok(deptAppointmentHours);
}
@Override
public R<?> addDeptAppthours(DeptAppointmentHours deptAppointmentHours) {
if (ObjectUtil.isNull(deptAppointmentHours)) {
return R.fail("数据不能为空");
}
if (StrUtil.isBlank(deptAppointmentHours.getInstitution())) {
return R.fail("所属机构不能为空");
}
if (StrUtil.isBlank(deptAppointmentHours.getDepartment())) {
return R.fail("科室名称不能为空");
}
deptAppointmentHours.setCreatedTime(LocalDateTime.now());
boolean save = deptAppointmentHoursService.save(deptAppointmentHours);
return R.ok(save);
}
@Override
public R<?> updateDeptAppthours(DeptAppointmentHours deptAppointmentHours) {
if (ObjectUtil.isNull(deptAppointmentHours) || ObjectUtil.isNull(deptAppointmentHours.getId())) {
return R.fail("ID不能为空");
}
DeptAppointmentHours existing = deptAppointmentHoursService.getById(deptAppointmentHours.getId());
if (ObjectUtil.isNull(existing)) {
return R.fail("数据不存在");
}
deptAppointmentHours.setUpdatedTime(LocalDateTime.now());
boolean update = deptAppointmentHoursService.updateById(deptAppointmentHours);
return R.ok(update);
}
@Override
public R<?> deleteDeptAppthours(Long id) {
if (ObjectUtil.isNull(id)) {
return R.fail("ID不能为空");
}
DeptAppointmentHours existing = deptAppointmentHoursService.getById(id);
if (ObjectUtil.isNull(existing)) {
return R.fail("数据不存在");
}
boolean remove = deptAppointmentHoursService.removeById(id);
return R.ok(remove);
}
}

View File

@@ -1,532 +0,0 @@
package com.openhis.web.appointmentmanage.appservice.impl;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.core.common.core.domain.R;
import com.core.common.utils.SecurityUtils;
import com.openhis.common.enums.SlotStatus;
import com.openhis.appointmentmanage.domain.DoctorSchedule;
import com.openhis.appointmentmanage.domain.DoctorScheduleWithDateDto;
import com.openhis.appointmentmanage.domain.SchedulePool;
import com.openhis.appointmentmanage.domain.ScheduleSlot;
import com.openhis.appointmentmanage.mapper.DoctorScheduleMapper;
import com.openhis.appointmentmanage.service.IDoctorScheduleService;
import com.openhis.appointmentmanage.service.ISchedulePoolService;
import com.openhis.appointmentmanage.service.IScheduleSlotService;
import com.openhis.web.appointmentmanage.appservice.IDoctorScheduleAppService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@Service
public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
@Resource
private IDoctorScheduleService doctorScheduleService;
@Resource
private ISchedulePoolService schedulePoolService;
@Resource
private IScheduleSlotService scheduleSlotService;
@Resource
private DoctorScheduleMapper doctorScheduleMapper;
@Override
public R<?> getDoctorScheduleList() {
List<DoctorSchedule> list = doctorScheduleService.list();
return R.ok(list);
}
@Override
public R<?> getDoctorScheduleListByDeptId(Long deptId) {
List<DoctorSchedule> list = doctorScheduleService.list(
new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<DoctorSchedule>()
.eq("dept_id", deptId));
return R.ok(list);
}
@Override
public R<?> getDoctorScheduleListByDeptIdAndDateRange(Long deptId, String startDate, String endDate) {
// 联表查询 adm_doctor_schedule LEFT JOIN adm_schedule_pool
// 通过 schedule_date 获取具体出诊日期,解决按星期匹配导致日期错位的问题
List<DoctorScheduleWithDateDto> list = doctorScheduleMapper.selectScheduleWithDateByDeptAndRange(
deptId, startDate, endDate);
return R.ok(list);
}
@Transactional(readOnly = true)
@Override
public R<?> getTodayDoctorScheduleList() {
// 联表查询 adm_schedule_pool按今日具体日期查询排班替代原来按星期匹配的方式
String todayStr = LocalDate.now().toString(); // yyyy-MM-dd
List<DoctorScheduleWithDateDto> list = doctorScheduleMapper.selectTodaySchedule(todayStr);
return R.ok(list);
}
@Transactional(readOnly = true)
@Override
public R<?> getTodayMySchedule() {
// 联表查询 adm_schedule_pool按今日具体日期 + 医生ID 查询个人排班
String todayStr = LocalDate.now().toString(); // yyyy-MM-dd
// 从 SecurityUtils 获取当前登录医生ID
Long currentDoctorId = SecurityUtils.getLoginUser().getPractitionerId();
if (currentDoctorId != null) {
List<DoctorScheduleWithDateDto> list = doctorScheduleMapper.selectTodayMySchedule(todayStr,
currentDoctorId);
return R.ok(list);
}
// 如果未绑定医生,则返回空列表
return R.ok(Collections.emptyList());
}
@Override
public R<?> addDoctorSchedule(DoctorSchedule doctorSchedule) {
if (ObjectUtil.isEmpty(doctorSchedule)) {
return R.fail("医生排班不能为空");
}
if (doctorSchedule.getLimitNumber() == null || doctorSchedule.getLimitNumber() <= 0) {
return R.fail("限号数量必须大于0");
}
// 创建新对象排除id字段数据库id列是GENERATED ALWAYS由数据库自动生成
DoctorSchedule newSchedule = new DoctorSchedule();
newSchedule.setWeekday(doctorSchedule.getWeekday());
newSchedule.setTimePeriod(doctorSchedule.getTimePeriod());
newSchedule.setDoctor(doctorSchedule.getDoctor());
newSchedule.setClinic(doctorSchedule.getClinic());
newSchedule.setStartTime(doctorSchedule.getStartTime());
newSchedule.setEndTime(doctorSchedule.getEndTime());
newSchedule.setLimitNumber(doctorSchedule.getLimitNumber());
// call_sign_record 字段不能为null设置默认值为空字符串
newSchedule.setCallSignRecord(
doctorSchedule.getCallSignRecord() != null ? doctorSchedule.getCallSignRecord() : "");
newSchedule.setRegisterItem(doctorSchedule.getRegisterItem() != null ? doctorSchedule.getRegisterItem() : "");
newSchedule.setRegisterFee(doctorSchedule.getRegisterFee() != null ? doctorSchedule.getRegisterFee() : 0);
newSchedule
.setDiagnosisItem(doctorSchedule.getDiagnosisItem() != null ? doctorSchedule.getDiagnosisItem() : "");
newSchedule.setDiagnosisFee(doctorSchedule.getDiagnosisFee() != null ? doctorSchedule.getDiagnosisFee() : 0);
newSchedule.setIsOnline(doctorSchedule.getIsOnline() != null ? doctorSchedule.getIsOnline() : true);
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字段让数据库自动生成
// 使用自定义的insertWithoutId方法确保INSERT语句不包含id字段
int result = doctorScheduleMapper.insertWithoutId(newSchedule);
if (result > 0) {
// 创建号源池并传入正确的医生ID
SchedulePool pool = createSchedulePool(newSchedule, doctorSchedule.getDoctorId());
boolean poolSaved = schedulePoolService.save(pool);
if (poolSaved) {
// 创建号源槽
List<ScheduleSlot> slots = createScheduleSlots(pool.getId(), newSchedule.getLimitNumber(),
newSchedule.getStartTime(), newSchedule.getEndTime());
boolean slotsSaved = scheduleSlotService.saveBatch(slots);
if (slotsSaved) {
// 不更新available_num字段因为它是数据库生成列
// pool.setAvailableNum(newSchedule.getLimitNumber());
// schedulePoolService.updateById(pool);
return R.ok(newSchedule);
} else {
throw new RuntimeException("创建号源槽失败");
}
} else {
throw new RuntimeException("创建号源池失败");
}
} else {
return R.fail("保存排班信息失败");
}
}
@Override
public R<?> addDoctorScheduleWithDate(DoctorSchedule doctorSchedule, String scheduledDate) {
if (ObjectUtil.isEmpty(doctorSchedule)) {
return R.fail("医生排班不能为空");
}
if (doctorSchedule.getLimitNumber() == null || doctorSchedule.getLimitNumber() <= 0) {
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());
newSchedule.setTimePeriod(doctorSchedule.getTimePeriod());
newSchedule.setDoctor(doctorSchedule.getDoctor());
newSchedule.setClinic(doctorSchedule.getClinic());
newSchedule.setStartTime(doctorSchedule.getStartTime());
newSchedule.setEndTime(doctorSchedule.getEndTime());
newSchedule.setLimitNumber(doctorSchedule.getLimitNumber());
// call_sign_record 字段不能为null设置默认值为空字符串
newSchedule.setCallSignRecord(
doctorSchedule.getCallSignRecord() != null ? doctorSchedule.getCallSignRecord() : "");
newSchedule.setRegisterItem(doctorSchedule.getRegisterItem() != null ? doctorSchedule.getRegisterItem() : "");
newSchedule.setRegisterFee(doctorSchedule.getRegisterFee() != null ? doctorSchedule.getRegisterFee() : 0);
newSchedule
.setDiagnosisItem(doctorSchedule.getDiagnosisItem() != null ? doctorSchedule.getDiagnosisItem() : "");
newSchedule.setDiagnosisFee(doctorSchedule.getDiagnosisFee() != null ? doctorSchedule.getDiagnosisFee() : 0);
newSchedule.setIsOnline(doctorSchedule.getIsOnline() != null ? doctorSchedule.getIsOnline() : true);
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字段让数据库自动生成
// 使用自定义的insertWithoutId方法确保INSERT语句不包含id字段
int result = doctorScheduleMapper.insertWithoutId(newSchedule);
if (result > 0) {
// 创建号源池并传入正确的医生ID和具体日期
SchedulePool pool = createSchedulePoolWithDate(newSchedule, doctorSchedule.getDoctorId(), scheduledDate);
boolean poolSaved = schedulePoolService.save(pool);
if (poolSaved) {
// 创建号源槽
List<ScheduleSlot> slots = createScheduleSlots(pool.getId(), newSchedule.getLimitNumber(),
newSchedule.getStartTime(), newSchedule.getEndTime());
boolean slotsSaved = scheduleSlotService.saveBatch(slots);
if (slotsSaved) {
return R.ok(newSchedule);
} else {
throw new RuntimeException("创建号源槽失败");
}
} else {
throw new RuntimeException("创建号源池失败");
}
} else {
return R.fail("保存排班信息失败");
}
}
@Transactional
@Override
public R<?> updateDoctorSchedule(DoctorSchedule doctorSchedule) {
if (ObjectUtil.isEmpty(doctorSchedule) || ObjectUtil.isEmpty(doctorSchedule.getId())) {
return R.fail("医生排班ID不能为空");
}
int result = doctorScheduleMapper.updateDoctorSchedule(doctorSchedule);
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);
}
/**
* 创建号源池
*/
private SchedulePool createSchedulePool(DoctorSchedule schedule, Long doctorId) {
SchedulePool pool = new SchedulePool();
// 生成唯一池编码
pool.setPoolCode("POOL_" + System.currentTimeMillis());
pool.setHospitalId(1L); // 默认医院ID实际项目中应从上下文获取
pool.setDoctorId(doctorId); // 使用正确的医生ID
pool.setDoctorName(schedule.getDoctor());
pool.setDeptId(schedule.getDeptId());
pool.setClinicRoom(schedule.getClinic());
// 设置出诊日期,这里假设是下周的对应星期
pool.setScheduleDate(calculateScheduleDate(schedule.getWeekday()));
pool.setShift(schedule.getTimePeriod());
pool.setStartTime(schedule.getStartTime());
pool.setEndTime(schedule.getEndTime());
pool.setTotalQuota(schedule.getLimitNumber());
pool.setBookedNum(0);
pool.setLockedNum(0);
// 不设置available_num因为它是数据库生成列
// pool.setAvailableNum(0); // 初始为0稍后更新
pool.setRegType(schedule.getRegisterItem() != null ? schedule.getRegisterItem() : "普通");
pool.setFee(schedule.getRegisterFee() != null ? Double.valueOf(schedule.getRegisterFee().toString()) : 0.0); // 直接使用原始价格
pool.setInsurancePrice(pool.getFee()); // 医保价格暂时与原价相同
// 暂时设置support_channel为空字符串避免JSON类型问题
pool.setSupportChannel("");
pool.setStatus(1); // 1表示可用
// 设置时间字段
java.util.Date now = new java.util.Date();
java.util.Date tomorrow = new java.util.Date(System.currentTimeMillis() + 24 * 60 * 60 * 1000); // 明天的时间
pool.setReleaseTime(now);
pool.setDeadlineTime(tomorrow); // 截止时间为明天
pool.setScheduleId(schedule.getId());
return pool;
}
/**
* 创建号源池(使用具体日期)
*/
private SchedulePool createSchedulePoolWithDate(DoctorSchedule schedule, Long doctorId, String scheduledDateStr) {
SchedulePool pool = new SchedulePool();
// 生成唯一池编码
pool.setPoolCode("POOL_" + System.currentTimeMillis());
pool.setHospitalId(1L); // 默认医院ID实际项目中应从上下文获取
pool.setDoctorId(doctorId); // 使用正确的医生ID
pool.setDoctorName(schedule.getDoctor());
pool.setDeptId(schedule.getDeptId());
pool.setClinicRoom(schedule.getClinic());
// 使用传入的具体日期
if (scheduledDateStr != null && !scheduledDateStr.isEmpty()) {
try {
LocalDate scheduledDate = LocalDate.parse(scheduledDateStr);
pool.setScheduleDate(scheduledDate);
} catch (Exception e) {
// 如果解析失败,回退到原来的计算方式
pool.setScheduleDate(calculateScheduleDate(schedule.getWeekday()));
}
} else {
// 如果没有提供具体日期,使用原来的计算方式
pool.setScheduleDate(calculateScheduleDate(schedule.getWeekday()));
}
pool.setShift(schedule.getTimePeriod());
pool.setStartTime(schedule.getStartTime());
pool.setEndTime(schedule.getEndTime());
pool.setTotalQuota(schedule.getLimitNumber());
pool.setBookedNum(0);
pool.setLockedNum(0);
// 不设置available_num因为它是数据库生成列
// pool.setAvailableNum(0); // 初始为0稍后更新
pool.setRegType(schedule.getRegisterItem() != null ? schedule.getRegisterItem() : "普通");
pool.setFee(schedule.getRegisterFee() != null ? Double.valueOf(schedule.getRegisterFee().toString()) : 0.0); // 直接使用原始价格
pool.setInsurancePrice(pool.getFee()); // 医保价格暂时与原价相同
// 暂时设置support_channel为空字符串避免JSON类型问题
pool.setSupportChannel("");
pool.setStatus(1); // 1表示可用
// 设置时间字段
java.util.Date now = new java.util.Date();
java.util.Date tomorrow = new java.util.Date(System.currentTimeMillis() + 24 * 60 * 60 * 1000); // 明天的时间
pool.setReleaseTime(now);
pool.setDeadlineTime(tomorrow); // 截止时间为明天
pool.setScheduleId(schedule.getId());
return pool;
}
/**
* 创建号源槽
*/
private List<ScheduleSlot> createScheduleSlots(Long poolId, Integer limitNumber, LocalTime startTime,
LocalTime endTime) {
List<ScheduleSlot> slots = new ArrayList<>();
// 计算时间间隔
long totalTimeMinutes = startTime.until(endTime, java.time.temporal.ChronoUnit.MINUTES);
long interval = totalTimeMinutes / limitNumber;
for (int i = 1; i <= limitNumber; i++) {
ScheduleSlot slot = new ScheduleSlot();
slot.setPoolId(poolId);
slot.setSeqNo(i); // 序号
slot.setStatus(0); // 0表示可用
// 计算预计叫号时间,均匀分布在开始时间和结束时间之间
LocalTime expectTime = startTime.plusMinutes(interval * (i - 1));
slot.setExpectTime(expectTime);
java.util.Date now = new java.util.Date();
slot.setCreateTime(now);
slot.setUpdateTime(now);
slots.add(slot);
}
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();
}
/**
* 根据星期几计算具体日期(下周的对应星期)
*/
private LocalDate calculateScheduleDate(String weekday) {
// 这里简单实现,实际项目中可能需要更复杂的日期计算逻辑
LocalDate today = LocalDate.now();
int currentDayOfWeek = today.getDayOfWeek().getValue(); // 1=Monday, 7=Sunday
int targetDayOfWeek = getDayOfWeekNumber(weekday); // 假设weekday是中文如"周一"
// 计算到下周对应星期的天数差
int daysToAdd = targetDayOfWeek - currentDayOfWeek + 7; // 加7确保是下周
return today.plusDays(daysToAdd);
}
/**
* 将中文星期转换为数字1=周一7=周日)
*/
private int getDayOfWeekNumber(String weekday) {
switch (weekday) {
case "周一":
return 1;
case "周二":
return 2;
case "周三":
return 3;
case "周四":
return 4;
case "周五":
return 5;
case "周六":
return 6;
case "周日":
return 7;
default:
return 1; // 默认周一
}
}
@Transactional
@Override
public R<?> removeDoctorSchedule(Integer doctorScheduleId) {
if (doctorScheduleId == null) {
return R.fail("排班id不能为空");
}
// 1. 根据排班ID找到关联的号源池
List<SchedulePool> pools = schedulePoolService.list(
new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<SchedulePool>()
.eq("schedule_id", doctorScheduleId));
if (ObjectUtil.isNotEmpty(pools)) {
List<Long> poolIds = pools.stream().map(SchedulePool::getId).collect(java.util.stream.Collectors.toList());
// 该排班下存在有效患者预约(号源槽:已预约/已锁定/已取号)则禁止删除;已退号、仅可用/已取消槽位不计入
long appointmentCount = scheduleSlotService.count(new QueryWrapper<ScheduleSlot>()
.in("pool_id", poolIds)
.in("status", SlotStatus.BOOKED.getValue(), SlotStatus.LOCKED.getValue(),
SlotStatus.CHECKED_IN.getValue()));
if (appointmentCount > 0) {
return R.fail("该排班已有患者预约,禁止删除!如需取消请先处理患者退预约或使用'停诊'功能。");
}
// 2. 根据号源池ID找到所有关联的号源槽
List<ScheduleSlot> slots = scheduleSlotService.list(
new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<ScheduleSlot>()
.in("pool_id", poolIds));
if (ObjectUtil.isNotEmpty(slots)) {
List<Long> slotIds = slots.stream().map(ScheduleSlot::getId)
.collect(java.util.stream.Collectors.toList());
// 3. 逻辑删除所有号源槽
scheduleSlotService.removeByIds(slotIds);
}
// 4. 逻辑删除所有号源池
schedulePoolService.removeByIds(poolIds);
}
// 5. 逻辑删除主排班记录
boolean removed = doctorScheduleService.removeById(doctorScheduleId);
return R.ok(removed);
}
}

View File

@@ -1,53 +0,0 @@
package com.openhis.web.appointmentmanage.appservice.impl;
import cn.hutool.core.util.ObjectUtil;
import com.core.common.core.domain.R;
import com.openhis.appointmentmanage.domain.SchedulePool;
import com.openhis.appointmentmanage.service.ISchedulePoolService;
import com.openhis.web.appointmentmanage.appservice.ISchedulePoolAppService;
import com.openhis.web.appointmentmanage.dto.SchedulePoolDto;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class SchedulePoolAppServiceImpl implements ISchedulePoolAppService {
@Resource
private ISchedulePoolService schedulePoolService;
@Override
public R<?> addSchedulePool(SchedulePoolDto schedulePoolDto) {
//1.数据检验
if(ObjectUtil.isNull(schedulePoolDto)){
return R.fail("号源不能为空");
}
//2.封装实体
SchedulePool schedulePool = new SchedulePool();
schedulePool.setHospitalId(schedulePoolDto.getHospitalId());
schedulePool.setDeptId(schedulePoolDto.getDeptId());
schedulePool.setDoctorId(schedulePoolDto.getDoctorId());
schedulePool.setDoctorName(schedulePoolDto.getDoctorName());
schedulePool.setScheduleDate(schedulePoolDto.getScheduleDate());
schedulePool.setShift(schedulePoolDto.getShift());
schedulePool.setStartTime(schedulePoolDto.getStartTime());
schedulePool.setEndTime(schedulePoolDto.getEndTime());
schedulePool.setRegType(schedulePoolDto.getRegType());
schedulePool.setFee(schedulePoolDto.getFee());
//3.保存
boolean save = schedulePoolService.save(schedulePool);
return R.ok(save);
}
@Override
public R<?> list(SchedulePoolDto schedulePoolDto) {
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<SchedulePool> wrapper =
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>();
wrapper.like(ObjectUtil.isNotEmpty(schedulePoolDto.getDoctorName()), SchedulePool::getDoctorName, schedulePoolDto.getDoctorName());
wrapper.eq(ObjectUtil.isNotNull(schedulePoolDto.getDeptId()), SchedulePool::getDeptId, schedulePoolDto.getDeptId());
wrapper.ge(ObjectUtil.isNotEmpty(schedulePoolDto.getQueryBeginDate()), SchedulePool::getScheduleDate, schedulePoolDto.getQueryBeginDate());
wrapper.le(ObjectUtil.isNotEmpty(schedulePoolDto.getQueryEndDate()), SchedulePool::getScheduleDate, schedulePoolDto.getQueryEndDate());
return R.ok(schedulePoolService.list(wrapper));
}
}

View File

@@ -1,8 +0,0 @@
package com.openhis.web.appointmentmanage.appservice.impl;
import com.openhis.web.appointmentmanage.appservice.IScheduleSlotAppService;
import org.springframework.stereotype.Service;
@Service
public class ScheduleSlotAppServiceImpl implements IScheduleSlotAppService {
}

View File

@@ -1,490 +0,0 @@
package com.openhis.web.appointmentmanage.appservice.impl;
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.mapper.ScheduleSlotMapper;
import com.openhis.clinical.domain.Ticket;
import com.openhis.clinical.service.ITicketService;
import com.openhis.web.appointmentmanage.appservice.ITicketAppService;
import com.openhis.web.appointmentmanage.dto.TicketDto;
import com.openhis.common.enums.SlotStatus;
import com.openhis.common.enums.OrderStatus;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 号源管理应用服务实现类
*
* @author system
*/
@Service
public class TicketAppServiceImpl implements ITicketAppService {
@Resource
private ITicketService ticketService;
@Resource
private ScheduleSlotMapper scheduleSlotMapper;
@Resource
private IPatientService patientService;
private static final Logger log = LoggerFactory.getLogger(TicketAppServiceImpl.class);
/**
* 预约号源 (重构版:精准锁定单一槽位)
*
* @param dto 预约参数
* @return 结果
*/
@Override
public R<?> bookTicket(com.openhis.appointmentmanage.domain.AppointmentBookDTO dto) {
Long slotId = dto.getSlotId();
if (slotId == null) {
return R.fail("参数校验失败:缺少排班槽位唯一标识");
}
try {
int result = ticketService.bookTicket(dto);
if (result > 0) {
return R.ok("预约成功!号源已安全锁定。");
}
return R.fail("预约挂单核发失败");
} catch (Exception e) {
log.error("大厅挂号捕获系统异常", e);
return R.fail("系统异常:" + e.getMessage());
}
}
/**
* 取消预约 (重构版:精准释放单一槽位)
*
* @param slotId 医生槽位排班ID
* @return 结果
*/
@Override
public R<?> cancelTicket(Long slotId) {
if (slotId == null) {
return R.fail("参数错误");
}
try {
int result = ticketService.cancelTicket(slotId);
return R.ok(result > 0 ? "取消成功,号源已重新释放回市场" : "取消失败");
} catch (Exception e) {
return R.fail(e.getMessage());
}
}
/**
* 取号
*
* @param slotId 槽位ID
* @return 结果
*/
@Override
public R<?> checkInTicket(Long slotId) {
if (slotId == null) {
return R.fail("参数错误");
}
try {
int result = ticketService.checkInTicket(slotId);
return R.ok(result > 0 ? "取号成功" : "取号失败");
} catch (Exception e) {
return R.fail(e.getMessage());
}
}
/**
* 停诊
*
* @param slotId 槽位ID
* @return 结果
*/
@Override
public R<?> cancelConsultation(Long slotId) {
if (slotId == null) {
return R.fail("参数错误");
}
try {
int result = ticketService.cancelConsultation(slotId);
return R.ok(result > 0 ? "停诊成功" : "停诊失败");
} catch (Exception e) {
return R.fail(e.getMessage());
}
}
@Override
public R<?> listTicket(com.openhis.appointmentmanage.dto.TicketQueryDTO query) {
// 1. 防空指针处理
if (query == null) {
query = new com.openhis.appointmentmanage.dto.TicketQueryDTO();
}
normalizeQueryStatus(query);
// 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());
// 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(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());
dto.setOrderId(raw.getOrderId());
dto.setOrderNo(raw.getOrderNo());
// 性别处理:直接使用患者表中的 genderEnum
Integer genderEnum = raw.getGenderEnum();
if (genderEnum != null) {
if (Integer.valueOf(1).equals(genderEnum)) {
dto.setGender("");
} else if (Integer.valueOf(2).equals(genderEnum)) {
dto.setGender("");
} else {
dto.setGender("未知");
}
} else {
dto.setGender("未知");
}
if (raw.getRegType() != null && raw.getRegType() == 1) {
dto.setTicketType("expert");
} else {
dto.setTicketType("general");
}
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());
}
}
if (Boolean.TRUE.equals(raw.getIsStopped())) {
dto.setStatus("已停诊");
} else {
SlotStatus status = SlotStatus.getByValue(raw.getSlotStatus());
if (status != null) {
if (status == SlotStatus.LOCKED) {
if (OrderStatus.PATIENT_CANCELLED.getValue().equals(raw.getOrderStatus())) {
dto.setStatus("已退号");
} else {
dto.setStatus("已锁定");
}
} else if (status == SlotStatus.BOOKED) {
if (OrderStatus.PATIENT_CANCELLED.getValue().equals(raw.getOrderStatus())) {
dto.setStatus("已退号");
} else {
dto.setStatus("已取号");
}
} else if (status == SlotStatus.CANCELLED) {
dto.setStatus("已停诊");
} else if (status == SlotStatus.RETURNED) {
dto.setStatus("已退号");
} else {
dto.setStatus("未预约");
}
} else {
dto.setStatus("未预约");
}
}
tickets.add(dto);
}
}
// 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 条件失效后回全量数据
*/
/**
* 规范前端传入的状态查询参数,映射到 SQL 的 slotStatusNormExpr 值。
* 数值映射: 0=待约 1=已约(签到后) 2=锁定(预约后) 3=已签到 4=已停诊 5=已退号
*/
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 "locked":
case "2":
case "已锁定":
query.setStatus("locked");
break;
case "checked":
case "checkin":
case "checkedin":
case "3":
case "已取号":
query.setStatus("checked");
break;
case "cancelled":
case "canceled":
case "4":
case "已停诊":
case "已取消":
query.setStatus("cancelled");
break;
case "returned":
case "5":
case "已退号":
query.setStatus("returned");
break;
default:
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: 已锁定...)
SlotStatus status = SlotStatus.getByValue(raw.getSlotStatus());
if (status != null) {
if (status == SlotStatus.LOCKED) {
if (OrderStatus.PATIENT_CANCELLED.getValue().equals(raw.getOrderStatus())) {
dto.setStatus("已退号");
} else {
dto.setStatus("已锁定");
}
} else if (status == SlotStatus.BOOKED) {
if (OrderStatus.PATIENT_CANCELLED.getValue().equals(raw.getOrderStatus())) {
dto.setStatus("已退号");
} else {
dto.setStatus("已取号");
}
} else if (status == SlotStatus.CANCELLED) {
dto.setStatus("已停诊");
} else if (status == SlotStatus.RETURNED) {
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);
}
/**
* 转换为DTO
*
* @param ticket 号源实体
* @return 号源DTO
*/
private TicketDto convertToDto(Ticket ticket) {
TicketDto dto = new TicketDto();
dto.setSlot_id(ticket.getId());
dto.setBusNo(ticket.getBusNo());
dto.setDepartment(ticket.getDepartment());
dto.setDoctor(ticket.getDoctor());
// 处理号源类型转换为英文前端期望的是general或expert
String ticketType = ticket.getTicketType();
if ("普通".equals(ticketType)) {
dto.setTicketType("general");
} else if ("专家".equals(ticketType)) {
dto.setTicketType("expert");
} else {
dto.setTicketType(ticketType);
}
// 处理号源时间dateTime
dto.setDateTime(ticket.getTime());
// 处理号源状态(转换为中文)
String status = ticket.getStatus();
switch (status) {
case "unbooked":
dto.setStatus("未预约");
break;
case "booked":
dto.setStatus("已预约");
break;
case "checked":
dto.setStatus("已取号");
break;
case "cancelled":
dto.setStatus("已取消");
break;
default:
dto.setStatus(status);
}
dto.setFee(ticket.getFee());
dto.setPatientName(ticket.getPatientName());
dto.setPatientId(ticket.getMedicalCard()); // 就诊卡号
dto.setPhone(ticket.getPhone());
// 获取患者性别
if (ticket.getPatientId() != null) {
Patient patient = patientService.getById(ticket.getPatientId());
if (patient != null) {
Integer genderEnum = patient.getGenderEnum();
if (genderEnum != null) {
if (Integer.valueOf(1).equals(genderEnum)) {
dto.setGender("");
} else if (Integer.valueOf(2).equals(genderEnum)) {
dto.setGender("");
} else {
dto.setGender("未知");
}
}
}
}
dto.setAppointmentDate(ticket.getAppointmentDate());
dto.setAppointmentTime(ticket.getAppointmentTime());
dto.setDepartmentId(ticket.getDepartmentId());
dto.setDoctorId(ticket.getDoctorId());
return dto;
}
}

View File

@@ -1,73 +0,0 @@
package com.openhis.web.appointmentmanage.controller;
import com.core.common.core.domain.R;
import com.openhis.appointmentmanage.domain.ClinicRoom;
import com.openhis.web.appointmentmanage.appservice.IClinicRoomAppService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@RestController
@RequestMapping("/appoinment/clinic-room")
public class ClinicRoomController {
@Resource
private IClinicRoomAppService clinicRoomAppService;
/**
* 分页查询诊室列表
* @param pageNum 页码
* @param pageSize 每页条数
* @param orgName 卫生机构名称
* @param roomName 诊室名称
* @return 分页查询结果
*/
@GetMapping("/page")
public R<?> selectClinicRoomPage(
@RequestParam(required = true) Integer pageNum,
@RequestParam(required = true) Integer pageSize,
@RequestParam(required = false) String orgName,
@RequestParam(required = false) String roomName) {
return clinicRoomAppService.selectClinicRoomPage(pageNum, pageSize, orgName, roomName);
}
/**
* 查询诊室详情
* @param id 诊室ID
* @return 诊室详情
*/
@GetMapping("/{id}")
public R<?> selectClinicRoomById(@PathVariable Long id) {
return clinicRoomAppService.selectClinicRoomById(id);
}
/**
* 新增诊室
* @param clinicRoom 诊室信息
* @return 新增结果
*/
@PostMapping
public R<?> insertClinicRoom(@RequestBody ClinicRoom clinicRoom) {
return clinicRoomAppService.insertClinicRoom(clinicRoom);
}
/**
* 更新诊室
* @param clinicRoom 诊室信息
* @return 更新结果
*/
@PutMapping
public R<?> updateClinicRoom(@RequestBody ClinicRoom clinicRoom) {
return clinicRoomAppService.updateClinicRoom(clinicRoom);
}
/**
* 删除诊室
* @param id 诊室ID
* @return 删除结果
*/
@DeleteMapping("/{id}")
public R<?> deleteClinicRoomById(@PathVariable Long id) {
return clinicRoomAppService.deleteClinicRoomById(id);
}
}

View File

@@ -1,82 +0,0 @@
package com.openhis.web.appointmentmanage.controller;
import com.core.common.core.domain.R;
import com.openhis.appointmentmanage.domain.DeptAppointmentHours;
import com.openhis.web.appointmentmanage.appservice.IDeptAppointmentHoursAppService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* 科室预约工作时间维护 Controller
*
* @author openhis
* @date 2025-12-12
*/
@RestController
@RequestMapping("/appoinment/dept-appthours")
public class DeptAppthoursController {
@Resource
private IDeptAppointmentHoursAppService deptAppointmentHoursAppService;
/**
* 获取科室预约工作时间列表
*
* @param deptAppointmentHours 查询条件
* @param pageNum 页码
* @param pageSize 每页大小
* @return 列表数据
*/
@GetMapping("/page")
public R<?> getDeptAppthoursList(
DeptAppointmentHours deptAppointmentHours,
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) {
return deptAppointmentHoursAppService.getDeptAppthoursList(deptAppointmentHours, pageNum, pageSize);
}
/**
* 获取科室预约工作时间详情
*
* @param id 记录ID
* @return 详情数据
*/
@GetMapping("/{id}")
public R<?> getDeptAppthoursDetail(@PathVariable("id") Long id) {
return deptAppointmentHoursAppService.getDeptAppthoursDetail(id);
}
/**
* 新增科室预约工作时间
*
* @param deptAppointmentHours 新增数据
* @return 操作结果
*/
@PostMapping
public R<?> addDeptAppthours(@RequestBody DeptAppointmentHours deptAppointmentHours) {
return deptAppointmentHoursAppService.addDeptAppthours(deptAppointmentHours);
}
/**
* 修改科室预约工作时间
*
* @param deptAppointmentHours 修改数据
* @return 操作结果
*/
@PutMapping
public R<?> updateDeptAppthours(@RequestBody DeptAppointmentHours deptAppointmentHours) {
return deptAppointmentHoursAppService.updateDeptAppthours(deptAppointmentHours);
}
/**
* 删除科室预约工作时间
*
* @param id 记录ID
* @return 操作结果
*/
@DeleteMapping("/{id}")
public R<?> deleteDeptAppthours(@PathVariable("id") Long id) {
return deptAppointmentHoursAppService.deleteDeptAppthours(id);
}
}

View File

@@ -1,61 +0,0 @@
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.*;
import javax.annotation.Resource;
@RestController
@RequestMapping("/dept")
public class DeptController {
@Resource
private IDeptAppService deptAppService;
@Resource
private IAppointmentConfigAppService appointmentConfigAppService;
/*
* 获取科室列表
*
* */
@GetMapping("/list")
public R<?> getDeptList(){
return R.ok(deptAppService.getDeptList());
}
/*
* 查询科室
*
* */
@GetMapping("/search")
public R<?> searchDept(
@RequestParam(required = false,defaultValue = "1") Integer pageNo,
@RequestParam(required = false,defaultValue = "10") Integer pageSize,
@RequestParam(required = false)String orgName,
@RequestParam(required = false)String deptName
){
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

@@ -1,100 +0,0 @@
package com.openhis.web.appointmentmanage.controller;
import com.core.common.core.domain.R;
import com.openhis.appointmentmanage.domain.DoctorSchedule;
import com.openhis.web.appointmentmanage.appservice.IDoctorScheduleAppService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@RestController
@RequestMapping("/doctor-schedule")
public class DoctorScheduleController {
@Resource
private IDoctorScheduleAppService doctorScheduleAppService;
/*
* 获取医生排班List
*
* */
@GetMapping("/list")
public R<?> getDoctorScheduleList() {
return R.ok(doctorScheduleAppService.getDoctorScheduleList());
}
/*
* 根据科室ID获取医生排班List
*
* */
@GetMapping("/list-by-dept/{deptId}")
public R<?> getDoctorScheduleListByDeptId(@PathVariable Long deptId) {
return R.ok(doctorScheduleAppService.getDoctorScheduleListByDeptId(deptId));
}
/*
* 根据科室ID和日期范围获取医生排班List
*
* */
@GetMapping("/list-by-dept-and-date")
public R<?> getDoctorScheduleListByDeptIdAndDateRange(@RequestParam Long deptId,
@RequestParam String startDate,
@RequestParam String endDate) {
return R.ok(doctorScheduleAppService.getDoctorScheduleListByDeptIdAndDateRange(deptId, startDate, endDate));
}
/*
* 新增医生排班
*
* */
@PostMapping("/add")
public R<?> addDoctorSchedule(@RequestBody DoctorSchedule doctorSchedule) {
return doctorScheduleAppService.addDoctorSchedule(doctorSchedule);
}
/*
* 新增医生排班(带具体日期)
* */
@PostMapping("/add-with-date")
public R<?> addDoctorScheduleWithDate(@RequestBody DoctorSchedule doctorSchedule) {
// 从DoctorSchedule对象中获取scheduledDate字段
String scheduledDate = doctorSchedule.getScheduledDate();
return doctorScheduleAppService.addDoctorScheduleWithDate(doctorSchedule, scheduledDate);
}
/*
* 修改医生排班
*
* */
@PutMapping("/update")
public R<?> updateDoctorSchedule(@RequestBody DoctorSchedule doctorSchedule) {
return doctorScheduleAppService.updateDoctorSchedule(doctorSchedule);
}
/*
* 删除医生排班
*
* */
@DeleteMapping("/delete/{doctorScheduleId}")
public R<?> removeDoctorSchedule(@PathVariable Integer doctorScheduleId){
return doctorScheduleAppService.removeDoctorSchedule(doctorScheduleId);
}
/*
* 获取今日医生排班List
*
* */
@GetMapping("/today")
public R<?> getTodayDoctorScheduleList() {
return R.ok(doctorScheduleAppService.getTodayDoctorScheduleList());
}
/*
* 获取当前登录医生今日排班List
*
* */
@GetMapping("/today-my-schedule")
public R<?> getTodayMySchedule() {
return doctorScheduleAppService.getTodayMySchedule();
}
}

View File

@@ -1,35 +0,0 @@
package com.openhis.web.appointmentmanage.controller;
import com.core.common.core.domain.R;
import com.openhis.web.appointmentmanage.appservice.ISchedulePoolAppService;
import com.openhis.web.appointmentmanage.dto.SchedulePoolDto;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@RestController
@RequestMapping("/schedule-pool")
public class SchedulePoolController {
@Resource
private ISchedulePoolAppService schedulePoolAppService;
/*
* 新增号源
*
* */
@PostMapping("/add")
public R<?> addSchedulePool(@RequestBody SchedulePoolDto schedulePoolDto) {
return schedulePoolAppService.addSchedulePool(schedulePoolDto);
}
/*
* 查询号源
*
* */
@GetMapping("/list")
public R<?> list(SchedulePoolDto schedulePoolDto) {
return schedulePoolAppService.list(schedulePoolDto);
}
}

View File

@@ -1,9 +0,0 @@
package com.openhis.web.appointmentmanage.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/schedule-slot")
public class ScheduleSlotController {
}

View File

@@ -1,107 +0,0 @@
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;
import java.util.Map;
/**
* 号源管理控制器
*
* @author system
*/
@RestController
@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 所有号源列表
*/
@Anonymous
@GetMapping("/listAll")
public R<?> listAllTickets() {
return ticketAppService.listAllTickets();
}
/**
* 预约号源
*
* @param dto 预约参数
* @return 结果
*/
@PostMapping("/book")
public R<?> bookTicket(@RequestBody @Validated AppointmentBookDTO dto) {
return ticketAppService.bookTicket(dto);
}
/**
* 取消预约
*
* @param slotId 槽位ID
* @return 结果
*/
@PostMapping("/cancel")
public R<?> cancelTicket(@RequestParam Long slotId) {
return ticketAppService.cancelTicket(slotId);
}
/**
* 取号
*
* @param slotId 槽位ID
* @return 结果
*/
@PostMapping("/checkin")
public R<?> checkInTicket(@RequestParam Long slotId) {
return ticketAppService.checkInTicket(slotId);
}
/**
* 停诊
*
* @param slotId 槽位ID
* @return 结果
*/
@PostMapping("/cancelConsultation")
public R<?> cancelConsultation(@RequestParam Long slotId) {
return ticketAppService.cancelConsultation(slotId);
}
}

View File

@@ -1,108 +0,0 @@
package com.openhis.web.appointmentmanage.dto;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
/**
* 号源池Dto
*
* @date 2025-12-12
*/
@Data
public class SchedulePoolDto {
/** id */
private Long id;
/** 业务编号 */
private String poolCode;
/** 医院ID */
private Long hospitalId;
/** 科室ID */
private Long deptId;
/** 医生ID */
private Long doctorId;
/** 医生姓名 */
private String doctorName;
/** 诊室 */
private String clinicRoom;
/** 出诊日期 */
private LocalDate scheduleDate;
/** 班别 */
private String shift;
/** 开始时间 */
private LocalTime startTime;
/** 结束时间 */
private LocalTime endTime;
/** 总号量 */
private Integer totalQuota;
/** 已约 */
private Integer bookedNum;
/** 铁号数 */
private Integer lockedNum;
/** 剩余号数 */
private Integer availableNum;
/** 号别 */
private String regType;
/** 原价 (元) */
private Double fee;
/** 医保限价 (元) */
private Double insurancePrice;
/** 支持渠道 */
private String supportChannel;
/** 号源状态 */
private Integer status;
/** 停诊原因 */
private String stopReason;
/** 放号时间 */
private LocalDateTime releaseTime;
/** 截止预约时间 */
private LocalDateTime deadlineTime;
/** 乐观锁版本 */
private Integer version;
/** 操作人ID */
private Long opUserId;
/** 备注 */
private String remark;
/** 排班ID */
private Long scheduleId;
/** 创建时间 */
private LocalDateTime createTime;
/** 更新时间 */
private LocalDateTime updateTime;
/** 查询开始日期 */
private String queryBeginDate;
/** 查询结束日期 */
private String queryEndDate;
}

View File

@@ -1,129 +0,0 @@
package com.openhis.web.appointmentmanage.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* 号源管理DTO
*
* @author system
*/
@Data
@Accessors(chain = true)
public class TicketDto {
/**
* 号源唯一ID
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long slot_id;
/**
* 号源序号(对应 adm_schedule_slot.seq_no
*/
private Integer seqNo;
/**
* 号源编码
*/
private String busNo;
/**
* 科室名称
*/
private String department;
/**
* 医生姓名
*/
private String doctor;
/**
* 号源类型 (普通/专家)
*/
private String ticketType;
/**
* 号源时间
*/
private String dateTime;
/**
* 状态
*/
private String status;
/**
* 挂号费
*/
private String fee;
/**
* 患者姓名
*/
private String patientName;
/**
* 就诊卡号
*/
private String patientId;
/**
* 手机号
*/
private String phone;
/**
* 患者性别
*/
private String gender;
/**
* 预约日期
*/
private Date appointmentDate;
/**
* 预约时间
*/
private Date appointmentTime;
/**
* 科室ID
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long departmentId;
/**
* 医生ID
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long doctorId;
/**
* 真实患者ID数据库主键区别于 patientId 存的就诊卡号)
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long realPatientId;
/**
* 身份证号
*/
private String idCard;
/**
* 预约订单ID
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long orderId;
/**
* 预约订单号
*/
private String orderNo;
}

View File

@@ -1,7 +0,0 @@
package com.openhis.web.appointmentmanage.mapper;
import org.springframework.stereotype.Repository;
@Repository
public interface DeptAppMapper {
}

View File

@@ -1,7 +0,0 @@
package com.openhis.web.appointmentmanage.mapper;
import org.springframework.stereotype.Repository;
@Repository
public interface DoctorScheduleAppMapper {
}

View File

@@ -1,7 +0,0 @@
package com.openhis.web.appointmentmanage.mapper;
import org.springframework.stereotype.Repository;
@Repository
public interface SchedulePoolAppMapper {
}

View File

@@ -1,7 +0,0 @@
package com.openhis.web.appointmentmanage.mapper;
import org.springframework.stereotype.Repository;
@Repository
public interface ScheduleSlotAppMapper {
}

View File

@@ -1,63 +0,0 @@
package com.openhis.web.basedatamanage.appservice;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
import com.openhis.web.basedatamanage.dto.BodyStructureDto;
import javax.servlet.http.HttpServletRequest;
/**
* BodyStructure 应该服务类
*/
public interface IBodyStructureAppService {
/**
* 查询身体部位树
*
* @param pageNo 当前页码
* @param pageSize 查询条数
* @param request 请求数据
* @return 身体部位树分页列表
*/
Page<BodyStructureDto> getBodyStructureTree(Integer pageNo, Integer pageSize, HttpServletRequest request);
/**
* 身体部位信息详情
*
* @param id 身体部位信息id
* @return 身体部位详情
*/
R<?> getBodyStructureInfo(Long id);
/**
* 添加/编辑体身体部位信息
*
* @param bodyStructureDto 身体部位信息
* @return 操作结果
*/
R<?> addOrEditBodyStructure(BodyStructureDto bodyStructureDto);
/**
* 身体部位信息
*
* @param ids 身体部位信息id
* @return 操作结果
*/
R<?> deleteBodyStructure(String ids);
/**
* 身体部位启用
*
* @param id 身体部位信息id
* @return 操作结果
*/
R<?> activeBodyStructure(Long id);
/**
* 身体部位停用
*
* @param id 身体部位信息id
* @return 操作结果
*/
R<?> inactiveBodyStructure(Long id);
}

View File

@@ -1,92 +0,0 @@
package com.openhis.web.basedatamanage.appservice;
import com.core.common.core.domain.R;
import com.openhis.web.basedatamanage.dto.LocationAddOrEditDto;
import com.openhis.web.basedatamanage.dto.LocationPageParam;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
/**
* Location 应该服务类
*/
public interface ILocationAppService {
/**
* 位置信息
*
* @param formList 类型
* @param pageNo 当前页码
* @param pageSize 查询条数
* @param isInHospital 是否为住院
* @return 位置信息分页列表
*/
R<?> getLocationTree(List<Integer> formList, Integer pageNo, Integer pageSize, String isInHospital);
/**
* 位置信息详情
*
* @param locationId 位置信息id
* @return 位置信息详情
*/
R<?> getLocationById(Long locationId);
/**
* 删除位置信息
*
* @param busNo 位置信息编码
* @return 操作结果
*/
R<?> deleteLocation(String busNo);
/**
* 位置分页列表
*
* @param locationPageParam 查询条件
* @param pageNo 当前页码
* @param pageSize 查询条数
* @param searchKey 模糊查询条件
* @param request 请求
* @return 位置分页列表
*/
R<?> getLocationPage(LocationPageParam locationPageParam, String searchKey, Integer pageNo, Integer pageSize,
HttpServletRequest request);
/**
* 新增位置信息
*
* @param locationAddOrEditDto 库房位置信息
* @return 操作结果
*/
R<?> addLocation(LocationAddOrEditDto locationAddOrEditDto);
/**
* 编辑位置信息
*
* @param locationAddOrEditDto 库房位置信息
* @return 操作结果
*/
R<?> editLocation(LocationAddOrEditDto locationAddOrEditDto);
/**
* 位置初始化
*
* @return 初始化信息
*/
R<?> locationInit();
/**
* 启用
*
* @param locationIdList 位置id
* @return 操作结果
*/
R<?> enableLocation(List<Long> locationIdList);
/**
* 停用
*
* @param locationIdList 位置id
* @return 操作结果
*/
R<?> deactivateLocation(List<Long> locationIdList);
}

Some files were not shown because too many files have changed in this diff Show More