Browse Source

update

master
dengbiao 3 months ago
parent
commit
c129f2056f
11 changed files with 326 additions and 11 deletions
  1. +5
    -0
      app/db/dao/original_wx_ad_data_dao.go
  2. +14
    -0
      app/db/implement/original_wx_ad_data_implement.go
  3. +35
    -9
      app/hdl/hdl_demo.go
  4. +0
    -1
      app/hdl/hdl_set_center.go
  5. +23
    -0
      app/lib/wechat/md/wechat_api_md.go
  6. +32
    -0
      app/lib/wechat/wechat_api.go
  7. +15
    -0
      app/md/md_generate_wx_ad_data.go
  8. +1
    -0
      app/router/router.go
  9. +197
    -0
      app/svc/svc_wx_data.go
  10. +3
    -0
      app/utils/convert.go
  11. +1
    -1
      go.mod

+ 5
- 0
app/db/dao/original_wx_ad_data_dao.go View File

@@ -0,0 +1,5 @@
package dao

type OriginalWxAdDataDao interface {
//TODO:: You can add specific method definitions here
}

+ 14
- 0
app/db/implement/original_wx_ad_data_implement.go View File

@@ -0,0 +1,14 @@
package implement

import (
"applet/app/db/dao"
"xorm.io/xorm"
)

func NewOriginalWxAdDataDb(engine *xorm.Engine) dao.OriginalWxAdDataDao {
return &OriginalWxAdDataDb{Db: engine}
}

type OriginalWxAdDataDb struct {
Db *xorm.Engine
}

+ 35
- 9
app/hdl/hdl_demo.go View File

@@ -2,24 +2,50 @@ package hdl

import (
"applet/app/e"
"applet/app/lib/wechat"
"applet/app/svc"
"applet/app/utils"
"fmt"
db "code.fnuoos.com/zhimeng/model.git/src"
"code.fnuoos.com/zhimeng/model.git/src/super/implement"
"github.com/gin-gonic/gin"
)

func Demo(c *gin.Context) {
mediumId := utils.GenerateUniqueRandomNumbers(8)
fmt.Println(mediumId)
var args interface{}
err := c.ShouldBindJSON(&args)
appId := c.DefaultQuery("app_id", "")
masterId := svc.GetMasterId(c)
adUnitId := c.DefaultQuery("adunit_id", "")

//1、查找对应 user_wx_applet_list 记录
userWxAppletListDb := implement.NewUserWxAppletListDb(db.Db)
UserWxAppletList, err := userWxAppletListDb.GetUserWxAppletList(masterId)
if err != nil {
err = svc.HandleValidateErr(err)
err1 := err.(e.E)
e.OutErr(c, err1.Code, err1.Error())
e.OutErr(c, e.ERR_DB_ORM, err.Error())
return
}
if UserWxAppletList == nil {
e.OutErr(c, e.ERR_NO_DATA, "未查询到对应记录")
return
}
wxOpenThirdPartyAppListDb := implement.NewWxOpenThirdPartyAppListDb(db.Db)
wxOpenThirdPartyAppList, err := wxOpenThirdPartyAppListDb.GetWxOpenThirdPartyAppList(utils.StrToInt(masterId))
if err != nil {
e.OutErr(c, e.ERR, err.Error())
return
}
if wxOpenThirdPartyAppList == nil {
e.OutErr(c, e.ERR_NOT_FAN, "未查询到对应三方应用记录")
return
}
wxApiService, err := wechat.NewWxApiService(masterId, wxOpenThirdPartyAppList.Appid, wxOpenThirdPartyAppList.AppSecret)
if err != nil {
e.OutErr(c, e.ERR, err.Error())
return
}
err, args := wxApiService.GetAdposDetail(appId, 1, 10, "2024-08-19", "2024-08-23", adUnitId)
if err != nil {
e.OutErr(c, e.ERR, err.Error())
return
}

e.OutSuc(c, map[string]interface{}{
"args": args,
}, nil)


+ 0
- 1
app/hdl/hdl_set_center.go View File

@@ -417,7 +417,6 @@ func AppletUnauthorized(c *gin.Context) {
e.OutErr(c, e.ERR_NOT_FAN, "未查询到对应三方应用记录")
return
}

wxApiService, err := wechat.NewWxApiService(masterId, wxOpenThirdPartyAppList.Appid, wxOpenThirdPartyAppList.AppSecret)
if err != nil {
e.OutErr(c, e.ERR, err.Error())


+ 23
- 0
app/lib/wechat/md/wechat_api_md.go View File

@@ -60,3 +60,26 @@ type GetAdunitList struct {
} `json:"ad_unit"`
TotalNum int `json:"total_num" example:"总广告单元数据量"`
}

type GetAdposDetail struct {
Ret int `json:"ret" example:"错误码"`
ErrMsg string `json:"err_msg" example:"错误信息"`
List []struct {
AdUnitId string `json:"ad_unit_id" example:"广告单元ID"`
AdUnitName string `json:"ad_unit_name" example:"广告单元名称"`
AppId string `json:"appid" example:"授权方 appid"`
StatItem struct {
AdSlot string `json:"ad_slot" example:"广告位类型名称"`
Date string `json:"date" example:"数据日期"`
ExposureCount int64 `json:"exposure_count" example:"曝光量"`
ReqSuccCount int64 `json:"req_succ_count" example:"拉取量"`
PublisherIncome int64 `json:"publisher_income" example:"小程序分账收入(分)"`
ClickCount int64 `json:"click_count" example:"点击量"`
Income float64 `json:"income"`
Ecpm float64 `json:"ecpm" example:"广告千次曝光收益(分)"`
ExposureRate float64 `json:"exposure_rate" example:"曝光率"`
ClickRate float64 `json:"click_rate" example:"点击量"`
} `json:"stat_item"`
} `json:"list"`
TotalNum int `json:"total_num" example:"请求返回总数"`
}

+ 32
- 0
app/lib/wechat/wechat_api.go View File

@@ -320,3 +320,35 @@ func (wxApiService *WxApiService) GetAdunitList(appId string, page, pageSize int
}
return
}

