home.go 7.9 KB

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