This commit is contained in:
2025-12-06 13:56:00 +08:00
parent 05b6623e75
commit 89367fb2ee
22 changed files with 2186 additions and 74 deletions

View File

@@ -0,0 +1,104 @@
package commands
import (
"fmt"
"time"
)
// CreateAnnouncementCommand 创建公告命令
type CreateAnnouncementCommand struct {
Title string `json:"title" binding:"required" comment:"公告标题"`
Content string `json:"content" binding:"required" comment:"公告内容"`
}
// UpdateAnnouncementCommand 更新公告命令
type UpdateAnnouncementCommand struct {
ID string `json:"-" uri:"id" binding:"required" comment:"公告ID"`
Title string `json:"title" comment:"公告标题"`
Content string `json:"content" comment:"公告内容"`
}
// DeleteAnnouncementCommand 删除公告命令
type DeleteAnnouncementCommand struct {
ID string `json:"-" uri:"id" binding:"required" comment:"公告ID"`
}
// PublishAnnouncementCommand 发布公告命令
type PublishAnnouncementCommand struct {
ID string `json:"-" uri:"id" binding:"required" comment:"公告ID"`
}
// WithdrawAnnouncementCommand 撤回公告命令
type WithdrawAnnouncementCommand struct {
ID string `json:"-" uri:"id" binding:"required" comment:"公告ID"`
}
// ArchiveAnnouncementCommand 归档公告命令
type ArchiveAnnouncementCommand struct {
ID string `json:"-" uri:"id" binding:"required" comment:"公告ID"`
}
// SchedulePublishAnnouncementCommand 定时发布公告命令
type SchedulePublishAnnouncementCommand struct {
ID string `json:"-" uri:"id" binding:"required" comment:"公告ID"`
ScheduledTime string `json:"scheduled_time" binding:"required" comment:"定时发布时间"`
}
// GetScheduledTime 获取解析后的定时发布时间
func (cmd *SchedulePublishAnnouncementCommand) GetScheduledTime() (time.Time, error) {
// 定义中国东八区时区
cst := time.FixedZone("CST", 8*3600)
// 支持多种时间格式
formats := []string{
"2006-01-02 15:04:05", // "2025-09-02 14:12:01"
"2006-01-02T15:04:05", // "2025-09-02T14:12:01"
"2006-01-02T15:04:05Z", // "2025-09-02T14:12:01Z"
"2006-01-02 15:04", // "2025-09-02 14:12"
time.RFC3339, // "2025-09-02T14:12:01+08:00"
}
for _, format := range formats {
if t, err := time.ParseInLocation(format, cmd.ScheduledTime, cst); err == nil {
// 确保返回的时间是东八区时区
return t.In(cst), nil
}
}
return time.Time{}, fmt.Errorf("不支持的时间格式: %s请使用 YYYY-MM-DD HH:mm:ss 格式", cmd.ScheduledTime)
}
// UpdateSchedulePublishAnnouncementCommand 更新定时发布公告命令
type UpdateSchedulePublishAnnouncementCommand struct {
ID string `json:"-" uri:"id" binding:"required" comment:"公告ID"`
ScheduledTime string `json:"scheduled_time" binding:"required" comment:"定时发布时间"`
}
// GetScheduledTime 获取解析后的定时发布时间
func (cmd *UpdateSchedulePublishAnnouncementCommand) GetScheduledTime() (time.Time, error) {
// 定义中国东八区时区
cst := time.FixedZone("CST", 8*3600)
// 支持多种时间格式
formats := []string{
"2006-01-02 15:04:05", // "2025-09-02 14:12:01"
"2006-01-02T15:04:05", // "2025-09-02T14:12:01"
"2006-01-02T15:04:05Z", // "2025-09-02T14:12:01Z"
"2006-01-02 15:04", // "2025-09-02 14:12"
time.RFC3339, // "2025-09-02T14:12:01+08:00"
}
for _, format := range formats {
if t, err := time.ParseInLocation(format, cmd.ScheduledTime, cst); err == nil {
// 确保返回的时间是东八区时区
return t.In(cst), nil
}
}
return time.Time{}, fmt.Errorf("不支持的时间格式: %s请使用 YYYY-MM-DD HH:mm:ss 格式", cmd.ScheduledTime)
}
// CancelSchedulePublishAnnouncementCommand 取消定时发布公告命令
type CancelSchedulePublishAnnouncementCommand struct {
ID string `json:"-" uri:"id" binding:"required" comment:"公告ID"`
}

