feat: 新增任务台功能

新增任务管理台功能
This commit is contained in:
cjy 2025-09-03 15:51:35 +08:00
parent 2edf4b82ae
commit 019197fc15
19 changed files with 5461 additions and 1121 deletions

View File

@ -5,6 +5,7 @@ import (
"micro-bundle/internal/controller" "micro-bundle/internal/controller"
_ "micro-bundle/internal/handler" _ "micro-bundle/internal/handler"
"micro-bundle/pkg/app" "micro-bundle/pkg/app"
"micro-bundle/pkg/db"
"micro-bundle/pkg/tracing" "micro-bundle/pkg/tracing"
"dubbo.apache.org/dubbo-go/v3/config" "dubbo.apache.org/dubbo-go/v3/config"
@ -12,15 +13,15 @@ import (
_ "dubbo.apache.org/dubbo-go/v3/imports" _ "dubbo.apache.org/dubbo-go/v3/imports"
"github.com/bwmarrin/snowflake" "github.com/bwmarrin/snowflake"
"go.uber.org/zap" "go.uber.org/zap"
"gorm.io/gorm"
) )
func NewApp(Lg *zap.Logger, JaegerTracer *tracing.JaegerProvider, SfNode *snowflake.Node, BundleDB *gorm.DB) *app.App { func NewApp(Lg *zap.Logger, JaegerTracer *tracing.JaegerProvider, SfNode *snowflake.Node, BundleDB *db.BundleDB, TaskBenchDB *db.TaskBenchDB) *app.App {
return &app.App{ return &app.App{
Lg: Lg, Lg: Lg,
JaegerTracer: JaegerTracer, JaegerTracer: JaegerTracer,
SfNode: SfNode, SfNode: SfNode,
BundleDB: BundleDB, BundleDB: BundleDB,
TaskBenchDB: TaskBenchDB,
} }
} }

View File

@ -14,6 +14,6 @@ import (
) )
func InitApp() (*app.App, error) { func InitApp() (*app.App, error) {
wire.Build(logger.Provider, tracing.Provider, snowf.Provider, db.Provider, NewApp) wire.Build(logger.Provider, tracing.Provider, snowf.Provider, db.Provider, db.TaskBenchProvider, NewApp)
return &app.App{}, nil return &app.App{}, nil
} }

View File

@ -1,6 +1,6 @@
// Code generated by Wire. DO NOT EDIT. // Code generated by Wire. DO NOT EDIT.
//go:generate go run github.com/google/wire/cmd/wire //go:generate go run -mod=mod github.com/google/wire/cmd/wire
//go:build !wireinject //go:build !wireinject
// +build !wireinject // +build !wireinject
@ -12,6 +12,12 @@ import (
"micro-bundle/pkg/logger" "micro-bundle/pkg/logger"
"micro-bundle/pkg/snowf" "micro-bundle/pkg/snowf"
"micro-bundle/pkg/tracing" "micro-bundle/pkg/tracing"
_ "dubbo.apache.org/dubbo-go/v3/filter/tps/strategy"
_ "dubbo.apache.org/dubbo-go/v3/imports"
_ "micro-bundle/internal/handler"
) )
// Injectors from wire.go: // Injectors from wire.go:
@ -20,7 +26,8 @@ func InitApp() (*app.App, error) {
zapLogger := logger.ZapInit() zapLogger := logger.ZapInit()
jaegerProvider := tracing.NewTracing() jaegerProvider := tracing.NewTracing()
node := snowf.NewSf() node := snowf.NewSf()
gormDB := db.NewBundleDB() bundleDB := db.NewBundleDB()
appApp := NewApp(zapLogger, jaegerProvider, node, gormDB) taskBenchDB := db.NewTaskBenchDB()
appApp := NewApp(zapLogger, jaegerProvider, node, bundleDB, taskBenchDB)
return appApp, nil return appApp, nil
} }

View File

@ -7,6 +7,12 @@ bundleDB:
user: artuser user: artuser
password: C250PflXIWv2SQm8 password: C250PflXIWv2SQm8
db_name: "fiee_bundle" db_name: "fiee_bundle"
taskBenchDB:
host: 121.229.45.214
port: 9007
user: artuser
password: C250PflXIWv2SQm8
db_name: "fiee_task_bench"
#aliYunRtc: #aliYunRtc:
# appid: "aeztom27" # appid: "aeztom27"
# app_key: "76c62466cbd77d7a3606660a15861d1e" # app_key: "76c62466cbd77d7a3606660a15861d1e"

View File

@ -7,6 +7,12 @@ bundleDB:
user: artuser user: artuser
password: C250PflXIWv2SQm8 password: C250PflXIWv2SQm8
db_name: "fiee_bundle" db_name: "fiee_bundle"
taskBenchDB:
host: 121.229.45.214
port: 9007
user: artuser
password: C250PflXIWv2SQm8
db_name: "fiee_task_bench"
#aliYunRtc: #aliYunRtc:
# appid: "aeztom27" # appid: "aeztom27"
# app_key: "76c62466cbd77d7a3606660a15861d1e" # app_key: "76c62466cbd77d7a3606660a15861d1e"

View File

@ -7,6 +7,12 @@ bundleDB:
user: fonchain_opv user: fonchain_opv
password: IhQmhg8HZjDmU=Ove5PnA^D password: IhQmhg8HZjDmU=Ove5PnA^D
db_name: "micro_bundle" db_name: "micro_bundle"
taskBenchDB:
host: svc-fontree-mysql-service
port: 3306
user: fonchain_opv
password: IhQmhg8HZjDmU=Ove5PnA^D
db_name: "fiee_task_bench"
#redis: #redis:
# db: ${oa-meeting.redis.db} # db: ${oa-meeting.redis.db}
# addr: ${redis.addr} # addr: ${redis.addr}

View File

@ -26,6 +26,13 @@ type AppConfig struct {
Password string Password string
DbName string `mapstructure:"db_name"` DbName string `mapstructure:"db_name"`
} }
TaskBenchDB struct {
Host string
Port string
User string
Password string
DbName string `mapstructure:"db_name"`
}
Redis struct { Redis struct {
DB string DB string
Addr string Addr string

296
internal/controller/task.go Normal file
View File

@ -0,0 +1,296 @@
package controller
import (
"context"
"fmt"
"micro-bundle/internal/dao"
"micro-bundle/internal/logic"
"micro-bundle/pb/bundle"
)
// GetPendingTaskList 查询待指派任务记录
func (b *BundleProvider) GetPendingTaskList(_ context.Context, req *bundle.TaskQueryRequest) (*bundle.TaskQueryResponse, error) {
// 转换请求参数
daoReq := &dao.TaskQueryRequest{
Keyword: req.Keyword,
Page: int(req.Page),
PageSize: int(req.PageSize),
SortBy: req.SortBy,
SortType: req.SortType,
}
// 调用logic层
tasks, total, err := logic.GetPendingTaskList(daoReq)
if err != nil {
return nil, err
}
// 转换响应数据
var taskInfos []*bundle.TaskManagementInfo
for _, task := range tasks {
taskInfo := &bundle.TaskManagementInfo{
SubNum: task.SubNum,
TelNum: task.TelNum,
ArtistName: task.ArtistName,
PendingVideoCount: int32(task.PendingVideoCount),
PendingPostCount: int32(task.PendingPostCount),
PendingDataCount: int32(task.PendingDataCount),
ProgressTaskCount: int32(task.ProgressTaskCount),
CompleteTaskCount: int32(task.CompleteTaskCount),
LastTaskAssignee: task.LastTaskAssignee,
TaskAssigneeNum: task.TaskAssigneeNum,
}
taskInfos = append(taskInfos, taskInfo)
}
return &bundle.TaskQueryResponse{
Tasks: taskInfos,
Total: total,
Page: req.Page,
PageSize: req.PageSize,
}, nil
}
// AssignTask 指派某位员工完成某个艺人的任务
// AssignTask 指派某位员工完成某个艺人的任务
func (b *BundleProvider) AssignTask(_ context.Context, req *bundle.TaskAssignRequest) (*bundle.CommonResponse, error) {
// 转换请求参数
daoReq := &dao.TaskAssignRequest{
SubNum: req.SubNum,
TelNum: req.TelNum,
ArtistName: req.ArtistName, // 添加缺失的ArtistName字段
TaskAssignee: req.TaskAssignee,
TaskAssigneeNum: req.TaskAssigneeNum,
Operator: req.Operator,
OperatorNum: req.OperatorNum,
AssignVideoCount: int(req.AssignVideoCount),
AssignPostCount: int(req.AssignPostCount),
AssignDataCount: int(req.AssignDataCount),
}
// 调用logic层
err := logic.AssignTask(daoReq)
if err != nil {
return &bundle.CommonResponse{
Msg: err.Error(),
}, err
}
return &bundle.CommonResponse{
Msg: "任务指派成功",
}, nil
}
// UpdatePendingCount 修改待发数量
func (b *BundleProvider) UpdatePendingCount(_ context.Context, req *bundle.UpdatePendingCountRequest) (*bundle.CommonResponse, error) {
// 转换请求参数
daoReq := &dao.UpdatePendingCountRequest{
SubNum: req.SubNum,
TelNum: req.TelNum,
ArtistName: req.ArtistName, // 添加缺失的ArtistName字段
PendingVideoCount: int(req.PendingVideoCount),
PendingPostCount: int(req.PendingPostCount),
PendingDataCount: int(req.PendingDataCount),
Operator: req.Operator,
OperatorNum: req.OperatorNum,
}
// 调用logic层
err := logic.UpdatePendingCount(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层
operatorList, err := logic.GetRecentAssignRecords(limit)
if err != nil {
return nil, err
}
return &bundle.RecentAssignRecordsResponse{
OperatorList: operatorList,
}, nil
}
// GetEmployeeAssignedTasks 根据登录人信息查询被指派给该员工的任务
func (b *BundleProvider) GetEmployeeAssignedTasks(_ context.Context, req *bundle.EmployeeTaskQueryRequest) (*bundle.EmployeeTaskQueryResponse, error) {
// 转换请求参数
daoReq := &dao.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),
}
// 调用logic层
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) {
// 调用logic层
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 := &dao.CompleteTaskRequest{
AssignRecordsUUID: req.AssignRecordsUUID,
EmployeeName: req.EmployeeName,
EmployeeNum: req.EmployeeNum,
TaskType: req.TaskType,
CompleteCount: int(req.CompleteCount),
}
// 调用logic层
err := logic.UpdateTaskProgress(daoReq)
if err != nil {
return &bundle.CommonResponse{
Msg: err.Error(),
}, err
}
return &bundle.CommonResponse{
Msg: "任务进度更新成功",
}, nil
}
// GetTaskAssignRecordsList 多条件查询操作记录表
func (b *BundleProvider) GetTaskAssignRecordsList(_ context.Context, req *bundle.TaskAssignRecordsQueryRequest) (*bundle.TaskAssignRecordsQueryResponse, error) {
// 转换请求参数
daoReq := &dao.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),
}
// 调用logic层
records, total, 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,
}, nil
}
// convertToTaskAssignRecordInfo 转换TaskAssignRecords模型为proto消息
func convertToTaskAssignRecordInfo(record *dao.TaskAssignRecordsResponse) *bundle.TaskAssignRecordInfo {
var completeTime string
if !record.CompleteTime.IsZero() {
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"),
}
}
// GetArtistBundleBalance 查询艺人套餐剩余数量
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,
}
// 调用logic层
result, err := logic.GetArtistBundleBalance(daoReq)
if err != nil {
return nil, err
}
// 转换响应数据
return &bundle.ArtistBundleBalanceResponse{
RemainingVideoCount: int32(result.RemainingVideoCount),
RemainingImageCount: int32(result.RemainingImageCount),
RemainingDataAnalysisCount: int32(result.RemainingDataAnalysisCount),
}, nil
}

