广告平台(站长使用)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

svc_wx_data.go 17 KiB

2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. package svc
  2. import (
  3. "applet/app/enum"
  4. "applet/app/md"
  5. "applet/app/utils"
  6. db "code.fnuoos.com/zhimeng/model.git/src"
  7. "code.fnuoos.com/zhimeng/model.git/src/super/implement"
  8. "code.fnuoos.com/zhimeng/model.git/src/super/model"
  9. "errors"
  10. "time"
  11. )
  12. func GenerateWxAdData(req md.GenerateWxAdData) (err error, generateWxAdData model.GenerateWxAdData) {
  13. //1、查找原始数据记录
  14. originalWxAdDataDb := implement.NewOriginalWxAdDataDb(db.Db)
  15. originalWxAdData, err := originalWxAdDataDb.GetOriginalWxAdData(req.OriginalDataId)
  16. if err != nil {
  17. return
  18. }
  19. if originalWxAdData == nil {
  20. err = errors.New("未查询到原始数据记录")
  21. return
  22. }
  23. //2、查询对应媒体、代理的分成策略
  24. mediumDivisionStrategyDb := implement.NewMediumDivisionStrategyDb(db.Db)
  25. mediumDivisionStrategy, err := mediumDivisionStrategyDb.GetOriginalWxAdDataByMediumId(originalWxAdData.MediumId)
  26. if err != nil {
  27. return
  28. }
  29. if mediumDivisionStrategy == nil {
  30. err = errors.New("未查询到对应代理的分成策略")
  31. return
  32. }
  33. mediumDivisionStrategyWithAgentFlowDb := implement.NewMediumDivisionStrategyWithAgentFlowDb(db.Db)
  34. mediumDivisionStrategyWithAgentFlows, err := mediumDivisionStrategyWithAgentFlowDb.FindMediumDivisionStrategyWithAgentFlowByStrategyId(mediumDivisionStrategy.MediumId)
  35. if err != nil {
  36. return
  37. }
  38. //3、计算媒体、代理收益、平台留存、佣金留存、协议分成、协议总分成
  39. publisherIncome := originalWxAdData.PublisherIncome
  40. mediaRevenue := publisherIncome * mediumDivisionStrategy.MediaRevenueRate / 100 //媒体收益
  41. agentRevenue := publisherIncome * mediumDivisionStrategy.AgentRevenueRate / 100 //代理收益
  42. platformRetention := publisherIncome * mediumDivisionStrategy.PlatformRetentionRate / 100 //平台留存
  43. commissionRetention := publisherIncome * mediumDivisionStrategy.CommissionRetentionRate / 100 //佣金留存
  44. agreementSharingTotal := (mediaRevenue + agentRevenue) / (100 - mediumDivisionStrategy.AgreementSharingRate) //协议总分成(倒推)
  45. agreementSharing := agreementSharingTotal - (mediaRevenue + agentRevenue) //协议分成
  46. //3、判断是否有调价留存
  47. var priceAdjustmentRetention int
  48. if req.NowEcpm != req.OriginalEcpm || req.NowExposureCount != req.OriginalExposureCount {
  49. tmpMediaRevenue := int(utils.StrToFloat64(req.NowEcpm) * float64(req.NowExposureCount) / 1000)
  50. priceAdjustmentRetention = tmpMediaRevenue - mediaRevenue
  51. mediaRevenue = tmpMediaRevenue
  52. }
  53. //4、计算各代理收益
  54. var extraRevenue int
  55. var agentRevenueFlows []struct {
  56. AgentId int `json:"agent_id"`
  57. AgentRevenueRate int `json:"agent_revenue_rate"`
  58. ExtraRevenueRate int `json:"extra_revenue_rate"`
  59. AgentRevenue int `json:"agent_revenue"`
  60. ExtraRevenue int `json:"extra_revenue"`
  61. }
  62. for _, v := range *mediumDivisionStrategyWithAgentFlows {
  63. tmpAgentRevenue := agentRevenue * v.AgentRevenueRate / 100
  64. tmpExtraRevenue := commissionRetention * v.ExtraRevenueRate / 100
  65. extraRevenue += tmpExtraRevenue
  66. agentRevenueFlows = append(agentRevenueFlows, struct {
  67. AgentId int `json:"agent_id"`
  68. AgentRevenueRate int `json:"agent_revenue_rate"`
  69. ExtraRevenueRate int `json:"extra_revenue_rate"`
  70. AgentRevenue int `json:"agent_revenue"`
  71. ExtraRevenue int `json:"extra_revenue"`
  72. }{
  73. AgentId: v.AgentId,
  74. AgentRevenueRate: v.AgentRevenueRate,
  75. ExtraRevenueRate: v.ExtraRevenueRate,
  76. AgentRevenue: tmpAgentRevenue,
  77. ExtraRevenue: tmpExtraRevenue,
  78. })
  79. }
  80. //5、插入 generate_wx_ad_data 、generate_wx_ad_data_with_agent_flow 数据
  81. session := db.Db.NewSession()
  82. defer session.Close()
  83. session.Begin()
  84. now := time.Now()
  85. generateWxAdData = model.GenerateWxAdData{
  86. Uuid: originalWxAdData.Uuid,
  87. AppId: originalWxAdData.AppId,
  88. OriginalDataId: originalWxAdData.Id,
  89. SlotId: originalWxAdData.SlotId,
  90. AdSlot: originalWxAdData.AdSlot,
  91. Date: originalWxAdData.Date,
  92. ReqSuccCount: originalWxAdData.ReqSuccCount,
  93. ExposureCount: req.NowExposureCount, //现-曝光量
  94. ExposureRate: originalWxAdData.ExposureRate,
  95. ClickCount: originalWxAdData.ClickCount,
  96. ClickRate: originalWxAdData.ClickRate,
  97. Ecpm: req.NowEcpm, //现-ecpm
  98. PlatformRetention: platformRetention,
  99. CommissionRetention: commissionRetention,
  100. PriceAdjustmentRetention: priceAdjustmentRetention,
  101. MediaRevenue: mediaRevenue,
  102. AgentRevenue: agentRevenue,
  103. ExtraRevenue: extraRevenue,
  104. AgreementSharing: agreementSharing,
  105. AgreementSharingTotal: agreementSharingTotal,
  106. PlatformRetentionRate: mediumDivisionStrategy.PlatformRetentionRate,
  107. CommissionRetentionRate: mediumDivisionStrategy.CommissionRetentionRate,
  108. MediaRevenueRate: mediumDivisionStrategy.MediaRevenueRate,
  109. AgentRevenueRate: mediumDivisionStrategy.AgentRevenueRate,
  110. ExtraRevenueRate: mediumDivisionStrategy.ExtraRevenueRate,
  111. AgreementSharingRate: mediumDivisionStrategy.AgreementSharingRate,
  112. IsGenerateReport: 0,
  113. CreateAt: now.Format("2006-01-02 15:04:05"),
  114. UpdateAt: now.Format("2006-01-02 15:04:05"),
  115. }
  116. generateWxAdDataDb := implement.NewGenerateWxAdDataDb(db.Db)
  117. _, err = generateWxAdDataDb.GenerateWxAdDataInsertBySession(session, &generateWxAdData)
  118. if err != nil {
  119. _ = session.Rollback()
  120. return
  121. }
  122. var generateWxAdDataWithAgentFlows []*model.GenerateWxAdDataWithAgentFlow
  123. for _, v := range agentRevenueFlows {
  124. generateWxAdDataWithAgentFlows = append(generateWxAdDataWithAgentFlows, &model.GenerateWxAdDataWithAgentFlow{
  125. Uuid: generateWxAdData.Uuid,
  126. AppId: generateWxAdData.AppId,
  127. AgentId: v.AgentId,
  128. GenerateDataId: generateWxAdData.Id,
  129. SlotId: generateWxAdData.SlotId,
  130. AdSlot: generateWxAdData.AdSlot,
  131. Date: generateWxAdData.Date,
  132. AgentRevenue: v.AgentRevenue,
  133. AgentRevenueRate: v.AgentRevenueRate,
  134. ExtraRevenue: v.ExtraRevenue,
  135. ExtraRevenueRate: v.ExtraRevenueRate,
  136. CreateAt: now.Format("2006-01-02 15:04:05"),
  137. UpdateAt: now.Format("2006-01-02 15:04:05"),
  138. })
  139. }
  140. generateWxAdDataWithAgentFlowDb := implement.NewGenerateWxAdDataWithAgentFlowDb(db.Db)
  141. _, err = generateWxAdDataWithAgentFlowDb.BatchAddGenerateWxAdDataWithAgentFlow(session, generateWxAdDataWithAgentFlows)
  142. if err != nil {
  143. _ = session.Rollback()
  144. return
  145. }
  146. //6、修改 original_wx_ad_data 记录中的 is_apply(是否已应用(0:未 1:已) )
  147. originalWxAdData.IsApply = 1
  148. _, err = originalWxAdDataDb.UpdateOriginalWxAdDataBySession(session, originalWxAdData, "is_apply")
  149. if err != nil {
  150. _ = session.Rollback()
  151. return
  152. }
  153. return session.Commit(), generateWxAdData
  154. }
  155. func ClacEcpm(req md.ClacEcpmReq) (err error, ecpm string) {
  156. //1、查找原始数据记录
  157. originalWxAdDataDb := implement.NewOriginalWxAdDataDb(db.Db)
  158. originalWxAdData, err := originalWxAdDataDb.GetOriginalWxAdData(req.GenerateDataId)
  159. if err != nil {
  160. return
  161. }
  162. if originalWxAdData == nil {
  163. err = errors.New("未查询到原始数据记录")
  164. return
  165. }
  166. //2、查询对应媒体分成策略
  167. mediumDivisionStrategyDb := implement.NewMediumDivisionStrategyDb(db.Db)
  168. mediumDivisionStrategy, err := mediumDivisionStrategyDb.GetOriginalWxAdDataByMediumId(originalWxAdData.MediumId)
  169. if err != nil {
  170. return
  171. }
  172. if mediumDivisionStrategy == nil {
  173. err = errors.New("未查询到对应代理的分成策略")
  174. return
  175. }
  176. //3、计算媒体、代理收益、协议总分成
  177. publisherIncome := originalWxAdData.PublisherIncome
  178. mediaRevenue := publisherIncome * mediumDivisionStrategy.MediaRevenueRate / 100 //媒体收益
  179. agentRevenue := publisherIncome * mediumDivisionStrategy.AgentRevenueRate / 100 //代理收益
  180. agreementSharingTotal := (mediaRevenue + agentRevenue) / (100 - mediumDivisionStrategy.AgreementSharingRate) //协议总分成(倒推)
  181. //4、倒退出当前ecpm值
  182. ecpm = utils.Float64ToStrPrec4(float64(agreementSharingTotal) / (float64(originalWxAdData.ExposureCount) / 1000))
  183. return
  184. }
  185. func SettlementWxAdData(req md.SettlementWxAdData) (err error) {
  186. //1、查找生成数据记录
  187. generateWxAdDataDb := implement.NewGenerateWxAdDataDb(db.Db)
  188. generateWxAdData, err := generateWxAdDataDb.GetGenerateWxAdData(req.GenerateDataId)
  189. if err != nil {
  190. return
  191. }
  192. if generateWxAdData == nil {
  193. err = errors.New("未查询到生成数据记录")
  194. return
  195. }
  196. originalWxAdDataDb := implement.NewOriginalWxAdDataDb(db.Db)
  197. originalWxAdData, err := originalWxAdDataDb.GetOriginalWxAdData(generateWxAdData.OriginalDataId)
  198. if err != nil {
  199. return
  200. }
  201. if originalWxAdData == nil {
  202. err = errors.New("未查询到原始数据记录")
  203. return
  204. }
  205. //2、查询 生成数据-代理明细 记录
  206. generateWxAdDataWithAgentFlowDb := implement.NewGenerateWxAdDataWithAgentFlowDb(db.Db)
  207. generateWxAdDataWithAgentFlow, err := generateWxAdDataWithAgentFlowDb.FindGenerateWxAdDataWithAgentFlowByStrategyId(generateWxAdData.Id)
  208. if err != nil {
  209. return
  210. }
  211. //3、查询 媒体、代理的结算方式
  212. mediumListDb := implement.NewMediumListDb(db.Db)
  213. medium, err := mediumListDb.GetMediumList(originalWxAdData.MediumId)
  214. if err != nil {
  215. return
  216. }
  217. if medium == nil {
  218. return errors.New("媒体:" + utils.IntToStr(originalWxAdData.MediumId) + "未查询到对应记录")
  219. }
  220. var agentMap = map[int]model.AgentList{}
  221. agentListDb := implement.NewAgentListDb(db.Db)
  222. for _, v := range *generateWxAdDataWithAgentFlow {
  223. agent, err1 := agentListDb.GetAgentList(v.AgentId)
  224. if err1 != nil {
  225. return err1
  226. }
  227. if agent == nil {
  228. return errors.New("代理:" + utils.IntToStr(v.AgentId) + "未查询到对应记录")
  229. }
  230. agentMap[v.AgentId] = *agent
  231. }
  232. //4、生成数据
  233. now := time.Now()
  234. session := db.Db.NewSession()
  235. defer session.Close()
  236. session.Begin()
  237. //4.1 新增/更新 medium_settlement 数据
  238. mediumSettlementDb := implement.NewMediumSettlementDb(db.Db)
  239. mediumSettlement, err := mediumSettlementDb.GetMediumSettlementForAvailable(originalWxAdData.MediumId)
  240. if err != nil {
  241. return
  242. }
  243. var basicIncomeBefore, mediumSettlementState, mediumSettlementPayState int
  244. //判断是否为预付结算类型
  245. if medium.SettlementType == enum.MediumSettlementTypeForPaymentInAdvance {
  246. mediumSettlementState = enum.MediumSettlementStateForCompleteSign
  247. mediumSettlementPayState = enum.MediumSettlementPayStateForPaymentAlready
  248. }
  249. if mediumSettlement == nil {
  250. //新增一条数据
  251. mediumSettlement = &model.MediumSettlement{
  252. Uuid: originalWxAdData.Uuid,
  253. MediumId: originalWxAdData.MediumId,
  254. AppId: originalWxAdData.AppId,
  255. BusinessKind: 1,
  256. Kind: medium.SettlementType,
  257. BasicIncome: generateWxAdData.MediaRevenue,
  258. OtherIncome: 0,
  259. State: mediumSettlementState,
  260. PayState: mediumSettlementPayState,
  261. StartDate: now.Format("2006-01-02"),
  262. EndDate: "",
  263. CreateAt: now.Format("2006-01-02 15:04:05"),
  264. UpdateAt: now.Format("2006-01-02 15:04:05"),
  265. }
  266. _, err = mediumSettlementDb.MediumSettlementInsertBySession(session, mediumSettlement)
  267. if err != nil {
  268. _ = session.Rollback()
  269. return
  270. }
  271. } else {
  272. //更新数据
  273. basicIncomeBefore = mediumSettlement.BasicIncome
  274. mediumSettlement.BasicIncome += generateWxAdData.MediaRevenue
  275. mediumSettlement.State = mediumSettlementState
  276. mediumSettlement.PayState = mediumSettlementPayState
  277. _, err = mediumSettlementDb.UpdateMediumSettlementBySession(session, mediumSettlement, "basic_income", "pay_state", "state")
  278. if err != nil {
  279. _ = session.Rollback()
  280. return
  281. }
  282. }
  283. if medium.SettlementType == enum.MediumSettlementTypeForPaymentInAdvance {
  284. err = DealMediumAmount(session, md.DealMediumAmount{
  285. Mid: utils.IntToStr(originalWxAdData.Uuid),
  286. Type: md.FinMediumFlowDirectionExpenditure,
  287. Kind: md.SettlementSubKindForMediumFlow,
  288. OrdId: utils.IntToStr(mediumSettlement.Id),
  289. MediumId: originalWxAdData.MediumId,
  290. Amount: float64(generateWxAdData.MediaRevenue) / 100,
  291. Memo: md.SettlementSubTitleForMediumFlow,
  292. })
  293. if err != nil {
  294. _ = session.Rollback()
  295. return
  296. }
  297. }
  298. //4.2 新增 medium_settlement_with_flow 数据
  299. mediumSettlementWithFlowDb := implement.NewMediumSettlementWithFlowDb(db.Db)
  300. _, err = mediumSettlementWithFlowDb.MediumSettlementWithFlowInsertBySession(session, &model.MediumSettlementWithFlow{
  301. SettlementId: mediumSettlement.Id,
  302. GenerateDataId: generateWxAdData.Id,
  303. Amount: generateWxAdData.MediaRevenue,
  304. BasicIncomeBefore: basicIncomeBefore,
  305. BasicIncomeAfter: mediumSettlement.BasicIncome,
  306. OtherIncomeBefore: 0,
  307. OtherIncomeAfter: 0,
  308. Kind: enum.MediumSettlementWithFlowKindForBasicIncome,
  309. CreateAt: now.Format("2006-01-02 15:04:05"),
  310. UpdateAt: now.Format("2006-01-02 15:04:05"),
  311. })
  312. if err != nil {
  313. _ = session.Rollback()
  314. return
  315. }
  316. //4.3 新增 agent_settlement、agent_settlement_with_flow 数据
  317. agentSettlementDb := implement.NewAgentSettlementDb(db.Db)
  318. agentSettlementWithFlowDb := implement.NewAgentSettlementWithFlowDb(db.Db)
  319. for _, v := range *generateWxAdDataWithAgentFlow {
  320. agentSettlement, err1 := agentSettlementDb.GetAgentSettlementForAvailable(v.AgentId)
  321. if err1 != nil {
  322. _ = session.Rollback()
  323. return err1
  324. }
  325. var agentBasicIncomeBefore, agentOtherIncomeBefore, agentSettlementState, agentSettlementPayState int
  326. //判断是否为预付结算类型
  327. if agentMap[v.AgentId].SettlementType == enum.AgentSettlementTypeForPaymentInAdvance {
  328. agentSettlementState = enum.AgentSettlementStateForCompleteSign
  329. agentSettlementPayState = enum.AgentSettlementPayStateForPaymentAlready
  330. }
  331. if agentSettlement == nil {
  332. //新增一条数据
  333. agentSettlement = &model.AgentSettlement{
  334. Uuid: v.Uuid,
  335. AgentId: v.AgentId,
  336. MediumId: originalWxAdData.MediumId,
  337. AppId: v.AppId,
  338. BusinessKind: 1,
  339. Kind: agentMap[v.AgentId].SettlementType,
  340. BasicIncome: v.AgentRevenue,
  341. OtherIncome: v.ExtraRevenue,
  342. State: agentSettlementState,
  343. PayState: agentSettlementPayState,
  344. StartDate: now.Format("2006-01-02"),
  345. EndDate: "",
  346. CreateAt: now.Format("2006-01-02 15:04:05"),
  347. UpdateAt: now.Format("2006-01-02 15:04:05"),
  348. }
  349. _, err = agentSettlementDb.AgentSettlementInsertBySession(session, agentSettlement)
  350. if err != nil {
  351. _ = session.Rollback()
  352. return
  353. }
  354. } else {
  355. //更新数据
  356. agentBasicIncomeBefore = agentSettlement.BasicIncome
  357. agentOtherIncomeBefore = agentSettlement.OtherIncome
  358. agentSettlement.BasicIncome += v.AgentRevenue
  359. agentSettlement.OtherIncome += v.ExtraRevenue
  360. agentSettlement.State += agentSettlementState
  361. agentSettlement.PayState += agentSettlementPayState
  362. _, err = agentSettlementDb.UpdateAgentSettlementBySession(session, agentSettlement, "basic_income", "other_income", "pay_state", "state")
  363. if err != nil {
  364. _ = session.Rollback()
  365. return
  366. }
  367. }
  368. if agentMap[v.AgentId].SettlementType == enum.AgentSettlementTypeForPaymentInAdvance {
  369. err = DealAgentAmount(session, md.DealAgentAmount{
  370. Mid: utils.IntToStr(originalWxAdData.Uuid),
  371. Type: md.FinAgentFlowDirectionExpenditure,
  372. Kind: md.SettlementSubKindForAgentFlow,
  373. OrdId: utils.IntToStr(v.Id),
  374. Amount: float64(v.AgentRevenue)/100 + float64(v.ExtraRevenue)/100,
  375. Memo: md.SettlementSubTitleForMediumFlow,
  376. })
  377. if err != nil {
  378. _ = session.Rollback()
  379. return
  380. }
  381. }
  382. _, err = agentSettlementWithFlowDb.AgentSettlementWithFlowInsertBySession(session, &model.AgentSettlementWithFlow{
  383. SettlementId: mediumSettlement.Id,
  384. GenerateDataId: generateWxAdData.Id,
  385. Amount: v.AgentRevenue,
  386. BasicIncomeBefore: agentBasicIncomeBefore,
  387. BasicIncomeAfter: agentSettlement.BasicIncome,
  388. OtherIncomeBefore: agentOtherIncomeBefore,
  389. OtherIncomeAfter: agentSettlement.OtherIncome,
  390. Kind: enum.AgentSettlementWithFlowKindForBasicIncome,
  391. CreateAt: now.Format("2006-01-02 15:04:05"),
  392. UpdateAt: now.Format("2006-01-02 15:04:05"),
  393. })
  394. if err != nil {
  395. _ = session.Rollback()
  396. return
  397. }
  398. }
  399. //4、修改 generate_wx_ad_data 记录中的 is_generate_report (是否已应用(0:未 1:已) )
  400. generateWxAdData.IsGenerateReport = 1
  401. _, err = generateWxAdDataDb.UpdateGenerateWxAdDataBySession(session, generateWxAdData, "is_generate_report")
  402. if err != nil {
  403. _ = session.Rollback()
  404. return
  405. }
  406. return session.Commit()
  407. }