| | |
| | | import com.ruoyi.common.core.domain.entity.SysDept; |
| | | import com.ruoyi.common.core.redis.RedisCache; |
| | | import com.ruoyi.common.core.service.IConfigService; |
| | | import com.ruoyi.common.dx.MessageSend; |
| | | import com.ruoyi.common.enums.WxGZHEnum; |
| | | import com.ruoyi.message.sms.provider.sltd.ws.MessageSend; |
| | | import com.ruoyi.common.exception.base.BaseException; |
| | | import com.ruoyi.common.utils.*; |
| | | import com.ruoyi.common.utils.http.HttpUtils; |
| | | import com.ruoyi.common.utils.sms.smsUtils; |
| | | import com.ruoyi.common.utils.spring.SpringUtils; |
| | | import com.ruoyi.message.SendResult; |
| | | import com.ruoyi.message.sms.SmsSendRequest; |
| | | import com.ruoyi.message.sms.SmsSenderFactory; |
| | | import com.ruoyi.message.wechat.WechatSendRequest; |
| | | import com.ruoyi.message.wechat.WechatSenderFactory; |
| | | import com.ruoyi.system.domain.SysConfig; |
| | | import com.ruoyi.system.mapper.SysConfigMapper; |
| | | import com.ruoyi.system.service.ISysConfigService; |
| | | import com.smartor.common.FtpService; |
| | | import com.smartor.common.MtSubmitSmUtil; |
| | | import com.smartor.common.ScheduleSubtaskBuilder; |
| | | import com.smartor.config.PhoneUtils; |
| | | import com.smartor.domain.DTO.MydTrendReqDTO; |
| | | import com.smartor.domain.DTO.MzMydScoreRankDTO; |
| | | import com.smartor.domain.DTO.QuestionCountKsOrBqDTO; |
| | | import com.smartor.domain.DTO.ServiceSubtaskDetailDTO; |
| | | import com.smartor.domain.DTO.ServiceSubtaskOptionStatDTO; |
| | | import com.smartor.domain.DTO.*; |
| | | import com.smartor.domain.*; |
| | | import com.smartor.domain.VO.*; |
| | | import com.smartor.domain.entity.ServiceSubtaskEntity; |
| | |
| | | private ISysConfigService configService; |
| | | |
| | | @Autowired |
| | | private MtSubmitSmUtil mtSubmitSmUtil; |
| | | private SysConfigMapper sysConfigMapper; |
| | | |
| | | /** |
| | | * 消息发送方工厂(短信/微信公众号),替代原来直接调用各站点发送代码的写法 |
| | | */ |
| | | @Autowired |
| | | private SmsSenderFactory smsSenderFactory; |
| | | |
| | | @Autowired |
| | | private SysConfigMapper sysConfigMapper; |
| | | private WechatSenderFactory wechatSenderFactory; |
| | | |
| | | @Autowired |
| | | private RedisTemplate redisTemplate; |
| | |
| | | |
| | | @Value("${req_path}") |
| | | private String req_path; |
| | | |
| | | @Value("${xhsmsPath}") |
| | | private String xhsmsPath; |
| | | |
| | | @Value("${phoneUpEveryHour}") |
| | | private Integer phoneUpEveryHour; |
| | |
| | | serviceOutPath.setUpdateTime(new Date()); |
| | | serviceOutPath.setUrl(url); |
| | | iServiceOutPathService.updateServiceOutPath(serviceOutPath); |
| | | Map<String, String> map = new HashMap<>(); |
| | | map.put("phone", serviceSubtask.getPhone()); |
| | | map.put("content", sendMagParam.getContent()); |
| | | HttpUtil.postJsonRequest(xhsmsPath, new Gson().toJson(map)); |
| | | //短信发送已收口到 ruoyi-message 模块;与原实现一致:不判断发送结果 |
| | | smsSenderFactory.send(active, SmsSendRequest.of(serviceSubtask.getPhone(), sendMagParam.getContent(), serviceSubtask.getOrgid())); |
| | | redisCache.setCacheObject(subTaskId + "recordAccept-hungup", "1", 10, TimeUnit.MINUTES); |
| | | if (StringUtils.isNotEmpty(serviceSubtask.getRemark())) |
| | | serviceSubtask.setRemark("电话发送拒接,短信补偿发送成功"); |
| | |
| | | sendMagParam.setContent(smsContemt.replace("${wjurl}", sendMagParam.getUrl())); |
| | | } |
| | | |
| | | //短信发送:各站点对接方式差异较大,已收口到 ruoyi-message 模块 |
| | | if (active.equals("nhfy")) { |
| | | Map<String, Object> smsResult = mtSubmitSmUtil.submitSm(sendMagParam.getPhone(), sendMagParam.getContent()); |
| | | if (smsResult != null && smsResult.get("result") != null && smsResult.get("result").toString().equals("0")) { |
| | | SendResult smsResult = smsSenderFactory.send(active, |
| | | SmsSendRequest.of(sendMagParam.getPhone(), sendMagParam.getContent(), serviceSubtask.getOrgid())); |
| | | if (smsResult.isOk()) { |
| | | resultMap.put("code", "200"); |
| | | resultMap.put("msg", "发送成功"); |
| | | serviceSubtask.setRemark(StringUtils.isNotEmpty(serviceSubtask.getRemark()) ? serviceSubtask.getRemark() + ";短信发送成功(手动提交)" : "短信发送成功(手动提交)"); |
| | |
| | | iServiceOutPathService.updateServiceOutPath(serviceOutPath); |
| | | |
| | | |
| | | //获取微信公众号请求信息根据机构ID |
| | | List<String> wxqqxx = WxGZHEnum.getDescByCode(serviceSubtask.getOrgid()); |
| | | if (CollectionUtils.isEmpty(wxqqxx) || wxqqxx.size() < 4) { |
| | | resultMap.put("code", -1); |
| | | resultMap.put("message", "发送异常:" + "【公众号】该机构的公众号配置信息不全,无法通过公众号发送"); |
| | | return resultMap; |
| | | } |
| | | |
| | | //his患者id校验(与原实现一致:先校验这一项) |
| | | if (StringUtils.isEmpty(serviceSubtask.getPatidHis())) { |
| | | resultMap.put("code", -1); |
| | | resultMap.put("message", "发送异常:" + "【公众号】公众号发送失败,his系统的患者id为空"); |
| | | return resultMap; |
| | | } |
| | | String wxCode = ""; |
| | | wxCode = getWXCode(serviceSubtask.getSfzh(), url, serviceSubtask.getTaskName(), serviceSubtask.getTaskDesc(), patArchive.getTelcode(), serviceSubtask.getSendname(), patArchive.getPatidHis(), wxqqxx); |
| | | Map map = JSONObject.parseObject(wxCode, Map.class); |
| | | Boolean wxCodeSuccess = false; |
| | | if (!map.isEmpty() && map.get("succ") != null) { |
| | | wxCodeSuccess = (boolean) map.get("succ"); |
| | | } |
| | | |
| | | //机构配置校验、报文签名与返回判定均已收口到 ruoyi-message 的发送方实现 |
| | | WechatSendRequest wechatRequest = new WechatSendRequest(); |
| | | wechatRequest.setOrgid(serviceSubtask.getOrgid()); |
| | | wechatRequest.setIdCard(serviceSubtask.getSfzh()); |
| | | wechatRequest.setUrl(url); |
| | | wechatRequest.setTitle(serviceSubtask.getTaskName()); |
| | | wechatRequest.setContent(serviceSubtask.getTaskDesc()); |
| | | wechatRequest.setPhone(patArchive.getTelcode()); |
| | | wechatRequest.setPatientName(serviceSubtask.getSendname()); |
| | | wechatRequest.setPatidHis(patArchive.getPatidHis()); |
| | | SendResult wechatResult = wechatSenderFactory.send(active, wechatRequest); |
| | | |
| | | //发送完成后,修改状态 |
| | | serviceSubtask.setSendstate(3L); |
| | | if (wxCodeSuccess) { |
| | | if (wechatResult.isOk()) { |
| | | serviceSubtask.setResult("success"); |
| | | resultMap.put("code", "200"); |
| | | resultMap.put("msg", "发送成功"); |
| | | } else { |
| | | log.error("【sfHandlle】公众号发送失败,患者信息:{},错误信息:{}", serviceSubtask, map.get("msg")); |
| | | log.error("【sfHandlle】公众号发送失败,患者信息:{},错误信息:{}", serviceSubtask, wechatResult.getMessage()); |
| | | resultMap.put("code", -1); |
| | | resultMap.put("message", "【公众号】公众号发送失败"); |
| | | return resultMap; |
| | |
| | | Date newDate = new Date(); |
| | | serviceSubtask.setLongSendTime(newDate); |
| | | serviceSubtask.setVisitTime(newDate); |
| | | // 院区:/scanGenerateSubtask 是匿名接口(SecurityConfig permitAll),取不到登录用户; |
| | | // 而 service_task.campusid 在本库是占位值 '1',直接沿用会让统计接口(@AddOrgId 按院区过滤)查不到数据。 |
| | | // 这里用任务配置的病区(其次科室)反查 sys_dept.campusid 落库,保证问卷统计能按院区取到。 |
| | | String campusIdByDept = queryCampusIdByDeptCode(serviceSubtask.getLeavehospitaldistrictcode(), serviceTask.getOrgid()); |
| | | if (StringUtils.isEmpty(campusIdByDept)) { |
| | | campusIdByDept = queryCampusIdByDeptCode(serviceSubtask.getDeptcode(), serviceTask.getOrgid()); |
| | | } |
| | | if (StringUtils.isNotEmpty(campusIdByDept)) { |
| | | serviceSubtask.setCampusid(campusIdByDept); |
| | | } |
| | | // 只配了科室(没有病区)的满意度任务:这道答卷在按病区筛选的报表里统计不到,留日志便于运维发现 |
| | | if (StringUtils.isEmpty(serviceSubtask.getLeavehospitaldistrictcode()) |
| | | && ("6".equals(serviceSubtask.getServiceType()) || "14".equals(serviceSubtask.getServiceType()))) { |
| | | log.warn("【扫码生成任务】满意度子任务没有病区,按病区筛选的报表将统计不到该答卷:taskid={}, deptcode={}, campusid={}", |
| | | serviceSubtask.getTaskid(), serviceSubtask.getDeptcode(), serviceSubtask.getCampusid()); |
| | | } |
| | | return serviceSubtask; |
| | | } |
| | | |
| | | /** |
| | | * 按科室/病区编码反查所属院区(查不到返回 null) |
| | | */ |
| | | private String queryCampusIdByDeptCode(String deptCode, String orgid) { |
| | | if (StringUtils.isEmpty(deptCode)) { |
| | | return null; |
| | | } |
| | | try { |
| | | SysDept sysDept = sysDept2Mapper.selectDeptByCode(deptCode, orgid); |
| | | return sysDept == null ? null : sysDept.getCampusid(); |
| | | } catch (Exception e) { |
| | | log.warn("按编码反查院区失败:deptCode={}, orgid={}, err={}", deptCode, orgid, e.getMessage()); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | return list; |
| | | } |
| | | |
| | | private String getWXCode(String idcard, String url, String taskName, String taskDesc, String phone, String setPatientname, String setPatientid, List<String> wxqqxx) { |
| | | XinHuaWXReq xinHuaWXReq = new XinHuaWXReq(); |
| | | xinHuaWXReq.setIdcard(idcard); |
| | | xinHuaWXReq.setUrl(url); |
| | | xinHuaWXReq.setPatientid(setPatientid); |
| | | xinHuaWXReq.setPatientname(setPatientname); |
| | | xinHuaWXReq.setMobile(phone); |
| | | xinHuaWXReq.setMedcardno(null); |
| | | xinHuaWXReq.setTitlename(taskName); |
| | | xinHuaWXReq.setContent(taskDesc); |
| | | xinHuaWXReq.setAppid(wxqqxx.get(1)); |
| | | log.info("【getWXCode】微信公众号请求参数:{}", xinHuaWXReq); |
| | | String body = new Gson().toJson(xinHuaWXReq); |
| | | String encode = encode(wxqqxx.get(2).concat(body)); |
| | | Map<String, String> headerMap = new HashMap<>(); |
| | | headerMap.put("sign", encode); |
| | | String result = HttpUtils.sendPostByHeader(wxqqxx.get(3), body, headerMap); |
| | | log.info("【getWXCode】微信公众号返回参数:{}", result); |
| | | JSONObject jsonObject = JSONObject.parseObject(result); |
| | | String code = (String) jsonObject.toString(); |
| | | return code; |
| | | } |
| | | public String encode(String arg) { |
| | | if (arg == null) { |
| | | arg = ""; |
| | | } |
| | | MessageDigest md5 = null; |
| | | try { |
| | | md5 = MessageDigest.getInstance("MD5"); |
| | | md5.update(arg.getBytes("UTF-8")); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return toHex(md5.digest()); |
| | | } |
| | | // --------------------------------------------------------------------- |
| | | // 说明:原私有 getWXCode / encode 已随发送方一起收口到 ruoyi-message 模块 |
| | | // (XinHuaMpApi),此处已删除,避免三份拷贝各写一套签名逻辑。 |
| | | // --------------------------------------------------------------------- |
| | | } |