skjcmanager/skjcmanager-service-api/skjcmanager-sm-api/src/main/java/cn/gistack/sm/intelligentCall/entity/CallNotFillRecord.java
@@ -82,4 +82,9 @@ */ @ApiModelProperty(value = "创建时间") private Date createTime; /** * 呼叫id */ private String callId; } skjcmanager/skjcmanager-service-api/skjcmanager-sm-api/src/main/java/cn/gistack/sm/intelligentCall/feign/OutCallClient.java
@@ -1,5 +1,6 @@ package cn.gistack.sm.intelligentCall.feign; import cn.gistack.sm.intelligentCall.entity.CallNotFillRecord; import cn.gistack.sm.sjztmd.feign.IAttResManagePersonClientFallback; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; @@ -18,6 +19,8 @@ String API_PREFIX = "/client"; String CREATE_OUT_CALL_TASK_JOB_HANDLER = API_PREFIX + "/createOutCallTaskJobHandler"; String CREATE_OUT_CALL_TASK_BY_NOT_CONNECT_JOB_HANDLER = API_PREFIX + "/createOutCallTaskByNotConnectJobHandler"; String GET_CALL_NOT_FILL_RECORD_INFO = API_PREFIX + "/getCallNotFillRecordInfo"; String TEST_OUT_CALL = API_PREFIX + "/testOutCall"; /** @@ -47,4 +50,20 @@ @RequestParam("taskScheduleTime") String taskScheduleTime, @RequestParam("personNumber") String personNumber, @RequestParam("day") String day); /** * 智能外呼呼叫前一天未接通人员 * @param taskScheduleTime 调度时间 * @return */ @GetMapping(CREATE_OUT_CALL_TASK_BY_NOT_CONNECT_JOB_HANDLER) List<String> createOutCallTaskByNotConnectJobHandler(@RequestParam("taskScheduleTime") String taskScheduleTime); /** * 查询未接通填报信息 * @param callId 呼叫id * @return */ @GetMapping(GET_CALL_NOT_FILL_RECORD_INFO) CallNotFillRecord getCallNotFillRecordInfo(@RequestParam("callId") String callId); } skjcmanager/skjcmanager-service-api/skjcmanager-sm-api/src/main/java/cn/gistack/sm/intelligentCall/feign/OutCallClientFallback.java
@@ -1,5 +1,6 @@ package cn.gistack.sm.intelligentCall.feign; import cn.gistack.sm.intelligentCall.entity.CallNotFillRecord; import org.springframework.stereotype.Component; import java.util.List; @@ -20,4 +21,14 @@ public String testOutCall(String isOver, String taskScheduleTime, String personNumber, String day) { return null; } @Override public List<String> createOutCallTaskByNotConnectJobHandler(String taskScheduleTime) { return null; } @Override public CallNotFillRecord getCallNotFillRecordInfo(String callId) { return null; } } skjcmanager/skjcmanager-service/skjcmanager-alerts/src/main/java/cn/gistack/alerts/sms/constant/MinConstant.java
@@ -10,7 +10,7 @@ /** * 水库水位情况信息填报 url */ public static final String fillWaterInfoUrl = ""; public static final String fillWaterInfoUrl = "sk.hubeishuiyi.cn/index.html"; /** * 前缀(未接电话发送短息记录),用于判断是否已发过短息 skjcmanager/skjcmanager-service/skjcmanager-alerts/src/main/java/cn/gistack/alerts/sms/controller/SmsController.java
@@ -277,11 +277,11 @@ /** * 通过手机号获取外呼未接通已发短信通知的人员水库信息 * @param phone 手机号码 * @param callId 呼叫id * @return */ @GetMapping("/getCallNotConnectSmsNoticeInfo") public R getCallNotConnectSmsNoticeInfo(String phone){ return R.data(smsService.getCallNotConnectSmsNoticeInfo(phone)); public R getCallNotConnectSmsNoticeInfo(String callId){ return R.data(smsService.getCallNotConnectSmsNoticeInfo(callId)); } } skjcmanager/skjcmanager-service/skjcmanager-alerts/src/main/java/cn/gistack/alerts/sms/mapper/SmsTemplateMapper.java
@@ -27,10 +27,10 @@ /** * 查询当前任务未接通的人员信息(包含水库编号)--MYSQL * @param taskId * @param phone * @param callId * @return */ @DS("znwh") List<Map<String, Object>> getNotConnectPatrolPersonList(@Param("taskId") String taskId, @Param("phone") String phone); @Param("callId") String callId); } skjcmanager/skjcmanager-service/skjcmanager-alerts/src/main/java/cn/gistack/alerts/sms/mapper/SmsTemplateMapper.xml
@@ -24,15 +24,15 @@ <!--查询当前任务未接通的人员信息(包含水库编号)-MYSQL--> <select id="getNotConnectPatrolPersonList" resultType="java.util.Map"> select ctc.callee_number as userPhone,ctc.task_id as taskId, select ctc.callee_number as userPhone,ctc.task_id as taskId,ctc.call_id callId, TRIM(BOTH '"' FROM JSON_EXTRACT(ctc.call_task_callee_content,'$."$水库编码$"')) as waterCode, TRIM(BOTH '"' FROM JSON_EXTRACT(ctc.call_task_callee_content,'$."$水库名称$"')) as waterName, TRIM(BOTH '"' FROM JSON_EXTRACT(ctc.call_task_callee_content,'$."$用户名$"')) as userName from call_task_callee ctc left join call_task_result ctr on ctc.call_id = ctr.call_id where ctc.task_id = #{taskId} and ctc.call_status = 4 and ctr.call_result!='200000' <if test="phone!=null and phone!=''"> and ctc.callee_number = #{phone} <if test="callId!=null and callId!=''"> and ctc.call_id = #{callId} </if> </select> </mapper> skjcmanager/skjcmanager-service/skjcmanager-alerts/src/main/java/cn/gistack/alerts/sms/service/ISmsTemplateService.java
@@ -27,9 +27,9 @@ /** * 查询当前任务未接通的人员信息(包含水库编号) * @param taskId * @param phone * @param callId * @return */ @DS("znwh") List<Map<String, Object>> getNotConnectPatrolPersonList(String taskId,String phone); List<Map<String, Object>> getNotConnectPatrolPersonList(String taskId,String callId); } skjcmanager/skjcmanager-service/skjcmanager-alerts/src/main/java/cn/gistack/alerts/sms/service/SmsService.java
@@ -73,8 +73,8 @@ /** * 通过手机号获取外呼未接通已发短信通知的人员水库信息 * @param phone 手机号码 * @param callId 呼叫id * @return */ Object getCallNotConnectSmsNoticeInfo(String phone); Object getCallNotConnectSmsNoticeInfo(String callId); } skjcmanager/skjcmanager-service/skjcmanager-alerts/src/main/java/cn/gistack/alerts/sms/service/impl/SmsServiceImpl.java
@@ -18,6 +18,8 @@ import cn.gistack.alerts.sms.util.SmsUtils; import cn.gistack.alerts.sms.vo.SmsRequestTemplate; import cn.gistack.common.cache.CacheNames; import cn.gistack.sm.intelligentCall.entity.CallNotFillRecord; import cn.gistack.sm.intelligentCall.feign.OutCallClient; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.IdWorker; import org.springblade.core.redis.cache.BladeRedis; @@ -26,6 +28,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -52,6 +56,9 @@ @Autowired private BladeRedis bladeRedis; @Autowired private OutCallClient outCallClient; /** * 发送 xx 变量模板短信 @@ -350,8 +357,8 @@ List<Map<String, Object>> newList = new ArrayList<>(); // 比对 for (Map<String, Object> map : list) { // 获取验证码 String redisByTaskId = bladeRedis.get(MinConstant.is_send_prefix + map.get("userPhone").toString() + ":" + map.get("waterCode").toString()); // 获取任务id String redisByTaskId = bladeRedis.get(MinConstant.is_send_prefix + map.get("callId").toString()); // 如果为null,并且不能匹配,加入发送短信集合 if (redisByTaskId == null || !StringUtil.equalsIgnoreCase(redisByTaskId, taskId)) { newList.add(map); @@ -362,14 +369,20 @@ StringBuilder builder = new StringBuilder(); // 遍历 for (Map<String, Object> map : newList) { // String callId = null; // try { // callId = URLEncoder.encode("callId=" + map.get("callId"), "UTF-8"); // } catch (UnsupportedEncodingException e) { // e.printStackTrace(); // } builder.append(map.get("userPhone") + ",") .append(time + ",") .append(MinConstant.fillWaterInfoUrl + ",") .append(map.get("waterName")) .append(MinConstant.fillWaterInfoUrl +"?" + "callId=" + map.get("callId") + ",") .append(";"); } String datas = builder.toString(); String title = "手机号码,时间范围,链接地址,水库名称"; String title = "手机号码,时间范围,水库名称,访问链接"; String[] titleArr = title.split(","); String[] rows = datas.split(";"); String[][] dyns = new String[rows.length + 1][titleArr.length]; @@ -402,10 +415,18 @@ SmsRecord smsRecord = new SmsRecord(); smsRecord.setId(IdWorker.getId()); smsRecord.setTel(map.get("userPhone").toString()); String callId = null; // try { // callId = URLEncoder.encode("callId=" + map.get("callId"), "UTF-8"); // } catch (UnsupportedEncodingException e) { // e.printStackTrace(); // } // 内容处理 String s = smsTemplate.getContent().replaceAll("\\{.+?\\}", "%s"); // 拼接内容 String arrString = time + "," + MinConstant.fillWaterInfoUrl + "," + map.get("waterName").toString(); String arrString = time + "," + map.get("waterName").toString() + "," + MinConstant.fillWaterInfoUrl + "?" + "callId=" + map.get("callId") ; // 格式转换 String format = String.format(s, arrString.split(",")); smsRecord.setContent(format); @@ -414,8 +435,8 @@ 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); bladeRedis.setEx(MinConstant.is_send_prefix + map.get("callId").toString(), taskId, 2 * 60 * 60L); bladeRedis.setEx(MinConstant.fill_info_prefix + map.get("callId").toString(), taskId, validTime); // 加入集合 smsRecordList.add(smsRecord); } @@ -449,22 +470,32 @@ /** * 通过手机号获取外呼未接通已发短信通知的人员水库信息 * @param phone 手机号码 * @param callId 呼叫id * @return */ @Override public Object getCallNotConnectSmsNoticeInfo(String phone) { public Object getCallNotConnectSmsNoticeInfo(String callId) { Map<String, Object> map = new HashMap<>(2); boolean flag = false; List<Map<String, Object>> list = new ArrayList<>(); // 通过手机号查询外呼任务id String taskId = bladeRedis.get(MinConstant.fill_info_prefix + phone); String taskId = bladeRedis.get(MinConstant.fill_info_prefix + callId); // 判断 if (null!=taskId && !taskId.equals("")){ // 通过手机号和外呼任务id 查询水库人员信息 list = smsTemplateService.getNotConnectPatrolPersonList(taskId,phone); list = smsTemplateService.getNotConnectPatrolPersonList(taskId,callId); // 查询是否填报 CallNotFillRecord callNotFillRecordInfo = outCallClient.getCallNotFillRecordInfo(callId); if (callNotFillRecordInfo != null){ flag = true; } // 封装数据 map.put("list",list); map.put("isFill",flag); // 返回 return list; return map; } // 没有,已过期 return list; return map; } } skjcmanager/skjcmanager-service/skjcmanager-alerts/src/main/java/cn/gistack/alerts/sms/service/impl/SmsTemplateServiceImpl.java
@@ -39,12 +39,12 @@ /** * 查询当前任务未接通的人员信息(包含水库编号) * @param taskId * @param phone * @param callId * @return */ @Override @DS("znwh") public List<Map<String, Object>> getNotConnectPatrolPersonList(String taskId,String phone) { return baseMapper.getNotConnectPatrolPersonList(taskId,phone); public List<Map<String, Object>> getNotConnectPatrolPersonList(String taskId,String callId) { return baseMapper.getNotConnectPatrolPersonList(taskId,callId); } } skjcmanager/skjcmanager-service/skjcmanager-alerts/src/main/resources/application-prod.yml
@@ -39,9 +39,9 @@ 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} driver-class-name: ${blade.datasource.prod.znwh.driver-class-name} url: ${blade.datasource.prod.znwh.url} username: ${blade.datasource.prod.znwh.username} password: ${blade.datasource.prod.znwh.password} main: allow-circular-references: true skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/intelligentCall/feign/OutCallImplImplClient.java
@@ -1,6 +1,9 @@ package cn.gistack.sm.intelligentCall.feign; import cn.gistack.sm.intelligentCall.entity.CallNotFillRecord; import cn.gistack.sm.intelligentCall.service.CallService; import cn.gistack.sm.intelligentCall.service.ICallNotFillRecordService; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springblade.core.tenant.annotation.NonDS; @@ -22,6 +25,8 @@ public class OutCallImplImplClient implements OutCallClient { private final CallService callService; private final ICallNotFillRecordService callNotFillerService; @Override @GetMapping(CREATE_OUT_CALL_TASK_JOB_HANDLER) @@ -53,4 +58,30 @@ // 创建定时任务并返回 return "测试返回成功"; } /** * 智能外呼呼叫前一天未接通人员 * @param taskScheduleTime 调度时间 * @return */ @Override @GetMapping(CREATE_OUT_CALL_TASK_BY_NOT_CONNECT_JOB_HANDLER) public List<String> createOutCallTaskByNotConnectJobHandler(String taskScheduleTime) { Map<String, Object> map = new HashMap<>(1); map.put("taskScheduleTime",taskScheduleTime); // 创建定时任务并返回 return callService.createOutCallTaskByNotConnectJobHandler(map); } /** * 查询未接通填报信息 * @param callId 呼叫id * @return */ @Override @GetMapping(GET_CALL_NOT_FILL_RECORD_INFO) public CallNotFillRecord getCallNotFillRecordInfo(String callId) { // 创建定时任务并返回 return callNotFillerService.getOne(new QueryWrapper<CallNotFillRecord>().eq("call_id",callId)); } } skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/intelligentCall/mapper/CallTaskMapper.java
@@ -1,5 +1,6 @@ package cn.gistack.sm.intelligentCall.mapper; import cn.gistack.sm.intelligentCall.entity.Scene; import cn.gistack.sm.intelligentCall.vo.CallTaskResultVO; import cn.gistack.sm.intelligentCall.vo.CallTaskStatistic; import com.baomidou.dynamic.datasource.annotation.DS; @@ -97,4 +98,11 @@ */ @DS("znwh") String getTaskIdByTaskName(@Param("taskName") String taskName); /** * 查询前一天呼叫未接通人员 * @return */ @DS("znwh") List<Scene> getBeforeOneDayCallNotConnect(@Param("params")Map<String, Object> params); } skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/intelligentCall/mapper/CallTaskMapper.xml
@@ -304,4 +304,20 @@ <select id="getTaskIdByTaskName" resultType="java.lang.String"> select id from call_task where task_name = #{taskName} </select> <!--通过任务名称查询taskId-mysql--> <select id="getBeforeOneDayCallNotConnect" resultType="cn.gistack.sm.intelligentCall.entity.Scene"> select ctc.callee_number as phone,ctc.callee_number as userId, TRIM(BOTH '"' FROM JSON_EXTRACT(ctc.call_task_callee_content,'$."$水库编码$"')) as waterCode, TRIM(BOTH '"' FROM JSON_EXTRACT(ctc.call_task_callee_content,'$."$水库名称$"')) as waterName, TRIM(BOTH '"' FROM JSON_EXTRACT(ctc.call_task_callee_content,'$."$用户名$"')) as username from call_task_callee ctc join ( select call_id,callee_number,call_result from call_task_result where date_format(gmt_create,'%Y-%m-%d') >= #{params.startTime} and date_format(gmt_create,'%Y-%m-%d') <= #{params.startTime} ) ctr on ctc.call_id = ctr.call_id and ctc.call_status = 4 and ctr.call_result!='200000' </select> </mapper> skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/intelligentCall/service/CallService.java
@@ -1,6 +1,7 @@ package cn.gistack.sm.intelligentCall.service; import cn.gistack.sm.intelligentCall.entity.CallNotFillRecord; import cn.gistack.sm.intelligentCall.vo.CallTaskResultVO; import cn.gistack.sm.intelligentCall.vo.CallTaskStatistic; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -68,4 +69,11 @@ * @return */ List<String> createCallTaskByParam(Map<String, Object> params); /** * 智能外呼呼叫前一天未接通人员 * @param map 包含调度时间 * @return */ List<String> createOutCallTaskByNotConnectJobHandler(Map<String, Object> map); } skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/intelligentCall/service/impl/CallServiceImpl.java
@@ -354,6 +354,31 @@ } /** * 智能外呼呼叫前一天未接通人员 * @param map 包含调度时间 * @return */ @Override public List<String> createOutCallTaskByNotConnectJobHandler(Map<String, Object> map) { map.put("day",3); // 自动创建任务的 条件1:昨天外呼未接通人员 条件2:前三天如果同一个人都未接通,则不再呼叫 // 计算开始时间,结束时间 computationTime(map); // 1. 查询前一天呼叫未接通人员 List<Scene> oneDayCallNotConnectList = callTaskMapper.getBeforeOneDayCallNotConnect(map); // 2. 查询三天都未接通的人员 // List<Scene> threeDayCallNotConnectList = callTaskMapper.getBeforeThreeDayCallNotConnect(); // 3. 组装数据 // 4. 传入调度时间和随机得到的人员信息进行任务的创建并返回 // map.put("list",setForListMap(taskRandomList)); // 调度时间处理 map.put("taskScheduleTime",new SimpleDateFormat("yyyy-MM-dd").format(new Date())+ " " +map.get("taskScheduleTime") + ":00"); // 创建任务并返回结果 return createTask(map); } /** * hashSet 转 List<Map<String,String>> * @param taskRandomList * @return skjcmanager/skjcmanager-service/skjcmanager-xxljob/src/main/java/cn/gistack/job/executor/jobhandler/OutCallXxlJob.java
@@ -47,27 +47,45 @@ // 创建外呼任务 List<String> result = outCallClient.createOutCallTaskJobHandler(isOver,taskScheduleTime,personNumber, day); XxlJobLogger.log("任务响应结果..." + result); // if (result.get(2).equals("true")) { // // 获取任务id // String taskId = result.get(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); // } // } if (result.get(2).equals("true")) { // 获取任务id String taskId = result.get(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; } /** * 智能外呼未接通呼叫 * @param param * @return * @throws Exception */ @XxlJob("createOutCallTaskByNotConnectJobHandler_test") public ReturnT<String> createOutCallTaskByNotConnectJobHandler(String param){ XxlJobLogger.log("开始执行智能外呼未接通呼叫任务..."); JSONObject jsonParam = JSON.parseObject(param); String taskScheduleTime = jsonParam.getString("taskScheduleTime"); // 创建外呼任务 List<String> result = outCallClient.createOutCallTaskByNotConnectJobHandler(taskScheduleTime); XxlJobLogger.log("任务响应结果..." + result); XxlJobLogger.log("结束自动创建任务..."); return ReturnT.SUCCESS; } skjcmanager/skjcmanager-service/skjcmanager-xxljob/src/main/java/cn/gistack/job/executor/jobhandler/SendSmsXxlJob.java
@@ -27,7 +27,7 @@ * @return * @throws Exception */ @XxlJob("sendSmsByOutCallNotConnect") @XxlJob("sendSmsByOutCallNotConnect_test") public ReturnT<String> createOutCallTaskJobHandler(String param){ XxlJobLogger.log("开始执行任务..."); JSONObject jsonParam = JSON.parseObject(param);