Merge branch 'dev-lwl/order'

This commit is contained in:
lwl0608 2024-05-17 14:08:57 +08:00
commit 16713c569f
13 changed files with 173 additions and 13 deletions

View File

@ -294,6 +294,7 @@ const (
ErrCodeVasInvalidVerifycode ErrCode = -7020 // 提现验证码错误
ErrCodeVasAlipayUniTransferFail ErrCode = -7021 // 支付宝提现失败
ErrCodeVasOverTodayWithdrawCnt ErrCode = -7022 // 今天提现次数到达上限
ErrCodeVasOverRefundLimit ErrCode = -7023 // 退款次数达上限
// Moment: 8xxx
ErrCodeMomentSrvOk ErrCode = ErrCodeOk

View File

@ -8,12 +8,9 @@ import (
func DealVasErr(err error) (errcode.ErrCode, error) {
var (
ec = errcode.ErrCodeVasSrvOk
ok bool
)
if err != nil {
ec, ok = ErrEcMap[err]
err = errors.Wrap(err, "VasError")
if ok {
if ec, ok := ErrEcMap[err]; ok {
return ec, err
}
ec = errcode.ErrCodeVasSrvFail
@ -41,6 +38,7 @@ var ErrEcMap = map[error]errcode.ErrCode{
ErrVasNoEnoughWithdrawDias: errcode.ErrCodeVasNoEnoughWithdrawDias,
ErrVasAlipayUniTransferFail: errcode.ErrCodeVasAlipayUniTransferFail,
ErrVasOverTodayWithdrawCnt: errcode.ErrCodeVasOverTodayWithdrawCnt,
ErrVasRefundLimit: errcode.ErrCodeVasOverRefundLimit,
}
var (
@ -62,4 +60,5 @@ var (
ErrVasNoEnoughWithdrawDias = errors.New("no enough withdraw dias")
ErrVasAlipayUniTransferFail = errors.New("alipay uni transfer fail")
ErrVasOverTodayWithdrawCnt = errors.New("over today withdraw cnt")
ErrVasRefundLimit = errors.New("账号已受限,解限请联系客服")
)

View File

@ -288,6 +288,7 @@ func Init(r *gin.Engine) {
vasPayGroup.POST("withdraw_apply", middleware.JSONParamValidator(vasproto.WithdrawApplyReq{}), WithdrawApply)
vasPayGroup.POST("deal_one_coin_order", middleware.JSONParamValidator(vasproto.DealOneCoinOrderReq{}), DealOneCoinOrder)
vasPayGroup.POST("deal_one_order", middleware.JSONParamValidator(vasproto.DealOneOrderReq{}), DealOneOrder)
vasPayGroup.POST("moment_order_list", middleware.JSONParamValidator(vasproto.ZoneMomentOrderListReq{}), ZoneMomentOrderList)
extVasPayGroup := r.Group("/ext/vas")
extVasPayGroup.POST("alipay_callback", AlipayCallback)

View File

@ -50,9 +50,13 @@ func CreateOrder(ctx *gin.Context) {
ReplyErrCodeMsg(ctx, errcode.ErrCodeBadParam)
return
}
data, ec := service.DefaultService.CreateOrder(ctx, req)
data, ec, err := service.DefaultService.CreateOrder(ctx, req)
if ec != errcode.ErrCodeVasSrvOk {
logger.Error("CreateOrder fail, req: %v, ec: %v", util.ToJson(req), ec)
if ec == errcode.ErrCodeVasSrvFail && err != nil {
ReplyErrorMsg(ctx, err.Error())
return
}
ReplyErrCodeMsg(ctx, ec)
return
}
@ -241,6 +245,15 @@ func isWithdrawFreeze(mid int64) bool {
return WithdrawFreezeMidMap[mid]
}
// 任意额度提现
var WithdrawAnyDiasMap = map[int64]bool{
74: true,
}
func isWithdrawAnyDiasEnable(mid int64) bool {
return WithdrawAnyDiasMap[mid]
}
// 提现发送验证码
func WithdrawSendVerifycode(ctx *gin.Context) {
req := ctx.MustGet("client_req").(*vasproto.WithdrawSendVerifycodeReq)

View File

@ -155,3 +155,31 @@ func ZoneExit(ctx *gin.Context) {
}
ReplyOk(ctx, nil)
}
func ZoneMomentOrderList(ctx *gin.Context) {
req := ctx.MustGet("client_req").(*vasproto.ZoneMomentOrderListReq)
if req.Mid <= 0 || req.MomentId <= 0 {
logger.Error("ZoneExit, invalid param, req: %v", util.ToJson(req))
ReplyErrCodeMsg(ctx, errcode.ErrCodeBadParam)
return
}
list, ec, err := service.DefaultService.ZoneMomentOrderList(ctx, req)
if ec != errcode.ErrCodeVasSrvOk {
logger.Error("ZoneExit fail, req: %v, ec: %v", util.ToJson(req), ec)
if ec == errcode.ErrCodeVasSrvFail && err != nil {
ReplyErrorMsg(ctx, err.Error())
return
}
ReplyErrCodeMsg(ctx, ec)
return
}
data := &vasproto.ZoneMomentOrderListData{
List: list,
Offset: req.Offset + len(list),
}
if len(list) >= req.Limit {
data.More = 1
}
ReplyOk(ctx, data)
}

View File

@ -270,6 +270,32 @@ func (m *Mysql) GetOrders(ctx *gin.Context, tx *sqlx.Tx, mid, st, et int64, offs
return
}
// 获取订单数
func (m *Mysql) GetOrderCnt(ctx *gin.Context, tx *sqlx.Tx, mid, st, et int64, orderStatus int32) (int, error) {
type S struct {
Cnt int `json:"cnt"`
}
var (
err error
s = S{}
)
sqlStr := fmt.Sprintf("select count(1) as cnt from %s where mid=? and order_status=? and ct>=? and ct<?", TableOrder)
args := []any{mid, orderStatus, st, et}
if tx != nil {
err = tx.GetContext(ctx, &s, sqlStr, args...)
} else {
db := m.getDBVas()
err = db.GetContext(ctx, &s, sqlStr, args...)
}
if err == sql.ErrNoRows {
return 0, nil
}
if err != nil {
return 0, err
}
return s.Cnt, nil
}
// 更新订单状态
func (m *Mysql) UpdateOrderStatus(ctx *gin.Context, tx *sqlx.Tx, orderId string, preStatus, aftStatus int32) error {
var err error

View File

@ -499,3 +499,24 @@ func (m *Mysql) GetZoneRefundHisList(ctx *gin.Context, tx *sqlx.Tx, mid, zid int
}
return
}
// 获取空间动态购买记录
func (m *Mysql) GetZoneMomentUnlockList(ctx *gin.Context, tx *sqlx.Tx, momentId int64, offset, limit int) (list []*dbstruct.ZoneMomentUnlock, err error) {
list = make([]*dbstruct.ZoneMomentUnlock, 0)
sqlStr := fmt.Sprintf("select * from %s where moment_id=? limit ? offset ?", TableVasZoneMomentUnlock)
args := []any{momentId, limit, offset}
if tx != nil {
err = tx.SelectContext(ctx, &list, sqlStr, args...)
} else {
db := m.getDBVas()
err = db.SelectContext(ctx, &list, sqlStr, args...)
}
if err == sql.ErrNoRows {
err = nil
return
}
if err != nil {
return
}
return
}

View File

@ -107,6 +107,22 @@ func (v *Vas) GetMembershipProductList(ctx *gin.Context, req *vasproto.GetMember
}
func (v *Vas) CreateOrder(ctx *gin.Context, req *vasproto.CreateOrderReq) (data *vasproto.CreateOrderData, err error) {
// 检查退订单次数
var (
et = time.Now().Unix()
st = et - 86400*30
)
cnt, err := v.store.GetOrderCnt(ctx, nil, req.Mid, st, et, dbstruct.VasOrderStatusRefund)
if err != nil {
logger.Error("GetOrderCnt fail, mid: %v, err: %v", req.Mid, err)
return
}
logger.Info("GetOrderCnt Refund, mid: %v, cnt: %v", req.Mid, cnt)
if cnt >= 8 {
err = fmt.Errorf("账号已受限,解限请联系客服")
return
}
var (
productId = req.ProductId
order *dbstruct.Order
@ -2970,6 +2986,9 @@ func (v *Vas) refundZoneMoment(ctx *gin.Context, order *dbstruct.Order, req *vas
return err
}
// 减购买人数
_ = v.store.DecZoneMomentBuyerCnt(ctx, zid, momentId)
return nil
}

View File

@ -14,6 +14,7 @@ import (
"service/bizcommon/util"
"service/dbstruct"
"service/library/logger"
"service/library/redis"
"time"
)
@ -911,7 +912,20 @@ func (v *Vas) ZoneGetRefundPage(ctx *gin.Context, req *vasproto.ZoneRefundPageRe
}
// 空间退款
func getCheckZoneRefundFreqKey(mid int64) string {
return fmt.Sprintf("zone_refund_freq_%d", mid)
}
func (v *Vas) ZoneRefund(ctx *gin.Context, req *vasproto.ZoneRefundReq) error {
redisKey := getCheckZoneRefundFreqKey(req.Mid)
redisCli := redis.GetRedisClient()
// 获取上次退款时间
t, _ := redisCli.GetInt64(redisKey)
logger.Info("ZoneRefund check freq, key: %v, t: %v", redisKey, t)
if time.Now().Unix()-t < 3600*12 {
return fmt.Errorf("12小时内您最多只能进行1次退款")
}
// 获取解锁信息
zv, err := v.store.GetZoneUnlock(ctx, nil, req.Mid, req.Zid)
if err == sql.ErrNoRows || zv == nil {
@ -951,6 +965,9 @@ func (v *Vas) ZoneRefund(ctx *gin.Context, req *vasproto.ZoneRefundReq) error {
return err
}
// redis记录退款时间
_ = redisCli.Set(redisKey, time.Now().Unix(), 86400)
return nil
}
@ -1184,3 +1201,8 @@ func (v *Vas) ZoneExit(ctx *gin.Context, mid, zid int64) error {
return nil
}
// 获取动态解锁记录
func (v *Vas) GetZoneMomentUnlockList(ctx *gin.Context, momentId int64, offset, limit int) (list []*dbstruct.ZoneMomentUnlock, err error) {
return v.store.GetZoneMomentUnlockList(ctx, nil, momentId, offset, limit)
}

View File

@ -1015,7 +1015,7 @@ func (s *Service) GetMembershipProductList(ctx *gin.Context, req *vasproto.GetMe
return
}
func (s *Service) CreateOrder(ctx *gin.Context, req *vasproto.CreateOrderReq) (data *vasproto.CreateOrderData, ec errcode.ErrCode) {
func (s *Service) CreateOrder(ctx *gin.Context, req *vasproto.CreateOrderReq) (data *vasproto.CreateOrderData, ec errcode.ErrCode, err error) {
switch req.ProductId {
case dbstruct.ProductIdMembership:
req.ReturnUrl = "https://tiefen.fun/vip"
@ -1023,7 +1023,7 @@ func (s *Service) CreateOrder(ctx *gin.Context, req *vasproto.CreateOrderReq) (d
req.ReturnUrl = "https://tiefen.fun/pay"
}
data, err := _DefaultVas.CreateOrder(ctx, req)
data, err = _DefaultVas.CreateOrder(ctx, req)
ec, err = errs.DealVasErr(err)
if err != nil {
logger.Error("CreateOrder fail, err: %v", err)

View File

@ -1040,3 +1040,33 @@ func (s *Service) OpZoneRefundList(ctx *gin.Context, req *zoneproto.OpZoneRefund
}
return
}
func (s *Service) ZoneMomentOrderList(ctx *gin.Context, req *vasproto.ZoneMomentOrderListReq) (list []*vasproto.ZoneMomentOrderVO, ec errcode.ErrCode, err error) {
list = make([]*vasproto.ZoneMomentOrderVO, 0)
// 空间动态解锁历史
zmuList, err := _DefaultVas.GetZoneMomentUnlockList(ctx, req.MomentId, req.Offset, req.Limit)
logger.Info("ZoneMomentOrderList, id: %v, zmuList: %v, err: %v", req.MomentId, len(zmuList), err)
ec, err = errs.DealVasErr(err)
if err != nil {
return
}
// 获取账号
mids := make([]int64, 0)
for _, zmu := range zmuList {
mids = append(mids, zmu.GetMid())
}
acntMap, _ := _DefaultAccount.GetAccountMapByMids(ctx, mids)
logger.Info("ZoneMomentOrderList, id: %v, acntMap: %v, err: %v", req.MomentId, len(acntMap), err)
// 组装
for _, zmu := range zmuList {
item := &vasproto.ZoneMomentOrderVO{
Account: acntMap[zmu.GetMid()],
BuyTime: zmu.GetCt(),
OrderId: zmu.GetOrderId(),
}
list = append(list, item)
}
return
}

View File

@ -141,10 +141,10 @@ func NewVideoFromJson(item any) (vid *Video, err error) {
err = errors.New("invalid video object with null md5")
return
}
if vid.Dur == 0 {
err = errors.New("invalid video object with zero dur")
return
}
//if vid.Dur == 0 {
// err = errors.New("invalid video object with zero dur")
// return
//}
if vid.Fmt == "" {
err = errors.New("invalid video object with null fmt")
return

View File

@ -59,7 +59,7 @@ crypto:
alipay:
appid: "2021004115647165"
private_key: "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtj6Nu2olEB8c8SDSANExaPbmk8LoYPEGB/APZDskhezO/w4OwPmG1Ak79XDpUUIihdmTZ8i2nBLhhRpFZGU4MMdil4X7a5nYHBm5dkGo3isIInn/qV7AYDqek4pGpMUPI6fbR05NWnUTZ+3AvMjTNBa979MgLyqS3jzpvuK6yXM5RinKVv8IF9KgthRKjH4LHyyRXBGu2cJSA5utjzFCL9KIu/T4XXZ09HOgz+JKPxXDj25Ob5eTtcBDsoJfXChcOvwCA7nxb1jzvGDrkqF36H1CC8KT1aoLRLisBsM+7sjEfNcB4RG5pGHSDGQJwZ0stGAhXf/fuWiLmI/zMOXODAgMBAAECggEAEL7CAuj8w16Iv20r+46QK0i3R42eNsZhf5wD9wYxK5TKal7/rppmLOObIWCrlATtGb7lfg2aj/mpnGEFlvYVDKImh+KYrZ/8lTLupQJQ7SjrDY/VQZPSPo/zZrohWZSSOKkyEg56samcwfc7XKJYa8t3odr9Df4wJDGibrL/z99xrJrz85le+NHBISXUyddS5ojuDNfGwE39wgLu52P74QYxv6s0xZKj2aALXaLXyTzF4ys34nVhhv75gXFtENiUet5/PVRYe7OE4cndcOP9WI3nXP5ojak8N4fY15S0YOm/0NZP8w6nWUemFjUNRXYRY42J+W+/myW8RIppaGuwkQKBgQDYH263Lh8C9EkjGA2po68LUTBhM2fT2L3batzHjXo0jvLT0IR88/9V7xhC3ZQZNcxQCK0xaCYfzFx3UV9veC1zeVRW0i/hyJ8B40w3WXCoGDiHgzQ/kcu/Iaw2qmJyhEFzOwAfrxIgco9EiZBaY7fXyy7YkZLGqXNFcLsuWR5qWwKBgQDNlc19CESIukT31Ap2QBe6t9YNXHZuKTePBRaIUCan3vZwPfZePLJQCgtoVhnCGoHZJ+ZlNhYri9x6DNLZpxCSHZNjccmqFGj3N7xWBqU38gu2dcPdMAxT1ERwf2gdlhgWAhVzD56hsWyrbP9YZACXy7TlevSj7s/5GaNaVuHT+QKBgQC2VZZ3zt51BJnrlLB6LVFRz/ZsGw1+qj5LLpYDeXXff7aYQzRzovsJigVC7GO0/TFZWGid5Us8ypI8TBejGJXn9TXVZdDlwPd9hUFY9QlZl82hbm0XMK7fms4K9KbIDJKXX/CTyoUVgPEkFpcF21lQIuhr6C0XlABfVmNlD+TcPwKBgHJuot2ov3UXsZH8/gHKNSsibswrHmS9HobGPz+K1al1Stk5NCxKPrqcjLL70gSf+ozkT7MggwCkLgnln2u1OV0Lh2HAEY9RIwgQhw2fT1GvseNS873no8T5j0rLMCnfxPJjIItWM2cvOhzFY/BQYaAcrElbwlaJdEvkgG+lkrgJAoGBAInYRdHo9V1exDUS0ucQuraoEtuvgOrqatnCbuNZ9EpgjFJxDbHXOIJYPvgfpyws4amdksNQL0Ux9+p+esJOS+JYYkE1nmCTCrfb6SNKr+PdeUteKtTiHJb4zJhGVC2Lk4uBg9AGa/d7j5apWw4RsZ/R1ky1S6KQUkqItbVrhC8l"
notify_url: ""
notify_url: "https://api.wishpal.cn/ext/vas/alipay_callback"
app_cert_path: "/app/wishpal-ironfan/etc/mix/alipaycert/appCertPublicKey_2021004115647165.crt"
alipay_root_cert_path: "/app/wishpal-ironfan/etc/mix/alipaycert/alipayRootCert.crt"
alipay_public_cert_path: "/app/wishpal-ironfan/etc/mix/alipaycert/alipayCertPublicKey_RSA2.crt"
@ -67,7 +67,7 @@ alipay:
alipay_myts:
appid: "2021004135664261"
private_key: "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCT2MbUzyyMFUJ8EXGVotZmNMDhkw4Zv9diPgLEmnExoBGj41waqtumFMo2o63J4akBP//87r2ap+e7KKqt+WkRZZ8UB/Mj5SwQBzxqJakI+pO7YM6kM6kiAAKOLG7lloMDiQwlMxHUC52o+xJQj7RA0M/pUcVar5rr+BOnhLSH5RTrA5u5xzT5vPdmwqOxnY1OiDe7WB6VbPusLKDVbtvdT7icLnS200FYg4AQ27Sa5L8Ss9MwNcNCh4Z2eA/iriVgCvdtgNiz2RRgmAReSn4u2BBb6dZEDG6SAVsNARYs+avcYaVHpflqDfDRqPgdJ+4mQSCetQ2HDPA8GDbkn05HAgMBAAECggEAHUeaIP0ikl+HejCuMPc9xKH/7OyFp13R1vf27l6zuiM8OxvE2tcphtupLGb//PI+2SuGk93oGN/VycAFBU1WnIZmmb31Tg+NyWLVeSQaNNgDN+G1Ktm8Tip4VxW/pKJJMgMLL7bMehUO1S9b8i5zgT6ZXli+X/ZVFRRdOBjU8/CCDntTI44JmSLDnGAmR0dz3rP5/Sp2x8Yo/2O77bEBPHmT//7RVk+x1pn6olHwAsztmMddurZuLGoCP4hhZGwjuplrlyEXpe6IEpI2G0UNS97PJfL6JU56TKwMYrbo9ZV6ru5AfEeAKANPL/Urb6Gx9pcpEgktLga5B6z1glh/gQKBgQDRcZeJmpBjLO3mYlz7jqGmMtNPK06JiFr9m3NGsiE3fQmqKvEY9W0nfPX5DFYx5NFb/UWTpeuYe3NHMVo8Jwh4gNip3/AkUQylYLNxirFf6/2FltlPCsnlmeFclz9xDKzQncO60m40g2oEQ4eXUmVEOfLzpLzlsL3aXUP/K3sWBwKBgQC0tgHdFgTqE7rVn/xvZsgBas26P1tM707EYYoMGccf6zbhEMCs5e1n5nvPenX2H11TOzQDLsQz6bsZvnJ8FSoo1+pTYWi6Zr1nWDZMEQQcVGf2yLsUzFSrWHNyII/ZEeSW1UV25zlMjbv7y/VnuBlH1EJZDlv5ssSUyaAugYn1wQKBgQDQMoW70Ly1CYWXXbImkjtYVe++JEOW7cfdkDiATzQ7z3za/oLaF6Yg+dQddMj+IgKH2fXe9rGCyzzlyUZ0wyxldVdrTmOOBk922fCm7oKx4ooK0NBGBWh7Z4Mhomv7OelUG2/k96d7ZiLuCB7yKoLl1mEPF3R7Mz0Wo12jexqI4wKBgGdr3scr6eYZIo1OAYe0F/UPrevQhK0ULE0h0YK5Yge3cvH9x3dsI6GZ+/OzDz2rl5qhwFOt+SYIt0a1gwnWhwlXAMl1bx123SD/EBwahPK9r75CBSeTBUYG2hNP5WOC5QMZzaaOEHHqj9I8WRdh+j3skYgsOqE+GVlZxy22f0FBAoGAXFiGFH/X2hbwRGE5KChzQsuClC7GJ/JJgjIhHuUqUa/rHiQwWyx+uJI0c91KwsGssdpMVTnlFzeDHxdICId7YLhOgSNX92gdZDpJc6RvrU834xBszLtuukHWXpShbBDcsN/sSChI1jg6CPbjKuI2FoNm66s6puSHDXEPMTZTQYA="
notify_url: ""
notify_url: "https://api.wishpal.cn/ext/vas/alipay_callback"
app_cert_path: "/app/wishpal-ironfan/etc/mix/alipaycert_myts/appCertPublicKey_2021004135664261.crt"
alipay_root_cert_path: "/app/wishpal-ironfan/etc/mix/alipaycert_myts/alipayRootCert.crt"
alipay_public_cert_path: "/app/wishpal-ironfan/etc/mix/alipaycert_myts/alipayCertPublicKey_RSA2.crt"