新增短信功能
This commit is contained in:
parent
1ad104e229
commit
51907b646d
|
|
@ -14,6 +14,18 @@
|
|||
<artifactId>fast-framework</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>dysmsapi20170525</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.tencentcloudapi</groupId>
|
||||
<artifactId>tencentcloud-sdk-java</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
48
fast-boot-module/fast-boot-message/src/main/java/net/maku/message/cache/SmsPlatformCache.java
vendored
Normal file
48
fast-boot-module/fast-boot-message/src/main/java/net/maku/message/cache/SmsPlatformCache.java
vendored
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
package net.maku.message.cache;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.maku.framework.common.utils.RedisUtils;
|
||||
import net.maku.message.sms.config.SmsConfig;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 短信平台 Cache
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class SmsPlatformCache {
|
||||
private final RedisUtils redisUtils;
|
||||
|
||||
/**
|
||||
* 短信平台轮询KEY
|
||||
*/
|
||||
private final String SMS_ROUND_KEY = "message:sms:round";
|
||||
|
||||
/**
|
||||
* 短信平台列表KEY
|
||||
*/
|
||||
private final String SMS_PLATFORM_KEY = "message:sms:platform";
|
||||
|
||||
/**
|
||||
* 获取短信轮询值
|
||||
*/
|
||||
public Long getRoundValue() {
|
||||
return redisUtils.increment(SMS_ROUND_KEY);
|
||||
}
|
||||
|
||||
public List<SmsConfig> list(){
|
||||
return (List<SmsConfig>)redisUtils.get(SMS_PLATFORM_KEY);
|
||||
}
|
||||
|
||||
public void save(List<SmsConfig> list){
|
||||
redisUtils.set(SMS_PLATFORM_KEY, list);
|
||||
}
|
||||
|
||||
public void delete(){
|
||||
redisUtils.delete(SMS_PLATFORM_KEY);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package net.maku.message.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.maku.framework.common.page.PageResult;
|
||||
import net.maku.framework.common.utils.Result;
|
||||
import net.maku.message.convert.SmsLogConvert;
|
||||
import net.maku.message.entity.SmsLogEntity;
|
||||
import net.maku.message.query.SmsLogQuery;
|
||||
import net.maku.message.service.SmsLogService;
|
||||
import net.maku.message.vo.SmsLogVO;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* 短信日志
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("message/sms/log")
|
||||
@Tag(name="短信日志")
|
||||
@AllArgsConstructor
|
||||
public class SmsLogController {
|
||||
private final SmsLogService smsLogService;
|
||||
|
||||
@GetMapping("page")
|
||||
@Operation(summary = "分页")
|
||||
@PreAuthorize("hasAuthority('sms:log')")
|
||||
public Result<PageResult<SmsLogVO>> page(@Valid SmsLogQuery query){
|
||||
PageResult<SmsLogVO> page = smsLogService.page(query);
|
||||
|
||||
return Result.ok(page);
|
||||
}
|
||||
|
||||
@GetMapping("{id}")
|
||||
@Operation(summary = "信息")
|
||||
@PreAuthorize("hasAuthority('sms:log')")
|
||||
public Result<SmsLogVO> get(@PathVariable("id") Long id){
|
||||
SmsLogEntity entity = smsLogService.getById(id);
|
||||
|
||||
return Result.ok(SmsLogConvert.INSTANCE.convert(entity));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
package net.maku.message.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.maku.framework.common.page.PageResult;
|
||||
import net.maku.framework.common.utils.ExceptionUtils;
|
||||
import net.maku.framework.common.utils.Result;
|
||||
import net.maku.message.convert.SmsPlatformConvert;
|
||||
import net.maku.message.entity.SmsPlatformEntity;
|
||||
import net.maku.message.query.SmsPlatformQuery;
|
||||
import net.maku.message.service.SmsPlatformService;
|
||||
import net.maku.message.sms.SmsContext;
|
||||
import net.maku.message.sms.config.SmsConfig;
|
||||
import net.maku.message.sms.service.SmsService;
|
||||
import net.maku.message.vo.SmsPlatformVO;
|
||||
import net.maku.message.vo.SmsSendVO;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 短信平台
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("message/sms/platform")
|
||||
@Tag(name="短信平台")
|
||||
@AllArgsConstructor
|
||||
public class SmsPlatformController {
|
||||
private final SmsPlatformService smsPlatformService;
|
||||
private final SmsService smsService;
|
||||
|
||||
@GetMapping("page")
|
||||
@Operation(summary = "分页")
|
||||
@PreAuthorize("hasAuthority('sms:platform:page')")
|
||||
public Result<PageResult<SmsPlatformVO>> page(@Valid SmsPlatformQuery query){
|
||||
PageResult<SmsPlatformVO> page = smsPlatformService.page(query);
|
||||
|
||||
return Result.ok(page);
|
||||
}
|
||||
|
||||
@GetMapping("{id}")
|
||||
@Operation(summary = "信息")
|
||||
@PreAuthorize("hasAuthority('sms:platform:info')")
|
||||
public Result<SmsPlatformVO> get(@PathVariable("id") Long id){
|
||||
SmsPlatformEntity entity = smsPlatformService.getById(id);
|
||||
|
||||
return Result.ok(SmsPlatformConvert.INSTANCE.convert(entity));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@Operation(summary = "保存")
|
||||
@PreAuthorize("hasAuthority('sms:platform:save')")
|
||||
public Result<String> save(@RequestBody SmsPlatformVO vo){
|
||||
smsPlatformService.save(vo);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@PostMapping("send")
|
||||
@Operation(summary = "发送短信")
|
||||
@PreAuthorize("hasAuthority('sms:platform:update')")
|
||||
public Result<String> send(@RequestBody SmsSendVO vo){
|
||||
SmsPlatformEntity entity = smsPlatformService.getById(vo.getId());
|
||||
SmsConfig config = SmsPlatformConvert.INSTANCE.convert2(entity);
|
||||
|
||||
// 短信参数
|
||||
Map<String, String> params = new HashMap<>();
|
||||
if(!StringUtils.isAnyBlank(vo.getParamKey(), vo.getParamValue())) {
|
||||
params.put(vo.getParamKey(), vo.getParamValue());
|
||||
}
|
||||
|
||||
try {
|
||||
// 发送短信
|
||||
new SmsContext(config).send(vo.getMobile(), params);
|
||||
|
||||
// 保存日志
|
||||
smsService.saveLog(config, vo.getMobile(), params, null);
|
||||
|
||||
return Result.ok();
|
||||
}catch (Exception e) {
|
||||
// 保存日志
|
||||
smsService.saveLog(config, vo.getMobile(), params, e);
|
||||
|
||||
return Result.error(ExceptionUtils.getExceptionMessage(e));
|
||||
}
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@Operation(summary = "修改")
|
||||
@PreAuthorize("hasAuthority('sms:platform:update')")
|
||||
public Result<String> update(@RequestBody @Valid SmsPlatformVO vo){
|
||||
smsPlatformService.update(vo);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping
|
||||
@Operation(summary = "删除")
|
||||
@PreAuthorize("hasAuthority('sms:platform:delete')")
|
||||
public Result<String> delete(@RequestBody List<Long> idList){
|
||||
smsPlatformService.delete(idList);
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package net.maku.message.convert;
|
||||
|
||||
import net.maku.message.entity.SmsLogEntity;
|
||||
import net.maku.message.vo.SmsLogVO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 短信日志
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Mapper
|
||||
public interface SmsLogConvert {
|
||||
SmsLogConvert INSTANCE = Mappers.getMapper(SmsLogConvert.class);
|
||||
|
||||
SmsLogVO convert(SmsLogEntity entity);
|
||||
|
||||
List<SmsLogVO> convertList(List<SmsLogEntity> list);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package net.maku.message.convert;
|
||||
|
||||
import net.maku.message.entity.SmsPlatformEntity;
|
||||
import net.maku.message.sms.config.SmsConfig;
|
||||
import net.maku.message.vo.SmsPlatformVO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 短信平台
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Mapper
|
||||
public interface SmsPlatformConvert {
|
||||
SmsPlatformConvert INSTANCE = Mappers.getMapper(SmsPlatformConvert.class);
|
||||
|
||||
SmsPlatformEntity convert(SmsPlatformVO vo);
|
||||
|
||||
SmsPlatformVO convert(SmsPlatformEntity entity);
|
||||
|
||||
List<SmsPlatformVO> convertList(List<SmsPlatformEntity> list);
|
||||
|
||||
SmsConfig convert2(SmsPlatformEntity entity);
|
||||
|
||||
List<SmsConfig> convertList2(List<SmsPlatformEntity> list);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package net.maku.message.dao;
|
||||
|
||||
import net.maku.framework.common.dao.BaseDao;
|
||||
import net.maku.message.entity.SmsLogEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 短信日志
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Mapper
|
||||
public interface SmsLogDao extends BaseDao<SmsLogEntity> {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package net.maku.message.dao;
|
||||
|
||||
import net.maku.framework.common.dao.BaseDao;
|
||||
import net.maku.message.entity.SmsPlatformEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 短信平台
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Mapper
|
||||
public interface SmsPlatformDao extends BaseDao<SmsPlatformEntity> {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
package net.maku.message.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 短信日志
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@TableName("sms_log")
|
||||
public class SmsLogEntity {
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 平台ID
|
||||
*/
|
||||
private Long platformId;
|
||||
|
||||
/**
|
||||
* 平台类型
|
||||
*/
|
||||
private Integer platform;
|
||||
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
private String mobile;
|
||||
|
||||
/**
|
||||
* 状态 0:失败 1:成功
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 参数
|
||||
*/
|
||||
private String params;
|
||||
|
||||
/**
|
||||
* 异常信息
|
||||
*/
|
||||
private String error;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private Date createTime;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
package net.maku.message.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import net.maku.framework.common.entity.BaseEntity;
|
||||
|
||||
/**
|
||||
* 短信平台
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@TableName("sms_platform")
|
||||
public class SmsPlatformEntity extends BaseEntity {
|
||||
/**
|
||||
* 平台类型 0:阿里云 1:腾讯云
|
||||
*/
|
||||
private Integer platform;
|
||||
|
||||
/**
|
||||
* 短信签名
|
||||
*/
|
||||
private String signName;
|
||||
|
||||
/**
|
||||
* 短信模板
|
||||
*/
|
||||
private String templateId;
|
||||
|
||||
/**
|
||||
* 短信应用的ID,如:腾讯云等
|
||||
*/
|
||||
private String appId;
|
||||
|
||||
/**
|
||||
* 腾讯云国际短信、华为云等需要
|
||||
*/
|
||||
private String senderId;
|
||||
|
||||
/**
|
||||
* AccessKey
|
||||
*/
|
||||
private String accessKey;
|
||||
|
||||
/**
|
||||
* SecretKey
|
||||
*/
|
||||
private String secretKey;
|
||||
|
||||
/**
|
||||
* 状态 0:禁用 1:启用
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package net.maku.message.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 短信平台枚举
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum SmsPlatformEnum {
|
||||
/**
|
||||
* 阿里云
|
||||
*/
|
||||
ALIYUN(0),
|
||||
/**
|
||||
* 腾讯云
|
||||
*/
|
||||
QCLOUD(1);
|
||||
|
||||
private final int value;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package net.maku.message.query;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import net.maku.framework.common.query.Query;
|
||||
|
||||
/**
|
||||
* 短信日志查询
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Schema(description = "短信日志查询")
|
||||
public class SmsLogQuery extends Query {
|
||||
@Schema(description = "平台ID")
|
||||
private Long platformId;
|
||||
|
||||
@Schema(description = "平台类型")
|
||||
private Integer platform;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package net.maku.message.query;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import net.maku.framework.common.query.Query;
|
||||
|
||||
/**
|
||||
* 短信平台查询
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Schema(description = "短信平台查询")
|
||||
public class SmsPlatformQuery extends Query {
|
||||
@Schema(description = "平台类型 0:阿里云 1:腾讯云")
|
||||
private Integer platform;
|
||||
|
||||
@Schema(description = "短信签名")
|
||||
private String signName;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package net.maku.message.service;
|
||||
|
||||
import net.maku.framework.common.page.PageResult;
|
||||
import net.maku.framework.common.service.BaseService;
|
||||
import net.maku.message.entity.SmsLogEntity;
|
||||
import net.maku.message.query.SmsLogQuery;
|
||||
import net.maku.message.vo.SmsLogVO;
|
||||
|
||||
/**
|
||||
* 短信日志
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public interface SmsLogService extends BaseService<SmsLogEntity> {
|
||||
|
||||
PageResult<SmsLogVO> page(SmsLogQuery query);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package net.maku.message.service;
|
||||
|
||||
import net.maku.framework.common.page.PageResult;
|
||||
import net.maku.framework.common.service.BaseService;
|
||||
import net.maku.message.entity.SmsPlatformEntity;
|
||||
import net.maku.message.query.SmsPlatformQuery;
|
||||
import net.maku.message.sms.config.SmsConfig;
|
||||
import net.maku.message.vo.SmsPlatformVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 短信平台
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public interface SmsPlatformService extends BaseService<SmsPlatformEntity> {
|
||||
|
||||
PageResult<SmsPlatformVO> page(SmsPlatformQuery query);
|
||||
|
||||
/**
|
||||
* 启用的短信平台列表
|
||||
*/
|
||||
List<SmsConfig> listByEnable();
|
||||
|
||||
void save(SmsPlatformVO vo);
|
||||
|
||||
void update(SmsPlatformVO vo);
|
||||
|
||||
void delete(List<Long> idList);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package net.maku.message.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.maku.framework.common.page.PageResult;
|
||||
import net.maku.framework.common.service.impl.BaseServiceImpl;
|
||||
import net.maku.message.convert.SmsLogConvert;
|
||||
import net.maku.message.dao.SmsLogDao;
|
||||
import net.maku.message.entity.SmsLogEntity;
|
||||
import net.maku.message.query.SmsLogQuery;
|
||||
import net.maku.message.service.SmsLogService;
|
||||
import net.maku.message.vo.SmsLogVO;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 短信日志
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class SmsLogServiceImpl extends BaseServiceImpl<SmsLogDao, SmsLogEntity> implements SmsLogService {
|
||||
|
||||
@Override
|
||||
public PageResult<SmsLogVO> page(SmsLogQuery query) {
|
||||
IPage<SmsLogEntity> page = baseMapper.selectPage(getPage(query), getWrapper(query));
|
||||
|
||||
return new PageResult<>(SmsLogConvert.INSTANCE.convertList(page.getRecords()), page.getTotal());
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<SmsLogEntity> getWrapper(SmsLogQuery query){
|
||||
LambdaQueryWrapper<SmsLogEntity> wrapper = Wrappers.lambdaQuery();
|
||||
wrapper.eq(query.getPlatform() != null, SmsLogEntity::getPlatform, query.getPlatform());
|
||||
wrapper.like(query.getPlatformId() != null, SmsLogEntity::getPlatformId, query.getPlatformId());
|
||||
wrapper.orderByDesc(SmsLogEntity::getId);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
package net.maku.message.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.maku.framework.common.constant.Constant;
|
||||
import net.maku.framework.common.page.PageResult;
|
||||
import net.maku.framework.common.service.impl.BaseServiceImpl;
|
||||
import net.maku.message.cache.SmsPlatformCache;
|
||||
import net.maku.message.convert.SmsPlatformConvert;
|
||||
import net.maku.message.dao.SmsPlatformDao;
|
||||
import net.maku.message.entity.SmsPlatformEntity;
|
||||
import net.maku.message.query.SmsPlatformQuery;
|
||||
import net.maku.message.service.SmsPlatformService;
|
||||
import net.maku.message.sms.config.SmsConfig;
|
||||
import net.maku.message.vo.SmsPlatformVO;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 短信平台
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class SmsPlatformServiceImpl extends BaseServiceImpl<SmsPlatformDao, SmsPlatformEntity> implements SmsPlatformService {
|
||||
private final SmsPlatformCache smsPlatformCache;
|
||||
|
||||
@Override
|
||||
public PageResult<SmsPlatformVO> page(SmsPlatformQuery query) {
|
||||
IPage<SmsPlatformEntity> page = baseMapper.selectPage(getPage(query), getWrapper(query));
|
||||
|
||||
return new PageResult<>(SmsPlatformConvert.INSTANCE.convertList(page.getRecords()), page.getTotal());
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<SmsPlatformEntity> getWrapper(SmsPlatformQuery query){
|
||||
LambdaQueryWrapper<SmsPlatformEntity> wrapper = Wrappers.lambdaQuery();
|
||||
wrapper.eq(query.getPlatform() != null, SmsPlatformEntity::getPlatform, query.getPlatform());
|
||||
wrapper.like(StrUtil.isNotBlank(query.getSignName()), SmsPlatformEntity::getSignName, query.getSignName());
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SmsConfig> listByEnable() {
|
||||
// 从缓存读取
|
||||
List<SmsConfig> cacheList = smsPlatformCache.list();
|
||||
|
||||
// 如果缓存没有,则从DB读取,然后保存到缓存里
|
||||
if(cacheList == null) {
|
||||
List<SmsPlatformEntity> list = this.list(new LambdaQueryWrapper<SmsPlatformEntity>().in(SmsPlatformEntity::getStatus, Constant.ENABLE));
|
||||
|
||||
cacheList = SmsPlatformConvert.INSTANCE.convertList2(list);
|
||||
smsPlatformCache.save(cacheList);
|
||||
}
|
||||
|
||||
return cacheList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(SmsPlatformVO vo) {
|
||||
SmsPlatformEntity entity = SmsPlatformConvert.INSTANCE.convert(vo);
|
||||
|
||||
baseMapper.insert(entity);
|
||||
|
||||
smsPlatformCache.delete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(SmsPlatformVO vo) {
|
||||
SmsPlatformEntity entity = SmsPlatformConvert.INSTANCE.convert(vo);
|
||||
|
||||
updateById(entity);
|
||||
|
||||
smsPlatformCache.delete();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void delete(List<Long> idList) {
|
||||
removeByIds(idList);
|
||||
|
||||
smsPlatformCache.delete();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
package net.maku.message.sms;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import com.aliyun.dysmsapi20170525.Client;
|
||||
import com.aliyun.dysmsapi20170525.models.*;
|
||||
import com.aliyun.teaopenapi.models.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.maku.framework.common.constant.Constant;
|
||||
import net.maku.framework.common.exception.FastException;
|
||||
import net.maku.framework.common.utils.JsonUtils;
|
||||
import net.maku.message.sms.config.SmsConfig;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 阿里云短信
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Slf4j
|
||||
public class AliyunSmsStrategy implements SmsStrategy {
|
||||
private final Client client;
|
||||
private final SmsConfig smsConfig;
|
||||
public AliyunSmsStrategy(SmsConfig smsConfig) {
|
||||
this.smsConfig = smsConfig;
|
||||
|
||||
try {
|
||||
Config config = new Config();
|
||||
config.setAccessKeyId(smsConfig.getAccessKey());
|
||||
config.setAccessKeySecret(smsConfig.getSecretKey());
|
||||
config.endpoint = "dysmsapi.aliyuncs.com";
|
||||
|
||||
this.client = new Client(config);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(String mobile, Map<String, String> params) {
|
||||
SendSmsRequest request = new SendSmsRequest();
|
||||
request.setSignName(smsConfig.getSignName());
|
||||
request.setTemplateCode(smsConfig.getTemplateId());
|
||||
request.setPhoneNumbers(mobile);
|
||||
// request.setTemplateParam("{\"code\":\"1234\"}");
|
||||
if(MapUtil.isNotEmpty(params)){
|
||||
request.setTemplateParam(JsonUtils.toJsonString(params));
|
||||
}
|
||||
|
||||
try {
|
||||
// 发送短信
|
||||
SendSmsResponse response = client.sendSms(request);
|
||||
|
||||
// 发送失败
|
||||
if(!Constant.OK.equalsIgnoreCase(response.getBody().getCode())) {
|
||||
throw new FastException(response.getBody().getMessage());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new FastException("短信发送失败:", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
package net.maku.message.sms;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import com.tencentcloudapi.common.Credential;
|
||||
import com.tencentcloudapi.common.profile.ClientProfile;
|
||||
import com.tencentcloudapi.common.profile.HttpProfile;
|
||||
import com.tencentcloudapi.sms.v20210111.SmsClient;
|
||||
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
|
||||
import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest;
|
||||
import com.tencentcloudapi.sms.v20210111.models.SendStatus;
|
||||
import net.maku.framework.common.constant.Constant;
|
||||
import net.maku.framework.common.exception.FastException;
|
||||
import net.maku.message.sms.config.SmsConfig;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 腾讯云短信
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public class QcloudSmsStrategy implements SmsStrategy {
|
||||
private final SmsConfig smsConfig;
|
||||
private SmsClient client;
|
||||
|
||||
public QcloudSmsStrategy(SmsConfig smsConfig){
|
||||
this.smsConfig = smsConfig;
|
||||
|
||||
try {
|
||||
HttpProfile httpProfile = new HttpProfile();
|
||||
httpProfile.setReqMethod("POST");
|
||||
httpProfile.setEndpoint("sms.tencentcloudapi.com");
|
||||
|
||||
ClientProfile clientProfile = new ClientProfile();
|
||||
clientProfile.setHttpProfile(httpProfile);
|
||||
|
||||
Credential cred = new Credential(smsConfig.getAccessKey(), smsConfig.getSecretKey());
|
||||
this.client = new SmsClient(cred, "ap-guangzhou", clientProfile);
|
||||
}catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(String mobile, Map<String, String> params) {
|
||||
SendSmsRequest request = new SendSmsRequest();
|
||||
request.setSmsSdkAppId(smsConfig.getAppId());
|
||||
request.setSignName(smsConfig.getSignName());
|
||||
request.setTemplateId(smsConfig.getTemplateId());
|
||||
|
||||
// 有参数则设置
|
||||
if(MapUtil.isNotEmpty(params)){
|
||||
request.setTemplateParamSet(params.values().toArray(new String[0]));
|
||||
}
|
||||
|
||||
// 手机号
|
||||
String[] phoneNumberSet = { "+86" + mobile };
|
||||
request.setPhoneNumberSet(phoneNumberSet);
|
||||
|
||||
// 国际、港澳台短信,需要添加SenderId,国内短信填空,默认未开通
|
||||
request.setSenderId(smsConfig.getSenderId());
|
||||
|
||||
try {
|
||||
// 发送短信
|
||||
SendSmsResponse response = client.SendSms(request);
|
||||
SendStatus sendStatus = response.getSendStatusSet()[0];
|
||||
|
||||
// 发送失败
|
||||
if(!Constant.OK.equalsIgnoreCase(sendStatus.getCode())) {
|
||||
throw new FastException(sendStatus.getMessage());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new FastException("短信发送失败:", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package net.maku.message.sms;
|
||||
|
||||
import net.maku.framework.common.exception.FastException;
|
||||
import net.maku.message.enums.SmsPlatformEnum;
|
||||
import net.maku.message.sms.config.SmsConfig;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 短信 Context
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public class SmsContext {
|
||||
private final SmsStrategy smsStrategy;
|
||||
|
||||
public SmsContext(SmsConfig config) {
|
||||
if(config.getPlatform() == SmsPlatformEnum.ALIYUN.getValue()) {
|
||||
this.smsStrategy = new AliyunSmsStrategy(config);
|
||||
}else if(config.getPlatform() == SmsPlatformEnum.QCLOUD.getValue()) {
|
||||
this.smsStrategy = new QcloudSmsStrategy(config);
|
||||
}else {
|
||||
throw new FastException("未知的短信平台");
|
||||
}
|
||||
}
|
||||
|
||||
public void send(String mobile, Map<String, String> params) {
|
||||
smsStrategy.send(mobile, params);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package net.maku.message.sms;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 短信
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public interface SmsStrategy {
|
||||
|
||||
/**
|
||||
* 发送短信
|
||||
* @param mobile 手机号
|
||||
* @param params 参数
|
||||
*/
|
||||
void send(String mobile, Map<String, String> params);
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package net.maku.message.sms.config;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 短信配置项
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
public class SmsConfig {
|
||||
/**
|
||||
* 平台ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 平台类型
|
||||
*/
|
||||
private Integer platform;
|
||||
|
||||
/**
|
||||
* 短信签名
|
||||
*/
|
||||
private String signName;
|
||||
|
||||
/**
|
||||
* 短信模板
|
||||
*/
|
||||
private String templateId;
|
||||
|
||||
/**
|
||||
* 短信应用的ID,如:腾讯云等
|
||||
*/
|
||||
private String appId;
|
||||
|
||||
/**
|
||||
* 腾讯云国际短信、华为云等需要
|
||||
*/
|
||||
private String senderId;
|
||||
|
||||
/**
|
||||
* AccessKey
|
||||
*/
|
||||
private String accessKey;
|
||||
|
||||
/**
|
||||
* SecretKey
|
||||
*/
|
||||
private String secretKey;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
package net.maku.message.sms.service;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.maku.framework.common.constant.Constant;
|
||||
import net.maku.framework.common.exception.FastException;
|
||||
import net.maku.framework.common.utils.ExceptionUtils;
|
||||
import net.maku.framework.common.utils.JsonUtils;
|
||||
import net.maku.message.entity.SmsLogEntity;
|
||||
import net.maku.message.service.SmsLogService;
|
||||
import net.maku.message.service.SmsPlatformService;
|
||||
import net.maku.message.cache.SmsPlatformCache;
|
||||
import net.maku.message.sms.SmsContext;
|
||||
import net.maku.message.sms.config.SmsConfig;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 短信服务
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class SmsService {
|
||||
private final SmsPlatformService smsPlatformService;
|
||||
private final SmsLogService smsLogService;
|
||||
private final SmsPlatformCache smsCacheService;
|
||||
|
||||
/**
|
||||
* 发送短信
|
||||
* @param mobile 手机号
|
||||
* @return 是否发送成功
|
||||
*/
|
||||
public boolean send(String mobile){
|
||||
return this.send(mobile, MapUtil.newHashMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送短信
|
||||
* @param mobile 手机号
|
||||
* @param params 参数
|
||||
* @return 是否发送成功
|
||||
*/
|
||||
public boolean send(String mobile, Map<String, String> params){
|
||||
SmsConfig config = roundSmsConfig();;
|
||||
|
||||
try {
|
||||
// 发送短信
|
||||
new SmsContext(config).send(mobile, params);
|
||||
|
||||
saveLog(config, mobile, params, null);
|
||||
return true;
|
||||
}catch (Exception e) {
|
||||
log.error("短信发送失败,手机号:{}", mobile, e);
|
||||
|
||||
saveLog(config, mobile, params, e);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存短信日志
|
||||
*/
|
||||
public void saveLog(SmsConfig config, String mobile, Map<String, String> params, Exception e) {
|
||||
SmsLogEntity logEntity = new SmsLogEntity();
|
||||
logEntity.setPlatform(config.getPlatform());
|
||||
logEntity.setPlatformId(config.getId());
|
||||
logEntity.setMobile(mobile);
|
||||
logEntity.setParams(JsonUtils.toJsonString(params));
|
||||
|
||||
if(e != null) {
|
||||
String error = StringUtils.substring(ExceptionUtils.getExceptionMessage(e), 0, 2000);
|
||||
logEntity.setStatus(Constant.FAIL);
|
||||
logEntity.setError(error);
|
||||
}else {
|
||||
logEntity.setStatus(Constant.SUCCESS);
|
||||
}
|
||||
|
||||
smsLogService.save(logEntity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过轮询算法,获取短信平台的配置
|
||||
*/
|
||||
private SmsConfig roundSmsConfig() {
|
||||
List<SmsConfig> platformList = smsPlatformService.listByEnable();
|
||||
|
||||
// 是否有可用的短信平台
|
||||
int count = platformList.size();
|
||||
if(count == 0) {
|
||||
throw new FastException("没有可用的短信平台,请先添加");
|
||||
}
|
||||
|
||||
// 采用轮询算法,发送短信
|
||||
long round = smsCacheService.getRoundValue();
|
||||
|
||||
return platformList.get((int)round % count);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package net.maku.message.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import net.maku.framework.common.utils.DateUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 短信日志
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "短信日志")
|
||||
public class SmsLogVO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "id")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "平台ID")
|
||||
private Long platformId;
|
||||
|
||||
@Schema(description = "平台类型")
|
||||
private Integer platform;
|
||||
|
||||
@Schema(description = "手机号")
|
||||
private String mobile;
|
||||
|
||||
@Schema(description = "状态 0:失败 1:成功")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "参数")
|
||||
private String params;
|
||||
|
||||
@Schema(description = "异常信息")
|
||||
private String error;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@JsonFormat(pattern = DateUtils.DATE_TIME_PATTERN)
|
||||
private Date createTime;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package net.maku.message.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import net.maku.framework.common.utils.DateUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 短信平台
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "短信平台")
|
||||
public class SmsPlatformVO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "id")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "平台类型 0:阿里云 1:腾讯云")
|
||||
private Integer platform;
|
||||
|
||||
@Schema(description = "短信签名")
|
||||
private String signName;
|
||||
|
||||
@Schema(description = "短信模板")
|
||||
private String templateId;
|
||||
|
||||
@Schema(description = "短信应用的ID,如:腾讯云等")
|
||||
private String appId;
|
||||
|
||||
@Schema(description = "腾讯云国际短信、华为云等需要")
|
||||
private String senderId;
|
||||
|
||||
@Schema(description = "AccessKey")
|
||||
private String accessKey;
|
||||
|
||||
@Schema(description = "SecretKey")
|
||||
private String secretKey;
|
||||
|
||||
@Schema(description = "状态 0:禁用 1:启用")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@JsonFormat(pattern = DateUtils.DATE_TIME_PATTERN)
|
||||
private Date createTime;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package net.maku.message.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 短信发送
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "短信发送")
|
||||
public class SmsSendVO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "id")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "手机号")
|
||||
private String mobile;
|
||||
|
||||
@Schema(description = "参数Key")
|
||||
private String paramKey;
|
||||
|
||||
@Schema(description = "参数Value")
|
||||
private String paramValue;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="net.maku.message.dao.SmsLogDao">
|
||||
|
||||
</mapper>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="net.maku.message.dao.SmsPlatformDao">
|
||||
|
||||
</mapper>
|
||||
|
|
@ -22,4 +22,25 @@ public interface Constant {
|
|||
* 超级管理员
|
||||
*/
|
||||
Integer SUPER_ADMIN = 1;
|
||||
/**
|
||||
* 禁用
|
||||
*/
|
||||
Integer DISABLE = 0;
|
||||
/**
|
||||
* 启用
|
||||
*/
|
||||
Integer ENABLE = 1;
|
||||
/**
|
||||
* 失败
|
||||
*/
|
||||
Integer FAIL = 0;
|
||||
/**
|
||||
* 成功
|
||||
*/
|
||||
Integer SUCCESS = 1;
|
||||
/**
|
||||
* OK
|
||||
*/
|
||||
String OK = "OK";
|
||||
|
||||
}
|
||||
|
|
@ -51,6 +51,14 @@ public class RedisUtils {
|
|||
return get(key, NOT_EXPIRE);
|
||||
}
|
||||
|
||||
public Long increment(String key){
|
||||
return redisTemplate.opsForValue().increment(key);
|
||||
}
|
||||
|
||||
public Boolean hasKey(String key){
|
||||
return redisTemplate.hasKey(key);
|
||||
}
|
||||
|
||||
public void delete(String key) {
|
||||
redisTemplate.delete(key);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,11 +14,11 @@
|
|||
<artifactId>fast-boot-new</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>net.maku</groupId>-->
|
||||
<!-- <artifactId>fast-boot-quartz</artifactId>-->
|
||||
<!-- <version>${revision}</version>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>net.maku</groupId>
|
||||
<artifactId>fast-boot-quartz</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.maku</groupId>
|
||||
<artifactId>fast-boot-message</artifactId>
|
||||
|
|
|
|||
12
pom.xml
12
pom.xml
|
|
@ -40,6 +40,8 @@
|
|||
<captcha.version>1.6.2</captcha.version>
|
||||
<mapstruct.version>1.4.2.Final</mapstruct.version>
|
||||
<aliyun.oss.version>3.8.0</aliyun.oss.version>
|
||||
<aliyun.dysmsapi.version>2.0.18</aliyun.dysmsapi.version>
|
||||
<tencentcloud.sdk.version>3.1.574</tencentcloud.sdk.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
|
@ -119,6 +121,16 @@
|
|||
<artifactId>aliyun-sdk-oss</artifactId>
|
||||
<version>${aliyun.oss.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>dysmsapi20170525</artifactId>
|
||||
<version>${aliyun.dysmsapi.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.tencentcloudapi</groupId>
|
||||
<artifactId>tencentcloud-sdk-java</artifactId>
|
||||
<version>${tencentcloud.sdk.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user