package models import ( "crypto/aes" "crypto/cipher" craned "crypto/rand" "encoding/base64" "encoding/json" "errors" "fmt" orm "go-admin/common/global" "go-admin/logger" "io" "math/rand" "time" ) // gen:qs // //go:generate goqueryset -in config.go type Config struct { Model Name string `gorm:"unique_index;not null"` Value string `gorm:"size:65535;not null"` } func (m *Config) TableName() string { return "config" } type PayConfig struct { MemberFee uint32 `json:"member_fee"` DepositFee uint32 `json:"deposit_fee"` NotifyUrl string `json:"notify_url"` RefundNotifyUrl string `json:"refund_notify_url"` } const ( ConfigNamePay = "pay_config" // 支付配置 ConfigNameMember = "member_config" // 会员配置 ConfigNameMemberVm = "member_vm_config" // 会员积分配置 ConfigNameAttendanceVm = "attendance_vm_config" // 签到积分配置 ConfigActivityRenewal = "activity_renewal_config" // 活动配置 ConfigRecycleCard = "recycle_card_config" // 回收卡配置 ConfigCooperativePayInfo = "cooperative_pay_info" // 合作商支付设置 ConfigErpOrderShowInfo = "erp_order_show_config" // 零售订单显示设置 ConfigSystemSmsCount = "sms_config" // 获取系统每月短信限额 ) func PayConfigInfo() (*PayConfig, error) { payConfig := new(PayConfig) var configAllocation Config err := orm.Eloquent.Table("config").Where("name=?", ConfigNamePay).Find(&configAllocation).Error //err := NewConfigQuerySet(DB).NameEq(ConfigNamePay).One(&configAllocation) if err != nil { logger.Errorf("err:", err) return payConfig, err } err = json.Unmarshal([]byte(configAllocation.Value), payConfig) if err != nil { logger.Errorf("err:", err) return payConfig, err } return payConfig, nil } type MemberConfig struct { MemberLever uint32 `json:"member_lever"` // 会员等级 MemberFee uint32 `json:"member_fee"` // 会员费 MemberDeposit uint32 `json:"member_deposit"` // 押金 CardMax uint32 `json:"card_max"` } func MemberConfigInfo() ([]MemberConfig, error) { var memberConfigs []MemberConfig var configAllocation Config err := orm.Eloquent.Table("config").Where("name=?", ConfigNameMember).Find(&configAllocation).Error //err := NewConfigQuerySet(DB).NameEq(ConfigNameMember).One(&configAllocation) if err != nil { logger.Errorf("err:", err) return memberConfigs, err } err = json.Unmarshal([]byte(configAllocation.Value), &memberConfigs) if err != nil { logger.Errorf("err:", err) return memberConfigs, err } return memberConfigs, nil } func GetMemberConfig(level uint32) (*MemberConfig, error) { if level == 3 { level = 2 } info, err := MemberConfigInfo() if err != nil { return nil, err } for _, config := range info { if config.MemberLever == level { return &config, nil } } return nil, errors.New("level err") } type MemberVmConfig struct { MemberLever uint32 `json:"member_lever"` // 会员等级 MemberVm uint32 `json:"member_vm"` Invite1Vm uint32 `json:"invite_1_vm"` Invite2Vm uint32 `json:"invite_2_vm"` AutomationMemberVm uint32 `json:"automation_member_vm"` } func memberVmConfigInfo() ([]MemberVmConfig, error) { var memberVmConfigs []MemberVmConfig var configAllocation Config err := orm.Eloquent.Table("config").Where("name=?", ConfigNameMemberVm).Find(&configAllocation).Error //err := NewConfigQuerySet(DB).NameEq(ConfigNameMemberVm).One(&configAllocation) if err != nil { logger.Errorf("err:", err) return memberVmConfigs, err } err = json.Unmarshal([]byte(configAllocation.Value), &memberVmConfigs) if err != nil { logger.Errorf("err:", err) return memberVmConfigs, err } return memberVmConfigs, nil } func GetMemberVmConfig(level uint32) (*MemberVmConfig, error) { if level == 3 { return nil, errors.New("level is 3") } info, err := memberVmConfigInfo() if err != nil { return nil, err } for _, config := range info { if config.MemberLever == level { return &config, nil } } return nil, errors.New("level err") } type AttendanceVmConfig struct { VmDay1 uint32 `json:"vm_day_1"` VmDay2 uint32 `json:"vm_day_2"` VmDay3 uint32 `json:"vm_day_3"` VmDay4 uint32 `json:"vm_day_4"` VmDay5 uint32 `json:"vm_day_5"` VmDay6 uint32 `json:"vm_day_6"` VmDay7 uint32 `json:"vm_day_7"` } func AttendanceVmConfigInfo() (*AttendanceVmConfig, error) { attendanceConfig := new(AttendanceVmConfig) var configAllocation Config err := orm.Eloquent.Table("config").Where("name=?", ConfigNameAttendanceVm).Find(&configAllocation).Error //err := NewConfigQuerySet(DB).NameEq(ConfigNameAttendanceVm).One(&configAllocation) if err != nil { logger.Errorf("err:", err) return attendanceConfig, err } err = json.Unmarshal([]byte(configAllocation.Value), attendanceConfig) if err != nil { logger.Errorf("err:", err) return attendanceConfig, err } return attendanceConfig, nil } func (m *AttendanceVmConfig) Vm(days uint32) uint32 { vm := uint32(0) switch days % 7 { case 1: vm = m.VmDay1 case 2: vm = m.VmDay2 case 3: vm = m.VmDay3 case 4: vm = m.VmDay4 case 5: vm = m.VmDay5 case 6: vm = m.VmDay6 case 0: vm = m.VmDay7 } return vm } type ActivityRenewalConfig struct { CouponValidity int `json:"coupon_validity"` ActivityContinuity int `json:"activity_continuity"` PopTrap int `json:"pop_trap"` // activity_renewal_config } func ActivityRenewalConfigInfo() (ActivityRenewalConfig, error) { activityRenewalConfig := ActivityRenewalConfig{} var configAllocation Config err := orm.Eloquent.Table("config"). Where("name=?", ConfigActivityRenewal).Find(&configAllocation).Error //err := NewConfigQuerySet(DB).NameEq(ConfigActivityRenewal).One(&configAllocation) if err != nil { logger.Errorf("err:", err) return activityRenewalConfig, err } err = json.Unmarshal([]byte(configAllocation.Value), &activityRenewalConfig) if err != nil { logger.Errorf("err:", err) return activityRenewalConfig, err } return activityRenewalConfig, nil } func ActivityRenewalConfigUpdate(activity ActivityRenewalConfig) (ActivityRenewalConfig, error) { bytes, err := json.Marshal(activity) if err != nil { logger.Errorf("err:", err) return activity, err } orm.Eloquent.Table("config"). Where("name=?", ConfigActivityRenewal).Update("Value", string(bytes)) if err != nil { logger.Errorf("err:", err) return activity, err } return activity, nil } func GetActivityRenewalConfig() ActivityRenewalConfig { info, err := ActivityRenewalConfigInfo() if err != nil { logger.Errorf("info err:", err) return info } return info } type RecycleCardConfig struct { RebateRate uint32 `json:"rebate_rate"` } func RecycleCardConfigInfo() (RecycleCardConfig, error) { var recycleConfig RecycleCardConfig var configAllocation Config //err := NewConfigQuerySet(DB).NameEq(ConfigRecycleCard).One(&configAllocation) err := orm.Eloquent.Table("config"). Where("name=?", ConfigRecycleCard).Find(&configAllocation).Error if err != nil { logger.Errorf("err:", err) return recycleConfig, err } err = json.Unmarshal([]byte(configAllocation.Value), &recycleConfig) if err != nil { logger.Errorf("err:", err) return recycleConfig, err } return recycleConfig, nil } func RecycleCardConfigUpdate(recycleConfig RecycleCardConfig) (RecycleCardConfig, error) { bytes, err := json.Marshal(recycleConfig) if err != nil { logger.Errorf("err:", err) return recycleConfig, err } orm.Eloquent.Table("config"). Where("name=?", ConfigRecycleCard).Update("Value", string(bytes)) if err != nil { logger.Errorf("err:", err) return recycleConfig, err } return recycleConfig, nil } // CooperativePayInfo 支付信息 type CooperativePayInfo struct { CooperativeBusinessId uint32 `json:"cooperative_business_id" binding:"required"` // 合作商id UnionPayMerchantId string `json:"union_pay_merchant_id" gorm:"index"` // 聚合支付平台商户号 WxAppId string `json:"wx_app_id" gorm:"index"` // 微信小程序AppID WxAppMchId string `json:"wx_app_mchId" gorm:"index"` // 微信支付商户号 WxAppMchSecret string `json:"wx_app_mchSecret" gorm:"index"` // 微信支付商户密钥 } // SetPayInfo 设置合作商的支付信息(聚合支付、微信支付等) func SetPayInfo(req *CooperativeSetPayInfoReq) error { payInfo := CooperativePayInfo{ CooperativeBusinessId: req.CooperativeBusinessId, UnionPayMerchantId: req.UnionPayMerchantId, WxAppId: req.WxAppId, WxAppMchId: req.WxAppMchId, WxAppMchSecret: req.WxAppMchSecret, } jPayInfo, err := json.Marshal(payInfo) if err != nil { logger.Errorf("CooperativePayInfo marshal err:", logger.Field("err", err)) return err } var configInfo Config err = orm.Eloquent.Table("config").Where("name=?", ConfigCooperativePayInfo).Find(&configInfo).Error if err != nil { logger.Error("query config err:", logger.Field("err", err)) return errors.New("操作失败:" + err.Error()) } if errors.Is(err, RecordNotFound) || configInfo.ID == 0 { // 没有记录则新增 configInfo.Name = ConfigCooperativePayInfo configInfo.Value = string(jPayInfo) err = orm.Eloquent.Create(&configInfo).Error if err != nil { logger.Errorf("create CooperativePayInfo err:", logger.Field("err", err)) return errors.New("保存失败:" + err.Error()) } } else { // 有记录则更新 var updateConfigInfo Config updateConfigInfo.ID = configInfo.ID updateConfigInfo.Name = ConfigCooperativePayInfo updateConfigInfo.Value = string(jPayInfo) err = orm.Eloquent.Model(&Config{}).Where("id = ?", configInfo.ID).Updates(updateConfigInfo).Error if err != nil { logger.Error("update CooperativePayInfo err:", logger.Field("err", err)) return errors.New("保存失败:" + err.Error()) } } return nil } // GetPayInfo 获取合作商的支付信息(聚合支付、微信支付等) func GetPayInfo() (*CooperativePayInfo, error) { payConfig := new(CooperativePayInfo) var configAllocation Config err := orm.Eloquent.Table("config").Where("name=?", ConfigCooperativePayInfo).Find(&configAllocation).Error if err != nil { logger.Errorf("err:", err) return payConfig, err } err = json.Unmarshal([]byte(configAllocation.Value), payConfig) if err != nil { logger.Errorf("err:", err) return payConfig, err } return payConfig, nil } type ErpOrderShowConfig struct { ShowAll string `json:"show_all" binding:"required"` // 展示所有订单配置:ON-打开,OFF-关闭 } type SystemSmsConfig struct { MonthFreeCount uint32 `json:"month_free_count" ` // 每月短信免费额度 } // SetErpOrderShowConfig 设置零售订单展示配置信息 func SetErpOrderShowConfig(req *ErpOrderShowConfig) error { showInfo := ErpOrderShowConfig{ ShowAll: req.ShowAll, } jShowInfo, err := json.Marshal(showInfo) if err != nil { logger.Errorf("ConfigErpOrderShowInfo marshal err:", logger.Field("err", err)) return err } var configInfo Config err = orm.Eloquent.Table("config").Where("name=?", ConfigErpOrderShowInfo).Find(&configInfo).Error if err != nil { logger.Error("query config err:", logger.Field("err", err)) return errors.New("操作失败:" + err.Error()) } if errors.Is(err, RecordNotFound) || configInfo.ID == 0 { // 没有记录则新增 configInfo.Name = ConfigErpOrderShowInfo configInfo.Value = string(jShowInfo) err = orm.Eloquent.Create(&configInfo).Error if err != nil { logger.Errorf("create ConfigErpOrderShowInfo err:", logger.Field("err", err)) return errors.New("保存失败:" + err.Error()) } } else { // 有记录则更新 var updateConfigInfo Config updateConfigInfo.ID = configInfo.ID updateConfigInfo.Name = ConfigErpOrderShowInfo updateConfigInfo.Value = string(jShowInfo) err = orm.Eloquent.Model(&Config{}).Where("id = ?", configInfo.ID).Updates(updateConfigInfo).Error if err != nil { logger.Error("update ConfigErpOrderShowInfo err:", logger.Field("err", err)) return errors.New("保存失败:" + err.Error()) } } return nil } // GetErpOrderShowConfig 获取零售订单展示配置信息 func GetErpOrderShowConfig() (*ErpOrderShowConfig, error) { erpOrderShowConfig := new(ErpOrderShowConfig) var configAllocation Config err := orm.Eloquent.Table("config").Where("name=?", ConfigErpOrderShowInfo).Find(&configAllocation).Error if err != nil { logger.Errorf("err:", err) return erpOrderShowConfig, err } err = json.Unmarshal([]byte(configAllocation.Value), erpOrderShowConfig) if err != nil { logger.Errorf("err:", err) return erpOrderShowConfig, err } return erpOrderShowConfig, nil } type DefaultUserNameAndPasswordResp struct { Username string `json:"username"` // 用户名 Password string `json:"password"` // 密码 } // GetDefaultUserNameAndPassword 获取合作商默认用户名和密码 func GetDefaultUserNameAndPassword() (*DefaultUserNameAndPasswordResp, error) { username, password := generateUsernameAndPassword() key := []byte("NfOM3p64ThVKX7Ck34R1mOeiniwuCwua") // 加密用户名和密码 encryptedUsername, err := encrypt(username, key) if err != nil { fmt.Println("Error encrypting username:", err) return nil, err } encryptedPassword, err := encrypt(password, key) if err != nil { fmt.Println("Error encrypting password:", err) return nil, err } return &DefaultUserNameAndPasswordResp{ Username: encryptedUsername, Password: encryptedPassword, }, nil } // 生成指定长度的随机字符串 func generateRandomString(length int) string { rand.Seed(time.Now().UnixNano()) characters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") result := make([]rune, length) for i := range result { result[i] = characters[rand.Intn(len(characters))] } return string(result) } // 生成用户名和密码 func generateUsernameAndPassword() (string, string) { var username, password string for { username = generateRandomString(4) var count int64 err := orm.Eloquent.Table("cooperative_business").Where("username = ?", username).Count(&count).Error if err == nil && count > 0 { continue } break } for { password = generateRandomString(6) var count int64 err := orm.Eloquent.Table("cooperative_business").Where("password = ?", password).Count(&count).Error if err == nil && count > 0 { continue } break } return username, password } // 加密字符串 func encrypt(plainText string, key []byte) (string, error) { block, err := aes.NewCipher(key) if err != nil { return "", err } // 对明文进行填充 plainBytes := []byte(plainText) padLen := aes.BlockSize - len(plainBytes)%aes.BlockSize padText := append(plainBytes, bytesRepeating(byte(padLen), padLen)...) // 创建一个加密分组链,使用 key 进行加密 cipherText := make([]byte, aes.BlockSize+len(padText)) iv := cipherText[:aes.BlockSize] if _, err := io.ReadFull(craned.Reader, iv); err != nil { return "", err } cfb := cipher.NewCFBEncrypter(block, iv) cfb.XORKeyStream(cipherText[aes.BlockSize:], padText) return base64.URLEncoding.EncodeToString(cipherText), nil } // bytesRepeating 重复生成一个字节的切片 func bytesRepeating(b byte, count int) []byte { result := make([]byte, count) for i := 0; i < count; i++ { result[i] = b } return result } // 解密字符串 func decrypt(cipherText string, key []byte) (string, error) { cipherBytes, err := base64.URLEncoding.DecodeString(cipherText) if err != nil { return "", err } block, err := aes.NewCipher(key) if err != nil { return "", err } if len(cipherBytes) < aes.BlockSize { return "", fmt.Errorf("cipher text too short") } iv := cipherBytes[:aes.BlockSize] cipherBytes = cipherBytes[aes.BlockSize:] cfb := cipher.NewCFBDecrypter(block, iv) cfb.XORKeyStream(cipherBytes, cipherBytes) // 去除填充部分 padLen := int(cipherBytes[len(cipherBytes)-1]) if padLen < 1 || padLen > aes.BlockSize { return "", fmt.Errorf("invalid padding length") } return string(cipherBytes[:len(cipherBytes)-padLen]), nil } // GetSystemSmsConfig 获取系统每月短信限额 func GetSystemSmsConfig() (int, error) { smsConfig := new(SystemSmsConfig) var configAllocation Config err := orm.Eloquent.Table("config").Where("name=?", ConfigSystemSmsCount).Find(&configAllocation).Error if err != nil { logger.Errorf("GetSystemSmsConfig err:", err) return 0, err } err = json.Unmarshal([]byte(configAllocation.Value), smsConfig) if err != nil { logger.Errorf("GetSystemSmsConfig err:", err) return int(smsConfig.MonthFreeCount), err } return int(smsConfig.MonthFreeCount), nil }