|
@@ -1,351 +1,351 @@
|
|
|
-//package com.management.platform.task;
|
|
|
-//
|
|
|
-//import java.time.LocalDate;
|
|
|
-//import java.time.Period;
|
|
|
-//import java.time.format.DateTimeFormatter;
|
|
|
-//
|
|
|
-//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
-//import com.management.platform.constant.Constant;
|
|
|
-//import com.management.platform.entity.*;
|
|
|
-//import com.management.platform.mapper.*;
|
|
|
-//import com.management.platform.service.CompanyDingdingService;
|
|
|
-//import com.management.platform.service.WxCorpInfoService;
|
|
|
-//import com.management.platform.util.*;
|
|
|
-//import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
|
|
|
-//import me.chanjar.weixin.mp.api.WxMpService;
|
|
|
-//import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
|
|
|
-//import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
|
|
|
-//import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
|
|
|
-//import org.springframework.beans.factory.annotation.Autowired;
|
|
|
-//import org.springframework.beans.factory.annotation.Value;
|
|
|
-//import org.springframework.format.annotation.DateTimeFormat;
|
|
|
-//import org.springframework.scheduling.annotation.EnableScheduling;
|
|
|
-//import org.springframework.scheduling.annotation.Scheduled;
|
|
|
-//import org.springframework.stereotype.Component;
|
|
|
-//
|
|
|
-//import javax.annotation.Resource;
|
|
|
-//import java.time.LocalDateTime;
|
|
|
-//import java.util.*;
|
|
|
-//import java.util.stream.Collectors;
|
|
|
-//
|
|
|
-///**
|
|
|
-// * Author: 吴涛涛
|
|
|
-// * Date : 2019 - 12 - 31 16:04
|
|
|
-// * Description:<描述>
|
|
|
-// * Version: 1.0
|
|
|
-// */
|
|
|
-//@EnableScheduling
|
|
|
-//@Component
|
|
|
-//public class TimingTask {
|
|
|
-//
|
|
|
-// @Value("${wx.template_report_fill}")
|
|
|
-// public String TEMPLATE_REPORT_FILL;
|
|
|
-// @Value("${wx.template_project_deadline}")
|
|
|
-// public String TEMPLATE_PROJECT_DEADLINE;
|
|
|
-// @Value("${wx.app_id}")
|
|
|
-// public String appId;
|
|
|
-// @Value("${wx.app_secret}")
|
|
|
-// public String appSecret;
|
|
|
-// @Autowired
|
|
|
-// private RedisUtil redisUtil;
|
|
|
-//
|
|
|
-// @Resource
|
|
|
-// private ScreenshotMapper screenshotMapper;
|
|
|
-// @Resource
|
|
|
-// private TimeTypeMapper timeTypeMapper;
|
|
|
-// @Resource
|
|
|
-// private UserMapper userMapper;
|
|
|
-// @Resource
|
|
|
-// private DepartmentMapper departmentMapper;
|
|
|
-// @Resource
|
|
|
-// private ReportMapper reportMapper;
|
|
|
-// @Resource
|
|
|
-// private WxCorpInfoService wxCorpInfoService;
|
|
|
-// @Resource
|
|
|
-// private WxCorpInfoMapper wxCorpInfoMapper;
|
|
|
-// @Value(value = "${upload.path}")
|
|
|
-// private String path;
|
|
|
-// @Resource
|
|
|
-// private ProjectMapper projectMapper;
|
|
|
-// @Resource
|
|
|
-// private CompanyDingdingService companyDingdingService;
|
|
|
-//
|
|
|
-// //检查项目到期,距离到期时间3天内的,每天提醒
|
|
|
-// @Scheduled(cron = "0 0 10 ? * *")
|
|
|
-// private void projectDeadlineAlert() {
|
|
|
-// LocalDate start = LocalDate.now();
|
|
|
-// start = start.plusDays(1);
|
|
|
-// LocalDate end = LocalDate.now();
|
|
|
-// end = end.plusDays(3);
|
|
|
-// //获取未来3天内超期的项目
|
|
|
-// List<Project> list = projectMapper.selectList(new QueryWrapper<Project>().eq("status", 1).between("plan_end_date", start, end));
|
|
|
-// System.out.println("即将超期项目=="+list.size());
|
|
|
-//
|
|
|
-// for (Project p : list) {
|
|
|
-//
|
|
|
-// Period period = Period.between(start, p.getPlanEndDate());
|
|
|
-// int days = period.getDays();
|
|
|
-// List<Map<String, Object>> userList = userMapper.getProjectPushUserList(p.getId());
|
|
|
-// userList.forEach(u->{
|
|
|
-// if (u.get("corpwxUserid") != null) {
|
|
|
-// //TODO: 推送到企业微信
|
|
|
-//// String corpUid = (String) u.get("corpwxUserid");
|
|
|
-//// wxCorpInfoService.sendWXCorpMsg(cpList.get(0), corpUid, "请及时填写今日的工作报告哦");
|
|
|
-// } else {
|
|
|
-// pushProjectNotify((String)u.get("wxOpenid"), p.getProjectName(), days, p.getPlanEndDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
|
|
|
-// }
|
|
|
-// });
|
|
|
-// }
|
|
|
-// }
|
|
|
-//
|
|
|
-// //每天7点同步昨天的企业微信考勤考勤打卡记录
|
|
|
-// @Scheduled(cron = "0 0 7 ? * *")
|
|
|
-// private void synCorpWXCardTime() {
|
|
|
-// LocalDateTime yestoday = LocalDateTime.now().minusDays(1);
|
|
|
-// yestoday = yestoday.withHour(0).withMinute(0).withSecond(0).withNano(0);
|
|
|
-//
|
|
|
-// List<TimeType> typeList = timeTypeMapper.selectList(new QueryWrapper<TimeType>().eq("sync_corpwx_time", 1));
|
|
|
-// for (TimeType type : typeList) {
|
|
|
-// Integer companyId = type.getCompanyId();
|
|
|
-// wxCorpInfoService.getUserCheckInDayData(companyId, null, yestoday, yestoday);
|
|
|
-// }
|
|
|
-// }
|
|
|
-//
|
|
|
-// //每周日晚上11点 同步一次本月的考勤打卡记录
|
|
|
-// @Scheduled(cron = "0 0 23 ? * 7")
|
|
|
-// private void weeklySyncCorpWXCardTime() {
|
|
|
-// LocalDateTime current = LocalDateTime.now();
|
|
|
-// LocalDateTime start = current.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
|
|
|
-// LocalDateTime now = LocalDateTime.now();
|
|
|
-// LocalDateTime end = now.minusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
|
|
|
-// System.out.println("每周同步,开始同步本月的考勤记录="+start+" 至 "+end);
|
|
|
-// List<TimeType> typeList = timeTypeMapper.selectList(new QueryWrapper<TimeType>().eq("sync_corpwx_time", 1));
|
|
|
-// for (TimeType type : typeList) {
|
|
|
-// Integer companyId = type.getCompanyId();
|
|
|
-// wxCorpInfoService.getUserCheckInDayData(companyId, null, start, end);
|
|
|
-// }
|
|
|
-// }
|
|
|
-//
|
|
|
-// //每个月6号早上6点同步上个月的企业微信考勤考勤打卡记录
|
|
|
-// @Scheduled(cron = "0 0 6 6 * ?")
|
|
|
-// private void synMonthCorpWXCardTime() {
|
|
|
-// LocalDateTime lastMonth = LocalDateTime.now().minusMonths(1);
|
|
|
-// LocalDateTime start = lastMonth.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
|
|
|
-// LocalDateTime now = LocalDateTime.now().withDayOfMonth(1);
|
|
|
-// LocalDateTime end = now.minusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
|
|
|
-// System.out.println("开始同步上个月的考勤记录");
|
|
|
-// List<TimeType> typeList = timeTypeMapper.selectList(new QueryWrapper<TimeType>().eq("sync_corpwx_time", 1));
|
|
|
-// for (TimeType type : typeList) {
|
|
|
-// Integer companyId = type.getCompanyId();
|
|
|
-// wxCorpInfoService.getUserCheckInDayData(companyId, null, start, end);
|
|
|
-// }
|
|
|
-// }
|
|
|
-//
|
|
|
-// //发送上周填写的工时统计
|
|
|
-// @Scheduled(cron = "0 0 8 ? * *")
|
|
|
-// private void lastWeekFillTimeAlert() {
|
|
|
-// //每日检查是否是周一,提醒上周工时汇总
|
|
|
-// LocalDate curDay = LocalDate.now();
|
|
|
-// if (curDay.getDayOfWeek().getValue() == 1) {
|
|
|
-// List<User> allUser = userMapper.selectList(new QueryWrapper<User>().isNotNull("wx_openid"));
|
|
|
-// for (User u : allUser) {
|
|
|
-// //取上周
|
|
|
-// LocalDate lastWeek = curDay.minusWeeks(1);
|
|
|
-//
|
|
|
-// int weekDay = lastWeek.getDayOfWeek().getValue();
|
|
|
-// LocalDate monday = lastWeek.minusDays(weekDay-1);
|
|
|
-// LocalDate sunday = monday.plusDays(6);
|
|
|
-// List<Report> reportList = reportMapper.selectList(new QueryWrapper<Report>().eq("creator_id", u.getId()).between("create_date", monday, sunday));
|
|
|
-// List<Integer> pids = reportList.stream().map(Report::getProjectId).distinct().collect(Collectors.toList());
|
|
|
-// List<Project> projectList = projectMapper.selectList(new QueryWrapper<Project>().in("id", pids));
|
|
|
-// String collect = projectList.stream().map(Project::getProjectName).collect(Collectors.joining(","));
|
|
|
-// //计算总工时
|
|
|
-// double sum = reportList.stream().mapToDouble(Report::getWorkingTime).sum();
|
|
|
-// double waiting = reportList.stream().filter(r -> r.getState() == 0).mapToDouble(Report::getWorkingTime).sum();
|
|
|
-// double reject = reportList.stream().filter(r -> r.getState() == 2).mapToDouble(Report::getWorkingTime).sum();
|
|
|
-// double pass = reportList.stream().filter(r -> r.getState() == 1).mapToDouble(Report::getWorkingTime).sum();
|
|
|
-// String str = "您上周共参与了" + projectList.size()+"个项目,总工时为" + sum+"小时。其中审核通过"+pass
|
|
|
-// +"小时, 待审核"+waiting+"小时,驳回"+reject+"小时。";
|
|
|
-// pushLastWeekReportFill(u, str);
|
|
|
-// }
|
|
|
-// }
|
|
|
-// }
|
|
|
-//
|
|
|
-// //每分钟校验是否有需要提醒的填报
|
|
|
-// @Scheduled(fixedRate = 60 * 1000)
|
|
|
-// private void process() {
|
|
|
-// LocalDateTime now = LocalDateTime.now();
|
|
|
-// LocalDate localDate = LocalDate.now();
|
|
|
-//
|
|
|
-// //判断是否是工作日,非工作日不提醒
|
|
|
-// if (!WorkDayCalculateUtils.isWorkDay(localDate)) {
|
|
|
-// return;
|
|
|
-// }
|
|
|
-// DateTimeFormatter dt = DateTimeFormatter.ofPattern("HH:mm");
|
|
|
-// String str = dt.format(now);
|
|
|
-// List<TimeType> typeList = timeTypeMapper.selectList(new QueryWrapper<TimeType>().isNotNull("alert_time")
|
|
|
-// .ge("alert_time", str));
|
|
|
-//
|
|
|
-// typeList.forEach(t->{
|
|
|
-// if (str.equals(t.getAlertTime())) {
|
|
|
-// //发送推送提醒
|
|
|
-// List<Map<String, Object>> userList = userMapper.getPushUserList(t.getCompanyId());
|
|
|
-// List<WxCorpInfo> cpList = wxCorpInfoMapper.selectList(new QueryWrapper<WxCorpInfo>().eq("company_id", t.getCompanyId()));
|
|
|
-// userList.forEach(u->{
|
|
|
-// if (u.get("corpwxUserid") != null) {
|
|
|
-// //推送到企业微信
|
|
|
-// String corpUid = (String) u.get("corpwxUserid");
|
|
|
-// wxCorpInfoService.sendWXCorpMsg(cpList.get(0), corpUid, t.getAlertMsg());
|
|
|
-// } else if (u.get("wxOpenid") != null) {
|
|
|
-// push(u, t.getAlertMsg());
|
|
|
-// }
|
|
|
-// });
|
|
|
-// }
|
|
|
-// });
|
|
|
-//
|
|
|
-// List<Map<String, Object>> dingdingUserList = userMapper.getPushDingdingUserList(str);
|
|
|
-// System.out.println("=============查询钉钉推送未填提醒的人员列表=====, size=" + dingdingUserList.size());
|
|
|
-//
|
|
|
-// //钉钉平台的用批量发送, 每分钟5000个
|
|
|
-// int minuteSize = 5000;
|
|
|
-// int minuteTimes = dingdingUserList.size()/minuteSize + (dingdingUserList.size()%minuteSize==0?0:1);
|
|
|
-// for (int m = 0; m < minuteTimes; m++) {
|
|
|
-// int startIndex = m*minuteSize;
|
|
|
-// int endIndex = (m+1)*minuteSize;
|
|
|
-// if (endIndex > dingdingUserList.size()) {
|
|
|
-// endIndex = dingdingUserList.size();
|
|
|
-// }
|
|
|
-// final List<Map<String, Object>> curUserList = dingdingUserList.subList(startIndex, endIndex);
|
|
|
-// final int curm = m;
|
|
|
-// //调用新的线程发送
|
|
|
-// new Thread(() -> {
|
|
|
-// if (curm > 0) {
|
|
|
-// try {
|
|
|
-// //每间隔60秒发送一次
|
|
|
-// System.out.println("开始间隔了60秒===");
|
|
|
-// Thread.currentThread().sleep(60000);
|
|
|
-// } catch (InterruptedException e) {
|
|
|
-// e.printStackTrace();
|
|
|
-// }
|
|
|
-// }
|
|
|
-// System.out.println("发送钉钉漏填提醒:" + LocalDateTime.now().toString() + ", size=" + curUserList.size());
|
|
|
-// //按照company组装,同一个company批量发送,最大不超过1000
|
|
|
-// Integer companyId = null;
|
|
|
-// Long agentId = null;
|
|
|
-// String alertMsg = null;
|
|
|
-// List<String> dingUid = new ArrayList<>();
|
|
|
-// int count = 0;
|
|
|
-// for (int i=0;i<curUserList.size(); i++) {
|
|
|
-// count++;
|
|
|
-// Map<String, Object> item = curUserList.get(i);
|
|
|
-// Integer curCompanyId = (Integer)item.get("companyId");
|
|
|
-// dingUid.add((String)item.get("dingdingUserid"));
|
|
|
-// if (companyId == null) {
|
|
|
-// companyId = curCompanyId;
|
|
|
-// agentId = companyDingdingService.getOne(new QueryWrapper<CompanyDingding>().eq("company_id", companyId)).getAgentId();
|
|
|
-// alertMsg = timeTypeMapper.selectById(companyId).getAlertMsg();
|
|
|
-// }
|
|
|
-//
|
|
|
-// if (i == curUserList.size() -1 || curCompanyId.intValue() != (int)curUserList.get(i+1).get("companyId")
|
|
|
-// || count == 1000) {
|
|
|
-// String idStr = dingUid.stream().collect(Collectors.joining(","));
|
|
|
-// System.out.println("发送给==="+idStr);
|
|
|
-// companyDingdingService.sendFillReportAlertMsg(companyId, agentId, alertMsg, idStr);
|
|
|
-// count = 0;
|
|
|
-// companyId = null;
|
|
|
-// dingUid.clear();
|
|
|
-// }
|
|
|
-// }
|
|
|
-// }).start();
|
|
|
-// }
|
|
|
-// }
|
|
|
-// //推送项目即将逾期通知
|
|
|
-// public void pushProjectNotify(String wxOpenid, String projectName, int days, String endDate) {
|
|
|
-// //1,配置
|
|
|
-// WxMpInMemoryConfigStorage wxStorage = new WxMpInMemoryConfigStorage();
|
|
|
-// wxStorage.setAppId(appId);
|
|
|
-// wxStorage.setSecret(appSecret);
|
|
|
-// WxMpService wxMpService = new WxMpServiceImpl();
|
|
|
-// wxMpService.setWxMpConfigStorage(wxStorage);
|
|
|
-//
|
|
|
-// //2,推送消息
|
|
|
-// WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
|
|
|
-// .toUser(wxOpenid)//要推送的用户openid
|
|
|
-// .templateId(TEMPLATE_PROJECT_DEADLINE)//模版id
|
|
|
-// .build();
|
|
|
-// //3,如果是正式版发送模版消息,这里需要配置你的信息
|
|
|
-// templateMessage.addData(new WxMpTemplateData("first", "项目还有"+days+"天到期", "#FF00FF"));
|
|
|
-// templateMessage.addData(new WxMpTemplateData("keyword1", projectName, "#000000"));
|
|
|
-// templateMessage.addData(new WxMpTemplateData("keyword2", endDate, "#000000"));
|
|
|
-// templateMessage.addData(new WxMpTemplateData("remark", "如有您参与的任务,请按时完成,谢谢", "#000000"));
|
|
|
-// // templateMessage.addData(new WxMpTemplateData(name2, value2, color2));
|
|
|
-// try {
|
|
|
-// System.out.println("======推送消息===");
|
|
|
-// wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
|
|
|
-// } catch (Exception e) {
|
|
|
-// System.out.println("推送失败:" + e.getMessage());
|
|
|
-// e.printStackTrace();
|
|
|
-// }
|
|
|
-// }
|
|
|
-//
|
|
|
-// //推送日报未填消息
|
|
|
-// public void push(Map<String, Object> user, String alertMsg) {
|
|
|
-// //1,配置
|
|
|
-// WxMpInMemoryConfigStorage wxStorage = new WxMpInMemoryConfigStorage();
|
|
|
-// wxStorage.setAppId(appId);
|
|
|
-// wxStorage.setSecret(appSecret);
|
|
|
-// WxMpService wxMpService = new WxMpServiceImpl();
|
|
|
-// wxMpService.setWxMpConfigStorage(wxStorage);
|
|
|
-//
|
|
|
-// //2,推送消息
|
|
|
-// WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
|
|
|
-// .toUser((String)user.get("wxOpenid"))//要推送的用户openid
|
|
|
-// .templateId(TEMPLATE_REPORT_FILL)//模版id
|
|
|
-// .url("http://mobworktime.ttkuaiban.com/#/edit")//点击模版消息要访问的网址
|
|
|
-// .build();
|
|
|
-// //3,如果是正式版发送模版消息,这里需要配置你的信息
|
|
|
-// templateMessage.addData(new WxMpTemplateData("first", alertMsg, "#FF00FF"));
|
|
|
-// templateMessage.addData(new WxMpTemplateData("keyword1", (String)user.get("name"), "#000000"));
|
|
|
-// templateMessage.addData(new WxMpTemplateData("keyword2", (String)user.get("departmentName"), "#000000"));
|
|
|
-// templateMessage.addData(new WxMpTemplateData("remark", "请尽快填报", "#000000"));
|
|
|
-// // templateMessage.addData(new WxMpTemplateData(name2, value2, color2));
|
|
|
-// try {
|
|
|
-// wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
|
|
|
-// } catch (Exception e) {
|
|
|
-// System.out.println("推送失败:" + e.getMessage());
|
|
|
-// e.printStackTrace();
|
|
|
-// }
|
|
|
-//
|
|
|
-// }
|
|
|
-//
|
|
|
-//
|
|
|
-// //推送上周填写的日报工时情况
|
|
|
-// public void pushLastWeekReportFill(User user, String alertMsg) {
|
|
|
-// //1,配置
|
|
|
-// WxMpInMemoryConfigStorage wxStorage = new WxMpInMemoryConfigStorage();
|
|
|
-// wxStorage.setAppId(appId);
|
|
|
-// wxStorage.setSecret(appSecret);
|
|
|
-// WxMpService wxMpService = new WxMpServiceImpl();
|
|
|
-// wxMpService.setWxMpConfigStorage(wxStorage);
|
|
|
-//
|
|
|
-// //2,推送消息
|
|
|
-// WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
|
|
|
-// .toUser(user.getWxOpenid())//要推送的用户openid
|
|
|
-// .templateId(TEMPLATE_REPORT_FILL)//模版id
|
|
|
-// .url("http://mobworktime.ttkuaiban.com/")//点击模版消息要访问的网址
|
|
|
-// .build();
|
|
|
-// //3,如果是正式版发送模版消息,这里需要配置你的信息
|
|
|
-// templateMessage.addData(new WxMpTemplateData("first", alertMsg, "#FF00FF"));
|
|
|
-// templateMessage.addData(new WxMpTemplateData("keyword1", user.getName(), "#000000"));
|
|
|
-// templateMessage.addData(new WxMpTemplateData("keyword2", user.getDepartmentName(), "#000000"));
|
|
|
-// templateMessage.addData(new WxMpTemplateData("remark", "-", "#000000"));
|
|
|
-// // templateMessage.addData(new WxMpTemplateData(name2, value2, color2));
|
|
|
-// try {
|
|
|
-// wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
|
|
|
-// } catch (Exception e) {
|
|
|
-// System.out.println("推送失败:" + e.getMessage());
|
|
|
-// e.printStackTrace();
|
|
|
-// }
|
|
|
-//
|
|
|
-// }
|
|
|
-//}
|
|
|
+package com.management.platform.task;
|
|
|
+
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.Period;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+import com.management.platform.constant.Constant;
|
|
|
+import com.management.platform.entity.*;
|
|
|
+import com.management.platform.mapper.*;
|
|
|
+import com.management.platform.service.CompanyDingdingService;
|
|
|
+import com.management.platform.service.WxCorpInfoService;
|
|
|
+import com.management.platform.util.*;
|
|
|
+import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
|
|
|
+import me.chanjar.weixin.mp.api.WxMpService;
|
|
|
+import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
|
|
|
+import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
|
|
|
+import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.format.annotation.DateTimeFormat;
|
|
|
+import org.springframework.scheduling.annotation.EnableScheduling;
|
|
|
+import org.springframework.scheduling.annotation.Scheduled;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * Author: 吴涛涛
|
|
|
+ * Date : 2019 - 12 - 31 16:04
|
|
|
+ * Description:<描述>
|
|
|
+ * Version: 1.0
|
|
|
+ */
|
|
|
+@EnableScheduling
|
|
|
+@Component
|
|
|
+public class TimingTask {
|
|
|
+
|
|
|
+ @Value("${wx.template_report_fill}")
|
|
|
+ public String TEMPLATE_REPORT_FILL;
|
|
|
+ @Value("${wx.template_project_deadline}")
|
|
|
+ public String TEMPLATE_PROJECT_DEADLINE;
|
|
|
+ @Value("${wx.app_id}")
|
|
|
+ public String appId;
|
|
|
+ @Value("${wx.app_secret}")
|
|
|
+ public String appSecret;
|
|
|
+ @Autowired
|
|
|
+ private RedisUtil redisUtil;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private ScreenshotMapper screenshotMapper;
|
|
|
+ @Resource
|
|
|
+ private TimeTypeMapper timeTypeMapper;
|
|
|
+ @Resource
|
|
|
+ private UserMapper userMapper;
|
|
|
+ @Resource
|
|
|
+ private DepartmentMapper departmentMapper;
|
|
|
+ @Resource
|
|
|
+ private ReportMapper reportMapper;
|
|
|
+ @Resource
|
|
|
+ private WxCorpInfoService wxCorpInfoService;
|
|
|
+ @Resource
|
|
|
+ private WxCorpInfoMapper wxCorpInfoMapper;
|
|
|
+ @Value(value = "${upload.path}")
|
|
|
+ private String path;
|
|
|
+ @Resource
|
|
|
+ private ProjectMapper projectMapper;
|
|
|
+ @Resource
|
|
|
+ private CompanyDingdingService companyDingdingService;
|
|
|
+
|
|
|
+ //检查项目到期,距离到期时间3天内的,每天提醒
|
|
|
+ @Scheduled(cron = "0 0 10 ? * *")
|
|
|
+ private void projectDeadlineAlert() {
|
|
|
+ LocalDate start = LocalDate.now();
|
|
|
+ start = start.plusDays(1);
|
|
|
+ LocalDate end = LocalDate.now();
|
|
|
+ end = end.plusDays(3);
|
|
|
+ //获取未来3天内超期的项目
|
|
|
+ List<Project> list = projectMapper.selectList(new QueryWrapper<Project>().eq("status", 1).between("plan_end_date", start, end));
|
|
|
+ System.out.println("即将超期项目=="+list.size());
|
|
|
+
|
|
|
+ for (Project p : list) {
|
|
|
+
|
|
|
+ Period period = Period.between(start, p.getPlanEndDate());
|
|
|
+ int days = period.getDays();
|
|
|
+ List<Map<String, Object>> userList = userMapper.getProjectPushUserList(p.getId());
|
|
|
+ userList.forEach(u->{
|
|
|
+ if (u.get("corpwxUserid") != null) {
|
|
|
+ //TODO: 推送到企业微信
|
|
|
+// String corpUid = (String) u.get("corpwxUserid");
|
|
|
+// wxCorpInfoService.sendWXCorpMsg(cpList.get(0), corpUid, "请及时填写今日的工作报告哦");
|
|
|
+ } else {
|
|
|
+ pushProjectNotify((String)u.get("wxOpenid"), p.getProjectName(), days, p.getPlanEndDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //每天7点同步昨天的企业微信考勤考勤打卡记录
|
|
|
+ @Scheduled(cron = "0 0 7 ? * *")
|
|
|
+ private void synCorpWXCardTime() {
|
|
|
+ LocalDateTime yestoday = LocalDateTime.now().minusDays(1);
|
|
|
+ yestoday = yestoday.withHour(0).withMinute(0).withSecond(0).withNano(0);
|
|
|
+
|
|
|
+ List<TimeType> typeList = timeTypeMapper.selectList(new QueryWrapper<TimeType>().eq("sync_corpwx_time", 1));
|
|
|
+ for (TimeType type : typeList) {
|
|
|
+ Integer companyId = type.getCompanyId();
|
|
|
+ wxCorpInfoService.getUserCheckInDayData(companyId, null, yestoday, yestoday);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //每周日晚上11点 同步一次本月的考勤打卡记录
|
|
|
+ @Scheduled(cron = "0 0 23 ? * 7")
|
|
|
+ private void weeklySyncCorpWXCardTime() {
|
|
|
+ LocalDateTime current = LocalDateTime.now();
|
|
|
+ LocalDateTime start = current.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
|
|
|
+ LocalDateTime now = LocalDateTime.now();
|
|
|
+ LocalDateTime end = now.minusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
|
|
|
+ System.out.println("每周同步,开始同步本月的考勤记录="+start+" 至 "+end);
|
|
|
+ List<TimeType> typeList = timeTypeMapper.selectList(new QueryWrapper<TimeType>().eq("sync_corpwx_time", 1));
|
|
|
+ for (TimeType type : typeList) {
|
|
|
+ Integer companyId = type.getCompanyId();
|
|
|
+ wxCorpInfoService.getUserCheckInDayData(companyId, null, start, end);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //每个月6号早上6点同步上个月的企业微信考勤考勤打卡记录
|
|
|
+ @Scheduled(cron = "0 0 6 6 * ?")
|
|
|
+ private void synMonthCorpWXCardTime() {
|
|
|
+ LocalDateTime lastMonth = LocalDateTime.now().minusMonths(1);
|
|
|
+ LocalDateTime start = lastMonth.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
|
|
|
+ LocalDateTime now = LocalDateTime.now().withDayOfMonth(1);
|
|
|
+ LocalDateTime end = now.minusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
|
|
|
+ System.out.println("开始同步上个月的考勤记录");
|
|
|
+ List<TimeType> typeList = timeTypeMapper.selectList(new QueryWrapper<TimeType>().eq("sync_corpwx_time", 1));
|
|
|
+ for (TimeType type : typeList) {
|
|
|
+ Integer companyId = type.getCompanyId();
|
|
|
+ wxCorpInfoService.getUserCheckInDayData(companyId, null, start, end);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //发送上周填写的工时统计
|
|
|
+ @Scheduled(cron = "0 0 8 ? * *")
|
|
|
+ private void lastWeekFillTimeAlert() {
|
|
|
+ //每日检查是否是周一,提醒上周工时汇总
|
|
|
+ LocalDate curDay = LocalDate.now();
|
|
|
+ if (curDay.getDayOfWeek().getValue() == 1) {
|
|
|
+ List<User> allUser = userMapper.selectList(new QueryWrapper<User>().isNotNull("wx_openid"));
|
|
|
+ for (User u : allUser) {
|
|
|
+ //取上周
|
|
|
+ LocalDate lastWeek = curDay.minusWeeks(1);
|
|
|
+
|
|
|
+ int weekDay = lastWeek.getDayOfWeek().getValue();
|
|
|
+ LocalDate monday = lastWeek.minusDays(weekDay-1);
|
|
|
+ LocalDate sunday = monday.plusDays(6);
|
|
|
+ List<Report> reportList = reportMapper.selectList(new QueryWrapper<Report>().eq("creator_id", u.getId()).between("create_date", monday, sunday));
|
|
|
+ List<Integer> pids = reportList.stream().map(Report::getProjectId).distinct().collect(Collectors.toList());
|
|
|
+ List<Project> projectList = projectMapper.selectList(new QueryWrapper<Project>().in("id", pids));
|
|
|
+ String collect = projectList.stream().map(Project::getProjectName).collect(Collectors.joining(","));
|
|
|
+ //计算总工时
|
|
|
+ double sum = reportList.stream().mapToDouble(Report::getWorkingTime).sum();
|
|
|
+ double waiting = reportList.stream().filter(r -> r.getState() == 0).mapToDouble(Report::getWorkingTime).sum();
|
|
|
+ double reject = reportList.stream().filter(r -> r.getState() == 2).mapToDouble(Report::getWorkingTime).sum();
|
|
|
+ double pass = reportList.stream().filter(r -> r.getState() == 1).mapToDouble(Report::getWorkingTime).sum();
|
|
|
+ String str = "您上周共参与了" + projectList.size()+"个项目,总工时为" + sum+"小时。其中审核通过"+pass
|
|
|
+ +"小时, 待审核"+waiting+"小时,驳回"+reject+"小时。";
|
|
|
+ pushLastWeekReportFill(u, str);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //每分钟校验是否有需要提醒的填报
|
|
|
+ @Scheduled(fixedRate = 60 * 1000)
|
|
|
+ private void process() {
|
|
|
+ LocalDateTime now = LocalDateTime.now();
|
|
|
+ LocalDate localDate = LocalDate.now();
|
|
|
+
|
|
|
+ //判断是否是工作日,非工作日不提醒
|
|
|
+ if (!WorkDayCalculateUtils.isWorkDay(localDate)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ DateTimeFormatter dt = DateTimeFormatter.ofPattern("HH:mm");
|
|
|
+ String str = dt.format(now);
|
|
|
+ List<TimeType> typeList = timeTypeMapper.selectList(new QueryWrapper<TimeType>().isNotNull("alert_time")
|
|
|
+ .ge("alert_time", str));
|
|
|
+
|
|
|
+ typeList.forEach(t->{
|
|
|
+ if (str.equals(t.getAlertTime())) {
|
|
|
+ //发送推送提醒
|
|
|
+ List<Map<String, Object>> userList = userMapper.getPushUserList(t.getCompanyId());
|
|
|
+ List<WxCorpInfo> cpList = wxCorpInfoMapper.selectList(new QueryWrapper<WxCorpInfo>().eq("company_id", t.getCompanyId()));
|
|
|
+ userList.forEach(u->{
|
|
|
+ if (u.get("corpwxUserid") != null) {
|
|
|
+ //推送到企业微信
|
|
|
+ String corpUid = (String) u.get("corpwxUserid");
|
|
|
+ wxCorpInfoService.sendWXCorpMsg(cpList.get(0), corpUid, t.getAlertMsg());
|
|
|
+ } else if (u.get("wxOpenid") != null) {
|
|
|
+ push(u, t.getAlertMsg());
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ List<Map<String, Object>> dingdingUserList = userMapper.getPushDingdingUserList(str);
|
|
|
+ System.out.println("=============查询钉钉推送未填提醒的人员列表=====, size=" + dingdingUserList.size());
|
|
|
+
|
|
|
+ //钉钉平台的用批量发送, 每分钟5000个
|
|
|
+ int minuteSize = 5000;
|
|
|
+ int minuteTimes = dingdingUserList.size()/minuteSize + (dingdingUserList.size()%minuteSize==0?0:1);
|
|
|
+ for (int m = 0; m < minuteTimes; m++) {
|
|
|
+ int startIndex = m*minuteSize;
|
|
|
+ int endIndex = (m+1)*minuteSize;
|
|
|
+ if (endIndex > dingdingUserList.size()) {
|
|
|
+ endIndex = dingdingUserList.size();
|
|
|
+ }
|
|
|
+ final List<Map<String, Object>> curUserList = dingdingUserList.subList(startIndex, endIndex);
|
|
|
+ final int curm = m;
|
|
|
+ //调用新的线程发送
|
|
|
+ new Thread(() -> {
|
|
|
+ if (curm > 0) {
|
|
|
+ try {
|
|
|
+ //每间隔60秒发送一次
|
|
|
+ System.out.println("开始间隔了60秒===");
|
|
|
+ Thread.currentThread().sleep(60000);
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ System.out.println("发送钉钉漏填提醒:" + LocalDateTime.now().toString() + ", size=" + curUserList.size());
|
|
|
+ //按照company组装,同一个company批量发送,最大不超过1000
|
|
|
+ Integer companyId = null;
|
|
|
+ Long agentId = null;
|
|
|
+ String alertMsg = null;
|
|
|
+ List<String> dingUid = new ArrayList<>();
|
|
|
+ int count = 0;
|
|
|
+ for (int i=0;i<curUserList.size(); i++) {
|
|
|
+ count++;
|
|
|
+ Map<String, Object> item = curUserList.get(i);
|
|
|
+ Integer curCompanyId = (Integer)item.get("companyId");
|
|
|
+ dingUid.add((String)item.get("dingdingUserid"));
|
|
|
+ if (companyId == null) {
|
|
|
+ companyId = curCompanyId;
|
|
|
+ agentId = companyDingdingService.getOne(new QueryWrapper<CompanyDingding>().eq("company_id", companyId)).getAgentId();
|
|
|
+ alertMsg = timeTypeMapper.selectById(companyId).getAlertMsg();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (i == curUserList.size() -1 || curCompanyId.intValue() != (int)curUserList.get(i+1).get("companyId")
|
|
|
+ || count == 1000) {
|
|
|
+ String idStr = dingUid.stream().collect(Collectors.joining(","));
|
|
|
+ System.out.println("发送给==="+idStr);
|
|
|
+ companyDingdingService.sendFillReportAlertMsg(companyId, agentId, alertMsg, idStr);
|
|
|
+ count = 0;
|
|
|
+ companyId = null;
|
|
|
+ dingUid.clear();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }).start();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //推送项目即将逾期通知
|
|
|
+ public void pushProjectNotify(String wxOpenid, String projectName, int days, String endDate) {
|
|
|
+ //1,配置
|
|
|
+ WxMpInMemoryConfigStorage wxStorage = new WxMpInMemoryConfigStorage();
|
|
|
+ wxStorage.setAppId(appId);
|
|
|
+ wxStorage.setSecret(appSecret);
|
|
|
+ WxMpService wxMpService = new WxMpServiceImpl();
|
|
|
+ wxMpService.setWxMpConfigStorage(wxStorage);
|
|
|
+
|
|
|
+ //2,推送消息
|
|
|
+ WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
|
|
|
+ .toUser(wxOpenid)//要推送的用户openid
|
|
|
+ .templateId(TEMPLATE_PROJECT_DEADLINE)//模版id
|
|
|
+ .build();
|
|
|
+ //3,如果是正式版发送模版消息,这里需要配置你的信息
|
|
|
+ templateMessage.addData(new WxMpTemplateData("first", "项目还有"+days+"天到期", "#FF00FF"));
|
|
|
+ templateMessage.addData(new WxMpTemplateData("keyword1", projectName, "#000000"));
|
|
|
+ templateMessage.addData(new WxMpTemplateData("keyword2", endDate, "#000000"));
|
|
|
+ templateMessage.addData(new WxMpTemplateData("remark", "如有您参与的任务,请按时完成,谢谢", "#000000"));
|
|
|
+ // templateMessage.addData(new WxMpTemplateData(name2, value2, color2));
|
|
|
+ try {
|
|
|
+ System.out.println("======推送消息===");
|
|
|
+ wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
|
|
|
+ } catch (Exception e) {
|
|
|
+ System.out.println("推送失败:" + e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //推送日报未填消息
|
|
|
+ public void push(Map<String, Object> user, String alertMsg) {
|
|
|
+ //1,配置
|
|
|
+ WxMpInMemoryConfigStorage wxStorage = new WxMpInMemoryConfigStorage();
|
|
|
+ wxStorage.setAppId(appId);
|
|
|
+ wxStorage.setSecret(appSecret);
|
|
|
+ WxMpService wxMpService = new WxMpServiceImpl();
|
|
|
+ wxMpService.setWxMpConfigStorage(wxStorage);
|
|
|
+
|
|
|
+ //2,推送消息
|
|
|
+ WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
|
|
|
+ .toUser((String)user.get("wxOpenid"))//要推送的用户openid
|
|
|
+ .templateId(TEMPLATE_REPORT_FILL)//模版id
|
|
|
+ .url("http://mobworktime.ttkuaiban.com/#/edit")//点击模版消息要访问的网址
|
|
|
+ .build();
|
|
|
+ //3,如果是正式版发送模版消息,这里需要配置你的信息
|
|
|
+ templateMessage.addData(new WxMpTemplateData("first", alertMsg, "#FF00FF"));
|
|
|
+ templateMessage.addData(new WxMpTemplateData("keyword1", (String)user.get("name"), "#000000"));
|
|
|
+ templateMessage.addData(new WxMpTemplateData("keyword2", (String)user.get("departmentName"), "#000000"));
|
|
|
+ templateMessage.addData(new WxMpTemplateData("remark", "请尽快填报", "#000000"));
|
|
|
+ // templateMessage.addData(new WxMpTemplateData(name2, value2, color2));
|
|
|
+ try {
|
|
|
+ wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
|
|
|
+ } catch (Exception e) {
|
|
|
+ System.out.println("推送失败:" + e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //推送上周填写的日报工时情况
|
|
|
+ public void pushLastWeekReportFill(User user, String alertMsg) {
|
|
|
+ //1,配置
|
|
|
+ WxMpInMemoryConfigStorage wxStorage = new WxMpInMemoryConfigStorage();
|
|
|
+ wxStorage.setAppId(appId);
|
|
|
+ wxStorage.setSecret(appSecret);
|
|
|
+ WxMpService wxMpService = new WxMpServiceImpl();
|
|
|
+ wxMpService.setWxMpConfigStorage(wxStorage);
|
|
|
+
|
|
|
+ //2,推送消息
|
|
|
+ WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
|
|
|
+ .toUser(user.getWxOpenid())//要推送的用户openid
|
|
|
+ .templateId(TEMPLATE_REPORT_FILL)//模版id
|
|
|
+ .url("http://mobworktime.ttkuaiban.com/")//点击模版消息要访问的网址
|
|
|
+ .build();
|
|
|
+ //3,如果是正式版发送模版消息,这里需要配置你的信息
|
|
|
+ templateMessage.addData(new WxMpTemplateData("first", alertMsg, "#FF00FF"));
|
|
|
+ templateMessage.addData(new WxMpTemplateData("keyword1", user.getName(), "#000000"));
|
|
|
+ templateMessage.addData(new WxMpTemplateData("keyword2", user.getDepartmentName(), "#000000"));
|
|
|
+ templateMessage.addData(new WxMpTemplateData("remark", "-", "#000000"));
|
|
|
+ // templateMessage.addData(new WxMpTemplateData(name2, value2, color2));
|
|
|
+ try {
|
|
|
+ wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
|
|
|
+ } catch (Exception e) {
|
|
|
+ System.out.println("推送失败:" + e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+}
|