/*
GetAdposDetail 获取小程序广告细分数据
*/
func (wxApiService *WxApiService) GetAdposDetail(appId string, page, pageSize int, startDate, endDate, adUnitId string) (err error, resp md.GetAdposDetail) { // set方法
apiAuthorizerToken, err := wxApiService.GetAuth(appId)
if err != nil {
return
}
url := "https://api.weixin.qq.com/wxa/operationams?action=agency_get_adunit_general&access_token=" + apiAuthorizerToken
params := map[string]interface{}{
"page": page,
"page_size": pageSize,
"ad_unit_id": adUnitId,
"start_date": startDate,
"end_date": endDate,
}
fmt.Println(utils.SerializeStr(params))
postBody, err := utils.CurlPost(url, utils.SerializeStr(params), nil)
if err != nil {
return
}

err = json.Unmarshal(postBody, &resp)
if err != nil {
return
}
if resp.Ret != 0 {
err = errors.New(resp.ErrMsg)
}
return
}

+ 15
- 0
app/md/md_generate_wx_ad_data.go View File

@@ -0,0 +1,15 @@
package md

type GenerateWxAdData struct {
GenerateDataId int `json:"generate_data_id" example:"原始数据id"`
OriginalExposureCount int `json:"original_exposure_count" example:"原-曝光量"`
OriginalEcpm string `json:"original_ecpm" example:"原-广告千次曝光收益(分)"`
NowExposureCount int `json:"now_exposure_count" example:"现-曝光量"`
NowEcpm string `json:"now_ecpm" example:"现-广告千次曝光收益(分)"`
}

type ClacEcpmReq struct {
OriginalExposureCount int `json:"original_exposure_count" example:"原-曝光量"`
OriginalEcpm string `json:"original_ecpm" example:"原-广告千次曝光收益(分)"`
GenerateDataId int `json:"generate_data_id" example:"原始数据id"`
}

+ 1
- 0
app/router/router.go View File

