liusheng
2026-11-03 7191c6d38f03f2e1baf39f959227ce9c038e4e96
ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/CollectHISServiceImpl.java
@@ -12,7 +12,6 @@
import com.ruoyi.quartz.mapper.CollectHISMapper;
import com.ruoyi.quartz.service.ICollectHISService;
import com.smartor.domain.*;
import com.smartor.domain.entity.ServiceSubtaskEntity;
import com.smartor.mapper.*;
import com.smartor.service.IPatMedOuthospService;
import lombok.extern.slf4j.Slf4j;
@@ -28,6 +27,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;
@@ -36,6 +36,18 @@
import com.ruoyi.othervisit.domain.PatMedOperation;
import com.ruoyi.outpatientvisit.domain.PatMedOuthosp;
import com.ruoyi.inhospvisit.domain.PatMedInhosp;
import com.ruoyi.common.core.domain.entity.PatArchive;
import com.ruoyi.task.domain.entity.ServiceSubtaskEntity;
import com.ruoyi.task.domain.ServiceSubtask;
import com.ruoyi.task.mapper.ServiceSubtaskMapper;
import com.ruoyi.patarchive.mapper.PatArchiveMapper;
import com.ruoyi.common.core.domain.entity.Icd10;
import com.ruoyi.common.mapper.Icd10Mapper;
import com.ruoyi.system.mapper.ext.SysUser2Mapper;
import com.ruoyi.system.mapper.ext.SysDept2Mapper;
import com.ruoyi.system.mapper.ext.SysUserDeptMapper;
import com.ruoyi.patarchive.mapper.ShardingMapper;
import com.ruoyi.datacollection.domain.HnDataGatherVO;
@Slf4j
@Service
public class CollectHISServiceImpl implements ICollectHISService {
@@ -89,6 +101,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";
@@ -712,6 +729,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);
@@ -826,7 +876,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);