package utils import ( "WorldEpcho/src/config" "WorldEpcho/src/utils/message" "bytes" "crypto/hmac" "crypto/md5" "crypto/sha256" "encoding/base64" "encoding/hex" "encoding/json" "errors" "fmt" unisms "github.com/apistd/uni-go-sdk/sms" "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" "golang.org/x/crypto/scrypt" "io" "io/ioutil" "log" "math/rand" "net" "net/http" "os" "regexp" "strconv" "strings" "time" ) // 获取当前时间 func GetTime() string { tn := time.Now() tf := tn.Format("2006-01-02 15:04:05") return tf } // 获取当前时间戳 默认返回int64类型 func GetTimeStamp() int64 { ts := time.Now().Unix() return ts } // 获取指定时间之前的时间戳 单位秒 func GetTimeStampOpt(num int64) int64 { ts := time.Now().Unix() tst := ts - (num) return tst } // 日期字符串转换成时间戳 func DateConversionStamp(data string) (int64, error) { timeTemplate := "2006-01-02 15:04:05" location, err := time.LoadLocation("Local") if err != nil { return 0, err } theTime, err := time.ParseInLocation(timeTemplate, data, location) if err != nil { return 0, nil } return theTime.Unix(), nil } // 时间戳转日期字符串 func StampConversionDate(stamp int64) string { timeTemplate := "2006-01-02 15:04:05" return time.Unix(stamp, 0).Format(timeTemplate) } // 時間轉切片 func TimeConversionslice(time time.Time) (times []byte) { timestamp := strconv.FormatInt(time.UTC().UnixNano(), 10) slice_times := []byte(timestamp) //把字符串轉成切片 return slice_times } // 验证日期 func VerifyDateFormat(date string) bool { regular := "^[1-9]\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])\\s+(20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d$" reg := regexp.MustCompile(regular) return reg.MatchString(date) } // 验证时间戳 func VerifyStampFormat(stamp int64) bool { regular := "^\\d{1,10}$" reg := regexp.MustCompile(regular) return reg.MatchString(strconv.FormatInt(stamp, 10)) } // 验证邮箱格式 func VerifyEmailFormat(email string) bool { pattern := `^[0-9a-z][_.0-9a-z-]{0,31}@([0-9a-z][0-9a-z-]{0,30}[0-9a-z]\.){1,4}[a-z]{2,4}$` reg := regexp.MustCompile(pattern) return reg.MatchString(email) } // 验证手机号格式 func VerifyMobileFormat(mobileNum string) bool { regular := "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$" reg := regexp.MustCompile(regular) return reg.MatchString(mobileNum) } // 验证姓名 func VerifyNameFormat(name string) bool { regular := "^([\u4e00-\u9fa5]+|([a-z]+\\s?)+)$" reg := regexp.MustCompile(regular) return reg.MatchString(name) } // 验证昵称 func VerifyNickFormat(nick string) bool { regular := "^[a-z][a-z0-9]{2,15}$" reg := regexp.MustCompile(regular) return reg.MatchString(nick) } // 验证密码(密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线)) func VerifyPasswordFormat(password string) bool { regular := "^[a-zA-Z]\\w{5,17}$" reg := regexp.MustCompile(regular) return reg.MatchString(password) } // 密码校验 // ValidatePassword 验证密码是否符合要求 func ValidatePassword(password string) bool { if len(password) < 8 || len(password) > 20 { return false } hasNumber, _ := regexp.MatchString(`[0-9]`, password) hasLetter, _ := regexp.MatchString(`[a-zA-Z]`, password) return hasNumber && hasLetter } // 验证码验证 func VerifyAuthCodeFormat(authCode int) bool { regular := "^\\d{6}$" reg := regexp.MustCompile(regular) return reg.MatchString(strconv.Itoa(authCode)) } // 验证性别 func VerifySexFormat(sex string) bool { regular := "^男$|^女$|^不确定$" reg := regexp.MustCompile(regular) return reg.MatchString(sex) } /* 获取6位随机数 */ func GetAuthCode() int { rand.Seed(time.Now().UnixNano()) code := make([]int, 0) for i := 0; i < 9; i++ { baseCode := rand.Intn(1000000) if baseCode >= 100000 { code = append(code, baseCode) } } return code[rand.Intn(len(code))] } // GenHmacSha256 hmac_sha256加密算法 func GenHmacSha256(secret string, message string) string { h := hmac.New(sha256.New, []byte(secret)) h.Write([]byte(message)) //sha := hex.EncodeToString(h.Sum(nil)) return base64.StdEncoding.EncodeToString(h.Sum(nil)) } /* MD5加密 */ func MD5(str string) string { md5str := fmt.Sprintf("%x", md5.Sum([]byte(str))) return md5str } /* MD5加密 加盐 */ func MD5BySalf(str string, salf string) (md5String string, err error) { hasher := md5.New() // #nosec _, err = hasher.Write([]byte(str)) _, err = hasher.Write([]byte(salf)) if err != nil { return } cipherStr := hasher.Sum(nil) md5String = hex.EncodeToString(cipherStr) return } //多byte拼接 func BytesCombine(pBytes ...[]byte) []byte { return bytes.Join(pBytes, []byte("")) } func EncryptPassword(password string, saltbehind []byte) (string, int) { const keyLen = 32 saltfront := []byte{64, 10, 13} salt := BytesCombine(saltfront, saltbehind) // Key(password []byte, salt []byte, N int, r int, p int, keyLen int) hashPassword, err := scrypt.Key([]byte(password), salt, 32768, 8, 1, 100) // log if err != nil { return "", message.ErrorUserEncrypt } fpw := base64.StdEncoding.EncodeToString(hashPassword) return fpw, message.SUCCESS } // Strval 获取变量的字符串值 // 浮点型 3.0将会转换成字符串3, "3" // 非数值或字符类型的变量将会被转换成JSON格式字符串 //将任意类型转换成字符串 func Strval(value interface{}) string { // interface 转 string var key string if value == nil { return key } switch value.(type) { case float64: ft := value.(float64) key = strconv.FormatFloat(ft, 'f', -1, 64) case float32: ft := value.(float32) key = strconv.FormatFloat(float64(ft), 'f', -1, 64) case int: it := value.(int) key = strconv.Itoa(it) case uint: it := value.(uint) key = strconv.Itoa(int(it)) case int8: it := value.(int8) key = strconv.Itoa(int(it)) case uint8: it := value.(uint8) key = strconv.Itoa(int(it)) case int16: it := value.(int16) key = strconv.Itoa(int(it)) case uint16: it := value.(uint16) key = strconv.Itoa(int(it)) case int32: it := value.(int32) key = strconv.Itoa(int(it)) case uint32: it := value.(uint32) key = strconv.Itoa(int(it)) case int64: it := value.(int64) key = strconv.FormatInt(it, 10) case uint64: it := value.(uint64) key = strconv.FormatUint(it, 10) case string: key = value.(string) case []byte: key = string(value.([]byte)) default: newValue, _ := json.Marshal(value) key = string(newValue) } return key } func ReadUserIP(r *http.Request) string { IPAddress := r.Header.Get("X-Real-Ip") if IPAddress == "" { IPAddress = r.Header.Get("X-Forwarded-For") } if IPAddress == "" { IPAddress = r.RemoteAddr } ip := strings.Split(IPAddress, ":")[0] return ip } func ReadUserIP2(r *http.Request) string { ip := r.Header.Get("X-Forwarded-For") if ip != "" { // X-Forwarded-For可能包含多个IP地址,用逗号分隔,取第一个非空IP地址作为真实IP ips := strings.Split(ip, ",") for _, val := range ips { // 清理空白字符 realIP := strings.TrimSpace(val) // 排除局域网IP地址 if realIP != "" && !strings.HasPrefix(realIP, "10.") && !strings.HasPrefix(realIP, "192.168.") && !strings.HasPrefix(realIP, "172.") && realIP != "localhost" { return realIP } } } ip = r.Header.Get("X-Real-Ip") if ip != "" { return ip } ip, _, _ = net.SplitHostPort(r.RemoteAddr) return ip } const ( TIMEFORMAT = "20060102150405" NORMALTIMEFORMAT = "2006-01-02 15:04:05" ) func GetNormalTimeString(t time.Time) string { return t.Format(NORMALTIMEFORMAT) } func Splite_Sercet(str string) (key string, val string, err bool) { defer func() { // 必须要先声明defer,否则不能捕获到panic异常 if errs := recover(); errs != nil { fmt.Println(errs) // 这里的err其实就是panic传入的内容 err = true } }() str = strings.Split(str, "σ")[0] json := strings.Split(str, ":") key = json[0] json = json[1:] value := strings.Join(json, ":") return key, value, false } func GetTimeByNormalString(timestring string) (time.Time, error) { if timestring == "" { return time.Time{}, nil } return time.ParseInLocation(NORMALTIMEFORMAT, timestring, time.Local) } // map转string func MapToString(param map[string]interface{}) string { dataType, _ := json.Marshal(param) dataString := string(dataType) return dataString } // string 转 map func StringToMap(str string) map[string]string { var tempMap map[string]string err := json.Unmarshal([]byte(str), &tempMap) if err != nil { panic(err) } return tempMap } func Exists(path string) bool { _, err := os.Stat(path) //os.Stat获取文件信息 if err != nil { if os.IsExist(err) { return true } return false } return true } //把一个字符串加密为base64 func Base64Encode(input string) string { return base64.StdEncoding.EncodeToString([]byte(input)) } //从session中获取用户id func GetSessionUserId(ctx *gin.Context) int64 { session := sessions.Default(ctx) userId := session.Get("UserID") if userId == nil { // 处理未找到值的情况,返回错误信息 userId = ctx.Query("id") if userId == "" { ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "Session中未找到用户ID,用户未登录"}) return 0 } } userID, ok := userId.(string) if !ok { // 类型断言失败,处理类型不匹配的情况 ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "用户ID类型错误"}) return 0 } uid, err := strconv.ParseInt(userID, 10, 64) if err != nil { fmt.Println("用户id转换失败:", err) return 0 } return uid } // GenerateInviteCode 根据用户 Id 生成一个唯一的邀请码。 func GenerateInviteCode(userID int64) string { // 获取当前时间的 Unix 时间戳 timestamp := time.Now().Unix() // 将时间戳和用户 Id 连接成字符串 seed := strconv.FormatInt(timestamp, 10) + strconv.FormatInt(userID, 10) // 使用 MD5 算法对字符串进行哈希计算 hash := md5.Sum([]byte(seed)) // 取出前 9 个字符作为邀请码 inviteCode := hex.EncodeToString(hash[:])[:9] return inviteCode } // GenerateUUID 生成一个唯一的 UUID 字符串 func GenerateUUID() string { // 获取当前时间的纳秒级时间戳 timestamp := time.Now().UnixNano() // 生成一个 16 字节的随机数 b := make([]byte, 16) _, err := rand.Read(b) if err != nil { // 处理错误 return "" } // 将时间戳和随机数进行拼接 uuidBytes := append(Int64ToBytes(timestamp), b...) // 使用 MD5 对拼接后的字节序列进行哈希运算 hash := md5.Sum(uuidBytes) // 将哈希值转换为 32 个字符的字符串并返回 return fmt.Sprintf("%x", hash) } // Int64ToBytes 将 int64 类型转换为字节切片 func Int64ToBytes(n int64) []byte { b := make([]byte, 8) for i := uint(0); i < 8; i++ { b[i] = byte(n >> (i * 8)) } return b } // 读心术(任意JSON转Map后取值) // jsonData := []byte(`{ // "name": "Alice", // "age": 25, // "isStudent": true, // "classes": ["Mathematics", "Physics"], // "grades": {"Mathematics": 90, "Physics": [{"A":1}, {"B":2}]} // }`) // // value, err := JSONReader(jsonData, "grades.Physics[0]") // if err != nil { // fmt.Println("Error:", err) // } else { // fmt.Println("Value:", value) // } func JSONReader(jsonData []byte, path string) (interface{}, error) { var data interface{} err := json.Unmarshal(jsonData, &data) if err != nil { return nil, err } pathSegments := splitPath(path) return getValue(data, pathSegments) } func getValue(data interface{}, pathSegments []string) (interface{}, error) { for _, segment := range pathSegments { switch dv := data.(type) { case map[string]interface{}: data = dv[segment] case []interface{}: index, err := strconv.Atoi(segment) if err != nil { return nil, err } if index < 0 || index >= len(dv) { return nil, errors.New("index out of range") } data = dv[index] default: return nil, errors.New("invalid data type for segment: " + segment) } } return data, nil } func splitPath(path string) []string { // Use a regular expression to parse the path and support both dot notation and array indexes re := regexp.MustCompile(`\[(\d+)\]|\.?(\w+)`) matches := re.FindAllStringSubmatch(path, -1) var segments []string for _, match := range matches { // The first group captures index access, the second captures property names if match[1] != "" { segments = append(segments, match[1]) } else if match[2] != "" { segments = append(segments, match[2]) } } return segments } //设置session func SetSession(c *gin.Context, UserId int64) error { session := sessions.Default(c) // 设置有效时间为1800秒 session.Options(sessions.Options{MaxAge: 1800}) // 设置用户ID到会话中 session.Set("UserID", Strval(UserId)) // 保存会话更改 err := session.Save() if err != nil { log.Printf("Error saving session: %v", err) return err } return nil } func generateActivationCode(input string) (string, error) { // 创建一个新的哈希 hasher := md5.New() // 添加当前时间戳 _, err := io.WriteString(hasher, time.Now().Format(time.RFC3339Nano)) if err != nil { return "", err } // 添加一些随机数据 randomBytes := make([]byte, 16) _, err = rand.Read(randomBytes) if err != nil { return "", err } hasher.Write(randomBytes) // 添加用户输入 _, err = io.WriteString(hasher, input) if err != nil { return "", err } // 计算最终的哈希 hash := hasher.Sum(nil) // 转换为16进制字符串并取前6个字符 return hex.EncodeToString(hash)[:6], nil } //生成激活码的工具函数 func GenerateActivationCode(userID int64) string { var letters = []rune("abcdefghijklmnopqrstuvwxyz0123456789") code := make([]rune, 6) rand.Seed(time.Now().UnixNano() + userID) // 使用 userID 作为随机数种子的一部分 for i := range code { code[i] = letters[rand.Intn(len(letters))] } return string(code) } //生成激活码工具函数 func GenerateActivationCode2() string { var letters = []rune("abcdefghijklmnopqrstuvwxyz0123456789") code := make([]rune, 6) rand.Seed(time.Now().UnixNano()) // 使用 userID 作为随机数种子的一部分 for i := range code { code[i] = letters[rand.Intn(len(letters))] } return string(code) } //学校识别码 func GenerateSchoolClassCode() string { var letters = []rune("abcdefghijklmnopqrstuvwxyz0123456789") code := make([]rune, 6) for i := range code { code[i] = letters[config.GlobalRand.Intn(len(letters))] } return string(code) } //展商识别码 func GenerateExhibitorCode() string { var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") code := make([]rune, 6) for i := range code { code[i] = letters[config.GlobalRand.Intn(len(letters))] } return string(code) } func GenerateServiceProviderCode() string { var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") code := make([]rune, 6) for i := range code { code[i] = letters[config.GlobalRand.Intn(len(letters))] } return string(code) } // Int64SliceToStringSlice 将int64类型的切片转换为字符串切片 func Int64SliceToStringSlice(slice []int64) []string { var strSlice []string for _, num := range slice { // 将int64转换为字符串并添加到结果切片中 strSlice = append(strSlice, strconv.FormatInt(num, 10)) } return strSlice } // RandomIDFromSlice 从int64类型的切片中随机选择一个值并返回 func RandomIDFromSlice(slice int) (index int, err error) { // 提供随机数生成器的种子值 rand.Seed(time.Now().UnixNano()) fmt.Println("slice: ", slice) if slice <= 0 { // 返回一个错误,如果slice小于或等于0 return 0, fmt.Errorf("slice 必须大于0") } // 从切片中随机选择一个索引 index = rand.Intn(slice) // 返回选中的值和nil表示没有错误 return index, nil } func IndexOf(slice []string, target string) (int, error) { // 检查切片是否为nil if slice == nil { return -1, errors.New("切片不能为nil") } for i, value := range slice { if value == target { return i, nil // 找到目标,返回下标和nil表示没有错误 } } return -1, nil // 如果没有找到则返回 -1 和nil表示没有错误 } // removeString 函数接受一个字符串数组和一个需要被剔除的字符串,返回剔除后的字符串数组 func RemoveString(slice []string, s string) []string { var result []string // 创建一个空的字符串数组用于存放结果 for _, item := range slice { // 如果当前项目不等于指定的字符串,则将其添加到结果数组中 if item != s { result = append(result, item) } } return result } //判断消息字符串中是否包含某个名字 func ContainsName(names []string, message string) bool { for _, name := range names { if strings.Contains(message, name) { return true } } return false } // GenerateRandomString 生成一个指定长度的随机字符串,包含大小写字母和数字 func GenerateRandomString(n int) (string, error) { const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" bytes := make([]byte, n) _, err := rand.Read(bytes) // 生成一个随机的byte切片 if err != nil { return "", err // 处理生成随机数时可能出现的错误 } for i, b := range bytes { bytes[i] = letters[b%byte(len(letters))] // 将每个byte转换为letters中的一个字符 } return string(bytes), nil } // combineStringsToMap 接收两个字符串数组,将它们按顺序组合成map func CombineStringsToMap(keys []string, values []string) (map[string]string, error) { if len(keys) != len(values) { // 如果数组长度不一致,返回错误 return nil, fmt.Errorf("keys and values must have the same length") } result := make(map[string]string) for i, key := range keys { result[key] = values[i] } return result, nil } // 填充用户信息模板 func FillUserInfoTemplate(template string, values []string) (string, error) { // 将 values 切片转换为 []interface{} 类型 interfaceValues := make([]interface{}, len(values)) for i, v := range values { interfaceValues[i] = v } // 使用 fmt.Sprintf 根据 values 填充模板 filledTemplate := fmt.Sprintf(template, interfaceValues...) return filledTemplate, nil } //判断数组是否包含某个值 func Contains(arr []int64, val int64) bool { for _, v := range arr { if v == val { return true } } return false } // 将两个interface{}类型的数组拼接成键值对类型的map func MergeToMap(keys []interface{}, values []interface{}) (map[string]string, error) { result := make(map[string]string) if len(keys) != len(values) { return nil, fmt.Errorf("keys and values arrays have different lengths") } for i := 0; i < len(keys); i++ { key, ok := keys[i].(string) if !ok { return nil, fmt.Errorf("Key at index %d is not a string", i) } value, ok := values[i].(string) if !ok { return nil, fmt.Errorf("Value at index %d is not a string", i) } result[key] = value } return result, nil } // 判断两个时间戳是否为同年同月 func IsSameYearMonth(timestamp1 int64, timestamp2 int64) bool { // 将时间戳转换为时间对象 time1 := time.Unix(timestamp1, 0) time2 := time.Unix(timestamp2, 0) // 检查年份和月份是否相同 return time1.Year() == time2.Year() && time1.Month() == time2.Month() } func ReadUserIP3(r *http.Request) string { // 获取X-Forwarded-For头部的值 ip := r.Header.Get("X-Forwarded-For") if ip != "" { // X-Forwarded-For可能包含多个IP地址,用逗号分隔,取第一个IP地址作为真实IP ips := strings.Split(ip, ",") for _, val := range ips { // 清理空白字符 realIP := strings.TrimSpace(val) // 验证IP地址是否私有地址或本地地址 if realIP != "" && !IsPrivateIP(realIP) && realIP != "localhost" { return realIP } } } // 获取X-Real-Ip头部的值 ip = r.Header.Get("X-Real-Ip") if ip != "" && !IsPrivateIP(ip) { return ip } // 直接从连接中获取IP地址 ip, _, _ = net.SplitHostPort(r.RemoteAddr) if ip != "" && !IsPrivateIP(ip) { return ip } // 如果所有头部都不存在或是私有地址,返回空字符串 return "" } // isPrivateIP 检查是否为私有IP地址 func IsPrivateIP(ip string) bool { // 检查特定的私有IP地址和环回地址范围。 privateIPBlocks := []*net.IPNet{ {IP: net.ParseIP("10.0.0.0"), Mask: net.CIDRMask(8, 32)}, {IP: net.ParseIP("172.16.0.0"), Mask: net.CIDRMask(12, 32)}, {IP: net.ParseIP("192.168.0.0"), Mask: net.CIDRMask(16, 32)}, {IP: net.ParseIP("127.0.0.0"), Mask: net.CIDRMask(8, 32)}, } // 解析传入的IP地址。 parsedIP := net.ParseIP(ip) if parsedIP == nil { return false } // 检查IP地址是否在私有地址或环回地址的范围内。 for _, block := range privateIPBlocks { if block.Contains(parsedIP) { return true } } return false } // 函数hasUnderscore检查给定的字符串s是否包含下划线,并返回相应的布尔值。 func HasUnderscore(s string) bool { return strings.Contains(s, "_") } // containsID 检查切片中是否包含特定的用户 ID func ContainsUserID(slice []int64, id int64) bool { for _, v := range slice { if v == id { return true } } return false } //sms平台生成短信提示,不用了 func PhoneSendMHTWarningMsg(phone string, timeStr, sname, indexs string) (err error) { //func PhoneSendMHTWarningMsg(phone string) (err error) { var accessKeyId = "n1mEGzBUkLGWBD8BP8eW74yN2iYhMB9M22Xfkt18e3XnfiQaN" var accessKeySecret = "23BJtYGSDzX94LmNJrUubmKEjU7zTdN" //accessKeyId := config.Conf.SmsAccessKeyId //accessKeySecret := config.Conf.SmsAccessKeySecret // 初始化 //通过 unisms.NewClient 方法初始化了一个通信服务的客户端 client,并传入了 accessKeyId 和 accessKeySecret。 client := unisms.NewClient(accessKeyId, accessKeySecret) // 若使用简易验签模式仅传入第一个参数即可 // 构建信息 SMS_24061200003 uniMessage := unisms.BuildMessage() uniMessage.SetTo(phone) // 接收人手机号 uniMessage.SetSignature("觉卿谛语智能科技") // 短信签名 uniMessage.SetTemplateId("b4219e1d") // 短信模板 //生成验证码code,并将其转换为字符串类型,然后将验证码和有效期传入短信模板中。 uniMessage.SetTemplateData(map[string]string{"TIME": timeStr, "Sname": sname, "MHTIndexs": indexs, "ttl": "3"}) // 设置自定义参数 (变量短信) // 发送短信 //调用 client.Send(uniMessage) 方法发送短信,并将返回结果存储在 _ 中,同时检查是否有错误发生,若有则打印错误并返回。 _, err = client.Send(uniMessage) if err != nil { fmt.Println("err => ", err) return err } //fmt.Println(" 短信内容, content: ", content) return err } // 华为云 发送短信的函数 func SendSms_HuaWei(url string, reqData SmsRequest) (*SmsResponse, error) { // 序列化请求数据 jsonData, err := json.Marshal(reqData) if err != nil { return nil, fmt.Errorf("error marshalling request data: %v", err) } // 创建HTTP请求 req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData)) if err != nil { return nil, fmt.Errorf("error creating request: %v", err) } req.Header.Set("Content-Type", "application/json") client := &http.Client{} resp, err := client.Do(req) if err != nil { return nil, fmt.Errorf("error sending request: %v", err) } defer resp.Body.Close() // 读取响应数据 body, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("error reading response body: %v", err) } // 解析响应数据 var response SmsResponse if err := json.Unmarshal(body, &response); err != nil { return nil, fmt.Errorf("error unmarshalling response data: %v", err) } return &response, nil } // 定义请求和响应的结构体 type SmsRequest struct { Account string `json:"account"` Password string `json:"password"` RequestLists []MtSmsMessage `json:"requestLists"` //RequestId string `json:"requestId,omitempty"` //StatusCallback string `json:"statusCallback,omitempty"` } type MtSmsMessage struct { Mobiles []string `json:"mobiles"` TemplateId string `json:"templateId"` TemplateParas map[string]string `json:"templateParas,omitempty"` Signature string `json:"signature"` } type SmsResponse struct { ResultCode string `json:"resultCode"` ResultDesc string `json:"resultDesc,omitempty"` ResultLists []MtSmsMessageRsp `json:"resultLists,omitempty"` } type MtSmsMessageRsp struct { Mobile string `json:"mobile"` ResultCode string `json:"resultCode"` ResultDesc string `json:"resultDesc"` MessageId string `json:"messageId"` } // 华为云短信平台,短信发送功能 func SendMessage_HUAWEICloud(templateParas map[string]string, phones, smsTemplate string) error { // 构建请求数据 url := config.Conf.HUAWEI_SMS_Url //判断 var templateId string switch smsTemplate { case "SMS_24052800005": // 发送短信至教师,MHT短信预警 templateId = "SMS_24052800005" // 短信模板 case "SMS_24061200003": //activeCodeSMS templateId = "SMS_24061200003" } requestData := SmsRequest{ Account: "970027", Password: "QM-jA9(tnBR==eiz", RequestLists: []MtSmsMessage{ { Mobiles: []string{phones}, TemplateId: templateId, //TemplateParas: map[string]string{ // "outTradeNo": outTradeNo, // "activeCode": activeCode, //}, TemplateParas: templateParas, Signature: "【觉卿科技】", }, }, } // 使用SendSms函数发送短信 response, err := SendSms_HuaWei(url, requestData) if err != nil { fmt.Printf("Error sending SMS: %v\n", err) return err } if response.ResultCode == "0" { fmt.Printf("发送消息成功!") } else if response.ResultCode == "100003" { fmt.Printf("参数格式错误!") return errors.New("参数格式错误") } return nil }