| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432 |
- package com.repair.controller;
- import com.repair.common.utils.*;
- import com.repair.config.WxOpenidConfig;
- import com.repair.model.pojo.*;
- import com.repair.model.vo.*;
- import com.repair.services.*;
- import org.apache.commons.lang3.StringUtils;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.scheduling.annotation.Async;
- import org.springframework.scheduling.annotation.Scheduled;
- import org.springframework.stereotype.Component;
- import org.springframework.transaction.annotation.Transactional;
- import java.math.BigDecimal;
- import java.text.SimpleDateFormat;
- import java.util.*;
- import java.util.stream.Collectors;
- @Component
- //@EnableAsync
- public class ScheduleController {
- /**
- * @Scheduled注解会在默认情况下以单线程的方式执行定时任务。 这个“单线程”指两个方面:
- * 如果一个定时任务执行时间大于其任务间隔时间,那么下一次将会等待上一次执行结束后再继续执行。
- * 如果多个定时任务在同一时刻执行,任务会依次执行。
- * @Async:对某个方法进行异步执行
- * @EnableAsync:开启异步支持
- */
- @Autowired
- private WxOpenidConfig wxOpenidConfig;
- @Autowired
- private RepairUserService repairUserService;
- @Autowired
- private RepairRecordService repairRecordService;
- @Autowired
- private RepairEvaluateService repairEvaluateService;
- @Autowired
- private RepairTrackRecordService repairTrackRecordService;
- @Autowired
- private RepairArticleBuildService repairArticleBuildService;
- @Autowired
- private RepairRefundRecordService repairRefundRecordService;
- @Autowired
- private RepairShiftSettingsService repairShiftSettingsService;
- @Autowired
- private RepairSystemSettingService repairSystemSettingService;
- @Autowired
- private RepairSystemMessagesService repairSystemMessagesService;
- @Autowired
- private RepairDispatchRecordService repairDispatchRecordService;
- //定时格式参考:https://blog.csdn.net/java13992394428/article/details/108740453
- /**
- * 每天八点自动派单
- * 周六周日定时器不生效
- * 其余时间都是早上八点前捞一遍当前时间以前的单子
- * 有合适的维修师傅就把单子派给维修师傅
- * 周一到周五早上七点执行:0 0 7 ? * MON-FRI
- * 周一到周五1、2、3、4、5、6、7、18、19、20、21、22点执行:0 0 1,2,3,4,5,6,7,18,19,20,21,22 ? * MON-FRI
- */
- //每小时执行一次:0 0 */1 * * ?
- //每分钟执行一次:0 */1 * * * ?
- @Async
- @Scheduled(cron = "0 0 7 ? * MON-FRI ")
- //@Scheduled(cron = "0 */1 * * * ? ")
- @Transactional(rollbackFor = {Exception.class})
- public void autoDispatch() throws Exception {
- System.out.println(TimeExchange.DateToString(new Date(), "yyyy-MM-dd HH:mm:ss") + ":自动派单进来执行了一次!");
- /**
- * 读取未被派单的数据
- * 拿到当前时间为止的所有未被派单的数据
- */
- List<pendingOrderVo> records = repairRecordService.queryPendingOrder();
- //有待接单数据
- if (records.size() >= 0) {
- Date nowDate = new Date();
- String dateHour = new SimpleDateFormat("HH:mm").format(nowDate);
- String dateNow = new SimpleDateFormat("yyyy-MM-dd").format(nowDate);
- /**
- * 只获取当天排班和能接单的
- * 获取维修师傅和郭班长的单子
- */
- List<AutoDispatchUserVo> users = repairUserService.autoDispatchUser(dateNow);
- String shiftStr = StringUtils.join(users.stream().map(AutoDispatchUserVo::getShiftId).collect(Collectors.toList()), ",");
- List<String> shifts = Arrays.asList(shiftStr.split(",")).stream().distinct().collect(Collectors.toList());
- //只获取不是值班 或下班后的排班数据
- List<RepairShiftSettings> shiftDatas = repairShiftSettingsService.getRepairsShiftIdByHour(shifts, dateHour);
- //2023-11-03 A-jax 添加获取报修关联楼栋
- List<ArticleBuildVo> articleBuilds = new ArrayList<>();
- if(users != null && users.size() > 0){
- List<Integer> userIds = users.stream().map(AutoDispatchUserVo::getId).collect(Collectors.toList());
- articleBuilds = repairArticleBuildService.queryArticleBuild(StringUtils.join(userIds,","));
- }
- List<RepairDispatchRecord> rdrs = new ArrayList<>();
- List<RepairSystemMessages> rsms = new ArrayList<>();
- List<RepairTrackRecord> rtrs = new ArrayList<>();
- for (pendingOrderVo record : records) {
- //跟张总确认一下是不是到时候维修师傅会把所有楼栋都勾选上
- List<AutoDispatchUserVo> schoolUsers = new ArrayList<>();
- for (AutoDispatchUserVo user:users) {
- long owner = articleBuilds != null && articleBuilds.size() > 0 ? articleBuilds.stream().filter(e -> e.getUserId() == user.getId() && ("," + e.getArticleId() + ",").contains("," + record.getArticleId() + ",") && ("," + e.getBuildId() + ",").contains("," + record.getBuildId() + ",")).count() : 0;
- if(owner > 0){
- schoolUsers.add(user);
- }
- }
- schoolUsers.sort(Comparator.comparing(AutoDispatchUserVo::getRdrCount));
- for (AutoDispatchUserVo user : schoolUsers) {
- List<RepairShiftSettings> datas = shiftDatas.stream().filter(e -> ("," + user.getShiftId() + ",").contains("," + e.getId() + ",")).collect(Collectors.toList());
- if (datas.size() <= 0) {
- continue;
- }
- Integer isDuty = 0;
- int acceptanceAssessTime = user.getAcceptanceTime();
- try {
- //2023-10-08 看是否是值班时间接单
- if (shiftDatas.size() > 0) {
- Optional<RepairShiftSettings> shiftData = datas.stream().filter(e -> nowDate.before(TimeExchange.StringToDate(e.getEndTime(), "HH:mm"))).sorted(Comparator.comparing(RepairShiftSettings::getStartTime)).findFirst();
- if (shiftData != null && shiftData.isPresent()) {
- if (shiftData.get().getIsDuty().intValue() == 1) {
- isDuty = 1;
- }
- }
- }
- //下班之后或者值班接的单不考核 将报修工单中的is_duty改为1
- Date workTime = TimeExchange.StringToDate(dateNow + " " + datas.get(0).getEndTime() + ":00", "yyyy-MM-dd HH:mm:ss");
- if (workTime.before(nowDate)) {
- isDuty = 1;
- }
- if (isDuty == 0) {
- //在工作时间才去派单
- List<timeVo> tvs = DelayedUtils.timeVos(datas);
- //工作的时间是否够修完 临下班接的单不做延长
- for (int i = 0; i < tvs.size(); i++) {
- Date startWorkTime = TimeExchange.StringToDate(dateNow + " " + tvs.get(i).getStart() + ":00", "yyyy-MM-dd HH:mm:ss");
- Date endWorkTime = TimeExchange.StringToDate(dateNow + " " + tvs.get(i).getEnd() + ":00", "yyyy-MM-dd HH:mm:ss");
- //小于工作时间段的开始时间
- if (nowDate.before(startWorkTime) || nowDate.equals(startWorkTime) && i == 0) {
- //早上开始上班之前的单子
- int minute = TimeExchange.getOffsetMinutes(nowDate, startWorkTime);
- int workMinte = TimeExchange.getOffsetMinutes(nowDate, endWorkTime);
- acceptanceAssessTime = acceptanceAssessTime + minute;
- acceptanceAssessTime = DelayedUtils.addMinuteStart(tvs, endWorkTime, acceptanceAssessTime, nowDate, dateNow, workMinte, i, 1);
- break;
- } else if ((startWorkTime.before(nowDate) || startWorkTime.equals(nowDate)) && (nowDate.before(endWorkTime) || nowDate.equals(endWorkTime))) {
- //工作时间段内的单子
- int workMinte = TimeExchange.getOffsetMinutes(nowDate, endWorkTime);
- acceptanceAssessTime = DelayedUtils.addMinuteStart(tvs, endWorkTime, acceptanceAssessTime, nowDate, dateNow, workMinte, i, 1);
- break;
- } else {
- //非工作时间段的单子
- Date nextStartWorkTime = TimeExchange.StringToDate(dateNow + " " + tvs.get(i + 1).getStart() + ":00", "yyyy-MM-dd HH:mm:ss");
- if ((endWorkTime.before(nowDate) || endWorkTime.equals(nowDate)) && (nowDate.before(nextStartWorkTime) || nowDate.equals(nextStartWorkTime))) {
- Date nextEndWorkTime = TimeExchange.StringToDate(dateNow + " " + tvs.get(i + 1).getEnd() + ":00", "yyyy-MM-dd HH:mm:ss");
- int minute = TimeExchange.getOffsetMinutes(nowDate, nextStartWorkTime);
- int workMinte = TimeExchange.getOffsetMinutes(nowDate, nextEndWorkTime);
- acceptanceAssessTime = acceptanceAssessTime + minute;
- acceptanceAssessTime = DelayedUtils.addMinuteStart(tvs, nextEndWorkTime, acceptanceAssessTime, nowDate, dateNow, workMinte, i, 2);
- break;
- }
- }
- }
- RepairDispatchRecord rdr = new RepairDispatchRecord();
- //创建派单记录
- rdr.setAssignedTime(new Date());
- rdr.setAcceptanceAssessTime(acceptanceAssessTime);
- rdr.setOrderType(0);
- rdr.setIsLoseEfficacy(0);
- rdr.setUsersId(user.getId());
- rdr.setRecordId(record.getId());
- rdr.setCreateTime(new Date());
- rdr.setUpdateTime(new Date());
- rdr.setCreateUser("定时器自动派单");
- rdr.setUpdateUser("定时器自动派单");
- rdr.setDeleted(0);
- rdrs.add(rdr);
- user.setRdrCount(user.getRdrCount() + 1);
- //给用户的消息中心数据
- RepairSystemMessages rsmU = new RepairSystemMessages();
- rsmU.setRecordId(record.getId());
- rsmU.setRecipientId(record.getUserId());
- rsmU.setContent("工单已交给系统,系统将催促师傅师尽快接单!");
- rsmU.setIsRead(0);
- rsmU.setCreateTime(new Date());
- rsmU.setUpdateTime(new Date());
- rsmU.setCreateUser("定时器自动派单");
- rsmU.setUpdateUser("定时器自动派单");
- rsmU.setDeleted(0);
- rsms.add(rsmU);
- //给师傅的消息中心数据
- RepairSystemMessages rsmS = new RepairSystemMessages();
- rsmS.setRecordId(record.getId());
- rsmS.setRecipientId(user.getId());
- rsmS.setContent("系统自动分配工单,请尽快处理!");
- rsmS.setIsRead(0);
- rsmS.setCreateTime(new Date());
- rsmS.setUpdateTime(new Date());
- rsmS.setCreateUser("定时器自动派单");
- rsmS.setUpdateUser("定时器自动派单");
- rsmS.setDeleted(0);
- rsms.add(rsmS);
- //添加跟踪记录
- RepairTrackRecord rtr = new RepairTrackRecord();
- rtr.setRecordId(record.getId());
- rtr.setMaintenanceState(1);
- rtr.setContent("已派单");
- rtr.setUserId(0);
- rtr.setUserZzstr("系统自动派单");
- rtr.setCreateTime(new Date());
- rtr.setUpdateTime(new Date());
- rtr.setCreateUser("定时器自动派单");
- rtr.setUpdateUser("定时器自动派单");
- rtr.setDeleted(0);
- rtrs.add(rtr);
- break;
- }
- } catch (Exception e) {
- System.out.println("自动派单失败:" + e.getMessage());
- throw new Exception("自动派单失败!");
- }
- }
- }
- try {
- boolean insertDis = repairDispatchRecordService.insertDispatchBatch(rdrs);
- if (!insertDis) {
- System.out.println(TimeExchange.DateToString(new Date(), "yyyy-MM-dd HH:mm:ss") + ":存储派单数据异常!");
- throw new Exception("自动派单失败!");
- }
- boolean insertRsm = repairSystemMessagesService.inserBatchSystemMessage(rsms);
- if (!insertRsm) {
- System.out.println(TimeExchange.DateToString(new Date(), "yyyy-MM-dd HH:mm:ss") + ":消息中心数据存储异常!");
- throw new Exception("自动派单失败!");
- }
- boolean insertRtr = repairTrackRecordService.insertTrackBatch(rtrs);
- if (!insertRtr) {
- System.out.println(TimeExchange.DateToString(new Date(), "yyyy-MM-dd HH:mm:ss") + ":根据记录数据存储异常!");
- throw new Exception("自动派单失败!");
- }
- } catch (Exception e) {
- System.out.println("新增自动派单失败:" + e.getMessage());
- throw new Exception("自动派单失败!");
- }
- }
- System.out.println(TimeExchange.DateToString(new Date(), "yyyy-MM-dd HH:mm:ss") + ":自动派单执行成功了一次!");
- }
- /**
- * 每小时执行一次
- * 自动好评定时器
- * XX小时后未评价的订单
- * 获取已完成没有好评数据的维修单数据,并且自动好评
- * 好评完成之后在消息中心添加自动好评提示信息
- * 发给维修师傅和用户
- */
- //每小时执行一次:0 0 */1 * * ?
- //每分钟执行一次:0 */1 * * * ?
- @Async
- @Scheduled(cron = "0 0 */1 * * ? ")
- @Transactional(rollbackFor = {Exception.class})
- public void autoEvaluate() throws Exception {
- //读取系统设置表数据 没设置就不好评
- RepairSystemSetting setting = repairSystemSettingService.queryRepairSystemSetting();
- if (setting != null && setting.getHour() != null) {
- String dateStr = TimeExchange.TimeRangeHour(new Date(), -setting.getHour(), "yyyy-MM-dd HH:mm:ss");
- List<RecordEvaluateVo> evaluates = repairEvaluateService.queryEvaluateList(dateStr);
- List<RepairEvaluate> res = new ArrayList<>();
- List<RepairSystemMessages> rsms = new ArrayList<>();
- for (RecordEvaluateVo evaluate : evaluates) {
- RepairEvaluate re = new RepairEvaluate();
- re.setRecordId(evaluate.getId());
- re.setStar(5);
- re.setContent("自动好评");
- re.setCreateTime(new Date());
- re.setUpdateTime(new Date());
- re.setCreateUser("定时器自动评价");
- re.setUpdateUser("定时器自动评价");
- re.setDeleted(0);
- res.add(re);
- RepairSystemMessages rsm = new RepairSystemMessages();
- rsm.setRecordId(evaluate.getId());
- rsm.setRecipientId(evaluate.getUserId());
- rsm.setContent("维修单" + setting.getHour() + "小时内未评价,系统自动5星好评");
- rsm.setIsRead(0);
- rsm.setCreateTime(new Date());
- rsm.setUpdateTime(new Date());
- rsm.setCreateUser("定时器自动评价");
- rsm.setUpdateUser("定时器自动评价");
- rsm.setDeleted(0);
- rsms.add(rsm);
- if (evaluate.getMaintenancerId() != null) {
- String[] userIds = evaluate.getMaintenancerId().split(",");
- for (int i = 0; i < userIds.length; i++) {
- RepairSystemMessages rsmSf = new RepairSystemMessages();
- rsmSf.setRecordId(evaluate.getId());
- rsmSf.setRecipientId(Integer.valueOf(userIds[i]));
- rsmSf.setContent("维修单二十四小时内未评价,系统自动5星好评");
- rsmSf.setIsRead(0);
- rsmSf.setCreateTime(new Date());
- rsmSf.setUpdateTime(new Date());
- rsmSf.setCreateUser("定时器自动评价");
- rsmSf.setUpdateUser("定时器自动评价");
- rsmSf.setDeleted(0);
- rsms.add(rsmSf);
- }
- }
- }
- try {
- boolean insertRes = repairEvaluateService.inserBatchEvaluate(res);
- if (!insertRes) {
- System.out.println(TimeExchange.DateToString(new Date(), "yyyy-MM-dd HH:mm:ss") + ":存储评价数据异常!");
- throw new Exception("自动评价失败!");
- }
- boolean insertRsm = repairSystemMessagesService.inserBatchSystemMessage(rsms);
- if (!insertRsm) {
- System.out.println(TimeExchange.DateToString(new Date(), "yyyy-MM-dd HH:mm:ss") + ":消息中心数据存储异常!");
- throw new Exception("自动评价失败!");
- }
- } catch (Exception e) {
- System.out.println(TimeExchange.DateToString(new Date(), "yyyy-MM-dd HH:mm:ss") + ":好评异常,异常信息:" + e.getMessage());
- throw new Exception("自动评价失败!");
- }
- System.out.println(TimeExchange.DateToString(new Date(), "yyyy-MM-dd HH:mm:ss") + ":好评执行成功了一次!");
- }
- }
- /**
- * 2023-10-26 A-jax 添加退款订单查询
- * 凌晨2点执行退款查询操作
- */
- //凌晨两点:0 0 2 * * ?
- //每分钟执行一次:0 */1 * * * ?
- @Async
- @Scheduled(cron = "0 0 2 * * ?")
- @Transactional(rollbackFor = {Exception.class})
- public void queryRefund() throws Exception {
- System.out.println(TimeExchange.DateToString(new Date(), "yyyy-MM-dd HH:mm:ss") + ":开始查询退款进度!");
- //获取退款中或部分退款的订单
- List<repairRefundVo> dataList = repairRefundRecordService.queryRefundRecord();
- List<String> datas = dataList == null ? new ArrayList<>() : dataList.stream().map(repairRefundVo::getRecordNo).distinct().collect(Collectors.toList());
- List<RepairRefundRecord> rrrs = new ArrayList<>();
- for (String data : datas) {
- Map<String, String> params = new HashMap<String, String>();
- params.put("appid", wxOpenidConfig.getXappid());//微信分配的小程序ID
- params.put("mch_id", wxOpenidConfig.getShappid());//微信支付分配的商户号
- params.put("out_trade_no", data);//"086339330913483");//商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一。详见商户订单号
- String nonceStr = WxUtil.getWxNonceStr();
- params.put("nonce_str", nonceStr);//随机字符串,长度要求在32位以内。推荐随机数生成算法
- String Sign = WxUtil.getSign(params, wxOpenidConfig.getShsecret());//参数 + 商户密钥
- params.put("sign", Sign);
- String retXml = WxUtil.getRequestXml(params);
- String msg = HttpUtils.post("https://api.mch.weixin.qq.com/pay/refundquery", retXml);
- System.out.println(msg);
- try {
- Map<String, Object> dateSre = XmlUtil.fromXML(msg);
- if (dateSre.get("return_code").toString().equals("SUCCESS") && dateSre.get("result_code").toString().equals("SUCCESS")) {
- List<repairRefundVo> repairRefunds = dataList.stream().filter(e -> e.getRecordNo().equals(data)).collect(Collectors.toList());
- if(repairRefunds != null && repairRefunds.size() > 0){
- for (repairRefundVo repairRefund : repairRefunds) {
- String price = repairRefund.getPayPrice().multiply(new BigDecimal(100)).toString();
- String outRefundNo =null;
- String refundId = null;
- for (int i = 0;i<repairRefunds.size();i++) {
- if(dateSre.get("refund_id_"+i).toString().equals(price)){
- if(dateSre.get("refund_status_"+i).toString().equals("SUCCESS")){
- outRefundNo = dateSre.get("out_refund_no_"+i).toString();//商户退款单号
- refundId = dateSre.get("refund_id_"+i).toString();//微信退款单号
- RepairRefundRecord rrr = new RepairRefundRecord();
- rrr.setId(repairRefund.getId());
- rrr.setIsSuccess(1);
- rrr.setWxNo(outRefundNo);//商户退款单号
- rrr.setRefundNo(refundId);//微信退款单号
- rrrs.add(rrr);
- }
- }
- }
- }
- }
- }
- } catch (Exception e) {
- System.out.println(TimeExchange.DateToString(new Date(), "yyyy-MM-dd HH:mm:ss") + ":退款进度,异常信息:" + e.getMessage());
- throw new Exception("退款进度查询失败!");
- }
- }
- try {
- if(rrrs.size() > 0){
- boolean result = repairRefundRecordService.updateRdfundBatch(rrrs);
- if(!result){
- System.out.println(TimeExchange.DateToString(new Date(), "yyyy-MM-dd HH:mm:ss") + ":退款进度更新失败!");
- throw new Exception("退款进度查询失败!");
- }
- }
- } catch (Exception e) {
- System.out.println(TimeExchange.DateToString(new Date(), "yyyy-MM-dd HH:mm:ss") + ":退款查询,异常信息:" + e.getMessage());
- throw new Exception("退款进度查询失败!");
- }
- }
- }
|