318 lines
12 KiB
Go
318 lines
12 KiB
Go
package logic
|
||
|
||
import (
|
||
"fmt"
|
||
"micro-bundle/internal/dao"
|
||
commonErr "micro-bundle/pkg/err"
|
||
)
|
||
|
||
// 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 {
|
||
// 计算聚合的待发数量:视频、图文、数据分析
|
||
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 {
|
||
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,
|
||
})
|
||
}
|
||
}
|
||
|
||
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.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)
|
||
}
|
||
|
||
// 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
|
||
}
|
||
|
||
// // 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)
|
||
}
|