| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427 |
- package daytask
- import (
- "app/commons/model/entity"
- "app/commons/services"
- "fmt"
- "strings"
- "github.com/gin-gonic/gin"
- )
- // TaskWithCategory 带分类信息的任务响应结构
- type TaskWithCategory struct {
- entity.DtTask
- CategoryName string `json:"categoryName"`
- CategoryIcon string `json:"categoryIcon"`
- Platform string `json:"platform"`
- }
- // HomeIndex 首页数据
- func (s *Server) HomeIndex(c *gin.Context) {
- ctx := s.FromContext(c)
- db := s.DB()
- // 获取Banner列表
- banners := make([]*entity.DtBanner, 0)
- db.Model(&entity.DtBanner{}).
- Where("status = ? AND position = ?", 1, "home").
- Order("sort DESC, id DESC").
- Limit(5).
- Find(&banners)
- // 获取任务分类
- categories := make([]*entity.DtTaskCategory, 0)
- db.Model(&entity.DtTaskCategory{}).
- Where("status = ?", 1).
- Order("sort ASC").
- Find(&categories)
- // 获取推荐任务
- recommendTasks := make([]*entity.DtTask, 0)
- // 尝试使用 is_recommend 字段,如果字段不存在则降级处理
- if err := db.Model(&entity.DtTask{}).Where("status = ? AND is_recommend = ?", 1, 1).
- Order("sort DESC, id DESC").Limit(10).Find(&recommendTasks).Error; err != nil {
- if isColumnNotExistError(err) {
- // 字段不存在,使用降级查询(不筛选推荐)
- db.Model(&entity.DtTask{}).Where("status = ?", 1).
- Order("sort DESC, id DESC").Limit(10).Find(&recommendTasks)
- }
- }
- // 获取普通任务
- normalTasks := make([]*entity.DtTask, 0)
- // 尝试使用 is_top 字段,如果字段不存在则降级处理
- if err := db.Model(&entity.DtTask{}).Where("status = ? AND remain_count > 0", 1).
- Order("is_top DESC, created_at DESC").Limit(20).Find(&normalTasks).Error; err != nil {
- if isColumnNotExistError(err) {
- // 字段不存在,使用降级查询(不按置顶排序)
- db.Model(&entity.DtTask{}).Where("status = ? AND remain_count > 0", 1).
- Order("created_at DESC").Limit(20).Find(&normalTasks)
- }
- }
- ctx.OK(gin.H{
- "banners": banners,
- "categories": categories,
- "recommendTasks": recommendTasks,
- "normalTasks": normalTasks,
- })
- }
- // HomeBanner Banner列表
- func (s *Server) HomeBanner(c *gin.Context) {
- ctx := s.FromContext(c)
- db := s.DB()
- position := c.DefaultQuery("position", "home")
- banners := make([]*entity.DtBanner, 0)
- db.Model(&entity.DtBanner{}).
- Where("status = ? AND position = ?", 1, position).
- Order("sort DESC, id DESC").
- Find(&banners)
- ctx.OK(banners)
- }
- // HomeHall 大厅数据
- func (s *Server) HomeHall(c *gin.Context) {
- ctx := s.FromContext(c)
- db := s.DB()
- // 平台发放收益统计
- var totalReward float64
- db.Model(&entity.DtUserTask{}).
- Where("status = ?", entity.UserTaskStatusCompleted).
- Select("COALESCE(SUM(reward_amount), 0)").
- Scan(&totalReward)
- // 已完成任务数
- var completedCount int64
- db.Model(&entity.DtUserTask{}).
- Where("status = ?", entity.UserTaskStatusCompleted).
- Count(&completedCount)
- // 任务列表
- paging := &services.Pagination{
- Current: ctx.QueryInt64("current", 1),
- Size: ctx.QueryInt64("size", 20),
- }
- tasks := make([]*entity.DtTask, 0)
- query := db.Model(&entity.DtTask{}).
- Where("status = ? AND remain_count > 0", 1)
- query.Count(&paging.Total)
- paging.Computer()
- // 尝试使用 is_top 和 is_recommend 字段,如果字段不存在则降级处理
- fallbackQuery := db.Model(&entity.DtTask{}).Where("status = ? AND remain_count > 0", 1)
- if err := query.Order("is_top DESC, is_recommend DESC, created_at DESC").
- Offset(int(paging.Start)).
- Limit(int(paging.Size)).
- Find(&tasks).Error; err != nil {
- if isColumnNotExistError(err) {
- // 字段不存在,使用全新查询(不按置顶和推荐排序)
- fallbackQuery.Order("created_at DESC").
- Offset(int(paging.Start)).
- Limit(int(paging.Size)).
- Find(&tasks)
- }
- }
- // 获取所有分类信息并构建映射
- categoryMap := make(map[int64]*entity.DtTaskCategory)
- if len(tasks) > 0 {
- categoryIds := make([]int64, 0)
- for _, task := range tasks {
- categoryIds = append(categoryIds, task.CategoryId)
- }
- categories := make([]*entity.DtTaskCategory, 0)
- db.Where("id IN ?", categoryIds).Find(&categories)
- for _, cat := range categories {
- categoryMap[cat.Id] = cat
- }
- }
- // 构建带分类信息的任务列表
- tasksWithCategory := make([]*TaskWithCategory, 0, len(tasks))
- for _, task := range tasks {
- twc := &TaskWithCategory{
- DtTask: *task,
- }
- if cat, ok := categoryMap[task.CategoryId]; ok {
- twc.CategoryName = cat.Name
- twc.CategoryIcon = cat.Icon
- twc.Platform = cat.Platform
- }
- tasksWithCategory = append(tasksWithCategory, twc)
- }
- ctx.OK(gin.H{
- "totalReward": totalReward,
- "completedCount": completedCount,
- "tasks": tasksWithCategory,
- "paging": paging,
- })
- }
- // TaskCategories 任务分类列表
- func (s *Server) TaskCategories(c *gin.Context) {
- ctx := s.FromContext(c)
- db := s.DB()
- categories := make([]*entity.DtTaskCategory, 0)
- db.Model(&entity.DtTaskCategory{}).
- Where("status = ?", 1).
- Order("sort ASC").
- Find(&categories)
- ctx.OK(categories)
- }
- // TaskList 任务列表
- func (s *Server) TaskList(c *gin.Context) {
- ctx := s.FromContext(c)
- db := s.DB()
- categoryId := ctx.QueryInt64("categoryId", 0)
- keyword := c.Query("keyword")
- paging := &services.Pagination{
- Current: ctx.QueryInt64("current", 1),
- Size: ctx.QueryInt64("size", 20),
- }
- query := db.Model(&entity.DtTask{}).
- Where("status = ? AND remain_count > 0", 1)
- if categoryId > 0 {
- query = query.Where("category_id = ?", categoryId)
- }
- if keyword != "" {
- query = query.Where("title LIKE ?", "%"+keyword+"%")
- }
- query.Count(&paging.Total)
- paging.Computer()
- tasks := make([]*entity.DtTask, 0)
- // 尝试使用 is_top 和 is_recommend 字段,如果字段不存在则降级处理
- fallbackQuery := db.Model(&entity.DtTask{}).Where("status = ? AND remain_count > 0", 1)
- if categoryId > 0 {
- fallbackQuery = fallbackQuery.Where("category_id = ?", categoryId)
- }
- if keyword != "" {
- fallbackQuery = fallbackQuery.Where("title LIKE ?", "%"+keyword+"%")
- }
- if err := query.Order("is_top DESC, is_recommend DESC, created_at DESC").
- Offset(int(paging.Start)).
- Limit(int(paging.Size)).
- Find(&tasks).Error; err != nil {
- if isColumnNotExistError(err) {
- // 字段不存在,使用全新查询(不按置顶和推荐排序)
- fallbackQuery.Order("created_at DESC").
- Offset(int(paging.Start)).
- Limit(int(paging.Size)).
- Find(&tasks)
- }
- }
- // 获取所有分类信息并构建映射
- categoryMap := make(map[int64]*entity.DtTaskCategory)
- if len(tasks) > 0 {
- categoryIds := make([]int64, 0)
- for _, task := range tasks {
- categoryIds = append(categoryIds, task.CategoryId)
- }
- categories := make([]*entity.DtTaskCategory, 0)
- db.Where("id IN ?", categoryIds).Find(&categories)
- for _, cat := range categories {
- categoryMap[cat.Id] = cat
- }
- }
- // 构建带分类信息的任务列表
- tasksWithCategory := make([]*TaskWithCategory, 0, len(tasks))
- for _, task := range tasks {
- twc := &TaskWithCategory{
- DtTask: *task,
- }
- if cat, ok := categoryMap[task.CategoryId]; ok {
- twc.CategoryName = cat.Name
- twc.CategoryIcon = cat.Icon
- twc.Platform = cat.Platform
- }
- tasksWithCategory = append(tasksWithCategory, twc)
- }
- ctx.OK(gin.H{
- "list": tasksWithCategory,
- "paging": paging,
- })
- }
- // TaskDetail 任务详情
- func (s *Server) TaskDetail(c *gin.Context) {
- ctx := s.FromContext(c)
- db := s.DB()
- taskId := ctx.QueryInt64("id", 0)
- if taskId == 0 {
- ctx.Fail("task_id_required")
- return
- }
- // 获取任务
- task := &entity.DtTask{}
- if err := db.Where("id = ? AND status = ?", taskId, 1).First(task).Error; err != nil {
- ctx.Fail("task_not_found")
- return
- }
- // 获取任务分类
- category := &entity.DtTaskCategory{}
- db.Where("id = ?", task.CategoryId).First(category)
- // 获取任务步骤
- steps := make([]*entity.DtTaskStep, 0)
- db.Model(&entity.DtTaskStep{}).
- Where("task_id = ?", taskId).
- Order("step_no ASC, id ASC").
- Find(&steps)
- // 获取审核样例
- examples := make([]*entity.DtTaskExample, 0)
- db.Model(&entity.DtTaskExample{}).
- Where("task_id = ?", taskId).
- Order("id ASC").
- Find(&examples)
- // 获取用户领取状态
- var apply *entity.DtUserTask
- userId := ctx.UserId()
- if userId > 0 {
- userTask := &entity.DtUserTask{}
- if err := db.Where("user_id = ? AND task_id = ?", userId, taskId).
- Order("id DESC").First(userTask).Error; err == nil {
- apply = userTask
- }
- }
- ctx.OK(gin.H{
- "task": task,
- "category": category,
- "steps": steps,
- "examples": examples,
- "apply": apply,
- })
- }
- // ConfigGet 获取配置
- func (s *Server) ConfigGet(c *gin.Context) {
- ctx := s.FromContext(c)
- db := s.DB()
- key := c.Query("key")
- group := c.Query("group")
- if key != "" {
- // 获取单个配置
- config := &entity.DtConfig{}
- if err := db.Where("`key` = ?", key).First(config).Error; err != nil {
- ctx.Fail("config_not_found")
- return
- }
- ctx.OK(config.Value)
- return
- }
- if group != "" {
- // 获取分组配置
- configs := make([]*entity.DtConfig, 0)
- db.Where("`group` = ?", group).Order("sort ASC").Find(&configs)
- result := make(map[string]string)
- for _, cfg := range configs {
- result[cfg.Key] = cfg.Value
- }
- ctx.OK(result)
- return
- }
- ctx.Fail("key_or_group_required")
- }
- // CustomerService 客服配置
- func (s *Server) CustomerService(c *gin.Context) {
- ctx := s.FromContext(c)
- db := s.DB()
- services := make([]*entity.DtCustomerService, 0)
- db.Model(&entity.DtCustomerService{}).
- Where("status = ?", 1).
- Order("sort ASC").
- Find(&services)
- ctx.OK(services)
- }
- // OAuthConfig 获取OAuth配置(公开接口,只返回客户端需要的信息)
- func (s *Server) OAuthConfig(c *gin.Context) {
- ctx := s.FromContext(c)
- db := s.DB()
- result := make(map[string]string)
- // 获取 Google Client ID
- var googleConfig entity.DtConfig
- if err := db.Where("`key` = ?", entity.ConfigKeyGoogleClientId).First(&googleConfig).Error; err == nil {
- result["googleClientId"] = googleConfig.Value
- }
- // 获取 Zalo App ID
- var zaloConfig entity.DtConfig
- if err := db.Where("`key` = ?", entity.ConfigKeyZaloAppId).First(&zaloConfig).Error; err == nil {
- result["zaloAppId"] = zaloConfig.Value
- }
- // 获取 Telegram Bot Name
- var telegramConfig entity.DtConfig
- if err := db.Where("`key` = ?", entity.ConfigKeyTelegramBotName).First(&telegramConfig).Error; err == nil {
- result["telegramBotName"] = telegramConfig.Value
- } else {
- fmt.Printf("Telegram config error: %v, key: %s\n", err, entity.ConfigKeyTelegramBotName)
- }
- // 获取 Telegram Bot ID
- var telegramIdConfig entity.DtConfig
- if err := db.Where("`key` = ?", entity.ConfigKeyTelegramBotId).First(&telegramIdConfig).Error; err == nil {
- result["telegramBotId"] = telegramIdConfig.Value
- }
- // 获取 TikTok Client Key
- var tiktokConfig entity.DtConfig
- if err := db.Where("`key` = ?", entity.ConfigKeyTiktokClientKey).First(&tiktokConfig).Error; err == nil {
- result["tiktokClientKey"] = tiktokConfig.Value
- }
- // 获取 Facebook App ID
- var facebookConfig entity.DtConfig
- if err := db.Where("`key` = ?", entity.ConfigKeyFacebookAppId).First(&facebookConfig).Error; err == nil {
- result["facebookAppId"] = facebookConfig.Value
- }
- ctx.OK(result)
- }
- // isColumnNotExistError 检查是否是列不存在的错误
- func isColumnNotExistError(err error) bool {
- if err == nil {
- return false
- }
- errStr := err.Error()
- // MySQL 错误 1054 表示列不存在
- return strings.Contains(errStr, "1054") || strings.Contains(errStr, "Unknown column")
- }
|