home.go 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. package daytask
  2. import (
  3. "app/commons/model/entity"
  4. "app/commons/services"
  5. "fmt"
  6. "strings"
  7. "github.com/gin-gonic/gin"
  8. )
  9. // HomeIndex 首页数据
  10. func (s *Server) HomeIndex(c *gin.Context) {
  11. ctx := s.FromContext(c)
  12. db := s.DB()
  13. // 获取Banner列表
  14. banners := make([]*entity.DtBanner, 0)
  15. db.Model(&entity.DtBanner{}).
  16. Where("status = ? AND position = ?", 1, "home").
  17. Order("sort DESC, id DESC").
  18. Limit(5).
  19. Find(&banners)
  20. // 获取任务分类
  21. categories := make([]*entity.DtTaskCategory, 0)
  22. db.Model(&entity.DtTaskCategory{}).
  23. Where("status = ?", 1).
  24. Order("sort ASC").
  25. Find(&categories)
  26. // 获取推荐任务
  27. recommendTasks := make([]*entity.DtTask, 0)
  28. // 尝试使用 is_recommend 字段,如果字段不存在则降级处理
  29. if err := db.Model(&entity.DtTask{}).Where("status = ? AND is_recommend = ?", 1, 1).
  30. Order("sort DESC, id DESC").Limit(10).Find(&recommendTasks).Error; err != nil {
  31. if isColumnNotExistError(err) {
  32. // 字段不存在,使用降级查询(不筛选推荐)
  33. db.Model(&entity.DtTask{}).Where("status = ?", 1).
  34. Order("sort DESC, id DESC").Limit(10).Find(&recommendTasks)
  35. }
  36. }
  37. // 获取普通任务
  38. normalTasks := make([]*entity.DtTask, 0)
  39. // 尝试使用 is_top 字段,如果字段不存在则降级处理
  40. if err := db.Model(&entity.DtTask{}).Where("status = ? AND remain_count > 0", 1).
  41. Order("is_top DESC, created_at DESC").Limit(20).Find(&normalTasks).Error; err != nil {
  42. if isColumnNotExistError(err) {
  43. // 字段不存在,使用降级查询(不按置顶排序)
  44. db.Model(&entity.DtTask{}).Where("status = ? AND remain_count > 0", 1).
  45. Order("created_at DESC").Limit(20).Find(&normalTasks)
  46. }
  47. }
  48. ctx.OK(gin.H{
  49. "banners": banners,
  50. "categories": categories,
  51. "recommendTasks": recommendTasks,
  52. "normalTasks": normalTasks,
  53. })
  54. }
  55. // HomeBanner Banner列表
  56. func (s *Server) HomeBanner(c *gin.Context) {
  57. ctx := s.FromContext(c)
  58. db := s.DB()
  59. position := c.DefaultQuery("position", "home")
  60. banners := make([]*entity.DtBanner, 0)
  61. db.Model(&entity.DtBanner{}).
  62. Where("status = ? AND position = ?", 1, position).
  63. Order("sort DESC, id DESC").
  64. Find(&banners)
  65. ctx.OK(banners)
  66. }
  67. // HomeHall 大厅数据
  68. func (s *Server) HomeHall(c *gin.Context) {
  69. ctx := s.FromContext(c)
  70. db := s.DB()
  71. // 平台发放收益统计
  72. var totalReward float64
  73. db.Model(&entity.DtUserTask{}).
  74. Where("status = ?", entity.UserTaskStatusCompleted).
  75. Select("COALESCE(SUM(reward_amount), 0)").
  76. Scan(&totalReward)
  77. // 已完成任务数
  78. var completedCount int64
  79. db.Model(&entity.DtUserTask{}).
  80. Where("status = ?", entity.UserTaskStatusCompleted).
  81. Count(&completedCount)
  82. // 任务列表
  83. paging := &services.Pagination{
  84. Current: ctx.QueryInt64("current", 1),
  85. Size: ctx.QueryInt64("size", 20),
  86. }
  87. tasks := make([]*entity.DtTask, 0)
  88. query := db.Model(&entity.DtTask{}).
  89. Where("status = ? AND remain_count > 0", 1)
  90. query.Count(&paging.Total)
  91. paging.Computer()
  92. // 尝试使用 is_top 和 is_recommend 字段,如果字段不存在则降级处理
  93. fallbackQuery := db.Model(&entity.DtTask{}).Where("status = ? AND remain_count > 0", 1)
  94. if err := query.Order("is_top DESC, is_recommend DESC, created_at DESC").
  95. Offset(int(paging.Start)).
  96. Limit(int(paging.Size)).
  97. Find(&tasks).Error; err != nil {
  98. if isColumnNotExistError(err) {
  99. // 字段不存在,使用全新查询(不按置顶和推荐排序)
  100. fallbackQuery.Order("created_at DESC").
  101. Offset(int(paging.Start)).
  102. Limit(int(paging.Size)).
  103. Find(&tasks)
  104. }
  105. }
  106. ctx.OK(gin.H{
  107. "totalReward": totalReward,
  108. "completedCount": completedCount,
  109. "tasks": tasks,
  110. "paging": paging,
  111. })
  112. }
  113. // TaskCategories 任务分类列表
  114. func (s *Server) TaskCategories(c *gin.Context) {
  115. ctx := s.FromContext(c)
  116. db := s.DB()
  117. categories := make([]*entity.DtTaskCategory, 0)
  118. db.Model(&entity.DtTaskCategory{}).
  119. Where("status = ?", 1).
  120. Order("sort ASC").
  121. Find(&categories)
  122. ctx.OK(categories)
  123. }
  124. // TaskList 任务列表
  125. func (s *Server) TaskList(c *gin.Context) {
  126. ctx := s.FromContext(c)
  127. db := s.DB()
  128. categoryId := ctx.QueryInt64("categoryId", 0)
  129. keyword := c.Query("keyword")
  130. paging := &services.Pagination{
  131. Current: ctx.QueryInt64("current", 1),
  132. Size: ctx.QueryInt64("size", 20),
  133. }
  134. query := db.Model(&entity.DtTask{}).
  135. Where("status = ? AND remain_count > 0", 1)
  136. if categoryId > 0 {
  137. query = query.Where("category_id = ?", categoryId)
  138. }
  139. if keyword != "" {
  140. query = query.Where("title LIKE ?", "%"+keyword+"%")
  141. }
  142. query.Count(&paging.Total)
  143. paging.Computer()
  144. tasks := make([]*entity.DtTask, 0)
  145. // 尝试使用 is_top 和 is_recommend 字段,如果字段不存在则降级处理
  146. fallbackQuery := db.Model(&entity.DtTask{}).Where("status = ? AND remain_count > 0", 1)
  147. if categoryId > 0 {
  148. fallbackQuery = fallbackQuery.Where("category_id = ?", categoryId)
  149. }
  150. if keyword != "" {
  151. fallbackQuery = fallbackQuery.Where("title LIKE ?", "%"+keyword+"%")
  152. }
  153. if err := query.Order("is_top DESC, is_recommend DESC, created_at DESC").
  154. Offset(int(paging.Start)).
  155. Limit(int(paging.Size)).
  156. Find(&tasks).Error; err != nil {
  157. if isColumnNotExistError(err) {
  158. // 字段不存在,使用全新查询(不按置顶和推荐排序)
  159. fallbackQuery.Order("created_at DESC").
  160. Offset(int(paging.Start)).
  161. Limit(int(paging.Size)).
  162. Find(&tasks)
  163. }
  164. }
  165. ctx.OK(gin.H{
  166. "list": tasks,
  167. "paging": paging,
  168. })
  169. }
  170. // TaskDetail 任务详情
  171. func (s *Server) TaskDetail(c *gin.Context) {
  172. ctx := s.FromContext(c)
  173. db := s.DB()
  174. taskId := ctx.QueryInt64("id", 0)
  175. if taskId == 0 {
  176. ctx.Fail("task_id_required")
  177. return
  178. }
  179. // 获取任务
  180. task := &entity.DtTask{}
  181. if err := db.Where("id = ? AND status = ?", taskId, 1).First(task).Error; err != nil {
  182. ctx.Fail("task_not_found")
  183. return
  184. }
  185. // 获取任务分类
  186. category := &entity.DtTaskCategory{}
  187. db.Where("id = ?", task.CategoryId).First(category)
  188. // 获取任务步骤
  189. steps := make([]*entity.DtTaskStep, 0)
  190. db.Model(&entity.DtTaskStep{}).
  191. Where("task_id = ?", taskId).
  192. Order("step_no ASC, id ASC").
  193. Find(&steps)
  194. // 获取审核样例
  195. examples := make([]*entity.DtTaskExample, 0)
  196. db.Model(&entity.DtTaskExample{}).
  197. Where("task_id = ?", taskId).
  198. Order("id ASC").
  199. Find(&examples)
  200. // 获取用户领取状态
  201. var apply *entity.DtUserTask
  202. userId := ctx.UserId()
  203. if userId > 0 {
  204. userTask := &entity.DtUserTask{}
  205. if err := db.Where("user_id = ? AND task_id = ?", userId, taskId).
  206. Order("id DESC").First(userTask).Error; err == nil {
  207. apply = userTask
  208. }
  209. }
  210. ctx.OK(gin.H{
  211. "task": task,
  212. "category": category,
  213. "steps": steps,
  214. "examples": examples,
  215. "apply": apply,
  216. })
  217. }
  218. // ConfigGet 获取配置
  219. func (s *Server) ConfigGet(c *gin.Context) {
  220. ctx := s.FromContext(c)
  221. db := s.DB()
  222. key := c.Query("key")
  223. group := c.Query("group")
  224. if key != "" {
  225. // 获取单个配置
  226. config := &entity.DtConfig{}
  227. if err := db.Where("`key` = ?", key).First(config).Error; err != nil {
  228. ctx.Fail("config_not_found")
  229. return
  230. }
  231. ctx.OK(config.Value)
  232. return
  233. }
  234. if group != "" {
  235. // 获取分组配置
  236. configs := make([]*entity.DtConfig, 0)
  237. db.Where("`group` = ?", group).Order("sort ASC").Find(&configs)
  238. result := make(map[string]string)
  239. for _, cfg := range configs {
  240. result[cfg.Key] = cfg.Value
  241. }
  242. ctx.OK(result)
  243. return
  244. }
  245. ctx.Fail("key_or_group_required")
  246. }
  247. // CustomerService 客服配置
  248. func (s *Server) CustomerService(c *gin.Context) {
  249. ctx := s.FromContext(c)
  250. db := s.DB()
  251. services := make([]*entity.DtCustomerService, 0)
  252. db.Model(&entity.DtCustomerService{}).
  253. Where("status = ?", 1).
  254. Order("sort ASC").
  255. Find(&services)
  256. ctx.OK(services)
  257. }
  258. // OAuthConfig 获取OAuth配置(公开接口,只返回客户端需要的信息)
  259. func (s *Server) OAuthConfig(c *gin.Context) {
  260. ctx := s.FromContext(c)
  261. db := s.DB()
  262. result := make(map[string]string)
  263. // 获取 Google Client ID
  264. var googleConfig entity.DtConfig
  265. if err := db.Where("`key` = ?", entity.ConfigKeyGoogleClientId).First(&googleConfig).Error; err == nil {
  266. result["googleClientId"] = googleConfig.Value
  267. }
  268. // 获取 Zalo App ID
  269. var zaloConfig entity.DtConfig
  270. if err := db.Where("`key` = ?", entity.ConfigKeyZaloAppId).First(&zaloConfig).Error; err == nil {
  271. result["zaloAppId"] = zaloConfig.Value
  272. }
  273. // 获取 Telegram Bot Name
  274. var telegramConfig entity.DtConfig
  275. if err := db.Where("`key` = ?", entity.ConfigKeyTelegramBotName).First(&telegramConfig).Error; err == nil {
  276. result["telegramBotName"] = telegramConfig.Value
  277. } else {
  278. fmt.Printf("Telegram config error: %v, key: %s\n", err, entity.ConfigKeyTelegramBotName)
  279. }
  280. ctx.OK(result)
  281. }
  282. // isColumnNotExistError 检查是否是列不存在的错误
  283. func isColumnNotExistError(err error) bool {
  284. if err == nil {
  285. return false
  286. }
  287. errStr := err.Error()
  288. // MySQL 错误 1054 表示列不存在
  289. return strings.Contains(errStr, "1054") || strings.Contains(errStr, "Unknown column")
  290. }