package utils import ( "crypto/rand" "crypto/rsa" "crypto/sha512" "encoding/base64" "encoding/hex" "encoding/json" "encoding/pem" "fmt" _ "github.com/go-sql-driver/mysql" "github.com/skip2/go-qrcode" "github.com/wechatpay-apiv3/wechatpay-go/core" "github.com/wechatpay-apiv3/wechatpay-go/services/payments/native" "os" "strings" ) func RandomString(size int, patten string) string { buffer, limit := make([]byte, size), len(patten) for i := 0; i < size; i++ { buffer[i] = patten[RandInt(limit)] } return string(buffer) } func WsEvent(event string, data any) WsMsg { return WsMsg{Event: event, Data: data} } func WsError(msg string) WsMsg { return WsMsg{Event: "__Error_Event__", Data: msg} } func Success(data any) Response { return Response{true, "success", data} } func Fail(msg string) Response { return Response{false, msg, nil} } func ReadConfig(filepath string) Config { config := Config{ Release: false, ServerAddr: "localhost:3080", ServerPrefix: "http://localhost:3080", TimeFormat: "15:04:05", MysqlHost: "127.0.0.1", MysqlPort: 3306, MysqlUser: "wine", MysqlPass: "Wine-Mysql.1000", MysqlDatabase: "wine", RedisHost: "127.0.0.1", RedisPort: 6379, RedisPass: "Wine-Redis.1000", RedisDatabase: 0, WxPayTitle: "贵州醴泉古酿酒业", ServerPrivate: "./server-private.pem", ServerPublic: "./server-public.pem", ClientPrivate: "./client-private.pem", ClientPublic: "./client-public.pem", } file, err := os.Open(filepath) if err != nil { return config } defer func() { err = file.Close() if err != nil { } }() decoder := json.NewDecoder(file) var conf Config err = decoder.Decode(&conf) if err != nil { return config } return conf } func loadPrivate(filename string) (*rsa.PrivateKey, error) { data, err := os.ReadFile(filename) if err != nil { return nil, err } block, _ := pem.Decode(data) if block == nil { return nil, fmt.Errorf("failed to decode[%s] PEM block", filename) } return ParsePrivateKey(block.Bytes) } func loadPublic(filename string) (*rsa.PublicKey, error) { keyData, err := os.ReadFile(filename) if err != nil { return nil, err } block, _ := pem.Decode(keyData) if block == nil { return nil, fmt.Errorf("failed to decode[%s] PEM block", filename) } return ParsePublicKey(block.Bytes) } func privateKeyToPEM(pri *rsa.PrivateKey) string { private := MarshalPrivateKey(pri) block := &pem.Block{ Type: "RSA PRIVATE KEY", Bytes: private, } return string(pem.EncodeToMemory(block)) } func publicKeyToPEM(pub *rsa.PublicKey) (string, error) { public, err := MarshalPublicKey(pub) if err != nil { return "", err } block := &pem.Block{ Type: "PUBLIC KEY", Bytes: public, } return string(pem.EncodeToMemory(block)), nil } func LoadRsaKeyPairs(conf *Config) error { pri1, err := loadPrivate(conf.ServerPrivate) if err != nil { return err } pub1, err := loadPublic(conf.ServerPublic) if err != nil { return err } ClientPub, err = publicKeyToPEM(pub1) if err != nil { return err } ServerPri = pri1 pri2, err := loadPrivate(conf.ServerPrivate) if err != nil { return err } pub2, err := loadPublic(conf.ServerPublic) if err != nil { return err } ClientPri = privateKeyToPEM(pri2) ServerPub = pub2 return nil } func Encrypt(text string) (string, error) { plain := []byte(text) ciphertext, err := rsa.EncryptPKCS1v15(rand.Reader, ServerPub, plain) if err != nil { return "", err } return base64.StdEncoding.EncodeToString(ciphertext), nil } func Decrypt(cipher string) (string, error) { ciphertext, err := base64.StdEncoding.DecodeString(cipher) if err != nil { return "", err } plain, err := rsa.DecryptPKCS1v15(rand.Reader, ServerPri, ciphertext) if err != nil { return "", err } return string(plain), nil } func UnZip(list JsonType) ([]string, []any) { var keys []string var values []any for k, v := range list { keys = append(keys, k) values = append(values, v) } return keys, values } func SqlFields(names []string) string { var res string for _, name := range names { res += fmt.Sprintf("`%s`=?,", name) } ll := len(res) if ll > 0 { return res[:ll-1] } return res } func SqlStringListJoin(values []string) string { var res string for _, item := range values { res += fmt.Sprintf("'%s',", item) } ll := len(res) if ll > 0 { return res[:ll-1] } return res } func SqlUint16ListJoin(values []uint16) string { var res string for _, item := range values { res += fmt.Sprintf("%d,", item) } ll := len(res) if ll > 0 { return res[:ll-1] } return res } func AnyTrans(data any, aim any) error { tmp, err := json.Marshal(data) if err != nil { return err } err = json.Unmarshal(tmp, aim) if err != nil { return err } return nil } func TryWxPay(tradeNo string, name string, cash int) ([]byte, error) { resp, _, err := WxPaySrv.Prepay(WxPayCli, native.PrepayRequest{ Appid: core.String(WxAppId), Mchid: core.String(WxMchId), Description: core.String(WxTitle + "-" + name), OutTradeNo: core.String(tradeNo), NotifyUrl: core.String("https://wine.ifarmcloud.com/api/seller/wxpay"), Amount: &native.Amount{Total: core.Int64(int64(1))}, // cash }, ) if err != nil { fmt.Printf("wxpay error: %s\n", err) return nil, err } return qrcode.Encode(*resp.CodeUrl, qrcode.Medium, 512) } func Format(str string, v ...any) string { return fmt.Sprintf(str, v...) } func HashPassword(password string) string { hash := sha512.New() hash.Write([]byte(password)) hashedPassword := hex.EncodeToString(hash.Sum(nil)) return hashedPassword } func IsPasswordMatch(pwdInDb, pwdFromUser string) bool { return pwdInDb == HashPassword(pwdFromUser) } func Query(SQL string) ([]JsonType, error) { rows, err := Mysql.Query(SQL) if err != nil { return nil, err } columns, _ := rows.Columns() count := len(columns) var values = make([]interface{}, count) for i := range values { var ii interface{} values[i] = &ii } ret := make([]JsonType, 0) for rows.Next() { err = rows.Scan(values...) m := make(JsonType) if err != nil { return nil, err } for i, colName := range columns { m[colName] = *(values[i].(*interface{})) } ret = append(ret, m) } defer func() { _ = rows.Close() }() return ret, nil } func SaveBase64(image, filepath string) (string, string, error) { split := strings.Split(image, ",") info, data := split[0], split[1] decoded, err := base64.StdEncoding.DecodeString(data) if err != nil { return "", "Base64 格式错误", err } ext := strings.Split(info, "/")[1] ext = strings.Split(ext, ";")[0] err = os.WriteFile(filepath+"."+ext, decoded, 0644) if err != nil { return "", "文件存储失败", err } return ext, "", nil }