diff --git a/bonus-business/src/main/java/com/bonus/job/controller/PmTaskController.java b/bonus-business/src/main/java/com/bonus/job/controller/PmTaskController.java new file mode 100644 index 0000000..0b2ee73 --- /dev/null +++ b/bonus-business/src/main/java/com/bonus/job/controller/PmTaskController.java @@ -0,0 +1,207 @@ +package com.bonus.job.controller; + +import com.bonus.common.annotation.Log; +import com.bonus.common.core.controller.BaseController; +import com.bonus.common.core.domain.AjaxResult; +import com.bonus.common.core.domain.entity.SysDept; +import com.bonus.common.core.domain.entity.SysRole; +import com.bonus.common.core.domain.entity.SysUser; +import com.bonus.common.core.page.TableDataInfo; +import com.bonus.common.enums.BusinessType; +import com.bonus.common.utils.SecurityUtils; +import com.bonus.common.utils.StringUtils; +import com.bonus.common.utils.poi.ExcelUtil; +import com.bonus.job.domain.PmTask; +import com.bonus.job.service.PmTaskService; +import com.bonus.message.dao.WorkerVo; +import com.bonus.system.service.ISysDeptService; +import com.bonus.system.service.ISysPostService; +import com.bonus.system.service.ISysRoleService; +import com.bonus.system.service.ISysUserService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ArrayUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 短信任务管理 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/msgJob") +@Slf4j +public class PmTaskController extends BaseController +{ + @Autowired + private PmTaskService service; + + /** + * 获取短信任务列表 + */ + @PreAuthorize("@ss.hasPermi('system:msgJob:list')") + @GetMapping("/list") + public TableDataInfo list(PmTask task) + { + try { + startPage(); + List list = service.getMsgTaskList(task); + return getDataTable(list); + } catch (Exception e) { + log.error(e.getMessage()); + return getDataTable(null); + } + } + + /** + * 新增短信任务 + */ + @PreAuthorize("@ss.hasPermi('system:msgJob:add')") + @Log(title = "新增短信任务", businessType = BusinessType.INSERT) + @PostMapping("/add") + public AjaxResult add(@Validated @RequestBody PmTask task) + { + try { + List msgTaskList = service.getMsgTaskList(task); + if (!msgTaskList.isEmpty()) { + return AjaxResult.error("任务已存在"); + } + return service.insert(task); + } catch (Exception e) { + log.error(e.getMessage()); + return AjaxResult.error("系统异常,请联系管理员"); + } + } + + /** + * 单个数据详情 + */ + @PreAuthorize("@ss.hasPermi('system:msgJob:one')") + @Log(title = "用户管理", businessType = BusinessType.DELETE) + @PostMapping("/getById") + public AjaxResult getById(@Validated @RequestBody PmTask task) + { + try { + PmTask data = service.getById(task); + return AjaxResult.success(data); + } catch (Exception e) { + log.error(e.getMessage()); + return AjaxResult.error("系统异常,请联系管理员"); + } + } + + /** + * 修改短信任务 + */ + @PreAuthorize("@ss.hasPermi('system:msgJob:edit')") + @Log(title = "修改短信任务", businessType = BusinessType.UPDATE) + @PostMapping("/update") + public AjaxResult edit(@Validated @RequestBody PmTask task) + { + try { + PmTask data = service.getById(task); + if(data == null){ + return AjaxResult.error("任务不存在,无法修改"); + } + if(!task.getTaskName().equals(data.getTaskName())){ + List msgTaskList = service.getMsgTaskList(task); + if (!msgTaskList.isEmpty()) { + return AjaxResult.error("任务已存在"); + } + } + return service.update(task); + } catch (Exception e) { + log.error(e.getMessage()); + return AjaxResult.error("系统异常,请联系管理员"); + } + } + + /** + * 删除短信任务 + */ + @PreAuthorize("@ss.hasPermi('system:msgJob:remove')") + @Log(title = "用户管理", businessType = BusinessType.DELETE) + @PostMapping("delete") + public AjaxResult delete(@Validated @RequestBody PmTask task) + { + try { + return service.delete(task); + } catch (Exception e) { + log.error(e.getMessage()); + return AjaxResult.error("系统异常,请联系管理员"); + } + } + + + /** + * 短信平台回执 + */ + @Log(title = "短信平台回执", businessType = BusinessType.DELETE) + @PostMapping("msgSendStatus") + public AjaxResult msgSendStatus(String msg) + { + try { + return service.msgSendStatus(msg); + } catch (Exception e) { + log.error(e.getMessage()); + return AjaxResult.error("数据格式异常"); + } + } + + + /** + * 查询短信循环次数 + */ + @Log(title = "查询短信循环数据", businessType = BusinessType.OTHER) + @PostMapping("getMsgLoopData") + public TableDataInfo getMsgLoopData(@Validated @RequestBody PmTask o) + { + try { + startPage(); + List list= service.getMsgLoopData(o); + return getDataTable(list); + } catch (Exception e) { + log.error(e.getMessage()); + return getDataTable(null); + } + } + + + /** + * 查询短信循环次数 + */ + @Log(title = "查询单次短信循环详细数据", businessType = BusinessType.OTHER) + @PostMapping("getOneLoopMsgData") + public AjaxResult getOneLoopMsgData(@Validated @RequestBody PmTask o) + { + try { + return service.getOneLoopMsgData(o); + } catch (Exception e) { + log.error(e.getMessage()); + return AjaxResult.error("系统异常,请联系管理员"); + } + } + + /** + * 手动重新发送 + */ + @Log(title = "单人重新发送", businessType = BusinessType.OTHER) + @PostMapping("oneWorkerResend") + public AjaxResult oneWorkerResend(@Validated @RequestBody WorkerVo o) + { + try { + return service.oneWorkerResend(o); + } catch (Exception e) { + log.error(e.getMessage()); + return AjaxResult.error("系统异常,请联系管理员"); + } + } + +} diff --git a/bonus-business/src/main/java/com/bonus/job/domain/PmTask.java b/bonus-business/src/main/java/com/bonus/job/domain/PmTask.java new file mode 100644 index 0000000..adee340 --- /dev/null +++ b/bonus-business/src/main/java/com/bonus/job/domain/PmTask.java @@ -0,0 +1,71 @@ +package com.bonus.job.domain; + +import java.util.Date; +import java.util.List; + +import com.bonus.message.dao.WorkerVo; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PmTask { + private Integer id; + + /** + * 任务名称 + */ + private String taskName; + + /** + * 任务要求(任务中文描述) + */ + private String remark; + + /** + * 1 通知 2计划 + */ + private Integer msgType; + + /** + * 发送内容 + */ + private String sendContent; + + /** + * 任务状态 (0正常 1暂停) + */ + private Integer taskStatus; + + /** + * 人员数量 + */ + private String workerCount; + + /** + * 人员列表 + */ + private List workerList; + + private String loopTime; + + private Long loopId; + + /** + * 并发执行 + */ + private String concurrent; + + /** + * 调度周期 + */ + private String cronExpression; + + /** + * 错失执行策略 + */ + private String misfirePolicy; + +} diff --git a/bonus-business/src/main/java/com/bonus/job/domain/SysJob.java b/bonus-business/src/main/java/com/bonus/job/domain/SysJob.java index 5aecb38..7daf4e8 100644 --- a/bonus-business/src/main/java/com/bonus/job/domain/SysJob.java +++ b/bonus-business/src/main/java/com/bonus/job/domain/SysJob.java @@ -57,6 +57,12 @@ public class SysJob extends BaseEntity @Excel(name = "任务状态", readConverterExp = "0=正常,1=暂停") private String status; + /** 关联id */ + private Integer relationId; + + /** 关联id */ + private String relationType; + @NotBlank(message = "任务名称不能为空") @Size(min = 0, max = 64, message = "任务名称不能超过64个字符") public String getJobName() diff --git a/bonus-business/src/main/java/com/bonus/job/mapper/PmTaskMapper.java b/bonus-business/src/main/java/com/bonus/job/mapper/PmTaskMapper.java new file mode 100644 index 0000000..91dd08d --- /dev/null +++ b/bonus-business/src/main/java/com/bonus/job/mapper/PmTaskMapper.java @@ -0,0 +1,41 @@ +package com.bonus.job.mapper; + +import com.bonus.common.core.domain.AjaxResult; +import com.bonus.job.domain.PmTask; +import com.bonus.message.dao.WorkerVo; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +public interface PmTaskMapper { + + int insert(PmTask record); + + List getMsgTaskList(PmTask task); + + PmTask getById(PmTask task); + + int update(PmTask task); + + int delete(PmTask task); + + /** + * 获取任务下的所有执行者 + * @return + */ + List getWorkerByTaskId(Integer taskId); + + void insertTaskWorker(@Param("list") List workerList); + + void delTaskWorker(PmTask task); + + int msgSendStatus(@Param("list") List list); + + List getMsgLoopData(PmTask o); + + PmTask getOneLoopMsgData(PmTask o); + + List getWorkerRecordByLoopId(Long loopId); + + int updateOneWorkerData(WorkerVo o); +} diff --git a/bonus-business/src/main/java/com/bonus/job/mapper/WorkerJobMapper.java b/bonus-business/src/main/java/com/bonus/job/mapper/WorkerJobMapper.java index 2860692..36d7ed6 100644 --- a/bonus-business/src/main/java/com/bonus/job/mapper/WorkerJobMapper.java +++ b/bonus-business/src/main/java/com/bonus/job/mapper/WorkerJobMapper.java @@ -1,6 +1,7 @@ package com.bonus.job.mapper; import com.bonus.job.domain.*; +import com.bonus.message.dao.WorkerVo; import org.apache.ibatis.annotations.Param; import java.util.List; @@ -12,4 +13,18 @@ import java.util.List; */ public interface WorkerJobMapper { + /** + * 通过调度ID查询调度任务信息 + * + * @param jobId 调度ID + * @return 角色对象信息 + */ + List getWorkerByJobId(String jobId); + + /** + * 批量插入任务记录 + * + * @param userList + */ + void insertTaskRecord(List userList); } diff --git a/bonus-business/src/main/java/com/bonus/job/service/PmTaskService.java b/bonus-business/src/main/java/com/bonus/job/service/PmTaskService.java new file mode 100644 index 0000000..4b3c4c1 --- /dev/null +++ b/bonus-business/src/main/java/com/bonus/job/service/PmTaskService.java @@ -0,0 +1,28 @@ +package com.bonus.job.service; + +import com.bonus.common.core.domain.AjaxResult; +import com.bonus.job.domain.PmTask; +import com.bonus.message.dao.WorkerVo; + +import java.util.List; + +public interface PmTaskService{ + + List getMsgTaskList(PmTask task); + + AjaxResult insert(PmTask task); + + PmTask getById(PmTask task); + + AjaxResult update(PmTask task); + + AjaxResult delete(PmTask task); + + AjaxResult msgSendStatus(String msg); + + List getMsgLoopData(PmTask o); + + AjaxResult getOneLoopMsgData(PmTask o); + + AjaxResult oneWorkerResend(WorkerVo o); +} diff --git a/bonus-business/src/main/java/com/bonus/job/service/PmTaskServiceImpl.java b/bonus-business/src/main/java/com/bonus/job/service/PmTaskServiceImpl.java new file mode 100644 index 0000000..a5ab48e --- /dev/null +++ b/bonus-business/src/main/java/com/bonus/job/service/PmTaskServiceImpl.java @@ -0,0 +1,129 @@ +package com.bonus.job.service; + +import com.bonus.common.core.domain.AjaxResult; +import com.bonus.job.util.MessageSendUtil; +import com.bonus.message.dao.WorkerVo; +import org.springframework.stereotype.Service; +import com.bonus.job.mapper.PmTaskMapper; +import com.bonus.job.domain.PmTask; +import javax.annotation.Resource; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +@Service +public class PmTaskServiceImpl implements PmTaskService{ + + @Resource + private PmTaskMapper mapper; + + @Override + public List getMsgTaskList(PmTask task) { + return mapper.getMsgTaskList(task); + } + + @Override + public AjaxResult insert(PmTask task) { + int insert = mapper.insert(task); + if(insert > 0){ + task.getWorkerList().forEach(worker -> worker.setTaskId(task.getId())); + mapper.insertTaskWorker(task.getWorkerList()); + } + return insert > 0 ? AjaxResult.success("添加成功",task) : AjaxResult.error("添加失败"); + } + + @Override + public PmTask getById(PmTask task) { + PmTask byId = mapper.getById(task); + if(byId != null && byId.getId() != null){ + List list = mapper.getWorkerByTaskId(task.getId()); + byId.setWorkerList(list); + } + return byId; + } + + @Override + public AjaxResult update(PmTask task) { + int update = mapper.update(task); + if(update > 0){ + task.getWorkerList().forEach(worker -> worker.setTaskId(task.getId())); + mapper.delTaskWorker(task); + mapper.insertTaskWorker(task.getWorkerList()); + } + return update > 0 ? AjaxResult.success("修改成功",task) : AjaxResult.error("修改失败"); + } + + @Override + public AjaxResult delete(PmTask task) { + int delete = mapper.delete(task); + return delete > 0 ? AjaxResult.success("删除成功",task) : AjaxResult.error("删除失败"); + } + + @Override + public AjaxResult msgSendStatus(String msg) { + if (msg == null) { + return AjaxResult.error("参数错误"); + } + String[] split = msg.split(";"); + List list = new ArrayList<>(); + for (String s : split) { + String[] splitStatus = s.split(","); + if (splitStatus.length >=3) { + WorkerVo bean = new WorkerVo(); + bean.setBatchNumber(splitStatus[0]); + bean.setPhone(splitStatus[1]); + if("1".equals(splitStatus[2])){ + bean.setSendStatus("发送成功"); + }else{ + bean.setReason("发送失败"); + } + list.add(bean); + } + } + int i = mapper.msgSendStatus(list); + return i > 0 ? AjaxResult.success("更新成功") : AjaxResult.error("更新失败"); + } + + @Override + public List getMsgLoopData(PmTask o) { + return mapper.getMsgLoopData(o); + } + + @Override + public AjaxResult getOneLoopMsgData(PmTask o) { + PmTask oneLoopMsgData = mapper.getOneLoopMsgData(o); + List list = mapper.getWorkerRecordByLoopId(oneLoopMsgData.getLoopId()); + oneLoopMsgData.setWorkerList(list); + return AjaxResult.success(oneLoopMsgData); + } + + @Override + public AjaxResult oneWorkerResend(WorkerVo o) { + //1.先去查短信内容 + List userList = new ArrayList<>(); + userList.add(o); + MessageSendUtil messageSendUtil = new MessageSendUtil(); + String msgResult = messageSendUtil.sendMessage(userList, o.getSendContent()); + if (msgResult == null){ + return AjaxResult.error("短信发送返回异常:"+msgResult); + } + String[] split = msgResult.split(","); + if (split.length == 2 && "ok".equals(split[0])) { + // 发送成功,更新任务状态为成功 + o.setSubmitStatus(split[0]); + o.setBatchNumber(split[1]); + } else { + // 发送失败,更新任务状态为失败 + o.setSubmitStatus(split[0]); + o.setReason(split[1]); + } + // 在设置发送时间时使用时分秒格式 + LocalTime currentTime = LocalTime.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss"); + o.setSendTime(currentTime.format(formatter)); + int i = mapper.updateOneWorkerData(o); + return i > 0 ? AjaxResult.success("更新成功") : AjaxResult.error("更新失败"); + } + +} diff --git a/bonus-business/src/main/java/com/bonus/job/task/WorkerSendMsgTask.java b/bonus-business/src/main/java/com/bonus/job/task/WorkerSendMsgTask.java index db61fae..c13c226 100644 --- a/bonus-business/src/main/java/com/bonus/job/task/WorkerSendMsgTask.java +++ b/bonus-business/src/main/java/com/bonus/job/task/WorkerSendMsgTask.java @@ -1,11 +1,21 @@ package com.bonus.job.task; import com.bonus.job.mapper.WorkerJobMapper; +import com.bonus.job.util.HttpRequestHelper; +import com.bonus.job.util.MessageSendUtil; +import com.bonus.job.util.SnowflakeIdGenerator; +import com.bonus.message.dao.WorkerVo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import javax.annotation.Resource; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; /** * 定时任务调度测试 @@ -20,16 +30,80 @@ public class WorkerSendMsgTask{ @Resource private WorkerJobMapper mapper; - /** - * 人员短信调度 - */ - public void updateEinDayRecord(){ - try{ + SnowflakeIdGenerator idGen = new SnowflakeIdGenerator(1, 1); + /** + * 人员短信调度执行 + */ + public void sendMsg(String jobId){ + try{ + //查询任务发送人人员信息 + List list = mapper.getWorkerByJobId(jobId); + sendInBatches(list); }catch (Exception e){ logger.error("人员短信调度,{}",e.getMessage()); } } + + /** + * 批量发送短信 + */ + public void sendInBatches(List workers) { + String content = workers.get(0).getSendContent(); + long loopId = idGen.nextId(); + final int BATCH_SIZE = 200; + if (workers.size() <= BATCH_SIZE) { + // 不超过200人,单次发送 + msgFlow(workers, content, loopId); + } else { + // 超过200人,分批次发送 + for (int i = 0; i < workers.size(); i += BATCH_SIZE) { + int end = Math.min(i + BATCH_SIZE, workers.size()); + List batch = workers.subList(i, end); + msgFlow(batch, content, loopId); + } + } + } + + /** + * 短信发送 + */ + private String msgFlow(List userList, String content, long loopId) { + //1.发送短信 + MessageSendUtil messageSendUtil = new MessageSendUtil(); + String msgResult = messageSendUtil.sendMessage(userList, content); + String[] split = msgResult.split(","); + if (split.length == 2 && "ok".equals(split[0])) { + // 批量发送成功,更新任务状态为成功 + userList.forEach(user -> { + user.setLoopId(loopId); + user.setPhone(user.getPhone()); + user.setSubmitStatus(split[0]); + user.setBatchNumber(split[1]); + // 在设置发送时间时使用时分秒格式 + LocalTime currentTime = LocalTime.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss"); + user.setSendTime(currentTime.format(formatter)); + }); + + } else { + // 批量发送失败,更新任务状态为失败 + userList.forEach(user -> { + user.setLoopId(loopId); + user.setPhone(user.getPhone()); + user.setSubmitStatus(split[0]); + user.setReason(split[1]); + // 在设置发送时间时使用时分秒格式 + LocalTime currentTime = LocalTime.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss"); + user.setSendTime(currentTime.format(formatter)); + }); + } + mapper.insertTaskRecord(userList); + return msgResult; + } + + } diff --git a/bonus-business/src/main/java/com/bonus/job/util/HttpRequestHelper.java b/bonus-business/src/main/java/com/bonus/job/util/HttpRequestHelper.java new file mode 100644 index 0000000..41a3bc4 --- /dev/null +++ b/bonus-business/src/main/java/com/bonus/job/util/HttpRequestHelper.java @@ -0,0 +1,128 @@ +package com.bonus.job.util; + +import java.io.*; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; + +public class HttpRequestHelper { + public HttpRequestHelper() { + } + + public static String doGet(String httpUrl) { + HttpURLConnection connection = null; + InputStream is = null; + BufferedReader br = null; + StringBuffer result = new StringBuffer(); + + try { + URL url = new URL(httpUrl); + connection = (HttpURLConnection)url.openConnection(); + connection.setRequestMethod("GET"); + connection.setConnectTimeout(15000); + connection.setReadTimeout(15000); + connection.connect(); + if (connection.getResponseCode() == 200) { + is = connection.getInputStream(); + if (is != null) { + br = new BufferedReader(new InputStreamReader(is, "UTF-8")); + String temp = null; + + while((temp = br.readLine()) != null) { + result.append(temp); + } + } + } + } catch (MalformedURLException var22) { + var22.printStackTrace(); + } catch (IOException var23) { + var23.printStackTrace(); + } finally { + if (br != null) { + try { + br.close(); + } catch (IOException var21) { + var21.printStackTrace(); + } + } + + if (is != null) { + try { + is.close(); + } catch (IOException var20) { + var20.printStackTrace(); + } + } + + connection.disconnect(); + } + + return result.toString(); + } + + public static String doPost(String httpUrl, String param) { + StringBuffer result = new StringBuffer(); + HttpURLConnection connection = null; + OutputStream os = null; + InputStream is = null; + BufferedReader br = null; + + try { + URL url = new URL(httpUrl); + connection = (HttpURLConnection)url.openConnection(); + connection.setRequestMethod("POST"); + connection.setConnectTimeout(15000); + connection.setReadTimeout(15000); + connection.setDoOutput(true); + connection.setDoInput(true); + connection.setRequestProperty("Content-Type", "application/json"); + if (param != null && !param.equals("")) { + os = connection.getOutputStream(); + os.write(param.getBytes("UTF-8")); + } + + if (connection.getResponseCode() == 200) { + is = connection.getInputStream(); + if (is != null) { + br = new BufferedReader(new InputStreamReader(is, "UTF-8")); + String temp = null; + if ((temp = br.readLine()) != null) { + result.append(temp); + } + } + } + } catch (MalformedURLException var29) { + var29.printStackTrace(); + } catch (IOException var30) { + var30.printStackTrace(); + } finally { + if (br != null) { + try { + br.close(); + } catch (IOException var28) { + var28.printStackTrace(); + } + } + + if (os != null) { + try { + os.close(); + } catch (IOException var27) { + var27.printStackTrace(); + } + } + + if (is != null) { + try { + is.close(); + } catch (IOException var26) { + var26.printStackTrace(); + } + } + + connection.disconnect(); + } + + return result.toString(); + } +} diff --git a/bonus-business/src/main/java/com/bonus/job/util/MessageSendUtil.java b/bonus-business/src/main/java/com/bonus/job/util/MessageSendUtil.java new file mode 100644 index 0000000..8efa30e --- /dev/null +++ b/bonus-business/src/main/java/com/bonus/job/util/MessageSendUtil.java @@ -0,0 +1,86 @@ +package com.bonus.job.util; + +import com.bonus.message.dao.WorkerVo; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class MessageSendUtil { + + // API配置常量 + final String DDTKEY = "bonusyn"; + final String SECRET_KEY = "IU0ypHbH"; + final String API_URL = "http://api.ktsms.cn/sms_token"; + + // 错误码映射表(根据你提供的文档) + private static final Map ERROR_CODE_TO_MESSAGE = new HashMap<>(); + static { + ERROR_CODE_TO_MESSAGE.put("1001", "用户名密码错误"); + ERROR_CODE_TO_MESSAGE.put("1002", "通道配置移除或没有配置通道"); + ERROR_CODE_TO_MESSAGE.put("1003", "IP验证错误"); + ERROR_CODE_TO_MESSAGE.put("1004", "签名不规范"); + ERROR_CODE_TO_MESSAGE.put("1005", "次数超限"); + ERROR_CODE_TO_MESSAGE.put("1006", "用户余额不足"); + ERROR_CODE_TO_MESSAGE.put("1007", "扣费异常"); + ERROR_CODE_TO_MESSAGE.put("1008", "数据接收失败,余额不足"); + ERROR_CODE_TO_MESSAGE.put("1009", "扣费失败或内容错误"); + ERROR_CODE_TO_MESSAGE.put("1010", "短信内容为空,或编码不正确引起"); + ERROR_CODE_TO_MESSAGE.put("1011", "有效号码为空"); + ERROR_CODE_TO_MESSAGE.put("1012", "接口参数异常,请检查参数名称"); + ERROR_CODE_TO_MESSAGE.put("1013", "发送内容超过500个字"); + ERROR_CODE_TO_MESSAGE.put("1014", "发送号码超过200个号码(个性化号码大于200或者小于1)"); + ERROR_CODE_TO_MESSAGE.put("1015", "用户名密码错误或余额不足,接口屏蔽"); + ERROR_CODE_TO_MESSAGE.put("1016", "定时参数不正确。格式为:yyyyMMddHHmmss"); + } + + /** + * 短信发送 + */ + /** + * 短信发送 + */ + public String sendMessage(List userList, String content) { + // 构建手机号字符串,用逗号分隔 + String mobiles = userList.stream() + .map(WorkerVo::getPhone) + .collect(Collectors.joining(",")); + // 构建请求URL + String url = API_URL + "?ddtkey=" + DDTKEY + "&secretkey=" + SECRET_KEY; + String uri = url + "&mobile=" + mobiles + "&content=" + content; + // 构建JSON参数 + String param = String.format( + "{\"ddtkey\":\"%s\",\"secretkey\":\"%s\",\"mobile\":\"%s\",\"content\":\"%s\"}", + DDTKEY, SECRET_KEY, mobiles, content + ); + return convertToMessage(HttpRequestHelper.doPost(uri, param)); + } + + /** + * 将短信平台返回的错误码转换为中文说明 + * + * @param response 原始响应,如 "error,1001" 或 "ok,MSG123" + * @return 转换后的字符串,如 "error,用户名密码错误" 或 "ok,MSG123" + */ + public static String convertToMessage(String response) { + if (response == null || response.isEmpty()) { + return response; + } + // 只处理以 "error," 开头的响应 + if (response.startsWith("error,")) { + String[] parts = response.split(",", 2); + if (parts.length == 2) { + String code = parts[1].trim(); + String message = ERROR_CODE_TO_MESSAGE.get(code); + if (message != null) { + return "error," + message; + } + } + return response; + } + return response; + } + + +} diff --git a/bonus-business/src/main/java/com/bonus/job/util/SnowflakeIdGenerator.java b/bonus-business/src/main/java/com/bonus/job/util/SnowflakeIdGenerator.java new file mode 100644 index 0000000..24cc3b9 --- /dev/null +++ b/bonus-business/src/main/java/com/bonus/job/util/SnowflakeIdGenerator.java @@ -0,0 +1,88 @@ +package com.bonus.job.util; + +public class SnowflakeIdGenerator { + + // ================== 基础配置 ================== + private final long twepoch = 1704067200000L; // 起始时间戳(2024-01-01 00:00:00 UTC) + + private final long datacenterIdBits = 5L; + private final long workerIdBits = 5L; + private final long sequenceBits = 12L; + + private final long maxDatacenterId = ~(-1L << datacenterIdBits); // 31 + private final long maxWorkerId = ~(-1L << workerIdBits); // 31 + private final long maxSequence = ~(-1L << sequenceBits); // 4095 + + private final long workerIdShift = sequenceBits; + private final long datacenterIdShift = sequenceBits + workerIdBits; + private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; + + // ================== 实例变量 ================== + private final long datacenterId; + private final long workerId; + private long sequence = 0L; + private long lastTimestamp = -1L; + + // ================== 构造函数 ================== + public SnowflakeIdGenerator(long datacenterId, long workerId) { + if (datacenterId > maxDatacenterId || datacenterId < 0) { + throw new IllegalArgumentException("datacenterId 不能大于 " + maxDatacenterId + " 或小于 0"); + } + if (workerId > maxWorkerId || workerId < 0) { + throw new IllegalArgumentException("workerId 不能大于 " + maxWorkerId + " 或小于 0"); + } + this.datacenterId = datacenterId; + this.workerId = workerId; + } + + // ================== 核心方法 ================== + public synchronized long nextId() { + long timestamp = timeGen(); + + // 时钟回拨检查 + if (timestamp < lastTimestamp) { + throw new RuntimeException("时钟回拨,拒绝生成 ID:" + lastTimestamp + " -> " + timestamp); + } + + if (lastTimestamp == timestamp) { + // 同一毫秒内,序列号自增 + sequence = (sequence + 1) & maxSequence; + if (sequence == 0) { + // 序列号用完,等待下一毫秒 + timestamp = tilNextMillis(lastTimestamp); + } + } else { + // 新的一毫秒,序列号重置 + sequence = 0L; + } + + lastTimestamp = timestamp; + + return ((timestamp - twepoch) << timestampLeftShift) + | (datacenterId << datacenterIdShift) + | (workerId << workerIdShift) + | sequence; + } + + // ================== 工具方法 ================== + private long tilNextMillis(long lastTimestamp) { + long timestamp = timeGen(); + while (timestamp <= lastTimestamp) { + timestamp = timeGen(); + } + return timestamp; + } + + private long timeGen() { + return System.currentTimeMillis(); + } + + // ================== 测试 ================== + public static void main(String[] args) { + SnowflakeIdGenerator idGen = new SnowflakeIdGenerator(1, 1); + + for (int i = 0; i < 10; i++) { + System.out.println(idGen.nextId()); + } + } +} diff --git a/bonus-business/src/main/java/com/bonus/message/dao/WorkerVo.java b/bonus-business/src/main/java/com/bonus/message/dao/WorkerVo.java index c0c57c5..9c7373e 100644 --- a/bonus-business/src/main/java/com/bonus/message/dao/WorkerVo.java +++ b/bonus-business/src/main/java/com/bonus/message/dao/WorkerVo.java @@ -67,4 +67,19 @@ public class WorkerVo { */ private int groupId; + private Integer taskId; + /** + * 任务名称 + */ + private String taskName; + + private String sendContent; + + //任务记录 + private String batchNumber; + private Long loopId; + private String sendTime; + private String submitStatus; + private String sendStatus; + private String reason; } diff --git a/bonus-business/src/main/resources/mapper/job/PmTaskMapper.xml b/bonus-business/src/main/resources/mapper/job/PmTaskMapper.xml new file mode 100644 index 0000000..9839510 --- /dev/null +++ b/bonus-business/src/main/resources/mapper/job/PmTaskMapper.xml @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + insert into pm_task (task_name, remark, msg_type, send_content) + values (#{taskName}, #{remark},#{msgType},#{sendContent}) + + + + + + + + update pm_task + + + task_name = #{taskName}, + + + remark = #{remark}, + + + msg_type = #{msgType}, + + + send_content = #{sendContent}, + + + where id = #{id} + + + + update pm_task set is_active = 0 + where id = #{id} + + + + + + insert into bm_task_worker (task_id, worker_id) + values + + (#{item.taskId},#{item.id}) + + + + + delete from bm_task_worker where task_id = #{id} + + + + + update bm_task_record set send_status = #{item.sendStatus} where batch_number = #{item.batchNumber} and phone = #{item.phone} + + + + + + + + + + + update bm_task_record set batch_number= #{batchNumber},submit_status = #{submitStatus},reason = #{reason} where id = #{id} + + diff --git a/bonus-business/src/main/resources/mapper/job/SysJobMapper.xml b/bonus-business/src/main/resources/mapper/job/SysJobMapper.xml index 99a2f63..6d91c40 100644 --- a/bonus-business/src/main/resources/mapper/job/SysJobMapper.xml +++ b/bonus-business/src/main/resources/mapper/job/SysJobMapper.xml @@ -91,6 +91,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" status, remark, create_by, + relation_id, + relation_type, create_time )values( #{jobId}, @@ -103,6 +105,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{status}, #{remark}, #{createBy}, + #{relationId}, + #{relationType}, sysdate() ) diff --git a/bonus-business/src/main/resources/mapper/job/WorkerJobMapper.xml b/bonus-business/src/main/resources/mapper/job/WorkerJobMapper.xml new file mode 100644 index 0000000..f06ee94 --- /dev/null +++ b/bonus-business/src/main/resources/mapper/job/WorkerJobMapper.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + insert into bm_task_record (task_id, loop_id, worker_id, phone, batch_number, submit_status, send_time, reason) + values + + (#{item.taskId}, #{item.loopId}, #{item.id}, #{item.phone}, #{item.batchNumber}, #{item.submitStatus}, #{item.sendTime}, #{item.reason}) + + +