387 lines
14 KiB
Go
387 lines
14 KiB
Go
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
|
||
}
|