964
internal/dao/taskDao.go Normal file
View File

@ -0,0 +1,964 @@
package dao
import (
"fmt"
"micro-bundle/internal/model"
"micro-bundle/pkg/app"
commonErr "micro-bundle/pkg/err"
"micro-bundle/pkg/msg"
"time"
"github.com/google/uuid"
"gorm.io/gorm"
)
// TaskQueryRequest 查询待指派任务记录请求参数
type TaskQueryRequest struct {
Keyword string `json:"keyword"` // 艺人姓名、编号、手机号搜索关键词
Page int `json:"page"` // 页码
PageSize int `json:"pageSize"` // 每页数量
SortBy string `json:"sortBy"` // 排序字段
SortType string `json:"sortType"` // 排序类型 asc/desc
}
// TaskAssignRequest 指派任务请求参数
type TaskAssignRequest struct {
SubNum string `json:"subNum"` // 艺人编号
TelNum string `json:"telNum"` // 艺人手机号
ArtistName string `json:"artistName"` // 艺人姓名
TaskAssignee string `json:"taskAssignee"` // 任务指派人
TaskAssigneeNum string `json:"taskAssigneeNum"` // 任务指派人账号
Operator string `json:"operator"` // 操作人
OperatorNum string `json:"operatorNum"` // 操作人账号
AssignVideoCount int `json:"assignVideoCount"` // 指派视频数
AssignPostCount int `json:"assignPostCount"` // 指派图文数
AssignDataCount int `json:"assignDataCount"` // 指派数据数
}
// UpdatePendingCountRequest 修改待发数量请求参数
type UpdatePendingCountRequest struct {
SubNum string `json:"subNum"` // 艺人编号
TelNum string `json:"telNum"` // 艺人手机号
ArtistName string `json:"artistName"` // 艺人姓名
PendingVideoCount int `json:"pendingVideoCount"` // 待发视频数量
PendingPostCount int `json:"pendingPostCount"` // 待发图文数量
PendingDataCount int `json:"pendingDataCount"` // 待发数据数量
Operator string `json:"operator"` // 操作人
OperatorNum string `json:"operatorNum"` // 操作人账号
}
// EmployeeTaskQueryRequest 员工任务查询请求参数
type EmployeeTaskQueryRequest struct {
TaskAssigneeNum string `json:"taskAssigneeNum"` // 被指派人账号
Keyword string `json:"keyword"` // 艺人姓名、编号、手机号搜索关键词
Operator string `json:"operator"` // 操作人
SortBy string `json:"sortBy"` // 排序字段
StartTime string `json:"startTime"` // 指派开始时间
EndTime string `json:"endTime"` // 指派结束时间
StartCompleteTime string `json:"startCompleteTime"` // 开始完成时间
EndCompleteTime string `json:"endCompleteTime"` // 结束完成时间
Status int `json:"status"` // 反馈完成状态
Page int `json:"page"` // 页码
PageSize int `json:"pageSize"` // 每页数量
}
// CompleteTaskRequest 完成任务请求参数
type CompleteTaskRequest struct {
AssignRecordsUUID string `json:"assignRecordsUUID,omitempty"` // 指派记录UUID可选
EmployeeName string `json:"employeeName"` // 员工姓名(必要)
EmployeeNum string `json:"employeeNum"` // 员工工号(必要)
TaskType string `json:"taskType"` // 任务类型: video/post/data
CompleteCount int `json:"completeCount"` // 完成数量
}
// TaskAssignRecordsQueryRequest 多条件查询操作记录表请求参数
type TaskAssignRecordsQueryRequest struct {
Keyword string `json:"keyword"` // 艺人姓名、编号、手机号搜索关键词
TaskAssignee string `json:"taskAssignee"` // 指派人姓名
Operator string `json:"operator"` // 操作人姓名
OperatorNum string `json:"operatorNum"` // 操作人手机号
StartTime string `json:"startTime"` // 操作开始时间
EndTime string `json:"endTime"` // 操作结束时间
Status int `json:"status"` // 反馈完成状态 0:全部 1:未完成 2:完成
ActualStatus int `json:"actualStatus"` // 实际完成状态 0:全部 1:未完成 2:完成
Page int `json:"page"` // 页码
PageSize int `json:"pageSize"` // 每页数量
}
// 待指派任务 response
type TaskQueryResponse struct {
SubNum string `json:"subNum"`
TelNum string `json:"telNum"`
ArtistName string `json:"artistName"`
PendingVideoCount int `gorm:"column:pending_video_count;comment:待发视频数量" json:"pendingVideoCount"`
PendingPostCount int `gorm:"column:pending_post_count;comment:待发图文数量" json:"pendingPostCount"`
PendingDataCount int `gorm:"column:pending_data_count;comment:待发数据数量" json:"pendingDataCount"`
ProgressTaskCount int `gorm:"column:progress_task_count;comment:进行中的任务数量" json:"progressTaskCount"`
CompleteTaskCount int `gorm:"column:complete_task_count;comment:已完成任务数量" json:"completeTaskCount"`
LastTaskAssignee string `gorm:"column:last_task_assignee;comment:最后一次的任务指派人" json:"lastTaskAssignee"`
TaskAssigneeNum string `gorm:"column:task_assignee_num;comment:最后一次指派人账号" json:"taskAssigneeNum"`
}
// 任务记录表返回结构体
type TaskAssignRecordsResponse struct {
AssignRecordsUUID string `gorm:"column:assign_records_uuid;comment:指派记录UUID" json:"assignRecordsUUID"`
SubNum string `gorm:"column:sub_num;comment:艺人编号" json:"subNum"`
TelNum string `gorm:"column:tel_num;comment:艺人手机号" json:"telNum"`
ArtistName string `gorm:"column:artist_name;comment:艺人名称" json:"artistName"`
Status int `gorm:"column:status;comment:反馈完成状态 1:未完成 2:完成" json:"status"`
ActualStatus int `gorm:"column:actual_status;comment:实际完成状态 1:未完成 2:完成" json:"actualStatus"`
CompleteTime *time.Time `gorm:"column:complete_time;comment:反馈完成时间" json:"completeTime"`
OperatorType int `gorm:"column:operator_type;comment:操作类型 1:修改待发数量 2:指派" json:"operatorType"`
Operator string `gorm:"column:operator;comment:操作人" json:"operator"`
OperatorNum string `gorm:"column:operator_num;comment:操作人账号" json:"operatorNum"`
OperatorTime time.Time `gorm:"column:operator_time;comment:操作时间" json:"operatorTime"`
TaskAssignee string `gorm:"column:task_assignee;comment:任务指派人" json:"taskAssignee"`
TaskAssigneeNum string `gorm:"column:task_assignee_num;comment:任务指派人账号" json:"taskAssigneeNum"`
PendingVideoCount int `gorm:"column:pending_video_count;comment:待发视频数量" json:"pendingVideoCount"`
PendingPostCount int `gorm:"column:pending_post_count;comment:待发图文数量" json:"pendingPostCount"`
PendingDataCount int `gorm:"column:pending_data_count;comment:待发数据数量" json:"pendingDataCount"`
UpdatedAt time.Time `gorm:"column:updated_at;comment:更新时间" json:"updatedAt"`
}
// 任务指派记录数量结构体
type TaskAssignRecords struct {
TaskAssigneeNum string `json:"taskAssigneeNum"` // 任务指派人工号
ProgressTaskCount int `json:"progressTaskCount"` // 进行中任务数量
CompleteTaskCount int `json:"completeTaskCount"` // 已完成任务数量
}
// ValidArtistInfo 有效艺人信息结构体
type ValidArtistInfo struct {
UserID int `json:"userId"` // 用户ID
CustomerNum string `json:"customerNum"` // 艺人编号
UserName string `json:"userName"` // 艺人姓名
UserPhoneNumber string `json:"userPhoneNumber"` // 艺人手机号
BundleName string `json:"bundleName"` // 套餐名称
ExpirationTime string `json:"expirationTime"` // 过期时间
Status int `json:"status"` // 套餐状态
OrderUUID string `json:"orderUUID"` // 订单UUID
AccountNumber int `json:"accountNumber"` // 账号数量
AccountConsumptionNumber int `json:"accountConsumptionNumber"` // 账号消耗数量
VideoNumber int `json:"videoNumber"` // 视频数量
VideoConsumptionNumber int `json:"videoConsumptionNumber"` // 视频消耗数量
ImageNumber int `json:"imageNumber"` // 图片数量
ImageConsumptionNumber int `json:"imageConsumptionNumber"` // 图片消耗数量
DataAnalysisNumber int `json:"dataAnalysisNumber"` // 数据分析数量
DataAnalysisConsumptionNumber int `json:"dataAnalysisConsumptionNumber"` // 数据分析消耗数量
ExpansionPacksNumber int `json:"expansionPacksNumber"` // 扩展套餐数量
}
// ArtistBundleBalanceRequest 查询艺人套餐剩余数量请求参数
type ArtistBundleBalanceRequest struct {
CustomerNum string `json:"customerNum"` // 艺人编号(推荐使用)
TelNum string `json:"telNum"` // 艺人手机号(备选)
}
// ArtistBundleBalanceResponse 艺人套餐剩余数量响应结构体
type ArtistBundleBalanceResponse struct {
RemainingVideoCount int `json:"remainingVideoCount"` // 剩余视频数量 (video_number - video_consumption_number)
RemainingImageCount int `json:"remainingImageCount"` // 剩余图片数量 (image_number - image_consumption_number)
RemainingDataAnalysisCount int `json:"remainingDataAnalysisCount"` // 剩余数据分析数量 (data_analysis_number - data_analysis_consumption_number)
}
// GetPendingTaskList 查询待指派任务记录
// 根据套餐没有过期的艺人查询TaskManagement表中的记录如果不存在则构建默认值
func GetPendingTaskList(req *TaskQueryRequest, validArtist []ValidArtistInfo) ([]*model.TaskManagement, int64, error) {
// 构建有效艺人ID列表
var validArtistIDs []string
for _, artist := range validArtist {
if artist.CustomerNum != "" {
validArtistIDs = append(validArtistIDs, artist.CustomerNum)
}
}
// 如果没有有效艺人,直接返回空结果
if len(validArtistIDs) == 0 {
return []*model.TaskManagement{}, 0, nil
}
// 第一步:查询所有有效艺人在数据库中的存在情况(不应用关键词过滤)
var existingTasks []*model.TaskManagement
existQuery := app.ModuleClients.TaskBenchDB.Model(&model.TaskManagement{}).Where("sub_num IN (?)", validArtistIDs)
err := existQuery.Find(&existingTasks).Error
if err != nil {
return nil, 0, commonErr.ReturnError(err, msg.ErrorGetBundleList, "查询现有任务记录失败: ")
}
// 创建已存在艺人编号的映射
existingSubNums := make(map[string]bool)
for _, task := range existingTasks {
existingSubNums[task.SubNum] = true
}
// 创建艺人编号到艺人信息的映射,便于快速查找
artistMap := make(map[string]ValidArtistInfo)
for _, artist := range validArtist {
artistMap[artist.CustomerNum] = artist
}
// 为不存在的艺人创建默认记录
var newTasksToCreate []*model.TaskManagement
for _, subNum := range validArtistIDs {
if !existingSubNums[subNum] {
artist := artistMap[subNum]
// 构建默认任务记录
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,
ProgressCount: 0,
CompleteCount: 0,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
newTasksToCreate = append(newTasksToCreate, defaultTask)
}
}
// 批量创建新的任务记录
if len(newTasksToCreate) > 0 {
if err := app.ModuleClients.TaskBenchDB.Create(&newTasksToCreate).Error; err != nil {
return nil, 0, commonErr.ReturnError(err, msg.ErrorGetBundleList, "创建默认任务记录失败: ")
}
}
// 第二步:应用完整的查询条件进行最终查询
var tasks []*model.TaskManagement
var total int64
// 构建最终查询条件
query := app.ModuleClients.TaskBenchDB.Model(&model.TaskManagement{})
// 限制在有效艺人范围内
query = query.Where("sub_num IN (?)", validArtistIDs)
// 关键词搜索(艺人姓名、编号、手机号)
if req.Keyword != "" {
query = query.Where("sub_num LIKE ? OR tel_num LIKE ? OR artist_name LIKE ?",
"%"+req.Keyword+"%", "%"+req.Keyword+"%", "%"+req.Keyword+"%")
}
// 计算总数
query.Count(&total)
// 排序
if req.SortBy != "" && req.SortType != "" {
orderClause := fmt.Sprintf("%s %s", req.SortBy, req.SortType)
query = query.Order(orderClause)
} else {
// 默认按待发视频降序
query = query.Order("pending_video_count DESC")
}
// 分页
if req.PageSize > 0 && req.Page > 0 {
offset := (req.Page - 1) * req.PageSize
query = query.Limit(req.PageSize).Offset(offset)
}
err = query.Find(&tasks).Error
if err != nil {
return nil, 0, commonErr.ReturnError(err, msg.ErrorGetBundleList, "查询待指派任务记录失败: ")
}
return tasks, total, nil
}
// AssignTask 指派某位员工完成某个艺人的任务
func AssignTask(req *TaskAssignRequest, progressTaskCount int, completeTaskCount int) error {
// 开启事务
tx := app.ModuleClients.TaskBenchDB.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
// 1. 查询当前艺人的任务记录
var taskManagement model.TaskManagement
err := tx.Where("sub_num = ? AND tel_num = ?", req.SubNum, req.TelNum).First(&taskManagement).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
// 如果不存在,创建新记录
taskManagement = model.TaskManagement{
SubNum: req.SubNum,
TelNum: req.TelNum,
ArtistName: req.ArtistName,
PendingVideoCount: 0,
PendingPostCount: 0,
PendingDataCount: 0,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
if err = tx.Create(&taskManagement).Error; err != nil {
tx.Rollback()
return commonErr.ReturnError(err, "创建任务记录失败", "创建任务记录失败: ")
}
} else {
tx.Rollback()
return commonErr.ReturnError(err, "查询任务记录失败", "查询任务记录失败: ")
}
}
// 2. 检查待发数量是否大于0
if taskManagement.PendingVideoCount <= 0 && taskManagement.PendingPostCount <= 0 && taskManagement.PendingDataCount <= 0 {
tx.Rollback()
return commonErr.ReturnError(nil, "无可指派任务", "当前艺人待发视频数、图文数、数据数均为0无法指派任务")
}
// 3. 检查指派数量是否合理(增强验证)
if req.AssignVideoCount < 0 || req.AssignPostCount < 0 || req.AssignDataCount < 0 {
tx.Rollback()
return commonErr.ReturnError(nil, "指派数量不能为负数", "指派数量必须大于等于0")
}
if req.AssignVideoCount > taskManagement.PendingVideoCount ||
req.AssignPostCount > taskManagement.PendingPostCount ||
req.AssignDataCount > taskManagement.PendingDataCount {
tx.Rollback()
return commonErr.ReturnError(nil, "指派数量超出限制",
fmt.Sprintf("指派数量不能超过待发数量。当前待发:视频%d图文%d数据%d",
taskManagement.PendingVideoCount, taskManagement.PendingPostCount, taskManagement.PendingDataCount))
}
if req.AssignVideoCount == 0 && req.AssignPostCount == 0 && req.AssignDataCount == 0 {
tx.Rollback()
return commonErr.ReturnError(nil, "指派数量不能全为0", "至少需要指派一种类型的任务")
}
// 4. 更新TaskManagement表
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,
"last_task_assignee": req.TaskAssignee,
"task_assignee_num": req.TaskAssigneeNum,
"progress_count": progressTaskCount,
"complete_count": completeTaskCount,
"updated_at": time.Now(),
}
if err = tx.Model(&taskManagement).Updates(updateData).Error; err != nil {
tx.Rollback()
return commonErr.ReturnError(err, "更新任务记录失败", "更新任务记录失败: ")
}
// 5. 创建指派记录
assignRecord := &model.TaskAssignRecords{
AssignRecordsUUID: uuid.New().String(), // 使用Google UUID
SubNum: req.SubNum,
TelNum: req.TelNum,
ArtistName: req.ArtistName,
Status: 1, // 1:未完成
ActualStatus: 1, // 1:未完成
OperatorType: 2, // 2:指派
Operator: req.Operator, // 当前操作人名字
OperatorNum: req.OperatorNum, // 当前操作人账号
OperatorTime: time.Now(),
TaskAssignee: req.TaskAssignee, // 指派员工姓名
TaskAssigneeNum: req.TaskAssigneeNum, // 指派员工账号
PendingVideoCount: taskManagement.PendingVideoCount,
PendingPostCount: taskManagement.PendingPostCount,
PendingDataCount: taskManagement.PendingDataCount,
AssignVideoCount: req.AssignVideoCount,
AssignPostCount: req.AssignPostCount,
AssignDataCount: req.AssignDataCount,
CompleteVideoCount: 0,
CompletePostCount: 0,
CompleteDataCount: 0,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
if err = tx.Create(assignRecord).Error; err != nil {
tx.Rollback()
return commonErr.ReturnError(err, "创建指派记录失败", "创建指派记录失败: ")
}
// 提交事务
if err = tx.Commit().Error; err != nil {
return commonErr.ReturnError(err, "提交事务失败", "提交事务失败: ")
}
return nil
}
// UpdatePendingCount 修改待发数量
func UpdatePendingCount(req *UpdatePendingCountRequest) error {
// 开启事务
tx := app.ModuleClients.TaskBenchDB.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
// 1. 查询或创建TaskManagement记录
var taskManagement model.TaskManagement
err := tx.Where("sub_num = ? AND tel_num = ?", req.SubNum, req.TelNum).First(&taskManagement).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return commonErr.ReturnError(err, "无该艺人任务记录", "无该艺人任务记录")
} else {
tx.Rollback()
return commonErr.ReturnError(err, "查询任务记录失败", "查询任务记录失败: ")
}
} else {
// 更新现有记录
updateData := map[string]interface{}{
"pending_video_count": req.PendingVideoCount,
"pending_post_count": req.PendingPostCount,
"pending_data_count": req.PendingDataCount,
"updated_at": time.Now(),
}
if err = tx.Model(&taskManagement).Updates(updateData).Error; err != nil {
tx.Rollback()
return commonErr.ReturnError(err, "更新任务记录失败", "更新任务记录失败: ")
}
}
// 提交事务
if err = tx.Commit().Error; err != nil {
return commonErr.ReturnError(err, "提交事务失败", "提交事务失败: ")
}
return nil
}
// GetRecentAssignRecords 查询最近被指派记录
// 查询操作类型为"指派"的最近n条不同员工的记录
func GetRecentAssignRecords(limit int) ([]*model.TaskAssignRecords, error) {
var records []*model.TaskAssignRecords
// 查询操作类型为指派(2)的记录,按操作时间倒序,去重员工
err := app.ModuleClients.TaskBenchDB.Model(&model.TaskAssignRecords{}).
Where("operator_type = ?", 2). // 2:指派
Group("task_assignee_num"). // 按指派人账号分组去重
Order("operator_time DESC"). // 按操作时间倒序
Limit(limit).
Find(&records).Error
if err != nil {
return nil, commonErr.ReturnError(err, "查询最近指派记录失败", "查询最近指派记录失败: ")
}
return records, nil
}
// GetEmployeeAssignedTasks 根据登录人信息查询被指派给该员工的艺人任务
func GetEmployeeAssignedTasks(req *EmployeeTaskQueryRequest) ([]*model.TaskAssignRecords, int64, error) {
var records []*model.TaskAssignRecords
var total int64
// 构建查询条件
query := app.ModuleClients.TaskBenchDB.Model(&model.TaskAssignRecords{}).
Where("task_assignee_num = ?", req.TaskAssigneeNum)
// 关键词搜索(艺人姓名、编号、手机号)
if req.Keyword != "" {
query = query.Where("sub_num LIKE ? OR tel_num LIKE ?",
"%"+req.Keyword+"%", "%"+req.Keyword+"%")
}
// 被指派人姓名
if req.Operator != "" {
query = query.Where("task_assignee LIKE ?", "%"+req.Operator+"%")
}
// 指派时间区间
if req.StartTime != "" {
query = query.Where("operator_time >= ?", req.StartTime)
}
if req.EndTime != "" {
query = query.Where("operator_time <= ?", req.EndTime)
}
// 完成时间区间
if req.StartCompleteTime != "" {
query = query.Where("complete_time >= ?", req.StartCompleteTime)
}
if req.EndCompleteTime != "" {
query = query.Where("complete_time <= ?", req.EndCompleteTime)
}
// 反馈完成状态
if req.Status != 0 {
query = query.Where("status = ?", req.Status)
}
// 根据排序字段倒序
if req.SortBy != "" {
query = query.Order(req.SortBy + " DESC")
}
// 计算总数
query.Count(&total)
// 分页
if req.PageSize > 0 && req.Page > 0 {
offset := (req.Page - 1) * req.PageSize
query = query.Limit(req.PageSize).Offset(offset)
}
// 按操作时间倒序
err := query.Order("operator_time DESC").Find(&records).Error
if err != nil {
return nil, 0, commonErr.ReturnError(err, "查询员工指派任务失败", "查询员工指派任务失败: ")
}
return records, total, nil
}
// CompleteTaskManually 员工手动点击完成任务
func CompleteTaskManually(assignRecordsUUID string) error {
now := time.Now()
updateData := map[string]interface{}{
"status": 2, // 2:完成
"complete_time": &now,
"updated_at": now,
}
err := app.ModuleClients.TaskBenchDB.Model(&model.TaskAssignRecords{}).
Where("assign_records_uuid = ?", assignRecordsUUID).
Updates(updateData).Error
if err != nil {
return commonErr.ReturnError(err, "更新任务完成状态失败", "更新任务完成状态失败: ")
}
return nil
}
// UpdateTaskProgress 员工实际完成任务状态更新
// 员工调用视频、图文、数据时,对应的待完成数据减一,已完成数据加一
func UpdateTaskProgress(req *CompleteTaskRequest) error {
// 开启事务
tx := app.ModuleClients.TaskBenchDB.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
// 1. 查询指派记录
var assignRecord model.TaskAssignRecords
var err error
if req.AssignRecordsUUID != "" {
// 如果提供了UUID直接根据UUID查询
err = tx.Where("assign_records_uuid = ?", req.AssignRecordsUUID).First(&assignRecord).Error
if err != nil {
tx.Rollback()
return commonErr.ReturnError(err, "查询指派记录失败", "查询指派记录失败: ")
}
} else {
// 如果没有提供UUID根据员工信息查询最早的未完成任务
if req.EmployeeName == "" || req.EmployeeNum == "" {
tx.Rollback()
return commonErr.ReturnError(nil, "参数错误", "员工姓名和手机号不能为空")
}
err = tx.Where("task_assignee = ? AND task_assignee_num = ? AND actual_status = 1",
req.EmployeeName, req.EmployeeNum).
Order("operator_time ASC").
First(&assignRecord).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
tx.Rollback()
return commonErr.ReturnError(nil, "未找到任务记录", "该员工没有未完成的任务记录")
}
tx.Rollback()
return commonErr.ReturnError(err, "查询指派记录失败", "查询指派记录失败: ")
}
}
// 2. 根据任务类型更新完成数量
updateData := map[string]interface{}{
"updated_at": time.Now(),
}
switch req.TaskType {
case "video":
newCompleteCount := assignRecord.CompleteVideoCount + req.CompleteCount
if newCompleteCount > assignRecord.AssignVideoCount {
tx.Rollback()
return commonErr.ReturnError(nil, "完成数量超出限制", "视频完成数量不能超过指派数量")
}
updateData["complete_video_count"] = newCompleteCount
case "post":
newCompleteCount := assignRecord.CompletePostCount + req.CompleteCount
if newCompleteCount > assignRecord.AssignPostCount {
tx.Rollback()
return commonErr.ReturnError(nil, "完成数量超出限制", "图文完成数量不能超过指派数量")
}
updateData["complete_post_count"] = newCompleteCount
case "data":
newCompleteCount := assignRecord.CompleteDataCount + req.CompleteCount
if newCompleteCount > assignRecord.AssignDataCount {
tx.Rollback()
return commonErr.ReturnError(nil, "完成数量超出限制", "数据完成数量不能超过指派数量")
}
updateData["complete_data_count"] = newCompleteCount
default:
tx.Rollback()
return commonErr.ReturnError(nil, "无效的任务类型", "任务类型必须是video、post或data")
}
// 3. 更新指派记录
if err = tx.Model(&assignRecord).Updates(updateData).Error; err != nil {
tx.Rollback()
return commonErr.ReturnError(err, "更新完成数量失败", "更新完成数量失败: ")
}
// 4. 重新查询更新后的记录,检查是否全部完成
if err = tx.Where("assign_records_uuid = ?", assignRecord.AssignRecordsUUID).First(&assignRecord).Error; err != nil {
tx.Rollback()
return commonErr.ReturnError(err, "查询更新后记录失败", "查询更新后记录失败: ")
}
// 5. 检查是否所有任务都已完成
if assignRecord.CompleteVideoCount == assignRecord.AssignVideoCount &&
assignRecord.CompletePostCount == assignRecord.AssignPostCount &&
assignRecord.CompleteDataCount == assignRecord.AssignDataCount {
// 更新实际完成状态
if err = tx.Model(&assignRecord).Update("actual_status", 2).Error; err != nil {
tx.Rollback()
return commonErr.ReturnError(err, "更新实际完成状态失败", "更新实际完成状态失败: ")
}
}
// 提交事务
if err = tx.Commit().Error; err != nil {
return commonErr.ReturnError(err, "提交事务失败", "提交事务失败: ")
}
return nil
}
// GetTaskManagementBySubNum 根据艺人编号查询任务管理记录
func GetTaskManagementBySubNum(subNum string) (*model.TaskManagement, error) {
var task model.TaskManagement
err := app.ModuleClients.TaskBenchDB.Where("sub_num = ?", subNum).First(&task).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil // 记录不存在
}
return nil, commonErr.ReturnError(err, "查询任务管理记录失败", "查询任务管理记录失败: ")
}
return &task, nil
}
// GetAssignRecordByUUID 根据UUID查询指派记录
func GetAssignRecordByUUID(uuid string) (*model.TaskAssignRecords, error) {
var record model.TaskAssignRecords
err := app.ModuleClients.TaskBenchDB.Where("assign_records_uuid = ?", uuid).First(&record).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil // 记录不存在
}
return nil, commonErr.ReturnError(err, "查询指派记录失败", "查询指派记录失败: ")
}
return &record, nil
}
// GetTaskAssignRecordsList 多条件查询操作记录表
// 支持通过艺人信息、指派人、操作人、操作时间、完成状态等多条件查询TaskAssignRecords表
func GetTaskAssignRecordsList(req *TaskAssignRecordsQueryRequest) ([]*model.TaskAssignRecords, int64, error) {
var records []*model.TaskAssignRecords
var total int64
// 构建查询条件
query := app.ModuleClients.TaskBenchDB.Model(&model.TaskAssignRecords{})
// 关键词搜索(艺人姓名、编号、手机号)
if req.Keyword != "" {
query = query.Where("sub_num LIKE ? OR tel_num LIKE ? OR artist_name LIKE ?",
"%"+req.Keyword+"%", "%"+req.Keyword+"%", "%"+req.Keyword+"%")
}
// 指派人姓名
if req.TaskAssignee != "" {
query = query.Where("task_assignee LIKE ?", "%"+req.TaskAssignee+"%")
}
// 操作人姓名
if req.Operator != "" {
query = query.Where("operator LIKE ?", "%"+req.Operator+"%")
}
// 操作人手机号
if req.OperatorNum != "" {
query = query.Where("operator_num LIKE ?", "%"+req.OperatorNum+"%")
}
// 操作时间区间
if req.StartTime != "" {
query = query.Where("operator_time >= ?", req.StartTime)
}
if req.EndTime != "" {
query = query.Where("operator_time <= ?", req.EndTime)
}
// 反馈完成状态
if req.Status != 0 {
query = query.Where("status = ?", req.Status)
}
// 实际完成状态
if req.ActualStatus != 0 {
query = query.Where("actual_status = ?", req.ActualStatus)
}
// 计算总数
query.Count(&total)
// 分页
if req.PageSize > 0 && req.Page > 0 {
offset := (req.Page - 1) * req.PageSize
query = query.Limit(req.PageSize).Offset(offset)
}
// 按更新时间倒序排序
err := query.Order("updated_at DESC").Find(&records).Error
if err != nil {
return nil, 0, commonErr.ReturnError(err, "查询操作记录失败", "查询操作记录失败: ")
}
return records, total, nil
}
// GetValidArtistList 查询套餐状态为有效中的艺人数据列表
// 根据BundleOrderRecords表查询过期时间大于当前时间且状态为已支付的艺人详细信息
func GetValidArtistList() ([]ValidArtistInfo, error) {
// 构建子查询,获取每个用户的最新订单记录
subQuery := app.ModuleClients.BundleDB.Table("bundle_order_records as bor1").
Select("bor1.*").
Joins(`INNER JOIN (
SELECT customer_id, MAX(created_at) AS max_created_time
FROM bundle_order_records
GROUP BY customer_id
) bor2 ON bor1.customer_id = bor2.customer_id AND bor1.created_at = bor2.max_created_time`)
// 主查询,关联用户表和实名信息表
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`).
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").
Where("rn.name IS NOT NULL").
Where("u.deleted_at = 0").
Where("bor.expiration_time > ?", time.Now().Format("2006-01-02 15:04:05")).
Where("bor.status = ?", 2). // 2:已签已支付
Order("bor.expiration_time desc")
var data []ValidArtistInfo
err := session.Find(&data).Error
if err != nil {
return nil, commonErr.ReturnError(err, "查询有效艺人失败", "查询有效艺人失败: ")
}
return data, nil
}
// 根据员工的工号从指派任务记录表中查询这名员工,进行中任务数量和已经完成的任务数量
func GetTaskAssigneeInfo(taskAssigneeNum string) (int, int, error) {
// 如果taskAssigneeNum为空直接返回默认值
if taskAssigneeNum == "" {
return 0, 0, nil
}
var taskAssignRecords TaskAssignRecords
err := app.ModuleClients.TaskBenchDB.Table("task_assign_records").
Select("task_assignee_num, count(*) as progress_task_count, sum(status = 2) as complete_task_count").
Where("task_assignee_num = ?", taskAssigneeNum).
Group("task_assignee_num").
First(&taskAssignRecords).Error
// 如果查询不到记录,返回默认值而不是错误
if err != nil {
if err == gorm.ErrRecordNotFound {
return 0, 0, nil
}
return 0, 0, commonErr.ReturnError(err, "查询任务指派记录失败", "查询任务指派记录失败: ")
}
return taskAssignRecords.ProgressTaskCount, taskAssignRecords.CompleteTaskCount, nil
}
// 更新被指派员工为 taskAssigneeNum 的记录中的ProgressCount + 1 和CompleteCount - 1
func UpdateTaskRecordsByAssigneeNum(taskAssigneeNum string) error {
err := app.ModuleClients.TaskBenchDB.Table("task_management").
Where("task_assignee_num = ?", taskAssigneeNum).
Update("progress_count", gorm.Expr("progress_count + ?", 1)).
Update("complete_count", gorm.Expr("complete_count - ?", 1)).Error
if err != nil {
return commonErr.ReturnError(err, "更新员工任务进度失败", "更新员工任务进度失败: ")
}
return nil
}
// GetArtistBundleBalance 根据艺人编号或手机号查询套餐剩余数量
// 优先使用艺人编号查询,如果为空则使用手机号查询
func GetArtistBundleBalance(req *ArtistBundleBalanceRequest) (*ArtistBundleBalanceResponse, error) {
// 构建子查询,获取用户的最新订单记录
subQuery := app.ModuleClients.BundleDB.Table("bundle_order_records as bor1").
Select("bor1.*").
Joins(`INNER JOIN (
SELECT customer_id, MAX(created_at) AS max_created_time
FROM bundle_order_records
GROUP BY customer_id
) bor2 ON bor1.customer_id = bor2.customer_id AND bor1.created_at = bor2.max_created_time`)
// 主查询,关联用户表和实名信息表
session := app.ModuleClients.BundleDB.Table("`micro-account`.`user` AS u").
Select(`u.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`).
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").
Where("rn.name IS NOT NULL").
Where("u.deleted_at = 0").
Where("bor.expiration_time > ?", time.Now().Format("2006-01-02 15:04:05")).
Where("bor.status = ?", 2) // 2:已签已支付
// 根据查询条件添加WHERE子句
if req.CustomerNum != "" {
session = session.Where("bor.customer_num = ?", req.CustomerNum)
} else if req.TelNum != "" {
session = session.Where("u.tel_num = ?", req.TelNum)
} else {
return nil, commonErr.ReturnError(nil, "查询参数错误", "艺人编号和手机号不能同时为空")
}
var data ValidArtistInfo
err := session.Take(&data).Error // 使用Take()替代First(),避免自动排序
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, commonErr.ReturnError(err, "艺人不存在或套餐已过期", "未找到有效的艺人套餐信息")
}
return nil, commonErr.ReturnError(err, "查询艺人套餐信息失败", "查询艺人套餐信息失败: ")
}
// 计算剩余数量
response := &ArtistBundleBalanceResponse{
RemainingVideoCount: data.VideoNumber - data.VideoConsumptionNumber,
RemainingImageCount: data.ImageNumber - data.ImageConsumptionNumber,
RemainingDataAnalysisCount: data.DataAnalysisNumber - data.DataAnalysisConsumptionNumber,
}
return response, nil
}
// AdjustPendingCountRequest 调整待发数量请求参数
type AdjustPendingCountRequest struct {
SubNum string `json:"subNum"` // 艺人编号
TelNum string `json:"telNum"` // 艺人手机号
ArtistName string `json:"artistName"` // 艺人姓名
AdjustVideoCount int `json:"adjustVideoCount"` // 调整视频数量(正数为增加,负数为减少)
AdjustPostCount int `json:"adjustPostCount"` // 调整图文数量(正数为增加,负数为减少)
AdjustDataCount int `json:"adjustDataCount"` // 调整数据数量(正数为增加,负数为减少)
CreateIfNotExists bool `json:"createIfNotExists"` // 如果记录不存在是否创建
}
// AdjustPendingCount 调整待发数量(增加或减少)
// 支持正数增加和负数减少,可用于套餐扩展时同步增加待发任务数量
func AdjustPendingCount(req *AdjustPendingCountRequest) error {
// 开启事务
tx := app.ModuleClients.TaskBenchDB.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
// 1. 查询现有任务记录
var taskManagement model.TaskManagement
err := tx.Where("sub_num = ? AND tel_num = ?", req.SubNum, req.TelNum).First(&taskManagement).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
if req.CreateIfNotExists {
// 创建新记录
taskManagement = model.TaskManagement{
SubNum: req.SubNum,
TelNum: req.TelNum,
ArtistName: req.ArtistName,
PendingVideoCount: req.AdjustVideoCount,
PendingPostCount: req.AdjustPostCount,
PendingDataCount: req.AdjustDataCount,
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, "创建任务记录失败", "创建任务记录失败: ")
}
} else {
tx.Rollback()
return commonErr.ReturnError(err, "任务记录不存在", "找不到对应的任务记录")
}
} else {
tx.Rollback()
return commonErr.ReturnError(err, "查询任务记录失败", "查询任务记录失败: ")
}
} else {
// 2. 计算调整后的数量
newVideoCount := taskManagement.PendingVideoCount + req.AdjustVideoCount
newPostCount := taskManagement.PendingPostCount + req.AdjustPostCount
newDataCount := taskManagement.PendingDataCount + req.AdjustDataCount
// 3. 确保调整后的数量不为负数
if newVideoCount < 0 {
newVideoCount = 0
}
if newPostCount < 0 {
newPostCount = 0
}
if newDataCount < 0 {
newDataCount = 0
}
// 4. 更新TaskManagement表
updateData := map[string]interface{}{
"pending_video_count": newVideoCount,
"pending_post_count": newPostCount,
"pending_data_count": newDataCount,
"updated_at": time.Now(),
}
if err = tx.Model(&taskManagement).Updates(updateData).Error; err != nil {
tx.Rollback()
return commonErr.ReturnError(err, "更新任务记录失败", "更新任务记录失败: ")
}
}
// 提交事务
if err = tx.Commit().Error; err != nil {
return commonErr.ReturnError(err, "提交事务失败", "提交事务失败: ")
}
return nil
}

314
internal/logic/taskLogic.go Normal file
View File

@ -0,0 +1,314 @@
package logic
import (
"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 {
// 根据 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: record.PendingPostCount,
PendingVideoCount: record.PendingVideoCount,
PendingDataCount: record.PendingDataCount,
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: record.PendingPostCount,
PendingVideoCount: record.PendingVideoCount,
PendingDataCount: record.PendingDataCount,
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, "艺人套餐已过期", "该艺人没有有效的套餐,无法修改待发数量")
}
// todo 需要调用套餐的接口,判断艺人是否有那么数量可以修改
// 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)
}
// // 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)
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)
}

62
internal/model/task.go Normal file
View File

@ -0,0 +1,62 @@
package model
import (
"time"
"gorm.io/plugin/soft_delete"
)
type TaskManagement struct {
ID int64 `gorm:"primarykey"`
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"`
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"`
CompleteCount int `gorm:"column:complete_count;comment:已完成的任务数量" json:"completeCount"`
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_deleted_at" json:"deletedAt"`
}
func (t *TaskManagement) TableName() string {
return "task_management"
}
// 指派记录表
type TaskAssignRecords struct {
ID int64 `gorm:"primarykey"`
AssignRecordsUUID string `gorm:"column:assign_records_uuid;comment:指派记录UUID;uniqueIndex:idx_assign_uuid" json:"assignRecordsUUID"`
SubNum string `gorm:"column:sub_num;comment:艺人编号;index:idx_assign_sub_num;index:idx_assign_sub_tel,priority:1" json:"subNum"`
TelNum string `gorm:"column:tel_num;comment:艺人手机号;index:idx_assign_tel_num;index:idx_assign_sub_tel,priority:2" json:"telNum"`
ArtistName string `gorm:"column:artist_name;comment:艺人名称;index:idx_assign_artist_name" json:"artistName"`
Status int `gorm:"column:status;comment:反馈完成状态 1:未完成 2:完成;index:idx_status;index:idx_status_assignee,priority:1" json:"status"`
ActualStatus int `gorm:"column:actual_status;comment:实际完成状态 1:未完成 2:完成;index:idx_actual_status;index:idx_actual_assignee,priority:1" json:"actualStatus"`
CompleteTime *time.Time `gorm:"column:complete_time;comment:反馈完成时间;index:idx_complete_time" json:"completeTime"`
OperatorType int `gorm:"column:operator_type;comment:操作类型 1:修改待发数量 2:指派;index:idx_operator_type;index:idx_operator_type_time,priority:1" json:"operatorType"`
Operator string `gorm:"column:operator;comment:操作人;index:idx_operator" json:"operator"`
OperatorNum string `gorm:"column:operator_num;comment:操作人账号;index:idx_operator_num" json:"operatorNum"`
OperatorTime time.Time `gorm:"column:operator_time;comment:操作时间;index:idx_operator_time;index:idx_operator_type_time,priority:2" json:"operatorTime"`
TaskAssignee string `gorm:"column:task_assignee;comment:任务指派人;index:idx_task_assignee;index:idx_status_assignee,priority:2;index:idx_actual_assignee,priority:2" json:"taskAssignee"`
TaskAssigneeNum string `gorm:"column:task_assignee_num;comment:任务指派人账号;index:idx_task_assignee_num" json:"taskAssigneeNum"`
PendingVideoCount int `gorm:"column:pending_video_count;comment:待发视频数量" json:"pendingVideoCount"`
PendingPostCount int `gorm:"column:pending_post_count;comment:待发图文数量" json:"pendingPostCount"`
PendingDataCount int `gorm:"column:pending_data_count;comment:待发数据数量" json:"pendingDataCount"`
AssignVideoCount int `gorm:"column:assign_video_count;comment:指派待发视频数" json:"assignVideoCount"`
AssignPostCount int `gorm:"column:assign_post_count;comment:指派待发图文数" json:"assignPostCount"`
AssignDataCount int `gorm:"column:assign_data_count;comment:指派待发数据数" json:"assignDataCount"`
CompleteVideoCount int `gorm:"column:complete_video_count;comment:已完成视频数" json:"completeVideoCount"`
CompletePostCount int `gorm:"column:complete_post_count;comment:已完成图文数" json:"completePostCount"`
CompleteDataCount int `gorm:"column:complete_data_count;comment:已完成数据数" json:"completeDataCount"`
CreatedAt time.Time `gorm:"column:created_at;comment:创建时间" json:"createdAt"`
UpdatedAt time.Time `gorm:"column:updated_at;comment:更新时间;index:idx_updated_at" json:"updatedAt"`
DeletedAt soft_delete.DeletedAt `gorm:"column:deleted_at;type:int(11);index:idx_assign_deleted_at" json:"deletedAt"`
}
func (t *TaskAssignRecords) TableName() string {
return "task_assign_records"
}

