320 lines
9.1 KiB
Go
Executable File
320 lines
9.1 KiB
Go
Executable File
package admin
|
||
|
||
import (
|
||
"net/http"
|
||
"strconv"
|
||
|
||
"bindbox-game/internal/code"
|
||
"bindbox-game/internal/pkg/core"
|
||
"bindbox-game/internal/pkg/validation"
|
||
"bindbox-game/internal/repository/mysql/model"
|
||
)
|
||
|
||
// ========== 黑名单管理 ==========
|
||
|
||
type addBlacklistRequest struct {
|
||
DouyinUserID string `json:"douyin_user_id" binding:"required"`
|
||
Reason string `json:"reason"`
|
||
}
|
||
|
||
type blacklistResponse struct {
|
||
ID int64 `json:"id"`
|
||
DouyinUserID string `json:"douyin_user_id"`
|
||
Reason string `json:"reason"`
|
||
OperatorID int64 `json:"operator_id"`
|
||
Status int32 `json:"status"`
|
||
CreatedAt string `json:"created_at"`
|
||
}
|
||
|
||
type listBlacklistRequest struct {
|
||
Page int `form:"page"`
|
||
PageSize int `form:"page_size"`
|
||
Keyword string `form:"keyword"`
|
||
}
|
||
|
||
type listBlacklistResponse struct {
|
||
List []blacklistResponse `json:"list"`
|
||
Total int64 `json:"total"`
|
||
Page int `json:"page"`
|
||
PageSize int `json:"page_size"`
|
||
}
|
||
|
||
// ListBlacklist 获取黑名单列表
|
||
// @Summary 获取黑名单列表
|
||
// @Description 获取抖音用户黑名单列表,支持分页和关键词搜索
|
||
// @Tags 管理端.黑名单
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Param page query int false "页码" default(1)
|
||
// @Param page_size query int false "每页数量" default(20)
|
||
// @Param keyword query string false "搜索关键词(抖音ID)"
|
||
// @Success 200 {object} listBlacklistResponse
|
||
// @Failure 400 {object} code.Failure
|
||
// @Router /api/admin/blacklist [get]
|
||
// @Security LoginVerifyToken
|
||
func (h *handler) ListBlacklist() core.HandlerFunc {
|
||
return func(ctx core.Context) {
|
||
req := new(listBlacklistRequest)
|
||
if err := ctx.ShouldBindQuery(req); err != nil {
|
||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
|
||
return
|
||
}
|
||
|
||
if req.Page <= 0 {
|
||
req.Page = 1
|
||
}
|
||
if req.PageSize <= 0 {
|
||
req.PageSize = 20
|
||
}
|
||
|
||
db := h.repo.GetDbR().WithContext(ctx.RequestContext()).
|
||
Table("douyin_blacklist").
|
||
Where("status = 1")
|
||
|
||
if req.Keyword != "" {
|
||
db = db.Where("douyin_user_id LIKE ?", "%"+req.Keyword+"%")
|
||
}
|
||
|
||
var total int64
|
||
if err := db.Count(&total).Error; err != nil {
|
||
ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, err.Error()))
|
||
return
|
||
}
|
||
|
||
var list []model.DouyinBlacklist
|
||
if err := db.Order("id DESC").
|
||
Offset((req.Page - 1) * req.PageSize).
|
||
Limit(req.PageSize).
|
||
Find(&list).Error; err != nil {
|
||
ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, err.Error()))
|
||
return
|
||
}
|
||
|
||
rsp := &listBlacklistResponse{
|
||
List: make([]blacklistResponse, len(list)),
|
||
Total: total,
|
||
Page: req.Page,
|
||
PageSize: req.PageSize,
|
||
}
|
||
|
||
for i, item := range list {
|
||
rsp.List[i] = blacklistResponse{
|
||
ID: item.ID,
|
||
DouyinUserID: item.DouyinUserID,
|
||
Reason: item.Reason,
|
||
OperatorID: item.OperatorID,
|
||
Status: item.Status,
|
||
CreatedAt: item.CreatedAt.Format("2006-01-02 15:04:05"),
|
||
}
|
||
}
|
||
|
||
ctx.Payload(rsp)
|
||
}
|
||
}
|
||
|
||
// AddBlacklist 添加黑名单
|
||
// @Summary 添加黑名单
|
||
// @Description 将抖音用户添加到黑名单
|
||
// @Tags 管理端.黑名单
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Param body body addBlacklistRequest true "请求参数"
|
||
// @Success 200 {object} blacklistResponse
|
||
// @Failure 400 {object} code.Failure
|
||
// @Router /api/admin/blacklist [post]
|
||
// @Security LoginVerifyToken
|
||
func (h *handler) AddBlacklist() core.HandlerFunc {
|
||
return func(ctx core.Context) {
|
||
req := new(addBlacklistRequest)
|
||
if err := ctx.ShouldBindJSON(req); err != nil {
|
||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
|
||
return
|
||
}
|
||
|
||
// 检查是否已在黑名单
|
||
var existCount int64
|
||
h.repo.GetDbR().WithContext(ctx.RequestContext()).
|
||
Table("douyin_blacklist").
|
||
Where("douyin_user_id = ? AND status = 1", req.DouyinUserID).
|
||
Count(&existCount)
|
||
|
||
if existCount > 0 {
|
||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "该用户已在黑名单中"))
|
||
return
|
||
}
|
||
|
||
operatorID := int64(0)
|
||
if ctx.SessionUserInfo().Id > 0 {
|
||
operatorID = int64(ctx.SessionUserInfo().Id)
|
||
}
|
||
|
||
blacklist := &model.DouyinBlacklist{
|
||
DouyinUserID: req.DouyinUserID,
|
||
Reason: req.Reason,
|
||
OperatorID: operatorID,
|
||
Status: 1,
|
||
}
|
||
|
||
if err := h.repo.GetDbW().WithContext(ctx.RequestContext()).Create(blacklist).Error; err != nil {
|
||
ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, err.Error()))
|
||
return
|
||
}
|
||
|
||
ctx.Payload(&blacklistResponse{
|
||
ID: blacklist.ID,
|
||
DouyinUserID: blacklist.DouyinUserID,
|
||
Reason: blacklist.Reason,
|
||
OperatorID: blacklist.OperatorID,
|
||
Status: blacklist.Status,
|
||
CreatedAt: blacklist.CreatedAt.Format("2006-01-02 15:04:05"),
|
||
})
|
||
}
|
||
}
|
||
|
||
// RemoveBlacklist 移除黑名单
|
||
// @Summary 移除黑名单
|
||
// @Description 将用户从黑名单中移除(软删除,status设为0)
|
||
// @Tags 管理端.黑名单
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Param id path integer true "黑名单ID"
|
||
// @Success 200 {object} simpleMessageResponse
|
||
// @Failure 400 {object} code.Failure
|
||
// @Router /api/admin/blacklist/{id} [delete]
|
||
// @Security LoginVerifyToken
|
||
func (h *handler) RemoveBlacklist() core.HandlerFunc {
|
||
return func(ctx core.Context) {
|
||
idStr := ctx.Param("id")
|
||
id, err := strconv.ParseInt(idStr, 10, 64)
|
||
if err != nil {
|
||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "无效的ID"))
|
||
return
|
||
}
|
||
|
||
result := h.repo.GetDbW().WithContext(ctx.RequestContext()).
|
||
Table("douyin_blacklist").
|
||
Where("id = ?", id).
|
||
Update("status", 0)
|
||
|
||
if result.Error != nil {
|
||
ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, result.Error.Error()))
|
||
return
|
||
}
|
||
|
||
if result.RowsAffected == 0 {
|
||
ctx.AbortWithError(core.Error(http.StatusNotFound, code.ParamBindError, "黑名单记录不存在"))
|
||
return
|
||
}
|
||
|
||
ctx.Payload(&simpleMessageResponse{Message: "移除成功"})
|
||
}
|
||
}
|
||
|
||
// CheckBlacklist 检查用户是否在黑名单
|
||
// @Summary 检查黑名单状态
|
||
// @Description 检查指定抖音用户是否在黑名单中
|
||
// @Tags 管理端.黑名单
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Param douyin_user_id query string true "抖音用户ID"
|
||
// @Success 200 {object} map[string]bool
|
||
// @Failure 400 {object} code.Failure
|
||
// @Router /api/admin/blacklist/check [get]
|
||
// @Security LoginVerifyToken
|
||
func (h *handler) CheckBlacklist() core.HandlerFunc {
|
||
return func(ctx core.Context) {
|
||
douyinUserID := ctx.RequestInputParams().Get("douyin_user_id")
|
||
if douyinUserID == "" {
|
||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "抖音用户ID不能为空"))
|
||
return
|
||
}
|
||
|
||
var count int64
|
||
h.repo.GetDbR().WithContext(ctx.RequestContext()).
|
||
Table("douyin_blacklist").
|
||
Where("douyin_user_id = ? AND status = 1", douyinUserID).
|
||
Count(&count)
|
||
|
||
ctx.Payload(map[string]any{
|
||
"douyin_user_id": douyinUserID,
|
||
"is_blacklisted": count > 0,
|
||
})
|
||
}
|
||
}
|
||
|
||
// BatchAddBlacklist 批量添加黑名单
|
||
// @Summary 批量添加黑名单
|
||
// @Description 批量将抖音用户添加到黑名单
|
||
// @Tags 管理端.黑名单
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Param body body batchAddBlacklistRequest true "请求参数"
|
||
// @Success 200 {object} batchAddBlacklistResponse
|
||
// @Failure 400 {object} code.Failure
|
||
// @Router /api/admin/blacklist/batch [post]
|
||
// @Security LoginVerifyToken
|
||
func (h *handler) BatchAddBlacklist() core.HandlerFunc {
|
||
return func(ctx core.Context) {
|
||
var req struct {
|
||
DouyinUserIDs []string `json:"douyin_user_ids" binding:"required"`
|
||
Reason string `json:"reason"`
|
||
}
|
||
|
||
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
|
||
return
|
||
}
|
||
|
||
if len(req.DouyinUserIDs) == 0 {
|
||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "抖音用户ID列表不能为空"))
|
||
return
|
||
}
|
||
|
||
// 获取操作人ID
|
||
operatorID := int64(0)
|
||
if ctx.SessionUserInfo().Id > 0 {
|
||
operatorID = int64(ctx.SessionUserInfo().Id)
|
||
}
|
||
|
||
// 查询已存在的黑名单
|
||
var existingIDs []string
|
||
h.repo.GetDbR().WithContext(ctx.RequestContext()).
|
||
Table("douyin_blacklist").
|
||
Where("douyin_user_id IN ? AND status = 1", req.DouyinUserIDs).
|
||
Pluck("douyin_user_id", &existingIDs)
|
||
|
||
existMap := make(map[string]bool)
|
||
for _, id := range existingIDs {
|
||
existMap[id] = true
|
||
}
|
||
|
||
// 过滤出需要新增的
|
||
var toAdd []model.DouyinBlacklist
|
||
for _, uid := range req.DouyinUserIDs {
|
||
if !existMap[uid] {
|
||
toAdd = append(toAdd, model.DouyinBlacklist{
|
||
DouyinUserID: uid,
|
||
Reason: req.Reason,
|
||
OperatorID: operatorID,
|
||
Status: 1,
|
||
})
|
||
}
|
||
}
|
||
|
||
addedCount := 0
|
||
if len(toAdd) > 0 {
|
||
if err := h.repo.GetDbW().WithContext(ctx.RequestContext()).Create(&toAdd).Error; err != nil {
|
||
ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, err.Error()))
|
||
return
|
||
}
|
||
addedCount = len(toAdd)
|
||
}
|
||
|
||
ctx.Payload(map[string]any{
|
||
"total_requested": len(req.DouyinUserIDs),
|
||
"added": addedCount,
|
||
"skipped": len(req.DouyinUserIDs) - addedCount,
|
||
})
|
||
}
|
||
}
|