micro-bundle/internal/controller/task.go

471 lines
17 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 controller
import (
"context"
"fmt"
"micro-bundle/internal/dto"
"micro-bundle/internal/logic"
"micro-bundle/internal/model"
"micro-bundle/pb/bundle"
"strings"
"time"
"go.uber.org/zap"
)
// AssignTask 指派某位员工完成某个艺人的任务
func (b *BundleProvider) AssignTask(_ context.Context, req *bundle.TaskAssignRequest) (*bundle.CommonResponse, error) {
daoReq := &dto.TaskAssignRequest{
SubNum: req.SubNum,
TelNum: req.TelNum,
ArtistName: req.ArtistName,
TaskAssignee: req.TaskAssignee,
TaskAssigneeNum: req.TaskAssigneeNum,
Operator: req.Operator,
OperatorNum: req.OperatorNum,
TaskBatch: req.TaskBatch,
AssignVideoCount: int(req.AssignVideoCount),
AssignPostCount: int(req.AssignPostCount),
AssignDataCount: int(req.AssignDataCount),
AssignVideoScriptCount: int(req.AssignVideoScriptCount),
}
err := logic.AssignTask(daoReq)
if err != nil {
return &bundle.CommonResponse{
Msg: err.Error(),
}, err
}
return &bundle.CommonResponse{
Msg: "任务指派成功",
}, nil
}
// GetRecentAssignRecords 查询最近被指派记录
func (b *BundleProvider) GetRecentAssignRecords(_ context.Context, req *bundle.RecentAssignRecordsRequest) (*bundle.RecentAssignRecordsResponse, error) {
limit := int(req.Limit)
if limit == 0 {
limit = 3 // 默认查询3条
}
// 调用logic层
assigneeList, err := logic.GetRecentAssignRecords(limit)
if err != nil {
return nil, err
}
return &bundle.RecentAssignRecordsResponse{
OperatorList: assigneeList,
}, nil
}
// GetEmployeeAssignedTasks 根据登录人信息查询被指派给该员工的任务
func (b *BundleProvider) GetEmployeeAssignedTasks(_ context.Context, req *bundle.EmployeeTaskQueryRequest) (*bundle.EmployeeTaskQueryResponse, error) {
// 如果 status 是已完成,就按照完成时间降序返回
if int(req.Status) == 2 {
req.SortBy = "complete_time"
}
daoReq := &dto.EmployeeTaskQueryRequest{
TaskAssigneeNum: req.TaskAssigneeNum,
Keyword: req.Keyword,
Operator: req.Operator,
SortBy: req.SortBy,
StartTime: req.StartTime,
EndTime: req.EndTime,
StartCompleteTime: req.StartCompleteTime,
EndCompleteTime: req.EndCompleteTime,
Status: int(req.Status),
Page: int(req.Page),
PageSize: int(req.PageSize),
TaskBatch: req.TaskBatch,
}
records, total, err := logic.GetEmployeeAssignedTasks(daoReq)
if err != nil {
return nil, err
}
var recordInfos []*bundle.TaskAssignRecordInfo
for _, record := range records {
recordInfo := convertToTaskAssignRecordInfo(record)
recordInfos = append(recordInfos, recordInfo)
}
return &bundle.EmployeeTaskQueryResponse{
Records: recordInfos,
Total: total,
Page: req.Page,
PageSize: req.PageSize,
}, nil
}
// CompleteTaskManually 员工手动点击完成任务
func (b *BundleProvider) CompleteTaskManually(_ context.Context, req *bundle.CompleteTaskManuallyRequest) (*bundle.CommonResponse, error) {
err := logic.CompleteTaskManually(req.AssignRecordsUUID, req.TaskAssigneeNum)
if err != nil {
return &bundle.CommonResponse{
Msg: err.Error(),
}, err
}
return &bundle.CommonResponse{
Msg: "任务完成",
}, nil
}
// UpdateTaskProgress 员工实际完成任务状态更新
func (b *BundleProvider) UpdateTaskProgress(_ context.Context, req *bundle.UpdateTaskProgressRequest) (*bundle.CommonResponse, error) {
daoReq := &dto.CompleteTaskRequest{
AssignRecordsUUID: req.AssignRecordsUUID,
EmployeeName: req.EmployeeName,
EmployeeNum: req.EmployeeNum,
TaskType: req.TaskType,
CompleteCount: int(req.CompleteCount),
UUID: req.Uuid,
}
err := logic.UpdateTaskProgress(daoReq)
if err != nil {
return &bundle.CommonResponse{
Msg: err.Error(),
}, err
}
return &bundle.CommonResponse{
Msg: "任务进度更新成功",
}, nil
}
// TerminateTaskByUUID 根据指派记录UUID终止任务
func (b *BundleProvider) TerminateTaskByUUID(_ context.Context, req *bundle.TerminateTaskByUUIDRequest) (*bundle.ComResponse, error) {
err := logic.TerminateTaskByUUID(req.AssignRecordsUUID)
if err != nil {
return &bundle.ComResponse{Msg: err.Error()}, err
}
return &bundle.ComResponse{Msg: "任务已终止"}, nil
}
// BatchTerminateTask 批量终止任务根据指派记录UUID列表
func (b *BundleProvider) BatchTerminateTask(_ context.Context, req *bundle.BatchTerminateTaskRequest) (*bundle.ComResponse, error) {
if req == nil || len(req.AssignRecordsUUIDs) == 0 {
return &bundle.ComResponse{Msg: "UUID 列表不能为空"}, fmt.Errorf("UUID 列表不能为空")
}
success, fail, failedUUIDs, err := logic.BatchTerminateTaskByUUIDs(req.AssignRecordsUUIDs)
if err != nil {
return &bundle.ComResponse{Msg: err.Error()}, err
}
// 组装返回信息
msg := fmt.Sprintf("批量中止完成:成功 %d 条,失败 %d 条", success, fail)
if fail > 0 && len(failedUUIDs) > 0 {
msg = fmt.Sprintf("%s失败UUID%s", msg, strings.Join(failedUUIDs, ","))
}
zap.L().Info(msg)
return &bundle.ComResponse{Msg: "批量中止完成"}, nil
}
func (b *BundleProvider) RevertTaskCompletionByUUIDItem(_ context.Context, req *bundle.RevertTaskCompletionByUUIDItemRequest) (*bundle.ComResponse, error) {
if req == nil || strings.TrimSpace(req.Uuid) == "" {
return &bundle.ComResponse{Msg: "UUID不能为空"}, fmt.Errorf("UUID不能为空")
}
if err := logic.RevertTaskCompletionByUUIDItem(req.Uuid); err != nil {
return &bundle.ComResponse{Msg: err.Error()}, err
}
return &bundle.ComResponse{Msg: "回退完成项成功"}, nil
}
// GetTaskActualStatusByUUID 根据指派记录UUID查询实际完成状态
func (b *BundleProvider) GetTaskActualStatusByUUID(_ context.Context, req *bundle.GetTaskActualStatusByUUIDRequest) (*bundle.GetTaskActualStatusByUUIDResponse, error) {
status, err := logic.GetTaskActualStatusByUUID(req.AssignRecordsUUID)
if err != nil {
return nil, err
}
return &bundle.GetTaskActualStatusByUUIDResponse{ActualStatus: int32(status)}, nil
}
// GetTaskAssignRecordsList 多条件查询操作记录表
func (b *BundleProvider) GetTaskAssignRecordsList(_ context.Context, req *bundle.TaskAssignRecordsQueryRequest) (*bundle.TaskAssignRecordsQueryResponse, error) {
// 如果 sortBy 是 pending_*,则转换为 assign_*
if sortBy, ok := model.OrderByPending[req.SortBy]; ok {
req.SortBy = sortBy
}
daoReq := &dto.TaskAssignRecordsQueryRequest{
Keyword: req.Keyword,
TaskAssignee: req.TaskAssignee,
Operator: req.Operator,
OperatorNum: req.OperatorNum,
StartTime: req.StartTime,
EndTime: req.EndTime,
Status: int(req.Status),
ActualStatus: int(req.ActualStatus),
Page: int(req.Page),
PageSize: int(req.PageSize),
TaskBatch: req.TaskBatch,
SortBy: req.SortBy,
SortType: req.SortType,
}
// 调用logic层
records, total, summary, err := logic.GetTaskAssignRecordsList(daoReq)
if err != nil {
return nil, err
}
var recordInfos []*bundle.TaskAssignRecordInfo
for _, record := range records {
recordInfo := convertToTaskAssignRecordInfo(record)
recordInfos = append(recordInfos, recordInfo)
}
return &bundle.TaskAssignRecordsQueryResponse{
Records: recordInfos,
Total: total,
Page: req.Page,
PageSize: req.PageSize,
Summary: convertToTaskAssignRecordsSummary(summary),
}, nil
}
// convertToTaskAssignRecordInfo 转换TaskAssignRecords模型为proto消息
func convertToTaskAssignRecordInfo(record *dto.TaskAssignRecordsResponse) *bundle.TaskAssignRecordInfo {
var completeTime string
if record.CompleteTime != nil {
completeTime = record.CompleteTime.Format("2006-01-02 15:04:05")
}
return &bundle.TaskAssignRecordInfo{
AssignRecordsUUID: record.AssignRecordsUUID,
SubNum: record.SubNum,
TelNum: record.TelNum,
ArtistName: record.ArtistName,
Status: int32(record.Status),
ActualStatus: int32(record.ActualStatus),
CompleteTime: completeTime,
OperatorType: int32(record.OperatorType),
Operator: record.Operator,
OperatorNum: record.OperatorNum,
OperatorTime: record.OperatorTime.Format("2006-01-02 15:04:05"),
TaskAssignee: record.TaskAssignee,
TaskAssigneeNum: record.TaskAssigneeNum,
PendingVideoCount: int32(record.PendingVideoCount),
PendingPostCount: int32(record.PendingPostCount),
PendingDataCount: int32(record.PendingDataCount),
UpdatedAt: record.UpdatedAt.Format("2006-01-02 15:04:05"),
TaskBatch: record.TaskBatch,
PendingVideoScriptCount: int32(record.PendingVideoScriptCount),
CompleteVideoScriptCount: int32(record.CompleteVideoScriptCount),
CompleteVideoCount: int32(record.CompleteVideoCount),
CompletePostCount: int32(record.CompletePostCount),
CompleteDataCount: int32(record.CompleteDataCount),
}
}
// convertToTaskAssignRecordsSummary 转换汇总结构到proto
func convertToTaskAssignRecordsSummary(s *dto.TaskAssignRecordsSummary) *bundle.TaskAssignRecordsSummary {
if s == nil {
return &bundle.TaskAssignRecordsSummary{}
}
return &bundle.TaskAssignRecordsSummary{
TotalPendingVideoScriptCount: int32(s.TotalPendingVideoScriptCount),
TotalPendingVideoCount: int32(s.TotalPendingVideoCount),
TotalPendingPostCount: int32(s.TotalPendingPostCount),
TotalPendingDataCount: int32(s.TotalPendingDataCount),
TotalCompleteVideoScriptCount: int32(s.TotalCompleteVideoScriptCount),
TotalCompleteVideoCount: int32(s.TotalCompleteVideoCount),
TotalCompletePostCount: int32(s.TotalCompletePostCount),
TotalCompleteDataCount: int32(s.TotalCompleteDataCount),
}
}
// BatchAssignTask 批量指派
func (b *BundleProvider) BatchAssignTask(_ context.Context, req *bundle.BatchAssignTaskRequest) (*bundle.ComResponse, error) {
if req == nil || len(req.Items) == 0 {
return &bundle.ComResponse{Msg: "批量指派项不能为空"}, fmt.Errorf("批量指派项不能为空")
}
// 转换请求项为DAO层结构
var items []*dto.BatchAssignItem
items = make([]*dto.BatchAssignItem, 0, len(req.Items))
for _, it := range req.Items {
if it == nil {
return &bundle.ComResponse{Msg: "存在空的指派项"}, fmt.Errorf("存在空的指派项")
}
items = append(items, &dto.BatchAssignItem{
SubNum: it.SubNum,
TelNum: it.TelNum,
ArtistName: it.ArtistName,
TaskAssignee: it.TaskAssignee,
TaskAssigneeNum: it.TaskAssigneeNum,
Operator: it.Operator,
OperatorNum: it.OperatorNum,
AssignVideoCount: int(it.AssignVideoCount),
AssignPostCount: int(it.AssignPostCount),
AssignDataCount: int(it.AssignDataCount),
AssignVideoScriptCount: int(it.AssignVideoScriptCount),
TaskBatch: it.TaskBatch,
})
}
// 调用逻辑层批量写入
if err := logic.BatchAssignTask(items); err != nil {
return &bundle.ComResponse{Msg: err.Error()}, err
}
return &bundle.ComResponse{Msg: "批量指派成功"}, nil
}
// GetArtistUploadStatsList 查询所有艺人的上传统计与额度信息
func (b *BundleProvider) GetArtistUploadStatsList(_ context.Context, req *bundle.TaskQueryRequest) (*bundle.ArtistUploadStatsResponse, error) {
// 对于数据分析的排序需求,转换一下
if sortBy, ok := model.OrderByDataAnalysis[req.SortBy]; ok {
req.SortBy = sortBy
}
daoReq := &dto.TaskQueryRequest{
Keyword: req.Keyword,
Page: int(req.Page),
PageSize: int(req.PageSize),
SortBy: req.SortBy,
SortType: req.SortType,
LastTaskAssignee: req.LastTaskAssignee,
SubNums: req.SubNums,
}
items, total, err := logic.GetArtistUploadStatsList(daoReq)
if err != nil {
return nil, err
}
formatTime := func(s string) string {
if s == "" {
return ""
}
if t, err := time.Parse(time.RFC3339, s); err == nil {
return t.Format("2006-01-02 15:04:05")
}
if _, err := time.Parse("2006-01-02 15:04:05", s); err == nil {
return s
}
return s
}
respItems := make([]*bundle.ArtistUploadStatsItem, 0, len(items))
for _, it := range items {
respItems = append(respItems, &bundle.ArtistUploadStatsItem{
SubNum: it.SubNum,
ArtistName: it.UserName,
TelNum: it.UserPhoneNumber,
StartAt: formatTime(it.StartAt),
ExpiredAt: formatTime(it.ExpiredAt),
UploadedVideoCount: int32(it.UploadedVideoCount),
BundleVideoTotal: int32(it.BundleVideoTotal),
IncreaseVideoTotal: int32(it.IncreaseVideoTotal),
ReleasedVideoTotal: int32(it.ReleasedVideoTotal),
PendingVideoCount: int32(it.PendingVideoCount),
UploadedPostCount: int32(it.UploadedPostCount),
BundlePostTotal: int32(it.BundlePostTotal),
IncreasePostTotal: int32(it.IncreasePostTotal),
ReleasedPostTotal: int32(it.ReleasedPostTotal),
PendingPostCount: int32(it.PendingPostCount),
UploadedDataAnalysisCount: int32(it.UploadedDataAnalysisCount),
BundleDataAnalysisTotal: int32(it.BundleDataAnalysisTotal),
IncreaseDataAnalysisTotal: int32(it.IncreaseDataAnalysisTotal),
ReleasedDataAnalysisTotal: int32(it.ReleasedDataAnalysisTotal),
PendingDataAnalysisCount: int32(it.PendingDataAnalysisCount),
LastTaskAssignee: it.LastTaskAssignee,
TaskAssigneeNum: it.TaskAssigneeNum,
ProgressTaskCount: int32(it.ProgressTaskCount),
CompleteTaskCount: int32(it.CompleteTaskCount),
UploadedVideoScriptCount: int32(it.UploadedVideoScriptCount),
PendingVideoScriptCount: int32(it.PendingVideoScriptCount),
AllowVideoScriptCount: int32(it.AllowVideoScriptCount),
AllowVideoCount: int32(it.AllowVideoCount),
AllowPostCount: int32(it.AllowPostCount),
AllowDataCount: int32(it.AllowDataCount),
})
}
return &bundle.ArtistUploadStatsResponse{
Items: respItems,
Total: total,
Page: req.Page,
PageSize: req.PageSize,
}, nil
}
// GetPendingAssign 查询艺人可指派数量
func (b *BundleProvider) GetPendingAssign(_ context.Context, req *bundle.PendingAssignRequest) (*bundle.PendingAssignResponse, error) {
items, total, err := logic.GetPendingAssignBySubNums(req.SubNums, int(req.Page), int(req.PageSize))
if err != nil {
return nil, err
}
respItems := make([]*bundle.PendingAssignItem, 0, len(items))
for _, it := range items {
respItems = append(respItems, &bundle.PendingAssignItem{
SubNum: it.SubNum,
TelNum: it.TelNum,
ArtistName: it.UserName,
AllowVideoScriptCount: int32(it.AllowVideoScriptCount),
AllowVideoCount: int32(it.AllowVideoCount),
AllowPostCount: int32(it.AllowPostCount),
AllowDataCount: int32(it.AllowDataCount),
})
}
return &bundle.PendingAssignResponse{Items: respItems, Total: total, Page: req.Page, PageSize: req.PageSize}, nil
}
func (b *BundleProvider) GetPendingTaskLayout(_ context.Context, _ *bundle.GetPendingTaskLayoutReq) (*bundle.GetPendingTaskLayoutResp, error) {
data, err := logic.GetPendingTaskLayout()
if err != nil {
return nil, err
}
return &bundle.GetPendingTaskLayoutResp{Data: data}, nil
}
func (b *BundleProvider) SetPendingTaskLayout(_ context.Context, req *bundle.SetPendingTaskLayoutReq) (*bundle.SetPendingTaskLayoutResp, error) {
if err := logic.SetPendingTaskLayout(req.Data); err != nil {
return &bundle.SetPendingTaskLayoutResp{}, err
}
return &bundle.SetPendingTaskLayoutResp{}, nil
}
func (b *BundleProvider) AddHiddenTaskAssignee(_ context.Context, req *bundle.AddHiddenTaskAssigneeRequest) (*bundle.ComResponse, error) {
if err := logic.AddHiddenTaskAssignee(req.TaskAssignee, req.TaskAssigneeNum); err != nil {
return &bundle.ComResponse{Msg: err.Error()}, err
}
return &bundle.ComResponse{Msg: "删除该指派人成功"}, nil
}
// CreateTaskWorkLog 创建任务日志记录
func (b *BundleProvider) CreateTaskWorkLog(_ context.Context, req *bundle.CreateTaskWorkLogRequest) (*bundle.CommonResponse, error) {
// 转换请求参数
daoReq := &dto.CreateTaskWorkLogRequest{
AssignRecordsUUID: req.AssignRecordsUUID,
WorkUUID: req.WorkUUID,
Title: req.Title,
ArtistUUID: req.ArtistUUID,
SubNum: req.SubNum,
TelNum: req.TelNum,
ArtistName: req.ArtistName,
OperationType: int(req.OperationType),
TaskType: int(req.TaskType),
TaskCount: int(req.TaskCount),
Remark: req.Remark,
OperatorName: req.OperatorName,
OperatorNum: req.OperatorNum,
}
// 调用logic层
err := logic.CreateTaskWorkLog(daoReq)
if err != nil {
return &bundle.CommonResponse{
Msg: err.Error(),
}, err
}
return &bundle.CommonResponse{
Msg: "任务日志创建成功",
}, nil
}