初始版本,工具基础类

This commit is contained in:
2025-11-30 13:02:34 +08:00
commit ea4e2e305d
37 changed files with 7480 additions and 0 deletions

370
docs/sms.md Normal file
View File

@@ -0,0 +1,370 @@
# 短信工具文档
## 概述
短信工具提供了阿里云短信发送功能使用Go标准库实现无需第三方依赖。
## 功能特性
- 支持阿里云短信服务
- 支持发送原始请求(完全由外部控制请求参数)
- 支持模板短信发送
- 支持批量发送
- 自动签名计算
- 使用配置工具统一管理配置
## 使用方法
### 1. 创建短信发送器
```go
import (
"github.com/go-common/config"
"github.com/go-common/sms"
)
// 从配置加载
cfg, err := config.LoadFromFile("./config.json")
if err != nil {
log.Fatal(err)
}
smsConfig := cfg.GetSMS()
if smsConfig == nil {
log.Fatal("SMS config is nil")
}
// 创建短信发送器
smsClient, err := sms.NewSMS(smsConfig)
if err != nil {
log.Fatal(err)
}
```
### 2. 发送原始请求(推荐,最灵活)
```go
// 外部构建完整的请求参数
params := map[string]string{
"PhoneNumbers": "13800138000,13900139000",
"SignName": "我的签名",
"TemplateCode": "SMS_123456789",
"TemplateParam": `{"code":"123456","expire":"5"}`,
}
// 发送短信(工具只负责添加系统参数、计算签名并发送)
resp, err := smsClient.SendRaw(params)
if err != nil {
log.Fatal(err)
}
fmt.Printf("发送成功RequestID: %s\n", resp.RequestID)
```
### 3. 发送简单短信(便捷方法)
```go
// 使用配置中的模板代码发送短信
templateParam := map[string]string{
"code": "123456",
}
resp, err := smsClient.SendSimple(
[]string{"13800138000"},
templateParam,
)
if err != nil {
log.Fatal(err)
}
fmt.Printf("发送成功RequestID: %s\n", resp.RequestID)
```
### 4. 使用指定模板发送短信(便捷方法)
```go
// 使用指定的模板代码发送短信
templateParam := map[string]string{
"code": "123456",
"expire": "5",
}
resp, err := smsClient.SendWithTemplate(
[]string{"13800138000"},
"SMS_123456789", // 模板代码
templateParam,
)
if err != nil {
log.Fatal(err)
}
```
### 5. 使用SendRequest结构发送便捷方法
```go
import "github.com/go-common/sms"
req := &sms.SendRequest{
PhoneNumbers: []string{"13800138000", "13900139000"},
TemplateCode: "SMS_123456789",
TemplateParam: map[string]string{
"code": "123456",
},
SignName: "我的签名", // 可选,如果为空使用配置中的签名
}
resp, err := smsClient.Send(req)
if err != nil {
log.Fatal(err)
}
```
### 6. 使用JSON字符串作为模板参数
```go
// TemplateParam可以是JSON字符串
req := &sms.SendRequest{
PhoneNumbers: []string{"13800138000"},
TemplateCode: "SMS_123456789",
TemplateParam: `{"code":"123456","expire":"5"}`, // 直接使用JSON字符串
}
resp, err := smsClient.Send(req)
```
## API 参考
### NewSMS(cfg *config.SMSConfig) (*SMS, error)
创建短信发送器。
**参数:**
- `cfg`: 短信配置对象
**返回:** 短信发送器实例和错误信息
### (s *SMS) SendRaw(params map[string]string) (*SendResponse, error)
发送原始请求(推荐使用,最灵活)。
**参数:**
- `params`: 请求参数map工具只负责添加必要的系统参数如签名、时间戳等并发送
**返回:** 发送响应和错误信息
**说明:** 此方法允许外部完全控制请求参数,工具只负责添加系统参数、计算签名并发送。
### (s *SMS) Send(req *SendRequest) (*SendResponse, error)
发送短信使用SendRequest结构
**参数:**
- `req`: 发送请求对象
**返回:** 发送响应和错误信息
**说明:** 如果需要完全控制请求参数请使用SendRaw方法。
### (s *SMS) SendSimple(phoneNumbers []string, templateParam map[string]string) (*SendResponse, error)
发送简单短信(便捷方法,使用配置中的模板代码)。
**参数:**
- `phoneNumbers`: 手机号列表
- `templateParam`: 模板参数
### (s *SMS) SendWithTemplate(phoneNumbers []string, templateCode string, templateParam map[string]string) (*SendResponse, error)
使用指定模板发送短信(便捷方法)。
**参数:**
- `phoneNumbers`: 手机号列表
- `templateCode`: 模板代码
- `templateParam`: 模板参数
### SendRequest 结构体
```go
type SendRequest struct {
PhoneNumbers []string // 手机号列表
TemplateCode string // 模板代码(可选,如果为空使用配置中的)
TemplateParam interface{} // 模板参数可以是map[string]string或JSON字符串
SignName string // 签名(可选,如果为空使用配置中的)
}
```
### SendResponse 结构体
```go
type SendResponse struct {
RequestID string // 请求ID
Code string // 响应码OK表示成功
Message string // 响应消息
BizID string // 业务ID
}
```
## 配置说明
短信配置通过 `config.SMSConfig` 提供:
| 字段 | 类型 | 说明 | 默认值 |
|------|------|------|--------|
| AccessKeyID | string | 阿里云AccessKey ID | - |
| AccessKeySecret | string | 阿里云AccessKey Secret | - |
| Region | string | 区域cn-hangzhou | cn-hangzhou |
| SignName | string | 短信签名 | - |
| TemplateCode | string | 短信模板代码 | - |
| Endpoint | string | 服务端点(可选) | - |
| Timeout | int | 请求超时时间(秒) | 10 |
## 阿里云短信配置步骤
1. **开通阿里云短信服务**
- 登录阿里云控制台
- 开通短信服务
2. **创建AccessKey**
- 在AccessKey管理页面创建AccessKey
- 保存AccessKey ID和Secret
3. **申请短信签名**
- 在短信服务控制台申请签名
- 等待审核通过
4. **创建短信模板**
- 在短信服务控制台创建模板
- 模板格式示例:`您的验证码是${code},有效期${expire}分钟`
- 等待审核通过获取模板代码SMS_123456789
5. **配置参数**
```json
{
"sms": {
"accessKeyId": "your-access-key-id",
"accessKeySecret": "your-access-key-secret",
"region": "cn-hangzhou",
"signName": "您的签名",
"templateCode": "SMS_123456789"
}
}
```
## 模板参数示例
### 验证码模板
模板内容:`您的验证码是${code},有效期${expire}分钟`
```go
templateParam := map[string]string{
"code": "123456",
"expire": "5",
}
```
### 通知模板
模板内容:`您的订单${orderNo}已发货,物流单号:${trackingNo}`
```go
templateParam := map[string]string{
"orderNo": "ORD123456",
"trackingNo": "SF1234567890",
}
```
## 响应码说明
| Code | 说明 |
|------|------|
| OK | 发送成功 |
| InvalidSignName | 签名不存在 |
| InvalidTemplateCode | 模板不存在 |
| InvalidPhoneNumbers | 手机号格式错误 |
| Throttling | 请求被限流 |
| 其他 | 参考阿里云短信服务错误码文档 |
## 注意事项
1. **推荐使用SendRaw方法**
- `SendRaw`方法允许外部完全控制请求参数
- 可以发送任意阿里云短信API支持的请求
- 工具只负责添加系统参数、计算签名并发送
2. **模板参数格式**
- `TemplateParam`可以是`map[string]string`或JSON字符串
- 如果使用JSON字符串必须是有效的JSON格式
- 模板参数必须与模板中定义的变量匹配
3. **AccessKey安全**
- AccessKey具有账户权限请妥善保管
- 建议使用子账户AccessKey并限制权限
4. **签名和模板**
- 签名和模板需要先申请并审核通过
- 模板参数必须与模板中定义的变量匹配
5. **手机号格式**
- 支持国内手机号11位数字
- 支持国际手机号(需要加国家代码)
6. **发送频率**
- 注意阿里云的发送频率限制
- 建议实现发送频率控制
7. **错误处理**
- 所有操作都应该进行错误处理
- 建议记录详细的错误日志
- 注意区分业务错误和系统错误
8. **批量发送**
- 支持一次发送给多个手机号
- 注意批量发送的数量限制
## 完整示例
```go
package main
import (
"fmt"
"log"
"github.com/go-common/config"
"github.com/go-common/sms"
)
func main() {
// 加载配置
cfg, err := config.LoadFromFile("./config.json")
if err != nil {
log.Fatal(err)
}
// 创建短信发送器
smsClient, err := sms.NewSMS(cfg.GetSMS())
if err != nil {
log.Fatal(err)
}
// 发送验证码短信
templateParam := map[string]string{
"code": "123456",
"expire": "5",
}
resp, err := smsClient.SendSimple(
[]string{"13800138000"},
templateParam,
)
if err != nil {
log.Fatal(err)
}
fmt.Printf("发送成功RequestID: %s\n", resp.RequestID)
}
```
## 示例
完整示例请参考 `examples/sms_example.go`