@@ -51,6 +51,7 @@ func Init() *gin.Engine {

func route(r *gin.RouterGroup) {
r.GET("/test", hdl.Demo)
r.GET("/authorize", hdl.AppletAuthorize)

r.Use(mw.DB) // 以下接口需要用到数据库
{


+ 197
- 0
app/svc/svc_wx_data.go View File

@@ -0,0 +1,197 @@
package svc

import (
"applet/app/md"
"applet/app/utils"
db "code.fnuoos.com/zhimeng/model.git/src"
"code.fnuoos.com/zhimeng/model.git/src/super/implement"
"code.fnuoos.com/zhimeng/model.git/src/super/model"
"errors"
"time"
)

func GenerateWxAdData(req md.GenerateWxAdData) (err error, generateWxAdData model.GenerateWxAdData) {
//1、查找原始数据记录
originalWxAdDataDb := implement.NewOriginalWxAdDataDb(db.Db)
originalWxAdData, err := originalWxAdDataDb.GetOriginalWxAdData(req.GenerateDataId)
if err != nil {
return
}
if originalWxAdData == nil {
err = errors.New("未查询到原始数据记录")
return
}

//2、查询对应媒体、代理的分成策略
mediumDivisionStrategyDb := implement.NewMediumDivisionStrategyDb(db.Db)
mediumDivisionStrategy, err := mediumDivisionStrategyDb.GetOriginalWxAdDataByMediumId(originalWxAdData.MediumId)
if err != nil {
return
}
if mediumDivisionStrategy == nil {
err = errors.New("未查询到对应代理的分成策略")
return
}
mediumDivisionStrategyWithAgentFlowDb := implement.NewMediumDivisionStrategyWithAgentFlowDb(db.Db)
mediumDivisionStrategyWithAgentFlows, err := mediumDivisionStrategyWithAgentFlowDb.FindMediumDivisionStrategyWithAgentFlowByStrategyId(mediumDivisionStrategy.MediumId)
if err != nil {
return
}

//3、计算媒体、代理收益、平台留存、佣金留存、协议分成、协议总分成
publisherIncome := originalWxAdData.PublisherIncome
mediaRevenue := publisherIncome * mediumDivisionStrategy.MediaRevenueRate / 100 //媒体收益
agentRevenue := publisherIncome * mediumDivisionStrategy.AgentRevenueRate / 100 //代理收益
platformRetention := publisherIncome * mediumDivisionStrategy.PlatformRetentionRate / 100 //平台留存
commissionRetention := publisherIncome * mediumDivisionStrategy.CommissionRetentionRate / 100 //佣金留存
agreementSharingTotal := (mediaRevenue + agentRevenue) / (100 - mediumDivisionStrategy.AgreementSharingRate) //协议总分成(倒推)
agreementSharing := agreementSharingTotal - (mediaRevenue + agentRevenue) //协议分成

//3、判断是否有调价留存
var priceAdjustmentRetention int
if req.NowEcpm != req.OriginalEcpm || req.NowExposureCount != req.OriginalExposureCount {
tmpMediaRevenue := int(utils.StrToFloat64(req.NowEcpm) * float64(req.NowExposureCount) / 1000)
priceAdjustmentRetention = tmpMediaRevenue - mediaRevenue
mediaRevenue = tmpMediaRevenue
}

//4、计算各代理收益
var extraRevenue int
var agentRevenueFlows []struct {
AgentId int `json:"agent_id"`
AgentRevenueRate int `json:"agent_revenue_rate"`
ExtraRevenueRate int `json:"extra_revenue_rate"`
AgentRevenue int `json:"agent_revenue"`
ExtraRevenue int `json:"extra_revenue"`
}
for _, v := range *mediumDivisionStrategyWithAgentFlows {
tmpAgentRevenue := agentRevenue * v.AgentRevenueRate / 100
tmpExtraRevenue := commissionRetention * v.ExtraRevenueRate / 100
extraRevenue += tmpExtraRevenue
agentRevenueFlows = append(agentRevenueFlows, struct {
AgentId int `json:"agent_id"`
AgentRevenueRate int `json:"agent_revenue_rate"`
ExtraRevenueRate int `json:"extra_revenue_rate"`
AgentRevenue int `json:"agent_revenue"`
ExtraRevenue int `json:"extra_revenue"`
}{
AgentId: v.AgentId,
AgentRevenueRate: v.AgentRevenueRate,
ExtraRevenueRate: v.ExtraRevenueRate,
AgentRevenue: tmpAgentRevenue,
ExtraRevenue: tmpExtraRevenue,
})
}

//5、插入 generate_wx_ad_data 、generate_wx_ad_data_with_agent_flow 数据
session := db.Db.NewSession()
defer session.Close()
session.Begin()

now := time.Now()
generateWxAdData = model.GenerateWxAdData{
Uuid: originalWxAdData.Uuid,
AppId: originalWxAdData.AppId,
GenerateDataId: originalWxAdData.Id,
SlotId: originalWxAdData.SlotId,
AdSlot: originalWxAdData.AdSlot,
Date: originalWxAdData.Date,
ReqSuccCount: originalWxAdData.ReqSuccCount,
ExposureCount: req.NowExposureCount, //现-曝光量
ExposureRate: originalWxAdData.ExposureRate,
ClickCount: originalWxAdData.ClickCount,
ClickRate: originalWxAdData.ClickRate,
Ecpm: req.NowEcpm, //现-ecpm
PlatformRetention: platformRetention,
CommissionRetention: commissionRetention,
PriceAdjustmentRetention: priceAdjustmentRetention,
MediaRevenue: mediaRevenue,
AgentRevenue: agentRevenue,
ExtraRevenue: extraRevenue,
AgreementSharing: agreementSharing,
AgreementSharingTotal: agreementSharingTotal,
PlatformRetentionRate: mediumDivisionStrategy.PlatformRetentionRate,
CommissionRetentionRate: mediumDivisionStrategy.CommissionRetentionRate,
MediaRevenueRate: mediumDivisionStrategy.MediaRevenueRate,
AgentRevenueRate: mediumDivisionStrategy.AgentRevenueRate,
ExtraRevenueRate: mediumDivisionStrategy.ExtraRevenueRate,
AgreementSharingRate: mediumDivisionStrategy.AgreementSharingRate,
IsGenerateReport: 0,
CreateAt: now.Format("2006-01-02 15:04:05"),
UpdateAt: now.Format("2006-01-02 15:04:05"),
}
generateWxAdDataDb := implement.NewGenerateWxAdDataDb(db.Db)
_, err = generateWxAdDataDb.GenerateWxAdDataInsertBySession(session, &generateWxAdData)
if err != nil {
_ = session.Rollback()
return
}

var generateWxAdDataWithAgentFlows []*model.GenerateWxAdDataWithAgentFlow
for _, v := range agentRevenueFlows {
generateWxAdDataWithAgentFlows = append(generateWxAdDataWithAgentFlows, &model.GenerateWxAdDataWithAgentFlow{
Uuid: generateWxAdData.Uuid,
AppId: generateWxAdData.AppId,
AgentId: v.AgentId,
GenerateDataId: generateWxAdData.Id,
SlotId: generateWxAdData.SlotId,
AdSlot: generateWxAdData.AdSlot,
Date: generateWxAdData.Date,
AgentRevenue: v.AgentRevenue,
AgentRevenueRate: v.AgentRevenueRate,
ExtraRevenue: v.ExtraRevenue,
ExtraRevenueRate: v.ExtraRevenueRate,
CreateAt: now.Format("2006-01-02 15:04:05"),
UpdateAt: now.Format("2006-01-02 15:04:05"),
})
}
generateWxAdDataWithAgentFlowDb := implement.NewGenerateWxAdDataWithAgentFlowDb(db.Db)
_, err = generateWxAdDataWithAgentFlowDb.BatchAddGenerateWxAdDataWithAgentFlow(session, generateWxAdDataWithAgentFlows)
if err != nil {
_ = session.Rollback()
return
}

//6、修改 original_wx_ad_data 记录中的 is_apply(是否已应用(0:未 1:已) )
originalWxAdData.IsApply = 1
_, err = originalWxAdDataDb.UpdateOriginalWxAdDataBySession(session, originalWxAdData, "is_apply")
if err != nil {
_ = session.Rollback()
return
}
return session.Commit(), generateWxAdData
}

func ClacEcpm(req md.ClacEcpmReq) (err error, ecpm string) {
//1、查找原始数据记录
originalWxAdDataDb := implement.NewOriginalWxAdDataDb(db.Db)
originalWxAdData, err := originalWxAdDataDb.GetOriginalWxAdData(req.GenerateDataId)
if err != nil {
return
}
if originalWxAdData == nil {
err = errors.New("未查询到原始数据记录")
return
}

//2、查询对应媒体分成策略
mediumDivisionStrategyDb := implement.NewMediumDivisionStrategyDb(db.Db)
mediumDivisionStrategy, err := mediumDivisionStrategyDb.GetOriginalWxAdDataByMediumId(originalWxAdData.MediumId)
if err != nil {
return
}
if mediumDivisionStrategy == nil {
err = errors.New("未查询到对应代理的分成策略")
return
}

//3、计算媒体、代理收益、协议总分成
publisherIncome := originalWxAdData.PublisherIncome
mediaRevenue := publisherIncome * mediumDivisionStrategy.MediaRevenueRate / 100 //媒体收益
agentRevenue := publisherIncome * mediumDivisionStrategy.AgentRevenueRate / 100 //代理收益
agreementSharingTotal := (mediaRevenue + agentRevenue) / (100 - mediumDivisionStrategy.AgreementSharingRate) //协议总分成(倒推)

//4、倒退出当前ecpm值
ecpm = utils.Float64ToStrPrec4(float64(agreementSharingTotal) / (float64(originalWxAdData.ExposureCount) / 1000))
return
}

+ 3
- 0
app/utils/convert.go View File

@@ -276,6 +276,9 @@ func Float64ToStr(f float64) string {
func Float64ToStrPrec1(f float64) string {
return strconv.FormatFloat(f, 'f', 1, 64)
}
func Float64ToStrPrec4(f float64) string {
return strconv.FormatFloat(f, 'f', 1, 64)
}

func Float32ToStr(f float32) string {
return Float64ToStr(float64(f))


+ 1
- 1
go.mod View File

@@ -5,7 +5,7 @@ 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.20240822030431-bf682f937fb0
code.fnuoos.com/zhimeng/model.git v0.0.3-0.20240827055504-c124d0031bf7
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


Loading…
Cancel
Save