parent
1a65a4e9de
commit
b5b213f113
8 changed files with 565 additions and 7 deletions
@ -0,0 +1,395 @@ |
||||
package handler |
||||
|
||||
import ( |
||||
"encoding/json" |
||||
"fmt" |
||||
"server/call" |
||||
"server/common" |
||||
"server/modules/backend/app" |
||||
"server/modules/backend/bdb" |
||||
"server/modules/backend/models" |
||||
"server/modules/backend/util" |
||||
"server/modules/backend/values" |
||||
"strings" |
||||
"time" |
||||
|
||||
utils "server/util" |
||||
|
||||
"github.com/gin-gonic/gin" |
||||
"github.com/liangdas/mqant/log" |
||||
"gorm.io/gorm" |
||||
) |
||||
|
||||
var ( |
||||
RechargerFee int64 = 10 |
||||
WithdrawFee int64 = 5 |
||||
ChangePer int64 = 95 |
||||
) |
||||
|
||||
// ADConfig ad配置
|
||||
func ADConfig(c *gin.Context) { |
||||
a := app.NewApp(c) |
||||
defer func() { |
||||
a.Response() |
||||
}() |
||||
a.DB = bdb.BackDB |
||||
path := c.Request.URL.Path |
||||
path = strings.ReplaceAll(path, "/advertisement/config/", "") |
||||
all := strings.Split(path, "/") |
||||
if len(all) > 1 || len(all) == 0 { |
||||
a.Code = values.CodeRetry |
||||
return |
||||
} |
||||
opt := all[0] |
||||
element := &values.ADConfig{} |
||||
list := &[]values.ADConfig{} |
||||
var resp interface{} |
||||
if opt == "list" { |
||||
req := &values.GMConfigCommonListReq{ |
||||
Condition: map[string]interface{}{}, |
||||
} |
||||
a.S(req) |
||||
count, pass := a.MGetSqlAll(element, list, req.Condition, req.Page, req.PageSize) |
||||
if !pass { |
||||
return |
||||
} |
||||
resp = values.GMConfigCommonListResp{ |
||||
Config: list, |
||||
Total: count, |
||||
} |
||||
} else if opt == "edit" { |
||||
req := new(values.GMConfigCommonEditReq) |
||||
if !a.S(req) { |
||||
return |
||||
} |
||||
if !a.MUpdateAll(req.Config, element) { |
||||
return |
||||
} |
||||
} else if opt == "del" { |
||||
req := new(values.GMConfigCommonDelReq) |
||||
if !a.S(req) { |
||||
return |
||||
} |
||||
if !a.MDel(req.ID, element) { |
||||
return |
||||
} |
||||
} |
||||
a.Data = resp |
||||
} |
||||
|
||||
func AdvertisementStats(c *gin.Context) { |
||||
a := app.NewApp(c) |
||||
defer func() { |
||||
a.Response() |
||||
}() |
||||
req := new(values.ADReq) |
||||
if !a.S(req) { |
||||
return |
||||
} |
||||
su, eu := util.GetQueryUnix(req.Start, req.End) |
||||
now := utils.GetZeroTime(time.Now()).Unix() |
||||
if su >= now { // 不允许查今天
|
||||
a.Code = values.CodeParam |
||||
a.Msg = "只能查今天之前的数据" |
||||
return |
||||
} |
||||
if eu >= now { |
||||
eu = now |
||||
} |
||||
|
||||
resp := &values.ADResp{} |
||||
a.Data = resp |
||||
resp.Count = (eu - su) / (24 * 60 * 60) |
||||
cids := []*int{} |
||||
// isSC := len(a.User.SChannels) > 0
|
||||
if len(req.ChannelID) > 0 { |
||||
cids = req.ChannelID |
||||
} else if req.GroupID > 0 { |
||||
adConfig := &values.ADConfig{ID: req.GroupID} |
||||
bdb.BackDB.Get(adConfig) |
||||
channels := []int{} |
||||
json.Unmarshal([]byte(adConfig.Channels), &channels) |
||||
if len(channels) == 0 { |
||||
a.Code = values.CodeParam |
||||
a.Msg = "该投放组未分配包" |
||||
return |
||||
} |
||||
for _, v := range channels { |
||||
one := v |
||||
cids = append(cids, &one) |
||||
} |
||||
} |
||||
// else if isSC {
|
||||
// for i := range a.User.SChannels {
|
||||
// cids = append(cids, &a.User.SChannels[i])
|
||||
// }
|
||||
// }
|
||||
// 如果是查一天的情况,罗列所有包
|
||||
if resp.Count == 1 { |
||||
if len(cids) == 1 { |
||||
one := &values.ADStats{Time: su, ChannelID: *cids[0]} |
||||
bdb.BackDB.Get(one) |
||||
if one.ID == 0 { |
||||
one = GetOneAD(su, su+24*60*60, cids) |
||||
if one.Time != now { |
||||
bdb.BackDB.Create(one) |
||||
} |
||||
} |
||||
CalStats(one) |
||||
resp.List = append(resp.List, *one) |
||||
one.ChannelID = 0 |
||||
resp.Total = *one |
||||
return |
||||
} |
||||
if len(cids) == 0 { |
||||
channels := call.GetChannelListByShow(2) |
||||
for _, v := range channels { |
||||
cids = append(cids, &v.ChannelID) |
||||
} |
||||
} |
||||
list := []*values.ADStats{} |
||||
bdb.BackDB.QueryAll(fmt.Sprintf("time = %d", su), "", &values.ADStats{}, &list) |
||||
|
||||
for _, v := range cids { |
||||
var one *values.ADStats |
||||
for _, j := range list { |
||||
if j.ChannelID == *v { |
||||
one = j |
||||
break |
||||
} |
||||
} |
||||
if one == nil { |
||||
one = GetOneAD(su, su+24*60*60, []*int{v}) |
||||
if one.Time != now { |
||||
bdb.BackDB.Create(one) |
||||
} |
||||
} |
||||
CalStats(one) |
||||
resp.List = append(resp.List, *one) |
||||
} |
||||
total := &values.ADStats{} |
||||
for _, v := range resp.List { |
||||
CalTotal(total, &v) |
||||
} |
||||
CalStats(total) |
||||
resp.Total = *total |
||||
return |
||||
} |
||||
|
||||
listLen := req.Num |
||||
if listLen > int(resp.Count) { |
||||
listLen = int(resp.Count) |
||||
} |
||||
resp.List = make([]values.ADStats, listLen) |
||||
list := []values.ADStats{} |
||||
sql := fmt.Sprintf("time >= %d and time < %d", su, eu) |
||||
if len(cids) == 0 { |
||||
sql += " and channel_id = 0" |
||||
} else if len(cids) == 1 { |
||||
sql += fmt.Sprintf(" and channel_id = %d", *cids[0]) |
||||
} |
||||
bdb.BackDB.QueryAll(sql, "time desc", &values.ADStats{}, &list) |
||||
|
||||
index := -1 |
||||
start := eu - 24*60*60 - int64((req.Page-1)*req.Num)*24*60*60 |
||||
end := start - int64(req.Num-1)*24*60*60 |
||||
if end < su { |
||||
end = su |
||||
} |
||||
for i := start; i >= end; i -= 24 * 60 * 60 { |
||||
index++ |
||||
total := &values.ADStats{} |
||||
if len(cids) == 0 { |
||||
find := false |
||||
for _, v := range list { |
||||
if v.Time != i { |
||||
continue |
||||
} |
||||
find = true |
||||
CalTotal(total, &v) |
||||
break |
||||
} |
||||
if !find { |
||||
one := GetOneAD(i, i+24*60*60, nil) |
||||
if one.Time != now { |
||||
bdb.BackDB.Create(one) |
||||
} |
||||
CalTotal(total, one) |
||||
} |
||||
} else { |
||||
for _, cid := range cids { |
||||
find := false |
||||
for _, v := range list { |
||||
if v.ChannelID != *cid { |
||||
continue |
||||
} |
||||
if v.Time != i { |
||||
continue |
||||
} |
||||
find = true |
||||
CalTotal(total, &v) |
||||
if len(cids) == 1 { |
||||
total.ID = v.ID |
||||
} |
||||
break |
||||
} |
||||
if !find { |
||||
one := GetOneAD(i, i+24*60*60, []*int{cid}) |
||||
if one.Time != now { |
||||
bdb.BackDB.Create(one) |
||||
} |
||||
CalTotal(total, one) |
||||
if len(cids) == 1 { |
||||
total.ID = one.ID |
||||
} |
||||
} |
||||
} |
||||
} |
||||
if len(cids) == 1 { |
||||
total.ChannelID = *cids[0] |
||||
} |
||||
CalStats(total) |
||||
resp.List[index] = *total |
||||
} |
||||
if index < listLen-1 { |
||||
resp.List = resp.List[:index+1] |
||||
} |
||||
} |
||||
|
||||
func GetOneAD(start, end int64, cids []*int) *values.ADStats { |
||||
one := &values.ADStats{ |
||||
Time: start, |
||||
Date: time.Unix(start, 0).Format("20060102"), |
||||
} |
||||
if len(cids) == 0 { |
||||
one.Cost = bdb.BackDB.Sum(&values.ADStats{}, fmt.Sprintf("channel_id != 0 and time = %d", one.Time), "cost") |
||||
one.TotalCost = bdb.BackDB.Sum(&values.ADStats{}, fmt.Sprintf("channel_id != 0 and time <= %d", one.Time), "cost") |
||||
} else if len(cids) == 1 { |
||||
one.ChannelID = *cids[0] |
||||
one.TotalCost = bdb.BackDB.Sum(&values.ADStats{}, fmt.Sprintf("channel_id = %d and time < %d", one.ChannelID, one.Time), "cost") |
||||
} |
||||
// 需要查的数据
|
||||
// 新增人数
|
||||
one.NewPlayers = models.GetNewPlayerCountBySqls(start, end, cids...) |
||||
// 总用户
|
||||
oldPlayers := models.GetOldPlayerCountBySqls(start, end, cids...) |
||||
one.TotalPlayers = one.NewPlayers + oldPlayers |
||||
// 新增付费人数
|
||||
one.NewPayPlayers = models.GetNewPayCountBySqls(start, end, cids...) |
||||
// 新增付费金额
|
||||
one.NewPay = models.GetNewPayAmountBySqls(start, end, common.CurrencyINR, cids...) |
||||
// 活跃付费金额
|
||||
one.ActivePay = models.GetOldPayAmountBySqls(start, end, common.CurrencyINR, cids...) |
||||
// 活跃付费人数
|
||||
one.ActivePayPlayers = models.GetOldPayCountBySqls(start, end, cids...) |
||||
// 总付费
|
||||
one.TotalPay = one.NewPay + one.ActivePay |
||||
// 总退出
|
||||
one.TotalWithdraw = models.GetWithdrawAmountTotalBySQLs(start, end, common.CurrencyINR, cids...) |
||||
|
||||
one.NewRegister = int(models.GetNewPlayerCountBySqls(start, end, cids...)) |
||||
one.ActiveDevice = int(models.GetDownloadCounts(&start, &end, cids...)) |
||||
one.NewWithdraw = models.GetNewWithdrawAmount(start, end, cids...) |
||||
oldActiveUser := models.GetOldPlayerCountBySqls(start, end, cids...) |
||||
one.ActiveUser = one.NewRegister + int(oldActiveUser) |
||||
newPayCount := models.GetNewPayCountBySqls(start, end, cids...) |
||||
oldPayCount := models.GetOldPayCountBySqls(start, end, cids...) |
||||
one.RechargeUser = int(newPayCount + oldPayCount) |
||||
// 以下为直接计算出来的数值
|
||||
|
||||
// 当日收益=当日充值金额*0.92-当日退出*1.05
|
||||
one.Profit = one.TotalPay*(100-RechargerFee)/100 - one.TotalWithdraw*(100+WithdrawFee)/100 |
||||
// 历史总收益=总充值*0.92-总退出*1.05
|
||||
totalPay := models.GetAmountTotalBySQLs(0, end, cids...) |
||||
totalWithdraw := models.GetWithdrawAmountTotalBySQLs(0, end, common.CurrencyINR, cids...) |
||||
one.TotalProfit = totalPay*(100-RechargerFee)/100 - totalWithdraw*(100+WithdrawFee)/100 |
||||
|
||||
// one.WithdrawPer = util.GetPer(one.TotalWithdraw, one.TotalPay)
|
||||
|
||||
// one.NewPayPer = util.GetPer(one.NewPayPlayers, one.NewPlayers)
|
||||
// one.NewPayUnit = util.GetPoint(one.NewPay, one.NewPlayers)
|
||||
// one.ARPU = util.GetPoint(one.ActivePay, one.ActivePayPlayers)
|
||||
return one |
||||
} |
||||
|
||||
// 修改投入
|
||||
func AdvertisementEdit(c *gin.Context) { |
||||
a := app.NewApp(c) |
||||
defer func() { |
||||
a.Response() |
||||
}() |
||||
req := new(values.ADEditReq) |
||||
if !a.S(req) { |
||||
return |
||||
} |
||||
if req.Cost < 0 { |
||||
a.Code = values.CodeParam |
||||
a.Msg = "消耗不能小于0" |
||||
return |
||||
} |
||||
one := &values.ADStats{ID: req.ID} |
||||
err := bdb.BackDB.Get(one) |
||||
if err != nil { |
||||
log.Error("err:%v", err) |
||||
a.Code = values.CodeParam |
||||
return |
||||
} |
||||
diff := req.Cost - one.Cost |
||||
if diff == 0 { |
||||
a.Code = values.CodeParam |
||||
a.Msg = "消耗无修改" |
||||
return |
||||
} |
||||
|
||||
one.Cost = req.Cost |
||||
|
||||
// one.NewCost = util.GetPoint(one.Cost, one.NewPlayers*100)
|
||||
// one.NewPayCost = util.GetPoint(one.Cost, one.NewPayPlayers*100)
|
||||
// one.NewROI = util.GetPer(one.Profit*100, one.Cost*93)
|
||||
// one.NewPayROI = util.GetPer(one.NewPay*100, one.Cost*93)
|
||||
|
||||
// totalCost := bdb.BackDB.Sum(&values.ADStats{}, fmt.Sprintf("channel_id = %d and time < %d", one.ChannelID, one.Time), "cost")
|
||||
// totalCost += one.Cost
|
||||
// one.TotalROI = util.GetPer(one.TotalProfit*100, totalCost*93)
|
||||
|
||||
bdb.BackDB.Update(&values.ADStats{ID: req.ID}, map[string]interface{}{"cost": one.Cost}) |
||||
bdb.BackDB.UpdateW(&values.ADStats{}, map[string]interface{}{"cost": gorm.Expr("cost + ?", diff)}, |
||||
fmt.Sprintf("channel_id = 0 and time = %d", one.Time)) |
||||
bdb.BackDB.UpdateW(&values.ADStats{}, map[string]interface{}{"total_cost": gorm.Expr("total_cost + ?", diff)}, |
||||
fmt.Sprintf("(channel_id = %d or channel_id = 0) and time >= %d", one.ChannelID, one.Time)) |
||||
} |
||||
|
||||
func CalTotal(total, one *values.ADStats) { |
||||
total.Time = one.Time |
||||
total.Date = one.Date |
||||
total.Cost += one.Cost |
||||
total.NewPlayers += one.NewPlayers |
||||
total.TotalPlayers += one.TotalPlayers |
||||
total.NewPayPlayers += one.NewPayPlayers |
||||
total.NewPay += one.NewPay |
||||
total.ActivePay += one.ActivePay |
||||
total.ActivePayPlayers += one.ActivePayPlayers |
||||
total.TotalPay += one.TotalPay |
||||
total.TotalWithdraw += one.TotalWithdraw |
||||
total.Profit += one.Profit |
||||
total.TotalProfit += one.TotalProfit |
||||
total.TotalCost += one.TotalCost |
||||
total.NewRegister += one.NewRegister |
||||
total.ActiveDevice += one.ActiveDevice |
||||
total.NewWithdraw += one.NewWithdraw |
||||
total.ActiveUser += one.ActiveUser |
||||
total.RechargeUser += one.RechargeUser |
||||
} |
||||
|
||||
// 通过自己数据计算相应收益/roi等数据
|
||||
func CalStats(one *values.ADStats) { |
||||
one.NewCost = util.GetPoint(one.Cost, one.NewPlayers) |
||||
one.NewPayCost = util.GetPoint(one.Cost, one.NewPayPlayers) |
||||
one.NewPayPer = util.GetPer(one.NewPayPlayers, one.NewPlayers) |
||||
one.NewPayUnit = util.GetPoint(one.NewPay, one.NewPlayers) |
||||
one.ARPU = util.GetPoint(one.ActivePay, one.ActivePayPlayers) |
||||
one.WithdrawPer = util.GetPer(one.TotalWithdraw, one.TotalPay) |
||||
one.NewROI = util.GetPer(one.Profit*100, one.Cost*ChangePer) |
||||
one.TotalROI = util.GetPer(one.TotalProfit*100, one.TotalCost*ChangePer) |
||||
one.NewPayROI = util.GetPer(one.NewPay*100, one.Cost*ChangePer) |
||||
} |
||||
@ -0,0 +1,14 @@ |
||||
// 账号相关的接口
|
||||
package routers |
||||
|
||||
import ( |
||||
handler "server/modules/backend/handler/advertisement" |
||||
|
||||
"github.com/gin-gonic/gin" |
||||
) |
||||
|
||||
func advertisement(e *gin.Engine) { |
||||
e.POST("/advertisement/config/*action", handler.ADConfig) |
||||
e.POST("/advertisement/list", handler.AdvertisementStats) |
||||
e.POST("/advertisement/edit", handler.AdvertisementEdit) |
||||
} |
||||
@ -0,0 +1,21 @@ |
||||
package values |
||||
|
||||
type ADReq struct { |
||||
Start string `json:"Start"` |
||||
End string `json:"End"` |
||||
Page int `json:"Page" binding:"required"` |
||||
Num int `json:"Num" binding:"required"` |
||||
ChannelID []*int `json:"ChannelID"` |
||||
GroupID int `json:"GroupID"` // 投放组ID
|
||||
} |
||||
|
||||
type ADResp struct { |
||||
Count int64 |
||||
List []ADStats |
||||
Total ADStats // 当查的是一天的数据时,改值为当天汇总数据
|
||||
} |
||||
|
||||
type ADEditReq struct { |
||||
ID int `json:"ID" binding:"required"` |
||||
Cost int64 `json:"Cost"` |
||||
} |
||||
Loading…
Reference in new issue