陈昶聿
2 天以前 cf8712a9c0816559f50644f15672e7359028c4c4
smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskAnswerServiceImpl.java
@@ -63,6 +63,9 @@
import com.ruoyi.task.service.IServiceSubtaskDetailTraceService;
import com.ruoyi.task.domain.ServiceSubtaskPreachform;
import com.ruoyi.task.service.IServiceTaskService;
import com.ruoyi.task.mapper.ServiceSubtaskPreachformMapper;
import com.ruoyi.task.event.FollowupCompletedEventPublisher;
import com.ruoyi.patarchive.mapper.PatArchiveMapper;
/**
 * 任务问卷问题选项Service业务层处理
 *
@@ -89,6 +92,9 @@
    @Autowired
    private ServiceSubtaskMapper serviceSubtaskMapper;
    @Autowired
    private FollowupCompletedEventPublisher followupCompletedEventPublisher;
    @Autowired
    private ServiceSubtaskPreachformMapper serviceSubtaskPreachformMapper;
@@ -474,6 +480,7 @@
                log.error("将该key和value从redis中,serviceSubtask的值为--------:{}", serviceSubtask);
                serviceSubtask.setScore(formatScore(scoreTotal));
                serviceSubtaskMapper.updateServiceSubtaskByCondition(serviceSubtask);
                followupCompletedEventPublisher.publish(serviceSubtask.getId());
                //将当前发送状态改成 9 完成(缓存 preachform 查询)
                String currentPreachform = serviceSubtask.getCurrentPreachform();
@@ -516,8 +523,29 @@
        }
    }
    /**
     * 同一份问卷的保存锁:按「任务+患者+子任务」加锁,
     * 前端重复点击 / 并发请求进来时串行执行,避免同一份问卷被写两遍。
     * 注意:只是串行化,不阻止再次保存——问卷仍然允许修改后再保存(走更新逻辑)。
     */
    private static final java.util.concurrent.ConcurrentHashMap<String, Object> SAVE_LOCKS =
            new java.util.concurrent.ConcurrentHashMap<>();
    @Override
    public Integer saveQuestionDetail(ServiceSubTaskCacheReq serviceSubTaskCacheReq, Long flag) {
        String lockKey = serviceSubTaskCacheReq.getParam1() + "_"
                + serviceSubTaskCacheReq.getParam2() + "_"
                + serviceSubTaskCacheReq.getParam6();
        Object lock = SAVE_LOCKS.computeIfAbsent(lockKey, k -> new Object());
        if (SAVE_LOCKS.size() > 20000) {
            SAVE_LOCKS.clear();
        }
        synchronized (lock) {
            return doSaveQuestionDetail(serviceSubTaskCacheReq, flag);
        }
    }
    private Integer doSaveQuestionDetail(ServiceSubTaskCacheReq serviceSubTaskCacheReq, Long flag) {
        Long tid = Long.valueOf(serviceSubTaskCacheReq.getParam1());
        Long pid = Long.valueOf(serviceSubTaskCacheReq.getParam2());
        Long subid = Long.valueOf(serviceSubTaskCacheReq.getParam6());
@@ -641,6 +669,7 @@
            serviceSubtask.setUpdateTime(new Date());
            serviceSubtask.setScore(formatScore(scoreTotal));
            serviceSubtaskMapper.updateServiceSubtaskByCondition(serviceSubtask);
            followupCompletedEventPublisher.publish(serviceSubtask.getId());
            //将当前发送状态改成9完成
            ServiceSubtaskPreachform serviceSubtaskPreachform = new ServiceSubtaskPreachform();
@@ -800,6 +829,7 @@
                serviceSubtask.setVisitTime(new Date());
                serviceSubtask.setScore(formatScore(scoreTotal));
                serviceSubtaskMapper.insertServiceSubtask(serviceSubtask);
                followupCompletedEventPublisher.publish(serviceSubtask.getId());
                //将当前发送状态改成9完成
                ServiceSubtaskPreachform serviceSubtaskPreachform = new ServiceSubtaskPreachform();
                serviceSubtaskPreachform.setPreachform(serviceSubtask.getCurrentPreachform());
@@ -920,7 +950,8 @@
        Map<String, Object> map = new HashMap<>();
        if (serviceSubTaskQueryReq.getSubId() != null) {
            ServiceSubtask serviceSubtask = serviceSubtaskMapper.selectServiceSubtaskById(serviceSubTaskQueryReq.getSubId());
            if (serviceSubtask.getSendstate() == 4L) {
            // 任务可能已被删除/查不到,sendstate 也可能为空,这里必须判空,否则拆箱会 NPE
            if (serviceSubtask != null && Long.valueOf(4L).equals(serviceSubtask.getSendstate())) {
                log.info("患者子任务ID为:{},状态为:{}", serviceSubTaskQueryReq.getSubId(), serviceSubtask.getSendstate());
                throw new BaseException("该任务不执行");
            }
@@ -933,7 +964,7 @@
        //获取上次的问答结果
        ServiceSubtask serviceSubtask = serviceSubtaskMapper.selectServiceSubtaskById(serviceSubTaskQueryReq.getSubId());
        map.put("upScriptResult", null);
        map.put("templateName", serviceSubtask.getTemplatename());
        map.put("templateName", serviceSubtask == null ? null : serviceSubtask.getTemplatename());
        map.put("upTaskName", null);
        if (ObjectUtils.isNotEmpty(serviceSubtask) && serviceSubtask.getUpid() != null) {
            Map<String, Object> scriptInfoByCondition2 = serviceTaskService.getScriptInfoByCondition(serviceSubTaskQueryReq.getTaskid(), serviceSubTaskQueryReq.getPatid(), serviceSubTaskQueryReq.getIsFinish(), serviceSubTaskQueryReq.getPatfrom(), serviceSubTaskQueryReq.getSubId());
@@ -951,7 +982,7 @@
    private Map<String, Object> getMap(Map<String, Object> scriptInfoByCondition, Long subid, Long patid) {
        Map<String, Object> map = new HashMap<>();
        if (ObjectUtils.isNotEmpty(scriptInfoByCondition) && ObjectUtils.isNotEmpty(scriptInfoByCondition.get("script"))) {
            if (scriptInfoByCondition.get("type").equals("1")) {
            if ("1".equals(scriptInfoByCondition.get("type"))) {
                List<IvrTaskTemplateScriptVO> ivrTaskTemplateScriptVOS = (List<IvrTaskTemplateScriptVO>) scriptInfoByCondition.get("script");
                // 批量查询所有明细,避免循环中逐条查数据库(N+1问题优化)
                Map<Long, ServiceSubtaskDetail> detailMap = getScriptResultMap(subid, patid);
@@ -964,7 +995,7 @@
                }
                map.put("scriptResult", ivrTaskTemplateScriptVOS);
                map.put("taskName", scriptInfoByCondition.get("taskName"));
            } else if (scriptInfoByCondition.get("type").equals("2")) {
            } else if ("2".equals(scriptInfoByCondition.get("type"))) {
                List<SvyTaskTemplateScriptVO> svyTaskTemplateScriptVOList = (List) scriptInfoByCondition.get("script");
                // 批量查询所有明细,避免循环中逐条查数据库(N+1问题优化)
                Map<Long, ServiceSubtaskDetail> detailMap = getScriptResultMap(subid, patid);
@@ -980,7 +1011,7 @@
                }
                map.put("scriptResult", svyTaskTemplateScriptVOList);
                map.put("taskName", scriptInfoByCondition.get("taskName"));
            } else if (scriptInfoByCondition.get("type").equals("3")) {
            } else if ("3".equals(scriptInfoByCondition.get("type"))) {
                //宣教不需要查看
                List<HeLibrary> heLibraryList = (List) scriptInfoByCondition.get("script");
                map.put("scriptResult", heLibraryList);
@@ -1220,6 +1251,8 @@
            //非满意度意见异常自动填入空
            subtaskDetailTrace.setMatchedtext(stt != null ? stt.getOptioncontent() : svyTaskTemplateScriptVO.getIsMydException());
            subtaskDetailTrace.setAsrtext(stt != null ? stt.getOptioncontent() : svyTaskTemplateScriptVO.getIsMydException());
            //补充描述(选了"其他/有症状"时填的文字)一并带到 trace 表
            subtaskDetailTrace.setAnswerps(serviceSubtaskDetail.getAnswerps());
            subtaskDetailTrace.setIsMydException(svyTaskTemplateScriptVO.getIsMydException());
            subtaskDetailTrace.setRecordpath(null);
@@ -1513,6 +1546,8 @@
            subtaskDetailTrace.setType(ivrLibaScriptAssort != null ? ivrLibaScriptAssort.getType() : null);
            subtaskDetailTrace.setScriptid(ivrTaskTemplateScriptVO.getId() == null ? ivrTaskTemplateScriptVO.getScriptID() : ivrTaskTemplateScriptVO.getId());
            subtaskDetailTrace.setAsrtext(ivrTaskTemplateScriptVO.getIvrtext());
            //补充描述一并带到 trace 表
            subtaskDetailTrace.setAnswerps(serviceSubtaskDetail.getAnswerps());
            subtaskDetailTrace.setRecordpath(null);
            subtaskDetailTrace.setPatid(selectServiceSubtaskList.get(0).getPatid());
            JSONObject patdescJson2 = new JSONObject();