@@ -83,6 +83,30 @@ func DataCenterRecordList(c *gin.Context) { | |||
return | |||
} | |||
// DataCenterRecordOutPut | |||
// @Summary 数据明细-导出 | |||
// @Tags 数据中心------嘉俊 | |||
// @Description 数据中心-数据明细-导出 | |||
// @param Authorization header string true "验证参数Bearer和token空格拼接" | |||
// @Accept json | |||
// @Produce json | |||
// @Param args body md.DataCenterRecordOutPutReq true "请求参数" | |||
// @Success 200 {string} "具体看返回内容 这是data里面的数据" | |||
// @Failure 400 {object} md.Response "具体错误" | |||
// @Router /api/dataCenter/record/output [POST] | |||
func DataCenterRecordOutPut(c *gin.Context) { | |||
var req md.DataCenterRecordOutPutReq | |||
err := c.ShouldBindJSON(&req) | |||
if err != nil { | |||
err = validate.HandleValidateErr(err) | |||
err1 := err.(e.E) | |||
e.OutErr(c, err1.Code, err1.Error()) | |||
return | |||
} | |||
svc.DataCenterRecordOutPut(c, req) | |||
return | |||
} | |||
// DataCenterSelectData | |||
// @Summary 筛选条件 | |||
// @Tags 数据中心------嘉俊 | |||
@@ -0,0 +1,77 @@ | |||
package hdl | |||
import ( | |||
"applet/app/e" | |||
"applet/app/lib/validate" | |||
"applet/app/md" | |||
"applet/app/svc" | |||
"applet/app/utils" | |||
db "code.fnuoos.com/zhimeng/model.git/src" | |||
"code.fnuoos.com/zhimeng/model.git/src/super/implement" | |||
"github.com/gin-gonic/gin" | |||
) | |||
// Base | |||
// @Summary 右上角基本数据 | |||
// @Tags 首页------嘉俊 | |||
// @Description 首页-右上角基本数据 | |||
// @param Authorization header string true "验证参数Bearer和token空格拼接" | |||
// @Accept json | |||
// @Produce json | |||
// @Success 200 {string} "具体看返回内容 这是data里面的数据" | |||
// @Failure 400 {object} md.Response "具体错误" | |||
// @Router /api/index/base [GET] | |||
func Base(c *gin.Context) { | |||
user := svc.GetUser(c) | |||
NewMediumListDb := implement.NewMediumListDb(db.Db) | |||
data, _ := NewMediumListDb.GetMediumList(user.MediumId) | |||
settleType := []string{"", "日结", "周结", "月结", "预付"} | |||
res := map[string]string{ | |||
"account_id": utils.IntToStr(user.MediumId), | |||
"name": user.Username, | |||
"account": user.Username, | |||
"settle_type": utils.IntToStr(data.SettlementType), | |||
"settle_type_str": settleType[data.SettlementType], | |||
} | |||
e.OutSuc(c, res, nil) | |||
return | |||
} | |||
// IndexTotal | |||
// @Summary 统计数据 | |||
// @Tags 首页------嘉俊 | |||
// @Description 首页-统计数据 | |||
// @param Authorization header string true "验证参数Bearer和token空格拼接" | |||
// @Accept json | |||
// @Produce json | |||
// @Success 200 {string} "具体看返回内容 这是data里面的数据" | |||
// @Failure 400 {object} md.Response "具体错误" | |||
// @Router /api/index/total [GET] | |||
func IndexTotal(c *gin.Context) { | |||
svc.IndexTotal(c) | |||
} | |||
// IndexAppList | |||
// @Summary 数据明细 | |||
// @Tags 数据中心------嘉俊 | |||
// @Description 数据中心-数据明细 | |||
// @param Authorization header string true "验证参数Bearer和token空格拼接" | |||
// @Accept json | |||
// @Produce json | |||
// @Param args body md.IndexAppListReq true "请求参数" | |||
// @Success 200 {object} md.IndexAppListRes "具体看返回内容 这是data里面的数据" | |||
// @Failure 400 {object} md.Response "具体错误" | |||
// @Router /api/index/app/list [POST] | |||
func IndexAppList(c *gin.Context) { | |||
var req md.IndexAppListReq | |||
err := c.ShouldBindJSON(&req) | |||
if err != nil { | |||
err = validate.HandleValidateErr(err) | |||
err1 := err.(e.E) | |||
e.OutErr(c, err1.Code, err1.Error()) | |||
return | |||
} | |||
res := svc.IndexAppList(c, req) | |||
e.OutSuc(c, res, nil) | |||
return | |||
} |
@@ -131,11 +131,11 @@ func Register(c *gin.Context) { | |||
return | |||
} | |||
engine := db.DBs[svc.GetMasterId(c)] | |||
check, err := svc.SmsCheck(c, req.UserName, req.Captcha) | |||
if check == false { | |||
e.OutErr(c, 400, e.NewErr(400, err.Error())) | |||
return | |||
} | |||
//check, err := svc.SmsCheck(c, req.UserName, req.Captcha) | |||
//if check == false { | |||
// e.OutErr(c, 400, e.NewErr(400, err.Error())) | |||
// return | |||
//} | |||
now := time.Now() | |||
//1、判断当前账号是否已存在 | |||
mediumDb := implement.NewMediumDb(engine) | |||
@@ -17,6 +17,15 @@ type DataCenterRecordReq struct { | |||
Limit string `json:"limit"` | |||
Page string `json:"page" ` | |||
} | |||
type DataCenterRecordOutPutReq struct { | |||
StartDate string `json:"start_date" example:"2024-08-30"` | |||
EndDate string `json:"end_date" example:"2024-08-30"` | |||
Platform string `json:"platform" example:"平台"` | |||
AppId string `json:"app_id" example:"应用"` | |||
AdType string `json:"ad_type" example:"广告位类型"` | |||
Limit string `json:"limit" example:"10000 个一页"` | |||
Page string `json:"page" ` | |||
} | |||
type DataCenterTableRes struct { | |||
List []DataCenterTableData `json:"list" ` | |||
} | |||
@@ -0,0 +1,24 @@ | |||
package md | |||
type IndexAppListReq struct { | |||
StartDate string `json:"start_date" example:"2024-08-30"` | |||
EndDate string `json:"end_date" example:"2024-08-30"` | |||
Sort string `json:"sort" example:"排序"` | |||
} | |||
type IndexAppListRes struct { | |||
List []IndexAppListData `json:"list" ` | |||
Sort []SelectData `json:"sort"` | |||
} | |||
type IndexAppListData struct { | |||
Name string `json:"name"` | |||
Logo string `json:"logo"` | |||
List []IndexAppListDataList `json:"list"` | |||
TableList []string `json:"table_list"` | |||
} | |||
type IndexAppListDataList struct { | |||
Name string `json:"name"` | |||
Value string `json:"value"` | |||
Type string `json:"type"` | |||
Bili string `json:"bili"` | |||
} |
@@ -64,9 +64,9 @@ func route(r *gin.RouterGroup) { | |||
r.POST("/qiniuyun/upload", hdl.ImgReqUpload) //七牛云上传 | |||
r.POST("/sms", hdl.Sms) //短信发送 | |||
} | |||
r.Use(mw.Auth) // 以下接口需要JWT验证 | |||
rRole(r.Group("/role")) //权限管理 | |||
r.Use(mw.Auth) // 以下接口需要JWT验证 | |||
rRole(r.Group("/role")) //权限管理 | |||
rIndex(r.Group("/index")) //首页 | |||
rApplication(r.Group("/application")) //应用管理 | |||
rAccount(r.Group("/account")) //账号中心 | |||
rSettleCenter(r.Group("/settleCenter")) //结算中心 | |||
@@ -117,8 +117,14 @@ func rInvoiceCenter(r *gin.RouterGroup) { | |||
} | |||
func rDataCenter(r *gin.RouterGroup) { | |||
r.GET("/select/data", hdl.DataCenterSelectData) //数据中心-筛选条件 | |||
r.POST("/table", hdl.DataCenterTable) //数据中心-数据图表 | |||
r.POST("/record/total", hdl.DataCenterRecordTotal) //数据中心-数据明细合计 | |||
r.POST("/record/list", hdl.DataCenterRecordList) //数据中心-数据明细 | |||
r.GET("/select/data", hdl.DataCenterSelectData) //数据中心-筛选条件 | |||
r.POST("/table", hdl.DataCenterTable) //数据中心-数据图表 | |||
r.POST("/record/total", hdl.DataCenterRecordTotal) //数据中心-数据明细合计 | |||
r.POST("/record/list", hdl.DataCenterRecordList) //数据中心-数据明细 | |||
r.POST("/record/output", hdl.DataCenterRecordOutPut) //数据中心-数据明细-导出 | |||
} | |||
func rIndex(r *gin.RouterGroup) { | |||
r.GET("/base", hdl.Base) //首页-基本信息 | |||
r.GET("/total", hdl.IndexTotal) //首页-统计数据 | |||
r.POST("/app/list", hdl.IndexAppList) //首页-应用数据 | |||
} |
@@ -23,7 +23,7 @@ func DataCenterTable(c *gin.Context, req md.DataCenterTableReq) md.DataCenterTab | |||
tmp := md.DataCenterTableData{ | |||
Date: v["date"], | |||
ExposureCount: v["exposure_count"], | |||
MediaRevenue: v["media_revenue"], | |||
MediaRevenue: utils.Float64ToStr(utils.StrToFloat64(v["media_revenue"]) / 100), | |||
Ecpm: v["ecpm"], | |||
} | |||
list = append(list, tmp) | |||
@@ -39,7 +39,7 @@ func DataCenterRecordTotal(c *gin.Context, req md.DataCenterTableReq) md.DataCen | |||
SELECT | |||
SUM(exposure_count) as exposure_count, | |||
SUM(click_count) as click_count, | |||
SUM(click_rate) as click_rate, | |||
SUM(click_count)/SUM(exposure_count)*100 as click_rate, | |||
SUM(ecpm) as ecpm, | |||
SUM(media_revenue) as media_revenue | |||
FROM generate_wx_ad_data | |||
@@ -68,9 +68,9 @@ func DataCenterRecordTotal(c *gin.Context, req md.DataCenterTableReq) md.DataCen | |||
PlatformName: "-", | |||
AdvName: "-", | |||
ExposureCount: v["exposure_count"], | |||
MediaRevenue: v["media_revenue"], | |||
Ecpm: v["ecpm"], | |||
ClickRate: v["click_rate"], | |||
MediaRevenue: utils.Float64ToStr(utils.StrToFloat64(v["media_revenue"]) / 100), | |||
Ecpm: utils.Float64ToStr(utils.StrToFloat64(v["ecpm"]) / 100), | |||
ClickRate: utils.GetPrec(v["click_rate"], "2"), | |||
ClickCount: v["click_count"], | |||
} | |||
} | |||
@@ -94,8 +94,8 @@ func DataCenterRecordList(c *gin.Context, req md.DataCenterRecordReq) md.DataCen | |||
PlatformName: md.AppletPlatformMap[platform], | |||
AdvName: enum.AdunitType(v["ad_slot"]).String(), | |||
ExposureCount: v["exposure_count"], | |||
MediaRevenue: v["media_revenue"], | |||
Ecpm: v["ecpm"], | |||
MediaRevenue: utils.Float64ToStr(utils.StrToFloat64(v["media_revenue"]) / 100), | |||
Ecpm: utils.Float64ToStr(utils.StrToFloat64(v["ecpm"]) / 100), | |||
ClickRate: v["click_rate"], | |||
ClickCount: v["click_count"], | |||
} | |||
@@ -107,6 +107,54 @@ func DataCenterRecordList(c *gin.Context, req md.DataCenterRecordReq) md.DataCen | |||
} | |||
return res | |||
} | |||
func DataCenterRecordOutPut(c *gin.Context, req md.DataCenterRecordOutPutReq) { | |||
var req1 md.DataCenterRecordReq | |||
copier.Copy(&req1, &req) | |||
req.Limit = "10000" | |||
nativeString, _ := comm(c, 0, req1) | |||
appId := make([]string, 0) | |||
for _, v := range nativeString { | |||
appId = append(appId, v["app_id"]) | |||
} | |||
var app []model2.AppletApplication | |||
appMap := make(map[string]model2.AppletApplication) | |||
MasterDb(c).In("app_id=?", appId).Find(&app) | |||
for _, v := range app { | |||
appMap[v.AppId] = v | |||
} | |||
name := req.StartDate + "~" + req.EndDate + "-第" + req.Page + "页" | |||
//写入数据 | |||
data := map[string]string{ | |||
"A1": "日期", | |||
"B1": "应用名称", | |||
"C1": "平台类型", | |||
"D1": "广告位", | |||
"E1": "曝光量", | |||
"F1": "点击量", | |||
"G1": "ECPM", | |||
"H1": "预估收益", | |||
} | |||
for k, v := range nativeString { | |||
i := utils.IntToStr(k + 2) | |||
data["A"+i] = v["date"] | |||
data["B"+i] = appMap[v["app_id"]].Name | |||
data["C"+i] = md.AppletPlatformMap[appMap[v["app_id"]].Platform] | |||
data["D"+i] = enum.AdunitType(v["ad_slot"]).String() | |||
data["E"+i] = v["exposure_count"] | |||
data["F"+i] = v["click_count"] | |||
data["G"+i] = utils.Float64ToStr(utils.StrToFloat64(v["ecpm"]) / 100) | |||
data["H"+i] = utils.Float64ToStr(utils.StrToFloat64(v["media_revenue"]) / 100) | |||
} | |||
file := utils.Output(c, name, data) | |||
filename := name + ".xlsx" | |||
r := map[string]string{ | |||
"file": file, | |||
"filename": filename, | |||
} | |||
e.OutSuc(c, r, nil) | |||
return | |||
} | |||
func comm(c *gin.Context, isTotal int, req md.DataCenterRecordReq) ([]map[string]string, int64) { | |||
appId := GetAppletId(c, req.AppId, req.Platform) | |||
sql := ` | |||
@@ -142,7 +190,7 @@ func comm(c *gin.Context, isTotal int, req md.DataCenterRecordReq) ([]map[string | |||
var total int64 = 0 | |||
if isTotal == 1 { | |||
sqlTotal := fmt.Sprintf(sql, "COUNT(*) as count ", where) | |||
sqlTotal := fmt.Sprintf(sql, "COUNT(*) as count ", where, "") | |||
nativeStringTotal, _ := db.QueryNativeString(db.Db, sqlTotal) | |||
for _, v := range nativeStringTotal { | |||
total = utils.StrToInt64(v["count"]) | |||
@@ -203,3 +251,18 @@ func GetAppletId(c *gin.Context, appId, platform string) string { | |||
} | |||
return mediumId | |||
} | |||
func GetAppletInfo(c *gin.Context, id string) map[string]string { | |||
var res = map[string]string{ | |||
"platform": "", | |||
"name": "", | |||
"logo": "", | |||
} | |||
NewAppletApplicationDb := implement.NewAppletApplicationDb(MasterDb(c)) | |||
data, _ := NewAppletApplicationDb.GetAppletApplicationListByAppid(id) | |||
if data != nil { | |||
res["platform"] = data.Platform | |||
res["name"] = data.Name | |||
res["logo"] = data.Logo | |||
} | |||
return res | |||
} |
@@ -0,0 +1,122 @@ | |||
package svc | |||
import ( | |||
"applet/app/e" | |||
"applet/app/md" | |||
"applet/app/utils" | |||
db "code.fnuoos.com/zhimeng/model.git/src" | |||
"fmt" | |||
"github.com/gin-gonic/gin" | |||
"time" | |||
) | |||
func IndexTotal(c *gin.Context) { | |||
yesterday := utils.GetTimeRange("yesterday") | |||
yesterdayTotal := commTotal(c, time.Unix(yesterday["start"], 0).Format("2006-01-02"), time.Unix(yesterday["end"]-3600, 0).Format("2006-01-02")) | |||
withinSevenDays := utils.GetTimeRange("new_within_seven_days") | |||
withinSevenDaysTotal := commTotal(c, time.Unix(withinSevenDays["start"], 0).Format("2006-01-02"), time.Unix(withinSevenDays["end"]-3600, 0).Format("2006-01-02")) | |||
currentMonth := utils.GetTimeRange("current_month") | |||
currentMonthTotal := commTotal(c, time.Unix(currentMonth["start"], 0).Format("2006-01-02"), time.Unix(currentMonth["end"]-3600, 0).Format("2006-01-02")) | |||
lastMonth := utils.GetTimeRange("last_month") | |||
lastMonthTotal := commTotal(c, time.Unix(lastMonth["start"], 0).Format("2006-01-02"), time.Unix(lastMonth["end"]-3600, 0).Format("2006-01-02")) | |||
res := []md.IndexAppListDataList{ | |||
{Name: "昨日收益", Type: "yesterday", Bili: "-%", Value: utils.Float64ToStr(utils.StrToFloat64(yesterdayTotal[0]["media_revenue"]) / 100)}, | |||
{Name: "七日收益", Type: "within_seven_days", Bili: "-%", Value: utils.Float64ToStr(utils.StrToFloat64(withinSevenDaysTotal[0]["media_revenue"]) / 100)}, | |||
{Name: "本月收益", Type: "current_month", Bili: "-%", Value: utils.Float64ToStr(utils.StrToFloat64(currentMonthTotal[0]["media_revenue"]) / 100)}, | |||
{Name: "上月收益", Type: "last_month", Bili: "-%", Value: utils.Float64ToStr(utils.StrToFloat64(lastMonthTotal[0]["media_revenue"]) / 100)}, | |||
} | |||
e.OutSuc(c, res, nil) | |||
return | |||
} | |||
func IndexAppList(c *gin.Context, req md.IndexAppListReq) md.IndexAppListRes { | |||
data := commTotalByApp(c, req) | |||
list := make([]md.IndexAppListData, 0) | |||
for _, v := range data { | |||
dataList := []md.IndexAppListDataList{ | |||
{Name: "广告预估收益", Type: "media_revenue", Bili: "-%", Value: utils.Float64ToStr(utils.StrToFloat64(v["media_revenue"]) / 100)}, | |||
{Name: "ECPM", Type: "ecpm", Bili: "-%", Value: v["ecpm"]}, | |||
{Name: "曝光量", Type: "exposure_count", Bili: "-%", Value: v["exposure_count"]}, | |||
{Name: "点击量", Type: "click_count", Bili: "-%", Value: v["click_count"]}, | |||
{Name: "点击率", Type: "click_rate", Bili: "-%", Value: utils.GetPrec(v["click_rate"], "2")}, | |||
} | |||
applet := GetAppletInfo(c, v["app_id"]) | |||
tmp := md.IndexAppListData{ | |||
Name: applet["name"], | |||
Logo: applet["logo"], | |||
List: dataList, | |||
TableList: []string{}, | |||
} | |||
list = append(list, tmp) | |||
} | |||
res := md.IndexAppListRes{ | |||
List: list, | |||
Sort: []md.SelectData{ | |||
{Name: "按收益最高", Value: "media_revenue desc"}, | |||
{Name: "按ECPM最高", Value: "ecpm desc"}, | |||
{Name: "按曝光量最高", Value: "exposure_count desc"}, | |||
}, | |||
} | |||
return res | |||
} | |||
func commTotal(c *gin.Context, startDate, endDate string) []map[string]string { | |||
sql := ` | |||
SELECT | |||
SUM(exposure_count) as exposure_count, | |||
SUM(click_count) as click_count, | |||
SUM(click_rate) as click_rate, | |||
SUM(ecpm) as ecpm, | |||
SUM(media_revenue) as media_revenue | |||
FROM generate_wx_ad_data | |||
where %s | |||
` | |||
where := "uuid=" + c.GetString("mid") | |||
if startDate != "" { | |||
where += " and date>='" + startDate + "'" | |||
} | |||
if endDate != "" { | |||
where += " and date<='" + endDate + "'" | |||
} | |||
sql = fmt.Sprintf(sql, where) | |||
nativeString, _ := db.QueryNativeString(db.Db, sql) | |||
if len(nativeString) == 0 { | |||
nativeString = []map[string]string{ | |||
{ | |||
"media_revenue": "0", | |||
}, | |||
} | |||
} | |||
return nativeString | |||
} | |||
func commTotalByApp(c *gin.Context, req md.IndexAppListReq) []map[string]string { | |||
sql := ` | |||
SELECT | |||
app_id as app_id, | |||
SUM(exposure_count) as exposure_count, | |||
SUM(click_count) as click_count, | |||
SUM(click_count)/SUM(exposure_count)*100 as click_rate, | |||
SUM(ecpm) as ecpm, | |||
SUM(media_revenue) as media_revenue | |||
FROM generate_wx_ad_data | |||
where %s group by app_id order by %s,id asc limit 10 | |||
` | |||
where := "uuid=" + c.GetString("mid") | |||
if req.StartDate != "" { | |||
where += " and date>='" + req.StartDate + "'" | |||
} | |||
if req.EndDate != "" { | |||
where += " and date<='" + req.EndDate + "'" | |||
} | |||
if req.Sort == "" { | |||
req.Sort = "media_revenue desc" | |||
} | |||
sql = fmt.Sprintf(sql, where, req.Sort) | |||
nativeString, _ := db.QueryNativeString(db.Db, sql) | |||
if len(nativeString) == 0 { | |||
nativeString = []map[string]string{ | |||
{ | |||
"media_revenue": "0", | |||
}, | |||
} | |||
} | |||
return nativeString | |||
} |
@@ -320,3 +320,55 @@ func IntToStr(i int) string { | |||
func Int64ToStr(i int64) string { | |||
return strconv.FormatInt(i, 10) | |||
} | |||
func StrToFormat(s string, prec int) string { | |||
ex := strings.Split(s, ".") | |||
if len(ex) == 2 { | |||
if StrToFloat64(ex[1]) == 0 { //小数点后面为空就是不要小数点了 | |||
return ex[0] | |||
} | |||
//看取多少位 | |||
str := ex[1] | |||
str1 := str | |||
if prec < len(str) { | |||
str1 = str[0:prec] | |||
} else { | |||
for i := 0; i < prec-len(str); i++ { | |||
str1 += "0" | |||
} | |||
} | |||
if prec > 0 { | |||
return ex[0] + "." + str1 | |||
} else { | |||
return ex[0] | |||
} | |||
} | |||
return s | |||
} | |||
func Float64ToStrByPrec(f float64, prec int) string { | |||
return strconv.FormatFloat(f, 'f', prec, 64) | |||
} | |||
func GetPrec(sum, commPrec string) string { | |||
if sum == "" { | |||
sum = "0" | |||
} | |||
sum = StrToFormat(sum, StrToInt(commPrec)) | |||
ex := strings.Split(sum, ".") | |||
if len(ex) == 2 { | |||
if StrToFloat64(ex[1]) == 0 { | |||
sum = ex[0] | |||
} else { | |||
val := Float64ToStrByPrec(StrToFloat64(ex[1]), 0) | |||
keyMax := 0 | |||
for i := 0; i < len(val); i++ { | |||
ch := string(val[i]) | |||
fmt.Println(StrToInt(ch)) | |||
if StrToInt(ch) > 0 { | |||
keyMax = i | |||
} | |||
} | |||
valNew := val[0 : keyMax+1] | |||
sum = ex[0] + "." + strings.ReplaceAll(ex[1], val, valNew) | |||
} | |||
} | |||
return sum | |||
} |
@@ -167,6 +167,11 @@ func GetTimeRange(s string) map[string]int64 { | |||
stime = time.Date(t.Year(), t.Month(), t.Day()-6, 0, 0, 0, 0, t.Location()) | |||
// 明天 0点 | |||
etime = time.Date(t.Year(), t.Month(), t.Day()+1, 0, 0, 0, 0, t.Location()) | |||
case "new_within_seven_days": | |||
// 前7天0点 | |||
stime = time.Date(t.Year(), t.Month(), t.Day()-7, 0, 0, 0, 0, t.Location()) | |||
// 今日 0点 | |||
etime = time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location()) | |||
case "current_month": | |||
stime = time.Date(t.Year(), t.Month(), 0, 0, 0, 0, 0, t.Location()) | |||
etime = time.Date(t.Year(), t.Month()+1, 0, 0, 0, 0, 0, t.Location()) | |||
@@ -209,18 +214,18 @@ func GetDateTimeRangeStr(s string) (string, string) { | |||
return stime.Format("2006-01-02 15:04:05"), etime.Format("2006-01-02 15:04:05") | |||
} | |||
//获取传入的时间所在月份的第一天,即某月第一天的0点。如传入time.Now(), 返回当前月份的第一天0点时间。 | |||
// 获取传入的时间所在月份的第一天,即某月第一天的0点。如传入time.Now(), 返回当前月份的第一天0点时间。 | |||
func GetFirstDateOfMonth(d time.Time) time.Time { | |||
d = d.AddDate(0, 0, -d.Day()+1) | |||
return GetZeroTime(d) | |||
} | |||
//获取传入的时间所在月份的最后一天,即某月最后一天的0点。如传入time.Now(), 返回当前月份的最后一天0点时间。 | |||
// 获取传入的时间所在月份的最后一天,即某月最后一天的0点。如传入time.Now(), 返回当前月份的最后一天0点时间。 | |||
func GetLastDateOfMonth(d time.Time) time.Time { | |||
return GetFirstDateOfMonth(d).AddDate(0, 1, -1) | |||
} | |||
//获取某一天的0点时间 | |||
// 获取某一天的0点时间 | |||
func GetZeroTime(d time.Time) time.Time { | |||
return time.Date(d.Year(), d.Month(), d.Day(), 0, 0, 0, 0, d.Location()) | |||
} |
@@ -0,0 +1,36 @@ | |||
package utils | |||
import ( | |||
"bytes" | |||
"fmt" | |||
"github.com/360EntSecGroup-Skylar/excelize" | |||
"github.com/gin-gonic/gin" | |||
"io/ioutil" | |||
) | |||
func Output(c *gin.Context, name string, data map[string]string) string { | |||
//创建excel文件 | |||
xlsx := excelize.NewFile() | |||
//创建新表单 | |||
index := xlsx.NewSheet(name) | |||
for k, v := range data { | |||
//设置单元格的值 | |||
xlsx.SetCellValue(name, k, v) | |||
} | |||
//设置默认打开的表单 | |||
xlsx.SetActiveSheet(index) | |||
////保存文件到指定路径 | |||
//err := xlsx.SaveAs("./" + name + ".xlsx") | |||
//if err != nil { | |||
// log.Fatal(err) | |||
//} | |||
//_ = file.Save(fileName) | |||
c.Header("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, name+".xlsx")) | |||
c.Header("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") | |||
var buffer bytes.Buffer | |||
_ = xlsx.Write(&buffer) | |||
r := bytes.NewReader(buffer.Bytes()) | |||
fSrc, _ := ioutil.ReadAll(r) | |||
str := "data:application/vnd.ms-excel;base64," + Base64RawStdEncode(string(fSrc)) | |||
return str | |||
} |
@@ -562,6 +562,53 @@ const docTemplate = `{ | |||
} | |||
} | |||
}, | |||
"/api/dataCenter/record/output": { | |||
"post": { | |||
"description": "数据中心-数据明细-导出", | |||
"consumes": [ | |||
"application/json" | |||
], | |||
"produces": [ | |||
"application/json" | |||
], | |||
"tags": [ | |||
"数据中心------嘉俊" | |||
], | |||
"summary": "数据明细-导出", | |||
"parameters": [ | |||
{ | |||
"type": "string", | |||
"description": "验证参数Bearer和token空格拼接", | |||
"name": "Authorization", | |||
"in": "header", | |||
"required": true | |||
}, | |||
{ | |||
"description": "请求参数", | |||
"name": "args", | |||
"in": "body", | |||
"required": true, | |||
"schema": { | |||
"$ref": "#/definitions/md.DataCenterRecordOutPutReq" | |||
} | |||
} | |||
], | |||
"responses": { | |||
"200": { | |||
"description": "具体看返回内容 这是data里面的数据", | |||
"schema": { | |||
"type": "string" | |||
} | |||
}, | |||
"400": { | |||
"description": "具体错误", | |||
"schema": { | |||
"$ref": "#/definitions/md.Response" | |||
} | |||
} | |||
} | |||
} | |||
}, | |||
"/api/dataCenter/record/total": { | |||
"post": { | |||
"description": "数据中心-数据明细合计", | |||
@@ -694,6 +741,129 @@ const docTemplate = `{ | |||
} | |||
} | |||
}, | |||
"/api/index/app/list": { | |||
"post": { | |||
"description": "数据中心-数据明细", | |||
"consumes": [ | |||
"application/json" | |||
], | |||
"produces": [ | |||
"application/json" | |||
], | |||
"tags": [ | |||
"数据中心------嘉俊" | |||
], | |||
"summary": "数据明细", | |||
"parameters": [ | |||
{ | |||
"type": "string", | |||
"description": "验证参数Bearer和token空格拼接", | |||
"name": "Authorization", | |||
"in": "header", | |||
"required": true | |||
}, | |||
{ | |||
"description": "请求参数", | |||
"name": "args", | |||
"in": "body", | |||
"required": true, | |||
"schema": { | |||
"$ref": "#/definitions/md.IndexAppListReq" | |||
} | |||
} | |||
], | |||
"responses": { | |||
"200": { | |||
"description": "具体看返回内容 这是data里面的数据", | |||
"schema": { | |||
"$ref": "#/definitions/md.IndexAppListRes" | |||
} | |||
}, | |||
"400": { | |||
"description": "具体错误", | |||
"schema": { | |||
"$ref": "#/definitions/md.Response" | |||
} | |||
} | |||
} | |||
} | |||
}, | |||
"/api/index/base": { | |||
"get": { | |||
"description": "首页-右上角基本数据", | |||
"consumes": [ | |||
"application/json" | |||
], | |||
"produces": [ | |||
"application/json" | |||
], | |||
"tags": [ | |||
"首页------嘉俊" | |||
], | |||
"summary": "右上角基本数据", | |||
"parameters": [ | |||
{ | |||
"type": "string", | |||
"description": "验证参数Bearer和token空格拼接", | |||
"name": "Authorization", | |||
"in": "header", | |||
"required": true | |||
} | |||
], | |||
"responses": { | |||
"200": { | |||
"description": "具体看返回内容 这是data里面的数据", | |||
"schema": { | |||
"type": "string" | |||
} | |||
}, | |||
"400": { | |||
"description": "具体错误", | |||
"schema": { | |||
"$ref": "#/definitions/md.Response" | |||
} | |||
} | |||
} | |||
} | |||
}, | |||
"/api/index/total": { | |||
"get": { | |||
"description": "首页-统计数据", | |||
"consumes": [ | |||
"application/json" | |||
], | |||
"produces": [ | |||
"application/json" | |||
], | |||
"tags": [ | |||
"首页------嘉俊" | |||
], | |||
"summary": "统计数据", | |||
"parameters": [ | |||
{ | |||
"type": "string", | |||
"description": "验证参数Bearer和token空格拼接", | |||
"name": "Authorization", | |||
"in": "header", | |||
"required": true | |||
} | |||
], | |||
"responses": { | |||
"200": { | |||
"description": "具体看返回内容 这是data里面的数据", | |||
"schema": { | |||
"type": "string" | |||
} | |||
}, | |||
"400": { | |||
"description": "具体错误", | |||
"schema": { | |||
"$ref": "#/definitions/md.Response" | |||
} | |||
} | |||
} | |||
} | |||
}, | |||
"/api/invoiceCenter/detail": { | |||
"post": { | |||
"description": "发票中心-发票详情", | |||
@@ -2224,6 +2394,38 @@ const docTemplate = `{ | |||
} | |||
} | |||
}, | |||
"md.DataCenterRecordOutPutReq": { | |||
"type": "object", | |||
"properties": { | |||
"ad_type": { | |||
"type": "string", | |||
"example": "广告位类型" | |||
}, | |||
"app_id": { | |||
"type": "string", | |||
"example": "应用" | |||
}, | |||
"end_date": { | |||
"type": "string", | |||
"example": "2024-08-30" | |||
}, | |||
"limit": { | |||
"type": "string", | |||
"example": "10000 个一页" | |||
}, | |||
"page": { | |||
"type": "string" | |||
}, | |||
"platform": { | |||
"type": "string", | |||
"example": "平台" | |||
}, | |||
"start_date": { | |||
"type": "string", | |||
"example": "2024-08-30" | |||
} | |||
} | |||
}, | |||
"md.DataCenterRecordReq": { | |||
"type": "object", | |||
"properties": { | |||
@@ -2379,6 +2581,80 @@ const docTemplate = `{ | |||
} | |||
} | |||
}, | |||
"md.IndexAppListData": { | |||
"type": "object", | |||
"properties": { | |||
"list": { | |||
"type": "array", | |||
"items": { | |||
"$ref": "#/definitions/md.IndexAppListDataList" | |||
} | |||
}, | |||
"logo": { | |||
"type": "string" | |||
}, | |||
"name": { | |||
"type": "string" | |||
}, | |||
"table_list": { | |||
"type": "array", | |||
"items": { | |||
"type": "string" | |||
} | |||
} | |||
} | |||
}, | |||
"md.IndexAppListDataList": { | |||
"type": "object", | |||
"properties": { | |||
"bili": { | |||
"type": "string" | |||
}, | |||
"name": { | |||
"type": "string" | |||
}, | |||
"type": { | |||
"type": "string" | |||
}, | |||
"value": { | |||
"type": "string" | |||
} | |||
} | |||
}, | |||
"md.IndexAppListReq": { | |||
"type": "object", | |||
"properties": { | |||
"end_date": { | |||
"type": "string", | |||
"example": "2024-08-30" | |||
}, | |||
"sort": { | |||
"type": "string", | |||
"example": "排序" | |||
}, | |||
"start_date": { | |||
"type": "string", | |||
"example": "2024-08-30" | |||
} | |||
} | |||
}, | |||
"md.IndexAppListRes": { | |||
"type": "object", | |||
"properties": { | |||
"list": { | |||
"type": "array", | |||
"items": { | |||
"$ref": "#/definitions/md.IndexAppListData" | |||
} | |||
}, | |||
"sort": { | |||
"type": "array", | |||
"items": { | |||
"$ref": "#/definitions/md.SelectData" | |||
} | |||
} | |||
} | |||
}, | |||
"md.Invoice": { | |||
"type": "object", | |||
"properties": { | |||
@@ -554,6 +554,53 @@ | |||
} | |||
} | |||
}, | |||
"/api/dataCenter/record/output": { | |||
"post": { | |||
"description": "数据中心-数据明细-导出", | |||
"consumes": [ | |||
"application/json" | |||
], | |||
"produces": [ | |||
"application/json" | |||
], | |||
"tags": [ | |||
"数据中心------嘉俊" | |||
], | |||
"summary": "数据明细-导出", | |||
"parameters": [ | |||
{ | |||
"type": "string", | |||
"description": "验证参数Bearer和token空格拼接", | |||
"name": "Authorization", | |||
"in": "header", | |||
"required": true | |||
}, | |||
{ | |||
"description": "请求参数", | |||
"name": "args", | |||
"in": "body", | |||
"required": true, | |||
"schema": { | |||
"$ref": "#/definitions/md.DataCenterRecordOutPutReq" | |||
} | |||
} | |||
], | |||
"responses": { | |||
"200": { | |||
"description": "具体看返回内容 这是data里面的数据", | |||
"schema": { | |||
"type": "string" | |||
} | |||
}, | |||
"400": { | |||
"description": "具体错误", | |||
"schema": { | |||
"$ref": "#/definitions/md.Response" | |||
} | |||
} | |||
} | |||
} | |||
}, | |||
"/api/dataCenter/record/total": { | |||
"post": { | |||
"description": "数据中心-数据明细合计", | |||
@@ -686,6 +733,129 @@ | |||
} | |||
} | |||
}, | |||
"/api/index/app/list": { | |||
"post": { | |||
"description": "数据中心-数据明细", | |||
"consumes": [ | |||
"application/json" | |||
], | |||
"produces": [ | |||
"application/json" | |||
], | |||
"tags": [ | |||
"数据中心------嘉俊" | |||
], | |||
"summary": "数据明细", | |||
"parameters": [ | |||
{ | |||
"type": "string", | |||
"description": "验证参数Bearer和token空格拼接", | |||
"name": "Authorization", | |||
"in": "header", | |||
"required": true | |||
}, | |||
{ | |||
"description": "请求参数", | |||
"name": "args", | |||
"in": "body", | |||
"required": true, | |||
"schema": { | |||
"$ref": "#/definitions/md.IndexAppListReq" | |||
} | |||
} | |||
], | |||
"responses": { | |||
"200": { | |||
"description": "具体看返回内容 这是data里面的数据", | |||
"schema": { | |||
"$ref": "#/definitions/md.IndexAppListRes" | |||
} | |||
}, | |||
"400": { | |||
"description": "具体错误", | |||
"schema": { | |||
"$ref": "#/definitions/md.Response" | |||
} | |||
} | |||
} | |||
} | |||
}, | |||
"/api/index/base": { | |||
"get": { | |||
"description": "首页-右上角基本数据", | |||
"consumes": [ | |||
"application/json" | |||
], | |||
"produces": [ | |||
"application/json" | |||
], | |||
"tags": [ | |||
"首页------嘉俊" | |||
], | |||
"summary": "右上角基本数据", | |||
"parameters": [ | |||
{ | |||
"type": "string", | |||
"description": "验证参数Bearer和token空格拼接", | |||
"name": "Authorization", | |||
"in": "header", | |||
"required": true | |||
} | |||
], | |||
"responses": { | |||
"200": { | |||
"description": "具体看返回内容 这是data里面的数据", | |||
"schema": { | |||
"type": "string" | |||
} | |||
}, | |||
"400": { | |||
"description": "具体错误", | |||
"schema": { | |||
"$ref": "#/definitions/md.Response" | |||
} | |||
} | |||
} | |||
} | |||
}, | |||
"/api/index/total": { | |||
"get": { | |||
"description": "首页-统计数据", | |||
"consumes": [ | |||
"application/json" | |||
], | |||
"produces": [ | |||
"application/json" | |||
], | |||
"tags": [ | |||
"首页------嘉俊" | |||
], | |||
"summary": "统计数据", | |||
"parameters": [ | |||
{ | |||
"type": "string", | |||
"description": "验证参数Bearer和token空格拼接", | |||
"name": "Authorization", | |||
"in": "header", | |||
"required": true | |||
} | |||
], | |||
"responses": { | |||
"200": { | |||
"description": "具体看返回内容 这是data里面的数据", | |||
"schema": { | |||
"type": "string" | |||
} | |||
}, | |||
"400": { | |||
"description": "具体错误", | |||
"schema": { | |||
"$ref": "#/definitions/md.Response" | |||
} | |||
} | |||
} | |||
} | |||
}, | |||
"/api/invoiceCenter/detail": { | |||
"post": { | |||
"description": "发票中心-发票详情", | |||
@@ -2216,6 +2386,38 @@ | |||
} | |||
} | |||
}, | |||
"md.DataCenterRecordOutPutReq": { | |||
"type": "object", | |||
"properties": { | |||
"ad_type": { | |||
"type": "string", | |||
"example": "广告位类型" | |||
}, | |||
"app_id": { | |||
"type": "string", | |||
"example": "应用" | |||
}, | |||
"end_date": { | |||
"type": "string", | |||
"example": "2024-08-30" | |||
}, | |||
"limit": { | |||
"type": "string", | |||
"example": "10000 个一页" | |||
}, | |||
"page": { | |||
"type": "string" | |||
}, | |||
"platform": { | |||
"type": "string", | |||
"example": "平台" | |||
}, | |||
"start_date": { | |||
"type": "string", | |||
"example": "2024-08-30" | |||
} | |||
} | |||
}, | |||
"md.DataCenterRecordReq": { | |||
"type": "object", | |||
"properties": { | |||
@@ -2371,6 +2573,80 @@ | |||
} | |||
} | |||
}, | |||
"md.IndexAppListData": { | |||
"type": "object", | |||
"properties": { | |||
"list": { | |||
"type": "array", | |||
"items": { | |||
"$ref": "#/definitions/md.IndexAppListDataList" | |||
} | |||
}, | |||
"logo": { | |||
"type": "string" | |||
}, | |||
"name": { | |||
"type": "string" | |||
}, | |||
"table_list": { | |||
"type": "array", | |||
"items": { | |||
"type": "string" | |||
} | |||
} | |||
} | |||
}, | |||
"md.IndexAppListDataList": { | |||
"type": "object", | |||
"properties": { | |||
"bili": { | |||
"type": "string" | |||
}, | |||
"name": { | |||
"type": "string" | |||
}, | |||
"type": { | |||
"type": "string" | |||
}, | |||
"value": { | |||
"type": "string" | |||
} | |||
} | |||
}, | |||
"md.IndexAppListReq": { | |||
"type": "object", | |||
"properties": { | |||
"end_date": { | |||
"type": "string", | |||
"example": "2024-08-30" | |||
}, | |||
"sort": { | |||
"type": "string", | |||
"example": "排序" | |||
}, | |||
"start_date": { | |||
"type": "string", | |||
"example": "2024-08-30" | |||
} | |||
} | |||
}, | |||
"md.IndexAppListRes": { | |||
"type": "object", | |||
"properties": { | |||
"list": { | |||
"type": "array", | |||
"items": { | |||
"$ref": "#/definitions/md.IndexAppListData" | |||
} | |||
}, | |||
"sort": { | |||
"type": "array", | |||
"items": { | |||
"$ref": "#/definitions/md.SelectData" | |||
} | |||
} | |||
} | |||
}, | |||
"md.Invoice": { | |||
"type": "object", | |||
"properties": { | |||
@@ -275,6 +275,29 @@ definitions: | |||
example: 列表id | |||
type: string | |||
type: object | |||
md.DataCenterRecordOutPutReq: | |||
properties: | |||
ad_type: | |||
example: 广告位类型 | |||
type: string | |||
app_id: | |||
example: 应用 | |||
type: string | |||
end_date: | |||
example: "2024-08-30" | |||
type: string | |||
limit: | |||
example: 10000 个一页 | |||
type: string | |||
page: | |||
type: string | |||
platform: | |||
example: 平台 | |||
type: string | |||
start_date: | |||
example: "2024-08-30" | |||
type: string | |||
type: object | |||
md.DataCenterRecordReq: | |||
properties: | |||
ad_type: | |||
@@ -383,6 +406,55 @@ definitions: | |||
description: 文件大小, 单位byte | |||
type: integer | |||
type: object | |||
md.IndexAppListData: | |||
properties: | |||
list: | |||
items: | |||
$ref: '#/definitions/md.IndexAppListDataList' | |||
type: array | |||
logo: | |||
type: string | |||
name: | |||
type: string | |||
table_list: | |||
items: | |||
type: string | |||
type: array | |||
type: object | |||
md.IndexAppListDataList: | |||
properties: | |||
bili: | |||
type: string | |||
name: | |||
type: string | |||
type: | |||
type: string | |||
value: | |||
type: string | |||
type: object | |||
md.IndexAppListReq: | |||
properties: | |||
end_date: | |||
example: "2024-08-30" | |||
type: string | |||
sort: | |||
example: 排序 | |||
type: string | |||
start_date: | |||
example: "2024-08-30" | |||
type: string | |||
type: object | |||
md.IndexAppListRes: | |||
properties: | |||
list: | |||
items: | |||
$ref: '#/definitions/md.IndexAppListData' | |||
type: array | |||
sort: | |||
items: | |||
$ref: '#/definitions/md.SelectData' | |||
type: array | |||
type: object | |||
md.Invoice: | |||
properties: | |||
count: | |||
@@ -1201,6 +1273,37 @@ paths: | |||
summary: 数据明细 | |||
tags: | |||
- 数据中心------嘉俊 | |||
/api/dataCenter/record/output: | |||
post: | |||
consumes: | |||
- application/json | |||
description: 数据中心-数据明细-导出 | |||
parameters: | |||
- description: 验证参数Bearer和token空格拼接 | |||
in: header | |||
name: Authorization | |||
required: true | |||
type: string | |||
- description: 请求参数 | |||
in: body | |||
name: args | |||
required: true | |||
schema: | |||
$ref: '#/definitions/md.DataCenterRecordOutPutReq' | |||
produces: | |||
- application/json | |||
responses: | |||
"200": | |||
description: 具体看返回内容 这是data里面的数据 | |||
schema: | |||
type: string | |||
"400": | |||
description: 具体错误 | |||
schema: | |||
$ref: '#/definitions/md.Response' | |||
summary: 数据明细-导出 | |||
tags: | |||
- 数据中心------嘉俊 | |||
/api/dataCenter/record/total: | |||
post: | |||
consumes: | |||
@@ -1288,6 +1391,87 @@ paths: | |||
summary: 数据图表 | |||
tags: | |||
- 数据中心------嘉俊 | |||
/api/index/app/list: | |||
post: | |||
consumes: | |||
- application/json | |||
description: 数据中心-数据明细 | |||
parameters: | |||
- description: 验证参数Bearer和token空格拼接 | |||
in: header | |||
name: Authorization | |||
required: true | |||
type: string | |||
- description: 请求参数 | |||
in: body | |||
name: args | |||
required: true | |||
schema: | |||
$ref: '#/definitions/md.IndexAppListReq' | |||
produces: | |||
- application/json | |||
responses: | |||
"200": | |||
description: 具体看返回内容 这是data里面的数据 | |||
schema: | |||
$ref: '#/definitions/md.IndexAppListRes' | |||
"400": | |||
description: 具体错误 | |||
schema: | |||
$ref: '#/definitions/md.Response' | |||
summary: 数据明细 | |||
tags: | |||
- 数据中心------嘉俊 | |||
/api/index/base: | |||
get: | |||
consumes: | |||
- application/json | |||
description: 首页-右上角基本数据 | |||
parameters: | |||
- description: 验证参数Bearer和token空格拼接 | |||
in: header | |||
name: Authorization | |||
required: true | |||
type: string | |||
produces: | |||
- application/json | |||
responses: | |||
"200": | |||
description: 具体看返回内容 这是data里面的数据 | |||
schema: | |||
type: string | |||
"400": | |||
description: 具体错误 | |||
schema: | |||
$ref: '#/definitions/md.Response' | |||
summary: 右上角基本数据 | |||
tags: | |||
- 首页------嘉俊 | |||
/api/index/total: | |||
get: | |||
consumes: | |||
- application/json | |||
description: 首页-统计数据 | |||
parameters: | |||
- description: 验证参数Bearer和token空格拼接 | |||
in: header | |||
name: Authorization | |||
required: true | |||
type: string | |||
produces: | |||
- application/json | |||
responses: | |||
"200": | |||
description: 具体看返回内容 这是data里面的数据 | |||
schema: | |||
type: string | |||
"400": | |||
description: 具体错误 | |||
schema: | |||
$ref: '#/definitions/md.Response' | |||
summary: 统计数据 | |||
tags: | |||
- 首页------嘉俊 | |||
/api/invoiceCenter/detail: | |||
post: | |||
consumes: | |||
@@ -3,9 +3,10 @@ module applet | |||
go 1.18 | |||
//replace code.fnuoos.com/zhimeng/model.git => E:/company/ad/models | |||
// | |||
require ( | |||
code.fnuoos.com/zhimeng/model.git v0.0.3-0.20240830085315-046c30582759 | |||
code.fnuoos.com/zhimeng/model.git v0.0.3-0.20240831024508-c37ec92bfc03 | |||
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 | |||
github.com/boombuler/barcode v1.0.1 | |||
github.com/dchest/uniuri v0.0.0-20200228104902-7aecb25e1fe5 | |||
@@ -37,6 +38,7 @@ require ( | |||
require ( | |||
code.fnuoos.com/go_rely_warehouse/zyos_go_third_party_api.git v1.1.21-0.20240821062104-50d608c7fd6a | |||
github.com/360EntSecGroup-Skylar/excelize v1.4.1 | |||
github.com/jinzhu/copier v0.4.0 | |||
) | |||
@@ -76,6 +78,7 @@ require ( | |||
github.com/mattn/go-isatty v0.0.19 // indirect | |||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect | |||
github.com/modern-go/reflect2 v1.0.2 // indirect | |||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect | |||
github.com/pelletier/go-toml/v2 v2.0.6 // indirect | |||
github.com/pkg/errors v0.9.1 // indirect | |||
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect | |||