diff --git a/cmd/app.go b/cmd/app.go index c7dad93..027b060 100644 --- a/cmd/app.go +++ b/cmd/app.go @@ -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) diff --git a/internal/controller/task.go b/internal/controller/task.go index d9ae791..d7b160f 100644 --- a/internal/controller/task.go +++ b/internal/controller/task.go @@ -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{ 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,7 +67,6 @@ func (b *BundleProvider) GetEmployeeAssignedTasks(_ context.Context, req *bundle if int(req.Status) == 2 { req.SortBy = "complete_time" } - // 转换请求参数 daoReq := &dao.EmployeeTaskQueryRequest{ TaskAssigneeNum: req.TaskAssigneeNum, Keyword: req.Keyword, @@ -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,7 +117,6 @@ 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{ AssignRecordsUUID: req.AssignRecordsUUID, EmployeeName: req.EmployeeName, @@ -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,7 +192,6 @@ func (b *BundleProvider) GetTaskAssignRecordsList(_ context.Context, req *bundle if sortBy, ok := model.OrderByPending[req.SortBy]; ok { req.SortBy = sortBy } - // 转换请求参数 daoReq := &dao.TaskAssignRecordsQueryRequest{ Keyword: req.Keyword, TaskAssignee: req.TaskAssignee, @@ -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) @@ -364,51 +280,7 @@ 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("批量指派项不能为空") @@ -451,7 +323,6 @@ func (b *BundleProvider) GetArtistUploadStatsList(_ context.Context, req *bundle if sortBy, ok := model.OrderByDataAnalysis[req.SortBy]; ok { req.SortBy = sortBy } - // 构造 DAO 请求参数 daoReq := &dao.TaskQueryRequest{ Keyword: req.Keyword, Page: int(req.Page), @@ -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)) diff --git a/internal/dao/bundleExtend.go b/internal/dao/bundleExtend.go index fd9001b..e71a2b8 100644 --- a/internal/dao/bundleExtend.go +++ b/internal/dao/bundleExtend.go @@ -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" ) @@ -454,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 } @@ -469,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 } diff --git a/internal/dao/taskBalanceSync.go b/internal/dao/taskBalanceSync.go deleted file mode 100644 index 4a557c4..0000000 --- a/internal/dao/taskBalanceSync.go +++ /dev/null @@ -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 -} diff --git a/internal/dao/taskDao.go b/internal/dao/taskDao.go index 9fae3f0..2b0e5e0 100644 --- a/internal/dao/taskDao.go +++ b/internal/dao/taskDao.go @@ -100,21 +100,6 @@ type BatchAssignItem struct { TaskBatch string `json:"taskBatch"` // 任务批次 } -// UpdatePendingCountRequest 修改待发数量请求参数 -type UpdatePendingCountRequest struct { - SubNum string `json:"subNum"` // 艺人编号 - TelNum string `json:"telNum"` // 艺人手机号 - ArtistName string `json:"artistName"` // 艺人姓名 - PendingVideoCount int `json:"pendingVideoCount"` // 待发视频数量 - PendingPostCount int `json:"pendingPostCount"` // 待发图文数量 - PendingDataCount int `json:"pendingDataCount"` // 待发数据数量 - Operator string `json:"operator"` // 操作人 - OperatorNum string `json:"operatorNum"` // 操作人账号 - TaskBatch string `json:"taskBatch"` // 任务批次 - TaskAssignee string `json:"taskAssignee"` // 任务指派人 - TaskAssigneeNum string `json:"taskAssigneeNum"` // 任务指派人账号 -} - // EmployeeTaskQueryRequest 员工任务查询请求参数 type EmployeeTaskQueryRequest struct { TaskAssigneeNum string `json:"taskAssigneeNum"` // 被指派人账号 @@ -159,26 +144,6 @@ type TaskAssignRecordsQueryRequest struct { SortType string `json:"sortType"` // 排序方式 } -// 待指派任务 response -type TaskQueryResponse struct { - SubNum string `json:"subNum"` - TelNum string `json:"telNum"` - ArtistName string `json:"artistName"` - PendingVideoCount int `json:"pendingVideoCount"` - PendingPostCount int `json:"pendingPostCount"` - PendingDataCount int `json:"pendingDataCount"` - ReleasedVideoCount int `json:"releasedVideoCount"` - ReleasedPostCount int `json:"releasedPostCount"` - ReleasedDataCount int `json:"releasedDataCount"` - UploadVideoCount int `json:"uploadVideoCount"` - UploadPostCount int `json:"uploadPostCount"` - UploadDataCount int `json:"uploadDataCount"` - ProgressTaskCount int `json:"progressTaskCount"` - CompleteTaskCount int `json:"completeTaskCount"` - LastTaskAssignee string `json:"lastTaskAssignee"` - TaskAssigneeNum string `json:"taskAssigneeNum"` -} - // 任务记录表返回结构体 type TaskAssignRecordsResponse struct { AssignRecordsUUID string `gorm:"column:assign_records_uuid;comment:指派记录UUID" json:"assignRecordsUUID"` @@ -219,13 +184,6 @@ type TaskAssignRecordsSummary struct { TotalCompleteDataCount int `json:"totalCompleteDataCount"` } -// 任务指派记录数量结构体 -type TaskAssignRecords struct { - TaskAssigneeNum string `json:"taskAssigneeNum"` // 任务指派人工号 - ProgressTaskCount int `json:"progressTaskCount"` // 进行中任务数量 - CompleteTaskCount int `json:"completeTaskCount"` // 已完成任务数量 -} - // ValidArtistInfo 有效艺人信息结构体 type ValidArtistInfo struct { UserID int `json:"userId"` // 用户ID @@ -247,103 +205,6 @@ type ValidArtistInfo struct { ExpansionPacksNumber int `json:"expansionPacksNumber"` // 扩展套餐数量 } -// ArtistBundleBalanceRequest 查询艺人套餐剩余数量请求参数 -type ArtistBundleBalanceRequest struct { - CustomerNum string `json:"customerNum"` // 艺人编号(推荐使用) - TelNum string `json:"telNum"` // 艺人手机号(备选) -} - -// ArtistBundleBalanceResponse 艺人套餐剩余数量响应结构体 -type ArtistBundleBalanceResponse struct { - RemainingVideoCount int `json:"remainingVideoCount"` // 剩余视频数量 (video_number - video_consumption_number) - RemainingImageCount int `json:"remainingImageCount"` // 剩余图片数量 (image_number - image_consumption_number) - RemainingDataAnalysisCount int `json:"remainingDataAnalysisCount"` // 剩余数据分析数量 (data_analysis_number - data_analysis_consumption_number) -} - -// PendingAndBalanceRequest 查询待发与任务余额请求参数 -// 优先使用艺人编号查询,如果为空则使用手机号查询 -type PendingAndBalanceRequest struct { - SubNum string `json:"subNum"` // 艺人编号(推荐使用) - TelNum string `json:"telNum"` // 艺人手机号(备选) -} - -// PendingAndBalanceResponse 查询待发与任务余额响应结构 -// 待发数量为细分待发字段求和;余额为对应总数减已使用数后再按类别(套餐/增值)聚合 -type PendingAndBalanceResponse struct { - // 待发(按类别聚合) - PendingBundleVideoCount int `json:"pendingBundleVideoCount"` // 待发套餐视频数量(非限制+限制非过期+限制会过期) - PendingBundleImageCount int `json:"pendingBundleImageCount"` // 待发套餐图文数量(非限制+限制非过期+限制会过期) - PendingBundleDataAnalysisCount int `json:"pendingBundleDataAnalysisCount"` // 待发套餐数据分析数量(非限制+限制非过期+限制会过期) - - PendingIncreaseVideoCount int `json:"pendingIncreaseVideoCount"` // 待发增值视频数量(非限制+限制非过期+限制会过期) - PendingIncreaseImageCount int `json:"pendingIncreaseImageCount"` // 待发增值图文数量(非限制+限制非过期+限制会过期) - PendingIncreaseDataAnalysisCount int `json:"pendingIncreaseDataAnalysisCount"` // 待发增值数据分析数量(非限制+限制非过期+限制会过期) - - // 任务余额(套餐/增值按类别聚合) - BundleVideoBalance int `json:"bundleVideoBalance"` // 套餐视频余额 - BundleImageBalance int `json:"bundleImageBalance"` // 套餐图文余额 - BundleDataAnalysisBalance int `json:"bundleDataAnalysisBalance"` // 套餐数据分析余额 - - IncreaseVideoBalance int `json:"increaseVideoBalance"` // 增值视频余额 - IncreaseImageBalance int `json:"increaseImageBalance"` // 增值图文余额 - IncreaseDataAnalysisBalance int `json:"increaseDataAnalysisBalance"` // 增值数据分析余额 -} - -// 新增:仅返回“剩余待发数量”的精简响应(区分套餐/增值,共6个字段) -type ArtistRemainingPendingResponse struct { - PendingBundleVideoCount int `json:"pendingBundleVideoCount"` // 待发套餐视频数量(非限制+限制非过期+限制会过期) - PendingBundleImageCount int `json:"pendingBundleImageCount"` // 待发套餐图文数量(非限制+限制非过期+限制会过期) - PendingBundleDataAnalysisCount int `json:"pendingBundleDataAnalysisCount"` // 待发套餐数据分析数量(非限制+限制非过期+限制会过期) - - PendingIncreaseVideoCount int `json:"pendingIncreaseVideoCount"` // 待发增值视频数量(非限制+限制非过期+限制会过期) - PendingIncreaseImageCount int `json:"pendingIncreaseImageCount"` // 待发增值图文数量(非限制+限制非过期+限制会过期) - PendingIncreaseDataAnalysisCount int `json:"pendingIncreaseDataAnalysisCount"` // 待发增值数据分析数量(非限制+限制非过期+限制会过期) -} - -// CalculateBundleBalances 计算套餐类别下的三类余额(视频/图文/数据分析) -// 余额=对应类别总数-对应类别已使用数;再将非限制、限制非过期、限制会过期三类相加 -func CalculateBundleBalances(tb *model.TaskBalance) (video int, image int, data int) { - // 视频套餐余额 - video = (tb.MonthlyBundleLimitExpiredVideoNumber - tb.MonthlyBundleLimitExpiredVideoConsumptionNumber) + - (tb.MonthlyBundleLimitVideoNumber - tb.MonthlyBundleLimitVideoConsumptionNumber) + - (tb.BundleVideoNumber - tb.BundleVideoConsumptionNumber) - - // 图文套餐余额 - image = (tb.MonthlyBundleLimitExpiredImageNumber - tb.MonthlyBundleLimitExpiredImageConsumptionNumber) + - (tb.MonthlyBundleLimitImageNumber - tb.MonthlyBundleLimitImageConsumptionNumber) + - (tb.BundleImageNumber - tb.BundleImageConsumptionNumber) - - // 数据分析套餐余额 - data = (tb.MonthlyBundleLimitExpiredDataAnalysisNumber - tb.MonthlyBundleLimitExpiredDataAnalysisConsumptionNumber) + - (tb.MonthlyBundleLimitDataAnalysisNumber - tb.MonthlyBundleLimitDataAnalysisConsumptionNumber) + - (tb.BundleDataAnalysisNumber - tb.BundleDataAnalysisConsumptionNumber) - return -} - -// CalculateIncreaseBalances 计算增值类别下的三类余额(视频/图文/数据分析) -// 余额=对应类别总数-对应类别已使用数;再将非限制、限制非过期、限制会过期三类相加 -func CalculateIncreaseBalances(tb *model.TaskBalance) (video int, image int, data int) { - // 视频增值余额 - video = (tb.IncreaseVideoNumber - tb.IncreaseVideoConsumptionNumber) + - (tb.MonthlyIncreaseLimitVideoNumber - tb.MonthlyIncreaseLimitVideoConsumptionNumber) + - (tb.MonthlyIncreaseLimitExpiredVideoNumber - tb.MonthlyIncreaseLimitExpiredVideoConsumptionNumber) + - (tb.ManualVideoNumber - tb.ManualVideoConsumptionNumber) - - // 图文增值余额 - image = (tb.IncreaseImageNumber - tb.IncreaseImageConsumptionNumber) + - (tb.MonthlyIncreaseLimitImageNumber - tb.MonthlyIncreaseLimitImageConsumptionNumber) + - (tb.MonthlyIncreaseLimitExpiredImageNumber - tb.MonthlyIncreaseLimitExpiredImageConsumptionNumber) + - (tb.ManualImageNumber - tb.ManualImageConsumptionNumber) - - // 数据分析增值余额 - data = (tb.IncreaseDataAnalysisNumber - tb.IncreaseDataAnalysisConsumptionNumber) + - (tb.MonthlyIncreaseLimitDataAnalysisNumber - tb.MonthlyIncreaseLimitDataAnalysisConsumptionNumber) + - (tb.MonthlyIncreaseLimitExpiredDataAnalysisNumber - tb.MonthlyIncreaseLimitExpiredDataAnalysisConsumptionNumber) + - (tb.ManualDataAnalysisNumber - tb.ManualDataAnalysisConsumptionNumber) - - return -} - // ArtistUploadStatsItem 艺人上传与额度统计(视频/图文/数据分析) type ArtistUploadStatsItem struct { // 身份信息 @@ -391,19 +252,6 @@ type ArtistUploadStatsItem struct { AllowDataCount int `json:"allowDataCount" gorm:"column:allow_data_count"` } -type ArtistPendingUploadBreakdownItem 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"` - PendingVideoScriptCount int `json:"pendingVideoScriptCount" gorm:"column:pending_video_script_count"` - PendingBundleVideoCount int `json:"pendingBundleVideoCount" gorm:"column:pending_bundle_video_count"` - PendingIncreaseVideoCount int `json:"pendingIncreaseVideoCount" gorm:"column:pending_increase_video_count"` - PendingBundlePostCount int `json:"pendingBundlePostCount" gorm:"column:pending_bundle_post_count"` - PendingIncreasePostCount int `json:"pendingIncreasePostCount" gorm:"column:pending_increase_post_count"` - PendingBundleDataCount int `json:"pendingBundleDataCount" gorm:"column:pending_bundle_data_count"` - PendingIncreaseDataCount int `json:"pendingIncreaseDataCount" gorm:"column:pending_increase_data_count"` -} - // ArtistPendingAssignItem 艺人可指派数量(可上传数 - 已指派且未完成的数量) type ArtistPendingAssignItem struct { SubNum string `json:"subNum" gorm:"column:customer_num"` @@ -416,7 +264,6 @@ type ArtistPendingAssignItem struct { } // GetArtistUploadStatsList 查询所有艺人的上传统计与额度信息(通过 BundleBalance 关联 CastWork/CastWorkAnalysis,及 subNum 关联 TaskManagement) -// 优化版本:减少CTE重复物化,简化JOIN结构 func GetArtistUploadStatsList(req *TaskQueryRequest) ([]*ArtistUploadStatsItem, int64, error) { taskSchema := bundleConfig.Data.TaskBenchDB.DbName nowMonth := time.Now().Format("2006-01") @@ -755,164 +602,7 @@ LEFT JOIN assigned_pending_agg apa ON apa.user_id = aw.user_id` return resp, total, nil } -func GetPendingUploadBreakdownBySubNums(subNums []string, page int, pageSize int) ([]*ArtistPendingUploadBreakdownItem, int64, error) { - if len(subNums) == 0 { - return []*ArtistPendingUploadBreakdownItem{}, 0, nil - } - - nowMonth := time.Now().Format("2006-01") - - sql := "WITH latest_bundle_balance AS (\n" + - " SELECT\n" + - " bb.user_id,\n" + - " COALESCE(SUM(\n" + - " bb.bundle_video_number + bb.monthly_bundle_limit_video_number + bb.monthly_bundle_limit_expired_video_number + bb.invalid_bundle_video_number +\n" + - " bb.bundle_limit_video_consumption_number + bb.bundle_limit_video_expired_consumption_number - bb.monthly_bundle_limit_expired_video_consumption_number - bb.monthly_bundle_limit_video_consumption_number\n" + - " ), 0) AS total_bundle_video,\n" + - " COALESCE(SUM(\n" + - " bb.increase_video_number + bb.monthly_increase_limit_video_number + bb.monthly_increase_limit_expired_video_number + bb.invalid_increase_video_number +\n" + - " bb.increase_limit_video_consumption_number + bb.increase_limit_video_expired_consumption_number - bb.monthly_increase_limit_expired_video_consumption_number - bb.monthly_increase_limit_video_consumption_number\n" + - " ), 0) AS total_increase_video,\n" + - " COALESCE(SUM(\n" + - " bb.bundle_image_number + bb.monthly_bundle_limit_image_number + bb.monthly_bundle_limit_expired_image_number + bb.invalid_bundle_image_number +\n" + - " bb.bundle_limit_image_consumption_number + bb.bundle_limit_image_expired_consumption_number - bb.monthly_bundle_limit_expired_image_consumption_number - bb.monthly_bundle_limit_image_consumption_number\n" + - " ), 0) AS total_bundle_image,\n" + - " COALESCE(SUM(\n" + - " bb.increase_image_number + bb.monthly_increase_limit_image_number + bb.monthly_increase_limit_expired_image_number + bb.invalid_increase_image_number +\n" + - " bb.increase_limit_image_consumption_number + bb.increase_limit_image_expired_consumption_number - bb.monthly_increase_limit_expired_image_consumption_number - bb.monthly_increase_limit_image_consumption_number\n" + - " ), 0) AS total_increase_image,\n" + - " COALESCE(SUM(\n" + - " bb.bundle_data_analysis_number + bb.monthly_bundle_limit_data_analysis_number + bb.monthly_bundle_limit_expired_data_analysis_number + bb.invalid_bundle_data_analysis_number +\n" + - " bb.bundle_limit_data_analysis_consumption_number + 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\n" + - " ), 0) AS total_bundle_data,\n" + - " COALESCE(SUM(\n" + - " bb.increase_data_analysis_number + bb.monthly_increase_limit_data_analysis_number + bb.monthly_increase_limit_expired_data_analysis_number + bb.invalid_increase_data_analysis_number +\n" + - " bb.increase_limit_data_analysis_consumption_number + 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\n" + - " ), 0) AS total_increase_data\n" + - " FROM bundle_balance AS bb\n" + - " JOIN (\n" + - " SELECT bb_inner.user_id, bb_inner.order_uuid, MAX(bb_inner.month) AS max_month\n" + - " FROM bundle_balance AS bb_inner\n" + - " JOIN bundle_order_records bor_inner ON bor_inner.uuid COLLATE utf8mb4_general_ci = bb_inner.order_uuid COLLATE utf8mb4_general_ci AND bor_inner.deleted_at IS NULL AND bor_inner.status = 2\n" + - " WHERE bb_inner.deleted_at IS NULL AND CAST(bb_inner.month AS CHAR) COLLATE utf8mb4_general_ci <= CAST(? AS CHAR) COLLATE utf8mb4_general_ci\n" + - " GROUP BY bb_inner.user_id, bb_inner.order_uuid\n" + - " ) AS bb_latest ON bb.user_id = bb_latest.user_id AND bb.order_uuid COLLATE utf8mb4_general_ci = bb_latest.order_uuid COLLATE utf8mb4_general_ci AND CAST(bb.month AS CHAR) COLLATE utf8mb4_general_ci = CAST(bb_latest.max_month AS CHAR) COLLATE utf8mb4_general_ci\n" + - " JOIN bundle_order_records bor2 ON bor2.uuid COLLATE utf8mb4_general_ci = bb.order_uuid COLLATE utf8mb4_general_ci AND bor2.deleted_at IS NULL AND bor2.status = 2\n" + - " WHERE bb.deleted_at IS NULL AND DATE_ADD(UTC_TIMESTAMP(), INTERVAL 8 HOUR) BETWEEN bb.start_at AND bb.expired_at\n" + - " GROUP BY bb.user_id\n" + - ")\n" + - "SELECT\n" + - " rn.name AS user_name,\n" + - " u.tel_num AS tel_num,\n" + - " bor1.customer_num,\n" + - " (COALESCE(lbb.total_bundle_video, 0) - COALESCE((\n" + - " SELECT COUNT(DISTINCT cwv.uuid)\n" + - " FROM cast_work cwv\n" + - " JOIN cast_work_extra cwev ON cwev.work_uuid = cwv.uuid AND cwev.deleted_at = 0\n" + - " WHERE cwv.artist_phone COLLATE utf8mb4_general_ci = u.tel_num COLLATE utf8mb4_general_ci\n" + - " AND cwv.deleted_at = 0 AND cwv.work_category = 2 AND cwv.cost = 1 AND (cwv.origin_uuid = '' OR cwv.origin_uuid IS NULL) AND cwv.submit_time BETWEEN bb.start_at AND bb.expired_at AND cwev.cost_type = 1\n" + - " ), 0)) - COALESCE(COUNT(DISTINCT CASE WHEN cw.work_category = 2 AND (cw.origin_uuid = '' OR cw.origin_uuid IS NULL) AND cwe.cost_type = 1 THEN cw.uuid END), 0) AS pending_bundle_video_count,\n" + - " ((COALESCE(lbb.total_increase_video, 0) + bb.manual_video_number - bb.manual_video_consumption_number) -\n" + - " COALESCE((\n" + - " SELECT COUNT(DISTINCT cwv.uuid)\n" + - " FROM cast_work cwv\n" + - " JOIN cast_work_extra cwev ON cwev.work_uuid = cwv.uuid AND cwev.deleted_at = 0\n" + - " WHERE cwv.artist_phone COLLATE utf8mb4_general_ci = u.tel_num COLLATE utf8mb4_general_ci\n" + - " AND cwv.deleted_at = 0 AND cwv.work_category = 2 AND cwv.cost = 1 AND (cwv.origin_uuid = '' OR cwv.origin_uuid IS NULL) AND cwv.submit_time BETWEEN bb.start_at AND bb.expired_at AND cwev.cost_type = 2\n" + - " ), 0) - COALESCE(COUNT(DISTINCT CASE WHEN cw.work_category = 2 AND (cw.origin_uuid = '' OR cw.origin_uuid IS NULL) AND cwe.cost_type = 2 THEN cw.uuid END), 0)) AS pending_increase_video_count,\n" + - " (COALESCE(lbb.total_bundle_image, 0) - COALESCE((\n" + - " SELECT COUNT(DISTINCT cwp.uuid)\n" + - " FROM cast_work cwp\n" + - " JOIN cast_work_extra cwep ON cwep.work_uuid = cwp.uuid AND cwep.deleted_at = 0\n" + - " WHERE cwp.artist_phone COLLATE utf8mb4_general_ci = u.tel_num COLLATE utf8mb4_general_ci\n" + - " AND cwp.deleted_at = 0 AND cwp.work_category = 1 AND cwp.cost = 1 AND (cwp.origin_uuid = '' OR cwp.origin_uuid IS NULL) AND cwp.submit_time BETWEEN bb.start_at AND bb.expired_at AND cwep.cost_type = 1\n" + - " ), 0)) - COALESCE(COUNT(DISTINCT CASE WHEN cw.work_category = 1 AND (cw.origin_uuid = '' OR cw.origin_uuid IS NULL) AND cwe.cost_type = 1 THEN cw.uuid END), 0) AS pending_bundle_post_count,\n" + - " ((COALESCE(lbb.total_increase_image, 0) + bb.manual_image_number - bb.manual_image_consumption_number) -\n" + - " COALESCE((\n" + - " SELECT COUNT(DISTINCT cwp.uuid)\n" + - " FROM cast_work cwp\n" + - " JOIN cast_work_extra cwep ON cwep.work_uuid = cwp.uuid AND cwep.deleted_at = 0\n" + - " WHERE cwp.artist_phone COLLATE utf8mb4_general_ci = u.tel_num COLLATE utf8mb4_general_ci\n" + - " AND cwp.deleted_at = 0 AND cwp.work_category = 1 AND cwp.cost = 1 AND (cwp.origin_uuid = '' OR cwp.origin_uuid IS NULL) AND cwp.submit_time BETWEEN bb.start_at AND bb.expired_at AND cwep.cost_type = 2\n" + - " ), 0) - COALESCE(COUNT(DISTINCT CASE WHEN cw.work_category = 1 AND (cw.origin_uuid = '' OR cw.origin_uuid IS NULL) AND cwe.cost_type = 2 THEN cw.uuid END), 0)) AS pending_increase_post_count,\n" + - " (COALESCE(lbb.total_bundle_data, 0) - COALESCE((\n" + - " SELECT COUNT(DISTINCT ca.uuid)\n" + - " FROM cast_work_analysis ca\n" + - " JOIN cast_work_analysis_extra cae ON cae.analysis_uuid = ca.uuid AND cae.deleted_at = 0\n" + - " WHERE ca.artist_phone COLLATE utf8mb4_general_ci = u.tel_num COLLATE utf8mb4_general_ci\n" + - " AND ca.deleted_at = 0 AND ca.cost = 1 AND (ca.work_analysis_status IS NULL OR ca.work_analysis_status != 1) AND ca.submit_time BETWEEN UNIX_TIMESTAMP(bb.start_at) AND UNIX_TIMESTAMP(bb.expired_at) AND cae.cost_type = 1\n" + - " ), 0)) - COALESCE(COUNT(DISTINCT CASE WHEN (cwa.work_analysis_status IS NULL OR cwa.work_analysis_status != 1) AND cwae.cost_type = 1 THEN cwa.uuid END), 0) AS pending_bundle_data_count,\n" + - " ((COALESCE(lbb.total_increase_data, 0) + bb.manual_data_analysis_number - bb.manual_data_analysis_consumption_number) -\n" + - " COALESCE((\n" + - " SELECT COUNT(DISTINCT ca.uuid)\n" + - " FROM cast_work_analysis ca\n" + - " JOIN cast_work_analysis_extra cae ON cae.analysis_uuid = ca.uuid AND cae.deleted_at = 0\n" + - " WHERE ca.artist_phone COLLATE utf8mb4_general_ci = u.tel_num COLLATE utf8mb4_general_ci\n" + - " AND ca.deleted_at = 0 AND ca.cost = 1 AND (ca.work_analysis_status IS NULL OR ca.work_analysis_status != 1) AND ca.submit_time BETWEEN UNIX_TIMESTAMP(bb.start_at) AND UNIX_TIMESTAMP(bb.expired_at) AND cae.cost_type = 2\n" + - " ), 0) - COALESCE(COUNT(DISTINCT CASE WHEN (cwa.work_analysis_status IS NULL OR cwa.work_analysis_status != 1) AND cwae.cost_type = 2 THEN cwa.uuid END), 0)) AS pending_increase_data_count,\n" + - " GREATEST(\n" + - " (COALESCE(lbb.total_bundle_video, 0) + COALESCE(lbb.total_increase_video, 0) + bb.manual_video_number - bb.manual_video_consumption_number) -\n" + - " COALESCE((SELECT COUNT(1) FROM cast_work cw2 WHERE cw2.artist_phone COLLATE utf8mb4_general_ci = u.tel_num COLLATE utf8mb4_general_ci AND cw2.deleted_at = 0 AND cw2.work_category = 2 AND cw2.cost = 1 AND (cw2.origin_uuid = '' OR cw2.origin_uuid IS NULL) AND cw2.submit_time BETWEEN bb.start_at AND bb.expired_at), 0),\n" + - " 0) -\n" + - " (SELECT COUNT(1) FROM cast_video_script cvs WHERE CAST(u.id AS CHAR) COLLATE utf8mb4_general_ci = cvs.artist_uuid COLLATE utf8mb4_general_ci AND cvs.deleted_at = 0 AND cvs.created_at BETWEEN UNIX_TIMESTAMP(CONVERT_TZ(bb.start_at, '+00:00', '+00:00')) AND UNIX_TIMESTAMP(CONVERT_TZ(bb.expired_at, '+00:00', '+00:00'))) AS pending_video_script_count\n" + - "FROM\n" + - " bundle_order_records AS bor1\n" + - "JOIN\n" + - " (SELECT customer_id, MAX(created_at) AS max_created_time FROM bundle_order_records WHERE status = 2 AND deleted_at IS NULL GROUP BY customer_id) AS bor2\n" + - " ON bor1.customer_id = bor2.customer_id AND bor1.created_at = bor2.max_created_time\n" + - "JOIN `micro-account`.user u ON u.id = bor1.customer_id AND u.deleted_at = 0\n" + - "JOIN `micro-account`.real_name rn ON rn.id = u.real_name_id AND rn.deleted_at = 0\n" + - "JOIN bundle_activate bc ON bc.user_id = u.id AND bc.activate = 2\n" + - "JOIN bundle_balance bb ON bb.order_uuid COLLATE utf8mb4_general_ci = bor1.uuid COLLATE utf8mb4_general_ci AND bb.user_id = u.id AND u.deleted_at = 0\n" + - "JOIN\n" + - " (SELECT user_id, MAX(month) AS month FROM bundle_balance WHERE deleted_at IS NULL GROUP BY user_id) AS newest_month\n" + - " ON bb.user_id = newest_month.user_id AND CAST(bb.month AS CHAR) COLLATE utf8mb4_general_ci = CAST(newest_month.month AS CHAR) COLLATE utf8mb4_general_ci\n" + - "LEFT JOIN latest_bundle_balance lbb ON lbb.user_id = u.id AND u.deleted_at = 0\n" + - "LEFT JOIN cast_work cw ON cw.artist_phone COLLATE utf8mb4_general_ci = u.tel_num COLLATE utf8mb4_general_ci AND cw.deleted_at = 0 AND (cw.origin_uuid = '' OR cw.origin_uuid IS NULL) AND cw.submit_time BETWEEN bb.start_at AND bb.expired_at\n" + - "LEFT JOIN cast_work_extra cwe ON cwe.work_uuid = cw.uuid AND cwe.deleted_at = 0\n" + - "LEFT JOIN cast_work_analysis cwa ON cwa.artist_phone COLLATE utf8mb4_general_ci = u.tel_num COLLATE utf8mb4_general_ci AND cwa.deleted_at = 0 AND (cwa.work_analysis_status IS NULL OR cwa.work_analysis_status != 1) AND cwa.submit_time BETWEEN UNIX_TIMESTAMP(bb.start_at) AND UNIX_TIMESTAMP(bb.expired_at)\n" + - "LEFT JOIN cast_work_analysis_extra cwae ON cwae.analysis_uuid = cwa.uuid AND cwae.deleted_at = 0\n" + - "WHERE bor1.deleted_at IS NULL AND bor1.status = 2 AND DATE_ADD(UTC_TIMESTAMP(), INTERVAL 8 HOUR) BETWEEN bb.start_at AND bb.expired_at AND bor1.customer_num IN ?\n" + - "GROUP BY u.id, rn.name, u.tel_num, bor1.customer_num, bb.start_at, bb.expired_at, bb.manual_video_number, bb.manual_video_consumption_number, bb.manual_image_number, bb.manual_image_consumption_number, bb.manual_data_analysis_number, bb.manual_data_analysis_consumption_number, lbb.total_bundle_video, lbb.total_increase_video, lbb.total_bundle_image, lbb.total_increase_image, lbb.total_bundle_data, lbb.total_increase_data\n" - - placeholders := strings.Repeat("?,", len(subNums)) - placeholders = placeholders[:len(placeholders)-1] - sql = strings.Replace(sql, "bor1.customer_num IN ?", "bor1.customer_num IN ("+placeholders+")", 1) - - args := make([]interface{}, 0, 1+len(subNums)) - args = append(args, nowMonth) - for i := range subNums { - args = append(args, subNums[i]) - } - - var total int64 - countSQL := "SELECT COUNT(1) FROM (" + sql + ") AS t" - if err := app.ModuleClients.BundleDB.Raw(countSQL, args...).Scan(&total).Error; err != nil { - return nil, 0, commonErr.ReturnError(err, "查询待发细分数量失败", "查询待发细分数量失败: ") - } - - listArgs := make([]interface{}, 0, len(args)+2) - listArgs = append(listArgs, args...) - if page > 0 && pageSize > 0 { - offset := (page - 1) * pageSize - sql = sql + " ORDER BY u.id LIMIT ? OFFSET ?" - listArgs = append(listArgs, pageSize, offset) - } - - items := make([]ArtistPendingUploadBreakdownItem, 0) - if err := app.ModuleClients.BundleDB.Raw(sql, listArgs...).Scan(&items).Error; err != nil { - return nil, 0, commonErr.ReturnError(err, "查询待发细分数量失败", "查询待发细分数量失败: ") - } - - resp := make([]*ArtistPendingUploadBreakdownItem, 0, len(items)) - for i := range items { - resp = append(resp, &items[i]) - } - return resp, total, nil -} - // GetPendingAssignBySubNums 查询指定艺人的可指派数量(可上传数 - 已指派且未完成的数量) -// 参考 GetArtistUploadStatsList 的 CTE 优化结构 func GetPendingAssignBySubNums(subNums []string, page int, pageSize int) ([]*ArtistPendingAssignItem, int64, error) { if len(subNums) == 0 { return []*ArtistPendingAssignItem{}, 0, nil @@ -1347,8 +1037,7 @@ func RevertTaskCompletionByUUIDItem(uuid string) error { return nil } -// BatchAssignTasks 批量指派(仅添加操作记录,不更新任务管理表) -// 优化版本:使用批量查询和批量插入,减少数据库交互次数 +// BatchAssignTasks 批量指派 func BatchAssignTasks(items []*BatchAssignItem) error { if len(items) == 0 { return commonErr.ReturnError(nil, "参数错误", "批量指派项不能为空") @@ -1356,8 +1045,6 @@ func BatchAssignTasks(items []*BatchAssignItem) error { now := time.Now() - // ============ 第一阶段:数据校验和预处理(无数据库操作) ============ - // 收集所有 sub_num 和 (sub_num, tel_num) 组合 subNumSet := make(map[string]struct{}) subTelKeys := make(map[string]*BatchAssignItem) // key: sub_num|tel_num for _, it := range items { @@ -1385,9 +1072,6 @@ func BatchAssignTasks(items []*BatchAssignItem) error { for sn := range subNumSet { subNums = append(subNums, sn) } - - // ============ 第二阶段:批量预查询(事务外,只读操作) ============ - // 2.1 批量查询已存在的 task_management 记录 existingTMMap := make(map[string]*model.TaskManagement) // key: sub_num|tel_num if len(subTelKeys) > 0 { @@ -1496,7 +1180,6 @@ func BatchAssignTasks(items []*BatchAssignItem) error { } } - // ============ 第三阶段:开启事务,批量写入 ============ tx := app.ModuleClients.TaskBenchDB.Begin() defer func() { if r := recover(); r != nil { @@ -1609,16 +1292,14 @@ func BatchAssignTasks(items []*BatchAssignItem) error { } // 3.5 批量更新 task_management 表 - // 按 sub_num|tel_num 分组,每个组只更新一次(取最后一个 item 的 TaskAssignee 信息) updateGroups := make(map[string]*BatchAssignItem) for _, it := range items { key := it.SubNum + "|" + it.TelNum - updateGroups[key] = it // 后面的会覆盖前面的,保持与原逻辑一致(最后一个) + updateGroups[key] = it } for key, it := range updateGroups { stats := statsMap[it.SubNum] - // 计算新的 progress_count:原有进行中数量 + 本批次该 sub_num 新增的指派数量 newProgressCount := stats.ProgressTaskCount + subNumAssignCount[it.SubNum] // 获取对应的 task_management 记录 ID @@ -1651,12 +1332,9 @@ func BatchAssignTasks(items []*BatchAssignItem) error { } // GetRecentAssignRecords 查询最近被指派记录 -// 查询操作类型为"指派"的最近n条不同员工的记录 func GetRecentAssignRecords(limit int) ([]*model.TaskAssignRecords, error) { var records []*model.TaskAssignRecords - // 使用JOIN方式获取每个指派人的最新指派记录 - // 避免MySQL版本不支持子查询中LIMIT的问题 err := app.ModuleClients.TaskBenchDB.Raw(` SELECT t1.* FROM task_assign_records t1 @@ -2234,427 +1912,6 @@ func GetTaskBalanceBySubNum(subNum string) (*model.TaskBalance, error) { return &taskBalance, nil } -// GetRemainingPendingBySubNum 根据艺人编号查询剩余待发数量(区分套餐/增值,共6个字段) -func GetRemainingPendingBySubNum(subNum string) (*ArtistRemainingPendingResponse, error) { - if subNum == "" { - return nil, commonErr.ReturnError(nil, "查询参数错误", "艺人编号不能为空") - } - - tb, err := GetTaskBalanceBySubNum(subNum) - if err != nil { - return nil, err - } - if tb == nil { - // 没有余额记录,视为 0 - return &ArtistRemainingPendingResponse{}, nil - } - - // 计算套餐与增值剩余待发数量(非限制 + 限制非过期 + 限制会过期) - bundleVideo, bundleImage, bundleData := CalculateBundleBalances(tb) - increaseVideo, increaseImage, increaseData := CalculateIncreaseBalances(tb) - - return &ArtistRemainingPendingResponse{ - PendingBundleVideoCount: bundleVideo, - PendingBundleImageCount: bundleImage, - PendingBundleDataAnalysisCount: bundleData, - - PendingIncreaseVideoCount: increaseVideo, - PendingIncreaseImageCount: increaseImage, - PendingIncreaseDataAnalysisCount: increaseData, - }, nil -} - -// UpdatePendingCount 扣减任务余额(一次可同时扣减视频/图文/数据),遵循套餐扣减优先级 -func UpdatePendingCount(req *UpdatePendingCountRequest) error { - // 参数校验 - if req.SubNum == "" { - return commonErr.ReturnError(nil, "参数错误", "艺人编号不能为空") - } - if req.PendingVideoCount < 0 || req.PendingPostCount < 0 || req.PendingDataCount < 0 { - return commonErr.ReturnError(nil, "参数错误", "扣减数量必须为非负") - } - if req.TaskBatch == "" { - req.TaskBatch = "未填写" - } - - // 开启事务 - tx := app.ModuleClients.TaskBenchDB.Begin() - defer func() { - if r := recover(); r != nil { - tx.Rollback() - } - }() - - // 查询当前有效期内或最新一条任务余额 - now := time.Now() - var tb model.TaskBalance - { - err := tx.Where("sub_num = ? AND start_at <= ? AND expired_at >= ?", req.SubNum, now, now).Order("start_at DESC").First(&tb).Error - if err != nil { - if err == gorm.ErrRecordNotFound { - err = tx.Where("sub_num = ?", req.SubNum).Order("start_at DESC").First(&tb).Error - if err != nil { - if err == gorm.ErrRecordNotFound { - tx.Rollback() - return commonErr.ReturnError(nil, "余额不存在", "未找到任务余额记录") - } - tx.Rollback() - return commonErr.ReturnError(err, "查询任务余额失败", "查询任务余额失败: ") - } - } else { - tx.Rollback() - return commonErr.ReturnError(err, "查询任务余额失败", "查询任务余额失败: ") - } - } - } - - // 先检查各类型是否有足够的总体余额(包含套餐、增值、手动) - bundleVideo, bundleImage, bundleData := CalculateBundleBalances(&tb) - increaseVideo, increaseImage, increaseData := CalculateIncreaseBalances(&tb) - - if req.PendingVideoCount > bundleVideo+increaseVideo { - tx.Rollback() - return commonErr.ReturnError(nil, "请输入正确的本次任务数字", "扣减视频数量超过当前余额") - } - if req.PendingPostCount > bundleImage+increaseImage { - tx.Rollback() - return commonErr.ReturnError(nil, "请输入正确的本次任务数字", "扣减图文数量超过当前余额") - } - if req.PendingDataCount > bundleData+increaseData { - tx.Rollback() - return commonErr.ReturnError(nil, "请输入正确的本次任务数字", "扣减数据分析数量超过当前余额") - } - - need := req.PendingVideoCount - if need > 0 { - // 当月可使用的会过期的限制 - if need > 0 { - totalRemain := tb.MonthlyBundleLimitExpiredVideoNumber - tb.MonthlyBundleLimitExpiredVideoConsumptionNumber - alloc := minInt(need, totalRemain) - if alloc > 0 { - tb.MonthlyBundleLimitExpiredVideoConsumptionNumber += alloc - tb.BundleLimitVideoExpiredConsumptionNumber += alloc - need -= alloc - } - } - // 限制会过期 - 增值(忽略当月限额,只看总余额) - if need > 0 { - totalRemain := tb.MonthlyIncreaseLimitExpiredVideoNumber - tb.MonthlyIncreaseLimitExpiredVideoConsumptionNumber - alloc := minInt(need, totalRemain) - if alloc > 0 { - tb.MonthlyIncreaseLimitExpiredVideoConsumptionNumber += alloc - tb.IncreaseLimitVideoExpiredConsumptionNumber += alloc - need -= alloc - } - } - if need > 0 { - totalRemain := tb.MonthlyBundleLimitVideoNumber - tb.MonthlyBundleLimitVideoConsumptionNumber - alloc := minInt(need, totalRemain) - if alloc > 0 { - tb.MonthlyBundleLimitVideoConsumptionNumber += alloc - tb.BundleLimitVideoConsumptionNumber += alloc - need -= alloc - } - } - // 限制不过期 - 套餐(忽略当月限额,只看总余额) - if need > 0 { - totalRemain := tb.MonthlyIncreaseLimitVideoNumber - tb.MonthlyIncreaseLimitVideoConsumptionNumber - alloc := minInt(need, totalRemain) - if alloc > 0 { - tb.MonthlyIncreaseLimitVideoConsumptionNumber += alloc - tb.IncreaseLimitVideoConsumptionNumber += alloc - need -= alloc - } - } - // 非限制 - 套餐 - if need > 0 { - totalRemain := tb.BundleVideoNumber - tb.BundleVideoConsumptionNumber - alloc := minInt(need, totalRemain) - if alloc > 0 { - tb.BundleVideoConsumptionNumber += alloc - tb.MonthlyBundleVideoConsumptionNumber += alloc - need -= alloc - } - } - // 限制不过期 - 增值(忽略当月限额,只看总余额) - if need > 0 { - totalRemain := tb.IncreaseVideoNumber - tb.IncreaseVideoConsumptionNumber - alloc := minInt(need, totalRemain) - if alloc > 0 { - tb.IncreaseVideoConsumptionNumber += alloc - tb.MonthlyIncreaseVideoConsumptionNumber += alloc - need -= alloc - } - } - - // 手动扩展 - if need > 0 { - totalRemain := tb.ManualVideoNumber - tb.ManualVideoConsumptionNumber - alloc := minInt(need, totalRemain) - if alloc > 0 { - tb.ManualVideoConsumptionNumber += alloc - tb.MonthlyManualVideoConsumptionNumber += alloc - need -= alloc - } - } - if need > 0 { - tx.Rollback() - return commonErr.ReturnError(nil, "可用视频数不足", "扣减视频数量超过当前余额") - } - } - - // 扣减图文 - need = req.PendingPostCount - if need > 0 { - // 限制会过期 - 套餐(忽略当月限额,只看总余额) - if need > 0 { - totalRemain := tb.MonthlyBundleLimitExpiredImageNumber - tb.MonthlyBundleLimitExpiredImageConsumptionNumber - alloc := minInt(need, totalRemain) - if alloc > 0 { - tb.MonthlyBundleLimitExpiredImageConsumptionNumber += alloc - tb.BundleLimitImageExpiredConsumptionNumber += alloc - need -= alloc - } - } - // 限制会过期 - 增值(忽略当月限额,只看总余额) - if need > 0 { - totalRemain := tb.MonthlyIncreaseLimitExpiredImageNumber - tb.MonthlyIncreaseLimitExpiredImageConsumptionNumber - alloc := minInt(need, totalRemain) - if alloc > 0 { - tb.MonthlyIncreaseLimitExpiredImageConsumptionNumber += alloc - tb.IncreaseLimitImageExpiredConsumptionNumber += alloc - need -= alloc - } - } - // 限制不过期 - 套餐(忽略当月限额,只看总余额) - if need > 0 { - totalRemain := tb.MonthlyBundleLimitImageNumber - tb.MonthlyBundleLimitImageConsumptionNumber - alloc := minInt(need, totalRemain) - if alloc > 0 { - tb.MonthlyBundleLimitImageConsumptionNumber += alloc - tb.BundleLimitImageConsumptionNumber += alloc - need -= alloc - } - } - // 非限制 - 套餐 - if need > 0 { - totalRemain := tb.MonthlyIncreaseLimitImageNumber - tb.MonthlyIncreaseLimitImageConsumptionNumber - alloc := minInt(need, totalRemain) - if alloc > 0 { - tb.MonthlyIncreaseLimitImageConsumptionNumber += alloc - tb.IncreaseLimitImageConsumptionNumber += alloc - need -= alloc - } - } - // 限制不过期 - 增值(忽略当月限额,只看总余额) - if need > 0 { - totalRemain := tb.BundleImageNumber - tb.BundleImageConsumptionNumber - alloc := minInt(need, totalRemain) - if alloc > 0 { - tb.BundleImageConsumptionNumber += alloc - tb.MonthlyBundleImageConsumptionNumber += alloc - need -= alloc - } - } - // 非限制 - 增值 - if need > 0 { - totalRemain := tb.IncreaseImageNumber - tb.IncreaseImageConsumptionNumber - alloc := minInt(need, totalRemain) - if alloc > 0 { - tb.IncreaseImageConsumptionNumber += alloc - tb.MonthlyIncreaseImageConsumptionNumber += alloc - need -= alloc - } - } - // 手动扩展 - if need > 0 { - totalRemain := tb.ManualImageNumber - tb.ManualImageConsumptionNumber - alloc := minInt(need, totalRemain) - if alloc > 0 { - tb.ManualImageConsumptionNumber += alloc - tb.MonthlyManualImageConsumptionNumber += alloc - need -= alloc - } - } - if need > 0 { - tx.Rollback() - return commonErr.ReturnError(nil, "可用图文数不足", "扣减图文数量超过当前余额") - } - } - - // 扣减数据分析 - need = req.PendingDataCount - if need > 0 { - // 限制会过期 - 套餐(忽略当月限额,只看总余额) - if need > 0 { - totalRemain := tb.MonthlyBundleLimitExpiredDataAnalysisNumber - tb.MonthlyBundleLimitExpiredDataAnalysisConsumptionNumber - alloc := minInt(need, totalRemain) - if alloc > 0 { - tb.MonthlyBundleLimitExpiredDataAnalysisConsumptionNumber += alloc - tb.BundleLimitDataAnalysisExpiredConsumptionNumber += alloc - need -= alloc - } - } - // 限制会过期 - 增值(忽略当月限额,只看总余额) - if need > 0 { - totalRemain := tb.MonthlyIncreaseLimitExpiredDataAnalysisNumber - tb.MonthlyIncreaseLimitExpiredDataAnalysisConsumptionNumber - alloc := minInt(need, totalRemain) - if alloc > 0 { - tb.MonthlyIncreaseLimitExpiredDataAnalysisConsumptionNumber += alloc - tb.IncreaseLimitDataAnalysisExpiredConsumptionNumber += alloc - need -= alloc - } - } - // 限制不过期 - 套餐(忽略当月限额,只看总余额) - if need > 0 { - totalRemain := tb.MonthlyBundleLimitDataAnalysisNumber - tb.MonthlyBundleLimitDataAnalysisConsumptionNumber - alloc := minInt(need, totalRemain) - if alloc > 0 { - tb.MonthlyBundleLimitDataAnalysisConsumptionNumber += alloc - tb.BundleLimitDataAnalysisConsumptionNumber += alloc - need -= alloc - } - } - // 非限制 - 套餐 - if need > 0 { - totalRemain := tb.MonthlyIncreaseLimitDataAnalysisNumber - tb.MonthlyIncreaseLimitDataAnalysisConsumptionNumber - alloc := minInt(need, totalRemain) - if alloc > 0 { - tb.MonthlyIncreaseLimitDataAnalysisConsumptionNumber += alloc - tb.IncreaseLimitDataAnalysisConsumptionNumber += alloc - need -= alloc - } - } - // 限制不过期 - 增值(忽略当月限额,只看总余额) - if need > 0 { - totalRemain := tb.BundleDataAnalysisNumber - tb.BundleLimitDataAnalysisNumber - alloc := minInt(need, totalRemain) - if alloc > 0 { - tb.BundleLimitDataAnalysisNumber += alloc - tb.MonthlyBundleDataAnalysisConsumptionNumber += alloc - need -= alloc - } - } - // 非限制 - 增值 - if need > 0 { - totalRemain := tb.IncreaseDataAnalysisNumber - tb.IncreaseDataAnalysisConsumptionNumber - alloc := minInt(need, totalRemain) - if alloc > 0 { - tb.IncreaseDataAnalysisConsumptionNumber += alloc - tb.MonthlyIncreaseDataAnalysisConsumptionNumber += alloc - need -= alloc - } - } - // 手动扩展 - if need > 0 { - totalRemain := tb.ManualDataAnalysisNumber - tb.ManualDataAnalysisConsumptionNumber - alloc := minInt(need, totalRemain) - if alloc > 0 { - tb.ManualDataAnalysisConsumptionNumber += alloc - tb.MonthlyManualDataAnalysisConsumptionNumber += alloc - need -= alloc - } - } - if need > 0 { - tx.Rollback() - return commonErr.ReturnError(nil, "可用数据分析数不足", "扣减数据分析数量超过当前余额") - } - } - - // 保存余额 - if err := tx.Model(&model.TaskBalance{}).Where("id = ?", tb.ID).Save(&tb).Error; err != nil { - tx.Rollback() - return commonErr.ReturnError(err, "更新任务余额失败", "更新任务余额失败: ") - } - - // 同步更新任务管理表(视为一次指派操作) - var taskManagement model.TaskManagement - err := tx.Where("sub_num = ? AND tel_num = ?", req.SubNum, req.TelNum).First(&taskManagement).Error - if err != nil { - if err == gorm.ErrRecordNotFound { - taskManagement = model.TaskManagement{ - SubNum: req.SubNum, - TelNum: req.TelNum, - ArtistName: req.ArtistName, - ProgressCount: 0, - CompleteCount: 0, - CreatedAt: time.Now(), - UpdatedAt: time.Now(), - } - if err = tx.Create(&taskManagement).Error; err != nil { - tx.Rollback() - return commonErr.ReturnError(err, "创建任务记录失败", "创建任务记录失败: ") - } - } else { - tx.Rollback() - return commonErr.ReturnError(err, "查询任务记录失败", "查询任务记录失败: ") - } - } - - progressTaskCount, completeTaskCount, err := GetArtistTaskStatsBySubNum(req.SubNum) - if err != nil { - // 查询不到的话,给一个默认值 - progressTaskCount, completeTaskCount = 0, 0 - } - - updateData := map[string]interface{}{ - "ProgressCount": progressTaskCount + 1, - "CompleteCount": completeTaskCount, - "LastTaskAssignee": req.TaskAssignee, - "TaskAssigneeNum": req.TaskAssigneeNum, - "UpdatedAt": time.Now(), - } - if err = tx.Model(&taskManagement).Updates(updateData).Error; err != nil { - tx.Rollback() - return commonErr.ReturnError(err, "更新任务记录失败", "更新任务记录失败: ") - } - - // 写入操作日志(修改待发数量) - assignRecord := &model.TaskAssignRecords{ - AssignRecordsUUID: uuid.New().String(), - SubNum: req.SubNum, - TelNum: req.TelNum, - Status: 1, - ActualStatus: 1, - OperatorType: 2, // 2 是指派,现在把修改待发数量接口改成指派 - Operator: req.Operator, - OperatorNum: req.OperatorNum, - OperatorTime: time.Now(), - TaskBatch: req.TaskBatch, - TaskAssignee: req.TaskAssignee, - TaskAssigneeNum: req.TaskAssigneeNum, - PendingVideoCount: req.PendingVideoCount, - PendingPostCount: req.PendingPostCount, - PendingDataCount: req.PendingDataCount, - AssignVideoCount: req.PendingVideoCount, - AssignPostCount: req.PendingPostCount, - AssignDataCount: req.PendingDataCount, - CompleteVideoCount: 0, - CompletePostCount: 0, - CompleteDataCount: 0, - CreatedAt: time.Now(), - UpdatedAt: time.Now(), - } - if err := tx.Create(assignRecord).Error; err != nil { - tx.Rollback() - return commonErr.ReturnError(err, "记录任务操作日志失败", "创建修改待发数量记录失败: ") - } - - // 提交事务 - if err := tx.Commit().Error; err != nil { - return commonErr.ReturnError(err, "提交事务失败", "提交事务失败: ") - } - return nil -} - -// minInt 返回两个整数的最小值 -func minInt(a, b int) int { - if a < b { - return a - } - return b -} - // GetAssignRecordByUUID 根据UUID查询指派记录 func GetAssignRecordByUUID(uuid string) (*model.TaskAssignRecords, error) { var record model.TaskAssignRecords @@ -2669,7 +1926,6 @@ func GetAssignRecordByUUID(uuid string) (*model.TaskAssignRecords, error) { } // GetTaskAssignRecordsList 多条件查询操作记录表 -// 支持通过艺人信息、指派人、操作人、操作时间、完成状态等多条件查询TaskAssignRecords表 func GetTaskAssignRecordsList(req *TaskAssignRecordsQueryRequest) ([]*model.TaskAssignRecords, int64, *TaskAssignRecordsSummary, error) { var records []*model.TaskAssignRecords var total int64 @@ -2826,7 +2082,6 @@ func GetTaskAssignRecordsList(req *TaskAssignRecordsQueryRequest) ([]*model.Task } // GetValidArtistList 查询套餐状态为有效中的艺人数据列表 -// 根据BundleOrderRecords表查询过期时间大于当前时间且状态为已支付,同时已激活的艺人详细信息 func GetValidArtistList() ([]ValidArtistInfo, error) { // 构建子查询,获取每个用户的最新订单记录 subQuery := app.ModuleClients.BundleDB.Table("bundle_order_records as bor1"). @@ -2907,371 +2162,6 @@ func UpdateTaskRecordsByAssigneeNum(taskAssigneeNum string) error { return nil } -// GetPendingTaskList 查询待指派任务记录(按有效艺人过滤) -// 说明:使用LEFT JOIN联表查询TaskManagement和TaskBalance表,直接在SQL层计算待发任务数量 -func GetPendingTaskList(req *TaskQueryRequest, validArtist []ValidArtistInfo) ([]*TaskQueryResponse, int64, error) { - // 首先为有TaskBalance记录但没有TaskManagement记录的有效艺人创建TaskManagement记录 - if err := CreateMissingTaskManagementRecords(validArtist); err != nil { - zap.L().Error("创建缺失的TaskManagement记录失败", zap.Error(err)) - // 记录错误但不中断流程,继续执行查询 - } - - // 提取有效艺人的艺人编号(sub_num) - subNums := make([]string, 0, len(validArtist)) - for _, a := range validArtist { - if a.CustomerNum != "" { - subNums = append(subNums, a.CustomerNum) - } - } - if len(subNums) == 0 { - // 没有有效艺人,直接返回空 - return []*TaskQueryResponse{}, 0, nil - } - - // 构建联表查询,计算待发任务数量 - now := time.Now() - selectFields := ` - tm.sub_num, - tm.tel_num, - tm.artist_name, - tm.last_task_assignee, - tm.task_assignee_num, - tm.progress_count AS progress_task_count, - tm.complete_count AS complete_task_count, - COALESCE( - (tb.monthly_bundle_limit_expired_video_number - tb.monthly_bundle_limit_expired_video_consumption_number) + - (tb.monthly_bundle_limit_video_number - tb.monthly_bundle_limit_video_consumption_number) + - (tb.bundle_video_number - tb.bundle_video_consumption_number) + - (tb.increase_video_number - tb.increase_video_consumption_number) + - (tb.monthly_increase_limit_video_number - tb.monthly_increase_limit_video_consumption_number) + - (tb.monthly_increase_limit_expired_video_number - tb.monthly_increase_limit_expired_video_consumption_number) + - (tb.manual_video_number - tb.manual_video_consumption_number), - 0 - ) AS pending_video_count, - COALESCE( - (tb.monthly_bundle_limit_expired_image_number - tb.monthly_bundle_limit_expired_image_consumption_number) + - (tb.monthly_bundle_limit_image_number - tb.monthly_bundle_limit_image_consumption_number) + - (tb.bundle_image_number - tb.bundle_image_consumption_number) + - (tb.increase_image_number - tb.increase_image_consumption_number) + - (tb.monthly_increase_limit_image_number - tb.monthly_increase_limit_image_consumption_number) + - (tb.monthly_increase_limit_expired_image_number - tb.monthly_increase_limit_expired_image_consumption_number) + - (tb.manual_image_number - tb.manual_image_consumption_number), - 0 - ) AS pending_post_count, - COALESCE( - (tb.monthly_bundle_limit_expired_data_analysis_number - tb.monthly_bundle_limit_expired_data_analysis_consumption_number) + - (tb.monthly_bundle_limit_data_analysis_number - tb.monthly_bundle_limit_data_analysis_consumption_number) + - (tb.bundle_data_analysis_number - tb.bundle_data_analysis_consumption_number) + - (tb.increase_data_analysis_number - tb.increase_data_analysis_consumption_number) + - (tb.monthly_increase_limit_data_analysis_number - tb.monthly_increase_limit_data_analysis_consumption_number) + - (tb.monthly_increase_limit_expired_data_analysis_number - tb.monthly_increase_limit_expired_data_analysis_consumption_number) + - (tb.manual_data_analysis_number - tb.manual_data_analysis_consumption_number), - 0 - ) AS pending_data_count, - COALESCE( - (tb.monthly_bundle_limit_expired_video_number + - tb.monthly_bundle_limit_video_number + - tb.bundle_video_number + - tb.increase_video_number + - tb.monthly_increase_limit_video_number + - tb.monthly_increase_limit_expired_video_number + - tb.manual_video_number) , - 0 - ) AS released_video_count, - COALESCE( - (tb.monthly_bundle_limit_expired_image_number + - tb.monthly_bundle_limit_image_number + - tb.bundle_image_number + - tb.increase_image_number + - tb.monthly_increase_limit_image_number + - tb.monthly_increase_limit_expired_image_number + - tb.manual_image_number) , - 0 - ) AS released_post_count, - COALESCE( - (tb.monthly_bundle_limit_expired_data_analysis_number + - tb.monthly_bundle_limit_data_analysis_number + - tb.bundle_data_analysis_number + - tb.increase_data_analysis_number + - tb.monthly_increase_limit_data_analysis_number + - tb.monthly_increase_limit_expired_data_analysis_number + - tb.manual_data_analysis_number ) , - 0 - ) AS released_data_count, - COALESCE( - tb.monthly_bundle_limit_expired_video_consumption_number + - tb.monthly_bundle_limit_video_consumption_number + - tb.bundle_video_consumption_number + - tb.increase_video_consumption_number + - tb.monthly_increase_limit_video_consumption_number + - tb.monthly_increase_limit_expired_video_consumption_number + - tb.manual_video_consumption_number, - 0 - ) AS upload_video_count, - COALESCE( - tb.monthly_bundle_limit_expired_image_consumption_number + - tb.monthly_bundle_limit_image_consumption_number + - tb.bundle_image_consumption_number + - tb.increase_image_consumption_number + - tb.monthly_increase_limit_image_consumption_number + - tb.monthly_increase_limit_expired_image_consumption_number + - tb.manual_image_consumption_number, - 0 - ) AS upload_post_count, - COALESCE( - tb.monthly_bundle_limit_expired_data_analysis_consumption_number + - tb.monthly_bundle_limit_data_analysis_consumption_number + - tb.bundle_data_analysis_consumption_number + - tb.increase_data_analysis_consumption_number + - tb.monthly_increase_limit_data_analysis_consumption_number + - tb.monthly_increase_limit_expired_data_analysis_consumption_number + - tb.manual_data_analysis_consumption_number, - 0 - ) AS upload_data_count` - - query := app.ModuleClients.TaskBenchDB.Table("task_management tm"). - Select(selectFields). - Joins(`LEFT JOIN task_balance_new tb ON tm.sub_num = tb.sub_num AND - tb.id = ( - SELECT COALESCE( - (SELECT id FROM task_balance_new tb1 WHERE tb1.sub_num = tm.sub_num AND tb1.start_at <= ? AND tb1.expired_at >= ? ORDER BY tb1.start_at DESC LIMIT 1), - (SELECT id FROM task_balance_new tb2 WHERE tb2.sub_num = tm.sub_num ORDER BY tb2.start_at DESC LIMIT 1) - ) - )`, now, now). - Where("tm.sub_num IN ?", subNums) - - // 关键词搜索(支持 sub_num / tel_num / artist_name) - if req.Keyword != "" { - like := "%" + req.Keyword + "%" - query = query.Where("(tm.sub_num LIKE ? OR tm.tel_num LIKE ? OR tm.artist_name LIKE ?)", like, like, like) - } - - // 处理排序 - if req.SortBy != "" && req.SortType != "" { - sortType := req.SortType - if sortType != "asc" && sortType != "desc" && sortType != "ASC" && sortType != "DESC" { - sortType = "DESC" - } - - switch req.SortBy { - case "pending_video_count", "pendingVideoCount": - query = query.Order(fmt.Sprintf("pending_video_count %s", sortType)) - case "pending_post_count", "pendingPostCount": - query = query.Order(fmt.Sprintf("pending_post_count %s", sortType)) - case "pending_data_count", "pendingDataCount": - query = query.Order(fmt.Sprintf("pending_data_count %s", sortType)) - case "progress_count", "progressCount": - query = query.Order(fmt.Sprintf("progress_task_count %s", sortType)) - case "complete_count", "completeCount": - query = query.Order(fmt.Sprintf("complete_task_count %s", sortType)) - case "released_video_count", "releasedVideoCount": - query = query.Order(fmt.Sprintf("released_video_count %s", sortType)) - case "released_post_count", "releasedPostCount": - query = query.Order(fmt.Sprintf("released_post_count %s", sortType)) - case "released_data_count", "releasedDataCount": - query = query.Order(fmt.Sprintf("released_data_count %s", sortType)) - case "upload_video_count", "uploadVideoCount": - query = query.Order(fmt.Sprintf("upload_video_count %s", sortType)) - case "upload_post_count", "uploadPostCount": - query = query.Order(fmt.Sprintf("upload_post_count %s", sortType)) - case "upload_data_count", "uploadDataCount": - query = query.Order(fmt.Sprintf("upload_data_count %s", sortType)) - default: - query = query.Order("tm.sub_num ASC") - } - } else { - query = query.Order("tm.sub_num ASC") - } - - // 先查询总数(不分页) - var totalCount int64 - countQuery := app.ModuleClients.TaskBenchDB.Table("task_management tm"). - Joins(`LEFT JOIN task_balance_new tb ON tm.sub_num = tb.sub_num AND - tb.id = ( - SELECT COALESCE( - (SELECT id FROM task_balance_new tb1 WHERE tb1.sub_num = tm.sub_num AND tb1.start_at <= ? AND tb1.expired_at >= ? ORDER BY tb1.start_at DESC LIMIT 1), - (SELECT id FROM task_balance_new tb2 WHERE tb2.sub_num = tm.sub_num ORDER BY tb2.start_at DESC LIMIT 1) - ) - )`, now, now). - Where("tm.sub_num IN ?", subNums) - - if req.Keyword != "" { - like := "%" + req.Keyword + "%" - countQuery = countQuery.Where("(tm.sub_num LIKE ? OR tm.tel_num LIKE ? OR tm.artist_name LIKE ?)", like, like, like) - } - - if err := countQuery.Count(&totalCount).Error; err != nil { - return nil, 0, commonErr.ReturnError(err, "查询待指派任务记录总数失败", "查询待指派任务记录总数失败: ") - } - - // 处理分页 - if req.PageSize > 0 && req.Page > 0 { - offset := (req.Page - 1) * req.PageSize - query = query.Offset(offset).Limit(req.PageSize) - } - - // 执行查询 - var results []TaskQueryResponse - if err := query.Scan(&results).Error; err != nil { - return nil, 0, commonErr.ReturnError(err, "查询待指派任务记录失败", "查询待指派任务记录失败: ") - } - - // 构建返回结果 - resp := make([]*TaskQueryResponse, 0, len(results)) - for i := range results { - // 确保待发数量不为负数 - if results[i].PendingVideoCount < 0 { - results[i].PendingVideoCount = 0 - } - if results[i].PendingPostCount < 0 { - results[i].PendingPostCount = 0 - } - if results[i].PendingDataCount < 0 { - results[i].PendingDataCount = 0 - } - resp = append(resp, &results[i]) - } - - return resp, totalCount, nil -} - -// CreateMissingTaskManagementRecords 为有TaskBalance记录但没有TaskManagement记录的有效艺人创建TaskManagement记录 -// 说明:检查有效艺人列表,如果艺人在TaskBalance表中有记录但在TaskManagement表中没有记录,则创建记录 -// 新创建的记录中的待发任务数量将从TaskBalance表中计算得出,而不是默认为0 -func CreateMissingTaskManagementRecords(validArtist []ValidArtistInfo) error { - if len(validArtist) == 0 { - return nil - } - - // 提取有效艺人的艺人编号(sub_num) - subNums := make([]string, 0, len(validArtist)) - artistMap := make(map[string]ValidArtistInfo) - for _, a := range validArtist { - if a.CustomerNum != "" { - subNums = append(subNums, a.CustomerNum) - artistMap[a.CustomerNum] = a - } - } - - if len(subNums) == 0 { - return nil - } - - // 查询已存在的TaskManagement记录 - var existingTaskManagement []model.TaskManagement - if err := app.ModuleClients.TaskBenchDB.Where("sub_num IN ?", subNums).Find(&existingTaskManagement).Error; err != nil { - return commonErr.ReturnError(err, "查询现有任务管理记录失败", "查询现有任务管理记录失败: ") - } - - // 构建已存在的sub_num集合 - existingSubNums := make(map[string]struct{}) - for _, tm := range existingTaskManagement { - existingSubNums[tm.SubNum] = struct{}{} - } - - // 查询有TaskBalance记录的艺人 - now := time.Now() - var taskBalances []model.TaskBalance - if err := app.ModuleClients.TaskBenchDB.Where(`sub_num IN ? AND id IN ( - SELECT COALESCE( - (SELECT id FROM task_balance_new tb1 WHERE tb1.sub_num = task_balance_new.sub_num AND tb1.start_at <= ? AND tb1.expired_at >= ? ORDER BY tb1.start_at DESC LIMIT 1), - (SELECT id FROM task_balance_new tb2 WHERE tb2.sub_num = task_balance_new.sub_num ORDER BY tb2.start_at DESC LIMIT 1) - ) FROM task_balance_new WHERE sub_num IN ? GROUP BY sub_num - )`, subNums, now, now, subNums).Find(&taskBalances).Error; err != nil { - return commonErr.ReturnError(err, "查询任务余额记录失败", "查询任务余额记录失败: ") - } - - // 构建有TaskBalance记录的sub_num集合 - balanceSubNums := make(map[string]model.TaskBalance) - for _, tb := range taskBalances { - balanceSubNums[tb.SubNum] = tb - } - - // 找出需要创建TaskManagement记录的艺人(有TaskBalance记录但没有TaskManagement记录) - var recordsToCreate []model.TaskManagement - for _, artist := range validArtist { - if artist.CustomerNum == "" { - continue - } - - // 检查是否已存在TaskManagement记录 - if _, exists := existingSubNums[artist.CustomerNum]; exists { - continue - } - - // 检查是否有TaskBalance记录 - tb, hasBalance := balanceSubNums[artist.CustomerNum] - if !hasBalance { - continue - } - - // 计算待发任务数量(使用与GetPendingTaskList相同的计算逻辑) - pendingVideoCount := (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) - - pendingPostCount := (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) - - pendingDataCount := (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 pendingVideoCount < 0 { - pendingVideoCount = 0 - } - if pendingPostCount < 0 { - pendingPostCount = 0 - } - if pendingDataCount < 0 { - pendingDataCount = 0 - } - - // 为所有有TaskBalance记录的艺人创建TaskManagement记录,无论待发任务数量是否为0 - // 这样确保与GetPendingTaskList的additionalResults逻辑保持一致 - newRecord := model.TaskManagement{ - SubNum: artist.CustomerNum, - TelNum: artist.UserPhoneNumber, - ArtistName: artist.UserName, - LastTaskAssignee: "", - TaskAssigneeNum: "", - ProgressCount: 0, - CompleteCount: 0, - CreatedAt: time.Now(), - UpdatedAt: time.Now(), - } - recordsToCreate = append(recordsToCreate, newRecord) - } - - // 批量创建记录 - if len(recordsToCreate) > 0 { - if err := app.ModuleClients.TaskBenchDB.Create(&recordsToCreate).Error; err != nil { - return commonErr.ReturnError(err, "批量创建任务管理记录失败", "批量创建任务管理记录失败: ") - } - - // 记录日志 - zap.L().Info("成功为有效艺人创建TaskManagement记录", - zap.Int("创建记录数", len(recordsToCreate)), - zap.Any("创建的记录", recordsToCreate)) - } - - return nil -} - // CreateTaskWorkLogRequest 创建任务日志请求参数 type CreateTaskWorkLogRequest struct { AssignRecordsUUID string `json:"assignRecordsUUID"` // 任务指派记录UUID(必填) diff --git a/internal/logic/taskLogic.go b/internal/logic/taskLogic.go index 7d38965..c424924 100644 --- a/internal/logic/taskLogic.go +++ b/internal/logic/taskLogic.go @@ -9,13 +9,11 @@ import ( ) // GetValidArtistList 查询套餐状态为有效中的艺人列表 -// 调用dao层获取艺人详细信息 func GetValidArtistList() ([]dao.ValidArtistInfo, error) { return dao.GetValidArtistList() } // GetValidArtistIDs 查询套餐没有过期的艺人ID列表(保持向后兼容) -// 根据BundleOrderRecords表查询过期时间大于当前时间且状态为已支付的艺人 func GetValidArtistIDs() ([]string, error) { artistList, err := GetValidArtistList() if err != nil { @@ -34,8 +32,6 @@ func GetValidArtistIDs() ([]string, error) { // todo 目前暂时不做检验,后续需要做判断 // GetValidEmployeeIDs 查询可以被指派任务的员工ID列表 -// 这里可以根据实际业务需求实现,比如查询员工表、权限表等 -// 目前先返回一个示例实现,实际项目中需要根据具体的员工管理逻辑来实现 func GetValidEmployeeIDs() ([]string, error) { var employeeIDs []string @@ -63,33 +59,11 @@ 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) { 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) { return dao.GetPendingAssignBySubNums(subNums, page, pageSize) @@ -160,42 +134,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) @@ -290,7 +228,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 不能为空") @@ -404,65 +341,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 +426,7 @@ func AddHiddenTaskAssignee(taskAssignee string, taskAssigneeNum string) error { } // CreateTaskWorkLog 创建任务日志记录 -// 用于记录任务操作日志,包括加任务、消耗任务、完成任务、任务过期等操作 func CreateTaskWorkLog(req *dao.CreateTaskWorkLogRequest) error { - // 参数校验已在 DAO 层完成,这里可以添加额外的业务逻辑校验 - // 例如:校验操作类型是否合法、任务类型是否合法等 if req.OperationType < 1 || req.OperationType > 4 { return commonErr.ReturnError(nil, "参数错误", "操作类型必须在1-4之间") } diff --git a/pkg/cron/cron.go b/pkg/cron/cron.go index 40e3d87..5542d28 100644 --- a/pkg/cron/cron.go +++ b/pkg/cron/cron.go @@ -1,7 +1,6 @@ package cron import ( - "fmt" "log" "micro-bundle/internal/logic" @@ -11,14 +10,13 @@ import ( func InitCronJob() { c := cron.New(cron.WithSeconds()) - // 避免冲突,任务余额每月更新定时任务 - 每月1号1点执行 - taskBalanceSpec := "0 0 1 1 * *" - _, err := c.AddFunc(taskBalanceSpec, func() { - log.Printf("执行任务余额每月数据更新") - logic.UpdateTaskBalanceEveryMonLogic() + spec := "0 0 0 1 * *" + + _, err := c.AddFunc(spec, func() { + log.Printf("执行余量每月数据更新") + logic.UpdateBundleBalance() }) if err != nil { - fmt.Println("添加任务余额每月数据更新定时任务失败", err) panic(err) }