| | |
| | | package cn.gistack.sm.intelligentCall.service.impl; |
| | | |
| | | import cn.gistack.sm.intelligentCall.constant.CallConstant; |
| | | import cn.gistack.sm.intelligentCall.constant.ZtConstant; |
| | | import cn.gistack.sm.intelligentCall.entity.Scene; |
| | | import cn.gistack.sm.intelligentCall.mapper.CallTaskMapper; |
| | | import cn.gistack.sm.intelligentCall.service.CallService; |
| | | import cn.gistack.sm.intelligentCall.vo.CallTaskResultVO; |
| | | import cn.gistack.sm.intelligentCall.vo.CallTaskStatistic; |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.dynamic.datasource.annotation.DS; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang3.RandomUtils; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.http.HttpEntity; |
| | | import org.springframework.http.HttpHeaders; |
| | | import org.springframework.http.HttpStatus; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.http.*; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.util.DigestUtils; |
| | | import org.springframework.util.LinkedMultiValueMap; |
| | | import org.springframework.util.MultiValueMap; |
| | | import org.springframework.web.client.RestTemplate; |
| | | |
| | | import java.text.SimpleDateFormat; |
| | | import java.time.LocalDateTime; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @Slf4j |
| | | @Service |
| | |
| | | * @return |
| | | */ |
| | | @Override |
| | | public Object createTask(Map<String,Object> map) { |
| | | public String createTask(Map<String,Object> map) { |
| | | List<Map<String, String>> params = (List<Map<String, String>>) map.get("list"); |
| | | String requestUrl = url + CREATE_TASK_URL; |
| | | LocalDateTime now = LocalDateTime.now(); |
| | | String timestamp = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss SSS")); |
| | | String transId = generateTransId(now); |
| | | // String taskName = now.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日HH:mm")) + "智能外呼"; |
| | | String taskName = map.get("taskName").toString(); |
| | | String taskName = now.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日HH:mm:ss")) + "智能外呼";; |
| | | if(null!= map.get("taskName") && !map.get("taskName").equals("")){ |
| | | taskName = map.get("taskName").toString(); |
| | | } |
| | | String[] numbers = StringUtils.split(callingNumbers,","); |
| | | // String taskScheduleTime = LocalDateTime.now().plusHours(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); |
| | | String taskScheduleTime = map.get("taskScheduleTime").toString(); |
| | | String taskScheduleTime = LocalDateTime.now().plusHours(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); |
| | | if (null!=map.get("taskScheduleTime") && !map.get("taskScheduleTime").equals("")){ |
| | | taskScheduleTime = map.get("taskScheduleTime").toString(); |
| | | } |
| | | String scenesIds = scenesId; |
| | | if (null!=map.get("scenesId") && !map.get("scenesId").equals("")){ |
| | | scenesIds = map.get("scenesId").toString(); |
| | | } |
| | | JSONArray arr = getCalleeInfo(params); |
| | | HttpHeaders httpHeaders = new HttpHeaders(); |
| | | httpHeaders.add("Content-Type", CONTENT_TYPE); |
| | |
| | | httpHeaders.add("Accept-Encoding", ACCEPT_ENCODING); |
| | | JSONObject paramJson = new JSONObject(); |
| | | paramJson.put("taskName", taskName); |
| | | paramJson.put("scenesId", scenesId); |
| | | paramJson.put("scenesId", scenesIds); |
| | | paramJson.put("callingNumbers", numbers); |
| | | paramJson.put("taskScheduleTime", taskScheduleTime); |
| | | paramJson.put("calleeData", arr); |
| | |
| | | HttpEntity<String> stringHttpEntity = new HttpEntity<>(bodyJson.toJSONString(), httpHeaders); |
| | | log.info("创建超汛限智能外呼任务请求参数:{}", bodyJson.toJSONString()); |
| | | ResponseEntity<String> response = restTemplate.postForEntity(requestUrl, stringHttpEntity, String.class); |
| | | log.info("创建外呼任务请求结果:{}", response); |
| | | log.info("创建外呼任务请求结果:{}", response.getBody()); |
| | | if (response.getStatusCode() != HttpStatus.OK) { |
| | | log.error("创建智能外呼任务失败:{}", response.getStatusCode()); |
| | | } |
| | | return response; |
| | | return response.getBody(); |
| | | } |
| | | |
| | | /** |
| | |
| | | List<String> list = new ArrayList<>(); |
| | | if (null!= callTaskResult.getAreaName() && !callTaskResult.getAreaName().equals("")){ |
| | | // 查询所有下级区域code |
| | | list = getWaterNameByAreaCode(callTaskResult.getAreaName()); |
| | | list = getAllChildrenAreaByAreaCode(callTaskResult.getAreaName()); |
| | | } |
| | | List<CallTaskResultVO> resultListPage = callTaskMapper.getCallTaskResultListPage(page, callTaskResult,list); |
| | | List<CallTaskResultVO> resultListPage = callTaskMapper.getCallTaskResultListPage(page, callTaskResult,list,null); |
| | | return page.setRecords(resultListPage); |
| | | } |
| | | |
| | |
| | | @Override |
| | | public Object getCallTaskResultList(CallTaskResultVO callTaskResult) { |
| | | List<String> list = new ArrayList<>(); |
| | | List<String> idsList = new ArrayList<>(); |
| | | if (null!= callTaskResult.getAreaName() && !callTaskResult.getAreaName().equals("")){ |
| | | // 查询所有下级区域code |
| | | list = getWaterNameByAreaCode(callTaskResult.getAreaName()); |
| | | list = getAllChildrenAreaByAreaCode(callTaskResult.getAreaName()); |
| | | } |
| | | List<CallTaskResultVO> resultListPage = callTaskMapper.getCallTaskResultListPage(null, callTaskResult,list); |
| | | if (null!= callTaskResult.getIds() && !callTaskResult.getIds().equals("")){ |
| | | // 查询所有下级区域code |
| | | idsList = Arrays.asList(callTaskResult.getIds().split(",")); |
| | | } |
| | | List<CallTaskResultVO> resultListPage = callTaskMapper.getCallTaskResultListPage(null, callTaskResult,list,idsList); |
| | | // 返回 |
| | | return resultListPage; |
| | | } |
| | | |
| | | /** |
| | | * 查询智能外呼统计数据-按日期-行政区统计 |
| | | * @param callTaskStatistic |
| | | * @return |
| | | */ |
| | | @Override |
| | | public Object getOutgoingStatisticList(IPage<CallTaskStatistic> page,CallTaskStatistic callTaskStatistic) { |
| | | List<String> list = new ArrayList<>(); |
| | | if (null!= callTaskStatistic.getAdName() && !callTaskStatistic.getAdName().equals("")){ |
| | | // 查询所有下级区域code |
| | | list = getAllChildrenAreaByAreaCode(callTaskStatistic.getAdName()); |
| | | } |
| | | // 勾选导出行政区 id 组装 |
| | | if (null!= callTaskStatistic.getIds() && !callTaskStatistic.getIds().equals("")){ |
| | | list = Arrays.asList(callTaskStatistic.getIds().split(",")); |
| | | } |
| | | // 判断是否分页 |
| | | if (null!= callTaskStatistic.getIsPage()){ |
| | | return callTaskMapper.getOutgoingStatisticList(null,callTaskStatistic,list); |
| | | } |
| | | return page.setRecords(callTaskMapper.getOutgoingStatisticList(page,callTaskStatistic,list)); |
| | | } |
| | | |
| | | /** |
| | | * 查询智能外呼统计数据-行政区统计 |
| | | * @param callTaskStatistic |
| | | * @return |
| | | */ |
| | | @Override |
| | | public Object getOutgoingStatisticByArea(CallTaskStatistic callTaskStatistic) { |
| | | return callTaskMapper.getOutgoingStatisticByArea(callTaskStatistic); |
| | | } |
| | | |
| | | /** |
| | | * 查询所有下级区域 |
| | | * @param areaCode |
| | | * @return |
| | | */ |
| | | private List<String> getAllChildrenAreaByAreaCode(String areaCode) { |
| | | return callTaskMapper.getAllChildrenAreaByAreaCode(areaCode); |
| | | } |
| | | |
| | | /** |
| | |
| | | // 通过行政区编号获取水库名称 |
| | | return callTaskMapper.getWaterNameByAreaCode(areaCode); |
| | | } |
| | | |
| | | /** |
| | | * 根据条件自动创建外呼任务 |
| | | * @param params |
| | | * @return |
| | | */ |
| | | @Override |
| | | public String createCallTaskByParam(Map<String, Object> params) { |
| | | // 自动创建任务的 4个条件 1:呼叫人数 2:调度时间 3:是否超汛限 4:多少天内呼叫过的不呼叫(天数) |
| | | //1. 调用中台接口查询出所有需要发任务的水库巡查责任人相关信息(该处需要将是否超汛限条件传入) |
| | | JSONArray jsonArray = getZtWaterMangerData(params); |
| | | // 过滤得到手机号集合(排查手机号为null的数据) |
| | | List<Scene> totalList = filterJsonToList(jsonArray); |
| | | //2. 查询外呼多少天内已呼叫过的人员手机号集合信息 |
| | | // 计算开始时间,结束时间 |
| | | computationTime(params); |
| | | // 查询对应数据 |
| | | List<String> list = callTaskMapper.getCallUserPhoneByParam(params); |
| | | //3. 比对中台得到的数据和外呼已呼叫信息,从中随机取出呼叫人数的信息 |
| | | Set<Scene> taskRandomList = getCreateTaskRandomList(params, totalList, list); |
| | | //4. 传入调度时间和随机得到的人员信息进行任务的创建并返回 |
| | | params.put("list",setForListMap(taskRandomList)); |
| | | // 调度时间处理 |
| | | params.put("taskScheduleTime",new SimpleDateFormat("yyyy-MM-dd").format(new Date())+ " " +params.get("taskScheduleTime") + ":00"); |
| | | // 创建任务并返回结果 |
| | | return createTask(params); |
| | | } |
| | | |
| | | /** |
| | | * hashSet 转 List<Map<String,String>> |
| | | * @param taskRandomList |
| | | * @return |
| | | */ |
| | | private List<Map<String,String>> setForListMap(Set<Scene> taskRandomList) { |
| | | List<Map<String,String>> list = new ArrayList<>(); |
| | | for (Scene scene : taskRandomList) { |
| | | Map<String, String> map = new HashMap<>(); |
| | | map.put("phone",scene.getPhone()); |
| | | map.put("name",scene.getWaterName()); |
| | | map.put("code",scene.getWaterCode()); |
| | | map.put("userName",scene.getUsername()); |
| | | map.put("userId",scene.getPhone()); |
| | | map.put("over",""); |
| | | // 加入集合 |
| | | list.add(map); |
| | | } |
| | | return list; |
| | | } |
| | | |
| | | /** |
| | | * 获取随机呼叫的相关信息 |
| | | * @param params |
| | | * @param totalList |
| | | * @param list |
| | | */ |
| | | private Set<Scene> getCreateTaskRandomList(Map<String, Object> params, List<Scene> totalList, List<String> list) { |
| | | Integer personNumber = ZtConstant.person_number; |
| | | if (!params.get("personNumber").equals("")){ |
| | | personNumber = Integer.parseInt(params.get("personNumber").toString()); |
| | | } |
| | | // 先取差集 |
| | | List<Scene> sceneList = totalList.stream().filter(item -> !list.contains(item.getPhone())).collect(Collectors.toList()); |
| | | // 如果差集数量不够 预定的数量(超汛情况),则从未超汛情况数据中补齐预定的数量 |
| | | if (sceneList.size()<personNumber){ |
| | | Map<String, Object> map = new HashMap<>(); |
| | | map.put("isOver",0); |
| | | // 查询未超汛的数据 |
| | | JSONArray jsonArray = getZtWaterMangerData(map); |
| | | // 过滤得到手机号集合(排查手机号为null的数据) |
| | | List<Scene> sceneListNoOver = filterJsonToList(jsonArray); |
| | | // 取差集 |
| | | List<Scene> differenceSceneListNoOver = sceneListNoOver.stream().filter(item -> !list.contains(item.getPhone())).collect(Collectors.toList()); |
| | | // 再随机抽取对应人员手机号 |
| | | Set<Scene> hashSet = new HashSet<>(); |
| | | // 先将超汛的加入集合 |
| | | for (Scene scene : sceneList) { |
| | | hashSet.add(scene); |
| | | } |
| | | // 未超汛的补充 |
| | | personNumber = personNumber - sceneList.size(); |
| | | Random random = new Random(); |
| | | for (int i = 0; i < differenceSceneListNoOver.size(); i++) { |
| | | // 获取随机数作为下标索引 |
| | | int num = random.nextInt(differenceSceneListNoOver.size()); |
| | | // 保存到 hashSet ,保证唯一 |
| | | hashSet.add(differenceSceneListNoOver.get(num)); |
| | | // 数量达到预期设定退出循环 |
| | | if (hashSet.size() == personNumber) { |
| | | break; |
| | | } |
| | | } |
| | | return hashSet; |
| | | }else { |
| | | // 再随机抽取对应人员手机号 |
| | | Set<Scene> hashSet = new HashSet<>(); |
| | | Random random = new Random(); |
| | | for (int i = 0; i < sceneList.size(); i++) { |
| | | // 获取随机数作为下标索引 |
| | | int num = random.nextInt(sceneList.size()); |
| | | // 保存到 hashSet ,保证唯一 |
| | | hashSet.add(sceneList.get(num)); |
| | | // 数量达到预期设定退出循环 |
| | | if (hashSet.size() == personNumber) { |
| | | break; |
| | | } |
| | | } |
| | | return hashSet; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 将 jsonArray 取出手机号得到新的集合 |
| | | * @param jsonArray |
| | | * @return |
| | | */ |
| | | private List<Scene> filterJsonToList(JSONArray jsonArray) { |
| | | List<Scene> list = new ArrayList<>(); |
| | | for (int i = 0; i < jsonArray.size(); i++) { |
| | | if (null != jsonArray.getJSONObject(i).get("user_phone") && |
| | | !jsonArray.getJSONObject(i).get("user_phone").equals("")){ |
| | | Scene scene = new Scene(); |
| | | scene.setPhone(jsonArray.getJSONObject(i).get("user_phone").toString()); |
| | | scene.setUsername(jsonArray.getJSONObject(i).get("user_name").toString()); |
| | | scene.setUserId(jsonArray.getJSONObject(i).get("user_phone").toString()); |
| | | scene.setWaterName(jsonArray.getJSONObject(i).get("res_nm").toString()); |
| | | scene.setWaterCode(jsonArray.getJSONObject(i).get("res_cd").toString()); |
| | | // 加入集合 |
| | | list.add(scene); |
| | | } |
| | | } |
| | | return list; |
| | | } |
| | | |
| | | /** |
| | | * 计算时间 |
| | | * @param params |
| | | */ |
| | | private void computationTime(Map<String, Object> params) { |
| | | long l = System.currentTimeMillis(); |
| | | Integer day = ZtConstant.day_number; |
| | | // 获取天数 |
| | | if (null != params.get("day")){ |
| | | day = Integer.parseInt(params.get("day").toString()); |
| | | } |
| | | long m = 60*60*24*1000*day; |
| | | // 相减得到时间 |
| | | Long x = l-m; |
| | | // 格式化日期 |
| | | String startTime = new SimpleDateFormat("yyyy-MM-dd").format(new Date(x)); |
| | | String endTime = new SimpleDateFormat("yyyy-MM-dd").format(new Date(l)); |
| | | // 加入到参数中 |
| | | params.put("startTime",startTime); |
| | | params.put("endTime",endTime); |
| | | } |
| | | |
| | | /** |
| | | * 调用中台接口查询出所有需要发任务的水库巡查责任人相关信息(该处需要将是否超汛限条件传入) |
| | | * @param params |
| | | * @return |
| | | */ |
| | | private JSONArray getZtWaterMangerData(Map<String, Object> params) { |
| | | //设置请求头 |
| | | HttpHeaders headers = new HttpHeaders(); |
| | | headers.add(ZtConstant.header_key, ZtConstant.header_value); |
| | | //封装请求头 |
| | | HttpEntity<MultiValueMap<String, Object>> formEntity = new HttpEntity<MultiValueMap<String, Object>>(headers); |
| | | try { |
| | | //有请求头,有参数请求 |
| | | ResponseEntity<String> responseEntity = |
| | | restTemplate.exchange(ZtConstant.patr_person_api+"?is_over="+params.get("isOver"), |
| | | HttpMethod.GET, |
| | | formEntity, |
| | | String.class); |
| | | JSONObject jsonObject = JSON.parseObject(responseEntity.getBody()); |
| | | JSONArray jsonArray = JSONArray.parseArray(jsonObject.get("resultList").toString()); |
| | | // 返回 |
| | | return jsonArray; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return null; |
| | | } |
| | | } |