micro-bundle/internal/logic/taskLogic.go

387 lines
14 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package logic
import (
"fmt"
"micro-bundle/internal/dao"
commonErr "micro-bundle/pkg/err"
"sort"
"strings"
)
// GetValidArtistList 查询套餐状态为有效中的艺人列表
// 调用dao层获取艺人详细信息
func GetValidArtistList() ([]dao.ValidArtistInfo, error) {
return dao.GetValidArtistList()
}
// GetValidArtistIDs 查询套餐没有过期的艺人ID列表保持向后兼容
// 根据BundleOrderRecords表查询过期时间大于当前时间且状态为已支付的艺人
func GetValidArtistIDs() ([]string, error) {
artistList, err := GetValidArtistList()
if err != nil {
return nil, err
}
var artistIDs []string
for _, artist := range artistList {
if artist.CustomerNum != "" {
artistIDs = append(artistIDs, artist.CustomerNum)
}
}
return artistIDs, nil
}
// todo 目前暂时不做检验,后续需要做判断
// GetValidEmployeeIDs 查询可以被指派任务的员工ID列表
// 这里可以根据实际业务需求实现,比如查询员工表、权限表等
// 目前先返回一个示例实现,实际项目中需要根据具体的员工管理逻辑来实现
func GetValidEmployeeIDs() ([]string, error) {
var employeeIDs []string
return employeeIDs, nil
}
// ValidateEmployee 验证员工是否可以被指派任务
func ValidateEmployee(employeeNum string) (bool, error) {
validEmployees, err := GetValidEmployeeIDs()
if err != nil {
return false, err
}
// 如果没有限制(返回空列表),则认为所有员工都可以被指派
if len(validEmployees) == 0 {
return true, nil
}
for _, validEmp := range validEmployees {
if validEmp == employeeNum {
return true, nil
}
}
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层查询待指派任务记录
record, total, err := dao.GetPendingTaskList(req, validArtist)
if err != nil {
return nil, 0, err
}
// 3. 转换为响应结构体
var recordResponse []*dao.TaskQueryResponse
for _, record := range record {
// 从TaskBalance表计算待发任务数量任务余额 - 消耗数量
videoTotal, imageTotal, dataTotal := calculatePendingFromTaskBalance(record.SubNum)
// 根据 SubNum 和 TelNum 查询对应的员工正在进行中的任务和已完成任务数量
progressTaskCount, completeTaskCount, err := dao.GetTaskAssigneeInfo(record.TaskAssigneeNum)
if err != nil {
recordResponse = append(recordResponse, &dao.TaskQueryResponse{
SubNum: record.SubNum,
TelNum: record.TelNum,
ArtistName: record.ArtistName,
TaskAssigneeNum: record.TaskAssigneeNum,
PendingPostCount: imageTotal,
PendingVideoCount: videoTotal,
PendingDataCount: dataTotal,
ProgressTaskCount: 0,
CompleteTaskCount: 0,
LastTaskAssignee: record.LastTaskAssignee,
})
} else {
recordResponse = append(recordResponse, &dao.TaskQueryResponse{
SubNum: record.SubNum,
TelNum: record.TelNum,
ArtistName: record.ArtistName,
TaskAssigneeNum: record.TaskAssigneeNum,
PendingPostCount: imageTotal,
PendingVideoCount: videoTotal,
PendingDataCount: dataTotal,
ProgressTaskCount: progressTaskCount,
CompleteTaskCount: completeTaskCount,
LastTaskAssignee: record.LastTaskAssignee,
})
}
}
// 4. 处理待发数量相关的排序在Logic层处理因为这些数据从TaskBalance表计算
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":
sort.Slice(recordResponse, func(i, j int) bool {
if strings.ToUpper(sortType) == "ASC" {
return recordResponse[i].PendingVideoCount < recordResponse[j].PendingVideoCount
}
return recordResponse[i].PendingVideoCount > recordResponse[j].PendingVideoCount
})
case "pending_post_count", "pendingPostCount":
sort.Slice(recordResponse, func(i, j int) bool {
if strings.ToUpper(sortType) == "ASC" {
return recordResponse[i].PendingPostCount < recordResponse[j].PendingPostCount
}
return recordResponse[i].PendingPostCount > recordResponse[j].PendingPostCount
})
case "pending_data_count", "pendingDataCount":
sort.Slice(recordResponse, func(i, j int) bool {
if strings.ToUpper(sortType) == "ASC" {
return recordResponse[i].PendingDataCount < recordResponse[j].PendingDataCount
}
return recordResponse[i].PendingDataCount > recordResponse[j].PendingDataCount
})
case "progress_task_count", "progressTaskCount":
sort.Slice(recordResponse, func(i, j int) bool {
if strings.ToUpper(sortType) == "ASC" {
return recordResponse[i].ProgressTaskCount < recordResponse[j].ProgressTaskCount
}
return recordResponse[i].ProgressTaskCount > recordResponse[j].ProgressTaskCount
})
case "complete_task_count", "completeTaskCount":
sort.Slice(recordResponse, func(i, j int) bool {
if strings.ToUpper(sortType) == "ASC" {
return recordResponse[i].CompleteTaskCount < recordResponse[j].CompleteTaskCount
}
return recordResponse[i].CompleteTaskCount > recordResponse[j].CompleteTaskCount
})
}
}
// 5. 分页(在排序后进行)
total = int64(len(recordResponse))
if req.PageSize > 0 && req.Page > 0 {
offset := (req.Page - 1) * req.PageSize
if offset < len(recordResponse) {
end := offset + req.PageSize
if end > len(recordResponse) {
end = len(recordResponse)
}
recordResponse = recordResponse[offset:end]
} else {
recordResponse = []*dao.TaskQueryResponse{}
}
}
return recordResponse, total, nil
}
// AssignTask 指派某位员工完成某个艺人的任务
func AssignTask(req *dao.TaskAssignRequest) error {
// 1. 验证员工是否可以被指派任务
isValid, err := ValidateEmployee(req.TaskAssigneeNum)
if err != nil {
return err
}
if !isValid {
return commonErr.ReturnError(nil, "员工不能被指派任务", "该员工不在可指派任务的员工列表中")
}
progressTaskCount, completeTaskCount, err := dao.GetTaskAssigneeInfo(req.TaskAssigneeNum)
if err != nil {
// 查询不到的话,给一个默认值
progressTaskCount, completeTaskCount = 1, 0
}
// 2. 调用DAO层执行指派任务
// 待完成任务数量需要+1因为这个任务暂时还没有指派所以+1
return dao.AssignTask(req, progressTaskCount+1, completeTaskCount)
}
// UpdatePendingCount 修改待发数量
func UpdatePendingCount(req *dao.UpdatePendingCountRequest) error {
// 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, "艺人套餐已过期", "该艺人没有有效的套餐,无法修改待发数量")
}
// 查询艺人当前任务余额,校验余额的总和是否足够
resp, err := dao.GetRemainingPendingBySubNum(req.SubNum)
if err != nil {
return commonErr.ReturnError(err, "查询艺人任务余额失败", "查询艺人任务余额失败: ")
}
fmt.Println(resp)
// 2. 调用DAO层更新待发数量
// return dao.UpdatePendingCount(req)
return nil
}
// GetRecentAssignRecords 查询最近被指派记录
func GetRecentAssignRecords(limit int) ([]string, error) {
records, err := dao.GetRecentAssignRecords(limit)
if err != nil {
return nil, err
}
var recordOperator []string
for _, record := range records {
recordOperator = append(recordOperator, record.TaskAssignee)
}
return recordOperator, nil
}
// GetEmployeeAssignedTasks 根据登录人信息查询被指派给该员工的艺人任务
func GetEmployeeAssignedTasks(req *dao.EmployeeTaskQueryRequest) ([]*dao.TaskAssignRecordsResponse, int64, error) {
// 1. 调用DAO层查询被指派给该员工的艺人任务
record, total, err := dao.GetEmployeeAssignedTasks(req)
if err != nil {
return nil, 0, err
}
// 2. 转换为响应结构体
var recordResponse []*dao.TaskAssignRecordsResponse
for _, record := range record {
recordResponse = append(recordResponse, &dao.TaskAssignRecordsResponse{
AssignRecordsUUID: record.AssignRecordsUUID,
SubNum: record.SubNum,
TelNum: record.TelNum,
ArtistName: record.ArtistName,
Status: record.Status,
ActualStatus: record.ActualStatus,
CompleteTime: record.CompleteTime,
OperatorType: record.OperatorType,
Operator: record.Operator,
OperatorNum: record.OperatorNum,
OperatorTime: record.OperatorTime,
TaskAssignee: record.TaskAssignee,
TaskAssigneeNum: record.TaskAssigneeNum,
PendingVideoCount: record.PendingVideoCount,
PendingPostCount: record.PendingPostCount,
PendingDataCount: record.PendingDataCount,
// todo: 将更新时间转换成人类可读的格式
UpdatedAt: record.UpdatedAt,
})
}
return recordResponse, total, nil
}
// CompleteTaskManually 员工手动点击完成任务
func CompleteTaskManually(assignRecordsUUID string, taskAssigneeNum string) error {
// // 第一步批量更新记录被指派的员工为taskAssigneeNum的待完成任务数量和已经完成任务的数量
// err := dao.UpdateTaskRecordsByAssigneeNum(taskAssigneeNum)
// if err != nil {
// return err
// }
return dao.CompleteTaskManually(assignRecordsUUID)
}
// UpdateTaskProgress 员工实际完成任务状态更新
func UpdateTaskProgress(req *dao.CompleteTaskRequest) error {
return dao.UpdateTaskProgress(req)
}
// GetTaskAssignRecordsList 多条件查询操作记录表
func GetTaskAssignRecordsList(req *dao.TaskAssignRecordsQueryRequest) ([]*dao.TaskAssignRecordsResponse, int64, error) {
record, total, err := dao.GetTaskAssignRecordsList(req)
if err != nil {
return nil, 0, err
}
// 2. 转换为响应结构体
var recordResponse []*dao.TaskAssignRecordsResponse
for _, record := range record {
recordResponse = append(recordResponse, &dao.TaskAssignRecordsResponse{
AssignRecordsUUID: record.AssignRecordsUUID,
SubNum: record.SubNum,
TelNum: record.TelNum,
ArtistName: record.ArtistName,
Status: record.Status,
ActualStatus: record.ActualStatus,
CompleteTime: record.CompleteTime,
OperatorType: record.OperatorType,
Operator: record.Operator,
OperatorNum: record.OperatorNum,
OperatorTime: record.OperatorTime,
TaskAssignee: record.TaskAssignee,
TaskAssigneeNum: record.TaskAssigneeNum,
PendingVideoCount: record.PendingVideoCount,
PendingPostCount: record.PendingPostCount,
PendingDataCount: record.PendingDataCount,
UpdatedAt: record.UpdatedAt,
})
}
return recordResponse, total, 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) {
// 查询用户的任务余额
taskBalance, err := dao.GetTaskBalanceBySubNum(subNum)
if err != nil || taskBalance == nil {
return 0, 0, 0
}
// 计算视频类待发数量:总余额 - 消耗数量
videoTotal = (taskBalance.TaskBundleVideoNumber - taskBalance.TaskBundleVideoConsumptionNumber) +
(taskBalance.TaskIncreaseVideoNumber - taskBalance.TaskIncreaseVideoConsumptionNumber) +
(taskBalance.TaskBundleLimitVideoNumber - taskBalance.TaskBundleLimitVideoConsumptionNumber) +
(taskBalance.TaskIncreaseLimitVideoNumber - taskBalance.TaskIncreaseLimitVideoConsumptionNumber) +
(taskBalance.TaskBundleLimitVideoExpiredNumber - taskBalance.TaskBundleLimitVideoExpiredConsumptionNumber) +
(taskBalance.TaskIncreaseLimitVideoExpiredNumber - taskBalance.TaskIncreaseLimitVideoExpiredConsumptionNumber)
if videoTotal < 0 {
videoTotal = 0
}
// 计算图片类待发数量:总余额 - 消耗数量
imageTotal = (taskBalance.TaskBundleImageNumber - taskBalance.TaskBundleImageConsumptionNumber) +
(taskBalance.TaskIncreaseImageNumber - taskBalance.TaskIncreaseImageConsumptionNumber) +
(taskBalance.TaskBundleLimitImageNumber - taskBalance.TaskBundleLimitImageConsumptionNumber) +
(taskBalance.TaskIncreaseLimitImageNumber - taskBalance.TaskIncreaseLimitImageConsumptionNumber) +
(taskBalance.TaskBundleLimitImageExpiredNumber - taskBalance.TaskBundleLimitImageExpiredConsumptionNumber) +
(taskBalance.TaskIncreaseLimitImageExpiredNumber - taskBalance.TaskIncreaseLimitImageExpiredConsumptionNumber)
if imageTotal < 0 {
imageTotal = 0
}
// 计算数据分析类待发数量:总余额 - 消耗数量
dataTotal = (taskBalance.TaskBundleDataAnalysisNumber - taskBalance.TaskBundleDataAnalysisConsumptionNumber) +
(taskBalance.TaskIncreaseDataAnalysisNumber - taskBalance.TaskIncreaseDataAnalysisConsumptionNumber) +
(taskBalance.TaskBundleLimitDataAnalysisNumber - taskBalance.TaskBundleLimitDataAnalysisConsumptionNumber) +
(taskBalance.TaskIncreaseLimitDataAnalysisNumber - taskBalance.TaskIncreaseLimitDataAnalysisConsumptionNumber) +
(taskBalance.TaskBundleLimitDataAnalysisExpiredNumber - taskBalance.TaskBundleLimitDataAnalysisExpiredConsumptionNumber) +
(taskBalance.TaskIncreaseLimitDataAnalysisExpiredNumber - taskBalance.TaskIncreaseLimitDataAnalysisExpiredConsumptionNumber)
if dataTotal < 0 {
dataTotal = 0
}
return videoTotal, imageTotal, dataTotal
}