需求介绍
增加对数据的订单监控,达到数据配置的要求时候发送短信
模型设计
create table MKT_WARING
(
mkt_waring_id NUMBER(16), --主键
waring_sql VARCHAR2(3000), --sql
waring_sql_param VARCHAR2(500), --sql参数
waring_cron VARCHAR2(200), --cron表达式
waring_status VARCHAR2(50), --状态
waring_sms_tempalte VARCHAR2(100), --短信模板
waring_sms_context VARCHAR2(3000), --短信内容
waring_phone VARCHAR2(50),--电话号码
waring_remark VARCHAR2(200),--备注
waring_type VARCHAR2(10),--类型
waring_expression VARCHAR2(3000) --表达式(正则最好)
)
代码部分
package com.sitech.waring.config;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.sitech.crmtpd.market.domain.comp.WaringConfigEntity;
import com.sitech.waring.scheduled.BaseJob;
import com.sitech.waring.scheduled.OrderOverStock;
import com.sitech.waring.scheduled.OrderSuccessRateLow;
import com.sitech.waring.scheduled.OrderTimeoutWaring;
import lombok.extern.slf4j.Slf4j;
import netscape.javascript.JSObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
/**
* @oauth: qiangSW
* @date: 2020/3/24 15:07
* @description: com.sitech.waring.config
* @doc:
*/
@Configuration
@Slf4j
public class WaringProjeactInit {
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private OrderOverStock orderOverStock;
@Autowired
private OrderSuccessRateLow orderSuccessRateLow;
@Autowired
private OrderTimeoutWaring orderTimeoutWaring;
public static List waringConfigEntities = Lists.newArrayList();
@Bean
public List initWaringConfig() {
String sql = "select mkt_waring_id,waring_sql,waring_sql_param,waring_cron,waring_status,waring_sms_tempalte," +
"waring_sms_context,waring_phone,waring_expression from mkt_waring where waring_status = '0' and waring_type = '0'";
List query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(WaringConfigEntity.class));
waringConfigEntities.addAll(query);
log.info("加载预警配置信息{}", JSONObject.toJSONString(query));
return query;
}
//项目初始化job
@Bean
public void addJobInfo() {
BaseJob.jobMap.put(orderOverStock.WARING_ID, orderOverStock);
BaseJob.jobMap.put(orderSuccessRateLow.WARING_ID, orderSuccessRateLow);
BaseJob.jobMap.put(orderTimeoutWaring.WARING_ID, orderTimeoutWaring);
}
}
package com.sitech.waring.scheduled;
import com.google.common.collect.Maps;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Map;
/**
* @oauth: qiangSW
* @date: 2020/4/5 9:57
* @description: com.sitech.waring.scheduled
* @doc:
*/
public interface BaseJob {
public Map jobMap = Maps.newHashMap();
public void addJob();
}
package com.sitech.waring.scheduled;
import com.sitech.waring.Service.SendSmsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
/**
* @oauth: qiangSW
* @date: 2020/3/25 11:04
* @description: com.sitech.waring.scheduled
* @doc: 工单积压预警
*/
@Component
@Slf4j
public class OrderOverStock implements Runnable {
public static final Long WARING_ID = 2l;
@Autowired
private SendSmsService sendSmsService;
@Override
public void run() {
/*发送短信*/
sendSmsService.smsContextMap(WARING_ID);
}
}
package com.sitech.waring.scheduled;
import com.google.common.collect.Lists;
import com.sitech.crmtpd.market.domain.comp.WaringConfigEntity;
import com.sitech.waring.Service.SendSmsService;
import com.sitech.waring.config.WaringProjeactInit;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.PostConstruct;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
* @oauth: qiangSW
* @date: 2020/3/25 11:05
* @description: com.sitech.waring.scheduled
* @doc: 转化率低于1%
*/
@Component
@Slf4j
public class OrderSuccessRateLow implements Runnable {
public static final Long WARING_ID = 1l;
@Autowired
private SendSmsService sendSmsService;
@PostConstruct
@Override
public void run() {
sendSmsService.smsContextIntger(WARING_ID);
}
}
package com.sitech.waring.Service;
import com.sitech.crmtpd.mapper.IntfPush0MsgMktMapper;
import com.sitech.crmtpd.market.domain.IntfPush0MsgMkt;
import com.sitech.crmtpd.market.domain.comp.WaringConfigEntity;
import com.sitech.jframe.jdbc.sequence.SeqService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import com.sitech.waring.config.WaringProjeactInit;
import org.springframework.util.StringUtils;
import java.text.MessageFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* @oauth: qiangSW
* @date: 2020/3/24 15:24
* @description: com.sitech.waring.Service
* @doc: 发送短信
*/
@Service
@Slf4j
public class SendSmsService {
@Autowired
private IntfPush0MsgMktMapper intfPush0MsgMktMapper;
@Autowired
private SeqService seqService;
@Autowired
private JdbcTemplate jdbcTemplate;
/**
* 返回 map
*
* @param configId
*/
public void smsContextMap(Long configId) {
WaringConfigEntity waringConfigEntity = filterWaringConfigEntity(configId);
if (null == waringConfigEntity) {
return;
}
String sql = waringConfigEntity.getWaringSql();
String sqlParam = waringConfigEntity.getWaringSqlParam();
String[] sqlParamArry = sqlParam.split(",");
Map map = jdbcTemplate.queryForMap(sql, sqlParamArry);
String waringContext = waringConfigEntity.getWaringSmsContext();
String smsContext = MessageFormat.format(waringContext, map.get("summary15day"), map.get("summary"));
String[] phones = waringConfigEntity.getWaringPhone().split(",");
for (int i = 0; i < phones.length; i++) {
StringBuffer buffer = new StringBuffer("{\"content\":\"").append(smsContext).append("\"}");
sendSms(phones[i], buffer.toString(), waringConfigEntity.getWaringSmsTempalte());
}
}
/**
* 返回Intger
*
* @param configId
*/
public void smsContextIntger(Long configId) {
WaringConfigEntity waringConfigEntity = filterWaringConfigEntity(configId);
if (null == waringConfigEntity) {
return;
}
String sql = waringConfigEntity.getWaringSql();
String sqlParam = waringConfigEntity.getWaringSqlParam();
Object result = 0;
if (!StringUtils.isEmpty(sqlParam)) {
String[] sqlParamArry = sqlParam.split(",");
result = jdbcTemplate.queryForObject(sql, sqlParamArry, Object.class);
} else {
result = jdbcTemplate.queryForObject(sql, Object.class);
}
String waringContext = waringConfigEntity.getWaringSmsContext();
String smsContext = MessageFormat.format(waringContext, result);
String[] phones = waringConfigEntity.getWaringPhone().split(",");
for (int i = 0; i < phones.length; i++) {
StringBuffer buffer = new StringBuffer("{\"content\":\"").append(smsContext).append("\"}");
sendSms(phones[i], buffer.toString(), waringConfigEntity.getWaringSmsTempalte());
}
}
/**
* 过滤
*
* @param configId
* @return
*/
public WaringConfigEntity filterWaringConfigEntity(Long configId) {
List waringConfigEntities = WaringProjeactInit.waringConfigEntities;
if (CollectionUtils.isEmpty(waringConfigEntities)) {
return null;
}
/*根据主键过滤,过滤后只有一条数据*/
List collect = waringConfigEntities.stream()
.filter(filter -> filter.getMktWaringId().longValue() == configId.longValue())
.collect(Collectors.toList());
return Optional.ofNullable(collect).map(a -> {
return a.get(0);
}).orElse(null);
}
public void smsContext(List configIds) {
List waringConfigEntities = WaringProjeactInit.waringConfigEntities;
if (CollectionUtils.isEmpty(waringConfigEntities)) {
return;
}
/*根据主键过滤,过滤后只有一条数据*/
List collect = waringConfigEntities.stream()
.filter(filter -> {
return configIds.contains(filter);
})
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(collect)) {
return;
}
collect.stream().forEach(each -> {
String sql = each.getWaringSql();
String sqlParam = each.getWaringSqlParam();
String[] sqlParamArry = sqlParam.split(",");
String result = jdbcTemplate.queryForObject(sql, sqlParamArry, String.class);
String waringExpression = each.getWaringExpression();
Pattern compile = Pattern.compile(waringExpression);
Matcher matcher = compile.matcher(result);
if (!matcher.matches()) {
return;
}
String waringContext = each.getWaringSmsContext();
String smsContext = String.format(waringContext, result);
String[] phones = each.getWaringPhone().split(",");
for (int i = 0; i < phones.length; i++) {
sendSms(phones[i], smsContext, each.getWaringSmsTempalte());
}
});
}
/**
* 发送短信
*
* @param phone
* @param smsContext
* @param msgTemplateId
*/
public void sendSms(String phone, String smsContext, String msgTemplateId) {
Date curDate = new Date();
IntfPush0MsgMkt intfPush0MsgMkt = new IntfPush0MsgMkt();
String seq = "100" + DateTimeFormatter.ofPattern("yyyyMMdd").format(LocalDate.now())
+ seqService.getNextval("SEQ_SMS_SEND_ID");
String sendFlag = "0";
String sendMsg = "";
String dealFlag = "00";
String dealMsg = "未调用统一推送平台接口";
intfPush0MsgMkt.setSeq(seq);
intfPush0MsgMkt.setMktCampaignId(0l);
intfPush0MsgMkt.setContactOrderId(0l);
intfPush0MsgMkt.setTemplateid(msgTemplateId);
intfPush0MsgMkt.setParameter(smsContext);
intfPush0MsgMkt.setPhoneNo(phone);
intfPush0MsgMkt.setInsertTime(curDate);
intfPush0MsgMkt.setSendFlag(sendFlag);
intfPush0MsgMkt.setSendMsg(sendMsg);
intfPush0MsgMkt.setOpCode("yingfu");
intfPush0MsgMkt.setLoginNo("admin");
intfPush0MsgMkt.setSendTime(curDate);
intfPush0MsgMkt.setHold1("0");
intfPush0MsgMkt.setHold3(Objects.toString(0));
intfPush0MsgMkt.setServNo("0");
intfPush0MsgMkt.setServiceNo("0");
intfPush0MsgMkt.setDealFlag(dealFlag);
intfPush0MsgMkt.setDealMsg(dealMsg);
intfPush0MsgMkt.setDealDate(curDate);
intfPush0MsgMktMapper.insertSelective(intfPush0MsgMkt);
log.info("{}发生告警短信",seq);
}
/* public Date getCron(TriggerContext triggerContext, Long configId, String scheduledName) {
List waringConfigEntities = WaringProjeactInit.waringConfigEntities;
if (CollectionUtils.isEmpty(waringConfigEntities)) {
return null;
}
*//*根据主键过滤,过滤后只有一条数据*//*
List collect = waringConfigEntities.stream()
.filter(filter -> filter.getMktWaringId().longValue() == configId.longValue())
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(collect)) {
return null;
}
WaringConfigEntity waringConfigEntity = collect.get(0);
log.info("{},cron表达式{}", scheduledName, waringConfigEntity.getWaringCron());
CronTrigger cronTrigger = new CronTrigger(waringConfigEntity.getWaringCron());
return cronTrigger.nextExecutionTime(triggerContext);
}*/
}
package com.sitech.waring.Service;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.sitech.crmtpd.market.domain.comp.WaringConfigEntity;
import com.sitech.waring.config.WaringProjeactInit;
import com.sitech.waring.scheduled.BaseJob;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ScheduledFuture;
/**
* @oauth: qiangSW
* @date: 2020/3/25 8:40
* @description: com.sitech.waring.Service
* @doc: 刷新配置
*/
@RestController
public class RefreshService {
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private ThreadPoolTaskScheduler threadPoolTaskScheduler;
@Autowired
private WaringProjeactInit waringProjeactInit;
Map> scheduledFutureMap = Maps.newHashMap();
Map allJob = BaseJob.jobMap;
@Bean
public ThreadPoolTaskScheduler trPoolTaskScheduler() {
return new ThreadPoolTaskScheduler();
}
/**
* 刷新job配置数据
*/
@GetMapping("/refreshConfigEntity")
public void refreshConfigEntity() {
String sql = "select mkt_waring_id,waring_sql,waring_sql_param,waring_cron,waring_status,waring_sms_tempalte," +
"waring_sms_context,waring_phone,waring_expression from mkt_waring where waring_status = '0'";
List query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(WaringConfigEntity.class));
WaringProjeactInit.waringConfigEntities.clear();
WaringProjeactInit.waringConfigEntities.addAll(query);
}
/**
* 启动全部job
*/
@GetMapping("/startAll")
public void startAll() {
List waringConfigEntities = waringProjeactInit.initWaringConfig();
Optional.ofNullable(allJob).ifPresent(a -> {
waringConfigEntities.stream().filter(filter -> {
return allJob.containsKey(filter.getMktWaringId());
}).forEach(each -> {
ScheduledFuture> schedule =
threadPoolTaskScheduler.schedule(allJob.get(each.getMktWaringId()),
new CronTrigger(each.getWaringCron()));
if (!scheduledFutureMap.containsKey(each.getMktWaringId())) {
scheduledFutureMap.put(each.getMktWaringId(), schedule);
} else {
scheduledFutureMap.remove(each.getMktWaringId());
scheduledFutureMap.put(each.getMktWaringId(), schedule);
}
});
});
}
/**
* 根据id启动job
*
* @param waringId
*/
@GetMapping("/startJobById")
public void startJon(@RequestParam("waringId") Long waringId) {
List waringConfigEntities = waringProjeactInit.initWaringConfig();
waringConfigEntities.stream()
.filter(filter -> filter.getMktWaringId().longValue() == waringId.longValue())
.forEach(each -> {
ScheduledFuture> schedule =
threadPoolTaskScheduler.schedule(allJob.get(each.getMktWaringId()),
new CronTrigger(each.getWaringCron()));
if (!scheduledFutureMap.containsKey(each.getMktWaringId())) {
scheduledFutureMap.put(each.getMktWaringId(), schedule);
} else {
scheduledFutureMap.remove(each.getMktWaringId());
scheduledFutureMap.put(each.getMktWaringId(), schedule);
}
});
}
/**
* 手动触发某个job
*
* @param waringId
*/
@GetMapping("/triggerJob")
public void triggerJob(@RequestParam("waringId") Long waringId) {
Optional.ofNullable(allJob).ifPresent(a -> {
for (Map.Entry map : allJob.entrySet()) {
if (map.getKey().longValue() == waringId.longValue()) {
threadPoolTaskScheduler.execute(map.getValue());
}
}
});
}
/**
* 停止job
*
* @param waringId
*/
@GetMapping("/stop")
public void stop(@RequestParam("waringId") Long waringId) {
if (null != waringId) {
if (scheduledFutureMap.containsKey(waringId)) {
scheduledFutureMap.get(waringId).cancel(true);
scheduledFutureMap.remove(waringId);
}
} else {
Optional.ofNullable(scheduledFutureMap).ifPresent(a -> {
a.forEach((k, v) -> {
v.cancel(true);
});
a.clear();
});
}
System.out.println("stop job");
}
/**
* 获取所有job
*
* @return
*/
@GetMapping("/getJobName")
public List getJobName() {
List list = Lists.newArrayList();
Optional.ofNullable(scheduledFutureMap).ifPresent(a -> {
a.forEach((k, v) -> {
list.add(k);
});
});
return list;
}
}