1547 lines
42 KiB
Go
1547 lines
42 KiB
Go
|
|
package biz
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"context"
|
|||
|
|
"encoding/json"
|
|||
|
|
"fmt"
|
|||
|
|
"strconv"
|
|||
|
|
"strings"
|
|||
|
|
"time"
|
|||
|
|
|
|||
|
|
"sandc/app/eonline/internal/conf"
|
|||
|
|
"sandc/app/eonline/internal/config"
|
|||
|
|
"sandc/pkg/geo"
|
|||
|
|
"sandc/pkg/middleware/xhttp"
|
|||
|
|
"sandc/pkg/utils"
|
|||
|
|
|
|||
|
|
"github.com/go-kratos/kratos/v2/log"
|
|||
|
|
"github.com/hibiken/asynq"
|
|||
|
|
"github.com/tx7do/kratos-transport/broker"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
type Eonline struct {
|
|||
|
|
Hello string
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
type EonlineRepo interface {
|
|||
|
|
CreateEonline(context.Context, *Eonline) error
|
|||
|
|
UpdateEonline(context.Context, *Eonline) error
|
|||
|
|
|
|||
|
|
GetUserByUuid(ctx context.Context, uuid string) (*PayoutUser, error)
|
|||
|
|
CreatePayoutUser(ctx context.Context, item *PayoutUser) (*PayoutUser, error)
|
|||
|
|
SearchPayoutRecord(ctx context.Context, opts *SearchPayoutRecordReq) (*ListPayoutRecord, error)
|
|||
|
|
GetPayoutLeftum(ctx context.Context, uuid string) (int, error)
|
|||
|
|
GetPayoutRecordCountByAccount(ctx context.Context, account string) (int, error)
|
|||
|
|
CreatePayoutRecord(ctx context.Context, item *PayoutRecord) (*PayoutRecord, error)
|
|||
|
|
UpdatePayoutRecordNotify(ctx context.Context, recordNo string, payoutId string, status uint8, fail string) error
|
|||
|
|
GetPayoutRecordListByUuid(ctx context.Context, uuid string) ([]*PayoutRecord, error)
|
|||
|
|
// GetPayoutRecordByRecordNo 获取提现记录
|
|||
|
|
GetPayoutRecordByRecordNo(ctx context.Context, recordNo string) (*PayoutRecord, error)
|
|||
|
|
// 根据account、status 获取提现记录
|
|||
|
|
GetPayoutRecordByAccountStatus(ctx context.Context, account string, status, pageIndex, pageSize int) ([]*PayoutRecord, error)
|
|||
|
|
// UpdatePayoutUserLoginDays 更新用户登录天数
|
|||
|
|
UpdatePayoutUserLoginDays(ctx context.Context, uuid string, loginDays uint) error
|
|||
|
|
// 更新 客户端上传的、需要保持的数据
|
|||
|
|
UpdatePayoutUserClientData(ctx context.Context, uuid string, clientData string) error
|
|||
|
|
|
|||
|
|
CreateBonusRecord(ctx context.Context, item *BonusRecord) (*BonusRecord, error)
|
|||
|
|
UpdateBonusCur(ctx context.Context, id uint32, bonusCur uint32) error
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
type EonlineUsecase struct {
|
|||
|
|
repo EonlineRepo
|
|||
|
|
conf *conf.Bootstrap
|
|||
|
|
log *log.Helper
|
|||
|
|
tx Transaction
|
|||
|
|
pscli *PagsmileClient
|
|||
|
|
cache Cache
|
|||
|
|
geocli *geo.GeoClient
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func NewEonlineUsecase(repo EonlineRepo, conf *conf.Bootstrap, tx Transaction, logger log.Logger, cache Cache) *EonlineUsecase {
|
|||
|
|
return &EonlineUsecase{
|
|||
|
|
repo: repo,
|
|||
|
|
tx: tx,
|
|||
|
|
log: log.NewHelper(logger),
|
|||
|
|
pscli: NewPagsmileClient(&PayoutClient{
|
|||
|
|
AppId: conf.Pagsmile.Payout.AppId,
|
|||
|
|
AppKey: conf.Pagsmile.Payout.AppKey,
|
|||
|
|
ApiUrl: conf.Pagsmile.Payout.ApiUrl,
|
|||
|
|
NotifyUrl: conf.Pagsmile.Payout.NotifyUrl,
|
|||
|
|
}, logger),
|
|||
|
|
conf: conf,
|
|||
|
|
cache: cache,
|
|||
|
|
geocli: geo.NewGeoClient(conf.Server.GeoFile),
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (uc *EonlineUsecase) Create(ctx context.Context, g *Eonline) error {
|
|||
|
|
return uc.repo.CreateEonline(ctx, g)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (uc *EonlineUsecase) Update(ctx context.Context, g *Eonline) error {
|
|||
|
|
return uc.repo.UpdateEonline(ctx, g)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (uc *EonlineUsecase) KakfaExampleConsumer(_ context.Context, topic string, headers broker.Headers, msg *ExampleStruct) error {
|
|||
|
|
log.Infof("Topic %s, Headers: %+v, Payload: %+v\n", topic, headers, msg)
|
|||
|
|
return nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const EonlineTaskName = "eonline:task"
|
|||
|
|
|
|||
|
|
// AsynqEonlineTaskHandler Asynq handler task
|
|||
|
|
func (uc *EonlineUsecase) AsynqEonlineTaskHandler(ctx context.Context, t *asynq.Task) error {
|
|||
|
|
// do something
|
|||
|
|
// do some else logging
|
|||
|
|
log.Info("AsynqEonlineTaskHandle: ", string(t.Payload()))
|
|||
|
|
return nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// PayInitReq 支付初始化请求
|
|||
|
|
type PayInitReq struct {
|
|||
|
|
DeviceId string
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// PayInitReply 支付初始化响应
|
|||
|
|
type PayInitReply struct {
|
|||
|
|
UUID string
|
|||
|
|
ClientData string
|
|||
|
|
Days uint32 // 登录天数
|
|||
|
|
Items []*PayoutItem
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// PayoutItem 支付项目
|
|||
|
|
type PayoutItem struct {
|
|||
|
|
Id uint
|
|||
|
|
Amount float64
|
|||
|
|
Status uint8
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// PayInit
|
|||
|
|
func (uc *EonlineUsecase) PayInit(ctx context.Context, req *PayoutAddtionalReq) (*PayInitReply, error) {
|
|||
|
|
// 生成唯一用户ID
|
|||
|
|
uuid := GenPayoutUuid(req.DeviceId)
|
|||
|
|
err := uc.initUserLoginDays(ctx, uuid, req)
|
|||
|
|
if err != nil {
|
|||
|
|
return nil, fmt.Errorf("init user login days error: %v", err)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 判断是否提现
|
|||
|
|
payoutValidRes, err, _ := uc.checkPayoutValid(ctx, uuid, req)
|
|||
|
|
if err != nil {
|
|||
|
|
// 如果不允许提现,状态全部更改为不可提现
|
|||
|
|
payoutValidRes.LeftNum[uint(PayoutItemId1)] = -1
|
|||
|
|
payoutValidRes.LeftNum[uint(PayoutItemId2)] = -1
|
|||
|
|
payoutValidRes.LeftNum[uint(PayoutItemId3)] = -1
|
|||
|
|
payoutValidRes.LeftNum[uint(PayoutItemId4)] = -1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
items := make([]*PayoutItem, 0)
|
|||
|
|
for k, v := range PayoutItemIdAmountes {
|
|||
|
|
if k == 0 {
|
|||
|
|
continue
|
|||
|
|
}
|
|||
|
|
// 生成对应的payoutItem
|
|||
|
|
payoutItem := &PayoutItem{
|
|||
|
|
Id: uint(k),
|
|||
|
|
Amount: v,
|
|||
|
|
Status: uint8(uc.getPayoutItemStatus(ctx, uuid, req.Ts, uint(k), payoutValidRes)),
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
items = append(items, payoutItem)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
reply := &PayInitReply{
|
|||
|
|
UUID: uuid,
|
|||
|
|
ClientData: payoutValidRes.ClientData,
|
|||
|
|
Days: payoutValidRes.Days,
|
|||
|
|
Items: items,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return reply, nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// initUserLoginDays 初始化用户登录天数
|
|||
|
|
func (uc *EonlineUsecase) initUserLoginDays(ctx context.Context, uuid string, req *PayoutAddtionalReq) error {
|
|||
|
|
// 插入用户登录信息
|
|||
|
|
// 判断当前用户是否存在
|
|||
|
|
user, err := uc.repo.GetUserByUuid(ctx, uuid)
|
|||
|
|
if err != nil {
|
|||
|
|
return err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 定义用户登录redis key
|
|||
|
|
keyDay := ""
|
|||
|
|
if uc.conf.Server.Env == "qa" {
|
|||
|
|
ts, _ := strconv.ParseInt(req.Ts, 10, 64)
|
|||
|
|
keyDay = time.Unix(ts, 0).Format("20060102")
|
|||
|
|
}
|
|||
|
|
userLoginRedisKey := GetUserLoginRedisKey(uuid, keyDay)
|
|||
|
|
|
|||
|
|
// 创建用户
|
|||
|
|
if user.Id == 0 {
|
|||
|
|
// 记录登录用户
|
|||
|
|
_, err = uc.repo.CreatePayoutUser(ctx, &PayoutUser{
|
|||
|
|
Uuid: uuid,
|
|||
|
|
DeviceId: req.DeviceId,
|
|||
|
|
Platform: req.Platform,
|
|||
|
|
Version: req.Version,
|
|||
|
|
Country: req.Country,
|
|||
|
|
Ip: req.Ip,
|
|||
|
|
LoginDays: 1,
|
|||
|
|
})
|
|||
|
|
if err != nil {
|
|||
|
|
return err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 是否已记录当前登录行为
|
|||
|
|
err = uc.cache.WriteValue(ctx, userLoginRedisKey, "1", 24*3600)
|
|||
|
|
if err != nil {
|
|||
|
|
return fmt.Errorf("write redis error: %v", err)
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
// 更新登录天数
|
|||
|
|
currentValue, err := uc.cache.GetValue(ctx, userLoginRedisKey)
|
|||
|
|
if err != nil {
|
|||
|
|
return fmt.Errorf("get redis value error: %v", err)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if currentValue == "" {
|
|||
|
|
// 更新登录天数
|
|||
|
|
loginDays := user.LoginDays + 1
|
|||
|
|
err = uc.repo.UpdatePayoutUserLoginDays(ctx, uuid, loginDays)
|
|||
|
|
if err != nil {
|
|||
|
|
return fmt.Errorf("update payout user login days error: %v", err)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 记录当前登录行为
|
|||
|
|
err = uc.cache.WriteValue(ctx, userLoginRedisKey, "1", 24*3600)
|
|||
|
|
if err != nil {
|
|||
|
|
return fmt.Errorf("write redis error: %v", err)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (uc *EonlineUsecase) updateUserClientData(ctx context.Context, uuid string, clientData string) error {
|
|||
|
|
err := uc.repo.UpdatePayoutUserClientData(ctx, uuid, clientData)
|
|||
|
|
if err != nil {
|
|||
|
|
return fmt.Errorf("update payout user clientData error: %v", err)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// getPayoutItemStatus 获取提现项目状态
|
|||
|
|
func (uc *EonlineUsecase) getPayoutItemStatus(ctx context.Context, uuid, ts string, itemId uint, payoutValidRes *PayoutValidRes) PayoutItemStatus {
|
|||
|
|
leftNum, ok := payoutValidRes.LeftNum[itemId]
|
|||
|
|
if !ok || leftNum <= 0 {
|
|||
|
|
return PayoutItemStatusForbidden
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if _, ok = payoutValidRes.RecordStatusMap[itemId]; ok {
|
|||
|
|
switch payoutValidRes.RecordStatusMap[itemId] {
|
|||
|
|
// 提现成功的状态,返回已提现
|
|||
|
|
case uint8(PayoutStatusPayouted):
|
|||
|
|
return PayoutItemStatusPayouted
|
|||
|
|
// 提现失败的状态,返回可提现
|
|||
|
|
case uint8(PayoutStatusPayoutFailed):
|
|||
|
|
return PayoutItemStatusAvailable
|
|||
|
|
// 提现中的状态,返回提现中
|
|||
|
|
case uint8(PayoutStatusPayouting):
|
|||
|
|
return PayoutItemStatusPayouting
|
|||
|
|
default:
|
|||
|
|
return PayoutItemStatusForbidden
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 如果没有提现记录,返回可提现
|
|||
|
|
if itemId == 1 {
|
|||
|
|
return PayoutItemStatusAvailable
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 如果没有提现记录,返回可提现
|
|||
|
|
// 根据uuid查询用户是否满足第二天的提现条件
|
|||
|
|
// user, err := uc.repo.GetUserByUuid(ctx, uuid)
|
|||
|
|
// if err != nil {
|
|||
|
|
// return PayoutItemStatusForbidden
|
|||
|
|
// }
|
|||
|
|
//
|
|||
|
|
// if user.LoginDays >= 3 && payoutValidRes.LeftNum[itemId] == 1 {
|
|||
|
|
// return PayoutItemStatusAvailable
|
|||
|
|
// } else {
|
|||
|
|
// return PayoutItemStatusUnfinished
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
keyDay := ""
|
|||
|
|
if uc.conf.Server.Env == "qa" {
|
|||
|
|
ts, _ := strconv.ParseInt(ts, 10, 64)
|
|||
|
|
keyDay = time.Unix(ts, 0).Format("20060102")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uuidRedisKey := GetUuidPayoutRedisKey(uuid, keyDay, uint32(itemId))
|
|||
|
|
v, err := uc.cache.GetValue(ctx, uuidRedisKey)
|
|||
|
|
if err != nil {
|
|||
|
|
// uc.log.WithContext(ctx).Errorf("get redis value error: %v", err)
|
|||
|
|
log.Infof("get redis value error: %v", err)
|
|||
|
|
return PayoutItemStatusUnfinished
|
|||
|
|
}
|
|||
|
|
if v == "" && leftNum > 0 {
|
|||
|
|
return PayoutItemStatusAvailable
|
|||
|
|
} else {
|
|||
|
|
return PayoutItemStatusUnfinished
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// PayoutValidRes 提现是否有效响应
|
|||
|
|
type PayoutValidRes struct {
|
|||
|
|
Days uint32
|
|||
|
|
LeftNum map[uint]int
|
|||
|
|
RecordStatusMap map[uint]uint8
|
|||
|
|
ClientData string
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// true表示可以提现的国家
|
|||
|
|
func canPayoutCountry(country string) bool {
|
|||
|
|
if country == "US" || country == "CA" || country == "IN" || country == "PH" || country == "ID" || country == "VN" || country == "TH" || country == "BR" {
|
|||
|
|
return true
|
|||
|
|
}
|
|||
|
|
return false
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 转换国家代码
|
|||
|
|
func convertCountry(country string) string {
|
|||
|
|
if country == "US" { // 美国
|
|||
|
|
return "USA"
|
|||
|
|
} else if country == "CA" { // 加拿大
|
|||
|
|
return "CAN"
|
|||
|
|
} else if country == "IN" { // 印度
|
|||
|
|
return "IND"
|
|||
|
|
} else if country == "PH" { // 菲律宾
|
|||
|
|
return "PHL"
|
|||
|
|
} else if country == "ID" { // 印度尼西亚
|
|||
|
|
return "IDN"
|
|||
|
|
} else if country == "VN" { // 越南
|
|||
|
|
return "VNM"
|
|||
|
|
} else if country == "TH" { // 泰国
|
|||
|
|
return "THA"
|
|||
|
|
} else if country == "BR" { // 巴西
|
|||
|
|
return "BRA"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
log.Infof("convertCountry error: country[%s]", country)
|
|||
|
|
return country
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// checkPayoutValid 检查提现是否有效,1+2位数
|
|||
|
|
func (uc *EonlineUsecase) checkPayoutValid(ctx context.Context, uuid string, opts *PayoutAddtionalReq) (*PayoutValidRes, error, int32) {
|
|||
|
|
payoutValidRes := &PayoutValidRes{
|
|||
|
|
Days: 0,
|
|||
|
|
LeftNum: make(map[uint]int),
|
|||
|
|
RecordStatusMap: make(map[uint]uint8),
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 判断是否可以提现,国家判断
|
|||
|
|
// if opts.Country != "US" && opts.Country != "CA" && opts.Country != "IN" && opts.Country != "PH" {
|
|||
|
|
// if !canPayoutCountry(opts.Country) {
|
|||
|
|
// return payoutValidRes, fmt.Errorf("country [%s] not support", opts.Country), 101
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
if opts.ItemId > 0 {
|
|||
|
|
if opts.ItemId <= uint32(len(PayoutItemIdAmountes)) {
|
|||
|
|
// 判断金额是否一致
|
|||
|
|
if int32(opts.Amount*100) != int32(PayoutItemIdAmountes[int(opts.ItemId)]*100) {
|
|||
|
|
return payoutValidRes, fmt.Errorf("amount error"), 102
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
return payoutValidRes, fmt.Errorf("ItemId error"), 103
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
user, err := uc.repo.GetUserByUuid(ctx, uuid)
|
|||
|
|
if err != nil {
|
|||
|
|
return payoutValidRes, err, 1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
payoutValidRes.Days = uint32(user.LoginDays)
|
|||
|
|
payoutValidRes.ClientData = user.ClientData
|
|||
|
|
|
|||
|
|
records, err := uc.repo.GetPayoutRecordListByUuid(ctx, uuid)
|
|||
|
|
if err != nil {
|
|||
|
|
return payoutValidRes, err, 1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var num1, num2, num3, num4 int
|
|||
|
|
var lastest1, lastest2, lastest3, lastest4 *PayoutRecord
|
|||
|
|
var leftAmount float64
|
|||
|
|
for _, record := range records {
|
|||
|
|
if record.ItemId == uint(PayoutItemId4) {
|
|||
|
|
continue
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
switch record.ItemId {
|
|||
|
|
case uint(PayoutItemId1):
|
|||
|
|
if record.Status == uint8(PayoutStatusPayouted) || record.Status == uint8(PayoutStatusPayouting) {
|
|||
|
|
num1++
|
|||
|
|
leftAmount += record.Amount
|
|||
|
|
}
|
|||
|
|
if lastest1 != nil {
|
|||
|
|
if lastest1.CreatedAt.Compare(record.CreatedAt) < 0 {
|
|||
|
|
lastest1 = record
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
lastest1 = record
|
|||
|
|
}
|
|||
|
|
case uint(PayoutItemId2):
|
|||
|
|
if record.Status == uint8(PayoutStatusPayouted) || record.Status == uint8(PayoutStatusPayouting) {
|
|||
|
|
num2++
|
|||
|
|
leftAmount += record.Amount
|
|||
|
|
}
|
|||
|
|
if lastest2 != nil {
|
|||
|
|
if lastest2.CreatedAt.Compare(record.CreatedAt) < 0 {
|
|||
|
|
lastest2 = record
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
lastest2 = record
|
|||
|
|
}
|
|||
|
|
case uint(PayoutItemId3):
|
|||
|
|
if record.Status == uint8(PayoutStatusPayouted) || record.Status == uint8(PayoutStatusPayouting) {
|
|||
|
|
num3++
|
|||
|
|
leftAmount += record.Amount
|
|||
|
|
}
|
|||
|
|
if lastest3 != nil {
|
|||
|
|
if lastest3.CreatedAt.Compare(record.CreatedAt) < 0 {
|
|||
|
|
lastest3 = record
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
lastest3 = record
|
|||
|
|
}
|
|||
|
|
case uint(PayoutItemId4):
|
|||
|
|
if record.Status == uint8(PayoutStatusPayouted) || record.Status == uint8(PayoutStatusPayouting) {
|
|||
|
|
num4++
|
|||
|
|
}
|
|||
|
|
if lastest4 != nil {
|
|||
|
|
if lastest4.CreatedAt.Compare(record.CreatedAt) < 0 {
|
|||
|
|
lastest4 = record
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
lastest4 = record
|
|||
|
|
}
|
|||
|
|
default:
|
|||
|
|
log.Infof("checkPayoutValid error: uuid[%s] record.ItemId[%d] not dispatch No.1", uuid, record.ItemId)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ts, _ := strconv.ParseInt(opts.Ts, 10, 64)
|
|||
|
|
|
|||
|
|
keyDay := ""
|
|||
|
|
if uc.conf.Server.Env == "qa" {
|
|||
|
|
keyDay = time.Unix(ts, 0).Format("20060102")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var now time.Time
|
|||
|
|
now = time.Unix(ts, 0)
|
|||
|
|
recordStatusMap := make(map[uint]uint8)
|
|||
|
|
if lastest1 != nil {
|
|||
|
|
if isSameDay(now, lastest1.CreatedAt) {
|
|||
|
|
recordStatusMap[lastest1.ItemId] = lastest1.Status
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if lastest2 != nil {
|
|||
|
|
if isSameDay(now, lastest2.CreatedAt) {
|
|||
|
|
recordStatusMap[lastest2.ItemId] = lastest2.Status
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if lastest3 != nil {
|
|||
|
|
if isSameDay(now, lastest3.CreatedAt) {
|
|||
|
|
recordStatusMap[lastest3.ItemId] = lastest3.Status
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if lastest4 != nil {
|
|||
|
|
if isSameDay(now, lastest4.CreatedAt) {
|
|||
|
|
recordStatusMap[lastest4.ItemId] = lastest4.Status
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// true表示今天已提现过
|
|||
|
|
// callCheckTodayPayoutStatus := func(itemId PayoutItemId) bool {
|
|||
|
|
// uuidRedisKey := GetUuidPayoutRedisKey(uuid, keyDay, uint32(itemId))
|
|||
|
|
// value, err := uc.cache.GetValue(ctx, uuidRedisKey)
|
|||
|
|
// if err == nil {
|
|||
|
|
// if value != "" {
|
|||
|
|
// return true
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
// return false
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
// 检查已提现次数
|
|||
|
|
if num1 < PayoutRecordLimit1 {
|
|||
|
|
payoutValidRes.LeftNum[uint(PayoutItemId1)] = PayoutRecordLimit1 - num1
|
|||
|
|
} else {
|
|||
|
|
payoutValidRes.LeftNum[uint(PayoutItemId1)] = -1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if num2 < PayoutRecordLimit2 {
|
|||
|
|
payoutValidRes.LeftNum[uint(PayoutItemId2)] = PayoutRecordLimit2 - num2
|
|||
|
|
} else {
|
|||
|
|
payoutValidRes.LeftNum[uint(PayoutItemId2)] = -1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if num3 < PayoutRecordLimit3 {
|
|||
|
|
payoutValidRes.LeftNum[uint(PayoutItemId3)] = PayoutRecordLimit3 - num3
|
|||
|
|
} else {
|
|||
|
|
payoutValidRes.LeftNum[uint(PayoutItemId3)] = -1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if num4 < PayoutRecordLimit4 {
|
|||
|
|
payoutValidRes.LeftNum[uint(PayoutItemId4)] = PayoutRecordLimit4 - num4
|
|||
|
|
} else {
|
|||
|
|
payoutValidRes.LeftNum[uint(PayoutItemId4)] = -1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
payoutValidRes.RecordStatusMap = recordStatusMap
|
|||
|
|
// 判断金额
|
|||
|
|
leftAmount += opts.Amount
|
|||
|
|
if leftAmount > PayoutAmountLimit {
|
|||
|
|
return payoutValidRes, fmt.Errorf("amount limit"), 104
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if opts.ItemId > 0 {
|
|||
|
|
// 首次提现必须是0.1
|
|||
|
|
if num1+num2+num3+num4 <= 0 {
|
|||
|
|
if opts.ItemId != uint32(PayoutItemId1) {
|
|||
|
|
return payoutValidRes, fmt.Errorf("ItemId error"), 108
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
switch opts.ItemId {
|
|||
|
|
case 1:
|
|||
|
|
if num1 >= PayoutRecordLimit1 {
|
|||
|
|
return payoutValidRes, fmt.Errorf("no payout chance"), 105
|
|||
|
|
}
|
|||
|
|
case 2:
|
|||
|
|
if num2 >= PayoutRecordLimit2 {
|
|||
|
|
return payoutValidRes, fmt.Errorf("no payout chance"), 105
|
|||
|
|
}
|
|||
|
|
case 3:
|
|||
|
|
if num3 >= PayoutRecordLimit3 {
|
|||
|
|
return payoutValidRes, fmt.Errorf("no payout chance"), 105
|
|||
|
|
}
|
|||
|
|
case 4:
|
|||
|
|
if num4 >= PayoutRecordLimit4 {
|
|||
|
|
return payoutValidRes, fmt.Errorf("no payout chance"), 105
|
|||
|
|
}
|
|||
|
|
default:
|
|||
|
|
log.Infof("checkPayoutValid error: uuid[%s] record.ItemId[%d] not dispatch No.2", uuid, opts.ItemId)
|
|||
|
|
return payoutValidRes, fmt.Errorf("no payout chance"), 105
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
// if leftNum1 <= 0 {
|
|||
|
|
// return payoutValidRes, fmt.Errorf("no payout chance"), 105
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
if opts.ItemId > 0 {
|
|||
|
|
uuidRedisKey := GetUuidPayoutRedisKey(uuid, keyDay, opts.ItemId)
|
|||
|
|
value, err := uc.cache.GetValue(ctx, uuidRedisKey)
|
|||
|
|
if err != nil {
|
|||
|
|
return payoutValidRes, err, 1
|
|||
|
|
}
|
|||
|
|
// 次日才能进行第二次提现(逻辑保留)
|
|||
|
|
if value != "" {
|
|||
|
|
return payoutValidRes, fmt.Errorf("no payout chance, please try tomorrow"), 106
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 登录第三日才能体现第二次
|
|||
|
|
// if leftNum1 == 1 && user.LoginDays < 3 && opts.ItemId > 0 {
|
|||
|
|
// return payoutValidRes, fmt.Errorf("no payout chance, please try tomorrow")
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
if len(opts.Account) > 0 {
|
|||
|
|
// 如果是qa环境,test账号不限制提现次数
|
|||
|
|
// if uc.conf.Server.Env == "qa" && opts.Account == "pagsmile_test_success@pagsmile.com" {
|
|||
|
|
if uc.conf.Server.Env == "qa" && strings.Contains(opts.Account, "@pagsmile.com") {
|
|||
|
|
return payoutValidRes, nil, 0
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 一个账号只能提现2次
|
|||
|
|
count, err := uc.repo.GetPayoutRecordCountByAccount(ctx, opts.Account)
|
|||
|
|
if err != nil {
|
|||
|
|
return payoutValidRes, err, 1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if count >= PayoutRecordLimit1+PayoutRecordLimit2+PayoutRecordLimit3+PayoutRecordLimit4 {
|
|||
|
|
return payoutValidRes, fmt.Errorf("account payouted limit"), 107
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return payoutValidRes, nil, 0
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 1+2位数
|
|||
|
|
func (uc *EonlineUsecase) checkPayoutValidNew(ctx context.Context, uuid string, opts *PayoutAddtionalReq) (*PayoutValidRes, error, int32) {
|
|||
|
|
x, err := uc.CheckInfo(ctx, &CheckInfoReq{
|
|||
|
|
Uuid: uuid,
|
|||
|
|
Ts: opts.Ts,
|
|||
|
|
})
|
|||
|
|
if err != nil {
|
|||
|
|
return nil, fmt.Errorf("error: %w", err), 1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if x.CanCheckPayOut == 1 {
|
|||
|
|
return nil, fmt.Errorf("can't payout"), 150
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
payoutValidRes := &PayoutValidRes{
|
|||
|
|
LeftNum: make(map[uint]int),
|
|||
|
|
RecordStatusMap: make(map[uint]uint8),
|
|||
|
|
}
|
|||
|
|
// 判断是否可以提现,国家判断
|
|||
|
|
// if opts.Country != "US" && opts.Country != "CA" && opts.Country != "IN" && opts.Country != "PH" {
|
|||
|
|
// if !canPayoutCountry(opts.Country) {
|
|||
|
|
// return payoutValidRes, fmt.Errorf("country [%s] not support", opts.Country), 101
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
// 判断金额是否一致
|
|||
|
|
if int32(opts.Amount*100) != config.PublicCheckCoin {
|
|||
|
|
return payoutValidRes, fmt.Errorf("amount error"), 102
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
records, err := uc.repo.GetPayoutRecordListByUuid(ctx, uuid)
|
|||
|
|
if err != nil {
|
|||
|
|
return payoutValidRes, err, 1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
recordStatusMap := make(map[uint]uint8)
|
|||
|
|
for _, record := range records {
|
|||
|
|
if _, ok := recordStatusMap[record.ItemId]; !ok {
|
|||
|
|
recordStatusMap[record.ItemId] = record.Status
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
payoutValidRes.RecordStatusMap = recordStatusMap
|
|||
|
|
|
|||
|
|
status, ok := recordStatusMap[uint(PayoutItemId4)]
|
|||
|
|
if ok {
|
|||
|
|
if status == uint8(PayoutStatusPayouted) || status == uint8(PayoutStatusPayouting) {
|
|||
|
|
return payoutValidRes, fmt.Errorf("no payout chance"), 105
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// keyDay := ""
|
|||
|
|
// if uc.conf.Server.Env == "qa" {
|
|||
|
|
// ts, _ := strconv.ParseInt(opts.Ts, 10, 64)
|
|||
|
|
// keyDay = time.Unix(ts, 0).Format("20060102")
|
|||
|
|
// }
|
|||
|
|
//
|
|||
|
|
// uuidRedisKey := GetUuidPayoutRedisKey(uuid, keyDay)
|
|||
|
|
// value, err := uc.cache.GetValue(ctx, uuidRedisKey)
|
|||
|
|
// if err != nil {
|
|||
|
|
// return payoutValidRes, err
|
|||
|
|
// }
|
|||
|
|
//
|
|||
|
|
// // 次日才能进行第二次体现(逻辑保留)
|
|||
|
|
// if value != "" && opts.ItemId > 0 {
|
|||
|
|
// return payoutValidRes, fmt.Errorf("no payout chance, please try tomorrow")
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
return payoutValidRes, nil, 0
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// PayoutAddtionalReq 支付附加请求
|
|||
|
|
type PayoutAddtionalReq struct {
|
|||
|
|
Platform string
|
|||
|
|
DeviceId string
|
|||
|
|
Version string
|
|||
|
|
EcpmLvl uint32
|
|||
|
|
ItemId uint32
|
|||
|
|
Ip string
|
|||
|
|
Amount float64
|
|||
|
|
Country string
|
|||
|
|
Account string
|
|||
|
|
Ts string
|
|||
|
|
Email string
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Payout 支付请求
|
|||
|
|
func (uc *EonlineUsecase) Payout(ctx context.Context, uuid string, opts *PayoutAddtionalReq, req *PayoutReq) (*PayoutReplyData, error, int32) {
|
|||
|
|
// 定义一个uuid的redis key
|
|||
|
|
keyDay := ""
|
|||
|
|
if uc.conf.Server.Env == "qa" {
|
|||
|
|
ts, _ := strconv.ParseInt(opts.Ts, 10, 64)
|
|||
|
|
keyDay = time.Unix(ts, 0).Format("20060102")
|
|||
|
|
}
|
|||
|
|
uuidRedisKey := GetUuidPayoutRedisKey(uuid, keyDay, opts.ItemId)
|
|||
|
|
// 定义一个uuid的redis lock key, 用于锁定, 防止并发
|
|||
|
|
uuidRedisLockKey := GetUuidLockRedisKey(uuid, keyDay)
|
|||
|
|
lock, _ := uc.cache.RedisLock(ctx, uuidRedisLockKey, 1, 20)
|
|||
|
|
if !lock {
|
|||
|
|
return nil, fmt.Errorf("lock error"), 1
|
|||
|
|
}
|
|||
|
|
defer func() {
|
|||
|
|
uc.cache.RedisUnLock(ctx, uuidRedisLockKey)
|
|||
|
|
}()
|
|||
|
|
|
|||
|
|
country, currentIp := uc.GetCountryCodeByIp(ctx, opts.Ip)
|
|||
|
|
opts.Country = country
|
|||
|
|
opts.Ip = currentIp
|
|||
|
|
|
|||
|
|
// 验证提现是否有效
|
|||
|
|
var err error
|
|||
|
|
var errCode int32
|
|||
|
|
if opts.ItemId == uint32(PayoutItemId4) {
|
|||
|
|
_, err, errCode = uc.checkPayoutValidNew(ctx, uuid, opts)
|
|||
|
|
} else {
|
|||
|
|
_, err, errCode = uc.checkPayoutValid(ctx, uuid, opts)
|
|||
|
|
}
|
|||
|
|
if err != nil {
|
|||
|
|
switch errCode {
|
|||
|
|
case 101:
|
|||
|
|
errCode = 5
|
|||
|
|
case 102:
|
|||
|
|
errCode = 6
|
|||
|
|
case 103:
|
|||
|
|
errCode = 7
|
|||
|
|
case 104:
|
|||
|
|
errCode = 8
|
|||
|
|
case 105:
|
|||
|
|
errCode = 9
|
|||
|
|
case 106:
|
|||
|
|
errCode = 10
|
|||
|
|
case 107:
|
|||
|
|
errCode = 11
|
|||
|
|
case 150:
|
|||
|
|
errCode = 12
|
|||
|
|
default:
|
|||
|
|
log.Infof("checkPayoutValid error: errCode[%d]", errCode)
|
|||
|
|
errCode = 1
|
|||
|
|
}
|
|||
|
|
return nil, err, errCode
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 判断当前用户是否存在
|
|||
|
|
user, err := uc.repo.GetUserByUuid(ctx, uuid)
|
|||
|
|
if err != nil {
|
|||
|
|
return nil, err, 1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 支付的时候需要替换掉country code
|
|||
|
|
// if country == "US" { // 美国
|
|||
|
|
// req.Country = "USA"
|
|||
|
|
// } else if country == "CA" { // 加拿大
|
|||
|
|
// req.Country = "CAN"
|
|||
|
|
// } else if country == "IN" { // 印度
|
|||
|
|
// req.Country = "IND"
|
|||
|
|
// } else if country == "PH" { // 菲律宾
|
|||
|
|
// req.Country = "PHL"
|
|||
|
|
// }
|
|||
|
|
req.Country = convertCountry(country)
|
|||
|
|
|
|||
|
|
// 创建提现用户
|
|||
|
|
if user.Id == 0 {
|
|||
|
|
// 记录提现的用户
|
|||
|
|
_, err = uc.repo.CreatePayoutUser(ctx, &PayoutUser{
|
|||
|
|
Uuid: uuid,
|
|||
|
|
DeviceId: opts.DeviceId,
|
|||
|
|
Platform: opts.Platform,
|
|||
|
|
Version: opts.Version,
|
|||
|
|
Country: country,
|
|||
|
|
Ip: opts.Ip,
|
|||
|
|
LoginDays: 1,
|
|||
|
|
})
|
|||
|
|
if err != nil {
|
|||
|
|
return nil, err, 1
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 记录提现及操作
|
|||
|
|
var payoutReplyData PayoutReplyData
|
|||
|
|
var payoutStatus uint8 // 记录提现状态
|
|||
|
|
err = uc.tx.InTx(ctx, func(ctx context.Context) error {
|
|||
|
|
// 创建提现记录
|
|||
|
|
|
|||
|
|
// 以下参数固定
|
|||
|
|
req.AccountType = "EMAIL"
|
|||
|
|
req.Method = "WALLET"
|
|||
|
|
req.Channel = "PayPal"
|
|||
|
|
req.FeeBear = "merchant" // beneficiary , merchant
|
|||
|
|
// 如果金额大于等于0.3, 收款方承担手续费
|
|||
|
|
if opts.Amount > 0.3 {
|
|||
|
|
req.FeeBear = "beneficiary"
|
|||
|
|
}
|
|||
|
|
req.SourceCurrency = "USD"
|
|||
|
|
req.ArrivalCurrency = "USD"
|
|||
|
|
reqMd5 := utils.MD5Any(req)
|
|||
|
|
customCode := fmt.Sprintf("PGS_%s", utils.MD5Any(fmt.Sprintf("%s-%d", reqMd5, time.Now().Unix())))
|
|||
|
|
// 类似唯一订单号
|
|||
|
|
req.CustomCode = customCode
|
|||
|
|
|
|||
|
|
record, err := uc.repo.CreatePayoutRecord(ctx, &PayoutRecord{
|
|||
|
|
Uuid: uuid,
|
|||
|
|
Channel: req.Channel,
|
|||
|
|
ItemId: uint(opts.ItemId),
|
|||
|
|
Amount: opts.Amount,
|
|||
|
|
Account: req.Account,
|
|||
|
|
Currency: req.SourceCurrency,
|
|||
|
|
Status: uint8(PayoutStatusPayouting),
|
|||
|
|
RecordNo: req.CustomCode,
|
|||
|
|
Version: opts.Version,
|
|||
|
|
Email: opts.Email,
|
|||
|
|
})
|
|||
|
|
if err != nil {
|
|||
|
|
return fmt.Errorf("create payout record error: %v", err)
|
|||
|
|
}
|
|||
|
|
// 第三方提现
|
|||
|
|
x, err := uc.pscli.out.Payout(ctx, req)
|
|||
|
|
if err != nil {
|
|||
|
|
return err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
payoutReplyData = *x
|
|||
|
|
payoutStatus = uint8(PayoutStatusPayouting)
|
|||
|
|
// 等待回调更新状态
|
|||
|
|
err = uc.repo.UpdatePayoutRecordNotify(ctx, payoutReplyData.CustomCode, payoutReplyData.Id, payoutStatus, "")
|
|||
|
|
if err != nil {
|
|||
|
|
return fmt.Errorf("update payout record_%d status error: %v", record.Id, err)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return nil
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
if err != nil {
|
|||
|
|
return nil, err, 1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 记录此次提现,用于判断是否可以继续提现
|
|||
|
|
uc.cache.WriteValue(ctx, uuidRedisKey, "1", 24*3600)
|
|||
|
|
return &payoutReplyData, nil, 0
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// PayoutBrazil 支付请求
|
|||
|
|
func (uc *EonlineUsecase) PayoutBrazil(ctx context.Context, uuid string, opts *PayoutAddtionalReq, req *PayoutReq) (*PayoutReplyData, error, int32) {
|
|||
|
|
// 定义一个uuid的redis key
|
|||
|
|
keyDay := ""
|
|||
|
|
if uc.conf.Server.Env == "qa" {
|
|||
|
|
ts, _ := strconv.ParseInt(opts.Ts, 10, 64)
|
|||
|
|
keyDay = time.Unix(ts, 0).Format("20060102")
|
|||
|
|
}
|
|||
|
|
uuidRedisKey := GetUuidPayoutRedisKey(uuid, keyDay, opts.ItemId)
|
|||
|
|
// 定义一个uuid的redis lock key, 用于锁定, 防止并发
|
|||
|
|
uuidRedisLockKey := GetUuidLockRedisKey(uuid, keyDay)
|
|||
|
|
lock, _ := uc.cache.RedisLock(ctx, uuidRedisLockKey, 1, 20)
|
|||
|
|
if !lock {
|
|||
|
|
return nil, fmt.Errorf("lock error"), 1
|
|||
|
|
}
|
|||
|
|
defer func() {
|
|||
|
|
uc.cache.RedisUnLock(ctx, uuidRedisLockKey)
|
|||
|
|
}()
|
|||
|
|
|
|||
|
|
country, currentIp := uc.GetCountryCodeByIp(ctx, opts.Ip)
|
|||
|
|
if country != "BR" {
|
|||
|
|
// return nil, fmt.Errorf("Not Brazil")
|
|||
|
|
country = "BR"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
opts.Country = country
|
|||
|
|
opts.Ip = currentIp
|
|||
|
|
|
|||
|
|
// 验证提现是否有效
|
|||
|
|
var err error
|
|||
|
|
var errCode int32
|
|||
|
|
if opts.ItemId == uint32(PayoutItemId4) {
|
|||
|
|
_, err, errCode = uc.checkPayoutValidNew(ctx, uuid, opts)
|
|||
|
|
} else {
|
|||
|
|
_, err, errCode = uc.checkPayoutValid(ctx, uuid, opts)
|
|||
|
|
}
|
|||
|
|
if err != nil {
|
|||
|
|
switch errCode {
|
|||
|
|
case 101:
|
|||
|
|
errCode = 5
|
|||
|
|
case 102:
|
|||
|
|
errCode = 6
|
|||
|
|
case 103:
|
|||
|
|
errCode = 7
|
|||
|
|
case 104:
|
|||
|
|
errCode = 8
|
|||
|
|
case 105:
|
|||
|
|
errCode = 9
|
|||
|
|
case 106:
|
|||
|
|
errCode = 10
|
|||
|
|
case 107:
|
|||
|
|
errCode = 11
|
|||
|
|
case 108:
|
|||
|
|
errCode = 25
|
|||
|
|
case 150:
|
|||
|
|
errCode = 12
|
|||
|
|
default:
|
|||
|
|
log.Infof("checkPayoutValid error: errCode[%d]", errCode)
|
|||
|
|
errCode = 1
|
|||
|
|
}
|
|||
|
|
return nil, err, errCode
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 判断当前用户是否存在
|
|||
|
|
user, err := uc.repo.GetUserByUuid(ctx, uuid)
|
|||
|
|
if err != nil {
|
|||
|
|
return nil, err, 1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 支付的时候需要替换掉country code
|
|||
|
|
req.Country = convertCountry(country)
|
|||
|
|
|
|||
|
|
// 创建提现用户
|
|||
|
|
if user.Id == 0 {
|
|||
|
|
// 记录提现的用户
|
|||
|
|
_, err = uc.repo.CreatePayoutUser(ctx, &PayoutUser{
|
|||
|
|
Uuid: uuid,
|
|||
|
|
DeviceId: opts.DeviceId,
|
|||
|
|
Platform: opts.Platform,
|
|||
|
|
Version: opts.Version,
|
|||
|
|
Country: country,
|
|||
|
|
Ip: opts.Ip,
|
|||
|
|
LoginDays: 1,
|
|||
|
|
})
|
|||
|
|
if err != nil {
|
|||
|
|
return nil, err, 1
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if len(req.ClientData) > 0 {
|
|||
|
|
uc.updateUserClientData(ctx, uuid, req.ClientData)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 记录提现及操作
|
|||
|
|
var payoutReplyData PayoutReplyData
|
|||
|
|
var payoutStatus uint8 // 记录提现状态
|
|||
|
|
err = uc.tx.InTx(ctx, func(ctx context.Context) error {
|
|||
|
|
// 创建提现记录
|
|||
|
|
|
|||
|
|
// 以下参数固定
|
|||
|
|
req.Method = "PIX"
|
|||
|
|
// req.Channel = "PayPal"
|
|||
|
|
req.FeeBear = "merchant" // beneficiary , merchant
|
|||
|
|
// 如果金额大于等于0.3, 收款方承担手续费
|
|||
|
|
if opts.Amount > 0.3 {
|
|||
|
|
req.FeeBear = "beneficiary"
|
|||
|
|
}
|
|||
|
|
req.SourceCurrency = "USD"
|
|||
|
|
req.ArrivalCurrency = "BRL"
|
|||
|
|
reqMd5 := utils.MD5Any(req)
|
|||
|
|
customCode := fmt.Sprintf("PGS_%s", utils.MD5Any(fmt.Sprintf("%s-%d", reqMd5, time.Now().Unix())))
|
|||
|
|
// 类似唯一订单号
|
|||
|
|
req.CustomCode = customCode
|
|||
|
|
|
|||
|
|
record, err := uc.repo.CreatePayoutRecord(ctx, &PayoutRecord{
|
|||
|
|
Uuid: uuid,
|
|||
|
|
Channel: req.Channel,
|
|||
|
|
ItemId: uint(opts.ItemId),
|
|||
|
|
Amount: opts.Amount,
|
|||
|
|
Account: req.Account,
|
|||
|
|
Currency: req.SourceCurrency,
|
|||
|
|
Status: uint8(PayoutStatusPayouting),
|
|||
|
|
RecordNo: req.CustomCode,
|
|||
|
|
Version: opts.Version,
|
|||
|
|
})
|
|||
|
|
if err != nil {
|
|||
|
|
return fmt.Errorf("create payout record error: %v", err)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 第三方提现
|
|||
|
|
x, err := uc.pscli.out.Payout(ctx, req)
|
|||
|
|
if err != nil {
|
|||
|
|
return err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
payoutReplyData = *x
|
|||
|
|
payoutStatus = uint8(PayoutStatusPayouting)
|
|||
|
|
// 等待回调更新状态
|
|||
|
|
err = uc.repo.UpdatePayoutRecordNotify(ctx, payoutReplyData.CustomCode, payoutReplyData.Id, payoutStatus, "")
|
|||
|
|
if err != nil {
|
|||
|
|
return fmt.Errorf("update payout record_%d status error: %v", record.Id, err)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return nil
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
if err != nil {
|
|||
|
|
return nil, err, 1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 记录此次提现,用于判断是否可以继续提现
|
|||
|
|
uc.cache.WriteValue(ctx, uuidRedisKey, "1", 24*3600)
|
|||
|
|
|
|||
|
|
orderId := GetPayoutOrderIdRedisKey(payoutReplyData.Id)
|
|||
|
|
uc.cache.WriteValue(ctx, orderId, uuidRedisKey, 15*3600)
|
|||
|
|
|
|||
|
|
return &payoutReplyData, nil, 0
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// PayoutNotify 支付回调
|
|||
|
|
func (uc *EonlineUsecase) PayoutNotify(ctx context.Context, req *PayoutNotifyReq) error {
|
|||
|
|
value, _ := json.Marshal(req)
|
|||
|
|
fmt.Printf("[%s] payout notify: %s \n", time.Now().Format("2006-01-02 15:04:05"), string(value))
|
|||
|
|
log.Infof("[%s] payout notify: %s \n", time.Now().Format("2006-01-02 15:04:05"), string(value))
|
|||
|
|
err := uc.pscli.out.PayoutNotify(ctx, req)
|
|||
|
|
if err != nil {
|
|||
|
|
return err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 测试用代码
|
|||
|
|
// callTest := func() {
|
|||
|
|
// uuidRedisKey := "pt_6b59480226f21f10a8939807dded2679_20250518_1"
|
|||
|
|
// orderTs := "TS202505080744025sxBs5nA47qPB"
|
|||
|
|
// err = uc.cache.WriteValue(ctx, uuidRedisKey, "1", 24*3600)
|
|||
|
|
// if err != nil {
|
|||
|
|
// err = nil
|
|||
|
|
// }
|
|||
|
|
// orderId := GetPayoutOrderIdRedisKey(orderTs)
|
|||
|
|
// err = uc.cache.WriteValue(ctx, orderId, uuidRedisKey, 15*3600)
|
|||
|
|
// if err != nil {
|
|||
|
|
// err = nil
|
|||
|
|
// }
|
|||
|
|
//
|
|||
|
|
// // 查找删除
|
|||
|
|
// ctx2 := ctx
|
|||
|
|
// orderId = GetPayoutOrderIdRedisKey(orderTs)
|
|||
|
|
// value2, err2 := uc.cache.GetValue(ctx2, orderId)
|
|||
|
|
// if err2 == nil {
|
|||
|
|
// if value2 != "" {
|
|||
|
|
// err2 = uc.cache.DelValue(ctx2, value2)
|
|||
|
|
// if err2 == nil {
|
|||
|
|
// log.Infof("del GetUuidPayoutRedisKey: %s", value2)
|
|||
|
|
//
|
|||
|
|
// err2 = uc.cache.DelValue(ctx2, orderId)
|
|||
|
|
// if err2 == nil {
|
|||
|
|
// log.Infof("del redis key orderId: %s", orderId)
|
|||
|
|
// } else {
|
|||
|
|
// log.Infof("del redis key orderId: %s err[%v]", orderId, err2)
|
|||
|
|
// }
|
|||
|
|
// } else {
|
|||
|
|
// log.Infof("del GetUuidPayoutRedisKey error: %s err[%v]", value2, err2)
|
|||
|
|
// }
|
|||
|
|
// } else {
|
|||
|
|
// log.Infof("GetPayoutOrderIdRedisKey error: key[%s] value2 is null", orderId)
|
|||
|
|
// }
|
|||
|
|
// } else {
|
|||
|
|
// log.Infof("GetPayoutOrderIdRedisKey error: key[%s] err[%v]", orderId, err2)
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
// 判断回调是否有效
|
|||
|
|
_, err = uc.repo.GetPayoutRecordByRecordNo(ctx, req.CustomCode)
|
|||
|
|
if err != nil {
|
|||
|
|
return fmt.Errorf("get payout record error: %v", err)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// callTest()
|
|||
|
|
|
|||
|
|
reportData := GetReportData(req.PayoutId)
|
|||
|
|
|
|||
|
|
// 更新提现记录状态
|
|||
|
|
var payoutStatus uint8
|
|||
|
|
switch req.Status {
|
|||
|
|
case "PAID":
|
|||
|
|
payoutStatus = uint8(PayoutStatusPayouted)
|
|||
|
|
|
|||
|
|
if reportData != nil && reportData.Adjust != nil && reportData.ShuShu != nil {
|
|||
|
|
adjust := GetAdjustData2(reportData.Adjust, "")
|
|||
|
|
shuShu := GetShuShuData2(reportData.ShuShu, "")
|
|||
|
|
SendReport(ctx, adjust, shuShu)
|
|||
|
|
}
|
|||
|
|
case "REJECTED":
|
|||
|
|
payoutStatus = uint8(PayoutStatusPayoutFailed)
|
|||
|
|
|
|||
|
|
ctx2 := ctx
|
|||
|
|
// ctx2 := context.Background()
|
|||
|
|
orderId := GetPayoutOrderIdRedisKey(req.PayoutId)
|
|||
|
|
value2, err2 := uc.cache.GetValue(ctx2, orderId)
|
|||
|
|
if err2 == nil {
|
|||
|
|
if value2 != "" {
|
|||
|
|
err2 = uc.cache.DelValue(ctx2, value2)
|
|||
|
|
if err2 == nil {
|
|||
|
|
log.Infof("del GetUuidPayoutRedisKey: %s", value2)
|
|||
|
|
|
|||
|
|
// err2 = uc.cache.DelValue(ctx2, orderId)
|
|||
|
|
// if err2 == nil {
|
|||
|
|
// log.Infof("del redis key orderId: %s", orderId)
|
|||
|
|
// } else {
|
|||
|
|
// log.Infof("del redis key orderId: %s err[%v]", orderId, err2)
|
|||
|
|
// }
|
|||
|
|
} else {
|
|||
|
|
log.Infof("del GetUuidPayoutRedisKey error: %s err[%v]", value2, err2)
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
log.Infof("GetPayoutOrderIdRedisKey error: key[%s] value2 is null", orderId)
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
log.Infof("GetPayoutOrderIdRedisKey error: key[%s] err[%v]", orderId, err2)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if reportData != nil && reportData.Adjust != nil && reportData.ShuShu != nil {
|
|||
|
|
adjust := GetAdjustData2(reportData.Adjust, req.Msg)
|
|||
|
|
shuShu := GetShuShuData2(reportData.ShuShu, req.Msg)
|
|||
|
|
SendReport(ctx, adjust, shuShu)
|
|||
|
|
}
|
|||
|
|
default:
|
|||
|
|
payoutStatus = uint8(PayoutStatusPayouting)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
err = uc.repo.UpdatePayoutRecordNotify(ctx, req.CustomCode, req.PayoutId, payoutStatus, req.Msg)
|
|||
|
|
if err != nil {
|
|||
|
|
return fmt.Errorf("update payout record status error: %v", err)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// //存入redis给请求提现的用户
|
|||
|
|
// payoutNotifyRedisKey := GetPayoutNotifyRedisKey(req.PayoutId)
|
|||
|
|
|
|||
|
|
// err = uc.cache.WriteValue(ctx, payoutNotifyRedisKey, string(value), 24*3600)
|
|||
|
|
// if err != nil {
|
|||
|
|
// return fmt.Errorf("write redis error: %v", err)
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
return nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// PayoutNotify 支付回调
|
|||
|
|
func (uc *EonlineUsecase) PayoutNotify2(ctx context.Context, req *PayoutNotifyReq) error {
|
|||
|
|
value, _ := json.Marshal(req)
|
|||
|
|
fmt.Printf("[%s] payout notify: %s \n", time.Now().Format("2006-01-02 15:04:05"), string(value))
|
|||
|
|
log.Infof("[%s] payout notify: %s \n", time.Now().Format("2006-01-02 15:04:05"), string(value))
|
|||
|
|
// err := uc.pscli.out.PayoutNotify(ctx, req)
|
|||
|
|
// if err != nil {
|
|||
|
|
// return err
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
// 判断回调是否有效
|
|||
|
|
_, err := uc.repo.GetPayoutRecordByRecordNo(ctx, req.CustomCode)
|
|||
|
|
if err != nil {
|
|||
|
|
return fmt.Errorf("get payout record error: %v", err)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// callTest()
|
|||
|
|
|
|||
|
|
reportData := GetReportData(req.PayoutId)
|
|||
|
|
|
|||
|
|
// 更新提现记录状态
|
|||
|
|
var payoutStatus uint8
|
|||
|
|
switch req.Status {
|
|||
|
|
case "PAID":
|
|||
|
|
payoutStatus = uint8(PayoutStatusPayouted)
|
|||
|
|
|
|||
|
|
if reportData != nil && reportData.Adjust != nil && reportData.ShuShu != nil {
|
|||
|
|
adjust := GetAdjustData2(reportData.Adjust, "")
|
|||
|
|
shuShu := GetShuShuData2(reportData.ShuShu, "")
|
|||
|
|
SendReport(ctx, adjust, shuShu)
|
|||
|
|
}
|
|||
|
|
case "REJECTED":
|
|||
|
|
payoutStatus = uint8(PayoutStatusPayoutFailed)
|
|||
|
|
|
|||
|
|
ctx2 := ctx
|
|||
|
|
// ctx2 := context.Background()
|
|||
|
|
orderId := GetPayoutOrderIdRedisKey(req.PayoutId)
|
|||
|
|
value2, err2 := uc.cache.GetValue(ctx2, orderId)
|
|||
|
|
if err2 == nil {
|
|||
|
|
if value2 != "" {
|
|||
|
|
err2 = uc.cache.DelValue(ctx2, value2)
|
|||
|
|
if err2 == nil {
|
|||
|
|
log.Infof("del GetUuidPayoutRedisKey: %s", value2)
|
|||
|
|
|
|||
|
|
// err2 = uc.cache.DelValue(ctx2, orderId)
|
|||
|
|
// if err2 == nil {
|
|||
|
|
// log.Infof("del redis key orderId: %s", orderId)
|
|||
|
|
// } else {
|
|||
|
|
// log.Infof("del redis key orderId: %s err[%v]", orderId, err2)
|
|||
|
|
// }
|
|||
|
|
} else {
|
|||
|
|
log.Infof("del GetUuidPayoutRedisKey error: %s err[%v]", value2, err2)
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
log.Infof("GetPayoutOrderIdRedisKey error: key[%s] value2 is null", orderId)
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
log.Infof("GetPayoutOrderIdRedisKey error: key[%s] err[%v]", orderId, err2)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if reportData != nil && reportData.Adjust != nil && reportData.ShuShu != nil {
|
|||
|
|
adjust := GetAdjustData2(reportData.Adjust, req.Msg)
|
|||
|
|
shuShu := GetShuShuData2(reportData.ShuShu, req.Msg)
|
|||
|
|
SendReport(ctx, adjust, shuShu)
|
|||
|
|
}
|
|||
|
|
default:
|
|||
|
|
payoutStatus = uint8(PayoutStatusPayouting)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
err = uc.repo.UpdatePayoutRecordNotify(ctx, req.CustomCode, req.PayoutId, payoutStatus, req.Msg)
|
|||
|
|
if err != nil {
|
|||
|
|
return fmt.Errorf("update payout record status error: %v", err)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ParseIp 解析IP
|
|||
|
|
func (uc *EonlineUsecase) ParseIp(ctx context.Context, ip string) (*geo.GeoInfo, error) {
|
|||
|
|
return uc.geocli.Parse(ip)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 通过IP获取对应country code 和 country ip, 如果IP为空,从服务端获取
|
|||
|
|
func (uc *EonlineUsecase) GetCountryCodeByIp(ctx context.Context, ip string) (string, string) {
|
|||
|
|
var country string
|
|||
|
|
var currentIp string
|
|||
|
|
currentIp = ip
|
|||
|
|
// 获取国家
|
|||
|
|
// 强制通过服务端获取IP,不支持客户端传递, QA环境仍然支持客户端传递
|
|||
|
|
if ip == "" || uc.conf.Server.Env != "qa" {
|
|||
|
|
httpCtx := xhttp.RequestFromContext(ctx)
|
|||
|
|
if httpCtx != nil {
|
|||
|
|
// 获取当前的IP地址
|
|||
|
|
currentIp = utils.GetClientPublicIP(httpCtx.Request())
|
|||
|
|
} else {
|
|||
|
|
uc.log.WithContext(ctx).Errorf("get http context error")
|
|||
|
|
return "", ""
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 解析IP地址
|
|||
|
|
geonInfo, err := uc.geocli.Parse(currentIp)
|
|||
|
|
if err != nil {
|
|||
|
|
uc.log.WithContext(ctx).Errorf("parse ip(%s) error: %v", currentIp, err)
|
|||
|
|
return currentIp, ""
|
|||
|
|
}
|
|||
|
|
country = geonInfo.Country.ISOCode
|
|||
|
|
fmt.Println("parse ip success: ", currentIp, country)
|
|||
|
|
return country, currentIp
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// PayoutCheck 检查提现状态
|
|||
|
|
func (uc *EonlineUsecase) PayoutCheck(ctx context.Context, recordNo string) (uint8, error) {
|
|||
|
|
record, err := uc.repo.GetPayoutRecordByRecordNo(ctx, recordNo)
|
|||
|
|
if err != nil {
|
|||
|
|
return 0, err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return record.Status, nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// PayoutCheck 检查提现状态
|
|||
|
|
func (uc *EonlineUsecase) GetPayoutRecordByAccount(ctx context.Context, account string, status, pageIndex, pageSize int) ([]*PayoutRecord, error) {
|
|||
|
|
record, err := uc.repo.GetPayoutRecordByAccountStatus(ctx, account, int(status), int(pageIndex), int(pageSize))
|
|||
|
|
if err != nil {
|
|||
|
|
return nil, err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return record, nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
type SubmitCheckReq struct {
|
|||
|
|
Account string
|
|||
|
|
Uuid string
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
type SubmitCheckReply struct {
|
|||
|
|
Result int32 // 0成功,1失败,2以前提交过,还没审核结果,3以前提交过,并审核通过(以前提交过,但审核失败的,可以继续提交),
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const (
|
|||
|
|
StringNull = "" // 审核无结果
|
|||
|
|
CheckResultFail = "0" // 审核没通过
|
|||
|
|
CheckResultSuccess = "1" // 审核通过
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// 提交审核,0成功,1失败,2以前提交过,还没审核结果,3以前提交过,并审核通过(以前提交过,但审核失败的,可以继续提交),
|
|||
|
|
func (uc *EonlineUsecase) SubmitCheck(ctx context.Context, req *SubmitCheckReq) (*SubmitCheckReply, error) {
|
|||
|
|
reply := &SubmitCheckReply{}
|
|||
|
|
|
|||
|
|
// 查询是否已经提交过
|
|||
|
|
v, err := uc.getCheckSubmit(ctx, req.Account)
|
|||
|
|
if err != nil {
|
|||
|
|
reply.Result = 1
|
|||
|
|
return reply, err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if v == 1 {
|
|||
|
|
// 提交过,检查审核结果
|
|||
|
|
v2, err := uc.getCheckResult(ctx, req.Account)
|
|||
|
|
if err != nil {
|
|||
|
|
reply.Result = 1
|
|||
|
|
return reply, err
|
|||
|
|
}
|
|||
|
|
// 还没审核结果
|
|||
|
|
if v2 == 0 {
|
|||
|
|
reply.Result = 2
|
|||
|
|
return reply, nil
|
|||
|
|
}
|
|||
|
|
// 审核通过的
|
|||
|
|
if v2 == 2 {
|
|||
|
|
reply.Result = 3
|
|||
|
|
return reply, nil
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 检查提交人数
|
|||
|
|
// v3, err := uc.getCheckSubmitNum(ctx)
|
|||
|
|
// _ = v3
|
|||
|
|
|
|||
|
|
// 提交计数
|
|||
|
|
err = uc.increaseCheckSubmitNum(ctx)
|
|||
|
|
if err != nil {
|
|||
|
|
reply.Result = 1
|
|||
|
|
return reply, err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 建立[uuid, paypal]
|
|||
|
|
err = uc.setUuid2Paypal(ctx, req.Account, req.Uuid)
|
|||
|
|
if err != nil {
|
|||
|
|
reply.Result = 1
|
|||
|
|
return reply, err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 不加redis锁,并发写入提交记录,也没什么影响
|
|||
|
|
// 存入redis
|
|||
|
|
key := GetCheckSubmitRedisKey(req.Account)
|
|||
|
|
uc.cache.WriteValue(ctx, key, req.Uuid, 0)
|
|||
|
|
|
|||
|
|
return reply, nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
type CheckInfoReq struct {
|
|||
|
|
Uuid string
|
|||
|
|
Ts string
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
type CheckInfoReply struct {
|
|||
|
|
CanCheckSubmit uint32
|
|||
|
|
CheckSubmit int32
|
|||
|
|
CheckResult int32
|
|||
|
|
CheckPayout int32
|
|||
|
|
CanCheckPayOut int32
|
|||
|
|
CheckResultFailedDesc string
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (uc *EonlineUsecase) CheckInfo(ctx context.Context, req *CheckInfoReq) (*CheckInfoReply, error) {
|
|||
|
|
reply := &CheckInfoReply{}
|
|||
|
|
|
|||
|
|
acc, err := uc.getUuid2Paypal(ctx, req.Uuid)
|
|||
|
|
if err != nil {
|
|||
|
|
return nil, err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if acc == StringNull {
|
|||
|
|
reply.CheckSubmit = 0
|
|||
|
|
reply.CheckResult = 0
|
|||
|
|
reply.CheckPayout = 0
|
|||
|
|
} else {
|
|||
|
|
// 提交身份文件验证情况
|
|||
|
|
v, err := uc.getCheckSubmit(ctx, acc)
|
|||
|
|
if err != nil {
|
|||
|
|
return nil, err
|
|||
|
|
}
|
|||
|
|
if v == 0 {
|
|||
|
|
reply.CheckSubmit = 0
|
|||
|
|
} else {
|
|||
|
|
reply.CheckSubmit = 1
|
|||
|
|
}
|
|||
|
|
// 身份文件审核有反馈的情况
|
|||
|
|
v2, err := uc.getCheckResult(ctx, acc)
|
|||
|
|
if err != nil {
|
|||
|
|
return nil, err
|
|||
|
|
}
|
|||
|
|
if v2 != 0 {
|
|||
|
|
if v2 == 2 {
|
|||
|
|
reply.CheckResult = 2
|
|||
|
|
} else {
|
|||
|
|
reply.CheckResult = 1
|
|||
|
|
|
|||
|
|
reply.CheckResultFailedDesc, err = uc.getCheckResultFailedDesc(ctx, acc)
|
|||
|
|
if err != nil {
|
|||
|
|
return nil, err
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// 提交身份文件奖励5美元领取的情况,0没有提现记录,1提现中,2提现成功,3提现失败
|
|||
|
|
records, err := uc.repo.GetPayoutRecordListByUuid(ctx, req.Uuid)
|
|||
|
|
if err != nil {
|
|||
|
|
return nil, err
|
|||
|
|
}
|
|||
|
|
for _, record := range records {
|
|||
|
|
if record.ItemId == uint(PayoutItemId4) {
|
|||
|
|
switch record.Status {
|
|||
|
|
case uint8(PayoutStatusPayouting):
|
|||
|
|
reply.CheckPayout = 1
|
|||
|
|
case uint8(PayoutStatusPayouted):
|
|||
|
|
reply.CheckPayout = 2
|
|||
|
|
case uint8(PayoutStatusPayoutFailed):
|
|||
|
|
reply.CheckPayout = 3
|
|||
|
|
}
|
|||
|
|
break
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获得当前提交审核计数
|
|||
|
|
v3, err := uc.getCheckSubmitNum(ctx)
|
|||
|
|
if err != nil {
|
|||
|
|
return nil, err
|
|||
|
|
}
|
|||
|
|
reply.CanCheckSubmit = v3
|
|||
|
|
log.Infof("CheckInfo: getCheckSubmitNum[%d]", v3)
|
|||
|
|
|
|||
|
|
if reply.CanCheckSubmit < config.PublicCheckNum {
|
|||
|
|
reply.CanCheckSubmit = 1
|
|||
|
|
} else {
|
|||
|
|
reply.CanCheckSubmit = 0
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var resultTixian int
|
|||
|
|
reply.CanCheckPayOut = 1 // 身份文件审核过的提现奖励5美元 能否 提现,0能提现,1条件不满足,不能提现,2当天已经提现过,不能再次提现
|
|||
|
|
if reply.CheckSubmit == 1 && reply.CheckResult == 2 && reply.CheckPayout == 0 {
|
|||
|
|
resultTixian, err = uc.GetCashStatus(ctx, req.Uuid, req.Ts, uint32(PayoutItemId4))
|
|||
|
|
if err != nil {
|
|||
|
|
return nil, fmt.Errorf("error: %w", err)
|
|||
|
|
}
|
|||
|
|
if resultTixian == 1 {
|
|||
|
|
reply.CanCheckPayOut = 2
|
|||
|
|
} else {
|
|||
|
|
reply.CanCheckPayOut = 0
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return reply, nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获取已经提交身份审核计数
|
|||
|
|
func (uc *EonlineUsecase) getCheckSubmitNum(ctx context.Context) (uint32, error) {
|
|||
|
|
key := GetCheckSubmitNumRedisKey()
|
|||
|
|
v, err := uc.cache.GetValue(ctx, key)
|
|||
|
|
if err != nil {
|
|||
|
|
return 0, err
|
|||
|
|
}
|
|||
|
|
if v == StringNull {
|
|||
|
|
return 0, nil
|
|||
|
|
} else {
|
|||
|
|
x, err := strconv.Atoi(v)
|
|||
|
|
if err != nil {
|
|||
|
|
return 0, err
|
|||
|
|
}
|
|||
|
|
return uint32(x), nil
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 提交身份审核计数 自增
|
|||
|
|
func (uc *EonlineUsecase) increaseCheckSubmitNum(ctx context.Context) error {
|
|||
|
|
key := GetCheckSubmitNumRedisKey()
|
|||
|
|
v, err := uc.cache.GetValue(ctx, key)
|
|||
|
|
if err != nil {
|
|||
|
|
return err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var x int
|
|||
|
|
if v != StringNull {
|
|||
|
|
x, err = strconv.Atoi(v)
|
|||
|
|
if err != nil {
|
|||
|
|
return err
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
err = uc.cache.WriteValue(ctx, key, x+1, 0)
|
|||
|
|
if err != nil {
|
|||
|
|
return err
|
|||
|
|
}
|
|||
|
|
return nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 提交身份文件验证情况,0没有提交,1提交过
|
|||
|
|
func (uc *EonlineUsecase) getCheckSubmit(ctx context.Context, account string) (int32, error) {
|
|||
|
|
key := GetCheckSubmitRedisKey(account)
|
|||
|
|
v, err := uc.cache.GetValue(ctx, key)
|
|||
|
|
if err != nil {
|
|||
|
|
return 0, err
|
|||
|
|
}
|
|||
|
|
if v == StringNull {
|
|||
|
|
return 0, nil
|
|||
|
|
} else {
|
|||
|
|
return 1, nil
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 身份文件审核有反馈的情况,0没有记录,1审核没通过,2审核通过
|
|||
|
|
func (uc *EonlineUsecase) getCheckResult(ctx context.Context, account string) (int32, error) {
|
|||
|
|
key := GetCheckResultRedisKey(account)
|
|||
|
|
v, err := uc.cache.GetValue(ctx, key)
|
|||
|
|
if err != nil {
|
|||
|
|
return 0, err
|
|||
|
|
}
|
|||
|
|
if v == StringNull {
|
|||
|
|
return 0, nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if v == CheckResultSuccess {
|
|||
|
|
return 2, nil
|
|||
|
|
} else {
|
|||
|
|
return 1, nil
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 提交身份文件奖励5美元领取的情况,0没有领取记录,1有领取记录
|
|||
|
|
func (uc *EonlineUsecase) getCheckPayout(ctx context.Context, account string) (int32, error) {
|
|||
|
|
return 0, nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 存储[uuid, paypal]
|
|||
|
|
func (uc *EonlineUsecase) setUuid2Paypal(ctx context.Context, account, uuid string) error {
|
|||
|
|
key := GetUuid2PaypalRedisKey(uuid)
|
|||
|
|
err := uc.cache.WriteValue(ctx, key, account, 0)
|
|||
|
|
if err != nil {
|
|||
|
|
return err
|
|||
|
|
}
|
|||
|
|
return nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 根据uuid获取paypal
|
|||
|
|
func (uc *EonlineUsecase) getUuid2Paypal(ctx context.Context, uuid string) (string, error) {
|
|||
|
|
key := GetUuid2PaypalRedisKey(uuid)
|
|||
|
|
v, err := uc.cache.GetValue(ctx, key)
|
|||
|
|
if err != nil {
|
|||
|
|
return StringNull, err
|
|||
|
|
}
|
|||
|
|
return v, nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 查询当天是否有提现记录,0没有,1有
|
|||
|
|
func (uc *EonlineUsecase) GetCashStatus(ctx context.Context, uuid, ts string, itemId uint32) (int, error) {
|
|||
|
|
keyDay := ""
|
|||
|
|
if uc.conf.Server.Env == "qa" {
|
|||
|
|
ts, _ := strconv.ParseInt(ts, 10, 64)
|
|||
|
|
keyDay = time.Unix(ts, 0).Format("20060102")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uuidRedisKey := GetUuidPayoutRedisKey(uuid, keyDay, itemId)
|
|||
|
|
value, err := uc.cache.GetValue(ctx, uuidRedisKey)
|
|||
|
|
if err != nil {
|
|||
|
|
return 0, err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if value != "" {
|
|||
|
|
return 1, nil
|
|||
|
|
}
|
|||
|
|
return 0, nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获取审核没通过的原因描述信息
|
|||
|
|
func (uc *EonlineUsecase) getCheckResultFailedDesc(ctx context.Context, account string) (string, error) {
|
|||
|
|
key := GetCheckResultFailRedisKey(account)
|
|||
|
|
v, err := uc.cache.GetValue(ctx, key)
|
|||
|
|
if err != nil {
|
|||
|
|
return "", err
|
|||
|
|
}
|
|||
|
|
return v, nil
|
|||
|
|
}
|