ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/CollectHISServiceImpl.java
@@ -26,6 +26,7 @@
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -76,6 +77,11 @@
    @Autowired
    private RedisCache redisCache;
    /**
     * 用户同步任务运行标记,避免重复点击/重复调用并发跑全量同步
     */
    private final AtomicBoolean userSyncRunning = new AtomicBoolean(false);
    private static final long SHARDING_THRESHOLD = 5_000_000L;
    private static final String PAT_ARCHIVE_TABLE = "pat_archive";
@@ -454,8 +460,14 @@
        if(StringUtils.isNotEmpty(operation.getOpid())){
            PatMedOperationItem patMedOperationItem = new PatMedOperationItem();
            //patMedOperation.opReqid = patMedOperationItem.operationid
            patMedOperationItem.setOperationid(operation.getOpreqid());
            List<PatMedOperationItem> patMedOperationItems = chMapper.selectOperItemList(patMedOperationItem);
            List<PatMedOperationItem> patMedOperationItems = new ArrayList<>();
            if (ObjectUtils.isNotEmpty(operation.getOpreqid())){
                patMedOperationItem.setOperationid(operation.getOpreqid());
                patMedOperationItems = chMapper.selectOperItemList(patMedOperationItem);
            }else {
                log.info("同步手术详情信息:手术申请单ID为空!");
                return count;
            }
            PatMedOperationItem operItem = new PatMedOperationItem();
            operItem.setOperationid(operation.getOpreqid());
@@ -697,6 +709,39 @@
        return size;
    }
    /**
     * 异步同步用户信息:接口立即返回,实际同步交给线程池后台执行。
     * 使用 AtomicBoolean 防止重复提交导致多个全量同步任务并发执行。
     */
    @Override
    public boolean selectUserListAsync(SysUser sysUser) {
        if (!userSyncRunning.compareAndSet(false, true)) {
            log.warn("用户信息同步任务正在执行中,忽略本次提交");
            return false;
        }
        try {
            taskExecutor.execute(() -> {
                long start = System.currentTimeMillis();
                log.info("用户信息异步同步任务开始执行");
                try {
                    Integer count = selectUserList(sysUser);
                    log.info("用户信息异步同步任务执行完成,处理数量:{},耗时:{}ms",
                            count, System.currentTimeMillis() - start);
                } catch (Throwable e) {
                    log.error("用户信息异步同步任务执行失败,耗时:{}ms",
                            System.currentTimeMillis() - start, e);
                } finally {
                    userSyncRunning.set(false);
                }
            });
            return true;
        } catch (RuntimeException e) {
            userSyncRunning.set(false);
            log.error("用户信息异步同步任务提交失败", e);
            return false;
        }
    }
    @Override
    public Integer selectUserList(SysUser sysUser) {
        List<SysUser> sysUserList = chMapper.selectUserList(sysUser);
@@ -811,7 +856,12 @@
        log.info("selectDeptList的采集到的数量为:{}", sysDepts.size());
        // count = sysDept2Mapper.batchDept(sysDepts);
        for (SysDept row : sysDepts) {
            SysDept sysDeptTemp = sysDept2Mapper.selectDeptByCode(row.getDeptCode(), null);
            // 科室和病区可能共用同一个 dept_code,必须按 dept_type + orgid 精确定位,否则 selectOne 会返回多条
            if (StringUtils.isEmpty(row.getDeptCode())) {
                log.warn("selectDeptList跳过deptCode为空的记录:{}", row);
                continue;
            }
            SysDept sysDeptTemp = sysDept2Mapper.selectDeptByCodeAndType(row.getDeptCode(), row.getOrgid(), row.getDeptType());
            if (sysDeptTemp != null && sysDeptTemp.getDeptName() != null) {
                row.setDeptId(sysDeptTemp.getDeptId());
                count += sysDept2Mapper.updateDept(row);