package controller import ( "crypto/md5" "encoding/json" "encoding/xml" "errors" "fmt" "github.com/codinl/go-logger" "github.com/gin-gonic/gin" "github.com/rs/zerolog/log" "io/ioutil" "mh-server/config" aliyun "mh-server/lib/ali" "mh-server/lib/auth" "mh-server/lib/status" "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 { RespJson(c, status.BadRequest, nil) return } fmt.Println("游戏类型:GameTypeIds:", req.GameTypeIds) cardList, totalPage, err := model.GetGameCardList(req.SortType, req.Page, req.PageSize, req.GameTypeIds, req.StoreId) 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"` }{} 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 model.HistoryBrowsingAdd(uint64(uc.Uid), req.GameId) info, err := model.GetGameCardInfo(req.GameId) if err != nil { logger.Error("err:", err) RespJson(c, status.InternalServerError, nil) return } 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) { carouselList, err := model.GetHomeCarouselList() if err != nil { logger.Error("err:", err) RespJson(c, status.InternalServerError, nil) return } 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"` } ) const ( PRIZE_WX_PAY_TYPE = "pwxpt" FB_WX_PAY_TYPE = "fbwxpt" ) // 0 元购 微信推送支付通知 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 notify wxpay.WechatNotifyInfo //if err := c.ShouldBindXML(¬ify); err != nil { // logger.Error(err) // RespBodyXML(c, map[string]string{ // "return_code": "FAIL", // }) // return //} err = xml.Unmarshal(body, ¬ify) if err != nil { logger.Error(err) } ret := WXPayNoticeResp{ ReturnCode: "FAIL", } correctSign, err := PayCallBackHandle(notify, config.AppConfig.WxMchSecret) if err != nil { logger.Error("PushWXPayNotice sign create fail") RespBodyXML(c, ret) return } if notify.Sign != correctSign { logger.Error("PushWXPayNotice sign verification fail") RespBodyXML(c, ret) return } if notify.Attach == wxpay.WxPayRentCard { logger.Info("租借游戏卡 支付成功:") var order model.Order err := model.NewOrderQuerySet(model.DB).OrderSnEq(notify.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 } err = order.InventoryReduction(begin) if err != nil { begin.Rollback() logger.Error("err:", err) // 库存不足取消订单 orderSn := model.GetOrderSn() 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) //count, err := model.NewOrderQuerySet(model.DB).UidEq(order.Uid).IDEq(order.ID).Count() //if err != nil { // logger.Error("err:", err) // return //} //go model.OrderCardUserRentCard(uint32(order.Uid), uint32(count), nil) } else if notify.Attach == wxpay.WxPayMember { logger.Info("开通会员 支付成功:") logger.Info("用户uid:", notify.OutTradeNo) //uid, err := strconv.Atoi(notify.OutTradeNo) //if err != nil { // logger.Error("err:", err) // return //} record := &model.UserOpenMemberRecord{OpenNo: notify.OutTradeNo} err := record.GetByOpenNo() if err != nil { logger.Error("err:", err) } var user model.User err = model.NewUserQuerySet(model.DB).UidEq(record.Uid).One(&user) if err != nil { logger.Error("err:", err) } else { //expireTime := user.MemberExpire.AddDate(1, 0, 0) //if user.MemberLevel == 1 { // expireTime = time.Now().AddDate(1, 0, 0) //} expireTime := time.Now().AddDate(1, 0, 0) if user.MemberExpire.After(time.Now()) { expireTime = user.MemberExpire.AddDate(1, 0, 0) } //configInfo, err := model.PayConfigInfo() //if err != nil { // logger.Error("err:", err) // return //} memberConfig, err := model.GetMemberConfig(record.MemberLevel) if err != nil { logger.Error("GetMemberConfig err:", err) return } openMemberTime := time.Now() if !user.OpenMemberTime.IsZero() { openMemberTime = user.OpenMemberTime } _, err = model.NewUserQuerySet(model.DB).UidEq(record.Uid).GetUpdater().SetMemberLevel(record.MemberLevel).SetMemberExpire(expireTime). SetDeposit(memberConfig.MemberDeposit).SetOpenMemberTime(openMemberTime).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 invite model.UserInvite err = model.NewUserInviteQuerySet(model.DB).ToUidEq(record.Uid).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: time.Now(), MemberType: 2, ToUid: record.Uid, MemberStatus: 2, MemberLevel: record.MemberLevel, } 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) } } else { qs := model.NewUserInviteQuerySet(model.DB).ToUidEq(record.Uid).GetUpdater() if user.MemberLevel != 2 { qs = qs.SetMemberOpenTime(time.Now()).SetMemberLevel(record.MemberLevel) } num, err := qs.SetMemberType(2).SetMemberStatus(2).UpdateNum() if err != nil { logger.Error("err:", err) } if num == 0 { logger.Error("更新错误") } if invite.FromUid != 0 { inviteUser := model.GetUserByUid(invite.FromUid) if inviteUser.UserType != 2 /*不是店员*/ && user.MemberLevel != 2 { // 邀请 新用户推送一次 //err := model.CodeSendToUser(invite.FromUid, model.CodeTypeMemberCard30, model.RedeemCodeActivityTypeUserInvite) //if err != nil { // logger.Error("err:", err) //} err = model.SendUserVm(inviteUser.Uid, record.MemberLevel, 1) if err != nil { logger.Error("send user vm err:", err) } } err = model.SendUserVm(user.Uid, record.MemberLevel, 0) if err != nil { logger.Error("send user vm err:", err) } } } } if user.MemberLevel != 2 { //err = model.CodeSendToUser(user.Uid, model.CodeTypeMemberCard30, model.RedeemCodeActivityTypeStore) //if err != nil { // logger.Error("code send to user err:", err) //} } model.CreateUserRentCardByMemberLevel(record.Uid, record.MemberLevel, memberConfig.CardMax) } fmt.Println("notify.TotalFee:", notify.TotalFee) fmt.Println("notify.OutTradeNo:", notify.OutTradeNo) } else if notify.Attach == wxpay.WxPayDeposit { record := &model.UserOpenMemberRecord{OpenNo: notify.OutTradeNo} err := record.GetByOpenNo() if err != nil { logger.Error("err:", err) return } //configInfo, err := model.PayConfigInfo() //if err != nil { // logger.Error("err:", err) // return //} 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 } 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") } } else if notify.Attach == wxpay.WxPayExchangeGoods { _, err := model.NewGoodsOrderQuerySet(model.DB).SerialNoEq(notify.OutTradeNo).GetUpdater(). SetPayTime(time.Now()). SetPayStatus(model.PayStatusOK).UpdateNum() if err != nil { logger.Error("err:", err) } var goodsOrder model.GoodsOrder err = model.NewGoodsOrderQuerySet(model.DB).SerialNoEq(notify.OutTradeNo).One(&goodsOrder) if err != nil { logger.Error("err:", err) } err = model.OrderUpdateGoodsStock(goodsOrder.GoodsId, goodsOrder.Quantity, model.DB) if err != nil { logger.Error("err:", err) } err = model.UserVmUpdate(goodsOrder.Uid, int(goodsOrder.Amount)*-1, model.VmEventExchangeGoods, "兑换奖品") if err != nil { logger.Error("err:", err) } } else if notify.Attach == wxpay.WxPayUpgradeMember { record := &model.UserOpenMemberRecord{OpenNo: notify.OutTradeNo} err := record.GetByOpenNo() if err != nil { logger.Error("err:", err) } 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 } memberConfig, err := model.GetMemberConfig(record.MemberLevel) if err != nil { logger.Error("GetMemberConfig err:", err) return } _, 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) } else if notify.Attach == wxpay.WxPayMemberExpireDelay { record := &model.UserOpenMemberRecord{OpenNo: notify.OutTradeNo} err := record.GetByOpenNo() if err != nil { logger.Error("err:", err) 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 } } else if notify.Attach == wxpay.WxPayShareCardRetrieve { record := &model.UserOpenMemberRecord{OpenNo: notify.OutTradeNo} err := record.GetByOpenNo() if err != nil { logger.Error("err:", err) } 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) } } logger.Debug("微信推动支付通知") ret.ReturnCode = "SUCCESS" RespBodyXML(c, ret) } 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) }