| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- package daytask
- import (
- "app/commons/model/entity"
- "app/commons/services"
- "encoding/json"
- "fmt"
- "github.com/gin-gonic/gin"
- "time"
- )
- // WalletInfo 钱包信息
- func (s *Server) WalletInfo(c *gin.Context) {
- ctx := s.FromContext(c)
- db := s.DB()
- userId := ctx.UserId()
- user := &entity.DtUser{}
- if err := db.Where("id = ?", userId).First(user).Error; err != nil {
- ctx.Fail("user_not_found")
- return
- }
- ctx.OK(gin.H{
- "balance": user.Balance,
- "frozenBalance": user.FrozenBalance,
- "totalRecharge": user.TotalRecharge,
- "totalWithdraw": user.TotalWithdraw,
- "totalTaskIncome": user.TotalTaskIncome,
- "totalInviteIncome": user.TotalInviteIncome,
- })
- }
- // BalanceLog 余额流水
- func (s *Server) BalanceLog(c *gin.Context) {
- ctx := s.FromContext(c)
- db := s.DB()
- userId := ctx.UserId()
- logType := ctx.QueryInt64("type", 0) // 0表示全部
- paging := &services.Pagination{
- Current: ctx.QueryInt64("current", 1),
- Size: ctx.QueryInt64("size", 20),
- }
- query := db.Model(&entity.DtBalanceLog{}).Where("user_id = ?", userId)
- if logType > 0 {
- query = query.Where("type = ?", logType)
- }
- query.Count(&paging.Total)
- paging.Computer()
- logs := make([]*entity.DtBalanceLog, 0)
- query.Order("created_at DESC").
- Offset(int(paging.Start)).
- Limit(int(paging.Size)).
- Find(&logs)
- ctx.OK(gin.H{
- "list": logs,
- "paging": paging,
- })
- }
- // WalletWithdraw 申请提现
- func (s *Server) WalletWithdraw(c *gin.Context) {
- ctx := s.FromContext(c)
- db := s.DB()
- userId := ctx.UserId()
- type WithdrawRequest struct {
- Amount float64 `json:"amount" binding:"required"`
- PaymentId int64 `json:"paymentId" binding:"required"`
- }
- var req WithdrawRequest
- if err := c.ShouldBindJSON(&req); err != nil {
- ctx.Fail("invalid_params")
- return
- }
- // 获取用户
- user := &entity.DtUser{}
- if err := db.Where("id = ?", userId).First(user).Error; err != nil {
- ctx.Fail("user_not_found")
- return
- }
- // 检查余额
- if user.Balance < req.Amount {
- ctx.Fail("balance_not_enough")
- return
- }
- // 获取最低提现金额配置
- minWithdraw := 100.0 // 默认100
- config := &entity.DtConfig{}
- if err := db.Where("`key` = ?", "min_withdraw").First(config).Error; err == nil {
- fmt.Sscanf(config.Value, "%f", &minWithdraw)
- }
- if req.Amount < minWithdraw {
- ctx.Fail("amount_too_small")
- return
- }
- // 检查金额是否是10的倍数
- if int(req.Amount)%10 != 0 {
- ctx.Fail("amount_must_be_multiple_of_10")
- return
- }
- // 获取收款账户
- payment := &entity.DtUserPayment{}
- if err := db.Where("id = ? AND user_id = ?", req.PaymentId, userId).First(payment).Error; err != nil {
- ctx.Fail("payment_not_found")
- return
- }
- // 获取手续费率
- feeRate := 0.02 // 默认2%
- feeConfig := &entity.DtConfig{}
- if err := db.Where("`key` = ?", "withdraw_fee").First(feeConfig).Error; err == nil {
- fmt.Sscanf(feeConfig.Value, "%f", &feeRate)
- }
- fee := req.Amount * feeRate
- actualAmount := req.Amount - fee
- // 生成订单号
- orderNo := fmt.Sprintf("W%d%d", time.Now().UnixNano(), userId)
- // 序列化收款账户信息
- paymentInfo, _ := json.Marshal(payment)
- // 开始事务
- tx := db.Begin()
- // 扣除余额(原子操作 + 检查影响行数)
- result := tx.Model(&entity.DtUser{}).
- Where("id = ? AND balance >= ?", userId, req.Amount).
- Update("balance", tx.Raw("balance - ?", req.Amount))
- if result.Error != nil {
- tx.Rollback()
- ctx.Fail("deduct_balance_failed")
- return
- }
- if result.RowsAffected == 0 {
- tx.Rollback()
- ctx.Fail("balance_not_enough")
- return
- }
- // 重新查询扣款后的余额
- var updatedUser entity.DtUser
- tx.Where("id = ?", userId).First(&updatedUser)
- // 创建提现订单
- order := &entity.DtWithdrawOrder{
- OrderNo: orderNo,
- UserId: userId,
- Amount: req.Amount,
- Fee: fee,
- ActualAmount: actualAmount,
- PaymentType: payment.Type,
- PaymentId: payment.Id,
- PaymentInfo: string(paymentInfo),
- Status: entity.WithdrawStatusPending,
- }
- if err := tx.Create(order).Error; err != nil {
- tx.Rollback()
- ctx.Fail("create_order_failed")
- return
- }
- // 记录余额变动
- balanceLog := &entity.DtBalanceLog{
- UserId: userId,
- Type: entity.BalanceLogTypeWithdraw,
- Amount: -req.Amount,
- BeforeBalance: updatedUser.Balance + req.Amount,
- AfterBalance: updatedUser.Balance,
- RelatedId: order.Id,
- Remark: fmt.Sprintf("%s %s", ctx.I18n("withdraw_apply"), orderNo),
- }
- tx.Create(balanceLog)
- tx.Commit()
- ctx.OK(order)
- }
- // WithdrawConfig 提现配置
- func (s *Server) WithdrawConfig(c *gin.Context) {
- ctx := s.FromContext(c)
- db := s.DB()
- // 获取最低提现金额
- minWithdraw := 100.0
- minConfig := &entity.DtConfig{}
- if err := db.Where("`key` = ?", "min_withdraw").First(minConfig).Error; err == nil {
- fmt.Sscanf(minConfig.Value, "%f", &minWithdraw)
- }
- // 获取手续费率
- feeRate := 0.02
- feeConfig := &entity.DtConfig{}
- if err := db.Where("`key` = ?", "withdraw_fee").First(feeConfig).Error; err == nil {
- fmt.Sscanf(feeConfig.Value, "%f", &feeRate)
- }
- // 获取最大提现金额
- maxWithdraw := 50000.0
- maxConfig := &entity.DtConfig{}
- if err := db.Where("`key` = ?", "max_withdraw").First(maxConfig).Error; err == nil {
- fmt.Sscanf(maxConfig.Value, "%f", &maxWithdraw)
- }
- ctx.OK(gin.H{
- "minAmount": minWithdraw,
- "maxAmount": maxWithdraw,
- "feeRate": feeRate,
- "multiple": 10, // 提现金额必须是10的倍数
- })
- }
- // WithdrawLog 提现记录
- func (s *Server) WithdrawLog(c *gin.Context) {
- ctx := s.FromContext(c)
- db := s.DB()
- userId := ctx.UserId()
- status := ctx.QueryInt64("status", -99) // -99表示全部
- paging := &services.Pagination{
- Current: ctx.QueryInt64("current", 1),
- Size: ctx.QueryInt64("size", 20),
- }
- query := db.Model(&entity.DtWithdrawOrder{}).Where("user_id = ?", userId)
- if status != -99 {
- query = query.Where("status = ?", status)
- }
- query.Count(&paging.Total)
- paging.Computer()
- orders := make([]*entity.DtWithdrawOrder, 0)
- query.Order("created_at DESC").
- Offset(int(paging.Start)).
- Limit(int(paging.Size)).
- Find(&orders)
- ctx.OK(gin.H{
- "list": orders,
- "paging": paging,
- })
- }
|