123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359 |
- package income
- import (
- "bytes"
- "context"
- "fmt"
- "strconv"
- "time"
- upModel "go-common/app/admin/main/growup/model"
- model "go-common/app/admin/main/growup/model/income"
- "go-common/app/admin/main/growup/service"
- "go-common/library/database/sql"
- "go-common/library/log"
- xtime "go-common/library/time"
- "go-common/library/xstr"
- "golang.org/x/sync/errgroup"
- )
- // BreachList list
- func (s *Service) BreachList(c context.Context, mids, aids []int64, typ int, fromTime, toTime int64, reason string, from, limit int) (breachs []*model.AvBreach, total int, err error) {
- query := formatBreachQuery(mids, aids, typ, fromTime, toTime, reason)
- total, err = s.dao.BreachCount(c, query)
- if err != nil {
- log.Error("s.dao.GetBreachCount error(%v)", err)
- return
- }
- query = fmt.Sprintf("%s LIMIT %d,%d", query, from, limit)
- breachs, err = s.dao.ListArchiveBreach(c, query)
- if err != nil {
- log.Error("s.dao.ListArchiveBreach error(%v)", err)
- }
- mids = make([]int64, 0, len(breachs))
- for _, b := range breachs {
- mids = append(mids, b.MID)
- }
- nickname, err := s.dao.ListUpInfo(c, mids)
- for _, b := range breachs {
- b.Nickname = nickname[b.MID]
- }
- return
- }
- // BreachStatis statis
- func (s *Service) BreachStatis(c context.Context, mids, aids []int64, typ, groupType int, fromTime, toTime int64, reason string) (date interface{}, err error) {
- from := getDateByGroup(groupType, time.Unix(fromTime, 0))
- to := getDateByGroup(groupType, time.Unix(toTime, 0))
- query := formatBreachQuery(mids, aids, typ, from.Unix(), to.Unix(), reason)
- breachs, err := s.dao.ListArchiveBreach(c, query)
- if err != nil {
- log.Error("s.dao.ListArchiveBreach error(%v)", err)
- return
- }
- date = breachStatis(breachs, from, to, groupType)
- return
- }
- func breachStatis(breachs []*model.AvBreach, from, to time.Time, groupType int) interface{} {
- dateIncome := make(map[string]int64)
- dateUps := make(map[string]map[int64]struct{})
- for _, breach := range breachs {
- date := formatDateByGroup(breach.CDate.Time(), groupType)
- if _, ok := dateIncome[date]; ok {
- dateIncome[date] += breach.Money
- } else {
- dateIncome[date] = breach.Money
- }
- if _, ok := dateUps[date]; !ok {
- dateUps[date] = make(map[int64]struct{})
- }
- dateUps[date][breach.MID] = struct{}{}
- }
- income, counts, xAxis := []string{}, []int{}, []string{}
- // get result by date
- to = to.AddDate(0, 0, 1)
- for from.Before(to) {
- dateStr := formatDateByGroup(from, groupType)
- xAxis = append(xAxis, dateStr)
- if val, ok := dateIncome[dateStr]; ok {
- income = append(income, fmt.Sprintf("%.2f", float64(val)/float64(100)))
- counts = append(counts, len(dateUps[dateStr]))
- } else {
- income = append(income, "0")
- counts = append(counts, 0)
- }
- from = addDayByGroup(groupType, from)
- }
- return map[string]interface{}{
- "counts": counts,
- "incomes": income,
- "xaxis": xAxis,
- }
- }
- // ExportBreach export
- func (s *Service) ExportBreach(c context.Context, mids, aids []int64, typ int, fromTime, toTime int64, reason string, from, limit int) (res []byte, err error) {
- breachs, _, err := s.BreachList(c, mids, aids, typ, fromTime, toTime, reason, from, limit)
- if err != nil {
- log.Error("s.BreachList error(%v)", err)
- return
- }
- records := formatBreach(breachs)
- res, err = service.FormatCSV(records)
- if err != nil {
- log.Error("FormatCSV error(%v)")
- }
- return
- }
- func formatBreachQuery(mids, aids []int64, typ int, fromTime, toTime int64, reason string) (query string) {
- query = fmt.Sprintf("cdate >= '%s' AND cdate <= '%s'", time.Unix(fromTime, 0).Format(_layout), time.Unix(toTime, 0).Format(_layout))
- if typ != 4 {
- query = fmt.Sprintf("%s AND ctype = %d", query, typ)
- }
- if len(mids) > 0 {
- query = fmt.Sprintf("%s AND mid IN (%s)", query, xstr.JoinInts(mids))
- }
- if len(aids) > 0 {
- query = fmt.Sprintf("%s AND av_id IN (%s)", query, xstr.JoinInts(aids))
- }
- if reason != "" {
- query = fmt.Sprintf("%s AND reason = '%s'", query, reason)
- }
- return
- }
- // ArchiveBreach breach archive batch
- func (s *Service) ArchiveBreach(c context.Context, typ int, aids []int64, mid int64, reason string, operator string) (err error) {
- count, err := s.dao.BreachCount(c, fmt.Sprintf("av_id in (%s) AND cdate = '%s'", xstr.JoinInts(aids), time.Now().Format(_layout)))
- if err != nil {
- log.Error("s.dao.AvBreachCount error(%v)", err)
- return
- }
- if count > 0 {
- err = fmt.Errorf("有稿件已被扣除")
- return
- }
- return s.avBreach(c, typ, aids, mid, reason, operator)
- }
- func assembleAvBreach(aids []int64, mid int64, ctype int, reason string, breach map[int64]int64, upload map[int64]string) (vals string) {
- var buf bytes.Buffer
- for _, aid := range aids {
- buf.WriteString("(")
- buf.WriteString(strconv.FormatInt(aid, 10))
- buf.WriteByte(',')
- buf.WriteString(strconv.FormatInt(mid, 10))
- buf.WriteByte(',')
- buf.WriteString("'" + time.Now().Format(_layout) + "'")
- buf.WriteByte(',')
- buf.WriteString(strconv.FormatInt(breach[aid], 10))
- buf.WriteByte(',')
- buf.WriteString(strconv.Itoa(ctype))
- buf.WriteByte(',')
- buf.WriteString("\"" + reason + "\"")
- buf.WriteByte(',')
- buf.WriteString("'" + upload[aid] + "'")
- buf.WriteString(")")
- buf.WriteByte(',')
- }
- if buf.Len() > 0 {
- buf.Truncate(buf.Len() - 1)
- }
- vals = buf.String()
- buf.Reset()
- return
- }
- // AvBreach av breach from av_income
- func (s *Service) avBreach(c context.Context, ctype int, aids []int64, mid int64, reason string, operator string) (err error) {
- archives, withdrawMonth, err := s.GetArchiveByUpAccount(c, ctype, aids, mid)
- if err != nil {
- log.Error("s.GetArchiveByUpAccount error(%v)", err)
- return
- }
- if len(archives) == 0 {
- return
- }
- preMonthBreach, thisMonthBreach, avBreach, avUpload := getBreachMoney(archives, withdrawMonth)
- tx, err := s.dao.BeginTran(c)
- if err != nil {
- log.Error("s.dao.BeginTran error(%v)", err)
- return
- }
- var eg errgroup.Group
- // insert av_breach
- eg.Go(func() (err error) {
- if _, err = s.dao.TxInsertAvBreach(tx, assembleAvBreach(aids, mid, ctype, reason, avBreach, avUpload)); err != nil {
- log.Error("s.TxInsertAvBreach error(%v)", err)
- tx.Rollback()
- }
- return
- })
- // update av breach pre state = 2
- eg.Go(func() (err error) {
- if _, err = s.dao.TxUpdateBreachPre(tx, aids, time.Now().Format(_layout)); err != nil {
- log.Error("s.TxUpdateBreachPre error(%v)", err)
- tx.Rollback()
- }
- return
- })
- // save av_black_list
- eg.Go(func() (err error) {
- if err = s.TxInsertAvBlacklist(c, tx, ctype, aids, mid, _avBreach, len(aids)); err != nil {
- log.Error("s.InsertAvBlacklist error(%v)", err)
- }
- return
- })
- // update up_account
- eg.Go(func() (err error) {
- if err = s.TxUpAccountBreach(c, tx, mid, preMonthBreach, thisMonthBreach); err != nil {
- log.Error("s.UpdateUpAccount error(%v)", err)
- }
- return
- })
- // update up credit score
- eg.Go(func() (err error) {
- if err = s.UpdateUpCredit(c, tx, ctype, mid, aids, operator); err != nil {
- log.Error("s.UpdateUpCredit error(%v)", err)
- }
- return
- })
- eg.Go(func() (err error) {
- if _, err = s.upDao.TxUpdateAvSpyState(tx, 1, aids); err != nil {
- tx.Rollback()
- log.Error("s.upDao.TxUpdateAvSpyState error(%v)", err)
- }
- return
- })
- if err = eg.Wait(); err != nil {
- log.Error("run eg.Wait error(%v)", err)
- return
- }
- if err = tx.Commit(); err != nil {
- log.Error("tx.Commit error")
- return
- }
- var business string
- switch ctype {
- case _video:
- business = "avid"
- case _column:
- business = "cv"
- case _bgm:
- business = "au"
- }
- for _, aid := range aids {
- err = s.msg.Send(c, "1_14_5",
- fmt.Sprintf("您的稿件 %s %d 违反创作激励计划规则。", business, aid),
- fmt.Sprintf("您的稿件 %s %d 因为%s原因被取消参加创作激励计划资格,已获得收入将被扣除。如有疑问,请联系客服。", business, aid, reason),
- []int64{mid},
- time.Now().Unix())
- if err != nil {
- log.Error("s.msg.Send error(%v)", err)
- return
- }
- }
- return
- }
- // UpdateUpCredit update up_info credit score
- func (s *Service) UpdateUpCredit(c context.Context, tx *sql.Tx, ctype int, mid int64, aids []int64, operator string) (err error) {
- score, err := s.upDao.CreditScore(c, mid)
- if err != nil {
- return
- }
- // insert credit_score_record
- creditRecord := &upModel.CreditRecord{
- MID: mid,
- OperateAt: xtime.Time(time.Now().Unix()),
- Operator: operator,
- Reason: 9,
- Deducted: 3 * len(aids),
- Remaining: score - 3*len(aids),
- }
- r1, err := s.upDao.TxInsertCreditRecord(tx, creditRecord)
- if err != nil {
- tx.Rollback()
- return
- }
- r2, err := s.upDao.TxUpdateCreditScore(tx, mid, score-3*len(aids))
- if err != nil {
- tx.Rollback()
- return
- }
- if r1 != r2 {
- tx.Rollback()
- return
- }
- return
- }
- // GetArchiveByUpAccount get archive income by withdraw date
- func (s *Service) GetArchiveByUpAccount(c context.Context, typ int, aids []int64, mid int64) (archives []*model.ArchiveIncome, withdrawMonth time.Month, err error) {
- archives = make([]*model.ArchiveIncome, 0)
- upAccount, err := s.dao.GetUpAccount(c, mid)
- if err != nil {
- if err == sql.ErrNoRows {
- err = nil
- return
- }
- log.Error("s.dao.GetUpAccount error(%v)", err)
- return
- }
- withdrawDateStr := upAccount.WithdrawDateVersion + "-01"
- withdrawDate, err := time.Parse(_layout, withdrawDateStr)
- if err != nil {
- log.Error("time.Parse error(%v)", err)
- return
- }
- withdrawMonth = withdrawDate.AddDate(0, 1, 0).Month()
- from, now := withdrawDate.AddDate(0, 1, 0).Format(_layout), time.Now().Format(_layout)
- query := ""
- switch typ {
- case _video:
- query = fmt.Sprintf("av_id in (%s)", xstr.JoinInts(aids))
- case _column:
- query = fmt.Sprintf("aid in (%s)", xstr.JoinInts(aids))
- case _bgm:
- query = fmt.Sprintf("sid in (%s)", xstr.JoinInts(aids))
- }
- archives, err = s.GetArchiveIncome(c, typ, query, from, now)
- if err != nil {
- log.Error("s.GetArchiveIncome error(%v)", err)
- }
- return
- }
- func getBreachMoney(archives []*model.ArchiveIncome, withdrawMonth time.Month) (int64, int64, map[int64]int64, map[int64]string) {
- var preMonthBreach, thisMonthBreach int64 = 0, 0
- avBreach := make(map[int64]int64)
- avUpload := make(map[int64]string)
- for _, arch := range archives {
- if arch.Date.Time().Month() == withdrawMonth {
- preMonthBreach += arch.Income
- } else {
- thisMonthBreach += arch.Income
- }
- avBreach[arch.AvID] += arch.Income
- avUpload[arch.AvID] = arch.UploadTime.Time().Format(_layout)
- }
- return preMonthBreach, thisMonthBreach, avBreach, avUpload
- }
|