income.go 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963
  1. package income
  2. import (
  3. "bytes"
  4. "context"
  5. "strconv"
  6. "time"
  7. incomeD "go-common/app/job/main/growup/dao/income"
  8. model "go-common/app/job/main/growup/model/income"
  9. xtime "go-common/library/time"
  10. )
  11. // Income income service
  12. type Income struct {
  13. avIncomeSvr *AvIncomeSvr
  14. upIncomeSvr *UpIncomeSvr
  15. avIncomeStatSvr *AvIncomeStatSvr
  16. bgmIncomeStatSvr *BgmIncomeStatSvr
  17. columnIncomeStatSvr *ColumnIncomeStatSvr
  18. upIncomeStatSvr *UpIncomeStatSvr
  19. upAccountSvr *UpAccountSvr
  20. dateStatisSvr *DateStatis
  21. bgmIncomeSvr *BgmIncomeSvr
  22. columnIncomeSvr *ColumnIncomeSvr
  23. }
  24. // NewIncome new income service
  25. func NewIncome(batchSize int, dao *incomeD.Dao) *Income {
  26. return &Income{
  27. avIncomeSvr: NewAvIncomeSvr(dao, batchSize),
  28. bgmIncomeSvr: NewBgmIncomeSvr(dao, batchSize),
  29. columnIncomeSvr: NewColumnIncomeSvr(dao, batchSize),
  30. upIncomeSvr: NewUpIncomeSvr(dao, batchSize),
  31. avIncomeStatSvr: NewAvIncomeStatSvr(dao, batchSize),
  32. bgmIncomeStatSvr: NewBgmIncomeStatSvr(dao, batchSize),
  33. columnIncomeStatSvr: NewColumnIncomeStatSvr(dao, batchSize),
  34. upIncomeStatSvr: NewUpIncomeStatSvr(dao, batchSize),
  35. upAccountSvr: NewUpAccountSvr(dao, batchSize),
  36. dateStatisSvr: NewDateStatis(dao),
  37. }
  38. }
  39. // CalAvIncome cal av income
  40. func (p *Income) CalAvIncome(ch chan []*model.AvCharge, urs map[int64]*model.UpChargeRatio, ars map[int64]*model.ArchiveChargeRatio, filters []AvFilter, signed map[int64]bool) (am map[int64][]*model.AvIncome, total map[int64]*model.UpBusinessIncome) {
  41. am, total = getClassifyAvIncome(ch, ars, filters)
  42. classifyAvIncome(am, urs, ars, total, signed)
  43. return
  44. }
  45. // CalColumnIncome cal column income
  46. func (p *Income) CalColumnIncome(ch chan []*model.ColumnCharge, urs map[int64]*model.UpChargeRatio, ars map[int64]*model.ArchiveChargeRatio, filters []ColumnFilter, signed map[int64]bool) (cm map[int64][]*model.ColumnIncome, total map[int64]*model.UpBusinessIncome) {
  47. cm, total = getClassifyColumnIncome(ch, ars, filters)
  48. classifyColumnIncome(cm, urs, ars, total, signed)
  49. return
  50. }
  51. // CalBgmIncome cal bgm income
  52. func (p *Income) CalBgmIncome(ch chan []*model.AvCharge, bgms map[int64][]*model.BGM, urs map[int64]*model.UpChargeRatio, ars map[int64]*model.ArchiveChargeRatio, avf []AvFilter, exclude BgmFilter, black map[int64]bool, signed map[int64]bool) (bm map[int64]map[int64]map[int64]*model.BgmIncome, total map[int64]*model.UpBusinessIncome) {
  53. bm, total = getClassifyBgmIncome(ch, bgms, avf, exclude, black, ars)
  54. classifyBgmIncome(bm, urs, ars, total, signed)
  55. return
  56. }
  57. func trans2AvIncome(charge *model.AvCharge, incr int64) *model.AvIncome {
  58. return &model.AvIncome{
  59. AvID: charge.AvID,
  60. MID: charge.MID,
  61. TagID: charge.TagID,
  62. IsOriginal: charge.IsOriginal,
  63. UploadTime: charge.UploadTime,
  64. PlayCount: charge.TotalPlayCount,
  65. Date: charge.Date,
  66. Income: incr,
  67. BaseIncome: charge.IncCharge,
  68. }
  69. }
  70. func av2BusinessIncome(a *model.AvIncome) *model.UpBusinessIncome {
  71. return &model.UpBusinessIncome{
  72. MID: a.MID,
  73. Income: a.Income,
  74. PlayCount: a.PlayCount,
  75. AvCount: 1,
  76. Business: 1,
  77. }
  78. }
  79. // av income before tax
  80. // total key:mid, value:total_income
  81. func getClassifyAvIncome(ch chan []*model.AvCharge, ratio map[int64]*model.ArchiveChargeRatio, filters []AvFilter) (am map[int64][]*model.AvIncome, total map[int64]*model.UpBusinessIncome) {
  82. am = make(map[int64][]*model.AvIncome)
  83. total = make(map[int64]*model.UpBusinessIncome)
  84. for charges := range ch {
  85. CHARGE:
  86. for _, charge := range charges {
  87. for _, filter := range filters {
  88. if filter(charge) {
  89. continue CHARGE
  90. }
  91. }
  92. var incr int64
  93. if r, ok := ratio[charge.AvID]; ok {
  94. if r.AdjustType == 0 {
  95. incr = int64(Round(float64(charge.IncCharge)*Div(float64(r.Ratio), float64(100)), 0))
  96. } else if r.AdjustType == 1 {
  97. incr = charge.IncCharge
  98. }
  99. } else {
  100. incr = charge.IncCharge
  101. }
  102. avIncome := trans2AvIncome(charge, incr)
  103. if _, ok := am[charge.MID]; ok {
  104. am[charge.MID] = append(am[charge.MID], avIncome)
  105. } else {
  106. am[charge.MID] = []*model.AvIncome{avIncome}
  107. }
  108. if business, ok := total[charge.MID]; ok {
  109. business.PlayCount += avIncome.PlayCount
  110. business.AvCount++
  111. business.Income += avIncome.Income
  112. } else {
  113. business := av2BusinessIncome(avIncome)
  114. total[charge.MID] = business
  115. }
  116. }
  117. }
  118. return
  119. }
  120. func classifyAvIncome(am map[int64][]*model.AvIncome,
  121. urs map[int64]*model.UpChargeRatio,
  122. ars map[int64]*model.ArchiveChargeRatio,
  123. total map[int64]*model.UpBusinessIncome,
  124. signed map[int64]bool) {
  125. for mid, business := range total {
  126. realIncome := business.Income
  127. if r, ok := urs[mid]; ok {
  128. if r.AdjustType == 0 {
  129. // up主浮动调节,分配到视频业务
  130. realIncome = int64(Round(float64(business.Income)*Div(float64(r.Ratio), float64(100)), 0))
  131. }
  132. }
  133. // up主浮动调节后视频业务的税
  134. tax := int64(Round(Tax(Div(float64(realIncome), 100))*100, 0))
  135. // 税后收入
  136. netIncome := realIncome - tax
  137. // update up income
  138. business.Percent = Div(float64(netIncome), float64(business.Income))
  139. business.Income = netIncome
  140. business.Tax = tax
  141. }
  142. // 计算每个视频浮动调节后收入
  143. for mid, as := range am {
  144. business := total[mid]
  145. // up主的固定调节收入
  146. var patchIncome int64
  147. var c bool
  148. for _, a := range as {
  149. avIncome := int64(Round(Mul(float64(a.Income), business.Percent), 0))
  150. a.Income = avIncome
  151. a.TaxMoney = int64(Round(Mul(float64(business.Tax), Div(float64(avIncome), float64(business.Income))), 0))
  152. // 以下是计算up主基础收入
  153. // original raito: 100
  154. var o int64 = 100
  155. if upRatio, ok := urs[mid]; ok {
  156. if upRatio.AdjustType == 0 {
  157. o = upRatio.Ratio
  158. c = true
  159. }
  160. }
  161. avBaseIncome := int64(Round(Div(float64(avIncome), Div(float64(o), 100)), 0))
  162. a.BaseIncome = avBaseIncome
  163. if r, ok := ars[a.AvID]; ok {
  164. if r.AdjustType == 0 {
  165. // 如果视频收入被加倍过,还原
  166. originIncome := int64(Round(Div(float64(avBaseIncome), Div(float64(r.Ratio), 100)), 0))
  167. a.BaseIncome = originIncome
  168. business.BaseIncome += originIncome
  169. c = true
  170. }
  171. if r.AdjustType == 1 {
  172. // av 固定调节, 更新av的收入和up主的基础收入
  173. a.Income += r.Ratio
  174. // 更新up主的av收入, Income在计算BaseIncome后更新
  175. // upIncome.AvIncome += r.Ratio
  176. // business.Income += r.Ratio
  177. patchIncome += r.Ratio
  178. business.BaseIncome += avBaseIncome
  179. }
  180. } else {
  181. business.BaseIncome += avBaseIncome
  182. }
  183. }
  184. // 如果没有被加倍过, 那么避免误差将BaseIncome直接置为Income
  185. if !c {
  186. business.BaseIncome = business.Income
  187. }
  188. // 最后加上该up主av的总固定调节收入
  189. business.Income += patchIncome
  190. }
  191. // + up主的固定调节
  192. for mid, ratio := range urs {
  193. if _, ok := signed[mid]; !ok {
  194. continue
  195. }
  196. if ratio.AdjustType == 0 {
  197. continue
  198. }
  199. if business, ok := total[mid]; ok {
  200. business.Income += ratio.Ratio
  201. } else {
  202. total[mid] = &model.UpBusinessIncome{
  203. MID: mid,
  204. Income: ratio.Ratio,
  205. Business: 1,
  206. }
  207. }
  208. }
  209. }
  210. /*################################################################## BGM ########################################################################*/
  211. func trans2BgmIncome(b *model.BGM, charge int64, date xtime.Time) *model.BgmIncome {
  212. return &model.BgmIncome{
  213. AID: b.AID,
  214. SID: b.SID,
  215. MID: b.MID,
  216. CID: b.CID,
  217. Income: charge,
  218. Date: date,
  219. }
  220. }
  221. func bgm2BusinessIncome(b *model.BgmIncome) *model.UpBusinessIncome {
  222. return &model.UpBusinessIncome{
  223. MID: b.MID,
  224. Income: b.Income,
  225. Business: 3,
  226. BgmCount: map[int64]bool{
  227. b.SID: true,
  228. },
  229. }
  230. }
  231. // bgms map[avid][sid]*model.BGM | bm map[mid]map[sid]map[avid]*model.BgmIncome
  232. func getClassifyBgmIncome(ch chan []*model.AvCharge, bgms map[int64][]*model.BGM, filters []AvFilter, exclude BgmFilter, black map[int64]bool, ratio map[int64]*model.ArchiveChargeRatio) (bm map[int64]map[int64]map[int64]*model.BgmIncome, total map[int64]*model.UpBusinessIncome) {
  233. bm = make(map[int64]map[int64]map[int64]*model.BgmIncome)
  234. total = make(map[int64]*model.UpBusinessIncome)
  235. for charges := range ch {
  236. CHARGE:
  237. for _, charge := range charges {
  238. for _, filter := range filters {
  239. if filter(charge) {
  240. continue CHARGE
  241. }
  242. }
  243. if bs, ok := bgms[charge.AvID]; ok {
  244. bgmCharge := int64(Round(Div(Mul(float64(charge.IncCharge), float64(0.3)), float64(len(bs))), 0))
  245. for _, b := range bs {
  246. // if av's bgm is own, continue
  247. if b.MID == charge.MID {
  248. continue
  249. }
  250. if _, ok := black[b.SID]; ok {
  251. continue
  252. }
  253. if exclude(charge, b) {
  254. continue
  255. }
  256. var incr int64
  257. if r, ok := ratio[b.SID]; ok {
  258. if r.AdjustType == 0 {
  259. incr = int64(Round(float64(bgmCharge)*Div(float64(r.Ratio), float64(100)), 0))
  260. } else if r.AdjustType == 1 {
  261. incr = bgmCharge
  262. }
  263. } else {
  264. incr = bgmCharge
  265. }
  266. // bm map[mid]map[sid]map[avid]*model.BgmIncome
  267. var bgmIncome *model.BgmIncome
  268. if sm, ok := bm[b.MID]; ok {
  269. if am, ok := sm[b.SID]; ok {
  270. if bgmIncome, ok = am[b.AID]; ok {
  271. bgmIncome.Income += incr
  272. } else {
  273. bgmIncome = trans2BgmIncome(b, incr, charge.Date)
  274. am[b.AID] = bgmIncome
  275. }
  276. } else {
  277. bgmIncome = trans2BgmIncome(b, incr, charge.Date)
  278. sm[b.SID] = map[int64]*model.BgmIncome{
  279. b.AID: bgmIncome,
  280. }
  281. }
  282. } else {
  283. bgmIncome = trans2BgmIncome(b, incr, charge.Date)
  284. // am map[avid]*model.BgmIncome
  285. am := map[int64]*model.BgmIncome{
  286. b.AID: bgmIncome,
  287. }
  288. // sm map[sid]map[avid]*model.BgmIncome
  289. sm := map[int64]map[int64]*model.BgmIncome{
  290. b.SID: am,
  291. }
  292. // bm map[mid]map[sid]map[avid]*model.BgmIncome
  293. bm[b.MID] = sm
  294. }
  295. if business, ok := total[b.MID]; ok {
  296. business.Income += incr
  297. business.BgmCount[b.SID] = true
  298. } else {
  299. business := bgm2BusinessIncome(bgmIncome)
  300. total[b.MID] = business
  301. }
  302. }
  303. }
  304. }
  305. }
  306. return
  307. }
  308. // 算税并分配收入
  309. func classifyBgmIncome(bm map[int64]map[int64]map[int64]*model.BgmIncome,
  310. urs map[int64]*model.UpChargeRatio,
  311. ars map[int64]*model.ArchiveChargeRatio,
  312. total map[int64]*model.UpBusinessIncome,
  313. signed map[int64]bool) {
  314. for mid, business := range total {
  315. if business.Income == 0 {
  316. delete(total, mid)
  317. delete(bm, mid)
  318. continue
  319. }
  320. realIncome := business.Income
  321. if r, ok := urs[mid]; ok {
  322. if r.AdjustType == 0 {
  323. // up主浮动调节,分配到视频业务
  324. realIncome = int64(Round(float64(business.Income)*Div(float64(r.Ratio), float64(100)), 0))
  325. }
  326. }
  327. // up主浮动调节后视频业务的税
  328. tax := int64(Round(Tax(Div(float64(realIncome), 100))*100, 0))
  329. // 税后收入
  330. netIncome := realIncome - tax
  331. // update up income
  332. business.Percent = Div(float64(netIncome), float64(business.Income))
  333. business.Income = netIncome
  334. business.Tax = tax
  335. }
  336. // bm map[mid]map[sid]map[avid]*model.BgmIncome
  337. for mid, sm := range bm {
  338. business := total[mid]
  339. var c bool
  340. var patchIncome int64
  341. for sid, bs := range sm {
  342. var dailyTotalIncome int64
  343. for _, b := range bs {
  344. income := int64(Round(Mul(float64(b.Income), business.Percent), 0))
  345. b.Income = income
  346. b.TaxMoney = int64(Round(Mul(float64(business.Tax), Div(float64(income), float64(business.Income))), 0))
  347. dailyTotalIncome += b.Income
  348. // 以下是计算up主基础收入
  349. // original raito: 100
  350. var o int64 = 100
  351. if upRatio, ok := urs[mid]; ok {
  352. if upRatio.AdjustType == 0 {
  353. o = upRatio.Ratio
  354. c = true
  355. }
  356. }
  357. bgmBaseIncome := int64(Round(Div(float64(income), Div(float64(o), 100)), 0))
  358. b.BaseIncome = bgmBaseIncome
  359. if r, ok := ars[sid]; ok {
  360. if r.AdjustType == 0 {
  361. // 如果bgm收入被加倍过,还原
  362. originIncome := int64(Round(Div(float64(bgmBaseIncome), Div(float64(r.Ratio), 100)), 0))
  363. b.BaseIncome = originIncome
  364. business.BaseIncome += originIncome
  365. c = true
  366. } else {
  367. business.BaseIncome += bgmBaseIncome
  368. }
  369. } else {
  370. business.BaseIncome += bgmBaseIncome
  371. }
  372. }
  373. if r, ok := ars[sid]; ok {
  374. if r.AdjustType == 1 {
  375. patchIncome += r.Ratio
  376. dailyTotalIncome += r.Ratio
  377. }
  378. }
  379. // update bgm daily total income
  380. for _, b := range bs {
  381. b.DailyTotalIncome = dailyTotalIncome
  382. }
  383. }
  384. if !c {
  385. business.BaseIncome = business.Income
  386. }
  387. // 最后加上该up主bgm的总固定调节收入
  388. business.Income += patchIncome
  389. }
  390. // + up主的固定调节
  391. for mid, ratio := range urs {
  392. if _, ok := signed[mid]; !ok {
  393. continue
  394. }
  395. if ratio.AdjustType == 0 {
  396. continue
  397. }
  398. if business, ok := total[mid]; ok {
  399. business.Income += ratio.Ratio
  400. } else {
  401. total[mid] = &model.UpBusinessIncome{
  402. MID: mid,
  403. Income: ratio.Ratio,
  404. Business: 3,
  405. }
  406. }
  407. }
  408. }
  409. /*###################################################### Column #######################################################*/
  410. func trans2ColumnIncome(charge *model.ColumnCharge, incr int64) (c *model.ColumnIncome) {
  411. return &model.ColumnIncome{
  412. ArticleID: charge.ArticleID,
  413. Title: charge.Title,
  414. MID: charge.MID,
  415. TagID: charge.TagID,
  416. UploadTime: charge.UploadTime,
  417. ViewCount: charge.IncViewCount,
  418. Date: charge.Date,
  419. Income: incr,
  420. BaseIncome: charge.IncCharge,
  421. }
  422. }
  423. // business type 2: column
  424. func column2BusinessIncome(c *model.ColumnIncome) *model.UpBusinessIncome {
  425. return &model.UpBusinessIncome{
  426. MID: c.MID,
  427. Income: c.Income,
  428. ViewCount: c.ViewCount,
  429. ColumnCount: 1,
  430. Business: 2,
  431. }
  432. }
  433. func getClassifyColumnIncome(ch chan []*model.ColumnCharge, ratio map[int64]*model.ArchiveChargeRatio, filters []ColumnFilter) (cm map[int64][]*model.ColumnIncome, total map[int64]*model.UpBusinessIncome) {
  434. cm = make(map[int64][]*model.ColumnIncome)
  435. total = make(map[int64]*model.UpBusinessIncome)
  436. for charges := range ch {
  437. CHARGE:
  438. for _, charge := range charges {
  439. for _, filter := range filters {
  440. if filter(charge) {
  441. continue CHARGE
  442. }
  443. }
  444. var incr int64
  445. if r, ok := ratio[charge.ArticleID]; ok {
  446. if r.AdjustType == 0 {
  447. incr = int64(Round(float64(charge.IncCharge)*Div(float64(r.Ratio), float64(100)), 0))
  448. } else if r.AdjustType == 1 {
  449. incr = charge.IncCharge
  450. }
  451. } else {
  452. incr = charge.IncCharge
  453. }
  454. columnIncome := trans2ColumnIncome(charge, incr)
  455. if _, ok := cm[charge.MID]; ok {
  456. cm[charge.MID] = append(cm[charge.MID], columnIncome)
  457. } else {
  458. cm[charge.MID] = []*model.ColumnIncome{columnIncome}
  459. }
  460. if business, ok := total[charge.MID]; ok {
  461. business.ViewCount += columnIncome.ViewCount
  462. business.ColumnCount++
  463. business.Income += columnIncome.Income
  464. } else {
  465. business := column2BusinessIncome(columnIncome)
  466. total[charge.MID] = business
  467. }
  468. }
  469. }
  470. return
  471. }
  472. // calculate column income and archive income
  473. func classifyColumnIncome(cm map[int64][]*model.ColumnIncome,
  474. urs map[int64]*model.UpChargeRatio,
  475. ars map[int64]*model.ArchiveChargeRatio,
  476. total map[int64]*model.UpBusinessIncome,
  477. signed map[int64]bool) {
  478. for mid, business := range total {
  479. realIncome := business.Income
  480. if r, ok := urs[mid]; ok {
  481. if r.AdjustType == 0 {
  482. // up主浮动调节,分配到视频业务
  483. realIncome = int64(Round(float64(business.Income)*Div(float64(r.Ratio), float64(100)), 0))
  484. }
  485. }
  486. // up主浮动调节后视频业务的税
  487. tax := int64(Round(Tax(Div(float64(realIncome), 100))*100, 0))
  488. // 税后收入
  489. netIncome := realIncome - tax
  490. // update up income
  491. business.Percent = Div(float64(netIncome), float64(business.Income))
  492. business.Income = netIncome
  493. business.Tax = tax
  494. }
  495. for mid, cs := range cm {
  496. business := total[mid]
  497. var x bool
  498. var patchIncome int64
  499. for _, c := range cs {
  500. columnIncome := int64(Round(Mul(float64(c.Income), business.Percent), 0))
  501. c.Income = columnIncome
  502. c.TaxMoney = int64(Round(Mul(float64(business.Tax), Div(float64(columnIncome), float64(business.Income))), 0))
  503. // 以下是计算up主基础收入
  504. // original raito: 100
  505. var o int64 = 100
  506. if upRatio, ok := urs[mid]; ok {
  507. if upRatio.AdjustType == 0 {
  508. o = upRatio.Ratio
  509. x = true
  510. }
  511. }
  512. columnBaseIncome := int64(Round(Div(float64(columnIncome), Div(float64(o), 100)), 0))
  513. c.BaseIncome = columnBaseIncome
  514. if r, ok := ars[c.ArticleID]; ok {
  515. if r.AdjustType == 0 {
  516. // 如果视频收入被加倍过,还原
  517. originIncome := int64(Round(Div(float64(columnBaseIncome), Div(float64(r.Ratio), 100)), 0))
  518. c.BaseIncome = originIncome
  519. business.BaseIncome += originIncome
  520. x = true
  521. }
  522. if r.AdjustType == 1 {
  523. // column 固定调节, 更新column 的收入和up主的基础收入
  524. c.Income += r.Ratio
  525. // 更新up主的column 收入, Income在计算BaseIncome后更新
  526. patchIncome += r.Ratio
  527. business.BaseIncome += columnBaseIncome
  528. }
  529. } else {
  530. business.BaseIncome += columnBaseIncome
  531. }
  532. }
  533. if !x {
  534. business.BaseIncome = business.Income
  535. }
  536. // 最后加上该up主column的总固定调节收入
  537. business.Income += patchIncome
  538. }
  539. // + up主的固定调节
  540. for mid, ratio := range urs {
  541. if _, ok := signed[mid]; !ok {
  542. continue
  543. }
  544. if ratio.AdjustType == 0 {
  545. continue
  546. }
  547. if business, ok := total[mid]; ok {
  548. business.Income += ratio.Ratio
  549. } else {
  550. total[mid] = &model.UpBusinessIncome{
  551. MID: mid,
  552. Income: ratio.Ratio,
  553. Business: 2,
  554. }
  555. }
  556. }
  557. }
  558. /**######################################################## UpIncome ###################################################################**/
  559. // CalUpIncome calculate upIncome
  560. func (p *Income) CalUpIncome(ch chan map[int64]*model.UpBusinessIncome, date time.Time) (m map[int64]*model.UpIncome) {
  561. defer close(ch)
  562. m = make(map[int64]*model.UpIncome)
  563. var finished int
  564. for bm := range ch {
  565. for mid, business := range bm {
  566. if upIncome, ok := m[mid]; ok {
  567. if business.Business == 1 {
  568. upIncome.AvCount = business.AvCount
  569. upIncome.PlayCount = business.PlayCount
  570. upIncome.AvIncome = business.Income
  571. upIncome.AvBaseIncome = business.BaseIncome
  572. upIncome.AvTax = business.Tax
  573. }
  574. if business.Business == 2 {
  575. upIncome.ColumnCount = business.ColumnCount
  576. upIncome.ColumnIncome = business.Income
  577. upIncome.ColumnBaseIncome = business.BaseIncome
  578. upIncome.ColumnTax = business.Tax
  579. }
  580. if business.Business == 3 {
  581. upIncome.BgmIncome = business.Income
  582. upIncome.BgmBaseIncome = business.BaseIncome
  583. upIncome.BgmTax = business.Tax
  584. upIncome.BgmCount = int64(len(business.BgmCount))
  585. }
  586. upIncome.TaxMoney += business.Tax
  587. upIncome.BaseIncome += business.BaseIncome
  588. upIncome.Income += business.Income
  589. } else {
  590. var upIncome *model.UpIncome
  591. if business.Business == 1 {
  592. upIncome = &model.UpIncome{
  593. AvCount: business.AvCount,
  594. PlayCount: business.PlayCount,
  595. AvIncome: business.Income,
  596. AvBaseIncome: business.BaseIncome,
  597. AvTax: business.Tax,
  598. }
  599. }
  600. if business.Business == 2 {
  601. upIncome = &model.UpIncome{
  602. ColumnCount: business.ColumnCount,
  603. ColumnIncome: business.Income,
  604. ColumnBaseIncome: business.BaseIncome,
  605. ColumnTax: business.Tax,
  606. }
  607. }
  608. if business.Business == 3 {
  609. upIncome = &model.UpIncome{
  610. BgmIncome: business.Income,
  611. BgmBaseIncome: business.BaseIncome,
  612. BgmTax: business.Tax,
  613. BgmCount: int64(len(business.BgmCount)),
  614. }
  615. }
  616. upIncome.MID = mid
  617. upIncome.TaxMoney = business.Tax
  618. upIncome.BaseIncome = business.BaseIncome
  619. upIncome.Income = business.Income
  620. upIncome.Date = xtime.Time(date.Unix())
  621. m[mid] = upIncome
  622. }
  623. }
  624. finished++
  625. if finished == 3 {
  626. break
  627. }
  628. }
  629. return
  630. }
  631. // IncomeStat income statistics
  632. func (p *Income) IncomeStat(
  633. um map[int64]*model.UpIncome,
  634. am map[int64][]*model.AvIncome,
  635. bm map[int64]map[int64]map[int64]*model.BgmIncome,
  636. cm map[int64][]*model.ColumnIncome,
  637. ustat map[int64]*model.UpIncomeStat,
  638. astat map[int64]*model.AvIncomeStat,
  639. bstat map[int64]*model.BgmIncomeStat,
  640. cstat map[int64]*model.ColumnIncomeStat) {
  641. for mid, upIncome := range um {
  642. // update up income total income
  643. ut, ok := ustat[mid]
  644. if !ok {
  645. ut = &model.UpIncomeStat{
  646. MID: upIncome.MID,
  647. DataState: 1, // insert
  648. }
  649. ustat[mid] = ut
  650. } else {
  651. ut.DataState = 2 // update
  652. }
  653. // update up income statis up total income
  654. // up av total income
  655. // up column total income
  656. // up bgm total income
  657. ut.TotalIncome += upIncome.Income
  658. upIncome.TotalIncome = ut.TotalIncome
  659. ut.AvTotalIncome += upIncome.AvIncome
  660. upIncome.AvTotalIncome = ut.AvTotalIncome
  661. ut.ColumnTotalIncome += upIncome.ColumnIncome
  662. upIncome.ColumnTotalIncome = ut.ColumnTotalIncome
  663. ut.BgmTotalIncome += upIncome.BgmIncome
  664. upIncome.BgmTotalIncome = ut.BgmTotalIncome
  665. // update av income total income
  666. for _, a := range am[mid] {
  667. at, ok := astat[a.AvID]
  668. if !ok {
  669. at = &model.AvIncomeStat{
  670. AvID: a.AvID,
  671. MID: a.MID,
  672. TagID: a.TagID,
  673. IsOriginal: a.IsOriginal,
  674. UploadTime: a.UploadTime,
  675. DataState: 1, // insert
  676. }
  677. astat[a.AvID] = at
  678. } else {
  679. at.DataState = 2 // update
  680. }
  681. at.TotalIncome += a.Income
  682. a.TotalIncome = at.TotalIncome
  683. }
  684. // update bgmIncome total income
  685. for sid, am := range bm[mid] {
  686. bt, ok := bstat[sid]
  687. if !ok {
  688. bt = &model.BgmIncomeStat{
  689. SID: sid,
  690. DataState: 1, // insert
  691. }
  692. bstat[sid] = bt
  693. } else {
  694. bt.DataState = 2 // update
  695. }
  696. for _, b := range am {
  697. bt.TotalIncome += b.DailyTotalIncome
  698. break
  699. }
  700. for _, b := range am {
  701. b.TotalIncome = bt.TotalIncome
  702. }
  703. }
  704. // update columnIncome total income
  705. for _, c := range cm[mid] {
  706. ct, ok := cstat[c.ArticleID]
  707. if !ok {
  708. ct = &model.ColumnIncomeStat{
  709. ArticleID: c.ArticleID,
  710. Title: c.Title,
  711. TagID: c.TagID,
  712. MID: c.MID,
  713. UploadTime: c.UploadTime,
  714. DataState: 1, // insert
  715. }
  716. cstat[c.ArticleID] = ct
  717. } else {
  718. ct.DataState = 2 // update
  719. }
  720. ct.TotalIncome += c.Income
  721. c.TotalIncome = ct.TotalIncome
  722. }
  723. }
  724. }
  725. // PurgeUpAccount purge up account
  726. func (p *Income) PurgeUpAccount(date time.Time, accs map[int64]*model.UpAccount, um map[int64]*model.UpIncome) {
  727. fd := time.Date(date.Year(), date.Month(), 1, 0, 0, 0, 0, time.Local)
  728. last := fd.AddDate(0, 0, -1).Format("2006-01")
  729. // TODO check
  730. for mid, upIncome := range um {
  731. // update old up account
  732. if upAccount, ok := accs[mid]; ok {
  733. upAccount.TotalIncome += upIncome.Income
  734. if upAccount.WithdrawDateVersion == last {
  735. upAccount.TotalUnwithdrawIncome += upIncome.Income
  736. }
  737. upAccount.DataState = 2
  738. } else { // append new up account
  739. accs[mid] = &model.UpAccount{
  740. MID: mid,
  741. HasSignContract: 1,
  742. TotalIncome: upIncome.Income,
  743. TotalUnwithdrawIncome: upIncome.Income,
  744. WithdrawDateVersion: last,
  745. DataState: 1,
  746. }
  747. }
  748. }
  749. }
  750. /************************************************************ FOR HISTORY ****************************************************************/
  751. // UpdateBusinessIncomeByDate update business income by date
  752. func (p *Income) UpdateBusinessIncomeByDate(c context.Context, date string) (err error) {
  753. ustat, err := p.upIncomeStatSvr.UpIncomeStat(c, int64(_limitSize))
  754. if err != nil {
  755. return
  756. }
  757. return p.updateBusinessIncomeByDate(c, date, ustat)
  758. }
  759. func (p *Income) updateBusinessIncomeByDate(c context.Context, date string, ustat map[int64]*model.UpIncomeStat) (err error) {
  760. us, err := p.businessTotalIncome(c, ustat, date)
  761. if err != nil {
  762. return
  763. }
  764. err = p.batchUpdateUpIncome(c, us)
  765. if err != nil {
  766. return
  767. }
  768. return p.batchUpdateUpIncomeStat(c, ustat)
  769. }
  770. // for history data m: map[mid]map[date]*model.UpIncome
  771. func (p *Income) businessTotalIncome(c context.Context, ustat map[int64]*model.UpIncomeStat, date string) (m []*model.UpIncome, err error) {
  772. var id int64
  773. for {
  774. var ups []*model.UpIncome
  775. ups, err = p.upIncomeSvr.dao.GetUpIncomeTable(c, "up_income", date, id, 2000)
  776. if err != nil {
  777. return
  778. }
  779. for _, up := range ups {
  780. if ut, ok := ustat[up.MID]; ok {
  781. ut.AvTotalIncome += up.AvIncome
  782. up.AvTotalIncome = ut.AvTotalIncome
  783. ut.ColumnTotalIncome += up.ColumnIncome
  784. up.ColumnTotalIncome = ut.ColumnTotalIncome
  785. ut.BgmTotalIncome += up.BgmIncome
  786. up.BgmTotalIncome = ut.BgmTotalIncome
  787. m = append(m, up)
  788. }
  789. }
  790. if len(ups) < 2000 {
  791. break
  792. }
  793. id = ups[len(ups)-1].ID
  794. }
  795. return
  796. }
  797. // BatchUpdateUpIncome insert up_income batch
  798. func (p *Income) batchUpdateUpIncome(c context.Context, us []*model.UpIncome) (err error) {
  799. var (
  800. buff = make([]*model.UpIncome, p.upIncomeSvr.batchSize)
  801. buffEnd = 0
  802. )
  803. for _, u := range us {
  804. buff[buffEnd] = u
  805. buffEnd++
  806. if buffEnd >= p.upIncomeSvr.batchSize {
  807. values := businessValues(buff[:buffEnd])
  808. buffEnd = 0
  809. _, err = p.upIncomeSvr.dao.FixInsertUpIncome(c, values)
  810. if err != nil {
  811. return
  812. }
  813. }
  814. }
  815. if buffEnd > 0 {
  816. values := businessValues(buff[:buffEnd])
  817. buffEnd = 0
  818. _, err = p.upIncomeSvr.dao.FixInsertUpIncome(c, values)
  819. }
  820. return
  821. }
  822. func businessValues(us []*model.UpIncome) (values string) {
  823. var buf bytes.Buffer
  824. for _, u := range us {
  825. buf.WriteString("(")
  826. buf.WriteString(strconv.FormatInt(u.MID, 10))
  827. buf.WriteByte(',')
  828. buf.WriteString(strconv.FormatInt(u.AvTotalIncome, 10))
  829. buf.WriteByte(',')
  830. buf.WriteString(strconv.FormatInt(u.ColumnTotalIncome, 10))
  831. buf.WriteByte(',')
  832. buf.WriteString(strconv.FormatInt(u.BgmTotalIncome, 10))
  833. buf.WriteByte(',')
  834. buf.WriteString("'" + u.Date.Time().Format(_layout) + "'")
  835. buf.WriteString(")")
  836. buf.WriteByte(',')
  837. }
  838. if buf.Len() > 0 {
  839. buf.Truncate(buf.Len() - 1)
  840. }
  841. values = buf.String()
  842. buf.Reset()
  843. return
  844. }
  845. // BatchUpdateUpIncome insert up_income batch
  846. func (p *Income) batchUpdateUpIncomeStat(c context.Context, us map[int64]*model.UpIncomeStat) (err error) {
  847. var (
  848. buff = make([]*model.UpIncomeStat, p.upIncomeStatSvr.batchSize)
  849. buffEnd = 0
  850. )
  851. for _, u := range us {
  852. buff[buffEnd] = u
  853. buffEnd++
  854. if buffEnd >= p.upIncomeStatSvr.batchSize {
  855. values := businessStatValues(buff[:buffEnd])
  856. buffEnd = 0
  857. _, err = p.upIncomeStatSvr.dao.FixInsertUpIncomeStat(c, values)
  858. if err != nil {
  859. return
  860. }
  861. }
  862. }
  863. if buffEnd > 0 {
  864. values := businessStatValues(buff[:buffEnd])
  865. buffEnd = 0
  866. _, err = p.upIncomeStatSvr.dao.FixInsertUpIncomeStat(c, values)
  867. }
  868. return
  869. }
  870. func businessStatValues(ustat []*model.UpIncomeStat) (values string) {
  871. var buf bytes.Buffer
  872. for _, u := range ustat {
  873. buf.WriteString("(")
  874. buf.WriteString(strconv.FormatInt(u.MID, 10))
  875. buf.WriteByte(',')
  876. buf.WriteString(strconv.FormatInt(u.AvTotalIncome, 10))
  877. buf.WriteByte(',')
  878. buf.WriteString(strconv.FormatInt(u.ColumnTotalIncome, 10))
  879. buf.WriteByte(',')
  880. buf.WriteString(strconv.FormatInt(u.BgmTotalIncome, 10))
  881. buf.WriteString(")")
  882. buf.WriteByte(',')
  883. }
  884. if buf.Len() > 0 {
  885. buf.Truncate(buf.Len() - 1)
  886. }
  887. values = buf.String()
  888. buf.Reset()
  889. return
  890. }