skjcmanager/skjcmanager-service-api/skjcmanager-sm-api/src/main/java/cn/gistack/sm/intelligentCall/entity/CallNotFillRecord.java
@@ -17,10 +17,10 @@ * @date 2023-06-13 */ @Data @TableName("sm_call_fill_record") @TableName("sm_call_not_fill_record") @EqualsAndHashCode(callSuper = false) @Accessors(chain = true) @ApiModel(value = "sm_call_fill_record对象", description = "外呼未接信息填报") @ApiModel(value = "sm_call_not_fill_record对象", description = "外呼未接信息填报") public class CallNotFillRecord { /** skjcmanager/skjcmanager-service/skjcmanager-alerts/src/main/java/cn/gistack/alerts/sms/constant/MinConstant.java
@@ -11,4 +11,14 @@ * 水库水位情况信息填报 url */ public static final String fillWaterInfoUrl = ""; /** * 前缀(未接电话发送短息记录),用于判断是否已发过短息 */ public static final String is_send_prefix = "blade:alerts:is:send:"; /** * 前缀(未接电话发送短息记录通知),用于填写水库信息 */ public static final String fill_info_prefix = "blade:alerts:fill:info:"; } skjcmanager/skjcmanager-service/skjcmanager-alerts/src/main/java/cn/gistack/alerts/sms/service/impl/SmsServiceImpl.java
@@ -17,9 +17,12 @@ import cn.gistack.alerts.sms.service.SmsService; import cn.gistack.alerts.sms.util.SmsUtils; import cn.gistack.alerts.sms.vo.SmsRequestTemplate; import cn.gistack.common.cache.CacheNames; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.IdWorker; import org.springblade.core.redis.cache.BladeRedis; import org.springblade.core.tool.api.R; import org.springblade.core.tool.utils.StringUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -46,6 +49,9 @@ @Autowired private ISmsTemplateService smsTemplateService; @Autowired private BladeRedis bladeRedis; /** * 发送 xx 变量模板短信 @@ -341,64 +347,83 @@ List<Map<String, Object>> list = smsTemplateService.getNotConnectPatrolPersonList(taskId); SmsTemplate smsTemplate = smsTemplateService.getOne(new QueryWrapper<SmsTemplate>().eq("template_id", templateId)); if (list.size()>0) { // 组装短信数据 StringBuilder builder = new StringBuilder(); // 遍历 List<Map<String, Object>> newList = new ArrayList<>(); // 比对 for (Map<String, Object> map : list) { builder.append(map.get("userPhone") + ",") .append(time + ",") .append(MinConstant.fillWaterInfoUrl + ",") .append(map.get("waterName")) .append(";"); } String datas = builder.toString(); String title = "手机号码,时间范围,链接地址,水库名称"; String[] titleArr = title.split(","); String[] rows = datas.split(";"); String[][] dyns = new String[rows.length + 1][titleArr.length]; dyns[0] = titleArr; int rowNum = 1; for (String row : rows) { String[] cols = row.split(","); dyns[rowNum++] = cols; } //请求参数 DynSMSSendRequest sendRequest = new DynSMSSendRequest(); sendRequest.setTemplateId(templateId); sendRequest.setDynData(dyns); // 发送 ComResult<DynSMSSendDataResult> resultComResult = SmsUtils.dynSendMethod(sendRequest); SMSSendRequest request = new SMSSendRequest(); request.setTemplateId(templateId); request.setMessageContent(""); request.setUserNumber(""); // 先保存结果记录 SmsResult smsResult = saveSendResult(request, rows.length); if (null != smsResult) { List<SmsRecord> smsRecordList = new ArrayList<>(); // 遍历保存 for (Map<String, Object> map : list) { SmsRecord smsRecord = new SmsRecord(); smsRecord.setId(IdWorker.getId()); smsRecord.setTel(map.get("userPhone").toString()); // 内容处理 String s = smsTemplate.getContent().replaceAll("\\{.+?\\}", "%s"); // 拼接内容 String arrString = time + "," + MinConstant.fillWaterInfoUrl + "," + map.get("waterName").toString(); // 格式转换 String format = String.format(s, arrString.split(",")); smsRecord.setContent(format); smsRecord.setTemplateId(templateId); smsRecord.setResultId(smsResult.getId()); smsRecord.setResponseStatus(resultComResult.getCode().toString()); smsRecord.setResponseMsg(resultComResult.getMsg()); // 加入集合 smsRecordList.add(smsRecord); // 获取验证码 String redisByTaskId = bladeRedis.get(MinConstant.is_send_prefix + map.get("userPhone").toString() + ":" + map.get("waterCode").toString()); // 如果为null,并且不能匹配,加入发送短信集合 if (redisByTaskId == null || !StringUtil.equalsIgnoreCase(redisByTaskId, taskId)) { newList.add(map); } // 批量保存记录 Integer count = smsRecordService.batchSaveSendRecord(smsRecordList); // 返回 return count.toString(); } if (newList.size() > 0) { // 组装短信数据 StringBuilder builder = new StringBuilder(); // 遍历 for (Map<String, Object> map : newList) { builder.append(map.get("userPhone") + ",") .append(time + ",") .append(MinConstant.fillWaterInfoUrl + ",") .append(map.get("waterName")) .append(";"); } String datas = builder.toString(); String title = "手机号码,时间范围,链接地址,水库名称"; String[] titleArr = title.split(","); String[] rows = datas.split(";"); String[][] dyns = new String[rows.length + 1][titleArr.length]; dyns[0] = titleArr; int rowNum = 1; for (String row : rows) { String[] cols = row.split(","); dyns[rowNum++] = cols; } //请求参数 DynSMSSendRequest sendRequest = new DynSMSSendRequest(); sendRequest.setTemplateId(templateId); sendRequest.setDynData(dyns); // 发送 ComResult<DynSMSSendDataResult> resultComResult = SmsUtils.dynSendMethod(sendRequest); SMSSendRequest request = new SMSSendRequest(); request.setTemplateId(templateId); request.setMessageContent(""); request.setUserNumber(""); // 先保存结果记录 SmsResult smsResult = saveSendResult(request, rows.length); if (null != smsResult) { List<SmsRecord> smsRecordList = new ArrayList<>(); Pattern compile = Pattern.compile("[^0-9]"); Integer result = Integer.parseInt(compile.matcher(time).replaceAll("").trim()); // 分钟或小时 Long validTime = time.contains("分钟") ? 60L * result : 60L * 60 * result; // 遍历保存 for (Map<String, Object> map : newList) { SmsRecord smsRecord = new SmsRecord(); smsRecord.setId(IdWorker.getId()); smsRecord.setTel(map.get("userPhone").toString()); // 内容处理 String s = smsTemplate.getContent().replaceAll("\\{.+?\\}", "%s"); // 拼接内容 String arrString = time + "," + MinConstant.fillWaterInfoUrl + "," + map.get("waterName").toString(); // 格式转换 String format = String.format(s, arrString.split(",")); smsRecord.setContent(format); smsRecord.setTemplateId(templateId); smsRecord.setResultId(smsResult.getId()); smsRecord.setResponseStatus(resultComResult.getCode().toString()); smsRecord.setResponseMsg(resultComResult.getMsg()); // 保存redis bladeRedis.setEx(MinConstant.is_send_prefix + map.get("userPhone").toString() + ":" + map.get("waterCode").toString(), taskId, 2 * 60 * 60L); bladeRedis.setEx(MinConstant.fill_info_prefix + map.get("userPhone").toString(), taskId, validTime); // 加入集合 smsRecordList.add(smsRecord); } // 批量保存记录 Integer count = smsRecordService.batchSaveSendRecord(smsRecordList); // 返回 return count.toString(); } } } return null; skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/intelligentCall/mapper/CallTaskMapper.java
@@ -89,4 +89,12 @@ * @return */ List<String> getCallUserPhoneByParam(@Param("params")Map<String, Object> params); /** * 通过任务名称查询taskId * @param taskName * @return */ @DS("znwh") String getTaskIdByTaskName(@Param("taskName") String taskName); } skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/intelligentCall/mapper/CallTaskMapper.xml
@@ -292,4 +292,9 @@ and date_format("gmt_create",'%Y-%m-%d') <= #{params.endTime} and "call_result" = '200000' </select> <!--通过任务名称查询taskId-mysql--> <select id="getTaskIdByTaskName" resultType="java.lang.String"> select id from call_task where task_name = #{taskName} </select> </mapper> skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/intelligentCall/service/impl/CallServiceImpl.java
@@ -118,8 +118,13 @@ } JSONObject jsonObject = JSON.parseObject(response.getBody()); Boolean success = jsonObject.getBoolean("success"); String taskId = ""; if (success){ //通过任务名称查询taskId taskId = callTaskMapper.getTaskIdByTaskName(taskName); } // 返回 return success + "," + taskName; return success + "," + taskId; } /** skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/resources/application-dev.yml
@@ -39,6 +39,12 @@ url: ${blade.datasource.dev.xxljob.url} username: ${blade.datasource.dev.xxljob.username} password: ${blade.datasource.dev.xxljob.password} ## 智能外呼数据源(mysql) znwh: driver-class-name: ${blade.datasource.dev.znwh.driver-class-name} url: ${blade.datasource.dev.znwh.url} username: ${blade.datasource.dev.znwh.username} password: ${blade.datasource.dev.znwh.password} main: allow-circular-references: true #xxl: skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/resources/application-prod.yml
@@ -37,6 +37,12 @@ url: ${blade.datasource.prod.xxljob.url} username: ${blade.datasource.prod.xxljob.username} password: ${blade.datasource.prod.xxljob.password} ## 智能外呼数据源(mysql) znwh: driver-class-name: ${blade.datasource.dev.znwh.driver-class-name} url: ${blade.datasource.dev.znwh.url} username: ${blade.datasource.dev.znwh.username} password: ${blade.datasource.dev.znwh.password} main: allow-circular-references: true #xxl: skjcmanager/skjcmanager-service/skjcmanager-xxljob/src/main/java/cn/gistack/job/executor/jobhandler/OutCallXxlJob.java
@@ -1,5 +1,8 @@ package cn.gistack.job.executor.jobhandler; import cn.gistack.job.executor.entity.XxlJobInfo; import cn.gistack.job.executor.service.IXxlJobInfoService; import cn.gistack.job.executor.vo.XxlJobInfoVO; import cn.gistack.sm.intelligentCall.feign.OutCallClient; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; @@ -8,6 +11,9 @@ import com.xxl.job.core.log.XxlJobLogger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.HashMap; import java.util.Map; /** * 智能外呼定时任务执行器 @@ -19,6 +25,9 @@ @Autowired private OutCallClient outCallClient; @Autowired private IXxlJobInfoService xxlJobInfoService; /** * 智能外呼定时创建任务执行器 @@ -36,7 +45,28 @@ String day = jsonParam.getString("day"); // 创建外呼任务 Object result = outCallClient.createOutCallTaskJobHandler(isOver,taskScheduleTime,personNumber, day); XxlJobLogger.log("任务响应结果:" + result); String[] split = result.toString().split(","); if (split[0].equals("true")) { // 获取任务id String taskId = split[1]; // 修改定时任务 XxlJobInfo jobInfo = xxlJobInfoService.getById(11); // 解析参数 Map mapParams = (Map) jobInfo.getExecutorParam(); String time = mapParams.get("time").toString(); XxlJobInfoVO xxlJobInfo = new XxlJobInfoVO(); xxlJobInfo.setId(11); Map<String, Object> map = new HashMap<>(2); map.put("taskId", taskId); map.put("time", time); xxlJobInfo.setExecutorParam(map); Object o = xxlJobInfoService.updateXxlJobById(xxlJobInfo); if (Boolean.parseBoolean(o.toString())) { XxlJobLogger.log("外呼未接通短信通知定时任务修改成功!任务ID:" + taskId); }else { XxlJobLogger.log("外呼未接通短信通知定时任务修改失败!任务ID:" + taskId); } } XxlJobLogger.log("结束自动创建任务..."); return ReturnT.SUCCESS; } @@ -50,14 +80,14 @@ @XxlJob("testOutCall") public ReturnT<String> testOutCall(String param){ XxlJobLogger.log("开始执行任务..."); JSONObject jsonParam = JSON.parseObject(param); String isOver = jsonParam.getString("isOver"); String taskScheduleTime = jsonParam.getString("taskScheduleTime"); String personNumber = jsonParam.getString("personNumber"); String day = jsonParam.getString("day"); // JSONObject jsonParam = JSON.parseObject(param); // String isOver = jsonParam.getString("isOver"); // String taskScheduleTime = jsonParam.getString("taskScheduleTime"); // String personNumber = jsonParam.getString("personNumber"); // String day = jsonParam.getString("day"); // 创建外呼任务 Object result = outCallClient.testOutCall(isOver,taskScheduleTime,personNumber, day); XxlJobLogger.log("任务响应结果:" + result); // Object result = outCallClient.testOutCall(isOver,taskScheduleTime,personNumber, day); // XxlJobLogger.log("任务响应结果:" + result); XxlJobLogger.log("结束自动创建任务..."); return ReturnT.SUCCESS; }