官方更新内容

pull/361/head
HXY 2 years ago
commit 7f68cac0e1

@ -1,4 +1,4 @@
.DS_Store .DS_Store
*.log *.log
__debug_bin __debug_bin
settings.json settings.json

@ -11,6 +11,10 @@ All notable changes to paopao-ce are documented in this file.
### Changed ### Changed
- change man content width to 600px and optimize tweet/comment/replay text length. [#333](https://github.com/rocboss/paopao-ce/pull/333) - change man content width to 600px and optimize tweet/comment/replay text length. [#333](https://github.com/rocboss/paopao-ce/pull/333)
## 0.3.1
### Fixed
- fixed: video player assets cdn error. [&caff8c0](https://github.com/rocboss/paopao-ce/commit/caff8c052be6c8d59576011192f830fd98e17ab3 'commit caff8c0')
## 0.3.0 ## 0.3.0
### Added ### Added
@ -70,6 +74,10 @@ All notable changes to paopao-ce are documented in this file.
- fixed user not list owner's collectioned private tweet error [#274](https://github.com/rocboss/paopao-ce/pull/274) - fixed user not list owner's collectioned private tweet error [#274](https://github.com/rocboss/paopao-ce/pull/274)
- fixed comments thumbs up/down state incorrect error [#283](https://github.com/rocboss/paopao-ce/pull/283) - fixed comments thumbs up/down state incorrect error [#283](https://github.com/rocboss/paopao-ce/pull/283)
### Fixed
- fixed sql ddl p_contact's column `is_delete` define error (change to `is_del`) in scripts/paopao-mysql.sql [&afd8fe1](https://github.com/rocboss/paopao-ce/commit/afd8fe18d2dce08a4af846c2f822379d99a3d3b3 'commit afd8fe1')
### Changed ### Changed
- use [github.com/rueian/rueidis](https://github.com/rueian/rueidis) as Redis client [#249](https://github.com/rocboss/paopao-ce/pull/249) - use [github.com/rueian/rueidis](https://github.com/rueian/rueidis) as Redis client [#249](https://github.com/rocboss/paopao-ce/pull/249)

@ -7,7 +7,7 @@ endif
TARGET_BIN = $(basename $(TARGET)) TARGET_BIN = $(basename $(TARGET))
ifeq (n$(CGO_ENABLED),n) ifeq (n$(CGO_ENABLED),n)
CGO_ENABLED := 0 CGO_ENABLED := 1
endif endif
RELEASE_ROOT = release RELEASE_ROOT = release

@ -30,6 +30,7 @@ type Priv interface {
DeleteComment(*web.DeleteCommentReq) mir.Error DeleteComment(*web.DeleteCommentReq) mir.Error
CreateComment(*web.CreateCommentReq) (*web.CreateCommentResp, mir.Error) CreateComment(*web.CreateCommentReq) (*web.CreateCommentResp, mir.Error)
VisibleTweet(*web.VisibleTweetReq) (*web.VisibleTweetResp, mir.Error) VisibleTweet(*web.VisibleTweetReq) (*web.VisibleTweetResp, mir.Error)
HighlightTweet(*web.HighlightTweetReq) (*web.HighlightTweetResp, mir.Error)
StickTweet(*web.StickTweetReq) (*web.StickTweetResp, mir.Error) StickTweet(*web.StickTweetReq) (*web.StickTweetResp, mir.Error)
LockTweet(*web.LockTweetReq) (*web.LockTweetResp, mir.Error) LockTweet(*web.LockTweetReq) (*web.LockTweetResp, mir.Error)
CollectionTweet(*web.CollectionTweetReq) (*web.CollectionTweetResp, mir.Error) CollectionTweet(*web.CollectionTweetReq) (*web.CollectionTweetResp, mir.Error)
@ -213,6 +214,20 @@ func RegisterPrivServant(e *gin.Engine, s Priv) {
resp, err := s.VisibleTweet(req) resp, err := s.VisibleTweet(req)
s.Render(c, resp, err) s.Render(c, resp, err)
}) })
router.Handle("POST", "/post/highlight", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req := new(web.HighlightTweetReq)
if err := s.Bind(c, req); err != nil {
s.Render(c, nil, err)
return
}
resp, err := s.HighlightTweet(req)
s.Render(c, resp, err)
})
router.Handle("POST", "/post/stick", func(c *gin.Context) { router.Handle("POST", "/post/stick", func(c *gin.Context) {
select { select {
case <-c.Request.Context().Done(): case <-c.Request.Context().Done():
@ -399,6 +414,10 @@ func (UnimplementedPrivServant) VisibleTweet(req *web.VisibleTweetReq) (*web.Vis
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
} }
func (UnimplementedPrivServant) HighlightTweet(req *web.HighlightTweetReq) (*web.HighlightTweetResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedPrivServant) StickTweet(req *web.StickTweetReq) (*web.StickTweetResp, mir.Error) { func (UnimplementedPrivServant) StickTweet(req *web.StickTweetReq) (*web.StickTweetResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
} }

@ -102,7 +102,7 @@ services:
- paopao-network - paopao-network
backend: backend:
image: bitbus/paopao-ce:0.3.0 image: bitbus/paopao-ce:0.3
restart: always restart: always
depends_on: depends_on:
- db - db

@ -0,0 +1,28 @@
| 编号 | 作者 | 发表时间 | 变更时间 | 版本 | 状态 |
| ----- | ----- | ----- | ----- | ----- | ----- |
| 010| 北野 | 2022-12-10 | 2022-12-10 | v0.0 | 提议 |
### 关于Sqlx功能项的设计
---- 这里写简要介绍 ----
### 场景
---- 这里描述在什么使用场景下会需要本提按 ----
### 需求
TODO-TL;DR...
### 方案
TODO
### 疑问
1. 如何开启这个功能?
TODO
### 更新记录
#### v0.0(2022-12-10) - 北野
* 初始文档, 先占个位置

@ -14,7 +14,7 @@ require (
github.com/cockroachdb/errors v1.10.0 github.com/cockroachdb/errors v1.10.0
github.com/disintegration/imaging v1.6.2 github.com/disintegration/imaging v1.6.2
github.com/fatih/color v1.15.0 github.com/fatih/color v1.15.0
github.com/getsentry/sentry-go v0.22.0 github.com/getsentry/sentry-go v0.23.0
github.com/gin-contrib/cors v1.4.0 github.com/gin-contrib/cors v1.4.0
github.com/gin-gonic/gin v1.9.1 github.com/gin-gonic/gin v1.9.1
github.com/go-resty/resty/v2 v2.7.0 github.com/go-resty/resty/v2 v2.7.0
@ -29,7 +29,7 @@ require (
github.com/onsi/ginkgo/v2 v2.11.0 github.com/onsi/ginkgo/v2 v2.11.0
github.com/onsi/gomega v1.27.10 github.com/onsi/gomega v1.27.10
github.com/pyroscope-io/client v0.7.1 github.com/pyroscope-io/client v0.7.1
github.com/redis/rueidis v1.0.13 github.com/redis/rueidis v1.0.14
github.com/sirupsen/logrus v1.9.3 github.com/sirupsen/logrus v1.9.3
github.com/smartwalle/alipay/v3 v3.2.14 github.com/smartwalle/alipay/v3 v3.2.14
github.com/sourcegraph/conc v0.3.0 github.com/sourcegraph/conc v0.3.0
@ -47,7 +47,7 @@ require (
gorm.io/gorm v1.25.2 gorm.io/gorm v1.25.2
gorm.io/plugin/dbresolver v1.4.1 gorm.io/plugin/dbresolver v1.4.1
gorm.io/plugin/soft_delete v1.2.1 gorm.io/plugin/soft_delete v1.2.1
modernc.org/sqlite v1.24.0 modernc.org/sqlite v1.25.0
) )
require ( require (
@ -88,7 +88,7 @@ require (
github.com/kr/pretty v0.3.1 // indirect github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect github.com/kr/text v0.2.0 // indirect
github.com/leodido/go-urn v1.2.4 // indirect github.com/leodido/go-urn v1.2.4 // indirect
github.com/lib/pq v1.10.2 // indirect github.com/lib/pq v1.10.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect github.com/magiconair/properties v1.8.7 // indirect
github.com/mailru/easyjson v0.7.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
@ -99,7 +99,7 @@ require (
github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mozillazg/go-httpheader v0.3.1 // indirect github.com/mozillazg/go-httpheader v0.2.1 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/pyroscope-io/godeltaprof v0.1.0 // indirect github.com/pyroscope-io/godeltaprof v0.1.0 // indirect
@ -121,7 +121,7 @@ require (
go.uber.org/atomic v1.9.0 // indirect go.uber.org/atomic v1.9.0 // indirect
golang.org/x/arch v0.3.0 // indirect golang.org/x/arch v0.3.0 // indirect
golang.org/x/crypto v0.11.0 // indirect golang.org/x/crypto v0.11.0 // indirect
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 // indirect golang.org/x/image v0.0.0-20210216034530-4410531fe030 // indirect
golang.org/x/mod v0.10.0 // indirect golang.org/x/mod v0.10.0 // indirect
golang.org/x/net v0.12.0 // indirect golang.org/x/net v0.12.0 // indirect
golang.org/x/sys v0.10.0 // indirect golang.org/x/sys v0.10.0 // indirect
@ -134,9 +134,9 @@ require (
lukechampine.com/uint128 v1.2.0 // indirect lukechampine.com/uint128 v1.2.0 // indirect
modernc.org/cc/v3 v3.40.0 // indirect modernc.org/cc/v3 v3.40.0 // indirect
modernc.org/ccgo/v3 v3.16.13 // indirect modernc.org/ccgo/v3 v3.16.13 // indirect
modernc.org/libc v1.22.5 // indirect modernc.org/libc v1.24.1 // indirect
modernc.org/mathutil v1.5.0 // indirect modernc.org/mathutil v1.5.0 // indirect
modernc.org/memory v1.5.0 // indirect modernc.org/memory v1.6.0 // indirect
modernc.org/opt v0.1.3 // indirect modernc.org/opt v0.1.3 // indirect
modernc.org/strutil v1.1.3 // indirect modernc.org/strutil v1.1.3 // indirect
modernc.org/token v1.0.1 // indirect modernc.org/token v1.0.1 // indirect

@ -451,8 +451,8 @@ github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
github.com/getsentry/sentry-go v0.22.0 h1:XNX9zKbv7baSEI65l+H1GEJgSeIC1c7EN5kluWaP6dM= github.com/getsentry/sentry-go v0.23.0 h1:dn+QRCeJv4pPt9OjVXiMcGIBIefaTJPw/h0bZWO05nE=
github.com/getsentry/sentry-go v0.22.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/getsentry/sentry-go v0.23.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gin-contrib/cors v1.4.0 h1:oJ6gwtUl3lqV0WEIwM/LxPF1QZ5qe2lGWdY2+bz7y0g= github.com/gin-contrib/cors v1.4.0 h1:oJ6gwtUl3lqV0WEIwM/LxPF1QZ5qe2lGWdY2+bz7y0g=
@ -875,9 +875,8 @@ github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.10.0 h1:Zx5DJFEYQXio93kgXnQ09fXNiUKsqv4OUEu2UtGcB1E=
github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo= github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo=
github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
@ -972,9 +971,8 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/mozillazg/go-httpheader v0.2.1 h1:geV7TrjbL8KXSyvghnFm+NyTux/hxwueTSrwhe88TQQ=
github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60= github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60=
github.com/mozillazg/go-httpheader v0.3.1 h1:IRP+HFrMX2SlwY9riuio7raffXUpzAosHtZu25BSJok=
github.com/mozillazg/go-httpheader v0.3.1/go.mod h1:PuT8h0pw6efvp8ZeUec1Rs7dwjK08bt6gKSReGMqtdA=
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
@ -1111,8 +1109,8 @@ github.com/pyroscope-io/client v0.7.1 h1:yFRhj3vbgjBxehvxQmedmUWJQ4CAfCHhn+itPsu
github.com/pyroscope-io/client v0.7.1/go.mod h1:4h21iOU4pUOq0prKyDlvYRL+SCKsBc5wKiEtV+rJGqU= github.com/pyroscope-io/client v0.7.1/go.mod h1:4h21iOU4pUOq0prKyDlvYRL+SCKsBc5wKiEtV+rJGqU=
github.com/pyroscope-io/godeltaprof v0.1.0 h1:UBqtjt0yZi4jTxqZmLAs34XG6ycS3vUTlhEUSq4NHLE= github.com/pyroscope-io/godeltaprof v0.1.0 h1:UBqtjt0yZi4jTxqZmLAs34XG6ycS3vUTlhEUSq4NHLE=
github.com/pyroscope-io/godeltaprof v0.1.0/go.mod h1:psMITXp90+8pFenXkKIpNhrfmI9saQnPbba27VIaiQE= github.com/pyroscope-io/godeltaprof v0.1.0/go.mod h1:psMITXp90+8pFenXkKIpNhrfmI9saQnPbba27VIaiQE=
github.com/redis/rueidis v1.0.13 h1:wQFMLqXQQPCow05i3KZXMB0z/6n4P0/6UVfJ1qYnDW4= github.com/redis/rueidis v1.0.14 h1:qdFZahk1F/2L+sZeOECx5E2N5J4Qc51b7ezSUpQXJfs=
github.com/redis/rueidis v1.0.13/go.mod h1:Z4/sLVfaxsAPKj0EF6q2P/gO6clKuQ3CE34/f/cPNkI= github.com/redis/rueidis v1.0.14/go.mod h1:8B+r5wdnjwK3lTFml5VtxjzGOQAC+5UmujoD12pDrEo=
github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
@ -1401,9 +1399,8 @@ golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+o
golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20210216034530-4410531fe030 h1:lP9pYkih3DUSC641giIXa2XqfTIbbbRr0w2EOTA7wHA=
golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 h1:LRtI4W37N+KFebI/qV0OFiLUv4GLOWeEW5hn/KEJvxE=
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -2085,8 +2082,8 @@ modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
modernc.org/internal v1.0.0/go.mod h1:VUD/+JAkhCpvkUitlEOnhpVxCgsBI90oTzSCRcqQVSM= modernc.org/internal v1.0.0/go.mod h1:VUD/+JAkhCpvkUitlEOnhpVxCgsBI90oTzSCRcqQVSM=
modernc.org/libc v1.7.13-0.20210308123627-12f642a52bb8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w= modernc.org/libc v1.7.13-0.20210308123627-12f642a52bb8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
modernc.org/libc v1.9.5/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w= modernc.org/libc v1.9.5/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
modernc.org/libc v1.22.5 h1:91BNch/e5B0uPbJFgqbxXuOnxBQjlS//icfQEGmvyjE= modernc.org/libc v1.24.1 h1:uvJSeCKL/AgzBo2yYIPPTy82v21KgGnizcGYfBHaNuM=
modernc.org/libc v1.22.5/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY= modernc.org/libc v1.24.1/go.mod h1:FmfO1RLrU3MHJfyi9eYYmZBfi/R+tqZ6+hQ3yQQUkak=
modernc.org/lldb v1.0.0/go.mod h1:jcRvJGWfCGodDZz8BPwiKMJxGJngQ/5DrRapkQnLob8= modernc.org/lldb v1.0.0/go.mod h1:jcRvJGWfCGodDZz8BPwiKMJxGJngQ/5DrRapkQnLob8=
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
@ -2094,16 +2091,16 @@ modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ= modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc= modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc=
modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds= modernc.org/memory v1.6.0 h1:i6mzavxrE9a30whzMfwf7XWVODx2r5OYXvU46cirX7o=
modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/memory v1.6.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
modernc.org/ql v1.0.0/go.mod h1:xGVyrLIatPcO2C1JvI/Co8c0sr6y91HKFNy4pt9JXEY= modernc.org/ql v1.0.0/go.mod h1:xGVyrLIatPcO2C1JvI/Co8c0sr6y91HKFNy4pt9JXEY=
modernc.org/sortutil v1.1.0/go.mod h1:ZyL98OQHJgH9IEfN71VsamvJgrtRX9Dj2gX+vH86L1k= modernc.org/sortutil v1.1.0/go.mod h1:ZyL98OQHJgH9IEfN71VsamvJgrtRX9Dj2gX+vH86L1k=
modernc.org/sqlite v1.10.6/go.mod h1:Z9FEjUtZP4qFEg6/SiADg9XCER7aYy9a/j7Pg9P7CPs= modernc.org/sqlite v1.10.6/go.mod h1:Z9FEjUtZP4qFEg6/SiADg9XCER7aYy9a/j7Pg9P7CPs=
modernc.org/sqlite v1.24.0 h1:EsClRIWHGhLTCX44p+Ri/JLD+vFGo0QGjasg2/F9TlI= modernc.org/sqlite v1.25.0 h1:AFweiwPNd/b3BoKnBOfFm+Y260guGMF+0UFk0savqeA=
modernc.org/sqlite v1.24.0/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk= modernc.org/sqlite v1.25.0/go.mod h1:FL3pVXie73rg3Rii6V/u5BoHlSoyeZeIgKZEgHARyCU=
modernc.org/strutil v1.1.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= modernc.org/strutil v1.1.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY=
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=

@ -1,84 +1,68 @@
// Copyright 2022 ROC. All rights reserved. // Copyright 2023 ROC. All rights reserved.
// Use of this source code is governed by a MIT style // Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package conf package conf
import ( import (
"database/sql"
"sync" "sync"
"time"
"github.com/alimy/cfg" "github.com/alimy/cfg"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"gorm.io/driver/mysql"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"gorm.io/gorm/schema"
"gorm.io/plugin/dbresolver"
) )
var ( var (
_gormDB *gorm.DB _sqldb *sql.DB
_onceGorm sync.Once _onceSql sync.Once
) )
func MustGormDB() *gorm.DB { const (
_onceGorm.Do(func() { TableAnouncement = "user"
TableAnouncementContent = "anouncement_content"
TableAttachment = "attachment"
TableCaptcha = "captcha"
TableComment = "comment"
TableCommentContent = "comment_content"
TableCommentReply = "comment_reply"
TableContact = "contact"
TableContactGroup = "contact_group"
TableMessage = "message"
TablePost = "post"
TablePostAttachmentBill = "post_attachment_bill"
TablePostCollection = "post_collection"
TablePostContent = "post_content"
TablePostStar = "post_star"
TableTag = "tag"
TableUser = "user"
TableWalletRecharge = "wallet_recharge"
TableWalletStatement = "wallet_statement"
)
type TableNameMap map[string]string
func MustSqlDB() *sql.DB {
_onceSql.Do(func() {
var err error var err error
if _gormDB, err = newGormDB(); err != nil { if _, _sqldb, err = newSqlDB(); err != nil {
logrus.Fatalf("new gorm db failed: %s", err) logrus.Fatalf("new sql db failed: %s", err)
} }
}) })
return _gormDB return _sqldb
} }
func newGormDB() (*gorm.DB, error) { func newSqlDB() (driver string, db *sql.DB, err error) {
newLogger := logger.New(
logrus.StandardLogger(), // io writer日志输出的目标前缀和日志包含的内容
logger.Config{
SlowThreshold: time.Second, // 慢 SQL 阈值
LogLevel: DatabaseSetting.logLevel(), // 日志级别
IgnoreRecordNotFoundError: true, // 忽略ErrRecordNotFound记录未找到错误
Colorful: false, // 禁用彩色打印
},
)
config := &gorm.Config{
Logger: newLogger,
NamingStrategy: schema.NamingStrategy{
TablePrefix: DatabaseSetting.TablePrefix,
SingularTable: true,
},
}
plugin := dbresolver.Register(dbresolver.Config{}).
SetConnMaxIdleTime(time.Hour).
SetConnMaxLifetime(24 * time.Hour).
SetMaxIdleConns(MysqlSetting.MaxIdleConns).
SetMaxOpenConns(MysqlSetting.MaxOpenConns)
var (
db *gorm.DB
err error
)
if cfg.If("MySQL") { if cfg.If("MySQL") {
logrus.Debugln("use MySQL as db") driver = "mysql"
if db, err = gorm.Open(mysql.Open(MysqlSetting.Dsn()), config); err == nil { db, err = sql.Open(driver, MysqlSetting.Dsn())
db.Use(plugin) } else if cfg.If("PostgreSQL") || cfg.If("Postgres") {
} driver = "pgx"
} else if cfg.If("Postgres") { db, err = sql.Open(driver, PostgresSetting.Dsn())
logrus.Debugln("use PostgreSQL as db")
db, err = gorm.Open(postgres.Open(PostgresSetting.Dsn()), config)
} else if cfg.If("Sqlite3") { } else if cfg.If("Sqlite3") {
logrus.Debugf("use Sqlite3 as db path:%s sqlite3InCgoEnabled:%t", Sqlite3Setting.Path, sqlite3InCgoEnabled) driver, db, err = OpenSqlite3()
db, err = gormOpenSqlite3(config)
} else { } else {
logrus.Debugln("use default of MySQL as db") driver = "mysql"
if db, err = gorm.Open(mysql.Open(MysqlSetting.Dsn()), config); err == nil { db, err = sql.Open(driver, MysqlSetting.Dsn())
db.Use(plugin)
}
} }
return
return db, err
} }

@ -18,8 +18,9 @@ const (
sqlite3InCgoEnabled = true sqlite3InCgoEnabled = true
) )
func OpenSqlite3() (*sql.DB, error) { func OpenSqlite3() (string, *sql.DB, error) {
return sql.Open("sqlite3", Sqlite3Setting.Dsn("sqlite3")) db, err := sql.Open("sqlite3", Sqlite3Setting.Dsn("sqlite3"))
return "sqlite3", db, err
} }
func gormOpenSqlite3(opts ...gorm.Option) (*gorm.DB, error) { func gormOpenSqlite3(opts ...gorm.Option) (*gorm.DB, error) {

@ -0,0 +1,84 @@
// Copyright 2022 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 conf
import (
"sync"
"time"
"github.com/alimy/cfg"
"github.com/sirupsen/logrus"
"gorm.io/driver/mysql"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"gorm.io/gorm/schema"
"gorm.io/plugin/dbresolver"
)
var (
_gormdb *gorm.DB
_onceGorm sync.Once
)
func MustGormDB() *gorm.DB {
_onceGorm.Do(func() {
var err error
if _gormdb, err = newGormDB(); err != nil {
logrus.Fatalf("new gorm db failed: %s", err)
}
})
return _gormdb
}
func newGormDB() (*gorm.DB, error) {
newLogger := logger.New(
logrus.StandardLogger(), // io writer日志输出的目标前缀和日志包含的内容
logger.Config{
SlowThreshold: time.Second, // 慢 SQL 阈值
LogLevel: DatabaseSetting.logLevel(), // 日志级别
IgnoreRecordNotFoundError: true, // 忽略ErrRecordNotFound记录未找到错误
Colorful: false, // 禁用彩色打印
},
)
config := &gorm.Config{
Logger: newLogger,
NamingStrategy: schema.NamingStrategy{
TablePrefix: DatabaseSetting.TablePrefix,
SingularTable: true,
},
}
plugin := dbresolver.Register(dbresolver.Config{}).
SetConnMaxIdleTime(time.Hour).
SetConnMaxLifetime(24 * time.Hour).
SetMaxIdleConns(MysqlSetting.MaxIdleConns).
SetMaxOpenConns(MysqlSetting.MaxOpenConns)
var (
db *gorm.DB
err error
)
if cfg.If("MySQL") {
logrus.Debugln("use MySQL as db")
if db, err = gorm.Open(mysql.Open(MysqlSetting.Dsn()), config); err == nil {
db.Use(plugin)
}
} else if cfg.If("Postgres") {
logrus.Debugln("use PostgreSQL as db")
db, err = gorm.Open(postgres.Open(PostgresSetting.Dsn()), config)
} else if cfg.If("Sqlite3") {
logrus.Debugf("use Sqlite3 as db path:%s sqlite3InCgoEnabled:%t", Sqlite3Setting.Path, sqlite3InCgoEnabled)
db, err = gormOpenSqlite3(config)
} else {
logrus.Debugln("use default of MySQL as db")
if db, err = gorm.Open(mysql.Open(MysqlSetting.Dsn()), config); err == nil {
db.Use(plugin)
}
}
return db, err
}

@ -19,8 +19,9 @@ const (
sqlite3InCgoEnabled = false sqlite3InCgoEnabled = false
) )
func OpenSqlite3() (*sql.DB, error) { func OpenSqlite3() (string, *sql.DB, error) {
return sql.Open("sqlite", Sqlite3Setting.Dsn("sqlite")) db, err := sql.Open("sqlite", Sqlite3Setting.Dsn("sqlite"))
return "sqlite", db, err
} }
func gormOpenSqlite3(opts ...gorm.Option) (*gorm.DB, error) { func gormOpenSqlite3(opts ...gorm.Option) (*gorm.DB, error) {

@ -296,6 +296,35 @@ func (s *databaseConf) logLevel() logger.LogLevel {
} }
} }
func (s *databaseConf) TableNames() (res TableNameMap) {
tableNames := []string{
TableAnouncement,
TableAnouncementContent,
TableAttachment,
TableCaptcha,
TableComment,
TableCommentContent,
TableCommentReply,
TableContact,
TableContactGroup,
TableMessage,
TablePost,
TablePostAttachmentBill,
TablePostCollection,
TablePostContent,
TablePostStar,
TableTag,
TableUser,
TableWalletRecharge,
TableWalletStatement,
}
res = make(TableNameMap, len(tableNames))
for _, name := range tableNames {
res[name] = s.TablePrefix + name
}
return
}
func (s *loggerConf) logLevel() logrus.Level { func (s *loggerConf) logLevel() logrus.Level {
switch strings.ToLower(s.Level) { switch strings.ToLower(s.Level) {
case "panic": case "panic":

@ -5,119 +5,13 @@
package core package core
import ( import (
"github.com/rocboss/paopao-ce/pkg/types" "github.com/rocboss/paopao-ce/internal/core/ms"
) )
const (
ActRegisterUser act = iota
ActCreatePublicTweet
ActCreatePublicAttachment
ActCreatePublicPicture
ActCreatePublicVideo
ActCreatePrivateTweet
ActCreatePrivateAttachment
ActCreatePrivatePicture
ActCreatePrivateVideo
ActCreateFriendTweet
ActCreateFriendAttachment
ActCreateFriendPicture
ActCreateFriendVideo
ActCreatePublicComment
ActCreatePublicPicureComment
ActCreateFriendComment
ActCreateFriendPicureComment
ActCreatePrivateComment
ActCreatePrivatePicureComment
ActStickTweet
ActTopTweet
ActLockTweet
ActVisibleTweet
ActDeleteTweet
ActCreateActivationCode
)
type (
act uint8
FriendFilter map[int64]types.Empty
FriendSet map[string]types.Empty
Action struct {
Act act
UserId int64
}
)
func (f FriendFilter) IsFriend(userId int64) bool {
_, yeah := f[userId]
return yeah
}
// IsAllow default true if user is admin
func (a act) IsAllow(user *User, userId int64, isFriend bool, isActivation bool) bool {
if user.IsAdmin {
return true
}
if user.ID == userId && isActivation {
switch a {
case ActCreatePublicTweet,
ActCreatePublicAttachment,
ActCreatePublicPicture,
ActCreatePublicVideo,
ActCreatePrivateTweet,
ActCreatePrivateAttachment,
ActCreatePrivatePicture,
ActCreatePrivateVideo,
ActCreateFriendTweet,
ActCreateFriendAttachment,
ActCreateFriendPicture,
ActCreateFriendVideo,
ActCreatePrivateComment,
ActCreatePrivatePicureComment,
ActStickTweet,
ActLockTweet,
ActVisibleTweet,
ActDeleteTweet:
return true
}
}
if user.ID == userId && !isActivation {
switch a {
case ActCreatePrivateTweet,
ActCreatePrivateComment,
ActStickTweet,
ActLockTweet,
ActDeleteTweet:
return true
}
}
if isFriend && isActivation {
switch a {
case ActCreatePublicComment,
ActCreatePublicPicureComment,
ActCreateFriendComment,
ActCreateFriendPicureComment:
return true
}
}
if !isFriend && isActivation {
switch a {
case ActCreatePublicComment,
ActCreatePublicPicureComment:
return true
}
}
return false
}
// AuthorizationManageService 授权管理服务 // AuthorizationManageService 授权管理服务
type AuthorizationManageService interface { type AuthorizationManageService interface {
IsAllow(user *User, action *Action) bool IsAllow(user *ms.User, action *ms.Action) bool
BeFriendFilter(userId int64) FriendFilter BeFriendFilter(userId int64) ms.FriendFilter
BeFriendIds(userId int64) ([]int64, error) BeFriendIds(userId int64) ([]int64, error)
MyFriendSet(userId int64) FriendSet MyFriendSet(userId int64) ms.FriendSet
} }

@ -7,6 +7,8 @@ package core
import ( import (
"context" "context"
"github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
) )
@ -26,6 +28,11 @@ type IndexAction struct {
Post *dbr.Post Post *dbr.Post
} }
type IndexActionA struct {
Act IdxAct
Tweet *cs.TweetInfo
}
func (a IdxAct) String() string { func (a IdxAct) String() string {
switch a { switch a {
case IdxActNop: case IdxActNop:
@ -45,13 +52,20 @@ func (a IdxAct) String() string {
} }
} }
func NewIndexAction(act IdxAct, post *dbr.Post) *IndexAction { func NewIndexAction(act IdxAct, post *ms.Post) *IndexAction {
return &IndexAction{ return &IndexAction{
Act: act, Act: act,
Post: post, Post: post,
} }
} }
func NewIndexActionA(act IdxAct, tweet *cs.TweetInfo) *IndexActionA {
return &IndexActionA{
Act: act,
Tweet: tweet,
}
}
// CacheIndexService cache index service interface // CacheIndexService cache index service interface
type CacheIndexService interface { type CacheIndexService interface {
IndexPostsService IndexPostsService
@ -59,6 +73,13 @@ type CacheIndexService interface {
SendAction(act IdxAct, post *dbr.Post) SendAction(act IdxAct, post *dbr.Post)
} }
// CacheIndexServantA cache index service interface
type CacheIndexServantA interface {
IndexPostsServantA
SendAction(act IdxAct, tweet *cs.TweetInfo)
}
// RedisCache memory cache by Redis // RedisCache memory cache by Redis
type RedisCache interface { type RedisCache interface {
SetPushToSearchJob(ctx context.Context) error SetPushToSearchJob(ctx context.Context) error

@ -6,35 +6,27 @@ package core
import ( import (
"github.com/rocboss/paopao-ce/internal/core/cs" "github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr" "github.com/rocboss/paopao-ce/internal/core/ms"
)
type (
Comment = dbr.Comment
CommentFormated = dbr.CommentFormated
CommentReply = dbr.CommentReply
CommentContent = dbr.CommentContent
CommentReplyFormated = dbr.CommentReplyFormated
) )
// CommentService 评论检索服务 // CommentService 评论检索服务
type CommentService interface { type CommentService interface {
GetComments(conditions *ConditionsT, offset, limit int) ([]*Comment, error) GetComments(conditions *ms.ConditionsT, offset, limit int) ([]*ms.Comment, error)
GetCommentByID(id int64) (*Comment, error) GetCommentByID(id int64) (*ms.Comment, error)
GetCommentCount(conditions *ConditionsT) (int64, error) GetCommentCount(conditions *ms.ConditionsT) (int64, error)
GetCommentReplyByID(id int64) (*CommentReply, error) GetCommentReplyByID(id int64) (*ms.CommentReply, error)
GetCommentContentsByIDs(ids []int64) ([]*CommentContent, error) GetCommentContentsByIDs(ids []int64) ([]*ms.CommentContent, error)
GetCommentRepliesByID(ids []int64) ([]*CommentReplyFormated, error) GetCommentRepliesByID(ids []int64) ([]*ms.CommentReplyFormated, error)
GetCommentThumbsMap(userId int64, tweetId int64) (cs.CommentThumbsMap, cs.CommentThumbsMap, error) GetCommentThumbsMap(userId int64, tweetId int64) (cs.CommentThumbsMap, cs.CommentThumbsMap, error)
} }
// CommentManageService 评论管理服务 // CommentManageService 评论管理服务
type CommentManageService interface { type CommentManageService interface {
DeleteComment(comment *Comment) error DeleteComment(comment *ms.Comment) error
CreateComment(comment *Comment) (*Comment, error) CreateComment(comment *ms.Comment) (*ms.Comment, error)
CreateCommentReply(reply *CommentReply) (*CommentReply, error) CreateCommentReply(reply *ms.CommentReply) (*ms.CommentReply, error)
DeleteCommentReply(reply *CommentReply) error DeleteCommentReply(reply *ms.CommentReply) error
CreateCommentContent(content *CommentContent) (*CommentContent, error) CreateCommentContent(content *ms.CommentContent) (*ms.CommentContent, error)
ThumbsUpComment(userId int64, tweetId, commentId int64) error ThumbsUpComment(userId int64, tweetId, commentId int64) error
ThumbsDownComment(userId int64, tweetId, commentId int64) error ThumbsDownComment(userId int64, tweetId, commentId int64) error
ThumbsUpReply(userId int64, tweetId, commentId, replyId int64) error ThumbsUpReply(userId int64, tweetId, commentId, replyId int64) error

@ -38,3 +38,14 @@ type DataService interface {
// share_key服务 // share_key服务
ShareKeyService ShareKeyService
} }
// WebDataServantA Web数据服务集成(版本A)
type WebDataServantA interface {
// 话题服务
TopicServantA
// 推文服务
TweetServantA
TweetManageServantA
TweetHelpServantA
}

@ -0,0 +1,26 @@
// 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 cs
const (
ContactStatusRequesting int8 = iota + 1
ContactStatusAgree
ContactStatusReject
ContactStatusDeleted
)
type Contact struct {
ID int64 `db:"id" json:"id"`
UserId int64 `db:"user_id" json:"user_id"`
FriendId int64 `db:"friend_id" json:"friend_id"`
GroupId int64 `json:"group_id"`
Remark string `json:"remark"`
Status int8 `json:"status"` // 1请求好友, 2已同意好友, 3已拒绝好友, 4已删除好友
IsTop int8 `json:"is_top"`
IsBlack int8 `json:"is_black"`
NoticeEnable int8 `json:"notice_enable"`
IsDel int8 `json:"-"`
DeletedOn int64 `db:"-" json:"-"`
}

@ -0,0 +1,7 @@
// 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 cs contain core data service interface type
// model define
package cs

@ -0,0 +1,38 @@
// 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 cs
const (
// 搜索查询类型
TsQueryTypeDefault TsQueryType = "search"
TsQueryTypeTag TsQueryType = "tag"
)
type (
// TsQueryType 搜索查询类型
TsQueryType string
// TsDocList 索引条陈列表
TsDocList []TsDocItem
)
// TsQueryReq 搜索查询请求
type TsQueryReq struct {
Query string
Visibility []TweetVisibleType
Type TsQueryType
}
// TsQueryResp 搜索查询响应
type TsQueryResp struct {
Items TweetList
Total int64
}
// TsDocItem 索引条陈
type TsDocItem struct {
Post *TweetInfo
Content string
}

@ -0,0 +1,11 @@
// 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 cs
// TweetBox 推文列表盒子,包含其他一些关于推文列表的信息
type TweetBox struct {
Tweets TweetList
Total int64
}

@ -0,0 +1,55 @@
// 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 cs
const (
// 标签类型
TagTypeHot TagType = "hot"
TagTypeNew TagType = "new"
TagTypeFollow TagType = "follow"
TagTypeHotExtral TagType = "hot_extral"
)
type (
// TagType 标签类型
TagType string
// TagInfoList 标签信息列表
TagInfoList []*TagInfo
// TagList 标签列表
TagList []*TagItem
)
// TagInfo 标签信息
type TagInfo struct {
ID int64 `json:"id" db:"id"`
UserID int64 `json:"user_id" db:"user_id"`
Tag string `json:"tag"`
QuoteNum int64 `json:"quote_num" db:"quote_num"`
}
// TagItem 标签信息条陈
type TagItem struct {
ID int64 `json:"id"`
UserID int64 `json:"user_id"`
User *UserInfo `json:"user" db:"u"`
Tag string `json:"tag"`
QuoteNum int64 `json:"quote_num"`
IsFollowing int8 `json:"is_following"`
IsTop int8 `json:"is_top"`
}
func (t *TagInfo) Format() *TagItem {
return &TagItem{
ID: t.ID,
UserID: t.UserID,
User: &UserInfo{},
Tag: t.Tag,
QuoteNum: t.QuoteNum,
IsFollowing: 0,
IsTop: 0,
}
}

@ -0,0 +1,12 @@
// 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 cs
type AttachmentBill struct {
ID int64 `json:"id"`
PostID int64 `json:"post_id"`
UserID int64 `json:"user_id"`
PaidAmount int64 `json:"paid_amount"`
}

@ -0,0 +1,141 @@
// 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 cs
const (
// 推文内容分快类型
TweetBlockTitle TweetBlockType = iota + 1
TweetBlockText
TweetBlockImage
TweetBlockVideo
TweetBlockAudio
TweetBlockLink
TweetBlockAttachment
TweetBlockChargeAttachment
// 推文可见性
TweetVisitPublic TweetVisibleType = iota
TweetVisitPrivate
TweetVisitFriend
TweetVisitInvalid
// 附件类型
AttachmentTypeImage AttachmentType = iota + 1
AttachmentTypeVideo
AttachmentTypeOther
)
type (
// TweetBlockType 推文内容分块类型1标题2文字段落3图片地址4视频地址5语音地址6链接地址7附件资源
// TODO: 优化一下类型为 uint8 需要底层数据库同步修改
TweetBlockType int
// TweetVisibleType 推文可见性0公开1私密2好友
TweetVisibleType uint8
// AttachmentType 附件类型, 1图片 2视频 3其他
// TODO: 优化一下类型为 uint8 需要底层数据库同步修改
AttachmentType int
// TweetList 推文列表
TweetList []*TweetItem
// TweetInfoList 推文信息列表
TweetInfoList []*TweetInfo
// FavoriteList 收藏列表
FavoriteList []*FavoriteItem
// ReactionList 点赞列表
ReactionList []*ReactionItem
// TweetBlockList 推文分块列表
TweetBlockList []*TweetBlock
)
// TweetBlock 推文分块
type TweetBlock struct {
ID int64 `json:"id" binding:"-"`
PostID int64 `json:"post_id" binding:"-"`
Content string `json:"content" binding:"required"`
Type TweetBlockType `json:"type" binding:"required"`
Sort int64 `json:"sort" binding:"required"`
}
// TweetInfo 推文信息
type TweetInfo struct {
ID int64 `json:"id"`
UserID int64 `json:"user_id"`
CommentCount int64 `json:"comment_count"`
CollectionCount int64 `json:"collection_count"`
UpvoteCount int64 `json:"upvote_count"`
Visibility TweetVisibleType `json:"visibility"`
IsTop int `json:"is_top"`
IsEssence int `json:"is_essence"`
IsLock int `json:"is_lock"`
LatestRepliedOn int64 `json:"latest_replied_on"`
Tags string `json:"tags"`
AttachmentPrice int64 `json:"attachment_price"`
IP string `json:"ip"`
IPLoc string `json:"ip_loc"`
CreatedOn int64 `json:"created_on"`
ModifiedOn int64 `json:"modified_on"`
}
// TweetItem 一条推文信息
type TweetItem struct {
ID int64 `json:"id"`
UserID int64 `json:"user_id"`
User *UserInfo `db:"user" json:"user"`
Contents []*TweetBlock `db:"-" json:"contents"`
CommentCount int64 `json:"comment_count"`
CollectionCount int64 `json:"collection_count"`
UpvoteCount int64 `json:"upvote_count"`
Visibility TweetVisibleType `json:"visibility"`
IsTop int `json:"is_top"`
IsEssence int `json:"is_essence"`
IsLock int `json:"is_lock"`
LatestRepliedOn int64 `json:"latest_replied_on"`
CreatedOn int64 `json:"created_on"`
ModifiedOn int64 `json:"modified_on"`
Tags map[string]int8 `json:"tags"`
AttachmentPrice int64 `json:"attachment_price"`
IPLoc string `json:"ip_loc"`
}
type Attachment struct {
ID int64 `json:"id"`
UserID int64 `json:"user_id"`
FileSize int64 `json:"file_size"`
ImgWidth int `json:"img_width"`
ImgHeight int `json:"img_height"`
Type AttachmentType `json:"type"`
Content string `json:"content"`
}
// Favorite 收藏
type FavoriteItem struct {
ID int64 `json:"id"`
Tweet *TweetInfo `json:"-"`
TweetID int64 `json:"post_id"`
UserID int64 `json:"user_id"`
}
// Reaction 反应、表情符号, 点赞、喜欢等
type ReactionItem struct {
ID int64 `json:"id"`
Tweet *TweetInfo `json:"-"`
TweetID int64 `json:"post_id"`
UserID int64 `json:"user_id"`
}
type NewTweetReq struct {
Contents TweetBlockList `json:"contents" binding:"required"`
Tags []string `json:"tags" binding:"required"`
Users []string `json:"users" binding:"required"`
AttachmentPrice int64 `json:"attachment_price"`
Visibility TweetVisibleType `json:"visibility"`
ClientIP string `json:"-" binding:"-"`
}

@ -0,0 +1,20 @@
// 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 cs
type (
// UserInfoList 用户信息列表
UserInfoList []*UserInfo
)
// UserInfo 用户基本信息
type UserInfo struct {
ID int64 `json:"id"`
Nickname string `json:"nickname"`
Username string `json:"username"`
Status int `json:"status"`
Avatar string `json:"avatar"`
IsAdmin bool `json:"is_admin"`
}

@ -5,32 +5,15 @@
package core package core
import ( import (
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr" "github.com/rocboss/paopao-ce/internal/core/ms"
)
const (
MsgTypePost = dbr.MsgTypePost
MsgtypeComment = dbr.MsgtypeComment
MsgTypeReply = dbr.MsgTypeReply
MsgTypeWhisper = dbr.MsgTypeWhisper
MsgTypeRequestingFriend = dbr.MsgTypeRequestingFriend
MsgTypeSystem = dbr.MsgTypeSystem
MsgStatusUnread = dbr.MsgStatusUnread
MsgStatusReaded = dbr.MsgStatusReaded
)
type (
Message = dbr.Message
MessageFormated = dbr.MessageFormated
) )
// MessageService 消息服务 // MessageService 消息服务
type MessageService interface { type MessageService interface {
CreateMessage(msg *Message) (*Message, error) CreateMessage(msg *ms.Message) (*ms.Message, error)
GetUnreadCount(userID int64) (int64, error) GetUnreadCount(userID int64) (int64, error)
GetMessageByID(id int64) (*Message, error) GetMessageByID(id int64) (*ms.Message, error)
ReadMessage(message *Message) error ReadMessage(message *ms.Message) error
GetMessages(conditions *ConditionsT, offset, limit int) ([]*MessageFormated, error) GetMessages(conditions *ms.ConditionsT, offset, limit int) ([]*ms.MessageFormated, error)
GetMessageCount(conditions *ConditionsT) (int64, error) GetMessageCount(conditions *ms.ConditionsT) (int64, error)
} }

@ -0,0 +1,115 @@
// 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 ms
import (
"github.com/rocboss/paopao-ce/pkg/types"
)
const (
ActRegisterUser act = iota
ActCreatePublicTweet
ActCreatePublicAttachment
ActCreatePublicPicture
ActCreatePublicVideo
ActCreatePrivateTweet
ActCreatePrivateAttachment
ActCreatePrivatePicture
ActCreatePrivateVideo
ActCreateFriendTweet
ActCreateFriendAttachment
ActCreateFriendPicture
ActCreateFriendVideo
ActCreatePublicComment
ActCreatePublicPicureComment
ActCreateFriendComment
ActCreateFriendPicureComment
ActCreatePrivateComment
ActCreatePrivatePicureComment
ActStickTweet
ActTopTweet
ActLockTweet
ActVisibleTweet
ActDeleteTweet
ActCreateActivationCode
)
type (
act uint8
FriendFilter map[int64]types.Empty
FriendSet map[string]types.Empty
Action struct {
Act act
UserId int64
}
)
func (f FriendFilter) IsFriend(userId int64) bool {
_, yeah := f[userId]
return yeah
}
// IsAllow default true if user is admin
func (a act) IsAllow(user *User, userId int64, isFriend bool, isActivation bool) bool {
if user.IsAdmin {
return true
}
if user.ID == userId && isActivation {
switch a {
case ActCreatePublicTweet,
ActCreatePublicAttachment,
ActCreatePublicPicture,
ActCreatePublicVideo,
ActCreatePrivateTweet,
ActCreatePrivateAttachment,
ActCreatePrivatePicture,
ActCreatePrivateVideo,
ActCreateFriendTweet,
ActCreateFriendAttachment,
ActCreateFriendPicture,
ActCreateFriendVideo,
ActCreatePrivateComment,
ActCreatePrivatePicureComment,
ActStickTweet,
ActLockTweet,
ActVisibleTweet,
ActDeleteTweet:
return true
}
}
if user.ID == userId && !isActivation {
switch a {
case ActCreatePrivateTweet,
ActCreatePrivateComment,
ActStickTweet,
ActLockTweet,
ActDeleteTweet:
return true
}
}
if isFriend && isActivation {
switch a {
case ActCreatePublicComment,
ActCreatePublicPicureComment,
ActCreateFriendComment,
ActCreateFriendPicureComment:
return true
}
}
if !isFriend && isActivation {
switch a {
case ActCreatePublicComment,
ActCreatePublicPicureComment:
return true
}
}
return false
}

@ -0,0 +1,17 @@
// 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 ms
import (
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
)
type (
Comment = dbr.Comment
CommentFormated = dbr.CommentFormated
CommentReply = dbr.CommentReply
CommentContent = dbr.CommentContent
CommentReplyFormated = dbr.CommentReplyFormated
)

@ -0,0 +1,26 @@
// 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 ms
import (
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
)
const (
MsgTypePost = dbr.MsgTypePost
MsgtypeComment = dbr.MsgtypeComment
MsgTypeReply = dbr.MsgTypeReply
MsgTypeWhisper = dbr.MsgTypeWhisper
MsgTypeRequestingFriend = dbr.MsgTypeRequestingFriend
MsgTypeSystem = dbr.MsgTypeSystem
MsgStatusUnread = dbr.MsgStatusUnread
MsgStatusReaded = dbr.MsgStatusReaded
)
type (
Message = dbr.Message
MessageFormated = dbr.MessageFormated
)

@ -1,8 +1,10 @@
// Copyright 2022 ROC. All rights reserved. // Copyright 2023 ROC. All rights reserved.
// Use of this source code is governed by a MIT style // Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package core // Package ms contain core data service interface type
// model define for gorm adapter
package ms
import ( import (
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"

@ -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 ms
import (
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
)
type (
Captcha = dbr.Captcha
)

@ -0,0 +1,10 @@
// 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 ms
type IndexTweetList struct {
Tweets []*PostFormated
Total int64
}

@ -0,0 +1,43 @@
// 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 ms
import (
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
)
const (
AttachmentTypeImage = dbr.AttachmentTypeImage
AttachmentTypeVideo = dbr.AttachmentTypeVideo
AttachmentTypeOther = dbr.AttachmentTypeOther
// 类型1标题2文字段落3图片地址4视频地址5语音地址6链接地址7附件资源
ContentTypeTitle = dbr.ContentTypeTitle
ContentTypeText = dbr.ContentTypeText
ContentTypeImage = dbr.ContentTypeImage
ContentTypeVideo = dbr.ContentTypeVideo
ContentTypeAudio = dbr.ContentTypeAudio
ContentTypeLink = dbr.ContentTypeLink
ContentTypeAttachment = dbr.ContentTypeAttachment
ContentTypeChargeAttachment = dbr.ContentTypeChargeAttachment
)
const (
PostVisitPublic PostVisibleT = iota
PostVisitPrivate
PostVisitFriend
PostVisitInvalid
)
type (
PostStar = dbr.PostStar
PostCollection = dbr.PostCollection
PostAttachmentBill = dbr.PostAttachmentBill
PostContent = dbr.PostContent
Attachment = dbr.Attachment
AttachmentType = dbr.AttachmentType
PostContentT = dbr.PostContentT
PostVisibleT = dbr.PostVisibleT
)

@ -0,0 +1,20 @@
// 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 ms
type (
ContactItem struct {
UserId int64 `json:"user_id"`
UserName string `db:"username" json:"username"`
Nickname string `json:"nickname"`
Avatar string `json:"avatar"`
Phone string `json:"phone"`
}
ContactList struct {
Contacts []ContactItem `json:"contacts"`
Total int64 `json:"total"`
}
)

@ -0,0 +1,14 @@
// 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 ms
import (
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
)
type (
WalletStatement = dbr.WalletStatement
WalletRecharge = dbr.WalletRecharge
)

@ -5,6 +5,7 @@
package core package core
import ( import (
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
) )
@ -21,6 +22,7 @@ const (
) )
type ( type (
// PostVisibleT 可访问类型0公开1私密2好友
PostVisibleT = dbr.PostVisibleT PostVisibleT = dbr.PostVisibleT
SearchType string SearchType string
@ -32,12 +34,12 @@ type (
} }
QueryResp struct { QueryResp struct {
Items []*PostFormated Items []*ms.PostFormated
Total int64 Total int64
} }
TsDocItem struct { TsDocItem struct {
Post *Post Post *ms.Post
Content string Content string
} }
) )
@ -47,5 +49,5 @@ type TweetSearchService interface {
IndexName() string IndexName() string
AddDocuments(data []TsDocItem, primaryKey ...string) (bool, error) AddDocuments(data []TsDocItem, primaryKey ...string) (bool, error)
DeleteDocuments(identifiers []string) error DeleteDocuments(identifiers []string) error
Search(user *User, q *QueryReq, offset, limit int) (*QueryResp, error) Search(user *ms.User, q *QueryReq, offset, limit int) (*QueryResp, error)
} }

@ -7,17 +7,13 @@ package core
import ( import (
"time" "time"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr" "github.com/rocboss/paopao-ce/internal/core/ms"
)
type (
Captcha = dbr.Captcha
) )
// SecurityService 安全相关服务 // SecurityService 安全相关服务
type SecurityService interface { type SecurityService interface {
GetLatestPhoneCaptcha(phone string) (*Captcha, error) GetLatestPhoneCaptcha(phone string) (*ms.Captcha, error)
UsePhoneCaptcha(captcha *Captcha) error UsePhoneCaptcha(captcha *ms.Captcha) error
SendPhoneCaptcha(phone string) error SendPhoneCaptcha(phone string) error
} }

@ -0,0 +1,20 @@
// 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 core
import (
"github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/core/ms"
)
// IndexPostsService 广场首页推文列表服务
type IndexPostsService interface {
IndexPosts(user *ms.User, offset int, limit int) (*ms.IndexTweetList, error)
}
// IndexPostsServantA 广场首页推文列表服务(版本A)
type IndexPostsServantA interface {
IndexPosts(user *ms.User, limit int, offset int) (*cs.TweetBox, error)
}

@ -5,24 +5,27 @@
package core package core
import ( import (
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr" "github.com/rocboss/paopao-ce/internal/core/cs"
)
type (
Tag = dbr.Tag
TagFormated = dbr.TagFormated
) )
// TopicService 话题服务 // TopicService 话题服务
type TopicService interface { type TopicService interface {
CreateTag(tag *Tag) (*Tag, error) UpsertTags(userId int64, tags []string) (cs.TagInfoList, error)
DeleteTag(tag *Tag) error DecrTagsById(ids []int64) error
GetTags(conditions *ConditionsT, offset, limit int) ([]*Tag, error) ListTags(typ cs.TagType, limit int, offset int) (cs.TagList, error)
GetHotTags(userId int64, limit int, offset int) ([]*TagFormated, error) TagsByKeyword(keyword string) (cs.TagInfoList, error)
GetNewestTags(userId int64, limit int, offset int) ([]*TagFormated, error) GetHotTags(userId int64, limit int, offset int) (cs.TagList, error)
GetFollowTags(userId int64, limit int, offset int) ([]*TagFormated, error) GetNewestTags(userId int64, limit int, offset int) (cs.TagList, error)
GetTagsByKeyword(keyword string) ([]*Tag, error) GetFollowTags(userId int64, limit int, offset int) (cs.TagList, error)
FollowTopic(userId int64, topicId int64) error FollowTopic(userId int64, topicId int64) error
UnfollowTopic(userId int64, topicId int64) error UnfollowTopic(userId int64, topicId int64) error
StickTopic(userId int64, topicId int64) (int8, error) StickTopic(userId int64, topicId int64) (int8, error)
} }
// TopicServantA 话题服务(版本A)
type TopicServantA interface {
UpsertTags(userId int64, tags []string) (cs.TagInfoList, error)
DecrTagsById(ids []int64) error
ListTags(typ cs.TagType, limit int, offset int) (cs.TagList, error)
TagsByKeyword(keyword string) (cs.TagInfoList, error)
}

@ -5,79 +5,76 @@
package core package core
import ( import (
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr" "github.com/rocboss/paopao-ce/internal/core/cs"
) "github.com/rocboss/paopao-ce/internal/core/ms"
const (
AttachmentTypeImage = dbr.AttachmentTypeImage
AttachmentTypeVideo = dbr.AttachmentTypeVideo
AttachmentTypeOther = dbr.AttachmentTypeOther
// 类型1标题2文字段落3图片地址4视频地址5语音地址6链接地址7附件资源
ContentTypeTitle = dbr.ContentTypeTitle
ContentTypeText = dbr.ContentTypeText
ContentTypeImage = dbr.ContentTypeImage
ContentTypeVideo = dbr.ContentTypeVideo
ContentTypeAudio = dbr.ContentTypeAudio
ContentTypeLink = dbr.ContentTypeLink
ContentTypeAttachment = dbr.ContentTypeAttachment
ContentTypeChargeAttachment = dbr.ContentTypeChargeAttachment
)
type (
PostStar = dbr.PostStar
PostCollection = dbr.PostCollection
PostAttachmentBill = dbr.PostAttachmentBill
PostContent = dbr.PostContent
Attachment = dbr.Attachment
AttachmentType = dbr.AttachmentType
PostContentT = dbr.PostContentT
IndexTweetList struct {
Tweets []*PostFormated
Total int64
}
) )
// TweetService 推文检索服务 // TweetService 推文检索服务
type TweetService interface { type TweetService interface {
GetPostByID(id int64) (*Post, error) GetPostByID(id int64) (*ms.Post, error)
GetPosts(conditions *ConditionsT, offset, limit int) ([]*Post, error) GetPosts(conditions ms.ConditionsT, offset, limit int) ([]*ms.Post, error)
GetPostCount(conditions *ConditionsT) (int64, error) GetPostCount(conditions ms.ConditionsT) (int64, error)
GetUserPostStar(postID, userID int64) (*PostStar, error) GetUserPostStar(postID, userID int64) (*ms.PostStar, error)
GetUserPostStars(userID int64, offset, limit int) ([]*PostStar, error) GetUserPostStars(userID int64, offset, limit int) ([]*ms.PostStar, error)
GetUserPostStarCount(userID int64) (int64, error) GetUserPostStarCount(userID int64) (int64, error)
GetUserPostCollection(postID, userID int64) (*PostCollection, error) GetUserPostCollection(postID, userID int64) (*ms.PostCollection, error)
GetUserPostCollections(userID int64, offset, limit int) ([]*PostCollection, error) GetUserPostCollections(userID int64, offset, limit int) ([]*ms.PostCollection, error)
GetUserPostCollectionCount(userID int64) (int64, error) GetUserPostCollectionCount(userID int64) (int64, error)
GetPostAttatchmentBill(postID, userID int64) (*PostAttachmentBill, error) GetPostAttatchmentBill(postID, userID int64) (*ms.PostAttachmentBill, error)
GetPostContentsByIDs(ids []int64) ([]*PostContent, error) GetPostContentsByIDs(ids []int64) ([]*ms.PostContent, error)
GetPostContentByID(id int64) (*PostContent, error) GetPostContentByID(id int64) (*ms.PostContent, error)
} }
// TweetManageService 推文管理服务,包括创建/删除/更新推文 // TweetManageService 推文管理服务,包括创建/删除/更新推文
type TweetManageService interface { type TweetManageService interface {
CreateAttachment(attachment *Attachment) (*Attachment, error) CreatePost(post *ms.Post) (*ms.Post, error)
CreatePost(post *Post) (*Post, error) DeletePost(post *ms.Post) ([]string, error)
DeletePost(post *Post) ([]string, error) LockPost(post *ms.Post) error
LockPost(post *Post) error StickPost(post *ms.Post) error
StickPost(post *Post) error VisiblePost(post *ms.Post, visibility PostVisibleT) error
VisiblePost(post *Post, visibility PostVisibleT) error UpdatePost(post *ms.Post) error
UpdatePost(post *Post) error CreatePostStar(postID, userID int64) (*ms.PostStar, error)
CreatePostStar(postID, userID int64) (*PostStar, error) DeletePostStar(p *ms.PostStar) error
DeletePostStar(p *PostStar) error CreatePostCollection(postID, userID int64) (*ms.PostCollection, error)
CreatePostCollection(postID, userID int64) (*PostCollection, error) DeletePostCollection(p *ms.PostCollection) error
DeletePostCollection(p *PostCollection) error CreatePostContent(content *ms.PostContent) (*ms.PostContent, error)
CreatePostContent(content *PostContent) (*PostContent, error) CreateAttachment(obj *ms.Attachment) (int64, error)
} }
// TweetHelpService 推文辅助服务 // TweetHelpService 推文辅助服务
type TweetHelpService interface { type TweetHelpService interface {
RevampPosts(posts []*PostFormated) ([]*PostFormated, error) RevampPosts(posts []*ms.PostFormated) ([]*ms.PostFormated, error)
MergePosts(posts []*Post) ([]*PostFormated, error) MergePosts(posts []*ms.Post) ([]*ms.PostFormated, error)
}
// TweetServantA 推文检索服务(版本A)
type TweetServantA interface {
TweetInfoById(id int64) (*cs.TweetInfo, error)
TweetItemById(id int64) (*cs.TweetItem, error)
UserTweets(visitorId, userId int64) (cs.TweetList, error)
ReactionByTweetId(userId int64, tweetId int64) (*cs.ReactionItem, error)
UserReactions(userId int64, limit int, offset int) (cs.ReactionList, error)
FavoriteByTweetId(userId int64, tweetId int64) (*cs.FavoriteItem, error)
UserFavorites(userId int64, limit int, offset int) (cs.FavoriteList, error)
AttachmentByTweetId(userId int64, tweetId int64) (*cs.AttachmentBill, error)
}
// TweetManageServantA 推文管理服务,包括创建/删除/更新推文(版本A)
type TweetManageServantA interface {
CreateAttachment(obj *cs.Attachment) (int64, error)
CreateTweet(userId int64, req *cs.NewTweetReq) (*cs.TweetItem, error)
DeleteTweet(userId int64, tweetId int64) ([]string, error)
LockTweet(userId int64, tweetId int64) error
StickTweet(userId int64, tweetId int64) error
VisibleTweet(userId int64, visibility cs.TweetVisibleType) error
CreateReaction(userId int64, tweetId int64) error
DeleteReaction(userId int64, reactionId int64) error
CreateFavorite(userId int64, tweetId int64) error
DeleteFavorite(userId int64, favoriteId int64) error
} }
// IndexPostsService 广场首页推文列表服务 // TweetHelpServantA 推文辅助服务(版本A)
type IndexPostsService interface { type TweetHelpServantA interface {
IndexPosts(user *User, offset int, limit int) (*IndexTweetList, error) RevampTweets(tweets cs.TweetList) (cs.TweetList, error)
MergeTweets(tweets cs.TweetInfo) (cs.TweetList, error)
} }

@ -4,30 +4,17 @@
package core package core
type ( import "github.com/rocboss/paopao-ce/internal/core/ms"
ContactItem struct {
UserId int64 `json:"user_id"`
UserName string `json:"username"`
Nickname string `json:"nickname"`
Avatar string `json:"avatar"`
Phone string `json:"phone"`
}
ContactList struct {
Contacts []ContactItem `json:"contacts"`
Total int64 `json:"total"`
}
)
// UserManageService 用户管理服务 // UserManageService 用户管理服务
type UserManageService interface { type UserManageService interface {
GetUserByID(id int64) (*User, error) GetUserByID(id int64) (*ms.User, error)
GetUserByUsername(username string) (*User, error) GetUserByUsername(username string) (*ms.User, error)
GetUserByPhone(phone string) (*User, error) GetUserByPhone(phone string) (*ms.User, error)
GetUsersByIDs(ids []int64) ([]*User, error) GetUsersByIDs(ids []int64) ([]*ms.User, error)
GetUsersByKeyword(keyword string) ([]*User, error) GetUsersByKeyword(keyword string) ([]*ms.User, error)
CreateUser(user *User) (*User, error) CreateUser(user *ms.User) (*ms.User, error)
UpdateUser(user *User) error UpdateUser(user *ms.User) error
} }
// ContactManageService 联系人管理服务 // ContactManageService 联系人管理服务
@ -36,6 +23,6 @@ type ContactManageService interface {
AddFriend(userId int64, friendId int64) error AddFriend(userId int64, friendId int64) error
RejectFriend(userId int64, friendId int64) error RejectFriend(userId int64, friendId int64) error
DeleteFriend(userId int64, friendId int64) error DeleteFriend(userId int64, friendId int64) error
GetContacts(userId int64, offset int, limit int) (*ContactList, error) GetContacts(userId int64, offset int, limit int) (*ms.ContactList, error)
IsFriend(userID int64, friendID int64) bool IsFriend(userID int64, friendID int64) bool
} }

@ -5,20 +5,15 @@
package core package core
import ( import (
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr" "github.com/rocboss/paopao-ce/internal/core/ms"
)
type (
WalletStatement = dbr.WalletStatement
WalletRecharge = dbr.WalletRecharge
) )
// WalletService wallet service interface // WalletService wallet service interface
type WalletService interface { type WalletService interface {
GetUserWalletBills(userID int64, offset, limit int) ([]*WalletStatement, error) GetUserWalletBills(userID int64, offset, limit int) ([]*ms.WalletStatement, error)
GetUserWalletBillCount(userID int64) (int64, error) GetUserWalletBillCount(userID int64) (int64, error)
GetRechargeByID(id int64) (*WalletRecharge, error) GetRechargeByID(id int64) (*ms.WalletRecharge, error)
CreateRecharge(userId, amount int64) (*WalletRecharge, error) CreateRecharge(userId, amount int64) (*ms.WalletRecharge, error)
HandleRechargeSuccess(recharge *WalletRecharge, tradeNo string) error HandleRechargeSuccess(recharge *ms.WalletRecharge, tradeNo string) error
HandlePostAttachmentBought(post *Post, user *User) error HandlePostAttachmentBought(post *ms.Post, user *ms.User) error
} }

@ -15,6 +15,7 @@ import (
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/rocboss/paopao-ce/internal/conf" "github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/pkg/types" "github.com/rocboss/paopao-ce/pkg/types"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -30,7 +31,7 @@ var (
type postsEntry struct { type postsEntry struct {
key string key string
tweets *core.IndexTweetList tweets *ms.IndexTweetList
} }
type tweetsCache interface { type tweetsCache interface {
@ -54,7 +55,7 @@ type cacheIndexSrv struct {
preventDuration time.Duration preventDuration time.Duration
} }
func (s *cacheIndexSrv) IndexPosts(user *core.User, offset int, limit int) (*core.IndexTweetList, error) { func (s *cacheIndexSrv) IndexPosts(user *ms.User, offset int, limit int) (*ms.IndexTweetList, error) {
key := s.keyFrom(user, offset, limit) key := s.keyFrom(user, offset, limit)
posts, err := s.getPosts(key) posts, err := s.getPosts(key)
if err == nil { if err == nil {
@ -70,7 +71,7 @@ func (s *cacheIndexSrv) IndexPosts(user *core.User, offset int, limit int) (*cor
return posts, nil return posts, nil
} }
func (s *cacheIndexSrv) getPosts(key string) (*core.IndexTweetList, error) { func (s *cacheIndexSrv) getPosts(key string) (*ms.IndexTweetList, error) {
data, err := s.cache.getTweetsBytes(key) data, err := s.cache.getTweetsBytes(key)
if err != nil { if err != nil {
logrus.Debugf("cacheIndexSrv.getPosts get posts by key: %s from cache err: %v", key, err) logrus.Debugf("cacheIndexSrv.getPosts get posts by key: %s from cache err: %v", key, err)
@ -78,7 +79,7 @@ func (s *cacheIndexSrv) getPosts(key string) (*core.IndexTweetList, error) {
} }
buf := bytes.NewBuffer(data) buf := bytes.NewBuffer(data)
dec := gob.NewDecoder(buf) dec := gob.NewDecoder(buf)
var resp core.IndexTweetList var resp ms.IndexTweetList
if err := dec.Decode(&resp); err != nil { if err := dec.Decode(&resp); err != nil {
logrus.Debugf("cacheIndexSrv.getPosts get posts from cache in decode err: %v", err) logrus.Debugf("cacheIndexSrv.getPosts get posts from cache in decode err: %v", err)
return nil, err return nil, err
@ -86,7 +87,7 @@ func (s *cacheIndexSrv) getPosts(key string) (*core.IndexTweetList, error) {
return &resp, nil return &resp, nil
} }
func (s *cacheIndexSrv) cachePosts(key string, tweets *core.IndexTweetList) { func (s *cacheIndexSrv) cachePosts(key string, tweets *ms.IndexTweetList) {
entry := &postsEntry{key: key, tweets: tweets} entry := &postsEntry{key: key, tweets: tweets}
select { select {
case s.cachePostsCh <- entry: case s.cachePostsCh <- entry:
@ -112,7 +113,7 @@ func (s *cacheIndexSrv) setPosts(entry *postsEntry) {
logrus.Debugf("cacheIndexSrv.setPosts setPosts set cache by key: %s", entry.key) logrus.Debugf("cacheIndexSrv.setPosts setPosts set cache by key: %s", entry.key)
} }
func (s *cacheIndexSrv) keyFrom(user *core.User, offset int, limit int) string { func (s *cacheIndexSrv) keyFrom(user *ms.User, offset int, limit int) string {
var userId int64 = -1 var userId int64 = -1
if user != nil { if user != nil {
userId = user.ID userId = user.ID
@ -120,7 +121,7 @@ func (s *cacheIndexSrv) keyFrom(user *core.User, offset int, limit int) string {
return fmt.Sprintf("%s:%d:%d:%d", _cacheIndexKey, userId, offset, limit) return fmt.Sprintf("%s:%d:%d:%d", _cacheIndexKey, userId, offset, limit)
} }
func (s *cacheIndexSrv) SendAction(act core.IdxAct, post *core.Post) { func (s *cacheIndexSrv) SendAction(act core.IdxAct, post *ms.Post) {
action := core.NewIndexAction(act, post) action := core.NewIndexAction(act, post)
select { select {
case s.indexActionCh <- action: case s.indexActionCh <- action:
@ -168,7 +169,7 @@ func (s *cacheIndexSrv) handleIndexAction(action *core.IndexAction) {
func (s *cacheIndexSrv) deleteCacheByUserId(id int64, oneself bool) { func (s *cacheIndexSrv) deleteCacheByUserId(id int64, oneself bool) {
var keys []string var keys []string
userId := strconv.FormatInt(id, 10) userId := strconv.FormatInt(id, 10)
friendSet := core.FriendSet{} friendSet := ms.FriendSet{}
if !oneself { if !oneself {
friendSet = s.ams.MyFriendSet(id) friendSet = s.ams.MyFriendSet(id)
} }

@ -7,6 +7,9 @@ package cache
import ( import (
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/pkg/debug"
) )
var ( var (
@ -18,11 +21,16 @@ type noneCacheIndexServant struct {
ips core.IndexPostsService ips core.IndexPostsService
} }
func (s *noneCacheIndexServant) IndexPosts(user *core.User, offset int, limit int) (*core.IndexTweetList, error) { func (s *noneCacheIndexServant) IndexPosts(user *ms.User, offset int, limit int) (*ms.IndexTweetList, error) {
return s.ips.IndexPosts(user, offset, limit) return s.ips.IndexPosts(user, offset, limit)
} }
func (s *noneCacheIndexServant) SendAction(_act core.IdxAct, _post *core.Post) { func (s *noneCacheIndexServant) TweetTimeline(userId int64, offset int, limit int) (*cs.TweetBox, error) {
// TODO
return nil, debug.ErrNotImplemented
}
func (s *noneCacheIndexServant) SendAction(_act core.IdxAct, _post *ms.Post) {
// empty // empty
} }

@ -10,6 +10,9 @@ import (
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/pkg/debug"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -22,21 +25,21 @@ type simpleCacheIndexServant struct {
ips core.IndexPostsService ips core.IndexPostsService
indexActionCh chan core.IdxAct indexActionCh chan core.IdxAct
indexPosts *core.IndexTweetList indexPosts *ms.IndexTweetList
atomicIndex atomic.Value atomicIndex atomic.Value
maxIndexSize int maxIndexSize int
checkTick *time.Ticker checkTick *time.Ticker
expireIndexTick *time.Ticker expireIndexTick *time.Ticker
} }
func (s *simpleCacheIndexServant) IndexPosts(user *core.User, offset int, limit int) (*core.IndexTweetList, error) { func (s *simpleCacheIndexServant) IndexPosts(user *ms.User, offset int, limit int) (*ms.IndexTweetList, error) {
cacheResp := s.atomicIndex.Load().(*core.IndexTweetList) cacheResp := s.atomicIndex.Load().(*ms.IndexTweetList)
end := offset + limit end := offset + limit
if cacheResp != nil { if cacheResp != nil {
size := len(cacheResp.Tweets) size := len(cacheResp.Tweets)
logrus.Debugf("simpleCacheIndexServant.IndexPosts get index posts from cache posts: %d offset:%d limit:%d start:%d, end:%d", size, offset, limit, offset, end) logrus.Debugf("simpleCacheIndexServant.IndexPosts get index posts from cache posts: %d offset:%d limit:%d start:%d, end:%d", size, offset, limit, offset, end)
if size >= end { if size >= end {
return &core.IndexTweetList{ return &ms.IndexTweetList{
Tweets: cacheResp.Tweets[offset:end], Tweets: cacheResp.Tweets[offset:end],
Total: cacheResp.Total, Total: cacheResp.Total,
}, nil }, nil
@ -47,7 +50,12 @@ func (s *simpleCacheIndexServant) IndexPosts(user *core.User, offset int, limit
return s.ips.IndexPosts(user, offset, limit) return s.ips.IndexPosts(user, offset, limit)
} }
func (s *simpleCacheIndexServant) SendAction(act core.IdxAct, _post *core.Post) { func (s *simpleCacheIndexServant) TweetTimeline(userId int64, offset int, limit int) (*cs.TweetBox, error) {
// TODO
return nil, debug.ErrNotImplemented
}
func (s *simpleCacheIndexServant) SendAction(act core.IdxAct, _post *ms.Post) {
select { select {
case s.indexActionCh <- act: case s.indexActionCh <- act:
logrus.Debugf("simpleCacheIndexServant.SendAction send indexAction by chan: %s", act) logrus.Debugf("simpleCacheIndexServant.SendAction send indexAction by chan: %s", act)

@ -18,87 +18,114 @@ import (
) )
var ( var (
ts core.TweetSearchService ts core.TweetSearchService
ds core.DataService ds core.DataService
oss core.ObjectStorageService oss core.ObjectStorageService
webDsa core.WebDataServantA
onceTs, onceDs, onceOss sync.Once _onceInitial sync.Once
) )
func DataService() core.DataService { func DataService() core.DataService {
onceDs.Do(func() { lazyInitial()
var v core.VersionInfo
if cfg.If("Gorm") {
ds, v = jinzhu.NewDataService()
} else if cfg.All("Sqlx", "MySQL") {
ds, v = sakila.NewDataService()
} else if cfg.If("Sqlx") && cfg.Any("Postgres", "PostgreSQL") {
ds, v = slonik.NewDataService()
} else {
// default use gorm as orm for sql database
ds, v = jinzhu.NewDataService()
}
logrus.Infof("use %s as data service with version %s", v.Name(), v.Version())
})
return ds return ds
} }
func WebDataServantA() core.WebDataServantA {
lazyInitial()
return webDsa
}
func ObjectStorageService() core.ObjectStorageService { func ObjectStorageService() core.ObjectStorageService {
onceOss.Do(func() { lazyInitial()
var v core.VersionInfo
if cfg.If("AliOSS") {
oss, v = storage.MustAliossService()
} else if cfg.If("COS") {
oss, v = storage.NewCosService()
} else if cfg.If("HuaweiOBS") {
oss, v = storage.MustHuaweiobsService()
} else if cfg.If("MinIO") {
oss, v = storage.MustMinioService()
} else if cfg.If("S3") {
oss, v = storage.MustS3Service()
logrus.Infof("use S3 as object storage by version %s", v.Version())
return
} else if cfg.If("LocalOSS") {
oss, v = storage.MustLocalossService()
} else {
// default use AliOSS as object storage service
oss, v = storage.MustAliossService()
logrus.Infof("use default AliOSS as object storage by version %s", v.Version())
return
}
logrus.Infof("use %s as object storage by version %s", v.Name(), v.Version())
})
return oss return oss
} }
func TweetSearchService() core.TweetSearchService { func TweetSearchService() core.TweetSearchService {
onceTs.Do(func() { lazyInitial()
var v core.VersionInfo
ams := newAuthorizationManageService()
if cfg.If("Zinc") {
ts, v = search.NewZincTweetSearchService(ams)
} else if cfg.If("Meili") {
ts, v = search.NewMeiliTweetSearchService(ams)
} else {
// default use Zinc as tweet search service
ts, v = search.NewZincTweetSearchService(ams)
}
logrus.Infof("use %s as tweet search serice by version %s", v.Name(), v.Version())
ts = search.NewBridgeTweetSearchService(ts)
})
return ts return ts
} }
func newAuthorizationManageService() (s core.AuthorizationManageService) { func newAuthorizationManageService() (ams core.AuthorizationManageService) {
if cfg.If("Gorm") { if cfg.If("Gorm") {
s = jinzhu.NewAuthorizationManageService() ams = jinzhu.NewAuthorizationManageService()
} else if cfg.All("Sqlx", "MySQL") { } else if cfg.If("Sqlx") {
s = sakila.NewAuthorizationManageService() ams = sakila.NewAuthorizationManageService()
} else if cfg.If("Sqlx") && cfg.Any("Postgres", "PostgreSQL") { } else if cfg.If("Sqlc") && cfg.Any("Postgres", "PostgreSQL") {
s = slonik.NewAuthorizationManageService() ams = slonik.NewAuthorizationManageService()
} else { } else {
s = jinzhu.NewAuthorizationManageService() ams = jinzhu.NewAuthorizationManageService()
} }
return return
} }
// lazyInitial do some package lazy initialize for performance
func lazyInitial() {
_onceInitial.Do(func() {
initDsX()
initOSS()
initTsX()
})
}
func initDsX() {
var dsVer, dsaVer core.VersionInfo
if cfg.If("Gorm") {
ds, dsVer = jinzhu.NewDataService()
webDsa, dsaVer = jinzhu.NewWebDataServantA()
} else if cfg.If("Sqlx") {
ds, dsVer = sakila.NewDataService()
webDsa, dsaVer = sakila.NewWebDataServantA()
} else if cfg.If("Sqlc") && cfg.Any("Postgres", "PostgreSQL") {
ds, dsVer = slonik.NewDataService()
webDsa, dsaVer = slonik.NewWebDataServantA()
} else {
// default use gorm as orm for sql database
ds, dsVer = jinzhu.NewDataService()
webDsa, dsaVer = jinzhu.NewWebDataServantA()
}
logrus.Infof("use %s as core.DataService with version %s", dsVer.Name(), dsVer.Version())
logrus.Infof("use %s as core.ServantA with version %s", dsaVer.Name(), dsaVer.Version())
}
func initOSS() {
var v core.VersionInfo
if cfg.If("AliOSS") {
oss, v = storage.MustAliossService()
} else if cfg.If("COS") {
oss, v = storage.NewCosService()
} else if cfg.If("HuaweiOBS") {
oss, v = storage.MustHuaweiobsService()
} else if cfg.If("MinIO") {
oss, v = storage.MustMinioService()
} else if cfg.If("S3") {
oss, v = storage.MustS3Service()
logrus.Infof("use S3 as object storage by version %s", v.Version())
return
} else if cfg.If("LocalOSS") {
oss, v = storage.MustLocalossService()
} else {
// default use AliOSS as object storage service
oss, v = storage.MustAliossService()
logrus.Infof("use default AliOSS as object storage by version %s", v.Version())
return
}
logrus.Infof("use %s as object storage by version %s", v.Name(), v.Version())
}
func initTsX() {
var v core.VersionInfo
ams := newAuthorizationManageService()
cfg.On(cfg.Actions{
"Zinc": func() {
ts, v = search.NewZincTweetSearchService(ams)
},
"Meili": func() {
ts, v = search.NewMeiliTweetSearchService(ams)
},
}, func() {
ts, v = search.NewZincTweetSearchService(ams)
})
logrus.Infof("use %s as tweet search serice by version %s", v.Name(), v.Version())
ts = search.NewBridgeTweetSearchService(ts)
}

@ -6,26 +6,27 @@ package jinzhu
import ( import (
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"github.com/rocboss/paopao-ce/pkg/types" "github.com/rocboss/paopao-ce/pkg/types"
"gorm.io/gorm" "gorm.io/gorm"
) )
var ( var (
_ core.AuthorizationManageService = (*authorizationManageServant)(nil) _ core.AuthorizationManageService = (*authorizationManageSrv)(nil)
) )
type authorizationManageServant struct { type authorizationManageSrv struct {
db *gorm.DB db *gorm.DB
} }
func newAuthorizationManageService(db *gorm.DB) core.AuthorizationManageService { func newAuthorizationManageService(db *gorm.DB) core.AuthorizationManageService {
return &authorizationManageServant{ return &authorizationManageSrv{
db: db, db: db,
} }
} }
func (s *authorizationManageServant) IsAllow(user *core.User, action *core.Action) bool { func (s *authorizationManageSrv) IsAllow(user *ms.User, action *ms.Action) bool {
// user is activation if had bind phone // user is activation if had bind phone
isActivation := (len(user.Phone) != 0) isActivation := (len(user.Phone) != 0)
isFriend := s.isFriend(user.ID, action.UserId) isFriend := s.isFriend(user.ID, action.UserId)
@ -33,37 +34,37 @@ func (s *authorizationManageServant) IsAllow(user *core.User, action *core.Actio
return action.Act.IsAllow(user, action.UserId, isFriend, isActivation) return action.Act.IsAllow(user, action.UserId, isFriend, isActivation)
} }
func (s *authorizationManageServant) MyFriendSet(userId int64) core.FriendSet { func (s *authorizationManageSrv) MyFriendSet(userId int64) ms.FriendSet {
ids, err := (&dbr.Contact{UserId: userId}).MyFriendIds(s.db) ids, err := (&dbr.Contact{UserId: userId}).MyFriendIds(s.db)
if err != nil { if err != nil {
return core.FriendSet{} return ms.FriendSet{}
} }
resp := make(core.FriendSet, len(ids)) resp := make(ms.FriendSet, len(ids))
for _, id := range ids { for _, id := range ids {
resp[id] = types.Empty{} resp[id] = types.Empty{}
} }
return resp return resp
} }
func (s *authorizationManageServant) BeFriendFilter(userId int64) core.FriendFilter { func (s *authorizationManageSrv) BeFriendFilter(userId int64) ms.FriendFilter {
ids, err := (&dbr.Contact{FriendId: userId}).BeFriendIds(s.db) ids, err := (&dbr.Contact{FriendId: userId}).BeFriendIds(s.db)
if err != nil { if err != nil {
return core.FriendFilter{} return ms.FriendFilter{}
} }
resp := make(core.FriendFilter, len(ids)) resp := make(ms.FriendFilter, len(ids))
for _, id := range ids { for _, id := range ids {
resp[id] = types.Empty{} resp[id] = types.Empty{}
} }
return resp return resp
} }
func (s *authorizationManageServant) BeFriendIds(userId int64) ([]int64, error) { func (s *authorizationManageSrv) BeFriendIds(userId int64) ([]int64, error) {
return (&dbr.Contact{FriendId: userId}).BeFriendIds(s.db) return (&dbr.Contact{FriendId: userId}).BeFriendIds(s.db)
} }
func (s *authorizationManageServant) isFriend(userId int64, friendId int64) bool { func (s *authorizationManageSrv) isFriend(userId int64, friendId int64) bool {
contact, err := (&dbr.Contact{UserId: friendId, FriendId: userId}).GetByUserFriend(s.db) contact, err := (&dbr.Contact{UserId: friendId, FriendId: userId}).GetByUserFriend(s.db)
if err == nil || contact.Status == dbr.ContactStatusAgree { if err == nil || contact.Status == dbr.ContactStatusAgree {
return true return true

@ -9,37 +9,38 @@ import (
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/cs" "github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"github.com/rocboss/paopao-ce/pkg/types" "github.com/rocboss/paopao-ce/pkg/types"
"gorm.io/gorm" "gorm.io/gorm"
) )
var ( var (
_ core.CommentService = (*commentServant)(nil) _ core.CommentService = (*commentSrv)(nil)
_ core.CommentManageService = (*commentManageServant)(nil) _ core.CommentManageService = (*commentManageSrv)(nil)
) )
type commentServant struct { type commentSrv struct {
db *gorm.DB db *gorm.DB
} }
type commentManageServant struct { type commentManageSrv struct {
db *gorm.DB db *gorm.DB
} }
func newCommentService(db *gorm.DB) core.CommentService { func newCommentService(db *gorm.DB) core.CommentService {
return &commentServant{ return &commentSrv{
db: db, db: db,
} }
} }
func newCommentManageService(db *gorm.DB) core.CommentManageService { func newCommentManageService(db *gorm.DB) core.CommentManageService {
return &commentManageServant{ return &commentManageSrv{
db: db, db: db,
} }
} }
func (s *commentServant) GetCommentThumbsMap(userId int64, tweetId int64) (cs.CommentThumbsMap, cs.CommentThumbsMap, error) { func (s *commentSrv) GetCommentThumbsMap(userId int64, tweetId int64) (cs.CommentThumbsMap, cs.CommentThumbsMap, error) {
if userId < 0 { if userId < 0 {
return nil, nil, nil return nil, nil, nil
} }
@ -59,11 +60,11 @@ func (s *commentServant) GetCommentThumbsMap(userId int64, tweetId int64) (cs.Co
return commentThumbs, replyThumbs, nil return commentThumbs, replyThumbs, nil
} }
func (s *commentServant) GetComments(conditions *core.ConditionsT, offset, limit int) ([]*core.Comment, error) { func (s *commentSrv) GetComments(conditions *ms.ConditionsT, offset, limit int) ([]*ms.Comment, error) {
return (&dbr.Comment{}).List(s.db, conditions, offset, limit) return (&dbr.Comment{}).List(s.db, conditions, offset, limit)
} }
func (s *commentServant) GetCommentByID(id int64) (*core.Comment, error) { func (s *commentSrv) GetCommentByID(id int64) (*ms.Comment, error) {
comment := &dbr.Comment{ comment := &dbr.Comment{
Model: &dbr.Model{ Model: &dbr.Model{
ID: id, ID: id,
@ -72,7 +73,7 @@ func (s *commentServant) GetCommentByID(id int64) (*core.Comment, error) {
return comment.Get(s.db) return comment.Get(s.db)
} }
func (s *commentServant) GetCommentReplyByID(id int64) (*core.CommentReply, error) { func (s *commentSrv) GetCommentReplyByID(id int64) (*ms.CommentReply, error) {
reply := &dbr.CommentReply{ reply := &dbr.CommentReply{
Model: &dbr.Model{ Model: &dbr.Model{
ID: id, ID: id,
@ -81,18 +82,18 @@ func (s *commentServant) GetCommentReplyByID(id int64) (*core.CommentReply, erro
return reply.Get(s.db) return reply.Get(s.db)
} }
func (s *commentServant) GetCommentCount(conditions *core.ConditionsT) (int64, error) { func (s *commentSrv) GetCommentCount(conditions *ms.ConditionsT) (int64, error) {
return (&dbr.Comment{}).Count(s.db, conditions) return (&dbr.Comment{}).Count(s.db, conditions)
} }
func (s *commentServant) GetCommentContentsByIDs(ids []int64) ([]*core.CommentContent, error) { func (s *commentSrv) GetCommentContentsByIDs(ids []int64) ([]*ms.CommentContent, error) {
commentContent := &dbr.CommentContent{} commentContent := &dbr.CommentContent{}
return commentContent.List(s.db, &dbr.ConditionsT{ return commentContent.List(s.db, &dbr.ConditionsT{
"comment_id IN ?": ids, "comment_id IN ?": ids,
}, 0, 0) }, 0, 0)
} }
func (s *commentServant) GetCommentRepliesByID(ids []int64) ([]*core.CommentReplyFormated, error) { func (s *commentSrv) GetCommentRepliesByID(ids []int64) ([]*ms.CommentReplyFormated, error) {
CommentReply := &dbr.CommentReply{} CommentReply := &dbr.CommentReply{}
replies, err := CommentReply.List(s.db, &dbr.ConditionsT{ replies, err := CommentReply.List(s.db, &dbr.ConditionsT{
"comment_id IN ?": ids, "comment_id IN ?": ids,
@ -112,7 +113,7 @@ func (s *commentServant) GetCommentRepliesByID(ids []int64) ([]*core.CommentRepl
if err != nil { if err != nil {
return nil, err return nil, err
} }
repliesFormated := []*core.CommentReplyFormated{} repliesFormated := []*ms.CommentReplyFormated{}
for _, reply := range replies { for _, reply := range replies {
replyFormated := reply.Format() replyFormated := reply.Format()
for _, user := range users { for _, user := range users {
@ -130,7 +131,7 @@ func (s *commentServant) GetCommentRepliesByID(ids []int64) ([]*core.CommentRepl
return repliesFormated, nil return repliesFormated, nil
} }
func (s *commentManageServant) DeleteComment(comment *core.Comment) error { func (s *commentManageSrv) DeleteComment(comment *ms.Comment) error {
db := s.db.Begin() db := s.db.Begin()
defer db.Rollback() defer db.Rollback()
@ -149,15 +150,15 @@ func (s *commentManageServant) DeleteComment(comment *core.Comment) error {
return nil return nil
} }
func (s *commentManageServant) CreateComment(comment *core.Comment) (*core.Comment, error) { func (s *commentManageSrv) CreateComment(comment *ms.Comment) (*ms.Comment, error) {
return comment.Create(s.db) return comment.Create(s.db)
} }
func (s *commentManageServant) CreateCommentReply(reply *core.CommentReply) (*core.CommentReply, error) { func (s *commentManageSrv) CreateCommentReply(reply *ms.CommentReply) (*ms.CommentReply, error) {
return reply.Create(s.db) return reply.Create(s.db)
} }
func (s *commentManageServant) DeleteCommentReply(reply *core.CommentReply) (err error) { func (s *commentManageSrv) DeleteCommentReply(reply *ms.CommentReply) (err error) {
db := s.db.Begin() db := s.db.Begin()
defer db.Rollback() defer db.Rollback()
@ -177,11 +178,11 @@ func (s *commentManageServant) DeleteCommentReply(reply *core.CommentReply) (err
return return
} }
func (s *commentManageServant) CreateCommentContent(content *core.CommentContent) (*core.CommentContent, error) { func (s *commentManageSrv) CreateCommentContent(content *ms.CommentContent) (*ms.CommentContent, error) {
return content.Create(s.db) return content.Create(s.db)
} }
func (s *commentManageServant) ThumbsUpComment(userId int64, tweetId, commentId int64) error { func (s *commentManageSrv) ThumbsUpComment(userId int64, tweetId, commentId int64) error {
db := s.db.Begin() db := s.db.Begin()
defer db.Rollback() defer db.Rollback()
@ -230,7 +231,7 @@ func (s *commentManageServant) ThumbsUpComment(userId int64, tweetId, commentId
return nil return nil
} }
func (s *commentManageServant) ThumbsDownComment(userId int64, tweetId, commentId int64) error { func (s *commentManageSrv) ThumbsDownComment(userId int64, tweetId, commentId int64) error {
db := s.db.Begin() db := s.db.Begin()
defer db.Rollback() defer db.Rollback()
@ -280,7 +281,7 @@ func (s *commentManageServant) ThumbsDownComment(userId int64, tweetId, commentI
return nil return nil
} }
func (s *commentManageServant) ThumbsUpReply(userId int64, tweetId, commentId, replyId int64) error { func (s *commentManageSrv) ThumbsUpReply(userId int64, tweetId, commentId, replyId int64) error {
db := s.db.Begin() db := s.db.Begin()
defer db.Rollback() defer db.Rollback()
@ -330,7 +331,7 @@ func (s *commentManageServant) ThumbsUpReply(userId int64, tweetId, commentId, r
return nil return nil
} }
func (s *commentManageServant) ThumbsDownReply(userId int64, tweetId, commentId, replyId int64) error { func (s *commentManageSrv) ThumbsDownReply(userId int64, tweetId, commentId, replyId int64) error {
db := s.db.Begin() db := s.db.Begin()
defer db.Rollback() defer db.Rollback()
@ -380,7 +381,7 @@ func (s *commentManageServant) ThumbsDownReply(userId int64, tweetId, commentId,
return nil return nil
} }
func (s *commentManageServant) updateCommentThumbsUpCount(obj any, id int64, thumbsUpCount, thumbsDownCount int32) error { func (s *commentManageSrv) updateCommentThumbsUpCount(obj any, id int64, thumbsUpCount, thumbsDownCount int32) error {
updateColumns := make(map[string]any, 2) updateColumns := make(map[string]any, 2)
if thumbsUpCount == 1 { if thumbsUpCount == 1 {
updateColumns["thumbs_up_count"] = gorm.Expr("thumbs_up_count + 1") updateColumns["thumbs_up_count"] = gorm.Expr("thumbs_up_count + 1")

@ -8,26 +8,27 @@ import (
"time" "time"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"gorm.io/gorm" "gorm.io/gorm"
) )
var ( var (
_ core.ContactManageService = (*contactManageServant)(nil) _ core.ContactManageService = (*contactManageSrv)(nil)
) )
type contactManageServant struct { type contactManageSrv struct {
db *gorm.DB db *gorm.DB
} }
func newContactManageService(db *gorm.DB) core.ContactManageService { func newContactManageService(db *gorm.DB) core.ContactManageService {
return &contactManageServant{ return &contactManageSrv{
db: db, db: db,
} }
} }
func (s *contactManageServant) fetchOrNewContact(db *gorm.DB, userId int64, friendId int64, status int8) (*dbr.Contact, error) { func (s *contactManageSrv) fetchOrNewContact(db *gorm.DB, userId int64, friendId int64, status int8) (*dbr.Contact, error) {
contact := &dbr.Contact{ contact := &dbr.Contact{
UserId: userId, UserId: userId,
FriendId: friendId, FriendId: friendId,
@ -40,14 +41,14 @@ func (s *contactManageServant) fetchOrNewContact(db *gorm.DB, userId int64, frie
Status: status, Status: status,
} }
if contact, err = contact.Create(db); err != nil { if contact, err = contact.Create(db); err != nil {
logrus.Errorf("contactManageServant.fetchOrNewContact create new contact err:%s", err) logrus.Errorf("contactManageSrv.fetchOrNewContact create new contact err:%s", err)
return nil, err return nil, err
} }
} }
return contact, nil return contact, nil
} }
func (s *contactManageServant) RequestingFriend(userId int64, friendId int64, greetings string) (err error) { func (s *contactManageSrv) RequestingFriend(userId int64, friendId int64, greetings string) (err error) {
db := s.db.Begin() db := s.db.Begin()
defer func() { defer func() {
if err == nil { if err == nil {
@ -70,7 +71,7 @@ func (s *contactManageServant) RequestingFriend(userId int64, friendId int64, gr
contact.Status = dbr.ContactStatusRequesting contact.Status = dbr.ContactStatusRequesting
contact.IsDel = 0 // remove deleted flag if needed contact.IsDel = 0 // remove deleted flag if needed
if err = contact.UpdateInUnscoped(db); err != nil { if err = contact.UpdateInUnscoped(db); err != nil {
logrus.Errorf("contactManageServant.RequestingFriend update exsit contact err:%s", err) logrus.Errorf("contactManageSrv.RequestingFriend update exsit contact err:%s", err)
return return
} }
} }
@ -84,13 +85,13 @@ func (s *contactManageServant) RequestingFriend(userId int64, friendId int64, gr
ReplyID: int64(dbr.ContactStatusRequesting), ReplyID: int64(dbr.ContactStatusRequesting),
} }
if _, err = msg.Create(db); err != nil { if _, err = msg.Create(db); err != nil {
logrus.Errorf("contactManageServant.RequestingFriend create message err:%s", err) logrus.Errorf("contactManageSrv.RequestingFriend create message err:%s", err)
return return
} }
return nil return nil
} }
func (s *contactManageServant) AddFriend(userId int64, friendId int64) (err error) { func (s *contactManageSrv) AddFriend(userId int64, friendId int64) (err error) {
db := s.db.Begin() db := s.db.Begin()
defer func() { defer func() {
if err == nil { if err == nil {
@ -109,7 +110,7 @@ func (s *contactManageServant) AddFriend(userId int64, friendId int64) (err erro
} }
// 如果还不是请求好友,啥也不干 // 如果还不是请求好友,啥也不干
if contact.Status != dbr.ContactStatusRequesting { if contact.Status != dbr.ContactStatusRequesting {
logrus.Debugf("contactManageServant.AddFriend not reuesting status now so skip") logrus.Debugf("contactManageSrv.AddFriend not reuesting status now so skip")
return nil return nil
} }
contact.Status = dbr.ContactStatusAgree contact.Status = dbr.ContactStatusAgree
@ -127,7 +128,7 @@ func (s *contactManageServant) AddFriend(userId int64, friendId int64) (err erro
contact.Status = dbr.ContactStatusAgree contact.Status = dbr.ContactStatusAgree
contact.IsDel = 0 // remove deleted flag contact.IsDel = 0 // remove deleted flag
if err = contact.UpdateInUnscoped(db); err != nil { if err = contact.UpdateInUnscoped(db); err != nil {
logrus.Errorf("contactManageServant.AddFriend update contact err:%s", err) logrus.Errorf("contactManageSrv.AddFriend update contact err:%s", err)
return return
} }
} }
@ -149,7 +150,7 @@ func (s *contactManageServant) AddFriend(userId int64, friendId int64) (err erro
return nil return nil
} }
func (s *contactManageServant) RejectFriend(userId int64, friendId int64) (err error) { func (s *contactManageSrv) RejectFriend(userId int64, friendId int64) (err error) {
db := s.db.Begin() db := s.db.Begin()
defer func() { defer func() {
if err == nil { if err == nil {
@ -192,7 +193,7 @@ func (s *contactManageServant) RejectFriend(userId int64, friendId int64) (err e
return nil return nil
} }
func (s *contactManageServant) DeleteFriend(userId int64, friendId int64) (err error) { func (s *contactManageSrv) DeleteFriend(userId int64, friendId int64) (err error) {
db := s.db.Begin() db := s.db.Begin()
defer func() { defer func() {
if err == nil { if err == nil {
@ -226,7 +227,7 @@ func (s *contactManageServant) DeleteFriend(userId int64, friendId int64) (err e
return nil return nil
} }
func (s *contactManageServant) GetContacts(userId int64, offset int, limit int) (*core.ContactList, error) { func (s *contactManageSrv) GetContacts(userId int64, offset int, limit int) (*ms.ContactList, error) {
contact := &dbr.Contact{} contact := &dbr.Contact{}
condition := dbr.ConditionsT{ condition := dbr.ConditionsT{
"user_id": userId, "user_id": userId,
@ -240,13 +241,13 @@ func (s *contactManageServant) GetContacts(userId int64, offset int, limit int)
if err != nil { if err != nil {
return nil, err return nil, err
} }
resp := &core.ContactList{ resp := &ms.ContactList{
Contacts: make([]core.ContactItem, 0, len(contacts)), Contacts: make([]ms.ContactItem, 0, len(contacts)),
Total: total, Total: total,
} }
for _, c := range contacts { for _, c := range contacts {
if c.User != nil { if c.User != nil {
resp.Contacts = append(resp.Contacts, core.ContactItem{ resp.Contacts = append(resp.Contacts, ms.ContactItem{
UserId: c.FriendId, UserId: c.FriendId,
UserName: c.User.Username, UserName: c.User.Username,
Nickname: c.User.Nickname, Nickname: c.User.Nickname,
@ -258,7 +259,7 @@ func (s *contactManageServant) GetContacts(userId int64, offset int, limit int)
return resp, nil return resp, nil
} }
func (s *contactManageServant) IsFriend(userId int64, friendId int64) bool { func (s *contactManageSrv) IsFriend(userId int64, friendId int64) bool {
contact := &dbr.Contact{ contact := &dbr.Contact{
UserId: friendId, UserId: friendId,
FriendId: userId, FriendId: userId,

@ -79,7 +79,7 @@ func (c *Comment) List(db *gorm.DB, conditions *ConditionsT, offset, limit int)
db = db.Offset(offset).Limit(limit) db = db.Offset(offset).Limit(limit)
} }
if c.PostID > 0 { if c.PostID > 0 {
db = db.Where("id = ?", c.PostID) db = db.Where("post_id = ?", c.PostID)
} }
for k, v := range *conditions { for k, v := range *conditions {

@ -13,9 +13,9 @@ import (
type CommentReply struct { type CommentReply struct {
*Model *Model
CommentID int64 `json:"comment_id"` CommentID int64 `db:"comment_id" json:"comment_id"`
UserID int64 `json:"user_id"` UserID int64 `db:"user_id" json:"user_id"`
AtUserID int64 `json:"at_user_id"` AtUserID int64 `db:"at_user_id" json:"at_user_id"`
Content string `json:"content"` Content string `json:"content"`
IP string `json:"ip"` IP string `json:"ip"`
IPLoc string `json:"ip_loc"` IPLoc string `json:"ip_loc"`
@ -25,10 +25,10 @@ type CommentReply struct {
type CommentReplyFormated struct { type CommentReplyFormated struct {
ID int64 `json:"id"` ID int64 `json:"id"`
CommentID int64 `json:"comment_id"` CommentID int64 `db:"comment_id" json:"comment_id"`
UserID int64 `json:"user_id"` UserID int64 `db:"user_id" json:"user_id"`
User *UserFormated `json:"user"` User *UserFormated `json:"user"`
AtUserID int64 `json:"at_user_id"` AtUserID int64 `db:"at_user_id" json:"at_user_id"`
AtUser *UserFormated `json:"at_user"` AtUser *UserFormated `json:"at_user"`
Content string `json:"content"` Content string `json:"content"`
IPLoc string `json:"ip_loc"` IPLoc string `json:"ip_loc"`

@ -120,7 +120,7 @@ func (p *Post) Get(db *gorm.DB) (*Post, error) {
return &post, nil return &post, nil
} }
func (p *Post) List(db *gorm.DB, conditions *ConditionsT, offset, limit int) ([]*Post, error) { func (p *Post) List(db *gorm.DB, conditions ConditionsT, offset, limit int) ([]*Post, error) {
var posts []*Post var posts []*Post
var err error var err error
if offset >= 0 && limit > 0 { if offset >= 0 && limit > 0 {
@ -129,7 +129,7 @@ func (p *Post) List(db *gorm.DB, conditions *ConditionsT, offset, limit int) ([]
if p.UserID > 0 { if p.UserID > 0 {
db = db.Where("user_id = ?", p.UserID) db = db.Where("user_id = ?", p.UserID)
} }
for k, v := range *conditions { for k, v := range conditions {
if k == "ORDER" { if k == "ORDER" {
db = db.Order(v) db = db.Order(v)
} else { } else {
@ -178,12 +178,12 @@ func (p *Post) CountBy(db *gorm.DB, predicates Predicates) (count int64, err err
return return
} }
func (p *Post) Count(db *gorm.DB, conditions *ConditionsT) (int64, error) { func (p *Post) Count(db *gorm.DB, conditions ConditionsT) (int64, error) {
var count int64 var count int64
if p.UserID > 0 { if p.UserID > 0 {
db = db.Where("user_id = ?", p.UserID) db = db.Where("user_id = ?", p.UserID)
} }
for k, v := range *conditions { for k, v := range conditions {
if k != "ORDER" { if k != "ORDER" {
db = db.Where(k, v) db = db.Where(k, v)
} }

@ -14,8 +14,8 @@ import (
type PostCollection struct { type PostCollection struct {
*Model *Model
Post *Post `json:"-"` Post *Post `json:"-"`
PostID int64 `json:"post_id"` PostID int64 `db:"post_id" json:"post_id"`
UserID int64 `json:"user_id"` UserID int64 `db:"user_id" json:"user_id"`
} }
func (p *PostCollection) Get(db *gorm.DB) (*PostCollection, error) { func (p *PostCollection) Get(db *gorm.DB) (*PostCollection, error) {

@ -44,7 +44,7 @@ type PostContent struct {
} }
type PostContentFormated struct { type PostContentFormated struct {
ID int64 `json:"id"` ID int64 `db:"id" json:"id"`
PostID int64 `json:"post_id"` PostID int64 `json:"post_id"`
Content string `json:"content"` Content string `json:"content"`
Type PostContentT `json:"type"` Type PostContentT `json:"type"`

@ -88,9 +88,7 @@ func (t *Tag) Delete(db *gorm.DB) error {
}).Error }).Error
} }
func (t *Tag) List(db *gorm.DB, conditions *ConditionsT, offset, limit int) ([]*Tag, error) { func (t *Tag) List(db *gorm.DB, conditions *ConditionsT, offset, limit int) (tags []*Tag, err error) {
var tags []*Tag
var err error
if offset >= 0 && limit > 0 { if offset >= 0 && limit > 0 {
db = db.Offset(offset).Limit(limit) db = db.Offset(offset).Limit(limit)
} }
@ -104,12 +102,8 @@ func (t *Tag) List(db *gorm.DB, conditions *ConditionsT, offset, limit int) ([]*
db = db.Where(k, v) db = db.Where(k, v)
} }
} }
err = db.Where("is_del = 0 and quote_num > 0").Find(&tags).Error
if err = db.Where("is_del = 0 and quote_num > 0").Find(&tags).Error; err != nil { return
return nil, err
}
return tags, nil
} }
func (t *Tag) TagsFrom(db *gorm.DB, tags []string) (res []*Tag, err error) { func (t *Tag) TagsFrom(db *gorm.DB, tags []string) (res []*Tag, err error) {

@ -4,7 +4,10 @@
package dbr package dbr
import "gorm.io/gorm" import (
"github.com/rocboss/paopao-ce/internal/core/cs"
"gorm.io/gorm"
)
const ( const (
UserStatusNormal int = iota + 1 UserStatusNormal int = iota + 1
@ -25,7 +28,7 @@ type User struct {
} }
type UserFormated struct { type UserFormated struct {
ID int64 `json:"id"` ID int64 `db:"id" json:"id"`
Nickname string `json:"nickname"` Nickname string `json:"nickname"`
Username string `json:"username"` Username string `json:"username"`
Status int `json:"status"` Status int `json:"status"`
@ -87,6 +90,11 @@ func (u *User) List(db *gorm.DB, conditions *ConditionsT, offset, limit int) ([]
return users, nil return users, nil
} }
func (u *User) ListUserInfoById(db *gorm.DB, ids []int64) (res cs.UserInfoList, err error) {
err = db.Model(u).Where("id IN ?", ids).Find(&res).Error
return
}
func (u *User) Create(db *gorm.DB) (*User, error) { func (u *User) Create(db *gorm.DB) (*User, error) {
err := db.Create(&u).Error err := db.Create(&u).Error

@ -0,0 +1,55 @@
// 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 jinzhu
import (
"github.com/rocboss/paopao-ce/internal/conf"
)
// 数据库表名,统一使用 _<table name>_ 的形式命名, 比如tag表 => _tag_
var (
_anouncement_ string
_anouncementContent_ string
_attachment_ string
_captcha_ string
_comment_ string
_commentContent_ string
_commentReply_ string
_contact_ string
_contactGroup_ string
_message_ string
_post_ string
_postAttachmentBill_ string
_postCollection_ string
_postContent_ string
_postStar_ string
_tag_ string
_user_ string
_walletRecharge_ string
_walletStatement_ string
)
func initTableName() {
m := conf.DatabaseSetting.TableNames()
_anouncement_ = m[conf.TableAnouncement]
_anouncementContent_ = m[conf.TableAnouncementContent]
_attachment_ = m[conf.TableAttachment]
_captcha_ = m[conf.TableCaptcha]
_comment_ = m[conf.TableComment]
_commentContent_ = m[conf.TableCommentContent]
_commentReply_ = m[conf.TableCommentReply]
_contact_ = m[conf.TableContact]
_contactGroup_ = m[conf.TableContactGroup]
_message_ = m[conf.TableMessage]
_post_ = m[conf.TablePost]
_postAttachmentBill_ = m[conf.TablePostAttachmentBill]
_postCollection_ = m[conf.TablePostCollection]
_postContent_ = m[conf.TablePostContent]
_postStar_ = m[conf.TablePostStar]
_tag_ = m[conf.TableTag]
_user_ = m[conf.TableUser]
_walletRecharge_ = m[conf.TableWalletRecharge]
_walletStatement_ = m[conf.TableWalletStatement]
}

@ -9,6 +9,8 @@
package jinzhu package jinzhu
import ( import (
"sync"
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/alimy/cfg" "github.com/alimy/cfg"
"github.com/rocboss/paopao-ce/internal/conf" "github.com/rocboss/paopao-ce/internal/conf"
@ -19,11 +21,16 @@ import (
) )
var ( var (
_ core.DataService = (*dataServant)(nil) _ core.DataService = (*dataSrv)(nil)
_ core.VersionInfo = (*dataServant)(nil) _ core.VersionInfo = (*dataSrv)(nil)
_ core.WebDataServantA = (*webDataSrvA)(nil)
_ core.VersionInfo = (*webDataSrvA)(nil)
_onceInitial sync.Once
) )
type dataServant struct { type dataSrv struct {
core.IndexPostsService core.IndexPostsService
core.WalletService core.WalletService
core.MessageService core.MessageService
@ -40,7 +47,16 @@ type dataServant struct {
core.ShareKeyService core.ShareKeyService
} }
type webDataSrvA struct {
core.TopicServantA
core.TweetServantA
core.TweetManageServantA
core.TweetHelpServantA
}
func NewDataService() (core.DataService, core.VersionInfo) { func NewDataService() (core.DataService, core.VersionInfo) {
lazyInitial()
var ( var (
v core.VersionInfo v core.VersionInfo
cis core.CacheIndexService cis core.CacheIndexService
@ -50,7 +66,6 @@ func NewDataService() (core.DataService, core.VersionInfo) {
pvs := security.NewPhoneVerifyService() pvs := security.NewPhoneVerifyService()
ams := NewAuthorizationManageService() ams := NewAuthorizationManageService()
ths := newTweetHelpService(db) ths := newTweetHelpService(db)
ums := newUserManageService(db)
// initialize core.IndexPostsService // initialize core.IndexPostsService
if cfg.If("Friendship") { if cfg.If("Friendship") {
@ -84,11 +99,11 @@ func NewDataService() (core.DataService, core.VersionInfo) {
}) })
logrus.Infof("use %s as cache index service by version: %s", v.Name(), v.Version()) logrus.Infof("use %s as cache index service by version: %s", v.Name(), v.Version())
ds := &dataServant{ ds := &dataSrv{
IndexPostsService: cis, IndexPostsService: cis,
WalletService: newWalletService(db), WalletService: newWalletService(db),
MessageService: newMessageService(db), MessageService: newMessageService(db),
TopicService: newTopicService(db, ums), TopicService: newTopicService(db),
TweetService: newTweetService(db), TweetService: newTweetService(db),
TweetManageService: newTweetManageService(db, cis), TweetManageService: newTweetManageService(db, cis),
TweetHelpService: newTweetHelpService(db), TweetHelpService: newTweetHelpService(db),
@ -103,14 +118,41 @@ func NewDataService() (core.DataService, core.VersionInfo) {
return ds, ds return ds, ds
} }
func NewWebDataServantA() (core.WebDataServantA, core.VersionInfo) {
lazyInitial()
db := conf.MustGormDB()
ds := &webDataSrvA{
TopicServantA: newTopicServantA(db),
TweetServantA: newTweetServantA(db),
TweetManageServantA: newTweetManageServantA(db),
TweetHelpServantA: newTweetHelpServantA(db),
}
return ds, ds
}
func NewAuthorizationManageService() core.AuthorizationManageService { func NewAuthorizationManageService() core.AuthorizationManageService {
return newAuthorizationManageService(conf.MustGormDB()) return newAuthorizationManageService(conf.MustGormDB())
} }
func (s *dataServant) Name() string { func (s *dataSrv) Name() string {
return "Gorm" return "Gorm"
} }
func (s *dataServant) Version() *semver.Version { func (s *dataSrv) Version() *semver.Version {
return semver.MustParse("v0.2.0") return semver.MustParse("v0.2.0")
} }
func (s *webDataSrvA) Name() string {
return "Gorm"
}
func (s *webDataSrvA) Version() *semver.Version {
return semver.MustParse("v0.1.0")
}
// lazyInitial do some package lazy initialize for performance
func lazyInitial() {
_onceInitial.Do(func() {
initTableName()
})
}

@ -6,50 +6,51 @@ package jinzhu
import ( import (
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"gorm.io/gorm" "gorm.io/gorm"
) )
var ( var (
_ core.MessageService = (*messageServant)(nil) _ core.MessageService = (*messageSrv)(nil)
) )
type messageServant struct { type messageSrv struct {
db *gorm.DB db *gorm.DB
} }
func newMessageService(db *gorm.DB) core.MessageService { func newMessageService(db *gorm.DB) core.MessageService {
return &messageServant{ return &messageSrv{
db: db, db: db,
} }
} }
func (d *messageServant) CreateMessage(msg *core.Message) (*core.Message, error) { func (s *messageSrv) CreateMessage(msg *ms.Message) (*ms.Message, error) {
return msg.Create(d.db) return msg.Create(s.db)
} }
func (d *messageServant) GetUnreadCount(userID int64) (int64, error) { func (s *messageSrv) GetUnreadCount(userID int64) (int64, error) {
return (&dbr.Message{}).Count(d.db, &dbr.ConditionsT{ return (&dbr.Message{}).Count(s.db, &dbr.ConditionsT{
"receiver_user_id": userID, "receiver_user_id": userID,
"is_read": dbr.MsgStatusUnread, "is_read": dbr.MsgStatusUnread,
}) })
} }
func (d *messageServant) GetMessageByID(id int64) (*core.Message, error) { func (s *messageSrv) GetMessageByID(id int64) (*ms.Message, error) {
return (&dbr.Message{ return (&dbr.Message{
Model: &dbr.Model{ Model: &dbr.Model{
ID: id, ID: id,
}, },
}).Get(d.db) }).Get(s.db)
} }
func (d *messageServant) ReadMessage(message *core.Message) error { func (s *messageSrv) ReadMessage(message *ms.Message) error {
message.IsRead = 1 message.IsRead = 1
return message.Update(d.db) return message.Update(s.db)
} }
func (d *messageServant) GetMessages(conditions *core.ConditionsT, offset, limit int) ([]*core.MessageFormated, error) { func (s *messageSrv) GetMessages(conditions *ms.ConditionsT, offset, limit int) ([]*ms.MessageFormated, error) {
messages, err := (&dbr.Message{}).List(d.db, conditions, offset, limit) messages, err := (&dbr.Message{}).List(s.db, conditions, offset, limit)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -63,6 +64,6 @@ func (d *messageServant) GetMessages(conditions *core.ConditionsT, offset, limit
return mfs, nil return mfs, nil
} }
func (d *messageServant) GetMessageCount(conditions *core.ConditionsT) (int64, error) { func (s *messageSrv) GetMessageCount(conditions *ms.ConditionsT) (int64, error) {
return (&dbr.Message{}).Count(d.db, conditions) return (&dbr.Message{}).Count(s.db, conditions)
} }

@ -10,46 +10,48 @@ import (
"time" "time"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"gorm.io/gorm" "gorm.io/gorm"
) )
var ( var (
_ core.SecurityService = (*securityServant)(nil) _ core.SecurityService = (*securitySrv)(nil)
) )
type securityServant struct { type securitySrv struct {
db *gorm.DB db *gorm.DB
rand *rand.Rand
phoneVerify core.PhoneVerifyService phoneVerify core.PhoneVerifyService
} }
func newSecurityService(db *gorm.DB, phoneVerify core.PhoneVerifyService) core.SecurityService { func newSecurityService(db *gorm.DB, phoneVerify core.PhoneVerifyService) core.SecurityService {
return &securityServant{ return &securitySrv{
db: db, db: db,
rand: rand.New(rand.NewSource(time.Now().UnixNano())),
phoneVerify: phoneVerify, phoneVerify: phoneVerify,
} }
} }
// GetLatestPhoneCaptcha 获取最新短信验证码 // GetLatestPhoneCaptcha 获取最新短信验证码
func (s *securityServant) GetLatestPhoneCaptcha(phone string) (*core.Captcha, error) { func (s *securitySrv) GetLatestPhoneCaptcha(phone string) (*ms.Captcha, error) {
return (&dbr.Captcha{ return (&dbr.Captcha{
Phone: phone, Phone: phone,
}).Get(s.db) }).Get(s.db)
} }
// UsePhoneCaptcha 更新短信验证码 // UsePhoneCaptcha 更新短信验证码
func (s *securityServant) UsePhoneCaptcha(captcha *core.Captcha) error { func (s *securitySrv) UsePhoneCaptcha(captcha *ms.Captcha) error {
captcha.UseTimes++ captcha.UseTimes++
return captcha.Update(s.db) return captcha.Update(s.db)
} }
// SendPhoneCaptcha 发送短信验证码 // SendPhoneCaptcha 发送短信验证码
func (s *securityServant) SendPhoneCaptcha(phone string) error { func (s *securitySrv) SendPhoneCaptcha(phone string) error {
expire := time.Duration(5) expire := time.Duration(5)
// 发送验证码 // 发送验证码
rand.Seed(time.Now().UnixNano()) captcha := strconv.Itoa(s.rand.Intn(900000) + 100000)
captcha := strconv.Itoa(rand.Intn(900000) + 100000)
if err := s.phoneVerify.SendPhoneCaptcha(phone, captcha, expire); err != nil { if err := s.phoneVerify.SendPhoneCaptcha(phone, captcha, expire); err != nil {
return err return err
} }

@ -6,6 +6,8 @@ package jinzhu
import ( import (
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"github.com/rocboss/paopao-ce/pkg/debug" "github.com/rocboss/paopao-ce/pkg/debug"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -13,35 +15,35 @@ import (
) )
var ( var (
_ core.IndexPostsService = (*friendIndexServant)(nil) _ core.IndexPostsService = (*friendIndexSrv)(nil)
_ core.IndexPostsService = (*followIndexServant)(nil) _ core.IndexPostsService = (*followIndexSrv)(nil)
_ core.IndexPostsService = (*lightIndexServant)(nil) _ core.IndexPostsService = (*lightIndexSrv)(nil)
_ core.IndexPostsService = (*simpleIndexPostsServant)(nil) _ core.IndexPostsService = (*simpleIndexPostsSrv)(nil)
) )
type friendIndexServant struct { type friendIndexSrv struct {
ams core.AuthorizationManageService ams core.AuthorizationManageService
ths core.TweetHelpService ths core.TweetHelpService
db *gorm.DB db *gorm.DB
} }
type followIndexServant struct { type followIndexSrv struct {
ths core.TweetHelpService ths core.TweetHelpService
db *gorm.DB db *gorm.DB
} }
type lightIndexServant struct { type lightIndexSrv struct {
ths core.TweetHelpService ths core.TweetHelpService
db *gorm.DB db *gorm.DB
} }
type simpleIndexPostsServant struct { type simpleIndexPostsSrv struct {
ths core.TweetHelpService ths core.TweetHelpService
db *gorm.DB db *gorm.DB
} }
// IndexPosts 根据userId查询广场推文列表简单做到不同用户的主页都是不同的 // IndexPosts 根据userId查询广场推文列表简单做到不同用户的主页都是不同的
func (s *friendIndexServant) IndexPosts(user *core.User, offset int, limit int) (*core.IndexTweetList, error) { func (s *friendIndexSrv) IndexPosts(user *ms.User, offset int, limit int) (*ms.IndexTweetList, error) {
predicates := dbr.Predicates{ predicates := dbr.Predicates{
"ORDER": []any{"is_top DESC, latest_replied_on DESC"}, "ORDER": []any{"is_top DESC, latest_replied_on DESC"},
} }
@ -56,7 +58,7 @@ func (s *friendIndexServant) IndexPosts(user *core.User, offset int, limit int)
posts, err := (&dbr.Post{}).Fetch(s.db, predicates, offset, limit) posts, err := (&dbr.Post{}).Fetch(s.db, predicates, offset, limit)
if err != nil { if err != nil {
logrus.Debugf("gormIndexPostsServant.IndexPosts err: %v", err) logrus.Debugf("gormIndexPostsSrv.IndexPosts err: %v", err)
return nil, err return nil, err
} }
formatPosts, err := s.ths.MergePosts(posts) formatPosts, err := s.ths.MergePosts(posts)
@ -69,20 +71,30 @@ func (s *friendIndexServant) IndexPosts(user *core.User, offset int, limit int)
return nil, err return nil, err
} }
return &core.IndexTweetList{ return &ms.IndexTweetList{
Tweets: formatPosts, Tweets: formatPosts,
Total: total, Total: total,
}, nil }, nil
} }
func (s *friendIndexSrv) TweetTimeline(userId int64, offset int, limit int) (*cs.TweetBox, error) {
// TODO
return nil, debug.ErrNotImplemented
}
// IndexPosts 根据userId查询广场推文列表 // IndexPosts 根据userId查询广场推文列表
func (s *followIndexServant) IndexPosts(user *core.User, offset int, limit int) (*core.IndexTweetList, error) { 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 // TODO
return nil, debug.ErrNotImplemented return nil, debug.ErrNotImplemented
} }
// IndexPosts 根据userId查询广场推文列表获取公开可见Tweet或者所属用户的私有Tweet // IndexPosts 根据userId查询广场推文列表获取公开可见Tweet或者所属用户的私有Tweet
func (s *lightIndexServant) IndexPosts(user *core.User, offset int, limit int) (*core.IndexTweetList, error) { func (s *lightIndexSrv) IndexPosts(user *ms.User, offset int, limit int) (*ms.IndexTweetList, error) {
predicates := dbr.Predicates{ predicates := dbr.Predicates{
"ORDER": []any{"is_top DESC, latest_replied_on DESC"}, "ORDER": []any{"is_top DESC, latest_replied_on DESC"},
} }
@ -95,7 +107,7 @@ func (s *lightIndexServant) IndexPosts(user *core.User, offset int, limit int) (
posts, err := (&dbr.Post{}).Fetch(s.db, predicates, offset, limit) posts, err := (&dbr.Post{}).Fetch(s.db, predicates, offset, limit)
if err != nil { if err != nil {
logrus.Debugf("gormIndexPostsServant.IndexPosts err: %v", err) logrus.Debugf("gormIndexPostsSrv.IndexPosts err: %v", err)
return nil, err return nil, err
} }
formatPosts, err := s.ths.MergePosts(posts) formatPosts, err := s.ths.MergePosts(posts)
@ -108,14 +120,19 @@ func (s *lightIndexServant) IndexPosts(user *core.User, offset int, limit int) (
return nil, err return nil, err
} }
return &core.IndexTweetList{ return &ms.IndexTweetList{
Tweets: formatPosts, Tweets: formatPosts,
Total: total, Total: total,
}, nil }, nil
} }
func (s *lightIndexSrv) TweetTimeline(userId int64, offset int, limit int) (*cs.TweetBox, error) {
// TODO
return nil, debug.ErrNotImplemented
}
// simpleCacheIndexGetPosts simpleCacheIndex 专属获取广场推文列表函数 // simpleCacheIndexGetPosts simpleCacheIndex 专属获取广场推文列表函数
func (s *simpleIndexPostsServant) IndexPosts(_user *core.User, offset int, limit int) (*core.IndexTweetList, error) { func (s *simpleIndexPostsSrv) IndexPosts(_user *ms.User, offset int, limit int) (*ms.IndexTweetList, error) {
predicates := dbr.Predicates{ predicates := dbr.Predicates{
"visibility = ?": []any{dbr.PostVisitPublic}, "visibility = ?": []any{dbr.PostVisitPublic},
"ORDER": []any{"is_top DESC, latest_replied_on DESC"}, "ORDER": []any{"is_top DESC, latest_replied_on DESC"},
@ -123,7 +140,7 @@ func (s *simpleIndexPostsServant) IndexPosts(_user *core.User, offset int, limit
posts, err := (&dbr.Post{}).Fetch(s.db, predicates, offset, limit) posts, err := (&dbr.Post{}).Fetch(s.db, predicates, offset, limit)
if err != nil { if err != nil {
logrus.Debugf("gormSimpleIndexPostsServant.IndexPosts err: %v", err) logrus.Debugf("gormSimpleIndexPostsSrv.IndexPosts err: %v", err)
return nil, err return nil, err
} }
@ -137,14 +154,19 @@ func (s *simpleIndexPostsServant) IndexPosts(_user *core.User, offset int, limit
return nil, err return nil, err
} }
return &core.IndexTweetList{ return &ms.IndexTweetList{
Tweets: formatPosts, Tweets: formatPosts,
Total: total, Total: total,
}, nil }, nil
} }
func (s *simpleIndexPostsSrv) TweetTimeline(userId int64, offset int, limit int) (*cs.TweetBox, error) {
// TODO
return nil, debug.ErrNotImplemented
}
func newFriendIndexService(db *gorm.DB, ams core.AuthorizationManageService, ths core.TweetHelpService) core.IndexPostsService { func newFriendIndexService(db *gorm.DB, ams core.AuthorizationManageService, ths core.TweetHelpService) core.IndexPostsService {
return &friendIndexServant{ return &friendIndexSrv{
ams: ams, ams: ams,
ths: ths, ths: ths,
db: db, db: db,
@ -152,21 +174,21 @@ func newFriendIndexService(db *gorm.DB, ams core.AuthorizationManageService, ths
} }
func newFollowIndexService(db *gorm.DB, ths core.TweetHelpService) core.IndexPostsService { func newFollowIndexService(db *gorm.DB, ths core.TweetHelpService) core.IndexPostsService {
return &followIndexServant{ return &followIndexSrv{
ths: ths, ths: ths,
db: db, db: db,
} }
} }
func newLightIndexService(db *gorm.DB, ths core.TweetHelpService) core.IndexPostsService { func newLightIndexService(db *gorm.DB, ths core.TweetHelpService) core.IndexPostsService {
return &lightIndexServant{ return &lightIndexSrv{
ths: ths, ths: ths,
db: db, db: db,
} }
} }
func newSimpleIndexPostsService(db *gorm.DB, ths core.TweetHelpService) core.IndexPostsService { func newSimpleIndexPostsService(db *gorm.DB, ths core.TweetHelpService) core.IndexPostsService {
return &simpleIndexPostsServant{ return &simpleIndexPostsSrv{
ths: ths, ths: ths,
db: db, db: db,
} }

@ -9,68 +9,108 @@ import (
"strings" "strings"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"gorm.io/gorm" "gorm.io/gorm"
) )
var ( var (
_ core.TopicService = (*topicServant)(nil) _ core.TopicService = (*topicSrv)(nil)
_ core.TopicServantA = (*topicSrvA)(nil)
) )
type topicServant struct { type topicSrv struct {
db *gorm.DB db *gorm.DB
ums core.UserManageService
tnTopicUser string tnTopicUser string
tnDotTopicUser string tnDotTopicUser string
} }
type topicSrvA struct {
db *gorm.DB
}
type topicInfo struct { type topicInfo struct {
TopicId int64 TopicId int64
IsTop int8 IsTop int8
} }
func newTopicService(db *gorm.DB, ums core.UserManageService) core.TopicService { func newTopicService(db *gorm.DB) core.TopicService {
return &topicServant{ return &topicSrv{
db: db, db: db,
ums: ums,
tnTopicUser: db.NamingStrategy.TableName("TopicUser"), tnTopicUser: db.NamingStrategy.TableName("TopicUser"),
tnDotTopicUser: db.NamingStrategy.TableName("TopicUser") + ".", tnDotTopicUser: db.NamingStrategy.TableName("TopicUser") + ".",
} }
} }
func (s *topicServant) CreateTag(tag *core.Tag) (*core.Tag, error) { func newTopicServantA(db *gorm.DB) core.TopicServantA {
return createTag(s.db, tag) return &topicSrvA{
db: db,
}
}
func (s *topicSrv) UpsertTags(userId int64, tags []string) (_ cs.TagInfoList, err error) {
db := s.db.Begin()
defer func() {
if err == nil {
db.Commit()
} else {
db.Rollback()
}
}()
return createTags(db, userId, tags)
} }
func (s *topicServant) DeleteTag(tag *core.Tag) error { func (s *topicSrv) DecrTagsById(ids []int64) (err error) {
return deleteTag(s.db, tag) db := s.db.Begin()
defer func() {
if err == nil {
db.Commit()
} else {
db.Rollback()
}
}()
return decrTagsByIds(db, ids)
} }
func (s *topicServant) GetTags(conditions *core.ConditionsT, offset, limit int) ([]*core.Tag, error) { func (s *topicSrv) ListTags(typ cs.TagType, offset, limit int) (res cs.TagList, err error) {
return (&dbr.Tag{}).List(s.db, conditions, offset, limit) conditions := &ms.ConditionsT{}
switch typ {
case cs.TagTypeHot:
// 热门标签
conditions = &ms.ConditionsT{
"ORDER": "quote_num DESC",
}
case cs.TagTypeNew:
// 最新标签
conditions = &ms.ConditionsT{
"ORDER": "id DESC",
}
}
return s.listTags(conditions, limit, offset)
} }
func (s *topicServant) GetHotTags(userId int64, limit int, offset int) ([]*core.TagFormated, error) { func (s *topicSrv) GetHotTags(userId int64, limit int, offset int) (cs.TagList, error) {
tags, err := (&dbr.Tag{}).List(s.db, &core.ConditionsT{ tags, err := s.listTags(&ms.ConditionsT{
"ORDER": "quote_num DESC", "ORDER": "quote_num DESC",
}, offset, limit) }, limit, offset)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return s.tagsFormat(userId, nil, tags) return s.tagsFormatA(userId, tags)
} }
func (s *topicServant) GetNewestTags(userId int64, limit int, offset int) ([]*core.TagFormated, error) { func (s *topicSrv) GetNewestTags(userId int64, limit int, offset int) (cs.TagList, error) {
tags, err := (&dbr.Tag{}).List(s.db, &core.ConditionsT{ tags, err := s.listTags(&ms.ConditionsT{
"ORDER": "id DESC", "ORDER": "id DESC",
}, offset, limit) }, limit, offset)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return s.tagsFormat(userId, nil, tags) return s.tagsFormatA(userId, tags)
} }
func (s *topicServant) GetFollowTags(userId int64, limit int, offset int) ([]*core.TagFormated, error) { func (s *topicSrv) GetFollowTags(userId int64, limit int, offset int) (cs.TagList, error) {
if userId < 0 { if userId < 0 {
return nil, nil return nil, nil
} }
@ -92,25 +132,89 @@ func (s *topicServant) GetFollowTags(userId int64, limit int, offset int) ([]*co
topicIds = append(topicIds, info.TopicId) topicIds = append(topicIds, info.TopicId)
topicIdsMap[info.TopicId] = idx topicIdsMap[info.TopicId] = idx
} }
var tags []*core.Tag var tags cs.TagInfoList
err = s.db.Model(&dbr.Tag{}).Where("quote_num > 0 and id in ?", topicIds).Order("quote_num DESC").Find(&tags).Error err = s.db.Model(&dbr.Tag{}).Where("quote_num > 0 and id in ?", topicIds).Order("quote_num DESC").Find(&tags).Error
if err != nil { if err != nil {
return nil, err return nil, err
} }
formtedTags, err := s.tagsFormat(-1, userTopicsMap, tags) formtedTags, err := s.tagsFormatB(userTopicsMap, tags)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// 置顶排序后处理 // 置顶排序后处理
// TODO: 垃圾办法最好是topic_user join tag 一次查询但是gorm的join真他喵的别扭F*K // TODO: 垃圾办法最好是topic_user join tag 一次查询但是gorm的join真他喵的别扭F*K
res := make([]*core.TagFormated, len(topicIds), len(topicIds)) res := make(cs.TagList, len(topicIds), len(topicIds))
for _, tag := range formtedTags { for _, tag := range formtedTags {
res[topicIdsMap[tag.ID]] = tag res[topicIdsMap[tag.ID]] = tag
} }
return res, nil return res, nil
} }
func (s *topicServant) tagsFormat(userId int64, userTopicsMap map[int64]*topicInfo, tags []*core.Tag) ([]*core.TagFormated, error) { func (s *topicSrv) listTags(conditions *ms.ConditionsT, limit int, offset int) (res cs.TagList, err error) {
// TODO: 优化查询方式,直接返回[]*core.Tag, 目前保持先转换一下
var (
tags []*dbr.Tag
item *cs.TagItem
)
if tags, err = (&dbr.Tag{}).List(s.db, conditions, offset, limit); err == nil {
if len(tags) == 0 {
return
}
tagMap := make(map[int64][]*cs.TagItem, len(tags))
for _, tag := range tags {
item = &cs.TagItem{
ID: tag.ID,
UserID: tag.UserID,
Tag: tag.Tag,
QuoteNum: tag.QuoteNum,
}
tagMap[item.UserID] = append(tagMap[item.UserID], item)
res = append(res, item)
}
ids := make([]int64, len(tagMap))
for userId := range tagMap {
ids = append(ids, userId)
}
userInfos, err := (&dbr.User{}).ListUserInfoById(s.db, ids)
if err != nil {
return nil, err
}
for _, userInfo := range userInfos {
for _, item = range tagMap[userInfo.ID] {
item.User = userInfo
}
}
}
return
}
func (s *topicSrv) tagsFormatA(userId int64, tags cs.TagList) (cs.TagList, error) {
// 获取创建者User IDs
tagIds := []int64{}
for _, tag := range tags {
tagIds = append(tagIds, tag.ID)
}
// 填充话题follow信息
if userId > -1 {
userTopics := []*topicInfo{}
err := s.db.Model(&dbr.TopicUser{}).Where("is_del=0 and user_id=? and topic_id in ?", userId, tagIds).Find(&userTopics).Error
if err != nil {
return nil, err
}
userTopicsMap := make(map[int64]*topicInfo, len(userTopics))
for _, info := range userTopics {
userTopicsMap[info.TopicId] = info
}
for _, tag := range tags {
if info, exist := userTopicsMap[tag.ID]; exist {
tag.IsFollowing, tag.IsTop = 1, info.IsTop
}
}
}
return tags, nil
}
func (s *topicSrv) tagsFormatB(userTopicsMap map[int64]*topicInfo, tags cs.TagInfoList) (cs.TagList, error) {
// 获取创建者User IDs // 获取创建者User IDs
userIds := []int64{} userIds := []int64{}
tagIds := []int64{} tagIds := []int64{}
@ -118,59 +222,161 @@ func (s *topicServant) tagsFormat(userId int64, userTopicsMap map[int64]*topicIn
userIds = append(userIds, tag.UserID) userIds = append(userIds, tag.UserID)
tagIds = append(tagIds, tag.ID) tagIds = append(tagIds, tag.ID)
} }
users, err := s.ums.GetUsersByIDs(userIds) users, err := (&dbr.User{}).ListUserInfoById(s.db, userIds)
if err != nil { if err != nil {
return nil, err return nil, err
} }
tagsFormated := []*core.TagFormated{} tagList := cs.TagList{}
for _, tag := range tags { for _, tag := range tags {
tagFormated := tag.Format() tagFormated := tag.Format()
for _, user := range users { for _, user := range users {
if user.ID == tagFormated.UserID { if user.ID == tagFormated.UserID {
tagFormated.User = user.Format() tagFormated.User = user
} }
} }
tagsFormated = append(tagsFormated, tagFormated) tagList = append(tagList, tagFormated)
} }
// 填充话题follow信息 // 填充话题follow信息
if userId > -1 && len(userTopicsMap) <= 0 {
userTopics := []*topicInfo{}
err = s.db.Model(&dbr.TopicUser{}).Where("is_del=0 and user_id=? and topic_id in ?", userId, tagIds).Find(&userTopics).Error
if err != nil {
return nil, err
}
userTopicsMap = make(map[int64]*topicInfo, len(userTopics))
for _, info := range userTopics {
userTopicsMap[info.TopicId] = info
}
}
if len(userTopicsMap) > 0 { if len(userTopicsMap) > 0 {
for _, tag := range tagsFormated { for _, tag := range tagList {
if info, exist := userTopicsMap[tag.ID]; exist { if info, exist := userTopicsMap[tag.ID]; exist {
tag.IsFollowing, tag.IsTop = 1, info.IsTop tag.IsFollowing, tag.IsTop = 1, info.IsTop
} }
} }
} }
return tagsFormated, nil return tagList, nil
} }
func (s *topicServant) GetTagsByKeyword(keyword string) ([]*core.Tag, error) { func (s *topicSrv) TagsByKeyword(keyword string) (res cs.TagInfoList, err error) {
keyword = "%" + strings.Trim(keyword, " ") + "%"
tag := &dbr.Tag{} tag := &dbr.Tag{}
var tags []*dbr.Tag
if keyword == "%%" {
tags, err = tag.List(s.db, &dbr.ConditionsT{
"ORDER": "quote_num DESC",
}, 0, 6)
} else {
tags, err = tag.List(s.db, &dbr.ConditionsT{
"tag LIKE ?": keyword,
"ORDER": "quote_num DESC",
}, 0, 6)
}
if err == nil {
for _, tag := range tags {
res = append(res, &cs.TagInfo{
ID: tag.ID,
UserID: tag.UserID,
Tag: tag.Tag,
QuoteNum: tag.QuoteNum,
})
}
}
return
}
func (s *topicSrvA) UpsertTags(userId int64, tags []string) (_ cs.TagInfoList, err error) {
db := s.db.Begin()
defer func() {
if err == nil {
db.Commit()
} else {
db.Rollback()
}
}()
return createTags(db, userId, tags)
}
func (s *topicSrvA) DecrTagsById(ids []int64) (err error) {
db := s.db.Begin()
defer func() {
if err == nil {
db.Commit()
} else {
db.Rollback()
}
}()
return decrTagsByIds(db, ids)
}
func (s *topicSrvA) ListTags(typ cs.TagType, offset, limit int) (res cs.TagList, err error) {
conditions := &ms.ConditionsT{}
switch typ {
case cs.TagTypeHot:
// 热门标签
conditions = &ms.ConditionsT{
"ORDER": "quote_num DESC",
}
case cs.TagTypeNew:
// 最新标签
conditions = &ms.ConditionsT{
"ORDER": "id DESC",
}
}
// TODO: 优化查询方式,直接返回[]*core.Tag, 目前保持先转换一下
var (
tags []*dbr.Tag
item *cs.TagItem
)
if tags, err = (&dbr.Tag{}).List(s.db, conditions, offset, limit); err == nil {
if len(tags) == 0 {
return
}
tagMap := make(map[int64][]*cs.TagItem, len(tags))
for _, tag := range tags {
item = &cs.TagItem{
ID: tag.ID,
UserID: tag.UserID,
Tag: tag.Tag,
QuoteNum: tag.QuoteNum,
}
tagMap[item.UserID] = append(tagMap[item.UserID], item)
res = append(res, item)
}
ids := make([]int64, len(tagMap))
for userId := range tagMap {
ids = append(ids, userId)
}
userInfos, err := (&dbr.User{}).ListUserInfoById(s.db, ids)
if err != nil {
return nil, err
}
for _, userInfo := range userInfos {
for _, item = range tagMap[userInfo.ID] {
item.User = userInfo
}
}
}
return
}
func (s *topicSrvA) TagsByKeyword(keyword string) (res cs.TagInfoList, err error) {
keyword = "%" + strings.Trim(keyword, " ") + "%" keyword = "%" + strings.Trim(keyword, " ") + "%"
tag := &dbr.Tag{}
var tags []*dbr.Tag
if keyword == "%%" { if keyword == "%%" {
return tag.List(s.db, &dbr.ConditionsT{ tags, err = tag.List(s.db, &dbr.ConditionsT{
"ORDER": "quote_num DESC", "ORDER": "quote_num DESC",
}, 0, 6) }, 0, 6)
} else { } else {
return tag.List(s.db, &dbr.ConditionsT{ tags, err = tag.List(s.db, &dbr.ConditionsT{
"tag LIKE ?": keyword, "tag LIKE ?": keyword,
"ORDER": "quote_num DESC", "ORDER": "quote_num DESC",
}, 0, 6) }, 0, 6)
} }
if err == nil {
for _, tag := range tags {
res = append(res, &cs.TagInfo{
ID: tag.ID,
UserID: tag.UserID,
Tag: tag.Tag,
QuoteNum: tag.QuoteNum,
})
}
}
return
} }
func (s *topicServant) FollowTopic(userId int64, topicId int64) (err error) { func (s *topicSrv) FollowTopic(userId int64, topicId int64) (err error) {
return s.db.Create(&dbr.TopicUser{ return s.db.Create(&dbr.TopicUser{
UserID: userId, UserID: userId,
TopicID: topicId, TopicID: topicId,
@ -178,11 +384,11 @@ func (s *topicServant) FollowTopic(userId int64, topicId int64) (err error) {
}).Error }).Error
} }
func (s *topicServant) UnfollowTopic(userId int64, topicId int64) error { func (s *topicSrv) UnfollowTopic(userId int64, topicId int64) error {
return s.db.Exec("DELETE FROM "+s.tnTopicUser+" WHERE user_id=? AND topic_id=?", userId, topicId).Error return s.db.Exec("DELETE FROM "+s.tnTopicUser+" WHERE user_id=? AND topic_id=?", userId, topicId).Error
} }
func (s *topicServant) StickTopic(userId int64, topicId int64) (status int8, err error) { func (s *topicSrv) StickTopic(userId int64, topicId int64) (status int8, err error) {
db := s.db.Begin() db := s.db.Begin()
defer db.Rollback() defer db.Rollback()

@ -9,50 +9,87 @@ import (
"time" "time"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"github.com/rocboss/paopao-ce/pkg/debug"
"gorm.io/gorm" "gorm.io/gorm"
) )
var ( var (
_ core.TweetService = (*tweetServant)(nil) _ core.TweetService = (*tweetSrv)(nil)
_ core.TweetManageService = (*tweetManageServant)(nil) _ core.TweetManageService = (*tweetManageSrv)(nil)
_ core.TweetHelpService = (*tweetHelpServant)(nil) _ core.TweetHelpService = (*tweetHelpSrv)(nil)
_ core.TweetServantA = (*tweetSrvA)(nil)
_ core.TweetManageServantA = (*tweetManageSrvA)(nil)
_ core.TweetHelpServantA = (*tweetHelpSrvA)(nil)
) )
type tweetServant struct { type tweetSrv struct {
db *gorm.DB db *gorm.DB
} }
type tweetManageServant struct { type tweetManageSrv struct {
cacheIndex core.CacheIndexService cacheIndex core.CacheIndexService
db *gorm.DB db *gorm.DB
} }
type tweetHelpServant struct { type tweetHelpSrv struct {
db *gorm.DB
}
type tweetSrvA struct {
db *gorm.DB
}
type tweetManageSrvA struct {
db *gorm.DB
}
type tweetHelpSrvA struct {
db *gorm.DB db *gorm.DB
} }
func newTweetService(db *gorm.DB) core.TweetService { func newTweetService(db *gorm.DB) core.TweetService {
return &tweetServant{ return &tweetSrv{
db: db, db: db,
} }
} }
func newTweetManageService(db *gorm.DB, cacheIndex core.CacheIndexService) core.TweetManageService { func newTweetManageService(db *gorm.DB, cacheIndex core.CacheIndexService) core.TweetManageService {
return &tweetManageServant{ return &tweetManageSrv{
cacheIndex: cacheIndex, cacheIndex: cacheIndex,
db: db, db: db,
} }
} }
func newTweetHelpService(db *gorm.DB) core.TweetHelpService { func newTweetHelpService(db *gorm.DB) core.TweetHelpService {
return &tweetHelpServant{ return &tweetHelpSrv{
db: db,
}
}
func newTweetServantA(db *gorm.DB) core.TweetServantA {
return &tweetSrvA{
db: db,
}
}
func newTweetManageServantA(db *gorm.DB) core.TweetManageServantA {
return &tweetManageSrvA{
db: db,
}
}
func newTweetHelpServantA(db *gorm.DB) core.TweetHelpServantA {
return &tweetHelpSrvA{
db: db, db: db,
} }
} }
// MergePosts post数据整合 // MergePosts post数据整合
func (s *tweetHelpServant) MergePosts(posts []*core.Post) ([]*core.PostFormated, error) { func (s *tweetHelpSrv) MergePosts(posts []*ms.Post) ([]*ms.PostFormated, error) {
postIds := make([]int64, 0, len(posts)) postIds := make([]int64, 0, len(posts))
userIds := make([]int64, 0, len(posts)) userIds := make([]int64, 0, len(posts))
for _, post := range posts { for _, post := range posts {
@ -92,7 +129,7 @@ func (s *tweetHelpServant) MergePosts(posts []*core.Post) ([]*core.PostFormated,
} }
// RevampPosts post数据整形修复 // RevampPosts post数据整形修复
func (s *tweetHelpServant) RevampPosts(posts []*core.PostFormated) ([]*core.PostFormated, error) { func (s *tweetHelpSrv) RevampPosts(posts []*ms.PostFormated) ([]*ms.PostFormated, error) {
postIds := make([]int64, 0, len(posts)) postIds := make([]int64, 0, len(posts))
userIds := make([]int64, 0, len(posts)) userIds := make([]int64, 0, len(posts))
for _, post := range posts { for _, post := range posts {
@ -128,14 +165,14 @@ func (s *tweetHelpServant) RevampPosts(posts []*core.PostFormated) ([]*core.Post
return posts, nil return posts, nil
} }
func (s *tweetHelpServant) getPostContentsByIDs(ids []int64) ([]*dbr.PostContent, error) { func (s *tweetHelpSrv) getPostContentsByIDs(ids []int64) ([]*dbr.PostContent, error) {
return (&dbr.PostContent{}).List(s.db, &dbr.ConditionsT{ return (&dbr.PostContent{}).List(s.db, &dbr.ConditionsT{
"post_id IN ?": ids, "post_id IN ?": ids,
"ORDER": "sort ASC", "ORDER": "sort ASC",
}, 0, 0) }, 0, 0)
} }
func (s *tweetHelpServant) getUsersByIDs(ids []int64) ([]*dbr.User, error) { func (s *tweetHelpSrv) getUsersByIDs(ids []int64) ([]*dbr.User, error) {
user := &dbr.User{} user := &dbr.User{}
return user.List(s.db, &dbr.ConditionsT{ return user.List(s.db, &dbr.ConditionsT{
@ -143,7 +180,7 @@ func (s *tweetHelpServant) getUsersByIDs(ids []int64) ([]*dbr.User, error) {
}, 0, 0) }, 0, 0)
} }
func (s *tweetManageServant) CreatePostCollection(postID, userID int64) (*core.PostCollection, error) { func (s *tweetManageSrv) CreatePostCollection(postID, userID int64) (*ms.PostCollection, error) {
collection := &dbr.PostCollection{ collection := &dbr.PostCollection{
PostID: postID, PostID: postID,
UserID: userID, UserID: userID,
@ -152,19 +189,20 @@ func (s *tweetManageServant) CreatePostCollection(postID, userID int64) (*core.P
return collection.Create(s.db) return collection.Create(s.db)
} }
func (s *tweetManageServant) DeletePostCollection(p *core.PostCollection) error { func (s *tweetManageSrv) DeletePostCollection(p *ms.PostCollection) error {
return p.Delete(s.db) return p.Delete(s.db)
} }
func (s *tweetManageServant) CreatePostContent(content *core.PostContent) (*core.PostContent, error) { func (s *tweetManageSrv) CreatePostContent(content *ms.PostContent) (*ms.PostContent, error) {
return content.Create(s.db) return content.Create(s.db)
} }
func (s *tweetManageServant) CreateAttachment(attachment *core.Attachment) (*core.Attachment, error) { func (s *tweetManageSrv) CreateAttachment(obj *ms.Attachment) (int64, error) {
return attachment.Create(s.db) attachment, err := obj.Create(s.db)
return attachment.ID, err
} }
func (s *tweetManageServant) CreatePost(post *core.Post) (*core.Post, error) { func (s *tweetManageSrv) CreatePost(post *ms.Post) (*ms.Post, error) {
post.LatestRepliedOn = time.Now().Unix() post.LatestRepliedOn = time.Now().Unix()
p, err := post.Create(s.db) p, err := post.Create(s.db)
if err != nil { if err != nil {
@ -174,7 +212,7 @@ func (s *tweetManageServant) CreatePost(post *core.Post) (*core.Post, error) {
return p, nil return p, nil
} }
func (s *tweetManageServant) DeletePost(post *core.Post) ([]string, error) { func (s *tweetManageSrv) DeletePost(post *ms.Post) ([]string, error) {
var mediaContents []string var mediaContents []string
postId := post.ID postId := post.ID
@ -221,7 +259,7 @@ func (s *tweetManageServant) DeletePost(post *core.Post) ([]string, error) {
return mediaContents, nil return mediaContents, nil
} }
func (s *tweetManageServant) deleteCommentByPostId(db *gorm.DB, postId int64) ([]string, error) { func (s *tweetManageSrv) deleteCommentByPostId(db *gorm.DB, postId int64) ([]string, error) {
comment := &dbr.Comment{} comment := &dbr.Comment{}
commentContent := &dbr.CommentContent{} commentContent := &dbr.CommentContent{}
@ -255,12 +293,12 @@ func (s *tweetManageServant) deleteCommentByPostId(db *gorm.DB, postId int64) ([
return mediaContents, nil return mediaContents, nil
} }
func (s *tweetManageServant) LockPost(post *core.Post) error { func (s *tweetManageSrv) LockPost(post *ms.Post) error {
post.IsLock = 1 - post.IsLock post.IsLock = 1 - post.IsLock
return post.Update(s.db) return post.Update(s.db)
} }
func (s *tweetManageServant) StickPost(post *core.Post) error { func (s *tweetManageSrv) StickPost(post *ms.Post) error {
post.IsTop = 1 - post.IsTop post.IsTop = 1 - post.IsTop
if err := post.Update(s.db); err != nil { if err := post.Update(s.db); err != nil {
return err return err
@ -269,7 +307,7 @@ func (s *tweetManageServant) StickPost(post *core.Post) error {
return nil return nil
} }
func (s *tweetManageServant) VisiblePost(post *core.Post, visibility core.PostVisibleT) error { func (s *tweetManageSrv) VisiblePost(post *ms.Post, visibility core.PostVisibleT) error {
oldVisibility := post.Visibility oldVisibility := post.Visibility
post.Visibility = visibility post.Visibility = visibility
// TODO: 这个判断是否可以不要呢 // TODO: 这个判断是否可以不要呢
@ -288,29 +326,22 @@ func (s *tweetManageServant) VisiblePost(post *core.Post, visibility core.PostVi
db.Rollback() db.Rollback()
return err return err
} }
// tag处理 // tag处理
tags := strings.Split(post.Tags, ",") tags := strings.Split(post.Tags, ",")
for _, t := range tags { // TODO: 暂时宽松不处理错误,这里或许可以有优化,后续完善
tag := &dbr.Tag{ if oldVisibility == dbr.PostVisitPrivate {
UserID: post.UserID, // 从私密转为非私密才需要重新创建tag
Tag: t, createTags(db, post.UserID, tags)
} } else if visibility == dbr.PostVisitPrivate {
// TODO: 暂时宽松不处理错误,这里或许可以有优化,后续完善 // 从非私密转为私密才需要删除tag
if oldVisibility == dbr.PostVisitPrivate { deleteTags(db, tags)
// 从私密转为非私密才需要重新创建tag
createTag(db, tag)
} else if visibility == dbr.PostVisitPrivate {
// 从非私密转为私密才需要删除tag
deleteTag(db, tag)
}
} }
db.Commit() db.Commit()
s.cacheIndex.SendAction(core.IdxActVisiblePost, post) s.cacheIndex.SendAction(core.IdxActVisiblePost, post)
return nil return nil
} }
func (s *tweetManageServant) UpdatePost(post *core.Post) error { func (s *tweetManageSrv) UpdatePost(post *ms.Post) error {
if err := post.Update(s.db); err != nil { if err := post.Update(s.db); err != nil {
return err return err
} }
@ -318,7 +349,7 @@ func (s *tweetManageServant) UpdatePost(post *core.Post) error {
return nil return nil
} }
func (s *tweetManageServant) CreatePostStar(postID, userID int64) (*core.PostStar, error) { func (s *tweetManageSrv) CreatePostStar(postID, userID int64) (*ms.PostStar, error) {
star := &dbr.PostStar{ star := &dbr.PostStar{
PostID: postID, PostID: postID,
UserID: userID, UserID: userID,
@ -326,11 +357,11 @@ func (s *tweetManageServant) CreatePostStar(postID, userID int64) (*core.PostSta
return star.Create(s.db) return star.Create(s.db)
} }
func (s *tweetManageServant) DeletePostStar(p *core.PostStar) error { func (s *tweetManageSrv) DeletePostStar(p *ms.PostStar) error {
return p.Delete(s.db) return p.Delete(s.db)
} }
func (s *tweetServant) GetPostByID(id int64) (*core.Post, error) { func (s *tweetSrv) GetPostByID(id int64) (*ms.Post, error) {
post := &dbr.Post{ post := &dbr.Post{
Model: &dbr.Model{ Model: &dbr.Model{
ID: id, ID: id,
@ -339,15 +370,15 @@ func (s *tweetServant) GetPostByID(id int64) (*core.Post, error) {
return post.Get(s.db) return post.Get(s.db)
} }
func (s *tweetServant) GetPosts(conditions *core.ConditionsT, offset, limit int) ([]*core.Post, error) { func (s *tweetSrv) GetPosts(conditions ms.ConditionsT, offset, limit int) ([]*ms.Post, error) {
return (&dbr.Post{}).List(s.db, conditions, offset, limit) return (&dbr.Post{}).List(s.db, conditions, offset, limit)
} }
func (s *tweetServant) GetPostCount(conditions *core.ConditionsT) (int64, error) { func (s *tweetSrv) GetPostCount(conditions ms.ConditionsT) (int64, error) {
return (&dbr.Post{}).Count(s.db, conditions) return (&dbr.Post{}).Count(s.db, conditions)
} }
func (s *tweetServant) GetUserPostStar(postID, userID int64) (*core.PostStar, error) { func (s *tweetSrv) GetUserPostStar(postID, userID int64) (*ms.PostStar, error) {
star := &dbr.PostStar{ star := &dbr.PostStar{
PostID: postID, PostID: postID,
UserID: userID, UserID: userID,
@ -355,7 +386,7 @@ func (s *tweetServant) GetUserPostStar(postID, userID int64) (*core.PostStar, er
return star.Get(s.db) return star.Get(s.db)
} }
func (s *tweetServant) GetUserPostStars(userID int64, offset, limit int) ([]*core.PostStar, error) { func (s *tweetSrv) GetUserPostStars(userID int64, offset, limit int) ([]*ms.PostStar, error) {
star := &dbr.PostStar{ star := &dbr.PostStar{
UserID: userID, UserID: userID,
} }
@ -365,14 +396,14 @@ func (s *tweetServant) GetUserPostStars(userID int64, offset, limit int) ([]*cor
}, offset, limit) }, offset, limit)
} }
func (s *tweetServant) GetUserPostStarCount(userID int64) (int64, error) { func (s *tweetSrv) GetUserPostStarCount(userID int64) (int64, error) {
star := &dbr.PostStar{ star := &dbr.PostStar{
UserID: userID, UserID: userID,
} }
return star.Count(s.db, &dbr.ConditionsT{}) return star.Count(s.db, &dbr.ConditionsT{})
} }
func (s *tweetServant) GetUserPostCollection(postID, userID int64) (*core.PostCollection, error) { func (s *tweetSrv) GetUserPostCollection(postID, userID int64) (*ms.PostCollection, error) {
star := &dbr.PostCollection{ star := &dbr.PostCollection{
PostID: postID, PostID: postID,
UserID: userID, UserID: userID,
@ -380,7 +411,7 @@ func (s *tweetServant) GetUserPostCollection(postID, userID int64) (*core.PostCo
return star.Get(s.db) return star.Get(s.db)
} }
func (s *tweetServant) GetUserPostCollections(userID int64, offset, limit int) ([]*core.PostCollection, error) { func (s *tweetSrv) GetUserPostCollections(userID int64, offset, limit int) ([]*ms.PostCollection, error) {
collection := &dbr.PostCollection{ collection := &dbr.PostCollection{
UserID: userID, UserID: userID,
} }
@ -390,14 +421,14 @@ func (s *tweetServant) GetUserPostCollections(userID int64, offset, limit int) (
}, offset, limit) }, offset, limit)
} }
func (s *tweetServant) GetUserPostCollectionCount(userID int64) (int64, error) { func (s *tweetSrv) GetUserPostCollectionCount(userID int64) (int64, error) {
collection := &dbr.PostCollection{ collection := &dbr.PostCollection{
UserID: userID, UserID: userID,
} }
return collection.Count(s.db, &dbr.ConditionsT{}) return collection.Count(s.db, &dbr.ConditionsT{})
} }
func (s *tweetServant) GetUserWalletBills(userID int64, offset, limit int) ([]*core.WalletStatement, error) { func (s *tweetSrv) GetUserWalletBills(userID int64, offset, limit int) ([]*ms.WalletStatement, error) {
statement := &dbr.WalletStatement{ statement := &dbr.WalletStatement{
UserID: userID, UserID: userID,
} }
@ -407,14 +438,14 @@ func (s *tweetServant) GetUserWalletBills(userID int64, offset, limit int) ([]*c
}, offset, limit) }, offset, limit)
} }
func (s *tweetServant) GetUserWalletBillCount(userID int64) (int64, error) { func (s *tweetSrv) GetUserWalletBillCount(userID int64) (int64, error) {
statement := &dbr.WalletStatement{ statement := &dbr.WalletStatement{
UserID: userID, UserID: userID,
} }
return statement.Count(s.db, &dbr.ConditionsT{}) return statement.Count(s.db, &dbr.ConditionsT{})
} }
func (s *tweetServant) GetPostAttatchmentBill(postID, userID int64) (*core.PostAttachmentBill, error) { func (s *tweetSrv) GetPostAttatchmentBill(postID, userID int64) (*ms.PostAttachmentBill, error) {
bill := &dbr.PostAttachmentBill{ bill := &dbr.PostAttachmentBill{
PostID: postID, PostID: postID,
UserID: userID, UserID: userID,
@ -423,17 +454,117 @@ func (s *tweetServant) GetPostAttatchmentBill(postID, userID int64) (*core.PostA
return bill.Get(s.db) return bill.Get(s.db)
} }
func (s *tweetServant) GetPostContentsByIDs(ids []int64) ([]*core.PostContent, error) { func (s *tweetSrv) GetPostContentsByIDs(ids []int64) ([]*ms.PostContent, error) {
return (&dbr.PostContent{}).List(s.db, &dbr.ConditionsT{ return (&dbr.PostContent{}).List(s.db, &dbr.ConditionsT{
"post_id IN ?": ids, "post_id IN ?": ids,
"ORDER": "sort ASC", "ORDER": "sort ASC",
}, 0, 0) }, 0, 0)
} }
func (s *tweetServant) GetPostContentByID(id int64) (*core.PostContent, error) { func (s *tweetSrv) GetPostContentByID(id int64) (*ms.PostContent, error) {
return (&dbr.PostContent{ return (&dbr.PostContent{
Model: &dbr.Model{ Model: &dbr.Model{
ID: id, ID: id,
}, },
}).Get(s.db) }).Get(s.db)
} }
func (s *tweetSrvA) TweetInfoById(id int64) (*cs.TweetInfo, error) {
// TODO
return nil, debug.ErrNotImplemented
}
func (s *tweetSrvA) TweetItemById(id int64) (*cs.TweetItem, error) {
// TODO
return nil, debug.ErrNotImplemented
}
func (s *tweetSrvA) UserTweets(visitorId, userId int64) (cs.TweetList, error) {
// TODO
return nil, debug.ErrNotImplemented
}
func (s *tweetSrvA) ReactionByTweetId(userId int64, tweetId int64) (*cs.ReactionItem, error) {
// TODO
return nil, debug.ErrNotImplemented
}
func (s *tweetSrvA) UserReactions(userId int64, offset int, limit int) (cs.ReactionList, error) {
// TODO
return nil, debug.ErrNotImplemented
}
func (s *tweetSrvA) FavoriteByTweetId(userId int64, tweetId int64) (*cs.FavoriteItem, error) {
// TODO
return nil, debug.ErrNotImplemented
}
func (s *tweetSrvA) UserFavorites(userId int64, offset int, limit int) (cs.FavoriteList, error) {
// TODO
return nil, debug.ErrNotImplemented
}
func (s *tweetSrvA) AttachmentByTweetId(userId int64, tweetId int64) (*cs.AttachmentBill, error) {
// TODO
return nil, debug.ErrNotImplemented
}
func (s *tweetManageSrvA) CreateAttachment(obj *cs.Attachment) (int64, error) {
// TODO
return 0, debug.ErrNotImplemented
}
func (s *tweetManageSrvA) CreateTweet(userId int64, req *cs.NewTweetReq) (*cs.TweetItem, error) {
// TODO
return nil, debug.ErrNotImplemented
}
func (s *tweetManageSrvA) DeleteTweet(userId int64, tweetId int64) ([]string, error) {
// TODO
return nil, debug.ErrNotImplemented
}
func (s *tweetManageSrvA) LockTweet(userId int64, tweetId int64) error {
// TODO
return debug.ErrNotImplemented
}
func (s *tweetManageSrvA) StickTweet(userId int64, tweetId int64) error {
// TODO
return debug.ErrNotImplemented
}
func (s *tweetManageSrvA) VisibleTweet(userId int64, visibility cs.TweetVisibleType) error {
// TODO
return debug.ErrNotImplemented
}
func (s *tweetManageSrvA) CreateReaction(userId int64, tweetId int64) error {
// TODO
return debug.ErrNotImplemented
}
func (s *tweetManageSrvA) DeleteReaction(userId int64, reactionId int64) error {
// TODO
return debug.ErrNotImplemented
}
func (s *tweetManageSrvA) CreateFavorite(userId int64, tweetId int64) error {
// TODO
return debug.ErrNotImplemented
}
func (s *tweetManageSrvA) DeleteFavorite(userId int64, favoriteId int64) error {
// TODO
return debug.ErrNotImplemented
}
func (s *tweetHelpSrvA) RevampTweets(tweets cs.TweetList) (cs.TweetList, error) {
// TODO
return nil, debug.ErrNotImplemented
}
func (s *tweetHelpSrvA) MergeTweets(tweets cs.TweetInfo) (cs.TweetList, error) {
// TODO
return nil, debug.ErrNotImplemented
}

@ -5,35 +5,52 @@
package jinzhu package jinzhu
import ( import (
"github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"gorm.io/gorm" "gorm.io/gorm"
) )
func createTag(db *gorm.DB, tag *dbr.Tag) (*dbr.Tag, error) { func createTags(db *gorm.DB, userId int64, tags []string) (res cs.TagInfoList, err error) {
t, err := tag.Get(db) for _, name := range tags {
if err != nil { tag := &dbr.Tag{Tag: name}
tag.QuoteNum = 1 if tag, err = tag.Get(db); err == nil {
return tag.Create(db) // 更新
} tag.QuoteNum++
if err = tag.Update(db); err != nil {
// 更新 return
t.QuoteNum++ }
err = t.Update(db) } else {
if tag, err = (&dbr.Tag{
if err != nil { UserID: userId,
return nil, err QuoteNum: 1,
Tag: name,
}).Create(db); err != nil {
return
}
}
res = append(res, &cs.TagInfo{
ID: tag.ID,
UserID: tag.UserID,
Tag: tag.Tag,
QuoteNum: tag.QuoteNum,
})
} }
return
return t, nil
} }
func deleteTag(db *gorm.DB, tag *dbr.Tag) error { func decrTagsByIds(db *gorm.DB, ids []int64) (err error) {
tag, err := tag.Get(db) for _, id := range ids {
if err != nil { tag := &dbr.Tag{Model: &dbr.Model{ID: id}}
return err if tag, err = tag.Get(db); err == nil {
tag.QuoteNum--
if err = tag.Update(db); err != nil {
return
}
} else {
continue
}
} }
tag.QuoteNum-- return nil
return tag.Update(db)
} }
func deleteTags(db *gorm.DB, tags []string) error { func deleteTags(db *gorm.DB, tags []string) error {

@ -17,6 +17,11 @@ func NewDataService() (core.DataService, core.VersionInfo) {
return nil, nil return nil, nil
} }
func NewWebDataServantA() (core.WebDataServantA, core.VersionInfo) {
logrus.Fatal("not support now")
return nil, nil
}
func NewAuthorizationManageService() core.AuthorizationManageService { func NewAuthorizationManageService() core.AuthorizationManageService {
logrus.Fatal("not support now") logrus.Fatal("not support now")
return nil return nil

@ -8,6 +8,7 @@ import (
"time" "time"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -46,7 +47,7 @@ func (s *bridgeTweetSearchServant) DeleteDocuments(identifiers []string) error {
return nil return nil
} }
func (s *bridgeTweetSearchServant) Search(user *core.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) { func (s *bridgeTweetSearchServant) Search(user *ms.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) {
return s.ts.Search(user, q, offset, limit) return s.ts.Search(user, q, offset, limit)
} }

@ -6,6 +6,7 @@ package search
import ( import (
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/pkg/types" "github.com/rocboss/paopao-ce/pkg/types"
) )
@ -13,13 +14,13 @@ type tweetSearchFilter struct {
ams core.AuthorizationManageService ams core.AuthorizationManageService
} }
func (s *tweetSearchFilter) filterResp(user *core.User, resp *core.QueryResp) { func (s *tweetSearchFilter) filterResp(user *ms.User, resp *core.QueryResp) {
// 管理员不过滤 // 管理员不过滤
if user != nil && user.IsAdmin { if user != nil && user.IsAdmin {
return return
} }
var item *core.PostFormated var item *ms.PostFormated
items := resp.Items items := resp.Items
latestIndex := len(items) - 1 latestIndex := len(items) - 1
if user == nil { if user == nil {

@ -11,6 +11,7 @@ import (
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/meilisearch/meilisearch-go" "github.com/meilisearch/meilisearch-go"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/pkg/json" "github.com/rocboss/paopao-ce/pkg/json"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -81,7 +82,7 @@ func (s *meiliTweetSearchServant) DeleteDocuments(identifiers []string) error {
return nil return nil
} }
func (s *meiliTweetSearchServant) Search(user *core.User, q *core.QueryReq, offset, limit int) (resp *core.QueryResp, err error) { func (s *meiliTweetSearchServant) Search(user *ms.User, q *core.QueryReq, offset, limit int) (resp *core.QueryResp, err error) {
if q.Type == core.SearchTypeDefault && q.Query != "" { if q.Type == core.SearchTypeDefault && q.Query != "" {
resp, err = s.queryByContent(user, q, offset, limit) resp, err = s.queryByContent(user, q, offset, limit)
} else if q.Type == core.SearchTypeTag && q.Query != "" { } else if q.Type == core.SearchTypeTag && q.Query != "" {
@ -99,7 +100,7 @@ func (s *meiliTweetSearchServant) Search(user *core.User, q *core.QueryReq, offs
return return
} }
func (s *meiliTweetSearchServant) queryByContent(user *core.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) { func (s *meiliTweetSearchServant) queryByContent(user *ms.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) {
request := &meilisearch.SearchRequest{ request := &meilisearch.SearchRequest{
Offset: int64(offset), Offset: int64(offset),
Limit: int64(limit), Limit: int64(limit),
@ -121,7 +122,7 @@ func (s *meiliTweetSearchServant) queryByContent(user *core.User, q *core.QueryR
return s.postsFrom(resp) return s.postsFrom(resp)
} }
func (s *meiliTweetSearchServant) queryByTag(user *core.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) { func (s *meiliTweetSearchServant) queryByTag(user *ms.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) {
request := &meilisearch.SearchRequest{ request := &meilisearch.SearchRequest{
Offset: int64(offset), Offset: int64(offset),
Limit: int64(limit), Limit: int64(limit),
@ -145,7 +146,7 @@ func (s *meiliTweetSearchServant) queryByTag(user *core.User, q *core.QueryReq,
return s.postsFrom(resp) return s.postsFrom(resp)
} }
func (s *meiliTweetSearchServant) queryAny(user *core.User, offset, limit int) (*core.QueryResp, error) { func (s *meiliTweetSearchServant) queryAny(user *ms.User, offset, limit int) (*core.QueryResp, error) {
request := &meilisearch.SearchRequest{ request := &meilisearch.SearchRequest{
Offset: int64(offset), Offset: int64(offset),
Limit: int64(limit), Limit: int64(limit),
@ -165,7 +166,7 @@ func (s *meiliTweetSearchServant) queryAny(user *core.User, offset, limit int) (
return s.postsFrom(resp) return s.postsFrom(resp)
} }
func (s *meiliTweetSearchServant) filterList(user *core.User) string { func (s *meiliTweetSearchServant) filterList(user *ms.User) string {
if user == nil { if user == nil {
return s.publicFilter return s.publicFilter
} }
@ -178,7 +179,7 @@ func (s *meiliTweetSearchServant) filterList(user *core.User) string {
} }
func (s *meiliTweetSearchServant) postsFrom(resp *meilisearch.SearchResponse) (*core.QueryResp, error) { func (s *meiliTweetSearchServant) postsFrom(resp *meilisearch.SearchResponse) (*core.QueryResp, error) {
posts := make([]*core.PostFormated, 0, len(resp.Hits)) posts := make([]*ms.PostFormated, 0, len(resp.Hits))
for _, hit := range resp.Hits { for _, hit := range resp.Hits {
raw, err := json.Marshal(hit) raw, err := json.Marshal(hit)
if err != nil { if err != nil {
@ -188,7 +189,7 @@ func (s *meiliTweetSearchServant) postsFrom(resp *meilisearch.SearchResponse) (*
if err = json.Unmarshal(raw, p); err != nil { if err = json.Unmarshal(raw, p); err != nil {
return nil, err return nil, err
} }
posts = append(posts, &core.PostFormated{ posts = append(posts, &ms.PostFormated{
ID: p.ID, ID: p.ID,
UserID: p.UserID, UserID: p.UserID,
CommentCount: p.CommentCount, CommentCount: p.CommentCount,

@ -9,6 +9,7 @@ import (
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/pkg/json" "github.com/rocboss/paopao-ce/pkg/json"
"github.com/rocboss/paopao-ce/pkg/zinc" "github.com/rocboss/paopao-ce/pkg/zinc"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -76,7 +77,7 @@ func (s *zincTweetSearchServant) DeleteDocuments(identifiers []string) error {
return nil return nil
} }
func (s *zincTweetSearchServant) Search(user *core.User, q *core.QueryReq, offset, limit int) (resp *core.QueryResp, err error) { func (s *zincTweetSearchServant) Search(user *ms.User, q *core.QueryReq, offset, limit int) (resp *core.QueryResp, err error) {
if q.Type == core.SearchTypeDefault && q.Query != "" { if q.Type == core.SearchTypeDefault && q.Query != "" {
resp, err = s.queryByContent(user, q, offset, limit) resp, err = s.queryByContent(user, q, offset, limit)
} else if q.Type == core.SearchTypeTag && q.Query != "" { } else if q.Type == core.SearchTypeTag && q.Query != "" {
@ -94,7 +95,7 @@ func (s *zincTweetSearchServant) Search(user *core.User, q *core.QueryReq, offse
return return
} }
func (s *zincTweetSearchServant) queryByContent(user *core.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) { func (s *zincTweetSearchServant) queryByContent(user *ms.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) {
resp, err := s.client.EsQuery(s.indexName, map[string]any{ resp, err := s.client.EsQuery(s.indexName, map[string]any{
"query": map[string]any{ "query": map[string]any{
"match_phrase": map[string]any{ "match_phrase": map[string]any{
@ -111,7 +112,7 @@ func (s *zincTweetSearchServant) queryByContent(user *core.User, q *core.QueryRe
return s.postsFrom(resp) return s.postsFrom(resp)
} }
func (s *zincTweetSearchServant) queryByTag(user *core.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) { func (s *zincTweetSearchServant) queryByTag(user *ms.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) {
resp, err := s.client.ApiQuery(s.indexName, map[string]any{ resp, err := s.client.ApiQuery(s.indexName, map[string]any{
"search_type": "querystring", "search_type": "querystring",
"query": map[string]any{ "query": map[string]any{
@ -127,7 +128,7 @@ func (s *zincTweetSearchServant) queryByTag(user *core.User, q *core.QueryReq, o
return s.postsFrom(resp) return s.postsFrom(resp)
} }
func (s *zincTweetSearchServant) queryAny(user *core.User, offset, limit int) (*core.QueryResp, error) { func (s *zincTweetSearchServant) queryAny(user *ms.User, offset, limit int) (*core.QueryResp, error) {
queryMap := map[string]any{ queryMap := map[string]any{
"query": map[string]any{ "query": map[string]any{
"match_all": map[string]string{}, "match_all": map[string]string{},
@ -144,9 +145,9 @@ func (s *zincTweetSearchServant) queryAny(user *core.User, offset, limit int) (*
} }
func (s *zincTweetSearchServant) postsFrom(resp *zinc.QueryResultT) (*core.QueryResp, error) { func (s *zincTweetSearchServant) postsFrom(resp *zinc.QueryResultT) (*core.QueryResp, error) {
posts := make([]*core.PostFormated, 0, len(resp.Hits.Hits)) posts := make([]*ms.PostFormated, 0, len(resp.Hits.Hits))
for _, hit := range resp.Hits.Hits { for _, hit := range resp.Hits.Hits {
item := &core.PostFormated{} item := &ms.PostFormated{}
raw, err := json.Marshal(hit.Source) raw, err := json.Marshal(hit.Source)
if err != nil { if err != nil {
return nil, err return nil, err

@ -17,6 +17,11 @@ func NewDataService() (core.DataService, core.VersionInfo) {
return nil, nil return nil, nil
} }
func NewWebDataServantA() (core.WebDataServantA, core.VersionInfo) {
logrus.Fatal("not support now")
return nil, nil
}
func NewAuthorizationManageService() core.AuthorizationManageService { func NewAuthorizationManageService() core.AuthorizationManageService {
logrus.Fatal("not support now") logrus.Fatal("not support now")
return nil return nil

@ -42,9 +42,9 @@ func Run() {
db, err = sql.Open("mysql", conf.MysqlSetting.Dsn()+"&multiStatements=true") db, err = sql.Open("mysql", conf.MysqlSetting.Dsn()+"&multiStatements=true")
} else if cfg.If("PostgreSQL") || cfg.If("Postgres") { } else if cfg.If("PostgreSQL") || cfg.If("Postgres") {
dbName = (*conf.PostgresSetting)["DBName"] dbName = (*conf.PostgresSetting)["DBName"]
db, err = sql.Open("postgres", conf.PostgresSetting.Dsn()) db, err = sql.Open("pgx", conf.PostgresSetting.Dsn())
} else if cfg.If("Sqlite3") { } else if cfg.If("Sqlite3") {
db, err = conf.OpenSqlite3() _, db, err = conf.OpenSqlite3()
} else { } else {
dbName = conf.MysqlSetting.DBName dbName = conf.MysqlSetting.DBName
db, err = sql.Open("mysql", conf.MysqlSetting.Dsn()) db, err = sql.Open("mysql", conf.MysqlSetting.Dsn())

@ -8,24 +8,28 @@ import (
"github.com/alimy/mir/v4" "github.com/alimy/mir/v4"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/servants/base" "github.com/rocboss/paopao-ce/internal/servants/base"
"github.com/rocboss/paopao-ce/pkg/app" "github.com/rocboss/paopao-ce/pkg/app"
) )
const ( const (
TagTypeHot TagType = "hot" TagTypeHot = cs.TagTypeHot
TagTypeNew TagType = "new" TagTypeNew = cs.TagTypeNew
TagTypeFollow TagType = "follow" TagTypeFollow = cs.TagTypeFollow
TagTypeHotExtral TagType = "hot_extral" TagTypeHotExtral = cs.TagTypeHotExtral
) )
const ( const (
UserPostsStylePost = "post" UserPostsStylePost = "post"
UserPostsStyleComment = "comment" UserPostsStyleComment = "comment"
UserPostsStyleMedia = "media" UserPostsStyleHighlight = "highlight"
UserPostsStyleStar = "star" UserPostsStyleMedia = "media"
UserPostsStyleStar = "star"
) )
type TagType = cs.TagType
type TweetCommentsReq struct { type TweetCommentsReq struct {
SimpleInfo `form:"-" binding:"-"` SimpleInfo `form:"-" binding:"-"`
TweetId int64 `form:"id" binding:"required"` TweetId int64 `form:"id" binding:"required"`
@ -36,8 +40,6 @@ type TweetCommentsReq struct {
type TweetCommentsResp base.PageResp type TweetCommentsResp base.PageResp
type TagType string
type TimelineReq struct { type TimelineReq struct {
BaseInfo `form:"-" binding:"-"` BaseInfo `form:"-" binding:"-"`
Query string `form:"query"` Query string `form:"query"`
@ -84,8 +86,8 @@ type TopicListReq struct {
// TopicListResp 主题返回值 // TopicListResp 主题返回值
// TODO: 优化内容定义 // TODO: 优化内容定义
type TopicListResp struct { type TopicListResp struct {
Topics []*core.TagFormated `json:"topics"` Topics cs.TagList `json:"topics"`
ExtralTopics []*core.TagFormated `json:"extral_topics,omitempty"` ExtralTopics cs.TagList `json:"extral_topics,omitempty"`
} }
func (r *GetUserTweetsReq) SetPageInfo(page int, pageSize int) { func (r *GetUserTweetsReq) SetPageInfo(page int, pageSize int) {

@ -12,6 +12,7 @@ import (
"github.com/alimy/mir/v4" "github.com/alimy/mir/v4"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/servants/base" "github.com/rocboss/paopao-ce/internal/servants/base"
"github.com/rocboss/paopao-ce/pkg/convert" "github.com/rocboss/paopao-ce/pkg/convert"
"github.com/rocboss/paopao-ce/pkg/xerror" "github.com/rocboss/paopao-ce/pkg/xerror"
@ -31,9 +32,9 @@ type TweetReplyThumbsReq struct {
} }
type PostContentItem struct { type PostContentItem struct {
Content string `json:"content" binding:"required"` Content string `json:"content" binding:"required"`
Type core.PostContentT `json:"type" binding:"required"` Type ms.PostContentT `json:"type" binding:"required"`
Sort int64 `json:"sort" binding:"required"` Sort int64 `json:"sort" binding:"required"`
} }
type CreateTweetReq struct { type CreateTweetReq struct {
@ -46,7 +47,7 @@ type CreateTweetReq struct {
ClientIP string `json:"-" binding:"-"` ClientIP string `json:"-" binding:"-"`
} }
type CreateTweetResp core.PostFormated type CreateTweetResp ms.PostFormated
type DeleteTweetReq struct { type DeleteTweetReq struct {
BaseInfo `json:"-" binding:"-"` BaseInfo `json:"-" binding:"-"`
@ -85,10 +86,19 @@ type StickTweetReq struct {
ID int64 `json:"id" binding:"required"` ID int64 `json:"id" binding:"required"`
} }
type HighlightTweetReq struct {
BaseInfo `json:"-" binding:"-"`
ID int64 `json:"id" binding:"required"`
}
type StickTweetResp struct { type StickTweetResp struct {
StickStatus int `json:"top_status"` StickStatus int `json:"top_status"`
} }
type HighlightTweetResp struct {
HighlightStatus int `json:"highlight_status"`
}
type VisibleTweetReq struct { type VisibleTweetReq struct {
BaseInfo `json:"-" binding:"-"` BaseInfo `json:"-" binding:"-"`
ID int64 `json:"id"` ID int64 `json:"id"`
@ -107,7 +117,7 @@ type CreateCommentReq struct {
ClientIP string `json:"-" binding:"-"` ClientIP string `json:"-" binding:"-"`
} }
type CreateCommentResp core.Comment type CreateCommentResp ms.Comment
type CreateCommentReplyReq struct { type CreateCommentReplyReq struct {
SimpleInfo `json:"-" binding:"-"` SimpleInfo `json:"-" binding:"-"`
@ -117,7 +127,7 @@ type CreateCommentReplyReq struct {
ClientIP string `json:"-" binding:"-"` ClientIP string `json:"-" binding:"-"`
} }
type CreateCommentReplyResp core.CommentReply type CreateCommentReplyResp ms.CommentReply
type DeleteCommentReq struct { type DeleteCommentReq struct {
BaseInfo `json:"-" binding:"-"` BaseInfo `json:"-" binding:"-"`
@ -138,12 +148,12 @@ type UploadAttachmentReq struct {
} }
type UploadAttachmentResp struct { type UploadAttachmentResp struct {
UserID int64 `json:"user_id"` UserID int64 `json:"user_id"`
FileSize int64 `json:"file_size"` FileSize int64 `json:"file_size"`
ImgWidth int `json:"img_width"` ImgWidth int `json:"img_width"`
ImgHeight int `json:"img_height"` ImgHeight int `json:"img_height"`
Type core.AttachmentType `json:"type"` Type ms.AttachmentType `json:"type"`
Content string `json:"content"` Content string `json:"content"`
} }
type DownloadAttachmentPrecheckReq struct { type DownloadAttachmentPrecheckReq struct {
@ -186,13 +196,13 @@ type UnfollowTopicReq struct {
// Check 检查PostContentItem属性 // Check 检查PostContentItem属性
func (p *PostContentItem) Check(acs core.AttachmentCheckService) error { func (p *PostContentItem) Check(acs core.AttachmentCheckService) error {
// 检查附件是否是本站资源 // 检查附件是否是本站资源
if p.Type == core.ContentTypeImage || p.Type == core.ContentTypeVideo || p.Type == core.ContentTypeAttachment { if p.Type == ms.ContentTypeImage || p.Type == ms.ContentTypeVideo || p.Type == ms.ContentTypeAttachment {
if err := acs.CheckAttachment(p.Content); err != nil { if err := acs.CheckAttachment(p.Content); err != nil {
return err return err
} }
} }
// 检查链接是否合法 // 检查链接是否合法
if p.Type == core.ContentTypeLink { if p.Type == ms.ContentTypeLink {
if strings.Index(p.Content, "http://") != 0 && strings.Index(p.Content, "https://") != 0 { if strings.Index(p.Content, "http://") != 0 && strings.Index(p.Content, "https://") != 0 {
return fmt.Errorf("链接不合法") return fmt.Errorf("链接不合法")
} }

@ -5,7 +5,7 @@
package web package web
import ( import (
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/pkg/version" "github.com/rocboss/paopao-ce/pkg/version"
) )
@ -13,7 +13,7 @@ type TweetDetailReq struct {
TweetId int64 `form:"id"` TweetId int64 `form:"id"`
} }
type TweetDetailResp core.PostFormated type TweetDetailResp ms.PostFormated
type GetCaptchaResp struct { type GetCaptchaResp struct {
Id string `json:"id"` Id string `json:"id"`

@ -7,7 +7,7 @@ package web
import ( import (
"github.com/alimy/mir/v4" "github.com/alimy/mir/v4"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/servants/base" "github.com/rocboss/paopao-ce/internal/servants/base"
"github.com/rocboss/paopao-ce/pkg/app" "github.com/rocboss/paopao-ce/pkg/app"
"github.com/rocboss/paopao-ce/pkg/xerror" "github.com/rocboss/paopao-ce/pkg/xerror"
@ -18,7 +18,7 @@ var (
) )
type BaseInfo struct { type BaseInfo struct {
User *core.User User *ms.User
} }
type SimpleInfo struct { type SimpleInfo struct {
@ -31,7 +31,7 @@ type BasePageReq struct {
PageSize int PageSize int
} }
func (b *BaseInfo) SetUser(user *core.User) { func (b *BaseInfo) SetUser(user *ms.User) {
b.User = user b.User = user
} }

@ -17,6 +17,7 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/conf" "github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/dao" "github.com/rocboss/paopao-ce/internal/dao"
"github.com/rocboss/paopao-ce/internal/dao/cache" "github.com/rocboss/paopao-ce/internal/dao/cache"
"github.com/rocboss/paopao-ce/pkg/app" "github.com/rocboss/paopao-ce/pkg/app"
@ -31,6 +32,7 @@ type BaseServant struct {
type DaoServant struct { type DaoServant struct {
*BaseServant *BaseServant
Dsa core.WebDataServantA
Ds core.DataService Ds core.DataService
Ts core.TweetSearchService Ts core.TweetSearchService
Redis core.RedisCache Redis core.RedisCache
@ -47,7 +49,7 @@ type SentryHubSetter interface {
} }
type UserSetter interface { type UserSetter interface {
SetUser(*core.User) SetUser(*ms.User)
} }
type UserIdSetter interface { type UserIdSetter interface {
@ -58,9 +60,9 @@ type PageInfoSetter interface {
SetPageInfo(page, pageSize int) SetPageInfo(page, pageSize int)
} }
func UserFrom(c *gin.Context) (*core.User, bool) { func UserFrom(c *gin.Context) (*ms.User, bool) {
if u, exists := c.Get("USER"); exists { if u, exists := c.Get("USER"); exists {
user, ok := u.(*core.User) user, ok := u.(*ms.User)
return user, ok return user, ok
} }
return nil, false return nil, false
@ -174,7 +176,7 @@ func (s *BaseServant) Render(c *gin.Context, data any, err mir.Error) {
} }
} }
func (s *DaoServant) GetTweetBy(id int64) (*core.PostFormated, error) { func (s *DaoServant) GetTweetBy(id int64) (*ms.PostFormated, error) {
post, err := s.Ds.GetPostByID(id) post, err := s.Ds.GetPostByID(id)
if err != nil { if err != nil {
return nil, err return nil, err
@ -205,20 +207,21 @@ func (s *DaoServant) PushPostsToSearch(c context.Context) {
defer s.Redis.DelPushToSearchJob(c) defer s.Redis.DelPushToSearchJob(c)
splitNum := 1000 splitNum := 1000
totalRows, _ := s.Ds.GetPostCount(&core.ConditionsT{ conditions := ms.ConditionsT{
"visibility IN ?": []core.PostVisibleT{core.PostVisitPublic, core.PostVisitFriend}, "visibility IN ?": []core.PostVisibleT{core.PostVisitPublic, core.PostVisitFriend},
}) }
totalRows, _ := s.Ds.GetPostCount(conditions)
pages := math.Ceil(float64(totalRows) / float64(splitNum)) pages := math.Ceil(float64(totalRows) / float64(splitNum))
nums := int(pages) nums := int(pages)
for i := 0; i < nums; i++ { for i := 0; i < nums; i++ {
posts, postsFormated, err := s.GetTweetList(&core.ConditionsT{}, i*splitNum, splitNum) posts, postsFormated, err := s.GetTweetList(conditions, i*splitNum, splitNum)
if err != nil || len(posts) != len(postsFormated) { if err != nil || len(posts) != len(postsFormated) {
continue continue
} }
for i, pf := range postsFormated { for i, pf := range postsFormated {
contentFormated := "" contentFormated := ""
for _, content := range pf.Contents { for _, content := range pf.Contents {
if content.Type == core.ContentTypeText || content.Type == core.ContentTypeTitle { if content.Type == ms.ContentTypeText || content.Type == ms.ContentTypeTitle {
contentFormated = contentFormated + content.Content + "\n" contentFormated = contentFormated + content.Content + "\n"
} }
} }
@ -234,9 +237,9 @@ func (s *DaoServant) PushPostsToSearch(c context.Context) {
} }
} }
func (s *DaoServant) PushPostToSearch(post *core.Post) { func (s *DaoServant) PushPostToSearch(post *ms.Post) {
postFormated := post.Format() postFormated := post.Format()
postFormated.User = &core.UserFormated{ postFormated.User = &ms.UserFormated{
ID: post.UserID, ID: post.UserID,
} }
contents, _ := s.Ds.GetPostContentsByIDs([]int64{post.ID}) contents, _ := s.Ds.GetPostContentsByIDs([]int64{post.ID})
@ -246,7 +249,7 @@ func (s *DaoServant) PushPostToSearch(post *core.Post) {
contentFormated := "" contentFormated := ""
for _, content := range postFormated.Contents { for _, content := range postFormated.Contents {
if content.Type == core.ContentTypeText || content.Type == core.ContentTypeTitle { if content.Type == ms.ContentTypeText || content.Type == ms.ContentTypeTitle {
contentFormated = contentFormated + content.Content + "\n" contentFormated = contentFormated + content.Content + "\n"
} }
} }
@ -258,11 +261,11 @@ func (s *DaoServant) PushPostToSearch(post *core.Post) {
s.Ts.AddDocuments(docs, fmt.Sprintf("%d", post.ID)) s.Ts.AddDocuments(docs, fmt.Sprintf("%d", post.ID))
} }
func (s *DaoServant) DeleteSearchPost(post *core.Post) error { func (s *DaoServant) DeleteSearchPost(post *ms.Post) error {
return s.Ts.DeleteDocuments([]string{fmt.Sprintf("%d", post.ID)}) return s.Ts.DeleteDocuments([]string{fmt.Sprintf("%d", post.ID)})
} }
func (s *DaoServant) GetTweetList(conditions *core.ConditionsT, offset, limit int) ([]*core.Post, []*core.PostFormated, error) { func (s *DaoServant) GetTweetList(conditions ms.ConditionsT, offset, limit int) ([]*ms.Post, []*ms.PostFormated, error) {
posts, err := s.Ds.GetPosts(conditions, offset, limit) posts, err := s.Ds.GetPosts(conditions, offset, limit)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
@ -288,6 +291,7 @@ func NewDaoServant() *DaoServant {
return &DaoServant{ return &DaoServant{
BaseServant: NewBaseServant(), BaseServant: NewBaseServant(),
Redis: cache.NewRedisCache(), Redis: cache.NewRedisCache(),
Dsa: dao.WebDataServantA(),
Ds: dao.DataService(), Ds: dao.DataService(),
Ts: dao.TweetSearchService(), Ts: dao.TweetSearchService(),
} }

@ -6,15 +6,15 @@ package chain
import ( import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/pkg/app" "github.com/rocboss/paopao-ce/pkg/app"
) )
func Admin() gin.HandlerFunc { func Admin() gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
if user, exist := c.Get("USER"); exist { if user, exist := c.Get("USER"); exist {
if userModel, ok := user.(*core.User); ok { if userModel, ok := user.(*ms.User); ok {
if userModel.Status == core.UserStatusNormal && userModel.IsAdmin { if userModel.Status == ms.UserStatusNormal && userModel.IsAdmin {
c.Next() c.Next()
return return
} }

@ -7,7 +7,7 @@ package chain
import ( import (
"github.com/alimy/cfg" "github.com/alimy/cfg"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/pkg/app" "github.com/rocboss/paopao-ce/pkg/app"
) )
@ -15,8 +15,8 @@ func Priv() gin.HandlerFunc {
if cfg.If("PhoneBind") { if cfg.If("PhoneBind") {
return func(c *gin.Context) { return func(c *gin.Context) {
if u, exist := c.Get("USER"); exist { if u, exist := c.Get("USER"); exist {
if user, ok := u.(*core.User); ok { if user, ok := u.(*ms.User); ok {
if user.Status == core.UserStatusNormal { if user.Status == ms.UserStatusNormal {
if user.Phone == "" { if user.Phone == "" {
response := app.NewResponse(c) response := app.NewResponse(c)
response.ToErrorResponse(_errAccountNoPhoneBind) response.ToErrorResponse(_errAccountNoPhoneBind)
@ -35,7 +35,7 @@ func Priv() gin.HandlerFunc {
} else { } else {
return func(c *gin.Context) { return func(c *gin.Context) {
if u, exist := c.Get("USER"); exist { if u, exist := c.Get("USER"); exist {
if user, ok := u.(*core.User); ok && user.Status == core.UserStatusNormal { if user, ok := u.(*ms.User); ok && user.Status == ms.UserStatusNormal {
c.Next() c.Next()
return return
} }

@ -14,6 +14,7 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
api "github.com/rocboss/paopao-ce/auto/api/v1" api "github.com/rocboss/paopao-ce/auto/api/v1"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/model/web" "github.com/rocboss/paopao-ce/internal/model/web"
"github.com/rocboss/paopao-ce/internal/servants/base" "github.com/rocboss/paopao-ce/internal/servants/base"
"github.com/rocboss/paopao-ce/internal/servants/chain" "github.com/rocboss/paopao-ce/internal/servants/chain"
@ -85,7 +86,7 @@ func (s *coreSrv) GetUnreadMsgCount(req *web.GetUnreadMsgCountReq) (*web.GetUnre
} }
func (s *coreSrv) GetMessages(req *web.GetMessagesReq) (*web.GetMessagesResp, mir.Error) { func (s *coreSrv) GetMessages(req *web.GetMessagesReq) (*web.GetMessagesResp, mir.Error) {
conditions := &core.ConditionsT{ conditions := &ms.ConditionsT{
"receiver_user_id": req.UserId, "receiver_user_id": req.UserId,
"ORDER": "id DESC", "ORDER": "id DESC",
} }
@ -98,7 +99,7 @@ func (s *coreSrv) GetMessages(req *web.GetMessagesReq) (*web.GetMessagesResp, mi
} }
} }
// 好友申请消息不需要获取其他信息 // 好友申请消息不需要获取其他信息
if mf.Type == core.MsgTypeRequestingFriend { if mf.Type == ms.MsgTypeRequestingFriend {
continue continue
} }
if mf.PostID > 0 { if mf.PostID > 0 {
@ -157,10 +158,10 @@ func (s *coreSrv) SendUserWhisper(req *web.SendWhisperReq) mir.Error {
} }
// 创建私信 // 创建私信
_, err := s.Ds.CreateMessage(&core.Message{ _, err := s.Ds.CreateMessage(&ms.Message{
SenderUserID: req.Uid, SenderUserID: req.Uid,
ReceiverUserID: req.UserID, ReceiverUserID: req.UserID,
Type: core.MsgTypeWhisper, Type: ms.MsgTypeWhisper,
Brief: "给你发送新私信了", Brief: "给你发送新私信了",
Content: req.Content, Content: req.Content,
}) })
@ -187,7 +188,7 @@ func (s *coreSrv) GetCollections(req *web.GetCollectionsReq) (*web.GetCollection
return nil, web.ErrGetCollectionsFailed return nil, web.ErrGetCollectionsFailed
} }
var posts []*core.Post var posts []*ms.Post
for _, collection := range collections { for _, collection := range collections {
posts = append(posts, collection.Post) posts = append(posts, collection.Post)
} }
@ -250,7 +251,7 @@ func (s *coreSrv) GetStars(req *web.GetStarsReq) (*web.GetStarsResp, mir.Error)
return nil, web.ErrGetStarsFailed return nil, web.ErrGetStarsFailed
} }
var posts []*core.Post var posts []*ms.Post
for _, star := range stars { for _, star := range stars {
posts = append(posts, star.Post) posts = append(posts, star.Post)
} }
@ -284,7 +285,7 @@ func (s *coreSrv) ChangePassword(req *web.ChangePasswordReq) mir.Error {
} }
func (s *coreSrv) SuggestTags(req *web.SuggestTagsReq) (*web.SuggestTagsResp, mir.Error) { func (s *coreSrv) SuggestTags(req *web.SuggestTagsReq) (*web.SuggestTagsResp, mir.Error) {
tags, err := s.Ds.GetTagsByKeyword(req.Keyword) tags, err := s.Ds.TagsByKeyword(req.Keyword)
if err != nil { if err != nil {
logrus.Errorf("Ds.GetTagsByKeyword err: %s", err) logrus.Errorf("Ds.GetTagsByKeyword err: %s", err)
return nil, xerror.ServerError return nil, xerror.ServerError

@ -10,6 +10,7 @@ import (
api "github.com/rocboss/paopao-ce/auto/api/v1" api "github.com/rocboss/paopao-ce/auto/api/v1"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/cs" "github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"github.com/rocboss/paopao-ce/internal/model/web" "github.com/rocboss/paopao-ce/internal/model/web"
"github.com/rocboss/paopao-ce/internal/servants/base" "github.com/rocboss/paopao-ce/internal/servants/base"
@ -65,6 +66,8 @@ func (s *looseSrv) GetUserTweets(req *web.GetUserTweetsReq) (res *web.GetUserTwe
switch req.Style { switch req.Style {
case web.UserPostsStyleComment: case web.UserPostsStyleComment:
res, err = s.getUserCommentTweets(req, isSelf) res, err = s.getUserCommentTweets(req, isSelf)
case web.UserPostsStyleHighlight:
res, err = s.getUserHighlightTweets(req, isSelf)
case web.UserPostsStyleMedia: case web.UserPostsStyleMedia:
res, err = s.getUserMediaTweets(req, isSelf) res, err = s.getUserMediaTweets(req, isSelf)
case web.UserPostsStyleStar: case web.UserPostsStyleStar:
@ -83,6 +86,12 @@ func (s *looseSrv) getUserCommentTweets(req *web.GetUserTweetsReq, isSelf bool)
return (*web.GetUserTweetsResp)(resp), nil return (*web.GetUserTweetsResp)(resp), nil
} }
func (s *looseSrv) getUserHighlightTweets(req *web.GetUserTweetsReq, isSelf bool) (*web.GetUserTweetsResp, mir.Error) {
// TODO: add implement logic
resp := base.PageRespFrom(nil, req.Page, req.PageSize, 0)
return (*web.GetUserTweetsResp)(resp), nil
}
func (s *looseSrv) getUserMediaTweets(req *web.GetUserTweetsReq, isSelf bool) (*web.GetUserTweetsResp, mir.Error) { func (s *looseSrv) getUserMediaTweets(req *web.GetUserTweetsReq, isSelf bool) (*web.GetUserTweetsResp, mir.Error) {
// TODO: add implement logic // TODO: add implement logic
resp := base.PageRespFrom(nil, req.Page, req.PageSize, 0) resp := base.PageRespFrom(nil, req.Page, req.PageSize, 0)
@ -121,7 +130,7 @@ func (s *looseSrv) getSelfStarTweets(req *web.GetUserTweetsReq) (*web.GetUserTwe
logrus.Errorf("Ds.GetUserPostStars err: %s", err) logrus.Errorf("Ds.GetUserPostStars err: %s", err)
return nil, web.ErrGetStarsFailed return nil, web.ErrGetStarsFailed
} }
var posts []*core.Post var posts []*ms.Post
for _, star := range stars { for _, star := range stars {
posts = append(posts, star.Post) posts = append(posts, star.Post)
} }
@ -151,7 +160,7 @@ func (s *looseSrv) getUserPostTweets(req *web.GetUserTweetsReq) (*web.GetUserTwe
visibilities = append(visibilities, core.PostVisitFriend) visibilities = append(visibilities, core.PostVisitFriend)
} }
} }
conditions := &core.ConditionsT{ conditions := ms.ConditionsT{
"user_id": other.ID, "user_id": other.ID,
"visibility IN ?": visibilities, "visibility IN ?": visibilities,
"ORDER": "latest_replied_on DESC", "ORDER": "latest_replied_on DESC",
@ -198,7 +207,7 @@ func (s *looseSrv) GetUserProfile(req *web.GetUserProfileReq) (*web.GetUserProfi
func (s *looseSrv) TopicList(req *web.TopicListReq) (*web.TopicListResp, mir.Error) { func (s *looseSrv) TopicList(req *web.TopicListReq) (*web.TopicListResp, mir.Error) {
var ( var (
tags, extralTags []*core.TagFormated tags, extralTags cs.TagList
err error err error
) )
num := req.Num num := req.Num
@ -236,7 +245,7 @@ func (s *looseSrv) TweetComments(req *web.TweetCommentsReq) (*web.TweetCommentsR
if req.SortStrategy == "newest" { if req.SortStrategy == "newest" {
sort = "id DESC" sort = "id DESC"
} }
conditions := &core.ConditionsT{ conditions := &ms.ConditionsT{
"post_id": req.TweetId, "post_id": req.TweetId,
"ORDER": sort, "ORDER": sort,
} }
@ -290,7 +299,7 @@ func (s *looseSrv) TweetComments(req *web.TweetCommentsReq) (*web.TweetCommentsR
} }
} }
commentsFormated := []*core.CommentFormated{} commentsFormated := []*ms.CommentFormated{}
for _, comment := range comments { for _, comment := range comments {
commentFormated := comment.Format() commentFormated := comment.Format()
if thumbs, exist := commentThumbs[comment.ID]; exist { if thumbs, exist := commentThumbs[comment.ID]; exist {

@ -16,6 +16,8 @@ import (
api "github.com/rocboss/paopao-ce/auto/api/v1" api "github.com/rocboss/paopao-ce/auto/api/v1"
"github.com/rocboss/paopao-ce/internal/conf" "github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/model/web" "github.com/rocboss/paopao-ce/internal/model/web"
"github.com/rocboss/paopao-ce/internal/servants/base" "github.com/rocboss/paopao-ce/internal/servants/base"
"github.com/rocboss/paopao-ce/internal/servants/chain" "github.com/rocboss/paopao-ce/internal/servants/chain"
@ -27,11 +29,17 @@ import (
var ( var (
_ api.Priv = (*privSrv)(nil) _ api.Priv = (*privSrv)(nil)
_uploadAttachmentTypeMap = map[string]core.AttachmentType{ _uploadAttachmentTypeMap = map[string]ms.AttachmentType{
"public/image": core.AttachmentTypeImage, "public/image": ms.AttachmentTypeImage,
"public/avatar": core.AttachmentTypeImage, "public/avatar": ms.AttachmentTypeImage,
"public/video": core.AttachmentTypeVideo, "public/video": ms.AttachmentTypeVideo,
"attachment": core.AttachmentTypeOther, "attachment": ms.AttachmentTypeOther,
}
_uploadAttachmentTypes = map[string]cs.AttachmentType{
"public/image": cs.AttachmentTypeImage,
"public/avatar": cs.AttachmentTypeImage,
"public/video": cs.AttachmentTypeVideo,
"attachment": cs.AttachmentTypeOther,
} }
) )
@ -118,20 +126,20 @@ func (s *privSrv) UploadAttachment(req *web.UploadAttachmentReq) (*web.UploadAtt
} }
// 构造附件Model // 构造附件Model
attachment := &core.Attachment{ attachment := &ms.Attachment{
UserID: req.Uid, UserID: req.Uid,
FileSize: req.FileSize, FileSize: req.FileSize,
Content: objectUrl, Content: objectUrl,
Type: _uploadAttachmentTypeMap[req.UploadType], Type: _uploadAttachmentTypeMap[req.UploadType],
} }
if attachment.Type == core.AttachmentTypeImage { if attachment.Type == ms.AttachmentTypeImage {
var src image.Image var src image.Image
src, err = imaging.Decode(req.File) src, err = imaging.Decode(req.File)
if err == nil { if err == nil {
attachment.ImgWidth, attachment.ImgHeight = getImageSize(src.Bounds()) attachment.ImgWidth, attachment.ImgHeight = getImageSize(src.Bounds())
} }
} }
attachment, err = s.Ds.CreateAttachment(attachment) attachment.ID, err = s.Ds.CreateAttachment(attachment)
if err != nil { if err != nil {
logrus.Errorf("Ds.CreateAttachment err: %s", err) logrus.Errorf("Ds.CreateAttachment err: %s", err)
return nil, web.ErrFileUploadFailed return nil, web.ErrFileUploadFailed
@ -154,7 +162,7 @@ func (s *privSrv) DownloadAttachmentPrecheck(req *web.DownloadAttachmentPrecheck
return nil, web.ErrInvalidDownloadReq return nil, web.ErrInvalidDownloadReq
} }
resp := &web.DownloadAttachmentPrecheckResp{Paid: true} resp := &web.DownloadAttachmentPrecheckResp{Paid: true}
if content.Type == core.ContentTypeChargeAttachment { if content.Type == ms.ContentTypeChargeAttachment {
tweet, err := s.GetTweetBy(content.PostID) tweet, err := s.GetTweetBy(content.PostID)
if err != nil { if err != nil {
logrus.Errorf("get tweet err: %v", err) logrus.Errorf("get tweet err: %v", err)
@ -177,7 +185,7 @@ func (s *privSrv) DownloadAttachment(req *web.DownloadAttachmentReq) (*web.Downl
return nil, web.ErrInvalidDownloadReq return nil, web.ErrInvalidDownloadReq
} }
// 收费附件 // 收费附件
if content.Type == core.ContentTypeChargeAttachment { if content.Type == ms.ContentTypeChargeAttachment {
post, err := s.GetTweetBy(content.PostID) post, err := s.GetTweetBy(content.PostID)
if err != nil { if err != nil {
logrus.Errorf("s.GetTweetBy err: %v", err) logrus.Errorf("s.GetTweetBy err: %v", err)
@ -190,8 +198,8 @@ func (s *privSrv) DownloadAttachment(req *web.DownloadAttachmentReq) (*web.Downl
} }
// 未购买,则尝试购买 // 未购买,则尝试购买
if !paidFlag { if !paidFlag {
err := s.buyPostAttachment(&core.Post{ err := s.buyPostAttachment(&ms.Post{
Model: &core.Model{ Model: &ms.Model{
ID: post.ID, ID: post.ID,
}, },
UserID: post.UserID, UserID: post.UserID,
@ -228,7 +236,7 @@ func (s *privSrv) CreateTweet(req *web.CreateTweetReq) (_ *web.CreateTweetResp,
} }
mediaContents = contents mediaContents = contents
tags := tagsFrom(req.Tags) tags := tagsFrom(req.Tags)
post := &core.Post{ post := &ms.Post{
UserID: req.User.ID, UserID: req.User.ID,
Tags: strings.Join(tags, ","), Tags: strings.Join(tags, ","),
IP: req.ClientIP, IP: req.ClientIP,
@ -249,10 +257,10 @@ func (s *privSrv) CreateTweet(req *web.CreateTweetReq) (_ *web.CreateTweetResp,
logrus.Infof("contents check err: %s", err) logrus.Infof("contents check err: %s", err)
continue continue
} }
if item.Type == core.ContentTypeAttachment && req.AttachmentPrice > 0 { if item.Type == ms.ContentTypeAttachment && req.AttachmentPrice > 0 {
item.Type = core.ContentTypeChargeAttachment item.Type = ms.ContentTypeChargeAttachment
} }
postContent := &core.PostContent{ postContent := &ms.PostContent{
PostID: post.ID, PostID: post.ID,
UserID: req.User.ID, UserID: req.User.ID,
Content: item.Content, Content: item.Content,
@ -268,13 +276,7 @@ func (s *privSrv) CreateTweet(req *web.CreateTweetReq) (_ *web.CreateTweetResp,
// 私密推文不创建标签与用户提醒 // 私密推文不创建标签与用户提醒
if post.Visibility != core.PostVisitPrivate { if post.Visibility != core.PostVisitPrivate {
// 创建标签 // 创建标签
for _, t := range tags { s.Ds.UpsertTags(req.User.ID, tags)
tag := &core.Tag{
UserID: req.User.ID,
Tag: t,
}
s.Ds.CreateTag(tag)
}
// 创建用户消息提醒 // 创建用户消息提醒
for _, u := range req.Users { for _, u := range req.Users {
@ -285,10 +287,10 @@ func (s *privSrv) CreateTweet(req *web.CreateTweetReq) (_ *web.CreateTweetResp,
// 创建消息提醒 // 创建消息提醒
// TODO: 优化消息提醒处理机制 // TODO: 优化消息提醒处理机制
go s.Ds.CreateMessage(&core.Message{ go s.Ds.CreateMessage(&ms.Message{
SenderUserID: req.User.ID, SenderUserID: req.User.ID,
ReceiverUserID: user.ID, ReceiverUserID: user.ID,
Type: core.MsgTypePost, Type: ms.MsgTypePost,
Brief: "在新发布的泡泡动态中@了你", Brief: "在新发布的泡泡动态中@了你",
PostID: post.ID, PostID: post.ID,
}) })
@ -296,7 +298,7 @@ func (s *privSrv) CreateTweet(req *web.CreateTweetReq) (_ *web.CreateTweetResp,
} }
// 推送Search // 推送Search
s.PushPostToSearch(post) s.PushPostToSearch(post)
formatedPosts, err := s.Ds.RevampPosts([]*core.PostFormated{post.Format()}) formatedPosts, err := s.Ds.RevampPosts([]*ms.PostFormated{post.Format()})
if err != nil { if err != nil {
logrus.Infof("Ds.RevampPosts err: %s", err) logrus.Infof("Ds.RevampPosts err: %s", err)
return nil, web.ErrCreatePostFailed return nil, web.ErrCreatePostFailed
@ -352,8 +354,8 @@ func (s *privSrv) DeleteCommentReply(req *web.DeleteCommentReplyReq) mir.Error {
func (s *privSrv) CreateCommentReply(req *web.CreateCommentReplyReq) (*web.CreateCommentReplyResp, mir.Error) { func (s *privSrv) CreateCommentReply(req *web.CreateCommentReplyReq) (*web.CreateCommentReplyResp, mir.Error) {
var ( var (
post *core.Post post *ms.Post
comment *core.Comment comment *ms.Comment
atUserID int64 atUserID int64
err error err error
) )
@ -363,7 +365,7 @@ func (s *privSrv) CreateCommentReply(req *web.CreateCommentReplyReq) (*web.Creat
} }
// 创建评论 // 创建评论
reply := &core.CommentReply{ reply := &ms.CommentReply{
CommentID: req.CommentID, CommentID: req.CommentID,
UserID: req.Uid, UserID: req.Uid,
Content: req.Content, Content: req.Content,
@ -388,10 +390,10 @@ func (s *privSrv) CreateCommentReply(req *web.CreateCommentReplyReq) (*web.Creat
// 创建用户消息提醒 // 创建用户消息提醒
commentMaster, err := s.Ds.GetUserByID(comment.UserID) commentMaster, err := s.Ds.GetUserByID(comment.UserID)
if err == nil && commentMaster.ID != req.Uid { if err == nil && commentMaster.ID != req.Uid {
go s.Ds.CreateMessage(&core.Message{ go s.Ds.CreateMessage(&ms.Message{
SenderUserID: req.Uid, SenderUserID: req.Uid,
ReceiverUserID: commentMaster.ID, ReceiverUserID: commentMaster.ID,
Type: core.MsgTypeReply, Type: ms.MsgTypeReply,
Brief: "在泡泡评论下回复了你", Brief: "在泡泡评论下回复了你",
PostID: post.ID, PostID: post.ID,
CommentID: comment.ID, CommentID: comment.ID,
@ -400,10 +402,10 @@ func (s *privSrv) CreateCommentReply(req *web.CreateCommentReplyReq) (*web.Creat
} }
postMaster, err := s.Ds.GetUserByID(post.UserID) postMaster, err := s.Ds.GetUserByID(post.UserID)
if err == nil && postMaster.ID != req.Uid && commentMaster.ID != postMaster.ID { if err == nil && postMaster.ID != req.Uid && commentMaster.ID != postMaster.ID {
go s.Ds.CreateMessage(&core.Message{ go s.Ds.CreateMessage(&ms.Message{
SenderUserID: req.Uid, SenderUserID: req.Uid,
ReceiverUserID: postMaster.ID, ReceiverUserID: postMaster.ID,
Type: core.MsgTypeReply, Type: ms.MsgTypeReply,
Brief: "在泡泡评论下发布了新回复", Brief: "在泡泡评论下发布了新回复",
PostID: post.ID, PostID: post.ID,
CommentID: comment.ID, CommentID: comment.ID,
@ -414,10 +416,10 @@ func (s *privSrv) CreateCommentReply(req *web.CreateCommentReplyReq) (*web.Creat
user, err := s.Ds.GetUserByID(atUserID) user, err := s.Ds.GetUserByID(atUserID)
if err == nil && user.ID != req.Uid && commentMaster.ID != user.ID && postMaster.ID != user.ID { if err == nil && user.ID != req.Uid && commentMaster.ID != user.ID && postMaster.ID != user.ID {
// 创建消息提醒 // 创建消息提醒
go s.Ds.CreateMessage(&core.Message{ go s.Ds.CreateMessage(&ms.Message{
SenderUserID: req.Uid, SenderUserID: req.Uid,
ReceiverUserID: user.ID, ReceiverUserID: user.ID,
Type: core.MsgTypeReply, Type: ms.MsgTypeReply,
Brief: "在泡泡评论的回复中@了你", Brief: "在泡泡评论的回复中@了你",
PostID: post.ID, PostID: post.ID,
CommentID: comment.ID, CommentID: comment.ID,
@ -480,7 +482,7 @@ func (s *privSrv) CreateComment(req *web.CreateCommentReq) (_ *web.CreateComment
if post.CommentCount >= conf.AppSetting.MaxCommentCount { if post.CommentCount >= conf.AppSetting.MaxCommentCount {
return nil, web.ErrMaxCommentCount return nil, web.ErrMaxCommentCount
} }
comment := &core.Comment{ comment := &ms.Comment{
PostID: post.ID, PostID: post.ID,
UserID: req.Uid, UserID: req.Uid,
IP: req.ClientIP, IP: req.ClientIP,
@ -494,12 +496,12 @@ func (s *privSrv) CreateComment(req *web.CreateCommentReq) (_ *web.CreateComment
for _, item := range req.Contents { for _, item := range req.Contents {
// 检查附件是否是本站资源 // 检查附件是否是本站资源
if item.Type == core.ContentTypeImage || item.Type == core.ContentTypeVideo || item.Type == core.ContentTypeAttachment { if item.Type == ms.ContentTypeImage || item.Type == ms.ContentTypeVideo || item.Type == ms.ContentTypeAttachment {
if err := s.Ds.CheckAttachment(item.Content); err != nil { if err := s.Ds.CheckAttachment(item.Content); err != nil {
continue continue
} }
} }
postContent := &core.CommentContent{ postContent := &ms.CommentContent{
CommentID: comment.ID, CommentID: comment.ID,
UserID: req.Uid, UserID: req.Uid,
Content: item.Content, Content: item.Content,
@ -520,10 +522,10 @@ func (s *privSrv) CreateComment(req *web.CreateCommentReq) (_ *web.CreateComment
// 创建用户消息提醒 // 创建用户消息提醒
postMaster, err := s.Ds.GetUserByID(post.UserID) postMaster, err := s.Ds.GetUserByID(post.UserID)
if err == nil && postMaster.ID != req.Uid { if err == nil && postMaster.ID != req.Uid {
go s.Ds.CreateMessage(&core.Message{ go s.Ds.CreateMessage(&ms.Message{
SenderUserID: req.Uid, SenderUserID: req.Uid,
ReceiverUserID: postMaster.ID, ReceiverUserID: postMaster.ID,
Type: core.MsgtypeComment, Type: ms.MsgtypeComment,
Brief: "在泡泡中评论了你", Brief: "在泡泡中评论了你",
PostID: post.ID, PostID: post.ID,
CommentID: comment.ID, CommentID: comment.ID,
@ -536,10 +538,10 @@ func (s *privSrv) CreateComment(req *web.CreateCommentReq) (_ *web.CreateComment
} }
// 创建消息提醒 // 创建消息提醒
go s.Ds.CreateMessage(&core.Message{ go s.Ds.CreateMessage(&ms.Message{
SenderUserID: req.Uid, SenderUserID: req.Uid,
ReceiverUserID: user.ID, ReceiverUserID: user.ID,
Type: core.MsgtypeComment, Type: ms.MsgtypeComment,
Brief: "在泡泡评论中@了你", Brief: "在泡泡评论中@了你",
PostID: post.ID, PostID: post.ID,
CommentID: comment.ID, CommentID: comment.ID,
@ -632,6 +634,11 @@ func (s *privSrv) StickTweet(req *web.StickTweetReq) (*web.StickTweetResp, mir.E
}, nil }, nil
} }
func (s *privSrv) HighlightTweet(req *web.HighlightTweetReq) (*web.HighlightTweetResp, mir.Error) {
// TODO
return nil, web.ErrNotImplemented
}
func (s *privSrv) LockTweet(req *web.LockTweetReq) (*web.LockTweetResp, mir.Error) { func (s *privSrv) LockTweet(req *web.LockTweetReq) (*web.LockTweetResp, mir.Error) {
post, err := s.Ds.GetPostByID(req.ID) post, err := s.Ds.GetPostByID(req.ID)
if err != nil { if err != nil {
@ -649,7 +656,7 @@ func (s *privSrv) LockTweet(req *web.LockTweetReq) (*web.LockTweetResp, mir.Erro
}, nil }, nil
} }
func (s *privSrv) deletePostCommentReply(reply *core.CommentReply) error { func (s *privSrv) deletePostCommentReply(reply *ms.CommentReply) error {
err := s.Ds.DeleteCommentReply(reply) err := s.Ds.DeleteCommentReply(reply)
if err != nil { if err != nil {
return err return err
@ -673,7 +680,7 @@ func (s *privSrv) deletePostCommentReply(reply *core.CommentReply) error {
return nil return nil
} }
func (s *privSrv) createPostPreHandler(commentID int64, userID, atUserID int64) (*core.Post, *core.Comment, int64, func (s *privSrv) createPostPreHandler(commentID int64, userID, atUserID int64) (*ms.Post, *ms.Comment, int64,
error) { error) {
// 加载Comment // 加载Comment
comment, err := s.Ds.GetCommentByID(commentID) comment, err := s.Ds.GetCommentByID(commentID)
@ -706,7 +713,7 @@ func (s *privSrv) createPostPreHandler(commentID int64, userID, atUserID int64)
return post, comment, atUserID, nil return post, comment, atUserID, nil
} }
func (s *privSrv) createPostStar(postID, userID int64) (*core.PostStar, mir.Error) { func (s *privSrv) createPostStar(postID, userID int64) (*ms.PostStar, mir.Error) {
post, err := s.Ds.GetPostByID(postID) post, err := s.Ds.GetPostByID(postID)
if err != nil { if err != nil {
return nil, xerror.ServerError return nil, xerror.ServerError
@ -732,7 +739,7 @@ func (s *privSrv) createPostStar(postID, userID int64) (*core.PostStar, mir.Erro
return star, nil return star, nil
} }
func (s *privSrv) deletePostStar(star *core.PostStar) mir.Error { func (s *privSrv) deletePostStar(star *ms.PostStar) mir.Error {
post, err := s.Ds.GetPostByID(star.PostID) post, err := s.Ds.GetPostByID(star.PostID)
if err != nil { if err != nil {
return xerror.ServerError return xerror.ServerError
@ -757,7 +764,7 @@ func (s *privSrv) deletePostStar(star *core.PostStar) mir.Error {
return nil return nil
} }
func (s *privSrv) createPostCollection(postID, userID int64) (*core.PostCollection, mir.Error) { func (s *privSrv) createPostCollection(postID, userID int64) (*ms.PostCollection, mir.Error) {
post, err := s.Ds.GetPostByID(postID) post, err := s.Ds.GetPostByID(postID)
if err != nil { if err != nil {
return nil, xerror.ServerError return nil, xerror.ServerError
@ -783,7 +790,7 @@ func (s *privSrv) createPostCollection(postID, userID int64) (*core.PostCollecti
return collection, nil return collection, nil
} }
func (s *privSrv) deletePostCollection(collection *core.PostCollection) mir.Error { func (s *privSrv) deletePostCollection(collection *ms.PostCollection) mir.Error {
post, err := s.Ds.GetPostByID(collection.PostID) post, err := s.Ds.GetPostByID(collection.PostID)
if err != nil { if err != nil {
return xerror.ServerError return xerror.ServerError
@ -812,7 +819,7 @@ func (s *privSrv) checkPostAttachmentIsPaid(postID, userID int64) bool {
return err == nil && bill.Model != nil && bill.ID > 0 return err == nil && bill.Model != nil && bill.ID > 0
} }
func (s *privSrv) buyPostAttachment(post *core.Post, user *core.User) mir.Error { func (s *privSrv) buyPostAttachment(post *ms.Post, user *ms.User) mir.Error {
if user.Balance < post.AttachmentPrice { if user.Balance < post.AttachmentPrice {
return web.ErrInsuffientDownloadMoney return web.ErrInsuffientDownloadMoney
} }

@ -17,7 +17,7 @@ import (
"github.com/alimy/mir/v4" "github.com/alimy/mir/v4"
"github.com/gofrs/uuid/v5" "github.com/gofrs/uuid/v5"
api "github.com/rocboss/paopao-ce/auto/api/v1" api "github.com/rocboss/paopao-ce/auto/api/v1"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/model/web" "github.com/rocboss/paopao-ce/internal/model/web"
"github.com/rocboss/paopao-ce/internal/servants/base" "github.com/rocboss/paopao-ce/internal/servants/base"
"github.com/rocboss/paopao-ce/internal/servants/web/assets" "github.com/rocboss/paopao-ce/internal/servants/web/assets"
@ -131,14 +131,13 @@ func (s *pubSrv) Register(req *web.RegisterReq) (*web.RegisterResp, mir.Error) {
return nil, web.ErrUserRegisterFailed return nil, web.ErrUserRegisterFailed
} }
password, salt := encryptPasswordAndSalt(req.Password) password, salt := encryptPasswordAndSalt(req.Password)
//password, salt := encryptPasswordAndSalt(req.Password, req.Username) user := &ms.User{
user := &core.User{
Nickname: req.Username, Nickname: req.Username,
Username: req.Username, Username: req.Username,
Password: password, Password: password,
Avatar: getRandomAvatar(), Avatar: getRandomAvatar(),
Salt: salt, Salt: salt,
Status: core.UserStatusNormal, Status: ms.UserStatusNormal,
} }
user, err := s.Ds.CreateUser(user) user, err := s.Ds.CreateUser(user)
if err != nil { if err != nil {
@ -165,7 +164,7 @@ func (s *pubSrv) Login(req *web.LoginReq) (*web.LoginResp, mir.Error) {
} }
// 对比密码是否正确 // 对比密码是否正确
if validPassword(user.Password, req.Password, user.Salt) { if validPassword(user.Password, req.Password, user.Salt) {
if user.Status == core.UserStatusClosed { if user.Status == ms.UserStatusClosed {
return nil, web.ErrUserHasBeenBanned return nil, web.ErrUserHasBeenBanned
} }
// 清空登录计数 // 清空登录计数

@ -14,6 +14,7 @@ import (
"github.com/alimy/mir/v4" "github.com/alimy/mir/v4"
"github.com/gofrs/uuid/v5" "github.com/gofrs/uuid/v5"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/model/web" "github.com/rocboss/paopao-ce/internal/model/web"
"github.com/rocboss/paopao-ce/pkg/utils" "github.com/rocboss/paopao-ce/pkg/utils"
"github.com/rocboss/paopao-ce/pkg/xerror" "github.com/rocboss/paopao-ce/pkg/xerror"
@ -120,11 +121,11 @@ func persistMediaContents(oss core.ObjectStorageService, contents []*web.PostCon
items = make([]string, 0, len(contents)) items = make([]string, 0, len(contents))
for _, item := range contents { for _, item := range contents {
switch item.Type { switch item.Type {
case core.ContentTypeImage, case ms.ContentTypeImage,
core.ContentTypeVideo, ms.ContentTypeVideo,
core.ContentTypeAudio, ms.ContentTypeAudio,
core.ContentTypeAttachment, ms.ContentTypeAttachment,
core.ContentTypeChargeAttachment: ms.ContentTypeChargeAttachment:
items = append(items, item.Content) items = append(items, item.Content)
if err != nil { if err != nil {
continue continue
@ -201,7 +202,7 @@ func tagsFrom(originTags []string) []string {
} }
// checkPermision 检查是否拥有者或管理员 // checkPermision 检查是否拥有者或管理员
func checkPermision(user *core.User, targetUserId int64) mir.Error { func checkPermision(user *ms.User, targetUserId int64) mir.Error {
if user == nil || (user.ID != targetUserId && !user.IsAdmin) { if user == nil || (user.ID != targetUserId && !user.IsAdmin) {
return web.ErrNoPermission return web.ErrNoPermission
} }

@ -23,7 +23,7 @@ import (
//go:generate go run $GOFILE //go:generate go run $GOFILE
func main() { func main() {
log.Println("generate code start") log.Println("[Mir] generate code start")
opts := Options{ opts := Options{
UseGin(), UseGin(),
SinkPath("../auto"), SinkPath("../auto"),
@ -34,5 +34,5 @@ func main() {
if err := Generate(opts); err != nil { if err := Generate(opts); err != nil {
log.Fatal(err) log.Fatal(err)
} }
log.Println("generate code finish") log.Println("[Mir] generate code finish")
} }

@ -42,6 +42,9 @@ type Priv struct {
// StickTweet 置顶动态 // StickTweet 置顶动态
StickTweet func(Post, web.StickTweetReq) web.StickTweetResp `mir:"/post/stick"` StickTweet func(Post, web.StickTweetReq) web.StickTweetResp `mir:"/post/stick"`
// HighlightTweet 推文亮点设置
HighlightTweet func(Post, web.HighlightTweetReq) web.HighlightTweetResp `mir:"/post/highlight"`
// VisibleTweet 修改动态可见度 // VisibleTweet 修改动态可见度
VisibleTweet func(Post, web.VisibleTweetReq) web.VisibleTweetResp `mir:"/post/visibility"` VisibleTweet func(Post, web.VisibleTweetReq) web.VisibleTweetResp `mir:"/post/visibility"`

@ -9,7 +9,7 @@ import (
"github.com/golang-jwt/jwt/v4" "github.com/golang-jwt/jwt/v4"
"github.com/rocboss/paopao-ce/internal/conf" "github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core/ms"
) )
type Claims struct { type Claims struct {
@ -22,7 +22,7 @@ func GetJWTSecret() []byte {
return []byte(conf.JWTSetting.Secret) return []byte(conf.JWTSetting.Secret)
} }
func GenerateToken(User *core.User) (string, error) { func GenerateToken(User *ms.User) (string, error) {
expireTime := time.Now().Add(conf.JWTSetting.Expire) expireTime := time.Now().Add(conf.JWTSetting.Expire)
claims := Claims{ claims := Claims{
UID: User.ID, UID: User.ID,

@ -0,0 +1,17 @@
// 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 (
"github.com/sirupsen/logrus"
)
func TODO() {
logrus.Fatalln("in todo progress")
}
func NotImplemented() {
logrus.Fatalln("not implemented")
}

@ -0,0 +1,10 @@
// Copyright 2020 Michael Li <alimy@gility.net>. All rights reserved.
// Use of this source code is governed by Apache License 2.0 that
// can be found in the LICENSE file.
package naming
// NamingStrategy naming strategy interface
type NamingStrategy interface {
Naming(string) string
}

@ -0,0 +1,57 @@
// Copyright 2020 Michael Li <alimy@gility.net>. All rights reserved.
// Use of this source code is governed by Apache License 2.0 that
// can be found in the LICENSE file.
package naming
import "testing"
func TestSnakeNamingStrategy_Naming(t *testing.T) {
ns := NewSnakeNamingStrategy()
for _, cs := range []struct {
name string
expected string
}{
{name: "abc", expected: "abc"},
{name: "Abc", expected: "abc"},
{name: "HostName", expected: "host_name"},
{name: "Host_Name", expected: "host_name"},
{name: "RESTfulAPI", expected: "res_tful_api"},
{name: "HTTPS_API", expected: "https_api"},
{name: "PKG_Name", expected: "pkg_name"},
{name: "UserID", expected: "user_id"},
{name: "UserId", expected: "user_id"},
{name: "IPLoc", expected: "ip_loc"},
{name: "API", expected: "api"},
{name: "HTTP", expected: "http"},
{name: "IP", expected: "ip"},
} {
result := ns.Naming(cs.name)
if result != cs.expected {
t.Errorf("give:%s expected:%s result:%s", cs.name, cs.expected, result)
}
}
}
func TestSimpleNamingStrategy_Naming(t *testing.T) {
ns := NewSimpleNamingStrategy()
for _, cs := range []struct {
name string
expected string
}{
{name: "abc", expected: "abc"},
{name: "Abc", expected: "abc"},
{name: "HostName", expected: "host_name"},
{name: "Host_Name", expected: "host__name"},
{name: "RESTfulAPI", expected: "r_e_s_tful_a_p_i"},
{name: "HTTPS_API", expected: "h_t_t_p_s__a_p_i"},
{name: "PKG_Name", expected: "p_k_g__name"},
{name: "API", expected: "a_p_i"},
{name: "HTTP", expected: "h_t_t_p"},
} {
result := ns.Naming(cs.name)
if result != cs.expected {
t.Errorf("give:%s expected:%s result:%s", cs.name, cs.expected, result)
}
}
}

@ -0,0 +1,37 @@
// Copyright 2020 Michael Li <alimy@gility.net>. All rights reserved.
// Use of this source code is governed by Apache License 2.0 that
// can be found in the LICENSE file.
package naming
import (
"strings"
"unicode"
)
type simpleNamingStrategy struct {
// just empty
}
func (s *simpleNamingStrategy) Naming(name string) string {
b := &strings.Builder{}
notFirst := false
b.Grow(len(name) + 3)
for _, r := range name {
if unicode.IsUpper(r) {
if notFirst {
b.WriteRune('_')
}
b.WriteRune(unicode.ToLower(r))
} else {
b.WriteRune(r)
}
notFirst = true
}
return b.String()
}
// NewSimpleNamingStrategy return simple naming strategy instance
func NewSimpleNamingStrategy() NamingStrategy {
return &simpleNamingStrategy{}
}

@ -0,0 +1,76 @@
// Copyright 2020 Michael Li <alimy@gility.net>. All rights reserved.
// Use of this source code is governed by Apache License 2.0 that
// can be found in the LICENSE file.
package naming
import (
"bytes"
"strings"
)
// snakeNamingStrategy snake naming strategy implement
// This implement is inspiration from https://github.com/jingzhu/gorm's naming logic.
type snakeNamingStrategy struct {
initialismsReplacer *strings.Replacer
}
func (s *snakeNamingStrategy) Naming(name string) string {
if name == "" {
return ""
}
var lastCase, currCase, nextCase, nextNumber bool
value := s.initialismsReplacer.Replace(name)
buf := bytes.NewBufferString("")
lower, upper := false, true
for i, v := range value[:len(value)-1] {
nextCase = value[i+1] >= 'A' && value[i+1] <= 'Z'
nextNumber = value[i+1] >= '0' && value[i+1] <= '9'
if i > 0 {
if currCase == upper {
if lastCase == upper && (nextCase == upper || nextNumber == upper) {
buf.WriteRune(v)
} else {
if value[i-1] != '_' && value[i+1] != '_' {
buf.WriteRune('_')
}
buf.WriteRune(v)
}
} else {
buf.WriteRune(v)
if i == len(value)-2 && (nextCase == upper && nextNumber == lower) {
buf.WriteRune('_')
}
}
} else {
currCase = upper
buf.WriteRune(v)
}
lastCase, currCase = currCase, nextCase
}
buf.WriteByte(value[len(value)-1])
res := strings.ToLower(buf.String())
return res
}
// NewSnakeNamingStrategy return snake naming strategy instance
func NewSnakeNamingStrategy() NamingStrategy {
// Copied from golint
initialisms := []string{
"API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP",
"HTTPS", "ID", "IP", "JSON", "LHS", "QPS", "RAM", "RHS", "RPC", "SLA",
"SMTP", "SSH", "TLS", "TTL", "UID", "UI", "UUID", "URI", "URL", "UTF8",
"VM", "XML", "XSRF", "XSS"}
var oldnews []string
for _, initialism := range initialisms {
oldnews = append(oldnews, initialism, strings.Title(strings.ToLower(initialism)))
}
replacer := strings.NewReplacer(oldnews...)
return &snakeNamingStrategy{
initialismsReplacer: replacer,
}
}

@ -40,5 +40,4 @@ var _ = Describe("Md5", Ordered, func() {
Expect(utils.EncodeMD5(t.value)).To(Equal(t.md5)) Expect(utils.EncodeMD5(t.value)).To(Equal(t.md5))
} }
}) })
}) })

@ -1 +1 @@
import{_ as s}from"./main-nav.vue_vue_type_style_index_0_lang-c955aa6b.js";import{u as a}from"./vue-router-b8e3382f.js";import{F as i,e as c,a2 as u}from"./naive-ui-62663ad7.js";import{d as l,c as d,V as t,a1 as o,o as f,e as x}from"./@vue-e0e89260.js";import{_ as g}from"./index-8b4e1776.js";import"./vuex-473b3783.js";import"./vooks-a50491fd.js";import"./evtd-b614532e.js";import"./@vicons-d502290a.js";import"./seemly-76b7b838.js";import"./vueuc-59ca65c3.js";import"./@css-render-580d83ec.js";import"./vdirs-b0483831.js";import"./@juggle-41516555.js";import"./css-render-6a5c5852.js";import"./@emotion-8a8e73f6.js";import"./lodash-es-8412e618.js";import"./treemate-25c27bff.js";import"./async-validator-dee29e8b.js";import"./date-fns-975a2d8f.js";import"./axios-4a70c6fc.js";/* empty css */const v=l({__name:"404",setup(h){const e=a(),_=()=>{e.push({path:"/"})};return(k,w)=>{const n=s,p=c,r=u,m=i;return f(),d("div",null,[t(n,{title:"404"}),t(m,{class:"main-content-wrap wrap404",bordered:""},{default:o(()=>[t(r,{status:"404",title:"404 资源不存在",description:"再看看其他的吧"},{footer:o(()=>[t(p,{onClick:_},{default:o(()=>[x("回主页")]),_:1})]),_:1})]),_:1})])}}});const M=g(v,[["__scopeId","data-v-e62daa85"]]);export{M as default}; import{_ as s}from"./main-nav.vue_vue_type_style_index_0_lang-18d4a8d3.js";import{u as a}from"./vue-router-b8e3382f.js";import{F as i,e as c,a2 as u}from"./naive-ui-62663ad7.js";import{d as l,c as d,V as t,a1 as o,o as f,e as x}from"./@vue-e0e89260.js";import{_ as g}from"./index-08d8af97.js";import"./vuex-473b3783.js";import"./vooks-a50491fd.js";import"./evtd-b614532e.js";import"./@vicons-6332ad63.js";import"./seemly-76b7b838.js";import"./vueuc-59ca65c3.js";import"./@css-render-580d83ec.js";import"./vdirs-b0483831.js";import"./@juggle-41516555.js";import"./css-render-6a5c5852.js";import"./@emotion-8a8e73f6.js";import"./lodash-es-8412e618.js";import"./treemate-25c27bff.js";import"./async-validator-dee29e8b.js";import"./date-fns-975a2d8f.js";import"./axios-4a70c6fc.js";/* empty css */const v=l({__name:"404",setup(h){const e=a(),_=()=>{e.push({path:"/"})};return(k,w)=>{const n=s,p=c,r=u,m=i;return f(),d("div",null,[t(n,{title:"404"}),t(m,{class:"main-content-wrap wrap404",bordered:""},{default:o(()=>[t(r,{status:"404",title:"404 资源不存在",description:"再看看其他的吧"},{footer:o(()=>[t(p,{onClick:_},{default:o(()=>[x("回主页")]),_:1})]),_:1})]),_:1})])}}});const M=g(v,[["__scopeId","data-v-e62daa85"]]);export{M as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +1 @@
import{_ as F}from"./post-skeleton-627d3fc3.js";import{_ as N}from"./main-nav.vue_vue_type_style_index_0_lang-c955aa6b.js";import{u as V}from"./vuex-473b3783.js";import{b as z}from"./vue-router-b8e3382f.js";import{a as A}from"./formatTime-cdf4e6f1.js";import{d as R,r as n,j as S,c as o,V as a,a1 as p,o as e,_ as u,O as l,F as I,a4 as L,Q as M,a as s,M as _,L as O}from"./@vue-e0e89260.js";import{F as P,G as j,I as q,H as D}from"./naive-ui-62663ad7.js";import{_ as E}from"./index-8b4e1776.js";import"./vooks-a50491fd.js";import"./evtd-b614532e.js";import"./@vicons-d502290a.js";import"./moment-2ab8298d.js";import"./seemly-76b7b838.js";import"./vueuc-59ca65c3.js";import"./@css-render-580d83ec.js";import"./vdirs-b0483831.js";import"./@juggle-41516555.js";import"./css-render-6a5c5852.js";import"./@emotion-8a8e73f6.js";import"./lodash-es-8412e618.js";import"./treemate-25c27bff.js";import"./async-validator-dee29e8b.js";import"./date-fns-975a2d8f.js";import"./axios-4a70c6fc.js";/* empty css */const G={key:0,class:"pagination-wrap"},H={key:0,class:"skeleton-wrap"},Q={key:1},T={key:0,class:"empty-wrap"},U={class:"bill-line"},$=R({__name:"Anouncement",setup(J){const d=V(),g=z(),v=n(!1),r=n([]),i=n(+g.query.p||1),f=n(20),c=n(0),h=m=>{i.value=m};return S(()=>{}),(m,K)=>{const y=N,k=j,x=F,w=q,B=D,C=P;return e(),o("div",null,[a(y,{title:"公告"}),a(C,{class:"main-content-wrap",bordered:""},{footer:p(()=>[c.value>1?(e(),o("div",G,[a(k,{page:i.value,"onUpdate:page":h,"page-slot":u(d).state.collapsedRight?5:8,"page-count":c.value},null,8,["page","page-slot","page-count"])])):l("",!0)]),default:p(()=>[v.value?(e(),o("div",H,[a(x,{num:f.value},null,8,["num"])])):(e(),o("div",Q,[r.value.length===0?(e(),o("div",T,[a(w,{size:"large",description:"暂无数据"})])):l("",!0),(e(!0),o(I,null,L(r.value,t=>(e(),M(B,{key:t.id},{default:p(()=>[s("div",U,[s("div",null,"NO."+_(t.id),1),s("div",null,_(t.reason),1),s("div",{class:O({income:t.change_amount>=0,out:t.change_amount<0})},_((t.change_amount>0?"+":"")+(t.change_amount/100).toFixed(2)),3),s("div",null,_(u(A)(t.created_on)),1)])]),_:2},1024))),128))]))]),_:1})])}}});const kt=E($,[["__scopeId","data-v-d4d04859"]]);export{kt as default}; import{_ as F}from"./post-skeleton-41befd31.js";import{_ as N}from"./main-nav.vue_vue_type_style_index_0_lang-18d4a8d3.js";import{u as V}from"./vuex-473b3783.js";import{b as z}from"./vue-router-b8e3382f.js";import{a as A}from"./formatTime-cdf4e6f1.js";import{d as R,r as n,j as S,c as o,V as a,a1 as p,o as e,_ as u,O as l,F as I,a4 as L,Q as M,a as s,M as _,L as O}from"./@vue-e0e89260.js";import{F as P,G as j,I as q,H as D}from"./naive-ui-62663ad7.js";import{_ as E}from"./index-08d8af97.js";import"./vooks-a50491fd.js";import"./evtd-b614532e.js";import"./@vicons-6332ad63.js";import"./moment-2ab8298d.js";import"./seemly-76b7b838.js";import"./vueuc-59ca65c3.js";import"./@css-render-580d83ec.js";import"./vdirs-b0483831.js";import"./@juggle-41516555.js";import"./css-render-6a5c5852.js";import"./@emotion-8a8e73f6.js";import"./lodash-es-8412e618.js";import"./treemate-25c27bff.js";import"./async-validator-dee29e8b.js";import"./date-fns-975a2d8f.js";import"./axios-4a70c6fc.js";/* empty css */const G={key:0,class:"pagination-wrap"},H={key:0,class:"skeleton-wrap"},Q={key:1},T={key:0,class:"empty-wrap"},U={class:"bill-line"},$=R({__name:"Anouncement",setup(J){const d=V(),g=z(),v=n(!1),r=n([]),i=n(+g.query.p||1),f=n(20),c=n(0),h=m=>{i.value=m};return S(()=>{}),(m,K)=>{const y=N,k=j,x=F,w=q,B=D,C=P;return e(),o("div",null,[a(y,{title:"公告"}),a(C,{class:"main-content-wrap",bordered:""},{footer:p(()=>[c.value>1?(e(),o("div",G,[a(k,{page:i.value,"onUpdate:page":h,"page-slot":u(d).state.collapsedRight?5:8,"page-count":c.value},null,8,["page","page-slot","page-count"])])):l("",!0)]),default:p(()=>[v.value?(e(),o("div",H,[a(x,{num:f.value},null,8,["num"])])):(e(),o("div",Q,[r.value.length===0?(e(),o("div",T,[a(w,{size:"large",description:"暂无数据"})])):l("",!0),(e(!0),o(I,null,L(r.value,t=>(e(),M(B,{key:t.id},{default:p(()=>[s("div",U,[s("div",null,"NO."+_(t.id),1),s("div",null,_(t.reason),1),s("div",{class:O({income:t.change_amount>=0,out:t.change_amount<0})},_((t.change_amount>0?"+":"")+(t.change_amount/100).toFixed(2)),3),s("div",null,_(u(A)(t.created_on)),1)])]),_:2},1024))),128))]))]),_:1})])}}});const kt=E($,[["__scopeId","data-v-d4d04859"]]);export{kt as default};

@ -1 +0,0 @@
import{_ as P,a as S}from"./post-item.vue_vue_type_style_index_0_lang-cf654b7f.js";import{_ as V}from"./post-skeleton-627d3fc3.js";import{_ as $}from"./main-nav.vue_vue_type_style_index_0_lang-c955aa6b.js";import{u as I}from"./vuex-473b3783.js";import{b as N}from"./vue-router-b8e3382f.js";import{K as R,_ as j}from"./index-8b4e1776.js";import{d as q,r as s,j as E,c as o,V as e,a1 as c,_ as g,O as v,o as t,F as f,a4 as h,Q as k}from"./@vue-e0e89260.js";import{F as G,G as H,I as K,H as L}from"./naive-ui-62663ad7.js";import"./content-c0ce69b7.js";import"./@vicons-d502290a.js";import"./paopao-video-player-aa5e8b3f.js";import"./formatTime-cdf4e6f1.js";import"./moment-2ab8298d.js";import"./copy-to-clipboard-1dd3075d.js";import"./toggle-selection-93f4ad84.js";import"./vooks-a50491fd.js";import"./evtd-b614532e.js";import"./axios-4a70c6fc.js";/* empty css */import"./seemly-76b7b838.js";import"./vueuc-59ca65c3.js";import"./@css-render-580d83ec.js";import"./vdirs-b0483831.js";import"./@juggle-41516555.js";import"./css-render-6a5c5852.js";import"./@emotion-8a8e73f6.js";import"./lodash-es-8412e618.js";import"./treemate-25c27bff.js";import"./async-validator-dee29e8b.js";import"./date-fns-975a2d8f.js";const O={key:0,class:"skeleton-wrap"},Q={key:1},T={key:0,class:"empty-wrap"},U={key:1},A={key:2},D={key:0,class:"pagination-wrap"},J=q({__name:"Collection",setup(W){const m=I(),y=N(),_=s(!1),i=s([]),p=s(+y.query.p||1),l=s(20),r=s(0),u=()=>{_.value=!0,R({page:p.value,page_size:l.value}).then(n=>{_.value=!1,i.value=n.list,r.value=Math.ceil(n.pager.total_rows/l.value),window.scrollTo(0,0)}).catch(n=>{_.value=!1})},w=n=>{p.value=n,u()};return E(()=>{u()}),(n,X)=>{const C=$,b=V,x=K,z=P,d=L,B=S,F=G,M=H;return t(),o("div",null,[e(C,{title:"收藏"}),e(F,{class:"main-content-wrap",bordered:""},{default:c(()=>[_.value?(t(),o("div",O,[e(b,{num:l.value},null,8,["num"])])):(t(),o("div",Q,[i.value.length===0?(t(),o("div",T,[e(x,{size:"large",description:"暂无数据"})])):v("",!0),g(m).state.desktopModelShow?(t(),o("div",U,[(t(!0),o(f,null,h(i.value,a=>(t(),k(d,{key:a.id},{default:c(()=>[e(z,{post:a},null,8,["post"])]),_:2},1024))),128))])):(t(),o("div",A,[(t(!0),o(f,null,h(i.value,a=>(t(),k(d,{key:a.id},{default:c(()=>[e(B,{post:a},null,8,["post"])]),_:2},1024))),128))]))]))]),_:1}),r.value>0?(t(),o("div",D,[e(M,{page:p.value,"onUpdate:page":w,"page-slot":g(m).state.collapsedRight?5:8,"page-count":r.value},null,8,["page","page-slot","page-count"])])):v("",!0)])}}});const Mt=j(J,[["__scopeId","data-v-a5302c9b"]]);export{Mt as default};

@ -0,0 +1 @@
import{_ as P,a as S}from"./post-item.vue_vue_type_style_index_0_lang-3baf8ba8.js";import{_ as V}from"./post-skeleton-41befd31.js";import{_ as $}from"./main-nav.vue_vue_type_style_index_0_lang-18d4a8d3.js";import{u as I}from"./vuex-473b3783.js";import{b as L}from"./vue-router-b8e3382f.js";import{L as N,_ as R}from"./index-08d8af97.js";import{d as j,r as s,j as q,c as o,V as e,a1 as c,_ as g,O as v,o as t,F as f,a4 as h,Q as k}from"./@vue-e0e89260.js";import{F as E,G,I as H,H as O}from"./naive-ui-62663ad7.js";import"./content-91ba374b.js";import"./@vicons-6332ad63.js";import"./paopao-video-player-aa5e8b3f.js";import"./formatTime-cdf4e6f1.js";import"./moment-2ab8298d.js";import"./copy-to-clipboard-1dd3075d.js";import"./toggle-selection-93f4ad84.js";import"./vooks-a50491fd.js";import"./evtd-b614532e.js";import"./axios-4a70c6fc.js";/* empty css */import"./seemly-76b7b838.js";import"./vueuc-59ca65c3.js";import"./@css-render-580d83ec.js";import"./vdirs-b0483831.js";import"./@juggle-41516555.js";import"./css-render-6a5c5852.js";import"./@emotion-8a8e73f6.js";import"./lodash-es-8412e618.js";import"./treemate-25c27bff.js";import"./async-validator-dee29e8b.js";import"./date-fns-975a2d8f.js";const Q={key:0,class:"skeleton-wrap"},T={key:1},U={key:0,class:"empty-wrap"},A={key:1},D={key:2},J={key:0,class:"pagination-wrap"},K=j({__name:"Collection",setup(W){const m=I(),y=L(),_=s(!1),i=s([]),p=s(+y.query.p||1),l=s(20),r=s(0),u=()=>{_.value=!0,N({page:p.value,page_size:l.value}).then(n=>{_.value=!1,i.value=n.list,r.value=Math.ceil(n.pager.total_rows/l.value),window.scrollTo(0,0)}).catch(n=>{_.value=!1})},w=n=>{p.value=n,u()};return q(()=>{u()}),(n,X)=>{const C=$,b=V,x=H,z=P,d=O,B=S,F=E,M=G;return t(),o("div",null,[e(C,{title:"收藏"}),e(F,{class:"main-content-wrap",bordered:""},{default:c(()=>[_.value?(t(),o("div",Q,[e(b,{num:l.value},null,8,["num"])])):(t(),o("div",T,[i.value.length===0?(t(),o("div",U,[e(x,{size:"large",description:"暂无数据"})])):v("",!0),g(m).state.desktopModelShow?(t(),o("div",A,[(t(!0),o(f,null,h(i.value,a=>(t(),k(d,{key:a.id},{default:c(()=>[e(z,{post:a},null,8,["post"])]),_:2},1024))),128))])):(t(),o("div",D,[(t(!0),o(f,null,h(i.value,a=>(t(),k(d,{key:a.id},{default:c(()=>[e(B,{post:a},null,8,["post"])]),_:2},1024))),128))]))]))]),_:1}),r.value>0?(t(),o("div",J,[e(M,{page:p.value,"onUpdate:page":w,"page-slot":g(m).state.collapsedRight?5:8,"page-count":r.value},null,8,["page","page-slot","page-count"])])):v("",!0)])}}});const Mt=R(K,[["__scopeId","data-v-a5302c9b"]]);export{Mt as default};

@ -1 +1 @@
import{u as M,b as P}from"./vue-router-b8e3382f.js";import{d as k,o as e,c as n,a as s,V as a,M as d,r as c,j as R,a1 as f,_ as S,O as h,F as y,a4 as U,Q as q}from"./@vue-e0e89260.js";import{o as x,F as D,G as T,I as j,H as E}from"./naive-ui-62663ad7.js";import{_ as b,N as G}from"./index-8b4e1776.js";import{_ as H}from"./post-skeleton-627d3fc3.js";import{_ as L}from"./main-nav.vue_vue_type_style_index_0_lang-c955aa6b.js";import{u as O}from"./vuex-473b3783.js";import"./seemly-76b7b838.js";import"./vueuc-59ca65c3.js";import"./evtd-b614532e.js";import"./@css-render-580d83ec.js";import"./vooks-a50491fd.js";import"./vdirs-b0483831.js";import"./@juggle-41516555.js";import"./css-render-6a5c5852.js";import"./@emotion-8a8e73f6.js";import"./lodash-es-8412e618.js";import"./treemate-25c27bff.js";import"./async-validator-dee29e8b.js";import"./date-fns-975a2d8f.js";import"./axios-4a70c6fc.js";import"./@vicons-d502290a.js";/* empty css */const Q={class:"avatar"},A={class:"base-info"},J={class:"username"},K={class:"uid"},W=k({__name:"contact-item",props:{contact:{}},setup(C){const l=M(),u=t=>{l.push({name:"user",query:{username:t}})};return(t,o)=>{const _=x;return e(),n("div",{class:"contact-item",onClick:o[0]||(o[0]=r=>u(t.contact.username))},[s("div",Q,[a(_,{size:"large",src:t.contact.avatar},null,8,["src"])]),s("div",A,[s("div",J,[s("strong",null,d(t.contact.nickname),1),s("span",null," @"+d(t.contact.username),1)]),s("div",K,"UID. "+d(t.contact.user_id),1)])])}}});const X=b(W,[["__scopeId","data-v-08ee9b2e"]]),Y={key:0,class:"skeleton-wrap"},Z={key:1},tt={key:0,class:"empty-wrap"},et={key:0,class:"pagination-wrap"},ot=k({__name:"Contacts",setup(C){const l=O(),u=P(),t=c(!1),o=c([]),_=c(+u.query.p||1),r=c(20),m=c(0),w=i=>{_.value=i,v()};R(()=>{v()});const v=(i=!1)=>{o.value.length===0&&(t.value=!0),G({page:_.value,page_size:r.value}).then(p=>{t.value=!1,o.value=p.list,m.value=Math.ceil(p.pager.total_rows/r.value),i&&setTimeout(()=>{window.scrollTo(0,99999)},50)}).catch(p=>{t.value=!1})};return(i,p)=>{const $=L,I=H,z=j,B=X,N=E,V=D,F=T;return e(),n(y,null,[s("div",null,[a($,{title:"好友"}),a(V,{class:"main-content-wrap",bordered:""},{default:f(()=>[t.value?(e(),n("div",Y,[a(I,{num:r.value},null,8,["num"])])):(e(),n("div",Z,[o.value.length===0?(e(),n("div",tt,[a(z,{size:"large",description:"暂无数据"})])):h("",!0),(e(!0),n(y,null,U(o.value,g=>(e(),q(N,{key:g.user_id},{default:f(()=>[a(B,{contact:g},null,8,["contact"])]),_:2},1024))),128))]))]),_:1})]),m.value>0?(e(),n("div",et,[a(F,{page:_.value,"onUpdate:page":w,"page-slot":S(l).state.collapsedRight?5:8,"page-count":m.value},null,8,["page","page-slot","page-count"])])):h("",!0)],64)}}});const zt=b(ot,[["__scopeId","data-v-3b2bf978"]]);export{zt as default}; import{u as N,b as P}from"./vue-router-b8e3382f.js";import{d as k,o as e,c as n,a as s,V as a,M as d,r as c,j as R,a1 as f,_ as S,O as h,F as y,a4 as U,Q as q}from"./@vue-e0e89260.js";import{o as x,F as D,G as O,I as T,H as j}from"./naive-ui-62663ad7.js";import{_ as b,O as E}from"./index-08d8af97.js";import{_ as G}from"./post-skeleton-41befd31.js";import{_ as H}from"./main-nav.vue_vue_type_style_index_0_lang-18d4a8d3.js";import{u as L}from"./vuex-473b3783.js";import"./seemly-76b7b838.js";import"./vueuc-59ca65c3.js";import"./evtd-b614532e.js";import"./@css-render-580d83ec.js";import"./vooks-a50491fd.js";import"./vdirs-b0483831.js";import"./@juggle-41516555.js";import"./css-render-6a5c5852.js";import"./@emotion-8a8e73f6.js";import"./lodash-es-8412e618.js";import"./treemate-25c27bff.js";import"./async-validator-dee29e8b.js";import"./date-fns-975a2d8f.js";import"./axios-4a70c6fc.js";import"./@vicons-6332ad63.js";/* empty css */const Q={class:"avatar"},A={class:"base-info"},J={class:"username"},K={class:"uid"},W=k({__name:"contact-item",props:{contact:{}},setup(C){const l=N(),u=t=>{l.push({name:"user",query:{username:t}})};return(t,o)=>{const _=x;return e(),n("div",{class:"contact-item",onClick:o[0]||(o[0]=r=>u(t.contact.username))},[s("div",Q,[a(_,{size:"large",src:t.contact.avatar},null,8,["src"])]),s("div",A,[s("div",J,[s("strong",null,d(t.contact.nickname),1),s("span",null," @"+d(t.contact.username),1)]),s("div",K,"UID. "+d(t.contact.user_id),1)])])}}});const X=b(W,[["__scopeId","data-v-08ee9b2e"]]),Y={key:0,class:"skeleton-wrap"},Z={key:1},tt={key:0,class:"empty-wrap"},et={key:0,class:"pagination-wrap"},ot=k({__name:"Contacts",setup(C){const l=L(),u=P(),t=c(!1),o=c([]),_=c(+u.query.p||1),r=c(20),m=c(0),w=i=>{_.value=i,v()};R(()=>{v()});const v=(i=!1)=>{o.value.length===0&&(t.value=!0),E({page:_.value,page_size:r.value}).then(p=>{t.value=!1,o.value=p.list,m.value=Math.ceil(p.pager.total_rows/r.value),i&&setTimeout(()=>{window.scrollTo(0,99999)},50)}).catch(p=>{t.value=!1})};return(i,p)=>{const $=H,I=G,z=T,B=X,V=j,F=D,M=O;return e(),n(y,null,[s("div",null,[a($,{title:"好友"}),a(F,{class:"main-content-wrap",bordered:""},{default:f(()=>[t.value?(e(),n("div",Y,[a(I,{num:r.value},null,8,["num"])])):(e(),n("div",Z,[o.value.length===0?(e(),n("div",tt,[a(z,{size:"large",description:"暂无数据"})])):h("",!0),(e(!0),n(y,null,U(o.value,g=>(e(),q(V,{key:g.user_id},{default:f(()=>[a(B,{contact:g},null,8,["contact"])]),_:2},1024))),128))]))]),_:1})]),m.value>0?(e(),n("div",et,[a(M,{page:_.value,"onUpdate:page":w,"page-slot":S(l).state.collapsedRight?5:8,"page-count":m.value},null,8,["page","page-slot","page-count"])])):h("",!0)],64)}}});const zt=b(ot,[["__scopeId","data-v-3b2bf978"]]);export{zt as default};

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save