refactor(server): decouple services and improve architecture
- Introduce interfaces for all major services (JWT, PostAI, Comment, Message, Notification, QRCodeLogin, Upload, Vote, etc.) to support dependency inversion. - Move query parameters from `internal/dto` to a new `internal/query` package to separate request payloads from data transfer objects. - Refactor `internal/router` to use embedded `RouterDeps` for cleaner dependency management. - Decouple handlers from repositories by injecting services instead of direct repository access, ensuring proper layering. - Improve database initialization by moving it from `internal/model` to `internal/database`. - Optimize message decryption by implementing a more efficient `BatchDecrypt` method in `MessageEncryptor` using a worker pool. - Enhance error handling and security by implementing fail-fast checks for encryption key length during startup. - Clean up unused code, including the `avatar` package and several unused DTOs.
This commit is contained in:
@@ -131,52 +131,6 @@ type AdminUpdateUserStatusRequest struct {
|
||||
Status string `json:"status" binding:"required,oneof=active banned"`
|
||||
}
|
||||
|
||||
// ==================== Post DTOs ====================
|
||||
|
||||
// PostChannelBrief 帖子所属频道(列表/详情卡片展示)
|
||||
type PostChannelBrief struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// PostImageResponse 帖子图片响应
|
||||
type PostImageResponse struct {
|
||||
ID string `json:"id"`
|
||||
URL string `json:"url"`
|
||||
ThumbnailURL string `json:"thumbnail_url"`
|
||||
PreviewURL string `json:"preview_url"` // 列表/网格预览图
|
||||
PreviewURLLarge string `json:"preview_url_large"` // 详情页预览图
|
||||
Width int `json:"width"`
|
||||
Height int `json:"height"`
|
||||
}
|
||||
|
||||
// PostResponse 帖子响应(列表用)
|
||||
type PostResponse struct {
|
||||
ID string `json:"id"`
|
||||
UserID string `json:"user_id"`
|
||||
ChannelID *string `json:"channel_id,omitempty"`
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"`
|
||||
Segments model.MessageSegments `json:"segments,omitempty"`
|
||||
Images []PostImageResponse `json:"images"`
|
||||
Status string `json:"status,omitempty"`
|
||||
LikesCount int `json:"likes_count"`
|
||||
CommentsCount int `json:"comments_count"`
|
||||
FavoritesCount int `json:"favorites_count"`
|
||||
SharesCount int `json:"shares_count"`
|
||||
ViewsCount int `json:"views_count"`
|
||||
IsPinned bool `json:"is_pinned"`
|
||||
IsLocked bool `json:"is_locked"`
|
||||
IsVote bool `json:"is_vote"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
ContentEditedAt string `json:"content_edited_at,omitempty"`
|
||||
Author *UserResponse `json:"author"`
|
||||
IsLiked bool `json:"is_liked"`
|
||||
IsFavorited bool `json:"is_favorited"`
|
||||
Channel *PostChannelBrief `json:"channel,omitempty"`
|
||||
}
|
||||
|
||||
// ==================== Comment DTOs ====================
|
||||
|
||||
// CommentImageResponse 评论图片响应
|
||||
@@ -224,16 +178,16 @@ type NotificationResponse struct {
|
||||
type SegmentType string
|
||||
|
||||
const (
|
||||
SegmentTypeText SegmentType = "text"
|
||||
SegmentTypeImage SegmentType = "image"
|
||||
SegmentTypeVoice SegmentType = "voice"
|
||||
SegmentTypeVideo SegmentType = "video"
|
||||
SegmentTypeFile SegmentType = "file"
|
||||
SegmentTypeAt SegmentType = "at"
|
||||
SegmentTypeReply SegmentType = "reply"
|
||||
SegmentTypeFace SegmentType = "face"
|
||||
SegmentTypeLink SegmentType = "link"
|
||||
SegmentTypeVote SegmentType = "vote"
|
||||
SegmentTypeText SegmentType = "text"
|
||||
SegmentTypeImage SegmentType = "image"
|
||||
SegmentTypeVoice SegmentType = "voice"
|
||||
SegmentTypeVideo SegmentType = "video"
|
||||
SegmentTypeFile SegmentType = "file"
|
||||
SegmentTypeAt SegmentType = "at"
|
||||
SegmentTypeReply SegmentType = "reply"
|
||||
SegmentTypeFace SegmentType = "face"
|
||||
SegmentTypeLink SegmentType = "link"
|
||||
SegmentTypeVote SegmentType = "vote"
|
||||
SegmentTypePostRef SegmentType = "post_ref"
|
||||
)
|
||||
|
||||
@@ -428,8 +382,8 @@ type CreateConversationRequest struct {
|
||||
// SendMessageRequest 发送消息请求
|
||||
type SendMessageRequest struct {
|
||||
Segments model.MessageSegments `json:"segments" binding:"required"` // 消息链(必须)
|
||||
ReplyToID *string `json:"reply_to_id,omitempty"` // 回复的消息ID (string类型)
|
||||
ClientMsgID string `json:"client_msg_id,omitempty"` // 客户端消息ID(幂等性去重)
|
||||
ReplyToID *string `json:"reply_to_id,omitempty"` // 回复的消息ID (string类型)
|
||||
ClientMsgID string `json:"client_msg_id,omitempty"` // 客户端消息ID(幂等性去重)
|
||||
}
|
||||
|
||||
// MarkReadRequest 标记已读请求
|
||||
@@ -619,122 +573,6 @@ func FormatTimePointer(t *time.Time) string {
|
||||
return FormatTime(*t)
|
||||
}
|
||||
|
||||
// ==================== Group DTOs ====================
|
||||
|
||||
// CreateGroupRequest 创建群组请求
|
||||
type CreateGroupRequest struct {
|
||||
Name string `json:"name" binding:"required,max=50"`
|
||||
Description string `json:"description" binding:"max=500"`
|
||||
MemberIDs []string `json:"member_ids"`
|
||||
}
|
||||
|
||||
// UpdateGroupRequest 更新群组请求
|
||||
type UpdateGroupRequest struct {
|
||||
Name string `json:"name" binding:"omitempty,max=50"`
|
||||
Description string `json:"description" binding:"omitempty,max=500"`
|
||||
Avatar string `json:"avatar" binding:"omitempty,url"`
|
||||
}
|
||||
|
||||
// InviteMembersRequest 邀请成员请求
|
||||
type InviteMembersRequest struct {
|
||||
MemberIDs []string `json:"member_ids" binding:"required,min=1"`
|
||||
}
|
||||
|
||||
// TransferOwnerRequest 转让群主请求
|
||||
type TransferOwnerRequest struct {
|
||||
NewOwnerID string `json:"new_owner_id" binding:"required"`
|
||||
}
|
||||
|
||||
// SetRoleRequest 设置角色请求
|
||||
type SetRoleRequest struct {
|
||||
Role string `json:"role" binding:"required,oneof=admin member"`
|
||||
}
|
||||
|
||||
// SetNicknameRequest 设置昵称请求
|
||||
type SetNicknameRequest struct {
|
||||
Nickname string `json:"nickname" binding:"max=50"`
|
||||
}
|
||||
|
||||
// MuteMemberRequest 禁言成员请求
|
||||
type MuteMemberRequest struct {
|
||||
Muted bool `json:"muted"`
|
||||
}
|
||||
|
||||
// SetMuteAllRequest 设置全员禁言请求
|
||||
type SetMuteAllRequest struct {
|
||||
MuteAll bool `json:"mute_all"`
|
||||
}
|
||||
|
||||
// SetJoinTypeRequest 设置加群方式请求
|
||||
type SetJoinTypeRequest struct {
|
||||
JoinType int `json:"join_type" binding:"min=0,max=2"`
|
||||
}
|
||||
|
||||
// CreateAnnouncementRequest 创建群公告请求
|
||||
type CreateAnnouncementRequest struct {
|
||||
Content string `json:"content" binding:"required,max=2000"`
|
||||
}
|
||||
|
||||
// GroupResponse 群组响应
|
||||
type GroupResponse struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Avatar string `json:"avatar"`
|
||||
Description string `json:"description"`
|
||||
OwnerID string `json:"owner_id"`
|
||||
MemberCount int `json:"member_count"`
|
||||
MaxMembers int `json:"max_members"`
|
||||
JoinType int `json:"join_type"`
|
||||
MuteAll bool `json:"mute_all"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
}
|
||||
|
||||
// GroupMemberResponse 群成员响应
|
||||
type GroupMemberResponse struct {
|
||||
ID string `json:"id"`
|
||||
GroupID string `json:"group_id"`
|
||||
UserID string `json:"user_id"`
|
||||
Role string `json:"role"`
|
||||
Nickname string `json:"nickname"`
|
||||
Muted bool `json:"muted"`
|
||||
JoinTime string `json:"join_time"`
|
||||
User *UserResponse `json:"user,omitempty"`
|
||||
}
|
||||
|
||||
// GroupAnnouncementResponse 群公告响应
|
||||
type GroupAnnouncementResponse struct {
|
||||
ID string `json:"id"`
|
||||
GroupID string `json:"group_id"`
|
||||
Content string `json:"content"`
|
||||
AuthorID string `json:"author_id"`
|
||||
IsPinned bool `json:"is_pinned"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
}
|
||||
|
||||
// GroupListResponse 群组列表响应
|
||||
type GroupListResponse struct {
|
||||
List []*GroupResponse `json:"list"`
|
||||
Total int64 `json:"total"`
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"page_size"`
|
||||
}
|
||||
|
||||
// GroupMemberListResponse 群成员列表响应
|
||||
type GroupMemberListResponse struct {
|
||||
List []*GroupMemberResponse `json:"list"`
|
||||
Total int64 `json:"total"`
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"page_size"`
|
||||
}
|
||||
|
||||
// GroupAnnouncementListResponse 群公告列表响应
|
||||
type GroupAnnouncementListResponse struct {
|
||||
List []*GroupAnnouncementResponse `json:"list"`
|
||||
Total int64 `json:"total"`
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"page_size"`
|
||||
}
|
||||
|
||||
// ==================== WebSocket Event DTOs ====================
|
||||
|
||||
// WSEventResponse WebSocket事件响应结构体
|
||||
@@ -745,7 +583,7 @@ type WSEventResponse struct {
|
||||
Type string `json:"type"` // 事件类型 (message, notification, system等)
|
||||
DetailType string `json:"detail_type"` // 详细类型 (private, group, like, comment等)
|
||||
ConversationID string `json:"conversation_id"` // 会话ID
|
||||
Seq int64 `json:"seq"` // 消息序列号
|
||||
Seq int64 `json:"seq"` // 消息序列号
|
||||
Segments model.MessageSegments `json:"segments"` // 消息段数组
|
||||
SenderID string `json:"sender_id"` // 发送者用户ID
|
||||
}
|
||||
@@ -754,11 +592,11 @@ type WSEventResponse struct {
|
||||
|
||||
// SendMessageParams 发送消息参数(用于 REST API)
|
||||
type SendMessageParams struct {
|
||||
DetailType string `json:"detail_type"` // 消息类型: private, group
|
||||
ConversationID string `json:"conversation_id"` // 会话ID
|
||||
Segments model.MessageSegments `json:"segments"` // 消息内容(消息段数组)
|
||||
ReplyToID *string `json:"reply_to_id,omitempty"` // 回复的消息ID
|
||||
ClientMsgID string `json:"client_msg_id,omitempty"` // 客户端消息ID(幂等性去重)
|
||||
DetailType string `json:"detail_type"` // 消息类型: private, group
|
||||
ConversationID string `json:"conversation_id"` // 会话ID
|
||||
Segments model.MessageSegments `json:"segments"` // 消息内容(消息段数组)
|
||||
ReplyToID *string `json:"reply_to_id,omitempty"` // 回复的消息ID
|
||||
ClientMsgID string `json:"client_msg_id,omitempty"` // 客户端消息ID(幂等性去重)
|
||||
}
|
||||
|
||||
// DeleteMsgParams 撤回消息参数
|
||||
@@ -809,7 +647,7 @@ type SetGroupAvatarParams struct {
|
||||
|
||||
// SetGroupDescriptionParams 设置群描述参数
|
||||
type SetGroupDescriptionParams struct {
|
||||
GroupID string `json:"group_id"` // 群组ID
|
||||
GroupID string `json:"group_id"` // 群组ID
|
||||
Description string `json:"description"` // 群描述
|
||||
}
|
||||
|
||||
@@ -935,41 +773,6 @@ type GetMyMemberInfoParams struct {
|
||||
GroupID string `json:"group_id"` // 群组ID
|
||||
}
|
||||
|
||||
// ==================== Vote DTOs ====================
|
||||
|
||||
// CreateVotePostRequest 创建投票帖子请求
|
||||
type CreateVotePostRequest struct {
|
||||
Title string `json:"title" binding:"required,max=200"`
|
||||
Content string `json:"content" binding:"max=2000"`
|
||||
ChannelID *string `json:"channel_id,omitempty"`
|
||||
Images []string `json:"images"`
|
||||
VoteOptions []string `json:"vote_options" binding:"required,min=2,max=10"`
|
||||
}
|
||||
|
||||
// CreatePostWithSegmentsRequest 创建帖子请求(含 segments)
|
||||
type CreatePostWithSegmentsRequest struct {
|
||||
Title string `json:"title" binding:"required,max=200"`
|
||||
Content string `json:"content"`
|
||||
Segments model.MessageSegments `json:"segments"`
|
||||
Images []string `json:"images"`
|
||||
ChannelID *string `json:"channel_id,omitempty"`
|
||||
}
|
||||
|
||||
// VoteOptionDTO 投票选项DTO
|
||||
type VoteOptionDTO struct {
|
||||
ID string `json:"id"`
|
||||
Content string `json:"content"`
|
||||
VotesCount int `json:"votes_count"`
|
||||
}
|
||||
|
||||
// VoteResultDTO 投票结果DTO
|
||||
type VoteResultDTO struct {
|
||||
Options []VoteOptionDTO `json:"options"`
|
||||
TotalVotes int `json:"total_votes"`
|
||||
HasVoted bool `json:"has_voted"`
|
||||
VotedOptionID string `json:"voted_option_id,omitzero"`
|
||||
}
|
||||
|
||||
// ==================== WebSocket Response DTOs ====================
|
||||
|
||||
// WSResponse WebSocket响应结构体
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
package dto
|
||||
|
||||
import "time"
|
||||
|
||||
// LogFilter 日志过滤条件
|
||||
type LogFilter struct {
|
||||
UserID string
|
||||
Operation string
|
||||
TargetType string
|
||||
TargetID string
|
||||
Status string
|
||||
IP string
|
||||
StartTime string
|
||||
EndTime string
|
||||
}
|
||||
|
||||
// LoginFilter 登录日志过滤条件
|
||||
type LoginFilter struct {
|
||||
UserID string
|
||||
Event string
|
||||
Result string
|
||||
FailReason string
|
||||
LoginType string
|
||||
IP string
|
||||
StartTime time.Time
|
||||
EndTime time.Time
|
||||
}
|
||||
|
||||
// DataChangeFilter 数据变更日志过滤条件
|
||||
type DataChangeFilter struct {
|
||||
UserID string
|
||||
OperatorID string
|
||||
ChangeType string
|
||||
TargetType string
|
||||
OperatorType string
|
||||
IP string
|
||||
StartTime string
|
||||
EndTime string
|
||||
}
|
||||
|
||||
// MaterialFileQueryParams 学习资料查询参数
|
||||
type MaterialFileQueryParams struct {
|
||||
SubjectID string
|
||||
FileType string
|
||||
Status string
|
||||
Keyword string
|
||||
Page int
|
||||
PageSize int
|
||||
SortBy string
|
||||
SortOrder string
|
||||
}
|
||||
119
internal/dto/group_dto.go
Normal file
119
internal/dto/group_dto.go
Normal file
@@ -0,0 +1,119 @@
|
||||
package dto
|
||||
|
||||
// ==================== Group DTOs ====================
|
||||
// 从 dto.go 拆分而来:群组相关的请求与响应 DTO。
|
||||
// 与 group_converter.go 同属群组域。
|
||||
|
||||
// CreateGroupRequest 创建群组请求
|
||||
type CreateGroupRequest struct {
|
||||
Name string `json:"name" binding:"required,max=50"`
|
||||
Description string `json:"description" binding:"max=500"`
|
||||
MemberIDs []string `json:"member_ids"`
|
||||
}
|
||||
|
||||
// UpdateGroupRequest 更新群组请求
|
||||
type UpdateGroupRequest struct {
|
||||
Name string `json:"name" binding:"omitempty,max=50"`
|
||||
Description string `json:"description" binding:"omitempty,max=500"`
|
||||
Avatar string `json:"avatar" binding:"omitempty,url"`
|
||||
}
|
||||
|
||||
// InviteMembersRequest 邀请成员请求
|
||||
type InviteMembersRequest struct {
|
||||
MemberIDs []string `json:"member_ids" binding:"required,min=1"`
|
||||
}
|
||||
|
||||
// TransferOwnerRequest 转让群主请求
|
||||
type TransferOwnerRequest struct {
|
||||
NewOwnerID string `json:"new_owner_id" binding:"required"`
|
||||
}
|
||||
|
||||
// SetRoleRequest 设置角色请求
|
||||
type SetRoleRequest struct {
|
||||
Role string `json:"role" binding:"required,oneof=admin member"`
|
||||
}
|
||||
|
||||
// SetNicknameRequest 设置昵称请求
|
||||
type SetNicknameRequest struct {
|
||||
Nickname string `json:"nickname" binding:"max=50"`
|
||||
}
|
||||
|
||||
// MuteMemberRequest 禁言成员请求
|
||||
type MuteMemberRequest struct {
|
||||
Muted bool `json:"muted"`
|
||||
}
|
||||
|
||||
// SetMuteAllRequest 设置全员禁言请求
|
||||
type SetMuteAllRequest struct {
|
||||
MuteAll bool `json:"mute_all"`
|
||||
}
|
||||
|
||||
// SetJoinTypeRequest 设置加群方式请求
|
||||
type SetJoinTypeRequest struct {
|
||||
JoinType int `json:"join_type" binding:"min=0,max=2"`
|
||||
}
|
||||
|
||||
// CreateAnnouncementRequest 创建群公告请求
|
||||
type CreateAnnouncementRequest struct {
|
||||
Content string `json:"content" binding:"required,max=2000"`
|
||||
}
|
||||
|
||||
// GroupResponse 群组响应
|
||||
type GroupResponse struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Avatar string `json:"avatar"`
|
||||
Description string `json:"description"`
|
||||
OwnerID string `json:"owner_id"`
|
||||
MemberCount int `json:"member_count"`
|
||||
MaxMembers int `json:"max_members"`
|
||||
JoinType int `json:"join_type"`
|
||||
MuteAll bool `json:"mute_all"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
}
|
||||
|
||||
// GroupMemberResponse 群成员响应
|
||||
type GroupMemberResponse struct {
|
||||
ID string `json:"id"`
|
||||
GroupID string `json:"group_id"`
|
||||
UserID string `json:"user_id"`
|
||||
Role string `json:"role"`
|
||||
Nickname string `json:"nickname"`
|
||||
Muted bool `json:"muted"`
|
||||
JoinTime string `json:"join_time"`
|
||||
User *UserResponse `json:"user,omitempty"`
|
||||
}
|
||||
|
||||
// GroupAnnouncementResponse 群公告响应
|
||||
type GroupAnnouncementResponse struct {
|
||||
ID string `json:"id"`
|
||||
GroupID string `json:"group_id"`
|
||||
Content string `json:"content"`
|
||||
AuthorID string `json:"author_id"`
|
||||
IsPinned bool `json:"is_pinned"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
}
|
||||
|
||||
// GroupListResponse 群组列表响应
|
||||
type GroupListResponse struct {
|
||||
List []*GroupResponse `json:"list"`
|
||||
Total int64 `json:"total"`
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"page_size"`
|
||||
}
|
||||
|
||||
// GroupMemberListResponse 群成员列表响应
|
||||
type GroupMemberListResponse struct {
|
||||
List []*GroupMemberResponse `json:"list"`
|
||||
Total int64 `json:"total"`
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"page_size"`
|
||||
}
|
||||
|
||||
// GroupAnnouncementListResponse 群公告列表响应
|
||||
type GroupAnnouncementListResponse struct {
|
||||
List []*GroupAnnouncementResponse `json:"list"`
|
||||
Total int64 `json:"total"`
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"page_size"`
|
||||
}
|
||||
86
internal/dto/post_dto.go
Normal file
86
internal/dto/post_dto.go
Normal file
@@ -0,0 +1,86 @@
|
||||
package dto
|
||||
|
||||
import "with_you/internal/model"
|
||||
|
||||
// ==================== Post DTOs ====================
|
||||
// 从 dto.go 拆分而来:帖子与投票相关的请求/响应 DTO。
|
||||
// 与 post_converter.go 同属帖子域。
|
||||
|
||||
// PostChannelBrief 帖子所属频道(列表/详情卡片展示)
|
||||
type PostChannelBrief struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// PostImageResponse 帖子图片响应
|
||||
type PostImageResponse struct {
|
||||
ID string `json:"id"`
|
||||
URL string `json:"url"`
|
||||
ThumbnailURL string `json:"thumbnail_url"`
|
||||
PreviewURL string `json:"preview_url"` // 列表/网格预览图
|
||||
PreviewURLLarge string `json:"preview_url_large"` // 详情页预览图
|
||||
Width int `json:"width"`
|
||||
Height int `json:"height"`
|
||||
}
|
||||
|
||||
// PostResponse 帖子响应(列表用)
|
||||
type PostResponse struct {
|
||||
ID string `json:"id"`
|
||||
UserID string `json:"user_id"`
|
||||
ChannelID *string `json:"channel_id,omitempty"`
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"`
|
||||
Segments model.MessageSegments `json:"segments,omitempty"`
|
||||
Images []PostImageResponse `json:"images"`
|
||||
Status string `json:"status,omitempty"`
|
||||
LikesCount int `json:"likes_count"`
|
||||
CommentsCount int `json:"comments_count"`
|
||||
FavoritesCount int `json:"favorites_count"`
|
||||
SharesCount int `json:"shares_count"`
|
||||
ViewsCount int `json:"views_count"`
|
||||
IsPinned bool `json:"is_pinned"`
|
||||
IsLocked bool `json:"is_locked"`
|
||||
IsVote bool `json:"is_vote"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
ContentEditedAt string `json:"content_edited_at,omitempty"`
|
||||
Author *UserResponse `json:"author"`
|
||||
IsLiked bool `json:"is_liked"`
|
||||
IsFavorited bool `json:"is_favorited"`
|
||||
Channel *PostChannelBrief `json:"channel,omitempty"`
|
||||
}
|
||||
|
||||
// ==================== Vote DTOs ====================
|
||||
|
||||
// CreateVotePostRequest 创建投票帖子请求
|
||||
type CreateVotePostRequest struct {
|
||||
Title string `json:"title" binding:"required,max=200"`
|
||||
Content string `json:"content" binding:"max=2000"`
|
||||
ChannelID *string `json:"channel_id,omitempty"`
|
||||
Images []string `json:"images"`
|
||||
VoteOptions []string `json:"vote_options" binding:"required,min=2,max=10"`
|
||||
}
|
||||
|
||||
// CreatePostWithSegmentsRequest 创建帖子请求(含 segments)
|
||||
type CreatePostWithSegmentsRequest struct {
|
||||
Title string `json:"title" binding:"required,max=200"`
|
||||
Content string `json:"content"`
|
||||
Segments model.MessageSegments `json:"segments"`
|
||||
Images []string `json:"images"`
|
||||
ChannelID *string `json:"channel_id,omitempty"`
|
||||
}
|
||||
|
||||
// VoteOptionDTO 投票选项DTO
|
||||
type VoteOptionDTO struct {
|
||||
ID string `json:"id"`
|
||||
Content string `json:"content"`
|
||||
VotesCount int `json:"votes_count"`
|
||||
}
|
||||
|
||||
// VoteResultDTO 投票结果DTO
|
||||
type VoteResultDTO struct {
|
||||
Options []VoteOptionDTO `json:"options"`
|
||||
TotalVotes int `json:"total_votes"`
|
||||
HasVoted bool `json:"has_voted"`
|
||||
VotedOptionID string `json:"voted_option_id,omitzero"`
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package dto
|
||||
package dto
|
||||
|
||||
import (
|
||||
"with_you/internal/model"
|
||||
@@ -8,10 +8,10 @@ import (
|
||||
|
||||
// CreateReportRequest 创建举报请求
|
||||
type CreateReportRequest struct {
|
||||
TargetType string `json:"target_type" binding:"required,oneof=post comment message"`
|
||||
TargetID string `json:"target_id" binding:"required"`
|
||||
Reason string `json:"reason" binding:"required,oneof=spam inappropriate harassment misinformation other"`
|
||||
Description string `json:"description" binding:"max=500"`
|
||||
TargetType string `json:"target_type" binding:"required,oneof=post comment message"`
|
||||
TargetID string `json:"target_id" binding:"required"`
|
||||
Reason string `json:"reason" binding:"required,oneof=spam inappropriate harassment misinformation other"`
|
||||
Description string `json:"description" binding:"max=500"`
|
||||
}
|
||||
|
||||
// ReportResponse 举报响应
|
||||
@@ -26,89 +26,77 @@ type ReportResponse struct {
|
||||
CreatedAt string `json:"created_at"`
|
||||
}
|
||||
|
||||
// AdminReportListQuery 管理端举报列表查询参数
|
||||
type AdminReportListQuery struct {
|
||||
Page int `form:"page" binding:"min=1"`
|
||||
PageSize int `form:"page_size" binding:"min=1,max=100"`
|
||||
TargetType string `form:"target_type" binding:"omitempty,oneof=post comment message"`
|
||||
Status string `form:"status" binding:"omitempty,oneof=pending processing resolved rejected"`
|
||||
StartDate string `form:"start_date" binding:"omitempty"`
|
||||
EndDate string `form:"end_date" binding:"omitempty"`
|
||||
Keyword string `form:"keyword" binding:"omitempty"`
|
||||
}
|
||||
|
||||
// AdminReportListResponse 管理端举报列表响应
|
||||
type AdminReportListResponse struct {
|
||||
ID string `json:"id"`
|
||||
ReporterID string `json:"reporter_id"`
|
||||
ID string `json:"id"`
|
||||
ReporterID string `json:"reporter_id"`
|
||||
Reporter *UserResponse `json:"reporter,omitempty"`
|
||||
TargetType string `json:"target_type"`
|
||||
TargetID string `json:"target_id"`
|
||||
Reason string `json:"reason"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Status string `json:"status"`
|
||||
HandledBy *string `json:"handled_by,omitempty"`
|
||||
TargetType string `json:"target_type"`
|
||||
TargetID string `json:"target_id"`
|
||||
Reason string `json:"reason"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Status string `json:"status"`
|
||||
HandledBy *string `json:"handled_by,omitempty"`
|
||||
Handler *UserResponse `json:"handler,omitempty"`
|
||||
HandledAt *string `json:"handled_at,omitempty"`
|
||||
Result *string `json:"result,omitempty"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
HandledAt *string `json:"handled_at,omitempty"`
|
||||
Result *string `json:"result,omitempty"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
}
|
||||
|
||||
// AdminReportDetailResponse 管理端举报详情响应
|
||||
type AdminReportDetailResponse struct {
|
||||
ID string `json:"id"`
|
||||
ReporterID string `json:"reporter_id"`
|
||||
ID string `json:"id"`
|
||||
ReporterID string `json:"reporter_id"`
|
||||
Reporter *UserResponse `json:"reporter"`
|
||||
TargetType string `json:"target_type"`
|
||||
TargetID string `json:"target_id"`
|
||||
Reason string `json:"reason"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Status string `json:"status"`
|
||||
HandledBy *string `json:"handled_by,omitempty"`
|
||||
TargetType string `json:"target_type"`
|
||||
TargetID string `json:"target_id"`
|
||||
Reason string `json:"reason"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Status string `json:"status"`
|
||||
HandledBy *string `json:"handled_by,omitempty"`
|
||||
Handler *UserResponse `json:"handler,omitempty"`
|
||||
HandledAt *string `json:"handled_at,omitempty"`
|
||||
Result *string `json:"result,omitempty"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
|
||||
HandledAt *string `json:"handled_at,omitempty"`
|
||||
Result *string `json:"result,omitempty"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
|
||||
// 被举报内容详情
|
||||
TargetContent *ReportTargetContent `json:"target_content,omitempty"`
|
||||
}
|
||||
|
||||
// ReportTargetContent 被举报内容详情
|
||||
type ReportTargetContent struct {
|
||||
Type string `json:"type"` // post, comment, message
|
||||
ID string `json:"id"`
|
||||
Author *UserResponse `json:"author,omitempty"`
|
||||
Content string `json:"content,omitempty"`
|
||||
Title string `json:"title,omitempty"` // 帖子标题
|
||||
Images []string `json:"images,omitempty"` // 图片列表
|
||||
Status string `json:"status,omitempty"` // 内容状态
|
||||
CreatedAt string `json:"created_at,omitempty"`
|
||||
Type string `json:"type"` // post, comment, message
|
||||
ID string `json:"id"`
|
||||
Author *UserResponse `json:"author,omitempty"`
|
||||
Content string `json:"content,omitempty"`
|
||||
Title string `json:"title,omitempty"` // 帖子标题
|
||||
Images []string `json:"images,omitempty"` // 图片列表
|
||||
Status string `json:"status,omitempty"` // 内容状态
|
||||
CreatedAt string `json:"created_at,omitempty"`
|
||||
}
|
||||
|
||||
// HandleReportRequest 处理举报请求
|
||||
type HandleReportRequest struct {
|
||||
Action string `json:"action" binding:"required,oneof=approve reject"` // approve: 确认违规, reject: 驳回
|
||||
Result string `json:"result" binding:"max=500"` // 处理结果说明
|
||||
Result string `json:"result" binding:"max=500"` // 处理结果说明
|
||||
}
|
||||
|
||||
// BatchHandleReportRequest 批量处理举报请求
|
||||
type BatchHandleReportRequest struct {
|
||||
IDs []string `json:"ids" binding:"required,min=1,max=100"`
|
||||
Action string `json:"action" binding:"required,oneof=approve reject"`
|
||||
Result string `json:"result" binding:"max=500"`
|
||||
Result string `json:"result" binding:"max=500"`
|
||||
}
|
||||
|
||||
// AdminBatchHandleResponse 批量处理响应
|
||||
type AdminBatchHandleResponse struct {
|
||||
SuccessCount int `json:"success_count"`
|
||||
FailedCount int `json:"failed_count"`
|
||||
FailedIDs []string `json:"failed_ids,omitempty"`
|
||||
FailedCount int `json:"failed_count"`
|
||||
FailedIDs []string `json:"failed_ids,omitempty"`
|
||||
}
|
||||
|
||||
// ==================== 转换函数 ====================
|
||||
|
||||
|
||||
// ConvertReportToResponse 将 Report 模型转换为响应
|
||||
func ConvertReportToResponse(report *model.Report) *ReportResponse {
|
||||
return &ReportResponse{
|
||||
@@ -180,4 +168,4 @@ func ConvertReportToAdminDetailResponse(report *model.Report, reporter *model.Us
|
||||
resp.HandledAt = &handledAt
|
||||
}
|
||||
return resp
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user