lin
2024-04-03 60074b98b4d4e914c30436299a46736602056d18
居住证短信通知
3 files modified
220 ■■■■■ changed files
src/main/java/org/springblade/modules/sms/controller/SmsSendController.java 24 ●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/sms/service/ISmsSendService.java 8 ●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/sms/service/impl/SmsSendServiceImpl.java 188 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/sms/controller/SmsSendController.java
@@ -16,25 +16,15 @@
 */
package org.springblade.modules.sms.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.sms.entity.SmsTemplateEntity;
import org.springblade.modules.sms.service.ISmsSendService;
import org.springblade.modules.sms.service.ISmsTemplateService;
import org.springblade.modules.sms.vo.SmsTemplateVO;
import org.springblade.modules.sms.wrapper.SmsTemplateWrapper;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
/**
 * 短信模版表 控制器
@@ -57,7 +47,19 @@
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "发送短信验证码")
    public R<SmsTemplateVO> detail(@RequestParam String phone) {
        Boolean aBoolean = iSmsSendService.smsSend(phone);
        Boolean aBoolean = iSmsSendService.sendVerificationCode(phone);
        return R.status(aBoolean);
    }
    /**
     * 发送居住申请通知
     */
    @GetMapping("/sendNotice")
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "发送居住申请通知")
    public R<SmsTemplateVO> sendNotice(@RequestParam("templateId") Long templateId,
                                       @RequestParam(value = "residenceId",required = false) Long residenceId) {
        Boolean aBoolean = iSmsSendService.sendNotice(templateId,residenceId);
        return R.status(aBoolean);
    }
src/main/java/org/springblade/modules/sms/service/ISmsSendService.java
@@ -16,13 +16,8 @@
 */
package org.springblade.modules.sms.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springblade.modules.sms.dto.SmsTemplateDTO;
import org.springblade.modules.sms.entity.SmsTemplateEntity;
import org.springblade.modules.sms.vo.SmsTemplateVO;
import java.util.List;
/**
 * 短信模版表 服务类
@@ -37,7 +32,8 @@
     *
     * @return
     */
    Boolean smsSend(String phone);
    Boolean sendVerificationCode(String phone);
    Boolean sendNotice(Long templateId,Long residenceId);
}
src/main/java/org/springblade/modules/sms/service/impl/SmsSendServiceImpl.java
@@ -20,9 +20,9 @@
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springblade.common.config.SmsConfig;
import org.springblade.common.utils.HttpClientUtils;
import org.springblade.common.utils.SpringUtils;
import org.springblade.common.utils.UtilRandom;
@@ -37,14 +37,17 @@
import org.springblade.modules.sms.service.ISmsTemplateService;
import org.springblade.modules.smsRecord.entity.SmsRecordEntity;
import org.springblade.modules.smsRecord.service.ISmsRecordService;
import org.springblade.modules.task.entity.TaskResidencePermitApplyEntity;
import org.springblade.modules.task.service.ITaskResidencePermitApplyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
 * 短信模版表 服务实现类
@@ -62,7 +65,7 @@
    public static final String SMS_VALIDATE_PHONE_NUM = "sms:validate:phone:";
    private static final String SMS_SEND_FAILED = "短信发送失败!";
    private static final String MESSAGE_SOP_EQUALS_MES_RESPONSE_CODE = "message_sop_equalsMes_response";
    private static final String SEND_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    private static final DateTimeFormatter SECOND_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    @Autowired
