| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- package handler
- import (
- "strconv"
- "spider/internal/model"
- "spider/internal/store"
- "github.com/gin-gonic/gin"
- )
- // ChannelHandler handles TG channel management.
- type ChannelHandler struct {
- store *store.Store
- }
- // List handles GET /channels
- func (h *ChannelHandler) List(c *gin.Context) {
- page, pageSize, offset := parsePage(c)
- query := h.store.DB.Model(&model.Channel{})
- if status := c.Query("status"); status != "" {
- query = query.Where("status = ?", status)
- }
- if source := c.Query("source"); source != "" {
- query = query.Where("source = ?", source)
- }
- if search := c.Query("search"); search != "" {
- query = query.Where("username LIKE ?", "%"+search+"%")
- }
- var total int64
- query.Count(&total)
- var channels []model.Channel
- if err := query.Order("created_at DESC").Limit(pageSize).Offset(offset).Find(&channels).Error; err != nil {
- Fail(c, 500, err.Error())
- return
- }
- PageOK(c, channels, total, page, pageSize)
- }
- // UpdateStatus handles PUT /channels/:id/status
- func (h *ChannelHandler) UpdateStatus(c *gin.Context) {
- id, err := strconv.ParseUint(c.Param("id"), 10, 64)
- if err != nil {
- Fail(c, 400, "invalid id")
- return
- }
- var body struct {
- Status string `json:"status" binding:"required"`
- }
- if err := c.ShouldBindJSON(&body); err != nil {
- Fail(c, 400, err.Error())
- return
- }
- allowed := map[string]bool{"pending": true, "scraped": true, "failed": true, "skipped": true}
- if !allowed[body.Status] {
- Fail(c, 400, "invalid status")
- return
- }
- var ch model.Channel
- if err := h.store.DB.First(&ch, id).Error; err != nil {
- Fail(c, 404, "channel not found")
- return
- }
- h.store.DB.Model(&ch).Update("status", body.Status)
- OK(c, ch)
- }
- // Delete handles DELETE /channels/:id
- func (h *ChannelHandler) Delete(c *gin.Context) {
- id, err := strconv.ParseUint(c.Param("id"), 10, 64)
- if err != nil {
- Fail(c, 400, "invalid id")
- return
- }
- if err := h.store.DB.Delete(&model.Channel{}, id).Error; err != nil {
- Fail(c, 500, err.Error())
- return
- }
- OK(c, gin.H{"message": "已删除"})
- }
- // Stats handles GET /channels/stats
- func (h *ChannelHandler) Stats(c *gin.Context) {
- type kv struct {
- Key string `gorm:"column:key"`
- Count int64 `gorm:"column:count"`
- }
- var byStatus []kv
- h.store.DB.Model(&model.Channel{}).
- Select("status as `key`, count(*) as `count`").
- Group("status").Find(&byStatus)
- var bySource []kv
- h.store.DB.Model(&model.Channel{}).
- Select("source as `key`, count(*) as `count`").
- Group("source").Find(&bySource)
- var total int64
- h.store.DB.Model(&model.Channel{}).Count(&total)
- OK(c, gin.H{
- "total": total,
- "by_status": byStatus,
- "by_source": bySource,
- })
- }
|