You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

622 lines
14 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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
}