412 lines
14 KiB
Go
412 lines
14 KiB
Go
package handlers
|
||
|
||
import (
|
||
"tyapi-server/internal/application/article"
|
||
"tyapi-server/internal/application/article/dto/commands"
|
||
appQueries "tyapi-server/internal/application/article/dto/queries"
|
||
"tyapi-server/internal/shared/interfaces"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
"go.uber.org/zap"
|
||
)
|
||
|
||
// AnnouncementHandler 公告HTTP处理器
|
||
type AnnouncementHandler struct {
|
||
appService article.AnnouncementApplicationService
|
||
responseBuilder interfaces.ResponseBuilder
|
||
validator interfaces.RequestValidator
|
||
logger *zap.Logger
|
||
}
|
||
|
||
// NewAnnouncementHandler 创建公告HTTP处理器
|
||
func NewAnnouncementHandler(
|
||
appService article.AnnouncementApplicationService,
|
||
responseBuilder interfaces.ResponseBuilder,
|
||
validator interfaces.RequestValidator,
|
||
logger *zap.Logger,
|
||
) *AnnouncementHandler {
|
||
return &AnnouncementHandler{
|
||
appService: appService,
|
||
responseBuilder: responseBuilder,
|
||
validator: validator,
|
||
logger: logger,
|
||
}
|
||
}
|
||
|
||
// CreateAnnouncement 创建公告
|
||
// @Summary 创建公告
|
||
// @Description 创建新的公告
|
||
// @Tags 公告管理-管理端
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security Bearer
|
||
// @Param request body commands.CreateAnnouncementCommand true "创建公告请求"
|
||
// @Success 201 {object} map[string]interface{} "公告创建成功"
|
||
// @Failure 400 {object} map[string]interface{} "请求参数错误"
|
||
// @Failure 401 {object} map[string]interface{} "未认证"
|
||
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
|
||
// @Router /api/v1/admin/announcements [post]
|
||
func (h *AnnouncementHandler) CreateAnnouncement(c *gin.Context) {
|
||
var cmd commands.CreateAnnouncementCommand
|
||
if err := h.validator.BindAndValidate(c, &cmd); err != nil {
|
||
return
|
||
}
|
||
|
||
// 验证用户是否已登录
|
||
if _, exists := c.Get("user_id"); !exists {
|
||
h.responseBuilder.Unauthorized(c, "用户未登录")
|
||
return
|
||
}
|
||
|
||
if err := h.appService.CreateAnnouncement(c.Request.Context(), &cmd); err != nil {
|
||
h.logger.Error("创建公告失败", zap.Error(err))
|
||
h.responseBuilder.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Created(c, nil, "公告创建成功")
|
||
}
|
||
|
||
// GetAnnouncementByID 获取公告详情
|
||
// @Summary 获取公告详情
|
||
// @Description 根据ID获取公告详情
|
||
// @Tags 公告管理-用户端
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Param id path string true "公告ID"
|
||
// @Success 200 {object} responses.AnnouncementInfoResponse "获取公告详情成功"
|
||
// @Failure 400 {object} map[string]interface{} "请求参数错误"
|
||
// @Failure 404 {object} map[string]interface{} "公告不存在"
|
||
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
|
||
// @Router /api/v1/announcements/{id} [get]
|
||
func (h *AnnouncementHandler) GetAnnouncementByID(c *gin.Context) {
|
||
var query appQueries.GetAnnouncementQuery
|
||
|
||
// 绑定URI参数(公告ID)
|
||
if err := h.validator.ValidateParam(c, &query); err != nil {
|
||
return
|
||
}
|
||
|
||
response, err := h.appService.GetAnnouncementByID(c.Request.Context(), &query)
|
||
if err != nil {
|
||
h.logger.Error("获取公告详情失败", zap.Error(err))
|
||
h.responseBuilder.NotFound(c, "公告不存在")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, response, "获取公告详情成功")
|
||
}
|
||
|
||
// ListAnnouncements 获取公告列表
|
||
// @Summary 获取公告列表
|
||
// @Description 分页获取公告列表,支持多种筛选条件
|
||
// @Tags 公告管理-用户端
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Param page query int false "页码" default(1)
|
||
// @Param page_size query int false "每页数量" default(10)
|
||
// @Param status query string false "公告状态"
|
||
// @Param title query string false "标题关键词"
|
||
// @Param order_by query string false "排序字段"
|
||
// @Param order_dir query string false "排序方向"
|
||
// @Success 200 {object} responses.AnnouncementListResponse "获取公告列表成功"
|
||
// @Failure 400 {object} map[string]interface{} "请求参数错误"
|
||
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
|
||
// @Router /api/v1/announcements [get]
|
||
func (h *AnnouncementHandler) ListAnnouncements(c *gin.Context) {
|
||
var query appQueries.ListAnnouncementQuery
|
||
if err := h.validator.ValidateQuery(c, &query); err != nil {
|
||
return
|
||
}
|
||
|
||
// 设置默认值
|
||
if query.Page <= 0 {
|
||
query.Page = 1
|
||
}
|
||
if query.PageSize <= 0 {
|
||
query.PageSize = 10
|
||
}
|
||
if query.PageSize > 100 {
|
||
query.PageSize = 100
|
||
}
|
||
|
||
response, err := h.appService.ListAnnouncements(c.Request.Context(), &query)
|
||
if err != nil {
|
||
h.logger.Error("获取公告列表失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取公告列表失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, response, "获取公告列表成功")
|
||
}
|
||
|
||
// PublishAnnouncement 发布公告
|
||
// @Summary 发布公告
|
||
// @Description 发布指定的公告
|
||
// @Tags 公告管理-管理端
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security Bearer
|
||
// @Param id path string true "公告ID"
|
||
// @Success 200 {object} map[string]interface{} "发布成功"
|
||
// @Failure 400 {object} map[string]interface{} "请求参数错误"
|
||
// @Failure 401 {object} map[string]interface{} "未认证"
|
||
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
|
||
// @Router /api/v1/admin/announcements/{id}/publish [post]
|
||
func (h *AnnouncementHandler) PublishAnnouncement(c *gin.Context) {
|
||
var cmd commands.PublishAnnouncementCommand
|
||
if err := h.validator.ValidateParam(c, &cmd); err != nil {
|
||
return
|
||
}
|
||
|
||
if err := h.appService.PublishAnnouncement(c.Request.Context(), &cmd); err != nil {
|
||
h.logger.Error("发布公告失败", zap.Error(err))
|
||
h.responseBuilder.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, nil, "发布成功")
|
||
}
|
||
|
||
// WithdrawAnnouncement 撤回公告
|
||
// @Summary 撤回公告
|
||
// @Description 撤回已发布的公告
|
||
// @Tags 公告管理-管理端
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security Bearer
|
||
// @Param id path string true "公告ID"
|
||
// @Success 200 {object} map[string]interface{} "撤回成功"
|
||
// @Failure 400 {object} map[string]interface{} "请求参数错误"
|
||
// @Failure 401 {object} map[string]interface{} "未认证"
|
||
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
|
||
// @Router /api/v1/admin/announcements/{id}/withdraw [post]
|
||
func (h *AnnouncementHandler) WithdrawAnnouncement(c *gin.Context) {
|
||
var cmd commands.WithdrawAnnouncementCommand
|
||
if err := h.validator.ValidateParam(c, &cmd); err != nil {
|
||
return
|
||
}
|
||
|
||
if err := h.appService.WithdrawAnnouncement(c.Request.Context(), &cmd); err != nil {
|
||
h.logger.Error("撤回公告失败", zap.Error(err))
|
||
h.responseBuilder.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, nil, "撤回成功")
|
||
}
|
||
|
||
// ArchiveAnnouncement 归档公告
|
||
// @Summary 归档公告
|
||
// @Description 归档指定的公告
|
||
// @Tags 公告管理-管理端
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security Bearer
|
||
// @Param id path string true "公告ID"
|
||
// @Success 200 {object} map[string]interface{} "归档成功"
|
||
// @Failure 400 {object} map[string]interface{} "请求参数错误"
|
||
// @Failure 401 {object} map[string]interface{} "未认证"
|
||
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
|
||
// @Router /api/v1/admin/announcements/{id}/archive [post]
|
||
func (h *AnnouncementHandler) ArchiveAnnouncement(c *gin.Context) {
|
||
var cmd commands.ArchiveAnnouncementCommand
|
||
if err := h.validator.ValidateParam(c, &cmd); err != nil {
|
||
return
|
||
}
|
||
|
||
if err := h.appService.ArchiveAnnouncement(c.Request.Context(), &cmd); err != nil {
|
||
h.logger.Error("归档公告失败", zap.Error(err))
|
||
h.responseBuilder.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, nil, "归档成功")
|
||
}
|
||
|
||
// UpdateAnnouncement 更新公告
|
||
// @Summary 更新公告
|
||
// @Description 更新指定的公告
|
||
// @Tags 公告管理-管理端
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security Bearer
|
||
// @Param id path string true "公告ID"
|
||
// @Param request body commands.UpdateAnnouncementCommand true "更新公告请求"
|
||
// @Success 200 {object} map[string]interface{} "更新成功"
|
||
// @Failure 400 {object} map[string]interface{} "请求参数错误"
|
||
// @Failure 401 {object} map[string]interface{} "未认证"
|
||
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
|
||
// @Router /api/v1/admin/announcements/{id} [put]
|
||
func (h *AnnouncementHandler) UpdateAnnouncement(c *gin.Context) {
|
||
var cmd commands.UpdateAnnouncementCommand
|
||
|
||
// 先绑定URI参数(公告ID)
|
||
if err := h.validator.ValidateParam(c, &cmd); err != nil {
|
||
return
|
||
}
|
||
|
||
// 再绑定JSON请求体(公告信息)
|
||
if err := h.validator.BindAndValidate(c, &cmd); err != nil {
|
||
return
|
||
}
|
||
|
||
if err := h.appService.UpdateAnnouncement(c.Request.Context(), &cmd); err != nil {
|
||
h.logger.Error("更新公告失败", zap.Error(err))
|
||
h.responseBuilder.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, nil, "更新成功")
|
||
}
|
||
|
||
// DeleteAnnouncement 删除公告
|
||
// @Summary 删除公告
|
||
// @Description 删除指定的公告
|
||
// @Tags 公告管理-管理端
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security Bearer
|
||
// @Param id path string true "公告ID"
|
||
// @Success 200 {object} map[string]interface{} "删除成功"
|
||
// @Failure 400 {object} map[string]interface{} "请求参数错误"
|
||
// @Failure 401 {object} map[string]interface{} "未认证"
|
||
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
|
||
// @Router /api/v1/admin/announcements/{id} [delete]
|
||
func (h *AnnouncementHandler) DeleteAnnouncement(c *gin.Context) {
|
||
var cmd commands.DeleteAnnouncementCommand
|
||
if err := h.validator.ValidateParam(c, &cmd); err != nil {
|
||
return
|
||
}
|
||
|
||
if err := h.appService.DeleteAnnouncement(c.Request.Context(), &cmd); err != nil {
|
||
h.logger.Error("删除公告失败", zap.Error(err))
|
||
h.responseBuilder.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, nil, "删除成功")
|
||
}
|
||
|
||
// SchedulePublishAnnouncement 定时发布公告
|
||
// @Summary 定时发布公告
|
||
// @Description 设置公告的定时发布时间
|
||
// @Tags 公告管理-管理端
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security Bearer
|
||
// @Param id path string true "公告ID"
|
||
// @Param request body commands.SchedulePublishAnnouncementCommand true "定时发布请求"
|
||
// @Success 200 {object} map[string]interface{} "设置成功"
|
||
// @Failure 400 {object} map[string]interface{} "请求参数错误"
|
||
// @Failure 401 {object} map[string]interface{} "未认证"
|
||
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
|
||
// @Router /api/v1/admin/announcements/{id}/schedule-publish [post]
|
||
func (h *AnnouncementHandler) SchedulePublishAnnouncement(c *gin.Context) {
|
||
var cmd commands.SchedulePublishAnnouncementCommand
|
||
|
||
// 先绑定URI参数(公告ID)
|
||
if err := h.validator.ValidateParam(c, &cmd); err != nil {
|
||
return
|
||
}
|
||
|
||
// 再绑定JSON请求体(定时发布时间)
|
||
if err := h.validator.BindAndValidate(c, &cmd); err != nil {
|
||
return
|
||
}
|
||
|
||
if err := h.appService.SchedulePublishAnnouncement(c.Request.Context(), &cmd); err != nil {
|
||
h.logger.Error("设置定时发布失败", zap.String("id", cmd.ID), zap.Error(err))
|
||
h.responseBuilder.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, nil, "设置成功")
|
||
}
|
||
|
||
// UpdateSchedulePublishAnnouncement 更新定时发布公告
|
||
// @Summary 更新定时发布公告
|
||
// @Description 修改公告的定时发布时间
|
||
// @Tags 公告管理-管理端
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security Bearer
|
||
// @Param id path string true "公告ID"
|
||
// @Param request body commands.UpdateSchedulePublishAnnouncementCommand true "更新定时发布请求"
|
||
// @Success 200 {object} map[string]interface{} "更新成功"
|
||
// @Failure 400 {object} map[string]interface{} "请求参数错误"
|
||
// @Failure 401 {object} map[string]interface{} "未认证"
|
||
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
|
||
// @Router /api/v1/admin/announcements/{id}/update-schedule-publish [post]
|
||
func (h *AnnouncementHandler) UpdateSchedulePublishAnnouncement(c *gin.Context) {
|
||
var cmd commands.UpdateSchedulePublishAnnouncementCommand
|
||
|
||
// 先绑定URI参数(公告ID)
|
||
if err := h.validator.ValidateParam(c, &cmd); err != nil {
|
||
return
|
||
}
|
||
|
||
// 再绑定JSON请求体(定时发布时间)
|
||
if err := h.validator.BindAndValidate(c, &cmd); err != nil {
|
||
return
|
||
}
|
||
|
||
if err := h.appService.UpdateSchedulePublishAnnouncement(c.Request.Context(), &cmd); err != nil {
|
||
h.logger.Error("更新定时发布时间失败", zap.String("id", cmd.ID), zap.Error(err))
|
||
h.responseBuilder.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, nil, "更新成功")
|
||
}
|
||
|
||
// CancelSchedulePublishAnnouncement 取消定时发布公告
|
||
// @Summary 取消定时发布公告
|
||
// @Description 取消公告的定时发布
|
||
// @Tags 公告管理-管理端
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security Bearer
|
||
// @Param id path string true "公告ID"
|
||
// @Success 200 {object} map[string]interface{} "取消成功"
|
||
// @Failure 400 {object} map[string]interface{} "请求参数错误"
|
||
// @Failure 401 {object} map[string]interface{} "未认证"
|
||
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
|
||
// @Router /api/v1/admin/announcements/{id}/cancel-schedule [post]
|
||
func (h *AnnouncementHandler) CancelSchedulePublishAnnouncement(c *gin.Context) {
|
||
var cmd commands.CancelSchedulePublishAnnouncementCommand
|
||
if err := h.validator.ValidateParam(c, &cmd); err != nil {
|
||
return
|
||
}
|
||
|
||
if err := h.appService.CancelSchedulePublishAnnouncement(c.Request.Context(), &cmd); err != nil {
|
||
h.logger.Error("取消定时发布失败", zap.Error(err))
|
||
h.responseBuilder.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, nil, "取消成功")
|
||
}
|
||
|
||
// GetAnnouncementStats 获取公告统计信息
|
||
// @Summary 获取公告统计信息
|
||
// @Description 获取公告的统计数据
|
||
// @Tags 公告管理-管理端
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security Bearer
|
||
// @Success 200 {object} responses.AnnouncementStatsResponse "获取统计信息成功"
|
||
// @Failure 401 {object} map[string]interface{} "未认证"
|
||
// @Failure 500 {object} map[string]interface{} "服务器内部错误"
|
||
// @Router /api/v1/admin/announcements/stats [get]
|
||
func (h *AnnouncementHandler) GetAnnouncementStats(c *gin.Context) {
|
||
response, err := h.appService.GetAnnouncementStats(c.Request.Context())
|
||
if err != nil {
|
||
h.logger.Error("获取公告统计信息失败", zap.Error(err))
|
||
h.responseBuilder.InternalError(c, "获取统计信息失败")
|
||
return
|
||
}
|
||
|
||
h.responseBuilder.Success(c, response, "获取统计信息成功")
|
||
}
|