【开发】特种设备(四):定时任务,向企业微信推送消息
以特种设备举例,假定下次验收时间为10月1日,那么按照制定的推送规则,则应当在9月1号,9月24号,和10月1号进行三次推送。
@Override
@Transactional
public void autoCheckAndSendToWx(){
// 查询符合条件的特种设备推送列表(30天,7天,当天)
List<SpecPush> specPushs = specPushMapper.selectSpecPushList();
if(specPushs == null || specPushs.size() == 0){
return;
}
long start = System.currentTimeMillis();
List<SpecPushLog> logList= new ArrayList<>();
List<Long> idList= new ArrayList<>();
for (SpecPush specPush : specPushs) {
// 推送内容主体
String description = getDescription(specPush);
// 拼接url地址
String url = getUrl(specPush);
// 生成JSONObject(支持批量推送)
JSONObject json = getJSONObject(description,url,specPush);
// 推送
String response = CommonUtil.autoSendMsgToWX(JSONObject.toJSONString(json), systemcode_mes);
// 处理返回结果
if (StringUtils.isNotEmpty(response) && JSONObject.parseObject(response).getBoolean("success")) {
//推送成功,将该条记录的id记录到list中
idList.add(specPush.getId());
//推送成功,创建一条新的safePushLog
SpecPushLog log = createNewSafePushLog(specPush,description,response);
logList.add(log);
}
}
if(idList.size()>0){
// 先删除后新增(事务执行)
specPushMapper.deleteBatch(idList);
specPushLogMapper.insertSpecPushBatch(logList);
}
long end = System.currentTimeMillis();
System.out.println((end - start)/1000 + "秒");
}
获取推送主体
private String getDescription(SpecPush specPush) {
StringBuilder sb = new StringBuilder();
sb.append(WXConstants.SPEC_NAME_PARAM).append(specPush.getSpecName()).
append(WXConstants.DEPT_PARAM).append(specPush.getDeptName()).
append(WXConstants.DUE_PARAM).append(specPush.getDiffer()).
append(WXConstants.NEXT_DATE_PARAM).append(specPush.getNextInspectionDate()).
append(WXConstants.SEND_DATE_PARAM).append(DateUtils.getTime());
return sb.toString();
}
获取推送的url
private String getUrl(SpecPush specPush) {
StringBuilder sb = new StringBuilder();
sb.append(WXConstants.WX_URL).append(corpid).append(WXConstants.REDIRECT_URI)
.append(EMSUrl).append(WXConstants.SPEC_URI).append(specPush.getSpecId())
.append(WXConstants.COMMON_PARAM);
return sb.toString();
}
生成JSONObject(支持批量推送)
private JSONObject getJSONObject(String description, String url, SpecPush specPush) {
JSONObject json = new JSONObject();
json.put(WXConstants.TITLE, WXConstants.SPEC_PUSH_TITLE);
json.put(WXConstants.DESCRIPTION, description);
json.put(WXConstants.URL, url);
// 批量推送
json.put(WXConstants.TOINUSER, specPush.getReceiveMan());
return json;
}
生成日志对象
private SpecPushLog createNewSafePushLog(SpecPush specPush, String description, String response) {
SpecPushLog log = new SpecPushLog();
log.setSpecId(specPush.getSpecId());
log.setSpecName(specPush.getSpecName());
log.setPushContent(description);
log.setPushTime(DateUtils.getNowDate());
log.setPushResponse(response);
log.setReceiveMan(specPush.getReceiveMan());
return log;
}
SQL语句:
<select id="selectSpecPushList" resultMap="SpecPushResult">
SELECT id, spec_id, spec_name, dept_name, push_time, next_inspection_date,
differ, receive_man
FROM (SELECT *, DATEDIFF(a.push_time, now()) AS differ FROM spec_push a) b
WHERE b.differ IN (30,7,0)
</select>
原先,我是将所有的记录都查出来,因为在向推送表中插入记录的时候,是按30,7,0天的方式,插入三条数据。
因此我判断今天是否是推送日期时,用当前时间.compareTo(推送时间)==0进行判断,这里需要将当前转换为当天的凌晨,推送时间也转换为当天的凌晨,
这样比较麻烦。
后来我发现,MySQL有DATEDIFF()函数,它能够判断两个日期之间相差的天数,最关键的是,它自动忽略时分秒,直接比较年月日,和我的需求无比契合。
而且这个内置函数的运行效率非常快,比我遍历所有,然后用JAVA程序判断是否应该推送要高效!