View File

@ -78,6 +78,17 @@ service Bundle {
// //
rpc ListUnfinishedInfos(AutoCreateUserAndOrderRequest) returns (UnfinishedInfos) {} // rpc ListUnfinishedInfos(AutoCreateUserAndOrderRequest) returns (UnfinishedInfos) {} //
rpc SoftDeleteUnfinishedInfo(SoftDeleteUnfinishedInfoRequest) returns (CommonResponse) {} // rpc SoftDeleteUnfinishedInfo(SoftDeleteUnfinishedInfoRequest) returns (CommonResponse) {} //
//
rpc GetPendingTaskList(TaskQueryRequest) returns (TaskQueryResponse) {} //
rpc AssignTask(TaskAssignRequest) returns (CommonResponse) {} //
rpc UpdatePendingCount(UpdatePendingCountRequest) returns (CommonResponse) {} //
rpc GetRecentAssignRecords(RecentAssignRecordsRequest) returns (RecentAssignRecordsResponse) {} //
rpc GetEmployeeAssignedTasks(EmployeeTaskQueryRequest) returns (EmployeeTaskQueryResponse) {} //
rpc CompleteTaskManually(CompleteTaskManuallyRequest) returns (CommonResponse) {} //
rpc UpdateTaskProgress(UpdateTaskProgressRequest) returns (CommonResponse) {} //
rpc GetTaskAssignRecordsList(TaskAssignRecordsQueryRequest) returns (TaskAssignRecordsQueryResponse) {} //
rpc GetArtistBundleBalance(ArtistBundleBalanceRequest) returns (ArtistBundleBalanceResponse) {} //
} }
message DeleteValueAddServiceRequest{ message DeleteValueAddServiceRequest{
string orderNo = 1; string orderNo = 1;
@ -121,6 +132,7 @@ message ReconciliationInfo{
string serialNumber = 13; string serialNumber = 13;
uint64 userID = 14; uint64 userID = 14;
string handlingFee = 15; string handlingFee = 15;
string subNum = 16;
} }
message OrderInfoByOrderNoRequest{ message OrderInfoByOrderNoRequest{
string orderNo = 1; string orderNo = 1;
@ -207,6 +219,7 @@ message OrderBundleRecordInfo{
repeated OrderAddBundleRecordInfo addBundleInfo = 8; repeated OrderAddBundleRecordInfo addBundleInfo = 8;
int64 customerId = 9; int64 customerId = 9;
string payTime = 10; string payTime = 10;
string subNum = 11;
} }
message OrderAddBundleRecordInfo{ message OrderAddBundleRecordInfo{
string orderAddNo = 1; string orderAddNo = 1;
@ -874,3 +887,162 @@ message UnfinishedInfo {
message SoftDeleteUnfinishedInfoRequest { message SoftDeleteUnfinishedInfoRequest {
uint32 ID = 1; uint32 ID = 1;
} }
//
//
message TaskQueryRequest {
string keyword = 1 [json_name = "keyword"]; //
int32 page = 2 [json_name = "page"]; //
int32 pageSize = 3 [json_name = "pageSize"]; //
string sortBy = 4 [json_name = "sortBy"]; //
string sortType = 5 [json_name = "sortType"]; // asc/desc
}
message TaskQueryResponse {
repeated TaskManagementInfo tasks = 1 [json_name = "tasks"];
int64 total = 2 [json_name = "total"];
int32 page = 3 [json_name = "page"];
int32 pageSize = 4 [json_name = "pageSize"];
}
message TaskManagementInfo {
string subNum = 1 [json_name = "subNum"]; //
string telNum = 2 [json_name = "telNum"]; //
string artistName = 3 [json_name = "artistName"]; //
int32 pendingVideoCount = 4 [json_name = "pendingVideoCount"]; //
int32 pendingPostCount = 5 [json_name = "pendingPostCount"]; //
int32 pendingDataCount = 6 [json_name = "pendingDataCount"]; //
int32 progressTaskCount = 7 [json_name = "progressTaskCount"]; //
int32 completeTaskCount = 8 [json_name = "completeTaskCount"]; //
string lastTaskAssignee = 9 [json_name = "lastTaskAssignee"]; //
string taskAssigneeNum = 10 [json_name = "taskAssigneeNum"]; //
}
//
message TaskAssignRequest {
string subNum = 1 [json_name = "subNum"]; //
string telNum = 2 [json_name = "telNum"]; //
string artistName = 3 [json_name = "artistName"]; //
string taskAssignee = 4 [json_name = "taskAssignee"]; //
string taskAssigneeNum = 5 [json_name = "taskAssigneeNum"]; //
string operator = 6 [json_name = "operator"]; //
string operatorNum = 7 [json_name = "operatorNum"]; //
int32 assignVideoCount = 8 [json_name = "assignVideoCount"]; //
int32 assignPostCount = 9 [json_name = "assignPostCount"]; //
int32 assignDataCount = 10 [json_name = "assignDataCount"]; //
}
//
message UpdatePendingCountRequest {
string subNum = 1 [json_name = "subNum"]; //
string telNum = 2 [json_name = "telNum"]; //
string artistName = 3 [json_name = "artistName"]; //
int32 pendingVideoCount = 4 [json_name = "pendingVideoCount"]; //
int32 pendingPostCount = 5 [json_name = "pendingPostCount"]; //
int32 pendingDataCount = 6 [json_name = "pendingDataCount"]; //
string operator = 7 [json_name = "operator"]; //
string operatorNum = 8 [json_name = "operatorNum"]; //
}
//
message RecentAssignRecordsRequest {
int32 limit = 1 [json_name = "limit"]; //
}
message RecentAssignRecordsResponse {
repeated string operatorList = 1 [json_name = "operatorList"];
}
//
message EmployeeTaskQueryRequest {
string taskAssigneeNum = 1 [json_name = "taskAssigneeNum"]; //
string keyword = 2 [json_name = "keyword"]; //
string operator = 3 [json_name = "operator"]; //
string sortBy = 4 [json_name = "sortBy"]; //
string startTime = 5 [json_name = "startTime"]; //
string endTime = 6 [json_name = "endTime"]; //
string startCompleteTime = 7 [json_name = "startCompleteTime"]; //
string endCompleteTime = 8 [json_name = "endCompleteTime"]; //
int32 status = 9 [json_name = "status"]; //
int32 page = 10 [json_name = "page"]; //
int32 pageSize = 11 [json_name = "pageSize"]; //
}
message EmployeeTaskQueryResponse {
repeated TaskAssignRecordInfo records = 1 [json_name = "records"];
int64 total = 2 [json_name = "total"];
int32 page = 3 [json_name = "page"];
int32 pageSize = 4 [json_name = "pageSize"];
}
//
message TaskAssignRecordInfo {
string assignRecordsUUID = 1 [json_name = "assignRecordsUUID"]; // UUID
string subNum = 2 [json_name = "subNum"]; //
string telNum = 3 [json_name = "telNum"]; //
string artistName = 4 [json_name = "artistName"]; //
int32 status = 5 [json_name = "status"]; //
int32 actualStatus = 6 [json_name = "actualStatus"]; //
string completeTime = 7 [json_name = "completeTime"]; //
int32 operatorType = 8 [json_name = "operatorType"]; //
string operator = 9 [json_name = "operator"]; //
string operatorNum = 10 [json_name = "operatorNum"]; //
string operatorTime = 11 [json_name = "operatorTime"]; //
string taskAssignee = 12 [json_name = "taskAssignee"]; //
string taskAssigneeNum = 13 [json_name = "taskAssigneeNum"]; //
int32 pendingVideoCount = 14 [json_name = "pendingVideoCount"]; //
int32 pendingPostCount = 15 [json_name = "pendingPostCount"]; //
int32 pendingDataCount = 16 [json_name = "pendingDataCount"]; //
string updatedAt = 24 [json_name = "updatedAt"]; //
}
//
message CompleteTaskManuallyRequest {
string assignRecordsUUID = 1 [json_name = "assignRecordsUUID"]; // UUID
string taskAssigneeNum = 2 [json_name = "taskAssigneeNum"]; //
}
//
message UpdateTaskProgressRequest {
string assignRecordsUUID = 1 [json_name = "assignRecordsUUID"]; // UUID
string employeeName = 2 [json_name = "employeeName"]; //
string employeeNum = 3 [json_name = "employeeNum"]; //
string taskType = 4 [json_name = "taskType"]; // : video/post/data
int32 completeCount = 5 [json_name = "completeCount"]; //
}
//
message TaskAssignRecordsQueryRequest {
string keyword = 1 [json_name = "keyword"]; //
string taskAssignee = 2 [json_name = "taskAssignee"]; //
string operator = 3 [json_name = "operator"]; //
string operatorNum = 4 [json_name = "operatorNum"]; //
string startTime = 5 [json_name = "startTime"]; //
string endTime = 6 [json_name = "endTime"]; //
int32 status = 7 [json_name = "status"]; //
int32 actualStatus = 8 [json_name = "actualStatus"]; //
int32 page = 9 [json_name = "page"]; //
int32 pageSize = 10 [json_name = "pageSize"]; //
}
message TaskAssignRecordsQueryResponse {
repeated TaskAssignRecordInfo records = 1 [json_name = "records"];
int64 total = 2 [json_name = "total"];
int32 page = 3 [json_name = "page"];
int32 pageSize = 4 [json_name = "pageSize"];
}
//
message ArtistBundleBalanceRequest {
string customerNum = 1 [json_name = "customerNum"]; // 使
string telNum = 2 [json_name = "telNum"]; //
}
//
message ArtistBundleBalanceResponse {
int32 remainingVideoCount = 1 [json_name = "remainingVideoCount"]; //
int32 remainingImageCount = 2 [json_name = "remainingImageCount"]; //
int32 remainingDataAnalysisCount = 3 [json_name = "remainingDataAnalysisCount"]; //
}

File diff suppressed because it is too large Load Diff

View File

@ -466,3 +466,72 @@ func (this *UnfinishedInfo) Validate() error {
func (this *SoftDeleteUnfinishedInfoRequest) Validate() error { func (this *SoftDeleteUnfinishedInfoRequest) Validate() error {
return nil return nil
} }
func (this *TaskQueryRequest) Validate() error {
return nil
}
func (this *TaskQueryResponse) Validate() error {
for _, item := range this.Tasks {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("Tasks", err)
}
}
}
return nil
}
func (this *TaskManagementInfo) Validate() error {
return nil
}
func (this *TaskAssignRequest) Validate() error {
return nil
}
func (this *UpdatePendingCountRequest) Validate() error {
return nil
}
func (this *RecentAssignRecordsRequest) Validate() error {
return nil
}
func (this *RecentAssignRecordsResponse) Validate() error {
return nil
}
func (this *EmployeeTaskQueryRequest) Validate() error {
return nil
}
func (this *EmployeeTaskQueryResponse) Validate() error {
for _, item := range this.Records {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("Records", err)
}
}
}
return nil
}
func (this *TaskAssignRecordInfo) Validate() error {
return nil
}
func (this *CompleteTaskManuallyRequest) Validate() error {
return nil
}
func (this *UpdateTaskProgressRequest) Validate() error {
return nil
}
func (this *TaskAssignRecordsQueryRequest) Validate() error {
return nil
}
func (this *TaskAssignRecordsQueryResponse) Validate() error {
for _, item := range this.Records {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("Records", err)
}
}
}
return nil
}
func (this *ArtistBundleBalanceRequest) Validate() error {
return nil
}
func (this *ArtistBundleBalanceResponse) Validate() error {
return nil
}

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go-triple. DO NOT EDIT. // Code generated by protoc-gen-go-triple. DO NOT EDIT.
// versions: // versions:
// - protoc-gen-go-triple v1.0.8 // - protoc-gen-go-triple v1.0.8
// - protoc v4.24.0--rc1 // - protoc v3.21.1
// source: pb/bundle.proto // source: pb/bundle.proto
package bundle package bundle
@ -83,6 +83,16 @@ type BundleClient interface {
// 查出没处理的数据 // 查出没处理的数据
ListUnfinishedInfos(ctx context.Context, in *AutoCreateUserAndOrderRequest, opts ...grpc_go.CallOption) (*UnfinishedInfos, common.ErrorWithAttachment) ListUnfinishedInfos(ctx context.Context, in *AutoCreateUserAndOrderRequest, opts ...grpc_go.CallOption) (*UnfinishedInfos, common.ErrorWithAttachment)
SoftDeleteUnfinishedInfo(ctx context.Context, in *SoftDeleteUnfinishedInfoRequest, opts ...grpc_go.CallOption) (*CommonResponse, common.ErrorWithAttachment) SoftDeleteUnfinishedInfo(ctx context.Context, in *SoftDeleteUnfinishedInfoRequest, opts ...grpc_go.CallOption) (*CommonResponse, common.ErrorWithAttachment)
// 任务台
GetPendingTaskList(ctx context.Context, in *TaskQueryRequest, opts ...grpc_go.CallOption) (*TaskQueryResponse, common.ErrorWithAttachment)
AssignTask(ctx context.Context, in *TaskAssignRequest, opts ...grpc_go.CallOption) (*CommonResponse, common.ErrorWithAttachment)
UpdatePendingCount(ctx context.Context, in *UpdatePendingCountRequest, opts ...grpc_go.CallOption) (*CommonResponse, common.ErrorWithAttachment)
GetRecentAssignRecords(ctx context.Context, in *RecentAssignRecordsRequest, opts ...grpc_go.CallOption) (*RecentAssignRecordsResponse, common.ErrorWithAttachment)
GetEmployeeAssignedTasks(ctx context.Context, in *EmployeeTaskQueryRequest, opts ...grpc_go.CallOption) (*EmployeeTaskQueryResponse, common.ErrorWithAttachment)
CompleteTaskManually(ctx context.Context, in *CompleteTaskManuallyRequest, opts ...grpc_go.CallOption) (*CommonResponse, common.ErrorWithAttachment)
UpdateTaskProgress(ctx context.Context, in *UpdateTaskProgressRequest, opts ...grpc_go.CallOption) (*CommonResponse, common.ErrorWithAttachment)
GetTaskAssignRecordsList(ctx context.Context, in *TaskAssignRecordsQueryRequest, opts ...grpc_go.CallOption) (*TaskAssignRecordsQueryResponse, common.ErrorWithAttachment)
GetArtistBundleBalance(ctx context.Context, in *ArtistBundleBalanceRequest, opts ...grpc_go.CallOption) (*ArtistBundleBalanceResponse, common.ErrorWithAttachment)
} }
type bundleClient struct { type bundleClient struct {
@ -139,6 +149,15 @@ type BundleClientImpl struct {
UpdateReconciliationStatusBySerialNumber func(ctx context.Context, in *UpdateStatusAndPayTimeBySerialNumber) (*CommonResponse, error) UpdateReconciliationStatusBySerialNumber func(ctx context.Context, in *UpdateStatusAndPayTimeBySerialNumber) (*CommonResponse, error)
ListUnfinishedInfos func(ctx context.Context, in *AutoCreateUserAndOrderRequest) (*UnfinishedInfos, error) ListUnfinishedInfos func(ctx context.Context, in *AutoCreateUserAndOrderRequest) (*UnfinishedInfos, error)
SoftDeleteUnfinishedInfo func(ctx context.Context, in *SoftDeleteUnfinishedInfoRequest) (*CommonResponse, error) SoftDeleteUnfinishedInfo func(ctx context.Context, in *SoftDeleteUnfinishedInfoRequest) (*CommonResponse, error)
GetPendingTaskList func(ctx context.Context, in *TaskQueryRequest) (*TaskQueryResponse, error)
AssignTask func(ctx context.Context, in *TaskAssignRequest) (*CommonResponse, error)
UpdatePendingCount func(ctx context.Context, in *UpdatePendingCountRequest) (*CommonResponse, error)
GetRecentAssignRecords func(ctx context.Context, in *RecentAssignRecordsRequest) (*RecentAssignRecordsResponse, error)
GetEmployeeAssignedTasks func(ctx context.Context, in *EmployeeTaskQueryRequest) (*EmployeeTaskQueryResponse, error)
CompleteTaskManually func(ctx context.Context, in *CompleteTaskManuallyRequest) (*CommonResponse, error)
UpdateTaskProgress func(ctx context.Context, in *UpdateTaskProgressRequest) (*CommonResponse, error)
GetTaskAssignRecordsList func(ctx context.Context, in *TaskAssignRecordsQueryRequest) (*TaskAssignRecordsQueryResponse, error)
GetArtistBundleBalance func(ctx context.Context, in *ArtistBundleBalanceRequest) (*ArtistBundleBalanceResponse, error)
} }
func (c *BundleClientImpl) GetDubboStub(cc *triple.TripleConn) BundleClient { func (c *BundleClientImpl) GetDubboStub(cc *triple.TripleConn) BundleClient {
@ -447,6 +466,60 @@ func (c *bundleClient) SoftDeleteUnfinishedInfo(ctx context.Context, in *SoftDel
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/SoftDeleteUnfinishedInfo", in, out) return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/SoftDeleteUnfinishedInfo", in, out)
} }
func (c *bundleClient) GetPendingTaskList(ctx context.Context, in *TaskQueryRequest, opts ...grpc_go.CallOption) (*TaskQueryResponse, common.ErrorWithAttachment) {
out := new(TaskQueryResponse)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/GetPendingTaskList", in, out)
}
func (c *bundleClient) AssignTask(ctx context.Context, in *TaskAssignRequest, opts ...grpc_go.CallOption) (*CommonResponse, common.ErrorWithAttachment) {
out := new(CommonResponse)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/AssignTask", in, out)
}
func (c *bundleClient) UpdatePendingCount(ctx context.Context, in *UpdatePendingCountRequest, opts ...grpc_go.CallOption) (*CommonResponse, common.ErrorWithAttachment) {
out := new(CommonResponse)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/UpdatePendingCount", in, out)
}
func (c *bundleClient) GetRecentAssignRecords(ctx context.Context, in *RecentAssignRecordsRequest, opts ...grpc_go.CallOption) (*RecentAssignRecordsResponse, common.ErrorWithAttachment) {
out := new(RecentAssignRecordsResponse)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/GetRecentAssignRecords", in, out)
}
func (c *bundleClient) GetEmployeeAssignedTasks(ctx context.Context, in *EmployeeTaskQueryRequest, opts ...grpc_go.CallOption) (*EmployeeTaskQueryResponse, common.ErrorWithAttachment) {
out := new(EmployeeTaskQueryResponse)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/GetEmployeeAssignedTasks", in, out)
}
func (c *bundleClient) CompleteTaskManually(ctx context.Context, in *CompleteTaskManuallyRequest, opts ...grpc_go.CallOption) (*CommonResponse, common.ErrorWithAttachment) {
out := new(CommonResponse)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/CompleteTaskManually", in, out)
}
func (c *bundleClient) UpdateTaskProgress(ctx context.Context, in *UpdateTaskProgressRequest, opts ...grpc_go.CallOption) (*CommonResponse, common.ErrorWithAttachment) {
out := new(CommonResponse)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/UpdateTaskProgress", in, out)
}
func (c *bundleClient) GetTaskAssignRecordsList(ctx context.Context, in *TaskAssignRecordsQueryRequest, opts ...grpc_go.CallOption) (*TaskAssignRecordsQueryResponse, common.ErrorWithAttachment) {
out := new(TaskAssignRecordsQueryResponse)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/GetTaskAssignRecordsList", in, out)
}
func (c *bundleClient) GetArtistBundleBalance(ctx context.Context, in *ArtistBundleBalanceRequest, opts ...grpc_go.CallOption) (*ArtistBundleBalanceResponse, common.ErrorWithAttachment) {
out := new(ArtistBundleBalanceResponse)
interfaceKey := ctx.Value(constant.InterfaceKey).(string)
return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/GetArtistBundleBalance", in, out)
}
// BundleServer is the server API for Bundle service. // BundleServer is the server API for Bundle service.
// All implementations must embed UnimplementedBundleServer // All implementations must embed UnimplementedBundleServer
// for forward compatibility // for forward compatibility
@ -506,6 +579,16 @@ type BundleServer interface {
// 查出没处理的数据 // 查出没处理的数据
ListUnfinishedInfos(context.Context, *AutoCreateUserAndOrderRequest) (*UnfinishedInfos, error) ListUnfinishedInfos(context.Context, *AutoCreateUserAndOrderRequest) (*UnfinishedInfos, error)
SoftDeleteUnfinishedInfo(context.Context, *SoftDeleteUnfinishedInfoRequest) (*CommonResponse, error) SoftDeleteUnfinishedInfo(context.Context, *SoftDeleteUnfinishedInfoRequest) (*CommonResponse, error)
// 任务台
GetPendingTaskList(context.Context, *TaskQueryRequest) (*TaskQueryResponse, error)
AssignTask(context.Context, *TaskAssignRequest) (*CommonResponse, error)
UpdatePendingCount(context.Context, *UpdatePendingCountRequest) (*CommonResponse, error)
GetRecentAssignRecords(context.Context, *RecentAssignRecordsRequest) (*RecentAssignRecordsResponse, error)
GetEmployeeAssignedTasks(context.Context, *EmployeeTaskQueryRequest) (*EmployeeTaskQueryResponse, error)
CompleteTaskManually(context.Context, *CompleteTaskManuallyRequest) (*CommonResponse, error)
UpdateTaskProgress(context.Context, *UpdateTaskProgressRequest) (*CommonResponse, error)
GetTaskAssignRecordsList(context.Context, *TaskAssignRecordsQueryRequest) (*TaskAssignRecordsQueryResponse, error)
GetArtistBundleBalance(context.Context, *ArtistBundleBalanceRequest) (*ArtistBundleBalanceResponse, error)
mustEmbedUnimplementedBundleServer() mustEmbedUnimplementedBundleServer()
} }
@ -661,6 +744,33 @@ func (UnimplementedBundleServer) ListUnfinishedInfos(context.Context, *AutoCreat
func (UnimplementedBundleServer) SoftDeleteUnfinishedInfo(context.Context, *SoftDeleteUnfinishedInfoRequest) (*CommonResponse, error) { func (UnimplementedBundleServer) SoftDeleteUnfinishedInfo(context.Context, *SoftDeleteUnfinishedInfoRequest) (*CommonResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method SoftDeleteUnfinishedInfo not implemented") return nil, status.Errorf(codes.Unimplemented, "method SoftDeleteUnfinishedInfo not implemented")
} }
func (UnimplementedBundleServer) GetPendingTaskList(context.Context, *TaskQueryRequest) (*TaskQueryResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetPendingTaskList not implemented")
}
func (UnimplementedBundleServer) AssignTask(context.Context, *TaskAssignRequest) (*CommonResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method AssignTask not implemented")
}
func (UnimplementedBundleServer) UpdatePendingCount(context.Context, *UpdatePendingCountRequest) (*CommonResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method UpdatePendingCount not implemented")
}
func (UnimplementedBundleServer) GetRecentAssignRecords(context.Context, *RecentAssignRecordsRequest) (*RecentAssignRecordsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetRecentAssignRecords not implemented")
}
func (UnimplementedBundleServer) GetEmployeeAssignedTasks(context.Context, *EmployeeTaskQueryRequest) (*EmployeeTaskQueryResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetEmployeeAssignedTasks not implemented")
}
func (UnimplementedBundleServer) CompleteTaskManually(context.Context, *CompleteTaskManuallyRequest) (*CommonResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CompleteTaskManually not implemented")
}
func (UnimplementedBundleServer) UpdateTaskProgress(context.Context, *UpdateTaskProgressRequest) (*CommonResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method UpdateTaskProgress not implemented")
}
func (UnimplementedBundleServer) GetTaskAssignRecordsList(context.Context, *TaskAssignRecordsQueryRequest) (*TaskAssignRecordsQueryResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetTaskAssignRecordsList not implemented")
}
func (UnimplementedBundleServer) GetArtistBundleBalance(context.Context, *ArtistBundleBalanceRequest) (*ArtistBundleBalanceResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetArtistBundleBalance not implemented")
}
func (s *UnimplementedBundleServer) XXX_SetProxyImpl(impl protocol.Invoker) { func (s *UnimplementedBundleServer) XXX_SetProxyImpl(impl protocol.Invoker) {
s.proxyImpl = impl s.proxyImpl = impl
} }
@ -2110,6 +2220,267 @@ func _Bundle_SoftDeleteUnfinishedInfo_Handler(srv interface{}, ctx context.Conte
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
func _Bundle_GetPendingTaskList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(TaskQueryRequest)
if err := dec(in); err != nil {
return nil, err
}
base := srv.(dubbo3.Dubbo3GrpcService)
args := []interface{}{}
args = append(args, in)
md, _ := metadata.FromIncomingContext(ctx)
invAttachment := make(map[string]interface{}, len(md))
for k, v := range md {
invAttachment[k] = v
}
invo := invocation.NewRPCInvocation("GetPendingTaskList", args, invAttachment)
if interceptor == nil {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
info := &grpc_go.UnaryServerInfo{
Server: srv,
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
return interceptor(ctx, in, info, handler)
}
func _Bundle_AssignTask_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(TaskAssignRequest)
if err := dec(in); err != nil {
return nil, err
}
base := srv.(dubbo3.Dubbo3GrpcService)
args := []interface{}{}
args = append(args, in)
md, _ := metadata.FromIncomingContext(ctx)
invAttachment := make(map[string]interface{}, len(md))
for k, v := range md {
invAttachment[k] = v
}
invo := invocation.NewRPCInvocation("AssignTask", args, invAttachment)
if interceptor == nil {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
info := &grpc_go.UnaryServerInfo{
Server: srv,
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
return interceptor(ctx, in, info, handler)
}
func _Bundle_UpdatePendingCount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(UpdatePendingCountRequest)
if err := dec(in); err != nil {
return nil, err
}
base := srv.(dubbo3.Dubbo3GrpcService)
args := []interface{}{}
args = append(args, in)
md, _ := metadata.FromIncomingContext(ctx)
invAttachment := make(map[string]interface{}, len(md))
for k, v := range md {
invAttachment[k] = v
}
invo := invocation.NewRPCInvocation("UpdatePendingCount", args, invAttachment)
if interceptor == nil {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
info := &grpc_go.UnaryServerInfo{
Server: srv,
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
return interceptor(ctx, in, info, handler)
}
func _Bundle_GetRecentAssignRecords_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(RecentAssignRecordsRequest)
if err := dec(in); err != nil {
return nil, err
}
base := srv.(dubbo3.Dubbo3GrpcService)
args := []interface{}{}
args = append(args, in)
md, _ := metadata.FromIncomingContext(ctx)
invAttachment := make(map[string]interface{}, len(md))
for k, v := range md {
invAttachment[k] = v
}
invo := invocation.NewRPCInvocation("GetRecentAssignRecords", args, invAttachment)
if interceptor == nil {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
info := &grpc_go.UnaryServerInfo{
Server: srv,
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
return interceptor(ctx, in, info, handler)
}
func _Bundle_GetEmployeeAssignedTasks_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(EmployeeTaskQueryRequest)
if err := dec(in); err != nil {
return nil, err
}
base := srv.(dubbo3.Dubbo3GrpcService)
args := []interface{}{}
args = append(args, in)
md, _ := metadata.FromIncomingContext(ctx)
invAttachment := make(map[string]interface{}, len(md))
for k, v := range md {
invAttachment[k] = v
}
invo := invocation.NewRPCInvocation("GetEmployeeAssignedTasks", args, invAttachment)
if interceptor == nil {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
info := &grpc_go.UnaryServerInfo{
Server: srv,
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
return interceptor(ctx, in, info, handler)
}
func _Bundle_CompleteTaskManually_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(CompleteTaskManuallyRequest)
if err := dec(in); err != nil {
return nil, err
}
base := srv.(dubbo3.Dubbo3GrpcService)
args := []interface{}{}
args = append(args, in)
md, _ := metadata.FromIncomingContext(ctx)
invAttachment := make(map[string]interface{}, len(md))
for k, v := range md {
invAttachment[k] = v
}
invo := invocation.NewRPCInvocation("CompleteTaskManually", args, invAttachment)
if interceptor == nil {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
info := &grpc_go.UnaryServerInfo{
Server: srv,
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
return interceptor(ctx, in, info, handler)
}
func _Bundle_UpdateTaskProgress_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(UpdateTaskProgressRequest)
if err := dec(in); err != nil {
return nil, err
}
base := srv.(dubbo3.Dubbo3GrpcService)
args := []interface{}{}
args = append(args, in)
md, _ := metadata.FromIncomingContext(ctx)
invAttachment := make(map[string]interface{}, len(md))
for k, v := range md {
invAttachment[k] = v
}
invo := invocation.NewRPCInvocation("UpdateTaskProgress", args, invAttachment)
if interceptor == nil {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
info := &grpc_go.UnaryServerInfo{
Server: srv,
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
return interceptor(ctx, in, info, handler)
}
func _Bundle_GetTaskAssignRecordsList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(TaskAssignRecordsQueryRequest)
if err := dec(in); err != nil {
return nil, err
}
base := srv.(dubbo3.Dubbo3GrpcService)
args := []interface{}{}
args = append(args, in)
md, _ := metadata.FromIncomingContext(ctx)
invAttachment := make(map[string]interface{}, len(md))
for k, v := range md {
invAttachment[k] = v
}
invo := invocation.NewRPCInvocation("GetTaskAssignRecordsList", args, invAttachment)
if interceptor == nil {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
info := &grpc_go.UnaryServerInfo{
Server: srv,
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
return interceptor(ctx, in, info, handler)
}
func _Bundle_GetArtistBundleBalance_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) {
in := new(ArtistBundleBalanceRequest)
if err := dec(in); err != nil {
return nil, err
}
base := srv.(dubbo3.Dubbo3GrpcService)
args := []interface{}{}
args = append(args, in)
md, _ := metadata.FromIncomingContext(ctx)
invAttachment := make(map[string]interface{}, len(md))
for k, v := range md {
invAttachment[k] = v
}
invo := invocation.NewRPCInvocation("GetArtistBundleBalance", args, invAttachment)
if interceptor == nil {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
info := &grpc_go.UnaryServerInfo{
Server: srv,
FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string),
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
result := base.XXX_GetProxyImpl().Invoke(ctx, invo)
return result, result.Error()
}
return interceptor(ctx, in, info, handler)
}
// Bundle_ServiceDesc is the grpc_go.ServiceDesc for Bundle service. // Bundle_ServiceDesc is the grpc_go.ServiceDesc for Bundle service.
// It's only intended for direct use with grpc_go.RegisterService, // It's only intended for direct use with grpc_go.RegisterService,
// and not to be introspected or modified (even as a copy) // and not to be introspected or modified (even as a copy)
@ -2313,6 +2684,42 @@ var Bundle_ServiceDesc = grpc_go.ServiceDesc{
MethodName: "SoftDeleteUnfinishedInfo", MethodName: "SoftDeleteUnfinishedInfo",
Handler: _Bundle_SoftDeleteUnfinishedInfo_Handler, Handler: _Bundle_SoftDeleteUnfinishedInfo_Handler,
}, },
{
MethodName: "GetPendingTaskList",
Handler: _Bundle_GetPendingTaskList_Handler,
},
{
MethodName: "AssignTask",
Handler: _Bundle_AssignTask_Handler,
},
{
MethodName: "UpdatePendingCount",
Handler: _Bundle_UpdatePendingCount_Handler,
},
{
MethodName: "GetRecentAssignRecords",
Handler: _Bundle_GetRecentAssignRecords_Handler,
},
{
MethodName: "GetEmployeeAssignedTasks",
Handler: _Bundle_GetEmployeeAssignedTasks_Handler,
},
{
MethodName: "CompleteTaskManually",
Handler: _Bundle_CompleteTaskManually_Handler,
},
{
MethodName: "UpdateTaskProgress",
Handler: _Bundle_UpdateTaskProgress_Handler,
},
{
MethodName: "GetTaskAssignRecordsList",
Handler: _Bundle_GetTaskAssignRecordsList_Handler,
},
{
MethodName: "GetArtistBundleBalance",
Handler: _Bundle_GetArtistBundleBalance_Handler,
},
}, },
Streams: []grpc_go.StreamDesc{}, Streams: []grpc_go.StreamDesc{},
Metadata: "pb/bundle.proto", Metadata: "pb/bundle.proto",

View File

@ -3,7 +3,7 @@ package app
import ( import (
"github.com/bwmarrin/snowflake" "github.com/bwmarrin/snowflake"
"go.uber.org/zap" "go.uber.org/zap"
"gorm.io/gorm" "micro-bundle/pkg/db"
"micro-bundle/pkg/tracing" "micro-bundle/pkg/tracing"
) )
@ -13,6 +13,7 @@ type App struct {
Lg *zap.Logger Lg *zap.Logger
//RedisClient *redis.Client //RedisClient *redis.Client
JaegerTracer *tracing.JaegerProvider JaegerTracer *tracing.JaegerProvider
BundleDB *gorm.DB
SfNode *snowflake.Node SfNode *snowflake.Node
BundleDB *db.BundleDB
TaskBenchDB *db.TaskBenchDB
} }

View File

@ -8,12 +8,17 @@ import (
"gorm.io/gorm" "gorm.io/gorm"
) )
// 定义一个新的类型来区分BundleDB
type BundleDB struct {
*gorm.DB
}
var Provider = wire.NewSet(NewBundleDB) var Provider = wire.NewSet(NewBundleDB)
func NewBundleDB() *gorm.DB { func NewBundleDB() *BundleDB {
connBundleDB := strings.Join([]string{bundleConfig.Data.BundleDB.User, ":", bundleConfig.Data.BundleDB.Password, connBundleDB := strings.Join([]string{bundleConfig.Data.BundleDB.User, ":", bundleConfig.Data.BundleDB.Password,
"@tcp(", bundleConfig.Data.BundleDB.Host, ":", bundleConfig.Data.BundleDB.Port, ")/", "@tcp(", bundleConfig.Data.BundleDB.Host, ":", bundleConfig.Data.BundleDB.Port, ")/",
bundleConfig.Data.BundleDB.DbName, "?charset=utf8mb4&parseTime=true&loc=Local"}, "") bundleConfig.Data.BundleDB.DbName, "?charset=utf8mb4&parseTime=true&loc=Local"}, "")
DciDB := loadMysqlConn(connBundleDB) db := loadMysqlConn(connBundleDB)
return DciDB return &BundleDB{DB: db}
} }

View File

@ -1,6 +1,8 @@
package db package db
import ( import (
"fmt"
"log"
"time" "time"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -36,10 +38,13 @@ func loadMysqlConn(conn string) *gorm.DB {
if err != nil { if err != nil {
panic(err) panic(err)
} }
fmt.Println("[BundleDB] 数据库连接成功, 连接字符串: %s", conn)
sqlDB, _ := db.DB() sqlDB, _ := db.DB()
sqlDB.SetMaxIdleConns(20) //设置连接池,空闲 sqlDB.SetMaxIdleConns(20) //设置连接池,空闲
sqlDB.SetMaxOpenConns(100) //打开 sqlDB.SetMaxOpenConns(100) //打开
sqlDB.SetConnMaxLifetime(time.Second * 30) sqlDB.SetConnMaxLifetime(time.Second * 30)
// Bundle数据库的自动迁移
err = db.AutoMigrate( err = db.AutoMigrate(
&model.BundleProfile{}, &model.BundleProfile{},
&model.BundleOrderRecords{}, &model.BundleOrderRecords{},
@ -58,15 +63,60 @@ func loadMysqlConn(conn string) *gorm.DB {
) )
if err != nil { if err != nil {
return nil // return nil
panic(err)
} }
return db return db
} }
// TaskBench数据库的自动迁移函数
func loadTaskBenchMysqlConn(conn string) *gorm.DB {
var ormLogger logger.Interface
if gin.Mode() == "debug" {
ormLogger = logger.Default.LogMode(logger.Info)
} else {
ormLogger = logger.Default
}
db, err := gorm.Open(mysql.New(mysql.Config{
DSN: conn,
DefaultStringSize: 256,
DisableDatetimePrecision: true,
DontSupportRenameIndex: true,
DontSupportRenameColumn: true,
SkipInitializeWithVersion: false,
}), &gorm.Config{
Logger: ormLogger,
NamingStrategy: schema.NamingStrategy{
SingularTable: true,
},
DisableForeignKeyConstraintWhenMigrating: true,
})
if err != nil {
panic(err)
}
sqlDB, _ := db.DB()
sqlDB.SetMaxIdleConns(20)
sqlDB.SetMaxOpenConns(100)
sqlDB.SetConnMaxLifetime(time.Second * 30)
// 自动迁移任务管理台相关数据库表
err = db.AutoMigrate(
&model.TaskManagement{},
&model.TaskAssignRecords{},
)
if err != nil {
log.Printf("[TaskBenchDB] 数据库迁移失败: %v", err)
panic(err)
}
log.Printf("[TaskBenchDB] 数据库迁移成功,已创建表: task_management, task_assign_records")
return db
}
func DBMigration() { func DBMigration() {
} }
func addColumn(dst interface{}, column string) { func addColumn(dst interface{}, column string) {
return return
} }

24
pkg/db/taskBenchDB.go Normal file
View File

@ -0,0 +1,24 @@
package db
import (
bundleConfig "micro-bundle/config"
"strings"
"github.com/google/wire"
"gorm.io/gorm"
)
// 定义一个新的类型来区分TaskBenchDB
type TaskBenchDB struct {
*gorm.DB
}
var TaskBenchProvider = wire.NewSet(NewTaskBenchDB)
func NewTaskBenchDB() *TaskBenchDB {
connTaskBenchDB := strings.Join([]string{bundleConfig.Data.TaskBenchDB.User, ":", bundleConfig.Data.TaskBenchDB.Password,
"@tcp(", bundleConfig.Data.TaskBenchDB.Host, ":", bundleConfig.Data.TaskBenchDB.Port, ")/",
bundleConfig.Data.TaskBenchDB.DbName, "?charset=utf8mb4&parseTime=true&loc=Local"}, "")
db := loadTaskBenchMysqlConn(connTaskBenchDB)
return &TaskBenchDB{DB: db}
}