123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- package service
- import (
- "context"
- "fmt"
- "time"
- "go-common/app/job/main/vip/model"
- "go-common/library/log"
- "github.com/pkg/errors"
- )
- //ScanSalaryVideoCoupon scan all vip user to salary video coupon.
- func (s *Service) ScanSalaryVideoCoupon(c context.Context) (err error) {
- var (
- userInfos []*model.VipInfoDB
- size = 100
- endID int
- now = time.Now()
- dv = now.Format("2006_01")
- y = now.Year()
- m = now.Month()
- salaryDate = time.Date(y, m, s.c.Property.SalaryDay, 0, 0, 0, 0, time.Local)
- )
- for {
- if endID, err = s.dao.SelUserInfoMaxID(context.TODO()); err != nil {
- log.Error("s.dao.SelMaxID error(%v)", err)
- time.Sleep(time.Minute * 2)
- continue
- }
- break
- }
- page := endID / size
- if endID%size != 0 {
- page++
- }
- for i := 0; i < page; {
- log.Info("salary page(%d) total(%d) ....................................", i, page)
- startID := i * size
- eID := (i + 1) * size
- if userInfos, err = s.dao.SelEffectiveScopeVipList(context.TODO(), startID, eID); err != nil {
- log.Error("s.dao.SelEffectiveScopeVipList error(%v)", err)
- time.Sleep(time.Second * 5)
- continue
- }
- i++
- for _, v := range userInfos {
- time.Sleep(time.Duration(s.c.Property.SalaryVideoCouponnIterval))
- var (
- vipType = model.NotVip
- )
- if v.Status != model.VipStatusNotOverTime && v.Status != model.VipStatusFrozen {
- continue
- }
- if salaryDate.Before(v.OverdueTime.Time()) {
- vipType = model.Vip
- if salaryDate.Before(v.AnnualVipOverdueTime.Time()) {
- vipType = model.AnnualVip
- }
- }
- if vipType == model.NotVip {
- continue
- }
- day := v.OverdueTime.Time().Sub(v.RecentTime.Time()).Hours() / model.DayOfHour
- if day < model.VipDaysMonth {
- continue
- }
- if err = s.salaryCoupon(c, v.Mid, model.TimingSalaryType, int8(vipType), dv, model.CouponSalaryTiming); err != nil {
- err = errors.Wrapf(err, "salaryCoupon mid(%d)(%v)", v.Mid, v)
- log.Error("%+v", err)
- continue
- }
- log.Info("salary suc mid(%d) ....................................", v.Mid)
- }
- }
- return
- }
- // salaryCoupon salary coupon.
- func (s *Service) salaryCoupon(c context.Context, mid int64, salaryType int8, vipType int8, dv string, atonce int8) (err error) {
- var (
- logs []*model.VideoCouponSalaryLog
- hs = map[int8]int64{} // key:coupontype value:salarycount
- ms map[string]int64 // key:viptype value:salarycount
- )
- if logs, err = s.dao.SalaryVideoCouponList(c, mid, dv); err != nil {
- err = errors.WithStack(err)
- return
- }
- for _, v := range logs {
- hs[v.CouponType] = hs[v.CouponType] + v.CouponCount
- }
- for _, v := range s.c.Property.SalaryCouponTypes {
- ms = s.c.Property.SalaryCouponMaps[fmt.Sprintf("%d", v)]
- if len(ms) != 0 {
- if salaryType == model.VipSupplyType {
- if hs[v] == 0 {
- hs[v] = ms[fmt.Sprintf("%d", model.AnnualVip)] - ms[fmt.Sprintf("%d", model.Vip)]
- } else {
- hs[v] = ms[fmt.Sprintf("%d", model.AnnualVip)] - hs[v]
- }
- } else {
- hs[v] = ms[fmt.Sprintf("%d", vipType)] - hs[v]
- }
- }
- }
- for k, count := range hs {
- var (
- token string
- tokenfmt string
- )
- if count <= 0 {
- continue
- }
- tokenfmt = s.c.Property.SalaryCouponBatchNoMaps[fmt.Sprintf("%d", k)]
- if len(tokenfmt) == 0 {
- continue
- }
- token = fmt.Sprintf(tokenfmt, atonce, dv)
- if err = s.dao.SalaryCoupon(c, mid, k, count, token); err != nil {
- err = errors.Wrapf(err, "s.dao.SalaryCoupon(%d)", mid)
- return
- }
- l := &model.VideoCouponSalaryLog{
- Mid: mid,
- CouponCount: count,
- State: model.HadSalaryState,
- Type: salaryType,
- CouponType: k,
- }
- if err = s.dao.AddSalaryLog(c, l, dv); err != nil {
- err = errors.WithStack(err)
- return
- }
- if s.c.Property.MsgOpen {
- var (
- title string
- content string
- )
- title = s.c.Property.SalaryCouponMsgTitleMaps[fmt.Sprintf("%d", k)]
- if len(title) == 0 {
- continue
- }
- if salaryType == model.VipSupplyType {
- content = s.c.Property.SalaryCouponMsgSupplyContentMaps[fmt.Sprintf("%d", k)]
- if len(content) == 0 {
- continue
- }
- content = fmt.Sprintf(content, count)
- } else {
- content = s.c.Property.SalaryCouponMsgContentMaps[fmt.Sprintf("%d", k)]
- if len(content) == 0 {
- continue
- }
- }
- s.sendmessage(func() {
- s.dao.SendMultipMsg(context.TODO(), fmt.Sprintf("%d", mid), content,
- title, model.MsgCouponSalaryMc, model.MsgSystemNotify)
- })
- }
- }
- return
- }
- // SalaryVideoCouponAtOnce salary video coupon at once.
- func (s *Service) SalaryVideoCouponAtOnce(c context.Context, nvip *model.VipUserInfoMsg, ovip *model.VipUserInfoMsg, act string) (res int, err error) {
- if act == _insertAction {
- if err = s.salaryInsertAct(c, nvip); err != nil {
- err = errors.Wrapf(err, "salaryInsertAct (%v)", nvip)
- return
- }
- } else if act == _updateAction {
- if err = s.salaryUpdateAct(c, nvip, ovip); err != nil {
- err = errors.Wrapf(err, "salaryInsertAct (%v)", nvip)
- return
- }
- }
- return
- }
- func (s *Service) salaryInsertAct(c context.Context, nvip *model.VipUserInfoMsg) (err error) {
- var (
- now = time.Now()
- otime time.Time
- aotime time.Time
- vipType = model.NotVip
- zeroTime = now.AddDate(-10, 0, 0)
- salaryType int8
- dv = now.Format("2006_01")
- )
- otime, err = time.ParseInLocation(model.TimeFormatSec, nvip.OverdueTime, time.Local)
- if err != nil {
- log.Error("time.ParseInLocation error(%v)", errors.Wrapf(err, "time(%s)", nvip.OverdueTime))
- otime = zeroTime
- err = nil
- }
- aotime, err = time.ParseInLocation(model.TimeFormatSec, nvip.AnnualVipOverdueTime, time.Local)
- if err != nil {
- aotime = zeroTime
- err = nil
- }
- if nvip.Status != model.VipStatusNotOverTime && nvip.Status != model.VipStatusFrozen {
- return
- }
- days := otime.Sub(now).Hours() / model.DayOfHour
- if days < model.VipDaysMonth {
- log.Info("cur user not enough send coupon (%+v)", nvip)
- return
- }
- if now.Before(otime) {
- vipType = model.Vip
- if now.Before(aotime) {
- vipType = model.AnnualVip
- }
- }
- switch vipType {
- case model.Vip:
- salaryType = model.NormalVipSalaryType
- case model.AnnualVip:
- salaryType = model.AnnualVipSalaryType
- default:
- return
- }
- if err = s.salaryCoupon(c, int64(nvip.Mid), salaryType, int8(vipType), dv, model.CouponSalaryAtonce); err != nil {
- err = errors.Wrapf(err, "salaryCoupon mid(%d)(%v)", nvip.Mid, nvip)
- }
- return
- }
- func (s *Service) salaryUpdateAct(c context.Context, nvip *model.VipUserInfoMsg, ovip *model.VipUserInfoMsg) (err error) {
- var (
- ovType int
- nvType int
- expire bool
- now = time.Now()
- zeroTime = now.AddDate(-10, 0, 0)
- ntime time.Time
- oatime time.Time
- natime time.Time
- salaryType int8
- dv = now.Format("2006_01")
- )
- ntime, err = time.ParseInLocation(model.TimeFormatSec, nvip.OverdueTime, time.Local)
- if err != nil {
- log.Error("time.ParseInLocation error(%v)", errors.Wrapf(err, "time(%s)", nvip.OverdueTime))
- ntime = zeroTime
- err = nil
- }
- natime, err = time.ParseInLocation(model.TimeFormatSec, nvip.AnnualVipOverdueTime, time.Local)
- if err != nil {
- natime = zeroTime
- err = nil
- }
- // check OverdueTime time.
- if ntime.Before(now) {
- return
- }
- nvType = model.Vip
- // check AnnualVipOverdueTime time.
- if now.Before(natime) {
- nvType = model.AnnualVip
- }
- // check old vip info expire.
- expire, _ = s.judgeVipExpire(c, ovip)
- if expire {
- //check open days is enough 31
- days := ntime.Sub(now).Hours() / model.DayOfHour
- if days < model.VipDaysMonth {
- log.Info("cur user not enough send coupon (%+v)", nvip)
- return
- }
- if nvType == model.Vip {
- // expire vip -> vip
- salaryType = model.NormalVipSalaryType
- } else if nvType == model.AnnualVip {
- // expire vip -> annual vip
- salaryType = model.AnnualVipSalaryType
- }
- } else {
- if ovip.Type == model.Vip {
- ovType = model.Vip
- }
- oatime, err = time.ParseInLocation(model.TimeFormatSec, ovip.AnnualVipOverdueTime, time.Local)
- if err != nil {
- oatime = zeroTime
- err = nil
- }
- if ovip.Type == model.AnnualVip && oatime.After(now) {
- ovType = model.AnnualVip
- }
- if ovType == model.Vip && nvType == model.AnnualVip {
- // normal vip -> annual vip
- salaryType = model.VipSupplyType
- }
- // short vip -> normal vip
- recentTime := parseTime(ovip.RecentTime)
- otime := parseTime(ovip.OverdueTime)
- days := otime.Sub(recentTime).Hours() / model.DayOfHour
- if days < model.VipDaysMonth {
- //check open days is enough 31
- days := ntime.Sub(now).Hours() / model.DayOfHour
- if days < model.VipDaysMonth {
- log.Info("cur user not enough send coupon (%+v)", nvip)
- return
- }
- if nvType == model.Vip {
- // expire vip -> vip
- salaryType = model.NormalVipSalaryType
- } else if nvType == model.AnnualVip {
- // expire vip -> annual vip
- salaryType = model.AnnualVipSalaryType
- }
- }
- }
- switch salaryType {
- case model.NormalVipSalaryType, model.AnnualVipSalaryType, model.VipSupplyType:
- if err = s.salaryCoupon(c, int64(nvip.Mid), salaryType, int8(nvType), dv, model.CouponSalaryAtonce); err != nil {
- err = errors.Wrapf(err, "salaryCoupon mid(%d)(%v)", int64(nvip.Mid), nvip)
- }
- }
- return
- }
- // judgeVipExpire judge vip is expire.
- func (s *Service) judgeVipExpire(c context.Context, v *model.VipUserInfoMsg) (expire bool, err error) {
- var (
- now = time.Now()
- overdueTime time.Time
- zeroTime = now.AddDate(-10, 0, 0)
- )
- if v.Status != model.VipStatusNotOverTime && v.Status != model.VipStatusFrozen {
- expire = true
- return
- }
- overdueTime, err = time.ParseInLocation(model.TimeFormatSec, v.OverdueTime, time.Local)
- if err != nil {
- log.Error("time.ParseInLocation error(%v)", errors.Wrapf(err, "time(%s)", v.OverdueTime))
- overdueTime = zeroTime
- err = nil
- }
- if overdueTime.Before(now) {
- expire = true
- return
- }
- return
- }
|