Prechádzať zdrojové kódy

feat(task): 任务打回/重新提交功能

1. 新增任务状态: 3=已拒绝, 5=已打回(可重新提交)
2. 新增 reject_reason 字段记录打回/拒绝原因
3. 新增补充截图接口 POST /task/supplement
4. 支持已拒绝(-1/3)和已打回(5)的任务重新提交
5. 修复任务限制: dailyLimit/totalLimit 为0时表示不限制
urbanu 1 mesiac pred
rodič
commit
76cbdfecb3

+ 6 - 5
apis/daytask/routers.go

@@ -84,11 +84,12 @@ func (h UserRouter) Register(group *gin.RouterGroup) {
 	group.POST("social/bind", server().SocialBind)  // 绑定社交账号
 
 	// 任务操作
-	group.POST("task/apply", server().TaskApply)       // 领取任务
-	group.POST("task/submit", server().TaskSubmit)     // 提交任务
-	group.POST("task/abandon", server().TaskAbandon)   // 放弃任务
-	group.GET("task/my", server().TaskMy)              // 我的任务列表
-	group.GET("task/my/detail", server().TaskMyDetail) // 我的任务详情
+	group.POST("task/apply", server().TaskApply)                      // 领取任务
+	group.POST("task/submit", server().TaskSubmit)                    // 提交任务(支持首次提交和打回后重新提交)
+	group.POST("task/supplement", server().TaskSupplementScreenshots) // 补充截图(待审核状态可补充)
+	group.POST("task/abandon", server().TaskAbandon)                  // 放弃任务
+	group.GET("task/my", server().TaskMy)                             // 我的任务列表
+	group.GET("task/my/detail", server().TaskMyDetail)                // 我的任务详情
 
 	// 财务相关
 	group.GET("wallet/info", server().WalletInfo)              // 钱包信息

+ 81 - 23
apis/daytask/task.go

@@ -55,25 +55,29 @@ func (s *Server) TaskApply(c *gin.Context) {
 		}
 	}
 
