273 lines
8.6 KiB
Go
273 lines
8.6 KiB
Go
package income
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"math"
|
|
"strconv"
|
|
"time"
|
|
|
|
incomeD "go-common/app/job/main/growup/dao/income"
|
|
model "go-common/app/job/main/growup/model/income"
|
|
|
|
"go-common/library/log"
|
|
xtime "go-common/library/time"
|
|
)
|
|
|
|
var (
|
|
_avIncomeDailyStatis = "av_income_daily_statis"
|
|
_avIncomeWeeklyStatis = "av_income_weekly_statis"
|
|
_avIncomeMonthlyStatis = "av_income_monthly_statis"
|
|
|
|
_cmIncomeDailyStatis = "column_income_daily_statis"
|
|
_cmIncomeWeeklyStatis = "column_income_weekly_statis"
|
|
_cmIncomeMonthlyStatis = "column_income_monthly_statis"
|
|
|
|
_bgmIncomeDailyStatis = "bgm_income_daily_statis"
|
|
_bgmIncomeWeeklyStatis = "bgm_income_weekly_statis"
|
|
_bgmIncomeMonthlyStatis = "bgm_income_monthly_statis"
|
|
)
|
|
|
|
// SectionEntries section entries
|
|
type SectionEntries struct {
|
|
avDaily []*model.DateStatis
|
|
avWeekly []*model.DateStatis
|
|
avMonthly []*model.DateStatis
|
|
}
|
|
|
|
// DateStatis income date statistics
|
|
type DateStatis struct {
|
|
dao *incomeD.Dao
|
|
}
|
|
|
|
// NewDateStatis new income date statistics service
|
|
func NewDateStatis(dao *incomeD.Dao) *DateStatis {
|
|
return &DateStatis{dao: dao}
|
|
}
|
|
|
|
func initIncomeSections(income, tagID int64, date xtime.Time) []*model.DateStatis {
|
|
incomeSections := make([]*model.DateStatis, 12)
|
|
incomeSections[0] = initIncomeSection(0, 1, 0, income, tagID, date)
|
|
incomeSections[1] = initIncomeSection(1, 5, 1, income, tagID, date)
|
|
incomeSections[2] = initIncomeSection(5, 10, 2, income, tagID, date)
|
|
incomeSections[3] = initIncomeSection(10, 30, 3, income, tagID, date)
|
|
incomeSections[4] = initIncomeSection(30, 50, 4, income, tagID, date)
|
|
incomeSections[5] = initIncomeSection(50, 100, 5, income, tagID, date)
|
|
incomeSections[6] = initIncomeSection(100, 200, 6, income, tagID, date)
|
|
incomeSections[7] = initIncomeSection(200, 500, 7, income, tagID, date)
|
|
incomeSections[8] = initIncomeSection(500, 1000, 8, income, tagID, date)
|
|
incomeSections[9] = initIncomeSection(1000, 3000, 9, income, tagID, date)
|
|
incomeSections[10] = initIncomeSection(3000, 5000, 10, income, tagID, date)
|
|
incomeSections[11] = initIncomeSection(5000, math.MaxInt32, 11, income, tagID, date)
|
|
return incomeSections
|
|
}
|
|
|
|
func initIncomeSection(min, max, section, income, tagID int64, date xtime.Time) *model.DateStatis {
|
|
var tips string
|
|
if max == math.MaxInt32 {
|
|
tips = fmt.Sprintf("\"%d+\"", min)
|
|
} else {
|
|
tips = fmt.Sprintf("\"%d~%d\"", min, max)
|
|
}
|
|
return &model.DateStatis{
|
|
MinIncome: min,
|
|
MaxIncome: max,
|
|
MoneySection: section,
|
|
MoneyTips: tips,
|
|
Income: income,
|
|
CategoryID: tagID,
|
|
CDate: date,
|
|
}
|
|
}
|
|
|
|
func (s *DateStatis) handleDateStatis(c context.Context, archiveCh chan []*model.ArchiveIncome, date time.Time, table string) (incomeSections []*model.DateStatis, err error) {
|
|
// delete
|
|
if table != "" {
|
|
_, err = s.dao.DelIncomeStatisTable(c, table, date.Format(_layout))
|
|
if err != nil {
|
|
log.Error("s.dao.DelIncomeStatisTable error(%v)", err)
|
|
return
|
|
}
|
|
}
|
|
// add
|
|
incomeSections = s.handleArchives(c, archiveCh, date)
|
|
return
|
|
}
|
|
|
|
// handleArchives handle archive_income_daily_statis, archive_income_weekly_statis, archive_income_monthly_statis
|
|
func (s *DateStatis) handleArchives(c context.Context, archiveCh chan []*model.ArchiveIncome, date time.Time) (incomeSections []*model.DateStatis) {
|
|
archTagMap := make(map[int64]map[int64]int64) // key TagID, value map[int64]int64 -> key aid, value income
|
|
tagIncomeMap := make(map[int64]int64) // key TagID, value TagID total income
|
|
for archive := range archiveCh {
|
|
handleArchive(archive, archTagMap, tagIncomeMap, date)
|
|
}
|
|
incomeSections = make([]*model.DateStatis, 0)
|
|
for tagID, avMap := range archTagMap {
|
|
incomeSection := countIncomeDailyStatis(avMap, tagIncomeMap[tagID], tagID, date)
|
|
incomeSections = append(incomeSections, incomeSection...)
|
|
}
|
|
return
|
|
}
|
|
|
|
func handleArchive(archives []*model.ArchiveIncome, archTagMap map[int64]map[int64]int64, tagIncomeMap map[int64]int64, startDate time.Time) {
|
|
if archives == nil {
|
|
return
|
|
}
|
|
if archTagMap == nil {
|
|
archTagMap = make(map[int64]map[int64]int64)
|
|
}
|
|
if tagIncomeMap == nil {
|
|
tagIncomeMap = make(map[int64]int64)
|
|
}
|
|
|
|
for _, archive := range archives {
|
|
if !startDate.After(archive.Date.Time()) {
|
|
tagIncomeMap[archive.TagID] += archive.Income
|
|
if _, ok := archTagMap[archive.TagID]; !ok {
|
|
archTagMap[archive.TagID] = make(map[int64]int64)
|
|
}
|
|
archTagMap[archive.TagID][archive.AID] += archive.Income
|
|
}
|
|
}
|
|
}
|
|
|
|
func (s *DateStatis) handleDateUp(c context.Context, upStatisCh chan []*model.UpIncome, date time.Time) (upSections, upAvSections, upCmSections, upBgmSections []*model.DateStatis, err error) {
|
|
_, err = s.dao.DelIncomeStatisTable(c, "up_income_daily_statis", date.Format(_layout))
|
|
if err != nil {
|
|
log.Error("s.dao.DelIncomeStatisTable error(%v)", err)
|
|
return
|
|
}
|
|
|
|
_, err = s.dao.DelIncomeStatisTable(c, "up_av_daily_statis", date.Format(_layout))
|
|
if err != nil {
|
|
log.Error("s.dao.DelIncomeStatisTable error(%v)", err)
|
|
return
|
|
}
|
|
|
|
_, err = s.dao.DelIncomeStatisTable(c, "up_column_daily_statis", date.Format(_layout))
|
|
if err != nil {
|
|
log.Error("s.dao.DelIncomeStatisTable error(%v)", err)
|
|
return
|
|
}
|
|
|
|
_, err = s.dao.DelIncomeStatisTable(c, "up_bgm_daily_statis", date.Format(_layout))
|
|
if err != nil {
|
|
log.Error("s.dao.DelIncomeStatisTable error(%v)", err)
|
|
return
|
|
}
|
|
|
|
upMap := make(map[int64]int64)
|
|
upAvMap := make(map[int64]int64)
|
|
upCmMap := make(map[int64]int64)
|
|
upBgmMap := make(map[int64]int64)
|
|
var upTotal, avTotal, cmTotal, bgmTotal int64
|
|
for up := range upStatisCh {
|
|
up, av, cm, bgm := handleUp(up, upMap, upAvMap, upCmMap, upBgmMap, date)
|
|
upTotal += up
|
|
avTotal += av
|
|
cmTotal += cm
|
|
bgmTotal += bgm
|
|
}
|
|
upSections = countIncomeDailyStatis(upMap, upTotal, 0, date)
|
|
upAvSections = countIncomeDailyStatis(upAvMap, avTotal, 0, date)
|
|
upCmSections = countIncomeDailyStatis(upCmMap, cmTotal, 0, date)
|
|
upBgmSections = countIncomeDailyStatis(upBgmMap, bgmTotal, 0, date)
|
|
return
|
|
}
|
|
|
|
func handleUp(upIncomes []*model.UpIncome, upMap, upAvMap, upCmMap, upBgmMap map[int64]int64, startDate time.Time) (income, avIncome, cmIncome, bgmIncome int64) {
|
|
if len(upIncomes) == 0 {
|
|
return
|
|
}
|
|
for _, upIncome := range upIncomes {
|
|
if startDate.Equal(upIncome.Date.Time()) {
|
|
income += upIncome.Income
|
|
avIncome += upIncome.AvIncome
|
|
cmIncome += upIncome.ColumnIncome
|
|
bgmIncome += upIncome.BgmIncome
|
|
upMap[upIncome.MID] += upIncome.Income
|
|
if upIncome.AvIncome > 0 {
|
|
upAvMap[upIncome.MID] += upIncome.AvIncome
|
|
}
|
|
if upIncome.ColumnIncome > 0 {
|
|
upCmMap[upIncome.MID] += upIncome.ColumnIncome
|
|
}
|
|
if upIncome.BgmIncome > 0 {
|
|
upBgmMap[upIncome.MID] += upIncome.BgmIncome
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (s *DateStatis) incomeDateStatisInsert(c context.Context, incomeSection []*model.DateStatis, table string) (rows int64, err error) {
|
|
var buf bytes.Buffer
|
|
for _, row := range incomeSection {
|
|
buf.WriteString("(")
|
|
buf.WriteString(strconv.FormatInt(row.Count, 10))
|
|
buf.WriteByte(',')
|
|
buf.WriteString(strconv.FormatInt(row.MoneySection, 10))
|
|
buf.WriteByte(',')
|
|
buf.WriteString(row.MoneyTips)
|
|
buf.WriteByte(',')
|
|
buf.WriteString(strconv.FormatInt(row.Income, 10))
|
|
buf.WriteByte(',')
|
|
buf.WriteString(strconv.FormatInt(row.CategoryID, 10))
|
|
buf.WriteByte(',')
|
|
buf.WriteString("'" + row.CDate.Time().Format(_layout) + "'")
|
|
buf.WriteString(")")
|
|
buf.WriteByte(',')
|
|
}
|
|
|
|
if buf.Len() > 0 {
|
|
buf.Truncate(buf.Len() - 1)
|
|
}
|
|
vals := buf.String()
|
|
buf.Reset()
|
|
rows, err = s.dao.InsertIncomeStatisTable(c, table, vals)
|
|
return
|
|
}
|
|
|
|
func countIncomeDailyStatis(incomes map[int64]int64, totalIncome, tagID int64, date time.Time) (incomeSections []*model.DateStatis) {
|
|
if len(incomes) == 0 {
|
|
return
|
|
}
|
|
incomeSections = initIncomeSections(totalIncome, tagID, xtime.Time(date.Unix()))
|
|
for _, income := range incomes {
|
|
for _, section := range incomeSections {
|
|
min, max := section.MinIncome*100, section.MaxIncome*100
|
|
if income >= min && income < max {
|
|
section.Count++
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (s *DateStatis) upIncomeDailyStatisInsert(c context.Context, upIncomeSection []*model.DateStatis, table string) (rows int64, err error) {
|
|
var buf bytes.Buffer
|
|
for _, row := range upIncomeSection {
|
|
buf.WriteString("(")
|
|
buf.WriteString(strconv.FormatInt(row.Count, 10))
|
|
buf.WriteByte(',')
|
|
buf.WriteString(strconv.FormatInt(row.MoneySection, 10))
|
|
buf.WriteByte(',')
|
|
buf.WriteString(row.MoneyTips)
|
|
buf.WriteByte(',')
|
|
buf.WriteString(strconv.FormatInt(row.Income, 10))
|
|
buf.WriteByte(',')
|
|
buf.WriteString("'" + row.CDate.Time().Format(_layout) + "'")
|
|
buf.WriteString(")")
|
|
buf.WriteByte(',')
|
|
}
|
|
|
|
if buf.Len() > 0 {
|
|
buf.Truncate(buf.Len() - 1)
|
|
}
|
|
vals := buf.String()
|
|
buf.Reset()
|
|
rows, err = s.dao.InsertUpIncomeDailyStatis(c, table, vals)
|
|
return
|
|
}
|