forked from all_user/stat_center
1508 lines
53 KiB
Go
1508 lines
53 KiB
Go
package channelSer
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"path"
|
|
"stat/api/proto"
|
|
"stat/common/log"
|
|
"stat/common/mongos"
|
|
"stat/common/utils"
|
|
"stat/middleware/define"
|
|
"stat/models/appInfoMod"
|
|
"stat/models/channelmod"
|
|
"stat/models/channelsettlementrecord"
|
|
"strings"
|
|
"time"
|
|
|
|
"go.mongodb.org/mongo-driver/mongo"
|
|
|
|
"github.com/360EntSecGroup-Skylar/excelize"
|
|
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
"go.mongodb.org/mongo-driver/mongo/options"
|
|
)
|
|
|
|
// SearchChannelSettlementStat 查询渠道结算纤细
|
|
func SearchChannelSettlementStat(ctx context.Context, req *proto.ChannelStatSettlementSearch) (*proto.ChannelStatSettlementSearchResp, error) {
|
|
resp := &proto.ChannelStatSettlementSearchResp{}
|
|
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 = bson.M{channelmod.FN.ChannelStat.Channel: *req.Channel}
|
|
}
|
|
}
|
|
if req.AppId != nil {
|
|
filter[channelmod.FN.ChannelStat.AppId] = *req.AppId
|
|
}
|
|
if req.UserName != nil && *req.UserName != "" {
|
|
filter[channelmod.FN.ChannelStat.UserName] = *req.UserName
|
|
}
|
|
if req.Settlement != nil && *req.Settlement != "" {
|
|
filter[channelmod.FN.ChannelStat.Settlement] = *req.Settlement
|
|
}
|
|
// 开始时间和结束时间
|
|
endTime := utils.BeginOfToday().AddDate(0, 0, -1)
|
|
if req.Start != nil {
|
|
if req.End != nil {
|
|
if req.End.Before(utils.BeginOfToday()) {
|
|
endTime = *req.End
|
|
}
|
|
}
|
|
|
|
filter[channelmod.FN.ChannelStat.SumDate] = bson.M{"$gte": *req.Start, "$lte": endTime}
|
|
} else {
|
|
if req.End != nil {
|
|
if req.End.Before(utils.BeginOfToday()) {
|
|
endTime = *req.End
|
|
}
|
|
}
|
|
filter[channelmod.FN.ChannelStat.SumDate] = bson.M{"$lte": endTime}
|
|
}
|
|
filter[channelmod.FN.ChannelStat.IsPay] = bson.M{"$ne": true}
|
|
|
|
totalParentChannelStatInfo, err := channelmod.FindManyChannelStat(ctx, filter)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if len(totalParentChannelStatInfo) == 0 {
|
|
return resp, nil
|
|
}
|
|
|
|
ChannelStatList, err := channelmod.FindManyChannelStat(ctx, filter, opt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
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
|
|
}
|
|
// 计算合计数据
|
|
for _, channelStatInfo := range totalParentChannelStatInfo {
|
|
channelmod.ChannelStatSummation(&resp.TotalInfo, channelStatInfo)
|
|
}
|
|
|
|
resp.Total = int64(len(totalParentChannelStatInfo))
|
|
resp.List = ChannelStatList
|
|
|
|
if ruleInfo != nil {
|
|
resp.Income, resp.Desc = channelmod.CalculateChannelIncome(resp.TotalInfo.CorrectValidData())
|
|
}
|
|
|
|
return resp, nil
|
|
}
|
|
|
|
// ChannelSettlementCalc 渠道结算项实时计算
|
|
func ChannelSettlementCalc(ctx context.Context, req *proto.SettlementCalcReq) (*proto.SettlementCalcResp, error) {
|
|
// 参数检查
|
|
if len(req.SettleIds) <= 0 {
|
|
return nil, errors.New("没有提交要结算的统计id数组")
|
|
}
|
|
// 在已结算表中检查是否有重复结算
|
|
settlementInfoFilter := bson.M{
|
|
channelsettlementrecord.FN.ChannelSettlementRecord.SettleIds: bson.M{"$in": req.SettleIds},
|
|
}
|
|
settlementInfoList, err := channelsettlementrecord.FindManyChannelSettlementRecord(ctx, settlementInfoFilter)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(settlementInfoList) > 0 {
|
|
return nil, errors.New("提交的统计记录列表中含有重复结算项")
|
|
}
|
|
// 获取扣量规则
|
|
ruleFilter := bson.M{
|
|
channelmod.FN.ChannelDeductionRule.ID: req.RuleId,
|
|
channelmod.FN.ChannelDeductionRule.AppId: req.AppId,
|
|
channelmod.FN.ChannelDeductionRule.Channel: req.Channel,
|
|
}
|
|
channelRule, err1 := channelmod.FindOneChannelDeductionRuleEx(ctx, ruleFilter)
|
|
// 检查扣量规则
|
|
if err1 != nil {
|
|
return nil, fmt.Errorf("查找渠道结算规则失败:%s", err1.Error())
|
|
}
|
|
// 开始时间和结束时间
|
|
req.BeginTime, req.EndTime, err = CheckAndFixTime(req.BeginTime, req.EndTime)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// 一级记录查找
|
|
opt := &options.FindOptions{}
|
|
opt.SetSort(bson.M{channelmod.FN.ChannelStat.SumDate: 1})
|
|
parentFilter := bson.M{
|
|
channelmod.FN.ChannelStat.AppId: req.AppId, // 应用限定
|
|
channelmod.FN.ChannelStat.Channel: req.Channel, // 渠道限定
|
|
channelmod.FN.ChannelStat.Type: channelmod.ChannelTypeParent, // 类型限定
|
|
channelmod.FN.ChannelStat.IsPay: bson.M{"$ne": true}, // 未结算过
|
|
channelmod.FN.ChannelStat.SumDate: bson.M{"$gte": req.BeginTime, "$lte": req.EndTime}, // 时间限定
|
|
channelmod.FN.ChannelStat.ID: bson.M{"$in": req.SettleIds}, // 提交的IDs
|
|
}
|
|
ParentList, err := channelmod.FindManyChannelStat(ctx, parentFilter, opt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(ParentList) != len(req.SettleIds) {
|
|
return nil, fmt.Errorf("提交的统计记录条数[%d]和查找到的[%d]不一致", len(req.SettleIds), len(ParentList))
|
|
}
|
|
// 结算项检查
|
|
for _, stat := range ParentList {
|
|
if stat.Type != channelmod.ChannelTypeParent {
|
|
return nil, fmt.Errorf("子渠道[%s]不能单独参与结算,只需提交其父渠道即可", stat.Channel)
|
|
}
|
|
}
|
|
if len(ParentList) == 0 {
|
|
return nil, fmt.Errorf("没有找到渠道结算数据")
|
|
}
|
|
// 列表的起止时间
|
|
listBeginTime := ParentList[0].SumDate
|
|
listEndTime := ParentList[len(ParentList)-1].SumDate
|
|
// 查找二级渠道的数据
|
|
childTypes := channelmod.GetChildChannelTypes()
|
|
childFilter := bson.M{
|
|
channelmod.FN.ChannelStat.ParentChannel: req.Channel, // 限定父渠道
|
|
channelmod.FN.ChannelStat.Type: bson.M{"$in": childTypes}, // 限定子渠道
|
|
channelmod.FN.ChannelStat.IsPay: bson.M{"$ne": true}, // 未结算过
|
|
channelmod.FN.ChannelStat.SumDate: bson.M{"$gte": listBeginTime, "$lte": listEndTime}, // 时间限定
|
|
}
|
|
ChildList, err := channelmod.FindManyChannelStat(ctx, childFilter)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// 把二级记录汇总到一级记录上面
|
|
for _, parent := range ParentList {
|
|
parent.CorrectValidData()
|
|
for _, child := range ChildList {
|
|
if child.ParentChannel == parent.Channel && child.SumDate.Equal(parent.SumDate) {
|
|
channelmod.ChannelStatSummation(parent, child.CorrectValidData()) // 把子渠道的数据累加到父渠道上面
|
|
}
|
|
}
|
|
}
|
|
// 对一级记录进行统计汇总
|
|
resp := &proto.SettlementCalcResp{}
|
|
resp.TotalCount = int64(len(ParentList))
|
|
for _, statInfo := range ParentList {
|
|
channelmod.ChannelStatSummation(&(resp.TotalInfo), statInfo)
|
|
}
|
|
resp.TotalInfo.Channel = req.Channel
|
|
resp.TotalInfo.AppId = req.AppId
|
|
resp.TotalInfo.Settlement = channelRule.Settlement
|
|
resp.TotalInfo.CPAPrice = channelRule.CPAPrice
|
|
resp.TotalInfo.CPSRate = channelRule.CPSRate
|
|
resp.TotalInfo.AppType = channelRule.AppType
|
|
resp.TotalInfo.PromoteMode = channelRule.PromoteMode
|
|
// 根据扣量规则计算结算金额
|
|
resp.TotalInfo.CalcIncomeRate()
|
|
resp.TotalIncome, resp.TotalDesc = channelmod.CalculateChannelIncome(resp.TotalInfo.CorrectValidData())
|
|
|
|
return resp, nil
|
|
}
|
|
|
|
// SearchChannelSettlementStat2 查询渠道结算纤细
|
|
func SearchChannelSettlementStat2(ctx context.Context, req *proto.ChannelStatSettlementSearch2) (*proto.ChannelStatSettlementSearch2Resp, error) {
|
|
resp := &proto.ChannelStatSettlementSearch2Resp{}
|
|
if req.Channel == nil || *req.Channel == "" {
|
|
return nil, fmt.Errorf("渠道必须填写")
|
|
}
|
|
if req.AppId == nil {
|
|
return nil, fmt.Errorf("应用ID必须填写")
|
|
}
|
|
appInfo, err := appInfoMod.GetAppInfoByIdEx(ctx, *req.AppId)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("应用不存在或查找失败:%s", err.Error())
|
|
}
|
|
channelInfo, err2 := channelmod.FindOneChannelInfoEx(ctx, bson.M{channelmod.FN.ChannelInfo.Channel: *req.Channel})
|
|
if err2 != nil || channelInfo.Channel == "" {
|
|
return nil, fmt.Errorf("渠道[%s]不存在,或查找失败", *req.Channel)
|
|
}
|
|
if channelInfo.Type != channelmod.ChannelTypeParent {
|
|
return nil, fmt.Errorf("渠道[%s]不是一级渠道,只有一级渠道才能结算", *req.Channel)
|
|
}
|
|
ruleFilter := bson.M{
|
|
channelmod.FN.ChannelDeductionRule.Channel: req.Channel,
|
|
channelmod.FN.ChannelDeductionRule.AppId: req.AppId,
|
|
}
|
|
ruleInfo, err1 := channelmod.FindOneChannelDeductionRuleEx(ctx, ruleFilter)
|
|
if err1 != nil {
|
|
return nil, fmt.Errorf("渠道[%s]的应用[%s]结算规则不存在或查找失败:%s", *req.Channel, appInfo.Name, err1.Error())
|
|
}
|
|
resp.RuleId = ruleInfo.ID
|
|
tmpStat := channelmod.ChannelStat{
|
|
Channel: ruleInfo.Channel,
|
|
AppId: ruleInfo.AppId,
|
|
Settlement: ruleInfo.Settlement,
|
|
CPAPrice: ruleInfo.CPAPrice,
|
|
CPSRate: ruleInfo.CPSRate,
|
|
AppType: ruleInfo.AppType,
|
|
PromoteMode: ruleInfo.PromoteMode,
|
|
}
|
|
resp.TotalInfo = tmpStat
|
|
resp.ValidInfo = tmpStat
|
|
resp.ValidInfo = tmpStat
|
|
|
|
opt := &options.FindOptions{}
|
|
opt.SetSkip((req.PageNum - 1) * req.PageSize)
|
|
opt.SetLimit(req.PageSize)
|
|
opt.SetSort(bson.D{
|
|
{Key: channelmod.FN.ChannelStat.SumDate, Value: -1},
|
|
{Key: channelmod.FN.ChannelStat.CreatedAt, Value: -1},
|
|
})
|
|
filter := bson.M{}
|
|
// 渠道结算一定包含子渠道
|
|
filter[channelmod.FN.ChannelStat.AppId] = *req.AppId
|
|
|
|
// 返回渠道的钱包信息
|
|
resp.Wallet = channelInfo.Wallet
|
|
|
|
if req.UserName != nil && *req.UserName != "" {
|
|
filter[channelmod.FN.ChannelStat.UserName] = *req.UserName
|
|
}
|
|
// 开始时间和结束时间
|
|
req.Start, req.End, err = CheckAndFixTime(req.Start, req.End)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
filter[channelmod.FN.ChannelStat.SumDate] = bson.M{"$gte": *req.Start, "$lte": *req.End}
|
|
|
|
// 已结算的是否显示
|
|
if req.IsPayed != nil {
|
|
if *req.IsPayed {
|
|
filter[channelmod.FN.ChannelStat.IsPay] = true
|
|
} else {
|
|
filter[channelmod.FN.ChannelStat.IsPay] = bson.M{"$ne": true}
|
|
}
|
|
}
|
|
// 找到所有一级记录
|
|
filter[channelmod.FN.ChannelStat.Channel] = *req.Channel
|
|
filter[channelmod.FN.ChannelStat.Type] = channelmod.ChannelTypeParent
|
|
ParentsChannelStatList, err := channelmod.FindManyChannelStat(ctx, filter)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(ParentsChannelStatList) == 0 {
|
|
return resp, nil
|
|
}
|
|
// 找到分页一级记录
|
|
PagedChannelStatList, err := channelmod.FindManyChannelStat(ctx, filter, opt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// 找到所有子级记录
|
|
delete(filter, channelmod.FN.ChannelStat.Channel)
|
|
filter[channelmod.FN.ChannelStat.ParentChannel] = *req.Channel
|
|
childTypes := channelmod.GetChildChannelTypes()
|
|
filter[channelmod.FN.ChannelStat.Type] = bson.M{"$in": childTypes}
|
|
ChildChannelStatList, err := channelmod.FindManyChannelStat(ctx, filter)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// 把子级记录汇总到一级记录上面
|
|
for _, parent := range ParentsChannelStatList {
|
|
parent.CorrectValidData()
|
|
for _, child := range ChildChannelStatList {
|
|
if child.ParentChannel == parent.Channel && child.SumDate.Equal(parent.SumDate) {
|
|
channelmod.ChannelStatSummation(parent, child) // 把子渠道的数据累加到父渠道上面
|
|
}
|
|
}
|
|
}
|
|
// 对一级记录进行统计汇总
|
|
for _, channelStatInfo := range ParentsChannelStatList {
|
|
resp.TotalCount++
|
|
channelmod.ChannelStatSummation(&(resp.TotalInfo), channelStatInfo)
|
|
if channelStatInfo.IsPay {
|
|
resp.InvalidCount++
|
|
channelmod.ChannelStatSummation(&(resp.InvalidInfo), channelStatInfo)
|
|
} else {
|
|
resp.ValidCount++
|
|
channelmod.ChannelStatSummation(&(resp.ValidInfo), channelStatInfo)
|
|
}
|
|
}
|
|
// 把Page列表项替换为带子渠道数据的项
|
|
for i, pageItem := range PagedChannelStatList {
|
|
for j, parentItem := range ParentsChannelStatList {
|
|
if pageItem.ID.String() == parentItem.ID.String() {
|
|
PagedChannelStatList[i] = ParentsChannelStatList[j]
|
|
break
|
|
}
|
|
}
|
|
}
|
|
// 计算金币的数值:金币等于渠道直推充值金额-购买VIP金额-扣量
|
|
for _, v := range PagedChannelStatList {
|
|
v.CorrectValidData()
|
|
v.CalcIncomeRate()
|
|
}
|
|
// 修正数据
|
|
resp.TotalInfo.CorrectValidData()
|
|
resp.ValidInfo.CorrectValidData()
|
|
resp.InvalidInfo.CorrectValidData()
|
|
// 收益率
|
|
resp.TotalInfo.CalcIncomeRate()
|
|
resp.ValidInfo.CalcIncomeRate()
|
|
resp.InvalidInfo.CalcIncomeRate()
|
|
// 结算数值及提示信息
|
|
resp.TotalIncome, resp.TotalDesc = channelmod.CalculateChannelIncome(&resp.TotalInfo)
|
|
resp.ValidIncome, resp.ValidDesc = channelmod.CalculateChannelIncome(&resp.ValidInfo)
|
|
resp.InvalidIncome, resp.InvalidDesc = channelmod.CalculateChannelIncome(&resp.InvalidInfo)
|
|
// 输出列表
|
|
resp.List = PagedChannelStatList
|
|
resp.Channel = channelInfo.Channel
|
|
resp.AppId = *req.AppId
|
|
|
|
return resp, nil
|
|
}
|
|
|
|
// SearchSettlementInfo 查询渠道信息
|
|
func GetSettlementApplicantList(ctx context.Context, req *proto.GetSettlementApplicantListReq) (*proto.GetSettlementApplicantListResp, error) {
|
|
resp := proto.GetSettlementApplicantListResp{}
|
|
match := bson.M{}
|
|
pipelines := []bson.M{
|
|
{"$match": match},
|
|
{"$group": bson.M{
|
|
"_id": bson.M{"applicant": "$applicant"},
|
|
"count": bson.M{"$sum": 1},
|
|
}},
|
|
{"$project": bson.M{
|
|
"applicant": "$_id.applicant",
|
|
"count": "$count",
|
|
"_id": 0,
|
|
}},
|
|
|
|
{"$sort": bson.D{{Key: "count", Value: -1}}},
|
|
}
|
|
type Data struct {
|
|
Applicant string `bson:"applicant" json:"applicant"`
|
|
Count int64 `bson:"count" json:"count"`
|
|
}
|
|
List := make([]Data, 0)
|
|
|
|
if err := channelsettlementrecord.AggregateChannelSettlementRecords(ctx, &List, pipelines); err != nil {
|
|
return nil, err
|
|
}
|
|
for _, item := range List {
|
|
resp.List = append(resp.List, item.Applicant)
|
|
}
|
|
return &resp, nil
|
|
}
|
|
|
|
// SearchApplyForm 查询渠道信息
|
|
func SearchApplyForm(ctx context.Context, req *proto.GetApplyFormReq, channel string) (
|
|
*proto.GetApplyFormResp, error) {
|
|
filter := bson.M{}
|
|
opt := &options.FindOptions{}
|
|
opt.SetSort(bson.M{channelsettlementrecord.FN.ChannelSettlementRecord.CreatedAt: -1})
|
|
opt.SetSkip((req.PageNum - 1) * req.PageSize)
|
|
opt.SetLimit(req.PageSize)
|
|
|
|
resp := &proto.GetApplyFormResp{}
|
|
filter[channelsettlementrecord.FN.ChannelSettlementRecord.Channel] = channel
|
|
|
|
if req.AppId != nil {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementRecord.AppId] = *req.AppId
|
|
}
|
|
|
|
if req.Start != nil && req.End != nil {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementRecord.CreatedAt] = bson.M{"$gte": *req.Start, "$lt": *req.End}
|
|
}
|
|
|
|
if req.Status != nil {
|
|
if *req.Status == channelsettlementrecord.SettlementInit || *req.Status == channelsettlementrecord.SettlementSuccess {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementRecord.Status] = *req.Status
|
|
} else {
|
|
return nil, fmt.Errorf("未知状态")
|
|
}
|
|
} else {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementRecord.Status] = bson.M{"$in": []channelsettlementrecord.SettlementStatus{
|
|
channelsettlementrecord.SettlementInit, channelsettlementrecord.SettlementSuccess,
|
|
}}
|
|
}
|
|
|
|
total, err := channelsettlementrecord.CountChannelSettlementRecords(ctx, filter)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if total == 0 {
|
|
return resp, nil
|
|
}
|
|
SettlementInfoList, err := channelsettlementrecord.FindManyChannelSettlementRecord(ctx, filter, opt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
resp.List = SettlementInfoListToApplyForm(SettlementInfoList)
|
|
resp.Total = total
|
|
return resp, nil
|
|
}
|
|
|
|
// SearchSettlementInfo 查询渠道信息
|
|
func SearchSettlementInfo(ctx context.Context, req *proto.SettlementInfoSearch) (
|
|
*proto.SettlementInfoSearchResp, error) {
|
|
filter := bson.M{}
|
|
opt := &options.FindOptions{}
|
|
opt.SetSort(bson.M{channelsettlementrecord.FN.ChannelSettlementRecord.CreatedAt: -1})
|
|
opt.SetSkip((req.PageNum - 1) * req.PageSize)
|
|
opt.SetLimit(req.PageSize)
|
|
|
|
resp := &proto.SettlementInfoSearchResp{}
|
|
if req.Channel != nil && *req.Channel != "" {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementRecord.Channel] = *req.Channel
|
|
}
|
|
|
|
if req.AppId != nil {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementRecord.AppId] = *req.AppId
|
|
}
|
|
|
|
if req.Start != nil && req.End != nil {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementRecord.CreatedAt] = bson.M{"$gte": *req.Start, "$lt": *req.End}
|
|
}
|
|
|
|
if req.Remark != nil && *req.Remark != "" {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementRecord.Remark] = bson.M{"$regex": *req.Remark}
|
|
}
|
|
|
|
if len(req.Applicants) > 0 {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementRecord.Applicant] = bson.M{"$in": req.Applicants}
|
|
}
|
|
if len(req.Status) > 0 {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementRecord.Status] = bson.M{"$in": req.Status}
|
|
} else {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementRecord.Status] = bson.M{"$in": []channelsettlementrecord.SettlementStatus{}}
|
|
}
|
|
|
|
total, serr := channelsettlementrecord.CountChannelSettlementRecords(ctx, filter)
|
|
if serr != nil {
|
|
return nil, serr
|
|
}
|
|
if total == 0 {
|
|
return resp, nil
|
|
}
|
|
|
|
SettlementInfoList, err := channelsettlementrecord.FindManyChannelSettlementRecord(ctx, filter, opt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
resp.List = SettlementInfoList
|
|
resp.Total = total
|
|
return resp, nil
|
|
}
|
|
|
|
// SearchDeletedSettlementInfo 查询渠道信息
|
|
func SearchDeletedSettlementInfo(ctx context.Context, req *proto.SettlementInfoSearch) (
|
|
*proto.SettlementInfoSearchResp, error) {
|
|
filter := bson.M{}
|
|
opt := &options.FindOptions{}
|
|
opt.SetSort(bson.M{channelsettlementrecord.FN.ChannelSettlementDeleted.CreatedAt: -1})
|
|
opt.SetSkip((req.PageNum - 1) * req.PageSize)
|
|
opt.SetLimit(req.PageSize)
|
|
|
|
resp := &proto.SettlementInfoSearchResp{}
|
|
if req.Channel != nil && *req.Channel != "" {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementDeleted.Channel] = *req.Channel
|
|
}
|
|
|
|
if req.AppId != nil {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementDeleted.AppId] = *req.AppId
|
|
}
|
|
|
|
if req.Start != nil && req.End != nil {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementDeleted.CreatedAt] = bson.M{"$gte": *req.Start, "$lt": *req.End}
|
|
}
|
|
|
|
if req.Remark != nil && *req.Remark != "" {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementDeleted.Remark] = bson.M{"$regex": *req.Remark}
|
|
}
|
|
|
|
//if req.PayType != nil {
|
|
// switch *req.PayType {
|
|
// case 1:
|
|
// filter[channelsettlementrecord.FN.ChannelSettlementDeleted.ERC] = bson.M{"$gt": ""}
|
|
// case 2:
|
|
// filter[channelsettlementrecord.FN.ChannelSettlementDeleted.TRC] = bson.M{"$gt": ""}
|
|
// case 3:
|
|
// filter[channelsettlementrecord.FN.ChannelSettlementDeleted.BankCard] = bson.M{"$gt": ""}
|
|
// case 4:
|
|
// filter[channelsettlementrecord.FN.ChannelSettlementDeleted.Alipay] = bson.M{"$gt": ""}
|
|
// }
|
|
//}
|
|
|
|
total, serr := channelsettlementrecord.CountChannelSettlementDeletes(ctx, filter)
|
|
if serr != nil {
|
|
return nil, serr
|
|
}
|
|
if total == 0 {
|
|
return resp, nil
|
|
}
|
|
|
|
SettlementInfoList, err := channelsettlementrecord.FindManyChannelSettlementDeleted(ctx, filter, opt)
|
|
if serr != nil {
|
|
return nil, err
|
|
}
|
|
resp.List = SettlementInfoList
|
|
resp.Total = total
|
|
return resp, nil
|
|
}
|
|
|
|
// SearchSettlementInfoExport 导出渠道信息
|
|
func SearchSettlementInfoExport(ctx context.Context, req *proto.SettlementInfoSearch) (string, error) {
|
|
filter := bson.M{}
|
|
opt := &options.FindOptions{}
|
|
opt.SetSort(bson.M{channelsettlementrecord.FN.ChannelSettlementRecord.CreatedAt: -1})
|
|
opt.SetSkip((req.PageNum - 1) * req.PageSize)
|
|
opt.SetLimit(req.PageSize)
|
|
|
|
if req.Channel != nil && *req.Channel != "" {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementRecord.Channel] = *req.Channel
|
|
}
|
|
|
|
if req.AppId != nil {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementRecord.AppId] = *req.AppId
|
|
}
|
|
|
|
if req.Start != nil && req.End != nil {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementRecord.CreatedAt] = bson.M{"$gte": *req.Start, "$lt": *req.End}
|
|
}
|
|
|
|
if req.Remark != nil && *req.Remark != "" {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementRecord.Remark] = bson.M{"$regex": *req.Remark}
|
|
}
|
|
|
|
if len(req.Applicants) > 0 {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementRecord.Applicant] = bson.M{"$in": req.Applicants}
|
|
}
|
|
|
|
if len(req.Status) > 0 {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementRecord.Status] = bson.M{"$in": req.Status}
|
|
}
|
|
|
|
appList, err := appInfoMod.GetAllAppInfo(ctx)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
total, err1 := channelsettlementrecord.CountChannelSettlementRecords(ctx, filter)
|
|
if err1 != nil {
|
|
return "", err1
|
|
}
|
|
if total == 0 {
|
|
return "", nil
|
|
}
|
|
SettlementInfoList, err2 := channelsettlementrecord.FindManyChannelSettlementRecord(ctx, filter, opt)
|
|
if err2 != nil {
|
|
return "", err2
|
|
}
|
|
|
|
filePath := fmt.Sprintf("./tmp/渠道结算列表-%s.xlsx", time.Now().Format("2006-01-02 15:04:05"))
|
|
|
|
if sErr := export(filePath, SettlementInfoList, appList); sErr != nil {
|
|
return "", sErr
|
|
}
|
|
return filePath, nil
|
|
}
|
|
|
|
// SearchSettlementInfoApplyExport 导出结算申请信息
|
|
func SearchSettlementInfoApplyExport(ctx context.Context, req *proto.SettlementInfoSearch) (string, error) {
|
|
filter := bson.M{}
|
|
opt := &options.FindOptions{}
|
|
opt.SetSort(bson.M{channelsettlementrecord.FN.ChannelSettlementRecord.CreatedAt: -1})
|
|
opt.SetSkip((req.PageNum - 1) * req.PageSize)
|
|
opt.SetLimit(req.PageSize)
|
|
|
|
if req.Channel != nil && *req.Channel != "" {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementRecord.Channel] = *req.Channel
|
|
}
|
|
|
|
if req.AppId != nil {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementRecord.AppId] = *req.AppId
|
|
}
|
|
|
|
if req.Start != nil && req.End != nil {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementRecord.CreatedAt] = bson.M{"$gte": *req.Start, "$lt": *req.End}
|
|
}
|
|
|
|
if req.Remark != nil && *req.Remark != "" {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementRecord.Remark] = bson.M{"$regex": *req.Remark}
|
|
}
|
|
|
|
if len(req.Applicants) > 0 {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementRecord.Applicant] = bson.M{"$in": req.Applicants}
|
|
}
|
|
|
|
if len(req.Status) > 0 {
|
|
filter[channelsettlementrecord.FN.ChannelSettlementRecord.Status] = bson.M{"$in": req.Status}
|
|
}
|
|
|
|
total, err1 := channelsettlementrecord.CountChannelSettlementRecords(ctx, filter)
|
|
if err1 != nil {
|
|
return "", err1
|
|
}
|
|
if total == 0 {
|
|
return "", nil
|
|
}
|
|
SettlementInfoList, err2 := channelsettlementrecord.FindManyChannelSettlementRecord(ctx, filter, opt)
|
|
if err2 != nil {
|
|
return "", err2
|
|
}
|
|
|
|
if len(SettlementInfoList) <= 0 {
|
|
return "", nil
|
|
}
|
|
|
|
appList, err := appInfoMod.GetAllAppInfo(ctx)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
filePath := fmt.Sprintf("./tmp/渠道结算申请列表-%s.xlsx", time.Now().Format("2006-01-02 15:04:05"))
|
|
|
|
if sErr := ExportSettleApplyForm(filePath, SettlementInfoList, appList); sErr != nil {
|
|
return "", sErr
|
|
}
|
|
return filePath, nil
|
|
}
|
|
|
|
// AddSettlementInfo 添加一个媒体视频
|
|
func AddSettlementInfo(ctx context.Context, req *proto.SettlementInfoAdd) error {
|
|
|
|
settlementInfoFilter := bson.M{
|
|
channelsettlementrecord.FN.ChannelSettlementRecord.Channel: req.Channel,
|
|
channelsettlementrecord.FN.ChannelSettlementRecord.AppId: req.AppId,
|
|
}
|
|
settlementInfoList, serr := channelsettlementrecord.FindManyChannelSettlementRecord(ctx, settlementInfoFilter)
|
|
for _, valueInfo := range settlementInfoList {
|
|
if req.BeginTime.After(valueInfo.BeginTime) && req.BeginTime.Before(valueInfo.EndTime) {
|
|
return errors.New("重复结算")
|
|
}
|
|
|
|
if req.EndTime.After(valueInfo.BeginTime) && req.EndTime.Before(valueInfo.EndTime) {
|
|
return errors.New("重复结算")
|
|
}
|
|
}
|
|
|
|
request := &proto.ChannelStatSettlementSearch{
|
|
Channel: &req.Channel,
|
|
AppId: &req.AppId,
|
|
Start: &req.BeginTime,
|
|
End: &req.EndTime,
|
|
}
|
|
resp, serr := SearchChannelSettlementStat(ctx, request)
|
|
if serr != nil {
|
|
return serr
|
|
}
|
|
|
|
if resp.Income != req.TotalMoney {
|
|
return errors.New("金额不一致")
|
|
}
|
|
|
|
// 更新是否已经结算
|
|
channelStatFilter := bson.M{
|
|
"$or": bson.A{
|
|
bson.M{channelmod.FN.ChannelStat.Channel: req.Channel},
|
|
bson.M{channelmod.FN.ChannelStat.ParentChannel: req.Channel},
|
|
},
|
|
channelmod.FN.ChannelStat.AppId: req.AppId,
|
|
channelmod.FN.ChannelStat.SumDate: bson.M{"$gte": req.BeginTime, "$lte": req.EndTime},
|
|
channelmod.FN.ChannelStat.IsPay: bson.M{"$ne": true},
|
|
}
|
|
|
|
set := bson.M{
|
|
"$set": bson.M{
|
|
channelmod.FN.ChannelStat.IsPay: true,
|
|
},
|
|
}
|
|
|
|
err := channelmod.UpdateManyChannelStat(ctx, channelStatFilter, set)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
filter := bson.M{
|
|
channelmod.FN.ChannelDeductionRule.Channel: req.Channel,
|
|
channelmod.FN.ChannelDeductionRule.AppId: req.AppId,
|
|
}
|
|
|
|
newRecord := &channelsettlementrecord.ChannelSettlementRecord{
|
|
Channel: req.Channel,
|
|
AppId: req.AppId,
|
|
BeginTime: req.BeginTime,
|
|
EndTime: req.EndTime,
|
|
TotalMoney: resp.Income,
|
|
NewDirectCount: resp.TotalInfo.NewDirectCount,
|
|
NewFissionCount: resp.TotalInfo.NewFissionCount,
|
|
NewDeductionCount: resp.TotalInfo.NewDeductionCount,
|
|
RechargeAmount: resp.TotalInfo.DirectAmount + resp.TotalInfo.FissionAmount + resp.TotalInfo.DeductionAmount,
|
|
VipPayMoney: resp.TotalInfo.VipPayMoney,
|
|
ValidDirectCount: resp.TotalInfo.ValidDirectCount,
|
|
ValidDeductionCount: resp.TotalInfo.ValidDeductionCount,
|
|
ValidPayMoney: resp.TotalInfo.ValidPayMoney,
|
|
ValidPayCoin: resp.TotalInfo.ValidPayCoin,
|
|
Status: channelsettlementrecord.SettlementInit,
|
|
CreatedAt: time.Now(),
|
|
}
|
|
ruleInfo, _ := channelmod.FindOneChannelDeductionRule(ctx, filter)
|
|
if ruleInfo != nil {
|
|
newRecord.AppType = ruleInfo.AppType
|
|
newRecord.PromoteMode = ruleInfo.PromoteMode
|
|
newRecord.Settlement = ruleInfo.Settlement
|
|
newRecord.CPAPrice = ruleInfo.CPAPrice
|
|
newRecord.CPSRate = ruleInfo.CPSRate
|
|
}
|
|
|
|
return channelsettlementrecord.InsertOneChannelSettlementRecord(ctx, newRecord)
|
|
}
|
|
|
|
// AddSettlementInfo 添加一个媒体视频
|
|
func AddSettlementInfo2(ctx context.Context, req *proto.SettlementInfoAdd2, accType define.ActType, account string) error {
|
|
// 参数检查
|
|
if len(req.SettleIds) <= 0 {
|
|
return errors.New("没有提交要结算的统计记录id数组")
|
|
}
|
|
if req.SettleMoney <= 0 {
|
|
return errors.New("结算的真实金额必须大于零")
|
|
}
|
|
// 在已结算表中检查是否有重复结算
|
|
settlementInfoFilter := bson.M{
|
|
channelsettlementrecord.FN.ChannelSettlementRecord.SettleIds: bson.M{"$in": req.SettleIds},
|
|
}
|
|
settlementInfoList, err := channelsettlementrecord.FindManyChannelSettlementRecord(ctx, settlementInfoFilter)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if len(settlementInfoList) > 0 {
|
|
return errors.New("重复结算")
|
|
}
|
|
// 获取扣量规则
|
|
ruleFilter := bson.M{
|
|
channelmod.FN.ChannelDeductionRule.ID: req.RuleId,
|
|
channelmod.FN.ChannelDeductionRule.AppId: req.AppId,
|
|
channelmod.FN.ChannelDeductionRule.Channel: req.Channel,
|
|
}
|
|
channelRule, err1 := channelmod.FindOneChannelDeductionRuleEx(ctx, ruleFilter)
|
|
// 检查扣量规则
|
|
if err1 != nil {
|
|
return fmt.Errorf("查找渠道结算规则失败:%s", err1.Error())
|
|
}
|
|
// 开始时间和结束时间
|
|
req.BeginTime, req.EndTime, err = CheckAndFixTime(req.BeginTime, req.EndTime)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// ids数据查找
|
|
opt := &options.FindOptions{}
|
|
opt.SetSort(bson.M{channelmod.FN.ChannelStat.SumDate: 1})
|
|
parentFilter := bson.M{
|
|
channelmod.FN.ChannelStat.AppId: req.AppId, // 应用限定
|
|
channelmod.FN.ChannelStat.Channel: req.Channel, // 渠道限定
|
|
channelmod.FN.ChannelStat.Type: channelmod.ChannelTypeParent, // 类型限定
|
|
channelmod.FN.ChannelStat.IsPay: bson.M{"$ne": true}, // 未结算过
|
|
channelmod.FN.ChannelStat.SumDate: bson.M{"$gte": req.BeginTime, "$lte": req.EndTime}, // 时间限定
|
|
channelmod.FN.ChannelStat.ID: bson.M{"$in": req.SettleIds}, // 提交的IDs
|
|
}
|
|
ParentList, err2 := channelmod.FindManyChannelStat(ctx, parentFilter, opt)
|
|
if err2 != nil {
|
|
return err2
|
|
}
|
|
if len(ParentList) != len(req.SettleIds) {
|
|
return fmt.Errorf("提交的统计记录条数[%d]和查找到的[%d]不一致", len(req.SettleIds), len(ParentList))
|
|
}
|
|
// 结算项检查
|
|
for _, stat := range ParentList {
|
|
if stat.Type != channelmod.ChannelTypeParent {
|
|
return fmt.Errorf("子渠道[%s]不能单独参与结算,只需提交其父渠道即可", stat.Channel)
|
|
}
|
|
}
|
|
if len(ParentList) == 0 {
|
|
return fmt.Errorf("没有找到渠道结算数据")
|
|
}
|
|
// 列表的起止时间
|
|
listBeginTime := ParentList[0].SumDate
|
|
listEndTime := ParentList[len(ParentList)-1].SumDate
|
|
// 查找子级渠道的数据
|
|
childTypes := channelmod.GetChildChannelTypes()
|
|
childFilter := bson.M{
|
|
channelmod.FN.ChannelStat.ParentChannel: req.Channel, // 限定父渠道
|
|
channelmod.FN.ChannelStat.Type: bson.M{"$in": childTypes}, // 限定子渠道
|
|
channelmod.FN.ChannelStat.IsPay: bson.M{"$ne": true}, // 未结算过
|
|
channelmod.FN.ChannelStat.SumDate: bson.M{"$gte": listBeginTime, "$lte": listEndTime}, // 时间限定
|
|
}
|
|
ChildList, err3 := channelmod.FindManyChannelStat(ctx, childFilter)
|
|
if err3 != nil {
|
|
return err3
|
|
}
|
|
// 把二级记录汇总到一级记录上面
|
|
for _, parent := range ParentList {
|
|
parent.CorrectValidData()
|
|
for _, child := range ChildList {
|
|
if child.ParentChannel == parent.Channel && child.SumDate.Equal(parent.SumDate) {
|
|
channelmod.ChannelStatSummation(parent, child) // 把子渠道的数据累加到父渠道上面
|
|
}
|
|
}
|
|
}
|
|
// 对一级记录进行统计汇总
|
|
sumInfo := &channelmod.ChannelStat{
|
|
Channel: channelRule.Channel,
|
|
AppId: channelRule.AppId,
|
|
Settlement: channelRule.Settlement,
|
|
CPAPrice: channelRule.CPAPrice,
|
|
CPSRate: channelRule.CPSRate,
|
|
AppType: channelRule.AppType,
|
|
PromoteMode: channelRule.PromoteMode,
|
|
}
|
|
for _, statInfo := range ParentList {
|
|
channelmod.ChannelStatSummation(sumInfo, statInfo)
|
|
}
|
|
// 根据扣量规则计算结算金额
|
|
// TODO 这里按当前 Rule规则 扣量
|
|
income, _ := channelmod.CalculateChannelIncome(sumInfo)
|
|
// 检查提交的和计算的是否一致
|
|
if income != req.TotalMoney {
|
|
return fmt.Errorf("提交的结算金额[%d分]和服务器统计的[%d分]不一致", req.TotalMoney, income)
|
|
}
|
|
// 获取操作者名字
|
|
var accName string
|
|
if accName, err = GetAccountName(ctx, accType, account); err != nil {
|
|
return fmt.Errorf("获取账号[%s]的信息失败:%s", account, err.Error())
|
|
}
|
|
// 获取渠道信息
|
|
channelInfo, err4 := channelmod.FindOneChannelInfoEx(ctx, bson.M{channelmod.FN.ChannelInfo.Channel: req.Channel})
|
|
if err4 != nil {
|
|
return fmt.Errorf("渠道不存在")
|
|
}
|
|
// 渠道级别检查
|
|
if channelInfo.Type != channelmod.ChannelTypeParent {
|
|
return fmt.Errorf("输入的渠道不是一级渠道,只有一级渠道才能进行结算")
|
|
}
|
|
// 结算钱包检查
|
|
if req.WalletAddr1 != nil && *req.WalletAddr1 != channelInfo.Wallet.Addr1 {
|
|
return fmt.Errorf("钱包地址1,和渠道信息中填写的不一致")
|
|
}
|
|
if req.WalletAddr2 != nil && *req.WalletAddr2 != channelInfo.Wallet.Addr2 {
|
|
return fmt.Errorf("钱包地址2,和渠道信息中填写的不一致")
|
|
}
|
|
if req.WalletAddr1 == nil && req.WalletAddr2 == nil {
|
|
return fmt.Errorf("结算的收款地址信息必须至少填写一个")
|
|
}
|
|
// 下面两步用事务
|
|
fn := func(sctx mongo.SessionContext) error {
|
|
// 更新是否已经结算
|
|
parentFilter = bson.M{
|
|
channelmod.FN.ChannelStat.ID: bson.M{"$in": req.SettleIds}, // 提交的IDs
|
|
channelmod.FN.ChannelStat.IsPay: bson.M{"$in": bson.A{nil, false}},
|
|
}
|
|
set := bson.M{
|
|
"$set": bson.M{
|
|
channelmod.FN.ChannelStat.IsPay: true,
|
|
},
|
|
}
|
|
if count, err := channelmod.UpdateManyChannelStatWithResult(sctx, parentFilter, set); err != nil {
|
|
return err
|
|
} else {
|
|
if count != int64(len(req.SettleIds)) {
|
|
return fmt.Errorf("数据修改冲突,同一结算,请不要多次点击提交")
|
|
}
|
|
}
|
|
// 渠道备注
|
|
var remark string
|
|
if req.Remark != nil {
|
|
remark = *req.Remark
|
|
}
|
|
now := time.Now()
|
|
newRecord := &channelsettlementrecord.ChannelSettlementRecord{
|
|
Channel: req.Channel,
|
|
IncludeChild: true,
|
|
AppId: req.AppId,
|
|
BeginTime: listBeginTime,
|
|
EndTime: listEndTime,
|
|
TotalMoney: income,
|
|
SettleMoney: req.SettleMoney,
|
|
Settlement: channelRule.Settlement,
|
|
CPAPrice: channelRule.CPAPrice,
|
|
CPSRate: channelRule.CPSRate,
|
|
AppType: channelRule.AppType,
|
|
PromoteMode: channelRule.PromoteMode,
|
|
NewDirectCount: sumInfo.NewDirectCount,
|
|
NewFissionCount: sumInfo.NewFissionCount,
|
|
NewDeductionCount: sumInfo.NewDeductionCount,
|
|
RechargeAmount: sumInfo.DirectAmount + sumInfo.FissionAmount + sumInfo.DeductionAmount,
|
|
VipPayMoney: sumInfo.VipPayMoney,
|
|
VipPayCoin: sumInfo.VipPayCoin,
|
|
VipPayDeduction: sumInfo.VipPayDeduction,
|
|
ValidDirectCount: sumInfo.ValidDirectCount,
|
|
ValidDeductionCount: sumInfo.ValidDeductionCount,
|
|
ValidPayMoney: sumInfo.ValidPayMoney,
|
|
ValidPayCoin: sumInfo.ValidPayCoin,
|
|
Wallet: channelmod.Wallet{
|
|
Addr1: checkParam(req.WalletAddr1),
|
|
Addr2: checkParam(req.WalletAddr2),
|
|
},
|
|
PayMoney: 0,
|
|
OperateHistory: []channelsettlementrecord.SettlementOperateItem{
|
|
{
|
|
OperateTime: time.Now(),
|
|
BeforeStatus: channelsettlementrecord.SettlementInit,
|
|
AfterStatus: channelsettlementrecord.SettlementInit,
|
|
OperatorAccount: account,
|
|
OperatorAccountName: accName,
|
|
OperatorAccountType: accType,
|
|
Pictures: []string{},
|
|
Content: fmt.Sprintf("【%s】提交了结算申请", accName),
|
|
Remark: remark,
|
|
},
|
|
},
|
|
Status: channelsettlementrecord.SettlementInit,
|
|
Remark: remark,
|
|
SettleIds: req.SettleIds,
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
Applicant: accName,
|
|
}
|
|
err = channelsettlementrecord.InsertOneChannelSettlementRecord(sctx, newRecord)
|
|
return err
|
|
}
|
|
if err := mongos.Transaction(ctx, fn); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func checkParam(req *string) string {
|
|
if req != nil {
|
|
return *req
|
|
} else {
|
|
return ""
|
|
}
|
|
}
|
|
|
|
// UpdateSettlementInfo 更新指定渠道
|
|
func UpdateSettlementInfo(ctx context.Context, info proto.SettlementInfoUpdate) error {
|
|
|
|
filter := bson.M{channelsettlementrecord.FN.ChannelSettlementRecord.ID: info.ID}
|
|
|
|
set := bson.M{}
|
|
if info.PayMoney != nil {
|
|
set[channelsettlementrecord.FN.ChannelSettlementRecord.PayMoney] = info.PayMoney
|
|
}
|
|
if info.Remark != nil {
|
|
set[channelsettlementrecord.FN.ChannelSettlementRecord.Remark] = info.Remark
|
|
}
|
|
if info.Status != nil {
|
|
set[channelsettlementrecord.FN.ChannelSettlementRecord.Status] = info.Status
|
|
}
|
|
|
|
if info.Usdt != nil {
|
|
set[channelsettlementrecord.FN.ChannelSettlementRecord.Usdt] = info.Usdt
|
|
}
|
|
//更新数据库
|
|
setDoc := bson.M{"$set": set}
|
|
|
|
serr := channelsettlementrecord.UpdateOneChannelSettlementRecord(ctx, filter, setDoc)
|
|
if serr != nil {
|
|
return serr
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// DeleteSettlementInfo 更新指定渠道
|
|
func DeleteSettlementInfo(ctx context.Context, req proto.SettlementInfoDelete, accType define.ActType, account string) error {
|
|
filter := bson.M{channelsettlementrecord.FN.ChannelSettlementRecord.ID: req.ID}
|
|
settle, err := channelsettlementrecord.FindOneChannelSettlementRecordEx(ctx, filter)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// 获取操作者名字
|
|
var accName string
|
|
if accName, err = GetAccountName(ctx, accType, account); err != nil {
|
|
return fmt.Errorf("获取账号[%s]的信息失败:%s", account, err.Error())
|
|
}
|
|
// 状态为【发起申请】【打款失败】这两种状态的结算记录可以删除
|
|
if settle.Status == channelsettlementrecord.SettlementInit || settle.Status == channelsettlementrecord.SettlementFailed {
|
|
|
|
// 下面用事务
|
|
fn := func(sctx mongo.SessionContext) error {
|
|
// 结算中的统计项全部修改为未结算状态
|
|
statFilter := bson.M{
|
|
channelmod.FN.ChannelStat.ID: bson.M{"$in": settle.SettleIds}, // 提交的IDs
|
|
}
|
|
set := bson.M{
|
|
"$set": bson.M{
|
|
channelmod.FN.ChannelStat.IsPay: false,
|
|
},
|
|
}
|
|
err := channelmod.UpdateManyChannelStat(sctx, statFilter, set)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// 插入要删除副本到删除备份表
|
|
settle.OperateHistory = append(settle.OperateHistory, channelsettlementrecord.SettlementOperateItem{
|
|
OperateTime: time.Now(),
|
|
BeforeStatus: settle.Status,
|
|
AfterStatus: channelsettlementrecord.SettlementDeleted,
|
|
OperatorAccount: account,
|
|
OperatorAccountType: accType,
|
|
OperatorAccountName: accName,
|
|
Content: fmt.Sprintf("状态改变:(%s => %s)\n", settle.Status.String(), channelsettlementrecord.SettlementDeleted.String()),
|
|
Pictures: nil,
|
|
Remark: "结算记录被删除",
|
|
})
|
|
status := settle.Status
|
|
settle.Status = channelsettlementrecord.SettlementDeleted
|
|
err = channelsettlementrecord.InsertOneChannelSettlementDeleted(ctx, settle)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// 删除结算项
|
|
settleFilter := bson.M{
|
|
channelsettlementrecord.FN.ChannelSettlementRecord.ID: settle.ID,
|
|
channelsettlementrecord.FN.ChannelSettlementRecord.Status: status,
|
|
}
|
|
_, err = channelsettlementrecord.DelOneChannelSettlementRecord(ctx, settleFilter)
|
|
return err
|
|
}
|
|
if err := mongos.Transaction(ctx, fn); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
|
|
} else {
|
|
return fmt.Errorf("当前结算项的状态[%s][%d]不能被删除!", channelsettlementrecord.GetSettStatus(settle.Status), settle.Status)
|
|
}
|
|
}
|
|
|
|
// DetailSettlementInfo 查看结算项详情
|
|
func DetailSettlementInfo(ctx context.Context, req proto.SettlementInfoDetail) (*proto.SettlementInfoDetailResp, error) {
|
|
resp := &proto.SettlementInfoDetailResp{}
|
|
settleFilter := bson.M{channelsettlementrecord.FN.ChannelSettlementRecord.ID: req.ID}
|
|
settle, err := channelsettlementrecord.FindOneChannelSettlementRecordEx(ctx, settleFilter)
|
|
if err != nil {
|
|
if err != mongo.ErrNoDocuments {
|
|
return nil, err
|
|
}
|
|
settle, err = channelsettlementrecord.FindOneChannelSettlementDeletedEx(ctx, settleFilter)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
// 找到所有一级记录
|
|
statFilter := bson.M{
|
|
channelmod.FN.ChannelStat.Type: channelmod.ChannelTypeParent,
|
|
channelmod.FN.ChannelStat.ID: bson.M{"$in": settle.SettleIds},
|
|
}
|
|
ParentsChannelStatList, err := channelmod.FindManyChannelStat(ctx, statFilter)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(ParentsChannelStatList) == 0 {
|
|
return resp, nil
|
|
}
|
|
// 找到分页一级记录
|
|
opt := &options.FindOptions{}
|
|
opt.SetSort(bson.M{channelmod.FN.ChannelStat.CreatedAt: -1})
|
|
opt.SetSkip((req.PageNum - 1) * req.PageSize)
|
|
opt.SetLimit(req.PageSize)
|
|
PagedChannelStatList, err := channelmod.FindManyChannelStat(ctx, statFilter, opt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// 找到所有子级记录
|
|
childTypes := channelmod.GetChildChannelTypes()
|
|
childFilter := bson.M{
|
|
channelmod.FN.ChannelStat.ParentChannel: settle.Channel,
|
|
channelmod.FN.ChannelStat.Type: bson.M{"$in": childTypes},
|
|
channelmod.FN.ChannelStat.SumDate: bson.M{"$gte": settle.BeginTime, "$lte": settle.EndTime}, // 时间限定
|
|
}
|
|
ChildsChannelStatList, err := channelmod.FindManyChannelStat(ctx, childFilter)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// 把子级记录汇总到一级记录上面
|
|
for _, parent := range ParentsChannelStatList {
|
|
for _, child := range ChildsChannelStatList {
|
|
if child.ParentChannel == parent.Channel && child.SumDate.Equal(parent.SumDate) {
|
|
channelmod.ChannelStatSummation(parent, child) // 把子渠道的数据累加到父渠道上面
|
|
}
|
|
}
|
|
}
|
|
// 把Page列表项替换为带子渠道数据的项
|
|
for i, pageItem := range PagedChannelStatList {
|
|
for j, parentItem := range ParentsChannelStatList {
|
|
if pageItem.ID.String() == parentItem.ID.String() {
|
|
PagedChannelStatList[i] = ParentsChannelStatList[j]
|
|
break
|
|
}
|
|
}
|
|
}
|
|
// 计算金币的数值:金币等于渠道直推充值金额-购买VIP金额-扣量
|
|
for _, v := range PagedChannelStatList {
|
|
//v.VipPayCoin = (v.DirectAmount + v.FissionAmount - v.VipPayMoney - v.VipPayDeduction)
|
|
v.CorrectValidData()
|
|
v.CalcIncomeRate()
|
|
}
|
|
resp.List = PagedChannelStatList
|
|
resp.Count = int64(len(ParentsChannelStatList))
|
|
return resp, nil
|
|
}
|
|
|
|
// UpdateSettlementInfo2 更新指定渠道
|
|
func UpdateSettlementInfo2(ctx context.Context, req proto.SettlementInfoUpdate2, accType define.ActType, account string) error {
|
|
|
|
chReq := proto.SettlementInfoUpdate2{}
|
|
filter := bson.M{channelsettlementrecord.FN.ChannelSettlementRecord.ID: req.ID}
|
|
settle, err := channelsettlementrecord.FindOneChannelSettlementRecordEx(ctx, filter)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// 获取操作者名字
|
|
var accName string
|
|
if accName, err = GetAccountName(ctx, accType, account); err != nil {
|
|
return fmt.Errorf("获取操作者账号[%s]的信息失败:%s", account, err.Error())
|
|
}
|
|
set := bson.M{channelsettlementrecord.FN.ChannelSettlementRecord.UpdatedAt: time.Now()}
|
|
if req.Remark != nil {
|
|
set[channelsettlementrecord.FN.ChannelSettlementRecord.Remark] = req.Remark
|
|
chReq.Remark = req.Remark
|
|
}
|
|
// 状态转换检查
|
|
switch settle.Status {
|
|
case channelsettlementrecord.SettlementInit: // 【发起】结算状态,可以修改和确认
|
|
{
|
|
if req.Status == nil { // 渠道可以修改要结算的钱数,及钱包地址
|
|
return fmt.Errorf("参数错误,要修改的状态字段为空")
|
|
} else {
|
|
if *req.Status == channelsettlementrecord.SettlementSuccess || *req.Status == channelsettlementrecord.SettlementFailed {
|
|
set[channelsettlementrecord.FN.ChannelSettlementRecord.Status] = req.Status
|
|
chReq.Status = req.Status
|
|
if *req.Status == channelsettlementrecord.SettlementSuccess {
|
|
if req.Usdt != nil {
|
|
set[channelsettlementrecord.FN.ChannelSettlementRecord.Usdt] = req.Usdt
|
|
chReq.Usdt = req.Usdt
|
|
}
|
|
if req.PayMoney != nil {
|
|
set[channelsettlementrecord.FN.ChannelSettlementRecord.PayMoney] = req.PayMoney
|
|
chReq.PayMoney = req.PayMoney
|
|
}
|
|
}
|
|
} else {
|
|
return fmt.Errorf("修改状态出错!因为结算状态为【发起申请】状态,只能修改为【打款成功】或【打款失败】")
|
|
}
|
|
}
|
|
}
|
|
case channelsettlementrecord.SettlementSuccess:
|
|
{
|
|
return fmt.Errorf("错误,已经成功的结算单不能修改")
|
|
}
|
|
case channelsettlementrecord.SettlementFailed:
|
|
{
|
|
return fmt.Errorf("错误,打款失败的结算单不能修改,只能删除后重新发起结算申请")
|
|
}
|
|
case channelsettlementrecord.SettlementDeleted:
|
|
{
|
|
return fmt.Errorf("错误,已删除的订单无法修改")
|
|
}
|
|
default:
|
|
{
|
|
return fmt.Errorf("状态无效")
|
|
}
|
|
}
|
|
|
|
opItem := GetUpdateSettlementOperateItem(*settle, chReq, accType, account, accName, req.Pictures)
|
|
push := bson.M{channelsettlementrecord.FN.ChannelSettlementRecord.OperateHistory: opItem}
|
|
|
|
//更新数据库
|
|
setDoc := bson.M{"$set": set, "$push": push}
|
|
|
|
serr := channelsettlementrecord.UpdateOneChannelSettlementRecord(ctx, filter, setDoc)
|
|
if serr != nil {
|
|
return serr
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func ExportSettleApplyForm(rPath string, transInfos []*channelsettlementrecord.ChannelSettlementRecord, appList []appInfoMod.AppInfo) error {
|
|
f := excelize.NewFile()
|
|
sheetName := "Sheet1"
|
|
// 设置列宽
|
|
f.SetColWidth("Sheet1", "A", "W", 20)
|
|
// 设置表头行高
|
|
f.SetRowHeight("Sheet1", 1, 30)
|
|
// 设置表头样式
|
|
headStyleID, _ := f.NewStyle(`{
|
|
"font":{
|
|
"color":"#333333",
|
|
"bold":true,
|
|
"size":16,
|
|
"family":"arial"
|
|
},
|
|
"alignment":{
|
|
"vertical":"center",
|
|
"horizontal":"center"
|
|
}
|
|
}`)
|
|
|
|
f.SetCellStyle("Sheet1", "A1", "W1", headStyleID)
|
|
|
|
idx := f.NewSheet(sheetName)
|
|
var exportTransWaterTitle = map[string]string{
|
|
"A1": "申请人",
|
|
"B1": "产品",
|
|
"C1": "渠道码",
|
|
"D1": "分成",
|
|
"E1": "结算期间",
|
|
"F1": "",
|
|
"G1": "新增",
|
|
"H1": "",
|
|
"I1": "金币充值",
|
|
"J1": "充值金额",
|
|
"K1": "结算金额",
|
|
"L1": "ARPU",
|
|
"M1": "收益比例",
|
|
"N1": "打款日期",
|
|
"O1": "打款金额",
|
|
"P1": "实际打款",
|
|
"Q1": "汇率",
|
|
"R1": "U金额",
|
|
"S1": "方式",
|
|
"T1": "钱包",
|
|
"U1": "打款资料",
|
|
"V1": "打款资料",
|
|
"W1": "备注",
|
|
}
|
|
for k, v := range exportTransWaterTitle {
|
|
f.SetCellValue(sheetName, k, v)
|
|
}
|
|
f.SetCellValue(sheetName, "E2", "开:")
|
|
f.SetCellValue(sheetName, "F2", "结:")
|
|
f.SetCellValue(sheetName, "G2", "未")
|
|
f.SetCellValue(sheetName, "H2", "扣")
|
|
|
|
f.MergeCell(sheetName, "E1", "F1")
|
|
f.MergeCell(sheetName, "G1", "H1")
|
|
|
|
SetCellValue := func(file *excelize.File, sheet, axis string, value string) {
|
|
//fmt.Printf("sheet: %s, axis:%s, value:%s\n", sheet, axis, value)
|
|
file.SetCellValue(sheetName, axis, value)
|
|
}
|
|
|
|
for index, item := range transInfos {
|
|
col := 'A' // col 不能超过Z,即列输不能超过26列,超出将出现bug
|
|
row := index + 3
|
|
axis := func() string {
|
|
ret := fmt.Sprintf("%s%d", string(col), row)
|
|
col++
|
|
return ret
|
|
}
|
|
operator := ""
|
|
remark := ""
|
|
if len(item.OperateHistory) > 0 {
|
|
operator = item.OperateHistory[0].OperatorAccountName
|
|
remark = item.OperateHistory[0].Remark
|
|
if len(item.OperateHistory) > 1 {
|
|
if remark == "" {
|
|
remark = item.OperateHistory[len(item.OperateHistory)-1].Remark
|
|
} else {
|
|
s := item.OperateHistory[len(item.OperateHistory)-1].Remark
|
|
if s != "" {
|
|
remark += " / " + s
|
|
}
|
|
}
|
|
}
|
|
}
|
|
begin := item.BeginTime.Local().Format("2006-01-02")
|
|
end := item.EndTime.Local().Format("2006-01-02")
|
|
divide := ""
|
|
if item.Settlement == channelmod.SettlementCPA {
|
|
divide = fmt.Sprintf("%.2f", float64(item.CPAPrice)/100)
|
|
} else if item.Settlement == channelmod.SettlementCPS {
|
|
divide = fmt.Sprintf("%d%%", item.CPSRate)
|
|
}
|
|
|
|
payMoneyStr := ""
|
|
if item.Status == channelsettlementrecord.SettlementSuccess {
|
|
payMoneyStr = IndentationDisplay(item.SettleMoney)
|
|
}
|
|
realMoneyStr := ""
|
|
realUsdtStr := ""
|
|
if item.Status == channelsettlementrecord.SettlementSuccess {
|
|
realMoneyStr = IndentationDisplay(item.PayMoney)
|
|
realUsdtStr = IndentationDisplay(item.Usdt)
|
|
}
|
|
//fmt.Printf("----- ROW %d -----\n", row)
|
|
product := fmt.Sprintf("%s%s", GetAppName(appList, item.AppId), strings.ToUpper(string(item.Settlement)))
|
|
SetCellValue(f, sheetName, axis(), operator) //申请人
|
|
SetCellValue(f, sheetName, axis(), product) //产品
|
|
SetCellValue(f, sheetName, axis(), item.Channel) //渠道码
|
|
SetCellValue(f, sheetName, axis(), divide) //分成
|
|
SetCellValue(f, sheetName, axis(), begin) //开
|
|
SetCellValue(f, sheetName, axis(), end) //结
|
|
SetCellValue(f, sheetName, axis(), FenToYuanDisplay(item.NewDirectCount+item.NewFissionCount+item.NewDeductionCount)) //未
|
|
SetCellValue(f, sheetName, axis(), FenToYuanDisplay(item.NewDirectCount)) //扣
|
|
SetCellValue(f, sheetName, axis(), IndentationDisplay(item.VipPayCoin)) //金币充值
|
|
SetCellValue(f, sheetName, axis(), IndentationDisplay(item.VipPayMoney+item.VipPayDeduction)) //充值金额(这里显示的是:总充值-金币)
|
|
SetCellValue(f, sheetName, axis(), IndentationDisplay(item.SettleMoney)) //结算金额
|
|
SetCellValue(f, sheetName, axis(), "") //ARPU
|
|
SetCellValue(f, sheetName, axis(), "") //收益比例
|
|
SetCellValue(f, sheetName, axis(), "") //打款日期
|
|
SetCellValue(f, sheetName, axis(), payMoneyStr) //打款金额
|
|
SetCellValue(f, sheetName, axis(), realMoneyStr) //实际打款
|
|
SetCellValue(f, sheetName, axis(), "") //汇率
|
|
SetCellValue(f, sheetName, axis(), realUsdtStr) //U金额
|
|
SetCellValue(f, sheetName, axis(), "") //方式
|
|
SetCellValue(f, sheetName, axis(), "") //钱包
|
|
SetCellValue(f, sheetName, axis(), item.Wallet.Addr1) //打款资料
|
|
SetCellValue(f, sheetName, axis(), item.Wallet.Addr2) //打款资料
|
|
SetCellValue(f, sheetName, axis(), remark) //备注
|
|
}
|
|
f.SetActiveSheet(idx)
|
|
p, _ := os.Getwd()
|
|
fileName := path.Join(p, rPath)
|
|
if err := f.SaveAs(fileName); err != nil {
|
|
log.Error("SettlementInfo:ExportSettleForm save file to disk failed",
|
|
log.Any("fileName", fileName),
|
|
log.E(err))
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func export(rPath string, transInfos []*channelsettlementrecord.ChannelSettlementRecord, appList []appInfoMod.AppInfo) error {
|
|
f := excelize.NewFile()
|
|
sheetName := "Sheet1"
|
|
// 设置列宽
|
|
f.SetColWidth("Sheet1", "A", "U", 20)
|
|
// 设置表头行高
|
|
f.SetRowHeight("Sheet1", 1, 30)
|
|
// 设置表头样式
|
|
headStyleID, _ := f.NewStyle(`{
|
|
"font":{
|
|
"color":"#333333",
|
|
"bold":true,
|
|
"size":16,
|
|
"family":"arial"
|
|
},
|
|
"alignment":{
|
|
"vertical":"center",
|
|
"horizontal":"center"
|
|
}
|
|
}`)
|
|
|
|
f.SetCellStyle("Sheet1", "A1", "U1", headStyleID)
|
|
|
|
idx := f.NewSheet(sheetName)
|
|
var exportTransWaterTitle = map[string]string{
|
|
"A1": "开始时间",
|
|
"B1": "结束时间",
|
|
"C1": "渠道",
|
|
"D1": "结算方式",
|
|
"E1": "收款信息1",
|
|
"F1": "收款信息2",
|
|
"G1": "单价",
|
|
"H1": "分成比列",
|
|
"I1": "应用名称",
|
|
"J1": "新增",
|
|
"K1": "扣量",
|
|
"L1": "充值金额",
|
|
"M1": "金币充值",
|
|
"N1": "统计结算金额",
|
|
"O1": "申请结算金额",
|
|
"P1": "打款金额(CNY)",
|
|
"Q1": "打款金额(USDT)",
|
|
"R1": "备注",
|
|
"S1": "状态",
|
|
"T1": "创建时间",
|
|
"U1": "申请结算人",
|
|
}
|
|
for k, v := range exportTransWaterTitle {
|
|
f.SetCellValue(sheetName, k, v)
|
|
}
|
|
for k, v := range transInfos {
|
|
i := 'A' // i 不能超过Z,即列输不能超过26列,超出将出现bug
|
|
begin := v.BeginTime.Local().Format("2006-01-02")
|
|
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), begin) //开始时间
|
|
i++
|
|
end := v.EndTime.Local().Format("2006-01-02")
|
|
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), end) //结束时间
|
|
i++
|
|
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), v.Settlement) //结算方式
|
|
i++
|
|
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), v.Wallet.Addr1) //打款地址1
|
|
i++
|
|
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), v.Wallet.Addr2) //打款地址2
|
|
i++
|
|
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), float64(v.CPAPrice)/100) //单价
|
|
i++
|
|
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), v.CPSRate) //分成比列
|
|
i++
|
|
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), GetAppName(appList, v.AppId)) //应用名称
|
|
i++
|
|
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), v.NewDirectCount) //新增
|
|
i++
|
|
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), v.NewDeductionCount) //扣量
|
|
i++
|
|
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), float64(v.VipPayMoney+v.VipPayDeduction)/100) //充值金额
|
|
i++
|
|
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), float64(v.VipPayCoin)/100) //金币充值
|
|
i++
|
|
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), float64(v.TotalMoney)/100) //统计结算金额
|
|
i++
|
|
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), float64(v.SettleMoney)/100) //申请结算金额
|
|
i++
|
|
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), float64(v.PayMoney)/100) //打款金额
|
|
i++
|
|
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), float64(v.Usdt)/100)
|
|
i++
|
|
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), v.Remark) //备注
|
|
i++
|
|
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), v.Status.String())
|
|
i++
|
|
timeStr := v.CreatedAt.Local().Format("2006-01-02")
|
|
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), timeStr)
|
|
opName := ""
|
|
if len(v.OperateHistory) > 0 {
|
|
opName = v.OperateHistory[0].OperatorAccountName
|
|
}
|
|
i++
|
|
f.SetCellValue(sheetName, fmt.Sprintf("%s%d", string(i), k+2), opName)
|
|
}
|
|
f.SetActiveSheet(idx)
|
|
p, _ := os.Getwd()
|
|
fileName := path.Join(p, rPath)
|
|
if err := f.SaveAs(fileName); err != nil {
|
|
log.Error("SettlementInfo:export save file to disk failed",
|
|
log.Any("fileName", fileName),
|
|
log.E(err))
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func GetAppName(appList []appInfoMod.AppInfo, appId int32) string {
|
|
for _, app := range appList {
|
|
if app.AppId == appId {
|
|
return app.Name
|
|
}
|
|
}
|
|
return "未知app"
|
|
}
|