沙钢智慧能源系统后端代码
houzhongjian
2024-10-09 97edd72e5e6dbb134cedae4b72c95be8c948c5ec
提交 | 用户 | 时间
97edd7 1 package com.iailab.module.shasteel.framework.sms.core.client.impl;
H 2
3 import cn.hutool.core.codec.Base64;
4 import cn.hutool.core.lang.Assert;
5 import cn.hutool.core.map.MapUtil;
6 import cn.hutool.core.util.StrUtil;
7 import cn.hutool.crypto.digest.DigestUtil;
8 import cn.hutool.crypto.digest.HmacAlgorithm;
9 import cn.hutool.http.HttpUtil;
10 import com.iailab.framework.common.core.KeyValue;
11 import com.iailab.framework.common.util.collection.MapUtils;
12 import com.iailab.framework.common.util.json.JsonUtils;
13 import com.iailab.module.shasteel.framework.sms.core.client.dto.SmsReceiveRespDTO;
14 import com.iailab.module.shasteel.framework.sms.core.client.dto.SmsSendRespDTO;
15 import com.iailab.module.shasteel.framework.sms.core.client.dto.SmsTemplateRespDTO;
16 import com.iailab.module.shasteel.framework.sms.core.enums.SmsTemplateAuditStatusEnum;
17 import com.iailab.module.shasteel.framework.sms.core.property.SmsChannelProperties;
18
19 import java.util.HashMap;
20 import java.util.List;
21 import java.util.Map;
22 import java.util.Objects;
23
24 /**
25  * 基于钉钉 WebHook 实现的调试的短信客户端实现类
26  *
27  * 考虑到省钱,我们使用钉钉 WebHook 模拟发送短信,方便调试。
28  *
29  * @author iailab
30  */
31 public class DebugDingTalkSmsClient extends AbstractSmsClient {
32
33     public DebugDingTalkSmsClient(SmsChannelProperties properties) {
34         super(properties);
35         Assert.notEmpty(properties.getApiKey(), "apiKey 不能为空");
36         Assert.notEmpty(properties.getApiSecret(), "apiSecret 不能为空");
37     }
38
39     @Override
40     protected void doInit() {
41     }
42
43     @Override
44     public SmsSendRespDTO sendSms(Long sendLogId, String mobile,
45                                   String apiTemplateId, List<KeyValue<String, Object>> templateParams) throws Throwable {
46         // 构建请求
47         String url = buildUrl("robot/send");
48         Map<String, Object> params = new HashMap<>();
49         params.put("msgtype", "text");
50         String content = String.format("【模拟短信】\n手机号:%s\n短信日志编号:%d\n模板参数:%s",
51                 mobile, sendLogId, MapUtils.convertMap(templateParams));
52         params.put("text", MapUtil.builder().put("content", content).build());
53         // 执行请求
54         String responseText = HttpUtil.post(url, JsonUtils.toJsonString(params));
55         // 解析结果
56         Map<?, ?> responseObj = JsonUtils.parseObject(responseText, Map.class);
57         String errorCode = MapUtil.getStr(responseObj, "errcode");
58         return new SmsSendRespDTO().setSuccess(Objects.equals(errorCode, "0")).setSerialNo(StrUtil.uuid())
59                 .setApiCode(errorCode).setApiMsg(MapUtil.getStr(responseObj, "errorMsg"));
60     }
61
62     /**
63      * 构建请求地址
64      *
65      * 参见 <a href="https://developers.dingtalk.com/document/app/custom-robot-access/title-nfv-794-g71">文档</a>
66      *
67      * @param path 请求路径
68      * @return 请求地址
69      */
70     @SuppressWarnings("SameParameterValue")
71     private String buildUrl(String path) {
72         // 生成 timestamp
73         long timestamp = System.currentTimeMillis();
74         // 生成 sign
75         String secret = properties.getApiSecret();
76         String stringToSign = timestamp + "\n" + secret;
77         byte[] signData = DigestUtil.hmac(HmacAlgorithm.HmacSHA256, StrUtil.bytes(secret)).digest(stringToSign);
78         String sign = Base64.encode(signData);
79         // 构建最终 URL
80         return String.format("https://oapi.dingtalk.com/%s?access_token=%s&timestamp=%d&sign=%s",
81                 path, properties.getApiKey(), timestamp, sign);
82     }
83
84     @Override
85     public List<SmsReceiveRespDTO> parseSmsReceiveStatus(String text) {
86         throw new UnsupportedOperationException("模拟短信客户端,暂时无需解析回调");
87     }
88
89     @Override
90     public SmsTemplateRespDTO getSmsTemplate(String apiTemplateId) {
91         return new SmsTemplateRespDTO().setId(apiTemplateId).setContent("")
92                 .setAuditStatus(SmsTemplateAuditStatusEnum.SUCCESS.getStatus()).setAuditReason("");
93     }
94
95 }