-	// 检查用户今日领取数量
-	today := time.Now().Format("2006-01-02")
-	var todayCount int64
-	db.Model(&entity.DtUserTask{}).
-		Where("user_id = ? AND task_id = ? AND DATE(FROM_UNIXTIME(created_at)) = ?", userId, req.TaskId, today).
-		Count(&todayCount)
-	if int(todayCount) >= task.DailyLimit {
-		ctx.Fail("daily_limit_reached")
-		return
+	// 检查用户今日领取数量(0表示不限制)
+	if task.DailyLimit > 0 {
+		today := time.Now().Format("2006-01-02")
+		var todayCount int64
+		db.Model(&entity.DtUserTask{}).
+			Where("user_id = ? AND task_id = ? AND DATE(FROM_UNIXTIME(created_at)) = ?", userId, req.TaskId, today).
+			Count(&todayCount)
+		if int(todayCount) >= task.DailyLimit {
+			ctx.Fail("daily_limit_reached")
+			return
+		}
 	}
 
-	// 检查用户总领取数量
-	var totalCount int64
-	db.Model(&entity.DtUserTask{}).
-		Where("user_id = ? AND task_id = ? AND status != ?", userId, req.TaskId, entity.UserTaskStatusAbandoned).
-		Count(&totalCount)
-	if int(totalCount) >= task.TotalLimit {
-		ctx.Fail("total_limit_reached")
-		return
+	// 检查用户总领取数量(0表示不限制)
+	if task.TotalLimit > 0 {
+		var totalCount int64
+		db.Model(&entity.DtUserTask{}).
+			Where("user_id = ? AND task_id = ? AND status != ?", userId, req.TaskId, entity.UserTaskStatusAbandoned).
+			Count(&totalCount)
+		if int(totalCount) >= task.TotalLimit {
+			ctx.Fail("total_limit_reached")
+			return
+		}
 	}
 
 	// 检查是否有进行中或待审核的任务
@@ -144,8 +148,11 @@ func (s *Server) TaskSubmit(c *gin.Context) {
 		return
 	}
 
-	// 检查状态
-	if userTask.Status != entity.UserTaskStatusPending {
+	// 检查状态:进行中(0)、审核失败(-1)、已拒绝(3)或已打回(5)的任务可以提交
+	if userTask.Status != entity.UserTaskStatusPending &&
+		userTask.Status != entity.UserTaskStatusFailed &&
+		userTask.Status != entity.UserTaskStatusRejected &&
+		userTask.Status != entity.UserTaskStatusReturnBack {
 		ctx.Fail("task_cannot_submit")
 		return
 	}
@@ -164,15 +171,66 @@ func (s *Server) TaskSubmit(c *gin.Context) {
 	db.Model(&entity.DtUserTask{}).
 		Where("id = ?", req.UserTaskId).
 		Updates(map[string]interface{}{
-			"screenshots": string(screenshotsJson),
-			"remark":      req.Remark,
-			"submit_time": time.Now().Unix(),
-			"status":      entity.UserTaskStatusSubmitted,
+			"screenshots":   string(screenshotsJson),
+			"remark":        req.Remark,
+			"submit_time":   time.Now().Unix(),
+			"status":        entity.UserTaskStatusSubmitted,
+			"reject_reason": "", // 重新提交时清空打回原因
 		})
 
 	ctx.OK(nil)
 }
 
+// TaskSupplementScreenshots 补充截图(待审核状态可以补充)
+func (s *Server) TaskSupplementScreenshots(c *gin.Context) {
+	ctx := s.FromContext(c)
+	db := s.DB()
+	userId := ctx.UserId()
+
+	type SupplementRequest struct {
+		UserTaskId  int64    `json:"userTaskId" binding:"required"`
+		Screenshots []string `json:"screenshots" binding:"required"` // 新增的截图
+	}
+
+	var req SupplementRequest
+	if err := c.ShouldBindJSON(&req); err != nil {
+		ctx.Fail("invalid_params")
+		return
+	}
+
+	// 获取用户任务
+	userTask := &entity.DtUserTask{}
+	if err := db.Where("id = ? AND user_id = ?", req.UserTaskId, userId).First(userTask).Error; err != nil {
+		ctx.Fail("user_task_not_found")
+		return
+	}
+
+	// 检查状态:只有待审核(1)的任务可以补充截图
+	if userTask.Status != entity.UserTaskStatusSubmitted {
+		ctx.Fail("task_cannot_supplement")
+		return
+	}
+
+	// 解析现有截图
+	existingScreenshots := make([]string, 0)
+	if userTask.Screenshots != "" {
+		json.Unmarshal([]byte(userTask.Screenshots), &existingScreenshots)
+	}
+
+	// 合并截图
+	allScreenshots := append(existingScreenshots, req.Screenshots...)
+	screenshotsJson, _ := json.Marshal(allScreenshots)
+
+	// 更新任务
+	db.Model(&entity.DtUserTask{}).
+		Where("id = ?", req.UserTaskId).
+		Update("screenshots", string(screenshotsJson))
+
+	ctx.OK(gin.H{
+		"screenshots": allScreenshots,
+	})
+}
+
 // TaskAbandon 放弃任务
 func (s *Server) TaskAbandon(c *gin.Context) {
 	ctx := s.FromContext(c)

+ 9 - 6
commons/model/entity/dt_user_task.go

@@ -14,7 +14,8 @@ type DtUserTask struct {
 	AuditTime    int64   `json:"auditTime" gorm:"comment:审核时间"`
 	AuditAdminId int64   `json:"auditAdminId" gorm:"comment:审核管理员ID"`
 	AuditRemark  string  `json:"auditRemark" gorm:"type:varchar(512);comment:审核备注"`
-	Status       int8    `json:"status" gorm:"default:0;index:idx_status;comment:状态: -2=已放弃 -1=审核失败 0=进行中 1=待审核 2=已完成"`
+	RejectReason string  `json:"rejectReason" gorm:"type:varchar(255);comment:拒绝/打回原因"`
+	Status       int8    `json:"status" gorm:"default:0;index:idx_status;comment:状态: -2=已放弃 -1=审核失败 0=进行中 1=待审核 2=已完成 5=已打回"`
 }
 
 func (*DtUserTask) TableName() string {
@@ -31,9 +32,11 @@ func NewDtUserTask() *DtUserTask {
 
 // 任务状态常量
 const (
-	UserTaskStatusAbandoned = -2 // 已放弃
-	UserTaskStatusFailed    = -1 // 审核失败
-	UserTaskStatusPending   = 0  // 进行中
-	UserTaskStatusSubmitted = 1  // 待审核
-	UserTaskStatusCompleted = 2  // 已完成
+	UserTaskStatusAbandoned  = -2 // 已放弃
+	UserTaskStatusFailed     = -1 // 审核失败
+	UserTaskStatusPending    = 0  // 进行中
+	UserTaskStatusSubmitted  = 1  // 待审核
+	UserTaskStatusCompleted  = 2  // 已完成
+	UserTaskStatusRejected   = 3  // 已拒绝
+	UserTaskStatusReturnBack = 5  // 已打回(可重新提交)
 )