Initial commit

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-15 13:57:10 +08:00
co-authored by Claude Opus 5
commit 8679200f41
1897 changed files with 257900 additions and 0 deletions
+330
View File
@@ -0,0 +1,330 @@
package walletser
import (
"91porn-server/common/constant/redisconst"
"encoding/json"
"fmt"
"strconv"
"sync"
"time"
"91porn-server/app/appg"
"91porn-server/common"
"91porn-server/common/log"
"91porn-server/common/timeutil"
"91porn-server/models/commod"
"91porn-server/models/v/proxymod"
"91porn-server/models/v/txnmod"
"91porn-server/models/v/usermod"
"91porn-server/models/v/walletmod"
"github.com/shopspring/decimal"
)
// UserInviteAmountInfo 用户账户信息
type UserInviteAmountInfo struct {
TotalAmount string `json:"totalAmount" bson:"totalAmount"` // 可提现收益
TotalIncomeAmount string `json:"totalIncomeAmount" bson:"totalIncomeAmount"` // 累计收益总额
TotalPayUserCount string `json:"totalPayUserCount" bson:"totalPayUserCount"` // 累计付费用户
TotalInviteUserCount string `json:"totalInviteUserCount" bson:"totalInviteUserCount"` // 累计推广用户
TodayInviteUserCount string `json:"todayInviteUserCount" bson:"todayInviteUserCount"` // 今日推广用户
MonthInviteUserCount string `json:"monthInviteUserCount" bson:"monthInviteUserCount"` // 当月推广用户
TodayIncomeAmount string `json:"todayIncomeAmount" bson:"todayIncomeAmount"` // 今日推广收益金币
MonthIncomeAmount string `json:"monthIncomeAmount" bson:"monthIncomeAmount"` // 当月推广收益金币
}
type VideoIncomeListRes struct {
TotalVideoAmount string `json:"totalVideoAmount"`
TodayTodayAmount string `json:"todayTodayAmount"`
YesterdayAmount string `json:"yesterdayAmount"`
MounthAmount string `json:"mounthAmount"`
HasNext bool `json:"hasNext"`
List []VideoIncomeInfo `json:"list"`
}
type VideoIncomeInfo struct {
Title string `json:"Title"` // 金币
IncomeAmount string `json:"incomeAmount"` // 收入金币
IncomeType int `json:"incomeType"` // 收入类型
IncomeTime time.Time `json:"incomeTime"` // 时间
}
func GetUserAmount(uid uint64) (resp *UserInviteAmountInfo, err error) {
data := UserInviteAmountInfo{}
str, err := appg.Redis.Get(redisconst.InviteCacheKey(uid))
if err != nil {
return
}
if str != nil {
if err = json.Unmarshal([]byte(*str), &data); err == nil {
return &data, nil
}
log.Warn(fmt.Sprintf("用户ID:%d;解析缓存数据异常:%v", uid, err))
}
var (
income string
todayInviteAmount float64
monthInviteAmount float64
proxyTotalIncome float64
monthInviteUserCount int64
toadyInviteUserCount int64
totalInviteUserCount int64
totalPayUserCount int64
)
nowTime := time.Now()
startD, endD := timeutil.EarlyLastDay(nowTime)
monthStartTime, _ := timeutil.EarlyLastMonth(nowTime)
var wg sync.WaitGroup
wg.Add(7)
common.Go(func() {
defer wg.Done()
w, _ := walletmod.GetWallet(uid)
if w == nil {
return
}
income = (decimal.NewFromInt(w.Income).Add(decimal.NewFromFloat(w.IncomePot))).Div(decimal.NewFromInt(10)).String()
//vidTotalIncome = w.VidIncome
proxyTotalIncome = w.ProxyIncome
})
common.Go(func() {
defer wg.Done()
totalInviteUserCount, err = proxymod.CountByUID(uid)
if err != nil {
return
}
})
common.Go(func() {
defer wg.Done()
totalPayUserCount, err = proxymod.CountPayUserByUID(uid)
if err != nil {
return
}
})
common.Go(func() {
defer wg.Done()
monthInviteUserCount, err = proxymod.CountByUIDAndTime(uid, monthStartTime)
if err != nil {
return
}
})
common.Go(func() {
defer wg.Done()
toadyInviteUserCount, err = proxymod.CountByUIDAndTime(uid, startD)
if err != nil {
return
}
})
common.Go(func() {
defer wg.Done()
// 今日成功推广金额
todayInviteAmount, _, _ = txnmod.GetIncomeByType(uid, txnmod.ProxyIncome, startD, endD)
})
common.Go(func() {
defer wg.Done()
// 当月成功推广金额
monthInviteAmount, _, _ = txnmod.GetIncomeByType(uid, txnmod.ProxyIncome, monthStartTime, endD)
})
wg.Wait()
data.TotalAmount = income
data.TotalIncomeAmount = strconv.FormatFloat(proxyTotalIncome/10, 'f', 2, 64)
data.TotalPayUserCount = strconv.FormatInt(totalPayUserCount, 10)
data.TotalInviteUserCount = strconv.FormatInt(totalInviteUserCount, 10)
data.TodayInviteUserCount = strconv.FormatInt(toadyInviteUserCount, 10)
data.MonthInviteUserCount = strconv.FormatInt(monthInviteUserCount, 10)
data.TodayIncomeAmount = strconv.FormatFloat(todayInviteAmount/10, 'f', 2, 64)
data.MonthIncomeAmount = strconv.FormatFloat(monthInviteAmount/10, 'f', 2, 64)
// 加入缓存
common.Go(func() {
dataInfo, err := json.Marshal(&data)
if err != nil {
log.Warn(fmt.Sprintf("用户ID:%d;json序列化缓存数据异常:%v", uid, err))
return
}
if err = appg.Redis.Set(redisconst.InviteCacheKey(uid), dataInfo, 2*time.Minute); err != nil {
log.Warn(fmt.Sprintf("用户ID:%d;保存缓存数据异常:%v", uid, err))
}
})
return &data, nil
}
func GetVideoIncomelist(uid, pageNumber, pageSize uint64) (resp VideoIncomeListRes, err error) {
var vidIncomeToday float64
var vidIncomeMonth float64
var vidTotalIncome float64
var vidYesterdayIncome float64
now := time.Now()
resp = VideoIncomeListRes{
List: make([]VideoIncomeInfo, 0),
}
startM, endM := timeutil.EarlyLastMonth(now)
startD, endD := timeutil.EarlyLastDay(now)
startY, endY := timeutil.YesterdayDay(now)
var wg sync.WaitGroup
wg.Add(5)
common.Go(func() { //1
defer wg.Done()
w, _ := walletmod.GetWallet(uid)
if w == nil {
return
}
vidTotalIncome = w.VidIncome
})
common.Go(func() { //2
defer wg.Done()
vidIncomeToday, _, _ = txnmod.GetIncomeByType(uid, txnmod.WorksIncome, startD, endD)
})
common.Go(func() { //3
defer wg.Done()
vidIncomeMonth, _, _ = txnmod.GetIncomeByType(uid, txnmod.WorksIncome, startM, endM)
})
common.Go(func() { //4
defer wg.Done()
vidYesterdayIncome, _, _ = txnmod.GetIncomeByType(uid, txnmod.WorksIncome, startY, endY)
})
common.Go(func() { //5
defer wg.Done()
videoList, hasNext, _ := txnmod.WorksIncomebills(uid, pageNumber, pageSize)
resp.HasNext = hasNext
for _, videotran := range videoList {
tmp := VideoIncomeInfo{
Title: videotran.Desc,
IncomeAmount: strconv.FormatFloat(videotran.ActualAmount, 'f', 2, 64),
IncomeTime: videotran.CreatedAt,
}
resp.List = append(resp.List, tmp)
}
})
wg.Wait()
resp.TotalVideoAmount = strconv.FormatFloat(vidTotalIncome, 'f', 2, 64)
resp.TodayTodayAmount = strconv.FormatFloat(vidIncomeToday, 'f', 2, 64)
resp.YesterdayAmount = strconv.FormatFloat(vidYesterdayIncome, 'f', 2, 64)
resp.MounthAmount = strconv.FormatFloat(vidIncomeMonth, 'f', 2, 64)
return resp, nil
}
type UserInviteIncomeListRes struct {
//总邀请数
TotalInvites int64 `json:"totalInvites"`
//今日邀请
TodayInvites int64 `json:"todayInvites"`
//总邀请充值
TotalInviteAmount float64 `json:"totalInviteAmount"`
//今日充值
TodayInviteAmount float64 `json:"todayInviteAmount"`
//列表总数
Total int64 `json:"total"`
//是否还有下一页
HasNext bool `json:"hasNext"`
//列表
List []UserInviteIncomeInfo `json:"list"`
}
type UserInviteIncomeInfo struct {
// 充值用户
UserName string `json:"userName"`
// 收入金币
IncomeAmount float64 `json:"incomeAmount" bson:"incomeAmount"`
// 充值时间
RechargeAt time.Time `json:"rechargeAt"`
}
func GetInviteIncomelist(uid, pageNumber, pageSize uint64) (resp UserInviteIncomeListRes, err error) {
//分页查询收益详情
txnList, hasNext, _ := txnmod.BuyProductLogWithPage(uid, txnmod.ProxyIncome, commod.Page{
PageNumber: pageNumber,
PageSize: pageSize,
})
resp.HasNext = hasNext
txnListLen := len(txnList)
uids := make([]uint64, txnListLen)
for i, tran := range txnList {
uids[i] = tran.RechargeId
}
resList := make([]UserInviteIncomeInfo, 0)
if len(uids) > 0 {
//批量查询用户信息
m, uErr := usermod.FindUsersMapByUID(uids)
if uErr == nil && len(m) > 0 {
resList = make([]UserInviteIncomeInfo, txnListLen)
for i, tran := range txnList {
tmp := UserInviteIncomeInfo{
IncomeAmount: tran.ActualAmount / 10,
RechargeAt: tran.CreatedAt,
}
if m[tran.RechargeId] != nil {
tmp.UserName = m[tran.RechargeId].Name
}
resList[i] = tmp
}
}
}
//从缓存获取其他数据
redisKey := "Get-Invite-Income-" + strconv.FormatUint(uid, 10)
str, err := appg.Redis.Get(redisKey)
if err != nil { // redis 错误不向上报告
log.Error("GetInviteIncomelist redisc.Get", log.Any("uid", uid), log.Any("redisKey", redisKey), log.E(err))
}
if str != nil {
if err = json.Unmarshal([]byte(*str), &resp); err == nil {
resp.List = resList
resp.HasNext = hasNext
return resp, nil
}
// json.Unmarshal的错误不向上报告,而是尝试去DB获取数据
log.Error("GetInviteIncomelist json.Unmarshal", log.Any("uid", uid), log.Any("redisKey", redisKey), log.E(err))
}
resp.List = resList
resp.HasNext = hasNext
now := time.Now()
resp = UserInviteIncomeListRes{
List: make([]UserInviteIncomeInfo, 0),
}
startD, endD := timeutil.EarlyLastDay(now)
var wg sync.WaitGroup
wg.Add(4)
common.Go(func() { //1
defer wg.Done()
w, _ := walletmod.GetWallet(uid)
if w == nil {
return
}
resp.TotalInviteAmount = w.ProxyIncome / 10
})
common.Go(func() { //2
defer wg.Done()
//成功推广数
resp.TotalInvites, _ = proxymod.CountByUID(uid)
//成功推广数 = 总数
resp.Total = resp.TotalInvites
})
common.Go(func() { //3
defer wg.Done()
//今日成功推广数
resp.TodayInvites, _ = proxymod.CountByUIDAndTime(uid, startD)
})
common.Go(func() { //4
defer wg.Done()
//今日成功推广金额
resp.TodayInviteAmount, _, _ = txnmod.GetIncomeByType(uid, txnmod.ProxyIncome, startD, endD)
resp.TodayInviteAmount = resp.TodayInviteAmount / 10
})
wg.Wait()
common.Go(func() {
jsonBytes, err := json.Marshal(resp)
if err != nil {
log.Error("GetInviteIncomelist json.Marshal", log.Any("uid", uid), log.E(err))
return
}
if err := appg.Redis.Set(redisKey, string(jsonBytes), 15*time.Minute); err != nil {
log.Error("GetInviteIncomelist redisc.Set", log.Any("uid", uid), log.Any("redisKey", redisKey), log.E(err))
}
})
return resp, nil
}