mh_server/controller/game_card.go
2022-11-01 14:23:06 +08:00

1314 lines
38 KiB
Go

package controller
import (
"context"
"crypto/md5"
"encoding/json"
"encoding/xml"
"fmt"
"github.com/codinl/go-logger"
"github.com/gin-gonic/gin"
"github.com/rs/zerolog/log"
"github.com/wechatpay-apiv3/wechatpay-go/core/auth/verifiers"
"github.com/wechatpay-apiv3/wechatpay-go/core/downloader"
"github.com/wechatpay-apiv3/wechatpay-go/core/notify"
"github.com/wechatpay-apiv3/wechatpay-go/services/payments"
wechatpayutils "github.com/wechatpay-apiv3/wechatpay-go/utils"
"io/ioutil"
"mh-server/config"
aliyun "mh-server/lib/ali"
"mh-server/lib/auth"
"mh-server/lib/status"
"mh-server/lib/utils"
"mh-server/lib/wxpay"
"mh-server/model"
"sort"
"strings"
"time"
)
func GameCardList(c *gin.Context) {
req := struct {
Page int `json:"cur_page"`
PageSize int `json:"page_size"`
SortType int `json:"sort_type"` // 排序类型 1-默认 2-新品 3-销量 4-价格 大到小 5-价格 小到大
GameTypeIds []uint64 `json:"game_type_id"` // 游戏类型id
StoreId uint32 `json:"store_id"`
}{
Page: 1,
PageSize: 10,
}
if c.ShouldBindJSON(&req) != nil {
logger.Error("para err")
RespJson(c, status.BadRequest, nil)
return
}
uc := auth.GetCurrentUser(c)
if uc == nil {
//RespJson(c, status.Unauthorized, nil)
//return
uc = &auth.UserClaims{Uid: 0}
}
fmt.Println("游戏类型:GameTypeIds:", req.GameTypeIds)
cardList, totalPage, err := model.GetGameCardList(req.SortType, req.Page, req.PageSize,
req.GameTypeIds, req.StoreId, uc.Uid)
if err != nil {
logger.Error("err:", err)
RespJson(c, status.InternalServerError, nil)
return
}
ret := map[string]interface{}{
"card_list": cardList,
"cur_page": req.Page,
"total_page": totalPage,
}
RespOK(c, ret)
}
func GameCardInfo(c *gin.Context) {
req := struct {
GameId uint64 `json:"game_id"`
StoreId uint32 `json:"store_id"` // 门店id
}{}
if c.ShouldBindJSON(&req) != nil {
RespJson(c, status.BadRequest, nil)
return
}
uc := auth.GetCurrentUser(c)
if uc == nil {
RespJson(c, status.Unauthorized, nil)
return
}
go func() {
err := model.HistoryBrowsingAdd(uint64(uc.Uid), req.GameId)
if err != nil {
log.Error().Msgf("history browsing add err:%#v", err)
}
}()
info, err := model.GetGameCardInfo(req.GameId, req.StoreId)
if err != nil {
logger.Error("err:", err)
RespJson(c, status.InternalServerError, nil)
return
}
user := model.GetUserByUid(uc.Uid)
if user.IsMember() {
info.RealPrice = 0
}
userCollection := model.GameCardUserCollection(uint64(uc.Uid), req.GameId)
ret := map[string]interface{}{
"card_info": info,
"is_collection": userCollection,
}
RespOK(c, ret)
}
func GameCardSearch(c *gin.Context) {
req := struct {
Page int `json:"page"`
PageSize int `json:"page_size"`
Name string `json:"name"` // 搜索
StoreId uint32 `json:"store_id"`
}{
Page: 1,
PageSize: 10,
}
if c.ShouldBindJSON(&req) != nil {
RespJson(c, status.BadRequest, nil)
return
}
uc := auth.GetCurrentUser(c)
if uc == nil {
RespJson(c, status.Unauthorized, nil)
return
}
cardList, totalPage, err := model.GetGameCardSearch(req.Name, req.Page, req.PageSize, req.StoreId)
if err != nil {
logger.Error("err:", err)
RespJson(c, status.InternalServerError, nil)
return
}
err = model.SearchHistoryAdd(uc.Uid, req.Name)
if err != nil {
logger.Error("err:", err)
RespJson(c, status.InternalServerError, nil)
return
}
ret := map[string]interface{}{
"card_list": cardList,
"cur_page": req.Page,
"total_page": totalPage,
}
RespOK(c, ret)
}
func GameCardSearchHistory(c *gin.Context) {
uc := auth.GetCurrentUser(c)
if uc == nil {
RespJson(c, status.Unauthorized, nil)
return
}
historyList, err := model.GetSearchHistoryList(uc.Uid)
if err != nil {
logger.Error("err:", err)
RespJson(c, status.InternalServerError, nil)
return
}
RespOK(c, historyList)
}
func GameCardHotSearch(c *gin.Context) {
searchList, err := model.HotSearchList()
if err != nil {
logger.Error("err:", err)
RespJson(c, status.InternalServerError, nil)
return
}
RespOK(c, searchList)
}
func HomeCarouselList(c *gin.Context) {
uc := auth.GetCurrentUser(c)
if uc == nil {
//RespJson(c, status.Unauthorized, nil)
//return
uc = &auth.UserClaims{Uid: 0}
}
carouselList, err := model.GetHomeCarouselList()
if err != nil {
logger.Error("err:", err)
RespJson(c, status.InternalServerError, nil)
return
}
var activityMemberRenewal model.ActivityMemberRenewal
if uc.Uid != 0 {
err = model.NewActivityMemberRenewalQuerySet(model.DB).UidEq(uc.Uid).OrderDescByID().
Limit(1).One(&activityMemberRenewal)
if err != nil && err != model.RecordNotFound {
logger.Error("activity member renewal err:", err)
RespJson(c, status.InternalServerError, nil)
return
}
}
user := model.GetUserByUid(uc.Uid)
if uc.Uid == 0 || !user.IsMember() || !(user.MemberExpire.Before(utils.Now().AddDate(0, 1, 0))) ||
activityMemberRenewal.State == 3 {
// && user.MemberExpire.After(utils.Now()))
list := make([]model.HomeCarousel, 0, len(carouselList))
for i, _ := range carouselList {
if carouselList[i].ActivityType == 1 {
continue
}
list = append(list, carouselList[i])
}
carouselList = list
}
RespOK(c, carouselList)
}
func GameCardTypeList(c *gin.Context) {
gameTypes, err := model.GetGameCardTypeList()
if err != nil {
logger.Error("err:", err)
RespJson(c, status.InternalServerError, nil)
return
}
RespOK(c, gameTypes)
return
}
func GameCardTypes(c *gin.Context) {
req := struct {
GameId uint64 `json:"game_id"`
}{}
if c.ShouldBindJSON(&req) != nil {
RespJson(c, status.BadRequest, nil)
return
}
gameCard := model.GameCard{}
gameCard.ID = uint32(req.GameId)
gameTypes, err := gameCard.GetGameType()
if err != nil {
logger.Error("err:", err)
RespJson(c, status.InternalServerError, nil)
return
}
RespOK(c, gameTypes)
return
}
type (
PushTemplateMessageTarget struct {
Uid uint32 `json:"uid"`
WxName string `json:"wx_name"`
WxOpenID string `json:"wx_open_id"`
FormIdID uint32 `json:"form_id_id"`
FormId string `json:"form_id"`
}
WXPayNoticeResp struct {
XMLName xml.Name `xml:"xml"`
ReturnCode string `xml:"return_code" json:"return_code"`
}
)
// 微信推送支付通知
func PushWXPayNotice(c *gin.Context) {
fmt.Println("微信推送支付通知")
body, err := ioutil.ReadAll(c.Request.Body)
if err != nil {
logger.Error(err)
}
logger.Error("xml Request.Body1:", string(body))
var notifyInfo wxpay.WechatNotifyInfo
//if err := c.ShouldBindXML(&notify); err != nil {
// logger.Error(err)
// RespBodyXML(c, map[string]string{
// "return_code": "FAIL",
// })
// return
//}
err = xml.Unmarshal(body, &notifyInfo)
if err != nil {
logger.Error(err)
}
ret := WXPayNoticeResp{
ReturnCode: "FAIL",
}
correctSign, err := PayCallBackHandle(notifyInfo, config.AppConfig.WxMchSecret)
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 {
logger.Info("租借游戏卡 支付成功:")
var order model.Order
err := model.NewOrderQuerySet(model.DB).OrderSnEq(notifyInfo.OutTradeNo).
PayStatusEq(PayStatusUnPay).CardStatusNe(OrderCardStatusCancel).One(&order)
if err != nil {
logger.Error("err:", err)
return
}
//orderJson, _ := json.Marshal(&order)
//fmt.Println("orderJson:", string(orderJson))
begin := model.DB.Begin()
err = model.NewOrderQuerySet(begin).IDEq(order.ID).GetUpdater().
SetPayStatus(model.PayStatusPaid).SetPayTime(time.Now()).Update()
if err != nil {
begin.Rollback()
logger.Error("err:", err)
return
}
//model.OrderCard{}
_, err = model.NewOrderCardQuerySet(begin).OrderIdEq(order.ID).GetUpdater().
SetPayStatus(model.PayStatusPaid).UpdateNum()
if err != nil {
begin.Rollback()
logger.Error("err:", err)
return
}
sub := model.DeliverTaskSub{
Uid: uint32(order.Uid),
UserAddressId: uint32(order.UserAddressId),
OrderType: 1,
OrderId: order.ID,
StoreId: uint32(order.StoreId),
}
err = sub.Add()
if err != nil {
logger.Error("deliver task sub add err:", err)
}
err = order.InventoryReduction(begin)
if err != nil {
begin.Rollback()
logger.Error("err:", err)
if order.PostageType == 1 {
// 库存不足取消订单
orderSn := model.GetOrderSn()
memberRecord := &model.UserOpenMemberRecord{OpenNo: orderSn, OrderType: 2, Order: &order}
err = memberRecord.OrderRefund(notifyInfo.OutTradeNo)
if err != nil {
logger.Error("err:", err)
return
}
}
// TODO
if order.PostageType == 2 {
var userCoupon model.UserCoupon
err = model.NewUserCouponQuerySet(model.DB).ActivityTypeEq(3).UidEq(uint32(order.Uid)).
StateEq(2).OrderAscByID().Limit(1).One(&userCoupon)
if err != nil && err != model.RecordNotFound {
logger.Error("user coupon err:", err)
RespJson(c, status.InternalServerError, nil)
return
}
err = model.NewUserCouponQuerySet(model.DB).IDEq(userCoupon.ID).GetUpdater().SetState(1).Update()
if err != nil {
logger.Error("user coupon err:", err)
}
}
//err = model.UserOpenMemberRecord{Uid: uint32(order.Uid), OpenNo: orderSn, OrderId: order.ID, OrderType: 2}.Insert()
//if err != nil {
// logger.Error(errors.New("WebPay err"))
// //RespJson(c, status.InternalServerError, nil)
// return
//}
//orderRefund := wxpay.OrderRefund{
// //OutTradeNo: outTradeNo,
// OutTradeNo: notify.OutTradeNo,
// OutRefundNo: orderSn,
// NotifyUrl: "",
// Amount: wxpay.OrderRefundAmount{
// Refund: order.PayPrice,
// Total: order.PayPrice,
// Currency: "CNY",
// },
//}
////bytes, _ := json.Marshal(order)
////fmt.Println("订单取消:", string(bytes))
////orderRefundJson, _ := json.Marshal(&orderRefund)
////fmt.Println("订单取消 orderRefundJson:", string(orderRefundJson))
//////err = wxpay.WxPayOrderRefund(orderRefund)
//err = wxpay.TransactionOrderRefund(orderRefund)
//if err != nil {
// logger.Error("err:", err)
// //RespJson(c, status.InternalServerError, nil)
// return
//}
_, err := model.NewOrderQuerySet(model.DB).IDEq(order.ID).GetUpdater().
SetCardStatus(OrderCardStatusCancel).UpdateNum()
if err != nil {
logger.Error("err:", err)
return
}
_, err = model.NewOrderCardQuerySet(model.DB).OrderIdEq(order.ID).GetUpdater().
SetCardStatus(OrderCardStatusCancel).UpdateNum()
if err != nil {
logger.Error("err:", err)
return
}
return
}
err = begin.Commit().Error
if err != nil {
begin.Rollback()
logger.Error("err:", err)
return
}
go model.ShoppingCartCreateOrderByOrder(order)
fundRecord.Uid = uint32(order.Uid)
fundRecord.FundType = model.FundTypeExpressFee
fundRecord.Remark = "借卡邮费"
}
if notifyInfo.Attach == wxpay.WxPayMember {
logger.Info("开通会员 支付成功:")
logger.Info("用户uid:", 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
}
remark := ""
if record.MemberLevel == 2 {
remark = "黄金会员费"
} else if record.MemberLevel == 4 {
remark = "白金会员费"
} else if record.MemberLevel == 5 {
remark = "黑金会员费"
}
fundRecord.Uid = uint32(record.Uid)
fundRecord.FundType = model.FundTypeMemberFee
fundRecord.Remark = remark
memberRecord := &model.UserMemberRecord{
Uid: record.Uid,
AfterMemberLevel: record.MemberLevel,
}
newTime := time.Now()
var spendType uint32
var user model.User
err = model.NewUserQuerySet(model.DB).UidEq(record.Uid).One(&user)
if err != nil {
logger.Error("err:", err)
return
} else {
spendType = uint32(2)
if !user.OpenMemberTime.IsZero() {
spendType = 3
}
expireTime := newTime.AddDate(1, 0, 0)
if user.MemberExpire.After(newTime) {
expireTime = user.MemberExpire.AddDate(1, 0, 0)
}
memberRecord.BeforeMemberLevel = user.MemberLevel
memberRecord.BeforeMemberExpire = user.MemberExpire
memberRecord.Serial = uint32(user.MemberExpire.Unix())
memberRecord.AfterMemberExpire = expireTime
if user.IsMember() {
memberRecord.OpenMemberLevel = user.OpenMemberLevel
memberRecord.OpenMemberTime = user.OpenMemberTime
} else {
memberRecord.OpenMemberLevel = record.MemberLevel
memberRecord.OpenMemberTime = newTime
}
memberConfig, err := model.GetMemberConfig(record.MemberLevel)
if err != nil {
logger.Error("GetMemberConfig err:", err)
return
}
//openMemberTime := newTime
userUpdateQs := model.NewUserQuerySet(model.DB).UidEq(record.Uid).GetUpdater().SetMemberLevel(record.MemberLevel).
SetMemberExpire(expireTime).SetDeposit(memberConfig.MemberDeposit)
if user.OpenMemberTime.IsZero() {
//openMemberTime = user.OpenMemberTime
userUpdateQs = userUpdateQs.SetOpenMemberTime(newTime).SetOpenMemberLevel(record.MemberLevel)
memberRecord.Type = model.GetUserMemberRecordType(record.MemberLevel, 1)
} else {
memberRecord.Type = model.GetUserMemberRecordType(record.MemberLevel, 2)
}
_, err = userUpdateQs.UpdateNum()
if err != nil {
logger.Error("err:", err)
return
}
if record.UserCouponId > 0 {
err = model.NewUserCouponQuerySet(model.DB).IDEq(record.UserCouponId).GetUpdater().
SetState(2).SetUseTime(utils.Now()).Update()
if err != nil {
logger.Error("update user coupon state err:", err)
}
var userCoupon model.UserCoupon
err = model.NewUserCouponQuerySet(model.DB).IDEq(record.UserCouponId).One(&userCoupon)
if err != nil {
logger.Error("user coupon err:", err)
} else {
if userCoupon.Approach == 1 {
err = model.StorePromotion(userCoupon.PromotionalSales, userCoupon.Uid, nil, &user)
if err != nil {
logger.Error("store promotion err:", err)
}
}
}
}
// 邀请记录
var invite model.UserInvite
//err = model.NewUserInviteQuerySet(model.DB).ToUidEq(record.Uid).OrderDescByID().Limit(1).One(&invite)
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 == model.RecordNotFound {
// userInvite := &model.UserInvite{
// FromUid: 0,
// UserType: 0,
// StoreId: 0,
// MemberOpenTime: newTime,
// MemberType: 2,
// ToUid: record.Uid,
// MemberStatus: 2,
// MemberLevel: record.MemberLevel,
// Action: 1,
// SpendType: 1,
// }
// err := userInvite.Create(model.DB)
// if err != nil {
// logger.Error("err:", err)
// }
// err = model.SendUserVm(record.Uid, record.MemberLevel, 100)
// if err != nil {
// logger.Error("send user vm err:", err)
// }
//}
if err == nil {
//qs := model.NewUserInviteQuerySet(model.DB).ToUidEq(record.Uid).GetUpdater()
if invite.Action != 2 {
qs := model.NewUserInviteQuerySet(model.DB).IDEq(invite.ID).GetUpdater()
// SpendType 类型
//if user.MemberLevel != 2 {
// qs = qs.SetMemberOpenTime(newTime).SetMemberLevel(record.MemberLevel)
//}
qs = qs.SetMemberOpenTime(newTime).SetMemberLevel(record.MemberLevel)
_, err = qs.SetMemberType(2).SetMemberStatus(2).
SetAction(2).SetSpendType(spendType).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).Update()
if err != nil {
logger.Error("update user invite record err:", err)
}
}()
}
} else {
inviteRecordNew := &model.UserInviteRecord{
ToUid: invite.ToUid,
FromUid: invite.FromUid,
Action: 2,
SpendType: spendType,
MemberLevel: record.MemberLevel,
First: 0,
Scan: 0, // 自动生成
ActionTime: newTime,
}
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: invite.StoreId,
//MemberOpenTime: invite.MemberOpenTime,
MemberOpenTime: time.Now(),
MemberType: 2,
MemberStatus: 2,
ToUid: invite.ToUid,
StoreType: invite.StoreType,
Action: 2,
SpendType: spendType,
MemberLevel: record.MemberLevel,
UserInviteRecordId: inviteRecordNew.ID,
FirstInvite: 0,
}
err = model.DB.Create(userInviteNew).Error
if err != nil {
logger.Error("create invite record err:", err)
}
}
if invite.FromUid != 0 {
inviteUser := model.GetUserByUid(invite.FromUid)
if inviteUser != nil {
if inviteUser.UserType != 2 /*不是店员*/ && user.MemberLevel != 2 { // 邀请 新用户推送一次
err = model.SendUserVm(inviteUser.Uid, record.MemberLevel, 1)
if err != nil {
logger.Error("send user vm err:", err)
}
}
if spendType == 2 {
err = model.SendUserVm(user.Uid, record.MemberLevel, 0)
if err != nil {
logger.Error("send user vm err:", err)
}
}
openMemberChannel := model.OpenMemberChannelUserInvite
userQs := model.NewUserQuerySet(model.DB).UidEq(record.Uid).GetUpdater()
if inviteUser.UserType == 2 {
openMemberChannel = model.OpenMemberChannelStorePromotion
if !user.OpenMemberTime.IsZero() {
userQs = userQs.SetCooperativeBusinessId(inviteUser.CooperativeBusinessId).
SetCooperativeName(inviteUser.CooperativeName)
fmt.Println("用户续费---")
model.AddCooperativeMemberRenewal(inviteUser.CooperativeBusinessId,
uint32(inviteUser.StoreId), inviteUser.Uid, int(record.MemberLevel))
} else {
fmt.Println("用户开通------")
model.AddCooperativeMemberPromotion(inviteUser.CooperativeBusinessId,
uint32(inviteUser.StoreId), inviteUser.Uid, int(record.MemberLevel))
}
}
_, err = userQs.SetOpenMemberChannel(openMemberChannel).UpdateNum()
if err != nil {
logger.Error("err:", err)
}
}
}
}
}
if user.MemberLevel != 2 {
}
go func() {
err = model.DB.Create(memberRecord).Error
if err != nil {
logger.Error("create member record err:", err)
}
}()
model.CreateUserRentCardByMemberLevel(record.Uid, record.MemberLevel, memberConfig.CardMax)
}
_, 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:", notifyInfo.TotalFee)
fmt.Println("notify.OutTradeNo:", notifyInfo.OutTradeNo)
}
if notifyInfo.Attach == wxpay.WxPayDeposit {
record := &model.UserOpenMemberRecord{OpenNo: notifyInfo.OutTradeNo}
err := record.GetByOpenNo()
if err != nil {
logger.Error("err:", err)
return
}
if record.State == 2 {
ret.ReturnCode = "SUCCESS"
RespBodyXML(c, ret)
return
}
//if record.State != 2 {
user := model.GetUserByUid(record.Uid)
if user == nil {
logger.Error("user nil")
return
}
memberConfig, err := model.GetMemberConfig(user.MemberLevel)
if err != nil {
logger.Error("err:", err)
return
}
remark := ""
if user.MemberLevel == 2 {
remark = "黄金会员押金"
} else if user.MemberLevel == 4 {
remark = "白金会员押金"
} else if user.MemberLevel == 5 {
remark = "黑金会员押金"
}
fundRecord.Uid = uint32(record.Uid)
fundRecord.FundType = model.FundTypeMemberDeposit
fundRecord.Remark = remark
num, err := model.NewUserQuerySet(model.DB).UidEq(record.Uid).GetUpdater().
SetDeposit(memberConfig.MemberDeposit).UpdateNum()
if err != nil {
logger.Error("update deposit err:", err)
}
if num == 0 {
logger.Error("update deposit num is 0")
}
_, 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)
}
//}
}
if notifyInfo.Attach == wxpay.WxPayBuyGoods {
_, err = model.NewGoodsOrderQuerySet(model.DB).SerialNoEq(notifyInfo.OutTradeNo).GetUpdater().
SetPayTime(time.Now()).
SetPayStatus(model.PayStatusOK).
SetState(model.GoodsOrderStateOnDeliver).UpdateNum()
if err != nil {
logger.Error("err:", err)
}
var goodsOrder model.GoodsOrder
err = model.NewGoodsOrderQuerySet(model.DB).SerialNoEq(notifyInfo.OutTradeNo).One(&goodsOrder)
if err != nil {
logger.Error("err:", err)
}
err = model.OrderUpdateGoodsStock(goodsOrder.GoodsAttributeId, goodsOrder.Quantity, model.DB)
if err != nil {
logger.Error("err:", err)
}
err = model.UserVmUpdate(goodsOrder.Uid, int(goodsOrder.Vm)*-1, model.VmEventBuyGoods, "购买商品积分抵扣")
if err != nil {
logger.Error("err:", err)
}
sub := model.DeliverTaskSub{
Uid: uint32(goodsOrder.Uid),
UserAddressId: uint32(goodsOrder.AddressId),
OrderType: 2,
OrderId: goodsOrder.OrderId,
StoreId: 13,
}
err = sub.Add()
if err != nil {
logger.Error("deliver task sub add err:", err)
}
fundRecord.Uid = uint32(goodsOrder.Uid)
fundRecord.FundType = model.FundTypeBuyGoods
fundRecord.Remark = "商城购买"
}
if notifyInfo.Attach == wxpay.WxPayUpgradeMember {
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
}
fmt.Println("UpgradeMember:", record.Uid)
var user model.User
err = model.NewUserQuerySet(model.DB).UidEq(record.Uid).One(&user)
if err != nil {
logger.Error("user err:", err)
return
}
memberRecord := &model.UserMemberRecord{
Uid: record.Uid,
BeforeMemberLevel: user.MemberLevel,
AfterMemberLevel: record.MemberLevel,
BeforeMemberExpire: user.MemberExpire,
AfterMemberExpire: record.MemberExpire,
InviteUid: 0,
DeductionDays: record.DeductionDays,
DeductionFee: record.DeductionFee,
CouponId: record.UserCouponId,
Serial: uint32(user.MemberExpire.Unix()),
Type: model.GetUserMemberRecordType(record.MemberLevel, 3),
OpenMemberLevel: user.OpenMemberLevel,
OpenMemberTime: user.OpenMemberTime,
}
memberRecord.Add()
memberConfig, err := model.GetMemberConfig(record.MemberLevel)
if err != nil {
logger.Error("GetMemberConfig err:", err)
return
}
var fundRecordRecord model.FundRecord
err = model.NewFundRecordQuerySet(model.DB).UidEq(record.Uid).FundTypeEq(model.FundTypeMemberFee).
CreatedAtGte(time.Now().Add(-10 * time.Minute)).One(&fundRecordRecord)
if err == nil && fundRecordRecord.OutTradeNo != "" {
var userOpenMemberRecord model.UserOpenMemberRecord
err := model.NewUserOpenMemberRecordQuerySet(model.DB).OpenNoEq(fundRecordRecord.OutTradeNo).One(&userOpenMemberRecord)
if err != nil {
logger.Error("user open member record err:", err)
return
}
if userOpenMemberRecord.CreatedAt.After(record.CreatedAt) {
record.MemberExpire = record.MemberExpire.AddDate(1, 0, 0)
}
}
_, err = model.NewUserQuerySet(model.DB).UidEq(record.Uid).GetUpdater().SetMemberLevel(record.MemberLevel).
SetMemberExpire(record.MemberExpire).SetDeposit(memberConfig.MemberDeposit).UpdateNum()
//err = model.UserUpdate(&model.User{Uid: uint32(record.Uid), MemberLevel: record.MemberLevel, MemberExpire: expireTime, Deposit: memberConfig.MemberDeposit})
if err != nil {
logger.Error("err:", err)
return
}
// 添加会员时长 等级 借卡数量
var userRentCard model.UserRentCard
err = model.NewUserRentCardQuerySet(model.DB).UidEq(record.Uid).One(&userRentCard)
if err != nil {
logger.Error("err:", err)
return
}
_, err = model.NewUserRentCardQuerySet(model.DB).UidEq(record.Uid).GetUpdater().SetMemberLevel(record.MemberLevel).
SetLevelRentCount(memberConfig.CardMax).SetCanRentCount(memberConfig.CardMax - userRentCard.HaveRentCount).UpdateNum()
if err != nil {
logger.Error("err:", err)
return
}
model.CreateUserRentCardByMemberLevel(record.Uid, record.MemberLevel, memberConfig.CardMax)
if record.UserCouponId > 0 {
_, err = model.NewUserCouponQuerySet(model.DB).IDEq(record.UserCouponId).GetUpdater().
SetState(2).SetUseTime(utils.Now()).UpdateNum()
if err != nil {
logger.Error("update user coupon state 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)
}
fundRecord.Uid = uint32(record.Uid)
fundRecord.FundType = model.FundTypeUpgradeMember
fundRecord.Remark = "升级会员"
}
if notifyInfo.Attach == wxpay.WxPayMemberExpireDelay {
record := &model.UserOpenMemberRecord{OpenNo: notifyInfo.OutTradeNo}
err := record.GetByOpenNo()
if err != nil {
logger.Error("err:", err)
return
}
if record.State == 2 {
ret.ReturnCode = "SUCCESS"
RespBodyXML(c, ret)
return
}
var user model.User
err = model.NewUserQuerySet(model.DB).UidEq(record.Uid).One(&user)
if err != nil {
logger.Error("err:", err)
return
}
_, err = model.NewUserMemberExpireDelayQuerySet(model.DB).UidEq(record.Uid).MemberExpireEq(user.MemberExpire).
GetUpdater().SetIsPay(1).UpdateNum()
if err != nil {
logger.Error("err:", err)
return
}
_, 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)
}
fundRecord.Uid = uint32(record.Uid)
fundRecord.FundType = model.FundTypeMemberExpireDelay
fundRecord.Remark = "会员过期滞纳金"
}
if notifyInfo.Attach == wxpay.WxPayShareCardRetrieve {
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
}
fmt.Println("UpgradeMember:", record.Uid)
//var user model.User
//err = model.NewUserQuerySet(model.DB).UidEq(record.Uid).One(&user)
//if err != nil {
// logger.Error("err:", err)
// return
//}
_, err = model.NewShareCardRetrieveQuerySet(model.DB).IDEq(record.OrderId).
GetUpdater().SetPayState(2).UpdateNum()
if err != nil {
logger.Error("update pay state err:", err)
}
_, err = model.NewShareCardRetrieveCardQuerySet(model.DB).ShareCardRetrieveIdEq(record.OrderId).GetUpdater().
SetPayState(2).UpdateNum()
if err != nil {
logger.Error("update pay state err:", err)
}
var share model.ShareCardRetrieve
err = model.NewShareCardRetrieveQuerySet(model.DB).IDEq(record.ID).One(&share)
if err != nil {
log.Error().Msgf("share card retrieve err:%#v", err)
}
if err == nil {
sub := model.DeliverTaskSub{
Uid: share.Uid,
UserAddressId: share.AddressId,
OrderType: 3,
OrderId: share.ID,
}
err = sub.Add()
if err != nil {
logger.Error("deliver task sub add 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)
}
fundRecord.Uid = uint32(record.Uid)
fundRecord.FundType = model.FundTypeExpressFee
fundRecord.Remark = "共享卡收回卡快递费"
}
if notifyInfo.Attach == wxpay.WxPayPostagePackage {
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
}
var activity model.Activity
err = model.NewActivityQuerySet(model.DB).IDEq(3).One(&activity)
if err != nil {
logger.Error("coupon err:", err)
return
}
var coupon model.Coupon
err = model.NewCouponQuerySet(model.DB).ActivityTypeEq(activity.ActivityType).One(&coupon)
if err != nil {
logger.Error("coupon err:", err)
ret.ReturnCode = "Error"
RespBodyXML(c, ret)
return
}
defer func() {
if err := recover(); err != nil {
logger.Error("err:", err)
}
}()
//info, err := model.PostagePackageFeeConfigInfo()
//if err != nil {
// logger.Error("postage package fee config err")
// ret.ReturnCode = "Error"
// RespBodyXML(c, ret)
// return
//}
//originalMemberConfig, err := model.GetMemberConfig(record.MemberLevel)
//if err != nil {
// logger.Error("err:", err)
// ret.ReturnCode = "Error"
// RespBodyXML(c, ret)
// return
//}
//days := (info.PostagePackageFee * 365) / originalMemberConfig.MemberFee
user := model.GetUserByUid(record.Uid)
days := model.GetPostagePackageMemberDuration(user.MemberLevel)
durationRecord := &model.UserMemberDurationRecord{
Uid: record.Uid,
Duration: days,
EventType: 1,
MemberLevel: record.MemberLevel,
}
nowTime := time.Now()
go func() {
begin := model.DB.Begin()
for i := 0; i < 10; i++ {
userCoupon := &model.UserCoupon{
Uid: record.Uid,
CouponId: coupon.ID,
CouponType: coupon.CouponType,
ActivityType: activity.ActivityType,
ActivityId: activity.ID,
Value: coupon.Value,
State: 1,
ActiveStart: nowTime,
ActiveEnd: nowTime.AddDate(10, 0, 0),
MemberLevel: record.MemberLevel,
}
err = begin.Create(userCoupon).Error
if err != nil {
begin.Rollback()
logger.Error("user coupon err:", err)
return
}
}
memberExpire := user.MemberExpire.AddDate(0, 0, int(days))
err := model.NewUserQuerySet(begin).UidEq(record.Uid).GetUpdater().SetMemberExpire(memberExpire).Update()
if err != nil {
begin.Rollback()
logger.Error("update member expire err:", err)
return
}
err = begin.Create(durationRecord).Error
if err != nil {
logger.Error("create duration record err:", err)
return
}
err = begin.Commit().Error
if err != nil {
begin.Rollback()
logger.Error("commit err:", err)
return
}
}()
fundRecord.Uid = uint32(record.Uid)
fundRecord.FundType = model.FundTypePostagePackageFee
fundRecord.Remark = "购买运费包"
}
fundRecord.Amount = int64(notifyInfo.TotalFee)
fundRecord.TransactionId = notifyInfo.TransactionId
fundRecord.OutTradeNo = notifyInfo.OutTradeNo
fundRecord.Status = 2
err = model.DB.Create(&fundRecord).Error
if err != nil {
logger.Error("create fund record err:", err)
}
logger.Debug("微信推动支付通知")
ret.ReturnCode = "SUCCESS"
RespBodyXML(c, ret)
}
type WxPayRefundPlaintext struct {
Mchid string `json:"mchid"`
OutTradeNo string `json:"out_trade_no"`
TransactionId string `json:"transaction_id"`
OutRefundNo string `json:"out_refund_no"`
RefundId string `json:"refund_id"`
RefundStatus string `json:"refund_status"`
SuccessTime time.Time `json:"success_time"`
Amount struct {
Total int `json:"total"`
Refund int `json:"refund"`
PayerTotal int `json:"payer_total"`
PayerRefund int `json:"payer_refund"`
} `json:"amount"`
UserReceivedAccount string `json:"user_received_account"`
}
// 0 元购 微信推送支付通知
func PushWXPayRefundNotice(c *gin.Context) {
fmt.Println("微信推送支付通知")
//body, err := ioutil.ReadAll(c.Request.Body)
//if err != nil {
// logger.Error(err)
//}
mchID := "1609877389"
mchAPIv3Key := "DeovoMingHuiRengTianTang45675123" // 商户APIv3密钥
mchCertificateSerialNumber := "7540301D8FD52CCF7D6267DCF7CD2BC0AB467EFF" // 商户证书序列号
mchPrivateKey, err := wechatpayutils.LoadPrivateKeyWithPath("./configs/merchant/apiclient_key.pem")
if err != nil {
log.Print("load merchant private key error")
}
ctx := context.Background()
// 1. 使用 `RegisterDownloaderWithPrivateKey` 注册下载器
err = downloader.MgrInstance().RegisterDownloaderWithPrivateKey(ctx, mchPrivateKey, mchCertificateSerialNumber, mchID, mchAPIv3Key)
if err != nil {
fmt.Println(err)
return
}
// 2. 获取商户号对应的微信支付平台证书访问器
certVisitor := downloader.MgrInstance().GetCertificateVisitor(mchID)
// 3. 使用证书访问器初始化 `notify.Handler`
handler := notify.NewNotifyHandler(mchAPIv3Key, verifiers.NewSHA256WithRSAVerifier(certVisitor))
transaction := new(payments.Transaction)
notifyReq, err := handler.ParseNotifyRequest(context.Background(), c.Request, transaction)
// 如果验签未通过,或者解密失败
if err != nil {
fmt.Println(err)
return
}
// 处理通知内容
//fmt.Println(notifyReq.Summary)
//fmt.Println(transaction.TransactionId)
//transactionJson, _ := json.Marshal(transaction)
//fmt.Println("transactionJson:", string(transactionJson))
//notifyReqJson, _ := json.Marshal(notifyReq)
//fmt.Println("notifyReqJson:", string(notifyReqJson))
if notifyReq.EventType == "REFUND.SUCCESS" {
plaintext := new(WxPayRefundPlaintext)
err = json.Unmarshal([]byte(notifyReq.Resource.Plaintext), plaintext)
if err != nil {
logger.Error("unmarshal plaintext err:", err)
return
}
count, err := model.NewFundRecordQuerySet(model.DB).RefundIdEq(plaintext.RefundId).Count()
if err != nil {
logger.Error("count refund id err:", err)
return
}
plaintextJson, _ := json.Marshal(plaintext)
fmt.Println("plaintextJson:", string(plaintextJson))
if count == 0 {
openMemberRecord := new(model.UserOpenMemberRecord)
err = model.NewUserOpenMemberRecordQuerySet(model.DB).OpenNoEq(plaintext.OutRefundNo).One(openMemberRecord)
if err != nil {
logger.Error("user open member record err:", err)
return
}
//fundType := model.FundTypeExpressFeeRefund
//if openMemberRecord.OrderType == 6 {
// fundType = model.FundTypeBuyGoodsRefund
//}
fundRecord := &model.FundRecord{
Uid: openMemberRecord.Uid,
FundType: GetFundRecordFundType(openMemberRecord.OrderType),
Amount: int64(plaintext.Amount.Refund) * (-1),
TransactionId: plaintext.TransactionId,
OutTradeNo: plaintext.OutTradeNo,
RefundId: plaintext.RefundId,
Status: 2,
Remark: GetFundRecordRemark(openMemberRecord.OrderType),
}
err = model.DB.Create(fundRecord).Error
if err != nil {
logger.Error("create fund record err:", err)
return
}
}
}
RespNotice(c, "SUCCESS", "成功")
return
//logger.Error("xml Request.Body1:", string(body))
}
func GetFundRecordRemark(orderType uint32) string {
switch orderType {
case 5:
return "邮费退款"
case 7:
return "商城购买取消订单"
case 8:
return "商城购买退货"
}
return ""
}
func GetFundRecordFundType(orderType uint32) string {
switch orderType {
case 2:
return model.FundTypeExpressFeeRefund
case 5:
return model.FundTypeExpressFeeRefund
case 7:
return model.FundTypeBuyGoodsCancel
case 8:
return model.FundTypeBuyGoodsRefund
}
return ""
}
func PayCallBackHandle(notify wxpay.WechatNotifyInfo, payKey string) (string, error) {
m, err := struct2Map(notify)
if err != nil {
return "", err
}
sign, err := GenWechatPaySign(m, payKey)
if err != nil {
return "", err
}
sign = strings.ToUpper(sign)
logger.Error("微信推送支付通知 sign : payKey", sign, payKey)
return sign, err
}
func GenWechatPaySign(m map[string]string, payKey string) (string, error) {
delete(m, "sign")
var signData []string
for k, v := range m {
if v != "" && v != "0" {
signData = append(signData, fmt.Sprintf("%s=%s", k, v))
}
}
sort.Strings(signData)
signStr := strings.Join(signData, "&")
signStr = signStr + "&key=" + payKey
logger.Error("签字符串1 :", signStr)
c := md5.New()
_, err := c.Write([]byte(signStr))
if err != nil {
return "", err
}
signByte := c.Sum(nil)
if err != nil {
return "", err
}
return fmt.Sprintf("%x", signByte), nil
}
func struct2Map(r interface{}) (s map[string]string, err error) {
var temp map[string]interface{}
var result = make(map[string]string)
bin, err := json.Marshal(r)
if err != nil {
return result, err
}
if err := json.Unmarshal(bin, &temp); err != nil {
return nil, err
}
for k, v := range temp {
switch v2 := v.(type) {
case string:
result[k] = v2
case uint, int8, uint8, int, int16, uint16, int32, uint32, int64, uint64:
result[k] = fmt.Sprintf("%d", v2)
case float32, float64:
result[k] = fmt.Sprintf("%.0f", v2)
}
}
return result, nil
}
func AliyunStsTokenGet(c *gin.Context) {
uploadInfo, err := aliyun.GenStsToken("21000505")
if err != nil {
log.Error().Msgf("err=%v", err)
return
}
stsToken := model.RspAliyunStsToken{
AccessKeyId: uploadInfo.AccessKeyId,
AccessKeySecret: uploadInfo.AccessKeySecret,
SecurityToken: uploadInfo.SecurityToken,
BucketName: uploadInfo.BucketName,
Expiration: uint64(uploadInfo.Expiration),
}
RespOK(c, stsToken)
}