src/main/java/com/mzl/flower/constant/Constants.java
@@ -712,5 +712,48 @@ } } public enum SMS_RECEIVE_TYPE { IMPORT("导入接收文件"), INPUT("手动输入"), SELECT("点击选择用户列表"); SMS_RECEIVE_TYPE(String desc) { this.desc = desc; } private String desc; public String getDesc() { return desc; } } public enum SMS_TASK_STATUS { wait_publish("待发布"), in_execution("执行中"), complete("已完成"), failure("失败"); SMS_TASK_STATUS(String desc) { this.desc = desc; } private String desc; public String getDesc() { return desc; } } public enum SMS_SEND_RESULT { success("成功"), failure("失败"); SMS_SEND_RESULT(String desc) { this.desc = desc; } private String desc; public String getDesc() { return desc; } } } src/main/java/com/mzl/flower/dto/request/sms/SmsTaskDTO.java
@@ -8,11 +8,11 @@ @ApiModelProperty(value = "短信任务管理id") private Long id; @ApiModelProperty("短信模板ID") private Long smsTemplateId; @ApiModelProperty("名称") private String name; @ApiModelProperty("短信模板ID") private Long smsTemplateId; @ApiModelProperty("任务类型") private String type; @@ -23,7 +23,6 @@ @ApiModelProperty("手机号") private String phones; @ApiModelProperty("发送数量") private Long num; } src/main/java/com/mzl/flower/dto/request/sms/SmsTaskQueryDTO.java
@@ -1,37 +1,31 @@ package com.mzl.flower.dto.request.sms; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; import java.util.Date; import java.time.LocalDateTime; @Data public class SmsTaskQueryDTO { @ApiModelProperty(value = "短信任务管理id") private Long id; @ApiModelProperty("短信模板ID") private Long smsTemplateId; @ApiModelProperty("名称") @ApiModelProperty(value = "任务名称") private String name; @ApiModelProperty("任务类型") private String type; @ApiModelProperty("模板名称") private String smsTemplateName; @ApiModelProperty("导入文件路径") private String fileUrl; @ApiModelProperty("手机号") private String phones; @ApiModelProperty("发送数量") private Long num; @ApiModelProperty("任务状态") private String status; @ApiModelProperty(value = "开始时间") private Date startDate; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime startDate; @ApiModelProperty(value = "结束时间") private Date endDate; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime endDate; } src/main/java/com/mzl/flower/dto/request/sms/SmsTemplateQueryDTO.java
@@ -1,10 +1,11 @@ package com.mzl.flower.dto.request.sms; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDateTime; import java.util.Date; @Data public class SmsTemplateQueryDTO { @@ -21,8 +22,12 @@ private String description; @ApiModelProperty(value = "开始时间") private Date startDate; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime startDate; @ApiModelProperty(value = "结束时间") private Date endDate; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime endDate; } src/main/java/com/mzl/flower/dto/response/sms/SmsTaskVO.java
@@ -1,30 +1,36 @@ package com.mzl.flower.dto.response.sms; import com.mzl.flower.base.AbstractTransDTO; import com.mzl.flower.base.annotation.DictTrans; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.time.LocalDateTime; @Data public class SmsTaskVO extends AbstractTransDTO { @ApiModelProperty(value = "短信任务管理id") private Long id; @ApiModelProperty("短信模板ID") private Long smsTemplateId; @ApiModelProperty("名称") private String name; @ApiModelProperty("任务类型") private String type; @ApiModelProperty("短信模板ID") private Long smsTemplateId; @ApiModelProperty("导入文件路径") private String fileUrl; @ApiModelProperty("短信模板名称") private String smsTemplateName; @ApiModelProperty("手机号") private String phones; @ApiModelProperty("短信模板描述") private String smsTemplateDesc; @ApiModelProperty("发送数量") private Long num; @ApiModelProperty("任务状态") @DictTrans(target = "statusStr", codeType = "SMS_TASK_STATUS") private String status; private String statusStr; @ApiModelProperty("创建时间") private LocalDateTime createTime; } src/main/java/com/mzl/flower/dto/response/sms/SmsTemplateListVO.java
对比新文件 @@ -0,0 +1,14 @@ package com.mzl.flower.dto.response.sms; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data public class SmsTemplateListVO { @ApiModelProperty("ID") private Long id; @ApiModelProperty("名称") private String name; } src/main/java/com/mzl/flower/entity/SmsTaskDO.java
@@ -1,6 +1,7 @@ package com.mzl.flower.entity; import com.baomidou.mybatisplus.annotation.TableName; import com.mzl.flower.base.BaseAutoEntity; import com.mzl.flower.base.BaseEntity; import lombok.Data; import lombok.EqualsAndHashCode; @@ -14,7 +15,7 @@ @EqualsAndHashCode(callSuper = true) @Accessors(chain = true) @TableName("t_sms_task") public class SmsTaskDO extends BaseEntity { public class SmsTaskDO extends BaseAutoEntity { /** @@ -48,4 +49,10 @@ private Long num; /** * 任务状态 */ private String status; } src/main/java/com/mzl/flower/entity/SmsTaskDetailDO.java
@@ -1,6 +1,7 @@ package com.mzl.flower.entity; import com.baomidou.mybatisplus.annotation.TableName; import com.mzl.flower.base.BaseAutoEntity; import com.mzl.flower.base.BaseEntity; import lombok.Data; import lombok.EqualsAndHashCode; @@ -14,7 +15,7 @@ @EqualsAndHashCode(callSuper = true) @Accessors(chain = true) @TableName("t_sms_task_detail") public class SmsTaskDetailDO extends BaseEntity { public class SmsTaskDetailDO extends BaseAutoEntity { /** src/main/java/com/mzl/flower/entity/SmsTemplateDO.java
@@ -1,6 +1,7 @@ package com.mzl.flower.entity; import com.baomidou.mybatisplus.annotation.TableName; import com.mzl.flower.base.BaseAutoEntity; import com.mzl.flower.base.BaseEntity; import lombok.Data; import lombok.EqualsAndHashCode; @@ -14,7 +15,7 @@ @EqualsAndHashCode(callSuper = true) @Accessors(chain = true) @TableName("t_sms_template") public class SmsTemplateDO extends BaseEntity { public class SmsTemplateDO extends BaseAutoEntity { /** src/main/java/com/mzl/flower/mapper/SmsTemplateMapper.java
@@ -2,9 +2,11 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.mzl.flower.dto.request.sms.SmsTemplateQueryDTO; import com.mzl.flower.dto.response.sms.SmsTemplateListVO; import com.mzl.flower.entity.SmsTemplateDO; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import java.util.List; @@ -20,4 +22,11 @@ List<SmsTemplateDO> queryPage(@Param("dto") SmsTemplateQueryDTO dto, Page page); @Select("select id,name from t_sms_template where deleted = '0'") List<SmsTemplateListVO> getAllTemplateName(); @Select("select * from t_sms_template where deleted = '0' and name = #{name} limit 1") SmsTemplateDO selectTemplateByName(String name); } src/main/java/com/mzl/flower/service/impl/sms/SmsTaskServiceImpl.java
@@ -1,25 +1,50 @@ package com.mzl.flower.service.impl.sms; import com.aliyun.oss.ClientException; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.OSSException; import com.aliyun.oss.model.GetObjectRequest; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.mzl.flower.config.OssProperties; import com.mzl.flower.config.exception.ValidationException; import com.mzl.flower.config.security.SecurityUtils; import com.mzl.flower.constant.Constants; import com.mzl.flower.dto.request.sms.SmsTaskDTO; import com.mzl.flower.dto.request.sms.SmsTaskQueryDTO; import com.mzl.flower.dto.response.sms.SmsTaskVO; import com.mzl.flower.entity.SmsTaskDO; import com.mzl.flower.entity.SmsTaskDetailDO; import com.mzl.flower.entity.SmsTemplateDO; import com.mzl.flower.mapper.SmsTaskDetailMapper; import com.mzl.flower.mapper.SmsTaskMapper; import com.mzl.flower.mapper.SmsTemplateMapper; import com.mzl.flower.service.sms.SmsTaskDetailService; import com.mzl.flower.service.sms.SmsTaskService; import com.mzl.flower.utils.SmsUtil; import lombok.RequiredArgsConstructor; import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; /** * <p> * 服务实现类 * 服务实现类 * </p> * * @author @TaoJie @@ -29,20 +54,184 @@ @Transactional @RequiredArgsConstructor public class SmsTaskServiceImpl extends ServiceImpl<SmsTaskMapper, SmsTaskDO> implements SmsTaskService { private final OssProperties ossProperties; private final SmsTaskMapper smsTaskMapper; private final SmsTemplateMapper smsTemplateMapper; private final SmsTaskDetailMapper smsTaskDetailMapper; private final SmsTaskDetailService smsTaskDetailService; private static final Pattern PHONE_NUMBER_PATTERN = Pattern.compile("^1[3-9]\\d{9}$"); private static final String PHONE_REGEX = "^1[3-9]\\d{9}$"; public static boolean isValidPhoneNumber(String phoneNumber) { if (phoneNumber == null || phoneNumber.length() != 11) { return false; } Pattern pattern = Pattern.compile(PHONE_REGEX); Matcher matcher = pattern.matcher(phoneNumber); return matcher.matches(); } @Override public void saveSmsTask(SmsTaskDTO smsTaskDTO) { //校验 if (StringUtils.isEmpty(smsTaskDTO.getName())) { throw new ValidationException("短信名称不能为空"); } if (StringUtils.isEmpty(smsTaskDTO.getSmsTemplateId())) { throw new ValidationException("短信模板不能为空"); } if (StringUtils.isEmpty(smsTaskDTO.getType())) { throw new ValidationException("接收号码类型不能为空"); } if ((Constants.SMS_RECEIVE_TYPE.INPUT.name().equals(smsTaskDTO.getType()) || Constants.SMS_RECEIVE_TYPE.SELECT.name().equals(smsTaskDTO.getType())) && StringUtils.isEmpty(smsTaskDTO.getPhones())) { throw new ValidationException("手机号不能为空"); } if (Constants.SMS_RECEIVE_TYPE.IMPORT.name().equals(smsTaskDTO.getType()) && StringUtils.isEmpty(smsTaskDTO.getFileUrl())) { throw new ValidationException("导入文件不能为空"); } if (Constants.SMS_RECEIVE_TYPE.INPUT.name().equals(smsTaskDTO.getType()) || Constants.SMS_RECEIVE_TYPE.SELECT.name().equals(smsTaskDTO.getType())) { //解析手机号,包含不同平台的换行符 String text = smsTaskDTO.getPhones(); // 使用正则表达式匹配所有类型的换行符 String[] lines = text.split("\\r?\\n|\\r"); // 将数组转换为 List List<String> lineList = Arrays.asList(lines); lineList.forEach(l -> { boolean validPhoneNumber = isValidPhoneNumber(l); if (!validPhoneNumber) { throw new ValidationException(l + "不是合法的手机号"); } }); smsTaskDTO.setNum((long) lineList.size()); } if (Constants.SMS_RECEIVE_TYPE.IMPORT.name().equals(smsTaskDTO.getType())) { dealImportExcel(smsTaskDTO); } SmsTaskDO smsTaskDO = new SmsTaskDO(); BeanUtils.copyProperties(smsTaskDTO, smsTaskDO); smsTaskDO.setStatus(Constants.SMS_TASK_STATUS.wait_publish.name()); smsTaskDO.setPhones(smsTaskDTO.getPhones()); smsTaskDO.create(SecurityUtils.getUserId()); smsTaskMapper.insert(smsTaskDO); } private void dealImportExcel(SmsTaskDTO smsTaskDTO) { String endPoint = ossProperties.getEndpoint(); String accessKeyId = ossProperties.getKeyid(); String accessKeySecret = ossProperties.getKeysecret(); String bucketName = ossProperties.getBucketname(); OSS ossClient = new OSSClientBuilder().build(endPoint, accessKeyId, accessKeySecret); try { // 下载Excel文件到本地临时文件 File tempFile = File.createTempFile("temp", ".xlsx"); ossClient.getObject(new GetObjectRequest(bucketName, smsTaskDTO.getFileUrl()), tempFile); // 解析Excel文件 try (FileInputStream inputStream = new FileInputStream(tempFile); Workbook workbook = new XSSFWorkbook(inputStream)) { Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表 int rowCount = sheet.getPhysicalNumberOfRows(); if (rowCount > 101) { throw new ValidationException("一次导入手机号最多100行"); } boolean isValid = true; StringBuffer message = new StringBuffer(); StringBuffer phones = new StringBuffer(); for (int i = 1; i < rowCount; i++) { // 跳过标题行,从第二行开始 Row row = sheet.getRow(i); if (row != null) { Cell cell = row.getCell(0); // 假设手机号在第一列 if (cell != null && cell.getCellType() == CellType.STRING) { String phoneNumber = cell.getStringCellValue(); if (!PHONE_NUMBER_PATTERN.matcher(phoneNumber).matches()) { message.append("第" + (i + 1) + "行手机号" + phoneNumber + "格式不正确"); isValid = false; break; // 退出循环 } else { phones.append(phoneNumber).append("\n"); } } else { message.append("行上的单元格为空或无效 " + (i + 1)); isValid = false; break; // 退出循环 } } else { message.append("空行 " + (i + 1)); isValid = false; break; // 退出循环 } } if (!isValid) { throw new ValidationException(message.toString()); } else { smsTaskDTO.setPhones(phones.toString()); smsTaskDTO.setNum((long) rowCount); } } catch (IOException e) { e.printStackTrace(); } finally { // 删除临时文件 if (tempFile.exists()) { tempFile.delete(); } } } catch (OSSException | ClientException | IOException e) { e.printStackTrace(); } finally { ossClient.shutdown(); } } @Override public void updateSmsTask(SmsTaskDTO smsTaskDTO) { SmsTaskDO smsTaskDO = smsTaskMapper.selectById(smsTaskDTO.getId()); if (!smsTaskDO.getStatus().equals(Constants.SMS_TASK_STATUS.wait_publish.name())) { throw new ValidationException("非待发布的任务不可编辑"); } if (StringUtils.isEmpty(smsTaskDTO.getName())) { throw new ValidationException("短信名称不能为空"); } if (StringUtils.isEmpty(smsTaskDTO.getSmsTemplateId())) { throw new ValidationException("短信模板不能为空"); } if (StringUtils.isEmpty(smsTaskDTO.getType())) { throw new ValidationException("接收号码类型不能为空"); } if ((Constants.SMS_RECEIVE_TYPE.INPUT.name().equals(smsTaskDTO.getType()) || Constants.SMS_RECEIVE_TYPE.SELECT.name().equals(smsTaskDTO.getType())) && StringUtils.isEmpty(smsTaskDTO.getPhones())) { throw new ValidationException("手机号不能为空"); } if (Constants.SMS_RECEIVE_TYPE.IMPORT.name().equals(smsTaskDTO.getType()) && StringUtils.isEmpty(smsTaskDTO.getFileUrl())) { throw new ValidationException("导入文件不能为空"); } if(!smsTaskDTO.getFileUrl().equals(smsTaskDO.getFileUrl())){ dealImportExcel(smsTaskDTO); } BeanUtils.copyProperties(smsTaskDTO, smsTaskDO); smsTaskDO.update(SecurityUtils.getUserId()); smsTaskDO.setPhones(smsTaskDTO.getPhones()); smsTaskMapper.updateById(smsTaskDO); } @@ -51,6 +240,9 @@ SmsTaskDO smsTaskDO = smsTaskMapper.selectById(id); if (smsTaskDO == null) { throw new ValidationException("短信任务ID不存在"); } if(!smsTaskDO.getStatus().equals(Constants.SMS_TASK_STATUS.wait_publish.name())){ throw new ValidationException("非待发布的任务不可删除"); } smsTaskMapper.deleteById(id); } @@ -61,4 +253,60 @@ page.setRecords(list); return page; } @Override public void publishSmsTask(SmsTaskDTO smsTaskDTO) { if (StringUtils.isEmpty(smsTaskDTO.getId())) { throw new ValidationException("任务ID不能为空"); } SmsTaskDO smsTaskDO = smsTaskMapper.selectById(smsTaskDTO.getId()); if(StringUtils.isEmpty(smsTaskDO.getPhones())){ throw new ValidationException("任务手机号不能为空"); } //解析手机号,包含不同平台的换行符 String text = smsTaskDO.getPhones(); // 使用正则表达式匹配所有类型的换行符 String[] lines = text.split("\\r?\\n|\\r"); // 将数组转换为 List List<String> lineList = Arrays.asList(lines); List<SmsTaskDetailDO> smsTaskDetailDOList = createSmsTaskDetails(smsTaskDO, lineList); smsTaskDO.setStatus(Constants.SMS_TASK_STATUS.in_execution.name()); smsTaskDO.update(SecurityUtils.getUserId()); smsTaskMapper.updateById(smsTaskDO); // 异步保存任务明细信息并发送短信 CompletableFuture.runAsync(() -> { smsTaskDetailService.saveBatch(smsTaskDetailDOList); sendSmsToAll(smsTaskDetailDOList, smsTaskDO.getSmsTemplateId()); }); } private List<SmsTaskDetailDO> createSmsTaskDetails(SmsTaskDO smsTaskDO, List<String> phoneNumbers) { return phoneNumbers.stream().map(phone -> { SmsTaskDetailDO detail = new SmsTaskDetailDO(); detail.setSmsTaskId(smsTaskDO.getId()); detail.setSmsTemplateId(smsTaskDO.getSmsTemplateId()); detail.setPhone(phone); return detail; }).collect(Collectors.toList()); } private void sendSmsToAll(List<SmsTaskDetailDO> smsTaskDetailDOList, Long smsTemplateId) { SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectById(smsTemplateId); String templateCode = smsTemplateDO.getCode(); for (SmsTaskDetailDO detail : smsTaskDetailDOList) { try { SmsUtil.sendSms(detail.getPhone(), templateCode, null); detail.setResult(Constants.SMS_SEND_RESULT.success.name()); } catch (Exception e) { detail.setResult(Constants.SMS_SEND_RESULT.failure.name()); System.err.println("Failed to send SMS to " + detail.getPhone() + ": " + e.getMessage()); } finally { //无论如何都更新结果 smsTaskDetailMapper.updateById(detail); } } } } src/main/java/com/mzl/flower/service/impl/sms/SmsTemplateServiceImpl.java
@@ -1,21 +1,20 @@ package com.mzl.flower.service.impl.sms; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.mzl.flower.config.exception.ValidationException; import com.mzl.flower.config.security.SecurityUtils; import com.mzl.flower.dto.request.sms.SmsTemplateDTO; import com.mzl.flower.dto.request.sms.SmsTemplateQueryDTO; import com.mzl.flower.dto.response.member.MemberVO; import com.mzl.flower.dto.response.sms.SmsTemplateListVO; import com.mzl.flower.entity.SmsTemplateDO; import com.mzl.flower.entity.menber.Member; import com.mzl.flower.entity.menber.MemberGrowthRecord; import com.mzl.flower.mapper.SmsTemplateMapper; import com.mzl.flower.service.sms.SmsTemplateService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.RequiredArgsConstructor; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.ObjectUtils; import java.util.List; @@ -35,14 +34,25 @@ private final SmsTemplateMapper smsTemplateMapper; @Override public void saveSmsTemplate(SmsTemplateDTO smsTemplateDTO) { SmsTemplateDO smsTemplateTemp = smsTemplateMapper.selectTemplateByName(smsTemplateDTO.getName()); if(!ObjectUtils.isEmpty(smsTemplateTemp)){ throw new ValidationException("短信模板名称已存在"); } SmsTemplateDO smsTemplateDO = new SmsTemplateDO(); BeanUtils.copyProperties(smsTemplateDTO, smsTemplateDO); smsTemplateDO.create(SecurityUtils.getUserId()); smsTemplateMapper.insert(smsTemplateDO); } @Override public void updateSmsTemplate(SmsTemplateDTO smsTemplateDTO) { SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectById(smsTemplateDTO.getId()); if (!smsTemplateDTO.getName().equals(smsTemplateDO.getName())) { SmsTemplateDO smsTemplateTemp = smsTemplateMapper.selectTemplateByName(smsTemplateDTO.getName()); if (!ObjectUtils.isEmpty(smsTemplateTemp)) { throw new ValidationException("短信模板名称已存在"); } } BeanUtils.copyProperties(smsTemplateDTO, smsTemplateDO); smsTemplateDO.update(SecurityUtils.getUserId()); smsTemplateMapper.updateById(smsTemplateDO); @@ -63,4 +73,9 @@ page.setRecords(list); return page; } @Override public List<SmsTemplateListVO> getAllTemplateName() { return smsTemplateMapper.getAllTemplateName(); } } src/main/java/com/mzl/flower/service/sms/SmsTaskService.java
@@ -25,4 +25,6 @@ Page<SmsTaskVO> queryPage(SmsTaskQueryDTO dto, Page page); void publishSmsTask(SmsTaskDTO smsTaskDTO); } src/main/java/com/mzl/flower/service/sms/SmsTemplateService.java
@@ -4,8 +4,11 @@ import com.mzl.flower.dto.request.sms.SmsTemplateDTO; import com.mzl.flower.dto.request.sms.SmsTemplateQueryDTO; import com.mzl.flower.dto.response.member.MemberVO; import com.mzl.flower.dto.response.sms.SmsTemplateListVO; import com.mzl.flower.entity.SmsTemplateDO; import com.baomidou.mybatisplus.extension.service.IService; import java.util.List; /** * <p> @@ -25,4 +28,7 @@ void deleteSmsTemplate(Long id); Page<SmsTemplateDO> queryPage(SmsTemplateQueryDTO dto, Page page); List<SmsTemplateListVO> getAllTemplateName(); } src/main/java/com/mzl/flower/web/v2/sms/SmsTaskController.java
@@ -1,29 +1,19 @@ package com.mzl.flower.web.v2.sms; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.mzl.flower.base.BaseController; import com.mzl.flower.base.R; import com.mzl.flower.base.ReturnDataDTO; import com.mzl.flower.dto.request.sms.SmsTaskDTO; import com.mzl.flower.dto.request.sms.SmsTaskQueryDTO; import com.mzl.flower.dto.request.sms.SmsTemplateDTO; import com.mzl.flower.dto.request.sms.SmsTemplateQueryDTO; import com.mzl.flower.dto.response.sms.SmsTaskVO; import com.mzl.flower.entity.SmsTemplateDO; import com.mzl.flower.service.sms.SmsTaskService; import com.mzl.flower.service.sms.SmsTemplateService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import com.mzl.flower.entity.SmsTaskDO; import javax.validation.constraints.Min; import javax.validation.constraints.Max; import javax.validation.constraints.NotNull; import javax.validation.constraints.Positive; /** * @author @TaoJie @@ -36,32 +26,40 @@ public class SmsTaskController extends BaseController { private final SmsTaskService smsTaskService; @PostMapping("/new") @ApiOperation(value = "保存短信任务模板", httpMethod = "POST") @ApiOperation(value = "保存短信任务", httpMethod = "POST") public ResponseEntity<ReturnDataDTO> create(@RequestBody SmsTaskDTO smsTaskDTO) { smsTaskService.saveSmsTask(smsTaskDTO); return returnData(R.SUCCESS.getCode(), null); } @PostMapping(value = "/edit") @ApiOperation(value = "更新短信任务模板", httpMethod = "POST") @ApiOperation(value = "更新短信任务", httpMethod = "POST") public ResponseEntity<ReturnDataDTO> update(@RequestBody SmsTaskDTO smsTaskDTO) { smsTaskService.updateSmsTask(smsTaskDTO); return returnData(R.SUCCESS.getCode(), null); } @GetMapping(value = "/delete") @ApiOperation(value = "删除短信任务模板 ", httpMethod = "GET", notes = "ID") @ApiOperation(value = "删除短信任务 ", httpMethod = "GET", notes = "ID") public ResponseEntity<ReturnDataDTO> delete(@NotNull(message = "id不能为空") Long id) { smsTaskService.deleteSmsTask(id); return returnData(R.SUCCESS.getCode(), null); } @GetMapping("/list") @ApiOperation(value = "短信模板任务列表", httpMethod = "GET") @ApiOperation(value = "短信任务列表", httpMethod = "GET") public ResponseEntity<ReturnDataDTO<Page<SmsTaskVO>>> getSmsTaskList(Page page, SmsTaskQueryDTO dto) { return returnData(R.SUCCESS.getCode(), smsTaskService.queryPage(dto, page)); } @PostMapping("/publish") @ApiOperation(value = "发布短信任务", httpMethod = "POST") public ResponseEntity<ReturnDataDTO> publish(@RequestBody SmsTaskDTO smsTaskDTO) { smsTaskService.publishSmsTask(smsTaskDTO); return returnData(R.SUCCESS.getCode(), null); } } src/main/java/com/mzl/flower/web/v2/sms/SmsTemplateController.java
@@ -13,6 +13,7 @@ import com.mzl.flower.base.ReturnDataDTO; import com.mzl.flower.dto.request.sms.SmsTemplateDTO; import com.mzl.flower.dto.request.sms.SmsTemplateQueryDTO; import com.mzl.flower.dto.response.sms.SmsTemplateListVO; import com.mzl.flower.entity.SmsTemplateDO; import com.mzl.flower.service.sms.SmsTemplateService; import io.swagger.annotations.Api; @@ -25,16 +26,16 @@ import java.util.List; /** * @author @TaoJie * @since 2024-12-25 */ * @author @TaoJie * @since 2024-12-25 */ @Api(value = "短信模板管理", tags = "短信模板管理") @RestController @RequestMapping("/v2/sms-template") @RequiredArgsConstructor public class SmsTemplateController extends BaseController { private final SmsTemplateService smsTemplateService; private final SmsTemplateService smsTemplateService; @PostMapping("/new") @ApiOperation(value = "保存短信模板", httpMethod = "POST") @@ -87,4 +88,11 @@ return new Client(config); } @GetMapping("/templateName/all") @ApiOperation(value = "短信模板下拉列表", httpMethod = "GET") public ResponseEntity<ReturnDataDTO> getSmsTemplateNameList() { List<SmsTemplateListVO> allTemplateName = smsTemplateService.getAllTemplateName(); return returnData(R.SUCCESS.getCode(), allTemplateName); } } src/main/resources/mapper/sms/SmsTaskMapper.xml
@@ -4,19 +4,20 @@ <select id="queryPage" resultType="com.mzl.flower.dto.response.sms.SmsTaskVO"> select t.* from t_sms_task t SELECT t.* ,st.`name` as sms_template_name,st.description as sms_template_desc FROM t_sms_task t LEFT JOIN t_sms_template st ON t.sms_template_id = st.id where t.deleted= 0 <if test="dto.id!=null "> and t.id = #{dto.id} </if> <if test="dto.code != null and dto.code != ''"> and t.code like concat('%', #{dto.code}, '%') </if> <if test="dto.name != null and dto.name != ''"> and t.name like concat('%', #{dto.name}, '%') </if> <if test="dto.description != null and dto.description != ''"> and t.description like concat('%', #{dto.description}, '%') <if test="dto.smsTemplateName != null and dto.smsTemplateName != ''"> and st.name like concat('%', #{dto.smsTemplateName}, '%') </if> <if test="dto.status != null and dto.status != ''"> and t.status = #{dto.status} </if> <if test="dto.startDate!=null "> <![CDATA[