add admin
This commit is contained in:
+10
-5
@@ -25,11 +25,16 @@ var (
|
||||
currentMd5 string
|
||||
)
|
||||
|
||||
func GetConfig(key string) interface{} { return runViper.Get(key) }
|
||||
func GetConfigString(key string) string { return runViper.GetString(key) }
|
||||
func GetConfigInt(key string) int { return runViper.GetInt(key) }
|
||||
func GetConfigInt64(key string) int64 { return runViper.GetInt64(key) }
|
||||
func GetConfigBool(key string) bool { return runViper.GetBool(key) }
|
||||
func GetConfig(key string) interface{} { return runViper.Get(key) }
|
||||
func GetConfigString(key string) string {
|
||||
data := make(map[string]string)
|
||||
data["encrypt.data_key"] = "u2t9T3luZtoRfhBstkFN6TiIMW38BA8a"
|
||||
data["encrypt_key"] = "M17fcaPeHDr05H17fcaPH1deDH17l3Bd"
|
||||
return data[key]
|
||||
}
|
||||
func GetConfigInt(key string) int { return runViper.GetInt(key) }
|
||||
func GetConfigInt64(key string) int64 { return runViper.GetInt64(key) }
|
||||
func GetConfigBool(key string) bool { return runViper.GetBool(key) }
|
||||
|
||||
func InitConfig() {
|
||||
loadOnce.Do(func() {
|
||||
|
||||
@@ -75,3 +75,106 @@ func HmacSha256ToHex(key string, data string) string {
|
||||
func HmacSha256ToBase64(key string, data string) string {
|
||||
return base64.URLEncoding.EncodeToString(HmacSha256(key, data))
|
||||
}
|
||||
|
||||
func EncryptPhone(phone string) (string, Error) {
|
||||
// 提取各部分
|
||||
prefix := phone[NumberZero:NumberThree] // 前三位
|
||||
middle := phone[NumberThree:NumberSeven] // 中四位
|
||||
suffix := phone[NumberSeven:NumberEleven] // 尾四位
|
||||
newPhone := StringEmpty
|
||||
username, cErr := Crypto{}.AESEncryptECB(prefix)
|
||||
if cErr != nil {
|
||||
return StringEmpty, cErr
|
||||
}
|
||||
newPhone = username
|
||||
username, cErr = Crypto{}.AESEncryptECB(middle)
|
||||
if cErr != nil {
|
||||
return StringEmpty, cErr
|
||||
}
|
||||
newPhone += username
|
||||
username, cErr = Crypto{}.AESEncryptECB(suffix)
|
||||
if cErr != nil {
|
||||
return StringEmpty, cErr
|
||||
}
|
||||
newPhone += username
|
||||
return newPhone, nil
|
||||
}
|
||||
|
||||
func DecryptPhone(phone string) (string, Error) {
|
||||
// 提取各部分
|
||||
prefix := phone[NumberZero:24] // 前三位
|
||||
middle := phone[24:48] // 中四位
|
||||
suffix := phone[48:72] // 尾四位
|
||||
newPhone := StringEmpty
|
||||
username, cErr := Crypto{}.AESDecryptECB(prefix)
|
||||
if cErr != nil {
|
||||
return StringEmpty, cErr
|
||||
}
|
||||
newPhone = username
|
||||
username, cErr = Crypto{}.AESDecryptECB(middle)
|
||||
if cErr != nil {
|
||||
return StringEmpty, cErr
|
||||
}
|
||||
newPhone += username
|
||||
username, cErr = Crypto{}.AESDecryptECB(suffix)
|
||||
if cErr != nil {
|
||||
return StringEmpty, cErr
|
||||
}
|
||||
newPhone += username
|
||||
return newPhone, nil
|
||||
}
|
||||
|
||||
func getSearchPhone(mobile string) string {
|
||||
phone := StringEmpty
|
||||
if len(mobile) == 11 {
|
||||
prefix := mobile[NumberZero:3] // 前三位
|
||||
username, cErr := Crypto{}.AESEncryptECB(prefix)
|
||||
if cErr == nil {
|
||||
phone = username
|
||||
}
|
||||
prefix = mobile[NumberThree:NumberSeven] // 中四位
|
||||
username, cErr = Crypto{}.AESEncryptECB(prefix)
|
||||
if cErr == nil {
|
||||
phone += username
|
||||
}
|
||||
prefix = mobile[NumberSeven:NumberEleven] // 尾四位
|
||||
username, cErr = Crypto{}.AESEncryptECB(prefix)
|
||||
if cErr == nil {
|
||||
phone += username
|
||||
}
|
||||
} else if len(mobile) > NumberTwo {
|
||||
prefix := mobile[NumberZero:NumberThree] //前三位
|
||||
if len(mobile) == NumberFour {
|
||||
prefix = mobile[NumberZero:NumberFour] // 前四位
|
||||
}
|
||||
username, cErr := Crypto{}.AESEncryptECB(prefix)
|
||||
if cErr == nil {
|
||||
phone = username
|
||||
}
|
||||
if len(mobile) > NumberFour {
|
||||
prefix = mobile[NumberThree:] // 中四位
|
||||
username, cErr = Crypto{}.AESEncryptECB(prefix)
|
||||
if cErr == nil {
|
||||
phone += username
|
||||
}
|
||||
}
|
||||
}
|
||||
return phone
|
||||
}
|
||||
|
||||
// GetRandstring 取得随机字符串:使用字符串拼接
|
||||
func GetRandstring(length int) string {
|
||||
if length < 1 {
|
||||
return StringEmpty
|
||||
}
|
||||
char := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
charArr := strings.Split(char, StringEmpty)
|
||||
charlen := len(charArr)
|
||||
ran := rand.New(rand.NewSource(time.Now().Unix()))
|
||||
|
||||
var rchar string = StringEmpty
|
||||
for i := 1; i <= length; i++ {
|
||||
rchar = rchar + charArr[ran.Intn(charlen)]
|
||||
}
|
||||
return rchar
|
||||
}
|
||||
|
||||
@@ -1,305 +0,0 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/smtp"
|
||||
|
||||
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
|
||||
dysmsapi20170525 "github.com/alibabacloud-go/dysmsapi-20170525/v3/client"
|
||||
"github.com/alibabacloud-go/tea/tea"
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
// 短信签名常量
|
||||
const (
|
||||
//SignLone = "爱萝湾"
|
||||
SignLone = "爱萝湾上海科技有限公司"
|
||||
)
|
||||
|
||||
// 短信模板CODE常量
|
||||
const (
|
||||
SmsCode = "SMS_506160477"
|
||||
SmsPwd = "SMS_506200455"
|
||||
)
|
||||
|
||||
// 状态码常量(模拟PHP中的Code类)
|
||||
const (
|
||||
CodeOK = 0 // 成功状态码
|
||||
CodeError = -1 // 错误状态码
|
||||
)
|
||||
|
||||
// ResponseData 短信发送返回结构体
|
||||
type ResponseData struct {
|
||||
Code int `json:"code"`
|
||||
Msg interface{} `json:"msg"`
|
||||
}
|
||||
|
||||
type EmailMsg struct {
|
||||
To []string // 收件人
|
||||
Cc []string // 抄送
|
||||
Bcc []string // 密送
|
||||
Subject string // 标题
|
||||
Body string // 正文,支持html
|
||||
IsHTML bool // 是否HTML格式
|
||||
}
|
||||
|
||||
// CreateClient 创建阿里云短信客户端
|
||||
func CreateClient() (*dysmsapi20170525.Client, error) {
|
||||
// 加载.env文件(如果需要)
|
||||
_ = godotenv.Load()
|
||||
|
||||
key := GetConfigString("sms.sms_ali_api_key")
|
||||
secret := GetConfigString("sms.sms_ali_api_secret")
|
||||
// 初始化配置
|
||||
config := &openapi.Config{
|
||||
// 从环境变量获取AccessKey ID
|
||||
AccessKeyId: &key,
|
||||
// 从环境变量获取AccessKey Secret
|
||||
AccessKeySecret: &secret,
|
||||
}
|
||||
// 设置短信服务接入点
|
||||
config.Endpoint = tea.String("dysmsapi.aliyuncs.com")
|
||||
|
||||
// 创建客户端
|
||||
client, err := dysmsapi20170525.NewClient(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return client, nil
|
||||
}
|
||||
|
||||
// SendSMS 发送短信主方法
|
||||
// mobile: 手机号
|
||||
// code: 短信模板CODE
|
||||
// data: 模板参数(map格式)
|
||||
// sign: 短信签名(可选,默认使用SignLone)
|
||||
func SendSMS(mobile, code string, data map[string]interface{}, sign ...string) ResponseData {
|
||||
test := GetConfigBool("sms.sms_test")
|
||||
retData := ResponseData{
|
||||
Code: CodeOK,
|
||||
Msg: "",
|
||||
}
|
||||
if test {
|
||||
return retData
|
||||
}
|
||||
// 设置默认签名
|
||||
signName := SignLone
|
||||
name := GetConfigString("sms.sms_sign")
|
||||
if name != "" {
|
||||
signName = name
|
||||
}
|
||||
|
||||
if len(sign) > 0 && sign[0] != "" {
|
||||
signName = sign[0]
|
||||
}
|
||||
|
||||
// 创建客户端
|
||||
client, err := CreateClient()
|
||||
if err != nil {
|
||||
return ResponseData{
|
||||
Code: CodeError,
|
||||
Msg: fmt.Sprintf("创建客户端失败: %s", err.Error()),
|
||||
}
|
||||
}
|
||||
|
||||
// 转换模板参数为JSON字符串
|
||||
templateParam, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return ResponseData{
|
||||
Code: CodeError,
|
||||
Msg: fmt.Sprintf("参数JSON编码失败: %s", err.Error()),
|
||||
}
|
||||
}
|
||||
|
||||
// 构建发送短信请求
|
||||
sendSmsRequest := &dysmsapi20170525.SendSmsRequest{
|
||||
PhoneNumbers: tea.String(mobile),
|
||||
SignName: tea.String(signName),
|
||||
TemplateCode: tea.String(code),
|
||||
TemplateParam: tea.String(string(templateParam)),
|
||||
}
|
||||
|
||||
Logger.Error(signName, "m=", mobile, "<UNK>:", sendSmsRequest, "2=", code, "tmpo:", string(templateParam))
|
||||
|
||||
// 发送短信
|
||||
response, err := client.SendSms(sendSmsRequest)
|
||||
if err != nil {
|
||||
// 处理错误
|
||||
retData.Code = CodeError
|
||||
retData.Msg = fmt.Sprintf("发送短信失败: %s", err.Error())
|
||||
return retData
|
||||
}
|
||||
|
||||
statusCode := *response.StatusCode
|
||||
|
||||
// 检查响应状态
|
||||
if statusCode != 200 {
|
||||
retData.Code = CodeError
|
||||
}
|
||||
|
||||
// 将响应转换为map返回
|
||||
retData.Msg = map[string]interface{}{
|
||||
"StatusCode": response.StatusCode,
|
||||
"Body": response.Body,
|
||||
}
|
||||
|
||||
return retData
|
||||
}
|
||||
|
||||
// 简化调用示例(可选)
|
||||
// SendCodeSMS 发送验证码短信
|
||||
func SendCodeSMS(mobile string, code string) ResponseData {
|
||||
data := map[string]interface{}{
|
||||
"code": code,
|
||||
}
|
||||
code = getConfig("sms.sms_code_sign")
|
||||
if code == "" {
|
||||
code = SmsCode
|
||||
}
|
||||
return SendSMS(mobile, code, data)
|
||||
}
|
||||
|
||||
func SendCodeMail(msg EmailMsg) ResponseData {
|
||||
user := GetConfigString("sms.sms_mail_user")
|
||||
pwd := GetConfigString("sms.sms_mail_pwd")
|
||||
host := GetConfigString("sms.sms_mail_host")
|
||||
port := GetConfigInt("sms.sms_mail_port")
|
||||
name := GetConfigString("sms.sms_mail_show_name")
|
||||
auth := smtp.PlainAuth("", user, pwd, host)
|
||||
from := fmt.Sprintf("%s <%s>", name, user)
|
||||
// 构建邮件头部
|
||||
var header string
|
||||
header += fmt.Sprintf("From: %s\r\n", from)
|
||||
header += fmt.Sprintf("To: %s\r\n", joinStrings(msg.To, ","))
|
||||
if len(msg.Cc) > 0 {
|
||||
header += fmt.Sprintf("Cc: %s\r\n", joinStrings(msg.Cc, ","))
|
||||
}
|
||||
if len(msg.Bcc) > 0 {
|
||||
header += fmt.Sprintf("Bcc: %s\r\n", joinStrings(msg.Bcc, ","))
|
||||
}
|
||||
header += fmt.Sprintf("Subject: %s\r\n", msg.Subject)
|
||||
|
||||
contentType := "text/plain; charset=utf-8"
|
||||
if msg.IsHTML {
|
||||
contentType = "text/html; charset=utf-8"
|
||||
}
|
||||
header += fmt.Sprintf("Content-Type: %s\r\n\r\n", contentType)
|
||||
fullMsg := []byte(header + msg.Body)
|
||||
|
||||
tlsConfig := &tls.Config{
|
||||
ServerName: host,
|
||||
}
|
||||
addr := fmt.Sprintf("%s:%d", host, port)
|
||||
|
||||
// 1. 先建立SSL连接(465端口)
|
||||
conn, err := tls.Dial("tcp", addr, tlsConfig)
|
||||
if err != nil {
|
||||
Logger.Error("tls dial err:", err)
|
||||
return ResponseData{
|
||||
Code: CodeError,
|
||||
Msg: err.Error(),
|
||||
}
|
||||
}
|
||||
// 2. 关键:用加密连接创建smtp client
|
||||
client, err := smtp.NewClient(conn, host)
|
||||
if err != nil {
|
||||
_ = conn.Close()
|
||||
Logger.Error("smtp.NewClient err:", err)
|
||||
return ResponseData{
|
||||
Code: CodeError,
|
||||
Msg: err.Error(),
|
||||
}
|
||||
}
|
||||
// 由client统一管理连接关闭
|
||||
defer client.Close()
|
||||
|
||||
if err = client.Auth(auth); err != nil {
|
||||
Logger.Error("client.Auth err:", err)
|
||||
return ResponseData{
|
||||
Code: CodeError,
|
||||
Msg: err.Error(),
|
||||
}
|
||||
}
|
||||
|
||||
if err = client.Mail(user); err != nil {
|
||||
Logger.Error("client.Mail err:", err)
|
||||
return ResponseData{
|
||||
Code: CodeError,
|
||||
Msg: err.Error(),
|
||||
}
|
||||
}
|
||||
|
||||
receivers := append(append(msg.To, msg.Cc...), msg.Bcc...)
|
||||
for _, r := range receivers {
|
||||
if err = client.Rcpt(r); err != nil {
|
||||
Logger.Error("client.Rcpt err:", err, "rcpt:", r)
|
||||
return ResponseData{
|
||||
Code: CodeError,
|
||||
Msg: err.Error(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
w, err := client.Data()
|
||||
if err != nil {
|
||||
Logger.Error("client.Data err:", err)
|
||||
return ResponseData{
|
||||
Code: CodeError,
|
||||
Msg: err.Error(),
|
||||
}
|
||||
}
|
||||
_, err = w.Write(fullMsg)
|
||||
if err != nil {
|
||||
Logger.Error("write mail body err:", err)
|
||||
return ResponseData{
|
||||
Code: CodeError,
|
||||
Msg: err.Error(),
|
||||
}
|
||||
}
|
||||
err = w.Close()
|
||||
if err != nil {
|
||||
Logger.Error("w.Close err:", err)
|
||||
return ResponseData{
|
||||
Code: CodeError,
|
||||
Msg: err.Error(),
|
||||
}
|
||||
}
|
||||
|
||||
err = client.Quit()
|
||||
if err != nil {
|
||||
Logger.Error("client.Quit err:", err)
|
||||
return ResponseData{
|
||||
Code: CodeError,
|
||||
Msg: "smtp quit failed: " + err.Error(),
|
||||
}
|
||||
}
|
||||
return ResponseData{
|
||||
Code: CodeOK,
|
||||
Msg: "",
|
||||
}
|
||||
}
|
||||
|
||||
func joinStrings(arr []string, sep string) string {
|
||||
if len(arr) == 0 {
|
||||
return ""
|
||||
}
|
||||
res := arr[0]
|
||||
for i := 1; i < len(arr); i++ {
|
||||
res += sep + arr[i]
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// SendPwdSMS 发送密码相关短信
|
||||
func SendPwdSMS(mobile string, pwd string) ResponseData {
|
||||
data := map[string]interface{}{
|
||||
"code": pwd,
|
||||
}
|
||||
code := getConfig("sms.sms_pwd_sign")
|
||||
if code == "" {
|
||||
code = SmsPwd
|
||||
}
|
||||
return SendSMS(mobile, code, data)
|
||||
}
|
||||
+12
-5
@@ -17,6 +17,9 @@ const (
|
||||
NumberSeven = 7
|
||||
NumberEight = 8
|
||||
NumberNine = 9
|
||||
NumberTen = 10
|
||||
NumberEleven = 11
|
||||
NumberTwelve = 12
|
||||
NumberSixteen = 16
|
||||
NumberThirtyTwo = 32
|
||||
|
||||
@@ -31,6 +34,9 @@ const (
|
||||
CentralHorizontalLine = " - "
|
||||
DecollatorEqual = "="
|
||||
StringEmpty = ""
|
||||
StringDot = "."
|
||||
StringStatusOk = "1"
|
||||
StringStatusNo = "2"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -52,10 +58,14 @@ const (
|
||||
|
||||
var (
|
||||
//新使用方法
|
||||
Ok = Status{Code: 10000, Msg: "OK"}
|
||||
Ok = Status{Code: 10000, Msg: "OK"}
|
||||
Fail = Status{Code: 999, Msg: "fail"}
|
||||
ErrorParams = Status{Code: 10001, Msg: "缺少参数或传值不对"}
|
||||
ErrorEncryptAesError = Status{Code: 10001, Msg: "加密失败"}
|
||||
ErrorNotFund = Status{Code: 11001, Msg: "not fund"}
|
||||
ErrorExistUser = Status{Code: 10009, Msg: "账号或手机号已存在"}
|
||||
|
||||
// 基础类
|
||||
Fail = NewError(999, "fail")
|
||||
ErrorExist = NewError(998, "已存在")
|
||||
ErrorOvertime = NewError(997, "请求已超时")
|
||||
ErrorDataTransform = NewError(996, "数据转换失败")
|
||||
@@ -63,7 +73,6 @@ var (
|
||||
ErrorWecomHttpError = NewError(994, "企业微信请求失败")
|
||||
|
||||
// 参数类
|
||||
ErrorMissingParams = NewError(10001, "缺少参数")
|
||||
ErrorReasonParams = NewError(10001, "原因不能为空")
|
||||
ErrorPwdError = NewError(10002, "密码错误")
|
||||
ErrorNoLogin = NewError(10003, "没有登录")
|
||||
@@ -74,14 +83,12 @@ var (
|
||||
ErrorAuthority = NewError(10008, "没有权限")
|
||||
ErrorMobileError = NewError(10009, "手机号不对")
|
||||
ErrorEncryptMissingKey = NewError(10010, "加密密钥错误")
|
||||
ErrorEncryptAesError = NewError(10011, "加密失败")
|
||||
ErrorDecryptAesError = NewError(10012, "解密失败")
|
||||
ErrorEncryptAesKeyError = NewError(10013, "AESKey失败")
|
||||
ErrorEncryptBase64Error = NewError(10014, "解码失败")
|
||||
ErrorNameInexistence = NewError(10015, "账号不存在")
|
||||
|
||||
// ErrorNotFund 数据类
|
||||
ErrorNotFund = NewError(11001, "not fund")
|
||||
ErrorNoChange = NewError(11002, "没有改变")
|
||||
ErrorDataIsExist = NewError(11004, "数据已存在")
|
||||
ErrorRepeatPayment = NewError(11005, "不能重复支付")
|
||||
|
||||
Reference in New Issue
Block a user