package provider import ( "context" "joybuywork/internal/app" "joybuywork/internal/repository/cache" "joybuywork/internal/repository/dao" "joybuywork/internal/repository/model" "joybuywork/internal/repository/mtype" "joybuywork/internal/utils" "joybuywork/internal/utils/merr" "fmt" ) type RewardAutoLang struct { KvData []*mtype.RewardKV `json:"kv_data,omitempty"` //奖品自定义参数数据 ReceiveType int32 `json:"receive_type"` //发放类型(1-系统发放,2-联系客服,3-客户端发放,4-实物) Contact string `json:"contact,omitempty"` //联系方式 Id int64 `json:"id"` Url string `json:"url,omitempty"` //回调地址 Title string `json:"title"` // 显示的奖品名称 ImgUrl string `json:"img_url"` // 显示的奖品图片 Mark string `json:"mark"` // 语言标识 IsDefault int32 `json:"is_default"` FindDefault bool `json:"find_default"` //只能找到默认数据 RewardTitle string `json:"reward_title"` //奖品标题 FormTitle string `json:"form_title"` //表单标题 OpenToUse int32 `json:"open_to_use"` //是否开启了“去使用” AppParam string `json:"app_param"` //app参数 PcParam string `json:"pc_param"` //pc参数 WebUrl string `json:"web_url"` //web端跳转参数 DyRewardType int32 `json:"dy_reward_type"` //动态奖品内容类型(0-无,1-兑换码) UrlId int64 `json:"url_id"` //回调地址 FormId int64 `json:"form_id"` //表单id } type RewardInfo struct { Id int64 `json:"id"` KvData []*mtype.RewardKV `json:"kv_data,omitempty"` //奖品自定义参数数据 ReceiveType int32 `json:"receive_type"` //发放类型(0-不做任何操作,1-系统发放,2-联系客服,3-客户端发放,4-实物) RewardTitle string `json:"reward_title,omitempty"` //奖品标题 Contact string `json:"contact,omitempty"` //联系方式 Url string `json:"url,omitempty"` //回调地址 Langs []*RewardLang `json:"langs,omitempty"` //语言数据 FormTitle string `json:"form_title"` //表单标题 DyRewardType int32 `json:"dy_reward_type"` //动态奖品内容类型(0-无,1-兑换码) UrlId int64 `json:"url_id"` //回调地址 FormId int64 `json:"form_id"` //表单id } type RewardLang struct { RewardId int64 `json:"reward_id"` Title string `json:"title"` ImgUrl string `json:"img_url"` Mark string `json:"mark"` IsDefault int32 `json:"is_default"` FindDefault bool `json:"find_default"` //只能找到默认数据 OpenToUse int32 `json:"open_to_use"` //是否开启了“去使用” AppParam string `json:"app_param"` //app参数 WebUrl string `json:"web_url"` //web端跳转参数 PcParam string `json:"pc_param"` //pc参数 } type Rewards struct { ctx context.Context be *merr.BusinessError projectId int64 find struct { list []*model.Reward } // 找到的数据 fmap map[int64]struct{} urlMap map[int64]string //地址id对应的地址信息 formMap map[int64]string //表单id对应的表单标题 rMap map[int64]*RewardInfo //奖品信息临时map rlMap map[string]RewardLang //奖品的语言信息临时map rls map[int64][]*model.RewardLang //奖品的语言信息列表临时map ralMap map[string]RewardAutoLang //奖品信息并且自动选匹配语种后的数据临时map } // NewRewards 奖品管理 func NewRewards(ctx context.Context, projectId int64, ids ...int64) (*Rewards, error) { p := &Rewards{ ctx: ctx, be: merr.NewBE(ctx), projectId: projectId, fmap: map[int64]struct{}{}, rlMap: map[string]RewardLang{}, rMap: map[int64]*RewardInfo{}, rls: map[int64][]*model.RewardLang{}, ralMap: map[string]RewardAutoLang{}, } err := p._find(ids...) return p, err } func (s *Rewards) Append(ids ...int64) (*Rewards, error) { err := s._find(ids...) return s, err } // InfoListWithLang 奖品列表信息带语言 func (s *Rewards) InfoListWithLang(ids ...int64) (list []*RewardInfo, err error) { list, err = s.InfoList(ids...) for _, v := range list { if len(v.Langs) != 0 { continue } langs := s.rls[v.Id] for _, lang := range langs { v.Langs = append(v.Langs, &RewardLang{ RewardId: lang.RewardID, Title: lang.Title, ImgUrl: lang.ImgURL, Mark: lang.Mark, IsDefault: int32(lang.IsDefault), }) } } return } // InfoWithLang 奖品信息带语言 func (s *Rewards) InfoWithLang(ids ...int64) (info *RewardInfo, err error) { info, err = s.Info(ids...) if err != nil { return } if len(info.Langs) != 0 { return } langs := s.rls[info.Id] for _, lang := range langs { info.Langs = append(info.Langs, &RewardLang{ RewardId: lang.RewardID, Title: lang.Title, ImgUrl: lang.ImgURL, Mark: lang.Mark, IsDefault: int32(lang.IsDefault), FindDefault: false, OpenToUse: int32(lang.OpenToUse), AppParam: lang.AppParam, WebUrl: lang.WebURL, PcParam: lang.PcParam, }) } return } // InfoList 奖品列表信息 func (s *Rewards) InfoList(ids ...int64) (list []*RewardInfo, err error) { urlMap, err := s._url() if err != nil { return } formMap, err := s._form() if err != nil { return } if len(ids) > 0 { // 找id list = make([]*RewardInfo, 0, len(ids)) var inMap = make(map[int64]struct{}) for _, id := range ids { inMap[id] = struct{}{} } for _, v := range s.find.list { if _, ok := inMap[v.ID]; ok { list = append(list, s.one(v, urlMap[v.URLID], formMap[v.FormID])) } } return } // 全都找 list = make([]*RewardInfo, 0, len(s.find.list)) for _, v := range s.find.list { list = append(list, s.one(v, urlMap[v.URLID], formMap[v.FormID])) } return } // InfoMap 奖品列表信息 func (s *Rewards) InfoMap(ids ...int64) (list map[int64]*RewardInfo, err error) { urlMap, err := s._url() if err != nil { return } formMap, err := s._form() if err != nil { return } if len(ids) > 0 { // 找id的 list = make(map[int64]*RewardInfo, len(ids)) var inMap = make(map[int64]struct{}) for _, id := range ids { inMap[id] = struct{}{} } for _, v := range s.find.list { if _, ok := inMap[v.ID]; ok { list[v.ID] = s.one(v, urlMap[v.URLID], formMap[v.FormID]) } } return } // 全都找 list = make(map[int64]*RewardInfo, len(s.find.list)) for _, v := range s.find.list { list[v.ID] = s.one(v, urlMap[v.URLID], formMap[v.FormID]) } return } // Info 奖品信息 func (s *Rewards) Info(ids ...int64) (info *RewardInfo, err error) { for _, id := range ids { var ok bool info, ok = s.rMap[id] if ok { return } } defer func() { if err == nil && info != nil { s.rMap[info.Id] = info } }() urlMap, err := s._url() if err != nil { return } formMap, err := s._form() if err != nil { return } if len(ids) == 0 { for _, v := range s.find.list { return s.one(v, urlMap[v.URLID], formMap[v.FormID]), nil } return } for _, v := range s.find.list { for _, id := range ids { if v.ID == id { return s.one(v, urlMap[v.URLID], formMap[v.FormID]), nil } } } return } // AutoLang 自动匹配语言 func (s *Rewards) AutoLang(rewardId int64, langMarks ...string) (lang RewardLang) { key := fmt.Sprint(rewardId) if len(langMarks) > 0 { key += "_" + langMarks[0] } if info, ok := s.rlMap[key]; ok { return info } defer func() { s.rlMap[key] = lang }() langs := s.rls[rewardId] for _, v := range langs { for _, mark := range langMarks { if v.Mark == mark { return RewardLang{ RewardId: v.RewardID, Title: v.Title, ImgUrl: v.ImgURL, Mark: v.Mark, IsDefault: int32(v.IsDefault), FindDefault: false, OpenToUse: int32(v.OpenToUse), AppParam: v.AppParam, WebUrl: v.WebURL, PcParam: v.PcParam, } } } } for _, v := range langs { if v.IsDefault == mtype.Yes { return RewardLang{ RewardId: v.RewardID, Title: v.Title, ImgUrl: v.ImgURL, Mark: v.Mark, IsDefault: int32(v.IsDefault), FindDefault: true, OpenToUse: int32(v.OpenToUse), AppParam: v.AppParam, WebUrl: v.WebURL, PcParam: v.PcParam, } } } return } func (s *Rewards) InfoAutoLang(rewardId int64, langMarks ...string) (data RewardAutoLang, err error) { key := fmt.Sprint(rewardId) if len(langMarks) > 0 { key += "_" + langMarks[0] } if cd, ok := s.ralMap[key]; ok { return cd, nil } defer func() { if err == nil { s.ralMap[key] = data } }() info, err := s.Info(rewardId) if err != nil { return } if info == nil { err = s.be.VerifyError("not found reward info") return } lang := s.AutoLang(rewardId, langMarks...) return RewardAutoLang{ KvData: info.KvData, ReceiveType: info.ReceiveType, Contact: info.Contact, Id: info.Id, Url: info.Url, Title: lang.Title, ImgUrl: lang.ImgUrl, Mark: lang.Mark, IsDefault: lang.IsDefault, FindDefault: lang.FindDefault, RewardTitle: info.RewardTitle, FormTitle: info.FormTitle, OpenToUse: lang.OpenToUse, AppParam: lang.AppParam, PcParam: lang.PcParam, WebUrl: lang.WebUrl, DyRewardType: info.DyRewardType, UrlId: info.UrlId, FormId: info.FormId, }, nil } func (s *Rewards) InfoAutoLangMap(langMarks ...string) (data map[int64]*RewardAutoLang, err error) { list, err := s.InfoList() if err != nil { return } data = make(map[int64]*RewardAutoLang, len(list)) for _, info := range list { lang := s.AutoLang(info.Id, langMarks...) data[info.Id] = &RewardAutoLang{ KvData: info.KvData, ReceiveType: info.ReceiveType, Contact: info.Contact, Id: info.Id, Url: info.Url, Title: lang.Title, ImgUrl: lang.ImgUrl, Mark: lang.Mark, IsDefault: lang.IsDefault, FindDefault: lang.FindDefault, RewardTitle: info.RewardTitle, FormTitle: info.FormTitle, OpenToUse: lang.OpenToUse, AppParam: lang.AppParam, PcParam: lang.PcParam, WebUrl: lang.WebUrl, DyRewardType: info.DyRewardType, UrlId: info.UrlId, FormId: info.FormId, } } return } // 找到对应的数据 func (s *Rewards) _find(fids ...int64) (err error) { var rewardIds []int64 if len(fids) == 0 { rewardIds, err = s._findByProjectId() } else { rewardIds, err = s._findByIds(fids...) } if err != nil { return } return s._findRewardLang(rewardIds) } func (s *Rewards) _findByProjectId() (rewardIds []int64, err error) { m := dao.Reward list, err := m.WithContext(s.ctx). Where( m.ProjectID.Eq(s.projectId), m.OldData.Eq(mtype.No), m.IsDel.Eq(mtype.No)). Order(m.ID.Desc()). Find() if err != nil { err = s.be.MysqlError(err) return } for _, v := range list { if _, ok := s.fmap[v.ID]; ok { continue } s.find.list = append(s.find.list, v) s.fmap[v.ID] = struct{}{} rewardIds = append(rewardIds, v.ID) } return } func (s *Rewards) _findByIds(fids ...int64) (rewardIds []int64, err error) { var fixIds, ids []int64 for _, v := range fids { if _, ok := s.fmap[v]; ok { continue } if v < 0 { fixIds = append(fixIds, v) continue } ids = append(ids, v) } if len(fixIds) > 0 { for _, reward := range app.FissionFixRewards { s.find.list = append(s.find.list, &model.Reward{ ID: reward.Id, RewardTitle: reward.RewardTitle, }) for _, lang := range reward.Langs { s.rls[reward.Id] = append(s.rls[reward.Id], &model.RewardLang{ RewardID: reward.Id, Mark: lang.Mark, IsDefault: utils.Ternary[int8](lang.IsDefault, mtype.Yes, mtype.No), Title: lang.Title, ImgURL: lang.ImgUrl, }) } } } if len(ids) == 0 { return } c := cache.NewReward(s.ctx) list, err := c.FindByIds(ids) if err != nil { err = s.be.CacheError(err) return } for _, v := range list { s.find.list = append(s.find.list, v) s.fmap[v.ID] = struct{}{} rewardIds = append(rewardIds, v.ID) } return } func (s *Rewards) _findRewardLang(rewardIds []int64) (err error) { rlm := dao.RewardLang list, err := rlm.WithContext(s.ctx).Where(rlm.RewardID.In(rewardIds...), rlm.IsDel.Eq(mtype.No)).Find() if err != nil { err = s.be.MysqlError(err) return } for _, v := range list { s.rls[v.RewardID] = append(s.rls[v.RewardID], v) } return } func (s *Rewards) _url() (urlMap map[int64]string, err error) { if len(s.urlMap) != 0 { return s.urlMap, nil } var ids []int64 urlMap = make(map[int64]string) for _, v := range s.find.list { if _, ok := urlMap[v.URLID]; !ok { ids = append(ids, v.URLID) urlMap[v.URLID] = "" } } if len(ids) == 0 { return } m := dao.NotifyURL list, err := m.WithContext(s.ctx).Where(m.ID.In(ids...)).Find() if err != nil { err = s.be.MysqlError(err) return } for _, url := range list { urlMap[url.ID] = url.URL } s.urlMap = urlMap return } func (s *Rewards) _form() (formMap map[int64]string, err error) { if len(s.formMap) != 0 { return s.formMap, nil } var ids []int64 formMap = make(map[int64]string) for _, v := range s.find.list { if _, ok := formMap[v.FormID]; !ok && v.FormID > 0 { ids = append(ids, v.FormID) formMap[v.FormID] = "" } } if len(ids) == 0 { return } m := dao.Form list, err := m.WithContext(s.ctx).Where(m.ID.In(ids...)).Find() if err != nil { err = s.be.MysqlError(err) return } for _, form := range list { formMap[form.ID] = form.Title } s.formMap = formMap return } func (s *Rewards) one(val *model.Reward, url, formTitle string) *RewardInfo { return &RewardInfo{ Id: val.ID, KvData: val.GetKvData(), ReceiveType: int32(val.ReceiveType), RewardTitle: val.RewardTitle, Contact: val.Contact, Url: url, Langs: nil, FormTitle: formTitle, DyRewardType: int32(val.DyRewardType), UrlId: val.URLID, FormId: val.FormID, } } func (s *Rewards) GetProjectId() int64 { return s.projectId }