1.零售尊享会员功能开发已完成;

This commit is contained in:
chenlin 2024-09-14 17:37:22 +08:00
parent 9826ce9c2c
commit 27068279ce
27 changed files with 1131 additions and 624 deletions

View File

@ -34,13 +34,15 @@ type config struct {
DBPassword string
DBName string
WxAppId string
WxAppSecret string
WxMchID string
WxMchSecret string
WxCertFile string
WxKeyFile string
WxRootCaFile string
WxAppId string
WxAppSecret string
WxMchID string
WxMchSecret string
WxDwMchID string
WxDwMchSecret string
WxCertFile string
WxKeyFile string
WxRootCaFile string
ApplicationAppId string
ApplicationAppSecret string
@ -126,10 +128,12 @@ func initConfig() {
DBPassword: viper.GetString("db.password"),
DBName: viper.GetString("db.db_name"),
WxAppId: viper.GetString("wx.app_id"),
WxAppSecret: viper.GetString("wx.app_secret"),
WxMchID: viper.GetString("wx.app_mchId"),
WxMchSecret: viper.GetString("wx.app_mchSecret"),
WxAppId: viper.GetString("wx.app_id"),
WxAppSecret: viper.GetString("wx.app_secret"),
WxMchID: viper.GetString("wx.app_mchId"),
WxMchSecret: viper.GetString("wx.app_mchSecret"),
WxDwMchID: viper.GetString("wx.app_mchId_dw"),
WxDwMchSecret: viper.GetString("wx.app_mchSecret_dw"),
//WxCertFile: viper.GetString("wx.wx_pay.cert_file"),
//WxKeyFile: viper.GetString("wx.wx_pay.key_file"),
//WxRootCaFile: viper.GetString("wx.wx_pay.root_ca_file"),

View File

@ -78,8 +78,11 @@ func AuthLogin(c *gin.Context) {
fmt.Println("InviteUid:", req.InviteUid)
nowTime := time.Now()
couponFlag := false
// 不存在则创建新用户
if sqlErr == model.RecordNotFound {
couponFlag = true
// 通过openid查询是否有历史遗留数据有openid但是手机号为空
_ = model.NewUserQuerySet(model.DB).WxOpenIDEq(resp.OpenID).One(&user)
if user.WxOpenID == resp.OpenID && user.Tel == "" {
@ -209,6 +212,8 @@ func AuthLogin(c *gin.Context) {
//return
} else {
if user.WxOpenID == "" { // 微信openid为空只是线下购物时新建了用户则更新补充数据
couponFlag = true
user.WxOpenID = resp.OpenID
user.WxUnionID = resp.UnionID
user.LastLoginAt = nowTime
@ -226,6 +231,48 @@ func AuthLogin(c *gin.Context) {
}
}
if couponFlag { // 新用户发放零售优惠券
// 发放优惠券
var coupons []model.Coupon
err = model.NewCouponQuerySet(model.DB).ActivityIdEq(model.CommonSaleActivityId).All(&coupons)
if err != nil {
logger.Error("coupons err:", err)
RespJson(c, status.InternalServerError, nil)
return
}
for i, _ := range coupons {
couponCode, err := utils.GenerateRandomNumber19()
if err != nil {
logger.Error("GenerateRandomNumber19err:", err)
}
userCoupon := &model.UserCoupon{
Uid: user.Uid,
CouponId: coupons[i].ID,
CouponType: coupons[i].CouponType,
ActivityType: coupons[i].ActivityType,
ActivityId: coupons[i].ActivityId,
Value: coupons[i].Value,
State: 1,
ActiveStart: time.Now(),
ActiveEnd: time.Now().AddDate(0, 0, 7),
UseTime: time.Time{},
MemberLevel: coupons[i].MemberLevel,
Approach: 0,
PromotionalSales: 0,
RedeemCode: "",
CategoryNumber: coupons[i].CategoryNumber,
Code: couponCode,
}
err = model.DB.Create(userCoupon).Error
if err != nil {
logger.Error("user coupon err:", err)
continue
}
}
}
if req.InviteUid != 0 && req.InviteUid != user.Uid && user.Uid != 0 { // 入参有邀请人id且非本人
inviteUser := model.GetUserByUid(req.InviteUid)
effectiveStoreInfo, err := model.GetUserEffectiveStore(req.InviteUid)
@ -1069,7 +1116,7 @@ func UserCodeToCoupon(c *gin.Context) {
}
var coupons []model.Coupon
err = model.NewCouponQuerySet(model.DB).ActivityIdEq(4).All(&coupons)
err = model.NewCouponQuerySet(model.DB).ActivityIdEq(model.OpenMemberActivityId).All(&coupons)
if err != nil {
logger.Error("coupons err:", err)
RespJson(c, status.InternalServerError, nil)

View File

@ -308,9 +308,18 @@ func PushWXPayNotice(c *gin.Context) {
return
}
if notifyInfo.Sign != correctSign {
logger.Error("PushWXPayNotice sign verification fail")
RespBodyXML(c, ret)
return
correctSign, err = PayCallBackHandle(notifyInfo, config.AppConfig.WxDwMchSecret)
if err != nil {
logger.Error("PushWXPayNotice sign create fail")
RespBodyXML(c, ret)
return
}
if notifyInfo.Sign != correctSign {
logger.Error("PushWXPayNotice sign verification fail")
RespBodyXML(c, ret)
return
}
}
fundRecord := new(model.FundRecord)
if notifyInfo.Attach == wxpay.WxPayRentCard {
@ -1305,6 +1314,315 @@ func PushWXPayNotice(c *gin.Context) {
fundRecord.Remark = "购买运费包"
}
if notifyInfo.Attach == wxpay.WxPayPrivilegeMember {
logger.Info("开通尊享会员 支付成功:")
logger.Info("订单号:", notifyInfo.OutTradeNo)
record := &model.UserOpenMemberRecord{OpenNo: notifyInfo.OutTradeNo}
err := record.GetByOpenNo()
if err != nil {
logger.Error("err:", err)
}
if record.State == 2 {
ret.ReturnCode = "SUCCESS"
RespBodyXML(c, ret)
return
}
fundRecord.Uid = record.Uid
fundRecord.FundType = model.FundTypePrivilegeMemberFee
fundRecord.Remark = "尊享会员费"
memberRecord := &model.UserMemberRecord{
Uid: record.Uid,
AfterMemberLevel: record.MemberLevel,
}
newTime := time.Now()
privilegeMemberNew := &model.PrivilegeMember{}
var spendType uint32 // 开通类型: 1-未开通 2-开通会员 3-续费
var user model.User
err = model.NewUserQuerySet(model.DB).UidEq(record.Uid).One(&user)
if err != nil {
logger.Error("err:", err)
RespJson(c, status.DBOperateError, nil)
return
} else {
var privilegeMember model.PrivilegeMember
err = model.NewPrivilegeMemberQuerySet(model.DB).UidEq(record.Uid).One(&privilegeMember)
if err != nil && err != model.RecordNotFound {
logger.Error("PrivilegeMember:", err)
RespJson(c, status.DBOperateError, nil)
return
}
var expireTime time.Time
expireTime = newTime.AddDate(1, 0, 0)
if err == model.RecordNotFound { // 没有记录,用户新开通尊享会员
spendType = 2 // 2-开通会员
memberRecord.OpenMemberTime = newTime
memberRecord.Type = 9 // 开通会员类型
privilegeMemberNew.Uid = record.Uid
privilegeMemberNew.Tel = user.Tel
privilegeMemberNew.MemberLevel = model.MemberLevelPrivilege
privilegeMemberNew.MemberExpire = &expireTime
privilegeMemberNew.OpenMemberTime = &newTime
privilegeMemberNew.ExtendStatus = model.ExtendWaitActive
} else { // 有记录,用户续费尊享会员
spendType = 3 // 3-续费
memberRecord.OpenMemberTime = *privilegeMember.OpenMemberTime
memberRecord.BeforeMemberLevel = privilegeMember.MemberLevel
memberRecord.BeforeMemberExpire = *privilegeMember.MemberExpire
memberRecord.Serial = uint32(privilegeMember.MemberExpire.Unix())
if privilegeMember.MemberExpire.After(newTime) {
expireTime = privilegeMember.MemberExpire.AddDate(1, 0, 0)
}
memberRecord.Type = 10 // 续费会员类型
userUpdateQs := model.NewPrivilegeMemberQuerySet(model.DB).UidEq(record.Uid).GetUpdater().
SetMemberLevel(record.MemberLevel).SetMemberExpire(&expireTime).SetExtendStatus(model.ExtendWaitActive)
_, err = userUpdateQs.UpdateNum()
if err != nil {
logger.Error("err:", err)
return
}
}
memberRecord.AfterMemberExpire = expireTime
memberRecord.OpenMemberLevel = record.MemberLevel
// 邀请记录
var invite model.UserInvite
err = model.NewUserInviteQuerySet(model.DB).ToUidEq(record.Uid).OrderDescByCreatedAt().Limit(1).One(&invite)
if err != nil && err != model.RecordNotFound {
logger.Error("err:", err)
} else {
if err == nil {
effectiveStoreInfo, err := model.GetUserEffectiveStore(invite.FromUid)
if err != nil {
logger.Error("GetUserEffectiveStore err:", err)
effectiveStoreInfo.StoreID = 0
}
privilegeMemberNew.StoreId = effectiveStoreInfo.StoreID
if invite.Action == 1 { // 首次开通会员
qs := model.NewUserInviteQuerySet(model.DB).IDEq(invite.ID).GetUpdater()
invite.RenewHide = 1 // 自动
qs = qs.SetMemberOpenTime(newTime).SetMemberLevel(record.MemberLevel)
_, err = qs.SetMemberType(2).SetMemberStatus(2).
SetAction(2).SetSpendType(spendType).SetMemberGenre(record.MemberGenre).UpdateNum()
if err != nil {
logger.Error("update user invite action spend type err:", err)
}
if invite.UserInviteRecordId != 0 {
go func() {
err = model.NewUserInviteRecordQuerySet(model.DB).IDEq(invite.UserInviteRecordId).GetUpdater().
SetAction(2).SetSpendType(spendType).SetMemberLevel(record.MemberLevel).
SetActionTime(newTime).SetMemberGenre(record.MemberGenre).SetRenewHide(invite.RenewHide).Update()
if err != nil {
logger.Error("update user invite record err:", err)
}
}()
}
} else { // 续费会员-用户直接续费
inviteRecordNew := &model.UserInviteRecord{
ToUid: invite.ToUid,
FromUid: invite.FromUid,
StoreId: effectiveStoreInfo.StoreID,
Action: 2,
SpendType: spendType,
MemberLevel: record.MemberLevel,
First: 0,
Scan: 0, // 自动生成
ActionTime: newTime,
MemberGenre: record.MemberGenre,
RenewHide: 1,
}
err = model.DB.Create(inviteRecordNew).Error
if err != nil {
logger.Error("create invite record err:", err)
}
userInviteNew := &model.UserInvite{
FromUid: invite.FromUid,
UserType: invite.UserType,
StoreId: effectiveStoreInfo.StoreID,
StoreType: invite.StoreType,
MemberOpenTime: time.Now(),
MemberType: 2,
MemberStatus: 2,
ToUid: invite.ToUid,
Action: 2,
SpendType: spendType,
MemberLevel: record.MemberLevel,
UserInviteRecordId: inviteRecordNew.ID,
FirstInvite: 0,
Scan: 0,
MemberGenre: record.MemberGenre,
RenewHide: 1,
//MemberOpenTime: invite.MemberOpenTime,
}
err = model.DB.Create(userInviteNew).Error
if err != nil {
logger.Error("create invite record err:", err)
}
}
if invite.FromUid != 0 {
logger.Info("invite.FromUid != 0")
fmt.Println("invite.FromUid != 0")
inviteUser := model.GetUserByUid(invite.FromUid)
if inviteUser != nil && inviteUser.UserType == 2 {
// 记录对应的数量
switch spendType {
case 2: // 开通
fmt.Println("用户开通------")
model.AddCooperativeMemberPromotion(inviteUser.CooperativeBusinessId,
uint32(effectiveStoreInfo.StoreID), inviteUser.Uid, int(record.MemberLevel),
int(record.MemberGenre))
case 3: // 续费
fmt.Println("用户续费---")
model.AddCooperativeMemberRenewal(inviteUser.CooperativeBusinessId,
uint32(invite.StoreId), inviteUser.Uid, int(record.MemberLevel),
int(record.MemberGenre), true)
}
}
}
} else if err == model.RecordNotFound { // 没有邀请记录,完全是用户自己开通会员,自己续费;按产品要求也需要有记录
inviteRecordNew := &model.UserInviteRecord{
ToUid: user.Uid,
Action: 2,
SpendType: spendType,
MemberLevel: record.MemberLevel,
First: 0,
Scan: 0, // 自动生成
ActionTime: newTime,
MemberGenre: record.MemberGenre,
RenewHide: 1,
}
err = model.DB.Create(inviteRecordNew).Error
if err != nil {
logger.Error("create invite record err:", err)
}
// 记录对应的数量
switch spendType {
case 2: // 开通
fmt.Println("用户开通------")
model.AddCooperativeMemberPromotion(user.CooperativeBusinessId, 0, 0,
int(record.MemberLevel), int(record.MemberGenre))
case 3: // 续费
fmt.Println("用户续费---")
model.AddCooperativeMemberRenewal(user.CooperativeBusinessId, 0, 0,
int(record.MemberLevel), int(record.MemberGenre), true)
}
}
}
if spendType == 2 { // 开通会员,新建尊享会员记录
err = model.DB.Create(privilegeMemberNew).Error
if err != nil {
logger.Error("create invite record err:", err)
}
}
// 赠送积分
err = model.NewSendUserVm(user.Uid, uint32(notifyInfo.TotalFee/100), spendType)
if err != nil {
logger.Error("send user vm err:", err)
}
go func() {
err = model.DB.Create(memberRecord).Error
if err != nil {
logger.Error("create member record err:", err)
}
}()
}
_, err = model.NewUserOpenMemberRecordQuerySet(model.DB).IDEq(record.ID).
GetUpdater().SetState(2).UpdateNum()
if err != nil {
logger.Error("update user open member record state:err", err)
}
fmt.Println("notify.TotalFee:", fundRecord.Amount)
fmt.Println("notify.OutTradeNo:", notifyInfo.OutTradeNo)
// 发放优惠券
var coupons []model.Coupon
err = model.NewCouponQuerySet(model.DB).ActivityIdEq(model.PrivilegeMemberActivityId).All(&coupons)
if err != nil {
logger.Error("coupons err:", err)
RespJson(c, status.InternalServerError, nil)
return
}
for i, _ := range coupons {
if coupons[i].ActivityType == 6 || coupons[i].ActivityType == 7 { // 15元周边券20元配件券发4张
for j := 0; j < 4; j++ {
couponCode, err := utils.GenerateRandomNumber19()
if err != nil {
logger.Error("GenerateRandomNumber19err:", err)
}
userCoupon := &model.UserCoupon{
Uid: record.Uid,
CouponId: coupons[i].ID,
CouponType: coupons[i].CouponType,
ActivityType: coupons[i].ActivityType,
ActivityId: coupons[i].ActivityId,
Value: coupons[i].Value,
State: 1,
ActiveStart: time.Now(),
ActiveEnd: time.Now().AddDate(0, 6, 0),
UseTime: time.Time{},
MemberLevel: coupons[i].MemberLevel,
Approach: 0,
PromotionalSales: 0,
RedeemCode: "",
CategoryNumber: coupons[i].CategoryNumber,
Code: couponCode,
}
err = model.DB.Create(userCoupon).Error
if err != nil {
logger.Error("user coupon err:", err)
continue
}
}
} else if coupons[i].ActivityType == 8 { // 20元游戏券发3张
for j := 0; j < 3; j++ {
couponCode, err := utils.GenerateRandomNumber19()
if err != nil {
logger.Error("GenerateRandomNumber19err:", err)
}
userCoupon := &model.UserCoupon{
Uid: record.Uid,
CouponId: coupons[i].ID,
CouponType: coupons[i].CouponType,
ActivityType: coupons[i].ActivityType,
ActivityId: coupons[i].ActivityId,
Value: coupons[i].Value,
State: 1,
ActiveStart: time.Now(),
ActiveEnd: time.Now().AddDate(0, 6, 0),
UseTime: time.Time{},
MemberLevel: coupons[i].MemberLevel,
Approach: 0,
PromotionalSales: 0,
RedeemCode: "",
CategoryNumber: coupons[i].CategoryNumber,
Code: couponCode,
}
err = model.DB.Create(userCoupon).Error
if err != nil {
logger.Error("user coupon err:", err)
continue
}
}
}
}
}
fundRecord.Amount = int64(notifyInfo.TotalFee)
fundRecord.TransactionId = notifyInfo.TransactionId
fundRecord.OutTradeNo = notifyInfo.OutTradeNo
@ -2380,10 +2698,10 @@ func HmPushWXPayNotice(c *gin.Context) {
privilegeMemberNew.Uid = record.Uid
privilegeMemberNew.Tel = user.Tel
privilegeMemberNew.MemberLevel = 6
privilegeMemberNew.MemberLevel = model.MemberLevelPrivilege
privilegeMemberNew.MemberExpire = &expireTime
privilegeMemberNew.OpenMemberTime = &newTime
privilegeMemberNew.ExtendStatus = 2
privilegeMemberNew.ExtendStatus = model.ExtendWaitActive
} else { // 有记录,用户续费尊享会员
spendType = 3 // 3-续费
memberRecord.OpenMemberTime = *privilegeMember.OpenMemberTime
@ -2396,7 +2714,7 @@ func HmPushWXPayNotice(c *gin.Context) {
memberRecord.Type = 10 // 续费会员类型
userUpdateQs := model.NewPrivilegeMemberQuerySet(model.DB).UidEq(record.Uid).GetUpdater().
SetMemberLevel(record.MemberLevel).SetMemberExpire(&expireTime).SetExtendStatus(2)
SetMemberLevel(record.MemberLevel).SetMemberExpire(&expireTime).SetExtendStatus(model.ExtendWaitActive)
_, err = userUpdateQs.UpdateNum()
if err != nil {
logger.Error("err:", err)
@ -2562,6 +2880,81 @@ func HmPushWXPayNotice(c *gin.Context) {
}
fmt.Println("notify.TotalFee:", fundRecord.Amount)
fmt.Println("notify.OutTradeNo:", outOrderNo)
// 发放优惠券
var coupons []model.Coupon
err = model.NewCouponQuerySet(model.DB).ActivityIdEq(model.PrivilegeMemberActivityId).All(&coupons)
if err != nil {
logger.Error("coupons err:", err)
RespJson(c, status.InternalServerError, nil)
return
}
for i, _ := range coupons {
if coupons[i].ActivityType == 6 || coupons[i].ActivityType == 7 { // 15元周边券20元配件券发4张
for j := 0; j < 4; j++ {
couponCode, err := utils.GenerateRandomNumber19()
if err != nil {
logger.Error("GenerateRandomNumber19err:", err)
}
userCoupon := &model.UserCoupon{
Uid: record.Uid,
CouponId: coupons[i].ID,
CouponType: coupons[i].CouponType,
ActivityType: coupons[i].ActivityType,
ActivityId: coupons[i].ActivityId,
Value: coupons[i].Value,
State: 1,
ActiveStart: time.Now(),
ActiveEnd: time.Now().AddDate(0, 6, 0),
UseTime: time.Time{},
MemberLevel: coupons[i].MemberLevel,
Approach: 0,
PromotionalSales: 0,
RedeemCode: "",
CategoryNumber: coupons[i].CategoryNumber,
Code: couponCode,
}
err = model.DB.Create(userCoupon).Error
if err != nil {
logger.Error("user coupon err:", err)
continue
}
}
} else if coupons[i].ActivityType == 8 { // 20元游戏券发3张
for j := 0; j < 3; j++ {
couponCode, err := utils.GenerateRandomNumber19()
if err != nil {
logger.Error("GenerateRandomNumber19err:", err)
}
userCoupon := &model.UserCoupon{
Uid: record.Uid,
CouponId: coupons[i].ID,
CouponType: coupons[i].CouponType,
ActivityType: coupons[i].ActivityType,
ActivityId: coupons[i].ActivityId,
Value: coupons[i].Value,
State: 1,
ActiveStart: time.Now(),
ActiveEnd: time.Now().AddDate(0, 6, 0),
UseTime: time.Time{},
MemberLevel: coupons[i].MemberLevel,
Approach: 0,
PromotionalSales: 0,
RedeemCode: "",
CategoryNumber: coupons[i].CategoryNumber,
Code: couponCode,
}
err = model.DB.Create(userCoupon).Error
if err != nil {
logger.Error("user coupon err:", err)
continue
}
}
}
}
}
fundRecord.TransactionId = bankOrderNo

View File

@ -1,7 +1,9 @@
package controller
import (
"encoding/json"
"errors"
"fmt"
"github.com/codinl/go-logger"
"github.com/gin-gonic/gin"
"github.com/rs/zerolog/log"
@ -10,6 +12,8 @@ import (
"mh-server/lib/utils"
"mh-server/lib/wxpay"
"mh-server/model"
"strconv"
"strings"
"time"
)
@ -79,6 +83,65 @@ func MallGoodsDetail(c *gin.Context) {
return
}
// GetCombinedCouponCode 定义一个函数来根据 number 和 couponType 组合结果
func GetCombinedCouponCode(goods *model.Goods, attribute *model.GoodsAttribute) (uint32, error) {
// 确保 goods 和 attribute 以及 SpecValues 不为空
if goods == nil || attribute == nil || attribute.SpecValues == nil {
return 0, fmt.Errorf("goods or attribute or SpecValues is nil")
}
// 确定 goods.Name 中的数字
var number int
switch {
case strings.Contains(goods.Name, "100"):
number = 100
case strings.Contains(goods.Name, "50"):
number = 50
case strings.Contains(goods.Name, "20"):
number = 20
case strings.Contains(goods.Name, "10"):
number = 10
case strings.Contains(goods.Name, "5"):
number = 5
default:
return 0, fmt.Errorf("优惠券金额有误")
}
// 遍历 SpecValues 查找匹配的 display_value
var couponType int
for _, specValue := range attribute.SpecValues {
if specValue == nil {
continue
}
switch specValue.DisplayValue {
case "周边券":
couponType = 3
case "配件券":
couponType = 2
case "游戏券":
couponType = 1
default:
continue
}
break
}
if couponType == 0 {
return 0, fmt.Errorf("优惠券规格有误")
}
// 生成对应的组合字符串
resultStr := fmt.Sprintf("%d%d", number, couponType)
// 将组合字符串转换为 uint32
result, err := strconv.ParseUint(resultStr, 10, 32)
if err != nil {
return 0, fmt.Errorf("转换为 uint32 时出错: %v", err)
}
return uint32(result), nil
}
func MallOrderCreate(c *gin.Context) {
req := struct {
GoodsId uint32 `json:"goods_id" binding:"required"` // 商品id
@ -138,12 +201,15 @@ func MallOrderCreate(c *gin.Context) {
return
}
// 检测收货地址是否正确
count, _ := model.NewUserAddressQuerySet(model.DB).UidEq(uc.Uid).IDEq(req.AddressId).Count()
if count != 1 {
logger.Error("err:", err)
RespJson(c, status.BadRequest, "收货地址错误")
return
// 如果不是发放优惠券,需要判断用户地址
if !strings.Contains(goods.Name, "优惠券") {
// 检测收货地址是否正确
count, _ := model.NewUserAddressQuerySet(model.DB).UidEq(uc.Uid).IDEq(req.AddressId).Count()
if count != 1 {
logger.Error("err:", err)
RespJson(c, status.BadRequest, "收货地址错误")
return
}
}
//// 计算总金额
@ -229,6 +295,11 @@ func MallOrderCreate(c *gin.Context) {
order.PayStatus = model.PayStatusOK
order.State = model.GoodsOrderStateOnDeliver
// 如果发放的是优惠券,则默认为用户已收货
if strings.Contains(goods.Name, "优惠券") {
order.State = model.GoodsOrderStateReceived
}
err = order.Create(tx)
if err != nil {
logger.Error("err:", err)
@ -253,6 +324,60 @@ func MallOrderCreate(c *gin.Context) {
return
}
if strings.Contains(goods.Name, "优惠券") {
// 发放优惠券:判断优惠券金额和种类
err = json.Unmarshal([]byte(attribute.SpecValueList), &attribute.SpecValues)
if err != nil {
log.Error().Msgf("spec value err:%#v", err)
}
nActivityType, err := GetCombinedCouponCode(&goods, &attribute)
if err != nil {
logger.Error("GetCombinedCouponCode err:", err)
RespJson(c, status.NoSpecValue, nil)
return
}
var coupons []model.Coupon
err = model.NewCouponQuerySet(model.DB).ActivityIdEq(model.VmActivityId).ActivityTypeEq(nActivityType).All(&coupons)
if err != nil {
logger.Error("coupons err:", err)
RespJson(c, status.InternalServerError, nil)
return
}
for i, _ := range coupons {
couponCode, err := utils.GenerateRandomNumber19()
if err != nil {
logger.Error("GenerateRandomNumber19err:", err)
}
userCoupon := &model.UserCoupon{
Uid: user.Uid,
CouponId: coupons[i].ID,
CouponType: coupons[i].CouponType,
ActivityType: coupons[i].ActivityType,
ActivityId: coupons[i].ActivityId,
Value: coupons[i].Value,
State: 1,
ActiveStart: time.Now(),
ActiveEnd: time.Now().AddDate(0, 0, 7),
UseTime: time.Time{},
MemberLevel: coupons[i].MemberLevel,
Approach: 0,
PromotionalSales: 0,
RedeemCode: "",
CategoryNumber: coupons[i].CategoryNumber,
Code: couponCode,
}
err = model.DB.Create(userCoupon).Error
if err != nil {
logger.Error("user coupon err:", err)
continue
}
}
}
err = tx.Commit().Error
if err != nil {
tx.Rollback()
@ -656,7 +781,7 @@ func MallOrderCancel(c *gin.Context) {
//}
if goodsOrder.Vm != 0 {
err = model.UserVmUpdate(goodsOrder.Uid, int(goodsOrder.Vm), model.VmEventBuyGoods, "购买商品积分抵扣取消")
err = model.UserVmUpdate(goodsOrder.Uid, int(goodsOrder.Vm), model.VmEventBuyGoodsReject, "购买商品积分抵扣取消")
if err != nil {
logger.Error("err:", err)
RespJson(c, status.InternalServerError, nil)
@ -668,6 +793,14 @@ func MallOrderCancel(c *gin.Context) {
return
}
// MallUserVmRecord 用户积分记录
// @Summary 用户积分记录
// @Tags 用户信息
// @Produce json
// @Accept json
// @Param request body model.MallUserVmRecordReq true "用户登陆模型"
// @Success 200 {object} model.MallUserVmRecordResp
// @Router /api/v1/mall/user/vm_record [post]
func MallUserVmRecord(c *gin.Context) {
req := model.MallUserVmRecordReq{}
if err := c.ShouldBindJSON(&req); err != nil {
@ -689,10 +822,10 @@ func MallUserVmRecord(c *gin.Context) {
return
}
ret := map[string]interface{}{
"list": list,
"cur_page": req.PageIdx,
"total_page": total,
ret := model.MallUserVmRecordResp{
List: list,
CurPage: req.PageIdx,
TotalPage: total,
}
RespOK(c, ret)

View File

@ -398,7 +398,10 @@ func RentCardOrderCreate(c *gin.Context) {
//fmt.Println("PayPrice:", order.PayPrice)
if req.Price == 0 {
//tx := model.TransactionBegin()
if tx == nil {
tx = model.TransactionBegin()
}
order.PayStatus = model.PayStatusPaid
fmt.Println("orderId:", order.PayStatus)
err = order.OrderCreate(tx)

View File

@ -352,7 +352,7 @@ func OpenMember(c *gin.Context) {
}
//选择支付渠道15号之前走微信15号之后走河马付
if genre == model.PaymentGenreWx {
webPay, err := wxpay.WebPay(orderSn, totalFee, user.WxOpenID, "N", wxpay.WxPayMember, configInfo.NotifyUrl)
webPay, err := wxpay.WebPay(orderSn, totalFee, user.WxOpenID, "N", wxpay.WxPayMember, configInfo.NotifyUrl, false)
if err != nil {
logger.Error(errors.New("WebPay err"))
RespJson(c, status.InternalServerError, nil)
@ -1303,7 +1303,7 @@ func OpenPrivilegeMember(c *gin.Context) {
}
orderSn := model.GetOrderSn()
err = model.UserOpenMemberRecord{Uid: uc.Uid, OpenNo: orderSn, MemberLevel: 6,
err = model.UserOpenMemberRecord{Uid: uc.Uid, OpenNo: orderSn, MemberLevel: model.MemberLevelPrivilege,
UserCouponId: req.UserCouponId, Attach: wxpay.WxPayPrivilegeMember}.Insert()
if err != nil {
logger.Error(errors.New("WebPay err"))
@ -1318,8 +1318,16 @@ func OpenPrivilegeMember(c *gin.Context) {
return
}
// 支付走河马付通过用户所属门店id选择不同的商户
webPay, err := wxpay.HmJsPayUnifiedOrder(orderSn, totalFee, user.WxOpenID, configInfo.NotifyUrl)
//支付走河马付通过用户所属门店id选择不同的商户
//webPay, err := wxpay.HmJsPayUnifiedOrderForPrivilege(orderSn, totalFee, user.WxOpenID, configInfo.NotifyUrl)
//if err != nil {
// logger.Error(errors.New("WebPay err"))
// RespJson(c, status.InternalServerError, nil)
// return
//}
//RespOK(c, webPay)
webPay, err := wxpay.WebPay(orderSn, totalFee, user.WxOpenID, "N", wxpay.WxPayPrivilegeMember, configInfo.NotifyUrl, true)
if err != nil {
logger.Error(errors.New("WebPay err"))
RespJson(c, status.InternalServerError, nil)

View File

@ -18,7 +18,7 @@ const (
ENCODINGAESKEY = "QoI6tG856JFGLZaWy2ljffJlkBOYeU6GSfGuzpt18Pu"
)
//func checkout(response http.ResponseWriter, request *http.Request) {
// func checkout(response http.ResponseWriter, request *http.Request) {
func WxMsg(c *gin.Context) {
// 获取参数
signature := c.PostForm("signature")

58
go.mod
View File

@ -1,6 +1,6 @@
module mh-server
go 1.20
go 1.16
require (
github.com/aliyun/aliyun-sts-go-sdk v0.0.0-20171106034748-98d3903a2309
@ -10,66 +10,20 @@ require (
github.com/gin-gonic/gin v1.7.1
github.com/holdno/snowFlakeByGo v0.0.0-20180510033652-d23f8a8cadd7
github.com/jinzhu/gorm v1.9.16
github.com/jinzhu/now v1.1.4 // indirect
github.com/medivhzhan/weapp v1.5.1
github.com/pkg/errors v0.9.1
github.com/qiniu/api.v7 v7.2.5+incompatible
github.com/qiniu/x v7.0.8+incompatible // indirect
github.com/rs/zerolog v1.23.0
github.com/satori/go.uuid v1.2.0 // indirect
github.com/spf13/cobra v1.1.3
github.com/spf13/viper v1.7.1
github.com/swaggo/swag v1.16.3
github.com/wechatpay-apiv3/wechatpay-go v0.2.6
github.com/xuri/excelize/v2 v2.6.0
golang.org/x/sync v0.8.0
)
require (
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/PuerkitoBio/purell v1.1.1 // indirect
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/jsonreference v0.19.6 // indirect
github.com/go-openapi/spec v0.20.4 // indirect
github.com/go-openapi/swag v0.19.15 // indirect
github.com/go-playground/locales v0.13.0 // indirect
github.com/go-playground/universal-translator v0.17.0 // indirect
github.com/go-playground/validator/v10 v10.4.1 // indirect
github.com/go-sql-driver/mysql v1.5.0 // indirect
github.com/golang/protobuf v1.3.3 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.4 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.9 // indirect
github.com/leodido/go-urn v1.2.0 // indirect
github.com/magiconair/properties v1.8.1 // indirect
github.com/mailru/easyjson v0.7.6 // indirect
github.com/mattn/go-isatty v0.0.12 // indirect
github.com/mitchellh/mapstructure v1.1.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/pelletier/go-toml v1.2.0 // indirect
github.com/qiniu/x v7.0.8+incompatible // indirect
github.com/richardlehane/mscfb v1.0.4 // indirect
github.com/richardlehane/msoleps v1.0.1 // indirect
github.com/satori/go.uuid v1.2.0 // indirect
github.com/spf13/afero v1.1.2 // indirect
github.com/spf13/cast v1.3.0 // indirect
github.com/spf13/jwalterweatherman v1.0.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.2.0 // indirect
github.com/ugorji/go/codec v1.1.7 // indirect
github.com/xuri/efp v0.0.0-20220407160117-ad0f7a785be8 // indirect
github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 // indirect
golang.org/x/crypto v0.26.0 // indirect
golang.org/x/net v0.28.0 // indirect
golang.org/x/sys v0.23.0 // indirect
golang.org/x/text v0.17.0 // indirect
golang.org/x/tools v0.24.0 // indirect
golang.org/x/sync v0.6.0
golang.org/x/tools v0.19.0 // indirect
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
gopkg.in/ini.v1 v1.51.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
qiniupkg.com/x v7.0.8+incompatible // indirect
)

486
go.sum
View File

@ -1,486 +0,0 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/agiledragon/gomonkey v2.0.2+incompatible h1:eXKi9/piiC3cjJD1658mEE2o3NjkJ5vDLgYjCQu0Xlw=
github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/aliyun/aliyun-sts-go-sdk v0.0.0-20171106034748-98d3903a2309 h1:XY4O/8U2nbXmsu5/6ojNSKJLcHkepBYDrsC2aOjTPBg=
github.com/aliyun/aliyun-sts-go-sdk v0.0.0-20171106034748-98d3903a2309/go.mod h1:teomK5dnKddyNHy+q8ab9v0jcGJuVxn9qWPcqEUHUus=
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/codinl/go-logger v1.0.0 h1:qjPNKi4v1hx7hraY3qlFvVf2tPuBy284zWJiYrPKMdQ=
github.com/codinl/go-logger v1.0.0/go.mod h1:tDJ+0Vgd7/hp/0V355poSk+rcdwmtbXYor/aG8O3+4A=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd h1:83Wprp6ROGeiHFAP8WJdI2RoxALQYgdllERc3N5N2DM=
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.7.1 h1:qC89GU3p8TvKWMAVhEpmpB2CIb1hnqt2UdKZaP93mS8=
github.com/gin-gonic/gin v1.7.1/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs=
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M=
github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/holdno/snowFlakeByGo v0.0.0-20180510033652-d23f8a8cadd7 h1:gWZtcY7JSWvcgFYUW147/2BOnxJg+er9eZI3nrfcFzU=
github.com/holdno/snowFlakeByGo v0.0.0-20180510033652-d23f8a8cadd7/go.mod h1:aqAI0YiLKgShMi9R71i5S81IWfb0x2ghGF2w1RjyNbs=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o=
github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jinzhu/now v1.1.4 h1:tHnRBy1i5F2Dh8BAFxqFzxKqqvezXrL2OW1TnX+Mlas=
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4=
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-sqlite3 v1.14.0 h1:mLyGNKR8+Vv9CAU7PphKa2hkEqxxhn8i32J6FPj1/QA=
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/medivhzhan/weapp v1.5.1 h1:v5F/ITY0FxIHd8XrETue+lmuo/hD5xVVQ5egDkV54Io=
github.com/medivhzhan/weapp v1.5.1/go.mod h1:a0lS9tWHTyO5yj9nIJFcmLjrQi7XN4BxaYXKWZcRiAc=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/qiniu/api.v7 v7.2.5+incompatible h1:6KKaGt7MbFzVGSniwzv7qsM/Qv0or4SkRJfmak8LqZE=
github.com/qiniu/api.v7 v7.2.5+incompatible/go.mod h1:V8/EzlTgLN6q0s0CJmg/I81ytsvldSF22F7h6MI02+c=
github.com/qiniu/x v7.0.8+incompatible h1:P4LASsfwJY7SoZ13dwqBwGhZh7HKU8cdFVCUkmz0gZ8=
github.com/qiniu/x v7.0.8+incompatible/go.mod h1:KpRKWYG/GaidPQVpoQ2Cvuvtts3gYnoo2PftgdmAiU4=
github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM=
github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
github.com/richardlehane/msoleps v1.0.1 h1:RfrALnSNXzmXLbGct/P2b4xkFz4e8Gmj/0Vj9M9xC1o=
github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/zerolog v1.23.0 h1:UskrK+saS9P9Y789yNNulYKdARjPZuS35B8gJF2x60g=
github.com/rs/zerolog v1.23.0/go.mod h1:6c7hFfxPOy7TacJc4Fcdi24/J0NKYGzjG8FWRI916Qo=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M=
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk=
github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/swaggo/swag v1.16.3 h1:PnCYjPCah8FK4I26l2F/KQ4yz3sILcVUN3cTlBFA9Pg=
github.com/swaggo/swag v1.16.3/go.mod h1:DImHIuOFXKpMFAQjcC7FG4m3Dg4+QuUgUzJmKjI/gRk=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/wechatpay-apiv3/wechatpay-go v0.2.6 h1:iWXgJ7nt8vTMU/MYYdZa6yklC8r4qdAJu+CKnRe0Bo0=
github.com/wechatpay-apiv3/wechatpay-go v0.2.6/go.mod h1:W8ucVAOCKOii933cWROLaDLmRQ2cg/vHHVF4vGAVq9Q=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xuri/efp v0.0.0-20220407160117-ad0f7a785be8 h1:3X7aE0iLKJ5j+tz58BpvIZkXNV7Yq4jC93Z/rbN2Fxk=
github.com/xuri/efp v0.0.0-20220407160117-ad0f7a785be8/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
github.com/xuri/excelize/v2 v2.6.0 h1:m/aXAzSAqxgt74Nfd+sNzpzVKhTGl7+S9nbG4A57mF4=
github.com/xuri/excelize/v2 v2.6.0/go.mod h1:Q1YetlHesXEKwGFfeJn7PfEZz2IvHb6wdOeYjBxVcVs=
github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 h1:OAmKAfT06//esDdpi/DZ8Qsdt4+M5+ltca05dA5bG2M=
github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20220408190544-5352b0902921/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20211028202545-6944b10bf410 h1:hTftEOvwiOq2+O8k2D5/Q7COC7k5Qcrgc2TFURJYnvQ=
golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220407224826-aac1ed45d8e3/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0 h1:hjy8E9ON/egN1tAYqKb61G10WtihqetD4sz2H+8nIeA=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
qiniupkg.com/x v7.0.8+incompatible h1:Ek0ZVi5IyaWUAFkJbPRiqlh34xDM4uoKw7KqdpankvU=
qiniupkg.com/x v7.0.8+incompatible/go.mod h1:6sLxR5IZ03vMaRAQAY/5MvzofeoBIjO4XE0Njv6V1ms=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=

View File

@ -115,6 +115,7 @@ const (
NotNewUser = 500532 // 您不是新用户,请领取续费优惠券
NotShopperCodeStoreUser = 500533 // 您不是推广门店用户,请扫店员推广码后再使用优惠券
NotAvailableCode = 500534 // 兑换码错误
NoSpecValue = 500535 // 优惠券未指定规格
ToastErr = 600 // 报错
)
@ -281,6 +282,7 @@ var statusMsg = map[int]string{
NotNewUser: "您不是新用户,请领取续费优惠券",
NotShopperCodeStoreUser: "您不是推广门店用户,请扫店员推广码后再使用优惠券",
NotAvailableCode: "兑换码错误",
NoSpecValue: "优惠券未指定规格",
}
func StatusDesc(code int) string {

View File

@ -1,8 +1,10 @@
package utils
import (
"crypto/rand"
"fmt"
"github.com/holdno/snowFlakeByGo"
"math/big"
"reflect"
"regexp"
@ -88,3 +90,24 @@ func GenPrizeOrderID() string {
OrderID := RandomLenNum(14)
return prixString + OrderID
}
func GenerateRandomNumber19() (string, error) {
// Define the maximum number for a single digit (0-9)
const digits = "0123456789"
const length = 19
// To store the generated number
number := make([]byte, length)
for i := 0; i < length; i++ {
// Generate a random index from 0 to 9
index, err := rand.Int(rand.Reader, big.NewInt(int64(len(digits))))
if err != nil {
return "", err
}
// Convert the index to a byte and add it to the number
number[i] = digits[index.Int64()]
}
return string(number), nil
}

View File

@ -62,10 +62,16 @@ const (
HmWxSubMerchantId = "546017470"
//HmPayUnifiedOrderUrl = "https://hmpay.sandpay.com.cn/gateway/api"
HmPayApiUrl = "https://hmpay.sandpay.com.cn/gateway/api"
// HmPayMerchantIdSwitchPub 任天堂项目-对公账户(密钥20240819161949)
HmPayMerchantIdSwitchPub = "664403000021225"
HmPubKeySwitchPub = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCBsfp+BrCGD39noWjW4z0VvvsFCWzU8vhAWlwGo/dkPxgQLXBNaTApUpavbQ6m/S0x5hQjcKwQ3UrJLDV70SAqPuO3QP0iagMKo2M6ROCO69L06In4gbqTTtTOb/1xpkbsVHd/9Wy/fyxreg1LY+MLzysH+OHAjjjiAYVL4e765QIDAQAB"
HmPubKeySwitchPubFp = "./pack/configs/hm_pay/switch_pub_private_key.pem"
TestHmPubKeySwitchPubFp = "/Users/max/Documents/code/deovo/mh_server/pack/configs/hm_pay/switch_pub_private_key.pem"
)
// web 微信支付
func WebPay(orderId string, totalFee uint32, openId, profitSharing, attach, notifyUrl string) (*Sextuple, error) {
func WebPay(orderId string, totalFee uint32, openId, profitSharing, attach, notifyUrl string, flag bool) (*Sextuple, error) {
now := time.Now().Local()
strTime := fmt.Sprintf("%04d%02d%02d%02d%02d%02d", now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second())
nonce := utils.GenRandStr(NonceStringLength)
@ -112,6 +118,9 @@ func WebPay(orderId string, totalFee uint32, openId, profitSharing, attach, noti
ProfitSharing: profitSharing,
Attach: attach,
}
if flag {
unifiedOrderReq.MchId = config.AppConfig.WxDwMchID
}
fmt.Println("OutTradeNo:", unifiedOrderReq.OutTradeNo)
@ -123,8 +132,12 @@ func WebPay(orderId string, totalFee uint32, openId, profitSharing, attach, noti
//mJson, _ := json.MarshalIndent(&m, "", " ")
//fmt.Println("mJson:", string(mJson))
payKey := config.AppConfig.WxMchSecret
if flag {
payKey = config.AppConfig.WxDwMchSecret
}
sign, err := GenWxPaySign(m, config.AppConfig.WxMchSecret)
sign, err := GenWxPaySign(m, payKey)
if err != nil {
logger.Error(err)
return nil, err
@ -154,7 +167,7 @@ func WebPay(orderId string, totalFee uint32, openId, profitSharing, attach, noti
return nil, err
}
sextuple.PaySign, err = GenWxPaySign(m, config.AppConfig.WxMchSecret)
sextuple.PaySign, err = GenWxPaySign(m, payKey)
if err != nil {
logger.Errorf("GenWxPaySign gen response sign error: %#v", err)
return nil, err
@ -894,6 +907,8 @@ const (
WxAppId = "wx806c079463b5b56c"
WxAppSecret = "3d7335cf0b9fa1d70aa7eb079526ebf0"
WxAppIdDeovo = "wx806c079463b5b56c"
WxAppMchId = "1609877389"
WxAppMchSecret = "DeovoMingHuiRengTianTang45675456"
WxCheckName = "NO_CHECK"
@ -1123,7 +1138,225 @@ type HmPayUnifiedOrderRsp struct {
Sign string `json:"sign"`
}
// hm 微信支付
// HmJsPayUnifiedOrderForPrivilege 微信支付(零售尊享会员支付)- 迪为主体
func HmJsPayUnifiedOrderForPrivilege(orderId string, totalFee uint32, openId, notifyUrl string) (*HmPayUnifiedOrderPayData, error) {
now := time.Now().Local()
strTime := fmt.Sprintf("%04d%02d%02d%02d%02d%02d", now.Year(), now.Month(), now.Day(), now.Hour(),
now.Minute(), now.Second())
expireTime := now.Add(time.Hour * 3)
strExpireTime := fmt.Sprintf("%04d%02d%02d%02d%02d%02d", expireTime.Year(), expireTime.Month(),
expireTime.Day(), expireTime.Hour(), expireTime.Minute(), expireTime.Second())
nonce := utils.GenRandStr(NonceStringLength)
if notifyUrl == "" {
logger.Error("NotifyUrl is null")
return nil, errors.New("NotifyUrl is null")
}
unifiedOrderReq := HmJsPayUnifiedOrderReq{}
publicPara := HmPayPublicPara{
AppId: HmPayMerchantIdSwitchPub,
//SubAppId: HmWxSubMerchantId,
Method: "trade.create",
//Charset: "UTF-8",
SignType: "RSA",
Sign: "",
Timestamp: now.Format(TimeFormat),
Nonce: nonce,
//Nonce: fmt.Sprintf("%d", time.Now().UnixNano()),
//Version: "1.0.0",
//Format: "JSON",
}
biz := HmPayBizContent{
Body: "服务费",
MerAppId: WxAppIdDeovo,
MerBuyerId: openId,
CreateIp: clientIp,
CreateTime: strTime,
ExpireTime: strExpireTime,
//LimitPay: "NO_CREDIT",
NotifyUrl: notifyUrl,
OutOrderNo: orderId,
PayType: "JSAPI",
PayWay: "WECHAT",
StoreId: "100001",
TotalAmount: float64(totalFee) / 100,
}
unifiedOrderReq.HmPayPublicPara = publicPara
bizString, err := json.Marshal(&biz)
if err != nil {
logger.Error("marshal biz err:", err)
return nil, err
}
unifiedOrderReq.HmPayPublicPara.BizContent = string(bizString)
m, err := struct2Map(unifiedOrderReq)
if err != nil {
logger.Error(err)
return nil, err
}
//mJson, _ := json.MarshalIndent(&m, "", " ")
//fmt.Println("mJson:", string(mJson))
sign, err := GenHmPaySignForPrivilege(m)
if err != nil {
logger.Error(err)
return nil, err
}
unifiedOrderReq.Sign = sign
//unifiedOrderReqJson, _ := json.Marshal(&unifiedOrderReq)
//fmt.Println("unifiedOrderReqJson:", string(unifiedOrderReqJson))
unifiedOrderResp, err := HmPayUnifiedOrder(unifiedOrderReq)
if err != nil {
logger.Errorf("WxUnifiedOrder unified order error %#v", err)
return nil, err
}
signContent, err := ToSignContent(unifiedOrderResp)
if err != nil {
logger.Error("ToSignContent err:", err)
return nil, err
}
err = HmVerifySha1RsaForPrivilege(signContent, unifiedOrderResp.Sign)
if err != nil {
logger.Error("HmVerifySha1Rsa err:", err)
return nil, err
}
//fmt.Println("unifiedOrderResp:", unifiedOrderResp.Data)
var hmPayDetail HmPayUnifiedOrderDetail
err = json.Unmarshal([]byte(unifiedOrderResp.Data), &hmPayDetail)
if err != nil {
logger.Errorf("hm pay unified order pay data unmarshal error %#v", err)
return nil, err
}
//fmt.Println("hmPayDetail:", hmPayDetail)
var hmPayData HmPayUnifiedOrderPayData
err = json.Unmarshal([]byte(hmPayDetail.PayData), &hmPayData)
if err != nil {
logger.Errorf("hm pay unified order pay data unmarshal error %#v", err)
return nil, err
}
//fmt.Println("hmPayData:", hmPayData)
return &hmPayData, nil
}
func GenHmPaySignForPrivilege(m map[string]string) (string, error) {
delete(m, "sign")
var signData []string
for k, v := range m {
if k == "openid" {
fmt.Println(k, ":", v)
}
if v != "" && v != "0" {
signData = append(signData, fmt.Sprintf("%s=%s", k, v))
}
}
//signDataJson, _ := json.MarshalIndent(&signData, "", " ")
//fmt.Println("signDataJson1", string(signDataJson))
sort.Strings(signData)
//signDataJson2, _ := json.MarshalIndent(&signData, "", " ")
//fmt.Println("signDataJson2", string(signDataJson2))
signStr := strings.Join(signData, "&")
//signStr = signStr + "&key=" + payKey
logger.Info("签字符串1 :", signStr)
signature, err := Sha1withRsaForPrivilege(signStr)
if err != nil {
logger.Error("signature err:", err)
return "", err
}
return signature, nil
}
func Sha1withRsaForPrivilege(signContent string) (string, error) {
hash := crypto.SHA1
shaNew := hash.New()
shaNew.Write([]byte(signContent))
hashed := shaNew.Sum(nil)
priKey, err := ParsePrivateKeyForPrivilege()
if err != nil {
logger.Error("parse err:", err)
return "", err
}
signature, err := rsa.SignPKCS1v15(rand.Reader, priKey, hash, hashed)
if err != nil {
logger.Error("sign err:", err)
return "", err
}
return b64.StdEncoding.EncodeToString(signature), nil
}
func ParsePrivateKeyForPrivilege() (*rsa.PrivateKey, error) {
fp := TestHmPubKeySwitchPubFp
privateKey, err := ioutil.ReadFile(fp)
if err != nil {
logger.Error("read file err:", err)
return nil, err
}
block, _ := pem.Decode([]byte(privateKey))
if block == nil {
return nil, errors.New("私钥信息错误!")
}
//priKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
priKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
return nil, err
}
if priKey == nil {
return nil, errors.New("pri key is nil")
}
return priKey.(*rsa.PrivateKey), nil
}
func HmVerifySha1RsaForPrivilege(signContent, signBase string) error {
block, _ := pem.Decode([]byte(FormatPrivateKey(HmPubKeySwitchPub)))
if block == nil {
fmt.Println("decode block is nil")
return errors.New("decode block is nil")
}
publicKey, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
fmt.Println("public key err:", err)
return err
}
if publicKey == nil {
fmt.Println("public key nil:")
return err
}
hash := crypto.SHA1
shaNew := hash.New()
shaNew.Write([]byte(signContent))
hashed := shaNew.Sum(nil)
sign, err := b64.StdEncoding.DecodeString(signBase)
if err != nil {
fmt.Println("sign decode err:", err)
return err
}
err = rsa.VerifyPKCS1v15(publicKey.(*rsa.PublicKey), hash, hashed, sign)
if err != nil {
fmt.Println("verify err:", err)
return err
}
//logger.Error("验签成功")
fmt.Println("验签成功")
return nil
}
// HmJsPayUnifiedOrder hm 微信支付
func HmJsPayUnifiedOrder(orderId string, totalFee uint32, openId, notifyUrl string) (*HmPayUnifiedOrderPayData, error) {
now := time.Now().Local()
strTime := fmt.Sprintf("%04d%02d%02d%02d%02d%02d", now.Year(), now.Month(), now.Day(), now.Hour(),

View File

@ -36,7 +36,7 @@ func TestWebPay(t *testing.T) {
uid := "62389201"
totalFee := uint32(100)
user := model.User{WxOpenID: "ohuHh4tpfro8u_fUPMbHEWYx5svQ"}
webPay, err := WebPay(uid, totalFee, user.WxOpenID, "N", WxPayMember, "")
webPay, err := WebPay(uid, totalFee, user.WxOpenID, "N", WxPayMember, "", false)
if err != nil {
fmt.Println("err:", err)

View File

@ -716,7 +716,7 @@ func (qs UserVmRecordQuerySet) AlterEq(alter int) UserVmRecordQuerySet {
// AlterGt is an autogenerated method
// nolint: dupl
func (qs UserVmRecordQuerySet) AlterGt(alter int) UserVmRecordQuerySet {
return qs.w(qs.db.Where("alter > ?", alter))
return qs.w(qs.db.Where("`alter` > ?", alter))
}
// AlterGte is an autogenerated method
@ -753,6 +753,10 @@ func (qs UserVmRecordQuerySet) AlterNe(alter int) UserVmRecordQuerySet {
return qs.w(qs.db.Where("alter != ?", alter))
}
func (qs UserVmRecordQuerySet) AlterNeUsedVm() UserVmRecordQuerySet {
return qs.w(qs.db.Where("`alter` != used_vm"))
}
// AlterNotIn is an autogenerated method
// nolint: dupl
func (qs UserVmRecordQuerySet) AlterNotIn(alter ...int) UserVmRecordQuerySet {
@ -845,6 +849,10 @@ func (qs UserVmRecordQuerySet) CreatedAtGte(createdAt time.Time) UserVmRecordQue
return qs.w(qs.db.Where("created_at >= ?", createdAt))
}
func (qs UserVmRecordQuerySet) ExpiryDateAtGte(expiryDate time.Time) UserVmRecordQuerySet {
return qs.w(qs.db.Where("expiry_date >= ?", expiryDate))
}
// CreatedAtLt is an autogenerated method
// nolint: dupl
func (qs UserVmRecordQuerySet) CreatedAtLt(createdAt time.Time) UserVmRecordQuerySet {
@ -857,6 +865,10 @@ func (qs UserVmRecordQuerySet) CreatedAtLte(createdAt time.Time) UserVmRecordQue
return qs.w(qs.db.Where("created_at <= ?", createdAt))
}
func (qs UserVmRecordQuerySet) ExpiryDateLte(expiryDate time.Time) UserVmRecordQuerySet {
return qs.w(qs.db.Where("expiry_date <= ?", expiryDate))
}
// CreatedAtNe is an autogenerated method
// nolint: dupl
func (qs UserVmRecordQuerySet) CreatedAtNe(createdAt time.Time) UserVmRecordQuerySet {
@ -1319,6 +1331,10 @@ func (qs UserVmRecordQuerySet) UidNe(uid uint32) UserVmRecordQuerySet {
return qs.w(qs.db.Where("uid != ?", uid))
}
func (qs UserVmRecordQuerySet) UsedVmNe(ID uint32) UserVmRecordQuerySet {
return qs.w(qs.db.Where("used_vm != ?", ID))
}
// UidNotIn is an autogenerated method
// nolint: dupl
func (qs UserVmRecordQuerySet) UidNotIn(uid ...uint32) UserVmRecordQuerySet {

View File

@ -3,20 +3,15 @@ package model
import "time"
const (
CouponTypeDeduction = "deduction" // 抵扣
CouponTypeDeduction = "deduction" // 抵扣
RenewalMemberActivityId = 1 // 会员续费优惠券
OpenMemberActivityId = 4 // 开通会员优惠券
CommonSaleActivityId = 5 // 零售销售(普通会员)
PrivilegeMemberActivityId = 6 // 零售销售(尊享会员
VmActivityId = 9 // 积分兑换优惠券
)
//var MemberRenewalExpiration int
//var PopTrap int
//var CouponValidity int
//func MemberRenewalActivityInit() {
// renewalConfig := GetActivityRenewalConfig()
// MemberRenewalExpiration = renewalConfig.ActivityContinuity
// PopTrap = renewalConfig.PopTrap
// CouponValidity = renewalConfig.CouponValidity
//}
// gen:qs
//
// 会员优惠券类型
@ -25,19 +20,20 @@ const (
type Coupon struct {
Model
Name string `json:"name"`
Describe string `json:"describe" gorm:"type:text"` // 描述
Rule string `json:"rule" gorm:"type:text"` // 优惠券使用规则
CouponType string `json:"coupon_type"`
ActivityType uint32 `json:"activity_type"` // 活动类型 1-会员续费 2-关注公众号 3-运费包 4-开通会员2024/7/17新增
ActivityId uint32 `json:"activity_id" gorm:"index"`
Value uint32 `json:"value"`
OutCount uint32 `json:"out_count"` // 用户已领取数量
UsedCount uint32 `json:"used_count"` // 用户已使用数量
ActiveStart time.Time `json:"active_start"` // 有效期开始
ActiveEnd time.Time `json:"active_end"` // 有效期结束 零值永不结束
MemberLevel uint32 `json:"member_level"` // 会员等级 1-用户 2-会员
IsDraw bool `json:"is_draw" gorm:"-"`
Name string `json:"name"`
Describe string `json:"describe" gorm:"type:text"` // 描述
Rule string `json:"rule" gorm:"type:text"` // 优惠券使用规则
CouponType string `json:"coupon_type"` //
ActivityType uint32 `json:"activity_type"` //
ActivityId uint32 `json:"activity_id" gorm:"index"` // 活动类型 1-会员续费 2-关注公众号 3-运费包 4-开通会员2024/7/17新增5-零售销售(普通会员) 6-零售销售尊享会员9-积分兑换优惠券
Value uint32 `json:"value"` //
OutCount uint32 `json:"out_count"` // 用户已领取数量
UsedCount uint32 `json:"used_count"` // 用户已使用数量
ActiveStart time.Time `json:"active_start"` // 有效期开始
ActiveEnd time.Time `json:"active_end"` // 有效期结束 零值永不结束
MemberLevel uint32 `json:"member_level"` // 会员等级 1-用户 2-会员
CategoryNumber string `json:"category_number"` // 可以使用该优惠券的商品分类,如果为空则表示没限制
IsDraw bool `json:"is_draw" gorm:"-"` //
}
// gen:qs
@ -55,10 +51,12 @@ type UserCoupon struct {
ActiveStart time.Time `json:"active_start"` // 有效期开始
ActiveEnd time.Time `json:"active_end"` // 有效期结束 零值永不结束
UseTime time.Time `json:"use_time"` //
MemberLevel uint32 `json:"member_level"` // 会员等级 1-用户 2-会员
MemberLevel uint32 `json:"member_level"` // 会员等级 1-用户 2-会员
Approach uint32 `json:"approach"` // 获取途径:1-通过店员兑换码获取
PromotionalSales uint32 `json:"promotional_sales"` // 推广人员用户id
RedeemCode string `json:"redeem_code"` //
CategoryNumber string `json:"category_number"` // 可以使用该优惠券的商品分类,如果为空则表示没限制
Code string `json:"code"` // 优惠券券码
StoreId uint32 `json:"store_id" gorm:"-"` // 邀请码对应门店id
Availability uint32 `json:"availability" gorm:"-"` // 1-不可用 2-可用
Coupon *Coupon `json:"coupon" gorm:"-"`

View File

@ -622,11 +622,18 @@ func GetGoodsAttributeMap(ids []uint32) (map[uint32]GoodsAttribute, error) {
}
type MallUserVmRecordReq struct {
PageIdx int `json:"page_idx"`
PageSize int `json:"page_size"`
PageIdx int `json:"page_idx"`
PageSize int `json:"page_size"`
VmType uint32 `json:"vm_type"` // 默认0-正常查询1-查询7天内即将过期积分
//Uid uint32 `json:"uid"`
}
type MallUserVmRecordResp struct {
List []UserVmRecord `json:"list"`
CurPage int `json:"cur_page"`
TotalPage int `json:"total_page"`
}
func (m *MallUserVmRecordReq) UserVmRecordList(uid uint32) ([]UserVmRecord, int, error) {
page := m.PageIdx - 1
if page < 0 {
@ -643,6 +650,18 @@ func (m *MallUserVmRecordReq) UserVmRecordList(uid uint32) ([]UserVmRecord, int,
qs = qs.UidEq(uid)
}
if m.VmType != 0 {
now := time.Now()
year, month, day := now.Date()
startTime := time.Date(year, month, day, 0, 0, 0, 0, time.UTC)
endTime := time.Date(year, month, day, 23, 59, 59, 0, time.UTC).AddDate(0, 0, 7)
qs = qs.ExpiryDateAtGte(startTime)
qs = qs.ExpiryDateLte(endTime)
qs = qs.AlterGt(0)
qs = qs.AlterNeUsedVm()
}
count, err := qs.Count()
if err != nil {
logger.Error("err:", err)
@ -656,6 +675,10 @@ func (m *MallUserVmRecordReq) UserVmRecordList(uid uint32) ([]UserVmRecord, int,
return nil, 0, err
}
for i, _ := range list {
list[i].ExpiryVm = list[i].Alter - list[i].UsedVm
}
return list, totalPage, nil
}

View File

@ -17,5 +17,6 @@ type PrivilegeMember struct {
HostCode string `json:"host_code"` // 主机编码
Images string `json:"images"` // 图片凭证
AuditorId uint32 `json:"auditor_id" gorm:"index"` // 审核人id
AuditorName string `json:"auditor_name"` // 审核人姓名
AuditTime *time.Time `json:"audit_time"` // 审核时间
}

View File

@ -9,8 +9,9 @@ import (
"time"
)
//go:generate goqueryset -in recycle_card.go
// gen:qs
//
//go:generate goqueryset -in recycle_card.go
type RecycleCardOrder struct {
Model

View File

@ -2,8 +2,9 @@ package model
import "github.com/codinl/go-logger"
//go:generate goqueryset -in search.go
// gen:qs
//
//go:generate goqueryset -in search.go
type SearchHistory struct {
Model

View File

@ -9,8 +9,9 @@ import (
"time"
)
//go:generate goqueryset -in share_card.go
// gen:qs
//
//go:generate goqueryset -in share_card.go
type UserShareCardBill struct {
Model
Uid uint32 `json:"uid" gorm:"index"`

View File

@ -2,8 +2,9 @@ package model
import "github.com/codinl/go-logger"
//go:generate goqueryset -in shopping_cart.go
// gen:qs
//
//go:generate goqueryset -in shopping_cart.go
type ShoppingCart struct {
Model

View File

@ -105,6 +105,7 @@ const (
MemberLevelPeriod = 3 // 短期会员
MemberLevelPlatinum = 4 // 白金会员
MemberLevelBlackGold = 5 // 黑金会员
MemberLevelPrivilege = 6 // 尊享会员
)
const (
@ -117,6 +118,12 @@ const (
OpenMemberChannelRedeemCode = "redeem_code"
)
const ( // 尊享会员延保状态
ExtendExpire = 1 // 已过期
ExtendWaitActive = 2 // 待激活
ExtendEffectivity = 3 // 已激活
)
// gen:qs
type UserInvite struct {
Model

View File

@ -5,8 +5,9 @@ import (
"mh-server/common"
)
//go:generate goqueryset -in user_address.go
// gen:qs
//
//go:generate goqueryset -in user_address.go
type UserAddress struct {
Model

View File

@ -1,7 +1,8 @@
package model
//go:generate goqueryset -in user_refresh_token.go
// gen:qs
//
//go:generate goqueryset -in user_refresh_token.go
type UserRefreshToken struct {
Model

View File

@ -4,11 +4,14 @@ import (
"errors"
"fmt"
"github.com/codinl/go-logger"
"github.com/jinzhu/gorm"
"time"
)
const (
//VmEventExchangeGoods = "exchange_goods"
VmEventBuyGoods = "buy_goods" // 购买商品积分抵扣
VmEventBuyGoodsReject = "buy_goods_reject" // 购买商品积分抵扣取消
VmEventOpenMember = "open_member" // 开通会员奖励
VmEventRenewMember = "renew_member" // 续费会员奖励
VmEventUpgradeMember = "upgrade_member" // 升级会员奖励
@ -35,13 +38,17 @@ type UserVm struct {
type UserVmRecord struct {
Model
Uid uint32 `json:"uid" gorm:"column:uid;index"`
BeforeVm uint32 `json:"before_vm"` // 变动前
AfterVm uint32 `json:"after_vm"` // 变动后
Alter int `json:"alter"` // 数值
Event string `json:"event" gorm:"type:varchar(100)"` // 事件
Describe string `json:"describe" gorm:"type:text"` // 描述
Uid uint32 `json:"uid" gorm:"column:uid;index"`
BeforeVm uint32 `json:"before_vm"` // 变动前
AfterVm uint32 `json:"after_vm"` // 变动后
Alter int `json:"alter"` // 数值
Event string `json:"event" gorm:"type:varchar(100)"` // 事件
Describe string `json:"describe" gorm:"type:text"` // 描述
ErpOrderId uint32 `json:"erp_order_id" gorm:"index"` // 零售订单id
BillSn string `json:"bill_sn"` // 零售订单编号
ExpiryDate time.Time `json:"expiry_date"` // 积分过期时间
UsedVm int `json:"used_vm"` // 已使用积分
ExpiryVm int `json:"expiry_vm" gorm:"-"` // 即将过期的积分
}
func UserVmUpdate(uid uint32, amount int, event, describe string) error {
@ -69,8 +76,14 @@ func UserVmUpdate(uid uint32, amount int, event, describe string) error {
return err
}
} else {
sql := fmt.Sprintf("UPDATE user_vm SET vm = vm+? WHERE uid=?;")
err = begin.Exec(sql, amount, uid).Error
// 如果用户积分不够抵扣则扣到0为止
if int(userVm.Vm)+amount <= 0 {
sql := fmt.Sprintf("UPDATE user_vm SET vm = ? WHERE uid=?")
err = begin.Exec(sql, 0, uid).Error
} else {
sql := fmt.Sprintf("UPDATE user_vm SET vm = vm+? WHERE uid=?")
err = begin.Exec(sql, amount, uid).Error
}
if err != nil {
begin.Rollback()
logger.Error("err:", err)
@ -86,6 +99,33 @@ func UserVmUpdate(uid uint32, amount int, event, describe string) error {
Event: event,
Describe: describe,
}
if newValue := int(userVm.Vm) + amount; newValue > 0 {
vmRecord.AfterVm = uint32(newValue)
}
// 如果是正积分,则记录该订单对应积分的有效时间
if amount > 0 {
vmRecord.ExpiryDate = time.Now().AddDate(1, 0, 0)
if event == VmEventBuyGoodsReject { // 使用积分购买商品后取消
err = RefundPoints(begin, uid, amount)
if err != nil {
begin.Rollback()
logger.Error("err:", err)
return err
}
}
} else { // 如果是负积分,则记录积分使用情况;优先扣除最早获得的积分
if event == VmEventBuyGoods || event == VmEventErpOrderReject { // 使用积分购买商品,或者零售退货扣除积分
err = UsePoints(begin, uid, -amount)
if err != nil {
begin.Rollback()
logger.Error("err:", err)
return err
}
}
}
err = begin.Create(vmRecord).Error
if err != nil {
begin.Rollback()
@ -101,3 +141,102 @@ func UserVmUpdate(uid uint32, amount int, event, describe string) error {
}
return nil
}
// GetUserAvailablePointsRecords 查找用户的所有可用积分记录,按时间排序
func GetUserAvailablePointsRecords(uid uint32) []UserVmRecord {
var userVmRecord []UserVmRecord
err := NewUserVmRecordQuerySet(DB).UidEq(uid).OrderDescByCreatedAt().
EventIn(VmEventOpenMember, VmEventInvite1Member, VmEventInvite2Member, VmEventRenewMember, VmEventUpgradeMember,
VmEventAttendance, VmEventErpOrderSale).All(&userVmRecord)
if err != nil {
logger.Error("get user_vm_record err:", err)
return []UserVmRecord{}
}
return userVmRecord
}
func UsePoints(gdb *gorm.DB, uid uint32, points int) error {
// 1. 查找用户的所有可用积分记录,按时间排序
records := GetUserAvailablePointsRecords(uid)
remaining := points
for _, record := range records {
available := record.Alter - record.UsedVm // 计算该订单剩余可用积分
if available >= remaining {
// 该订单的剩余积分足够
record.UsedVm += remaining
// 更新积分记录
err := gdb.Omit("created_at").Save(record).Error
if err != nil {
logger.Error("update user_vm_record err:", err)
return err
}
break
} else {
// 该订单的剩余积分不足,全部使用,继续扣减下一条记录
record.UsedVm = record.Alter
remaining -= available
// 更新积分记录
err := gdb.Omit("created_at").Save(record).Error
if err != nil {
logger.Error("update user_vm_record err:", err)
return err
}
}
}
return nil
}
// GetUserUsedPointsRecords 查找用户的已使用积分记录,按使用时间倒序排序
func GetUserUsedPointsRecords(uid uint32) []UserVmRecord {
var userVmRecord []UserVmRecord
err := NewUserVmRecordQuerySet(DB).UidEq(uid).OrderDescByCreatedAt().
EventIn(VmEventOpenMember, VmEventInvite1Member, VmEventInvite2Member, VmEventRenewMember, VmEventUpgradeMember,
VmEventAttendance, VmEventErpOrderSale).UsedVmNe(0).All(&userVmRecord)
if err != nil {
logger.Error("get user_vm_record err:", err)
return []UserVmRecord{}
}
return userVmRecord
}
// RefundPoints 查找用户的已使用积分记录,按使用时间倒序排序
func RefundPoints(gdb *gorm.DB, uid uint32, points int) error {
// 1. 查找用户的已使用积分记录,按使用时间倒序排序
usedRecords := GetUserUsedPointsRecords(uid)
remaining := points
for _, record := range usedRecords {
used := record.UsedVm // 获取该订单已使用的积分
if used >= remaining {
// 该订单已使用的积分足够返还
record.UsedVm -= remaining
// 更新积分记录
err := gdb.Omit("created_at").Save(record).Error
if err != nil {
logger.Error("RefundPoints update user_vm_record err:", err)
return err
}
break
} else {
// 该订单已使用的积分不足以完全返还,全部返还后继续处理下一条记录
record.UsedVm = 0
remaining -= used
// 更新积分记录
err := gdb.Omit("created_at").Save(record).Error
if err != nil {
logger.Error("RefundPoints update user_vm_record err:", err)
return err
}
}
}
return nil
}

View File

@ -13,8 +13,9 @@ import (
"strings"
)
//go:generate goqueryset -in wx_msg.go
// gen:qs
//
//go:generate goqueryset -in wx_msg.go
type PublicRecord struct {
Model

View File

@ -33,7 +33,9 @@
"app_id": "wx806c079463b5b56c",
"app_secret": "cb125688bf4e482f66e8c46062d568fc",
"app_mchId": "1609877389",
"app_mchSecret": "DeovoMingHuiRengTianTang45675456"
"app_mchSecret": "DeovoMingHuiRengTianTang45675456",
"app_mchId_dw": "1494954322",
"app_mchSecret_dw": "6c9eozed9Hq0hmXPzh5QTcO1KwrJbG3z"
},
"app": {
"app_id": "wx806c079463b5b56c",