This repository has been archived on 2026-06-21. You can view files and clone it, but cannot push or open issues or pull requests.
Files
MetaLab/internal/service/repository.go
Victor_Jay d9eff2df08 refactor: 重构 Space 页面为统一多 Tab 布局 + 移除独立关注/粉丝子页面
- 后端:SpaceController 支持 5 个 Tab(文章/关注/粉丝/收藏/设置),统一处理本人与访客视图
- 后端:注入 FavoriteService 支持收藏夹 Tab,新增用户统计数据查询
- 后端:新增 PUT /api/space/privacy 隐私设置 API 端点
- 后端:移除 FollowPageController 及 /space/:uid/followers|following 路由
- 前端:完全重写 space/index.html,顶部信息栏 + Tab 导航 + 左侧栏 + 主内容区
- 前端:重写 space.css 适配新布局(Profile Header/Tab Bar/文章/收藏/设置)
- 清理:删除独立的 follow HTML 模板和 CSS 文件
- 模型:User 表新增 follower_list_public 隐私字段
2026-06-01 21:48:01 +08:00

217 lines
7.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package service
import (
"time"
"metazone.cc/metalab/internal/model"
"gorm.io/gorm"
)
// userAuthStore AuthService 所需的最小仓储接口ISP7 个方法)
type userAuthStore interface {
ExistsByEmail(email string) (bool, error)
Create(user *model.User) error
FindByEmail(email string) (*model.User, error)
FindByID(id uint) (*model.User, error)
Update(user *model.User) error
ExistsByUsername(username string) (bool, error)
}
// userAdminStore AdminService 所需的最小仓储接口ISP7 个方法)
type userAdminStore interface {
CountSearchUsers(keyword, role, status string) (int64, error)
SearchUsers(keyword, role, status string, offset, limit int) ([]model.User, error)
FindByIDUnscoped(userID uint) (*model.User, error)
UpdateStatus(uid uint, status string) error
SoftDelete(uid uint) error
Restore(uid uint) error
ExistsByEmailExclude(email string, excludeUID uint) (bool, error)
}
// postStore PostService 所需的最小仓储接口
type postStore interface {
Create(post *model.Post) error
FindByID(id uint) (*model.Post, error)
FindByIDWithAuthor(id uint) (*model.Post, error)
FindPageable(keyword string, offset, limit int) ([]model.Post, int64, error)
FindAdminPageable(keyword, status string, offset, limit int) ([]model.Post, int64, error)
FindByUserIDAndStatus(userID uint, status string, offset, limit int) ([]model.Post, int64, error)
FindPendingRevisions(keyword string, offset, limit int) ([]model.Post, int64, error)
Update(post *model.Post) error
SoftDelete(id uint) error
Restore(id uint) error
}
// spaceUserStore SpaceService 所需的最小用户仓储接口
type spaceUserStore interface {
FindByID(id uint) (*model.User, error)
Update(user *model.User) error
}
// spacePostStore SpaceService 所需的最小帖子仓储接口
type spacePostStore interface {
FindByUserID(userID uint, offset, limit int) ([]model.Post, int64, error)
CountUserPosts(userID uint) (int64, error)
GetUserStats(userID uint) (likes, favorites int64, err error)
}
// postAdminStatStore AdminService 所需的帖子统计接口ISP2 个方法)
type postAdminStatStore interface {
CountPostsByStatus(status string) (int64, error)
CountPending() (int64, error)
}
// postNotifier PostService 所需的通知服务接口
type postNotifier interface {
NotifyPostApproved(userID uint, postTitle string, postID uint)
NotifyPostRejected(userID uint, postTitle, reason string, postID uint)
}
// userLevelStore LevelService 所需的用户仓储接口
type userLevelStore interface {
FindByID(id uint) (*model.User, error)
AddExp(userID uint, delta int) error
}
// checkInStore 签到记录仓储接口
type checkInStore interface {
FindCheckIn(userID uint, date time.Time) (*model.UserCheckIn, error)
CreateCheckIn(ci *model.UserCheckIn) error
}
// taskStore 任务完成记录仓储接口
type taskStore interface {
FindTask(userID uint, taskType string) (*model.UserTask, error)
CreateTask(task *model.UserTask) error
HasTask(userID uint, taskType string) (bool, error)
}
// levelNotifier 等级升级通知接口
type levelNotifier interface {
Create(userID uint, notifyType, title, content string, relatedID, commentID *uint) error
}
// EnergyStore EnergyService 所需的完整仓储接口
type EnergyStore interface {
FindUserByID(userID uint) (*model.User, error)
FindPostByID(postID uint) (*model.Post, error)
AddEnergy(userID uint, amount int) error
IncrPostEnergy(postID uint, amount int) error
CreateEnergyLog(log *model.EnergyLog) error
SumUserPostEnergy(userID, postID uint) (int, error)
CreateEnergizeLog(log *model.PostEnergizeLog) error
GetDailyEnergizeExp(userID uint, date time.Time) (*model.DailyExpSummary, error)
UpsertDailyExp(summary *model.DailyExpSummary) error
AddDailyExp(userID uint, date time.Time, delta int) error
ListEnergyLogsByUser(userID uint, days int, offset, limit int) ([]model.EnergyLog, error)
CountEnergyLogsByUser(userID uint, days int) (int64, error)
ListAllEnergyLogs(energyType string, offset, limit int) ([]model.EnergyLog, int64, error)
// WithTx 基于给定事务连接创建新的 EnergyStore确保事务内操作原子性
WithTx(tx *gorm.DB) EnergyStore
}
// energyStore 向后兼容别名
type energyStore = EnergyStore
// FundStore 公户仓储接口ISP
type FundStore interface {
GetBalance() (int, error)
LockAndGetBalance() (int, error)
IncrBalance(amount int) error
CreateLog(log *model.FundLog) error
ListLogs(logType string, offset, limit int) ([]model.FundLog, int64, error)
WithTx(tx *gorm.DB) FundStore
}
// energyNotifier EnergyService 所需的通知接口ISP
type energyNotifier interface {
Create(userID uint, notifyType, title, content string, relatedID, commentID *uint) error
}
// commentStore CommentService 所需的最小仓储接口ISP
type commentStore interface {
Create(comment *model.Comment) error
UpdateRootID(id, rootID uint) error
FindByID(id uint) (*model.Comment, error)
FindRootComments(postID uint, offset, limit int) ([]model.Comment, int64, error)
FindReplies(rootID uint) ([]model.Comment, error)
SoftDelete(id uint) error
IncrCommentsCount(postID uint) error
DecrCommentsCount(postID uint) error
CreateMention(mention *model.CommentMention) error
FindPostIDByComment(commentID uint) (uint, error)
FindPostAuthorID(postID uint) (uint, error)
SearchUsersByLevel(keyword string, minLevel, limit int) ([]struct {
UID string
Username string
Exp int
}, error)
GetUserUIDByID(userID uint) (string, error)
GetUsernameByID(userID uint) (string, error)
ListAllComments(keyword string, showDeleted bool, offset, limit int) ([]model.AdminCommentRow, int64, error)
}
// commentNotifier CommentService 所需的通知接口ISP
type commentNotifier interface {
Create(userID uint, notifyType, title, content string, relatedID, commentID *uint) error
}
// ReactionStore ReactionService 所需的仓储接口ISP
type ReactionStore interface {
FindLike(userID, postID uint) (*model.PostLike, error)
CreateLike(like *model.PostLike) error
DeleteLike(userID, postID uint) error
FindDislike(userID, postID uint) (*model.PostDislike, error)
CreateDislike(dislike *model.PostDislike) error
DeleteDislike(userID, postID uint) error
IncrPostLikes(postID uint, delta int) error
IncrPostDislikes(postID uint, delta int) error
GetPostAuthorID(postID uint) (uint, error)
UpsertDailyLikeSummary(authorUID uint, date string, likerUID string) error
GetUnnotifiedSummaries(userID uint) ([]model.DailyLikeSummary, error)
MarkSummaryNotified(id uint) error
WithTx(tx *gorm.DB) ReactionStore
}
// FollowStore FollowService 所需的最小仓储接口ISP
type FollowStore interface {
Create(follow *model.UserFollow) error
Delete(followerID, followeeID uint) error
Exists(followerID, followeeID uint) (bool, error)
CountFollowers(userID uint) (int64, error)
CountFollowing(userID uint) (int64, error)
ListFollowers(userID uint, offset, limit int) ([]model.UserFollow, int64, error)
ListFollowing(userID uint, offset, limit int) ([]model.UserFollow, int64, error)
IncrFollowersCount(userID uint, delta int) error
IncrFollowingCount(userID uint, delta int) error
GetFollowListPublic(userID uint) (bool, error)
WithTx(tx *gorm.DB) FollowStore
}
// TrendPoint 趋势数据点
type TrendPoint struct {
Date string `json:"date"`
Value int `json:"value"`
}
// EnergyTrendStore 赋能趋势聚合ISP
type EnergyTrendStore interface {
AggregateEnergyByAuthor(userID uint, since string) ([]TrendPoint, error)
}
// CommentTrendStore 评论趋势聚合ISP
type CommentTrendStore interface {
AggregateCommentsByAuthor(userID uint, since string) ([]TrendPoint, error)
}
// LikeTrendStore 点赞趋势聚合ISP
type LikeTrendStore interface {
AggregateLikesByAuthor(userID uint, since string) ([]TrendPoint, error)
}
// FavoriteTrendStore 收藏趋势聚合ISP
type FavoriteTrendStore interface {
AggregateFavoritesByAuthor(userID uint, since string) ([]TrendPoint, error)
}