keyword.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. package handler
  2. import (
  3. "net/http"
  4. "strconv"
  5. "spider/internal/model"
  6. "spider/internal/store"
  7. "github.com/gin-gonic/gin"
  8. )
  9. // KeywordHandler handles unified keyword + seed CRUD.
  10. type KeywordHandler struct {
  11. store *store.Store
  12. }
  13. // List returns keywords with optional filters and pagination.
  14. // GET /keywords?page=1&page_size=20&industry_tag=
  15. func (h *KeywordHandler) List(c *gin.Context) {
  16. page, pageSize, offset := parsePage(c)
  17. industryTag := c.Query("industry_tag")
  18. query := h.store.DB.Model(&model.Keyword{})
  19. if industryTag != "" {
  20. query = query.Where("industry_tag = ?", industryTag)
  21. }
  22. var total int64
  23. query.Count(&total)
  24. var keywords []model.Keyword
  25. if err := query.Order("id DESC").Limit(pageSize).Offset(offset).Find(&keywords).Error; err != nil {
  26. Fail(c, 500, err.Error())
  27. return
  28. }
  29. PageOK(c, keywords, total, page, pageSize)
  30. }
  31. // Create creates one or more keywords in batch.
  32. // POST /keywords body: {keywords:["k1","k2"], industry_tag:"机场"}
  33. func (h *KeywordHandler) Create(c *gin.Context) {
  34. var body struct {
  35. Keywords []string `json:"keywords" binding:"required,min=1"`
  36. IndustryTag string `json:"industry_tag"`
  37. }
  38. if err := c.ShouldBindJSON(&body); err != nil {
  39. Fail(c, http.StatusBadRequest, err.Error())
  40. return
  41. }
  42. var created []model.Keyword
  43. for _, kw := range body.Keywords {
  44. if kw == "" {
  45. continue
  46. }
  47. k := model.Keyword{
  48. Keyword: kw,
  49. IndustryTag: body.IndustryTag,
  50. Enabled: true,
  51. }
  52. if err := h.store.DB.Where(model.Keyword{Keyword: kw}).FirstOrCreate(&k).Error; err != nil {
  53. Fail(c, 500, err.Error())
  54. return
  55. }
  56. created = append(created, k)
  57. }
  58. OK(c, created)
  59. }
  60. // Update modifies a keyword.
  61. // PUT /keywords/:id
  62. func (h *KeywordHandler) Update(c *gin.Context) {
  63. id, err := strconv.ParseUint(c.Param("id"), 10, 64)
  64. if err != nil {
  65. Fail(c, http.StatusBadRequest, "invalid id")
  66. return
  67. }
  68. var body struct {
  69. Keyword string `json:"keyword"`
  70. IndustryTag string `json:"industry_tag"`
  71. Enabled *bool `json:"enabled"`
  72. }
  73. if err := c.ShouldBindJSON(&body); err != nil {
  74. Fail(c, http.StatusBadRequest, err.Error())
  75. return
  76. }
  77. var kw model.Keyword
  78. if err := h.store.DB.First(&kw, id).Error; err != nil {
  79. Fail(c, 404, "keyword not found")
  80. return
  81. }
  82. updates := map[string]any{}
  83. if body.Keyword != "" {
  84. updates["keyword"] = body.Keyword
  85. }
  86. if body.IndustryTag != "" {
  87. updates["industry_tag"] = body.IndustryTag
  88. }
  89. if body.Enabled != nil {
  90. updates["enabled"] = *body.Enabled
  91. }
  92. if err := h.store.DB.Model(&kw).Updates(updates).Error; err != nil {
  93. Fail(c, 500, err.Error())
  94. return
  95. }
  96. h.store.DB.First(&kw, id)
  97. OK(c, kw)
  98. }
  99. // Delete removes a keyword by ID.
  100. // DELETE /keywords/:id
  101. func (h *KeywordHandler) Delete(c *gin.Context) {
  102. id, err := strconv.ParseUint(c.Param("id"), 10, 64)
  103. if err != nil {
  104. Fail(c, http.StatusBadRequest, "invalid id")
  105. return
  106. }
  107. if err := h.store.DB.Delete(&model.Keyword{}, id).Error; err != nil {
  108. Fail(c, 500, err.Error())
  109. return
  110. }
  111. OK(c, nil)
  112. }