diff --git a/README.md b/README.md index d86d454d..11a0be12 100644 --- a/README.md +++ b/README.md @@ -328,8 +328,8 @@ release/paopao-ce --no-default-features --features sqlite3,localoss,loggerfile,r |`Bot` | 子服务 | WIP | 开启Bot服务| |`NativeOBS` | 子服务 | WIP | 开启NativeOBS服务| |`Docs` | 子服务 | WIP | 开启开发者文档服务| -|`Frontend:Web` | 子服务 | 内测 | 开启独立前端服务| -|`Frontend:EmbedWeb` | 子服务 | 内测 | 开启内嵌于后端Web API服务中的前端服务| +|`Frontend:Web` | 子服务 | 稳定 | 开启独立前端服务| +|`Frontend:EmbedWeb` | 子服务 | 稳定 | 开启内嵌于后端Web API服务中的前端服务| |`Deprecated:Web` | 子服务 | 稳定 | 开启旧的Web服务| |`Gorm` | 数据库 | 稳定(默认) | 使用[gorm](https://github.com/go-gorm/gorm)作为数据库的ORM,默认使用 `Gorm` + `MySQL`组合| |`Sqlx`| 数据库 | WIP | 使用[sqlx](https://github.com/jmoiron/sqlx)作为数据库的ORM| @@ -345,7 +345,7 @@ release/paopao-ce --no-default-features --features sqlite3,localoss,loggerfile,r |`OSS:Retention` | 对象存储 | 内测 |基于对象存储系统的对象过期自动删除特性实现 先创建临时对象再持久化的功能| |`OSS:TempDir` | 对象存储 | 内测 |基于对象存储系统的对象拷贝/移动特性实现 先创建临时对象再持久化的功能| |`Redis` | 缓存 | 稳定 | Redis缓存功能 | -|`SimpleCacheIndex` | 缓存 | 稳定 | 提供简单的 广场推文列表 的缓存功能 | +|`SimpleCacheIndex` | 缓存 | Deprecated | 提供简单的 广场推文列表 的缓存功能 | |`BigCacheIndex` | 缓存 | 稳定(推荐) | 使用[BigCache](https://github.com/allegro/bigcache)缓存 广场推文列表,缓存每个用户每一页,简单做到千人千面 | |`Zinc` | 搜索 | 稳定(推荐) | 基于[Zinc](https://github.com/zinclabs/zinc)搜索引擎提供推文搜索服务 | |`Meili` | 搜索 | 稳定(推荐) | 基于[Meilisearch](https://github.com/meilisearch/meilisearch)搜索引擎提供推文搜索服务 | @@ -355,6 +355,7 @@ release/paopao-ce --no-default-features --features sqlite3,localoss,loggerfile,r |`LoggerMeili` | 日志 | 内测 | 使用[Meilisearch](https://github.com/meilisearch/meilisearch)写日志 | |`Friendship` | 关系模式 | 内测(默认) | 弱关系好友模式,类似微信朋友圈 | |`Followship` | 关系模式 | WIP | 关注者模式,类似Twitter的Follow模式 | +|`Lightship` | 关系模式 | 内测 | 开放模式,所有推文都公开可见 | |`Alipay` | 支付 | 稳定 | 开启基于[支付宝开放平台](https://open.alipay.com/)的钱包功能 | |`Sms` | 短信验证 | 稳定 | 开启短信验证码功能,用于手机绑定验证手机是否注册者的;功能如果没有开启,手机绑定时任意短信验证码都可以绑定手机 | |`Docs:OpenAPI` | 开发文档 | 稳定 | 开启openapi文档功能,提供web api文档说明(visit http://127.0.0.1:8008/docs/openapi) | diff --git a/ROADMAP.md b/ROADMAP.md index fc0e6681..2ab924bf 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -3,7 +3,7 @@ paopao-ce roadmap. ### v0.2.0 * [x] add `Friendship` feature -* [ ] add `Lightship` feature +* [x] add `Lightship` feature * [ ] add `Sqlx` feature * [x] add new `Web` service * [x] add `Frontend:Web` feature diff --git a/docs/proposal/011-关于Lightship功能项的设计.md b/docs/proposal/011-关于Lightship功能项的设计.md new file mode 100644 index 00000000..ac6c2ee6 --- /dev/null +++ b/docs/proposal/011-关于Lightship功能项的设计.md @@ -0,0 +1,46 @@ +| 编号 | 作者 | 发表时间 | 变更时间 | 版本 | 状态 | +| ----- | ----- | ----- | ----- | ----- | ----- | +| 011| 北野 | 2022-12-14 | 2022-01-09 | v1.1 | 提议 | + +### 关于Lightship功能项的设计 +Lightship(开放模式)功能提供完全公开的推文分享服务,有别于[Friendship](002-关于Friendship功能项的设计.md "关于Friendship功能项的设计")、[Followship](003-关于Followship功能项的设计.md "关于Followship功能项的设计"),使用Lightship用户模式部署paopao-ce,用户发布的所有推文都是公开可访问的,广场推文列表展示的是全站所有公开推文的Timeline Tweets。 + +### 场景 +一般用于非常小的站点,或者推文更新不频繁的站点。 +* 推文更新不频繁站点; +* 个人推文站点; +* 单纯想要所有推文公开访问; + +### 需求 +* 广场推文列表只展示公开可访问推文; +* 推文访问权限只能是 `公开/私密`; + +### 方案 + +#### 实现细节 +* 广场推文列表只展示公开可访问推文 - 前端/后端 +* 推文访问权限只能是 `公开/私密` - 前端/后端 + +#### 参考实现(PR): +[add Lightship feature support #198](https://github.com/rocboss/paopao-ce/pull/198) + +### 疑问 + +1. 公开模式为什么命名为Lightship? +Lightship有灯塔的意思,灯塔是为航行船只指明方向的公共设施,这里取其公有设施的属性指喻 开放模式下paopao-ce不需要授权公开访问推 文的意思。 +1. 如何开启这个功能? +在配置文件config.yaml中的`Features`中添加`Lightship`功能项开启该功能: +```yaml +... +# features中加上 Lightship +Features: + Default: ["Meili", "LoggerMeili", "Base", "Sqlite3", "BigCacheIndex", "MinIO", "Lightship"] + Base: ["Redis", "PhoneBind"] +... +``` + +### 更新记录 +#### v1.0(2022-12-14) - 北野 +* 初始文档 +#### v1.1(2022-01-09) - 北野 +* 添加参考实现PR信息 diff --git a/features-status.md b/features-status.md index 8937a2bc..c2ac559b 100644 --- a/features-status.md +++ b/features-status.md @@ -97,7 +97,7 @@ * [ ] 提按文档 * [x] 接口定义 * [x] 业务逻辑实现 -* `SimpleCacheIndex` 提供简单的 广场推文列表 的缓存功能能; +* `SimpleCacheIndex` 提供简单的 广场推文列表 的缓存功能能(目前状态: Deprecated); * [ ] 提按文档 * [x] 接口定义 * [x] 业务逻辑实现 @@ -142,6 +142,10 @@ * [ ] 提按文档 * [ ] 接口定义 * [ ] 业务逻辑实现 +* `Lightship` 开放模式,所有推文都公开可见(目前状态: WIP); + * [x] 提按文档 + * [x] 接口定义 + * [x] 业务逻辑实现 ### 支付: * `Alipay` 开启基于[支付宝开放平台](https://open.alipay.com/)的钱包功能; diff --git a/internal/dao/jinzhu/index.go b/internal/dao/jinzhu/index.go index 7548de49..fc7e2007 100644 --- a/internal/dao/jinzhu/index.go +++ b/internal/dao/jinzhu/index.go @@ -7,43 +7,41 @@ package jinzhu import ( "github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr" + "github.com/rocboss/paopao-ce/pkg/debug" "github.com/sirupsen/logrus" "gorm.io/gorm" ) var ( - _ core.IndexPostsService = (*indexPostsServant)(nil) + _ core.IndexPostsService = (*friendIndexServant)(nil) + _ core.IndexPostsService = (*followIndexServant)(nil) + _ core.IndexPostsService = (*lightIndexServant)(nil) _ core.IndexPostsService = (*simpleIndexPostsServant)(nil) ) -type indexPostsServant struct { +type friendIndexServant struct { ams core.AuthorizationManageService ths core.TweetHelpService db *gorm.DB } -type simpleIndexPostsServant struct { +type followIndexServant struct { ths core.TweetHelpService db *gorm.DB } -func newIndexPostsService(db *gorm.DB) core.IndexPostsService { - return &indexPostsServant{ - ams: NewAuthorizationManageService(), - ths: newTweetHelpService(db), - db: db, - } +type lightIndexServant struct { + ths core.TweetHelpService + db *gorm.DB } -func newSimpleIndexPostsService(db *gorm.DB) core.IndexPostsService { - return &simpleIndexPostsServant{ - ths: newTweetHelpService(db), - db: db, - } +type simpleIndexPostsServant struct { + ths core.TweetHelpService + db *gorm.DB } // IndexPosts 根据userId查询广场推文列表,简单做到不同用户的主页都是不同的; -func (s *indexPostsServant) IndexPosts(user *core.User, offset int, limit int) (*core.IndexTweetList, error) { +func (s *friendIndexServant) IndexPosts(user *core.User, offset int, limit int) (*core.IndexTweetList, error) { predicates := dbr.Predicates{ "ORDER": []any{"is_top DESC, latest_replied_on DESC"}, } @@ -77,6 +75,45 @@ func (s *indexPostsServant) IndexPosts(user *core.User, offset int, limit int) ( }, nil } +// IndexPosts 根据userId查询广场推文列表 +func (s *followIndexServant) IndexPosts(user *core.User, offset int, limit int) (*core.IndexTweetList, error) { + // TODO + return nil, debug.ErrNotImplemented +} + +// IndexPosts 根据userId查询广场推文列表,获取公开可见Tweet或者所属用户的私有Tweet +func (s *lightIndexServant) IndexPosts(user *core.User, offset int, limit int) (*core.IndexTweetList, error) { + predicates := dbr.Predicates{ + "ORDER": []any{"is_top DESC, latest_replied_on DESC"}, + } + if user == nil { + predicates["visibility = ?"] = []any{dbr.PostVisitPublic} + } else if !user.IsAdmin { + args := []any{dbr.PostVisitPublic, dbr.PostVisitPrivate, user.ID} + predicates["visibility = ? OR (visibility = ? AND user_id = ?)"] = args + } + + posts, err := (&dbr.Post{}).Fetch(s.db, predicates, offset, limit) + if err != nil { + logrus.Debugf("gormIndexPostsServant.IndexPosts err: %v", err) + return nil, err + } + formatPosts, err := s.ths.MergePosts(posts) + if err != nil { + return nil, err + } + + total, err := (&dbr.Post{}).CountBy(s.db, predicates) + if err != nil { + return nil, err + } + + return &core.IndexTweetList{ + Tweets: formatPosts, + Total: total, + }, nil +} + // simpleCacheIndexGetPosts simpleCacheIndex 专属获取广场推文列表函数 func (s *simpleIndexPostsServant) IndexPosts(_user *core.User, offset int, limit int) (*core.IndexTweetList, error) { predicates := dbr.Predicates{ @@ -105,3 +142,32 @@ func (s *simpleIndexPostsServant) IndexPosts(_user *core.User, offset int, limit Total: total, }, nil } + +func newFriendIndexService(db *gorm.DB, ams core.AuthorizationManageService, ths core.TweetHelpService) core.IndexPostsService { + return &friendIndexServant{ + ams: ams, + ths: ths, + db: db, + } +} + +func newFollowIndexService(db *gorm.DB, ths core.TweetHelpService) core.IndexPostsService { + return &followIndexServant{ + ths: ths, + db: db, + } +} + +func newLightIndexService(db *gorm.DB, ths core.TweetHelpService) core.IndexPostsService { + return &lightIndexServant{ + ths: ths, + db: db, + } +} + +func newSimpleIndexPostsService(db *gorm.DB, ths core.TweetHelpService) core.IndexPostsService { + return &simpleIndexPostsServant{ + ths: ths, + db: db, + } +} diff --git a/internal/dao/jinzhu/jinzhu.go b/internal/dao/jinzhu/jinzhu.go index f708e064..6d15f1b5 100644 --- a/internal/dao/jinzhu/jinzhu.go +++ b/internal/dao/jinzhu/jinzhu.go @@ -40,33 +40,48 @@ type dataServant struct { } func NewDataService() (core.DataService, core.VersionInfo) { - // initialize CacheIndex if needed var ( - c core.CacheIndexService - v core.VersionInfo + v core.VersionInfo + cis core.CacheIndexService + ips core.IndexPostsService ) db := conf.MustGormDB() pvs := security.NewPhoneVerifyService() + ams := NewAuthorizationManageService() + ths := newTweetHelpService(db) - i := newIndexPostsService(db) + // initialize core.IndexPostsService + if cfg.If("Friendship") { + ips = newFriendIndexService(db, ams, ths) + } else if cfg.If("Followship") { + ips = newFollowIndexService(db, ths) + } else if cfg.If("Lightship") { + ips = newLightIndexService(db, ths) + } else { + // default use lightship post index service + ips = newLightIndexService(db, ths) + } + + // initialize core.CacheIndexService if cfg.If("SimpleCacheIndex") { - i = newSimpleIndexPostsService(db) - c, v = cache.NewSimpleCacheIndexService(i) + // simpleCache use special post index service + ips = newSimpleIndexPostsService(db, ths) + cis, v = cache.NewSimpleCacheIndexService(ips) } else if cfg.If("BigCacheIndex") { - a := newAuthorizationManageService(db) - c, v = cache.NewBigCacheIndexService(i, a) + // TODO: make cache index post in different scence like friendship/followship/lightship + cis, v = cache.NewBigCacheIndexService(ips, ams) } else { - c, v = cache.NewNoneCacheIndexService(i) + cis, v = cache.NewNoneCacheIndexService(ips) } logrus.Infof("use %s as cache index service by version: %s", v.Name(), v.Version()) ds := &dataServant{ - IndexPostsService: c, + IndexPostsService: cis, WalletService: newWalletService(db), MessageService: newMessageService(db), TopicService: newTopicService(db), TweetService: newTweetService(db), - TweetManageService: newTweetManageService(db, c), + TweetManageService: newTweetManageService(db, cis), TweetHelpService: newTweetHelpService(db), CommentService: newCommentService(db), CommentManageService: newCommentManageService(db), diff --git a/pkg/debug/errors.go b/pkg/debug/errors.go new file mode 100644 index 00000000..04a404ca --- /dev/null +++ b/pkg/debug/errors.go @@ -0,0 +1,13 @@ +// Copyright 2023 ROC. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package debug + +import ( + "errors" +) + +var ( + ErrNotImplemented = errors.New("not implemented") +)