diff --git a/CHANGELOG.md b/CHANGELOG.md index 28c7fc91..814fef3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,15 +21,6 @@ All notable changes to paopao-ce are documented in this file. CREATE TABLE p_following (ID BIGSERIAL PRIMARY KEY,user_id BIGINT NOT NULL,follow_id BIGINT NOT NULL,is_del SMALLINT NOT NULL DEFAULT 0,created_on BIGINT NOT NULL DEFAULT 0,modified_on BIGINT NOT NULL DEFAULT 0,deleted_on BIGINT NOT NULL DEFAULT 0); CREATE INDEX idx_following_user_follow ON p_following USING btree (user_id,follow_id); ``` - custom set config.yaml in `Features` section add `Followship` to enable Followship feature: - ```yaml - ... - # add Followship to enable this feature - Features: - Default: ["Meili", "LoggerMeili", "Base", "Sqlite3", "BigCacheIndex", "MinIO", "Followship"] - Base: ["Redis", "PhoneBind"] - ... - ``` ### Changed - change man content width to 600px and optimize tweet/comment/replay text length. [#333](https://github.com/rocboss/paopao-ce/pull/333) @@ -41,6 +32,8 @@ All notable changes to paopao-ce are documented in this file. make build TAGS='slim embed' ``` - frontend: optimize user profile page route path to domain/#/u/?s=username. [&c857142](https://github.com/rocboss/paopao-ce/commit/c857142565f0c28294344c7abc5c2df4e363b04c +- change the `Friendship` feature and `Followship` feature as builtin feature. [#362](https://github.com/rocboss/paopao-ce/pull/362) +- deprecated/remove `Lightship` feature. [#362](https://github.com/rocboss/paopao-ce/pull/362) ## 0.3.1 ### Fixed diff --git a/README.md b/README.md index 2908f224..3d7c1b2c 100644 --- a/README.md +++ b/README.md @@ -373,9 +373,9 @@ release/paopao-ce --no-default-features --features sqlite3,localoss,loggerfile,r |`LoggerFile` | 日志 | 稳定 | 使用文件写日志 | |`LoggerZinc` | 日志 | 稳定(推荐) | 使用[Zinc](https://github.com/zinclabs/zinc)写日志 | |`LoggerMeili` | 日志 | 内测 | 使用[Meilisearch](https://github.com/meilisearch/meilisearch)写日志 | -|[`Friendship`](docs/proposal/002-关于Friendship功能项的设计.md) | 关系模式 | 内测 | 弱关系好友模式,类似微信朋友圈 | -|[`Followship`](docs/proposal/003-关于Followship功能项的设计.md) | 关系模式 | WIP | 关注者模式,类似Twitter的Follow模式 | -|[`Lightship`](docs/proposal/011-关于Lightship功能项的设计.md) | 关系模式 | 内测(默认) | 开放模式,所有推文都公开可见 | +|[`Friendship`](docs/proposal/22110410-关于Friendship功能项的设计.md) | 关系模式 | 内置 Builtin | 弱关系好友模式,类似微信朋友圈 | +|[`Followship`](docs/proposal/22110409-关于Followship功能项的设计.md) | 关系模式 | 内置 Builtin | 关注者模式,类似Twitter的Follow模式 | +|[`Lightship`](docs/proposal/22121409-关于Lightship功能项的设计.md) | 关系模式 | 弃用 Deprecated | 开放模式,所有推文都公开可见 | |`Alipay` | 支付 | 稳定 | 开启基于[支付宝开放平台](https://open.alipay.com/)的钱包功能 | |`Sms` | 短信验证 | 稳定 | 开启短信验证码功能,用于手机绑定验证手机是否注册者的;功能如果没有开启,手机绑定时任意短信验证码都可以绑定手机 | |`Docs:OpenAPI` | 开发文档 | 稳定 | 开启openapi文档功能,提供web api文档说明(visit http://127.0.0.1:8008/docs/openapi) | diff --git a/config.yaml.sample b/config.yaml.sample index 3e6c7f0f..33f9b73d 100644 --- a/config.yaml.sample +++ b/config.yaml.sample @@ -12,7 +12,7 @@ Server: # 服务设置 ReadTimeout: 60 WriteTimeout: 60 Features: - Default: ["Web", "Frontend:EmbedWeb", "Meili", "LocalOSS", "MySQL", "BigCacheIndex", "LoggerFile", "Friendship", "Followship"] + Default: ["Web", "Frontend:EmbedWeb", "Meili", "LocalOSS", "MySQL", "BigCacheIndex", "LoggerFile"] Develop: ["Base", "MySQL", "BigCacheIndex", "Meili", "Sms", "AliOSS", "LoggerMeili", "OSS:Retention"] Demo: ["Base", "MySQL", "Option", "Zinc", "Sms", "MinIO", "LoggerZinc", "Migration"] Slim: ["Base", "Sqlite3", "LocalOSS", "LoggerFile", "OSS:TempDir"] diff --git a/docs/proposal/22110409-关于Followship功能项的设计.md b/docs/proposal/22110409-关于Followship功能项的设计.md index 9a385d71..d709562b 100644 --- a/docs/proposal/22110409-关于Followship功能项的设计.md +++ b/docs/proposal/22110409-关于Followship功能项的设计.md @@ -1,6 +1,6 @@ | 编号 | 作者 | 发表时间 | 变更时间 | 版本 | 状态 | | ----- | ----- | ----- | ----- | ----- | ----- | -| 22110409| 北野 | 2022-11-04 | 2023-08-14 | v1.0 | 提议 | +| 22110409| 北野 | 2022-11-04 | 2023-08-16 | v1.0 | 提议 | ### 关于Followship功能项的设计 Followship是实现类似Twitter Timeline模式**关注者模型**的时间线信息流,广场推文列表的生成将主要与推文时间、用户的关注者相关。Twitter的推文消息流是非常智能的,用户体验也非常好,这得益于其背后的智能推荐算法以及完善的关注者模型体系,当然还有很多其他机制共同作用下的结果。本提按作为一个总纲为paopao-ce引入类似的机制,这将是一个持续完善的缓慢过程,一切都是为了用户体验,用户就是上帝,用户需要什么,paopao-ce就努力提供什么! @@ -39,21 +39,16 @@ * 参考实现(PR): [add Followship feature #355](https://github.com/rocboss/paopao-ce/pull/355) +#### 状态: +内置 Builtin + ### 疑问 1. Friendship与Followship这两功能项是否可以共存还是互斥呢? 理论上这两个功能项是可以共存的,如果设置成共存,就需要同时提供这两个机制的UI交互,同时广场推文列表的生成机制也需要做相应适配,可能会比较复杂。前期开发将把这两个功能设置为互斥的,即**用户关系模型**只能设置为其中之一,待两个功能项都趋于稳定后,再测试这两个功能项共存后的用户体验,如果效果还不错就引入共存机制。 1. 如何开启这个功能? - 在配置文件config.yaml中的`Features`中添加`Followship`功能项开启该功能: - ```yaml - ... - # features中加上 Followship - Features: - Default: ["Meili", "LoggerMeili", "Base", "Sqlite3", "BigCacheIndex", "MinIO", "Followship"] - Base: ["Redis", "PhoneBind"] - ... - ``` + 内置 Builtin ### 更新记录 #### v0.0(2022-11-04) - 北野 @@ -63,4 +58,7 @@ * 添加初始内容; #### v1.0(2023-08-14) - 北野 -* 添加参考实现; \ No newline at end of file +* 添加参考实现; + +#### v1.1(2023-08-16) - 北野 +* 添加状态信息; diff --git a/docs/proposal/22110410-关于Friendship功能项的设计.md b/docs/proposal/22110410-关于Friendship功能项的设计.md index c90b6002..b05f6cae 100644 --- a/docs/proposal/22110410-关于Friendship功能项的设计.md +++ b/docs/proposal/22110410-关于Friendship功能项的设计.md @@ -1,6 +1,6 @@ | 编号 | 作者 | 发表时间 | 变更时间 | 版本 | 状态 | | ----- | ----- | ----- | ----- | ----- | ----- | -| 22110410 | 北野 | 2022-11-04 | 2023-01-04 | v1.0 | 提议 | +| 22110410 | 北野 | 2022-11-04 | 2023-08-16 | v1.1 | 提议 | ### Friendship功能项的设计概要 Friendship功能提供好友间分享推文信息的机制,更好的帮助用户建立自己的推文分享小圈子。Friendship本质上想优化的是泡泡广场页面推文列表的生成机制,开启功能后,推文列表只能获取 `公开/私密/好友` 的推文,每个用户都有属于自己的个性化推文列表。在提供个性化推文列表生成机制的同时,好友体系的建立也顺便帮助用户建立自己的个性化有限范围内的灵魂社交小圈子,只有相互间拥有个性化认同感的用户才能互为好友。 @@ -30,6 +30,9 @@ Friendship功能提供好友间分享推文信息的机制,更好的帮助用 * 参考实现(PR): [add support Friendship feature #192](https://github.com/rocboss/paopao-ce/pull/192) +#### 状态: +内置 Builtin + * 预览 | | @@ -46,15 +49,7 @@ Friendship功能提供好友间分享推文信息的机制,更好的帮助用 2. 如何形成这种好友体系? 形成好友体系分 **建立、维持、解除** 好友关系。Friendship提供 *建立/解除* 好友关系的机制,泡泡广场的推文列表依据这个好友体系为每个用户生成个性化推文列表。而好友关系的**维持**,本质上就是用户推文的持久更新、思想的持续演化,使得好友对你一直保持兴趣;Friendship也为每一条推文的访问权限进行**标记(私密/好友可见)**,这可以传达这样一种信息: **“时刻让好友知道我非常在乎好友、对好友特殊关照,你看这条推文就是只有我的好友(也就是你)才可以看到,够意思吧”!** 顺便一说,每一条推文的访问权限标记(公开/私密/好友可见)是建立Friendship弱关系体系的隐性催化剂,可以加速Friendship的形成。 3. 如何开启这个功能? -在配置文件config.yaml中的`Features`中添加`Friendship`功能项开启该功能: - ```yaml - ... - # features中加上 Friendship - Features: - Default: ["Meili", "LoggerMeili", "Base", "Sqlite3", "BigCacheIndex", "MinIO", "Friendship"] - Base: ["Redis", "PhoneBind"] - ... - ``` +内置 Builtin ### 更新记录 #### v0.1(2022-11-04) - 北野 @@ -65,3 +60,6 @@ Friendship功能提供好友间分享推文信息的机制,更好的帮助用 #### v1.0(2023-01-04) - 北野 * 添加参考实现PR信息 + +#### v1.1(2023-08-16) - 北野 +* 添加状态信息; diff --git a/docs/proposal/22121409-关于Lightship功能项的设计.md b/docs/proposal/22121409-关于Lightship功能项的设计.md index a4063640..dd273d5a 100644 --- a/docs/proposal/22121409-关于Lightship功能项的设计.md +++ b/docs/proposal/22121409-关于Lightship功能项的设计.md @@ -1,9 +1,9 @@ | 编号 | 作者 | 发表时间 | 变更时间 | 版本 | 状态 | | ----- | ----- | ----- | ----- | ----- | ----- | -| 22121409 | 北野 | 2022-12-14 | 2022-01-09 | v1.1 | 提议 | +| 22121409 | 北野 | 2022-12-14 | 2023-08-16 | v1.2 | 提议 | ### 关于Lightship功能项的设计 -Lightship(开放模式)功能提供完全公开的推文分享服务,有别于[Friendship](002-关于Friendship功能项的设计.md "关于Friendship功能项的设计")、[Followship](003-关于Followship功能项的设计.md "关于Followship功能项的设计"),使用Lightship用户模式部署paopao-ce,用户发布的所有推文都是公开可访问的,广场推文列表展示的是全站所有公开推文的Timeline Tweets。 +Lightship(开放模式)功能提供完全公开的推文分享服务,有别于[Friendship](22110410-关于Friendship功能项的设计.md "关于Friendship功能项的设计")、[Followship](22110410-关于Followship功能项的设计.md "关于Followship功能项的设计"),使用Lightship用户模式部署paopao-ce,用户发布的所有推文都是公开可访问的,广场推文列表展示的是全站所有公开推文的Timeline Tweets。 ### 场景 一般用于非常小的站点,或者推文更新不频繁的站点。 @@ -24,6 +24,9 @@ Lightship(开放模式)功能提供完全公开的推文分享服务,有别于 #### 参考实现(PR): [add Lightship feature support #198](https://github.com/rocboss/paopao-ce/pull/198) +#### 状态: +弃用 Deprecated + ### 疑问 1. 公开模式为什么命名为Lightship? @@ -45,3 +48,6 @@ Features: #### v1.1(2022-01-09) - 北野 * 添加参考实现PR信息 + +#### v1.2(2023-08-16) - 北野 +* 添加状态信息 diff --git a/features-status.md b/features-status.md index 60f17aff..be734b22 100644 --- a/features-status.md +++ b/features-status.md @@ -145,15 +145,15 @@ * [x] 业务逻辑实现 #### 关系模式: -* `Friendship` 弱关系好友模式,类似微信朋友圈(目前状态: 内测); +* `Friendship` 弱关系好友模式,类似微信朋友圈(目前状态: 内置Builtin); * [x] [提按文档](docs/proposal/22110410-关于Friendship功能项的设计.md) * [x] 接口定义 * [x] 业务逻辑实现 -* `Followship` 关注者模式,类似Twitter的Follow模式(目前状态: WIP); +* `Followship` 关注者模式,类似Twitter的Follow模式(目前状态: 内置Builtin); * [ ] [提按文档](docs/proposal/22110409-关于Followship功能项的设计.md) * [ ] 接口定义 * [ ] 业务逻辑实现 -* `Lightship` 开放模式,所有推文都公开可见(目前状态: 内测、默认); +* `Lightship` 开放模式,所有推文都公开可见(目前状态: 弃用Deprecated); * [x] [提按文档](docs/proposal/22121409-关于Lightship功能项的设计.md) * [x] 接口定义 * [x] 业务逻辑实现 diff --git a/internal/dao/jinzhu/jinzhu.go b/internal/dao/jinzhu/jinzhu.go index 5f8dbb15..a3255010 100644 --- a/internal/dao/jinzhu/jinzhu.go +++ b/internal/dao/jinzhu/jinzhu.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT style // license that can be found in the LICENSE file. -// Core service implement base gorm+mysql/postgresql/sqlite3. +// package jinzhu Core service implement base gorm+mysql/postgresql/sqlite3. // Jinzhu is the primary developer of gorm so use his name as // package name as a saluter. @@ -60,24 +60,12 @@ func NewDataService() (core.DataService, core.VersionInfo) { var ( v core.VersionInfo cis core.CacheIndexService - ips core.IndexPostsService ) db := conf.MustGormDB() pvs := security.NewPhoneVerifyService() ams := NewAuthorizationManageService() ths := newTweetHelpService(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) - } + ips := newShipIndexService(db, ams, ths) // initialize core.CacheIndexService cfg.On(cfg.Actions{ @@ -87,7 +75,6 @@ func NewDataService() (core.DataService, core.VersionInfo) { cis, v = cache.NewSimpleCacheIndexService(ips) }, "BigCacheIndex": func() { - // TODO: make cache index post in different scence like friendship/followship/lightship cis, v = cache.NewBigCacheIndexService(ips, ams) }, "RedisCacheIndex": func() { diff --git a/internal/dao/jinzhu/timeline.go b/internal/dao/jinzhu/timeline.go index f81e3619..456d90ab 100644 --- a/internal/dao/jinzhu/timeline.go +++ b/internal/dao/jinzhu/timeline.go @@ -15,35 +15,23 @@ import ( ) var ( - _ core.IndexPostsService = (*friendIndexSrv)(nil) - _ core.IndexPostsService = (*followIndexSrv)(nil) - _ core.IndexPostsService = (*lightIndexSrv)(nil) + _ core.IndexPostsService = (*shipIndexSrv)(nil) _ core.IndexPostsService = (*simpleIndexPostsSrv)(nil) ) -type friendIndexSrv struct { +type shipIndexSrv struct { ams core.AuthorizationManageService ths core.TweetHelpService db *gorm.DB } -type followIndexSrv struct { - ths core.TweetHelpService - db *gorm.DB -} - -type lightIndexSrv struct { - ths core.TweetHelpService - db *gorm.DB -} - type simpleIndexPostsSrv struct { ths core.TweetHelpService db *gorm.DB } // IndexPosts 根据userId查询广场推文列表,简单做到不同用户的主页都是不同的; -func (s *friendIndexSrv) IndexPosts(user *ms.User, offset int, limit int) (*ms.IndexTweetList, error) { +func (s *shipIndexSrv) IndexPosts(user *ms.User, offset int, limit int) (*ms.IndexTweetList, error) { predicates := dbr.Predicates{ "ORDER": []any{"is_top DESC, latest_replied_on DESC"}, } @@ -77,60 +65,6 @@ func (s *friendIndexSrv) IndexPosts(user *ms.User, offset int, limit int) (*ms.I }, nil } -func (s *friendIndexSrv) TweetTimeline(userId int64, offset int, limit int) (*cs.TweetBox, error) { - // TODO - return nil, debug.ErrNotImplemented -} - -// IndexPosts 根据userId查询广场推文列表 -func (s *followIndexSrv) IndexPosts(user *ms.User, offset int, limit int) (*ms.IndexTweetList, error) { - // TODO - return nil, debug.ErrNotImplemented -} - -func (s *followIndexSrv) TweetTimeline(userId int64, offset int, limit int) (*cs.TweetBox, error) { - // TODO - return nil, debug.ErrNotImplemented -} - -// IndexPosts 根据userId查询广场推文列表,获取公开可见Tweet或者所属用户的私有Tweet -func (s *lightIndexSrv) IndexPosts(user *ms.User, offset int, limit int) (*ms.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("gormIndexPostsSrv.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 &ms.IndexTweetList{ - Tweets: formatPosts, - Total: total, - }, nil -} - -func (s *lightIndexSrv) TweetTimeline(userId int64, offset int, limit int) (*cs.TweetBox, error) { - // TODO - return nil, debug.ErrNotImplemented -} - // simpleCacheIndexGetPosts simpleCacheIndex 专属获取广场推文列表函数 func (s *simpleIndexPostsSrv) IndexPosts(_user *ms.User, offset int, limit int) (*ms.IndexTweetList, error) { predicates := dbr.Predicates{ @@ -165,28 +99,14 @@ func (s *simpleIndexPostsSrv) TweetTimeline(userId int64, offset int, limit int) return nil, debug.ErrNotImplemented } -func newFriendIndexService(db *gorm.DB, ams core.AuthorizationManageService, ths core.TweetHelpService) core.IndexPostsService { - return &friendIndexSrv{ +func newShipIndexService(db *gorm.DB, ams core.AuthorizationManageService, ths core.TweetHelpService) core.IndexPostsService { + return &shipIndexSrv{ ams: ams, ths: ths, db: db, } } -func newFollowIndexService(db *gorm.DB, ths core.TweetHelpService) core.IndexPostsService { - return &followIndexSrv{ - ths: ths, - db: db, - } -} - -func newLightIndexService(db *gorm.DB, ths core.TweetHelpService) core.IndexPostsService { - return &lightIndexSrv{ - ths: ths, - db: db, - } -} - func newSimpleIndexPostsService(db *gorm.DB, ths core.TweetHelpService) core.IndexPostsService { return &simpleIndexPostsSrv{ ths: ths, diff --git a/internal/servants/web/web.go b/internal/servants/web/web.go index e4684a1e..e58a426b 100644 --- a/internal/servants/web/web.go +++ b/internal/servants/web/web.go @@ -32,19 +32,13 @@ func RouteWeb(e *gin.Engine) { api.RegisterLooseServant(e, newLooseSrv(ds)) api.RegisterPrivServant(e, newPrivSrv(ds, oss)) api.RegisterPubServant(e, newPubSrv(ds)) + api.RegisterFollowshipServant(e, newFollowshipSrv(ds)) + api.RegisterFriendshipServant(e, newFriendshipSrv(ds)) // regster servants if needed by configure - cfg.In(cfg.Actions{ - "Alipay": func() { - client := conf.MustAlipayClient() - api.RegisterAlipayPubServant(e, newAlipayPubSrv(ds)) - api.RegisterAlipayPrivServant(e, newAlipayPrivSrv(ds, client)) - }, - "Followship": func() { - api.RegisterFollowshipServant(e, newFollowshipSrv(ds)) - }, - "Friendship": func() { - api.RegisterFriendshipServant(e, newFriendshipSrv(ds)) - }, + cfg.Be("Alipay", func() { + client := conf.MustAlipayClient() + api.RegisterAlipayPubServant(e, newAlipayPubSrv(ds)) + api.RegisterAlipayPrivServant(e, newAlipayPrivSrv(ds, client)) }) }