官方更新内容

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

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

@ -11,6 +11,10 @@ All notable changes to paopao-ce are documented in this file.
### Changed
- 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
### 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 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
- 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))
ifeq (n$(CGO_ENABLED),n)
CGO_ENABLED := 0
CGO_ENABLED := 1
endif
RELEASE_ROOT = release

@ -30,6 +30,7 @@ type Priv interface {
DeleteComment(*web.DeleteCommentReq) mir.Error
CreateComment(*web.CreateCommentReq) (*web.CreateCommentResp, mir.Error)
VisibleTweet(*web.VisibleTweetReq) (*web.VisibleTweetResp, mir.Error)
HighlightTweet(*web.HighlightTweetReq) (*web.HighlightTweetResp, mir.Error)
StickTweet(*web.StickTweetReq) (*web.StickTweetResp, mir.Error)
LockTweet(*web.LockTweetReq) (*web.LockTweetResp, 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)
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) {
select {
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))
}
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) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}

@ -102,7 +102,7 @@ services:
- paopao-network
backend:
image: bitbus/paopao-ce:0.3.0
image: bitbus/paopao-ce:0.3
restart: always
depends_on:
- 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/disintegration/imaging v1.6.2
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-gonic/gin v1.9.1
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/gomega v1.27.10
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/smartwalle/alipay/v3 v3.2.14
github.com/sourcegraph/conc v0.3.0
@ -47,7 +47,7 @@ require (
gorm.io/gorm v1.25.2
gorm.io/plugin/dbresolver v1.4.1
gorm.io/plugin/soft_delete v1.2.1
modernc.org/sqlite v1.24.0
modernc.org/sqlite v1.25.0
)
require (
@ -88,7 +88,7 @@ require (
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // 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/mailru/easyjson v0.7.7 // 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/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // 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/pkg/errors v0.9.1 // indirect
github.com/pyroscope-io/godeltaprof v0.1.0 // indirect
@ -121,7 +121,7 @@ require (
go.uber.org/atomic v1.9.0 // indirect
golang.org/x/arch v0.3.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/net v0.12.0 // indirect
golang.org/x/sys v0.10.0 // indirect
@ -134,9 +134,9 @@ require (
lukechampine.com/uint128 v1.2.0 // indirect
modernc.org/cc/v3 v3.40.0 // 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/memory v1.5.0 // indirect
modernc.org/memory v1.6.0 // indirect
modernc.org/opt v0.1.3 // indirect
modernc.org/strutil v1.1.3 // 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/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/sentry-go v0.22.0 h1:XNX9zKbv7baSEI65l+H1GEJgSeIC1c7EN5kluWaP6dM=
github.com/getsentry/sentry-go v0.22.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
github.com/getsentry/sentry-go v0.23.0 h1:dn+QRCeJv4pPt9OjVXiMcGIBIefaTJPw/h0bZWO05nE=
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 v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
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.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
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.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/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w=
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/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
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.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/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=
@ -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/godeltaprof v0.1.0 h1:UBqtjt0yZi4jTxqZmLAs34XG6ycS3vUTlhEUSq4NHLE=
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.13/go.mod h1:Z4/sLVfaxsAPKj0EF6q2P/gO6clKuQ3CE34/f/cPNkI=
github.com/redis/rueidis v1.0.14 h1:qdFZahk1F/2L+sZeOECx5E2N5J4Qc51b7ezSUpQXJfs=
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-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
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-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-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-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-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
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/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.22.5 h1:91BNch/e5B0uPbJFgqbxXuOnxBQjlS//icfQEGmvyjE=
modernc.org/libc v1.22.5/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY=
modernc.org/libc v1.24.1 h1:uvJSeCKL/AgzBo2yYIPPTy82v21KgGnizcGYfBHaNuM=
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/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
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/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
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.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
modernc.org/memory v1.6.0 h1:i6mzavxrE9a30whzMfwf7XWVODx2r5OYXvU46cirX7o=
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.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
modernc.org/ql v1.0.0/go.mod h1:xGVyrLIatPcO2C1JvI/Co8c0sr6y91HKFNy4pt9JXEY=
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.24.0 h1:EsClRIWHGhLTCX44p+Ri/JLD+vFGo0QGjasg2/F9TlI=
modernc.org/sqlite v1.24.0/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk=
modernc.org/sqlite v1.25.0 h1:AFweiwPNd/b3BoKnBOfFm+Y260guGMF+0UFk0savqeA=
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.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY=
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
// license that can be found in the LICENSE file.
package conf
import (
"database/sql"
"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
_sqldb *sql.DB
_onceSql sync.Once
)
func MustGormDB() *gorm.DB {
_onceGorm.Do(func() {
const (
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
if _gormDB, err = newGormDB(); err != nil {
logrus.Fatalf("new gorm db failed: %s", err)
if _, _sqldb, err = newSqlDB(); err != nil {
logrus.Fatalf("new sql db failed: %s", err)
}
})
return _gormDB
return _sqldb
}
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
)
func newSqlDB() (driver string, db *sql.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)
driver = "mysql"
db, err = sql.Open(driver, MysqlSetting.Dsn())
} else if cfg.If("PostgreSQL") || cfg.If("Postgres") {
driver = "pgx"
db, err = sql.Open(driver, PostgresSetting.Dsn())
} else if cfg.If("Sqlite3") {
logrus.Debugf("use Sqlite3 as db path:%s sqlite3InCgoEnabled:%t", Sqlite3Setting.Path, sqlite3InCgoEnabled)
db, err = gormOpenSqlite3(config)
driver, db, err = OpenSqlite3()
} else {
logrus.Debugln("use default of MySQL as db")
if db, err = gorm.Open(mysql.Open(MysqlSetting.Dsn()), config); err == nil {
db.Use(plugin)
}
driver = "mysql"
db, err = sql.Open(driver, MysqlSetting.Dsn())
}
return db, err
return
}

@ -18,8 +18,9 @@ const (
sqlite3InCgoEnabled = true
)
func OpenSqlite3() (*sql.DB, error) {
return sql.Open("sqlite3", Sqlite3Setting.Dsn("sqlite3"))
func OpenSqlite3() (string, *sql.DB, error) {
db, err := sql.Open("sqlite3", Sqlite3Setting.Dsn("sqlite3"))
return "sqlite3", db, err
}
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
)
func OpenSqlite3() (*sql.DB, error) {
return sql.Open("sqlite", Sqlite3Setting.Dsn("sqlite"))
func OpenSqlite3() (string, *sql.DB, error) {
db, err := sql.Open("sqlite", Sqlite3Setting.Dsn("sqlite"))
return "sqlite", db, err
}
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 {
switch strings.ToLower(s.Level) {
case "panic":

@ -5,119 +5,13 @@
package core
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 授权管理服务
type AuthorizationManageService interface {
IsAllow(user *User, action *Action) bool
BeFriendFilter(userId int64) FriendFilter
IsAllow(user *ms.User, action *ms.Action) bool
BeFriendFilter(userId int64) ms.FriendFilter
BeFriendIds(userId int64) ([]int64, error)
MyFriendSet(userId int64) FriendSet
MyFriendSet(userId int64) ms.FriendSet
}

@ -7,6 +7,8 @@ package core
import (
"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"
)
@ -26,6 +28,11 @@ type IndexAction struct {
Post *dbr.Post
}
type IndexActionA struct {
Act IdxAct
Tweet *cs.TweetInfo
}
func (a IdxAct) String() string {
switch a {
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{
Act: act,
Post: post,
}
}
func NewIndexActionA(act IdxAct, tweet *cs.TweetInfo) *IndexActionA {
return &IndexActionA{
Act: act,
Tweet: tweet,
}
}
// CacheIndexService cache index service interface
type CacheIndexService interface {
IndexPostsService
@ -59,6 +73,13 @@ type CacheIndexService interface {
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
type RedisCache interface {
SetPushToSearchJob(ctx context.Context) error

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

@ -38,3 +38,14 @@ type DataService interface {
// share_key服务
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
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
"github.com/rocboss/paopao-ce/internal/core/ms"
)
// MessageService 消息服务
type MessageService interface {
CreateMessage(msg *Message) (*Message, error)
CreateMessage(msg *ms.Message) (*ms.Message, error)
GetUnreadCount(userID int64) (int64, error)
GetMessageByID(id int64) (*Message, error)
ReadMessage(message *Message) error
GetMessages(conditions *ConditionsT, offset, limit int) ([]*MessageFormated, error)
GetMessageCount(conditions *ConditionsT) (int64, error)
GetMessageByID(id int64) (*ms.Message, error)
ReadMessage(message *ms.Message) error
GetMessages(conditions *ms.ConditionsT, offset, limit int) ([]*ms.MessageFormated, 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
// 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 (
"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
import (
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
)
@ -21,6 +22,7 @@ const (
)
type (
// PostVisibleT 可访问类型0公开1私密2好友
PostVisibleT = dbr.PostVisibleT
SearchType string
@ -32,12 +34,12 @@ type (
}
QueryResp struct {
Items []*PostFormated
Items []*ms.PostFormated
Total int64
}
TsDocItem struct {
Post *Post
Post *ms.Post
Content string
}
)
@ -47,5 +49,5 @@ type TweetSearchService interface {
IndexName() string
AddDocuments(data []TsDocItem, primaryKey ...string) (bool, 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 (
"time"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
)
type (
Captcha = dbr.Captcha
"github.com/rocboss/paopao-ce/internal/core/ms"
)
// SecurityService 安全相关服务
type SecurityService interface {
GetLatestPhoneCaptcha(phone string) (*Captcha, error)
UsePhoneCaptcha(captcha *Captcha) error
GetLatestPhoneCaptcha(phone string) (*ms.Captcha, error)
UsePhoneCaptcha(captcha *ms.Captcha) 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
import (
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
)
type (
Tag = dbr.Tag
TagFormated = dbr.TagFormated
"github.com/rocboss/paopao-ce/internal/core/cs"
)
// TopicService 话题服务
type TopicService interface {
CreateTag(tag *Tag) (*Tag, error)
DeleteTag(tag *Tag) error
GetTags(conditions *ConditionsT, offset, limit int) ([]*Tag, error)
GetHotTags(userId int64, limit int, offset int) ([]*TagFormated, error)
GetNewestTags(userId int64, limit int, offset int) ([]*TagFormated, error)
GetFollowTags(userId int64, limit int, offset int) ([]*TagFormated, error)
GetTagsByKeyword(keyword string) ([]*Tag, error)
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)
GetHotTags(userId int64, limit int, offset int) (cs.TagList, error)
GetNewestTags(userId int64, limit int, offset int) (cs.TagList, error)
GetFollowTags(userId int64, limit int, offset int) (cs.TagList, error)
FollowTopic(userId int64, topicId int64) error
UnfollowTopic(userId int64, topicId int64) 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
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
)
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
}
"github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/core/ms"
)
// TweetService 推文检索服务
type TweetService interface {
GetPostByID(id int64) (*Post, error)
GetPosts(conditions *ConditionsT, offset, limit int) ([]*Post, error)
GetPostCount(conditions *ConditionsT) (int64, error)
GetUserPostStar(postID, userID int64) (*PostStar, error)
GetUserPostStars(userID int64, offset, limit int) ([]*PostStar, error)
GetPostByID(id int64) (*ms.Post, error)
GetPosts(conditions ms.ConditionsT, offset, limit int) ([]*ms.Post, error)
GetPostCount(conditions ms.ConditionsT) (int64, error)
GetUserPostStar(postID, userID int64) (*ms.PostStar, error)
GetUserPostStars(userID int64, offset, limit int) ([]*ms.PostStar, error)
GetUserPostStarCount(userID int64) (int64, error)
GetUserPostCollection(postID, userID int64) (*PostCollection, error)
GetUserPostCollections(userID int64, offset, limit int) ([]*PostCollection, error)
GetUserPostCollection(postID, userID int64) (*ms.PostCollection, error)
GetUserPostCollections(userID int64, offset, limit int) ([]*ms.PostCollection, error)
GetUserPostCollectionCount(userID int64) (int64, error)
GetPostAttatchmentBill(postID, userID int64) (*PostAttachmentBill, error)
GetPostContentsByIDs(ids []int64) ([]*PostContent, error)
GetPostContentByID(id int64) (*PostContent, error)
GetPostAttatchmentBill(postID, userID int64) (*ms.PostAttachmentBill, error)
GetPostContentsByIDs(ids []int64) ([]*ms.PostContent, error)
GetPostContentByID(id int64) (*ms.PostContent, error)
}
// TweetManageService 推文管理服务,包括创建/删除/更新推文
type TweetManageService interface {
CreateAttachment(attachment *Attachment) (*Attachment, error)
CreatePost(post *Post) (*Post, error)
DeletePost(post *Post) ([]string, error)
LockPost(post *Post) error
StickPost(post *Post) error
VisiblePost(post *Post, visibility PostVisibleT) error
UpdatePost(post *Post) error
CreatePostStar(postID, userID int64) (*PostStar, error)
DeletePostStar(p *PostStar) error
CreatePostCollection(postID, userID int64) (*PostCollection, error)
DeletePostCollection(p *PostCollection) error
CreatePostContent(content *PostContent) (*PostContent, error)
CreatePost(post *ms.Post) (*ms.Post, error)
DeletePost(post *ms.Post) ([]string, error)
LockPost(post *ms.Post) error
StickPost(post *ms.Post) error
VisiblePost(post *ms.Post, visibility PostVisibleT) error
UpdatePost(post *ms.Post) error
CreatePostStar(postID, userID int64) (*ms.PostStar, error)
DeletePostStar(p *ms.PostStar) error
CreatePostCollection(postID, userID int64) (*ms.PostCollection, error)
DeletePostCollection(p *ms.PostCollection) error
CreatePostContent(content *ms.PostContent) (*ms.PostContent, error)
CreateAttachment(obj *ms.Attachment) (int64, error)
}
// TweetHelpService 推文辅助服务
type TweetHelpService interface {
RevampPosts(posts []*PostFormated) ([]*PostFormated, error)
MergePosts(posts []*Post) ([]*PostFormated, error)
RevampPosts(posts []*ms.PostFormated) ([]*ms.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 广场首页推文列表服务
type IndexPostsService interface {
IndexPosts(user *User, offset int, limit int) (*IndexTweetList, error)
// TweetHelpServantA 推文辅助服务(版本A)
type TweetHelpServantA interface {
RevampTweets(tweets cs.TweetList) (cs.TweetList, error)
MergeTweets(tweets cs.TweetInfo) (cs.TweetList, error)
}

@ -4,30 +4,17 @@
package core
type (
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"`
}
)
import "github.com/rocboss/paopao-ce/internal/core/ms"
// UserManageService 用户管理服务
type UserManageService interface {
GetUserByID(id int64) (*User, error)
GetUserByUsername(username string) (*User, error)
GetUserByPhone(phone string) (*User, error)
GetUsersByIDs(ids []int64) ([]*User, error)
GetUsersByKeyword(keyword string) ([]*User, error)
CreateUser(user *User) (*User, error)
UpdateUser(user *User) error
GetUserByID(id int64) (*ms.User, error)
GetUserByUsername(username string) (*ms.User, error)
GetUserByPhone(phone string) (*ms.User, error)
GetUsersByIDs(ids []int64) ([]*ms.User, error)
GetUsersByKeyword(keyword string) ([]*ms.User, error)
CreateUser(user *ms.User) (*ms.User, error)
UpdateUser(user *ms.User) error
}
// ContactManageService 联系人管理服务
@ -36,6 +23,6 @@ type ContactManageService interface {
AddFriend(userId int64, friendId int64) error
RejectFriend(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
}

@ -5,20 +5,15 @@
package core
import (
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
)
type (
WalletStatement = dbr.WalletStatement
WalletRecharge = dbr.WalletRecharge
"github.com/rocboss/paopao-ce/internal/core/ms"
)
// WalletService wallet service 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)
GetRechargeByID(id int64) (*WalletRecharge, error)
CreateRecharge(userId, amount int64) (*WalletRecharge, error)
HandleRechargeSuccess(recharge *WalletRecharge, tradeNo string) error
HandlePostAttachmentBought(post *Post, user *User) error
GetRechargeByID(id int64) (*ms.WalletRecharge, error)
CreateRecharge(userId, amount int64) (*ms.WalletRecharge, error)
HandleRechargeSuccess(recharge *ms.WalletRecharge, tradeNo string) error
HandlePostAttachmentBought(post *ms.Post, user *ms.User) error
}

@ -15,6 +15,7 @@ import (
"github.com/Masterminds/semver/v3"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/pkg/types"
"github.com/sirupsen/logrus"
)
@ -30,7 +31,7 @@ var (
type postsEntry struct {
key string
tweets *core.IndexTweetList
tweets *ms.IndexTweetList
}
type tweetsCache interface {
@ -54,7 +55,7 @@ type cacheIndexSrv struct {
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)
posts, err := s.getPosts(key)
if err == nil {
@ -70,7 +71,7 @@ func (s *cacheIndexSrv) IndexPosts(user *core.User, offset int, limit int) (*cor
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)
if err != nil {
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)
dec := gob.NewDecoder(buf)
var resp core.IndexTweetList
var resp ms.IndexTweetList
if err := dec.Decode(&resp); err != nil {
logrus.Debugf("cacheIndexSrv.getPosts get posts from cache in decode err: %v", err)
return nil, err
@ -86,7 +87,7 @@ func (s *cacheIndexSrv) getPosts(key string) (*core.IndexTweetList, error) {
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}
select {
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)
}
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
if user != nil {
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)
}
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)
select {
case s.indexActionCh <- action:
@ -168,7 +169,7 @@ func (s *cacheIndexSrv) handleIndexAction(action *core.IndexAction) {
func (s *cacheIndexSrv) deleteCacheByUserId(id int64, oneself bool) {
var keys []string
userId := strconv.FormatInt(id, 10)
friendSet := core.FriendSet{}
friendSet := ms.FriendSet{}
if !oneself {
friendSet = s.ams.MyFriendSet(id)
}

@ -7,6 +7,9 @@ package cache
import (
"github.com/Masterminds/semver/v3"
"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 (
@ -18,11 +21,16 @@ type noneCacheIndexServant struct {
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)
}
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
}

@ -10,6 +10,9 @@ import (
"github.com/Masterminds/semver/v3"
"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"
)
@ -22,21 +25,21 @@ type simpleCacheIndexServant struct {
ips core.IndexPostsService
indexActionCh chan core.IdxAct
indexPosts *core.IndexTweetList
indexPosts *ms.IndexTweetList
atomicIndex atomic.Value
maxIndexSize int
checkTick *time.Ticker
expireIndexTick *time.Ticker
}
func (s *simpleCacheIndexServant) IndexPosts(user *core.User, offset int, limit int) (*core.IndexTweetList, error) {
cacheResp := s.atomicIndex.Load().(*core.IndexTweetList)
func (s *simpleCacheIndexServant) IndexPosts(user *ms.User, offset int, limit int) (*ms.IndexTweetList, error) {
cacheResp := s.atomicIndex.Load().(*ms.IndexTweetList)
end := offset + limit
if cacheResp != nil {
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)
if size >= end {
return &core.IndexTweetList{
return &ms.IndexTweetList{
Tweets: cacheResp.Tweets[offset:end],
Total: cacheResp.Total,
}, nil
@ -47,7 +50,12 @@ func (s *simpleCacheIndexServant) IndexPosts(user *core.User, offset int, 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 {
case s.indexActionCh <- act:
logrus.Debugf("simpleCacheIndexServant.SendAction send indexAction by chan: %s", act)

@ -18,87 +18,114 @@ import (
)
var (
ts core.TweetSearchService
ds core.DataService
oss core.ObjectStorageService
ts core.TweetSearchService
ds core.DataService
oss core.ObjectStorageService
webDsa core.WebDataServantA
onceTs, onceDs, onceOss sync.Once
_onceInitial sync.Once
)
func DataService() core.DataService {
onceDs.Do(func() {
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())
})
lazyInitial()
return ds
}
func WebDataServantA() core.WebDataServantA {
lazyInitial()
return webDsa
}
func ObjectStorageService() core.ObjectStorageService {
onceOss.Do(func() {
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())
})
lazyInitial()
return oss
}
func TweetSearchService() core.TweetSearchService {
onceTs.Do(func() {
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)
})
lazyInitial()
return ts
}
func newAuthorizationManageService() (s core.AuthorizationManageService) {
func newAuthorizationManageService() (ams core.AuthorizationManageService) {
if cfg.If("Gorm") {
s = jinzhu.NewAuthorizationManageService()
} else if cfg.All("Sqlx", "MySQL") {
s = sakila.NewAuthorizationManageService()
} else if cfg.If("Sqlx") && cfg.Any("Postgres", "PostgreSQL") {
s = slonik.NewAuthorizationManageService()
ams = jinzhu.NewAuthorizationManageService()
} else if cfg.If("Sqlx") {
ams = sakila.NewAuthorizationManageService()
} else if cfg.If("Sqlc") && cfg.Any("Postgres", "PostgreSQL") {
ams = slonik.NewAuthorizationManageService()
} else {
s = jinzhu.NewAuthorizationManageService()
ams = jinzhu.NewAuthorizationManageService()
}
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 (
"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/pkg/types"
"gorm.io/gorm"
)
var (
_ core.AuthorizationManageService = (*authorizationManageServant)(nil)
_ core.AuthorizationManageService = (*authorizationManageSrv)(nil)
)
type authorizationManageServant struct {
type authorizationManageSrv struct {
db *gorm.DB
}
func newAuthorizationManageService(db *gorm.DB) core.AuthorizationManageService {
return &authorizationManageServant{
return &authorizationManageSrv{
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
isActivation := (len(user.Phone) != 0)
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)
}
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)
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 {
resp[id] = types.Empty{}
}
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)
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 {
resp[id] = types.Empty{}
}
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)
}
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)
if err == nil || contact.Status == dbr.ContactStatusAgree {
return true

@ -9,37 +9,38 @@ import (
"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/pkg/types"
"gorm.io/gorm"
)
var (
_ core.CommentService = (*commentServant)(nil)
_ core.CommentManageService = (*commentManageServant)(nil)
_ core.CommentService = (*commentSrv)(nil)
_ core.CommentManageService = (*commentManageSrv)(nil)
)
type commentServant struct {
type commentSrv struct {
db *gorm.DB
}
type commentManageServant struct {
type commentManageSrv struct {
db *gorm.DB
}
func newCommentService(db *gorm.DB) core.CommentService {
return &commentServant{
return &commentSrv{
db: db,
}
}
func newCommentManageService(db *gorm.DB) core.CommentManageService {
return &commentManageServant{
return &commentManageSrv{
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 {
return nil, nil, nil
}
@ -59,11 +60,11 @@ func (s *commentServant) GetCommentThumbsMap(userId int64, tweetId int64) (cs.Co
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)
}
func (s *commentServant) GetCommentByID(id int64) (*core.Comment, error) {
func (s *commentSrv) GetCommentByID(id int64) (*ms.Comment, error) {
comment := &dbr.Comment{
Model: &dbr.Model{
ID: id,
@ -72,7 +73,7 @@ func (s *commentServant) GetCommentByID(id int64) (*core.Comment, error) {
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{
Model: &dbr.Model{
ID: id,
@ -81,18 +82,18 @@ func (s *commentServant) GetCommentReplyByID(id int64) (*core.CommentReply, erro
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)
}
func (s *commentServant) GetCommentContentsByIDs(ids []int64) ([]*core.CommentContent, error) {
func (s *commentSrv) GetCommentContentsByIDs(ids []int64) ([]*ms.CommentContent, error) {
commentContent := &dbr.CommentContent{}
return commentContent.List(s.db, &dbr.ConditionsT{
"comment_id IN ?": ids,
}, 0, 0)
}
func (s *commentServant) GetCommentRepliesByID(ids []int64) ([]*core.CommentReplyFormated, error) {
func (s *commentSrv) GetCommentRepliesByID(ids []int64) ([]*ms.CommentReplyFormated, error) {
CommentReply := &dbr.CommentReply{}
replies, err := CommentReply.List(s.db, &dbr.ConditionsT{
"comment_id IN ?": ids,
@ -112,7 +113,7 @@ func (s *commentServant) GetCommentRepliesByID(ids []int64) ([]*core.CommentRepl
if err != nil {
return nil, err
}
repliesFormated := []*core.CommentReplyFormated{}
repliesFormated := []*ms.CommentReplyFormated{}
for _, reply := range replies {
replyFormated := reply.Format()
for _, user := range users {
@ -130,7 +131,7 @@ func (s *commentServant) GetCommentRepliesByID(ids []int64) ([]*core.CommentRepl
return repliesFormated, nil
}
func (s *commentManageServant) DeleteComment(comment *core.Comment) error {
func (s *commentManageSrv) DeleteComment(comment *ms.Comment) error {
db := s.db.Begin()
defer db.Rollback()
@ -149,15 +150,15 @@ func (s *commentManageServant) DeleteComment(comment *core.Comment) error {
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)
}
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)
}
func (s *commentManageServant) DeleteCommentReply(reply *core.CommentReply) (err error) {
func (s *commentManageSrv) DeleteCommentReply(reply *ms.CommentReply) (err error) {
db := s.db.Begin()
defer db.Rollback()
@ -177,11 +178,11 @@ func (s *commentManageServant) DeleteCommentReply(reply *core.CommentReply) (err
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)
}
func (s *commentManageServant) ThumbsUpComment(userId int64, tweetId, commentId int64) error {
func (s *commentManageSrv) ThumbsUpComment(userId int64, tweetId, commentId int64) error {
db := s.db.Begin()
defer db.Rollback()
@ -230,7 +231,7 @@ func (s *commentManageServant) ThumbsUpComment(userId int64, tweetId, commentId
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()
defer db.Rollback()
@ -280,7 +281,7 @@ func (s *commentManageServant) ThumbsDownComment(userId int64, tweetId, commentI
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()
defer db.Rollback()
@ -330,7 +331,7 @@ func (s *commentManageServant) ThumbsUpReply(userId int64, tweetId, commentId, r
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()
defer db.Rollback()
@ -380,7 +381,7 @@ func (s *commentManageServant) ThumbsDownReply(userId int64, tweetId, commentId,
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)
if thumbsUpCount == 1 {
updateColumns["thumbs_up_count"] = gorm.Expr("thumbs_up_count + 1")

@ -8,26 +8,27 @@ import (
"time"
"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/sirupsen/logrus"
"gorm.io/gorm"
)
var (
_ core.ContactManageService = (*contactManageServant)(nil)
_ core.ContactManageService = (*contactManageSrv)(nil)
)
type contactManageServant struct {
type contactManageSrv struct {
db *gorm.DB
}
func newContactManageService(db *gorm.DB) core.ContactManageService {
return &contactManageServant{
return &contactManageSrv{
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{
UserId: userId,
FriendId: friendId,
@ -40,14 +41,14 @@ func (s *contactManageServant) fetchOrNewContact(db *gorm.DB, userId int64, frie
Status: status,
}
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 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()
defer func() {
if err == nil {
@ -70,7 +71,7 @@ func (s *contactManageServant) RequestingFriend(userId int64, friendId int64, gr
contact.Status = dbr.ContactStatusRequesting
contact.IsDel = 0 // remove deleted flag if needed
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
}
}
@ -84,13 +85,13 @@ func (s *contactManageServant) RequestingFriend(userId int64, friendId int64, gr
ReplyID: int64(dbr.ContactStatusRequesting),
}
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 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()
defer func() {
if err == nil {
@ -109,7 +110,7 @@ func (s *contactManageServant) AddFriend(userId int64, friendId int64) (err erro
}
// 如果还不是请求好友,啥也不干
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
}
contact.Status = dbr.ContactStatusAgree
@ -127,7 +128,7 @@ func (s *contactManageServant) AddFriend(userId int64, friendId int64) (err erro
contact.Status = dbr.ContactStatusAgree
contact.IsDel = 0 // remove deleted flag
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
}
}
@ -149,7 +150,7 @@ func (s *contactManageServant) AddFriend(userId int64, friendId int64) (err erro
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()
defer func() {
if err == nil {
@ -192,7 +193,7 @@ func (s *contactManageServant) RejectFriend(userId int64, friendId int64) (err e
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()
defer func() {
if err == nil {
@ -226,7 +227,7 @@ func (s *contactManageServant) DeleteFriend(userId int64, friendId int64) (err e
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{}
condition := dbr.ConditionsT{
"user_id": userId,
@ -240,13 +241,13 @@ func (s *contactManageServant) GetContacts(userId int64, offset int, limit int)
if err != nil {
return nil, err
}
resp := &core.ContactList{
Contacts: make([]core.ContactItem, 0, len(contacts)),
resp := &ms.ContactList{
Contacts: make([]ms.ContactItem, 0, len(contacts)),
Total: total,
}
for _, c := range contacts {
if c.User != nil {
resp.Contacts = append(resp.Contacts, core.ContactItem{
resp.Contacts = append(resp.Contacts, ms.ContactItem{
UserId: c.FriendId,
UserName: c.User.Username,
Nickname: c.User.Nickname,
@ -258,7 +259,7 @@ func (s *contactManageServant) GetContacts(userId int64, offset int, limit int)
return resp, nil
}
func (s *contactManageServant) IsFriend(userId int64, friendId int64) bool {
func (s *contactManageSrv) IsFriend(userId int64, friendId int64) bool {
contact := &dbr.Contact{
UserId: friendId,
FriendId: userId,

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

@ -13,9 +13,9 @@ import (
type CommentReply struct {
*Model
CommentID int64 `json:"comment_id"`
UserID int64 `json:"user_id"`
AtUserID int64 `json:"at_user_id"`
CommentID int64 `db:"comment_id" json:"comment_id"`
UserID int64 `db:"user_id" json:"user_id"`
AtUserID int64 `db:"at_user_id" json:"at_user_id"`
Content string `json:"content"`
IP string `json:"ip"`
IPLoc string `json:"ip_loc"`
@ -25,10 +25,10 @@ type CommentReply struct {
type CommentReplyFormated struct {
ID int64 `json:"id"`
CommentID int64 `json:"comment_id"`
UserID int64 `json:"user_id"`
CommentID int64 `db:"comment_id" json:"comment_id"`
UserID int64 `db:"user_id" json:"user_id"`
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"`
Content string `json:"content"`
IPLoc string `json:"ip_loc"`

@ -120,7 +120,7 @@ func (p *Post) Get(db *gorm.DB) (*Post, error) {
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 err error
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 {
db = db.Where("user_id = ?", p.UserID)
}
for k, v := range *conditions {
for k, v := range conditions {
if k == "ORDER" {
db = db.Order(v)
} else {
@ -178,12 +178,12 @@ func (p *Post) CountBy(db *gorm.DB, predicates Predicates) (count int64, err err
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
if p.UserID > 0 {
db = db.Where("user_id = ?", p.UserID)
}
for k, v := range *conditions {
for k, v := range conditions {
if k != "ORDER" {
db = db.Where(k, v)
}

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

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

@ -88,9 +88,7 @@ func (t *Tag) Delete(db *gorm.DB) error {
}).Error
}
func (t *Tag) List(db *gorm.DB, conditions *ConditionsT, offset, limit int) ([]*Tag, error) {
var tags []*Tag
var err error
func (t *Tag) List(db *gorm.DB, conditions *ConditionsT, offset, limit int) (tags []*Tag, err error) {
if offset >= 0 && limit > 0 {
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)
}
}
if err = db.Where("is_del = 0 and quote_num > 0").Find(&tags).Error; err != nil {
return nil, err
}
return tags, nil
err = db.Where("is_del = 0 and quote_num > 0").Find(&tags).Error
return
}
func (t *Tag) TagsFrom(db *gorm.DB, tags []string) (res []*Tag, err error) {

@ -4,7 +4,10 @@
package dbr
import "gorm.io/gorm"
import (
"github.com/rocboss/paopao-ce/internal/core/cs"
"gorm.io/gorm"
)
const (
UserStatusNormal int = iota + 1
@ -25,7 +28,7 @@ type User struct {
}
type UserFormated struct {
ID int64 `json:"id"`
ID int64 `db:"id" json:"id"`
Nickname string `json:"nickname"`
Username string `json:"username"`
Status int `json:"status"`
@ -87,6 +90,11 @@ func (u *User) List(db *gorm.DB, conditions *ConditionsT, offset, limit int) ([]
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) {
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
import (
"sync"
"github.com/Masterminds/semver/v3"
"github.com/alimy/cfg"
"github.com/rocboss/paopao-ce/internal/conf"
@ -19,11 +21,16 @@ import (
)
var (
_ core.DataService = (*dataServant)(nil)
_ core.VersionInfo = (*dataServant)(nil)
_ core.DataService = (*dataSrv)(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.WalletService
core.MessageService
@ -40,7 +47,16 @@ type dataServant struct {
core.ShareKeyService
}
type webDataSrvA struct {
core.TopicServantA
core.TweetServantA
core.TweetManageServantA
core.TweetHelpServantA
}
func NewDataService() (core.DataService, core.VersionInfo) {
lazyInitial()
var (
v core.VersionInfo
cis core.CacheIndexService
@ -50,7 +66,6 @@ func NewDataService() (core.DataService, core.VersionInfo) {
pvs := security.NewPhoneVerifyService()
ams := NewAuthorizationManageService()
ths := newTweetHelpService(db)
ums := newUserManageService(db)
// initialize core.IndexPostsService
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())
ds := &dataServant{
ds := &dataSrv{
IndexPostsService: cis,
WalletService: newWalletService(db),
MessageService: newMessageService(db),
TopicService: newTopicService(db, ums),
TopicService: newTopicService(db),
TweetService: newTweetService(db),
TweetManageService: newTweetManageService(db, cis),
TweetHelpService: newTweetHelpService(db),
@ -103,14 +118,41 @@ func NewDataService() (core.DataService, core.VersionInfo) {
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 {
return newAuthorizationManageService(conf.MustGormDB())
}
func (s *dataServant) Name() string {
func (s *dataSrv) Name() string {
return "Gorm"
}
func (s *dataServant) Version() *semver.Version {
func (s *dataSrv) Version() *semver.Version {
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 (
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"gorm.io/gorm"
)
var (
_ core.MessageService = (*messageServant)(nil)
_ core.MessageService = (*messageSrv)(nil)
)
type messageServant struct {
type messageSrv struct {
db *gorm.DB
}
func newMessageService(db *gorm.DB) core.MessageService {
return &messageServant{
return &messageSrv{
db: db,
}
}
func (d *messageServant) CreateMessage(msg *core.Message) (*core.Message, error) {
return msg.Create(d.db)
func (s *messageSrv) CreateMessage(msg *ms.Message) (*ms.Message, error) {
return msg.Create(s.db)
}
func (d *messageServant) GetUnreadCount(userID int64) (int64, error) {
return (&dbr.Message{}).Count(d.db, &dbr.ConditionsT{
func (s *messageSrv) GetUnreadCount(userID int64) (int64, error) {
return (&dbr.Message{}).Count(s.db, &dbr.ConditionsT{
"receiver_user_id": userID,
"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{
Model: &dbr.Model{
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
return message.Update(d.db)
return message.Update(s.db)
}
func (d *messageServant) GetMessages(conditions *core.ConditionsT, offset, limit int) ([]*core.MessageFormated, error) {
messages, err := (&dbr.Message{}).List(d.db, conditions, offset, limit)
func (s *messageSrv) GetMessages(conditions *ms.ConditionsT, offset, limit int) ([]*ms.MessageFormated, error) {
messages, err := (&dbr.Message{}).List(s.db, conditions, offset, limit)
if err != nil {
return nil, err
}
@ -63,6 +64,6 @@ func (d *messageServant) GetMessages(conditions *core.ConditionsT, offset, limit
return mfs, nil
}
func (d *messageServant) GetMessageCount(conditions *core.ConditionsT) (int64, error) {
return (&dbr.Message{}).Count(d.db, conditions)
func (s *messageSrv) GetMessageCount(conditions *ms.ConditionsT) (int64, error) {
return (&dbr.Message{}).Count(s.db, conditions)
}

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

@ -6,6 +6,8 @@ package jinzhu
import (
"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/pkg/debug"
"github.com/sirupsen/logrus"
@ -13,35 +15,35 @@ import (
)
var (
_ core.IndexPostsService = (*friendIndexServant)(nil)
_ core.IndexPostsService = (*followIndexServant)(nil)
_ core.IndexPostsService = (*lightIndexServant)(nil)
_ core.IndexPostsService = (*simpleIndexPostsServant)(nil)
_ core.IndexPostsService = (*friendIndexSrv)(nil)
_ core.IndexPostsService = (*followIndexSrv)(nil)
_ core.IndexPostsService = (*lightIndexSrv)(nil)
_ core.IndexPostsService = (*simpleIndexPostsSrv)(nil)
)
type friendIndexServant struct {
type friendIndexSrv struct {
ams core.AuthorizationManageService
ths core.TweetHelpService
db *gorm.DB
}
type followIndexServant struct {
type followIndexSrv struct {
ths core.TweetHelpService
db *gorm.DB
}
type lightIndexServant struct {
type lightIndexSrv struct {
ths core.TweetHelpService
db *gorm.DB
}
type simpleIndexPostsServant struct {
type simpleIndexPostsSrv struct {
ths core.TweetHelpService
db *gorm.DB
}
// 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{
"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)
if err != nil {
logrus.Debugf("gormIndexPostsServant.IndexPosts err: %v", err)
logrus.Debugf("gormIndexPostsSrv.IndexPosts err: %v", err)
return nil, err
}
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 &core.IndexTweetList{
return &ms.IndexTweetList{
Tweets: formatPosts,
Total: total,
}, nil
}
func (s *friendIndexSrv) TweetTimeline(userId int64, offset int, limit int) (*cs.TweetBox, error) {
// TODO
return nil, debug.ErrNotImplemented
}
// 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
return nil, debug.ErrNotImplemented
}
// 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{
"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)
if err != nil {
logrus.Debugf("gormIndexPostsServant.IndexPosts err: %v", err)
logrus.Debugf("gormIndexPostsSrv.IndexPosts err: %v", err)
return nil, err
}
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 &core.IndexTweetList{
return &ms.IndexTweetList{
Tweets: formatPosts,
Total: total,
}, nil
}
func (s *lightIndexSrv) TweetTimeline(userId int64, offset int, limit int) (*cs.TweetBox, error) {
// TODO
return nil, debug.ErrNotImplemented
}
// simpleCacheIndexGetPosts simpleCacheIndex 专属获取广场推文列表函数
func (s *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{
"visibility = ?": []any{dbr.PostVisitPublic},
"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)
if err != nil {
logrus.Debugf("gormSimpleIndexPostsServant.IndexPosts err: %v", err)
logrus.Debugf("gormSimpleIndexPostsSrv.IndexPosts err: %v", err)
return nil, err
}
@ -137,14 +154,19 @@ func (s *simpleIndexPostsServant) IndexPosts(_user *core.User, offset int, limit
return nil, err
}
return &core.IndexTweetList{
return &ms.IndexTweetList{
Tweets: formatPosts,
Total: total,
}, 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 {
return &friendIndexServant{
return &friendIndexSrv{
ams: ams,
ths: ths,
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 {
return &followIndexServant{
return &followIndexSrv{
ths: ths,
db: db,
}
}
func newLightIndexService(db *gorm.DB, ths core.TweetHelpService) core.IndexPostsService {
return &lightIndexServant{
return &lightIndexSrv{
ths: ths,
db: db,
}
}
func newSimpleIndexPostsService(db *gorm.DB, ths core.TweetHelpService) core.IndexPostsService {
return &simpleIndexPostsServant{
return &simpleIndexPostsSrv{
ths: ths,
db: db,
}

@ -9,68 +9,108 @@ import (
"strings"
"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"
"gorm.io/gorm"
)
var (
_ core.TopicService = (*topicServant)(nil)
_ core.TopicService = (*topicSrv)(nil)
_ core.TopicServantA = (*topicSrvA)(nil)
)
type topicServant struct {
type topicSrv struct {
db *gorm.DB
ums core.UserManageService
tnTopicUser string
tnDotTopicUser string
}
type topicSrvA struct {
db *gorm.DB
}
type topicInfo struct {
TopicId int64
IsTop int8
}
func newTopicService(db *gorm.DB, ums core.UserManageService) core.TopicService {
return &topicServant{
func newTopicService(db *gorm.DB) core.TopicService {
return &topicSrv{
db: db,
ums: ums,
tnTopicUser: db.NamingStrategy.TableName("TopicUser"),
tnDotTopicUser: db.NamingStrategy.TableName("TopicUser") + ".",
}
}
func (s *topicServant) CreateTag(tag *core.Tag) (*core.Tag, error) {
return createTag(s.db, tag)
func newTopicServantA(db *gorm.DB) core.TopicServantA {
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 {
return deleteTag(s.db, tag)
func (s *topicSrv) 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 *topicServant) GetTags(conditions *core.ConditionsT, offset, limit int) ([]*core.Tag, error) {
return (&dbr.Tag{}).List(s.db, conditions, offset, limit)
func (s *topicSrv) 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",
}
}
return s.listTags(conditions, limit, offset)
}
func (s *topicServant) GetHotTags(userId int64, limit int, offset int) ([]*core.TagFormated, error) {
tags, err := (&dbr.Tag{}).List(s.db, &core.ConditionsT{
func (s *topicSrv) GetHotTags(userId int64, limit int, offset int) (cs.TagList, error) {
tags, err := s.listTags(&ms.ConditionsT{
"ORDER": "quote_num DESC",
}, offset, limit)
}, limit, offset)
if err != nil {
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) {
tags, err := (&dbr.Tag{}).List(s.db, &core.ConditionsT{
func (s *topicSrv) GetNewestTags(userId int64, limit int, offset int) (cs.TagList, error) {
tags, err := s.listTags(&ms.ConditionsT{
"ORDER": "id DESC",
}, offset, limit)
}, limit, offset)
if err != nil {
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 {
return nil, nil
}
@ -92,25 +132,89 @@ func (s *topicServant) GetFollowTags(userId int64, limit int, offset int) ([]*co
topicIds = append(topicIds, info.TopicId)
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
if err != nil {
return nil, err
}
formtedTags, err := s.tagsFormat(-1, userTopicsMap, tags)
formtedTags, err := s.tagsFormatB(userTopicsMap, tags)
if err != nil {
return nil, err
}
// 置顶排序后处理
// 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 {
res[topicIdsMap[tag.ID]] = tag
}
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
userIds := []int64{}
tagIds := []int64{}
@ -118,59 +222,161 @@ func (s *topicServant) tagsFormat(userId int64, userTopicsMap map[int64]*topicIn
userIds = append(userIds, tag.UserID)
tagIds = append(tagIds, tag.ID)
}
users, err := s.ums.GetUsersByIDs(userIds)
users, err := (&dbr.User{}).ListUserInfoById(s.db, userIds)
if err != nil {
return nil, err
}
tagsFormated := []*core.TagFormated{}
tagList := cs.TagList{}
for _, tag := range tags {
tagFormated := tag.Format()
for _, user := range users {
if user.ID == tagFormated.UserID {
tagFormated.User = user.Format()
tagFormated.User = user
}
}
tagsFormated = append(tagsFormated, tagFormated)
tagList = append(tagList, tagFormated)
}
// 填充话题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 {
for _, tag := range tagsFormated {
for _, tag := range tagList {
if info, exist := userTopicsMap[tag.ID]; exist {
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{}
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, " ") + "%"
tag := &dbr.Tag{}
var tags []*dbr.Tag
if keyword == "%%" {
return tag.List(s.db, &dbr.ConditionsT{
tags, err = tag.List(s.db, &dbr.ConditionsT{
"ORDER": "quote_num DESC",
}, 0, 6)
} else {
return tag.List(s.db, &dbr.ConditionsT{
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 *topicServant) FollowTopic(userId int64, topicId int64) (err error) {
func (s *topicSrv) FollowTopic(userId int64, topicId int64) (err error) {
return s.db.Create(&dbr.TopicUser{
UserID: userId,
TopicID: topicId,
@ -178,11 +384,11 @@ func (s *topicServant) FollowTopic(userId int64, topicId int64) (err 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
}
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()
defer db.Rollback()

@ -9,50 +9,87 @@ import (
"time"
"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/pkg/debug"
"gorm.io/gorm"
)
var (
_ core.TweetService = (*tweetServant)(nil)
_ core.TweetManageService = (*tweetManageServant)(nil)
_ core.TweetHelpService = (*tweetHelpServant)(nil)
_ core.TweetService = (*tweetSrv)(nil)
_ core.TweetManageService = (*tweetManageSrv)(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
}
type tweetManageServant struct {
type tweetManageSrv struct {
cacheIndex core.CacheIndexService
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
}
func newTweetService(db *gorm.DB) core.TweetService {
return &tweetServant{
return &tweetSrv{
db: db,
}
}
func newTweetManageService(db *gorm.DB, cacheIndex core.CacheIndexService) core.TweetManageService {
return &tweetManageServant{
return &tweetManageSrv{
cacheIndex: cacheIndex,
db: db,
}
}
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,
}
}
// 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))
userIds := make([]int64, 0, len(posts))
for _, post := range posts {
@ -92,7 +129,7 @@ func (s *tweetHelpServant) MergePosts(posts []*core.Post) ([]*core.PostFormated,
}
// 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))
userIds := make([]int64, 0, len(posts))
for _, post := range posts {
@ -128,14 +165,14 @@ func (s *tweetHelpServant) RevampPosts(posts []*core.PostFormated) ([]*core.Post
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{
"post_id IN ?": ids,
"ORDER": "sort ASC",
}, 0, 0)
}
func (s *tweetHelpServant) getUsersByIDs(ids []int64) ([]*dbr.User, error) {
func (s *tweetHelpSrv) getUsersByIDs(ids []int64) ([]*dbr.User, error) {
user := &dbr.User{}
return user.List(s.db, &dbr.ConditionsT{
@ -143,7 +180,7 @@ func (s *tweetHelpServant) getUsersByIDs(ids []int64) ([]*dbr.User, error) {
}, 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{
PostID: postID,
UserID: userID,
@ -152,19 +189,20 @@ func (s *tweetManageServant) CreatePostCollection(postID, userID int64) (*core.P
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)
}
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)
}
func (s *tweetManageServant) CreateAttachment(attachment *core.Attachment) (*core.Attachment, error) {
return attachment.Create(s.db)
func (s *tweetManageSrv) CreateAttachment(obj *ms.Attachment) (int64, error) {
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()
p, err := post.Create(s.db)
if err != nil {
@ -174,7 +212,7 @@ func (s *tweetManageServant) CreatePost(post *core.Post) (*core.Post, error) {
return p, nil
}
func (s *tweetManageServant) DeletePost(post *core.Post) ([]string, error) {
func (s *tweetManageSrv) DeletePost(post *ms.Post) ([]string, error) {
var mediaContents []string
postId := post.ID
@ -221,7 +259,7 @@ func (s *tweetManageServant) DeletePost(post *core.Post) ([]string, error) {
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{}
commentContent := &dbr.CommentContent{}
@ -255,12 +293,12 @@ func (s *tweetManageServant) deleteCommentByPostId(db *gorm.DB, postId int64) ([
return mediaContents, nil
}
func (s *tweetManageServant) LockPost(post *core.Post) error {
func (s *tweetManageSrv) LockPost(post *ms.Post) error {
post.IsLock = 1 - post.IsLock
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
if err := post.Update(s.db); err != nil {
return err
@ -269,7 +307,7 @@ func (s *tweetManageServant) StickPost(post *core.Post) error {
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
post.Visibility = visibility
// TODO: 这个判断是否可以不要呢
@ -288,29 +326,22 @@ func (s *tweetManageServant) VisiblePost(post *core.Post, visibility core.PostVi
db.Rollback()
return err
}
// tag处理
tags := strings.Split(post.Tags, ",")
for _, t := range tags {
tag := &dbr.Tag{
UserID: post.UserID,
Tag: t,
}
// TODO: 暂时宽松不处理错误,这里或许可以有优化,后续完善
if oldVisibility == dbr.PostVisitPrivate {
// 从私密转为非私密才需要重新创建tag
createTag(db, tag)
} else if visibility == dbr.PostVisitPrivate {
// 从非私密转为私密才需要删除tag
deleteTag(db, tag)
}
// TODO: 暂时宽松不处理错误,这里或许可以有优化,后续完善
if oldVisibility == dbr.PostVisitPrivate {
// 从私密转为非私密才需要重新创建tag
createTags(db, post.UserID, tags)
} else if visibility == dbr.PostVisitPrivate {
// 从非私密转为私密才需要删除tag
deleteTags(db, tags)
}
db.Commit()
s.cacheIndex.SendAction(core.IdxActVisiblePost, post)
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 {
return err
}
@ -318,7 +349,7 @@ func (s *tweetManageServant) UpdatePost(post *core.Post) error {
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{
PostID: postID,
UserID: userID,
@ -326,11 +357,11 @@ func (s *tweetManageServant) CreatePostStar(postID, userID int64) (*core.PostSta
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)
}
func (s *tweetServant) GetPostByID(id int64) (*core.Post, error) {
func (s *tweetSrv) GetPostByID(id int64) (*ms.Post, error) {
post := &dbr.Post{
Model: &dbr.Model{
ID: id,
@ -339,15 +370,15 @@ func (s *tweetServant) GetPostByID(id int64) (*core.Post, error) {
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)
}
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)
}
func (s *tweetServant) GetUserPostStar(postID, userID int64) (*core.PostStar, error) {
func (s *tweetSrv) GetUserPostStar(postID, userID int64) (*ms.PostStar, error) {
star := &dbr.PostStar{
PostID: postID,
UserID: userID,
@ -355,7 +386,7 @@ func (s *tweetServant) GetUserPostStar(postID, userID int64) (*core.PostStar, er
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{
UserID: userID,
}
@ -365,14 +396,14 @@ func (s *tweetServant) GetUserPostStars(userID int64, offset, limit int) ([]*cor
}, offset, limit)
}
func (s *tweetServant) GetUserPostStarCount(userID int64) (int64, error) {
func (s *tweetSrv) GetUserPostStarCount(userID int64) (int64, error) {
star := &dbr.PostStar{
UserID: userID,
}
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{
PostID: postID,
UserID: userID,
@ -380,7 +411,7 @@ func (s *tweetServant) GetUserPostCollection(postID, userID int64) (*core.PostCo
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{
UserID: userID,
}
@ -390,14 +421,14 @@ func (s *tweetServant) GetUserPostCollections(userID int64, offset, limit int) (
}, offset, limit)
}
func (s *tweetServant) GetUserPostCollectionCount(userID int64) (int64, error) {
func (s *tweetSrv) GetUserPostCollectionCount(userID int64) (int64, error) {
collection := &dbr.PostCollection{
UserID: userID,
}
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{
UserID: userID,
}
@ -407,14 +438,14 @@ func (s *tweetServant) GetUserWalletBills(userID int64, offset, limit int) ([]*c
}, offset, limit)
}
func (s *tweetServant) GetUserWalletBillCount(userID int64) (int64, error) {
func (s *tweetSrv) GetUserWalletBillCount(userID int64) (int64, error) {
statement := &dbr.WalletStatement{
UserID: userID,
}
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{
PostID: postID,
UserID: userID,
@ -423,17 +454,117 @@ func (s *tweetServant) GetPostAttatchmentBill(postID, userID int64) (*core.PostA
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{
"post_id IN ?": ids,
"ORDER": "sort ASC",
}, 0, 0)
}
func (s *tweetServant) GetPostContentByID(id int64) (*core.PostContent, error) {
func (s *tweetSrv) GetPostContentByID(id int64) (*ms.PostContent, error) {
return (&dbr.PostContent{
Model: &dbr.Model{
ID: id,
},
}).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
import (
"github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"gorm.io/gorm"
)
func createTag(db *gorm.DB, tag *dbr.Tag) (*dbr.Tag, error) {
t, err := tag.Get(db)
if err != nil {
tag.QuoteNum = 1
return tag.Create(db)
}
// 更新
t.QuoteNum++
err = t.Update(db)
if err != nil {
return nil, err
func createTags(db *gorm.DB, userId int64, tags []string) (res cs.TagInfoList, err error) {
for _, name := range tags {
tag := &dbr.Tag{Tag: name}
if tag, err = tag.Get(db); err == nil {
// 更新
tag.QuoteNum++
if err = tag.Update(db); err != nil {
return
}
} else {
if tag, err = (&dbr.Tag{
UserID: userId,
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 t, nil
return
}
func deleteTag(db *gorm.DB, tag *dbr.Tag) error {
tag, err := tag.Get(db)
if err != nil {
return err
func decrTagsByIds(db *gorm.DB, ids []int64) (err error) {
for _, id := range ids {
tag := &dbr.Tag{Model: &dbr.Model{ID: id}}
if tag, err = tag.Get(db); err == nil {
tag.QuoteNum--
if err = tag.Update(db); err != nil {
return
}
} else {
continue
}
}
tag.QuoteNum--
return tag.Update(db)
return nil
}
func deleteTags(db *gorm.DB, tags []string) error {

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

@ -8,6 +8,7 @@ import (
"time"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/sirupsen/logrus"
)
@ -46,7 +47,7 @@ func (s *bridgeTweetSearchServant) DeleteDocuments(identifiers []string) error {
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)
}

@ -6,6 +6,7 @@ package search
import (
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/pkg/types"
)
@ -13,13 +14,13 @@ type tweetSearchFilter struct {
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 {
return
}
var item *core.PostFormated
var item *ms.PostFormated
items := resp.Items
latestIndex := len(items) - 1
if user == nil {

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

@ -9,6 +9,7 @@ import (
"github.com/Masterminds/semver/v3"
"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/zinc"
"github.com/sirupsen/logrus"
@ -76,7 +77,7 @@ func (s *zincTweetSearchServant) DeleteDocuments(identifiers []string) error {
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 != "" {
resp, err = s.queryByContent(user, q, offset, limit)
} else if q.Type == core.SearchTypeTag && q.Query != "" {
@ -94,7 +95,7 @@ func (s *zincTweetSearchServant) Search(user *core.User, q *core.QueryReq, offse
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{
"query": 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)
}
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{
"search_type": "querystring",
"query": map[string]any{
@ -127,7 +128,7 @@ func (s *zincTweetSearchServant) queryByTag(user *core.User, q *core.QueryReq, o
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{
"query": map[string]any{
"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) {
posts := make([]*core.PostFormated, 0, len(resp.Hits.Hits))
posts := make([]*ms.PostFormated, 0, len(resp.Hits.Hits))
for _, hit := range resp.Hits.Hits {
item := &core.PostFormated{}
item := &ms.PostFormated{}
raw, err := json.Marshal(hit.Source)
if err != nil {
return nil, err

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

@ -42,9 +42,9 @@ func Run() {
db, err = sql.Open("mysql", conf.MysqlSetting.Dsn()+"&multiStatements=true")
} else if cfg.If("PostgreSQL") || cfg.If("Postgres") {
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") {
db, err = conf.OpenSqlite3()
_, db, err = conf.OpenSqlite3()
} else {
dbName = conf.MysqlSetting.DBName
db, err = sql.Open("mysql", conf.MysqlSetting.Dsn())

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

@ -12,6 +12,7 @@ import (
"github.com/alimy/mir/v4"
"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/pkg/convert"
"github.com/rocboss/paopao-ce/pkg/xerror"
@ -31,9 +32,9 @@ type TweetReplyThumbsReq struct {
}
type PostContentItem struct {
Content string `json:"content" binding:"required"`
Type core.PostContentT `json:"type" binding:"required"`
Sort int64 `json:"sort" binding:"required"`
Content string `json:"content" binding:"required"`
Type ms.PostContentT `json:"type" binding:"required"`
Sort int64 `json:"sort" binding:"required"`
}
type CreateTweetReq struct {
@ -46,7 +47,7 @@ type CreateTweetReq struct {
ClientIP string `json:"-" binding:"-"`
}
type CreateTweetResp core.PostFormated
type CreateTweetResp ms.PostFormated
type DeleteTweetReq struct {
BaseInfo `json:"-" binding:"-"`
@ -85,10 +86,19 @@ type StickTweetReq struct {
ID int64 `json:"id" binding:"required"`
}
type HighlightTweetReq struct {
BaseInfo `json:"-" binding:"-"`
ID int64 `json:"id" binding:"required"`
}
type StickTweetResp struct {
StickStatus int `json:"top_status"`
}
type HighlightTweetResp struct {
HighlightStatus int `json:"highlight_status"`
}
type VisibleTweetReq struct {
BaseInfo `json:"-" binding:"-"`
ID int64 `json:"id"`
@ -107,7 +117,7 @@ type CreateCommentReq struct {
ClientIP string `json:"-" binding:"-"`
}
type CreateCommentResp core.Comment
type CreateCommentResp ms.Comment
type CreateCommentReplyReq struct {
SimpleInfo `json:"-" binding:"-"`
@ -117,7 +127,7 @@ type CreateCommentReplyReq struct {
ClientIP string `json:"-" binding:"-"`
}
type CreateCommentReplyResp core.CommentReply
type CreateCommentReplyResp ms.CommentReply
type DeleteCommentReq struct {
BaseInfo `json:"-" binding:"-"`
@ -138,12 +148,12 @@ type UploadAttachmentReq struct {
}
type UploadAttachmentResp struct {
UserID int64 `json:"user_id"`
FileSize int64 `json:"file_size"`
ImgWidth int `json:"img_width"`
ImgHeight int `json:"img_height"`
Type core.AttachmentType `json:"type"`
Content string `json:"content"`
UserID int64 `json:"user_id"`
FileSize int64 `json:"file_size"`
ImgWidth int `json:"img_width"`
ImgHeight int `json:"img_height"`
Type ms.AttachmentType `json:"type"`
Content string `json:"content"`
}
type DownloadAttachmentPrecheckReq struct {
@ -186,13 +196,13 @@ type UnfollowTopicReq struct {
// Check 检查PostContentItem属性
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 {
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 {
return fmt.Errorf("链接不合法")
}

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

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

@ -17,6 +17,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/conf"
"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/cache"
"github.com/rocboss/paopao-ce/pkg/app"
@ -31,6 +32,7 @@ type BaseServant struct {
type DaoServant struct {
*BaseServant
Dsa core.WebDataServantA
Ds core.DataService
Ts core.TweetSearchService
Redis core.RedisCache
@ -47,7 +49,7 @@ type SentryHubSetter interface {
}
type UserSetter interface {
SetUser(*core.User)
SetUser(*ms.User)
}
type UserIdSetter interface {
@ -58,9 +60,9 @@ type PageInfoSetter interface {
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 {
user, ok := u.(*core.User)
user, ok := u.(*ms.User)
return user, ok
}
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)
if err != nil {
return nil, err
@ -205,20 +207,21 @@ func (s *DaoServant) PushPostsToSearch(c context.Context) {
defer s.Redis.DelPushToSearchJob(c)
splitNum := 1000
totalRows, _ := s.Ds.GetPostCount(&core.ConditionsT{
conditions := ms.ConditionsT{
"visibility IN ?": []core.PostVisibleT{core.PostVisitPublic, core.PostVisitFriend},
})
}
totalRows, _ := s.Ds.GetPostCount(conditions)
pages := math.Ceil(float64(totalRows) / float64(splitNum))
nums := int(pages)
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) {
continue
}
for i, pf := range postsFormated {
contentFormated := ""
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"
}
}
@ -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.User = &core.UserFormated{
postFormated.User = &ms.UserFormated{
ID: post.UserID,
}
contents, _ := s.Ds.GetPostContentsByIDs([]int64{post.ID})
@ -246,7 +249,7 @@ func (s *DaoServant) PushPostToSearch(post *core.Post) {
contentFormated := ""
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"
}
}
@ -258,11 +261,11 @@ func (s *DaoServant) PushPostToSearch(post *core.Post) {
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)})
}
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)
if err != nil {
return nil, nil, err
@ -288,6 +291,7 @@ func NewDaoServant() *DaoServant {
return &DaoServant{
BaseServant: NewBaseServant(),
Redis: cache.NewRedisCache(),
Dsa: dao.WebDataServantA(),
Ds: dao.DataService(),
Ts: dao.TweetSearchService(),
}

@ -6,15 +6,15 @@ package chain
import (
"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"
)
func Admin() gin.HandlerFunc {
return func(c *gin.Context) {
if user, exist := c.Get("USER"); exist {
if userModel, ok := user.(*core.User); ok {
if userModel.Status == core.UserStatusNormal && userModel.IsAdmin {
if userModel, ok := user.(*ms.User); ok {
if userModel.Status == ms.UserStatusNormal && userModel.IsAdmin {
c.Next()
return
}

@ -7,7 +7,7 @@ package chain
import (
"github.com/alimy/cfg"
"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"
)
@ -15,8 +15,8 @@ func Priv() gin.HandlerFunc {
if cfg.If("PhoneBind") {
return func(c *gin.Context) {
if u, exist := c.Get("USER"); exist {
if user, ok := u.(*core.User); ok {
if user.Status == core.UserStatusNormal {
if user, ok := u.(*ms.User); ok {
if user.Status == ms.UserStatusNormal {
if user.Phone == "" {
response := app.NewResponse(c)
response.ToErrorResponse(_errAccountNoPhoneBind)
@ -35,7 +35,7 @@ func Priv() gin.HandlerFunc {
} else {
return func(c *gin.Context) {
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()
return
}

@ -14,6 +14,7 @@ import (
"github.com/gin-gonic/gin"
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/servants/base"
"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) {
conditions := &core.ConditionsT{
conditions := &ms.ConditionsT{
"receiver_user_id": req.UserId,
"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
}
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,
ReceiverUserID: req.UserID,
Type: core.MsgTypeWhisper,
Type: ms.MsgTypeWhisper,
Brief: "给你发送新私信了",
Content: req.Content,
})
@ -187,7 +188,7 @@ func (s *coreSrv) GetCollections(req *web.GetCollectionsReq) (*web.GetCollection
return nil, web.ErrGetCollectionsFailed
}
var posts []*core.Post
var posts []*ms.Post
for _, collection := range collections {
posts = append(posts, collection.Post)
}
@ -250,7 +251,7 @@ func (s *coreSrv) GetStars(req *web.GetStarsReq) (*web.GetStarsResp, mir.Error)
return nil, web.ErrGetStarsFailed
}
var posts []*core.Post
var posts []*ms.Post
for _, star := range stars {
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) {
tags, err := s.Ds.GetTagsByKeyword(req.Keyword)
tags, err := s.Ds.TagsByKeyword(req.Keyword)
if err != nil {
logrus.Errorf("Ds.GetTagsByKeyword err: %s", err)
return nil, xerror.ServerError

@ -10,6 +10,7 @@ import (
api "github.com/rocboss/paopao-ce/auto/api/v1"
"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/model/web"
"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 {
case web.UserPostsStyleComment:
res, err = s.getUserCommentTweets(req, isSelf)
case web.UserPostsStyleHighlight:
res, err = s.getUserHighlightTweets(req, isSelf)
case web.UserPostsStyleMedia:
res, err = s.getUserMediaTweets(req, isSelf)
case web.UserPostsStyleStar:
@ -83,6 +86,12 @@ func (s *looseSrv) getUserCommentTweets(req *web.GetUserTweetsReq, isSelf bool)
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) {
// TODO: add implement logic
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)
return nil, web.ErrGetStarsFailed
}
var posts []*core.Post
var posts []*ms.Post
for _, star := range stars {
posts = append(posts, star.Post)
}
@ -151,7 +160,7 @@ func (s *looseSrv) getUserPostTweets(req *web.GetUserTweetsReq) (*web.GetUserTwe
visibilities = append(visibilities, core.PostVisitFriend)
}
}
conditions := &core.ConditionsT{
conditions := ms.ConditionsT{
"user_id": other.ID,
"visibility IN ?": visibilities,
"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) {
var (
tags, extralTags []*core.TagFormated
tags, extralTags cs.TagList
err error
)
num := req.Num
@ -236,7 +245,7 @@ func (s *looseSrv) TweetComments(req *web.TweetCommentsReq) (*web.TweetCommentsR
if req.SortStrategy == "newest" {
sort = "id DESC"
}
conditions := &core.ConditionsT{
conditions := &ms.ConditionsT{
"post_id": req.TweetId,
"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 {
commentFormated := comment.Format()
if thumbs, exist := commentThumbs[comment.ID]; exist {

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

@ -17,7 +17,7 @@ import (
"github.com/alimy/mir/v4"
"github.com/gofrs/uuid/v5"
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/servants/base"
"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
}
password, salt := encryptPasswordAndSalt(req.Password)
//password, salt := encryptPasswordAndSalt(req.Password, req.Username)
user := &core.User{
user := &ms.User{
Nickname: req.Username,
Username: req.Username,
Password: password,
Avatar: getRandomAvatar(),
Salt: salt,
Status: core.UserStatusNormal,
Status: ms.UserStatusNormal,
}
user, err := s.Ds.CreateUser(user)
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 user.Status == core.UserStatusClosed {
if user.Status == ms.UserStatusClosed {
return nil, web.ErrUserHasBeenBanned
}
// 清空登录计数

@ -14,6 +14,7 @@ import (
"github.com/alimy/mir/v4"
"github.com/gofrs/uuid/v5"
"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/pkg/utils"
"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))
for _, item := range contents {
switch item.Type {
case core.ContentTypeImage,
core.ContentTypeVideo,
core.ContentTypeAudio,
core.ContentTypeAttachment,
core.ContentTypeChargeAttachment:
case ms.ContentTypeImage,
ms.ContentTypeVideo,
ms.ContentTypeAudio,
ms.ContentTypeAttachment,
ms.ContentTypeChargeAttachment:
items = append(items, item.Content)
if err != nil {
continue
@ -201,7 +202,7 @@ func tagsFrom(originTags []string) []string {
}
// 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) {
return web.ErrNoPermission
}

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

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

@ -9,7 +9,7 @@ import (
"github.com/golang-jwt/jwt/v4"
"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 {
@ -22,7 +22,7 @@ func GetJWTSecret() []byte {
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)
claims := Claims{
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))
}
})
})

@ -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