go-common/app/job/main/growup/service/income/income.go
2019-04-22 18:49:16 +08:00

964 lines
27 KiB
Go

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
}