Compare commits

...

30 Commits

Author SHA1 Message Date
cjy
67d4cf0aaa feat: 增加按照subNum排序 2026-01-27 14:45:09 +08:00
jiaji.H
8c0f2eabcf Updata:修正计数bug 2026-01-27 13:28:51 +08:00
jiaji.H
0d1becb99b Updata:增加竞品数手动扩展字段 2026-01-26 13:08:21 +08:00
jiaji.H
f924c003eb Updata:修正扩展信息 2026-01-21 14:48:26 +08:00
cjy
c87f1defa9 移除dao层没用代码 2026-01-21 10:32:38 +08:00
cjy
e1702d7b46 把所有请求参数放到dto文件 2026-01-21 10:26:49 +08:00
cjy
4d8203bf8c 增加 dto 用来放请求参数 2026-01-21 10:11:36 +08:00
cjy
a03f14de50 删除没用controller层没用的注释 2026-01-20 17:48:23 +08:00
cjy
2a75c3eb78 移除没用的代码 2026-01-20 17:30:54 +08:00
jiaji.H
278606b5e7 Updata:修改季度发放余量逻辑 2026-01-20 15:05:19 +08:00
jiaji.H
cd261657fd Updata:增加竞品数异常发布统计 2026-01-19 13:20:03 +08:00
jiaji.H
54296dd70a Updata:修改手动扩展计费类型 2026-01-19 09:36:15 +08:00
jiaji.H
e170a086af Updata:修正sql 2026-01-16 11:42:01 +08:00
jiaji.H
cbe50785c3 Fix:修正sql 2026-01-15 13:19:24 +08:00
jiaji.H
bf4aa92713 fix:修正sql 2026-01-15 13:15:57 +08:00
jiaji.H
c4571c8bef Updata:更新sql 2026-01-15 13:11:11 +08:00
jiaji.H
a89e39abc5 Updata:修正sql 2026-01-15 11:47:17 +08:00
jiaji.H
508f714dae Updata:增加竞品数数据指标 2026-01-15 11:08:32 +08:00
jiaji.H
3abd57aa9a Updata:解决冲突 2026-01-14 13:33:23 +08:00
jiaji.H
94258657e7 Updata:解决冲突 2026-01-13 09:43:01 +08:00
jiaji.H
debb225291 Updata:解决冲突 2026-01-13 09:38:41 +08:00
jiaji.H
8536070eea Updata:增加每月季度发放竞品数函数 2026-01-12 15:07:23 +08:00
jiaji.H
bf41622eab Updata:更新创建每月数据的时间 2026-01-09 16:48:33 +08:00
jiaji.H
55d1554e13 Updata:修正查询sql 2026-01-05 13:46:25 +08:00
jiaji.H
b9c44fdc7e Updata:修正sql 2026-01-05 11:40:34 +08:00
jiaji.H
5ad9417042 Updata:导出补充竞品数字段 2026-01-05 11:23:55 +08:00
jiaji.H
65ffc2c43a Updata 2026-01-04 16:22:50 +08:00
jiaji.H
44c4a8627c Updata:修正数据分析发放值 2026-01-04 16:22:18 +08:00
jiaji.H
f40fc853de feat:列表布局增加竞品数字段 2026-01-04 14:32:08 +08:00
jiaji.H
2a75b9b6db Updata:套餐与余量增加竞品数字段与对应功能 2026-01-04 11:12:34 +08:00
14 changed files with 4279 additions and 5070 deletions

View File

@ -34,16 +34,6 @@ func main() {
panic(err)
}
// // 一次性执行任务余额同步(幂等):若已执行或存在数据则跳过
// if syncErr := dao.RunInitialTaskBalanceSync(); syncErr != nil {
// app.ModuleClients.Lg.Warn("initial task-balance sync failed", zap.Error(syncErr))
// }
// // 增量同步:每次服务重启时执行,同步套餐余额表中的新数据到任务余额表
// if incrementalSyncErr := dao.RunIncrementalTaskBalanceSync(); incrementalSyncErr != nil {
// app.ModuleClients.Lg.Warn("incremental task-balance sync failed", zap.Error(incrementalSyncErr))
// }
//l, err := net.Listen("tcp", ":8883")
//if err != nil {
// fmt.Printf("failed to listen: %v", err)

View File

