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