View File

@@ -0,0 +1,18 @@
package queries
import "tyapi-server/internal/domains/article/entities"
// ListAnnouncementQuery 公告列表查询
type ListAnnouncementQuery struct {
Page int `form:"page" binding:"min=1" comment:"页码"`
PageSize int `form:"page_size" binding:"min=1,max=100" comment:"每页数量"`
Status entities.AnnouncementStatus `form:"status" comment:"公告状态"`
Title string `form:"title" comment:"标题关键词"`
OrderBy string `form:"order_by" comment:"排序字段"`
OrderDir string `form:"order_dir" comment:"排序方向"`
}
// GetAnnouncementQuery 获取公告详情查询
type GetAnnouncementQuery struct {
ID string `uri:"id" binding:"required" comment:"公告ID"`
}

View File

@@ -0,0 +1,79 @@
package responses
import (
"time"
"tyapi-server/internal/domains/article/entities"
)
// AnnouncementInfoResponse 公告详情响应
type AnnouncementInfoResponse struct {
ID string `json:"id" comment:"公告ID"`
Title string `json:"title" comment:"公告标题"`
Content string `json:"content" comment:"公告内容"`
Status string `json:"status" comment:"公告状态"`
ScheduledAt *time.Time `json:"scheduled_at" comment:"定时发布时间"`
CreatedAt time.Time `json:"created_at" comment:"创建时间"`
UpdatedAt time.Time `json:"updated_at" comment:"更新时间"`
}
// AnnouncementListItemResponse 公告列表项响应
type AnnouncementListItemResponse struct {
ID string `json:"id" comment:"公告ID"`
Title string `json:"title" comment:"公告标题"`
Content string `json:"content" comment:"公告内容"`
Status string `json:"status" comment:"公告状态"`
ScheduledAt *time.Time `json:"scheduled_at" comment:"定时发布时间"`
CreatedAt time.Time `json:"created_at" comment:"创建时间"`
UpdatedAt time.Time `json:"updated_at" comment:"更新时间"`
}
// AnnouncementListResponse 公告列表响应
type AnnouncementListResponse struct {
Total int64 `json:"total" comment:"总数"`
Page int `json:"page" comment:"页码"`
Size int `json:"size" comment:"每页数量"`
Items []AnnouncementListItemResponse `json:"items" comment:"公告列表"`
}
// AnnouncementStatsResponse 公告统计响应
type AnnouncementStatsResponse struct {
TotalAnnouncements int64 `json:"total_announcements" comment:"公告总数"`
PublishedAnnouncements int64 `json:"published_announcements" comment:"已发布公告数"`
DraftAnnouncements int64 `json:"draft_announcements" comment:"草稿公告数"`
ArchivedAnnouncements int64 `json:"archived_announcements" comment:"归档公告数"`
ScheduledAnnouncements int64 `json:"scheduled_announcements" comment:"定时发布公告数"`
}
// FromAnnouncementEntity 从公告实体转换为响应对象
func FromAnnouncementEntity(announcement *entities.Announcement) *AnnouncementInfoResponse {
if announcement == nil {
return nil
}
return &AnnouncementInfoResponse{
ID: announcement.ID,
Title: announcement.Title,
Content: announcement.Content,
Status: string(announcement.Status),
ScheduledAt: announcement.ScheduledAt,
CreatedAt: announcement.CreatedAt,
UpdatedAt: announcement.UpdatedAt,
}
}
// FromAnnouncementEntityList 从公告实体列表转换为列表项响应
func FromAnnouncementEntityList(announcements []*entities.Announcement) []AnnouncementListItemResponse {
items := make([]AnnouncementListItemResponse, 0, len(announcements))
for _, announcement := range announcements {
items = append(items, AnnouncementListItemResponse{
ID: announcement.ID,
Title: announcement.Title,
Content: announcement.Content,
Status: string(announcement.Status),
ScheduledAt: announcement.ScheduledAt,
CreatedAt: announcement.CreatedAt,
UpdatedAt: announcement.UpdatedAt,
})
}
return items
}