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(), ¶ms) 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 }