You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

564 lines
16 KiB

package service
import (
"context"
"encoding/json"
"errors"
"fmt"
"gorm.io/gorm"
"pure-admin/global"
"pure-admin/initialize/api"
"pure-admin/model"
"pure-admin/model/request"
"pure-admin/model/response"
"pure-admin/utils"
"time"
)
func GetBillData(platform string, info *request.BillSearch) (error, response.BillData) {
var (
err error
money float64
total int64
result response.BillData
)
info.Status = 1
_, money, total = getBillAmount(platform, info)
result.Income = money
result.IncomeCount = total
info.Status = 2
_, money, total = getBillAmount(platform, info)
result.Expend = money
result.ExpendCount = total
return err, result
}
func getBillAmount(platform string, info *request.BillSearch) (error, float64, int64) {
var (
err error
result float64
total int64
)
db := global.MG_DB.Model(&model.Bill{})
if platform != "" {
db = db.Where("platform = ?", platform)
}
if info.StartTime != "" {
db = db.Where("created_at >= ?", info.StartTime)
}
if info.EndTime != "" {
if len(info.EndTime) == 10 {
tmp, _ := time.ParseInLocation(utils.DateFormat, info.EndTime, time.Local)
info.EndTime = tmp.AddDate(0, 0, 1).Format(utils.DateFormat)
}
db = db.Where("created_at < ?", info.EndTime)
}
if info.Status != 0 {
db = db.Where("`status` = ?", info.Status)
}
if info.Receipt != 0 {
db = db.Where("receipt = ?", info.Receipt)
}
_ = db.Count(&total).Error
err = db.Select("IFNULL(SUM(`price`),0)").Scan(&result).Error
if err != nil {
return errors.New("获取失败"), result, total
}
return nil, result, total
}
func GetBillList(platform string, info *request.BillSearch) (error, []model.BillList, int64) {
var (
err error
total int64
result []model.BillList
)
limit := info.PageSize
offset := info.PageSize * (info.Page - 1)
db := global.MG_DB.Model(&model.Bill{})
if platform != "" {
db = db.Where("platform = ?", platform)
}
if info.StartTime != "" {
db = db.Where("created_at >= ?", info.StartTime)
}
if info.EndTime != "" {
if len(info.EndTime) == 10 {
tmp, _ := time.ParseInLocation(utils.DateFormat, info.EndTime, time.Local)
info.EndTime = tmp.AddDate(0, 0, 1).Format(utils.DateFormat)
}
db = db.Where("created_at < ?", info.EndTime)
}
if info.Status != 0 {
db = db.Where("`status` = ?", info.Status)
}
if info.Receipt != 0 {
db = db.Where("receipt = ?", info.Receipt)
}
_ = db.Count(&total).Error
err = db.Select("id,user_id,title,order_id,price,`status`,remark,platform,transaction_id,created_at,updated_at").Order("id desc").Offset(offset).Limit(limit).Find(&result).Error
if err != nil {
return errors.New("获取失败"), result, total
}
var (
uuids []string
userMap map[string]model.UserView
)
for _, bill := range result {
uuids = append(uuids, bill.UserID)
}
userMap, err = getUserViewMap(uuids...)
if err != nil {
return errors.New("get user info fail"), result, total
}
for i := 0; i < len(result); i++ {
if val, ok := userMap[result[i].UserID]; ok {
result[i].User = val
}
}
return err, result, total
}
func GetInfluenceWithdrawalData(info *request.WithdrawalSearch) (error, response.InfluenceWithdrawalData) {
var (
err error
money float64
total int64
result response.InfluenceWithdrawalData
)
// 网红账户总额
_ = global.MG_DB.Model(&model.Wallet{}).Where("platform = 'influencer'").Select("IFNULL(SUM(`balance`),0)").Scan(&result.Balance).Error
_, money, total = getWithdrawalAmount("1", info)
result.Unexamined = money
result.UnexaminedCount = total
return err, result
}
func getWithdrawalAmount(platform string, info *request.WithdrawalSearch) (error, float64, int64) {
var (
err error
result float64
total int64
)
db := global.MG_DB.Model(&model.Withdrawal{})
if platform != "" {
db = db.Where("platform = ?", platform)
}
if info.StartTime != "" {
db = db.Where("created_at >= ?", info.StartTime)
}
if info.EndTime != "" {
if len(info.EndTime) == 10 {
tmp, _ := time.ParseInLocation(utils.DateFormat, info.EndTime, time.Local)
info.EndTime = tmp.AddDate(0, 0, 1).Format(utils.DateFormat)
}
db = db.Where("created_at < ?", info.EndTime)
}
if info.CheckStatus != "" {
db = db.Where("check_status = ?", info.CheckStatus)
}
_ = db.Count(&total).Error
err = db.Select("IFNULL(SUM(`amount`),0)").Scan(&result).Error
if err != nil {
return errors.New("获取失败"), result, total
}
return nil, result, total
}
func GetWithdrawalList(platform string, info *request.WithdrawalSearch) (error, []model.Withdrawal, int64) {
var (
err error
total int64
result []model.Withdrawal
)
limit := info.PageSize
offset := info.PageSize * (info.Page - 1)
db := global.MG_DB.Model(&model.Withdrawal{})
if platform != "" {
db = db.Where("platform = ?", platform)
}
if info.StartTime != "" {
db = db.Where("created_at >= ?", info.StartTime)
}
if info.EndTime != "" {
if len(info.EndTime) == 10 {
tmp, _ := time.ParseInLocation(utils.DateFormat, info.EndTime, time.Local)
info.EndTime = tmp.AddDate(0, 0, 1).Format(utils.DateFormat)
}
db = db.Where("created_at < ?", info.EndTime)
}
if info.CheckStatus != "" {
db = db.Where("check_status = ?", info.CheckStatus)
}
_ = db.Count(&total).Error
err = db.Order("id desc").Offset(offset).Limit(limit).Find(&result).Error
if err != nil {
return errors.New("获取失败"), result, total
}
return err, result, total
}
func ExamineWithdrawal(platform string, info *request.ExamineWithdrawal) error {
var (
err error
withdrawal model.Withdrawal
notifyContent string
)
err = global.MG_DB.Model(&model.Withdrawal{}).Where("platform = ? AND flow_no = ?", platform, info.FlowNo).First(&withdrawal).Error
if err != nil {
return err
}
if withdrawal.CheckStatus != "0" || withdrawal.Status != "0" {
return errors.New("withdrawal reply status error")
}
tx := global.MG_DB.Begin()
if info.CheckStatus == "1" { // 审核通过
err = tx.Model(&model.Withdrawal{}).Where("id = ?", withdrawal.ID).Updates(map[string]interface{}{"check_status": info.CheckStatus, "check_time": time.Now()}).Error
if err != nil {
tx.Rollback()
return err
}
notifyContent = "您的提现申请已通过!"
} else if info.CheckStatus == "2" { // 审核不通过
err = tx.Model(&model.Withdrawal{}).Where("id = ?", withdrawal.ID).Updates(map[string]interface{}{"check_status": info.CheckStatus, "remark": info.Remark, "check_time": time.Now()}).Error
if err != nil {
tx.Rollback()
return err
}
notifyContent = "您的提现申请未通过!"
} else {
tx.Rollback()
return errors.New("check status error")
}
// 更改申请账号钱包状态
err = tx.Model(&model.Wallet{}).Where("user_id = ?", withdrawal.CreateBy).UpdateColumn("state", "0").Error
if err != nil {
tx.Rollback()
return errors.New("update wallet state error")
}
tx.Commit()
if platform == "influencer" {
// 发送消息
_ = createOrUpdateNotify(request.CreateNotify{
UserId: withdrawal.CreateBy,
RelationType: "1",
RelationId: withdrawal.FlowNo,
Title: notifyContent,
})
}
return err
}
func UpdateWithdrawalStatus(info *request.TransferResult) error {
// 开始交易
for {
ok, err := global.MG_REDIS.SetNX("withdrawal-"+info.FlowNo, "used", 10*time.Second).Result()
if ok && err == nil {
// 获取成功
break
}
}
defer func() {
// 释放锁
_, _ = utils.RedisDel("withdrawal-" + info.FlowNo)
}()
var (
err error
notifyContent string
withdrawal model.Withdrawal
)
err = global.MG_DB.Model(&model.Withdrawal{}).Where("flow_no = ?", info.FlowNo).First(&withdrawal).Error
if err != nil {
return err
}
if withdrawal.Status != "0" {
err = errors.New("repeat operation")
return err
}
tx := global.MG_DB.Begin()
err = tx.Model(&model.Withdrawal{}).Where("id = ?", withdrawal.ID).UpdateColumns(map[string]interface{}{"status": info.Status, "remark": info.Remark}).Error
if err != nil {
tx.Rollback()
return err
}
// 恢复网红用户钱包状态
if withdrawal.Platform == "1" {
err = tx.Model(&model.Wallet{}).Where("user_id = ?", withdrawal.CreateBy).UpdateColumn("state", "0").Error
if err != nil {
tx.Rollback()
return err
}
}
if info.Status == "1" {
notifyContent = "您的提现申请已通过!"
} else { // 审核不通过,将金额返还至用户余额
notifyContent = "您的提现申请未通过!"
err = tx.Model(&model.Wallet{}).Where("user_id = ?", withdrawal.CreateBy).UpdateColumn("balance", gorm.Expr("balance + ?", withdrawal.Amount)).Error
if err != nil {
tx.Rollback()
return err
}
}
tx.Commit()
if withdrawal.Platform == "1" {
// 发送消息
_ = createOrUpdateNotify(request.CreateNotify{
UserId: withdrawal.CreateBy,
RelationType: "1",
RelationId: withdrawal.FlowNo,
Title: notifyContent,
})
}
return err
}
//func TransferWithdrawalRetry(platform string, info *request.RetryWithdrawal) error {
// var (
// err error
// transfer request.TransferWithdrawal
// withdrawal model.Withdrawal
// )
// err = global.MG_DB.Model(&model.Withdrawal{}).Where("platform = ? AND flow_no = ?", platform, info.FlowNo).First(&withdrawal).Error
// if err != nil {
// return err
// }
// if withdrawal.CheckStatus != "1" || withdrawal.Status != "2" {
// return errors.New("withdrawal reply status error")
// }
// transfer.AccountType = withdrawal.AccountType
// transfer.AccountName = withdrawal.Account
// transfer.Account = withdrawal.Account
// transfer.Amount = withdrawal.Amount
// transfer.FlowNo = withdrawal.FlowNo
// err, payout := transferWithdrawal(&transfer)
// err = global.MG_DB.Model(&model.Withdrawal{}).Where("id = ?", withdrawal.ID).UpdateColumn("pay_id", payout.PayId).Error
// if err != nil {
// return err
// }
// return err
//}
func transferWithdrawal(info *request.TransferWithdrawal) (error, *api.PayUrlResponse) {
var err error
attach, _ := json.Marshal(map[string]string{"transactionId": info.FlowNo})
params := api.PayoutRequest{
Appid: "bkb5918273465092837",
Mchid: "11000001",
OutTradeNo: info.FlowNo,
Attach: string(attach),
NotifyUrl: global.MG_CONFIG.Paypal.NotifyUrl + "/base/payment/payback",
Amount: info.Amount,
Currency: "USD",
PayChannel: info.AccountType,
PaypalName: info.AccountName,
}
payoutOrder, err := global.PAY_CLIENT.PayoutsAppUrl(context.Background(), &params)
if err != nil {
fmt.Println(err.Error())
return errors.New("open " + info.AccountType + " failed"), nil
}
return err, payoutOrder
}
func GetSellerWithdrawalData(info *request.WithdrawalSearch) (error, response.SellerWithdrawalData) {
var (
err error
money float64
total int64
result response.SellerWithdrawalData
)
_ = global.MG_DB.Model(&model.Wallet{}).Where("platform = 'seller'").Select("IFNULL(SUM(`balance`),0)").Scan(&result.Balance).Error
_ = global.MG_DB.Model(&model.Wallet{}).Where("platform = 'seller'").Select("IFNULL(SUM(`fund`),0)").Scan(&result.Fund).Error
_, money, total = getWithdrawalAmount("2", info)
result.Unexamined = money
result.UnexaminedCount = total
return err, result
}
func getBillFundAmount(platform string, info *request.BillFundSearch) (error, float64, int64) {
var (
err error
result float64
total int64
)
db := global.MG_DB.Model(&model.BillFund{})
if platform != "" {
db = db.Where("platform = ?", platform)
}
if info.UserID != "" {
db = db.Where("user_id = ?", info.UserID)
}
if info.TransactionType != 0 {
db = db.Where("transaction_type = ?", info.TransactionType)
}
if info.StartTime != "" {
db = db.Where("created_at >= ?", info.StartTime)
}
if info.EndTime != "" {
if len(info.EndTime) == 10 {
tmp, _ := time.ParseInLocation(utils.DateFormat, info.EndTime, time.Local)
info.EndTime = tmp.AddDate(0, 0, 1).Format(utils.DateFormat)
}
db = db.Where("created_at < ?", info.EndTime)
}
if info.Status != 0 {
db = db.Where("`status` = ?", info.Status)
}
_ = db.Count(&total).Error
err = db.Select("SUM(`price`)").Scan(&result).Error
if err != nil {
return errors.New("获取失败"), result, total
}
return nil, result, total
}
func GetSellerFundData(info *request.BillFundSearch) (error, response.SellerFundData) {
var (
err error
money float64
total int64
result response.SellerFundData
)
_, money, total = getBillFundAmount("seller", info)
result.Expend = money
result.ExpendCount = total
_, money, total = getMissionFundLockAmount(&request.SearchMissionFund{})
result.Lock = money
result.LockCount = total
return err, result
}
func GetSellerFundList(platform string, info *request.BillFundSearch) (error, []model.SellerBillFund, int64) {
var (
err error
total int64
billFundList []model.BillFund
result []model.SellerBillFund
)
err, billFundList, total = getBillFundList(platform, info)
if err != nil {
return err, result, 0
}
var (
sellerIds []string
claimNos []string
)
for i := 0; i < len(billFundList); i++ {
sellerIds = append(sellerIds, billFundList[i].UserID)
claimNos = append(claimNos, billFundList[i].RelatedId)
result = append(result, model.SellerBillFund{
UserID: billFundList[i].UserID,
TransactionType: billFundList[i].TransactionType,
TransactionId: billFundList[i].TransactionId,
Price: billFundList[i].Price,
Remark: billFundList[i].Remark,
RelatedId: billFundList[i].RelatedId,
Status: billFundList[i].Status,
MG_MODEL: billFundList[i].MG_MODEL,
})
}
storeMap, _ := getSellerStoreMap(sellerIds)
claimMap, _ := getMissionClaimViewMap(claimNos)
for i := 0; i < len(result); i++ {
if val, ok := storeMap[result[i].UserID]; ok {
result[i].Seller = val
}
if val, ok := claimMap[result[i].RelatedId]; ok {
result[i].Mission = val
}
}
return err, result, total
}
func getBillFundList(platform string, info *request.BillFundSearch) (error, []model.BillFund, int64) {
var (
err error
total int64
result []model.BillFund
)
limit := info.PageSize
offset := info.PageSize * (info.Page - 1)
db := global.MG_DB.Model(&model.BillFund{})
if platform != "" {
db = db.Where("platform = ?", platform)
}
if info.StartTime != "" {
db = db.Where("created_at >= ?", info.StartTime)
}
if info.EndTime != "" {
if len(info.EndTime) == 10 {
tmp, _ := time.ParseInLocation(utils.DateFormat, info.EndTime, time.Local)
info.EndTime = tmp.AddDate(0, 0, 1).Format(utils.DateFormat)
}
db = db.Where("created_at < ?", info.EndTime)
}
if info.Status != 0 {
db = db.Where("`status` = ?", info.Status)
}
_ = db.Count(&total).Error
err = db.Order("id desc").Offset(offset).Limit(limit).Find(&result).Error
if err != nil {
return errors.New("获取失败"), result, total
}
return err, result, total
}
func GetBkbWithdrawalData(info *request.WithdrawalSearch) (error, response.BkbData) {
var (
err error
money float64
total int64
result response.BkbData
)
_, money, total = getWithdrawalAmount("", info)
result.Unexamined = money
result.UnexaminedCount = total
return err, result
}
func GetBkbFundData(info *request.BillFundSearch) (error, response.AdminFundData) {
var (
err error
money float64
total int64
result response.AdminFundData
)
info.TransactionType = 1
_, money, total = getBillFundAmount("bkb", info)
result.Expend = money
result.ExpendCount = total
info.TransactionType = 2
_, money, total = getBillFundAmount("bkb", info)
result.Recharge = money
result.RechargeCount = total
return err, result
}
func GetBkbFundList(platform string, info *request.BillFundSearch) (error, []model.AdminBillFund, int64) {
var (
err error
total int64
billFundList []model.BillFund
result []model.AdminBillFund
)
err, billFundList, total = getBillFundList(platform, info)
if err != nil {
return err, result, 0
}
for i := 0; i < len(billFundList); i++ {
result = append(result, model.AdminBillFund{
UserID: billFundList[i].UserID,
TransactionType: billFundList[i].TransactionType,
TransactionId: billFundList[i].TransactionId,
Price: billFundList[i].Price,
Remark: billFundList[i].Remark,
RelatedId: billFundList[i].RelatedId,
Status: billFundList[i].Status,
MG_MODEL: billFundList[i].MG_MODEL,
})
}
return err, result, total
}