@ -3,7 +3,7 @@ package controller
import (
"context"
"fmt"
"micro-bundle/internal/dao"
"micro-bundle/internal/dto"
"micro-bundle/internal/logic"
"micro-bundle/internal/model"
"micro-bundle/pb/bundle"
@ -13,57 +13,12 @@ import (
"go.uber.org/zap"
)
// GetPendingTaskList 查询待指派任务记录
func (b *BundleProvider) GetPendingTaskList(_ context.Context, req *bundle.TaskQueryRequest) (*bundle.TaskQueryResponse, error) {
// 转换请求参数
daoReq := &dao.TaskQueryRequest{
Keyword: req.Keyword,
Page: int(req.Page),
PageSize: int(req.PageSize),
SortBy: req.SortBy,
SortType: req.SortType,
}
// 调用logic层
tasks, total, err := logic.GetPendingTaskList(daoReq)
if err != nil {
return nil, err
}
// 转换响应数据
var taskInfos []*bundle.TaskManagementInfo
for _, task := range tasks {
taskInfo := &bundle.TaskManagementInfo{
SubNum: task.SubNum,
TelNum: task.TelNum,
ArtistName: task.ArtistName,
PendingVideoCount: int32(task.PendingVideoCount),
PendingPostCount: int32(task.PendingPostCount),
PendingDataCount: int32(task.PendingDataCount),
ProgressTaskCount: int32(task.ProgressTaskCount),
CompleteTaskCount: int32(task.CompleteTaskCount),
LastTaskAssignee: task.LastTaskAssignee,
TaskAssigneeNum: task.TaskAssigneeNum,
PendingVideoScriptCount: 0,
}
taskInfos = append(taskInfos, taskInfo)
}
return &bundle.TaskQueryResponse{
Tasks: taskInfos,
Total: total,
Page: req.Page,
PageSize: req.PageSize,
}, nil
}
// AssignTask 指派某位员工完成某个艺人的任务
func (b *BundleProvider) AssignTask(_ context.Context, req *bundle.TaskAssignRequest) (*bundle.CommonResponse, error) {
// 转换请求参数
daoReq := &dao.TaskAssignRequest{
daoReq := &dto.TaskAssignRequest{
SubNum: req.SubNum,
TelNum: req.TelNum,
ArtistName: req.ArtistName, // 添加缺失的ArtistName字段
ArtistName: req.ArtistName,
TaskAssignee: req.TaskAssignee,
TaskAssigneeNum: req.TaskAssigneeNum,
Operator: req.Operator,
@ -75,7 +30,6 @@ func (b *BundleProvider) AssignTask(_ context.Context, req *bundle.TaskAssignReq
AssignVideoScriptCount: int(req.AssignVideoScriptCount),
}
// 调用logic层
err := logic.AssignTask(daoReq)
if err != nil {
return &bundle.CommonResponse{
@ -88,35 +42,6 @@ func (b *BundleProvider) AssignTask(_ context.Context, req *bundle.TaskAssignReq
}, nil
}
// UpdatePendingCount 修改待发数量
func (b *BundleProvider) UpdatePendingCount(_ context.Context, req *bundle.UpdatePendingCountRequest) (*bundle.CommonResponse, error) {
// 转换请求参数
daoReq := &dao.UpdatePendingCountRequest{
SubNum: req.SubNum,
TelNum: req.TelNum,
ArtistName: req.ArtistName, // 添加缺失的ArtistName字段
PendingVideoCount: int(req.PendingVideoCount),
PendingPostCount: int(req.PendingPostCount),
PendingDataCount: int(req.PendingDataCount),
Operator: req.Operator,
OperatorNum: req.OperatorNum,
TaskAssignee: req.TaskAssignee,
TaskAssigneeNum: req.TaskAssigneeNum,
}
// 调用logic层
err := logic.UpdatePendingCount(daoReq)
if err != nil {
return &bundle.CommonResponse{
Msg: err.Error(),
}, err
}
return &bundle.CommonResponse{
Msg: "待发数量修改成功",
}, nil
}
// GetRecentAssignRecords 查询最近被指派记录
func (b *BundleProvider) GetRecentAssignRecords(_ context.Context, req *bundle.RecentAssignRecordsRequest) (*bundle.RecentAssignRecordsResponse, error) {
limit := int(req.Limit)
@ -142,8 +67,7 @@ func (b *BundleProvider) GetEmployeeAssignedTasks(_ context.Context, req *bundle
if int(req.Status) == 2 {
req.SortBy = "complete_time"
}
// 转换请求参数
daoReq := &dao.EmployeeTaskQueryRequest{
daoReq := &dto.EmployeeTaskQueryRequest{
TaskAssigneeNum: req.TaskAssigneeNum,
Keyword: req.Keyword,
Operator: req.Operator,
@ -158,13 +82,11 @@ func (b *BundleProvider) GetEmployeeAssignedTasks(_ context.Context, req *bundle
TaskBatch: req.TaskBatch,
}
// 调用logic层
records, total, err := logic.GetEmployeeAssignedTasks(daoReq)
if err != nil {
return nil, err
}
// 转换响应数据
var recordInfos []*bundle.TaskAssignRecordInfo
for _, record := range records {
recordInfo := convertToTaskAssignRecordInfo(record)
@ -181,7 +103,6 @@ func (b *BundleProvider) GetEmployeeAssignedTasks(_ context.Context, req *bundle
// CompleteTaskManually 员工手动点击完成任务
func (b *BundleProvider) CompleteTaskManually(_ context.Context, req *bundle.CompleteTaskManuallyRequest) (*bundle.CommonResponse, error) {
// 调用logic层
err := logic.CompleteTaskManually(req.AssignRecordsUUID, req.TaskAssigneeNum)
if err != nil {
return &bundle.CommonResponse{
@ -196,8 +117,7 @@ func (b *BundleProvider) CompleteTaskManually(_ context.Context, req *bundle.Com
// UpdateTaskProgress 员工实际完成任务状态更新
func (b *BundleProvider) UpdateTaskProgress(_ context.Context, req *bundle.UpdateTaskProgressRequest) (*bundle.CommonResponse, error) {
// 转换请求参数
daoReq := &dao.CompleteTaskRequest{
daoReq := &dto.CompleteTaskRequest{
AssignRecordsUUID: req.AssignRecordsUUID,
EmployeeName: req.EmployeeName,
EmployeeNum: req.EmployeeNum,
@ -206,7 +126,6 @@ func (b *BundleProvider) UpdateTaskProgress(_ context.Context, req *bundle.Updat
UUID: req.Uuid,
}
// 调用logic层
err := logic.UpdateTaskProgress(daoReq)
if err != nil {
return &bundle.CommonResponse{
@ -219,9 +138,8 @@ func (b *BundleProvider) UpdateTaskProgress(_ context.Context, req *bundle.Updat
}, nil
}
// TerminateTaskByUUID 根据指派记录UUID终止任务(实际状态置为已中止)
// TerminateTaskByUUID 根据指派记录UUID终止任务
func (b *BundleProvider) TerminateTaskByUUID(_ context.Context, req *bundle.TerminateTaskByUUIDRequest) (*bundle.ComResponse, error) {
// 调用logic层
err := logic.TerminateTaskByUUID(req.AssignRecordsUUID)
if err != nil {
return &bundle.ComResponse{Msg: err.Error()}, err
@ -274,8 +192,7 @@ func (b *BundleProvider) GetTaskAssignRecordsList(_ context.Context, req *bundle
if sortBy, ok := model.OrderByPending[req.SortBy]; ok {
req.SortBy = sortBy
}
// 转换请求参数
daoReq := &dao.TaskAssignRecordsQueryRequest{
daoReq := &dto.TaskAssignRecordsQueryRequest{
Keyword: req.Keyword,
TaskAssignee: req.TaskAssignee,
Operator: req.Operator,
@ -297,7 +214,6 @@ func (b *BundleProvider) GetTaskAssignRecordsList(_ context.Context, req *bundle
return nil, err
}
// 转换响应数据
var recordInfos []*bundle.TaskAssignRecordInfo
for _, record := range records {
recordInfo := convertToTaskAssignRecordInfo(record)
@ -314,7 +230,7 @@ func (b *BundleProvider) GetTaskAssignRecordsList(_ context.Context, req *bundle
}
// convertToTaskAssignRecordInfo 转换TaskAssignRecords模型为proto消息
func convertToTaskAssignRecordInfo(record *dao.TaskAssignRecordsResponse) *bundle.TaskAssignRecordInfo {
func convertToTaskAssignRecordInfo(record *dto.TaskAssignRecordsResponse) *bundle.TaskAssignRecordInfo {
var completeTime string
if record.CompleteTime != nil {
completeTime = record.CompleteTime.Format("2006-01-02 15:04:05")
@ -348,7 +264,7 @@ func convertToTaskAssignRecordInfo(record *dao.TaskAssignRecordsResponse) *bundl
}
// convertToTaskAssignRecordsSummary 转换汇总结构到proto
func convertToTaskAssignRecordsSummary(s *dao.TaskAssignRecordsSummary) *bundle.TaskAssignRecordsSummary {
func convertToTaskAssignRecordsSummary(s *dto.TaskAssignRecordsSummary) *bundle.TaskAssignRecordsSummary {
if s == nil {
return &bundle.TaskAssignRecordsSummary{}
}
@ -364,64 +280,20 @@ func convertToTaskAssignRecordsSummary(s *dao.TaskAssignRecordsSummary) *bundle.
}
}
// GetArtistBundleBalance 查询艺人的当前任务余额与待发数量(区分套餐/增值两类)
// 说明:
// - 查询条件优先使用艺人编号customerNum为空时使用手机号telNum
// - 返回同时包含“套餐类型”和“增值类型”的余额与待发数量,均按视频/图文/数据分析三类区分
func (b *BundleProvider) GetArtistBundleBalance(_ context.Context, req *bundle.ArtistBundleBalanceRequest) (*bundle.ArtistBundleBalanceResponse, error) {
// 参数校验:艺人编号与手机号不能同时为空
if req.CustomerNum == "" && req.TelNum == "" {
return nil, fmt.Errorf("艺人编号和手机号不能同时为空")
}
// 仅使用艺人编号进行查询与DAO层 GetRemainingPendingBySubNum 一致)
subNum := req.CustomerNum
if subNum == "" {
// 暂不支持通过手机号查询剩余待发数据
return nil, fmt.Errorf("暂不支持通过手机号查询剩余待发数据,请传入艺人编号")
}
// 调用逻辑层:仅查询剩余待发数量(区分套餐/增值)
resp, err := logic.GetArtistRemainingPending(subNum)
if err != nil {
return nil, err
}
// 组装proto响应非DAO返回字段统一置为0
return &bundle.ArtistBundleBalanceResponse{
// 套餐类型余额暂置0
BundleVideoBalance: 0,
BundleImageBalance: 0,
BundleDataAnalysisBalance: 0,
// 增值类型余额暂置0
IncreaseVideoBalance: 0,
IncreaseImageBalance: 0,
IncreaseDataAnalysisBalance: 0,
// 套餐类型待发数量
BundlePendingVideoCount: int32(resp.PendingBundleVideoCount),
BundlePendingImageCount: int32(resp.PendingBundleImageCount),
BundlePendingDataAnalysisCount: int32(resp.PendingBundleDataAnalysisCount),
// 增值类型待发数量
IncreasePendingVideoCount: int32(resp.PendingIncreaseVideoCount),
IncreasePendingImageCount: int32(resp.PendingIncreaseImageCount),
IncreasePendingDataAnalysisCount: int32(resp.PendingIncreaseDataAnalysisCount),
}, nil
}
// BatchAssignTask 批量指派(仅写入指派记录,不更新任务管理表)
// BatchAssignTask 批量指派
func (b *BundleProvider) BatchAssignTask(_ context.Context, req *bundle.BatchAssignTaskRequest) (*bundle.ComResponse, error) {
if req == nil || len(req.Items) == 0 {
return &bundle.ComResponse{Msg: "批量指派项不能为空"}, fmt.Errorf("批量指派项不能为空")
}
// 转换请求项为DAO层结构
var items []*dao.BatchAssignItem
items = make([]*dao.BatchAssignItem, 0, len(req.Items))
var items []*dto.BatchAssignItem
items = make([]*dto.BatchAssignItem, 0, len(req.Items))
for _, it := range req.Items {
if it == nil {
return &bundle.ComResponse{Msg: "存在空的指派项"}, fmt.Errorf("存在空的指派项")
}
items = append(items, &dao.BatchAssignItem{
items = append(items, &dto.BatchAssignItem{
SubNum: it.SubNum,
TelNum: it.TelNum,
ArtistName: it.ArtistName,
@ -451,8 +323,7 @@ func (b *BundleProvider) GetArtistUploadStatsList(_ context.Context, req *bundle
if sortBy, ok := model.OrderByDataAnalysis[req.SortBy]; ok {
req.SortBy = sortBy
}
// 构造 DAO 请求参数
daoReq := &dao.TaskQueryRequest{
daoReq := &dto.TaskQueryRequest{
Keyword: req.Keyword,
Page: int(req.Page),
PageSize: int(req.PageSize),
@ -462,13 +333,11 @@ func (b *BundleProvider) GetArtistUploadStatsList(_ context.Context, req *bundle
SubNums: req.SubNums,
}
// 调用逻辑层
items, total, err := logic.GetArtistUploadStatsList(daoReq)
if err != nil {
return nil, err
}
// 转换响应数据
formatTime := func(s string) string {
if s == "" {
return ""
@ -525,29 +394,6 @@ func (b *BundleProvider) GetArtistUploadStatsList(_ context.Context, req *bundle
}, nil
}
func (b *BundleProvider) GetPendingUploadBreakdown(_ context.Context, req *bundle.PendingUploadBreakdownRequest) (*bundle.PendingUploadBreakdownResponse, error) {
items, total, err := logic.GetPendingUploadBreakdownBySubNums(req.SubNums, int(req.Page), int(req.PageSize))
if err != nil {
return nil, err
}
respItems := make([]*bundle.PendingUploadBreakdownItem, 0, len(items))
for _, it := range items {
respItems = append(respItems, &bundle.PendingUploadBreakdownItem{
SubNum: it.SubNum,
TelNum: it.TelNum,
ArtistName: it.UserName,
PendingVideoScriptCount: int32(it.PendingVideoScriptCount),
PendingBundleVideoCount: int32(it.PendingBundleVideoCount),
PendingIncreaseVideoCount: int32(it.PendingIncreaseVideoCount),
PendingBundlePostCount: int32(it.PendingBundlePostCount),
PendingIncreasePostCount: int32(it.PendingIncreasePostCount),
PendingBundleDataCount: int32(it.PendingBundleDataCount),
PendingIncreaseDataCount: int32(it.PendingIncreaseDataCount),
})
}
return &bundle.PendingUploadBreakdownResponse{Items: respItems, Total: total, Page: req.Page, PageSize: req.PageSize}, nil
}
// GetPendingAssign 查询艺人可指派数量
func (b *BundleProvider) GetPendingAssign(_ context.Context, req *bundle.PendingAssignRequest) (*bundle.PendingAssignResponse, error) {
items, total, err := logic.GetPendingAssignBySubNums(req.SubNums, int(req.Page), int(req.PageSize))
@ -594,7 +440,7 @@ func (b *BundleProvider) AddHiddenTaskAssignee(_ context.Context, req *bundle.Ad
// CreateTaskWorkLog 创建任务日志记录
func (b *BundleProvider) CreateTaskWorkLog(_ context.Context, req *bundle.CreateTaskWorkLogRequest) (*bundle.CommonResponse, error) {
// 转换请求参数
daoReq := &dao.CreateTaskWorkLogRequest{
daoReq := &dto.CreateTaskWorkLogRequest{
AssignRecordsUUID: req.AssignRecordsUUID,
WorkUUID: req.WorkUUID,
Title: req.Title,

View File

@ -10,7 +10,6 @@ import (
"micro-bundle/pkg/utils"
"time"
"dubbo.apache.org/dubbo-go/v3/common/logger"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
@ -202,7 +201,7 @@ func AddBundleBalanceByUserId(data model.BundleBalanceUsePo) (usedType int, err
if oldData.ManualAccountConsumptionNumber < oldData.ManualAccountNumber { // 最后消耗手动扩展的
oldData.ManualAccountConsumptionNumber++
oldData.MonthlyManualAccountConsumptionNumber++
usedType = 3
usedType = 2
goto Over
}
return errors.New("账号数不足")
@ -210,7 +209,7 @@ func AddBundleBalanceByUserId(data model.BundleBalanceUsePo) (usedType int, err
if oldData.ManualAccountConsumptionNumber > 0 { // 最后消耗手动扩展的
oldData.ManualAccountConsumptionNumber--
oldData.MonthlyManualAccountConsumptionNumber--
usedType = 3
usedType = 2
goto Over
}
if oldData.IncreaseAccountConsumptionNumber > 0 {
@ -269,14 +268,13 @@ func AddBundleBalanceByUserId(data model.BundleBalanceUsePo) (usedType int, err
if oldData.ManualVideoConsumptionNumber < oldData.ManualVideoNumber { // 手动扩展类型充足
oldData.ManualVideoConsumptionNumber++
oldData.MonthlyManualVideoConsumptionNumber++ // 记录本月使用的手动扩展
usedType = 3
usedType = 2
goto Over
}
return errors.New("可用视频数不足")
}
if data.ImageNumber > 0 {
// 当月可使用的会过期的限制类型充足
// 当月可使用的会过期的限制类型充足
if oldData.MonthlyBundleLimitExpiredImageConsumptionNumber < oldData.MonthlyBundleLimitExpiredImageNumber { // 套餐内会过期的限制类型图片充足
oldData.MonthlyBundleLimitExpiredImageConsumptionNumber++
@ -327,7 +325,6 @@ func AddBundleBalanceByUserId(data model.BundleBalanceUsePo) (usedType int, err
}
if data.DataAnalysisNumber > 0 {
// 当月可使用的会过期的限制类型充足
// 当月可使用的会过期的限制类型充足
if oldData.MonthlyBundleLimitExpiredDataAnalysisConsumptionNumber < oldData.MonthlyBundleLimitExpiredDataAnalysisNumber { // 套餐内会过期的限制类型数据分析充足
oldData.MonthlyBundleLimitExpiredDataAnalysisConsumptionNumber++
@ -376,6 +373,52 @@ func AddBundleBalanceByUserId(data model.BundleBalanceUsePo) (usedType int, err
}
return errors.New("可用数据分析数不足")
}
if data.CompetitiveNumber > 0 {
// 当月可使用的会过期的限制类型充足
if oldData.MonthlyBundleLimitExpiredCompetitiveConsumptionNumber < oldData.MonthlyBundleLimitExpiredCompetitiveNumber { // 套餐内会过期的限制类型竞品数充足
oldData.MonthlyBundleLimitExpiredCompetitiveConsumptionNumber++
oldData.BundleLimitCompetitiveExpiredConsumptionNumber++
usedType = 1
goto Over
}
if oldData.MonthlyIncreaseLimitExpiredCompetitiveConsumptionNumber < oldData.MonthlyIncreaseLimitExpiredCompetitiveNumber { // 增值服务会过期的限制类型竞品数充足
oldData.MonthlyIncreaseLimitExpiredCompetitiveConsumptionNumber++
oldData.IncreaseLimitCompetitiveExpiredConsumptionNumber++
usedType = 2
goto Over
}
if oldData.MonthlyBundleLimitCompetitiveConsumptionNumber < oldData.MonthlyBundleLimitCompetitiveNumber { // 套餐内限制类型竞品数充足
oldData.MonthlyBundleLimitCompetitiveConsumptionNumber++
oldData.BundleLimitCompetitiveConsumptionNumber++
usedType = 1
goto Over
}
if oldData.MonthlyIncreaseLimitCompetitiveConsumptionNumber < oldData.MonthlyIncreaseLimitCompetitiveNumber { // 增值服务限制类型竞品数充足
oldData.MonthlyIncreaseLimitCompetitiveConsumptionNumber++
oldData.IncreaseLimitCompetitiveConsumptionNumber++
usedType = 2
goto Over
}
if oldData.BundleLimitCompetitiveNumber < oldData.BundleCompetitiveNumber { //套餐内非限制类型的竞品数充足
oldData.BundleLimitCompetitiveConsumptionNumber++
oldData.MonthlyBundleCompetitiveConsumptionNumber++
usedType = 1
goto Over
}
if oldData.IncreaseCompetitiveConsumptionNumber < oldData.IncreaseCompetitiveNumber { //增值服务非限制类型的竞品数充足
oldData.IncreaseCompetitiveConsumptionNumber++
oldData.MonthlyIncreaseCompetitiveConsumptionNumber++
usedType = 2
goto Over
}
if oldData.ManualCompetitiveConsumptionNumber < oldData.ManualCompetitiveNumber { // 手动扩展类型充足
oldData.ManualCompetitiveConsumptionNumber++
oldData.MonthlyManualCompetitiveConsumptionNumber++ // 记录本月使用的手动扩展
usedType = 2
goto Over
}
return errors.New("可用竞品数不足")
}
Over:
return tx.Model(&model.BundleBalance{}).Where("id = ?", oldData.ID).Save(&oldData).Error
})
@ -389,7 +432,7 @@ func CreateUsedRecord(tx *gorm.DB, data model.BundleUsedRecord) error {
func ExtendBundleBalanceByUserId(data model.BundleBalanceExtendPo) error {
err := app.ModuleClients.BundleDB.Transaction(func(tx *gorm.DB) error {
oldData := model.BundleBalance{}
if err := tx.Model(&model.BundleBalance{}).Where("user_id = ?", data.UserId).Where("deleted_at is null").Order("created_at desc").First(&oldData).Error; err != nil {
if err := tx.Model(&model.BundleBalance{}).Where("user_id = ?", data.UserId).Where("deleted_at is null").Order("month desc,created_at desc").First(&oldData).Error; err != nil {
return errors.New("用户还没有套餐信息")
}
oldData.ManualAccountNumber += data.AccountNumber
@ -400,6 +443,8 @@ func ExtendBundleBalanceByUserId(data model.BundleBalanceExtendPo) error {
oldData.MonthlyNewManualDataAnalysisNumber += data.DataAnalysisNumber
oldData.ManualVideoNumber += data.VideoNumber
oldData.MonthlyNewManualVideoNumber += data.VideoNumber
oldData.ManualCompetitiveNumber += data.CompetitiveNumber
oldData.MonthlyNewManualCompetitiveNumber += data.CompetitiveNumber
oldData.MonthlyNewDurationNumber += data.DurationNumber // 记录本月新增手动扩展时长
oldData.ExpiredAt = oldData.ExpiredAt.Add(time.Hour * 24 * time.Duration(data.DurationNumber))
return tx.Model(&model.BundleBalance{}).Where("id = ?", oldData.ID).Save(&oldData).Error
@ -408,14 +453,6 @@ func ExtendBundleBalanceByUserId(data model.BundleBalanceExtendPo) error {
if err != nil {
return err
}
// 套餐余额更新成功后,同步增量更新任务余额
// 如果任务余额更新失败,只记录错误日志,不影响主流程
if taskErr := ExtendTaskBalanceByUserId(data.UserId, data.ImageNumber, data.DataAnalysisNumber, data.VideoNumber, data.DurationNumber); taskErr != nil {
// 记录错误日志但不返回错误,避免影响主流程
logger.Errorf("任务余额同步失败用户ID: %d, 错误: %v", data.UserId, taskErr)
}
return nil
}
@ -423,13 +460,6 @@ func CreateBundleBalance(data model.BundleBalance) error {
if err := app.ModuleClients.BundleDB.Save(&data).Error; err != nil {
return err
}
// 同步任务余额(新建套餐余额时)
// 如果任务余额同步失败,只记录错误日志,不影响主流程
if taskErr := SyncTaskBalanceFromBundleBalance(data); taskErr != nil {
// 记录错误日志但不返回错误,避免影响主流程
logger.Errorf("新建套餐余额时任务余额同步失败,更新数据: %v, 错误 %v", data, taskErr)
}
return nil
}
@ -647,6 +677,26 @@ inner join (
return min(limit, remaining)
}
//计算每个季度发放的数目
qua := func(total, limit int) int {
var released int // 已释放的次数
if v.StartAt.Month() == now.Month() && v.StartAt.Year() == now.Year() {
} else {
released += limit
}
interval := max((now.Year()*12+int(now.Month())-(v.StartAt.Year()*12+int(v.StartAt.Month())))/3, 1) // 释放了多少个季度
released += max(interval-1, 0) * limit // 已经释放的数量
remaining := max(total-released, 0) // 还剩余多少次没有发放
if v.StartAt.Month() == now.Month() && v.StartAt.Year() == now.Year() { // 本月为第一个月后购买
return min(limit, remaining)
}
monthDiff := now.Year()*12 + int(now.Month()) - (v.StartAt.Year()*12 + int(v.StartAt.Month()))
if monthDiff%3 == 0 && v.ExpiredAt.Month() != now.Month() {
return min(limit, remaining)
}
return 0
}
// 当月过期的视频数
v.MonthlyInvalidBundleVideoNumber = v.MonthlyBundleLimitExpiredVideoNumber - v.MonthlyBundleLimitExpiredVideoConsumptionNumber
// 历史失效的套餐权益视频总数
@ -659,6 +709,10 @@ inner join (
v.MonthlyInvalidBundleDataAnalysisNumber = v.MonthlyBundleLimitExpiredDataAnalysisNumber - v.MonthlyBundleLimitExpiredDataAnalysisConsumptionNumber // 当月过期的数据分析数
// 历史失效的套餐权益数据分析总数
v.InvalidBundleDataAnalysisNumber += v.MonthlyInvalidBundleDataAnalysisNumber
// 当月过期的竞品数
v.MonthlyInvalidBundleCompetitiveNumber = v.MonthlyBundleLimitExpiredCompetitiveNumber - v.MonthlyBundleLimitExpiredCompetitiveConsumptionNumber
// 历史失效的套餐权益竞品数总数
v.InvalidBundleCompetitiveNumber += v.MonthlyInvalidBundleCompetitiveNumber
// 当月失效的增值权益视频总数
v.MonthlyInvalidIncreaseVideoNumber = v.MonthlyIncreaseLimitExpiredVideoNumber - v.MonthlyIncreaseLimitExpiredVideoConsumptionNumber
@ -672,6 +726,10 @@ inner join (
v.MonthlyInvalidIncreaseDataAnalysisNumber = v.MonthlyIncreaseLimitExpiredDataAnalysisNumber - v.MonthlyIncreaseLimitExpiredDataAnalysisConsumptionNumber
// 历史失效的增值权益数据分析总数
v.InvalidIncreaseDataAnalysisNumber += v.MonthlyInvalidIncreaseDataAnalysisNumber
// 当月失效的增值权益竞品数总数
v.MonthlyInvalidIncreaseCompetitiveNumber = v.MonthlyIncreaseLimitExpiredCompetitiveNumber - v.MonthlyIncreaseLimitExpiredCompetitiveConsumptionNumber
// 历史失效的增值权益竞品数总数
v.InvalidIncreaseCompetitiveNumber += v.MonthlyInvalidIncreaseCompetitiveNumber
// 当月套餐限制类会过期型视频可使用额度
v.MonthlyBundleLimitExpiredVideoNumber = cal(v.BundleLimitVideoExpiredNumber, v.MonthlyLimitVideoQuotaNumber)
@ -681,6 +739,7 @@ inner join (
v.MonthlyBundleLimitVideoNumber = v.MonthlyBundleLimitVideoNumber - v.MonthlyBundleLimitVideoConsumptionNumber + cal(v.BundleLimitVideoNumber, v.MonthlyLimitVideoQuotaNumber)
// 当月增值限制类型视频可使用额度
v.MonthlyIncreaseLimitVideoNumber = v.MonthlyIncreaseLimitVideoNumber - v.MonthlyIncreaseLimitVideoConsumptionNumber + cal(v.IncreaseLimitVideoNumber, v.MonthlyLimitVideoQuotaNumber)
// 当月套餐限制类会过期型图片可使用额度
v.MonthlyBundleLimitExpiredImageNumber = cal(v.BundleLimitImageExpiredNumber, v.MonthlyLimitImageQuotaNumber)
// 当月增值限制类会过期型图片可使用额度
@ -689,6 +748,7 @@ inner join (
v.MonthlyBundleLimitImageNumber = v.MonthlyBundleLimitImageNumber - v.MonthlyBundleLimitImageConsumptionNumber + cal(v.BundleLimitImageNumber, v.MonthlyLimitImageQuotaNumber)
// 当月增值限制类型图片可使用额度
v.MonthlyIncreaseLimitImageNumber = v.MonthlyIncreaseLimitImageNumber - v.MonthlyIncreaseLimitImageConsumptionNumber + cal(v.IncreaseLimitImageNumber, v.MonthlyLimitImageQuotaNumber)
// 当月套餐限制类会过期型数据分析可使用额度
v.MonthlyBundleLimitExpiredDataAnalysisNumber = cal(v.BundleLimitDataAnalysisExpiredNumber, v.MonthlyLimitDataAnalysisQuotaNumber)
// 当月增值限制类会过期型数据分析可使用额度
@ -698,7 +758,17 @@ inner join (
// 当月增值限制类型数据分析可使用额度
v.MonthlyIncreaseLimitDataAnalysisNumber = v.MonthlyIncreaseLimitDataAnalysisNumber - v.MonthlyIncreaseLimitDataAnalysisConsumptionNumber + cal(v.IncreaseLimitDataAnalysisNumber, v.MonthlyLimitDataAnalysisQuotaNumber)
// 当月套餐限制类会过期型竞品数可使用额度
v.MonthlyBundleLimitExpiredCompetitiveNumber = qua(v.BundleLimitCompetitiveExpiredNumber, v.MonthlyLimitCompetitiveQuotaNumber)
// 当月增值限制类会过期型竞品数可使用额度
v.MonthlyIncreaseLimitExpiredCompetitiveNumber = qua(v.IncreaseLimitCompetitiveExpiredNumber, v.MonthlyLimitCompetitiveQuotaNumber)
// 当月套餐限制类型竞品数可使用额度
v.MonthlyBundleLimitCompetitiveNumber = v.MonthlyBundleLimitCompetitiveNumber - v.MonthlyBundleLimitCompetitiveConsumptionNumber + qua(v.BundleLimitCompetitiveNumber, v.MonthlyLimitCompetitiveQuotaNumber)
// 当月增值限制类型竞品数可使用额度
v.MonthlyIncreaseLimitCompetitiveNumber = v.MonthlyIncreaseLimitCompetitiveNumber - v.MonthlyIncreaseLimitCompetitiveConsumptionNumber + qua(v.IncreaseLimitCompetitiveNumber, v.MonthlyLimitCompetitiveQuotaNumber)
// 重置单月消耗数量
//视频
v.MonthlyBundleVideoConsumptionNumber = 0
v.MonthlyIncreaseVideoConsumptionNumber = 0
v.MonthlyBundleLimitVideoConsumptionNumber = 0
@ -707,6 +777,7 @@ inner join (
v.MonthlyIncreaseLimitExpiredVideoConsumptionNumber = 0
v.MonthlyNewManualVideoNumber = 0
v.MonthlyManualVideoConsumptionNumber = 0
//图文
v.MonthlyBundleImageConsumptionNumber = 0
v.MonthlyIncreaseImageConsumptionNumber = 0
v.MonthlyBundleLimitImageConsumptionNumber = 0
@ -715,6 +786,7 @@ inner join (
v.MonthlyIncreaseLimitExpiredImageConsumptionNumber = 0
v.MonthlyNewManualImageNumber = 0
v.MonthlyManualImageConsumptionNumber = 0
//数据分析
v.MonthlyBundleDataAnalysisConsumptionNumber = 0
v.MonthlyIncreaseDataAnalysisConsumptionNumber = 0
v.MonthlyBundleLimitDataAnalysisConsumptionNumber = 0
@ -723,9 +795,20 @@ inner join (
v.MonthlyIncreaseLimitExpiredDataAnalysisConsumptionNumber = 0
v.MonthlyNewManualDataAnalysisNumber = 0
v.MonthlyManualDataAnalysisConsumptionNumber = 0
//竞品数
v.MonthlyBundleCompetitiveConsumptionNumber = 0
v.MonthlyIncreaseCompetitiveConsumptionNumber = 0
v.MonthlyBundleLimitCompetitiveConsumptionNumber = 0
v.MonthlyIncreaseLimitCompetitiveConsumptionNumber = 0
v.MonthlyBundleLimitExpiredCompetitiveConsumptionNumber = 0
v.MonthlyIncreaseLimitExpiredCompetitiveConsumptionNumber = 0
v.MonthlyNewManualCompetitiveNumber = 0
v.MonthlyManualCompetitiveConsumptionNumber = 0
v.Month = month
v.ID = 0
v.CreatedAt = time.Time{}
v.UpdatedAt = time.Time{}
app.ModuleClients.BundleDB.Create(&v)
}
return nil
@ -760,7 +843,7 @@ left join (
where r.deleted_at is null
group by
r.bundle_order_on
) r on r.bundle_order_on = bor.order_no
) r on r.bundle_order_on COLLATE utf8mb4_general_ci = bor.order_no COLLATE utf8mb4_general_ci
`).Scan(&data).Error
return
}

View File

@ -21,7 +21,7 @@ func MetricsBusiness(req *bundle.MetricsBusinessReq) (result *bundle.MetricsBusi
// ---------- 总金额统计 ----------
subQuery := app.ModuleClients.BundleDB.Model(&model.Reconciliation{}).
Select("TRUNCATE(COALESCE(SUM(CAST(handling_fee AS DECIMAL(12,3))), 0), 3) as total_fee_payment_amount").
Joins("LEFT JOIN bundle_order_records bor ON bor.order_no = bundle_order_on").
Joins("LEFT JOIN bundle_order_records bor ON bor.order_no COLLATE utf8mb4_general_ci = reconciliation.bundle_order_on COLLATE utf8mb4_general_ci").
Where("bor.deleted_at is null and bor.status=2")
// if req.BundleUuid != "" {
// subQuery = subQuery.Where("bor.bundle_uuid = ?", req.BundleUuid)
@ -524,7 +524,7 @@ func MetricsBusiness(req *bundle.MetricsBusinessReq) (result *bundle.MetricsBusi
Where("cwa.submit_time <= ?", req.End+" 23:59:59").
Where("cwa.deleted_at = 0")
if req.BundleUuid != "" {
query = query.Where("ccl.bundle_uuid = ?", req.BundleUuid)
query = query.Where("ccal.bundle_uuid = ?", req.BundleUuid)
}
err = query.Scan(&dataAnalysisCountInfo).Error
if err != nil {
@ -577,6 +577,78 @@ func MetricsBusiness(req *bundle.MetricsBusinessReq) (result *bundle.MetricsBusi
return
}
//==================竞品数====================
var newConpetitiveUsed int64
type ConpetitiveResult struct {
ConpetitiveUsed int64 `gorm:"column:conpetitive_used"`
UnUsedConpetitive int64 `gorm:"column:un_used_conpetitive"`
}
var conpetitiveCountInfo ConpetitiveResult
query = app.ModuleClients.BundleDB.Table("cast_competitive_report as ccr").
Select(`
SUM(CASE WHEN cccrl.uuid IS NOT NULL AND cccrl.deleted_at = 0 THEN 1 ELSE 0 END) AS conpetitive_used,
SUM(CASE WHEN cccrl.uuid IS NULL THEN 1 ELSE 0 END) AS un_used_conpetitive
`).
Joins("left join cast_cost_competitive_report_log cccrl on cccrl.report_uuid = ccr.uuid").
Where("ccr.submit_time >= ?", req.Start+" 00:00:00").
Where("ccr.submit_time <= ?", req.End+" 23:59:59").
Where("ccr.deleted_at = 0")
if req.BundleUuid != "" {
query = query.Where("cccrl.bundle_uuid = ?", req.BundleUuid)
}
err = query.Scan(&conpetitiveCountInfo).Error
if err != nil {
return
}
if req.BundleUuid == "" {
newConpetitiveUsed = conpetitiveCountInfo.ConpetitiveUsed + conpetitiveCountInfo.UnUsedConpetitive
} else {
query = app.ModuleClients.BundleDB.Table("cast_competitive_report as ccr").
Joins("left join bundle_balance bb ON CAST(bb.user_id AS CHAR) COLLATE utf8mb4_general_ci = ccr.artist_id COLLATE utf8mb4_general_ci AND ccr.submit_time >= bb.start_at AND ccr.submit_time <= bb.expired_at and bb.month = DATE_FORMAT(ccr.submit_time, '%Y-%m')").
Joins("left join bundle_order_records bor ON bor.uuid = bb.order_uuid").
Where("ccr.submit_time >= ?", req.Start+" 00:00:00").
Where("ccr.submit_time <= ?", req.End+" 23:59:59").
Where("ccr.deleted_at = 0 and bor.deleted_at IS NULL and bb.deleted_at IS NULL").
Where("bor.bundle_uuid = ?", req.BundleUuid)
err = query.Count(&newConpetitiveUsed).Error
if err != nil {
return
}
}
//竞品数套餐总已上传数
var totalUploadedBundleConpetitiveCount int64
queryBundleConpetitive := app.ModuleClients.BundleDB.Table("cast_competitive_report as ccr").
Joins("left join cast_cost_competitive_report_log cccrl on cccrl.report_uuid = ccr.uuid AND cccrl.deleted_at = 0").
Joins("left join cast_competitive_report_extra ccrpe on ccrpe.report_uuid = ccr.uuid AND ccrpe.deleted_at = 0").
Where("ccr.submit_time <= ?", req.End+" 23:59:59").
Where("ccrpe.cost_type = 1"). // 套餐类型
Where("ccr.deleted_at = 0")
if req.BundleUuid != "" {
queryBundleConpetitive = queryBundleConpetitive.Where("cccrl.bundle_uuid = ?", req.BundleUuid)
}
err = queryBundleConpetitive.Count(&totalUploadedBundleConpetitiveCount).Error
if err != nil {
return
}
//竞品数增值总已上传数
var totalUploadedIncreaseConpetitiveCount int64
queryIncreaseConpetitive := app.ModuleClients.BundleDB.Table("cast_competitive_report as ccr").
Joins("left join cast_cost_competitive_report_log cccrl on cccrl.report_uuid = ccr.uuid AND cccrl.deleted_at = 0").
Joins("left join cast_competitive_report_extra ccrpe on ccrpe.report_uuid = ccr.uuid AND ccrpe.deleted_at = 0").
Where("ccr.submit_time <= ?", req.End+" 23:59:59").
Where("ccrpe.cost_type in ?", []int{2, 3}). // 增值类型
Where("ccr.deleted_at = 0")
if req.BundleUuid != "" {
queryIncreaseConpetitive = queryIncreaseConpetitive.Where("cccrl.bundle_uuid = ?", req.BundleUuid)
}
err = queryIncreaseConpetitive.Count(&totalUploadedIncreaseConpetitiveCount).Error
if err != nil {
return
}
//获取手动增加套餐额度
manualIncreaseBalance, err := manualIncreaseBundleBalance(req.Start+" 00:00:00", req.End+" 23:59:59", req.BundleUuid)
if err != nil {
@ -595,6 +667,8 @@ func MetricsBusiness(req *bundle.MetricsBusinessReq) (result *bundle.MetricsBusi
result.NewUploadedImageCount = newImageUsed
//----------数据分析---------
result.NewUploadedDataAnalysisCount = newDataAnalysisUsed
//----------竞品数---------
result.NewUploadedCompetitiveCount = newConpetitiveUsed
// ==============数据分析暂时没数据============
@ -625,7 +699,9 @@ func MetricsBusiness(req *bundle.MetricsBusinessReq) (result *bundle.MetricsBusi
//数据分析
result.NewPendingUploadDataAnalysisCount = int64(BundleRelease.DataAnalysis) + int64(BundleAutoRelease.DataAnalysis) + int64(IncreaseRelease.DataAnalysis) + int64(IncreaseAutoRelease.DataAnalysis) + int64(manualIncreaseBalance.TotalDataAnalysisAdditional)
result.TotalPendingUploadDataAnalysisCount = int64(endBundleRelease.DataAnalysis) + int64(endIncreaseRelease.DataAnalysis) - int64(totalUploadedBundleDataAnalysisCount) - int64(totalUploadedIncreaseDataAnalysisCount) + int64(totalManualIncreaseBalance.TotalDataAnalysisAdditional)
//竞品数
result.NewPendingUploadCompetitiveCount = int64(BundleRelease.Competitive) + int64(BundleAutoRelease.Competitive) + int64(IncreaseRelease.Competitive) + int64(IncreaseAutoRelease.Competitive) + int64(manualIncreaseBalance.TotalCompetitiveAdditional)
result.TotalPendingUploadCompetitiveCount = int64(endBundleRelease.Competitive) + int64(endIncreaseRelease.Competitive) - int64(totalUploadedBundleConpetitiveCount) - int64(totalUploadedIncreaseConpetitiveCount) + int64(totalManualIncreaseBalance.TotalCompetitiveAdditional)
return
}
@ -642,6 +718,7 @@ type BalanceInfo struct {
Video int
Image int
DataAnalysis int
Competitive int
}
func MetricsOperatingCreate(req *bundle.MetricsOperatingCreateReq) (result *bundle.MetricsOperatingCreateResp, err error) {
@ -799,9 +876,41 @@ func MetricsOperatingCreate(req *bundle.MetricsOperatingCreateReq) (result *bund
Joins("left join cast_work_analysis_extra cwae on cwae.analysis_uuid = cwa.uuid AND cwae.deleted_at = 0").
Where("cwa.submit_time <= ?", req.End+" 23:59:59").
Where("cwae.cost_type in ?", []int{2, 3}). // 增值类型
Where("cwa.deleted_at = 0 and cwe.deleted_at = 0").
Where("cwa.deleted_at = 0 and cwae.deleted_at = 0").
Count(&totalUploadedIncreaseDataAnalysisCount)
//====================竞品数=======================
var newUploadedBundleCompetitiveCount int64
app.ModuleClients.BundleDB.Table("cast_competitive_report as ccr").
Where("ccr.submit_time >= ?", req.Start+" 00:00:00").
Where("ccr.submit_time <= ?", req.End+" 23:59:59").
Where("ccr.deleted_at = 0").
Count(&newUploadedBundleCompetitiveCount)
result.NewUploadedBundleCompetitiveCount = newUploadedBundleCompetitiveCount
var totalUploadedCompetitiveCount int64
app.ModuleClients.BundleDB.Table("cast_competitive_report as ccr").
Where("ccr.submit_time <= ?", req.End+" 23:59:59").
Where("ccr.deleted_at = 0").
Count(&totalUploadedCompetitiveCount)
result.TotalUploadedBundleCompetitiveCount = totalUploadedCompetitiveCount
var totalUploadedBundleCompetitiveCount int64
app.ModuleClients.BundleDB.Table("cast_competitive_report as ccr").
Joins("left join cast_competitive_report_extra ccre on ccre.report_uuid = ccr.uuid AND ccre.deleted_at = 0").
Where("ccr.submit_time <= ?", req.End+" 23:59:59").
Where("ccre.cost_type = 1"). // 套餐类型
Where("ccr.deleted_at = 0 and ccre.deleted_at = 0").
Count(&totalUploadedBundleCompetitiveCount)
var totalUploadedIncreaseCompetitiveCount int64
app.ModuleClients.BundleDB.Table("cast_competitive_report as ccr").
Joins("left join cast_competitive_report_extra ccre on ccre.report_uuid = ccr.uuid AND ccre.deleted_at = 0").
Where("ccr.submit_time <= ?", req.End+" 23:59:59").
Where("ccre.cost_type in ?", []int{2, 3}). // 增值类型
Where("ccr.deleted_at = 0 and ccre.deleted_at = 0").
Count(&totalUploadedIncreaseCompetitiveCount)
endMonth := timeParse(req.End + " 23:59:59").Format("2006-01")
startMonth := timeParse(req.Start + " 00:00:00").Format("2006-01")
@ -841,14 +950,18 @@ func MetricsOperatingCreate(req *bundle.MetricsOperatingCreateReq) (result *bund
result.NewPendingUploadIncreaseDataAnalysisCount = int64(IncreaseRelease.DataAnalysis) + int64(IncreaseAutoRelease.DataAnalysis) + int64(manualIncreaseBalance.TotalDataAnalysisAdditional)
result.TotalPendingUploadBundleDataAnalysisCount = int64(endBundleRelease.DataAnalysis) - int64(totalUploadedBundleDataAnalysisCount)
result.TotalPendingUploadIncreaseDataAnalysisCount = int64(endIncreaseRelease.DataAnalysis) - int64(totalUploadedIncreaseDataAnalysisCount) + int64(totalManualIncreaseBalance.TotalDataAnalysisAdditional)
//竞品数
result.NewPendingUploadBundleCompetitiveCount = int64(BundleRelease.Competitive) + int64(BundleAutoRelease.Competitive)
result.NewPendingUploadIncreaseCompetitiveCount = int64(IncreaseRelease.Competitive) + int64(IncreaseAutoRelease.Competitive) + int64(manualIncreaseBalance.TotalCompetitiveAdditional)
result.TotalPendingUploadBundleCompetitiveCount = int64(endBundleRelease.Competitive) - int64(totalUploadedBundleCompetitiveCount)
result.TotalPendingUploadIncreaseCompetitiveCount = int64(endIncreaseRelease.Competitive) - int64(totalUploadedIncreaseCompetitiveCount) + int64(totalManualIncreaseBalance.TotalCompetitiveAdditional)
return
}
// 手动扩套餐总数统计
func manualIncreaseBundleBalance(startTime string, endTime string, bundleUUID string) (data model.ManualIncreaseBundleBalance, err error) {
quary := app.ModuleClients.BundleDB.Model(&model.BundleExtensionRecords{}).
Select("SUM(account_additional) as total_account_additional, SUM(video_additional) as total_video_additional, SUM(images_additional) as total_image_additional, SUM(data_additional) as total_data_analysis_additional").
Select("SUM(account_additional) as total_account_additional, SUM(video_additional) as total_video_additional, SUM(images_additional) as total_image_additional, SUM(data_additional) as total_data_analysis_additional, SUM(competitive_additional) as total_competitive_additional").
Where("bundle_extension_records.type = 1").
Where("bundle_extension_records.deleted_at is null")
if startTime != "" {
@ -891,7 +1004,12 @@ func balanceInfoWithShop(startMonth string, endMonth string, startTime string, e
bb.bundle_data_analysis_number +
bb.monthly_bundle_limit_data_analysis_number +
bb.monthly_bundle_limit_expired_data_analysis_number
) AS data_analysis
) AS data_analysis,
(
bb.bundle_competitive_number +
bb.monthly_bundle_limit_competitive_number +
bb.monthly_bundle_limit_expired_competitive_number
) AS competitive
`). // 不限制类型的总数 + 限制不过期类型的当月可用 + 限制过期类型的当月可用 = 新增待上传数量
Joins("LEFT JOIN bundle_order_records bor ON bor.uuid = bb.order_uuid").
Joins(`INNER JOIN (
@ -920,7 +1038,8 @@ func balanceInfoWithShop(startMonth string, endMonth string, startTime string, e
SUM(statistic.account) AS account,
SUM(statistic.video) AS video,
SUM(statistic.image) AS image,
SUM(statistic.data_analysis) AS data_analysis
SUM(statistic.data_analysis) AS data_analysis,
SUM(statistic.competitive) AS competitive
`).
Scan(&data)
return
@ -946,7 +1065,12 @@ func IncreasealanceInfoWithShop(startMonth string, endMonth string, startTime st
bb.increase_data_analysis_number +
bb.monthly_increase_limit_data_analysis_number +
bb.monthly_increase_limit_expired_data_analysis_number
) AS data_analysis
) AS data_analysis,
(
bb.increase_competitive_number +
bb.monthly_increase_limit_competitive_number +
bb.monthly_increase_limit_expired_competitive_number
) AS competitive
`). // 不限制类型的总数 + 限制不过期类型的当月可用 + 限制过期类型的当月可用 = 新增待上传数量
Joins("LEFT JOIN bundle_order_records bor ON bor.uuid = bb.order_uuid").
Joins(`INNER JOIN (
@ -974,7 +1098,8 @@ func IncreasealanceInfoWithShop(startMonth string, endMonth string, startTime st
SUM(statistic.account) AS account,
SUM(statistic.video) AS video,
SUM(statistic.image) AS image,
SUM(statistic.data_analysis) AS data_analysis
SUM(statistic.data_analysis) AS data_analysis,
SUM(statistic.competitive) AS competitive
`).
Scan(&data)
return
@ -988,6 +1113,7 @@ func getBalanceInfo(month string, bundleUUID string) (data BalanceInfo) { // 获
data.Video = bundle.Video + increase.Video
data.Image = bundle.Image + increase.Image
data.DataAnalysis = bundle.DataAnalysis + increase.DataAnalysis
data.Competitive = bundle.Competitive + increase.Competitive
return
}
@ -1025,7 +1151,17 @@ func getBundleBalanceInfo(month string, bundleUUID string, endTime string) (data
bb.bundle_limit_data_analysis_expired_consumption_number -
bb.monthly_bundle_limit_expired_data_analysis_consumption_number -
bb.monthly_bundle_limit_data_analysis_consumption_number
) AS data_analysis
) AS data_analysis,
(
bb.bundle_competitive_number +
bb.monthly_bundle_limit_competitive_number +
bb.monthly_bundle_limit_expired_competitive_number +
bb.invalid_bundle_competitive_number +
bb.bundle_limit_competitive_consumption_number +
bb.bundle_limit_competitive_expired_consumption_number -
bb.monthly_bundle_limit_expired_competitive_consumption_number -
bb.monthly_bundle_limit_competitive_consumption_number
) AS competitive
`). // 不限制类型的总数 + 限制不过期类型的当月可用 + 限制过期类型的当月可用 + 限制不过期类型的总共已用 + 限制过期类型的总共已用 + 已过期的数量 = 总发放数
Joins("LEFT JOIN bundle_order_records bor ON bor.uuid = bb.order_uuid").
Where("bor.deleted_at is null and bor.status=2").
@ -1060,7 +1196,8 @@ func getBundleBalanceInfo(month string, bundleUUID string, endTime string) (data
SUM(statistic.account) AS account,
SUM(statistic.video) AS video,
SUM(statistic.image) AS image,
SUM(statistic.data_analysis) AS data_analysis
SUM(statistic.data_analysis) AS data_analysis,
SUM(statistic.competitive) AS competitive
`).
Scan(&data)
return
@ -1100,7 +1237,17 @@ func getIncreaseBalanceInfo(month string, bundleUUID string, endTime string) (da
bb.increase_limit_data_analysis_expired_consumption_number -
bb.monthly_increase_limit_expired_data_analysis_consumption_number -
bb.monthly_increase_limit_data_analysis_consumption_number
) AS data_analysis
) AS data_analysis,
(
bb.increase_competitive_number +
bb.monthly_increase_limit_competitive_number +
bb.monthly_increase_limit_expired_competitive_number +
bb.invalid_increase_competitive_number +
bb.increase_limit_competitive_consumption_number +
bb.increase_limit_competitive_expired_consumption_number -
bb.monthly_increase_limit_expired_competitive_consumption_number -
bb.monthly_increase_limit_competitive_consumption_number
) AS competitive
`). // 不限制类型的总数 + 限制不过期类型的当月可用 + 限制过期类型的当月可用 + 限制不过期类型的总共已用 + 限制过期类型的总共已用 + 已过期的数量 = 总发放数
Joins("LEFT JOIN bundle_order_records bor ON bor.uuid = bb.order_uuid").
Joins(`INNER JOIN (
@ -1135,7 +1282,8 @@ func getIncreaseBalanceInfo(month string, bundleUUID string, endTime string) (da
SUM(statistic.account) AS account,
SUM(statistic.video) AS video,
SUM(statistic.image) AS image,
SUM(statistic.data_analysis) AS data_analysis
SUM(statistic.data_analysis) AS data_analysis,
SUM(statistic.competitive) AS competitive
`).
Scan(&data)
return
@ -1222,7 +1370,32 @@ func MetricsOperatingStatus(req *bundle.MetricsOperatingStatusReq) (data *bundle
Where("ccal.operator_name = '系统自动确定'").
Where("cast_work_analysis.submit_time <= ?", req.Date+" 23:59:59").
Count(&data.AutoConfirmDataAnalysisCount)
//================竞品数==================
var competitiveStatistic = func(status int8) (i int64) {
app.ModuleClients.BundleDB.Table("cast_competitive_report as ccr").Where("ccr.work_report_status = ?", status).Where("deleted_at = 0 and submit_time <= ?", req.Date+" 23:59:59").Count(&i)
return
}
data.ReviewingCompetitiveCount = competitiveStatistic(2)
data.RejectCompetitiveCount = competitiveStatistic(3)
data.WaitConfirmCompetitiveCount = competitiveStatistic(4)
data.PendingUploadCompetitiveCount = competitiveStatistic(6)
data.UploadSuccessCompetitiveCount = competitiveStatistic(7)
data.UploadFailedCompetitiveCount = competitiveStatistic(5)
app.ModuleClients.BundleDB.Table("cast_competitive_report as ccr").
Joins("left join cast_cost_competitive_report_log cccrl on cccrl.report_uuid = ccr.uuid AND cccrl.deleted_at = 0").
Where("ccr.work_report_status in ?", []int{6, 7}).
Where("ccr.submit_time <= ?", req.Date+" 23:59:59").
Where("cccrl.operator_name != '系统自动确定'").
Where("ccr.deleted_at = 0").
Count(&data.ArtistConfirmCompetitiveCount)
app.ModuleClients.BundleDB.Table("cast_competitive_report as ccr").
Joins("left join cast_cost_competitive_report_log cccrl on cccrl.report_uuid = ccr.uuid AND cccrl.deleted_at = 0").
Where("ccr.work_report_status in ?", []int{6, 7}).
Where("ccr.submit_time <= ?", req.Date+" 23:59:59").
Where("cccrl.operator_name = '系统自动确定'").
Where("ccr.deleted_at = 0").
Count(&data.AutoConfirmCompetitiveCount)
return
}
@ -1393,11 +1566,11 @@ func MetricsVideoSubmitExport(req *bundle.MetricsVideoSubmitExportReq) (result *
if len(req.Month) == 0 {
query = app.ModuleClients.BundleDB.Table("cast_work AS cw").
Select(`cw.artist_name ,
cw.title as video_title,
tiktok.created_at as tiktok_upload_time,
dm.created_at as dm_upload_time,
ins.created_at as instagram_upload_time,
bor.customer_num as user_num`).
cw.title as video_title,
tiktok.created_at as tiktok_upload_time,
dm.created_at as dm_upload_time,
ins.created_at as instagram_upload_time,
bor.customer_num as user_num`).
Joins("left join (select created_at,work_uuid from cast_work_platform_info cwi where cwi.platform_id = 1) tiktok on tiktok.work_uuid = cw.uuid").
Joins("left join (select created_at,work_uuid from cast_work_platform_info cwi where cwi.platform_id = 4) dm on dm.work_uuid = cw.uuid").
Joins("left join (select created_at,work_uuid from cast_work_platform_info cwi where cwi.platform_id = 3) ins on ins.work_uuid = cw.uuid").
@ -1472,10 +1645,12 @@ func getRangeMonthlyRelease(startTime time.Time, endTime time.Time, bundleUuid s
bundleBalanceInfo.Video += b.Video
bundleBalanceInfo.Image += b.Image
bundleBalanceInfo.DataAnalysis += b.DataAnalysis
bundleBalanceInfo.Competitive += b.Competitive
// increaseBalanceInfo.Account += i.Account
increaseBalanceInfo.Video += i.Video
increaseBalanceInfo.Image += i.Image
increaseBalanceInfo.DataAnalysis += i.DataAnalysis
increaseBalanceInfo.Competitive += i.Competitive
}
return
}
@ -1519,6 +1694,8 @@ func getMonthlyRelease(month string, bundleUuid string) (bundleBalanceInfo Balan
increaseBalanceInfo.Image += (cal(item, item.IncreaseLimitImageNumber, item.MonthlyLimitImageQuotaNumber, t) + cal(item, item.IncreaseLimitImageExpiredNumber, item.MonthlyLimitImageQuotaNumber, t))
bundleBalanceInfo.DataAnalysis += (cal(item, item.BundleLimitDataAnalysisNumber, item.MonthlyLimitDataAnalysisQuotaNumber, t) + cal(item, item.BundleLimitDataAnalysisExpiredNumber, item.MonthlyLimitDataAnalysisQuotaNumber, t))
increaseBalanceInfo.DataAnalysis += (cal(item, item.IncreaseLimitDataAnalysisNumber, item.MonthlyLimitDataAnalysisQuotaNumber, t) + cal(item, item.IncreaseLimitDataAnalysisExpiredNumber, item.MonthlyLimitDataAnalysisQuotaNumber, t))
bundleBalanceInfo.Competitive += (qua(item, item.BundleLimitCompetitiveNumber, item.MonthlyLimitCompetitiveQuotaNumber, t) + qua(item, item.BundleLimitCompetitiveExpiredNumber, item.MonthlyLimitCompetitiveQuotaNumber, t))
increaseBalanceInfo.Competitive += (qua(item, item.IncreaseLimitCompetitiveNumber, item.MonthlyLimitCompetitiveQuotaNumber, t) + qua(item, item.IncreaseLimitCompetitiveExpiredNumber, item.MonthlyLimitCompetitiveQuotaNumber, t))
})
return
}
@ -1545,3 +1722,23 @@ func cal(data model.BundleBalance, total, limit int, date time.Time) int {
}
return min(limit, remaining)
}
// 计算每个季度发放的数目
func qua(data model.BundleBalance, total, limit int, date time.Time) int {
var released int // 已释放的次数
if data.StartAt.Month() == date.Month() && data.StartAt.Year() == date.Year() {
} else {
released += limit
}
interval := max((date.Year()*12+int(date.Month())-(data.StartAt.Year()*12+int(data.StartAt.Month())))/3, 1) // 释放了多少个季度
released += max(interval-1, 0) * limit // 已经释放的数量
remaining := max(total-released, 0) // 还剩余多少次没有发放
if data.StartAt.Month() == date.Month() && data.StartAt.Year() == date.Year() { // 本月为第一个月购买
return min(limit, remaining)
}
monthDiff := date.Year()*12 + int(date.Month()) - (data.StartAt.Year()*12 + int(data.StartAt.Month()))
if monthDiff%3 == 0 && data.ExpiredAt.Month() != date.Month() {
return min(limit, remaining)
}
return 0
}

View File

@ -1,570 +0,0 @@
package dao
import (
"errors"
"fmt"
"time"
"gorm.io/gorm"
"micro-bundle/internal/model"
"micro-bundle/pkg/app"
)
// RunInitialTaskBalanceSync 一次性将 BundleBalance 同步到 TaskBalance
// 仅在未执行过且任务余额表为空时运行;执行成功后写入标记,避免再次执行
func RunInitialTaskBalanceSync() error {
// 确保标记表存在
_ = app.ModuleClients.TaskBenchDB.AutoMigrate(&model.TaskSyncStatus{})
// 已执行标记检查
var markerCount int64
if err := app.ModuleClients.TaskBenchDB.Model(&model.TaskSyncStatus{}).
Where("sync_key = ?", model.InitialSyncKey).Count(&markerCount).Error; err != nil {
return err
}
if markerCount > 0 {
return nil
}
// 安全检查:如果任务余额表已存在数据,则不再执行,同样写入标记
var existing int64
if err := app.ModuleClients.TaskBenchDB.Model(&model.TaskBalance{}).Count(&existing).Error; err != nil {
return err
}
if existing > 0 {
_ = app.ModuleClients.TaskBenchDB.Create(&model.TaskSyncStatus{
SyncKey: model.InitialSyncKey,
ExecutedAt: time.Now(),
Remark: "skipped: task_balance already has data",
}).Error
return nil
}
// 获取当前有效(未过期且已支付)的艺人及其最新订单
validArtists, err := GetValidArtistList()
if err != nil {
return err
}
fmt.Println(validArtists)
if len(validArtists) == 0 {
// 不写入已执行标记,留待后续有数据时再次执行
fmt.Println("无数据更新")
return nil
}
// 构造待插入的 TaskBalance 列表
tasks := make([]model.TaskBalance, 0, len(validArtists))
for _, a := range validArtists {
// 根据 user_id + order_uuid 获取 BundleBalance 明细
var bb model.BundleBalance
if err := app.ModuleClients.BundleDB.Where("user_id = ? AND order_uuid = ?", a.UserID, a.OrderUUID).First(&bb).Error; err != nil {
// 若未查到则跳过该条
if err == gorm.ErrRecordNotFound {
continue
}
return err
}
subNum, telNum, err := fetchIdentityForBundle(&bb)
if err != nil {
// 无法获取身份信息则跳过该条
continue
}
tb := model.TaskBalance{
SubNum: subNum,
TelNum: telNum,
Month: bb.Month,
StartAt: bb.StartAt,
ExpiredAt: bb.ExpiredAt,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
copyBundleToTaskBalance(&tb, &bb)
tasks = append(tasks, tb)
}
// 原子写入:插入 TaskBalance + 插入标记(确保有插入才写标记)
tx := app.ModuleClients.TaskBenchDB.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
if len(tasks) == 0 {
// 没有可插入的数据,不写标记,直接返回
tx.Rollback()
return nil
}
if err := tx.Create(&tasks).Error; err != nil {
tx.Rollback()
return err
}
if err := tx.Create(&model.TaskSyncStatus{
SyncKey: model.InitialSyncKey,
ExecutedAt: time.Now(),
Remark: "initial sync executed",
}).Error; err != nil {
tx.Rollback()
return err
}
if err := tx.Commit().Error; err != nil {
return err
}
return nil
}
// RunIncrementalTaskBalanceSync 增量同步:每次服务重启时执行
// 将套餐余额表中的新数据同步到任务余额表,跳过已存在的记录
func RunIncrementalTaskBalanceSync() error {
// 获取当前有效(未过期且已支付)的艺人及其最新订单
validArtists, err := GetValidArtistList()
if err != nil {
return err
}
if len(validArtists) == 0 {
fmt.Println("增量同步:无有效艺人数据")
return nil
}
// 构造待插入的 TaskBalance 列表(仅包含不存在的记录)
tasks := make([]model.TaskBalance, 0)
skippedCount := 0
for _, a := range validArtists {
// 根据 user_id + order_uuid 获取 BundleBalance 明细
var bb model.BundleBalance
if err := app.ModuleClients.BundleDB.Where("user_id = ? AND order_uuid = ?", a.UserID, a.OrderUUID).First(&bb).Error; err != nil {
// 若未查到则跳过该条
if err == gorm.ErrRecordNotFound {
continue
}
return err
}
subNum, telNum, err := fetchIdentityForBundle(&bb)
if err != nil {
// 无法获取身份信息则跳过该条
continue
}
// 检查任务余额表中是否已存在该记录(按 sub_num + tel_num + month 唯一)
var existingCount int64
if err := app.ModuleClients.TaskBenchDB.Model(&model.TaskBalance{}).
Where("sub_num = ? AND tel_num = ? AND month = ?", subNum, telNum, bb.Month).
Count(&existingCount).Error; err != nil {
return err
}
if existingCount > 0 {
// 记录已存在,跳过
skippedCount++
continue
}
// 构造新的 TaskBalance 记录
tb := model.TaskBalance{
SubNum: subNum,
TelNum: telNum,
Month: bb.Month,
StartAt: bb.StartAt,
ExpiredAt: bb.ExpiredAt,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
copyBundleToTaskBalance(&tb, &bb)
tasks = append(tasks, tb)
}
fmt.Printf("增量同步:跳过已存在记录 %d 条,准备插入新记录 %d 条\n", skippedCount, len(tasks))
// 如果没有新记录需要插入,直接返回
if len(tasks) == 0 {
fmt.Println("增量同步:无新记录需要同步")
return nil
}
// 批量插入新记录
if err := app.ModuleClients.TaskBenchDB.Create(&tasks).Error; err != nil {
return err
}
fmt.Printf("增量同步:成功插入 %d 条新记录\n", len(tasks))
return nil
}
// 用户新买套餐时使用
// SyncTaskBalanceFromBundleBalance 增量/每月:根据单条 BundleBalance 同步或更新 TaskBalance按 sub_num + tel_num + month 唯一)
func SyncTaskBalanceFromBundleBalance(bb model.BundleBalance) error {
// 获取身份信息sub_num, tel_num
subNum, telNum, err := fetchIdentityForBundle(&bb)
if err != nil {
return err
}
// 组装 TaskBalance
tb := model.TaskBalance{
SubNum: subNum,
TelNum: telNum,
Month: bb.Month,
ExpiredAt: bb.ExpiredAt,
StartAt: bb.StartAt,
UpdatedAt: time.Now(),
CreatedAt: time.Now(),
}
copyBundleToTaskBalance(&tb, &bb)
// 查询是否已存在唯一sub_num + tel_num + month
var existing model.TaskBalance
err = app.ModuleClients.TaskBenchDB.
Where("sub_num = ? AND tel_num = ? AND month = ?", subNum, telNum, bb.Month).
First(&existing).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
// 不存在则创建
return app.ModuleClients.TaskBenchDB.Create(&tb).Error
}
return err
}
// 已存在则更新所有映射字段与时间
tb.ID = existing.ID
return app.ModuleClients.TaskBenchDB.Save(&tb).Error
}
// fetchIdentityForBundle 根据 BundleBalance 拿到 sub_num 与 tel_num
func fetchIdentityForBundle(bb *model.BundleBalance) (string, string, error) {
// tel_num 来自 micro-account.user
type userRow struct {
Tel string
}
var ur userRow
if err := app.ModuleClients.BundleDB.Table("`micro-account`.`user`").Unscoped().
Select("tel_num AS tel").Where("id = ?", bb.UserId).Limit(1).Scan(&ur).Error; err != nil {
return "", "", err
}
// customer_num 来自 bundle_order_records按 order_uuid
type orderRow struct {
Customer string
}
var or orderRow
if bb.OrderUUID == "" {
return "", "", errors.New("bundle order_uuid missing")
}
if err := app.ModuleClients.BundleDB.Table("bundle_order_records").
Select("customer_num AS customer").Where("uuid = ?", bb.OrderUUID).Limit(1).Scan(&or).Error; err != nil {
return "", "", err
}
return or.Customer, ur.Tel, nil
}
// UpdateTaskBalance 每月批量更新任务余额
// 类似于 UpdateBundleBalance 的逻辑,但针对任务余额表
func UpdateTaskBalanceEveryMon() error {
// 查询需要更新的任务余额记录(最新月份且未过期的记录)
tl := []model.TaskBalance{}
if err := app.ModuleClients.TaskBenchDB.Raw(`select
*
from
task_balance tb
inner join (
select
max(tb.month) as month ,
sub_num,
tel_num
from
task_balance tb
group by
tb.sub_num, tb.tel_num
) newest on
newest.month = tb.month
and (tb.sub_num = newest.sub_num OR tb.tel_num = newest.tel_num)
and tb.expired_at > now()`).Find(&tl).Error; err != nil {
return err
}
now := time.Now()
month := time.Now().Format("2006-01")
for _, v := range tl {
if v.Month == month {
continue
}
cal := func(total, limit int) int { // 计算本月发放的限制类型数量
var released int // 已释放的次数
if v.StartAt.Month() == now.Month() && v.StartAt.Year() == now.Year() {
} else if v.StartAt.Day() >= 16 { //第一个月释放的
released += (limit + 1) / 2
} else {
released += limit
}
interval := now.Year()*12 + int(now.Month()) - (v.StartAt.Year()*12 + int(v.StartAt.Month())) // 释放了多少个月
released += max(interval-1, 0) * limit // 后续月份释放的
remaining := max(total-released, 0) // 还剩余多少次没有发放
if v.StartAt.Month() == now.Month() && v.StartAt.Year() == now.Year() && v.StartAt.Day() >= 16 { // 本月为第一个月并且16号后购买只给一半向上取整
return min((limit+1)/2, remaining)
}
if v.ExpiredAt.Month() == now.Month() && v.ExpiredAt.Year() == now.Year() && v.ExpiredAt.Day() < 16 { // 本月为最后一个月并且16号前到期只给一半向下取整
return min(limit/2, remaining)
}
return min(limit, remaining)
}
v.MonthlyInvalidBundleVideoNumber = v.MonthlyBundleLimitExpiredVideoNumber - v.MonthlyBundleLimitExpiredVideoConsumptionNumber // 当月过期的视频数
v.InvalidBundleVideoNumber += v.MonthlyInvalidBundleVideoNumber
v.MonthlyInvalidBundleImageNumber = v.MonthlyBundleLimitExpiredImageNumber - v.MonthlyBundleLimitExpiredImageConsumptionNumber // 当月过期的图片数
v.InvalidBundleImageNumber += v.MonthlyInvalidBundleImageNumber
v.MonthlyInvalidBundleDataAnalysisNumber = v.MonthlyBundleLimitExpiredDataAnalysisNumber - v.MonthlyBundleLimitExpiredDataAnalysisConsumptionNumber // 当月过期的数据分析数
v.InvalidBundleDataAnalysisNumber += v.MonthlyInvalidBundleDataAnalysisNumber
// 当月可用的限制类型数等于本月方法的套餐和增值两种类型的总和
v.MonthlyBundleLimitExpiredVideoNumber = cal(v.BundleLimitVideoExpiredNumber, v.MonthlyLimitVideoQuotaNumber)
v.MonthlyIncreaseLimitExpiredVideoNumber = cal(v.IncreaseLimitVideoExpiredNumber, v.MonthlyLimitVideoQuotaNumber)
v.MonthlyBundleLimitVideoNumber = v.MonthlyBundleLimitVideoNumber - v.MonthlyBundleLimitVideoConsumptionNumber + cal(v.BundleLimitVideoNumber, v.MonthlyLimitVideoQuotaNumber)
v.MonthlyIncreaseLimitVideoNumber = v.MonthlyIncreaseLimitVideoNumber - v.MonthlyIncreaseLimitVideoConsumptionNumber + cal(v.IncreaseLimitVideoNumber, v.MonthlyLimitVideoQuotaNumber)
v.MonthlyBundleLimitExpiredImageNumber = cal(v.BundleLimitImageExpiredNumber, v.MonthlyLimitImageQuotaNumber)
v.MonthlyIncreaseLimitExpiredImageNumber = cal(v.IncreaseLimitImageExpiredNumber, v.MonthlyLimitImageQuotaNumber)
v.MonthlyBundleLimitImageNumber = v.MonthlyBundleLimitImageNumber - v.MonthlyBundleLimitImageConsumptionNumber + cal(v.BundleLimitImageNumber, v.MonthlyLimitImageQuotaNumber)
v.MonthlyIncreaseLimitImageNumber = v.MonthlyIncreaseLimitImageNumber - v.MonthlyIncreaseLimitImageConsumptionNumber + cal(v.IncreaseLimitImageNumber, v.MonthlyLimitImageQuotaNumber)
v.MonthlyBundleLimitExpiredDataAnalysisNumber = cal(v.BundleLimitDataAnalysisExpiredNumber, v.MonthlyLimitDataAnalysisQuotaNumber)
v.MonthlyIncreaseLimitExpiredDataAnalysisNumber = cal(v.IncreaseLimitDataAnalysisExpiredNumber, v.MonthlyLimitDataAnalysisQuotaNumber)
v.MonthlyBundleLimitDataAnalysisNumber = v.MonthlyBundleLimitDataAnalysisNumber - v.MonthlyBundleLimitDataAnalysisConsumptionNumber + cal(v.BundleLimitDataAnalysisNumber, v.MonthlyLimitDataAnalysisQuotaNumber)
v.MonthlyIncreaseLimitDataAnalysisNumber = v.MonthlyIncreaseLimitDataAnalysisNumber - v.MonthlyIncreaseLimitDataAnalysisConsumptionNumber + cal(v.IncreaseLimitDataAnalysisNumber, v.MonthlyLimitDataAnalysisQuotaNumber)
// 重置单月消耗数量
v.MonthlyBundleVideoConsumptionNumber = 0
v.MonthlyIncreaseVideoConsumptionNumber = 0
v.MonthlyBundleLimitVideoConsumptionNumber = 0
v.MonthlyIncreaseLimitVideoConsumptionNumber = 0
v.MonthlyBundleLimitExpiredVideoConsumptionNumber = 0
v.MonthlyIncreaseLimitExpiredVideoConsumptionNumber = 0
v.MonthlyNewManualVideoNumber = 0
v.MonthlyManualVideoConsumptionNumber = 0
v.MonthlyBundleImageConsumptionNumber = 0
v.MonthlyIncreaseImageConsumptionNumber = 0
v.MonthlyBundleLimitImageConsumptionNumber = 0
v.MonthlyIncreaseLimitImageConsumptionNumber = 0
v.MonthlyBundleLimitExpiredImageConsumptionNumber = 0
v.MonthlyIncreaseLimitExpiredImageConsumptionNumber = 0
v.MonthlyNewManualImageNumber = 0
v.MonthlyManualImageConsumptionNumber = 0
v.MonthlyBundleDataAnalysisConsumptionNumber = 0
v.MonthlyIncreaseDataAnalysisConsumptionNumber = 0
v.MonthlyBundleLimitDataAnalysisConsumptionNumber = 0
v.MonthlyIncreaseLimitDataAnalysisConsumptionNumber = 0
v.MonthlyBundleLimitExpiredDataAnalysisConsumptionNumber = 0
v.MonthlyIncreaseLimitExpiredDataAnalysisConsumptionNumber = 0
v.MonthlyNewManualDataAnalysisNumber = 0
v.MonthlyManualDataAnalysisConsumptionNumber = 0
// 设置新月份和重置ID
v.Month = month
v.ID = 0
// 创建新的任务余额记录
if err := app.ModuleClients.TaskBenchDB.Create(&v).Error; err != nil {
return err
}
}
return nil
}
// updateTaskBalanceExpiredAt 更新任务余额表的ExpiredAt字段
func updateTaskBalanceExpiredAt(subNum, telNum string, durationNumber int) error {
return app.ModuleClients.TaskBenchDB.Transaction(func(tx *gorm.DB) error {
var taskBalance model.TaskBalance
query := tx.Model(&model.TaskBalance{})
// 构建查询条件,优先使用 subNum
if subNum != "" {
query = query.Where("sub_num = ?", subNum)
} else {
query = query.Where("tel_num = ?", telNum)
}
// 查询当前有效的任务余额记录,按最新的开始时间排序
now := time.Now()
err := query.Where("start_at <= ? AND expired_at >= ?", now, now).Order("start_at DESC").First(&taskBalance).Error
if err != nil {
return err
}
// 增加过期时间
taskBalance.ExpiredAt = taskBalance.ExpiredAt.Add(time.Hour * 24 * time.Duration(durationNumber))
return tx.Save(&taskBalance).Error
})
}
// copyBundleToTaskBalance 将 BundleBalance 的图片、视频、数据分析相关字段映射到 TaskBalance
func copyBundleToTaskBalance(tb *model.TaskBalance, bb *model.BundleBalance) {
// ===== 视频类 =====
tb.BundleVideoNumber = bb.BundleVideoNumber
tb.IncreaseVideoNumber = bb.IncreaseVideoNumber
tb.BundleLimitVideoNumber = bb.BundleLimitVideoNumber
tb.IncreaseLimitVideoNumber = bb.IncreaseLimitVideoNumber
tb.BundleLimitVideoExpiredNumber = bb.BundleLimitVideoExpiredNumber
tb.IncreaseLimitVideoExpiredNumber = bb.IncreaseLimitVideoExpiredNumber
tb.MonthlyInvalidBundleVideoNumber = bb.MonthlyInvalidBundleVideoNumber
tb.InvalidBundleVideoNumber = bb.InvalidBundleVideoNumber
tb.MonthlyInvalidIncreaseVideoNumber = bb.MonthlyInvalidIncreaseVideoNumber
tb.InvalidIncreaseVideoNumber = bb.InvalidIncreaseVideoNumber
tb.BundleVideoConsumptionNumber = bb.BundleVideoConsumptionNumber
tb.IncreaseVideoConsumptionNumber = bb.IncreaseVideoConsumptionNumber
tb.BundleLimitVideoConsumptionNumber = bb.BundleLimitVideoConsumptionNumber
tb.IncreaseLimitVideoConsumptionNumber = bb.IncreaseLimitVideoConsumptionNumber
tb.BundleLimitVideoExpiredConsumptionNumber = bb.BundleLimitVideoExpiredConsumptionNumber
tb.IncreaseLimitVideoExpiredConsumptionNumber = bb.IncreaseLimitVideoExpiredConsumptionNumber
tb.MonthlyBundleVideoConsumptionNumber = bb.MonthlyBundleVideoConsumptionNumber
tb.MonthlyIncreaseVideoConsumptionNumber = bb.MonthlyIncreaseVideoConsumptionNumber
tb.MonthlyBundleLimitVideoNumber = bb.MonthlyBundleLimitVideoNumber
tb.MonthlyIncreaseLimitVideoNumber = bb.MonthlyIncreaseLimitVideoNumber
tb.MonthlyBundleLimitVideoConsumptionNumber = bb.MonthlyBundleLimitVideoConsumptionNumber
tb.MonthlyIncreaseLimitVideoConsumptionNumber = bb.MonthlyIncreaseLimitVideoConsumptionNumber
tb.MonthlyBundleLimitExpiredVideoNumber = bb.MonthlyBundleLimitExpiredVideoNumber
tb.MonthlyIncreaseLimitExpiredVideoNumber = bb.MonthlyIncreaseLimitExpiredVideoNumber
tb.MonthlyBundleLimitExpiredVideoConsumptionNumber = bb.MonthlyBundleLimitExpiredVideoConsumptionNumber
tb.MonthlyIncreaseLimitExpiredVideoConsumptionNumber = bb.MonthlyIncreaseLimitExpiredVideoConsumptionNumber
tb.MonthlyLimitVideoQuotaNumber = bb.MonthlyLimitVideoQuotaNumber
// 手动扩展(视频)
tb.ManualVideoNumber = bb.ManualVideoNumber
tb.ManualVideoConsumptionNumber = bb.ManualVideoConsumptionNumber
tb.MonthlyNewManualVideoNumber = bb.MonthlyNewManualVideoNumber
tb.MonthlyManualVideoConsumptionNumber = bb.MonthlyManualVideoConsumptionNumber
// ===== 图片类 =====
tb.BundleImageNumber = bb.BundleImageNumber
tb.IncreaseImageNumber = bb.IncreaseImageNumber
tb.BundleLimitImageNumber = bb.BundleLimitImageNumber
tb.IncreaseLimitImageNumber = bb.IncreaseLimitImageNumber
tb.BundleLimitImageExpiredNumber = bb.BundleLimitImageExpiredNumber
tb.IncreaseLimitImageExpiredNumber = bb.IncreaseLimitImageExpiredNumber
tb.MonthlyInvalidBundleImageNumber = bb.MonthlyInvalidBundleImageNumber
tb.InvalidBundleImageNumber = bb.InvalidBundleImageNumber
tb.MonthlyInvalidIncreaseImageNumber = bb.MonthlyInvalidIncreaseImageNumber
tb.InvalidIncreaseImageNumber = bb.InvalidIncreaseImageNumber
tb.BundleImageConsumptionNumber = bb.BundleImageConsumptionNumber
tb.IncreaseImageConsumptionNumber = bb.IncreaseImageConsumptionNumber
tb.BundleLimitImageConsumptionNumber = bb.BundleLimitImageConsumptionNumber
tb.IncreaseLimitImageConsumptionNumber = bb.IncreaseLimitImageConsumptionNumber
tb.BundleLimitImageExpiredConsumptionNumber = bb.BundleLimitImageExpiredConsumptionNumber
tb.IncreaseLimitImageExpiredConsumptionNumber = bb.IncreaseLimitImageExpiredConsumptionNumber
tb.MonthlyBundleImageConsumptionNumber = bb.MonthlyBundleImageConsumptionNumber
tb.MonthlyIncreaseImageConsumptionNumber = bb.MonthlyIncreaseImageConsumptionNumber
tb.MonthlyBundleLimitImageNumber = bb.MonthlyBundleLimitImageNumber
tb.MonthlyIncreaseLimitImageNumber = bb.MonthlyIncreaseLimitImageNumber
tb.MonthlyBundleLimitImageConsumptionNumber = bb.MonthlyBundleLimitImageConsumptionNumber
tb.MonthlyIncreaseLimitImageConsumptionNumber = bb.MonthlyIncreaseLimitImageConsumptionNumber
tb.MonthlyBundleLimitExpiredImageNumber = bb.MonthlyBundleLimitExpiredImageNumber
tb.MonthlyIncreaseLimitExpiredImageNumber = bb.MonthlyIncreaseLimitExpiredImageNumber
tb.MonthlyBundleLimitExpiredImageConsumptionNumber = bb.MonthlyBundleLimitExpiredImageConsumptionNumber
tb.MonthlyIncreaseLimitExpiredImageConsumptionNumber = bb.MonthlyIncreaseLimitExpiredImageConsumptionNumber
tb.MonthlyLimitImageQuotaNumber = bb.MonthlyLimitImageQuotaNumber
// 手动扩展(图片)
tb.ManualImageNumber = bb.ManualImageNumber
tb.ManualImageConsumptionNumber = bb.ManualImageConsumptionNumber
tb.MonthlyNewManualImageNumber = bb.MonthlyNewManualImageNumber
tb.MonthlyManualImageConsumptionNumber = bb.MonthlyManualImageConsumptionNumber
// ===== 数据分析类 =====
tb.BundleDataAnalysisNumber = bb.BundleDataAnalysisNumber
tb.IncreaseDataAnalysisNumber = bb.IncreaseDataAnalysisNumber
tb.BundleLimitDataAnalysisNumber = bb.BundleLimitDataAnalysisNumber
tb.IncreaseLimitDataAnalysisNumber = bb.IncreaseLimitDataAnalysisNumber
tb.BundleLimitDataAnalysisExpiredNumber = bb.BundleLimitDataAnalysisExpiredNumber
tb.IncreaseLimitDataAnalysisExpiredNumber = bb.IncreaseLimitDataAnalysisExpiredNumber
tb.MonthlyInvalidBundleDataAnalysisNumber = bb.MonthlyInvalidBundleDataAnalysisNumber
tb.InvalidBundleDataAnalysisNumber = bb.InvalidBundleDataAnalysisNumber
tb.MonthlyInvalidIncreaseDataAnalysisNumber = bb.MonthlyInvalidIncreaseDataAnalysisNumber
tb.InvalidIncreaseDataAnalysisNumber = bb.InvalidIncreaseDataAnalysisNumber
tb.BundleDataAnalysisConsumptionNumber = bb.BundleDataAnalysisConsumptionNumber
tb.IncreaseDataAnalysisConsumptionNumber = bb.IncreaseDataAnalysisConsumptionNumber
tb.BundleLimitDataAnalysisConsumptionNumber = bb.BundleLimitDataAnalysisConsumptionNumber
tb.IncreaseLimitDataAnalysisConsumptionNumber = bb.IncreaseLimitDataAnalysisConsumptionNumber
tb.BundleLimitDataAnalysisExpiredConsumptionNumber = bb.BundleLimitDataAnalysisExpiredConsumptionNumber
tb.IncreaseLimitDataAnalysisExpiredConsumptionNumber = bb.IncreaseLimitDataAnalysisExpiredConsumptionNumber
tb.MonthlyBundleDataAnalysisConsumptionNumber = bb.MonthlyBundleDataAnalysisConsumptionNumber
tb.MonthlyIncreaseDataAnalysisConsumptionNumber = bb.MonthlyIncreaseDataAnalysisConsumptionNumber
tb.MonthlyBundleLimitDataAnalysisNumber = bb.MonthlyBundleLimitDataAnalysisNumber
tb.MonthlyIncreaseLimitDataAnalysisNumber = bb.MonthlyIncreaseLimitDataAnalysisNumber
tb.MonthlyBundleLimitDataAnalysisConsumptionNumber = bb.MonthlyBundleLimitDataAnalysisConsumptionNumber
tb.MonthlyIncreaseLimitDataAnalysisConsumptionNumber = bb.MonthlyIncreaseLimitDataAnalysisConsumptionNumber
tb.MonthlyBundleLimitExpiredDataAnalysisNumber = bb.MonthlyBundleLimitExpiredDataAnalysisNumber
tb.MonthlyIncreaseLimitExpiredDataAnalysisNumber = bb.MonthlyIncreaseLimitExpiredDataAnalysisNumber
tb.MonthlyBundleLimitExpiredDataAnalysisConsumptionNumber = bb.MonthlyBundleLimitExpiredDataAnalysisConsumptionNumber
tb.MonthlyIncreaseLimitExpiredDataAnalysisConsumptionNumber = bb.MonthlyIncreaseLimitExpiredDataAnalysisConsumptionNumber
tb.MonthlyLimitDataAnalysisQuotaNumber = bb.MonthlyLimitDataAnalysisQuotaNumber
// 手动扩展(数据分析)
tb.ManualDataAnalysisNumber = bb.ManualDataAnalysisNumber
tb.ManualDataAnalysisConsumptionNumber = bb.ManualDataAnalysisConsumptionNumber
tb.MonthlyNewManualDataAnalysisNumber = bb.MonthlyNewManualDataAnalysisNumber
tb.MonthlyManualDataAnalysisConsumptionNumber = bb.MonthlyManualDataAnalysisConsumptionNumber
// 其他字段
tb.MonthlyNewDurationNumber = bb.MonthlyNewDurationNumber
tb.ExpansionPacksNumber = bb.ExpansionPacksNumber
}
func ExtendTaskBalanceByUserId(userId int, imageNumber int, dataAnalysisNumber int, videoNumber int, durationNumber int) error {
// 根据用户ID获取其最新套餐记录进而获取 sub_num、tel_num
oldBundle := model.BundleBalance{}
if err := app.ModuleClients.BundleDB.Model(&model.BundleBalance{}).
Where("user_id = ?", userId).
Order("created_at desc").
First(&oldBundle).Error; err != nil {
return errors.New("用户还没有套餐信息")
}
subNum, telNum, err := fetchIdentityForBundle(&oldBundle)
if err != nil {
return err
}
// 事务更新当前有效的任务余额记录(按 start_at 最近的一条)
err = app.ModuleClients.TaskBenchDB.Transaction(func(tx *gorm.DB) error {
var tb model.TaskBalance
now := time.Now()
query := tx.Model(&model.TaskBalance{}).
Where("sub_num = ? AND tel_num = ? AND start_at <= ? AND expired_at >= ?", subNum, telNum, now, now).
Order("start_at DESC")
if err := query.First(&tb).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return errors.New("用户还没有任务余额信息")
}
return err
}
// 手动扩展额度与当月新增记录
tb.ManualImageNumber += imageNumber
tb.MonthlyNewManualImageNumber += imageNumber
tb.ManualDataAnalysisNumber += dataAnalysisNumber
tb.MonthlyNewManualDataAnalysisNumber += dataAnalysisNumber
tb.ManualVideoNumber += videoNumber
tb.MonthlyNewManualVideoNumber += videoNumber
tb.MonthlyNewDurationNumber += durationNumber
return tx.Model(&model.TaskBalance{}).Where("id = ?", tb.ID).Save(&tb).Error
})
if err != nil {
return err
}
// 增加过期时间(按天)
if durationNumber > 0 {
if err := updateTaskBalanceExpiredAt(subNum, telNum, durationNumber); err != nil {
return err
}
}
return nil
}

File diff suppressed because it is too large Load Diff

231
internal/dto/task.go Normal file
View File

@ -0,0 +1,231 @@
package dto
import "time"
// TaskQueryRequest 查询待指派任务记录请求参数
type TaskQueryRequest struct {
Keyword string `json:"keyword"` // 艺人姓名、编号、手机号搜索关键词
LastTaskAssignee string `json:"lastTaskAssignee"` // 最近一次指派人筛选(模糊匹配)
Page int `json:"page"` // 页码
PageSize int `json:"pageSize"` // 每页数量
SortBy string `json:"sortBy"` // 排序字段(支持白名单字段)
SortType string `json:"sortType"` // 排序类型 asc/desc
SubNums []string `json:"subNums"` // 选中导出的艺人编号集合(可选)
}
// TaskAssignRequest 指派任务请求参数
type TaskAssignRequest struct {
SubNum string `json:"subNum"` // 艺人编号
TelNum string `json:"telNum"` // 艺人手机号
ArtistName string `json:"artistName"` // 艺人姓名
TaskAssignee string `json:"taskAssignee"` // 任务指派人
TaskAssigneeNum string `json:"taskAssigneeNum"` // 任务指派人账号
Operator string `json:"operator"` // 操作人
OperatorNum string `json:"operatorNum"` // 操作人账号
AssignVideoCount int `json:"assignVideoCount"` // 指派视频数
AssignPostCount int `json:"assignPostCount"` // 指派图文数
AssignDataCount int `json:"assignDataCount"` // 指派数据数
AssignVideoScriptCount int `json:"assignVideoScriptCount"` // 指派视频脚本数
TaskBatch string `json:"taskBatch"` // 任务批次
}
// BatchAssignItem 批量指派项(仅写入指派记录,不更新任务管理表)
type BatchAssignItem struct {
SubNum string `json:"subNum"` // 艺人编号
TelNum string `json:"telNum"` // 艺人手机号
ArtistName string `json:"artistName"` // 艺人姓名
TaskAssignee string `json:"taskAssignee"` // 任务指派人
TaskAssigneeNum string `json:"taskAssigneeNum"` // 任务指派人账号
Operator string `json:"operator"` // 操作人
OperatorNum string `json:"operatorNum"` // 操作人账号
AssignVideoCount int `json:"assignVideoCount"` // 指派视频数
AssignPostCount int `json:"assignPostCount"` // 指派图文数
AssignDataCount int `json:"assignDataCount"` // 指派数据数
AssignVideoScriptCount int `json:"assignVideoScriptCount"` // 指派视频脚本数
TaskBatch string `json:"taskBatch"` // 任务批次
}
// EmployeeTaskQueryRequest 员工任务查询请求参数
type EmployeeTaskQueryRequest struct {
TaskAssigneeNum string `json:"taskAssigneeNum"` // 被指派人账号
Keyword string `json:"keyword"` // 艺人姓名、编号、手机号搜索关键词
Operator string `json:"operator"` // 操作人
SortBy string `json:"sortBy"` // 排序字段
StartTime string `json:"startTime"` // 指派开始时间
EndTime string `json:"endTime"` // 指派结束时间
StartCompleteTime string `json:"startCompleteTime"` // 开始完成时间
EndCompleteTime string `json:"endCompleteTime"` // 结束完成时间
Status int `json:"status"` // 反馈完成状态
TaskBatch string `json:"taskBatch"` // 任务批次
Page int `json:"page"` // 页码
PageSize int `json:"pageSize"` // 每页数量
}
// CompleteTaskRequest 完成任务请求参数
type CompleteTaskRequest struct {
AssignRecordsUUID string `json:"assignRecordsUUID,omitempty"` // 指派记录UUID可选
EmployeeName string `json:"employeeName"` // 员工姓名(必要)
EmployeeNum string `json:"employeeNum"` // 员工工号(必要)
TaskType string `json:"taskType"` // 任务类型: video/post/data/script
UUID string `json:"uuid"` // 任务UUID
CompleteCount int `json:"completeCount"` // 完成数量
}
// TaskAssignRecordsQueryRequest 多条件查询操作记录表请求参数
type TaskAssignRecordsQueryRequest struct {
Keyword string `json:"keyword"` // 艺人姓名、编号、手机号搜索关键词
TaskAssignee string `json:"taskAssignee"` // 指派人姓名
Operator string `json:"operator"` // 操作人姓名
OperatorNum string `json:"operatorNum"` // 操作人手机号
StartTime string `json:"startTime"` // 操作开始时间
EndTime string `json:"endTime"` // 操作结束时间
Status int `json:"status"` // 反馈完成状态 0:全部 1:未完成 2:完成
ActualStatus int `json:"actualStatus"` // 实际完成状态 0:全部 1:未完成 2:完成
TaskBatch string `json:"taskBatch"` // 任务批次
Page int `json:"page"` // 页码
PageSize int `json:"pageSize"` // 每页数量
SortBy string `json:"sortBy"` // 排序字段(白名单)
SortType string `json:"sortType"` // 排序方式
}
// 任务记录表返回结构体
type TaskAssignRecordsResponse struct {
AssignRecordsUUID string `gorm:"column:assign_records_uuid;comment:指派记录UUID" json:"assignRecordsUUID"`
SubNum string `gorm:"column:sub_num;comment:艺人编号" json:"subNum"`
TelNum string `gorm:"column:tel_num;comment:艺人手机号" json:"telNum"`
ArtistName string `gorm:"column:artist_name;comment:艺人名称" json:"artistName"`
Status int `gorm:"column:status;comment:反馈完成状态 1:未完成 2:完成" json:"status"`
ActualStatus int `gorm:"column:actual_status;comment:实际完成状态 1:未完成 2:完成" json:"actualStatus"`
CompleteTime *time.Time `gorm:"column:complete_time;comment:反馈完成时间" json:"completeTime"`
OperatorType int `gorm:"column:operator_type;comment:操作类型 1:修改待发数量 2:指派" json:"operatorType"`
Operator string `gorm:"column:operator;comment:操作人" json:"operator"`
OperatorNum string `gorm:"column:operator_num;comment:操作人账号" json:"operatorNum"`
OperatorTime time.Time `gorm:"column:operator_time;comment:操作时间" json:"operatorTime"`
TaskAssignee string `gorm:"column:task_assignee;comment:任务指派人" json:"taskAssignee"`
TaskAssigneeNum string `gorm:"column:task_assignee_num;comment:任务指派人账号" json:"taskAssigneeNum"`
TaskBatch string `gorm:"column:task_batch;comment:任务批次" json:"taskBatch"`
PendingVideoCount int `gorm:"column:pending_video_count;comment:待发视频数量" json:"pendingVideoCount"`
PendingPostCount int `gorm:"column:pending_post_count;comment:待发图文数量" json:"pendingPostCount"`
PendingDataCount int `gorm:"column:pending_data_count;comment:待发数据数量" json:"pendingDataCount"`
PendingVideoScriptCount int `gorm:"column:pending_video_script_count;comment:待发视频脚本数量" json:"pendingVideoScriptCount"`
// 已完成统计
CompleteVideoScriptCount int `gorm:"column:complete_video_script_count;comment:已完成视频脚本数" json:"completeVideoScriptCount"`
CompleteVideoCount int `gorm:"column:complete_video_count;comment:已完成视频数" json:"completeVideoCount"`
CompletePostCount int `gorm:"column:complete_post_count;comment:已完成图文数" json:"completePostCount"`
CompleteDataCount int `gorm:"column:complete_data_count;comment:已完成数据数" json:"completeDataCount"`
UpdatedAt time.Time `gorm:"column:updated_at;comment:更新时间" json:"updatedAt"`
}
// 多条件查询后分页前的艺人数量汇总
type TaskAssignRecordsSummary struct {
TotalPendingVideoScriptCount int `json:"totalPendingVideoScriptCount"`
TotalPendingVideoCount int `json:"totalPendingVideoCount"`
TotalPendingPostCount int `json:"totalPendingPostCount"`
TotalPendingDataCount int `json:"totalPendingDataCount"`
TotalCompleteVideoScriptCount int `json:"totalCompleteVideoScriptCount"`
TotalCompleteVideoCount int `json:"totalCompleteVideoCount"`
TotalCompletePostCount int `json:"totalCompletePostCount"`
TotalCompleteDataCount int `json:"totalCompleteDataCount"`
}
// ValidArtistInfo 有效艺人信息结构体
type ValidArtistInfo struct {
UserID int `json:"userId"` // 用户ID
CustomerNum string `json:"customerNum"` // 艺人编号
UserName string `json:"userName"` // 艺人姓名
UserPhoneNumber string `json:"userPhoneNumber"` // 艺人手机号
BundleName string `json:"bundleName"` // 套餐名称
ExpirationTime string `json:"expirationTime"` // 过期时间
Status int `json:"status"` // 套餐状态
OrderUUID string `json:"orderUUID"` // 订单UUID
AccountNumber int `json:"accountNumber"` // 账号数量
AccountConsumptionNumber int `json:"accountConsumptionNumber"` // 账号消耗数量
VideoNumber int `json:"videoNumber"` // 视频数量
VideoConsumptionNumber int `json:"videoConsumptionNumber"` // 视频消耗数量
ImageNumber int `json:"imageNumber"` // 图片数量
ImageConsumptionNumber int `json:"imageConsumptionNumber"` // 图片消耗数量
DataAnalysisNumber int `json:"dataAnalysisNumber"` // 数据分析数量
DataAnalysisConsumptionNumber int `json:"dataAnalysisConsumptionNumber"` // 数据分析消耗数量
ExpansionPacksNumber int `json:"expansionPacksNumber"` // 扩展套餐数量
}
// ArtistUploadStatsItem 艺人上传与额度统计(视频/图文/数据分析)
type ArtistUploadStatsItem struct {
// 身份信息
SubNum string `json:"subNum" gorm:"column:customer_num"`
UserName string `json:"userName" gorm:"column:user_name"`
UserPhoneNumber string `json:"userPhoneNumber" gorm:"column:user_phone_number"`
StartAt string `json:"startAt" gorm:"column:start_at"`
ExpiredAt string `json:"expiredAt" gorm:"column:expired_at"`
// 视频
UploadedVideoCount int `json:"uploadedVideoCount" gorm:"column:uploaded_video_count"`
BundleVideoTotal int `json:"bundleVideoTotal" gorm:"column:bundle_video_total"`
IncreaseVideoTotal int `json:"increaseVideoTotal" gorm:"column:increase_video_total"`
ReleasedVideoTotal int `json:"releasedVideoTotal" gorm:"column:released_video_total"`
PendingVideoCount int `json:"pendingVideoCount" gorm:"column:pending_video_count"`
// 图文
UploadedPostCount int `json:"uploadedPostCount" gorm:"column:uploaded_post_count"`
BundlePostTotal int `json:"bundlePostTotal" gorm:"column:bundle_post_total"`
IncreasePostTotal int `json:"increasePostTotal" gorm:"column:increase_post_total"`
ReleasedPostTotal int `json:"releasedPostTotal" gorm:"column:released_post_total"`
PendingPostCount int `json:"pendingPostCount" gorm:"column:pending_post_count"`
// 数据分析
UploadedDataAnalysisCount int `json:"uploadedDataAnalysisCount" gorm:"column:uploaded_data_count"`
BundleDataAnalysisTotal int `json:"bundleDataAnalysisTotal" gorm:"column:bundle_data_total"`
IncreaseDataAnalysisTotal int `json:"increaseDataAnalysisTotal" gorm:"column:increase_data_total"`
ReleasedDataAnalysisTotal int `json:"releasedDataAnalysisTotal" gorm:"column:released_data_total"`
PendingDataAnalysisCount int `json:"pendingDataAnalysisCount" gorm:"column:pending_data_count"`
// 任务管理
LastTaskAssignee string `json:"lastTaskAssignee" gorm:"column:last_task_assignee"`
TaskAssigneeNum string `json:"taskAssigneeNum" gorm:"column:task_assignee_num"`
ProgressTaskCount int `json:"progressTaskCount" gorm:"column:progress_task_count"`
CompleteTaskCount int `json:"completeTaskCount" gorm:"column:complete_task_count"`
// 脚本
UploadedVideoScriptCount int `json:"uploadedVideoScriptCount" gorm:"column:uploaded_video_script_count"`
PendingVideoScriptCount int `json:"pendingVideoScriptCount" gorm:"column:pending_video_script_count"`
// 可指派数(可上传数 - 已指派且未完成的数量)
AllowVideoScriptCount int `json:"allowVideoScriptCount" gorm:"column:allow_video_script_count"`
AllowVideoCount int `json:"allowVideoCount" gorm:"column:allow_video_count"`
AllowPostCount int `json:"allowPostCount" gorm:"column:allow_post_count"`
AllowDataCount int `json:"allowDataCount" gorm:"column:allow_data_count"`
}
// ArtistPendingAssignItem 艺人可指派数量(可上传数 - 已指派且未完成的数量)
type ArtistPendingAssignItem struct {
SubNum string `json:"subNum" gorm:"column:customer_num"`
TelNum string `json:"telNum" gorm:"column:tel_num"`
UserName string `json:"userName" gorm:"column:user_name"`
AllowVideoScriptCount int `json:"allowVideoScriptCount" gorm:"column:allow_video_script_count"`
AllowVideoCount int `json:"allowVideoCount" gorm:"column:allow_video_count"`
AllowPostCount int `json:"allowPostCount" gorm:"column:allow_post_count"`
AllowDataCount int `json:"allowDataCount" gorm:"column:allow_data_count"`
}
// CreateTaskWorkLogRequest 创建任务日志请求参数
type CreateTaskWorkLogRequest struct {
AssignRecordsUUID string `json:"assignRecordsUUID"` // 任务指派记录UUID必填
WorkUUID string `json:"workUUID"` // 任务作品UUID必填
Title string `json:"title"` // 任务作品标题
ArtistUUID string `json:"artistUUID"` // 任务艺人UUID
SubNum string `json:"subNum"` // 任务用户编号(必填)
TelNum string `json:"telNum"` // 任务用户手机号(必填)
ArtistName string `json:"artistName"` // 任务艺人名称
// 操作信息
OperationType int `json:"operationType"` // 任务操作类型 1:加任务 2:消耗任务 3:完成任务 4:任务过期(必填)
TaskType int `json:"taskType"` // 任务类型 1:视频 2:图片 3:数据分析(必填)
TaskCount int `json:"taskCount"` // 任务数量(必填)
Remark string `json:"remark"` // 任务备注
// 操作人信息
OperatorName string `json:"operatorName"` // 任务操作人姓名
OperatorNum string `json:"operatorNum"` // 任务操作人账号
}

View File

@ -42,6 +42,7 @@ func BundleExtend(req *bundle.BundleExtendRequest) (*bundle.BundleExtendResponse
ImageNumber: int(req.ImagesAdditional),
DataAnalysisNumber: int(req.DataAdditional),
AccountNumber: int(req.AccountAdditional),
CompetitiveNumber: int(req.CompetitiveAdditional),
DurationNumber: durationNumber,
}); err != nil {
return nil, errors.New("用户没有余量信息")
@ -147,6 +148,21 @@ func GetBundleBalanceList(req *bundle.GetBundleBalanceListReq) (*bundle.GetBundl
MonthlyIncreaseDataAnalysisNumber: int32(m.IncreaseDataAnalysisNumber) - int32(m.IncreaseDataAnalysisConsumptionNumber) + int32(m.MonthlyIncreaseLimitDataAnalysisNumber) + int32(m.MonthlyIncreaseLimitExpiredDataAnalysisNumber),
MonthlyInvalidBundleDataAnalysisNumber: int32(m.MonthlyInvalidBundleDataAnalysisNumber),
MonthlyInvalidIncreaseDataAnalysisNumber: int32(m.MonthlyInvalidIncreaseDataAnalysisNumber),
//竞品数
BundleCompetitiveNumber: int32(m.BundleCompetitiveNumber) + int32(m.BundleLimitCompetitiveNumber) + int32(m.BundleLimitCompetitiveExpiredNumber),
IncreaseCompetitiveNumber: int32(m.IncreaseCompetitiveNumber) + int32(m.IncreaseLimitCompetitiveNumber) + int32(m.IncreaseLimitCompetitiveExpiredNumber),
BundleCompetitiveConsumptionNumber: int32(m.BundleCompetitiveConsumptionNumber) + int32(m.BundleLimitCompetitiveConsumptionNumber) + int32(m.BundleLimitCompetitiveExpiredConsumptionNumber),
IncreaseCompetitiveConsumptionNumber: int32(m.IncreaseCompetitiveConsumptionNumber) + int32(m.IncreaseLimitCompetitiveConsumptionNumber) + int32(m.IncreaseLimitCompetitiveExpiredConsumptionNumber),
InvalidBundleCompetitiveNumber: int32(m.InvalidBundleCompetitiveNumber),
InvalidIncreaseCompetitiveNumber: int32(m.InvalidIncreaseCompetitiveNumber),
MonthlyNewBundleCompetitiveNumber: int32(cal(m.BundleBalance, m.BundleLimitCompetitiveNumber, m.MonthlyLimitCompetitiveQuotaNumber, date) + cal(m.BundleBalance, m.BundleLimitCompetitiveExpiredNumber, m.MonthlyLimitCompetitiveQuotaNumber, date)),
MonthlyNewIncreaseCompetitiveNumber: int32(cal(m.BundleBalance, m.IncreaseLimitCompetitiveNumber, m.MonthlyLimitCompetitiveQuotaNumber, date) + cal(m.BundleBalance, m.IncreaseLimitCompetitiveExpiredNumber, m.MonthlyLimitCompetitiveQuotaNumber, date)),
MonthBundleCompetitiveConsumptionNumber: int32(m.MonthlyBundleCompetitiveConsumptionNumber) + int32(m.MonthlyBundleLimitCompetitiveConsumptionNumber) + int32(m.MonthlyBundleLimitExpiredCompetitiveConsumptionNumber),
MonthIncreaseCompetitiveConsumptionNumber: int32(m.MonthlyIncreaseCompetitiveConsumptionNumber) + int32(m.MonthlyIncreaseLimitCompetitiveConsumptionNumber) + int32(m.MonthlyIncreaseLimitExpiredCompetitiveConsumptionNumber),
MonthlyBundleCompetitiveNumber: int32(m.BundleCompetitiveNumber) - int32(m.BundleCompetitiveConsumptionNumber) + int32(m.MonthlyBundleLimitCompetitiveNumber) + int32(m.MonthlyBundleLimitExpiredCompetitiveNumber) - int32(m.MonthlyBundleLimitCompetitiveConsumptionNumber),
MonthlyIncreaseCompetitiveNumber: int32(m.IncreaseCompetitiveNumber) - int32(m.IncreaseCompetitiveConsumptionNumber) + int32(m.MonthlyIncreaseLimitCompetitiveNumber) + int32(m.MonthlyIncreaseLimitExpiredCompetitiveNumber),
MonthlyInvalidBundleCompetitiveNumber: int32(m.MonthlyInvalidBundleCompetitiveNumber),
MonthlyInvalidIncreaseCompetitiveNumber: int32(m.MonthlyInvalidIncreaseCompetitiveNumber),
// 手动扩展类
MonthlyNewManualAccountNumber: int32(m.MonthlyNewAccountNumber),
MonthlyNewManualVideoNumber: int32(m.MonthlyNewManualVideoNumber),
@ -174,6 +190,8 @@ func GetBundleBalanceList(req *bundle.GetBundleBalanceListReq) (*bundle.GetBundl
result.MonthlyNewIncreaseImageNumber += int32(m.IncreaseImageNumber)
result.MonthlyNewBundleDataAnalysisNumber += int32(m.BundleDataAnalysisNumber)
result.MonthlyNewIncreaseDataAnalysisNumber += int32(m.IncreaseDataAnalysisNumber)
result.MonthlyNewBundleCompetitiveNumber += int32(m.BundleCompetitiveNumber)
result.MonthlyNewIncreaseCompetitiveNumber += int32(m.IncreaseCompetitiveNumber)
}
if result.Activate != 2 { // 除了等于0的情况
result.Activate = 1
@ -230,6 +248,11 @@ func GetBundleBalanceByUserId(req *bundle.GetBundleBalanceByUserIdReq) (*bundle.
DataAnalysisExtendConsumptionNumber: int32(data.MonthlyBundleLimitDataAnalysisConsumptionNumber) + int32(data.MonthlyIncreaseLimitDataAnalysisConsumptionNumber) + int32(data.MonthlyBundleLimitExpiredDataAnalysisConsumptionNumber) + int32(data.MonthlyIncreaseLimitExpiredDataAnalysisConsumptionNumber) + int32(data.ManualDataAnalysisConsumptionNumber) + int32(data.IncreaseDataAnalysisConsumptionNumber) + int32(data.BundleDataAnalysisConsumptionNumber),
DataAnalysisAdditional: int32(data.ManualDataAnalysisNumber),
DataAnalysisConsumptionNumber: int32(data.BundleDataAnalysisConsumptionNumber) + int32(data.BundleLimitDataAnalysisConsumptionNumber) + int32(data.BundleLimitDataAnalysisExpiredConsumptionNumber) + int32(data.IncreaseDataAnalysisConsumptionNumber) + int32(data.IncreaseLimitDataAnalysisConsumptionNumber) + int32(data.IncreaseLimitDataAnalysisExpiredConsumptionNumber) + int32(data.ManualDataAnalysisConsumptionNumber),
CompetitiveNumber: int32(data.BundleCompetitiveNumber) + int32(data.BundleLimitCompetitiveNumber) + int32(data.BundleLimitCompetitiveExpiredNumber) + int32(data.IncreaseCompetitiveNumber) + int32(data.IncreaseLimitCompetitiveNumber) + int32(data.IncreaseLimitCompetitiveExpiredNumber) + int32(data.ManualCompetitiveNumber),
CompetitiveExtendNumber: int32(data.MonthlyBundleLimitCompetitiveNumber) + int32(data.MonthlyIncreaseLimitCompetitiveNumber) + int32(data.MonthlyBundleLimitExpiredCompetitiveNumber) + int32(data.MonthlyIncreaseLimitExpiredCompetitiveNumber) + int32(data.ManualCompetitiveNumber) + int32(data.IncreaseCompetitiveNumber) + int32(data.BundleCompetitiveNumber),
CompetitiveExtendConsumptionNumber: int32(data.MonthlyBundleLimitCompetitiveConsumptionNumber) + int32(data.MonthlyIncreaseLimitCompetitiveConsumptionNumber) + int32(data.MonthlyBundleLimitExpiredCompetitiveConsumptionNumber) + int32(data.MonthlyIncreaseLimitExpiredCompetitiveConsumptionNumber) + int32(data.ManualCompetitiveConsumptionNumber) + int32(data.IncreaseCompetitiveConsumptionNumber) + int32(data.BundleCompetitiveConsumptionNumber),
CompetitiveAdditional: int32(data.ManualCompetitiveNumber),
CompetitiveConsumptionNumber: int32(data.BundleCompetitiveConsumptionNumber) + int32(data.BundleLimitCompetitiveConsumptionNumber) + int32(data.BundleLimitCompetitiveExpiredConsumptionNumber) + int32(data.IncreaseCompetitiveConsumptionNumber) + int32(data.IncreaseLimitCompetitiveConsumptionNumber) + int32(data.IncreaseLimitCompetitiveExpiredConsumptionNumber) + int32(data.ManualCompetitiveConsumptionNumber),
}
return result, nil
}
@ -241,6 +264,7 @@ func AddBundleBalance(req *bundle.AddBundleBalanceReq) (*bundle.AddBundleBalance
ImageNumber: int(req.ImageConsumptionNumber),
VideoNumber: int(req.VideoConsumptionNumber),
DataAnalysisNumber: int(req.DataAnalysisConsumptionNumber),
CompetitiveNumber: int(req.CompetitiveConsumptionNumber),
}
uesdType, err := dao.AddBundleBalanceByUserId(data)
return &bundle.AddBundleBalanceResp{
@ -359,7 +383,6 @@ func CreateBundleBalance(req *bundle.CreateBundleBalanceReq) (*bundle.CreateBund
data.IncreaseLimitDataAnalysisNumber += int(v.Num)
}
} else {
data.IncreaseDataAnalysisNumber += int(v.Num)
}
}
@ -378,6 +401,30 @@ func CreateBundleBalance(req *bundle.CreateBundleBalanceReq) (*bundle.CreateBund
case "年":
data.ExpiredAt = data.ExpiredAt.Add(time.Hour * 24 * 365 * time.Duration(v.Num))
}
case 6: // 竞品数
if v.EquityType == 1 { // 套餐权益
if v.QuotaType == 2 { // 限制额度
data.MonthlyLimitCompetitiveQuotaNumber = int(v.QuotaValue)
if v.IsExpired { // 会过期的限制类型
data.BundleLimitCompetitiveExpiredNumber += int(v.Num)
} else {
data.BundleLimitCompetitiveNumber += int(v.Num)
}
} else {
data.BundleCompetitiveNumber += int(v.Num)
}
} else {
if v.QuotaType == 2 { // 限制额度
data.MonthlyLimitCompetitiveQuotaNumber = int(v.QuotaValue)
if v.IsExpired { // 会过期的限制类型
data.IncreaseLimitCompetitiveExpiredNumber += int(v.Num)
} else {
data.IncreaseLimitCompetitiveNumber += int(v.Num)
}
} else {
data.IncreaseCompetitiveNumber += int(v.Num)
}
}
}
}
now := time.Now()
@ -396,6 +443,11 @@ func CreateBundleBalance(req *bundle.CreateBundleBalanceReq) (*bundle.CreateBund
data.MonthlyBundleLimitDataAnalysisNumber = cal(data, data.BundleLimitDataAnalysisNumber, data.MonthlyLimitDataAnalysisQuotaNumber, now)
data.MonthlyIncreaseLimitDataAnalysisNumber = cal(data, data.IncreaseLimitDataAnalysisNumber, data.MonthlyLimitDataAnalysisQuotaNumber, now)
data.MonthlyBundleLimitExpiredCompetitiveNumber = cal(data, data.BundleLimitCompetitiveExpiredNumber, data.MonthlyLimitCompetitiveQuotaNumber, now)
data.MonthlyIncreaseLimitExpiredCompetitiveNumber = cal(data, data.IncreaseLimitCompetitiveExpiredNumber, data.MonthlyLimitCompetitiveQuotaNumber, now)
data.MonthlyBundleLimitCompetitiveNumber = cal(data, data.BundleLimitCompetitiveNumber, data.MonthlyLimitCompetitiveQuotaNumber, now)
data.MonthlyIncreaseLimitCompetitiveNumber = cal(data, data.IncreaseLimitCompetitiveNumber, data.MonthlyLimitCompetitiveQuotaNumber, now)
err = dao.CreateBundleBalance(data)
if err != nil {
logger.Error(err)
@ -532,6 +584,8 @@ func BundleBalanceExport(req *bundle.BundleBalanceExportReq) (*bundle.BundleBala
item.MonthlyIncreaseImageConsumptionNumber = v.MonthIncreaseImageConsumptionNumber
item.MonthlyBundleDataAnalysisConsumptionNumber = v.MonthBundleDataAnalysisConsumptionNumber
item.MonthlyIncreaseDataAnalysisConsumptionNumber = v.MonthIncreaseDataAnalysisConsumptionNumber
item.MonthlyBundleCompetitiveConsumptionNumber = v.MonthBundleCompetitiveConsumptionNumber
item.MonthlyIncreaseCompetitiveConsumptionNumber = v.MonthIncreaseCompetitiveConsumptionNumber
item.Currency = "USD"
f, _ := strconv.ParseFloat(prefixItem.Fee, 64)
item.Fee = fmt.Sprintf("%.2f", f)
@ -637,15 +691,31 @@ func buildDefaultBalanceLayout() string {
{"当月可用增值数据数", "monthlyIncreaseDataAnalysisNumber", 2},
{"当月作废套餐数据数", "monthlyInvalidBundleDataAnalysisNumber", 2},
{"当月作废增值数据数", "monthlyInvalidIncreaseDataAnalysisNumber", 2},
{"套餐竞品总数", "bundleCompetitiveNumber", 2},
{"增值竞品总数", "increaseCompetitiveNumber", 2},
{"当前已用套餐竞品数", "bundleCompetitiveConsumptionNumber", 2},
{"当前已用增值竞品数", "increaseCompetitiveConsumptionNumber", 2},
{"当前作废套餐竞品数", "invalidBundleCompetitiveNumber", 2},
{"当前作废增值竞品数", "invalidIncreaseCompetitiveNumber", 2},
{"当月新增套餐竞品数", "monthlyNewBundleCompetitiveNumber", 2},
{"当月新增增值竞品数", "monthlyNewIncreaseCompetitiveNumber", 2},
{"当月使用套餐竞品数", "monthBundleCompetitiveConsumptionNumber", 2},
{"当月使用增值竞品数", "monthIncreaseCompetitiveConsumptionNumber", 2},
{"当月可用套餐竞品数", "monthlyBundleCompetitiveNumber", 2},
{"当月可用增值竞品数", "monthlyIncreaseCompetitiveNumber", 2},
{"当月作废套餐竞品数", "monthlyInvalidBundleCompetitiveNumber", 2},
{"当月作废增值竞品数", "monthlyInvalidIncreaseCompetitiveNumber", 2},
{"当月新增手动扩展账号数", "monthlyNewManualAccountNumber", 2},
{"当月新增手动扩展视频数", "monthlyNewManualVideoNumber", 2},
{"当月新增手动扩展图文数", "monthlyNewManualImageNumber", 2},
{"当月新增手动扩展数据数", "monthlyNewManualDataAnalysisNumber", 2},
{"当月新增手动扩展竞品数", "monthlyNewManualCompetitiveNumber", 2},
{"当月新增手动扩展时长(日)", "monthlyNewDurationNumber", 2},
{"当月已用手动扩展账号数", "monthlyManualAccountConsumptionNumber", 2},
{"当月已用手动扩展视频数", "monthlyManualVideoConsumptionNumber", 2},
{"当月已用手动扩展图文数", "monthlyManualImageConsumptionNumber", 2},
{"当月已用手动扩展数据数", "monthlyManualDataAnalysisConsumptionNumber", 2},
{"当月已用手动扩展竞品数", "monthlyManualCompetitiveConsumptionNumber", 2},
}
jsonMap := []map[string]any{}
for _, v := range data {

View File

@ -3,19 +3,18 @@ package logic
import (
"encoding/json"
"micro-bundle/internal/dao"
"micro-bundle/internal/dto"
"micro-bundle/pb/bundle"
commonErr "micro-bundle/pkg/err"
"strings"
)
// GetValidArtistList 查询套餐状态为有效中的艺人列表
// 调用dao层获取艺人详细信息
func GetValidArtistList() ([]dao.ValidArtistInfo, error) {
func GetValidArtistList() ([]dto.ValidArtistInfo, error) {
return dao.GetValidArtistList()
}
// GetValidArtistIDs 查询套餐没有过期的艺人ID列表保持向后兼容
// 根据BundleOrderRecords表查询过期时间大于当前时间且状态为已支付的艺人
func GetValidArtistIDs() ([]string, error) {
artistList, err := GetValidArtistList()
if err != nil {
@ -34,8 +33,6 @@ func GetValidArtistIDs() ([]string, error) {
// todo 目前暂时不做检验,后续需要做判断
// GetValidEmployeeIDs 查询可以被指派任务的员工ID列表
// 这里可以根据实际业务需求实现,比如查询员工表、权限表等
// 目前先返回一个示例实现,实际项目中需要根据具体的员工管理逻辑来实现
func GetValidEmployeeIDs() ([]string, error) {
var employeeIDs []string
@ -63,40 +60,18 @@ func ValidateEmployee(employeeNum string) (bool, error) {
return false, nil
}
// GetPendingTaskList 查询待指派任务记录
func GetPendingTaskList(req *dao.TaskQueryRequest) ([]*dao.TaskQueryResponse, int64, error) {
// 1. 先查询套餐没有过期的艺人
validArtist, err := GetValidArtistList()
if err != nil {
return nil, 0, err
}
// 2. 调用DAO层查询待指派任务记录已包含联表查询和排序分页
recordResponse, total, err := dao.GetPendingTaskList(req, validArtist)
if err != nil {
return nil, 0, err
}
// 3. 直接返回DAO层的结果已经包含了所有计算和排序分页逻辑
return recordResponse, total, nil
}
// GetArtistUploadStatsList 查询艺人上传与额度统计列表
func GetArtistUploadStatsList(req *dao.TaskQueryRequest) ([]*dao.ArtistUploadStatsItem, int64, error) {
func GetArtistUploadStatsList(req *dto.TaskQueryRequest) ([]*dto.ArtistUploadStatsItem, int64, error) {
return dao.GetArtistUploadStatsList(req)
}
func GetPendingUploadBreakdownBySubNums(subNums []string, page int, pageSize int) ([]*dao.ArtistPendingUploadBreakdownItem, int64, error) {
return dao.GetPendingUploadBreakdownBySubNums(subNums, page, pageSize)
}
// GetPendingAssignBySubNums 查询指定艺人的可指派数量
func GetPendingAssignBySubNums(subNums []string, page int, pageSize int) ([]*dao.ArtistPendingAssignItem, int64, error) {
func GetPendingAssignBySubNums(subNums []string, page int, pageSize int) ([]*dto.ArtistPendingAssignItem, int64, error) {
return dao.GetPendingAssignBySubNums(subNums, page, pageSize)
}
// AssignTask 指派某位员工完成某个艺人的任务
func AssignTask(req *dao.TaskAssignRequest) error {
func AssignTask(req *dto.TaskAssignRequest) error {
// 1. 验证员工是否可以被指派任务
isValid, err := ValidateEmployee(req.TaskAssigneeNum)
if err != nil {
@ -124,7 +99,7 @@ func AssignTask(req *dao.TaskAssignRequest) error {
}
// BatchAssignTask 批量指派
func BatchAssignTask(items []*dao.BatchAssignItem) error {
func BatchAssignTask(items []*dto.BatchAssignItem) error {
if len(items) == 0 {
return commonErr.ReturnError(nil, "参数错误", "批量指派项不能为空")
}
@ -160,42 +135,6 @@ func BatchAssignTask(items []*dao.BatchAssignItem) error {
return dao.BatchAssignTasks(items)
}
// UpdatePendingCount 修改待发数量
func UpdatePendingCount(req *dao.UpdatePendingCountRequest) error {
// 待发视频数、图文数、数据分析数不能都为0
if req.PendingVideoCount == 0 && req.PendingPostCount == 0 && req.PendingDataCount == 0 {
return commonErr.ReturnError(nil, "请输入正确的本次任务数字", "待发视频数、图文数、数据分析数不能都为0")
}
// 1. 验证艺人是否有有效套餐
validArtistIDs, err := GetValidArtistIDs()
if err != nil {
return err
}
// 检查艺人是否在有效列表中
isValidArtist := false
for _, artistID := range validArtistIDs {
if artistID == req.SubNum {
isValidArtist = true
break
}
}
if !isValidArtist {
return commonErr.ReturnError(nil, "艺人套餐已过期", "该艺人没有有效的套餐,无法修改待发数量")
}
// 查询艺人当前任务余额,校验是否存在记录(不做数量比较,避免排除手动余额)
_, err = dao.GetRemainingPendingBySubNum(req.SubNum)
if err != nil {
return commonErr.ReturnError(err, "查询艺人任务余额失败", "查询艺人任务余额失败: ")
}
// 2. 调用DAO层更新待发数量DAO 内部已做充足的额度与当月限额校验)
return dao.UpdatePendingCount(req)
}
// GetRecentAssignRecords 查询最近被指派记录
func GetRecentAssignRecords(limit int) ([]*bundle.RecentAssigneeItem, error) {
records, err := dao.GetRecentAssignRecords(limit)
@ -214,7 +153,7 @@ func GetRecentAssignRecords(limit int) ([]*bundle.RecentAssigneeItem, error) {
}
// GetEmployeeAssignedTasks 根据登录人信息查询被指派给该员工的艺人任务
func GetEmployeeAssignedTasks(req *dao.EmployeeTaskQueryRequest) ([]*dao.TaskAssignRecordsResponse, int64, error) {
func GetEmployeeAssignedTasks(req *dto.EmployeeTaskQueryRequest) ([]*dto.TaskAssignRecordsResponse, int64, error) {
// 1. 调用DAO层查询被指派给该员工的艺人任务
record, total, err := dao.GetEmployeeAssignedTasks(req)
if err != nil {
@ -223,9 +162,9 @@ func GetEmployeeAssignedTasks(req *dao.EmployeeTaskQueryRequest) ([]*dao.TaskAss
// 如果查询的 status = 2 的话,待发数量就为指派时,指派的数量
if req.Status == 2 {
var recordResponse []*dao.TaskAssignRecordsResponse
var recordResponse []*dto.TaskAssignRecordsResponse
for _, record := range record {
recordResponse = append(recordResponse, &dao.TaskAssignRecordsResponse{
recordResponse = append(recordResponse, &dto.TaskAssignRecordsResponse{
AssignRecordsUUID: record.AssignRecordsUUID,
SubNum: record.SubNum,
TelNum: record.TelNum,
@ -252,9 +191,9 @@ func GetEmployeeAssignedTasks(req *dao.EmployeeTaskQueryRequest) ([]*dao.TaskAss
}
// 2. 转换为响应结构体
var recordResponse []*dao.TaskAssignRecordsResponse
var recordResponse []*dto.TaskAssignRecordsResponse
for _, record := range record {
recordResponse = append(recordResponse, &dao.TaskAssignRecordsResponse{
recordResponse = append(recordResponse, &dto.TaskAssignRecordsResponse{
AssignRecordsUUID: record.AssignRecordsUUID,
SubNum: record.SubNum,
TelNum: record.TelNum,
@ -290,7 +229,6 @@ func TerminateTaskByUUID(assignRecordsUUID string) error {
}
// BatchTerminateTaskByUUIDs 批量根据指派记录UUID终止任务实际状态置为已中止
// 返回成功数量、失败数量、失败UUID列表和错误仅当整体参数错误时返回错误
func BatchTerminateTaskByUUIDs(assignRecordsUUIDs []string) (int, int, []string, error) {
if len(assignRecordsUUIDs) == 0 {
return 0, 0, nil, commonErr.ReturnError(nil, "参数错误", "AssignRecordsUUIDs 不能为空")
@ -357,7 +295,7 @@ func CompleteTaskManually(assignRecordsUUID string, taskAssigneeNum string) erro
}
// UpdateTaskProgress 员工实际完成任务状态更新
func UpdateTaskProgress(req *dao.CompleteTaskRequest) error {
func UpdateTaskProgress(req *dto.CompleteTaskRequest) error {
if req.UUID == "" {
return commonErr.ReturnError(nil, "作品UUID不能为空", "UUID不能为空")
}
@ -365,16 +303,16 @@ func UpdateTaskProgress(req *dao.CompleteTaskRequest) error {
}
// GetTaskAssignRecordsList 多条件查询操作记录表
func GetTaskAssignRecordsList(req *dao.TaskAssignRecordsQueryRequest) ([]*dao.TaskAssignRecordsResponse, int64, *dao.TaskAssignRecordsSummary, error) {
func GetTaskAssignRecordsList(req *dto.TaskAssignRecordsQueryRequest) ([]*dto.TaskAssignRecordsResponse, int64, *dto.TaskAssignRecordsSummary, error) {
record, total, summary, err := dao.GetTaskAssignRecordsList(req)
if err != nil {
return nil, 0, nil, err
}
// 2. 转换为响应结构体
var recordResponse []*dao.TaskAssignRecordsResponse
var recordResponse []*dto.TaskAssignRecordsResponse
for _, record := range record {
recordResponse = append(recordResponse, &dao.TaskAssignRecordsResponse{
recordResponse = append(recordResponse, &dto.TaskAssignRecordsResponse{
AssignRecordsUUID: record.AssignRecordsUUID,
SubNum: record.SubNum,
TelNum: record.TelNum,
@ -404,65 +342,6 @@ func GetTaskAssignRecordsList(req *dao.TaskAssignRecordsQueryRequest) ([]*dao.Ta
return recordResponse, total, summary, nil
}
// 新增:查询艺人剩余待发数量(区分套餐/增值共6个字段
func GetArtistRemainingPending(subNum string) (*dao.ArtistRemainingPendingResponse, error) {
if strings.TrimSpace(subNum) == "" {
return nil, commonErr.ReturnError(nil, "查询参数错误", "艺人编号不能为空")
}
return dao.GetRemainingPendingBySubNum(subNum)
}
// calculatePendingFromTaskBalance 从TaskBalance表计算待发任务数量
func calculatePendingFromTaskBalance(subNum string) (videoTotal, imageTotal, dataTotal int) {
// 查询用户的任务余额
tb, err := dao.GetTaskBalanceBySubNum(subNum)
if err != nil || tb == nil {
return 0, 0, 0
}
// 计算视频类待发数量:总余额 - 消耗数量
videoTotal = (tb.MonthlyBundleLimitExpiredVideoNumber - tb.MonthlyBundleLimitExpiredVideoConsumptionNumber) +
(tb.MonthlyBundleLimitVideoNumber - tb.MonthlyBundleLimitVideoConsumptionNumber) +
(tb.BundleVideoNumber - tb.BundleVideoConsumptionNumber) +
(tb.IncreaseVideoNumber - tb.IncreaseVideoConsumptionNumber) +
(tb.MonthlyIncreaseLimitVideoNumber - tb.MonthlyIncreaseLimitVideoConsumptionNumber) +
(tb.MonthlyIncreaseLimitExpiredVideoNumber - tb.MonthlyIncreaseLimitExpiredVideoConsumptionNumber) +
(tb.ManualVideoNumber - tb.ManualVideoConsumptionNumber)
if videoTotal < 0 {
videoTotal = 0
}
// 计算图片类待发数量:总余额 - 消耗数量
imageTotal = (tb.MonthlyBundleLimitExpiredImageNumber - tb.MonthlyBundleLimitExpiredImageConsumptionNumber) +
(tb.MonthlyBundleLimitImageNumber - tb.MonthlyBundleLimitImageConsumptionNumber) +
(tb.BundleImageNumber - tb.BundleImageConsumptionNumber) +
(tb.IncreaseImageNumber - tb.IncreaseImageConsumptionNumber) +
(tb.MonthlyIncreaseLimitImageNumber - tb.MonthlyIncreaseLimitImageConsumptionNumber) +
(tb.MonthlyIncreaseLimitExpiredImageNumber - tb.MonthlyIncreaseLimitExpiredImageConsumptionNumber) +
(tb.ManualImageNumber - tb.ManualImageConsumptionNumber)
if imageTotal < 0 {
imageTotal = 0
}
// 计算数据分析类待发数量:总余额 - 消耗数量
dataTotal = (tb.MonthlyBundleLimitExpiredDataAnalysisNumber - tb.MonthlyBundleLimitExpiredDataAnalysisConsumptionNumber) +
(tb.MonthlyBundleLimitDataAnalysisNumber - tb.MonthlyBundleLimitDataAnalysisConsumptionNumber) +
(tb.BundleDataAnalysisNumber - tb.BundleDataAnalysisConsumptionNumber) +
(tb.IncreaseDataAnalysisNumber - tb.IncreaseDataAnalysisConsumptionNumber) +
(tb.MonthlyIncreaseLimitDataAnalysisNumber - tb.MonthlyIncreaseLimitDataAnalysisConsumptionNumber) +
(tb.MonthlyIncreaseLimitExpiredDataAnalysisNumber - tb.MonthlyIncreaseLimitExpiredDataAnalysisConsumptionNumber) +
(tb.ManualDataAnalysisNumber - tb.ManualDataAnalysisConsumptionNumber)
if dataTotal < 0 {
dataTotal = 0
}
return videoTotal, imageTotal, dataTotal
}
func UpdateTaskBalanceEveryMonLogic() {
dao.UpdateTaskBalanceEveryMon()
}
// GetTaskActualStatusByUUID 根据指派记录UUID查询实际完成状态
func GetTaskActualStatusByUUID(assignRecordsUUID string) (int, error) {
if strings.TrimSpace(assignRecordsUUID) == "" {
@ -548,10 +427,7 @@ func AddHiddenTaskAssignee(taskAssignee string, taskAssigneeNum string) error {
}
// CreateTaskWorkLog 创建任务日志记录
// 用于记录任务操作日志,包括加任务、消耗任务、完成任务、任务过期等操作
func CreateTaskWorkLog(req *dao.CreateTaskWorkLogRequest) error {
// 参数校验已在 DAO 层完成,这里可以添加额外的业务逻辑校验
// 例如:校验操作类型是否合法、任务类型是否合法等
func CreateTaskWorkLog(req *dto.CreateTaskWorkLogRequest) error {
if req.OperationType < 1 || req.OperationType > 4 {
return commonErr.ReturnError(nil, "参数错误", "操作类型必须在1-4之间")
}

View File

@ -97,6 +97,7 @@ type BundleExtensionRecords struct {
OperatorName string `gorm:"column:operator_name;type:varchar(256)" json:"operatorName"`
OperatorPhoneNumber string `gorm:"column:operator_phone_number;type:varchar(256)" json:"operatorPhoneNumber"`
TimeUnit uint `gorm:"column:time_unit;type:int(11) unsigned;comment:时间单位" json:"timeUnit"`
CompetitiveAdditional uint `gorm:"column:competitive_additional;type:int(11) unsigned;comment:竞品数额外增加" json:"competitive_additional"`
}
// TableName 表名称
@ -111,6 +112,7 @@ type BundleExtendRecordItemPo struct {
ImagesAdditional int
DataAdditional int
VideoAdditional int
CompetitiveAdditional int
AvailableDurationAdditional uint `gorm:"column:available_duration_additional;type:int(11) unsigned;comment:可用时长增加" json:"available_duration_additional"`
Type int
Remark string
@ -290,6 +292,39 @@ type BundleBalance struct {
MonthlyNewDurationNumber int `gorm:"column:monthly_new_duration_number;comment:当月新增手动扩展时长(天)"`
ExpansionPacksNumber int `gorm:"column:expansion_packs_number;not null;comment:扩展包数量"`
// ===== 竞品数 =====
BundleCompetitiveNumber int `gorm:"column:bundle_competitive_number;not null;comment:非限制类型套餐权益竞品数总数"`
IncreaseCompetitiveNumber int `gorm:"column:increase_competitive_number;not null;comment:非限制类型增值权益竞品数总数"`
BundleLimitCompetitiveNumber int `gorm:"column:bundle_limit_competitive_number;not null;comment:套餐权益限制类型竞品数非过期总数"`
IncreaseLimitCompetitiveNumber int `gorm:"column:increase_limit_competitive_number;not null;comment:增值权益限制类型竞品数非过期总数"`
BundleLimitCompetitiveExpiredNumber int `gorm:"column:bundle_limit_competitive_expired_number;not null;comment:套餐权益限制类型竞品数会过期总数"`
IncreaseLimitCompetitiveExpiredNumber int `gorm:"column:increase_limit_competitive_expired_number;not null;comment:增值权益限制类型竞品数会过期总数"`
MonthlyInvalidBundleCompetitiveNumber int `gorm:"column:monthly_invalid_bundle_competitive_number;not null;comment:当月失效的套餐权益竞品数总数"`
InvalidBundleCompetitiveNumber int `gorm:"column:invalid_bundle_competitive_number;not null;comment:历史失效的套餐权益竞品数总数"`
MonthlyInvalidIncreaseCompetitiveNumber int `gorm:"column:monthly_invalid_increase_competitive_number;not null;comment:当月失效的增值权益竞品数总数"`
InvalidIncreaseCompetitiveNumber int `gorm:"column:invalid_increase_competitive_number;not null;comment:历史失效的增值权益竞品数总数"`
BundleCompetitiveConsumptionNumber int `gorm:"column:bundle_competitive_consumption_number;not null;comment:非限制类型套餐权益竞品数使用数"`
IncreaseCompetitiveConsumptionNumber int `gorm:"column:increase_competitive_consumption_number;not null;comment:非限制类型增值权益竞品数使用数"`
BundleLimitCompetitiveConsumptionNumber int `gorm:"column:bundle_limit_competitive_consumption_number;not null;comment:套餐权益限制类型竞品数非过期使用数"`
IncreaseLimitCompetitiveConsumptionNumber int `gorm:"column:increase_limit_competitive_consumption_number;not null;comment:增值权益限制类型竞品数非过期使用数"`
BundleLimitCompetitiveExpiredConsumptionNumber int `gorm:"column:bundle_limit_competitive_expired_consumption_number;not null;comment:套餐权益限制类型竞品数会过期使用数"`
IncreaseLimitCompetitiveExpiredConsumptionNumber int `gorm:"column:increase_limit_competitive_expired_consumption_number;not null;comment:增值权益限制类型竞品数会过期使用数"`
MonthlyBundleCompetitiveConsumptionNumber int `gorm:"column:monthly_bundle_competitive_consumption_number;not null;comment:当月套餐类型竞品数已使用额度"`
MonthlyIncreaseCompetitiveConsumptionNumber int `gorm:"column:monthly_increase_competitive_consumption_number;not null;comment:当月增值类型竞品数已使用额度"`
MonthlyBundleLimitCompetitiveNumber int `gorm:"column:monthly_bundle_limit_competitive_number;not null;comment:当月套餐限制类型竞品数可使用额度"`
MonthlyIncreaseLimitCompetitiveNumber int `gorm:"column:monthly_increase_limit_competitive_number;not null;comment:当月增值限制类型竞品数可使用额度"`
MonthlyBundleLimitCompetitiveConsumptionNumber int `gorm:"column:monthly_bundle_limit_competitive_consumption_number;not null;comment:当月套餐限制类型竞品数已使用额度"`
MonthlyIncreaseLimitCompetitiveConsumptionNumber int `gorm:"column:monthly_increase_limit_competitive_consumption_number;not null;comment:当月增值限制类型竞品数已使用额度"`
MonthlyBundleLimitExpiredCompetitiveNumber int `gorm:"column:monthly_bundle_limit_expired_competitive_number;not null;comment:当月套餐限制类会过期型竞品数可使用额度"`
MonthlyIncreaseLimitExpiredCompetitiveNumber int `gorm:"column:monthly_increase_limit_expired_competitive_number;not null;comment:当月增值限制类会过期型竞品数可使用额度"`
MonthlyBundleLimitExpiredCompetitiveConsumptionNumber int `gorm:"column:monthly_bundle_limit_expired_competitive_consumption_number;not null;comment:当月套餐限制类型会过期竞品数已使用额度"`
MonthlyIncreaseLimitExpiredCompetitiveConsumptionNumber int `gorm:"column:monthly_increase_limit_expired_competitive_consumption_number;not null;comment:当月增值限制类会过期型竞品数已使用额度"`
MonthlyLimitCompetitiveQuotaNumber int `gorm:"column:monthly_limit_competitive_quota_number;not null;comment:当月限制类型竞品数额度"`
ManualCompetitiveNumber int `gorm:"column:manual_competitive_number;comment:手动扩展竞品数总数"`
ManualCompetitiveConsumptionNumber int `gorm:"column:manual_competitive_consumption_number;comment:手动扩展竞品数使用数"`
MonthlyNewManualCompetitiveNumber int `gorm:"column:monthly_new_manual_competitive_number;comment:当月手动扩展竞品数新增数"`
MonthlyManualCompetitiveConsumptionNumber int `gorm:"column:monthly_manual_competitive_consumption_number;comment:当月手动扩展竞品数使用数"`
}
// TableName 表名称
@ -314,12 +349,14 @@ type BundleBalanceUsePo struct {
VideoNumber int
ImageNumber int
DataAnalysisNumber int
CompetitiveNumber int
}
type BundleBalanceExtendPo struct {
UserId int
AccountNumber int
VideoNumber int
ImageNumber int
CompetitiveNumber int
DataAnalysisNumber int
DurationNumber int
}
@ -377,6 +414,7 @@ type ManualIncreaseBundleBalance struct {
TotalVideoAdditional int `gorm:"column:total_video_additional"`
TotalImageAdditional int `gorm:"column:total_image_additional"`
TotalDataAnalysisAdditional int `gorm:"column:total_data_analysis_additional"`
TotalCompetitiveAdditional int `gorm:"column:total_competitive_additional"`
}
// 套餐购买导出

View File

@ -12,6 +12,7 @@ var OrderByDataAnalysis = map[string]string{
"increase_data_analysis_total": "increase_data_total",
"released_data_analysis_total": "released_data_total",
"pending_data_analysis_count": "pending_data_count",
"sub_num": "customer_num",
}
var OrderByPending = map[string]string{

View File

@ -14,15 +14,11 @@ service Bundle {
rpc HandShelf(HandShelfRequest) returns(CommonResponse) {} //
rpc SaveBundle(BundleProfile)returns (SaveResponse) {}
rpc BundleListV2(BundleListRequest) returns(BundleListResponse) {}
rpc BundleDetailV2(BundleDetailRequest) returns(BundleDetailResponseV2) {}
rpc BundleListH5V2(BundleListRequest) returns(BundleListResponse) {}
rpc BundleLangDetailV2(BundleDetailRequest) returns(BundleProfileLang) {}
rpc BundleList(BundleListRequest) returns (BundleListResponse) {}
rpc BundleDetail(BundleDetailRequest) returns (BundleDetailResponse) {}
@ -604,7 +600,7 @@ message ValueAddService {
message ValueAddServiceLang {
string uuid = 1 [json_name = "uuid"];
string serviceName = 2 [json_name = "serviceName"]; //
int32 serviceType = 3 [json_name = "serviceType"]; // 1: 2: 3: 4: 5:
int32 serviceType = 3 [json_name = "serviceType"]; // 1: 2: 3: 4: 5: 6:
int32 priceMode = 4 [json_name = "priceMode"]; // 1: 2:
string originalPrice = 5 [json_name = "originalPrice"];//
string unit = 6 [json_name = "unit"];// 1: 2: 3: 4: 5: 6: 7: 8: 9:
@ -671,17 +667,18 @@ message BatchGetValueAddServiceLangResponse{
message BundleExtendRequest{
int64 userId = 1;
uint32 accountAdditional = 2;
uint32 videoAdditional = 3;
uint32 imagesAdditional = 4;
uint32 dataAdditional = 5;
uint32 availableDurationAdditional = 6;
uint32 timeUnit = 7; // 1 2 3
string remark = 8;
string associatedorderNumber = 9;
uint64 operatorId = 10;
string operatorName = 11;
string operatorPhoneNumber = 12;
int32 type = 13;
uint32 videoAdditional = 3;//
uint32 imagesAdditional = 4; //
uint32 dataAdditional = 5;//
uint32 competitiveAdditional = 6;//
uint32 availableDurationAdditional = 7;
uint32 timeUnit = 8; // 1 2 3
string remark = 9;
string associatedorderNumber = 10;
uint64 operatorId = 11;
string operatorName = 12;
string operatorPhoneNumber = 13;
int32 type = 14;
}
message BundleExtendResponse{
@ -814,24 +811,44 @@ message BundleBalanceItem {
int32 monthlyInvalidBundleDataAnalysisNumber = 57; //
int32 monthlyInvalidIncreaseDataAnalysisNumber = 58; //
//
int32 bundleCompetitiveNumber = 59; //
int32 increaseCompetitiveNumber = 60; //
int32 bundleCompetitiveConsumptionNumber = 61; //
int32 increaseCompetitiveConsumptionNumber = 62; //
int32 invalidBundleCompetitiveNumber = 63; //
int32 invalidIncreaseCompetitiveNumber = 64; //
int32 monthlyNewBundleCompetitiveNumber = 65; //
int32 monthlyNewIncreaseCompetitiveNumber = 66; //
int32 monthlyBundleCompetitiveNumber = 67; //
int32 monthlyIncreaseCompetitiveNumber = 68; //
int32 monthBundleCompetitiveConsumptionNumber = 69; // 使
int32 monthIncreaseCompetitiveConsumptionNumber = 70; // 使
int32 monthlyInvalidBundleCompetitiveNumber = 71; //
int32 monthlyInvalidIncreaseCompetitiveNumber = 72; //
//
int32 monthlyNewManualAccountNumber = 59; //
int32 monthlyNewManualVideoNumber = 60; //
int32 monthlyNewManualImageNumber = 61; //
int32 monthlyNewManualDataAnalysisNumber = 62; //
int32 monthlyNewDurationNumber = 63; // ()
int32 monthlyManualAccountConsumptionNumber = 64; //
int32 monthlyManualVideoConsumptionNumber = 65; //
int32 monthlyManualImageConsumptionNumber = 66; //
int32 monthlyManualDataAnalysisConsumptionNumber = 67; //
int32 manualAccountConsumptionNumber = 68; //
int32 manualVideoConsumptionNumber = 69; //
int32 manualImageConsumptionNumber = 70; //
int32 manualDataAnalysisConsumptionNumber = 71; //
int32 manualAccountNumber = 72; //
int32 manualVideoNumber = 73; //
int32 manualImageNumber = 74; //
int32 manualDataAnalysisNumber = 75; //
int32 monthlyNewManualAccountNumber = 73; //
int32 monthlyNewManualVideoNumber = 74; //
int32 monthlyNewManualImageNumber = 75; //
int32 monthlyNewManualDataAnalysisNumber = 76; //
int32 monthlyNewManualCompetitiveNumber = 77; //
int32 monthlyNewDurationNumber = 78; // ()
int32 monthlyManualAccountConsumptionNumber = 79; //
int32 monthlyManualVideoConsumptionNumber = 80; //
int32 monthlyManualImageConsumptionNumber = 81; //
int32 monthlyManualDataAnalysisConsumptionNumber = 82; //
int32 monthlyManualCompetitiveConsumptionNumber = 83; //
int32 manualAccountConsumptionNumber = 84; //
int32 manualVideoConsumptionNumber = 85; //
int32 manualImageConsumptionNumber = 86; //
int32 manualDataAnalysisConsumptionNumber = 87; //
int32 manualCompetitiveConsumptionNumber = 88; //
int32 manualAccountNumber = 89; //
int32 manualVideoNumber = 90; //
int32 manualImageNumber = 91; //
int32 manualDataAnalysisNumber = 92; //
int32 manualCompetitiveNumber = 93; //
}
@ -905,20 +922,38 @@ message BundleBalanceExportItem {
int32 monthlyInvalidBundleDataAnalysisNumber = 57; //
int32 monthlyInvalidIncreaseDataAnalysisNumber = 58; //
//
int32 bundleCompetitiveNumber = 59; //
int32 increaseCompetitiveNumber = 60; //
int32 bundleCompetitiveConsumptionNumber = 61; //
int32 increaseCompetitiveConsumptionNumber = 62; //
int32 invalidBundleCompetitiveNumber = 63; //
int32 invalidIncreaseCompetitiveNumber = 64; //
int32 monthlyNewBundleCompetitiveNumber = 65; //
int32 monthlyNewIncreaseCompetitiveNumber = 66; //
int32 monthlyBundleCompetitiveNumber = 67; //
int32 monthlyIncreaseCompetitiveNumber = 68; //
int32 monthlyBundleCompetitiveConsumptionNumber = 69; // 使
int32 monthlyIncreaseCompetitiveConsumptionNumber = 70; // 使
int32 monthlyInvalidBundleCompetitiveNumber = 71; //
int32 monthlyInvalidIncreaseCompetitiveNumber = 72; //
//
int32 monthlyNewManualAccountNumber = 59; //
int32 monthlyNewManualVideoNumber = 60; //
int32 monthlyNewManualImageNumber = 61; //
int32 monthlyNewManualDataAnalysisNumber = 62; //
int32 monthlyNewDurationNumber = 63; //
int32 monthlyManualAccountConsumptionNumber = 64; // 使
int32 monthlyManualVideoConsumptionNumber = 65; // 使
int32 monthlyManualImageConsumptionNumber = 66; // 使
int32 monthlyManualDataAnalysisConsumptionNumber = 67; // 使
int32 monthlyNewManualAccountNumber = 73; //
int32 monthlyNewManualVideoNumber = 74; //
int32 monthlyNewManualImageNumber = 75; //
int32 monthlyNewManualDataAnalysisNumber = 76; //
int32 monthlyNewManualCompetitiveNumber = 77; //
int32 monthlyNewDurationNumber = 78; //
int32 monthlyManualAccountConsumptionNumber = 79; // 使
int32 monthlyManualVideoConsumptionNumber = 80; // 使
int32 monthlyManualImageConsumptionNumber = 81; // 使
int32 monthlyManualDataAnalysisConsumptionNumber = 82; // 使
int32 monthlyManualCompetitiveConsumptionNumber = 83; // 使
//
string monthlyBundleVideoConsumptionPrice = 68;//
string monthlyIncreaseVideoConsumptionPrice = 69;//
string monthlyBundleVideoConsumptionPrice = 84;//
string monthlyIncreaseVideoConsumptionPrice = 85;//
}
@ -971,7 +1006,9 @@ message AddBundleBalanceReq{
int32 imageConsumptionNumber = 9;
int32 dataAnalysisNumber = 10;
int32 dataAnalysisConsumptionNumber = 11;
int32 expansionPacksNumber = 12;
int32 competitiveNumber = 12;
int32 competitiveConsumptionNumber = 13;
int32 expansionPacksNumber = 14;
}
message AddBundleBalanceResp{
@ -1100,7 +1137,12 @@ message GetBundleBalanceByUserIdResp{
int32 dataAnalysisExtendConsumptionNumber = 25;
int32 dataAnalysisAdditional = 26;
int32 dataAnalysisConsumptionNumber = 27;
int32 expansionPacksNumber = 28;
int32 competitiveNumber = 28;
int32 competitiveExtendNumber = 29;
int32 competitiveExtendConsumptionNumber = 30;
int32 competitiveAdditional = 31;
int32 competitiveConsumptionNumber = 32;
int32 expansionPacksNumber = 33;
}
message OnlyAddValueListByOrderNoRequest{
@ -1658,6 +1700,11 @@ message MetricsBusinessResp {
int64 newUploadedDataAnalysisCount = 30; //
int64 newPendingUploadDataAnalysisCount = 31; //
int64 totalPendingUploadDataAnalysisCount = 32; //
// ====== ======
int64 newUploadedCompetitiveCount = 33; //
int64 newPendingUploadCompetitiveCount = 34; //
int64 totalPendingUploadCompetitiveCount = 35; //
}
@ -1702,6 +1749,16 @@ message MetricsOperatingCreateResp {
int64 newUploadedIncreaseDataAnalysisCount = 26; //
int64 totalUploadedBundleDataAnalysisCount = 27; //
int64 totalUploadedIncreaseDataAnalysisCount = 28; //
// ======================== / ========================
int64 newPendingUploadBundleCompetitiveCount = 29; //
int64 newPendingUploadIncreaseCompetitiveCount = 30; //
int64 totalPendingUploadBundleCompetitiveCount = 31; //
int64 totalPendingUploadIncreaseCompetitiveCount = 32; //
int64 newUploadedBundleCompetitiveCount = 33; //
int64 newUploadedIncreaseCompetitiveCount = 34; //
int64 totalUploadedBundleCompetitiveCount = 35; //
int64 totalUploadedIncreaseCompetitiveCount = 36; //
}
message MetricsOperatingStatusReq{
@ -1740,8 +1797,18 @@ message MetricsOperatingStatusResp {
int64 pendingUploadDataAnalysisCount = 24;//
int64 uploadSuccessDataAnalysisCount = 25;//
int64 uploadFailedDataAnalysisCount = 26;//
// ===== =====
int64 reviewingCompetitiveCount = 27; //
int64 rejectCompetitiveCount = 28; //
int64 waitConfirmCompetitiveCount = 29; //
int64 artistConfirmCompetitiveCount = 30; //
int64 autoConfirmCompetitiveCount = 31; //
int64 pendingUploadCompetitiveCount = 32; //
int64 uploadSuccessCompetitiveCount = 33; //
int64 uploadFailedCompetitiveCount = 34; //
int64 abnormalAccountAcount = 27; //
int64 abnormalAccountAcount = 35; //
}
message MetricsBundlePurchaseExportReq{

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,6 @@
package cron
import (
"fmt"
"log"
"micro-bundle/internal/logic"
@ -21,17 +20,6 @@ func InitCronJob() {
panic(err)
}
// 避免冲突,任务余额每月更新定时任务 - 每月1号1点执行
taskBalanceSpec := "0 0 1 1 * *"
_, err = c.AddFunc(taskBalanceSpec, func() {
log.Printf("执行任务余额每月数据更新")
logic.UpdateTaskBalanceEveryMonLogic()
})
if err != nil {
fmt.Println("添加任务余额每月数据更新定时任务失败", err)
panic(err)
}
c.Start()
}