Initial commit
This commit is contained in:
@@ -0,0 +1,588 @@
|
||||
package channelSer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"stat/api/proto"
|
||||
"stat/common/log"
|
||||
"stat/models/adminMod"
|
||||
"stat/models/appInfoMod"
|
||||
"stat/models/channelmod"
|
||||
"stat/models/registermod"
|
||||
"time"
|
||||
|
||||
"github.com/360EntSecGroup-Skylar/excelize"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
// SearchChannelInfo 查询渠道信息
|
||||
func SearchChannelInfo(ctx context.Context, req *proto.ChannelInfoSearch) (
|
||||
*proto.ChannelInfoSearchResp, error) {
|
||||
filter := bson.M{}
|
||||
opt := &options.FindOptions{}
|
||||
opt.SetSort(bson.M{channelmod.FN.ChannelInfo.CreatedAt: -1})
|
||||
opt.SetSkip((req.PageNum - 1) * req.PageSize)
|
||||
opt.SetLimit(req.PageSize)
|
||||
|
||||
resp := &proto.ChannelInfoSearchResp{}
|
||||
|
||||
if req.ID != nil && *req.ID != "" {
|
||||
id, err := primitive.ObjectIDFromHex(*req.ID)
|
||||
if err != nil {
|
||||
return nil, errors.New("ID 格式错误")
|
||||
}
|
||||
filter[channelmod.FN.ChannelInfo.ID] = id
|
||||
}
|
||||
if req.Channel != nil && *req.Channel != "" {
|
||||
filter[channelmod.FN.ChannelInfo.Channel] = bson.M{"$regex": *req.Channel}
|
||||
}
|
||||
|
||||
if req.AppId != nil {
|
||||
filter[channelmod.FN.ChannelInfo.AppIds] = bson.M{"$in": []int32{*req.AppId}}
|
||||
}
|
||||
if req.Type != nil {
|
||||
filter[channelmod.FN.ChannelInfo.Type] = *req.Type
|
||||
}
|
||||
if req.ParentChannel != nil && *req.ParentChannel != "" {
|
||||
filter[channelmod.FN.ChannelInfo.ParentChannel] = bson.M{"$regex": *req.ParentChannel}
|
||||
}
|
||||
if req.UserName != nil && *req.UserName != "" {
|
||||
filter[channelmod.FN.ChannelInfo.UserName] = *req.UserName
|
||||
}
|
||||
if req.Status != nil {
|
||||
filter[channelmod.FN.ChannelInfo.Status] = *req.Status
|
||||
}
|
||||
if req.Remark != nil && *req.Remark != "" {
|
||||
filter[channelmod.FN.ChannelInfo.Remark] = bson.M{"$regex": *req.Remark}
|
||||
}
|
||||
|
||||
if req.Mobile != nil && *req.Mobile != "" {
|
||||
filter[channelmod.FN.ChannelInfo.Mobile] = bson.M{"$regex": *req.Mobile}
|
||||
}
|
||||
|
||||
total, serr := channelmod.CountChannelInfos(ctx, filter)
|
||||
if serr != nil {
|
||||
return nil, serr
|
||||
}
|
||||
if total == 0 {
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
channelInfoList, err := channelmod.FindManyChannelInfo(ctx, filter, opt)
|
||||
if serr != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := range channelInfoList {
|
||||
channelInfoList[i].Token = ""
|
||||
}
|
||||
resp.List = channelInfoList
|
||||
resp.Total = total
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// SearchChannelInfoExport 导出渠道信息
|
||||
func SearchChannelInfoExport(ctx context.Context, req *proto.ChannelInfoSearch) (string, error) {
|
||||
filter := bson.M{}
|
||||
opt := &options.FindOptions{}
|
||||
opt.SetSort(bson.M{channelmod.FN.ChannelInfo.CreatedAt: -1})
|
||||
opt.SetSkip((req.PageNum - 1) * req.PageSize)
|
||||
opt.SetLimit(req.PageSize)
|
||||
|
||||
if req.ID != nil && *req.ID != "" {
|
||||
id, err := primitive.ObjectIDFromHex(*req.ID)
|
||||
if err != nil {
|
||||
return "", errors.New("ID 格式错误")
|
||||
}
|
||||
filter[channelmod.FN.ChannelInfo.ID] = id
|
||||
}
|
||||
if req.Channel != nil && *req.Channel != "" {
|
||||
filter[channelmod.FN.ChannelInfo.Channel] = bson.M{"$regex": *req.Channel}
|
||||
}
|
||||
|
||||
if req.AppId != nil {
|
||||
filter[channelmod.FN.ChannelInfo.AppIds] = bson.M{"$in": []int32{*req.AppId}}
|
||||
}
|
||||
if req.Type != nil {
|
||||
filter[channelmod.FN.ChannelInfo.Type] = *req.Type
|
||||
}
|
||||
if req.ParentChannel != nil && *req.ParentChannel != "" {
|
||||
filter[channelmod.FN.ChannelInfo.ParentChannel] = bson.M{"$regex": *req.ParentChannel}
|
||||
}
|
||||
if req.UserName != nil && *req.UserName != "" {
|
||||
filter[channelmod.FN.ChannelInfo.UserName] = bson.M{"$regex": *req.UserName}
|
||||
}
|
||||
if req.Status != nil {
|
||||
filter[channelmod.FN.ChannelInfo.Status] = *req.Status
|
||||
}
|
||||
if req.Remark != nil && *req.Remark != "" {
|
||||
filter[channelmod.FN.ChannelInfo.Remark] = bson.M{"$regex": *req.Remark}
|
||||
}
|
||||
|
||||
if req.Remark != nil && *req.Remark != "" {
|
||||
filter[channelmod.FN.ChannelInfo.Remark] = bson.M{"$regex": *req.Remark}
|
||||
}
|
||||
|
||||
total, serr := channelmod.CountChannelInfos(ctx, filter)
|
||||
if serr != nil {
|
||||
return "", serr
|
||||
}
|
||||
if total == 0 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
appList, err := appInfoMod.GetAllAppInfo(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
channelInfoList, err := channelmod.FindManyChannelInfo(ctx, filter, opt)
|
||||
if serr != nil {
|
||||
return "", err
|
||||
}
|
||||
filePath := fmt.Sprintf("./tmp/兑换记录-%s.xlsx", time.Now().Format("2006-01-02 15:04:05"))
|
||||
if sErr := channelInfoExport(filePath, channelInfoList, appList); sErr != nil {
|
||||
return "", sErr
|
||||
}
|
||||
return filePath, nil
|
||||
}
|
||||
|
||||
// channelInfoExport 导出
|
||||
func channelInfoExport(filePath string, list channelmod.ChannelInfoList, appList []appInfoMod.AppInfo) error {
|
||||
f := excelize.NewFile()
|
||||
sheetName := "Sheet1"
|
||||
// 设置列宽
|
||||
f.SetColWidth("Sheet1", "A", "L", 23)
|
||||
|
||||
// 设置表头行高
|
||||
f.SetRowHeight("Sheet1", 1, 25)
|
||||
// 设置表头样式
|
||||
headStyleID, _ := f.NewStyle(`{
|
||||
"font":{
|
||||
"color":"#333333",
|
||||
"bold":true,
|
||||
"size":16,
|
||||
"family":"arial"
|
||||
},
|
||||
"alignment":{
|
||||
"vertical":"center",
|
||||
"horizontal":"center",
|
||||
"wrap_text":true
|
||||
}
|
||||
}`)
|
||||
f.SetCellStyle("Sheet1", "A1", "L1", headStyleID)
|
||||
idx := f.NewSheet(sheetName)
|
||||
var exportTransWaterTitle = map[string]string{
|
||||
"A1": "名称",
|
||||
"B1": "应用列表",
|
||||
"C1": "渠道类型",
|
||||
"D1": "IP",
|
||||
"E1": "下级代理数",
|
||||
"F1": "父渠道",
|
||||
"G1": "禁止登陆",
|
||||
"H1": "渠道状态",
|
||||
"I1": "登陆错误次数",
|
||||
"J1": "创建者",
|
||||
"K1": "创建时间",
|
||||
"L1": "更新时间",
|
||||
}
|
||||
for k, v := range exportTransWaterTitle {
|
||||
f.SetCellValue(sheetName, k, v)
|
||||
}
|
||||
var cLock string
|
||||
var cStatus string
|
||||
for k, v := range list {
|
||||
apps := string2app(appList, v.AppIds)
|
||||
i := 'A' // i 不能超过Z,即列输不能超过26列,超出将出现bug
|
||||
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), v.Channel) //名称
|
||||
i++
|
||||
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), apps) //应用列表
|
||||
i++
|
||||
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), v.Type.String()) //渠道类型
|
||||
i++
|
||||
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), v.IP) //IP
|
||||
i++
|
||||
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), v.ChildCount) //下级代理数
|
||||
i++
|
||||
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), v.ParentChannel) //父渠道
|
||||
i++
|
||||
if v.Lock {
|
||||
cLock = "封禁"
|
||||
} else if !v.Lock {
|
||||
cLock = "未封禁"
|
||||
}
|
||||
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), cLock) //禁止登陆
|
||||
i++
|
||||
if v.Status {
|
||||
cStatus = "开启"
|
||||
} else if !v.Status {
|
||||
cStatus = "关闭"
|
||||
}
|
||||
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), cStatus) //渠道状态
|
||||
i++
|
||||
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), v.ShowMagic) //登陆错误次数
|
||||
i++
|
||||
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), v.UserName) //创建者
|
||||
i++
|
||||
created := v.CreatedAt.Local().Format("2006-01-02 15:04:05")
|
||||
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), created) //创建时间
|
||||
i++
|
||||
updated := v.UpdatedAt.Local().Format("2006-01-02 15:04:05")
|
||||
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), updated) //更新时间
|
||||
}
|
||||
f.SetActiveSheet(idx)
|
||||
p, _ := os.Getwd()
|
||||
fileName := path.Join(p, filePath)
|
||||
if err := f.SaveAs(fileName); err != nil {
|
||||
log.Error("redeemCodeExport:export save file to disk failed",
|
||||
log.Any("fileName", fileName),
|
||||
log.E(err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func string2app(appList []appInfoMod.AppInfo, appIds []int32) string {
|
||||
var result string
|
||||
for count, id := range appIds {
|
||||
if count == len(appIds)-1 {
|
||||
result += GetAppName(appList, id)
|
||||
} else {
|
||||
result += (GetAppName(appList, id) + "、")
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// AddChannelInfo 添加一个媒体视频
|
||||
func AddChannelInfo(ctx context.Context, username string, req *proto.ChannelInfoAdd) (*channelmod.ChannelInfo, error) {
|
||||
if channelmod.IsOfficialChannelName(req.Channel) {
|
||||
return nil, fmt.Errorf("渠道名字为系统保留字,请换一个渠道名字")
|
||||
}
|
||||
checkFilter := bson.M{channelmod.FN.ChannelInfo.Channel: req.Channel}
|
||||
channelInfo, err := channelmod.FindOneChannelInfo(ctx, checkFilter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if channelInfo.Channel == req.Channel {
|
||||
return channelInfo, errors.New("渠道已经存在")
|
||||
}
|
||||
now := time.Now()
|
||||
newChannelInfo := channelmod.ChannelInfo{
|
||||
Channel: req.Channel,
|
||||
UserName: username,
|
||||
ParentChannel: req.ParentChannel,
|
||||
Password: req.Password,
|
||||
Status: req.Status,
|
||||
Mobile: req.Mobile,
|
||||
Type: req.Type,
|
||||
Remark: req.Remark,
|
||||
Lock: req.Lock,
|
||||
ChildShowDivideRate: req.ChildShowDivideRate,
|
||||
ShowMagic: 0,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
if req.Type == channelmod.ChannelTypeParent {
|
||||
newChannelInfo.ParentChannel = ""
|
||||
newChannelInfo.ParentAgent = ""
|
||||
} else if req.Type == channelmod.ChannelTypeSecond {
|
||||
parentInfo, err := channelmod.FindOneChannelInfo(ctx, bson.M{channelmod.FN.ChannelInfo.Channel: req.ParentChannel})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if parentInfo.Channel != req.ParentChannel {
|
||||
return nil, fmt.Errorf("指定的父渠道[%s]不存在", req.ParentChannel)
|
||||
}
|
||||
newChannelInfo.ParentChannel = req.ParentChannel
|
||||
newChannelInfo.ParentAgent = req.ParentChannel
|
||||
} else {
|
||||
return nil, errors.New("后台只支持添加一级和二级渠道,其他级别的渠道请登陆渠道后台添加")
|
||||
}
|
||||
|
||||
err = channelmod.InsertOneChannelInfo(ctx, &newChannelInfo)
|
||||
if err != nil {
|
||||
log.Error("AddChannelInfo InsertOneChannelInfo", log.Any("channel", newChannelInfo.ParentChannel), log.E(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if req.Type.IsChild() {
|
||||
setdoc := bson.M{"$inc": bson.M{channelmod.FN.ChannelInfo.ChildCount: 1}}
|
||||
err = channelmod.UpdateOneChannelInfo(ctx, bson.M{channelmod.FN.ChannelInfo.Channel: newChannelInfo.ParentChannel}, setdoc)
|
||||
if err != nil {
|
||||
log.Error("AddChannelInfo UpdateOneChannelInfo", log.Any("channel", newChannelInfo.ParentChannel), log.E(err))
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return channelmod.FindOneChannelInfo(ctx, checkFilter)
|
||||
}
|
||||
|
||||
// DelChannelInfo 删除指定渠道信息
|
||||
func DelChannelInfo(ctx context.Context, channelId string) error {
|
||||
id, err := primitive.ObjectIDFromHex(channelId)
|
||||
if err != nil {
|
||||
return errors.New("ID 格式错误")
|
||||
}
|
||||
// 1. 查询渠道信息
|
||||
channelFilter := bson.M{channelmod.FN.ChannelInfo.ID: id}
|
||||
channelInfo, err := channelmod.FindOneChannelInfo(ctx, channelFilter)
|
||||
if err != nil {
|
||||
log.Error("DelChannelInfo FindOneChannelInfo", log.Any("channelId", channelId), log.E(err))
|
||||
return err
|
||||
}
|
||||
// 3. 查询子代理数
|
||||
childFilter := bson.M{channelmod.FN.ChannelInfo.ParentAgent: channelInfo.Channel}
|
||||
childCount, err := channelmod.CountChannelInfos(ctx, childFilter)
|
||||
if err != nil {
|
||||
log.Error("DelChannelInfo CountChannelDeductionRules", log.Any("channelId", channelId), log.E(err))
|
||||
return err
|
||||
}
|
||||
if childCount > 0 {
|
||||
return errors.New("代理下级代理不为空,请先删除下级代理")
|
||||
}
|
||||
|
||||
// 2. 查询渠道绑定应用
|
||||
ruleFilter := bson.M{channelmod.FN.ChannelDeductionRule.Channel: channelInfo.Channel}
|
||||
ruleCount, err := channelmod.CountChannelDeductionRules(ctx, ruleFilter)
|
||||
if err != nil {
|
||||
log.Error("DelChannelInfo CountChannelDeductionRules", log.Any("channelId", channelId), log.E(err))
|
||||
return err
|
||||
}
|
||||
if ruleCount > 0 {
|
||||
return errors.New("绑定应用不为空,请先删除绑定应用")
|
||||
}
|
||||
// 4. 删除渠道
|
||||
_, err = channelmod.DelOneChannelInfo(ctx, channelFilter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 5 更新父渠道子渠道数量
|
||||
if channelInfo.Type.IsChild() {
|
||||
setdoc := bson.M{"$inc": bson.M{channelmod.FN.ChannelInfo.ChildCount: -1}}
|
||||
err = channelmod.UpdateOneChannelInfo(ctx, bson.M{channelmod.FN.ChannelInfo.Channel: channelInfo.ParentAgent}, setdoc)
|
||||
if err != nil {
|
||||
log.Error("DelChannelInfo UpdateOneChannelInfo", log.Any("channel", channelInfo.ParentAgent), log.E(err))
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateChannelInfo 更新指定渠道
|
||||
func UpdateChannelInfo(ctx context.Context, channelId string, req proto.ChannelInfoUpdate) error {
|
||||
|
||||
id, err := primitive.ObjectIDFromHex(channelId)
|
||||
if err != nil {
|
||||
return errors.New("ID 格式错误")
|
||||
}
|
||||
filter := bson.M{channelmod.FN.ChannelInfo.ID: id}
|
||||
|
||||
//更新数据库
|
||||
setDoc := bson.M{"$set": req}
|
||||
|
||||
serr := channelmod.UpdateOneChannelInfo(ctx, filter, setDoc)
|
||||
if serr != nil {
|
||||
return serr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateOneChannelOwner 更新指定渠道的所有者
|
||||
func UpdateOneChannelOwner(ctx context.Context, operator, account string, req proto.ChannelOwnerUpdate) error {
|
||||
|
||||
filter := bson.M{channelmod.FN.ChannelInfo.Channel: req.Channel}
|
||||
|
||||
cInfo, serr := channelmod.FindOneChannelInfo(ctx, filter)
|
||||
if serr != nil {
|
||||
log.Error("UpdateOneChannelOwner:FindOneChannelInfo err", log.Any("serr", serr),
|
||||
log.Any("req", req))
|
||||
return serr
|
||||
} else if cInfo != nil && cInfo.Channel == "" {
|
||||
log.Error("UpdateOneChannelOwner:FindOneChannelInfo err", log.Any("serr", serr),
|
||||
log.Any("req", req))
|
||||
return errors.New("渠道不存在")
|
||||
}
|
||||
|
||||
if req.UserName == "" {
|
||||
return errors.New("变更的所有者不能为空")
|
||||
} else if req.UserName == cInfo.UserName {
|
||||
return errors.New("变更的所有者不能与之前的相同")
|
||||
// } else if cInfo.Type != 1 { // 只能操作1级渠道
|
||||
// return errors.New("变更所有者,只能操作1级渠道")
|
||||
}
|
||||
|
||||
admin, serr := adminMod.FindOnedmin(ctx, bson.M{"name": req.UserName})
|
||||
if serr != nil {
|
||||
log.Error("UpdateOneChannelOwner:FindOnedmin err", log.Any("serr", serr),
|
||||
log.Any("req", req))
|
||||
return serr
|
||||
} else if admin != nil && admin.Name == "" {
|
||||
log.Error("UpdateOneChannelOwner:FindOnedmin err", log.Any("serr", serr),
|
||||
log.Any("req", req))
|
||||
return errors.New("账号不存在")
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
|
||||
// 更新渠道信息
|
||||
setDoc := bson.M{"$set": bson.M{
|
||||
channelmod.FN.ChannelInfo.UserName: req.UserName,
|
||||
channelmod.FN.ChannelInfo.UpdatedAt: now,
|
||||
}}
|
||||
|
||||
serr = channelmod.UpdateOneChannelInfo(ctx, filter, setDoc)
|
||||
if serr != nil {
|
||||
log.Error("UpdateOneChannelOwner:UpdateOneChannelInfo err", log.Any("serr", serr),
|
||||
log.Any("req", req))
|
||||
return serr
|
||||
}
|
||||
|
||||
// 更新渠道统计信息
|
||||
csFilter := bson.M{channelmod.FN.ChannelStat.Channel: cInfo.Channel}
|
||||
csSetDoc := bson.M{"$set": bson.M{channelmod.FN.ChannelStat.UserName: req.UserName}}
|
||||
|
||||
serr = channelmod.UpdateManyChannelStat(ctx, csFilter, csSetDoc)
|
||||
if serr != nil {
|
||||
log.Error("UpdateOneChannelOwner:UpdateManyChannelStat err", log.Any("serr", serr),
|
||||
log.Any("req", req))
|
||||
return serr
|
||||
}
|
||||
|
||||
// 找到一级渠道的所有子渠道
|
||||
allFlter := bson.M{channelmod.FN.ChannelInfo.ParentChannel: req.Channel}
|
||||
|
||||
chanIds := make([]string, 0)
|
||||
cInfos, _ := channelmod.FindManyChannelInfo(ctx, allFlter)
|
||||
if len(cInfos) > 0 {
|
||||
for _, info := range cInfos {
|
||||
chanIds = append(chanIds, info.Channel)
|
||||
}
|
||||
|
||||
// 更新一级渠道的所有子渠道
|
||||
serr = channelmod.UpdateManyChannelInfo(ctx, bson.M{channelmod.FN.ChannelInfo.Channel: bson.M{"$in": chanIds}}, setDoc)
|
||||
if serr != nil {
|
||||
log.Error("UpdateOneChannelOwner:UpdateManyChannelInfo 2 err", log.Any("serr", serr),
|
||||
log.Any("req", req))
|
||||
}
|
||||
// 更新一级渠道的所有子渠道统计
|
||||
serr = channelmod.UpdateManyChannelStat(ctx, bson.M{channelmod.FN.ChannelStat.Channel: bson.M{"$in": chanIds}}, csSetDoc)
|
||||
if serr != nil {
|
||||
log.Error("UpdateOneChannelOwner:UpdateManyChannelStat 2 err", log.Any("serr", serr),
|
||||
log.Any("req", req))
|
||||
}
|
||||
}
|
||||
|
||||
// 添加变更记录
|
||||
new := &channelmod.ChannelOwnerChange{
|
||||
ID: primitive.NewObjectID(),
|
||||
Channel: cInfo.Channel,
|
||||
OldUser: cInfo.UserName,
|
||||
NewUser: req.UserName,
|
||||
Mark: req.Mark,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
Operator: operator,
|
||||
Account: account,
|
||||
}
|
||||
serr = channelmod.InsertOneChannelOwnerChange(ctx, new)
|
||||
if serr != nil {
|
||||
log.Error("UpdateOneChannelOwner:InsertOneChannelOwnerChange err", log.Any("new", new),
|
||||
log.Any("err", serr))
|
||||
return serr
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SearchChannelOwnerChangeInfo 查询渠道所有者变更信息
|
||||
func SearchChannelOwnerChangeInfo(ctx context.Context, req *proto.ChannelOwnerChangeInfoSearch) (
|
||||
*proto.ChannelOwnerChangeInfoSearchResp, error) {
|
||||
filter := bson.M{}
|
||||
opt := &options.FindOptions{}
|
||||
opt.SetSort(bson.M{channelmod.FN.ChannelInfo.CreatedAt: -1})
|
||||
opt.SetSkip((req.PageNum - 1) * req.PageSize)
|
||||
opt.SetLimit(req.PageSize)
|
||||
|
||||
resp := &proto.ChannelOwnerChangeInfoSearchResp{}
|
||||
|
||||
if req.ID != nil {
|
||||
filter[channelmod.FN.ChannelOwnerChange.ID] = req.ID
|
||||
}
|
||||
if req.Channel != nil {
|
||||
filter[channelmod.FN.ChannelOwnerChange.Channel] = *req.Channel
|
||||
}
|
||||
if req.OldUser != nil {
|
||||
filter[channelmod.FN.ChannelOwnerChange.OldUser] = *req.OldUser
|
||||
}
|
||||
if req.NewUser != nil {
|
||||
filter[channelmod.FN.ChannelOwnerChange.NewUser] = *req.NewUser
|
||||
}
|
||||
|
||||
total, serr := channelmod.CountChannelOwnerChanges(ctx, filter)
|
||||
if serr != nil {
|
||||
return nil, serr
|
||||
}
|
||||
if total == 0 {
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
ownerChangeList, err := channelmod.FindManyChannelOwnerChanges(ctx, filter, opt)
|
||||
if serr != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp.List = ownerChangeList
|
||||
resp.Total = total
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// SearchUserInfo 查询用户信息
|
||||
func SearchUserInfo(ctx context.Context, req *proto.UserInfoSearch) (
|
||||
*proto.UserInfoSearchResp, error) {
|
||||
resp := &proto.UserInfoSearchResp{}
|
||||
|
||||
filter := bson.M{}
|
||||
if req.UserId != nil {
|
||||
filter["userId"] = *req.UserId
|
||||
}
|
||||
if req.Channel != nil {
|
||||
filter["districtCode"] = *req.Channel
|
||||
}
|
||||
if req.AppId != nil {
|
||||
filter["appId"] = *req.AppId
|
||||
}
|
||||
if req.IP != nil {
|
||||
filter["ip"] = *req.IP
|
||||
}
|
||||
if req.Start != nil && req.End != nil {
|
||||
filter["createdAt"] = bson.M{"$gt": *req.Start, "$lt": *req.End}
|
||||
}
|
||||
|
||||
total, err := registermod.CountRegister(ctx, filter)
|
||||
if err != nil {
|
||||
log.Error("SearchUserInfo CountRegister", log.Any("err", err))
|
||||
return nil, err
|
||||
}
|
||||
opt := &options.FindOptions{}
|
||||
opt.SetSort(bson.M{"createdAt": -1})
|
||||
opt.SetSkip((req.PageNum - 1) * req.PageSize)
|
||||
opt.SetLimit(req.PageSize)
|
||||
|
||||
userList, err := registermod.FindManyRegister(ctx, filter, opt)
|
||||
if err != nil {
|
||||
log.Error("SearchUserInfo FindManyRegister", log.Any("err", err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp.Total = total
|
||||
resp.List = userList
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package channelSer
|
||||
|
||||
import "math/rand"
|
||||
|
||||
var (
|
||||
//所有的字符
|
||||
ALL_CHARS = []string{
|
||||
"1", "2", "3", "4", "5",
|
||||
"6", "7", "8", "9", "A",
|
||||
"B", "C", "D", "E", "F",
|
||||
"G", "H", "J", "K",
|
||||
"L", "M", "N", "O", "P",
|
||||
"Q", "R", "S", "T", "U",
|
||||
"V", "W", "X", "Y", "Z"}
|
||||
aLen = len(ALL_CHARS)
|
||||
)
|
||||
|
||||
const (
|
||||
//默认长度
|
||||
DEFAULT_LEN = 6
|
||||
)
|
||||
|
||||
// 用户推广码
|
||||
func InviteShartPasswd() (code string) {
|
||||
for i := 0; i < DEFAULT_LEN; i++ {
|
||||
index := rand.Intn(aLen)
|
||||
code += ALL_CHARS[index]
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
package channelSer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"stat/api/proto"
|
||||
"stat/common/log"
|
||||
"stat/models/channelmod"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
// SearchChannelDeductionRule 查询渠道扣量规则信息
|
||||
func SearchChannelDeductionRule(ctx context.Context, req *proto.ChannelDeductionRuleSearch) (*proto.ChannelDeductionRuleSearchResp, error) {
|
||||
resp := &proto.ChannelDeductionRuleSearchResp{}
|
||||
filter := bson.M{}
|
||||
opt := &options.FindOptions{}
|
||||
opt.SetSort(bson.M{channelmod.FN.ChannelDeductionRule.BeginTime: -1})
|
||||
opt.SetSkip((req.PageNum - 1) * req.PageSize)
|
||||
opt.SetLimit(req.PageSize)
|
||||
|
||||
if req.Channel != nil && *req.Channel != "" {
|
||||
filter[channelmod.FN.ChannelDeductionRule.Channel] = bson.M{"$regex": *req.Channel}
|
||||
}
|
||||
|
||||
if req.AppId != nil {
|
||||
filter[channelmod.FN.ChannelDeductionRule.AppId] = *req.AppId
|
||||
}
|
||||
|
||||
if req.Channel != nil && *req.Channel != "" {
|
||||
filter[channelmod.FN.ChannelDeductionRule.Channel] = *req.Channel
|
||||
}
|
||||
|
||||
total, err := channelmod.CountChannelDeductionRules(ctx, filter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if total == 0 {
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
ChannelDeductionRuleList, err := channelmod.FindManyChannelDeductionRule(ctx, filter, opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, rule := range ChannelDeductionRuleList {
|
||||
if rule.DivideRate == 0 {
|
||||
rule.DivideRate = 100
|
||||
}
|
||||
}
|
||||
|
||||
resp.Total = total
|
||||
resp.List = ChannelDeductionRuleList
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// AddChannelDeductionRule 添加一个媒体视频
|
||||
func AddChannelDeductionRule(ctx context.Context, req *proto.ChannelDeductionRuleAdd) (*channelmod.ChannelDeductionRule, error) {
|
||||
checkFilter := bson.M{channelmod.FN.ChannelDeductionRule.Channel: req.Channel, channelmod.FN.ChannelDeductionRule.AppId: req.AppId}
|
||||
ChannelDeductionRule, err := channelmod.FindOneChannelDeductionRule(ctx, checkFilter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ChannelDeductionRule.Channel == req.Channel {
|
||||
return ChannelDeductionRule, errors.New("渠道扣量规则已经存在")
|
||||
}
|
||||
channelInfo, err := channelmod.FindOneChannelInfoEx(ctx, bson.M{channelmod.FN.ChannelInfo.Channel: req.Channel})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var one float64
|
||||
if req.LessIncomeRate == nil {
|
||||
one = 0.0
|
||||
} else {
|
||||
one = *req.LessIncomeRate
|
||||
}
|
||||
now := time.Now()
|
||||
rule := channelmod.ChannelDeductionRule{
|
||||
AppId: req.AppId,
|
||||
AppType: req.AppType,
|
||||
PromoteMode: req.PromoteMode,
|
||||
Channel: req.Channel,
|
||||
Settlement: req.Settlement,
|
||||
First: req.First,
|
||||
Second: req.Second,
|
||||
Third: req.Third,
|
||||
Fourth: req.Fourth,
|
||||
Fifth: req.Fifth,
|
||||
CPAPrice: req.CPAPrice,
|
||||
CPSRate: req.CPSRate,
|
||||
BeginTime: req.BeginTime,
|
||||
CPSBegin: req.CPSBegin,
|
||||
CPSDeductionRate: req.CPSDeductionRate,
|
||||
DivideRate: req.DivideRate,
|
||||
LandingPage: req.LandingPage,
|
||||
ProxyDeduction: req.ProxyDeduction,
|
||||
AutoDeduction: req.AutoDeduction,
|
||||
LessIncomeRate: one,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
|
||||
err = channelmod.InsertOneChannelDeductionRule(ctx, &rule)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
channelInfo.AppIds = append(channelInfo.AppIds, req.AppId)
|
||||
|
||||
setdoc := bson.M{"$set": bson.M{channelmod.FN.ChannelInfo.AppIds: channelInfo.AppIds}}
|
||||
err = channelmod.UpdateOneChannelInfo(ctx, bson.M{channelmod.FN.ChannelInfo.Channel: req.Channel}, setdoc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return channelmod.FindOneChannelDeductionRuleEx(ctx, checkFilter)
|
||||
}
|
||||
|
||||
// DelChannelDeductionRule 删除指定渠道扣量规则信息
|
||||
func DelChannelDeductionRule(ctx context.Context, channelId string) error {
|
||||
id, err := primitive.ObjectIDFromHex(channelId)
|
||||
if err != nil {
|
||||
return errors.New("ID 格式错误")
|
||||
}
|
||||
ruleFilter := bson.M{channelmod.FN.ChannelDeductionRule.ID: id}
|
||||
channelRuleInfo, err := channelmod.FindOneChannelDeductionRuleEx(ctx, ruleFilter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
channelInfo, err := channelmod.FindOneChannelInfoEx(ctx, bson.M{channelmod.FN.ChannelInfo.Channel: channelRuleInfo.Channel})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
count, err := channelmod.CountChannelInfos(ctx, bson.M{channelmod.FN.ChannelInfo.ParentAgent: channelInfo.Channel})
|
||||
if err != nil {
|
||||
log.Error("DelChannelDeductionRule CountChannelInfos", log.Any("channelId", channelId), log.E(err))
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
return errors.New("下级代理不为空,请先删除下级代理, 再删除应用规则")
|
||||
}
|
||||
|
||||
_, err = channelmod.DelOneChannelDeductionRule(ctx, ruleFilter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
appids := make([]int32, 0)
|
||||
for _, appid := range channelInfo.AppIds {
|
||||
if appid != channelRuleInfo.AppId {
|
||||
appids = append(appids, appid)
|
||||
}
|
||||
}
|
||||
|
||||
setdoc := bson.M{"$set": bson.M{channelmod.FN.ChannelInfo.AppIds: appids}}
|
||||
err = channelmod.UpdateOneChannelInfo(ctx, bson.M{channelmod.FN.ChannelInfo.Channel: channelRuleInfo.Channel}, setdoc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateChannelDeductionRule 更新指定渠道扣量规则
|
||||
func UpdateChannelDeductionRule(ctx context.Context, channelId string, info proto.ChannelDeductionRuleUpdate) error {
|
||||
|
||||
id, err := primitive.ObjectIDFromHex(channelId)
|
||||
if err != nil {
|
||||
return errors.New("ID 格式错误")
|
||||
}
|
||||
filter := bson.M{channelmod.FN.ChannelDeductionRule.ID: id}
|
||||
|
||||
//更新数据库
|
||||
setDoc := bson.M{"$set": info}
|
||||
|
||||
serr := channelmod.UpdateOneChannelDeductionRule(ctx, filter, setDoc)
|
||||
if serr != nil {
|
||||
return serr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,150 @@
|
||||
package channelSer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"stat/api/proto"
|
||||
"stat/common/utils"
|
||||
"stat/middleware/define"
|
||||
"stat/models/adminMod"
|
||||
channelmod "stat/models/channelmod"
|
||||
"stat/models/channelsettlementrecord"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
)
|
||||
|
||||
var (
|
||||
SystemStartTime = time.Date(2020, time.January, 1, 0, 0, 0, 0, time.UTC)
|
||||
)
|
||||
|
||||
func SettlementInfoToApplyRecord(src *channelsettlementrecord.ChannelSettlementRecord) *proto.ApplyFormRecord {
|
||||
ret := &proto.ApplyFormRecord{
|
||||
ID: src.ID,
|
||||
Channel: src.Channel,
|
||||
AppId: src.AppId,
|
||||
BeginTime: src.BeginTime,
|
||||
EndTime: src.EndTime,
|
||||
TotalMoney: src.TotalMoney,
|
||||
SettleMoney: src.SettleMoney,
|
||||
Settlement: src.Settlement,
|
||||
Wallet: src.Wallet,
|
||||
PayMoney: src.PayMoney,
|
||||
Usdt: src.Usdt,
|
||||
Status: src.Status,
|
||||
Remark: "",
|
||||
Pictures: nil,
|
||||
UpdatedAt: src.UpdatedAt,
|
||||
CreatedAt: src.CreatedAt,
|
||||
}
|
||||
remark := ""
|
||||
if len(src.OperateHistory) > 0 {
|
||||
remark = src.OperateHistory[0].Remark
|
||||
if len(src.OperateHistory) > 1 {
|
||||
if remark == "" {
|
||||
remark = src.OperateHistory[len(src.OperateHistory)-1].Remark
|
||||
} else {
|
||||
s := src.OperateHistory[len(src.OperateHistory)-1].Remark
|
||||
if s != "" {
|
||||
remark += " / " + s
|
||||
}
|
||||
}
|
||||
}
|
||||
ret.Pictures = src.OperateHistory[len(src.OperateHistory)-1].Pictures
|
||||
}
|
||||
ret.Remark = remark
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func SettlementInfoListToApplyForm(lst channelsettlementrecord.ChannelSettlementRecordList) proto.ApplyFormRecordList {
|
||||
res := make(proto.ApplyFormRecordList, 0)
|
||||
for _, item := range lst {
|
||||
a := SettlementInfoToApplyRecord(item)
|
||||
res = append(res, a)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func FenToYuanDisplay(fen int64) string {
|
||||
return fmt.Sprintf("%.2f", float64(fen)/float64(100))
|
||||
}
|
||||
|
||||
func IndentationDisplay(v int64) string {
|
||||
return fmt.Sprintf("%.2f", float64(v)/float64(10000))
|
||||
}
|
||||
|
||||
func CheckAndFixTime(startTime, endTime *time.Time) (*time.Time, *time.Time, error) {
|
||||
var start, end *time.Time
|
||||
// 开始时间和结束时间
|
||||
if endTime == nil {
|
||||
e := utils.BeginOfYesterday()
|
||||
end = &e
|
||||
} else {
|
||||
end = endTime
|
||||
}
|
||||
if startTime == nil {
|
||||
start = &SystemStartTime
|
||||
} else {
|
||||
start = startTime
|
||||
}
|
||||
//
|
||||
if end.After(utils.BeginOfYesterday()) {
|
||||
e := utils.BeginOfYesterday()
|
||||
end = &e
|
||||
}
|
||||
if end.Before(*start) {
|
||||
return nil, nil, fmt.Errorf("开始和结束的时间区间填写不正确")
|
||||
}
|
||||
return start, end, nil
|
||||
}
|
||||
|
||||
func GetUpdateSettlementOperateItem(old channelsettlementrecord.ChannelSettlementRecord, update proto.SettlementInfoUpdate2,
|
||||
accType define.ActType, account string, accountName string, images []string) channelsettlementrecord.SettlementOperateItem {
|
||||
res := channelsettlementrecord.SettlementOperateItem{}
|
||||
res.OperateTime = time.Now()
|
||||
if update.Remark != nil {
|
||||
res.Remark = *update.Remark
|
||||
}
|
||||
res.OperatorAccountType = accType
|
||||
res.OperatorAccount = account
|
||||
res.OperatorAccountName = accountName
|
||||
res.BeforeStatus = old.Status
|
||||
if update.Status != nil && *update.Status != old.Status {
|
||||
res.AfterStatus = *update.Status
|
||||
res.Content += fmt.Sprintf("状态改变:(%s => %s)\n", old.Status.String(), update.Status.String())
|
||||
} else {
|
||||
res.AfterStatus = old.Status
|
||||
}
|
||||
if update.Usdt != nil && *update.Usdt != old.Usdt {
|
||||
res.Content += fmt.Sprintf("修改了打款金额(USDT):(%s => %s)\n", FenToYuanDisplay(old.Usdt), FenToYuanDisplay(*update.Usdt))
|
||||
}
|
||||
if update.PayMoney != nil && *update.PayMoney != old.PayMoney {
|
||||
res.Content += fmt.Sprintf("修改了打款金额(CNY): (%s => %s)\n", FenToYuanDisplay(old.PayMoney), FenToYuanDisplay(*update.PayMoney))
|
||||
}
|
||||
if update.SettleMoney != nil && *update.SettleMoney != old.SettleMoney {
|
||||
res.Content += fmt.Sprintf("修改了申请结算金额:(%s => %s)\n", FenToYuanDisplay(old.SettleMoney), FenToYuanDisplay(*update.SettleMoney))
|
||||
}
|
||||
for _, img := range images {
|
||||
res.Pictures = append(res.Pictures, img)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func GetAccountName(ctx context.Context, accType define.ActType, account string) (string, error) {
|
||||
if accType == define.Admin {
|
||||
if acc, err := adminMod.FindOneByAccount(ctx, account); err != nil {
|
||||
return "", err
|
||||
} else {
|
||||
return acc.Name, nil
|
||||
}
|
||||
} else if accType == define.Channel {
|
||||
if acc, err := channelmod.FindOneChannelInfo(ctx, bson.M{channelmod.FN.ChannelInfo.Channel: account}); err != nil {
|
||||
return "", err
|
||||
} else {
|
||||
return acc.Channel, nil
|
||||
}
|
||||
} else {
|
||||
return "", fmt.Errorf("error account type: %s", accType)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,321 @@
|
||||
package channelSer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"runtime"
|
||||
"stat/api/proto"
|
||||
"stat/common/utils"
|
||||
"stat/models/channelmod"
|
||||
"time"
|
||||
|
||||
"github.com/jinzhu/now"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
// SearchChannelStat 查询渠道扣量规则信息
|
||||
func SearchChannelStat(ctx context.Context, req *proto.ChannelStatSearch) (*proto.ChannelStatSearchResp, error) {
|
||||
resp := &proto.ChannelStatSearchResp{
|
||||
List: make(channelmod.ChannelStatList, 0),
|
||||
}
|
||||
filter := bson.M{}
|
||||
opt := &options.FindOptions{}
|
||||
opt.SetSkip((req.PageNum - 1) * req.PageSize)
|
||||
opt.SetLimit(req.PageSize)
|
||||
|
||||
if req.Channel != nil && *req.Channel != "" {
|
||||
if req.WithChild != nil && *req.WithChild {
|
||||
filter = bson.M{
|
||||
"$or": bson.A{
|
||||
bson.M{channelmod.FN.ChannelStat.Channel: *req.Channel},
|
||||
bson.M{channelmod.FN.ChannelStat.ParentChannel: *req.Channel},
|
||||
},
|
||||
}
|
||||
} else {
|
||||
filter[channelmod.FN.ChannelStat.Channel] = *req.Channel
|
||||
}
|
||||
} else if req.DayType != nil {
|
||||
timeNow := time.Now()
|
||||
now.WeekStartDay = time.Monday
|
||||
Now := now.With(timeNow.In(time.Local))
|
||||
todayBegin := utils.BeginWithTime(timeNow)
|
||||
weekBegin := Now.BeginningOfWeek()
|
||||
monthBegin := Now.BeginningOfMonth()
|
||||
var timeBegin time.Time
|
||||
if *req.DayType == 1 { // 今天内
|
||||
timeBegin = todayBegin
|
||||
} else if *req.DayType == 2 { // 昨天和今天
|
||||
timeBegin = todayBegin.AddDate(0, 0, -1)
|
||||
} else if *req.DayType == 3 { // 三天内
|
||||
timeBegin = todayBegin.AddDate(0, 0, -2)
|
||||
} else if *req.DayType == 4 { // 七天内
|
||||
timeBegin = todayBegin.AddDate(0, 0, -6)
|
||||
} else if *req.DayType == 5 { // 本周内
|
||||
timeBegin = weekBegin
|
||||
} else if *req.DayType == 6 { // 两周内
|
||||
timeBegin = weekBegin.AddDate(0, 0, -7)
|
||||
} else if *req.DayType == 7 { // 本月内
|
||||
timeBegin = monthBegin
|
||||
} else if *req.DayType == 8 { // 两月内
|
||||
timeBegin = monthBegin.AddDate(0, -1, 0)
|
||||
}
|
||||
channelList, err := channelmod.FindManyChannelInfo(ctx, bson.M{
|
||||
channelmod.FN.ChannelInfo.CreatedAt: bson.M{
|
||||
"$gte": timeBegin,
|
||||
"$lte": timeNow,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
channelIds := make([]string, 0)
|
||||
for _, channelInfo := range channelList {
|
||||
channelIds = append(channelIds, channelInfo.Channel)
|
||||
}
|
||||
|
||||
if len(channelIds) > 0 {
|
||||
if req.WithChild != nil && *req.WithChild {
|
||||
filter = bson.M{
|
||||
"$or": bson.A{
|
||||
bson.M{channelmod.FN.ChannelStat.Channel: bson.M{"$in": channelIds}},
|
||||
bson.M{channelmod.FN.ChannelStat.ParentChannel: bson.M{"$in": channelIds}},
|
||||
},
|
||||
}
|
||||
} else {
|
||||
filter[channelmod.FN.ChannelStat.Channel] = bson.M{"$in": channelIds}
|
||||
}
|
||||
} else {
|
||||
return resp, nil
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//排序
|
||||
if req.RankType != nil {
|
||||
if *req.RankType == 1 {
|
||||
opt.SetSort(bson.D{{Key: channelmod.FN.ChannelStat.SumDate, Value: -1}, {Key: channelmod.FN.ChannelStat.DirectAmount, Value: -1}})
|
||||
} else if *req.RankType == 2 {
|
||||
opt.SetSort(bson.D{{Key: channelmod.FN.ChannelStat.SumDate, Value: -1}, {Key: channelmod.FN.ChannelStat.NewDirectCount, Value: -1}})
|
||||
} else if *req.RankType == 3 {
|
||||
opt.SetSort(bson.D{{Key: channelmod.FN.ChannelStat.SumDate, Value: -1}, {Key: channelmod.FN.ChannelStat.NewRechargeAmount, Value: -1}})
|
||||
} else if *req.RankType == 4 {
|
||||
opt.SetSort(bson.D{{Key: channelmod.FN.ChannelStat.SumDate, Value: -1}, {Key: channelmod.FN.ChannelStat.IncomeRate, Value: -1}})
|
||||
}
|
||||
} else {
|
||||
opt.SetSort(bson.D{{Key: channelmod.FN.ChannelStat.SumDate, Value: -1}, {Key: channelmod.FN.ChannelStat.NewDirectCount, Value: -1}})
|
||||
}
|
||||
|
||||
if req.UserName != nil && *req.UserName != "" {
|
||||
filter[channelmod.FN.ChannelStat.UserName] = bson.M{"$regex": *req.UserName}
|
||||
}
|
||||
|
||||
if req.AppId != nil {
|
||||
filter[channelmod.FN.ChannelStat.AppId] = bson.M{"$in": *req.AppId}
|
||||
}
|
||||
|
||||
if req.Start != nil && req.End != nil {
|
||||
filter[channelmod.FN.ChannelStat.SumDate] = bson.M{"$gte": *req.Start, "$lte": *req.End}
|
||||
}
|
||||
|
||||
if req.WithChild != nil && !*req.WithChild {
|
||||
filter[channelmod.FN.ChannelStat.Type] = channelmod.ChannelTypeParent
|
||||
}
|
||||
if req.Settlement != nil {
|
||||
filter[channelmod.FN.ChannelStat.Settlement] = *req.Settlement
|
||||
}
|
||||
if req.Detail != nil && *req.Detail {
|
||||
if req.SumDate == nil {
|
||||
return resp, errors.New("param error")
|
||||
}
|
||||
filter = bson.M{
|
||||
"$or": bson.A{
|
||||
bson.M{channelmod.FN.ChannelStat.Channel: *req.Channel},
|
||||
bson.M{channelmod.FN.ChannelStat.ParentChannel: *req.Channel},
|
||||
},
|
||||
channelmod.FN.ChannelStat.SumDate: *req.SumDate,
|
||||
}
|
||||
}
|
||||
|
||||
ChannelStatList, err := channelmod.FindManyChannelStat(ctx, filter, opt)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
for _, v := range ChannelStatList {
|
||||
v.CorrectValidData()
|
||||
v.CalcIncomeRate()
|
||||
}
|
||||
resp.List = ChannelStatList
|
||||
|
||||
// 汇总
|
||||
canSum := utils.M(filter).HasKey(channelmod.FN.ChannelStat.AppId) && utils.M(filter).HasKey(channelmod.FN.ChannelStat.SumDate)
|
||||
|
||||
if canSum {
|
||||
var total int64
|
||||
err = channelmod.FindManyChannelStatShard(ctx, filter, 10000, func(item *channelmod.ChannelStat) {
|
||||
total++
|
||||
channelmod.ChannelStatSummation(&resp.TotalInfo, item)
|
||||
if req.WithChild != nil && *req.WithChild {
|
||||
for _, v := range ChannelStatList {
|
||||
if item.ParentChannel == v.Channel && v.SumDate.Equal(item.SumDate) {
|
||||
channelmod.ChannelStatSummation(v, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
if total == 0 {
|
||||
return resp, nil
|
||||
}
|
||||
if total > 10000 {
|
||||
runtime.GC()
|
||||
}
|
||||
resp.Total = total
|
||||
var ruleInfo *channelmod.ChannelDeductionRule
|
||||
if req.Channel != nil && *req.Channel != "" {
|
||||
ruleFilter := bson.M{
|
||||
channelmod.FN.ChannelDeductionRule.Channel: req.Channel,
|
||||
// channelmod.FN.ChannelDeductionRule.AppId: req.AppId,
|
||||
}
|
||||
ruleInfo, _ = channelmod.FindOneChannelDeductionRule(ctx, ruleFilter)
|
||||
}
|
||||
if ruleInfo != nil {
|
||||
resp.TotalInfo.Channel = ruleInfo.Channel
|
||||
resp.TotalInfo.Settlement = ruleInfo.Settlement
|
||||
resp.TotalInfo.AppId = ruleInfo.AppId
|
||||
resp.TotalInfo.CPAPrice = ruleInfo.CPAPrice
|
||||
resp.TotalInfo.CPSRate = ruleInfo.CPSRate
|
||||
resp.TotalInfo.AppType = ruleInfo.AppType
|
||||
resp.TotalInfo.PromoteMode = ruleInfo.PromoteMode
|
||||
resp.TotalInfo.CalcIncomeRate()
|
||||
resp.Income, resp.Desc = channelmod.CalculateChannelIncome(&resp.TotalInfo)
|
||||
}
|
||||
} else {
|
||||
resp.Total = 1000000
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// SearchChannelSettlement 查询渠道结算信息
|
||||
func SearchChannelSettlement(ctx context.Context, req *proto.ChannelSettlementSearch) (
|
||||
*proto.ChannelSettlementSearchResp, error) {
|
||||
resp := &proto.ChannelSettlementSearchResp{}
|
||||
filter := bson.M{}
|
||||
opt := &options.FindOptions{}
|
||||
opt.SetSort(bson.M{channelmod.FN.ChannelSettlement.CreatedAt: -1})
|
||||
opt.SetSkip((req.PageNum - 1) * req.PageSize)
|
||||
opt.SetLimit(req.PageSize)
|
||||
|
||||
if req.Channel != nil && *req.Channel != "" {
|
||||
filter[channelmod.FN.ChannelSettlement.Channel] = *req.Channel
|
||||
}
|
||||
|
||||
if req.AppId != nil {
|
||||
filter[channelmod.FN.ChannelSettlement.AppId] = *req.AppId
|
||||
}
|
||||
|
||||
if req.Start != nil && req.End != nil {
|
||||
filter[channelmod.FN.ChannelSettlement.SumDate] = bson.M{"$gt": *req.Start, "$lt": *req.End}
|
||||
}
|
||||
|
||||
if req.WithChild != nil && *req.WithChild {
|
||||
filter[channelmod.FN.ChannelSettlement.Type] = channelmod.ChannelTypeParent
|
||||
}
|
||||
|
||||
total, serr := channelmod.CountChannelSettlements(ctx, filter)
|
||||
if serr != nil {
|
||||
return nil, serr
|
||||
}
|
||||
if total == 0 {
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
ChannelSettlementList, err := channelmod.FindManyChannelSettlement(ctx, filter, opt)
|
||||
if serr != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if req.WithChild != nil && *req.WithChild {
|
||||
channels := make([]string, 0)
|
||||
for _, v := range ChannelSettlementList {
|
||||
channels = append(channels, v.Channel)
|
||||
}
|
||||
childTypes := channelmod.GetChildChannelTypes()
|
||||
filter[channelmod.FN.ChannelSettlement.Type] = bson.M{"$in": childTypes}
|
||||
filter[channelmod.FN.ChannelSettlement.ParentChannel] = bson.M{"$in": channels}
|
||||
channelsettlementList, err := channelmod.FindManyChannelStat(ctx, filter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, channnelSettlementInfo := range channelsettlementList {
|
||||
for _, v := range ChannelSettlementList {
|
||||
if channnelSettlementInfo.ParentChannel == v.Channel {
|
||||
channnelSettlementInfo.AccumulateTo(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resp.Total = total
|
||||
resp.List = ChannelSettlementList
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// SearchChannelStatCompared 渠道同时段对比
|
||||
func SearchChannelStatCompared(ctx context.Context, req *proto.SearchChannelStatComparedReq) (*proto.SearchChannelStatComparedResp, error) {
|
||||
resp := &proto.SearchChannelStatComparedResp{}
|
||||
filter := bson.M{}
|
||||
opt := &options.FindOptions{}
|
||||
opt.SetSkip((req.PageNum - 1) * req.PageSize)
|
||||
opt.SetLimit(req.PageSize)
|
||||
opt.SetSort(
|
||||
bson.D{
|
||||
{Key: channelmod.FN.ChannelStatYestoday.SumDate, Value: -1},
|
||||
{Key: channelmod.FN.ChannelStatYestoday.NewCount, Value: -1},
|
||||
},
|
||||
)
|
||||
|
||||
if req.Channel != nil && *req.Channel != "" {
|
||||
if req.WithChild != nil && *req.WithChild {
|
||||
filter = bson.M{
|
||||
"$or": bson.A{
|
||||
bson.M{channelmod.FN.ChannelStatYestoday.Channel: *req.Channel},
|
||||
bson.M{channelmod.FN.ChannelStatYestoday.ParentChannel: *req.Channel},
|
||||
},
|
||||
}
|
||||
} else {
|
||||
filter[channelmod.FN.ChannelStatYestoday.Channel] = *req.Channel
|
||||
}
|
||||
}
|
||||
|
||||
if req.AppId != nil {
|
||||
filter[channelmod.FN.ChannelStatYestoday.AppId] = *req.AppId
|
||||
}
|
||||
|
||||
if req.Start != nil && req.End != nil {
|
||||
filter[channelmod.FN.ChannelStatYestoday.SumDate] = bson.M{"$gte": *req.Start, "$lte": *req.End}
|
||||
}
|
||||
|
||||
if req.Settlement != nil {
|
||||
filter[channelmod.FN.ChannelStatYestoday.Settlement] = *req.Settlement
|
||||
}
|
||||
total, err := channelmod.CountChannelStatYestoday(ctx, filter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
channelStatList, err := channelmod.FindManyChannelStatYestoday(ctx, filter, opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp.Total = total
|
||||
resp.List = channelStatList
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
Reference in New Issue
Block a user