service/app/mix/service/vasservice.go

1167 lines
36 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package service
import (
"encoding/base64"
"fmt"
"service/api/base"
"service/api/errcode"
"service/api/errs"
accountproto "service/api/proto/account/proto"
vasproto "service/api/proto/vas/proto"
vericodeproto "service/api/proto/vericode/proto"
zoneproto "service/api/proto/zone/proto"
"service/bizcommon/common"
"service/bizcommon/util"
"service/dbstruct"
"service/library/logger"
"service/library/mycrypto"
"service/library/payclients/applepaycli"
"strconv"
"strings"
goproto "google.golang.org/protobuf/proto"
"github.com/gin-gonic/gin"
)
// 一键解锁
func (s *Service) OneStepUnlockContact(ctx *gin.Context, req *vasproto.OneStepUnlockContactReq) (data *vasproto.OneStepUnlockContactData, ec errcode.ErrCode) {
lockType, orderId, contact, err := _DefaultVas.OneStepUnlockContact(ctx, req)
ec, err = errs.DealVasErr(err)
if err != nil {
logger.Error("OneStepUnlockContact fail, req: %v, err: %v", util.ToJson(req), err)
return
}
data = &vasproto.OneStepUnlockContactData{
LockType: lockType,
OrderId: orderId,
Contact: contact,
}
return
}
func (s *Service) getUidInviterMid(ctx *gin.Context, uid int64) int64 {
mp, _ := _DefaultStreamer.GetStreamerMapByMids(ctx, []int64{uid})
if mp[uid] == nil {
return 0
}
if mp[uid].Inviters != nil && len(*mp[uid].Inviters) > 0 {
return (*mp[uid].Inviters)[0]
}
return 0
}
// 填写联系方式
func (s *Service) ConsumerFillContact(ctx *gin.Context, req *vasproto.ConsumerFillContactReq) (ec errcode.ErrCode) {
ec = errcode.ErrCodeVasSrvOk
var ok bool
err := _DefaultVas.ConsumerFillContact(ctx, req)
if err != nil {
logger.Error("ConsumerFillContact fail, req: %v, err: %v", util.ToJson(req), err)
ec, ok = errs.ErrEcMap[err]
if ok {
return
}
ec = errcode.ErrCodeVasSrvFail
return
}
return
}
// 添加微信列表
func (s *Service) GetAddWechatList(ctx *gin.Context, req *vasproto.GetAddWechatListReq) (data *vasproto.GetAddWechatListData, ec errcode.ErrCode) {
ec = errcode.ErrCodeVasSrvOk
coinOrders, err := _DefaultVas.GetAddWechatCoinOrders(ctx, req.Mid, req.Offset, req.Limit, req.Tab)
if err != nil {
logger.Error("GetAddWechatCoinOrders fail, req: %v, err: %v", util.ToJson(req), err)
ec = errcode.ErrCodeVasSrvFail
return
}
logger.Info("GetAddWechatCoinOrders len: %v", len(coinOrders))
// 获取用户
mids := make([]int64, 0)
for _, co := range coinOrders {
mids = append(mids, co.GetMid())
}
acntMap, _ := _DefaultAccount.GetAccountMapByMids(ctx, mids)
logger.Info("GetAccountMapByMids mids: %v, len: %v", mids, len(mids))
// 组装
list := make([]*vasproto.AddWechatSt, 0)
for _, co := range coinOrders {
acnt, ok := acntMap[co.GetMid()]
if !ok {
continue
}
item := &vasproto.AddWechatSt{
Account: acnt,
OrderId: co.GetID(),
OrderStatus: util.DerefInt32(co.OrderStatus),
Ct: util.DerefInt64(co.Ct),
ConsumerWechat: util.DerefString(co.Wechat),
ConsumerNote: util.DerefString(co.Note),
}
list = append(list, item)
}
data = &vasproto.GetAddWechatListData{
List: list,
Offset: req.Offset + len(list),
}
if len(list) >= req.Limit {
data.More = 1
}
return
}
// 确定添加微信
func (s *Service) ConfirmAddWechat(ctx *gin.Context, req *vasproto.ConfirmAddWechatReq) (data *vasproto.GetAddWechatListData, ec errcode.ErrCode) {
ec = errcode.ErrCodeVasSrvOk
var ok bool
err := _DefaultVas.ConfirmAddWechat(ctx, req.Mid, req.OrderId)
if err != nil {
logger.Error("ConfirmAddWechat fail, req: %v, err: %v", util.ToJson(req), err)
ec, ok = errs.ErrEcMap[err]
if ok {
return
}
ec = errcode.ErrCodeVasSrvFail
return
}
return
}
// 已解锁微信列表
func (s *Service) GetUnlockWechatList(ctx *gin.Context, req *vasproto.GetUnlockWechatListReq) (data *vasproto.GetUnlockWechatListData, ec errcode.ErrCode) {
ec = errcode.ErrCodeVasSrvOk
unlockList, err := _DefaultVas.GetUnlockWechatList(ctx, req.Mid, req.Offset, req.Limit)
if err != nil {
logger.Error("GetUnlockWechatList fail, req: %v, err: %v", util.ToJson(req), err)
ec = errcode.ErrCodeVasSrvFail
return
}
// 获取用户
mids := make([]int64, 0)
for _, uu := range unlockList {
mid := util.DerefInt64(uu.Uid)
if mid > 0 {
mids = append(mids, mid)
}
}
acntMap, _ := _DefaultAccount.GetAccountMapByMids(ctx, mids)
streamerMap, _ := _DefaultStreamer.GetStreamerMapByMids(ctx, mids)
// 组装
list := make([]*vasproto.UnlockWechatSt, 0)
for _, uu := range unlockList {
acnt, ok := acntMap[uu.GetUid()]
if !ok {
continue
}
streamer, ok := streamerMap[uu.GetUid()]
if !ok {
continue
}
coinOrderId := uu.GetOrderId()
coinOrder, _ := _DefaultVas.GetCoinOrderById(ctx, coinOrderId)
item := &vasproto.UnlockWechatSt{
Streamer: streamer,
Account: acnt,
LockType: uu.GetLockType(),
OrderId: coinOrderId,
OrderStatus: coinOrder.GetOrderStatus(),
}
list = append(list, item)
}
data = &vasproto.GetUnlockWechatListData{
List: list,
Offset: req.Offset + len(list),
}
if len(list) >= req.Limit {
data.More = 1
}
return
}
func (s *Service) GetCHList(ctx *gin.Context, req *vasproto.GetCHListReq) (data *vasproto.GetCHListData, ec errcode.ErrCode) {
ec = errcode.ErrCodeVasSrvOk
chList, err := _DefaultVas.GetCHList(ctx, req.Mid, req.Type, req.Offset, req.Limit)
if err != nil {
logger.Error("GetUnlockWechatList fail, req: %v, err: %v", util.ToJson(req), err)
ec = errcode.ErrCodeVasSrvFail
return
}
var list = make([]*vasproto.CHSt, 0)
switch req.Type {
case dbstruct.CHTypeCost:
list = s.chListCost(ctx, chList)
case dbstruct.CHTypeCharge:
list = s.chListCharge(ctx, chList)
case dbstruct.CHTypeIncome:
list = s.chListIncome(ctx, chList)
case dbstruct.CHTypeWithdraw:
list = s.chListWithdraw(ctx, chList)
}
data = &vasproto.GetCHListData{
List: list,
Offset: req.Offset + len(list),
}
if len(list) >= req.Limit {
data.More = 1
}
return
}
func (s *Service) chListCost(ctx *gin.Context, chList []*dbstruct.ConsumeHistory) (list []*vasproto.CHSt) {
// 获取用户
mids := make([]int64, 0)
for _, chDB := range chList {
mid := util.DerefInt64(chDB.Uid)
if mid > 0 {
mids = append(mids, mid)
}
}
acntMap, _ := _DefaultAccount.GetAccountMapByMids(ctx, mids)
// 组装
list = make([]*vasproto.CHSt, 0)
for _, chDB := range chList {
mid := util.DerefInt64(chDB.Uid)
acnt, ok := acntMap[mid]
if !ok {
continue
}
item := &vasproto.CHSt{
Ct: util.DerefInt64(chDB.Ct),
}
changeMark := "-"
if chDB.GetChange() > 0 {
changeMark = "+"
}
switch chDB.GetSType() {
case dbstruct.CHSTypeCostContact:
item.Desc = fmt.Sprintf("购买\"%s\"微信", util.DerefString(acnt.Name))
item.Change = changeMark + fmt.Sprintf("%d金币", chDB.GetChange())
if chDB.GetChange() < 0 {
item.Change = fmt.Sprintf("%d金币", chDB.GetChange())
}
case dbstruct.CHSTypeCostRefundContactWechat:
item.Desc = fmt.Sprintf("购买\"%s\"微信退款", util.DerefString(acnt.Name))
item.Change = changeMark + fmt.Sprintf("%d金币", chDB.GetChange())
case dbstruct.CHSTypeCostMembership:
item.Desc = "购买会员"
item.Change = changeMark + fmt.Sprintf("%d金币", chDB.GetChange())
if chDB.GetChange() < 0 {
item.Change = fmt.Sprintf("%d金币", chDB.GetChange())
}
case dbstruct.CHSTypeCostRefundMembership:
item.Desc = fmt.Sprintf("会员退款")
item.Change = changeMark + fmt.Sprintf("%d金币", chDB.GetChange())
}
list = append(list, item)
}
return
}
func (s *Service) chListCharge(ctx *gin.Context, chList []*dbstruct.ConsumeHistory) (list []*vasproto.CHSt) {
// 组装
list = make([]*vasproto.CHSt, 0)
for _, chDB := range chList {
item := &vasproto.CHSt{
Ct: util.DerefInt64(chDB.Ct),
}
changeMark := "-"
if chDB.GetChange() >= 0 {
changeMark = "+"
}
switch chDB.GetSType() {
case dbstruct.CHSTypeChargeUser:
item.Desc = "充值"
item.Change = changeMark + fmt.Sprintf("%d金币", chDB.GetChange())
case dbstruct.CHSTypeChargeOp:
item.Desc = "运营充值"
item.Change = changeMark + fmt.Sprintf("%d金币", chDB.GetChange())
case dbstruct.CHSTypeChargeRefundCoins:
item.Desc = "金币退款"
item.Change = fmt.Sprintf("%d金币", chDB.GetChange())
case dbstruct.CHSTypeChargeRefundMembership:
item.Desc = "会员退款"
item.Change = fmt.Sprintf("%d金币", chDB.GetChange())
case dbstruct.CHSTypeChargeMembership:
item.Desc = "会员充值"
item.Change = changeMark + fmt.Sprintf("%d金币", chDB.GetChange())
case dbstruct.CHSTypeChargeRefundContactWechat:
item.Desc = "微信联系方式退款"
item.Change = fmt.Sprintf("%d金币", chDB.GetChange())
case dbstruct.CHSTypeChargeZoneMoment:
item.Desc = "解锁空间动态"
item.Change = fmt.Sprintf("-%.1f元", float64(util.AbsInt64(chDB.GetChange()))/100.0)
case dbstruct.CHSTypeChargeZoneAdmission:
item.Desc = "加入空间"
item.Change = fmt.Sprintf("-%.1f元", float64(util.AbsInt64(chDB.GetChange()))/100.0)
case dbstruct.CHSTypeChargeZoneSuperfanship:
item.Desc = "解锁空间超粉"
item.Change = fmt.Sprintf("-%.1f元", float64(util.AbsInt64(chDB.GetChange()))/100.0)
case dbstruct.CHSTypeChargeZoneRefundAdmission:
item.Desc = "加入空间退款"
item.Change = fmt.Sprintf("+%.1f元", float64(util.AbsInt64(chDB.GetChange()))/100.0)
case dbstruct.CHSTypeChargeZoneRefundMoment:
item.Desc = "解锁空间动态退款"
item.Change = fmt.Sprintf("+%.1f元", float64(util.AbsInt64(chDB.GetChange()))/100.0)
case dbstruct.CHSTypeChargeZoneRefundSuperfanship:
item.Desc = "解锁空间超粉退款"
item.Change = fmt.Sprintf("+%.1f元", float64(util.AbsInt64(chDB.GetChange()))/100.0)
}
if strings.Contains(chDB.GetTypeId(), ":_:pay_type=coin") && strings.Contains(item.Change, "元") {
oldChange := item.Change
newChange := ""
if len(item.Change) > 0 {
newChange += oldChange[:1]
}
newChange += fmt.Sprintf("%d金币", util.AbsInt64(chDB.GetChange()))
item.Change = newChange
}
list = append(list, item)
}
return
}
func (s *Service) chListIncome(ctx *gin.Context, chList []*dbstruct.ConsumeHistory) (list []*vasproto.CHSt) {
// 组装
list = make([]*vasproto.CHSt, 0)
for _, chDB := range chList {
item := &vasproto.CHSt{
Ct: util.DerefInt64(chDB.Ct),
}
changeMark := "-"
if chDB.GetChange() >= 0 {
changeMark = "+"
}
switch chDB.GetSType() {
case dbstruct.CHSTypeIncomeContact:
item.Desc = "解锁微信"
item.Change = changeMark + fmt.Sprintf("%d钻石", chDB.GetChange())
case dbstruct.CHSTypeIncomeInvite:
item.Desc = "邀请收益"
item.Change = changeMark + fmt.Sprintf("%d钻石", chDB.GetChange())
case dbstruct.CHSTypeIncomeRefundMembership:
item.Desc = "用户会员退款"
item.Change = fmt.Sprintf("%d钻石", chDB.GetChange())
case dbstruct.CHSTypeIncomeRefundContactWechat:
item.Desc = "用户微信退款"
item.Change = fmt.Sprintf("%d钻石", chDB.GetChange())
case dbstruct.CHSTypeIncomeThirdPartner:
item.Desc = "代运营收益" + getTypeIdDesc(chDB.GetTypeId())
switch chDB.GetTypeId() {
case dbstruct.ProductIdH5ZoneAdmission:
item.Desc = "代运营(空间成员)"
case dbstruct.ProductIdH5ZoneMoment:
item.Desc = "代运营(空间动态)"
case dbstruct.ProductIdH5ZoneSuperfanship:
item.Desc = "代运营(空间超粉)"
}
item.Change = changeMark + fmt.Sprintf("%d钻石", chDB.GetChange())
case dbstruct.CHSTypeIncomeCollaborator:
item.Desc = "协作收益" + getTypeIdDesc(chDB.GetTypeId())
switch chDB.GetTypeId() {
case dbstruct.ProductIdH5ZoneAdmission:
item.Desc = "合伙人(空间成员)"
case dbstruct.ProductIdH5ZoneMoment:
item.Desc = "合伙人(空间动态)"
case dbstruct.ProductIdH5ZoneSuperfanship:
item.Desc = "合伙人(空间超粉)"
}
item.Change = changeMark + fmt.Sprintf("%d钻石", chDB.GetChange())
case dbstruct.CHSTypeIncomeZoneStreamer:
item.Desc = "空间收益" + getTypeIdDesc(chDB.GetTypeId())
switch chDB.GetTypeId() {
case dbstruct.ProductIdH5ZoneAdmission:
item.Desc = "空间成员"
case dbstruct.ProductIdH5ZoneMoment:
item.Desc = "空间动态"
case dbstruct.ProductIdH5ZoneSuperfanship:
item.Desc = "空间超粉"
}
item.Change = changeMark + fmt.Sprintf("%d钻石", chDB.GetChange())
case dbstruct.CHSTypeIncomeMembership:
item.Desc = "永久会员收益" + getTypeIdDesc(chDB.GetTypeId())
item.Change = changeMark + fmt.Sprintf("%d钻石", chDB.GetChange())
case dbstruct.CHSTypeIncomeRefundZoneAdmission:
item.Desc = "(旧)空间退款" + getTypeIdDesc(chDB.GetTypeId())
item.Change = fmt.Sprintf("%d钻石", chDB.GetChange())
if chDB.GetChange() == 0 {
item.Change = fmt.Sprintf("-%d钻石", chDB.GetChange())
}
case dbstruct.CHSTypeIncomeRefundThirdPartner:
item.Desc = "代运营空间退款" + getTypeIdDesc(chDB.GetTypeId())
switch chDB.GetTypeId() {
case dbstruct.ProductIdH5ZoneAdmission:
item.Desc = "代运营(空间成员退款)"
case dbstruct.ProductIdH5ZoneMoment:
item.Desc = "代运营(空间动态退款)"
case dbstruct.ProductIdH5ZoneSuperfanship:
item.Desc = "代运营(空间超粉退款)"
}
item.Change = fmt.Sprintf("%d钻石", chDB.GetChange())
if chDB.GetChange() == 0 {
item.Change = fmt.Sprintf("-%d钻石", chDB.GetChange())
}
case dbstruct.CHSTypeIncomeRefundCollaborator:
item.Desc = "合伙人空间退款" + getTypeIdDesc(chDB.GetTypeId())
switch chDB.GetTypeId() {
case dbstruct.ProductIdH5ZoneAdmission:
item.Desc = "合伙人(空间成员退款)"
case dbstruct.ProductIdH5ZoneMoment:
item.Desc = "合伙人(空间动态退款)"
case dbstruct.ProductIdH5ZoneSuperfanship:
item.Desc = "合伙人(空间超粉退款)"
}
item.Change = fmt.Sprintf("%d钻石", chDB.GetChange())
if chDB.GetChange() == 0 {
item.Change = fmt.Sprintf("-%d钻石", chDB.GetChange())
}
case dbstruct.CHSTypeIncomeRefundZoneStreamer:
item.Desc = "空间退款" + getTypeIdDesc(chDB.GetTypeId())
switch chDB.GetTypeId() {
case dbstruct.ProductIdH5ZoneAdmission:
item.Desc = "空间成员(用户退款)"
case dbstruct.ProductIdH5ZoneMoment:
item.Desc = "空间动态(用户退款)"
case dbstruct.ProductIdH5ZoneSuperfanship:
item.Desc = "空间超粉(用户退款)"
}
item.Change = fmt.Sprintf("%d钻石", chDB.GetChange())
if chDB.GetChange() == 0 {
item.Change = fmt.Sprintf("-%d钻石", chDB.GetChange())
}
}
list = append(list, item)
}
return
}
func getTypeIdDesc(typeId string) string {
if v, ok := dbstruct.ProductIdDescMap[typeId]; ok {
return fmt.Sprintf("(%s)", v)
}
return ""
}
func (s *Service) chListWithdraw(ctx *gin.Context, chList []*dbstruct.ConsumeHistory) (list []*vasproto.CHSt) {
// 组装
list = make([]*vasproto.CHSt, 0)
for _, chDB := range chList {
item := &vasproto.CHSt{
Ct: util.DerefInt64(chDB.Ct),
}
changeMark := "-"
if chDB.GetChange() > 0 {
changeMark = "+"
}
switch chDB.GetSType() {
case dbstruct.CHSTypeWithdrawDiamondAuto:
item.Desc = "自动提现"
item.Change = changeMark + fmt.Sprintf("%d钻石", chDB.GetChange())
if chDB.GetChange() < 0 {
item.Change = fmt.Sprintf("%d钻石", chDB.GetChange())
}
case dbstruct.CHSTypeWithdrawDiamondHvyogo:
item.Desc = "钻石提现"
item.Change = changeMark + fmt.Sprintf("%d钻石", chDB.GetChange())
if chDB.GetChange() < 0 {
item.Change = fmt.Sprintf("%d钻石", chDB.GetChange())
}
case dbstruct.CHSTypeWithdrawDiamondReversal:
item.Desc = "钻石返还"
item.Change = changeMark + fmt.Sprintf("%d钻石", chDB.GetChange())
if chDB.GetChange() < 0 {
item.Change = fmt.Sprintf("%d钻石", chDB.GetChange())
}
}
list = append(list, item)
}
return
}
// 更新微信
func (s *Service) UpdateWechat(ctx *gin.Context, req *vasproto.UpdateWechatReq) (ec errcode.ErrCode) {
err := _DefaultVas.UpdateWechat(ctx, req)
ec, err = errs.DealVasErr(err)
if err != nil {
logger.Error("UpdateWechat fail, req: %v, err: %v", util.ToJson(req), err)
return
}
return
}
// 查看网红微信
func (s *Service) QueryWechat(ctx *gin.Context, req *vasproto.QueryWechatReq) (isUnlock, lockType int32, wechat string, ec errcode.ErrCode) {
isUnlock, lockType, wechat, err := _DefaultVas.QueryWechat(ctx, req)
ec, err = errs.DealVasErr(err)
if err != nil {
logger.Error("UpdateWechat fail, req: %v, err: %v", util.ToJson(req), err)
return
}
return
}
// h5直接解锁微信
func (s *Service) H5DirectUnlockWechat(ctx *gin.Context, req *vasproto.H5DirectUnlockWechatReq) (data *vasproto.H5DirectUnlockWechatData, ec errcode.ErrCode) {
data, err := _DefaultVas.H5DirectUnlockWechat(ctx, req)
ec, err = errs.DealVasErr(err)
if err != nil {
logger.Error("H5DirectUnlockWechat fail, req: %v, err: %v", util.ToJson(req), err)
return
}
return
}
// 支付回调
func (s *Service) PayCallback(ctx *gin.Context, req *vasproto.PayCallbackParamIn) error {
return _DefaultVas.PayCallback(ctx, req)
}
// 提现页面
func (s *Service) WithdrawPage(ctx *gin.Context, req *vasproto.WithdrawPageReq) (data *vasproto.WithdrawPageData, ec errcode.ErrCode) {
data = new(vasproto.WithdrawPageData)
wallet, _ := _DefaultVas.CheckWalletExist(ctx, nil, req.Mid)
if wallet != nil {
data.WithdrawDiamonds = wallet.GetWithdrawDiamonds()
}
st := util.GetTodayZeroTime().Unix() - 86400*7
et := st + 86400
// 获取 7天前024点总收益
day7TotalDiamonds := int64(0)
incomeList, err := _DefaultVas.GetIncomeList(ctx, nil, req.Mid, st, et)
if err != nil {
logger.Error("GetIncomeList fail, mid: %v, st: %v, et: %v, err: %v", req.Mid, st, et)
}
orderIds := make([]string, 0)
for _, c := range incomeList {
day7TotalDiamonds += c.GetChange()
orderIds = append(orderIds, c.GetOrderId())
}
data.Day7TotalDiamonds = day7TotalDiamonds
// 获取 7天前024点已结算总收益
day7TotalWithdrawDiamonds, err := _DefaultVas.GetTotalFinishIncome(ctx, nil, req.Mid, orderIds)
if err != nil {
logger.Error("GetTotalFinishIncome fail, mid: %v, st: %v, et: %v, err: %v", req.Mid, st, et)
}
data.Day7TotalWithdrawDiamonds = day7TotalWithdrawDiamonds
ec = errcode.ErrCodeOk
return
}
// 提现发送验证码
func (s *Service) WithdrawSendVerifycode(ctx *gin.Context, req *vasproto.WithdrawSendVerifycodeReq) (ec errcode.ErrCode) {
// 获取电话号
acntMap, _ := _DefaultAccount.GetAccountMapByMids(ctx, []int64{req.Mid})
acnt, has := acntMap[req.Mid]
if !has {
ec = errcode.ErrCodeVasSrvFail
return
}
// 获取验证码
bytes, _ := base64.StdEncoding.DecodeString(util.DerefString(acnt.MobilePhone))
phoneBs, _ := mycrypto.CryptoServiceInstance().AES.Decrypt(bytes)
logger.Info("WithdrawSendVerifycode, mid: %v, phone: %v", req.Mid, string(phoneBs))
err := _DefaultVeriCode.OpSendVeriCode(ctx, &vericodeproto.OpSendReq{
BaseRequest: req.BaseRequest,
MobilePhone: string(phoneBs),
RegionCode: util.DerefString(acnt.RegionCode),
Trigger: vericodeproto.VerifyCodeTriggerWithdraw,
})
ec, err = errs.DealVasErr(err)
if err != nil {
logger.Error("OpSendVeriCode fail, req: %v, err: %v", util.ToJson(req), err)
return
}
return
}
// 提现申请
func (s *Service) WithdrawApply(ctx *gin.Context, req *vasproto.WithdrawApplyReq) (data *vasproto.WithdrawApplyData, ec errcode.ErrCode) {
// 获取用户
acntMap, _ := _DefaultAccount.GetAccountMapByMids(ctx, []int64{req.Mid})
acnt, has := acntMap[req.Mid]
if !has {
ec = errcode.ErrCodeVasSrvFail
return
}
// 校验验证码
vCode, _ := _DefaultVeriCode.OpListByPhoneHash(ctx, &vericodeproto.OpListByPhoneHashReq{
BaseRequest: req.BaseRequest,
PhoneHash: util.DerefString(acnt.PhoneHash),
RegionCode: util.DerefString(acnt.RegionCode),
})
if vCode == nil || vCode.VeriCode != req.VerifyCode {
ec = errcode.ErrCodeVasInvalidVerifycode
return
}
// 检验完删除
err := _DefaultVeriCode.OpDelete(ctx, vCode.Id)
if err != nil {
logger.Error("_DefaultVeriCode.OpDelete fail, req: %v, code: %v, err: %v", util.ToJson(req), util.ToJson(vCode), err)
ec = errcode.ErrCodeVasInvalidVerifycode
return
}
// 提现
data = new(vasproto.WithdrawApplyData)
data.TransferResp, err = _DefaultVas.WithdrawApply(ctx, req)
ec, err = errs.DealVasErr(err)
if err != nil {
logger.Error("WithdrawApply fail, req: %v, resp: %v, err: %v", util.ToJson(req), util.ToJson(data.TransferResp), err)
return
}
return
}
func (s *Service) OpCoinOrderList(ctx *gin.Context, req *vasproto.OpCoinOrderListReq) (list []*vasproto.OpCoinOrderVO, ec errcode.ErrCode) {
list = make([]*vasproto.OpCoinOrderVO, 0)
if req.UserId > 0 && req.Mid <= 0 {
a, _ := _DefaultAccount.OpListByUserId(ctx, &accountproto.OpListByUserIdReq{
UserId: goproto.Int64(req.UserId),
})
if a != nil && a.Mid != nil {
req.Mid = *a.Mid
}
}
// 获取金币订单
coinOrders, err := _DefaultVas.OpCoinOrderList(ctx, req)
ec, err = errs.DealVasErr(err)
if err != nil {
logger.Error("OpCoinOrderList fail, req: %v, err: %v", util.ToJson(req), err)
return
}
// 获取用户信息
mids := make([]int64, 0)
productIdMap := make(map[string]struct{})
for _, co := range coinOrders {
mids = append(mids, co.GetMid())
mids = append(mids, co.GetUid())
productIdMap[co.GetProductId()] = struct{}{}
}
acntMap, _ := _DefaultAccount.GetAccountMapByMids(ctx, mids)
// 获取商品
productIds := make([]string, 0)
for id := range productIdMap {
productIds = append(productIds, id)
}
_, _ = _DefaultVas.GetProductMapByIds(ctx, productIds)
// 组装
for _, co := range coinOrders {
var (
userUserId = int64(0)
streamerUserId = int64(0)
)
if a, ok := acntMap[co.GetMid()]; ok {
userUserId = util.DerefInt64(a.UserId)
}
if a, ok := acntMap[co.GetUid()]; ok {
streamerUserId = util.DerefInt64(a.UserId)
}
item := &vasproto.OpCoinOrderVO{
Mid: co.GetMid(),
UserUserId: userUserId,
Uid: co.GetUid(),
StreamerUserId: streamerUserId,
OrderId: co.GetID(),
OrderStatus: co.GetOrderStatus(),
OrderStatusDesc: dbstruct.CoinOrderStatusDescMap[co.GetOrderStatus()],
Coins: co.GetCoins(),
Ct: co.GetCt(),
RefundType: "退金币",
}
item.ProductName = dbstruct.ProductIdDescMap[co.GetProductId()]
list = append(list, item)
}
return
}
func (s *Service) OpOrderList(ctx *gin.Context, req *vasproto.OpOrderListReq) (list []*vasproto.OpOrderVO, ec errcode.ErrCode) {
list = make([]*vasproto.OpOrderVO, 0)
if req.UserId > 0 && req.Mid <= 0 {
a, _ := _DefaultAccount.OpListByUserId(ctx, &accountproto.OpListByUserIdReq{
UserId: goproto.Int64(req.UserId),
})
if a != nil && a.Mid != nil {
req.Mid = *a.Mid
}
}
// 获取订单
orders, err := _DefaultVas.OpOrderList(ctx, req)
ec, err = errs.DealVasErr(err)
if err != nil {
logger.Error("OpOrderList fail, req: %v, err: %v", util.ToJson(req), err)
return
}
// 获取用户信息
mids := make([]int64, 0)
for _, co := range orders {
mids = append(mids, co.GetMid())
mids = append(mids, co.GetUid())
}
acntMap, _ := _DefaultAccount.GetAccountMapByMids(ctx, mids)
// 获取空间动态信息
momentIds := make([]int64, 0)
for _, o := range orders {
if o.GetProductId() == dbstruct.ProductIdH5ZoneMoment {
momentIds = append(momentIds, o.GetMomentId())
}
}
zmMap, _ := _DefaultZoneMoment.GetMapById(ctx, momentIds)
// 组装
for _, o := range orders {
var (
userUserId = int64(0)
streamerUserId = int64(0)
)
if a, ok := acntMap[o.GetMid()]; ok {
userUserId = util.DerefInt64(a.UserId)
}
if a, ok := acntMap[o.GetUid()]; ok {
streamerUserId = util.DerefInt64(a.UserId)
}
item := &vasproto.OpOrderVO{
Mid: o.GetMid(),
UserUserId: userUserId,
Uid: o.GetUid(),
StreamerUserId: streamerUserId,
OrderId: o.GetID(),
OrderStatus: o.GetOrderStatus(),
OrderStatusDesc: dbstruct.OrderStatusDescMap[o.GetOrderStatus()],
Coins: o.GetCoins(),
Money: o.GetPayAmount(),
Ct: o.GetCt(),
ProductName: dbstruct.ProductIdDescMap[o.GetProductId()],
RefundType: "退现金",
PayType: o.GetPayType(),
}
if o.GetPayType() == vasproto.PayTypeCoin {
item.Coins = o.GetPayAmount()
item.Money = 0
}
if o.GetProductId() == dbstruct.ProductIdH5ZoneMoment {
item.ZoneMoment = zmMap[o.GetMomentId()]
}
list = append(list, item)
}
return
}
func (s *Service) DealOneCoinOrder(ctx *gin.Context, req *vasproto.DealOneCoinOrderReq) (ec errcode.ErrCode, err error) {
ec = errcode.ErrCodeVasSrvOk
err = _DefaultVas.DealOneCoinOrder(ctx, req.CoinOrderId)
if err != nil {
logger.Error("DealOneCoinOrder fail, req: %v, err: %v", util.ToJson(req), err)
ec = errcode.ErrCodeVasSrvFail
return
}
return
}
func (s *Service) DealOneOrder(ctx *gin.Context, req *vasproto.DealOneOrderReq) (ec errcode.ErrCode, err error) {
ec = errcode.ErrCodeVasSrvOk
err = _DefaultVas.DealOneOrder(ctx, req.OrderId)
if err != nil {
logger.Error("DealOneCoinOrder fail, req: %v, err: %v", util.ToJson(req), err)
ec = errcode.ErrCodeVasSrvFail
return
}
return
}
func (s *Service) RefundOrder(ctx *gin.Context, req *vasproto.RefundOrderReq) (ec errcode.ErrCode, err error) {
ec = errcode.ErrCodeVasSrvOk
err = _DefaultVas.RefundOrder(ctx, req, nil)
if err != nil {
logger.Error("RefundOrder fail, req: %v, err: %v", util.ToJson(req), err)
ec = errcode.ErrCodeVasSrvFail
return
}
return
}
func (s *Service) RefundCoinOrder(ctx *gin.Context, req *vasproto.RefundCoinOrderReq) (ec errcode.ErrCode, err error) {
ec = errcode.ErrCodeVasSrvOk
err = _DefaultVas.RefundCoinOrder(ctx, req)
if err != nil {
logger.Error("RefundCoinOrder fail, req: %v, err: %v", util.ToJson(req), err)
ec = errcode.ErrCodeVasSrvFail
return
}
return
}
func (s *Service) ZoneCreateOrder(ctx *gin.Context, req *vasproto.ZoneCreateOrderReq) (data *vasproto.ZoneCreateOrderData, ec errcode.ErrCode, err error) {
data, err = _DefaultVas.ZoneCreateOrder(ctx, req)
ec, err = errs.DealVasErr(err)
if err != nil {
logger.Error("ZoneCreateOrder fail, err: %v", err)
return
}
return
}
func (s *Service) ZoneGetCashier(ctx *gin.Context, req *vasproto.ZoneGetCashierReq) (data *vasproto.ZoneGetCashierData, ec errcode.ErrCode, err error) {
ec = errcode.ErrCodeVasSrvOk
data = new(vasproto.ZoneGetCashierData)
data.Validity = "永久"
mid := req.Mid
zid := req.Zid
zv, _ := _DefaultVas.GetZoneVasInfo(ctx, zid)
switch req.ProductId {
case dbstruct.ProductIdH5ZoneMoment:
// 判断是否已解锁该动态
zmuMap, err := _DefaultVas.GetZoneMomentUnlockMapByMidMomentIds(ctx, req.Mid, []int64{req.MomentId})
if err != nil {
ec = errcode.ErrCodeVasSrvFail
logger.Error("GetZoneMomentUnlockMapByMidMomentIds fail, mid: %v, momentId: %v", req.Mid, req.MomentId)
return nil, ec, fmt.Errorf("无法获取动态解锁记录")
}
if _, ok := zmuMap[req.MomentId]; ok {
ec = errcode.ErrCodeVasSrvOk
data.HasBought = 1
return data, ec, nil
//ec = errcode.ErrCodeVasSrvFail
//return nil, ec, fmt.Errorf("已解锁该动态,请勿重复购买")
}
data.Name = "单条付费动态"
// 获取动态价格
zmp, _ := _DefaultVas.GetZoneMomentPriceById(ctx, req.MomentId)
if zmp != nil {
data.Price = zmp.Price
}
case dbstruct.ProductIdH5ZoneAdmission:
// 是否解锁了空间普通会员
zuMap, _ := _DefaultVas.GetZoneUnlockMapByMidZids(ctx, mid, []int64{zid})
logger.Info("GetZoneUnlockMapByMidZids, mid: %v, zid: %v, zuMap: %v", mid, zid, util.ToJson(zuMap))
if zu, ok := zuMap[zid]; ok && zu.IsUnlockAdmission() {
ec = errcode.ErrCodeVasSrvOk
data.HasBought = 1
return data, ec, nil
}
// 判断主播是否开通空间
zone, err := _DefaultZone.GetById(ctx, zid)
if err != nil || zone == nil {
ec = errcode.ErrCodeVasSrvFail
logger.Error("GetById fail, mid: %v, zid: %v, erR: %v", req.Mid, zid, err)
return nil, ec, fmt.Errorf("无法获取主播动态")
}
data.Name = "空间会员"
// 获取主播信息
acntMap, _ := _DefaultAccount.GetAccountMapByMids(ctx, []int64{zone.GetMid()})
if a, ok := acntMap[zone.GetMid()]; ok && a.Name != nil {
data.Name = *a.Name + "-空间成员"
}
if zv == nil {
ec = errcode.ErrCodeVasSrvFail
return nil, ec, fmt.Errorf("该主播未设置空间价格")
}
data.Price = zv.AdmissionPrice
case dbstruct.ProductIdH5ZoneIronfanship:
data.Name = "铁粉"
if zv == nil {
ec = errcode.ErrCodeVasSrvFail
return nil, ec, fmt.Errorf("该主播未设置空间价格")
}
data.Price = zv.IronfanshipPrice
case dbstruct.ProductIdH5ZoneSuperfanship:
// 判断主播是否开启超粉
if zv.IsSuperfanshipEnabled != 1 {
ec = errcode.ErrCodeVasSrvFail
return nil, ec, fmt.Errorf("该主播未开启超粉空间")
}
// 用户是否解锁了空间超粉
zuMap, _ := _DefaultVas.GetZoneUnlockMapByMidZids(ctx, mid, []int64{zid})
if zu, ok := zuMap[zid]; ok && zu.IsUnlockSuperfanship() {
ec = errcode.ErrCodeVasSrvOk
data.HasBought = 1
return data, ec, nil
}
data.Name = "超粉"
// 获取主播信息
zone, _ := _DefaultZone.GetById(ctx, zid)
acntMap, _ := _DefaultAccount.GetAccountMapByMids(ctx, []int64{zone.GetMid()})
if a, ok := acntMap[zone.GetMid()]; ok && a.Name != nil {
data.Name = *a.Name + "-超粉"
}
if zv == nil {
ec = errcode.ErrCodeVasSrvFail
return nil, ec, fmt.Errorf("该主播未设置空间价格")
}
data.Price = zv.SuperfanshipPrice
data.Validity = zv.GetSuperfanshipDurationDesc()
}
return
}
func (s *Service) ZoneGetRefundPage(ctx *gin.Context, req *vasproto.ZoneRefundPageReq) (name string, price int64, payType string, ec errcode.ErrCode, err error) {
name, price, payType, err = _DefaultVas.ZoneGetRefundPage(ctx, req)
ec, err = errs.DealVasErr(err)
if err != nil {
logger.Error("ZoneGetRefundPage fail, err: %v", err)
return
}
return
}
func (s *Service) ZoneRefund(ctx *gin.Context, req *vasproto.ZoneRefundReq) (ec errcode.ErrCode, err error) {
err = _DefaultVas.ZoneRefund(ctx, req)
ec, err = errs.DealVasErr(err)
if err != nil {
logger.Error("ZoneRefund fail, err: %v", err)
return
}
return
}
func (s *Service) ZoneMemberList(ctx *gin.Context, req *vasproto.GetZoneMemberListReq) (list []*vasproto.ZoneMemberVo, ec errcode.ErrCode, err error) {
list = make([]*vasproto.ZoneMemberVo, 0)
// 获取成员列表
zmList, err := _DefaultVas.GetZoneMemberList(ctx, req.Zid, req.MemberType)
ec, err = errs.DealVasErr(err)
if err != nil {
logger.Error("ZoneRefund fail, err: %v", err)
return
}
mids := make([]int64, 0)
for _, zm := range zmList {
mids = append(mids, zm.GetMid())
}
logger.Info("ZoneMemberList, zid: %v, typ: %v, mids: %v, zmList: %v", req.Zid, req.MemberType, mids, util.ToJson(zmList))
// 获取用户信息
acntMap, _ := _DefaultAccount.GetAccountMapByMids(ctx, mids)
logger.Info("GetAccountMapByMids, zid: %v, typ: %v, acntMap: %v", req.Zid, req.MemberType, util.ToJson(acntMap))
for _, zm := range zmList {
mid := zm.GetMid()
tmp := &vasproto.ZoneMemberVo{
Account: acntMap[mid],
JoinCt: zm.GetCt(),
}
list = append(list, tmp)
}
return
}
func (s *Service) ZoneFreeJoin(ctx *gin.Context, req *vasproto.ZoneFreeJoinReq) (ec errcode.ErrCode, err error) {
err = _DefaultVas.ZoneFreeJoin(ctx, req.Mid, req.Zid)
ec, err = errs.DealVasErr(err)
if err != nil {
logger.Error("ZoneFreeJoin fail, err: %v", err)
return
}
return
}
func (s *Service) ZoneExit(ctx *gin.Context, req *vasproto.ZoneExitReq) (ec errcode.ErrCode, err error) {
err = _DefaultVas.ZoneExit(ctx, req.Mid, req.Zid)
ec, err = errs.DealVasErr(err)
if err != nil {
logger.Error("ZoneExit fail, err: %v", err)
return
}
return
}
func (s *Service) OpZoneRefundList(ctx *gin.Context, req *zoneproto.OpZoneRefundListParam) (list []*zoneproto.OpZoneRefundVO, ec errcode.ErrCode) {
list = make([]*zoneproto.OpZoneRefundVO, 0)
if req.UserId > 0 && req.Mid <= 0 {
a, _ := _DefaultAccount.OpListByUserId(ctx, &accountproto.OpListByUserIdReq{
UserId: goproto.Int64(req.UserId),
})
if a != nil && a.Mid != nil {
req.Mid = *a.Mid
}
}
// 获取空间退款历史
hisList, err := _DefaultVas.OpZoneRefundList(ctx, req)
ec, err = errs.DealVasErr(err)
if err != nil {
logger.Error("OpZoneRefundList fail, req: %v, err: %v", util.ToJson(req), err)
return
}
// 获取订单
orderIds := make([]string, 0)
for _, h := range hisList {
orderIds = append(orderIds, h.GetOrderId())
}
orderMap, _ := _DefaultVas.GetOrderMapByIds(ctx, nil, orderIds)
// 获取用户
mids := make([]int64, 0)
for _, h := range hisList {
mids = append(mids, h.GetMid())
}
for _, o := range orderMap {
mids = append(mids, o.GetUid())
}
acntMap, _ := _DefaultAccount.GetAccountMapByMids(ctx, mids)
// 组装
for _, h := range hisList {
o := orderMap[h.GetOrderId()]
if o == nil {
continue
}
var (
userUserId = int64(0)
streamerUserId = int64(0)
)
if a, ok := acntMap[o.GetMid()]; ok {
userUserId = util.DerefInt64(a.UserId)
}
if a, ok := acntMap[o.GetUid()]; ok {
streamerUserId = util.DerefInt64(a.UserId)
}
item := &zoneproto.OpZoneRefundVO{
OrderId: o.GetID(),
OrderStatus: o.GetOrderStatus(),
OrderStatusDesc: dbstruct.OrderStatusDescMap[o.GetOrderStatus()],
Ct: o.GetCt(),
RefundT: h.GetCt(),
Zid: h.GetZid(),
ProductName: dbstruct.ProductIdDescMap[o.GetProductId()],
Money: o.GetPayAmount(),
Mid: o.GetMid(),
UserUserId: userUserId,
Uid: o.GetUid(),
StreamerUserId: streamerUserId,
ContactName: h.GetContactName(),
ContactPhone: h.GetContactPhone(),
Note: h.GetNote(),
}
list = append(list, item)
}
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
}
func (s *Service) OpManualUnlockWechat(ctx *gin.Context, req *zoneproto.OpManualUnlockWechatParam) (ec errcode.ErrCode, err error) {
err = _DefaultVas.SuperfanUnlockContact(ctx, nil, req.Mid, req.StreamerMid, req.Oid2)
ec, err = errs.DealVasErr(err)
if err != nil {
logger.Error("OneStepUnlockContact fail, req: %v, err: %v", util.ToJson(req), err)
return
}
return
}
func (s *Service) ApplepayCallback(ctx *gin.Context, notify applepaycli.ApplepayRevenueNotify) error {
var (
event = notify.Event
mid, _ = strconv.ParseInt(event.AppUserID, 10, 64)
)
switch event.Type {
case applepaycli.NotifyTypeNonRenewingPurchase:
// 验证用户
acnt, _ := _DefaultAccount.GetAccountMapByMids(ctx, []int64{mid})
if _, ok := acnt[mid]; !ok {
err := fmt.Errorf("invalid user")
logger.Error("ApplepayCallback fail, invalid user, mid: %v, notify: %v", mid, notify)
return err
}
// 先创建订单
createOrderParam := &vasproto.CreateOrderReq{
BaseRequest: base.BaseRequest{
Mid: mid,
DevType: common.DeviceTypeIos,
},
ProductId: event.ProductID,
PayType: vasproto.PayTypeApplepay,
Oid3: event.AppID,
}
data, err := _DefaultVas.CreateOrder(ctx, createOrderParam)
if err != nil {
logger.Error("CreateOrder fail, param: %v, err: %v", createOrderParam, err)
return err
}
orderId := data.OrderId
// 手动回调
payCallbackParam := &vasproto.PayCallbackParamIn{
OrderId: orderId,
OutOrderId: event.TransactionID,
CallbackPayType: vasproto.CallBackPayTypeApplepay,
}
err = _DefaultVas.PayCallback(ctx, payCallbackParam)
if err != nil {
logger.Error("PayCallback fail, param: %v, err: %v", payCallbackParam, err)
return err
}
}
return nil
}