Compare commits

...

5 Commits

Author SHA1 Message Date
cjy
ad202d8739 Merge branch 'feat-cjy-taskBench' into dev
# Conflicts:
#	pb/bundle.proto
#	pb/bundle/bundle.pb.go
#	pb/bundle/bundle_triple.pb.go
2025-10-17 16:16:27 +08:00
cjy
5269d7e24c bugfix: 根据余额表细分的情况,将任务表细分,并添加任务余额表,不依赖套餐余额 2025-10-17 14:25:41 +08:00
cjy
6d0ccb0c9d Merge branch 'main' into feat-cjy-taskBench
# Conflicts:
#	pb/bundle/bundle.pb.go
#	pb/bundle/bundle_triple.pb.go
2025-10-16 16:45:28 +08:00
cjy
6b12c7441d bugfix:修改关于时间区间的处理 2025-10-16 16:16:50 +08:00
cjy
b82f4159ba bugfix: 修复查询报错 2025-10-16 16:16:50 +08:00
7 changed files with 2386 additions and 1347 deletions

View File

@ -268,29 +268,45 @@ func convertToTaskAssignRecordInfo(record *dao.TaskAssignRecordsResponse) *bundl
}
}
// GetArtistBundleBalance 查询艺人套餐剩余数量
// GetArtistBundleBalance 查询艺人的当前任务余额与待发数量(区分套餐/增值两类)
// 说明:
// - 查询条件优先使用艺人编号customerNum为空时使用手机号telNum
// - 返回同时包含“套餐类型”和“增值类型”的余额与待发数量,均按视频/图文/数据分析三类区分
func (b *BundleProvider) GetArtistBundleBalance(_ context.Context, req *bundle.ArtistBundleBalanceRequest) (*bundle.ArtistBundleBalanceResponse, error) {
// 参数验证
// 参数
if req.CustomerNum == "" && req.TelNum == "" {
return nil, fmt.Errorf("艺人编号和手机号不能同时为空")
}
// 转换请求参数
daoReq := &dao.ArtistBundleBalanceRequest{
CustomerNum: req.CustomerNum,
TelNum: req.TelNum,
// 组装查询参数(逻辑层/DAO层使用 SubNum 与 TelNum
pendingReq := &dao.PendingAndBalanceRequest{
SubNum: req.CustomerNum, // 映射 customerNum -> SubNum
TelNum: req.TelNum, // 映射 telNum -> TelNum
}
// 调用logic层
result, err := logic.GetArtistBundleBalance(daoReq)
// 调用逻辑层:查询待发数量与任务余额(区分套餐/增值)
resp, err := logic.GetPendingAndTaskBalances(pendingReq)
if err != nil {
return nil, err
}
// 转换响应数据
// 映射为proto响应结构套餐/增值分别返回视频/图文/数据分析的余额与待发数量)
return &bundle.ArtistBundleBalanceResponse{
RemainingVideoCount: int32(result.RemainingVideoCount),
RemainingImageCount: int32(result.RemainingImageCount),
RemainingDataAnalysisCount: int32(result.RemainingDataAnalysisCount),
// 套餐类型余额
BundleVideoBalance: int32(resp.BundleVideoBalance),
BundleImageBalance: int32(resp.BundleImageBalance),
BundleDataAnalysisBalance: int32(resp.BundleDataAnalysisBalance),
// 增值类型余额
IncreaseVideoBalance: int32(resp.IncreaseVideoBalance),
IncreaseImageBalance: int32(resp.IncreaseImageBalance),
IncreaseDataAnalysisBalance: int32(resp.IncreaseDataAnalysisBalance),
// 套餐类型待发数量
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
}

View File

@ -12,6 +12,90 @@ import (
"gorm.io/gorm"
)
// ===== 聚合和扣减的辅助函数 =====
// aggregatePendingVideo 汇总所有视频分类的待发数量
func aggregatePendingVideo(t *model.TaskManagement) int {
return t.PendingBundleLimitVideoExpiredCount + t.PendingBundleLimitVideoCount +
t.PendingIncreaseLimitVideoExpiredCount + t.PendingIncreaseLimitVideoCount +
t.PendingBundleVideoCount + t.PendingIncreaseVideoCount
}
// aggregatePendingImage 汇总所有图文分类的待发数量
func aggregatePendingImage(t *model.TaskManagement) int {
return t.PendingBundleLimitImageExpiredCount + t.PendingBundleLimitImageCount +
t.PendingIncreaseLimitImageExpiredCount + t.PendingIncreaseLimitImageCount +
t.PendingBundleImageCount + t.PendingIncreaseImageCount
}
// aggregatePendingData 汇总所有数据分析分类的待发数量
func aggregatePendingData(t *model.TaskManagement) int {
return t.PendingBundleLimitDataAnalysisExpiredCount + t.PendingBundleLimitDataAnalysisCount +
t.PendingIncreaseLimitDataAnalysisExpiredCount + t.PendingIncreaseLimitDataAnalysisCount +
t.PendingBundleDataAnalysisCount + t.PendingIncreaseDataAnalysisCount
}
// deductCount 按顺序从各个桶中扣减数量剩余未扣减数量应为0正常情况
func deductCount(count *int, buckets ...*int) {
if count == nil {
return
}
for _, b := range buckets {
if *count <= 0 {
break
}
if b == nil || *b <= 0 {
continue
}
if *b >= *count {
*b = *b - *count
*count = 0
} else {
*count = *count - *b
*b = 0
}
}
}
// deductVideo 视频扣减优先级:受限 > 非受限;同类型中:打包 > 增量;受限类型中:过期优先
func deductVideo(t *model.TaskManagement, n int) {
c := n
deductCount(&c,
&t.PendingBundleLimitVideoExpiredCount,
&t.PendingBundleLimitVideoCount,
&t.PendingIncreaseLimitVideoExpiredCount,
&t.PendingIncreaseLimitVideoCount,
&t.PendingBundleVideoCount,
&t.PendingIncreaseVideoCount,
)
}
// deductImage 图文扣减优先级:受限 > 非受限;同类型中:打包 > 增量;受限类型中:过期优先
func deductImage(t *model.TaskManagement, n int) {
c := n
deductCount(&c,
&t.PendingBundleLimitImageExpiredCount,
&t.PendingBundleLimitImageCount,
&t.PendingIncreaseLimitImageExpiredCount,
&t.PendingIncreaseLimitImageCount,
&t.PendingBundleImageCount,
&t.PendingIncreaseImageCount,
)
}
// deductData 数据分析扣减优先级:受限 > 非受限;同类型中:打包 > 增量;受限类型中:过期优先
func deductData(t *model.TaskManagement, n int) {
c := n
deductCount(&c,
&t.PendingBundleLimitDataAnalysisExpiredCount,
&t.PendingBundleLimitDataAnalysisCount,
&t.PendingIncreaseLimitDataAnalysisExpiredCount,
&t.PendingIncreaseLimitDataAnalysisCount,
&t.PendingBundleDataAnalysisCount,
&t.PendingIncreaseDataAnalysisCount,
)
}
// TaskQueryRequest 查询待指派任务记录请求参数
type TaskQueryRequest struct {
Keyword string `json:"keyword"` // 艺人姓名、编号、手机号搜索关键词
@ -162,6 +246,147 @@ type ArtistBundleBalanceResponse struct {
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"` // 增值数据分析余额
}
// calculateBundleBalances 计算套餐类别下的三类余额(视频/图文/数据分析)
// 余额=对应类别总数-对应类别已使用数;再将非限制、限制非过期、限制会过期三类相加
func calculateBundleBalances(tb *model.TaskBalance) (video int, image int, data int) {
// 视频套餐余额
video = (tb.TaskBundleVideoNumber - tb.TaskBundleVideoConsumptionNumber) +
(tb.TaskBundleLimitVideoNumber - tb.TaskBundleLimitVideoConsumptionNumber) +
(tb.TaskBundleLimitVideoExpiredNumber - tb.TaskBundleLimitVideoExpiredConsumptionNumber)
// 图文套餐余额
image = (tb.TaskBundleImageNumber - tb.TaskBundleImageConsumptionNumber) +
(tb.TaskBundleLimitImageNumber - tb.TaskBundleLimitImageConsumptionNumber) +
(tb.TaskBundleLimitImageExpiredNumber - tb.TaskBundleLimitImageExpiredConsumptionNumber)
// 数据分析套餐余额
data = (tb.TaskBundleDataAnalysisNumber - tb.TaskBundleDataAnalysisConsumptionNumber) +
(tb.TaskBundleLimitDataAnalysisNumber - tb.TaskBundleLimitDataAnalysisConsumptionNumber) +
(tb.TaskBundleLimitDataAnalysisExpiredNumber - tb.TaskBundleLimitDataAnalysisExpiredConsumptionNumber)
return
}
// calculateIncreaseBalances 计算增值类别下的三类余额(视频/图文/数据分析)
// 余额=对应类别总数-对应类别已使用数;再将非限制、限制非过期、限制会过期三类相加
func calculateIncreaseBalances(tb *model.TaskBalance) (video int, image int, data int) {
// 视频增值余额
video = (tb.TaskIncreaseVideoNumber - tb.TaskIncreaseVideoConsumptionNumber) +
(tb.TaskIncreaseLimitVideoNumber - tb.TaskIncreaseLimitVideoConsumptionNumber) +
(tb.TaskIncreaseLimitVideoExpiredNumber - tb.TaskIncreaseLimitVideoExpiredConsumptionNumber)
// 图文增值余额
image = (tb.TaskIncreaseImageNumber - tb.TaskIncreaseImageConsumptionNumber) +
(tb.TaskIncreaseLimitImageNumber - tb.TaskIncreaseLimitImageConsumptionNumber) +
(tb.TaskIncreaseLimitImageExpiredNumber - tb.TaskIncreaseLimitImageExpiredConsumptionNumber)
// 数据分析增值余额
data = (tb.TaskIncreaseDataAnalysisNumber - tb.TaskIncreaseDataAnalysisConsumptionNumber) +
(tb.TaskIncreaseLimitDataAnalysisNumber - tb.TaskIncreaseLimitDataAnalysisConsumptionNumber) +
(tb.TaskIncreaseLimitDataAnalysisExpiredNumber - tb.TaskIncreaseLimitDataAnalysisExpiredConsumptionNumber)
return
}
// GetUserPendingAndTaskBalances 查询用户待发套餐/增值数量与任务余额(套餐/增值)
// 待发数量来自 task_management余额来自 task_balance均按视频/图文/数据分析三类返回
// 待发聚合口径:将该类别下(套餐或增值)的非限制、限制非过期、限制会过期三类相加
// 余额聚合口径:对应类别总数减已使用数后,再将三类相加
func GetUserPendingAndTaskBalances(req *PendingAndBalanceRequest) (*PendingAndBalanceResponse, error) {
// 校验查询条件
if req.SubNum == "" && req.TelNum == "" {
return nil, commonErr.ReturnError(nil, "查询参数错误", "艺人编号和手机号不能同时为空")
}
// 查询任务管理表(待发)
var tm model.TaskManagement
tmQuery := app.ModuleClients.TaskBenchDB.Model(&model.TaskManagement{})
if req.SubNum != "" {
tmQuery = tmQuery.Where("sub_num = ?", req.SubNum)
} else {
tmQuery = tmQuery.Where("tel_num = ?", req.TelNum)
}
// 若不存在,待发视为 0
_ = tmQuery.Take(&tm).Error
// 聚合待发(套餐与增值分开统计)
pendingBundleVideo := tm.PendingBundleVideoCount + tm.PendingBundleLimitVideoCount + tm.PendingBundleLimitVideoExpiredCount
pendingBundleImage := tm.PendingBundleImageCount + tm.PendingBundleLimitImageCount + tm.PendingBundleLimitImageExpiredCount
pendingBundleData := tm.PendingBundleDataAnalysisCount + tm.PendingBundleLimitDataAnalysisCount + tm.PendingBundleLimitDataAnalysisExpiredCount
pendingIncreaseVideo := tm.PendingIncreaseVideoCount + tm.PendingIncreaseLimitVideoCount + tm.PendingIncreaseLimitVideoExpiredCount
pendingIncreaseImage := tm.PendingIncreaseImageCount + tm.PendingIncreaseLimitImageCount + tm.PendingIncreaseLimitImageExpiredCount
pendingIncreaseData := tm.PendingIncreaseDataAnalysisCount + tm.PendingIncreaseLimitDataAnalysisCount + tm.PendingIncreaseLimitDataAnalysisExpiredCount
// 查询任务余额表(当前有效月份优先)
var tb model.TaskBalance
now := time.Now()
tbQuery := app.ModuleClients.TaskBenchDB.Model(&model.TaskBalance{})
if req.SubNum != "" {
tbQuery = tbQuery.Where("sub_num = ?", req.SubNum)
} else {
tbQuery = tbQuery.Where("tel_num = ?", req.TelNum)
}
// 选择当前有效区间的记录,若无则回退到最近一条
err := tbQuery.Where("start_at <= ? AND expired_at >= ?", now, now).Order("start_at DESC").Take(&tb).Error
if err != nil {
// 回退:取最近一条记录(可能没有有效期覆盖 now
_ = tbQuery.Order("start_at DESC").Take(&tb).Error
}
// 计算套餐与增值余额
bundleVideo, bundleImage, bundleData := calculateBundleBalances(&tb)
increaseVideo, increaseImage, increaseData := calculateIncreaseBalances(&tb)
resp := &PendingAndBalanceResponse{
PendingBundleVideoCount: pendingBundleVideo,
PendingBundleImageCount: pendingBundleImage,
PendingBundleDataAnalysisCount: pendingBundleData,
PendingIncreaseVideoCount: pendingIncreaseVideo,
PendingIncreaseImageCount: pendingIncreaseImage,
PendingIncreaseDataAnalysisCount: pendingIncreaseData,
BundleVideoBalance: bundleVideo,
BundleImageBalance: bundleImage,
BundleDataAnalysisBalance: bundleData,
IncreaseVideoBalance: increaseVideo,
IncreaseImageBalance: increaseImage,
IncreaseDataAnalysisBalance: increaseData,
}
return resp, nil
}
// GetPendingTaskList 查询待指派任务记录
// 根据套餐没有过期的艺人查询TaskManagement表中的记录如果不存在则构建默认值
func GetPendingTaskList(req *TaskQueryRequest, validArtist []ValidArtistInfo) ([]*model.TaskManagement, int64, error) {
@ -204,13 +429,49 @@ func GetPendingTaskList(req *TaskQueryRequest, validArtist []ValidArtistInfo) ([
if !existingSubNums[subNum] {
artist := artistMap[subNum]
// 构建默认任务记录
// 默认将剩余数量分配到“非限制-套餐权益”类别,其它类别置零
remainingVideo := artist.VideoNumber - artist.VideoConsumptionNumber
remainingImage := artist.ImageNumber - artist.ImageConsumptionNumber
remainingData := artist.DataAnalysisNumber - artist.DataAnalysisConsumptionNumber
if remainingVideo < 0 {
remainingVideo = 0
}
if remainingImage < 0 {
remainingImage = 0
}
if remainingData < 0 {
remainingData = 0
}
defaultTask := &model.TaskManagement{
SubNum: subNum,
TelNum: artist.UserPhoneNumber,
ArtistName: artist.UserName,
PendingVideoCount: artist.VideoNumber - artist.VideoConsumptionNumber,
PendingPostCount: artist.ImageNumber - artist.ImageConsumptionNumber,
PendingDataCount: artist.DataAnalysisNumber - artist.DataAnalysisConsumptionNumber,
// 视频
PendingBundleVideoCount: remainingVideo,
PendingIncreaseVideoCount: 0,
PendingBundleLimitVideoCount: 0,
PendingIncreaseLimitVideoCount: 0,
PendingBundleLimitVideoExpiredCount: 0,
PendingIncreaseLimitVideoExpiredCount: 0,
// 图片
PendingBundleImageCount: remainingImage,
PendingIncreaseImageCount: 0,
PendingBundleLimitImageCount: 0,
PendingIncreaseLimitImageCount: 0,
PendingBundleLimitImageExpiredCount: 0,
PendingIncreaseLimitImageExpiredCount: 0,
// 数据分析
PendingBundleDataAnalysisCount: remainingData,
PendingIncreaseDataAnalysisCount: 0,
PendingBundleLimitDataAnalysisCount: 0,
PendingIncreaseLimitDataAnalysisCount: 0,
PendingBundleLimitDataAnalysisExpiredCount: 0,
PendingIncreaseLimitDataAnalysisExpiredCount: 0,
ProgressCount: 0,
CompleteCount: 0,
CreatedAt: time.Now(),
@ -248,11 +509,25 @@ func GetPendingTaskList(req *TaskQueryRequest, validArtist []ValidArtistInfo) ([
// 排序
if req.SortBy != "" && req.SortType != "" {
orderClause := fmt.Sprintf("%s %s", req.SortBy, req.SortType)
sortBy := req.SortBy
sortType := req.SortType
if sortType != "asc" && sortType != "desc" && sortType != "ASC" && sortType != "DESC" {
sortType = "DESC"
}
// 将常用聚合字段映射为详细字段总和表达式
switch sortBy {
case "pending_video_count", "pendingVideoCount":
sortBy = "(pending_bundle_limit_video_expired_count + pending_bundle_limit_video_count + pending_increase_limit_video_expired_count + pending_increase_limit_video_count + pending_bundle_video_count + pending_increase_video_count)"
case "pending_post_count", "pendingPostCount":
sortBy = "(pending_bundle_limit_image_expired_count + pending_bundle_limit_image_count + pending_increase_limit_image_expired_count + pending_increase_limit_image_count + pending_bundle_image_count + pending_increase_image_count)"
case "pending_data_count", "pendingDataCount":
sortBy = "(pending_bundle_limit_data_analysis_expired_count + pending_bundle_limit_data_analysis_count + pending_increase_limit_data_analysis_expired_count + pending_increase_limit_data_analysis_count + pending_bundle_data_analysis_count + pending_increase_data_analysis_count)"
}
orderClause := fmt.Sprintf("%s %s", sortBy, sortType)
query = query.Order(orderClause)
} else {
// 默认按待发视频降序
query = query.Order("pending_video_count DESC")
// 默认按待发视频总和降序
query = query.Order("(pending_bundle_limit_video_expired_count + pending_bundle_limit_video_count + pending_increase_limit_video_expired_count + pending_increase_limit_video_count + pending_bundle_video_count + pending_increase_video_count) DESC")
}
// 分页
@ -289,9 +564,30 @@ func AssignTask(req *TaskAssignRequest, progressTaskCount int, completeTaskCount
SubNum: req.SubNum,
TelNum: req.TelNum,
ArtistName: req.ArtistName,
PendingVideoCount: 0,
PendingPostCount: 0,
PendingDataCount: 0,
// 待发视频
PendingBundleVideoCount: 0,
PendingIncreaseVideoCount: 0,
PendingBundleLimitVideoCount: 0,
PendingIncreaseLimitVideoCount: 0,
PendingBundleLimitVideoExpiredCount: 0,
PendingIncreaseLimitVideoExpiredCount: 0,
// 待发图片
PendingBundleImageCount: 0,
PendingIncreaseImageCount: 0,
PendingBundleLimitImageCount: 0,
PendingIncreaseLimitImageCount: 0,
PendingBundleLimitImageExpiredCount: 0,
PendingIncreaseLimitImageExpiredCount: 0,
// 待发数据分析
PendingBundleDataAnalysisCount: 0,
PendingIncreaseDataAnalysisCount: 0,
PendingBundleLimitDataAnalysisCount: 0,
PendingIncreaseLimitDataAnalysisCount: 0,
PendingBundleLimitDataAnalysisExpiredCount: 0,
PendingIncreaseLimitDataAnalysisExpiredCount: 0,
// 其他字段
ProgressCount: 0,
CompleteCount: 0,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
@ -305,8 +601,8 @@ func AssignTask(req *TaskAssignRequest, progressTaskCount int, completeTaskCount
}
}
// 2. 检查待发数量是否大于0
if taskManagement.PendingVideoCount <= 0 && taskManagement.PendingPostCount <= 0 && taskManagement.PendingDataCount <= 0 {
// 2. 检查待发数量是否大于0(聚合总和)
if aggregatePendingVideo(&taskManagement) <= 0 && aggregatePendingImage(&taskManagement) <= 0 && aggregatePendingData(&taskManagement) <= 0 {
tx.Rollback()
return commonErr.ReturnError(nil, "无可指派任务", "当前艺人待发视频数、图文数、数据数均为0无法指派任务")
}
@ -317,13 +613,13 @@ func AssignTask(req *TaskAssignRequest, progressTaskCount int, completeTaskCount
return commonErr.ReturnError(nil, "指派数量不能为负数", "指派数量必须大于等于0")
}
if req.AssignVideoCount > taskManagement.PendingVideoCount ||
req.AssignPostCount > taskManagement.PendingPostCount ||
req.AssignDataCount > taskManagement.PendingDataCount {
if req.AssignVideoCount > aggregatePendingVideo(&taskManagement) ||
req.AssignPostCount > aggregatePendingImage(&taskManagement) ||
req.AssignDataCount > aggregatePendingData(&taskManagement) {
tx.Rollback()
return commonErr.ReturnError(nil, "指派数量超出限制",
fmt.Sprintf("指派数量不能超过待发数量。当前待发:视频%d图文%d数据%d",
taskManagement.PendingVideoCount, taskManagement.PendingPostCount, taskManagement.PendingDataCount))
aggregatePendingVideo(&taskManagement), aggregatePendingImage(&taskManagement), aggregatePendingData(&taskManagement)))
}
if req.AssignVideoCount == 0 && req.AssignPostCount == 0 && req.AssignDataCount == 0 {
@ -331,11 +627,41 @@ func AssignTask(req *TaskAssignRequest, progressTaskCount int, completeTaskCount
return commonErr.ReturnError(nil, "指派数量不能全为0", "至少需要指派一种类型的任务")
}
// 4. 更新TaskManagement表
// 4. 按优先级扣减详细待发数量
if req.AssignVideoCount > 0 {
deductVideo(&taskManagement, req.AssignVideoCount)
}
if req.AssignPostCount > 0 {
deductImage(&taskManagement, req.AssignPostCount)
}
if req.AssignDataCount > 0 {
deductData(&taskManagement, req.AssignDataCount)
}
// 汇总更新字段
updateData := map[string]interface{}{
"pending_video_count": taskManagement.PendingVideoCount - req.AssignVideoCount,
"pending_post_count": taskManagement.PendingPostCount - req.AssignPostCount,
"pending_data_count": taskManagement.PendingDataCount - req.AssignDataCount,
// 视频
"pending_bundle_limit_video_expired_count": taskManagement.PendingBundleLimitVideoExpiredCount,
"pending_bundle_limit_video_count": taskManagement.PendingBundleLimitVideoCount,
"pending_increase_limit_video_expired_count": taskManagement.PendingIncreaseLimitVideoExpiredCount,
"pending_increase_limit_video_count": taskManagement.PendingIncreaseLimitVideoCount,
"pending_bundle_video_count": taskManagement.PendingBundleVideoCount,
"pending_increase_video_count": taskManagement.PendingIncreaseVideoCount,
// 图片
"pending_bundle_limit_image_expired_count": taskManagement.PendingBundleLimitImageExpiredCount,
"pending_bundle_limit_image_count": taskManagement.PendingBundleLimitImageCount,
"pending_increase_limit_image_expired_count": taskManagement.PendingIncreaseLimitImageExpiredCount,
"pending_increase_limit_image_count": taskManagement.PendingIncreaseLimitImageCount,
"pending_bundle_image_count": taskManagement.PendingBundleImageCount,
"pending_increase_image_count": taskManagement.PendingIncreaseImageCount,
// 数据分析
"pending_bundle_limit_data_analysis_expired_count": taskManagement.PendingBundleLimitDataAnalysisExpiredCount,
"pending_bundle_limit_data_analysis_count": taskManagement.PendingBundleLimitDataAnalysisCount,
"pending_increase_limit_data_analysis_expired_count": taskManagement.PendingIncreaseLimitDataAnalysisExpiredCount,
"pending_increase_limit_data_analysis_count": taskManagement.PendingIncreaseLimitDataAnalysisCount,
"pending_bundle_data_analysis_count": taskManagement.PendingBundleDataAnalysisCount,
"pending_increase_data_analysis_count": taskManagement.PendingIncreaseDataAnalysisCount,
// 其他字段
"last_task_assignee": req.TaskAssignee,
"task_assignee_num": req.TaskAssigneeNum,
"progress_count": progressTaskCount,
@ -362,9 +688,9 @@ func AssignTask(req *TaskAssignRequest, progressTaskCount int, completeTaskCount
OperatorTime: time.Now(),
TaskAssignee: req.TaskAssignee, // 指派员工姓名
TaskAssigneeNum: req.TaskAssigneeNum, // 指派员工账号
PendingVideoCount: taskManagement.PendingVideoCount,
PendingPostCount: taskManagement.PendingPostCount,
PendingDataCount: taskManagement.PendingDataCount,
PendingVideoCount: aggregatePendingVideo(&taskManagement),
PendingPostCount: aggregatePendingImage(&taskManagement),
PendingDataCount: aggregatePendingData(&taskManagement),
AssignVideoCount: req.AssignVideoCount,
AssignPostCount: req.AssignPostCount,
AssignDataCount: req.AssignDataCount,
@ -400,7 +726,14 @@ func UpdatePendingCount(req *UpdatePendingCountRequest) error {
// 1. 查询或创建TaskManagement记录
var taskManagement model.TaskManagement
err := tx.Where("sub_num = ? AND tel_num = ?", req.SubNum, req.TelNum).First(&taskManagement).Error
// 与查询余额保持一致:优先使用 sub_num否则使用 tel_num
tmQuery := tx.Model(&model.TaskManagement{})
if req.SubNum != "" {
tmQuery = tmQuery.Where("sub_num = ?", req.SubNum)
} else {
tmQuery = tmQuery.Where("tel_num = ?", req.TelNum)
}
err := tmQuery.First(&taskManagement).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return commonErr.ReturnError(err, "无该艺人任务记录", "无该艺人任务记录")
@ -408,18 +741,356 @@ func UpdatePendingCount(req *UpdatePendingCountRequest) error {
tx.Rollback()
return commonErr.ReturnError(err, "查询任务记录失败", "查询任务记录失败: ")
}
}
// 2. 查询任务余额记录(当前有效月份优先,若无则回退到最近一条)
var taskBalance model.TaskBalance
now := time.Now()
tbQuery := tx.Model(&model.TaskBalance{})
if req.SubNum != "" {
tbQuery = tbQuery.Where("sub_num = ?", req.SubNum)
} else {
// 更新现有记录
tbQuery = tbQuery.Where("tel_num = ?", req.TelNum)
}
tbErr := tbQuery.Where("start_at <= ? AND expired_at >= ?", now, now).Order("start_at DESC").Take(&taskBalance).Error
if tbErr != nil {
// 回退:取最近一条记录
_ = tbQuery.Order("start_at DESC").Take(&taskBalance).Error
}
// 若余额记录不存在,且本次需要“扣返余额”(目标小于当前)或“占用余额”(目标大于当前),直接报错
// 说明:此处不创建余额记录,避免无源数据导致余额错账
hasBalanceRecord := taskBalance.ID != 0
// 3. 计算当前聚合待发与目标值的差异(目标为绝对值,不是增减)
curVideo := aggregatePendingVideo(&taskManagement)
curImage := aggregatePendingImage(&taskManagement)
curData := aggregatePendingData(&taskManagement)
diffVideo := req.PendingVideoCount - curVideo
diffImage := req.PendingPostCount - curImage
diffData := req.PendingDataCount - curData
// 4. 若需要增加目标diff>0从艺人余额中按优先级占用并分配到待发分类
// 优先级:受限>非受限;同类型:打包>增量;受限内:过期优先
if diffVideo > 0 || diffImage > 0 || diffData > 0 {
if !hasBalanceRecord {
tx.Rollback()
return commonErr.ReturnError(nil, "无可用任务余额记录", "该艺人没有任务余额记录,无法占用余额用于增加待发")
}
// 视频占用
if diffVideo > 0 {
need := diffVideo
// 可用余额按分类拆分
availBLE := taskBalance.TaskBundleLimitVideoExpiredNumber - taskBalance.TaskBundleLimitVideoExpiredConsumptionNumber
availILE := taskBalance.TaskIncreaseLimitVideoExpiredNumber - taskBalance.TaskIncreaseLimitVideoExpiredConsumptionNumber
availBL := taskBalance.TaskBundleLimitVideoNumber - taskBalance.TaskBundleLimitVideoConsumptionNumber
availIL := taskBalance.TaskIncreaseLimitVideoNumber - taskBalance.TaskIncreaseLimitVideoConsumptionNumber
availB := taskBalance.TaskBundleVideoNumber - taskBalance.TaskBundleVideoConsumptionNumber
availI := taskBalance.TaskIncreaseVideoNumber - taskBalance.TaskIncreaseVideoConsumptionNumber
// 逐类占用并写入待发分类与消费数
if need > 0 && availBLE > 0 {
take := minInt(need, availBLE)
taskManagement.PendingBundleLimitVideoExpiredCount += take
taskBalance.TaskBundleLimitVideoExpiredConsumptionNumber += take
need -= take
}
if need > 0 && availILE > 0 {
take := minInt(need, availILE)
taskManagement.PendingIncreaseLimitVideoExpiredCount += take
taskBalance.TaskIncreaseLimitVideoExpiredConsumptionNumber += take
need -= take
}
if need > 0 && availBL > 0 {
take := minInt(need, availBL)
taskManagement.PendingBundleLimitVideoCount += take
taskBalance.TaskBundleLimitVideoConsumptionNumber += take
need -= take
}
if need > 0 && availIL > 0 {
take := minInt(need, availIL)
taskManagement.PendingIncreaseLimitVideoCount += take
taskBalance.TaskIncreaseLimitVideoConsumptionNumber += take
need -= take
}
if need > 0 && availB > 0 {
take := minInt(need, availB)
taskManagement.PendingBundleVideoCount += take
taskBalance.TaskBundleVideoConsumptionNumber += take
need -= take
}
if need > 0 && availI > 0 {
take := minInt(need, availI)
taskManagement.PendingIncreaseVideoCount += take
taskBalance.TaskIncreaseVideoConsumptionNumber += take
need -= take
}
if need > 0 {
tx.Rollback()
return commonErr.ReturnError(nil, "视频任务余额不足", "可用余额不足以达到目标待发视频数量")
}
}
// 图片占用
if diffImage > 0 {
need := diffImage
availBLE := taskBalance.TaskBundleLimitImageExpiredNumber - taskBalance.TaskBundleLimitImageExpiredConsumptionNumber
availILE := taskBalance.TaskIncreaseLimitImageExpiredNumber - taskBalance.TaskIncreaseLimitImageExpiredConsumptionNumber
availBL := taskBalance.TaskBundleLimitImageNumber - taskBalance.TaskBundleLimitImageConsumptionNumber
availIL := taskBalance.TaskIncreaseLimitImageNumber - taskBalance.TaskIncreaseLimitImageConsumptionNumber
availB := taskBalance.TaskBundleImageNumber - taskBalance.TaskBundleImageConsumptionNumber
availI := taskBalance.TaskIncreaseImageNumber - taskBalance.TaskIncreaseImageConsumptionNumber
if need > 0 && availBLE > 0 {
take := minInt(need, availBLE)
taskManagement.PendingBundleLimitImageExpiredCount += take
taskBalance.TaskBundleLimitImageExpiredConsumptionNumber += take
need -= take
}
if need > 0 && availILE > 0 {
take := minInt(need, availILE)
taskManagement.PendingIncreaseLimitImageExpiredCount += take
taskBalance.TaskIncreaseLimitImageExpiredConsumptionNumber += take
need -= take
}
if need > 0 && availBL > 0 {
take := minInt(need, availBL)
taskManagement.PendingBundleLimitImageCount += take
taskBalance.TaskBundleLimitImageConsumptionNumber += take
need -= take
}
if need > 0 && availIL > 0 {
take := minInt(need, availIL)
taskManagement.PendingIncreaseLimitImageCount += take
taskBalance.TaskIncreaseLimitImageConsumptionNumber += take
need -= take
}
if need > 0 && availB > 0 {
take := minInt(need, availB)
taskManagement.PendingBundleImageCount += take
taskBalance.TaskBundleImageConsumptionNumber += take
need -= take
}
if need > 0 && availI > 0 {
take := minInt(need, availI)
taskManagement.PendingIncreaseImageCount += take
taskBalance.TaskIncreaseImageConsumptionNumber += take
need -= take
}
if need > 0 {
tx.Rollback()
return commonErr.ReturnError(nil, "图文任务余额不足", "可用余额不足以达到目标待发图文数量")
}
}
// 数据分析占用
if diffData > 0 {
need := diffData
availBLE := taskBalance.TaskBundleLimitDataAnalysisExpiredNumber - taskBalance.TaskBundleLimitDataAnalysisExpiredConsumptionNumber
availILE := taskBalance.TaskIncreaseLimitDataAnalysisExpiredNumber - taskBalance.TaskIncreaseLimitDataAnalysisExpiredConsumptionNumber
availBL := taskBalance.TaskBundleLimitDataAnalysisNumber - taskBalance.TaskBundleLimitDataAnalysisConsumptionNumber
availIL := taskBalance.TaskIncreaseLimitDataAnalysisNumber - taskBalance.TaskIncreaseLimitDataAnalysisConsumptionNumber
availB := taskBalance.TaskBundleDataAnalysisNumber - taskBalance.TaskBundleDataAnalysisConsumptionNumber
availI := taskBalance.TaskIncreaseDataAnalysisNumber - taskBalance.TaskIncreaseDataAnalysisConsumptionNumber
if need > 0 && availBLE > 0 {
take := minInt(need, availBLE)
taskManagement.PendingBundleLimitDataAnalysisExpiredCount += take
taskBalance.TaskBundleLimitDataAnalysisExpiredConsumptionNumber += take
need -= take
}
if need > 0 && availILE > 0 {
take := minInt(need, availILE)
taskManagement.PendingIncreaseLimitDataAnalysisExpiredCount += take
taskBalance.TaskIncreaseLimitDataAnalysisExpiredConsumptionNumber += take
need -= take
}
if need > 0 && availBL > 0 {
take := minInt(need, availBL)
taskManagement.PendingBundleLimitDataAnalysisCount += take
taskBalance.TaskBundleLimitDataAnalysisConsumptionNumber += take
need -= take
}
if need > 0 && availIL > 0 {
take := minInt(need, availIL)
taskManagement.PendingIncreaseLimitDataAnalysisCount += take
taskBalance.TaskIncreaseLimitDataAnalysisConsumptionNumber += take
need -= take
}
if need > 0 && availB > 0 {
take := minInt(need, availB)
taskManagement.PendingBundleDataAnalysisCount += take
taskBalance.TaskBundleDataAnalysisConsumptionNumber += take
need -= take
}
if need > 0 && availI > 0 {
take := minInt(need, availI)
taskManagement.PendingIncreaseDataAnalysisCount += take
taskBalance.TaskIncreaseDataAnalysisConsumptionNumber += take
need -= take
}
if need > 0 {
tx.Rollback()
return commonErr.ReturnError(nil, "数据分析任务余额不足", "可用余额不足以达到目标待发数据分析数量")
}
}
}
// 5. 若需要减少目标diff<0先按优先级从待发分类扣减并将扣减的数量按对应分类冲回余额减少消费数
if diffVideo < 0 || diffImage < 0 || diffData < 0 {
if !hasBalanceRecord {
tx.Rollback()
return commonErr.ReturnError(nil, "无可用任务余额记录", "该艺人没有任务余额记录,无法将多余待发冲回余额")
}
// 视频冲回
if diffVideo < 0 {
refund := -diffVideo
// 记录扣减前的各分类待发值
prevBLE := taskManagement.PendingBundleLimitVideoExpiredCount
prevILE := taskManagement.PendingIncreaseLimitVideoExpiredCount
prevBL := taskManagement.PendingBundleLimitVideoCount
prevIL := taskManagement.PendingIncreaseLimitVideoCount
prevB := taskManagement.PendingBundleVideoCount
prevI := taskManagement.PendingIncreaseVideoCount
deductVideo(&taskManagement, refund)
// 计算各分类被扣减的数量并减少对应消费数不可小于0
removedBLE := prevBLE - taskManagement.PendingBundleLimitVideoExpiredCount
removedILE := prevILE - taskManagement.PendingIncreaseLimitVideoExpiredCount
removedBL := prevBL - taskManagement.PendingBundleLimitVideoCount
removedIL := prevIL - taskManagement.PendingIncreaseLimitVideoCount
removedB := prevB - taskManagement.PendingBundleVideoCount
removedI := prevI - taskManagement.PendingIncreaseVideoCount
taskBalance.TaskBundleLimitVideoExpiredConsumptionNumber = maxInt(0, taskBalance.TaskBundleLimitVideoExpiredConsumptionNumber-removedBLE)
taskBalance.TaskIncreaseLimitVideoExpiredConsumptionNumber = maxInt(0, taskBalance.TaskIncreaseLimitVideoExpiredConsumptionNumber-removedILE)
taskBalance.TaskBundleLimitVideoConsumptionNumber = maxInt(0, taskBalance.TaskBundleLimitVideoConsumptionNumber-removedBL)
taskBalance.TaskIncreaseLimitVideoConsumptionNumber = maxInt(0, taskBalance.TaskIncreaseLimitVideoConsumptionNumber-removedIL)
taskBalance.TaskBundleVideoConsumptionNumber = maxInt(0, taskBalance.TaskBundleVideoConsumptionNumber-removedB)
taskBalance.TaskIncreaseVideoConsumptionNumber = maxInt(0, taskBalance.TaskIncreaseVideoConsumptionNumber-removedI)
}
// 图片冲回
if diffImage < 0 {
refund := -diffImage
prevBLE := taskManagement.PendingBundleLimitImageExpiredCount
prevILE := taskManagement.PendingIncreaseLimitImageExpiredCount
prevBL := taskManagement.PendingBundleLimitImageCount
prevIL := taskManagement.PendingIncreaseLimitImageCount
prevB := taskManagement.PendingBundleImageCount
prevI := taskManagement.PendingIncreaseImageCount
deductImage(&taskManagement, refund)
removedBLE := prevBLE - taskManagement.PendingBundleLimitImageExpiredCount
removedILE := prevILE - taskManagement.PendingIncreaseLimitImageExpiredCount
removedBL := prevBL - taskManagement.PendingBundleLimitImageCount
removedIL := prevIL - taskManagement.PendingIncreaseLimitImageCount
removedB := prevB - taskManagement.PendingBundleImageCount
removedI := prevI - taskManagement.PendingIncreaseImageCount
taskBalance.TaskBundleLimitImageExpiredConsumptionNumber = maxInt(0, taskBalance.TaskBundleLimitImageExpiredConsumptionNumber-removedBLE)
taskBalance.TaskIncreaseLimitImageExpiredConsumptionNumber = maxInt(0, taskBalance.TaskIncreaseLimitImageExpiredConsumptionNumber-removedILE)
taskBalance.TaskBundleLimitImageConsumptionNumber = maxInt(0, taskBalance.TaskBundleLimitImageConsumptionNumber-removedBL)
taskBalance.TaskIncreaseLimitImageConsumptionNumber = maxInt(0, taskBalance.TaskIncreaseLimitImageConsumptionNumber-removedIL)
taskBalance.TaskBundleImageConsumptionNumber = maxInt(0, taskBalance.TaskBundleImageConsumptionNumber-removedB)
taskBalance.TaskIncreaseImageConsumptionNumber = maxInt(0, taskBalance.TaskIncreaseImageConsumptionNumber-removedI)
}
// 数据分析冲回
if diffData < 0 {
refund := -diffData
prevBLE := taskManagement.PendingBundleLimitDataAnalysisExpiredCount
prevILE := taskManagement.PendingIncreaseLimitDataAnalysisExpiredCount
prevBL := taskManagement.PendingBundleLimitDataAnalysisCount
prevIL := taskManagement.PendingIncreaseLimitDataAnalysisCount
prevB := taskManagement.PendingBundleDataAnalysisCount
prevI := taskManagement.PendingIncreaseDataAnalysisCount
deductData(&taskManagement, refund)
removedBLE := prevBLE - taskManagement.PendingBundleLimitDataAnalysisExpiredCount
removedILE := prevILE - taskManagement.PendingIncreaseLimitDataAnalysisExpiredCount
removedBL := prevBL - taskManagement.PendingBundleLimitDataAnalysisCount
removedIL := prevIL - taskManagement.PendingIncreaseLimitDataAnalysisCount
removedB := prevB - taskManagement.PendingBundleDataAnalysisCount
removedI := prevI - taskManagement.PendingIncreaseDataAnalysisCount
taskBalance.TaskBundleLimitDataAnalysisExpiredConsumptionNumber = maxInt(0, taskBalance.TaskBundleLimitDataAnalysisExpiredConsumptionNumber-removedBLE)
taskBalance.TaskIncreaseLimitDataAnalysisExpiredConsumptionNumber = maxInt(0, taskBalance.TaskIncreaseLimitDataAnalysisExpiredConsumptionNumber-removedILE)
taskBalance.TaskBundleLimitDataAnalysisConsumptionNumber = maxInt(0, taskBalance.TaskBundleLimitDataAnalysisConsumptionNumber-removedBL)
taskBalance.TaskIncreaseLimitDataAnalysisConsumptionNumber = maxInt(0, taskBalance.TaskIncreaseLimitDataAnalysisConsumptionNumber-removedIL)
taskBalance.TaskBundleDataAnalysisConsumptionNumber = maxInt(0, taskBalance.TaskBundleDataAnalysisConsumptionNumber-removedB)
taskBalance.TaskIncreaseDataAnalysisConsumptionNumber = maxInt(0, taskBalance.TaskIncreaseDataAnalysisConsumptionNumber-removedI)
}
}
// 6. 更新TaskManagement表
updateData := map[string]interface{}{
"pending_video_count": req.PendingVideoCount,
"pending_post_count": req.PendingPostCount,
"pending_data_count": req.PendingDataCount,
// 视频
"pending_bundle_limit_video_expired_count": taskManagement.PendingBundleLimitVideoExpiredCount,
"pending_bundle_limit_video_count": taskManagement.PendingBundleLimitVideoCount,
"pending_increase_limit_video_expired_count": taskManagement.PendingIncreaseLimitVideoExpiredCount,
"pending_increase_limit_video_count": taskManagement.PendingIncreaseLimitVideoCount,
"pending_bundle_video_count": taskManagement.PendingBundleVideoCount,
"pending_increase_video_count": taskManagement.PendingIncreaseVideoCount,
// 图片
"pending_bundle_limit_image_expired_count": taskManagement.PendingBundleLimitImageExpiredCount,
"pending_bundle_limit_image_count": taskManagement.PendingBundleLimitImageCount,
"pending_increase_limit_image_expired_count": taskManagement.PendingIncreaseLimitImageExpiredCount,
"pending_increase_limit_image_count": taskManagement.PendingIncreaseLimitImageCount,
"pending_bundle_image_count": taskManagement.PendingBundleImageCount,
"pending_increase_image_count": taskManagement.PendingIncreaseImageCount,
// 数据分析
"pending_bundle_limit_data_analysis_expired_count": taskManagement.PendingBundleLimitDataAnalysisExpiredCount,
"pending_bundle_limit_data_analysis_count": taskManagement.PendingBundleLimitDataAnalysisCount,
"pending_increase_limit_data_analysis_expired_count": taskManagement.PendingIncreaseLimitDataAnalysisExpiredCount,
"pending_increase_limit_data_analysis_count": taskManagement.PendingIncreaseLimitDataAnalysisCount,
"pending_bundle_data_analysis_count": taskManagement.PendingBundleDataAnalysisCount,
"pending_increase_data_analysis_count": taskManagement.PendingIncreaseDataAnalysisCount,
// 通用
"updated_at": time.Now(),
}
if err = tx.Model(&taskManagement).Updates(updateData).Error; err != nil {
tx.Rollback()
return commonErr.ReturnError(err, "更新任务记录失败", "更新任务记录失败: ")
}
// 7. 更新TaskBalance消费数发生变化时
if hasBalanceRecord {
updateBal := map[string]interface{}{
// 视频消费数
"task_bundle_limit_video_expired_consumption_number": taskBalance.TaskBundleLimitVideoExpiredConsumptionNumber,
"task_increase_limit_video_expired_consumption_number": taskBalance.TaskIncreaseLimitVideoExpiredConsumptionNumber,
"task_bundle_limit_video_consumption_number": taskBalance.TaskBundleLimitVideoConsumptionNumber,
"task_increase_limit_video_consumption_number": taskBalance.TaskIncreaseLimitVideoConsumptionNumber,
"task_bundle_video_consumption_number": taskBalance.TaskBundleVideoConsumptionNumber,
"task_increase_video_consumption_number": taskBalance.TaskIncreaseVideoConsumptionNumber,
// 图片消费数
"task_bundle_limit_image_expired_consumption_number": taskBalance.TaskBundleLimitImageExpiredConsumptionNumber,
"task_increase_limit_image_expired_consumption_number": taskBalance.TaskIncreaseLimitImageExpiredConsumptionNumber,
"task_bundle_limit_image_consumption_number": taskBalance.TaskBundleLimitImageConsumptionNumber,
"task_increase_limit_image_consumption_number": taskBalance.TaskIncreaseLimitImageConsumptionNumber,
"task_bundle_image_consumption_number": taskBalance.TaskBundleImageConsumptionNumber,
"task_increase_image_consumption_number": taskBalance.TaskIncreaseImageConsumptionNumber,
// 数据分析消费数
"task_bundle_limit_data_analysis_expired_consumption_number": taskBalance.TaskBundleLimitDataAnalysisExpiredConsumptionNumber,
"task_increase_limit_data_analysis_expired_consumption_number": taskBalance.TaskIncreaseLimitDataAnalysisExpiredConsumptionNumber,
"task_bundle_limit_data_analysis_consumption_number": taskBalance.TaskBundleLimitDataAnalysisConsumptionNumber,
"task_increase_limit_data_analysis_consumption_number": taskBalance.TaskIncreaseLimitDataAnalysisConsumptionNumber,
"task_bundle_data_analysis_consumption_number": taskBalance.TaskBundleDataAnalysisConsumptionNumber,
"task_increase_data_analysis_consumption_number": taskBalance.TaskIncreaseDataAnalysisConsumptionNumber,
// 通用
"updated_at": time.Now(),
}
if err = tx.Model(&taskBalance).Updates(updateBal).Error; err != nil {
tx.Rollback()
return commonErr.ReturnError(err, "更新任务余额失败", "更新任务余额失败: ")
}
}
// 提交事务
@ -430,6 +1101,22 @@ func UpdatePendingCount(req *UpdatePendingCountRequest) error {
return nil
}
// minInt 返回两个整数的较小值
func minInt(a, b int) int {
if a < b {
return a
}
return b
}
// maxInt 返回两个整数的较大值
func maxInt(a, b int) int {
if a > b {
return a
}
return b
}
// GetRecentAssignRecords 查询最近被指派记录
// 查询操作类型为"指派"的最近n条不同员工的记录
func GetRecentAssignRecords(limit int) ([]*model.TaskAssignRecords, error) {
@ -752,9 +1439,16 @@ func GetValidArtistList() ([]ValidArtistInfo, error) {
session := app.ModuleClients.BundleDB.Table("`micro-account`.`user` AS u").
Select(`u.id as user_id, bor.customer_num, rn.name as user_name,
u.tel_num as user_phone_number, bor.bundle_name, bor.expiration_time,
bor.status, bor.uuid as order_uuid, bb.account_number, bb.account_consumption_number,
bb.video_number, bb.video_consumption_number, bb.image_number, bb.image_consumption_number,
bb.data_analysis_number, bb.data_analysis_consumption_number, bb.expansion_packs_number`).
bor.status, bor.uuid as order_uuid,
(bb.bundle_account_number + bb.increase_account_number + bb.manual_account_number) as account_number,
(bb.bundle_account_consumption_number + bb.increase_account_consumption_number + bb.manual_account_consumption_number) as account_consumption_number,
(bb.bundle_video_number + bb.increase_video_number) as video_number,
(bb.bundle_video_consumption_number + bb.increase_video_consumption_number) as video_consumption_number,
(bb.bundle_image_number + bb.increase_image_number + bb.manual_image_number) as image_number,
(bb.bundle_image_consumption_number + bb.increase_image_consumption_number + bb.manual_image_consumption_number) as image_consumption_number,
(bb.bundle_data_analysis_number + bb.increase_data_analysis_number + bb.manual_data_analysis_number) as data_analysis_number,
(bb.bundle_data_analysis_consumption_number + bb.increase_data_analysis_consumption_number + bb.manual_data_analysis_consumption_number) as data_analysis_consumption_number,
bb.expansion_packs_number`).
Joins("LEFT JOIN `micro-account`.real_name rn ON u.real_name_id = rn.id").
Joins("LEFT JOIN (?) as bor ON bor.customer_id = u.id", subQuery).
Joins("LEFT JOIN bundle_balance bb ON u.id = bb.user_id AND bb.order_uuid = bor.uuid").
@ -892,29 +1586,53 @@ func AdjustPendingCount(req *AdjustPendingCountRequest) error {
if err != nil {
if err == gorm.ErrRecordNotFound {
if req.CreateIfNotExists {
// 创建新记录
// 创建新记录,正数增加分配到“非限制-套餐权益”负数忽略置0
video := req.AdjustVideoCount
post := req.AdjustPostCount
data := req.AdjustDataCount
if video < 0 {
video = 0
}
if post < 0 {
post = 0
}
if data < 0 {
data = 0
}
taskManagement = model.TaskManagement{
SubNum: req.SubNum,
TelNum: req.TelNum,
ArtistName: req.ArtistName,
PendingVideoCount: req.AdjustVideoCount,
PendingPostCount: req.AdjustPostCount,
PendingDataCount: req.AdjustDataCount,
// 视频
PendingBundleVideoCount: video,
PendingIncreaseVideoCount: 0,
PendingBundleLimitVideoCount: 0,
PendingIncreaseLimitVideoCount: 0,
PendingBundleLimitVideoExpiredCount: 0,
PendingIncreaseLimitVideoExpiredCount: 0,
// 图片
PendingBundleImageCount: post,
PendingIncreaseImageCount: 0,
PendingBundleLimitImageCount: 0,
PendingIncreaseLimitImageCount: 0,
PendingBundleLimitImageExpiredCount: 0,
PendingIncreaseLimitImageExpiredCount: 0,
// 数据分析
PendingBundleDataAnalysisCount: data,
PendingIncreaseDataAnalysisCount: 0,
PendingBundleLimitDataAnalysisCount: 0,
PendingIncreaseLimitDataAnalysisCount: 0,
PendingBundleLimitDataAnalysisExpiredCount: 0,
PendingIncreaseLimitDataAnalysisExpiredCount: 0,
ProgressCount: 0,
CompleteCount: 0,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
// 确保数量不为负数
if taskManagement.PendingVideoCount < 0 {
taskManagement.PendingVideoCount = 0
}
if taskManagement.PendingPostCount < 0 {
taskManagement.PendingPostCount = 0
}
if taskManagement.PendingDataCount < 0 {
taskManagement.PendingDataCount = 0
}
if err = tx.Create(&taskManagement).Error; err != nil {
tx.Rollback()
return commonErr.ReturnError(err, "创建任务记录失败", "创建任务记录失败: ")
@ -928,27 +1646,49 @@ func AdjustPendingCount(req *AdjustPendingCountRequest) error {
return commonErr.ReturnError(err, "查询任务记录失败", "查询任务记录失败: ")
}
} else {
// 2. 计算调整后的数量
newVideoCount := taskManagement.PendingVideoCount + req.AdjustVideoCount
newPostCount := taskManagement.PendingPostCount + req.AdjustPostCount
newDataCount := taskManagement.PendingDataCount + req.AdjustDataCount
// 2. 计算调整:正数增加分配到“非限制-套餐权益”;负数按优先级扣减
if req.AdjustVideoCount > 0 {
taskManagement.PendingBundleVideoCount += req.AdjustVideoCount
} else if req.AdjustVideoCount < 0 {
deductVideo(&taskManagement, -req.AdjustVideoCount)
}
// 3. 确保调整后的数量不为负数
if newVideoCount < 0 {
newVideoCount = 0
if req.AdjustPostCount > 0 {
taskManagement.PendingBundleImageCount += req.AdjustPostCount
} else if req.AdjustPostCount < 0 {
deductImage(&taskManagement, -req.AdjustPostCount)
}
if newPostCount < 0 {
newPostCount = 0
}
if newDataCount < 0 {
newDataCount = 0
if req.AdjustDataCount > 0 {
taskManagement.PendingBundleDataAnalysisCount += req.AdjustDataCount
} else if req.AdjustDataCount < 0 {
deductData(&taskManagement, -req.AdjustDataCount)
}
// 4. 更新TaskManagement表
updateData := map[string]interface{}{
"pending_video_count": newVideoCount,
"pending_post_count": newPostCount,
"pending_data_count": newDataCount,
// 视频
"pending_bundle_limit_video_expired_count": taskManagement.PendingBundleLimitVideoExpiredCount,
"pending_bundle_limit_video_count": taskManagement.PendingBundleLimitVideoCount,
"pending_increase_limit_video_expired_count": taskManagement.PendingIncreaseLimitVideoExpiredCount,
"pending_increase_limit_video_count": taskManagement.PendingIncreaseLimitVideoCount,
"pending_bundle_video_count": taskManagement.PendingBundleVideoCount,
"pending_increase_video_count": taskManagement.PendingIncreaseVideoCount,
// 图片
"pending_bundle_limit_image_expired_count": taskManagement.PendingBundleLimitImageExpiredCount,
"pending_bundle_limit_image_count": taskManagement.PendingBundleLimitImageCount,
"pending_increase_limit_image_expired_count": taskManagement.PendingIncreaseLimitImageExpiredCount,
"pending_increase_limit_image_count": taskManagement.PendingIncreaseLimitImageCount,
"pending_bundle_image_count": taskManagement.PendingBundleImageCount,
"pending_increase_image_count": taskManagement.PendingIncreaseImageCount,
// 数据分析
"pending_bundle_limit_data_analysis_expired_count": taskManagement.PendingBundleLimitDataAnalysisExpiredCount,
"pending_bundle_limit_data_analysis_count": taskManagement.PendingBundleLimitDataAnalysisCount,
"pending_increase_limit_data_analysis_expired_count": taskManagement.PendingIncreaseLimitDataAnalysisExpiredCount,
"pending_increase_limit_data_analysis_count": taskManagement.PendingIncreaseLimitDataAnalysisCount,
"pending_bundle_data_analysis_count": taskManagement.PendingBundleDataAnalysisCount,
"pending_increase_data_analysis_count": taskManagement.PendingIncreaseDataAnalysisCount,
// 通用
"updated_at": time.Now(),
}

View File

@ -1,6 +1,7 @@
package logic
import (
"fmt"
"micro-bundle/internal/dao"
commonErr "micro-bundle/pkg/err"
)
@ -77,6 +78,11 @@ func GetPendingTaskList(req *dao.TaskQueryRequest) ([]*dao.TaskQueryResponse, in
// 3. 转换为响应结构体
var recordResponse []*dao.TaskQueryResponse
for _, record := range record {
// 计算聚合的待发数量:视频、图文、数据分析
videoTotal := record.PendingBundleLimitVideoExpiredCount + record.PendingBundleLimitVideoCount + record.PendingIncreaseLimitVideoExpiredCount + record.PendingIncreaseLimitVideoCount + record.PendingBundleVideoCount + record.PendingIncreaseVideoCount
imageTotal := record.PendingBundleLimitImageExpiredCount + record.PendingBundleLimitImageCount + record.PendingIncreaseLimitImageExpiredCount + record.PendingIncreaseLimitImageCount + record.PendingBundleImageCount + record.PendingIncreaseImageCount
dataTotal := record.PendingBundleLimitDataAnalysisExpiredCount + record.PendingBundleLimitDataAnalysisCount + record.PendingIncreaseLimitDataAnalysisExpiredCount + record.PendingIncreaseLimitDataAnalysisCount + record.PendingBundleDataAnalysisCount + record.PendingIncreaseDataAnalysisCount
// 根据 SubNum 和 TelNum 查询对应的员工正在进行中的任务和已完成任务数量
progressTaskCount, completeTaskCount, err := dao.GetTaskAssigneeInfo(record.TaskAssigneeNum)
if err != nil {
@ -85,9 +91,9 @@ func GetPendingTaskList(req *dao.TaskQueryRequest) ([]*dao.TaskQueryResponse, in
TelNum: record.TelNum,
ArtistName: record.ArtistName,
TaskAssigneeNum: record.TaskAssigneeNum,
PendingPostCount: record.PendingPostCount,
PendingVideoCount: record.PendingVideoCount,
PendingDataCount: record.PendingDataCount,
PendingPostCount: imageTotal,
PendingVideoCount: videoTotal,
PendingDataCount: dataTotal,
ProgressTaskCount: 0,
CompleteTaskCount: 0,
LastTaskAssignee: record.LastTaskAssignee,
@ -98,9 +104,9 @@ func GetPendingTaskList(req *dao.TaskQueryRequest) ([]*dao.TaskQueryResponse, in
TelNum: record.TelNum,
ArtistName: record.ArtistName,
TaskAssigneeNum: record.TaskAssigneeNum,
PendingPostCount: record.PendingPostCount,
PendingVideoCount: record.PendingVideoCount,
PendingDataCount: record.PendingDataCount,
PendingPostCount: imageTotal,
PendingVideoCount: videoTotal,
PendingDataCount: dataTotal,
ProgressTaskCount: progressTaskCount,
CompleteTaskCount: completeTaskCount,
LastTaskAssignee: record.LastTaskAssignee,
@ -154,7 +160,46 @@ func UpdatePendingCount(req *dao.UpdatePendingCountRequest) error {
return commonErr.ReturnError(nil, "艺人套餐已过期", "该艺人没有有效的套餐,无法修改待发数量")
}
// todo 需要调用套餐的接口,判断艺人是否有那么数量可以修改
// 查询艺人当前任务余额与待发汇总,校验待发数量和余额的总和是否足够
resp, err := dao.GetUserPendingAndTaskBalances(&dao.PendingAndBalanceRequest{
SubNum: req.SubNum,
TelNum: req.TelNum,
})
if err != nil {
return commonErr.ReturnError(err, "查询艺人任务余额失败", "查询艺人任务余额失败: ")
}
// 计算当前待发数量(聚合所有类型)
curVideo := resp.PendingBundleVideoCount + resp.PendingIncreaseVideoCount
curImage := resp.PendingBundleImageCount + resp.PendingIncreaseImageCount
curData := resp.PendingBundleDataAnalysisCount + resp.PendingIncreaseDataAnalysisCount
// 计算可用余额(套餐 + 增值)
availVideo := resp.BundleVideoBalance + resp.IncreaseVideoBalance
availImage := resp.BundleImageBalance + resp.IncreaseImageBalance
availData := resp.BundleDataAnalysisBalance + resp.IncreaseDataAnalysisBalance
// 校验:当前待发数量 + 艺人余额 >= 目标数量
// 这确保了可以优先扣减待发数量,不足时再扣减余额
totalAvailVideo := curVideo + availVideo
totalAvailImage := curImage + availImage
totalAvailData := curData + availData
if req.PendingVideoCount > totalAvailVideo {
return commonErr.ReturnError(nil, "视频任务数量不足",
fmt.Sprintf("目标待发视频数量(%d)超出当前待发数量(%d)和可用余额(%d)的总和(%d)",
req.PendingVideoCount, curVideo, availVideo, totalAvailVideo))
}
if req.PendingPostCount > totalAvailImage {
return commonErr.ReturnError(nil, "图文任务数量不足",
fmt.Sprintf("目标待发图文数量(%d)超出当前待发数量(%d)和可用余额(%d)的总和(%d)",
req.PendingPostCount, curImage, availImage, totalAvailImage))
}
if req.PendingDataCount > totalAvailData {
return commonErr.ReturnError(nil, "数据分析任务数量不足",
fmt.Sprintf("目标待发数据分析数量(%d)超出当前待发数量(%d)和可用余额(%d)的总和(%d)",
req.PendingDataCount, curData, availData, totalAvailData))
}
// 2. 调用DAO层更新待发数量
return dao.UpdatePendingCount(req)
@ -212,11 +257,11 @@ func GetEmployeeAssignedTasks(req *dao.EmployeeTaskQueryRequest) ([]*dao.TaskAss
// CompleteTaskManually 员工手动点击完成任务
func CompleteTaskManually(assignRecordsUUID string, taskAssigneeNum string) error {
// 第一步批量更新记录被指派的员工为taskAssigneeNum的待完成任务数量和已经完成任务的数量
err := dao.UpdateTaskRecordsByAssigneeNum(taskAssigneeNum)
if err != nil {
return err
}
// // 第一步批量更新记录被指派的员工为taskAssigneeNum的待完成任务数量和已经完成任务的数量
// err := dao.UpdateTaskRecordsByAssigneeNum(taskAssigneeNum)
// if err != nil {
// return err
// }
return dao.CompleteTaskManually(assignRecordsUUID)
}
@ -225,55 +270,6 @@ func UpdateTaskProgress(req *dao.CompleteTaskRequest) error {
return dao.UpdateTaskProgress(req)
}
// // GetArtistBundleInfo 获取艺人套餐信息(用于判断套餐多媒体数量)
// func GetArtistBundleInfo(customerNum string) ([]*model.BundleOrderRecords, error) {
// var orderRecords []*model.BundleOrderRecords
// currentTime := time.Now().Format("2006-01-02 15:04:05")
// // 查询该艺人的有效套餐订单
// err := app.ModuleClients.BundleDB.Model(&model.BundleOrderRecords{}).
// Where("customer_num = ? AND expiration_time > ? AND status = ?",
// customerNum, currentTime, 2). // 2:已签已支付
// Preload("BundleOrderValueAdd").
// Find(&orderRecords).Error
// if err != nil {
// return nil, commonErr.ReturnError(err, "查询艺人套餐信息失败", "查询艺人套餐信息失败: ")
// }
// return orderRecords, nil
// }
// // CalculateArtistPendingCounts 计算艺人的待发数量
// // 根据套餐信息计算艺人可以额外多发的多媒体内容数量
// func CalculateArtistPendingCounts(customerNum string) (videoCount, postCount, dataCount int, err error) {
// // 获取艺人套餐信息
// orderRecords, err := GetArtistBundleInfo(customerNum)
// if err != nil {
// return 0, 0, 0, err
// }
// // 计算总的可用数量
// for _, record := range orderRecords {
// // 从套餐基础数量计算
// videoCount += int(record.Num) // 假设Num字段表示视频数量
// // 从增值服务计算
// for _, valueAdd := range record.BundleOrderValueAdd {
// switch valueAdd.ServiceType {
// case 1: // 视频
// videoCount += int(valueAdd.Num)
// case 2: // 图文
// postCount += int(valueAdd.Num)
// case 3: // 数据报表
// dataCount += int(valueAdd.Num)
// }
// }
// }
// return videoCount, postCount, dataCount, nil
// }
// GetTaskAssignRecordsList 多条件查询操作记录表
func GetTaskAssignRecordsList(req *dao.TaskAssignRecordsQueryRequest) ([]*dao.TaskAssignRecordsResponse, int64, error) {
record, total, err := dao.GetTaskAssignRecordsList(req)
@ -308,7 +304,14 @@ func GetTaskAssignRecordsList(req *dao.TaskAssignRecordsQueryRequest) ([]*dao.Ta
return recordResponse, total, nil
}
// GetArtistBundleBalance 查询艺人套餐剩余数量
func GetArtistBundleBalance(req *dao.ArtistBundleBalanceRequest) (*dao.ArtistBundleBalanceResponse, error) {
return dao.GetArtistBundleBalance(req)
// // GetArtistBundleBalance 查询艺人套餐剩余数量
// func GetArtistBundleBalance(req *dao.ArtistBundleBalanceRequest) (*dao.ArtistBundleBalanceResponse, error) {
// return dao.GetArtistBundleBalance(req)
// }
// GetPendingAndTaskBalances 查询艺人当前的待发数量与任务余额(区分套餐/增值)
// 根据艺人的编号 SubNum 或手机号 TelNum 进行查询,优先使用编号
// 返回的数据会区分为“套餐类型”和“增值类型”两大类,涵盖视频/图文/数据分析三种任务
func GetPendingAndTaskBalances(req *dao.PendingAndBalanceRequest) (*dao.PendingAndBalanceResponse, error) {
return dao.GetUserPendingAndTaskBalances(req)
}

View File

@ -11,9 +11,31 @@ type TaskManagement struct {
SubNum string `gorm:"column:sub_num;comment:用户编号;index:idx_sub_num;index:idx_sub_tel,priority:1" json:"subNum"`
TelNum string `gorm:"column:tel_num;comment:手机号;index:idx_tel_num;index:idx_sub_tel,priority:2" json:"telNum"`
ArtistName string `gorm:"column:artist_name;comment:艺人名称;index:idx_artist_name" json:"artistName"`
PendingVideoCount int `gorm:"column:pending_video_count;comment:待发视频数量;index:idx_pending_video" json:"pendingVideoCount"`
PendingPostCount int `gorm:"column:pending_post_count;comment:待发图文数量" json:"pendingPostCount"`
PendingDataCount int `gorm:"column:pending_data_count;comment:待发数据数量" json:"pendingDataCount"`
// ===== 待发视频类任务 =====
PendingBundleVideoCount int `gorm:"column:pending_bundle_video_count;comment:待发非限制类型套餐权益视频数量" json:"pendingBundleVideoCount"`
PendingIncreaseVideoCount int `gorm:"column:pending_increase_video_count;comment:待发非限制类型增值权益视频数量" json:"pendingIncreaseVideoCount"`
PendingBundleLimitVideoCount int `gorm:"column:pending_bundle_limit_video_count;comment:待发套餐权益限制类型非过期视频数量" json:"pendingBundleLimitVideoCount"`
PendingIncreaseLimitVideoCount int `gorm:"column:pending_increase_limit_video_count;comment:待发增值权益限制类型非过期视频数量" json:"pendingIncreaseLimitVideoCount"`
PendingBundleLimitVideoExpiredCount int `gorm:"column:pending_bundle_limit_video_expired_count;comment:待发套餐权益限制类型会过期视频数量" json:"pendingBundleLimitVideoExpiredCount"`
PendingIncreaseLimitVideoExpiredCount int `gorm:"column:pending_increase_limit_video_expired_count;comment:待发增值权益限制类型会过期视频数量" json:"pendingIncreaseLimitVideoExpiredCount"`
// ===== 待发图片类任务 =====
PendingBundleImageCount int `gorm:"column:pending_bundle_image_count;comment:待发非限制类型套餐权益图片数量" json:"pendingBundleImageCount"`
PendingIncreaseImageCount int `gorm:"column:pending_increase_image_count;comment:待发非限制类型增值权益图片数量" json:"pendingIncreaseImageCount"`
PendingBundleLimitImageCount int `gorm:"column:pending_bundle_limit_image_count;comment:待发套餐权益限制类型非过期图片数量" json:"pendingBundleLimitImageCount"`
PendingIncreaseLimitImageCount int `gorm:"column:pending_increase_limit_image_count;comment:待发增值权益限制类型非过期图片数量" json:"pendingIncreaseLimitImageCount"`
PendingBundleLimitImageExpiredCount int `gorm:"column:pending_bundle_limit_image_expired_count;comment:待发套餐权益限制类型会过期图片数量" json:"pendingBundleLimitImageExpiredCount"`
PendingIncreaseLimitImageExpiredCount int `gorm:"column:pending_increase_limit_image_expired_count;comment:待发增值权益限制类型会过期图片数量" json:"pendingIncreaseLimitImageExpiredCount"`
// ===== 待发数据分析类任务 =====
PendingBundleDataAnalysisCount int `gorm:"column:pending_bundle_data_analysis_count;comment:待发非限制类型套餐权益数据分析数量" json:"pendingBundleDataAnalysisCount"`
PendingIncreaseDataAnalysisCount int `gorm:"column:pending_increase_data_analysis_count;comment:待发非限制类型增值权益数据分析数量" json:"pendingIncreaseDataAnalysisCount"`
PendingBundleLimitDataAnalysisCount int `gorm:"column:pending_bundle_limit_data_analysis_count;comment:待发套餐权益限制类型非过期数据分析数量" json:"pendingBundleLimitDataAnalysisCount"`
PendingIncreaseLimitDataAnalysisCount int `gorm:"column:pending_increase_limit_data_analysis_count;comment:待发增值权益限制类型非过期数据分析数量" json:"pendingIncreaseLimitDataAnalysisCount"`
PendingBundleLimitDataAnalysisExpiredCount int `gorm:"column:pending_bundle_limit_data_analysis_expired_count;comment:待发套餐权益限制类型会过期数据分析数量" json:"pendingBundleLimitDataAnalysisExpiredCount"`
PendingIncreaseLimitDataAnalysisExpiredCount int `gorm:"column:pending_increase_limit_data_analysis_expired_count;comment:待发增值权益限制类型会过期数据分析数量" json:"pendingIncreaseLimitDataAnalysisExpiredCount"`
LastTaskAssignee string `gorm:"column:last_task_assignee;comment:最后一次的任务指派人" json:"lastTaskAssignee"`
TaskAssigneeNum string `gorm:"column:task_assignee_num;comment:任务指派人账号" json:"taskAssigneeNum"`
ProgressCount int `gorm:"column:progress_count;comment:进行中的任务数量" json:"progressCount"`
@ -60,3 +82,131 @@ type TaskAssignRecords struct {
func (t *TaskAssignRecords) TableName() string {
return "task_assign_records"
}
// 任务余额表
type TaskBalance struct {
ID int64 `gorm:"primarykey"`
SubNum string `gorm:"column:sub_num;comment:用户编号;index:idx_task_sub_num;not null" json:"subNum"`
TelNum string `gorm:"column:tel_num;comment:手机号;index:idx_task_tel_num;not null" json:"telNum"`
Month string `gorm:"column:month;type:varchar(32);comment:月份;index:idx_task_month;not null" json:"month"`
ExpiredAt time.Time `gorm:"column:expired_at;type:datetime;comment:任务过期时间" json:"expiredAt"`
StartAt time.Time `gorm:"column:start_at;type:datetime;comment:任务开始时间" json:"startAt"`
// ===== 任务视频类 =====
TaskBundleVideoNumber int `gorm:"column:task_bundle_video_number;not null;comment:任务非限制类型套餐权益视频总数" json:"taskBundleVideoNumber"`
TaskIncreaseVideoNumber int `gorm:"column:task_increase_video_number;not null;comment:任务非限制类型增值权益视频总数" json:"taskIncreaseVideoNumber"`
TaskBundleLimitVideoNumber int `gorm:"column:task_bundle_limit_video_number;not null;comment:任务套餐权益限制类型非过期总数" json:"taskBundleLimitVideoNumber"`
TaskIncreaseLimitVideoNumber int `gorm:"column:task_increase_limit_video_number;not null;comment:任务增值权益限制类型非过期总数" json:"taskIncreaseLimitVideoNumber"`
TaskBundleLimitVideoExpiredNumber int `gorm:"column:task_bundle_limit_video_expired_number;not null;comment:任务套餐权益限制类型会过期总数" json:"taskBundleLimitVideoExpiredNumber"`
TaskIncreaseLimitVideoExpiredNumber int `gorm:"column:task_increase_limit_video_expired_number;not null;comment:任务增值权益限制类型会过期总数" json:"taskIncreaseLimitVideoExpiredNumber"`
TaskMonthlyInvalidBundleVideoNumber int `gorm:"column:task_monthly_invalid_bundle_video_number;not null;comment:任务当月失效的套餐权益视频总数" json:"taskMonthlyInvalidBundleVideoNumber"`
TaskInvalidBundleVideoNumber int `gorm:"column:task_invalid_bundle_video_number;not null;comment:任务历史失效的套餐权益视频总数" json:"taskInvalidBundleVideoNumber"`
TaskMonthlyInvalidIncreaseVideoNumber int `gorm:"column:task_monthly_invalid_increase_video_number;not null;comment:任务当月失效的增值权益视频总数" json:"taskMonthlyInvalidIncreaseVideoNumber"`
TaskInvalidIncreaseVideoNumber int `gorm:"column:task_invalid_increase_video_number;not null;comment:任务历史失效的增值权益视频总数" json:"taskInvalidIncreaseVideoNumber"`
TaskBundleVideoConsumptionNumber int `gorm:"column:task_bundle_video_consumption_number;not null;comment:任务非限制类型套餐权益视频使用数" json:"taskBundleVideoConsumptionNumber"`
TaskIncreaseVideoConsumptionNumber int `gorm:"column:task_increase_video_consumption_number;not null;comment:任务非限制类型增值权益视频使用数" json:"taskIncreaseVideoConsumptionNumber"`
TaskBundleLimitVideoConsumptionNumber int `gorm:"column:task_bundle_limit_video_consumption_number;not null;comment:任务套餐权益限制类型非过期使用数" json:"taskBundleLimitVideoConsumptionNumber"`
TaskIncreaseLimitVideoConsumptionNumber int `gorm:"column:task_increase_limit_video_consumption_number;not null;comment:任务增值权益限制类型非过期使用数" json:"taskIncreaseLimitVideoConsumptionNumber"`
TaskBundleLimitVideoExpiredConsumptionNumber int `gorm:"column:task_bundle_limit_video_expired_consumption_number;not null;comment:任务套餐权益限制类型会过期使用数" json:"taskBundleLimitVideoExpiredConsumptionNumber"`
TaskIncreaseLimitVideoExpiredConsumptionNumber int `gorm:"column:task_increase_limit_video_expired_consumption_number;not null;comment:任务增值权益限制类型会过期使用数" json:"taskIncreaseLimitVideoExpiredConsumptionNumber"`
TaskMonthlyLimitVideoNumber int `gorm:"column:task_monthly_limit_video_number;not null;comment:任务当月限制类型视频可用数" json:"taskMonthlyLimitVideoNumber"`
TaskMonthlyLimitVideoConsumptionNumber int `gorm:"column:task_monthly_limit_video_consumption_number;not null;comment:任务当月限制类型视频已使用额度" json:"taskMonthlyLimitVideoConsumptionNumber"`
TaskMonthlyLimitVideoExpireNumber int `gorm:"column:task_monthly_limit_video_expired_number;not null;comment:任务当月限制类型视频会过期可用数" json:"taskMonthlyLimitVideoExpireNumber"`
TaskMonthlyLimitVideoExpireConsumptionNumber int `gorm:"column:task_monthly_limit_video_expired_consumption_number;not null;comment:任务当月限制类型视频会过期已使用额度" json:"taskMonthlyLimitVideoExpireConsumptionNumber"`
TaskMonthlyBundleVideoConsumptionNumber int `gorm:"column:task_monthly_bundle_video_consumption_number;not null;comment:任务当月套餐类型总使用数" json:"taskMonthlyBundleVideoConsumptionNumber"`
TaskMonthlyIncreaseVideoConsumptionNumber int `gorm:"column:task_monthly_increase_video_consumption_number;not null;comment:任务当月增值类型总使用数" json:"taskMonthlyIncreaseVideoConsumptionNumber"`
TaskMonthlyLimitVideoQuotaNumber int `gorm:"column:task_monthly_limit_video_quota_number;not null;comment:任务当月限制类型视频额度" json:"taskMonthlyLimitVideoQuotaNumber"`
// ===== 任务图片类 =====
TaskBundleImageNumber int `gorm:"column:task_bundle_image_number;not null;comment:任务非限制类型套餐权益图片总数" json:"taskBundleImageNumber"`
TaskIncreaseImageNumber int `gorm:"column:task_increase_image_number;not null;comment:任务非限制类型增值权益图片总数" json:"taskIncreaseImageNumber"`
TaskBundleLimitImageNumber int `gorm:"column:task_bundle_limit_image_number;not null;comment:任务套餐权益限制类型非过期总数" json:"taskBundleLimitImageNumber"`
TaskIncreaseLimitImageNumber int `gorm:"column:task_increase_limit_image_number;not null;comment:任务增值权益限制类型非过期总数" json:"taskIncreaseLimitImageNumber"`
TaskBundleLimitImageExpiredNumber int `gorm:"column:task_bundle_limit_image_expired_number;not null;comment:任务套餐权益限制类型会过期总数" json:"taskBundleLimitImageExpiredNumber"`
TaskIncreaseLimitImageExpiredNumber int `gorm:"column:task_increase_limit_image_expired_number;not null;comment:任务增值权益限制类型会过期总数" json:"taskIncreaseLimitImageExpiredNumber"`
TaskMonthlyInvalidBundleImageNumber int `gorm:"column:task_monthly_invalid_bundle_image_number;not null;comment:任务当月失效的套餐权益图片总数" json:"taskMonthlyInvalidBundleImageNumber"`
TaskInvalidBundleImageNumber int `gorm:"column:task_invalid_bundle_image_number;not null;comment:任务历史失效的套餐权益图片总数" json:"taskInvalidBundleImageNumber"`
TaskMonthlyInvalidIncreaseImageNumber int `gorm:"column:task_monthly_invalid_increase_image_number;not null;comment:任务当月失效的增值权益图片总数" json:"taskMonthlyInvalidIncreaseImageNumber"`
TaskInvalidIncreaseImageNumber int `gorm:"column:task_invalid_increase_image_number;not null;comment:任务历史失效的增值权益图片总数" json:"taskInvalidIncreaseImageNumber"`
TaskBundleImageConsumptionNumber int `gorm:"column:task_bundle_image_consumption_number;not null;comment:任务非限制类型套餐权益图片使用数" json:"taskBundleImageConsumptionNumber"`
TaskIncreaseImageConsumptionNumber int `gorm:"column:task_increase_image_consumption_number;not null;comment:任务非限制类型增值权益图片使用数" json:"taskIncreaseImageConsumptionNumber"`
TaskBundleLimitImageConsumptionNumber int `gorm:"column:task_bundle_limit_image_consumption_number;not null;comment:任务套餐权益限制类型非过期使用数" json:"taskBundleLimitImageConsumptionNumber"`
TaskIncreaseLimitImageConsumptionNumber int `gorm:"column:task_increase_limit_image_consumption_number;not null;comment:任务增值权益限制类型非过期使用数" json:"taskIncreaseLimitImageConsumptionNumber"`
TaskBundleLimitImageExpiredConsumptionNumber int `gorm:"column:task_bundle_limit_image_expired_consumption_number;not null;comment:任务套餐权益限制类型会过期使用数" json:"taskBundleLimitImageExpiredConsumptionNumber"`
TaskIncreaseLimitImageExpiredConsumptionNumber int `gorm:"column:task_increase_limit_image_expired_consumption_number;not null;comment:任务增值权益限制类型会过期使用数" json:"taskIncreaseLimitImageExpiredConsumptionNumber"`
TaskMonthlyLimitImageNumber int `gorm:"column:task_monthly_limit_image_number;not null;comment:任务当月限制类型图片可使用额度" json:"taskMonthlyLimitImageNumber"`
TaskMonthlyLimitImageConsumptionNumber int `gorm:"column:task_monthly_limit_image_consumption_number;not null;comment:任务当月限制类型图片已使用额度" json:"taskMonthlyLimitImageConsumptionNumber"`
TaskMonthlyLimitImageExpireNumber int `gorm:"column:task_monthly_limit_image_expired_number;not null;comment:任务当月限制类型图片会过期可用数" json:"taskMonthlyLimitImageExpireNumber"`
TaskMonthlyLimitImageExpireConsumptionNumber int `gorm:"column:task_monthly_limit_image_expired_consumption_number;not null;comment:任务当月限制类型图片会过期已使用额度" json:"taskMonthlyLimitImageExpireConsumptionNumber"`
TaskMonthlyBundleImageConsumptionNumber int `gorm:"column:task_monthly_bundle_image_consumption_number;not null;comment:任务当月套餐类型总使用数" json:"taskMonthlyBundleImageConsumptionNumber"`
TaskMonthlyIncreaseImageConsumptionNumber int `gorm:"column:task_monthly_increase_image_consumption_number;not null;comment:任务当月增值类型总使用数" json:"taskMonthlyIncreaseImageConsumptionNumber"`
TaskMonthlyLimitImageQuotaNumber int `gorm:"column:task_monthly_limit_image_quota_number;not null;comment:任务当月限制类型图片额度" json:"taskMonthlyLimitImageQuotaNumber"`
// ===== 任务数据分析类 =====
TaskBundleDataAnalysisNumber int `gorm:"column:task_bundle_data_analysis_number;not null;comment:任务非限制类型套餐权益数据分析总数" json:"taskBundleDataAnalysisNumber"`
TaskIncreaseDataAnalysisNumber int `gorm:"column:task_increase_data_analysis_number;not null;comment:任务非限制类型增值权益数据分析总数" json:"taskIncreaseDataAnalysisNumber"`
TaskBundleLimitDataAnalysisNumber int `gorm:"column:task_bundle_limit_data_analysis_number;not null;comment:任务套餐权益限制类型非过期总数" json:"taskBundleLimitDataAnalysisNumber"`
TaskIncreaseLimitDataAnalysisNumber int `gorm:"column:task_increase_limit_data_analysis_number;not null;comment:任务增值权益限制类型非过期总数" json:"taskIncreaseLimitDataAnalysisNumber"`
TaskBundleLimitDataAnalysisExpiredNumber int `gorm:"column:task_bundle_limit_data_analysis_expired_number;not null;comment:任务套餐权益限制类型会过期总数" json:"taskBundleLimitDataAnalysisExpiredNumber"`
TaskIncreaseLimitDataAnalysisExpiredNumber int `gorm:"column:task_increase_limit_data_analysis_expired_number;not null;comment:任务增值权益限制类型会过期总数" json:"taskIncreaseLimitDataAnalysisExpiredNumber"`
TaskMonthlyInvalidBundleDataAnalysisNumber int `gorm:"column:task_monthly_invalid_bundle_data_analysis_number;not null;comment:任务当月失效的套餐权益数据分析总数" json:"taskMonthlyInvalidBundleDataAnalysisNumber"`
TaskInvalidBundleDataAnalysisNumber int `gorm:"column:task_invalid_bundle_data_analysis_number;not null;comment:任务历史失效的套餐权益数据分析总数" json:"taskInvalidBundleDataAnalysisNumber"`
TaskMonthlyInvalidIncreaseDataAnalysisNumber int `gorm:"column:task_monthly_invalid_increase_data_analysis_number;not null;comment:任务当月失效的增值权益数据分析总数" json:"taskMonthlyInvalidIncreaseDataAnalysisNumber"`
TaskInvalidIncreaseDataAnalysisNumber int `gorm:"column:task_invalid_increase_data_analysis_number;not null;comment:任务历史失效的增值权益数据分析总数" json:"taskInvalidIncreaseDataAnalysisNumber"`
TaskBundleDataAnalysisConsumptionNumber int `gorm:"column:task_bundle_data_analysis_consumption_number;not null;comment:任务非限制类型套餐权益数据分析使用数" json:"taskBundleDataAnalysisConsumptionNumber"`
TaskIncreaseDataAnalysisConsumptionNumber int `gorm:"column:task_increase_data_analysis_consumption_number;not null;comment:任务非限制类型增值权益数据分析使用数" json:"taskIncreaseDataAnalysisConsumptionNumber"`
TaskBundleLimitDataAnalysisConsumptionNumber int `gorm:"column:task_bundle_limit_data_analysis_consumption_number;not null;comment:任务套餐权益限制类型非过期使用数" json:"taskBundleLimitDataAnalysisConsumptionNumber"`
TaskIncreaseLimitDataAnalysisConsumptionNumber int `gorm:"column:task_increase_limit_data_analysis_consumption_number;not null;comment:任务增值权益限制类型非过期使用数" json:"taskIncreaseLimitDataAnalysisConsumptionNumber"`
TaskBundleLimitDataAnalysisExpiredConsumptionNumber int `gorm:"column:task_bundle_limit_data_analysis_expired_consumption_number;not null;comment:任务套餐权益限制类型会过期使用数" json:"taskBundleLimitDataAnalysisExpiredConsumptionNumber"`
TaskIncreaseLimitDataAnalysisExpiredConsumptionNumber int `gorm:"column:task_increase_limit_data_analysis_expired_consumption_number;not null;comment:任务增值权益限制类型会过期使用数" json:"taskIncreaseLimitDataAnalysisExpiredConsumptionNumber"`
TaskMonthlyLimitDataAnalysisNumber int `gorm:"column:task_monthly_limit_data_analysis_number;not null;comment:任务当月限制类型数据分析可使用额度" json:"taskMonthlyLimitDataAnalysisNumber"`
TaskMonthlyLimitDataAnalysisConsumptionNumber int `gorm:"column:task_monthly_limit_data_analysis_consumption_number;not null;comment:任务当月限制类型数据分析已使用额度" json:"taskMonthlyLimitDataAnalysisConsumptionNumber"`
TaskMonthlyLimitDataAnalysisExpireNumber int `gorm:"column:task_monthly_limit_data_analysis_expired_number;not null;comment:任务当月限制类型数据分析会过期可用数" json:"taskMonthlyLimitDataAnalysisExpireNumber"`
TaskMonthlyLimitDataAnalysisExpireConsumptionNumber int `gorm:"column:task_monthly_limit_data_analysis_expired_consumption_number;not null;comment:任务当月限制类型数据分析会过期已使用额度" json:"taskMonthlyLimitDataAnalysisExpireConsumptionNumber"`
TaskMonthlyBundleDataAnalysisConsumptionNumber int `gorm:"column:task_monthly_bundle_data_analysis_consumption_number;not null;comment:任务当月套餐类型总使用数" json:"taskMonthlyBundleDataAnalysisConsumptionNumber"`
TaskMonthlyIncreaseDataAnalysisConsumptionNumber int `gorm:"column:task_monthly_increase_data_analysis_consumption_number;not null;comment:任务当月增值类型总使用数" json:"taskMonthlyIncreaseDataAnalysisConsumptionNumber"`
TaskMonthlyLimitDataAnalysisQuotaNumber int `gorm:"column:task_monthly_limit_data_analysis_quota_number;not null;comment:任务当月限制类型数据分析额度" json:"taskMonthlyLimitDataAnalysisQuotaNumber"`
CreatedAt time.Time `gorm:"column:created_at;comment:创建时间" json:"createdAt"`
UpdatedAt time.Time `gorm:"column:updated_at;comment:更新时间" json:"updatedAt"`
DeletedAt soft_delete.DeletedAt `gorm:"column:deleted_at;type:int(11);index:idx_task_balance_deleted_at" json:"deletedAt"`
}
func (t *TaskBalance) TableName() string {
return "task_balance"
}
// 任务日志表
type TaskLog struct {
LogUUID string `gorm:"column:log_uuid;type:varchar(50)comment:任务日志UUID;uniqueIndex:idx_task_log_uuid;not null" json:"taskLogUUID"`
SubNum string `gorm:"column:sub_num;comment:任务用户编号;index:idx_task_log_sub_num;not null" json:"taskSubNum"`
TelNum string `gorm:"column:tel_num;comment:任务用户手机号;index:idx_task_log_tel_num;not null" json:"taskTelNum"`
ArtistName string `gorm:"column:artist_name;comment:任务艺人名称;index:idx_task_log_artist_name" json:"taskArtistName"`
// ===== 操作信息 =====
OperationType int `gorm:"column:operation_type;type:int(11);comment:任务操作类型 1:加任务 2:消耗任务 3:完成任务;4:任务过期;index:idx_task_operation_type;not null" json:"taskOperationType"`
TaskType int `gorm:"column:task_type;type:int(11);comment:任务类型 1:视频 2:图片 3:数据分析;index:idx_task_type;not null" json:"taskType"`
TaskCount int `gorm:"column:task_count;type:int(11);comment:任务数量;not null" json:"taskCount"`
Remark string `gorm:"column:remark;type:varchar(500);comment:任务备注" json:"taskRemark"`
// ===== 操作人信息 =====
OperatorName string `gorm:"column:operator_name;comment:任务操作人姓名;index:idx_task_operator_name" json:"taskOperatorName"`
OperatorNum string `gorm:"column:operator_num;comment:任务操作人账号;index:idx_task_operator_num" json:"taskOperatorNum"`
CompletorName string `gorm:"column:completor_name;comment:任务完成人姓名;index:idx_task_completor_name" json:"taskCompletorName"`
CompletorNum string `gorm:"column:completor_num;comment:任务完成人账号;index:idx_task_completor_num" json:"taskCompletorNum"`
// ===== 关联ID字段 =====
VideoPublishUUID string `gorm:"column:video_publish_id;type:varchar(50);comment:任务关联的发布视频UUID;index:idx_task_video_publish_id" json:"taskVideoPublishID"`
PostPublishUUID string `gorm:"column:post_publish_id;type:varchar(50);comment:任务关联的图文发布UUID;index:idx_task_post_publish_id" json:"taskPostPublishID"`
DataAnalysisUUID string `gorm:"column:data_analysis_id;type:varchar(50);comment:任务关联的数据分析UUID;index:idx_task_data_analysis_id" json:"taskDataAnalysisID"`
// ===== 时间字段 =====
OperationTime int `gorm:"column:operation_time;type:int(11);comment:任务操作时间;index:idx_task_operation_time;not null" json:"taskOperationTime"`
CreatedAt int `gorm:"column:created_at;type:int(11);comment:任务日志创建时间" json:"taskCreatedAt"`
UpdatedAt int `gorm:"column:updated_at;type:int(11);comment:任务日志更新时间" json:"taskUpdatedAt"`
DeletedAt soft_delete.DeletedAt `gorm:"column:deleted_at;type:int(11);index:idx_task_log_deleted_at" json:"taskDeletedAt"`
}
func (t *TaskLog) TableName() string {
return "task_log"
}

View File

@ -1188,7 +1188,7 @@ message TaskAssignRecordInfo {
int32 pendingVideoCount = 14 [json_name = "pendingVideoCount"]; //
int32 pendingPostCount = 15 [json_name = "pendingPostCount"]; //
int32 pendingDataCount = 16 [json_name = "pendingDataCount"]; //
string updatedAt = 24 [json_name = "updatedAt"]; //
string updatedAt = 17 [json_name = "updatedAt"]; //
}
//
@ -1235,9 +1235,28 @@ message ArtistBundleBalanceRequest {
//
message ArtistBundleBalanceResponse {
int32 remainingVideoCount = 1 [json_name = "remainingVideoCount"]; //
int32 remainingImageCount = 2 [json_name = "remainingImageCount"]; //
int32 remainingDataAnalysisCount = 3 [json_name = "remainingDataAnalysisCount"]; //
//
// task_balancetask_management//
// - //
int32 bundleVideoBalance = 1 [json_name = "bundleVideoBalance"]; //
int32 bundleImageBalance = 2 [json_name = "bundleImageBalance"]; //
int32 bundleDataAnalysisBalance = 3 [json_name = "bundleDataAnalysisBalance"]; //
// - //
int32 increaseVideoBalance = 4 [json_name = "increaseVideoBalance"]; //
int32 increaseImageBalance = 5 [json_name = "increaseImageBalance"]; //
int32 increaseDataAnalysisBalance = 6 [json_name = "increaseDataAnalysisBalance"]; //
// - //
int32 bundlePendingVideoCount = 7 [json_name = "bundlePendingVideoCount"]; //
int32 bundlePendingImageCount = 8 [json_name = "bundlePendingImageCount"]; //
int32 bundlePendingDataAnalysisCount = 9 [json_name = "bundlePendingDataAnalysisCount"]; //
// - //
int32 increasePendingVideoCount = 10 [json_name = "increasePendingVideoCount"]; //
int32 increasePendingImageCount = 11 [json_name = "increasePendingImageCount"]; //
int32 increasePendingDataAnalysisCount = 12 [json_name = "increasePendingDataAnalysisCount"]; //
}
message SetBundleBalanceLayoutReq{

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go-triple. DO NOT EDIT.
// versions:
// - protoc-gen-go-triple v1.0.8
// - protoc v3.12.4
// - protoc v3.21.1
// source: pb/bundle.proto
package bundle