package income import ( "bytes" "context" "strconv" "time" incomeD "go-common/app/job/main/growup/dao/income" model "go-common/app/job/main/growup/model/income" xtime "go-common/library/time" ) // Income income service type Income struct { avIncomeSvr *AvIncomeSvr upIncomeSvr *UpIncomeSvr avIncomeStatSvr *AvIncomeStatSvr bgmIncomeStatSvr *BgmIncomeStatSvr columnIncomeStatSvr *ColumnIncomeStatSvr upIncomeStatSvr *UpIncomeStatSvr upAccountSvr *UpAccountSvr dateStatisSvr *DateStatis bgmIncomeSvr *BgmIncomeSvr columnIncomeSvr *ColumnIncomeSvr } // NewIncome new income service func NewIncome(batchSize int, dao *incomeD.Dao) *Income { return &Income{ avIncomeSvr: NewAvIncomeSvr(dao, batchSize), bgmIncomeSvr: NewBgmIncomeSvr(dao, batchSize), columnIncomeSvr: NewColumnIncomeSvr(dao, batchSize), upIncomeSvr: NewUpIncomeSvr(dao, batchSize), avIncomeStatSvr: NewAvIncomeStatSvr(dao, batchSize), bgmIncomeStatSvr: NewBgmIncomeStatSvr(dao, batchSize), columnIncomeStatSvr: NewColumnIncomeStatSvr(dao, batchSize), upIncomeStatSvr: NewUpIncomeStatSvr(dao, batchSize), upAccountSvr: NewUpAccountSvr(dao, batchSize), dateStatisSvr: NewDateStatis(dao), } } // CalAvIncome cal av income 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) { am, total = getClassifyAvIncome(ch, ars, filters) classifyAvIncome(am, urs, ars, total, signed) return } // CalColumnIncome cal column income 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) { cm, total = getClassifyColumnIncome(ch, ars, filters) classifyColumnIncome(cm, urs, ars, total, signed) return } // CalBgmIncome cal bgm income 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) { bm, total = getClassifyBgmIncome(ch, bgms, avf, exclude, black, ars) classifyBgmIncome(bm, urs, ars, total, signed) return } func trans2AvIncome(charge *model.AvCharge, incr int64) *model.AvIncome { return &model.AvIncome{ AvID: charge.AvID, MID: charge.MID, TagID: charge.TagID, IsOriginal: charge.IsOriginal, UploadTime: charge.UploadTime, PlayCount: charge.TotalPlayCount, Date: charge.Date, Income: incr, BaseIncome: charge.IncCharge, } } func av2BusinessIncome(a *model.AvIncome) *model.UpBusinessIncome { return &model.UpBusinessIncome{ MID: a.MID, Income: a.Income, PlayCount: a.PlayCount, AvCount: 1, Business: 1, } } // av income before tax // total key:mid, value:total_income func getClassifyAvIncome(ch chan []*model.AvCharge, ratio map[int64]*model.ArchiveChargeRatio, filters []AvFilter) (am map[int64][]*model.AvIncome, total map[int64]*model.UpBusinessIncome) { am = make(map[int64][]*model.AvIncome) total = make(map[int64]*model.UpBusinessIncome) for charges := range ch { CHARGE: for _, charge := range charges { for _, filter := range filters { if filter(charge) { continue CHARGE } } var incr int64 if r, ok := ratio[charge.AvID]; ok { if r.AdjustType == 0 { incr = int64(Round(float64(charge.IncCharge)*Div(float64(r.Ratio), float64(100)), 0)) } else if r.AdjustType == 1 { incr = charge.IncCharge } } else { incr = charge.IncCharge } avIncome := trans2AvIncome(charge, incr) if _, ok := am[charge.MID]; ok { am[charge.MID] = append(am[charge.MID], avIncome) } else { am[charge.MID] = []*model.AvIncome{avIncome} } if business, ok := total[charge.MID]; ok { business.PlayCount += avIncome.PlayCount business.AvCount++ business.Income += avIncome.Income } else { business := av2BusinessIncome(avIncome) total[charge.MID] = business } } } return } func classifyAvIncome(am map[int64][]*model.AvIncome, urs map[int64]*model.UpChargeRatio, ars map[int64]*model.ArchiveChargeRatio, total map[int64]*model.UpBusinessIncome, signed map[int64]bool) { for mid, business := range total { realIncome := business.Income if r, ok := urs[mid]; ok { if r.AdjustType == 0 { // up主浮动调节,分配到视频业务 realIncome = int64(Round(float64(business.Income)*Div(float64(r.Ratio), float64(100)), 0)) } } // up主浮动调节后视频业务的税 tax := int64(Round(Tax(Div(float64(realIncome), 100))*100, 0)) // 税后收入 netIncome := realIncome - tax // update up income business.Percent = Div(float64(netIncome), float64(business.Income)) business.Income = netIncome business.Tax = tax } // 计算每个视频浮动调节后收入 for mid, as := range am { business := total[mid] // up主的固定调节收入 var patchIncome int64 var c bool for _, a := range as { avIncome := int64(Round(Mul(float64(a.Income), business.Percent), 0)) a.Income = avIncome a.TaxMoney = int64(Round(Mul(float64(business.Tax), Div(float64(avIncome), float64(business.Income))), 0)) // 以下是计算up主基础收入 // original raito: 100 var o int64 = 100 if upRatio, ok := urs[mid]; ok { if upRatio.AdjustType == 0 { o = upRatio.Ratio c = true } } avBaseIncome := int64(Round(Div(float64(avIncome), Div(float64(o), 100)), 0)) a.BaseIncome = avBaseIncome if r, ok := ars[a.AvID]; ok { if r.AdjustType == 0 { // 如果视频收入被加倍过,还原 originIncome := int64(Round(Div(float64(avBaseIncome), Div(float64(r.Ratio), 100)), 0)) a.BaseIncome = originIncome business.BaseIncome += originIncome c = true } if r.AdjustType == 1 { // av 固定调节, 更新av的收入和up主的基础收入 a.Income += r.Ratio // 更新up主的av收入, Income在计算BaseIncome后更新 // upIncome.AvIncome += r.Ratio // business.Income += r.Ratio patchIncome += r.Ratio business.BaseIncome += avBaseIncome } } else { business.BaseIncome += avBaseIncome } } // 如果没有被加倍过, 那么避免误差将BaseIncome直接置为Income if !c { business.BaseIncome = business.Income } // 最后加上该up主av的总固定调节收入 business.Income += patchIncome } // + up主的固定调节 for mid, ratio := range urs { if _, ok := signed[mid]; !ok { continue } if ratio.AdjustType == 0 { continue } if business, ok := total[mid]; ok { business.Income += ratio.Ratio } else { total[mid] = &model.UpBusinessIncome{ MID: mid, Income: ratio.Ratio, Business: 1, } } } } /*################################################################## BGM ########################################################################*/ func trans2BgmIncome(b *model.BGM, charge int64, date xtime.Time) *model.BgmIncome { return &model.BgmIncome{ AID: b.AID, SID: b.SID, MID: b.MID, CID: b.CID, Income: charge, Date: date, } } func bgm2BusinessIncome(b *model.BgmIncome) *model.UpBusinessIncome { return &model.UpBusinessIncome{ MID: b.MID, Income: b.Income, Business: 3, BgmCount: map[int64]bool{ b.SID: true, }, } } // bgms map[avid][sid]*model.BGM | bm map[mid]map[sid]map[avid]*model.BgmIncome 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) { bm = make(map[int64]map[int64]map[int64]*model.BgmIncome) total = make(map[int64]*model.UpBusinessIncome) for charges := range ch { CHARGE: for _, charge := range charges { for _, filter := range filters { if filter(charge) { continue CHARGE } } if bs, ok := bgms[charge.AvID]; ok { bgmCharge := int64(Round(Div(Mul(float64(charge.IncCharge), float64(0.3)), float64(len(bs))), 0)) for _, b := range bs { // if av's bgm is own, continue if b.MID == charge.MID { continue } if _, ok := black[b.SID]; ok { continue } if exclude(charge, b) { continue } var incr int64 if r, ok := ratio[b.SID]; ok { if r.AdjustType == 0 { incr = int64(Round(float64(bgmCharge)*Div(float64(r.Ratio), float64(100)), 0)) } else if r.AdjustType == 1 { incr = bgmCharge } } else { incr = bgmCharge } // bm map[mid]map[sid]map[avid]*model.BgmIncome var bgmIncome *model.BgmIncome if sm, ok := bm[b.MID]; ok { if am, ok := sm[b.SID]; ok { if bgmIncome, ok = am[b.AID]; ok { bgmIncome.Income += incr } else { bgmIncome = trans2BgmIncome(b, incr, charge.Date) am[b.AID] = bgmIncome } } else { bgmIncome = trans2BgmIncome(b, incr, charge.Date) sm[b.SID] = map[int64]*model.BgmIncome{ b.AID: bgmIncome, } } } else { bgmIncome = trans2BgmIncome(b, incr, charge.Date) // am map[avid]*model.BgmIncome am := map[int64]*model.BgmIncome{ b.AID: bgmIncome, } // sm map[sid]map[avid]*model.BgmIncome sm := map[int64]map[int64]*model.BgmIncome{ b.SID: am, } // bm map[mid]map[sid]map[avid]*model.BgmIncome bm[b.MID] = sm } if business, ok := total[b.MID]; ok { business.Income += incr business.BgmCount[b.SID] = true } else { business := bgm2BusinessIncome(bgmIncome) total[b.MID] = business } } } } } return } // 算税并分配收入 func classifyBgmIncome(bm map[int64]map[int64]map[int64]*model.BgmIncome, urs map[int64]*model.UpChargeRatio, ars map[int64]*model.ArchiveChargeRatio, total map[int64]*model.UpBusinessIncome, signed map[int64]bool) { for mid, business := range total { if business.Income == 0 { delete(total, mid) delete(bm, mid) continue } realIncome := business.Income if r, ok := urs[mid]; ok { if r.AdjustType == 0 { // up主浮动调节,分配到视频业务 realIncome = int64(Round(float64(business.Income)*Div(float64(r.Ratio), float64(100)), 0)) } } // up主浮动调节后视频业务的税 tax := int64(Round(Tax(Div(float64(realIncome), 100))*100, 0)) // 税后收入 netIncome := realIncome - tax // update up income business.Percent = Div(float64(netIncome), float64(business.Income)) business.Income = netIncome business.Tax = tax } // bm map[mid]map[sid]map[avid]*model.BgmIncome for mid, sm := range bm { business := total[mid] var c bool var patchIncome int64 for sid, bs := range sm { var dailyTotalIncome int64 for _, b := range bs { income := int64(Round(Mul(float64(b.Income), business.Percent), 0)) b.Income = income b.TaxMoney = int64(Round(Mul(float64(business.Tax), Div(float64(income), float64(business.Income))), 0)) dailyTotalIncome += b.Income // 以下是计算up主基础收入 // original raito: 100 var o int64 = 100 if upRatio, ok := urs[mid]; ok { if upRatio.AdjustType == 0 { o = upRatio.Ratio c = true } } bgmBaseIncome := int64(Round(Div(float64(income), Div(float64(o), 100)), 0)) b.BaseIncome = bgmBaseIncome if r, ok := ars[sid]; ok { if r.AdjustType == 0 { // 如果bgm收入被加倍过,还原 originIncome := int64(Round(Div(float64(bgmBaseIncome), Div(float64(r.Ratio), 100)), 0)) b.BaseIncome = originIncome business.BaseIncome += originIncome c = true } else { business.BaseIncome += bgmBaseIncome } } else { business.BaseIncome += bgmBaseIncome } } if r, ok := ars[sid]; ok { if r.AdjustType == 1 { patchIncome += r.Ratio dailyTotalIncome += r.Ratio } } // update bgm daily total income for _, b := range bs { b.DailyTotalIncome = dailyTotalIncome } } if !c { business.BaseIncome = business.Income } // 最后加上该up主bgm的总固定调节收入 business.Income += patchIncome } // + up主的固定调节 for mid, ratio := range urs { if _, ok := signed[mid]; !ok { continue } if ratio.AdjustType == 0 { continue } if business, ok := total[mid]; ok { business.Income += ratio.Ratio } else { total[mid] = &model.UpBusinessIncome{ MID: mid, Income: ratio.Ratio, Business: 3, } } } } /*###################################################### Column #######################################################*/ func trans2ColumnIncome(charge *model.ColumnCharge, incr int64) (c *model.ColumnIncome) { return &model.ColumnIncome{ ArticleID: charge.ArticleID, Title: charge.Title, MID: charge.MID, TagID: charge.TagID, UploadTime: charge.UploadTime, ViewCount: charge.IncViewCount, Date: charge.Date, Income: incr, BaseIncome: charge.IncCharge, } } // business type 2: column func column2BusinessIncome(c *model.ColumnIncome) *model.UpBusinessIncome { return &model.UpBusinessIncome{ MID: c.MID, Income: c.Income, ViewCount: c.ViewCount, ColumnCount: 1, Business: 2, } } func getClassifyColumnIncome(ch chan []*model.ColumnCharge, ratio map[int64]*model.ArchiveChargeRatio, filters []ColumnFilter) (cm map[int64][]*model.ColumnIncome, total map[int64]*model.UpBusinessIncome) { cm = make(map[int64][]*model.ColumnIncome) total = make(map[int64]*model.UpBusinessIncome) for charges := range ch { CHARGE: for _, charge := range charges { for _, filter := range filters { if filter(charge) { continue CHARGE } } var incr int64 if r, ok := ratio[charge.ArticleID]; ok { if r.AdjustType == 0 { incr = int64(Round(float64(charge.IncCharge)*Div(float64(r.Ratio), float64(100)), 0)) } else if r.AdjustType == 1 { incr = charge.IncCharge } } else { incr = charge.IncCharge } columnIncome := trans2ColumnIncome(charge, incr) if _, ok := cm[charge.MID]; ok { cm[charge.MID] = append(cm[charge.MID], columnIncome) } else { cm[charge.MID] = []*model.ColumnIncome{columnIncome} } if business, ok := total[charge.MID]; ok { business.ViewCount += columnIncome.ViewCount business.ColumnCount++ business.Income += columnIncome.Income } else { business := column2BusinessIncome(columnIncome) total[charge.MID] = business } } } return } // calculate column income and archive income func classifyColumnIncome(cm map[int64][]*model.ColumnIncome, urs map[int64]*model.UpChargeRatio, ars map[int64]*model.ArchiveChargeRatio, total map[int64]*model.UpBusinessIncome, signed map[int64]bool) { for mid, business := range total { realIncome := business.Income if r, ok := urs[mid]; ok { if r.AdjustType == 0 { // up主浮动调节,分配到视频业务 realIncome = int64(Round(float64(business.Income)*Div(float64(r.Ratio), float64(100)), 0)) } } // up主浮动调节后视频业务的税 tax := int64(Round(Tax(Div(float64(realIncome), 100))*100, 0)) // 税后收入 netIncome := realIncome - tax // update up income business.Percent = Div(float64(netIncome), float64(business.Income)) business.Income = netIncome business.Tax = tax } for mid, cs := range cm { business := total[mid] var x bool var patchIncome int64 for _, c := range cs { columnIncome := int64(Round(Mul(float64(c.Income), business.Percent), 0)) c.Income = columnIncome c.TaxMoney = int64(Round(Mul(float64(business.Tax), Div(float64(columnIncome), float64(business.Income))), 0)) // 以下是计算up主基础收入 // original raito: 100 var o int64 = 100 if upRatio, ok := urs[mid]; ok { if upRatio.AdjustType == 0 { o = upRatio.Ratio x = true } } columnBaseIncome := int64(Round(Div(float64(columnIncome), Div(float64(o), 100)), 0)) c.BaseIncome = columnBaseIncome if r, ok := ars[c.ArticleID]; ok { if r.AdjustType == 0 { // 如果视频收入被加倍过,还原 originIncome := int64(Round(Div(float64(columnBaseIncome), Div(float64(r.Ratio), 100)), 0)) c.BaseIncome = originIncome business.BaseIncome += originIncome x = true } if r.AdjustType == 1 { // column 固定调节, 更新column 的收入和up主的基础收入 c.Income += r.Ratio // 更新up主的column 收入, Income在计算BaseIncome后更新 patchIncome += r.Ratio business.BaseIncome += columnBaseIncome } } else { business.BaseIncome += columnBaseIncome } } if !x { business.BaseIncome = business.Income } // 最后加上该up主column的总固定调节收入 business.Income += patchIncome } // + up主的固定调节 for mid, ratio := range urs { if _, ok := signed[mid]; !ok { continue } if ratio.AdjustType == 0 { continue } if business, ok := total[mid]; ok { business.Income += ratio.Ratio } else { total[mid] = &model.UpBusinessIncome{ MID: mid, Income: ratio.Ratio, Business: 2, } } } } /**######################################################## UpIncome ###################################################################**/ // CalUpIncome calculate upIncome func (p *Income) CalUpIncome(ch chan map[int64]*model.UpBusinessIncome, date time.Time) (m map[int64]*model.UpIncome) { defer close(ch) m = make(map[int64]*model.UpIncome) var finished int for bm := range ch { for mid, business := range bm { if upIncome, ok := m[mid]; ok { if business.Business == 1 { upIncome.AvCount = business.AvCount upIncome.PlayCount = business.PlayCount upIncome.AvIncome = business.Income upIncome.AvBaseIncome = business.BaseIncome upIncome.AvTax = business.Tax } if business.Business == 2 { upIncome.ColumnCount = business.ColumnCount upIncome.ColumnIncome = business.Income upIncome.ColumnBaseIncome = business.BaseIncome upIncome.ColumnTax = business.Tax } if business.Business == 3 { upIncome.BgmIncome = business.Income upIncome.BgmBaseIncome = business.BaseIncome upIncome.BgmTax = business.Tax upIncome.BgmCount = int64(len(business.BgmCount)) } upIncome.TaxMoney += business.Tax upIncome.BaseIncome += business.BaseIncome upIncome.Income += business.Income } else { var upIncome *model.UpIncome if business.Business == 1 { upIncome = &model.UpIncome{ AvCount: business.AvCount, PlayCount: business.PlayCount, AvIncome: business.Income, AvBaseIncome: business.BaseIncome, AvTax: business.Tax, } } if business.Business == 2 { upIncome = &model.UpIncome{ ColumnCount: business.ColumnCount, ColumnIncome: business.Income, ColumnBaseIncome: business.BaseIncome, ColumnTax: business.Tax, } } if business.Business == 3 { upIncome = &model.UpIncome{ BgmIncome: business.Income, BgmBaseIncome: business.BaseIncome, BgmTax: business.Tax, BgmCount: int64(len(business.BgmCount)), } } upIncome.MID = mid upIncome.TaxMoney = business.Tax upIncome.BaseIncome = business.BaseIncome upIncome.Income = business.Income upIncome.Date = xtime.Time(date.Unix()) m[mid] = upIncome } } finished++ if finished == 3 { break } } return } // IncomeStat income statistics func (p *Income) IncomeStat( um map[int64]*model.UpIncome, am map[int64][]*model.AvIncome, bm map[int64]map[int64]map[int64]*model.BgmIncome, cm map[int64][]*model.ColumnIncome, ustat map[int64]*model.UpIncomeStat, astat map[int64]*model.AvIncomeStat, bstat map[int64]*model.BgmIncomeStat, cstat map[int64]*model.ColumnIncomeStat) { for mid, upIncome := range um { // update up income total income ut, ok := ustat[mid] if !ok { ut = &model.UpIncomeStat{ MID: upIncome.MID, DataState: 1, // insert } ustat[mid] = ut } else { ut.DataState = 2 // update } // update up income statis up total income // up av total income // up column total income // up bgm total income ut.TotalIncome += upIncome.Income upIncome.TotalIncome = ut.TotalIncome ut.AvTotalIncome += upIncome.AvIncome upIncome.AvTotalIncome = ut.AvTotalIncome ut.ColumnTotalIncome += upIncome.ColumnIncome upIncome.ColumnTotalIncome = ut.ColumnTotalIncome ut.BgmTotalIncome += upIncome.BgmIncome upIncome.BgmTotalIncome = ut.BgmTotalIncome // update av income total income for _, a := range am[mid] { at, ok := astat[a.AvID] if !ok { at = &model.AvIncomeStat{ AvID: a.AvID, MID: a.MID, TagID: a.TagID, IsOriginal: a.IsOriginal, UploadTime: a.UploadTime, DataState: 1, // insert } astat[a.AvID] = at } else { at.DataState = 2 // update } at.TotalIncome += a.Income a.TotalIncome = at.TotalIncome } // update bgmIncome total income for sid, am := range bm[mid] { bt, ok := bstat[sid] if !ok { bt = &model.BgmIncomeStat{ SID: sid, DataState: 1, // insert } bstat[sid] = bt } else { bt.DataState = 2 // update } for _, b := range am { bt.TotalIncome += b.DailyTotalIncome break } for _, b := range am { b.TotalIncome = bt.TotalIncome } } // update columnIncome total income for _, c := range cm[mid] { ct, ok := cstat[c.ArticleID] if !ok { ct = &model.ColumnIncomeStat{ ArticleID: c.ArticleID, Title: c.Title, TagID: c.TagID, MID: c.MID, UploadTime: c.UploadTime, DataState: 1, // insert } cstat[c.ArticleID] = ct } else { ct.DataState = 2 // update } ct.TotalIncome += c.Income c.TotalIncome = ct.TotalIncome } } } // PurgeUpAccount purge up account func (p *Income) PurgeUpAccount(date time.Time, accs map[int64]*model.UpAccount, um map[int64]*model.UpIncome) { fd := time.Date(date.Year(), date.Month(), 1, 0, 0, 0, 0, time.Local) last := fd.AddDate(0, 0, -1).Format("2006-01") // TODO check for mid, upIncome := range um { // update old up account if upAccount, ok := accs[mid]; ok { upAccount.TotalIncome += upIncome.Income if upAccount.WithdrawDateVersion == last { upAccount.TotalUnwithdrawIncome += upIncome.Income } upAccount.DataState = 2 } else { // append new up account accs[mid] = &model.UpAccount{ MID: mid, HasSignContract: 1, TotalIncome: upIncome.Income, TotalUnwithdrawIncome: upIncome.Income, WithdrawDateVersion: last, DataState: 1, } } } } /************************************************************ FOR HISTORY ****************************************************************/ // UpdateBusinessIncomeByDate update business income by date func (p *Income) UpdateBusinessIncomeByDate(c context.Context, date string) (err error) { ustat, err := p.upIncomeStatSvr.UpIncomeStat(c, int64(_limitSize)) if err != nil { return } return p.updateBusinessIncomeByDate(c, date, ustat) } func (p *Income) updateBusinessIncomeByDate(c context.Context, date string, ustat map[int64]*model.UpIncomeStat) (err error) { us, err := p.businessTotalIncome(c, ustat, date) if err != nil { return } err = p.batchUpdateUpIncome(c, us) if err != nil { return } return p.batchUpdateUpIncomeStat(c, ustat) } // for history data m: map[mid]map[date]*model.UpIncome func (p *Income) businessTotalIncome(c context.Context, ustat map[int64]*model.UpIncomeStat, date string) (m []*model.UpIncome, err error) { var id int64 for { var ups []*model.UpIncome ups, err = p.upIncomeSvr.dao.GetUpIncomeTable(c, "up_income", date, id, 2000) if err != nil { return } for _, up := range ups { if ut, ok := ustat[up.MID]; ok { ut.AvTotalIncome += up.AvIncome up.AvTotalIncome = ut.AvTotalIncome ut.ColumnTotalIncome += up.ColumnIncome up.ColumnTotalIncome = ut.ColumnTotalIncome ut.BgmTotalIncome += up.BgmIncome up.BgmTotalIncome = ut.BgmTotalIncome m = append(m, up) } } if len(ups) < 2000 { break } id = ups[len(ups)-1].ID } return } // BatchUpdateUpIncome insert up_income batch func (p *Income) batchUpdateUpIncome(c context.Context, us []*model.UpIncome) (err error) { var ( buff = make([]*model.UpIncome, p.upIncomeSvr.batchSize) buffEnd = 0 ) for _, u := range us { buff[buffEnd] = u buffEnd++ if buffEnd >= p.upIncomeSvr.batchSize { values := businessValues(buff[:buffEnd]) buffEnd = 0 _, err = p.upIncomeSvr.dao.FixInsertUpIncome(c, values) if err != nil { return } } } if buffEnd > 0 { values := businessValues(buff[:buffEnd]) buffEnd = 0 _, err = p.upIncomeSvr.dao.FixInsertUpIncome(c, values) } return } func businessValues(us []*model.UpIncome) (values string) { var buf bytes.Buffer for _, u := range us { buf.WriteString("(") buf.WriteString(strconv.FormatInt(u.MID, 10)) buf.WriteByte(',') buf.WriteString(strconv.FormatInt(u.AvTotalIncome, 10)) buf.WriteByte(',') buf.WriteString(strconv.FormatInt(u.ColumnTotalIncome, 10)) buf.WriteByte(',') buf.WriteString(strconv.FormatInt(u.BgmTotalIncome, 10)) buf.WriteByte(',') buf.WriteString("'" + u.Date.Time().Format(_layout) + "'") buf.WriteString(")") buf.WriteByte(',') } if buf.Len() > 0 { buf.Truncate(buf.Len() - 1) } values = buf.String() buf.Reset() return } // BatchUpdateUpIncome insert up_income batch func (p *Income) batchUpdateUpIncomeStat(c context.Context, us map[int64]*model.UpIncomeStat) (err error) { var ( buff = make([]*model.UpIncomeStat, p.upIncomeStatSvr.batchSize) buffEnd = 0 ) for _, u := range us { buff[buffEnd] = u buffEnd++ if buffEnd >= p.upIncomeStatSvr.batchSize { values := businessStatValues(buff[:buffEnd]) buffEnd = 0 _, err = p.upIncomeStatSvr.dao.FixInsertUpIncomeStat(c, values) if err != nil { return } } } if buffEnd > 0 { values := businessStatValues(buff[:buffEnd]) buffEnd = 0 _, err = p.upIncomeStatSvr.dao.FixInsertUpIncomeStat(c, values) } return } func businessStatValues(ustat []*model.UpIncomeStat) (values string) { var buf bytes.Buffer for _, u := range ustat { buf.WriteString("(") buf.WriteString(strconv.FormatInt(u.MID, 10)) buf.WriteByte(',') buf.WriteString(strconv.FormatInt(u.AvTotalIncome, 10)) buf.WriteByte(',') buf.WriteString(strconv.FormatInt(u.ColumnTotalIncome, 10)) buf.WriteByte(',') buf.WriteString(strconv.FormatInt(u.BgmTotalIncome, 10)) buf.WriteString(")") buf.WriteByte(',') } if buf.Len() > 0 { buf.Truncate(buf.Len() - 1) } values = buf.String() buf.Reset() return }