| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295 |
- package daytask
- import (
- "app/commons/model/entity"
- "app/commons/services"
- "encoding/json"
- "time"
- "github.com/gin-gonic/gin"
- )
- // TaskApply 领取任务
- func (s *Server) TaskApply(c *gin.Context) {
- ctx := s.FromContext(c)
- db := s.DB()
- userId := ctx.UserId()
- type ApplyRequest struct {
- TaskId int64 `json:"taskId" binding:"required"`
- }
- var req ApplyRequest
- if err := c.ShouldBindJSON(&req); err != nil {
- ctx.Fail("invalid_params")
- return
- }
- // 获取任务
- task := &entity.DtTask{}
- if err := db.Where("id = ? AND status = ?", req.TaskId, 1).First(task).Error; err != nil {
- ctx.Fail("task_not_found")
- return
- }
- // 检查任务剩余数量
- if task.RemainCount <= 0 {
- ctx.Fail("task_sold_out")
- return
- }
- // 获取用户
- user := &entity.DtUser{}
- if err := db.Where("id = ?", userId).First(user).Error; err != nil {
- ctx.Fail("user_not_found")
- return
- }
- // 检查用户等级
- if task.MinLevel > 0 {
- level := &entity.DtUserLevel{}
- db.Where("id = ?", user.LevelId).First(level)
- if level.Level < task.MinLevel {
- ctx.Fail("level_not_enough")
- return
- }
- }
- // 检查用户今日领取数量
- 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
- }
- // 检查是否有进行中或待审核的任务
- var pendingCount int64
- db.Model(&entity.DtUserTask{}).
- Where("user_id = ? AND task_id = ? AND status IN (?, ?)", userId, req.TaskId, entity.UserTaskStatusPending, entity.UserTaskStatusSubmitted).
- Count(&pendingCount)
- if pendingCount > 0 {
- ctx.Fail("task_in_progress")
- return
- }
- // 创建任务记录
- userTask := &entity.DtUserTask{
- UserId: userId,
- TaskId: req.TaskId,
- TaskNo: task.TaskNo,
- RewardAmount: task.RewardAmount,
- Status: entity.UserTaskStatusPending,
- }
- if err := db.Create(userTask).Error; err != nil {
- ctx.Fail("claim_failed")
- return
- }
- // 更新任务剩余数量(原子操作)
- db.Model(&entity.DtTask{}).
- Where("id = ? AND remain_count > 0", req.TaskId).
- UpdateColumn("remain_count", db.Raw("remain_count - 1"))
- ctx.OK(userTask)
- }
- // TaskSubmit 提交任务
- func (s *Server) TaskSubmit(c *gin.Context) {
- ctx := s.FromContext(c)
- db := s.DB()
- userId := ctx.UserId()
- type SubmitRequest struct {
- UserTaskId int64 `json:"userTaskId" binding:"required"`
- Screenshots []string `json:"screenshots" binding:"required"`
- Remark string `json:"remark"`
- }
- var req SubmitRequest
- 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
- }
- // 检查状态
- if userTask.Status != entity.UserTaskStatusPending {
- ctx.Fail("task_cannot_submit")
- return
- }
- // 获取任务检查是否需要截图
- task := &entity.DtTask{}
- db.Where("id = ?", userTask.TaskId).First(task)
- if task.RequireScreenshot == 1 && len(req.Screenshots) == 0 {
- ctx.Fail("screenshot_required")
- return
- }
- // 更新任务
- screenshotsJson, _ := json.Marshal(req.Screenshots)
- 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,
- })
- ctx.OK(nil)
- }
- // TaskAbandon 放弃任务
- func (s *Server) TaskAbandon(c *gin.Context) {
- ctx := s.FromContext(c)
- db := s.DB()
- userId := ctx.UserId()
- type AbandonRequest struct {
- UserTaskId int64 `json:"userTaskId" binding:"required"`
- }
- var req AbandonRequest
- 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
- }
- // 只有进行中的任务可以放弃
- if userTask.Status != entity.UserTaskStatusPending {
- ctx.Fail("task_cannot_abandon")
- return
- }
- // 更新状态
- db.Model(&entity.DtUserTask{}).
- Where("id = ?", req.UserTaskId).
- Update("status", entity.UserTaskStatusAbandoned)
- // 恢复任务数量
- db.Model(&entity.DtTask{}).
- Where("id = ?", userTask.TaskId).
- Update("remain_count", db.Raw("remain_count + 1"))
- ctx.OK(nil)
- }
- // TaskMy 我的任务列表
- func (s *Server) TaskMy(c *gin.Context) {
- ctx := s.FromContext(c)
- db := s.DB()
- userId := ctx.UserId()
- status := ctx.QueryInt64("status", -99) // -99表示全部
- paging := &services.Pagination{
- Current: ctx.QueryInt64("current", 1),
- Size: ctx.QueryInt64("size", 20),
- }
- query := db.Model(&entity.DtUserTask{}).Where("user_id = ?", userId)
- if status != -99 {
- query = query.Where("status = ?", status)
- }
- query.Count(&paging.Total)
- paging.Computer()
- userTasks := make([]*entity.DtUserTask, 0)
- query.Order("created_at DESC").
- Offset(int(paging.Start)).
- Limit(int(paging.Size)).
- Find(&userTasks)
- // 获取关联的任务信息
- type TaskWithInfo struct {
- *entity.DtUserTask
- Task *entity.DtTask `json:"task"`
- }
- result := make([]*TaskWithInfo, 0)
- for _, ut := range userTasks {
- task := &entity.DtTask{}
- db.Where("id = ?", ut.TaskId).First(task)
- result = append(result, &TaskWithInfo{
- DtUserTask: ut,
- Task: task,
- })
- }
- ctx.OK(gin.H{
- "list": result,
- "paging": paging,
- })
- }
- // TaskMyDetail 我的任务详情
- func (s *Server) TaskMyDetail(c *gin.Context) {
- ctx := s.FromContext(c)
- db := s.DB()
- userId := ctx.UserId()
- userTaskId := ctx.QueryInt64("id", 0)
- if userTaskId == 0 {
- ctx.Fail("id_required")
- return
- }
- // 获取用户任务
- userTask := &entity.DtUserTask{}
- if err := db.Where("id = ? AND user_id = ?", userTaskId, userId).First(userTask).Error; err != nil {
- ctx.Fail("user_task_not_found")
- return
- }
- // 获取任务
- task := &entity.DtTask{}
- db.Where("id = ?", userTask.TaskId).First(task)
- // 获取任务分类
- category := &entity.DtTaskCategory{}
- db.Where("id = ?", task.CategoryId).First(category)
- // 获取任务步骤
- steps := make([]*entity.DtTaskStep, 0)
- db.Model(&entity.DtTaskStep{}).
- Where("task_id = ?", userTask.TaskId).
- Order("step_no ASC").
- Find(&steps)
- ctx.OK(gin.H{
- "userTask": userTask,
- "task": task,
- "category": category,
- "steps": steps,
- })
- }
|