sl-express/sl-express-ms-sms-service/README.md

6.6 KiB
Raw Blame History

sl-express-ms-sms-service使用手册

1、说明

为了将短信相关的代码进行统一所以将发送短信的代码抽取到sl-express-ms-sms-service

主要功能:

  • 发送短信包含文字短信、语音短信,现在第三方短信通道还没有对接
  • 可以配置多个第三方短信通过实现动态切换
  • 一条短信同时可以多条发送

2、SQL脚本

CREATE TABLE `sl_sms_record` (
  `id` bigint NOT NULL COMMENT '短信发送记录id',
  `send_channel_id` bigint NOT NULL COMMENT '发送通道id对应sl_sms_third_channel的主键',
  `batch_id` bigint NOT NULL COMMENT '发送批次id用于判断这些数据是同一批次发送的',
  `app_name` varchar(100) COLLATE utf8mb4_general_ci NOT NULL COMMENT '发起发送请求的微服务名称sl-express-ms-work',
  `mobile` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '手机号',
  `sms_content` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '短信内容一般为json格式的参数数据用于填充短信模板中的占位符参数',
  `status` int NOT NULL COMMENT '发送状态1成功2失败',
  `created` datetime NOT NULL COMMENT '创建时间',
  `updated` datetime NOT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `created` (`created`) USING BTREE,
  KEY `batch_id` (`batch_id`) USING BTREE,
  KEY `mobile` (`mobile`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='短信发送记录';



CREATE TABLE `sl_sms_third_channel` (
  `id` bigint NOT NULL COMMENT '主键id',
  `sms_type` int NOT NULL COMMENT '短信类型1验证类型短信2通知类型短信',
  `content_type` int NOT NULL COMMENT '内容类型1:文字短信2语音短信',
  `sms_code` int NOT NULL COMMENT '短信code短信微服务发放的code与sms_code是一对多的关系',
  `template_code` varchar(50) COLLATE utf8mb4_general_ci NOT NULL COMMENT '第三方平台模板code',
  `send_channel` int NOT NULL COMMENT '第三方短信平台码',
  `sign_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '签名',
  `sms_priority` int NOT NULL COMMENT '数字越大优先级越高',
  `account` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '三方平台对应的账户信息accessKeyId、accessKeySecret等以json格式存储使用时自行解析',
  `status` int NOT NULL COMMENT '通道状态1使用 中2已经停用',
  `created` datetime NOT NULL COMMENT '创建时间',
  `updated` datetime NOT NULL COMMENT '更新时间',
  `is_delete` bit(1) NOT NULL COMMENT '是否删除',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `created` (`created`) USING BTREE,
  KEY `sms_priority` (`sms_priority`),
  KEY `index_type` (`sms_type`,`content_type`,`sms_code`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='短信发送通道';

3、使用

短信中心使用方法见 sl-express-ms-sms-api项目中的README.md

4.配置

4.1、通道配置(表字段介绍)

表sl_sms_third_channel
通道信息:
sms_type短信类型1验证类型短信2通知类型短信
content_type内容类型1:文字短信2语音短信
sms_code短信code短信微服务发放的code与sms_code是一对多的关系
template_code 第三方平台模板code
send_channel 第三方短信平台码
sign_name 签名,短信中的签名 
sms_priority 数字越大优先级越高
account 三方平台对应的账户信息accessKeyId、accessKeySecret等以json格式存储使用时自行解析

4.2、路由规则

路由规则现在只有一个: 根据短信类型、内容类型、短信code、状态使用中作为查询条件通过权重排序取优先级前五的通道然后从这些通道中随机选择一条通道。 路由规则后续可以进行拓展。代码展示

    /**
     * 目前只根据优先级进行路由选出前五,然后随机选择渠道
     *
     * @param smsTypeEnum        短信类型
     * @param smsContentTypeEnum 内容类型
     * @param smsCode            短信code短信微服务发放的code与sms_code是一对多的关系
     * @return 选中的发送通道信息
     */
    @Override
    public SmsThirdChannelEntity route(SmsTypeEnum smsTypeEnum, SmsContentTypeEnum smsContentTypeEnum, String smsCode) {

        //取前五条记录
        LambdaQueryWrapper<SmsThirdChannelEntity> queryWrapper = Wrappers.<SmsThirdChannelEntity>lambdaQuery()
                .eq(SmsThirdChannelEntity::getSmsType, smsTypeEnum)
                .eq(SmsThirdChannelEntity::getContentType, smsContentTypeEnum)
                .eq(SmsThirdChannelEntity::getSmsCode, smsCode)
                .eq(SmsThirdChannelEntity::getStatus, 1) //使用中的状态
                .orderByDesc(SmsThirdChannelEntity::getSmsPriority).last("LIMIT 5");

        //查询数据
        List<SmsThirdChannelEntity> smsThirdChannelEntities = super.list(queryWrapper);
        if (CollUtil.isEmpty(smsThirdChannelEntities)) {
            return null;
        }

        //随机选择
        int index = RandomUtil.randomInt(0, CollUtil.size(smsThirdChannelEntities));
        return CollUtil.get(smsThirdChannelEntities, index);
    }

4.3、第三方通道对接

例如

package com.sl.ms.sms.handler;

import cn.hutool.core.collection.CollUtil;
import com.sl.ms.sms.annotation.SendChannel;
import com.sl.ms.sms.entity.SmsRecordEntity;
import com.sl.ms.sms.entity.SmsThirdChannelEntity;
import com.sl.ms.sms.enums.SendChannelEnum;
import com.sl.ms.sms.enums.SendStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.List;

@Slf4j
@Component
@SendChannel(type = SendChannelEnum.ALI_YUN)
public class AliYunSmsSendHandler implements SmsSendHandler {

    @Override
    public void send(SmsThirdChannelEntity smsThirdChannelEntity, List<SmsRecordEntity> smsRecordEntities) {
        //第三方发送短信验证码
        log.info("smsRecordEntities{}", smsRecordEntities);
        log.info("smsThirdChannelEntity{}", smsThirdChannelEntity);
        CollUtil.forEach(smsRecordEntities, (value, index) -> {
            log.info("短信发送成功 ...");
            //设置发送成功状态
            value.setStatus(SendStatusEnum.SUCCESS);
        });
    }
}

对接短信通道时一定要加上@SendChannel注解并且指定type枚举中的code与sl_sms_third_channel表中的send_channel字段值一致