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.

239 lines
6.4 KiB

package wallet
import (
"math"
"recook/internal/back"
"recook/internal/dbc"
"recook/internal/model/user"
"recook/internal/service/comFunc"
user2 "recook/internal/v2/model/recook/user"
"recook/tools"
"strconv"
"strings"
"time"
"github.com/gin-gonic/gin"
"github.com/shopspring/decimal"
)
func QueryCoinList(c *gin.Context) {
var p queryWalletCoinParam
err := tools.ParseParams(&p, c)
if err != nil {
back.Fail(c, err.Error())
return
}
if p.UserID == 0 {
back.Suc(c, "", gin.H{
"coin_number": 0,
"list": []user.WalletCoinList{},
})
return
}
var wallet user.Wallet
dbc.DB.Select("coin").First(&wallet, "user_id = ?", p.UserID)
list := make([]user.WalletCoinList, 0)
dbc.DB.Select("number,title,comment,order_id,created_at").Limit(20).Offset(p.Page*20).Order("id desc").Find(&list, "user_id = ?", p.UserID)
back.Suc(c, "", gin.H{
"coin_number": wallet.Coin,
"list": list,
})
}
type coinToBalanceReq struct {
UserID uint `json:"userId" validate:"numeric"`
CoinNum decimal.Decimal `json:"coinNum" validate:"numeric,min=1"`
}
// 将瑞币转为余额
func CoinToBalance(c *gin.Context) {
var p coinToBalanceReq
err := tools.ParseParams(&p, c)
if err != nil {
back.Fail(c, err.Error())
return
}
var wallet user.Wallet
tx := dbc.DB.Begin()
// 锁定单条数据
tx.Raw("SELECT * FROM recook_user_wallet WHERE (user_id =" + strconv.Itoa(int(p.UserID)) + ") for update").Scan(&wallet)
if wallet.Coin.LessThan(p.CoinNum) {
tx.Rollback()
back.Fail(c, "瑞币余额不足")
return
}
// 瑞币转入记录
var coinHis user.CoinHistory
coinHis.CoinNum = p.CoinNum.Neg()
coinHis.CoinType = user.TransferTypeForCoinHistory
coinHis.UserID = p.UserID
if err := dbc.DB.Save(&coinHis).Error; err != nil {
tx.Rollback()
back.Fail(c, "操作失败"+err.Error())
return
}
// 修改总金额
wallet.Coin = wallet.Coin.Sub(p.CoinNum)
wallet.Balance = wallet.Balance.Add(p.CoinNum)
err = tx.Model(&wallet).Update(user.Wallet{Coin: wallet.Coin, Balance: wallet.Balance}).Error
//err = tx.Save(&wallet).Error
if err != nil {
tx.Rollback()
back.Fail(c, "操作失败"+err.Error())
return
}
recookUserWalletBalanceListModel := &user2.RecookUserWalletBalanceListModel{
UserId: wallet.UserID,
IncomeType: user2.RecookUserWalletBalanceListIncomeTypeTransfer, // 瑞币转入
Amount: p.CoinNum,
Comment: "瑞币转入",
}
recookUserWalletBalanceListModel.SetDb(tx)
recookUserWalletBalanceListModel.Create(recookUserWalletBalanceListModel)
if recookUserWalletBalanceListModel.Id == 0 {
back.Err(c, "系统异常")
tx.Rollback()
return
}
tx.Commit()
back.Suc(c, "操作成功", nil)
return
}
type queryCoinReq struct {
UserID uint `json:"userId" validate:"required,numeric"`
Date string `json:"date" validate:"required"`
CoinType string `json:"coinType" validate:"omitempty,oneof=share team shopping transfer purchase refund coin_refund recommend reward"`
Page uint `json:"page" validate:"omitempty,numeric"` // 加入分页功能
}
type queryCoinResp struct {
Total decimal.Decimal `json:"total"` // 总共可使用
History decimal.Decimal `json:"history"` // 累计收益
List []dataList `json:"list"` // 数据列表
TotalPage uint `json:"totalPage"` // 总页数
}
type dataList struct {
UserCoin user.CoinHistory
TypeName string `json:"typeName"`
}
// 瑞币类型:分享收益,团队收益,消费,转出,
var coinType = map[string]int{
"share": 1, // 分享收益
"team": 2, // 团队收益
"shopping": 3, // 自购收益
"transfer": 4, // 转出
"purchase": 5, // 消费
"refund": 6,
"coin_refund": 7,
"recommend": 8,
"reward": 9,
}
var coinTypeName = map[string]string{
"share": "分享收益",
"team": "自营补贴",
"shopping": "自购收益",
"transfer": "转出",
"purchase": "消费",
"refund": "退款返还",
"coin_refund": "瑞币退回",
"recommend": "分销补贴",
"reward": "代理补贴",
}
var coinRType = map[int]string{
user.RoleTypeForCoinHistory: "分享收益",
user.TeamTypeForCoinHistory: "自营补贴",
user.SelfShoppingTypeForCoinHistory: "自购收益",
user.TransferTypeForCoinHistory: "转出",
user.PurchasedTypeForCoinHistory: "消费",
user.RefundTypeForCoinHistory: "退款返还",
user.RefundTypeForCoinHistory1: "瑞币退回",
user.RecommendTypeForCoinHistory: "分销补贴",
user.RewardTypeForCoinHistory: "代理补贴",
}
// 查询瑞币
func QueryCoin(c *gin.Context) {
var p queryCoinReq
err := tools.ParseParams(&p, c)
if err != nil {
back.Fail(c, err.Error())
return
}
var where user.CoinHistory
where.UserID = p.UserID
where.CoinType = coinType[p.CoinType]
// 支持按月与按年
var timeLayout string
if len(strings.TrimSpace(p.Date)) == 7 {
timeLayout = "2006-01"
} else {
timeLayout = "2006"
}
st, err := time.Parse(timeLayout, p.Date)
if err != nil {
back.Fail(c, "错误的参数")
return
}
var limit uint = 20
var userCoin []user.CoinHistory
query := dbc.DB.Where(&where).Where("created_at >= ? and created_at < ?", comFunc.GetTheFirstDayOfMonth(st),
comFunc.GetTheFirstDayOfMonth(st.AddDate(0, 1, 0))).Order("id DESC")
if p.Page <= 0 {
// 没有分页信息 则为全部
query.Find(&userCoin)
} else {
query.Limit(limit).Offset((p.Page + 1) * 20).Find(&userCoin)
}
var dList []dataList
for _, val := range userCoin {
dList = append(dList, dataList{UserCoin: val, TypeName: coinRType[val.CoinType]})
}
// todo 优化
var history struct {
History decimal.Decimal
}
dbc.DB.Model(&user.CoinHistory{}).Select("sum(coin_num) as history").Where("user_id = ? and coin_type NOT IN (?)", p.UserID, []int{user.TransferTypeForCoinHistory, user.PurchasedTypeForCoinHistory, user.RefundTypeForCoinHistory, user.RefundTypeForCoinHistory1}).Scan(&history)
var total struct {
TotalCoin decimal.Decimal
TotalPage uint
}
dbc.DB.Model(&user.CoinHistory{}).Select("count(*) as total_page, sum(coin_num) as total_coin").Where("user_id = ?", p.UserID).Scan(&total)
var uWallet user.Wallet
if err := dbc.DB.Where("user_id = ?", p.UserID).First(&uWallet).Error; err != nil {
back.Fail(c, "用户错误"+err.Error())
return
}
back.Suc(c, "操作成功", &queryCoinResp{
Total: uWallet.Coin,
History: history.History,
List: dList,
TotalPage: uint(math.Ceil(float64(total.TotalPage) / float64(limit))),
})
return
}