@@ -72,7 +75,7 @@
    private ISmsTemplateService iSmsTemplateService;
    @Override
    public Boolean smsSend(String phone) {
    public Boolean sendVerificationCode(String phone) {
        if (phone == null || phone.length() != 11) {
            logger.error("手机号格式错误");
            return false;
@@ -92,86 +95,163 @@
        //发送的手机号
        List<Map> phonesList = new ArrayList<>();
        Map phoneMap = new HashMap();
        phoneMap.put("phone", phone);
        List<String> varList = new ArrayList<>();
        Integer code = UtilRandom.randomCount(111111, 999999);
        varList.add(code.toString());
        phoneMap.put("varList", varList);
        phonesList.add(phoneMap);
        //短信主题
        String subject = "对外接口不同内容发送-动态模板";
        //短信内容
        String content = smsTemplateEntity.getContent();
        //短信模板
        String template_id = null;
        //发送时间
        SimpleDateFormat df = new SimpleDateFormat(SEND_TIME_FORMAT);
        String send_time = df.format(new Date());
        //优先级,高级=5,中级=3,低级=1
        String priority = "1";
        //不同内容发送类型,1=动态模板发送,2=文件内容发送
        String type = "1";
        LocalDateTime nowDateTime = LocalDateTime.now();
        String send_time = nowDateTime.format(SECOND_FORMATTER);
        Map params = new HashMap();
        params.put("phones", phonesList);
        params.put("subject", subject);
        //短信主题
        params.put("subject", "对外接口不同内容发送-动态模板");
        params.put("content", content);
        params.put("template_id", template_id);
        //短信模板
        params.put("template_id", null);
        // 发送时间
        params.put("send_time", send_time);
        params.put("priority", priority);
        params.put("type", type);
        //优先级,高级=5,中级=3,低级=1
        params.put("priority", "1");
        //不同内容发送类型,1=动态模板发送,2=文件内容发送
        params.put("type", "1");
        //创建人主键
        params.put("sop_create_by", serviceOne.getSmsCode());
        String result = null;
        //短信发送记录
        saveSmsRecord(phone, serviceOne, code.toString(), content);
        Boolean aBoolean = sendSmsGet(serviceOne, params);
        if (aBoolean) {
            // 将验证码存入redis,其中phone为手机号,code为验证码
            // SMS_VALIDATE_PHONE 为前缀,通过phone和code在redis中设置一个过期的键值对
            redisTemplate.setEx(SMS_VALIDATE_PHONE + phone, code, 300L);
            // 同时,为了记录该手机短时间内已接收的验证码次数,使用另一个键值对进行计数
            // SMS_VALIDATE_PHONE_NUM 为计数器的前缀,过期时间为60秒
            redisTemplate.setEx(SMS_VALIDATE_PHONE_NUM + phone, 1, 60L);
        }
        return aBoolean;
    }
    /**
     *
     * @param templateId
     * @param residenceId
     * @return
     */
    @Override
    public Boolean sendNotice( Long templateId, Long residenceId) {
        Sms serviceOne = iSmsService.getOne(Wrappers.<Sms>lambdaQuery().eq(Sms::getStatus, 2));
        if (serviceOne == null) {
            logger.error("未找到状态为2的Sms服务");
            return false;
        }
        SmsTemplateEntity smsTemplateEntity = iSmsTemplateService.getOne(Wrappers.<SmsTemplateEntity>lambdaQuery()
            .eq(SmsTemplateEntity::getId, templateId));
        if (smsTemplateEntity == null) {
            logger.error("未找到对应的短信模板");
            return false;
        }
        ITaskResidencePermitApplyService bean = SpringUtils.getBean(ITaskResidencePermitApplyService.class);
        TaskResidencePermitApplyEntity residencePermitApplyEntity = bean.getById(residenceId);
        String phone = residencePermitApplyEntity.getPhone();
        //发送的手机号
        List<Map> phonesList = new ArrayList<>();
        Map phoneMap = new HashMap();
        phoneMap.put("phone", phone);
        List<String> varList = new ArrayList<>();
        // 设置参数
        varList.add(residencePermitApplyEntity.getName());
        phoneMap.put("varList", varList);
        phonesList.add(phoneMap);
        //短信内容
        String content = smsTemplateEntity.getContent();
        //发送时间
        LocalDateTime nowDateTime = LocalDateTime.now();
        String send_time = nowDateTime.format(SECOND_FORMATTER);
        Map params = new HashMap();
        params.put("phones", phonesList);
        //短信主题
        params.put("subject", "对外接口不同内容发送-动态模板");
        params.put("content", content);
        //短信模板
        params.put("template_id", null);
        // 发送时间
        params.put("send_time", send_time);
        //优先级,高级=5,中级=3,低级=1
        params.put("priority", "1");
        //不同内容发送类型,1=动态模板发送,2=文件内容发送
        params.put("type", "1");
        //创建人主键
        params.put("sop_create_by", serviceOne.getSmsCode());
        //短信发送记录
        saveSmsRecord(phone, serviceOne, residencePermitApplyEntity.getName(), content);
        Boolean aBoolean = sendSmsGet(serviceOne, params);
        return aBoolean;
    }
    /**
     * 发送短信并获取发送结果。
     *
     * @param serviceOne 用于发送短信的服务对象
     * @param params     发送短信所需的参数映射
     * @return 如果短信发送成功,则返回true;否则返回false。
     */
    @NotNull
    private Boolean sendSmsGet(Sms serviceOne, Map params) {
        try {
            //短信发送记录
            saveSmsRecord(phone, serviceOne, code, content);
            result = testGet(params, "message.sop.differentMes", serviceOne);
            // 尝试发送短信并解析响应结果
            String result = sendSms(params, "message.sop.differentMes", serviceOne);
            JSONObject jsonObject = JSON.parseObject(result);
            JSONObject messageSopEqualsMesResponse = (JSONObject) jsonObject.get(MESSAGE_SOP_EQUALS_MES_RESPONSE_CODE);
            if (messageSopEqualsMesResponse.get("code").equals(200)) {
                // 将验证码存入redis
                redisTemplate.setEx(SMS_VALIDATE_PHONE + phone, code, 300L);
                redisTemplate.setEx(SMS_VALIDATE_PHONE_NUM + phone, 1, 60L);
                // 如果响应代码为200,表示短信发送成功
                return true;
            } else {
                // 记录短信发送失败的日志
                logger.error("短信发送失败!");
            }
        } catch (Exception e) {
            // 记录发送短信过程中出现的异常
            logger.error(SMS_SEND_FAILED, e);
            throw new RuntimeException(e);
        }
        // 如果执行到这里,表示短信发送失败或出现异常
        return false;
    }
    /**
     * 保存短信发送记录
     *
     * @param phone 接收短信的手机号码
     * @param phone      接收短信的手机号码
     * @param serviceOne 发送短信所使用的服务
     * @param code 短信中的验证码
     * @param content 短信内容,其中可能包含占位符"#P_1#"用于被验证码替换
     * @param code       短信中的验证码
     * @param content    短信内容,其中可能包含占位符"#P_1#"用于被验证码替换
     */
    private static void saveSmsRecord(String phone, Sms serviceOne, Integer code, String content) {
        // 通过Spring工具类获取短信记录服务的实例
        ISmsRecordService smsRecordService = SpringUtils.getBean(ISmsRecordService.class);
        // 创建一个新的短信记录实体
        SmsRecordEntity smsRecordEntity = new SmsRecordEntity();
        // 设置短信内容,将占位符"#P_1#"替换为验证码
        smsRecordEntity.setContent(content.replace("#P_1#", code.toString()));
        // 设置手机号码
        smsRecordEntity.setPhone(phone);
        // 设置短信模板ID
        smsRecordEntity.setTemplateId(Long.valueOf(serviceOne.getTemplateId()));
        // 设置创建用户ID,来自认证工具类
        smsRecordEntity.setCreateUser(AuthUtil.getUserId());
        // 保存短信记录实体
        smsRecordService.save(smsRecordEntity);
    private static void saveSmsRecord(String phone, Sms serviceOne, String code, String content) {
        // 通过Spring工具类获取短信记录服务的实例
        ISmsRecordService smsRecordService = SpringUtils.getBean(ISmsRecordService.class);
        // 创建一个新的短信记录实体
        SmsRecordEntity smsRecordEntity = new SmsRecordEntity();
        // 设置短信内容,将占位符"#P_1#"替换为验证码
        smsRecordEntity.setContent(content.replace("#P_1#", code));
        // 设置手机号码
        smsRecordEntity.setPhone(phone);
        // 设置短信模板ID
        smsRecordEntity.setTemplateId(Long.valueOf(serviceOne.getTemplateId()));
        // 设置创建用户ID,来自认证工具类
        smsRecordEntity.setCreateUser(AuthUtil.getUserId());
        // 保存短信记录实体
        smsRecordService.save(smsRecordEntity);
    }
    public String testGet(Object bizContent, String method, Sms serviceOne) throws Exception {
    public String sendSms(Object bizContent, String method, Sms serviceOne) throws Exception {
        // 公共请求参数
        Map<String, String> params = new HashMap<String, String>();
@@ -188,17 +268,9 @@
        String content = AlipaySignature.getSignContent(params);
        String sign = AlipaySignature.rsa256Sign(content, serviceOne.getSecretKey(), "utf-8");
        params.put("sign", sign);
        System.out.println("----------- 请求信息 -----------");
        System.out.println("请求参数:" + buildParamQuery(params));
        System.out.println("商户秘钥:" + serviceOne.getSecretKey());
        System.out.println("待签名内容:" + content);
        System.out.println("签名(sign):" + sign);
        System.out.println("URL参数:" + buildUrlQuery(params));
        System.out.println("----------- 返回结果 -----------");
        logger.info("短信请求参数:" + buildParamQuery(params));
        String responseData = HttpClientUtils.doGet(serviceOne.getRemark(), params);// 发送请求
        System.out.println("返回数据" + responseData);
        logger.info("短信响应结果:" + responseData);
        return responseData;
    }