更新泡泡作者新增内容,即新增好友条栏,优化推文创建逻辑。优化私信(已隐藏)

pull/406/head
HXY 2 years ago
commit eb24396c6d

1
.gitignore vendored

@ -12,3 +12,4 @@ __debug_bin
/data
/custom
/.custom
/run.sh

@ -21,6 +21,19 @@ All notable changes to paopao-ce are documented in this file.
MaxLogBuffer: 100 # 最大log缓存条数, 设置范围[10, 10000], 默认100
...
```
- Added friend tweets bar feature support in home page. [#377](https://github.com/rocboss/paopao-ce/pull/377)
- web: add custom `Friendship` feature support. To custom setup `Friendship` use below configure in `web/.env` or `web/.env.local`
```
# 功能特性开启
VITE_USE_FRIENDSHIP=true
# 模块开启
VITE_ENABLE_FRIENDS_BAR=true
```
## 0.4.2
### Fixed
- fixed remove multi-objects no effects and occurs resource leak error when use Minio as OSS(Object Storage System).[#371](https://github.com/rocboss/paopao-ce/pull/371) [#372](https://github.com/rocboss/paopao-ce/pull/372)
## 0.4.1
### Changed

@ -39,7 +39,7 @@ Web端
更多演示请前往[官网](https://www.paopao.info)体验(谢绝灌水)
桌面端:
![](docs/proposal/.assets/000-00.png)
![](docs/proposal/.assets/000-00.jpg)
<p align="right">(<a href="#top">back to top</a>)</p>

@ -31,7 +31,6 @@ type Core interface {
SendUserWhisper(*web.SendWhisperReq) mir.Error
ReadMessage(*web.ReadMessageReq) mir.Error
GetMessages(*web.GetMessagesReq) (*web.GetMessagesResp, mir.Error)
GetUnreadMsgCount(*web.GetUnreadMsgCountReq) (*web.GetUnreadMsgCountResp, mir.Error)
GetUserInfo(*web.UserInfoReq) (*web.UserInfoResp, mir.Error)
SyncSearchIndex(*web.SyncSearchIndexReq) mir.Error
@ -229,20 +228,6 @@ func RegisterCoreServant(e *gin.Engine, s Core) {
resp, err := s.GetMessages(req)
s.Render(c, resp, err)
})
router.Handle("GET", "/user/msgcount/unread", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req := new(web.GetUnreadMsgCountReq)
if err := s.Bind(c, req); err != nil {
s.Render(c, nil, err)
return
}
resp, err := s.GetUnreadMsgCount(req)
s.Render(c, resp, err)
})
router.Handle("GET", "/user/info", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
@ -332,10 +317,6 @@ func (UnimplementedCoreServant) GetMessages(req *web.GetMessagesReq) (*web.GetMe
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedCoreServant) GetUnreadMsgCount(req *web.GetUnreadMsgCountReq) (*web.GetUnreadMsgCountResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedCoreServant) GetUserInfo(req *web.UserInfoReq) (*web.UserInfoResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}

@ -0,0 +1,66 @@
// Code generated by go-mir. DO NOT EDIT.
// versions:
// - mir v4.0.0
package v1
import (
"net/http"
"github.com/alimy/mir/v4"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/model/web"
)
type Relax interface {
_default_
// Chain provide handlers chain for gin
Chain() gin.HandlersChain
GetUnreadMsgCount(*web.GetUnreadMsgCountReq) (*web.GetUnreadMsgCountResp, mir.Error)
mustEmbedUnimplementedRelaxServant()
}
// RegisterRelaxServant register Relax servant to gin
func RegisterRelaxServant(e *gin.Engine, s Relax) {
router := e.Group("v1")
// use chain for router
middlewares := s.Chain()
router.Use(middlewares...)
// register routes info to router
router.Handle("GET", "/user/msgcount/unread", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req := new(web.GetUnreadMsgCountReq)
if err := s.Bind(c, req); err != nil {
s.Render(c, nil, err)
return
}
resp, err := s.GetUnreadMsgCount(req)
if err != nil {
s.Render(c, nil, err)
return
}
var rv _render_ = resp
rv.Render(c)
})
}
// UnimplementedRelaxServant can be embedded to have forward compatible implementations.
type UnimplementedRelaxServant struct{}
func (UnimplementedRelaxServant) Chain() gin.HandlersChain {
return nil
}
func (UnimplementedRelaxServant) GetUnreadMsgCount(req *web.GetUnreadMsgCountReq) (*web.GetUnreadMsgCountResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedRelaxServant) mustEmbedUnimplementedRelaxServant() {}

@ -51,20 +51,20 @@ services:
networks:
- paopao-network
zinc:
image: bitbus/zincsearch:latest
user: zincsearch
restart: always
ports:
- 4080:4080
volumes:
- ./custom/data/zinc/data:/data
environment:
ZINC_FIRST_ADMIN_USER: admin
ZINC_FIRST_ADMIN_PASSWORD: admin
DATA_PATH: /data
networks:
- paopao-network
# zinc:
# image: bitbus/zincsearch:latest
# user: zincsearch
# restart: always
# ports:
# - 4080:4080
# volumes:
# - ./custom/data/zinc/data:/data
# environment:
# ZINC_FIRST_ADMIN_USER: admin
# ZINC_FIRST_ADMIN_PASSWORD: admin
# DATA_PATH: /data
# networks:
# - paopao-network
meili:
image: getmeili/meilisearch:v1.3
@ -78,6 +78,14 @@ services:
networks:
- paopao-network
meilisearch-ui:
image: riccoxie/meilisearch-ui:latest
restart: always
ports:
- 24900:24900
networks:
- paopao-network
# openobserve:
# image: public.ecr.aws/zinclabs/openobserve:latest
# restart: always
@ -102,18 +110,18 @@ services:
# networks:
# - paopao-network
phpmyadmin:
image: phpmyadmin:5.2
depends_on:
- db
ports:
- 8080:80
environment:
- PMA_HOST=db
- PMA_USER=paopao
- PMA_PASSWORD=paopao
networks:
- paopao-network
# phpmyadmin:
# image: phpmyadmin:5.2
# depends_on:
# - db
# ports:
# - 8080:80
# environment:
# - PMA_HOST=db
# - PMA_USER=paopao
# - PMA_PASSWORD=paopao
# networks:
# - paopao-network
backend:
image: bitbus/paopao-ce:nightly

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 KiB

@ -6,39 +6,42 @@ require (
github.com/Masterminds/semver/v3 v3.2.1
github.com/afocus/captcha v0.0.0-20191010092841-4bd1f21c8868
github.com/alimy/mir/v4 v4.0.0
github.com/alimy/tryst v0.3.0
github.com/aliyun/aliyun-oss-go-sdk v2.2.8+incompatible
github.com/alimy/tryst v0.8.2
github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible
github.com/allegro/bigcache/v3 v3.1.0
github.com/bufbuild/connect-go v1.10.0
github.com/bytedance/sonic v1.10.0
github.com/cockroachdb/errors v1.10.0
github.com/cockroachdb/errors v1.11.1
github.com/disintegration/imaging v1.6.2
github.com/fatih/color v1.15.0
github.com/getsentry/sentry-go v0.23.0
github.com/getsentry/sentry-go v0.24.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
github.com/goccy/go-json v0.10.2
github.com/gofrs/uuid/v5 v5.0.0
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/golang-jwt/jwt/v5 v5.0.0
github.com/golang-migrate/migrate/v4 v4.15.2
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
github.com/huaweicloud/huaweicloud-sdk-go-obs v3.23.4+incompatible
github.com/json-iterator/go v1.1.12
github.com/meilisearch/meilisearch-go v0.25.0
github.com/minio/minio-go/v7 v7.0.62
github.com/onsi/ginkgo/v2 v2.11.0
github.com/minio/minio-go/v7 v7.0.63
github.com/onsi/ginkgo/v2 v2.12.0
github.com/onsi/gomega v1.27.10
github.com/pyroscope-io/client v0.7.2
github.com/redis/rueidis v1.0.15
github.com/redis/rueidis v1.0.17
github.com/robfig/cron/v3 v3.0.1
github.com/sirupsen/logrus v1.9.3
github.com/smartwalle/alipay/v3 v3.2.15
github.com/smartwalle/alipay/v3 v3.2.16
github.com/sourcegraph/conc v0.3.0
github.com/spf13/cobra v1.7.0
github.com/spf13/viper v1.16.0
github.com/tencentyun/cos-go-sdk-v5 v0.7.42
github.com/tencentyun/cos-go-sdk-v5 v0.7.43
github.com/yinheli/mahonia v0.0.0-20131226213531-0eef680515cc
go.uber.org/automaxprocs v1.5.3
google.golang.org/grpc v1.57.0
golang.org/x/image v0.0.0-20210216034530-4410531fe030
google.golang.org/grpc v1.58.0
google.golang.org/protobuf v1.31.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1
gopkg.in/resty.v1 v1.12.0
@ -69,7 +72,7 @@ require (
github.com/go-sql-driver/mysql v1.7.0 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/go-querystring v1.1.0 // indirect
@ -77,6 +80,7 @@ require (
github.com/google/uuid v1.3.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.6 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
@ -109,8 +113,8 @@ require (
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rogpeppe/go-internal v1.9.0 // indirect
github.com/rs/xid v1.5.0 // indirect
github.com/smartwalle/ncrypto v1.0.2 // indirect
github.com/smartwalle/ngx v1.0.6 // indirect
github.com/smartwalle/ncrypto v1.0.3 // indirect
github.com/smartwalle/ngx v1.0.7 // indirect
github.com/smartwalle/nsign v1.0.8 // indirect
github.com/spf13/afero v1.9.5 // indirect
github.com/spf13/cast v1.5.1 // indirect
@ -124,14 +128,13 @@ require (
go.uber.org/atomic v1.9.0 // indirect
golang.org/x/arch v0.3.0 // indirect
golang.org/x/crypto v0.12.0 // indirect
golang.org/x/image v0.0.0-20210216034530-4410531fe030 // indirect
golang.org/x/mod v0.10.0 // indirect
golang.org/x/mod v0.12.0 // indirect
golang.org/x/net v0.14.0 // indirect
golang.org/x/sys v0.11.0 // indirect
golang.org/x/text v0.12.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.9.3 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect
golang.org/x/tools v0.12.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
lukechampine.com/uint128 v1.2.0 // indirect

@ -125,10 +125,10 @@ github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:C
github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY9UnI16Z+UJqRyk=
github.com/alimy/mir/v4 v4.0.0 h1:MzGfmoLjjvR69jbZEmpKJO3tUuqB0RGRv1UWPbtukBg=
github.com/alimy/mir/v4 v4.0.0/go.mod h1:d58dBvw2KImcVbAUANrciEV/of0arMNsI9c/5UNCMMc=
github.com/alimy/tryst v0.3.0 h1:8oeKy8iQQnO6BCs0YGJBnVyVxi6Y3w18n5Xz/uefUtk=
github.com/alimy/tryst v0.3.0/go.mod h1:K//dPeoE/nnv2Jw8C3iPE7n8mO6LVqAxVmqbopM9nAk=
github.com/aliyun/aliyun-oss-go-sdk v2.2.8+incompatible h1:6JF1bjhT0WN2srEmijfOFtVWwV91KZ6dJY1/JbdtGrI=
github.com/aliyun/aliyun-oss-go-sdk v2.2.8+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
github.com/alimy/tryst v0.8.2 h1:azu5B58vS6m/ZeHovYGWjVvEOJN2llDIBLxuN3qtMtk=
github.com/alimy/tryst v0.8.2/go.mod h1:ua2eJbFrisHPh7z93Bgc0jNBE8Khu1SCx2p/6t3OzZI=
github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible h1:Sg/2xHwDrioHpxTN6WMiwbXTpUEinBpHsN7mG21Rc2k=
github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
github.com/allegro/bigcache/v3 v3.1.0 h1:H2Vp8VOvxcrB91o86fUSVJFqeuz8kpyyB02eH3bSzwk=
github.com/allegro/bigcache/v3 v3.1.0/go.mod h1:aPyh7jEvrog9zAwx5N7+JUQX5dZTSGpxF1LAR4dr35I=
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
@ -243,8 +243,8 @@ github.com/cockroachdb/cockroach-go/v2 v2.1.1/go.mod h1:7NtUnP6eK+l6k483WSYNrq3K
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo=
github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=
github.com/cockroachdb/errors v1.10.0 h1:lfxS8zZz1+OjtV4MtNWgboi/W5tyLEB6VQZBXN+0VUU=
github.com/cockroachdb/errors v1.10.0/go.mod h1:lknhIsEVQ9Ss/qKDBQS/UqFSvPQjOwNq2qyKAxtHRqE=
github.com/cockroachdb/errors v1.11.1 h1:xSEW75zKaKCWzR3OfxXUxgrk/NtT4G1MiOv5lWZazG8=
github.com/cockroachdb/errors v1.11.1/go.mod h1:8MUxA3Gi6b25tYlFEBGLf+D8aISL+M4MIpiWMSNRfxw=
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE=
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs=
@ -456,8 +456,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.23.0 h1:dn+QRCeJv4pPt9OjVXiMcGIBIefaTJPw/h0bZWO05nE=
github.com/getsentry/sentry-go v0.23.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
github.com/getsentry/sentry-go v0.24.0 h1:02b7qEmJ56EHGe9KFgjArjU/vG/aywm7Efgu+iPc01Y=
github.com/getsentry/sentry-go v0.24.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=
@ -581,6 +581,8 @@ github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzw
github.com/golang-jwt/jwt/v4 v4.1.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang-migrate/migrate/v4 v4.15.2 h1:vU+M05vs6jWHKDdmE1Ecwj0BznygFc4QsdRe2E/L7kc=
github.com/golang-migrate/migrate/v4 v4.15.2/go.mod h1:f2toGLkYqD3JH+Todi4aZ2ZdbeUNx4sIwiOK96rE9Lw=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
@ -727,6 +729,8 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru/v2 v2.0.6 h1:3xi/Cafd1NaoEnS/yDssIiuVeDVywU0QdFGl3aQaQHM=
github.com/hashicorp/golang-lru/v2 v2.0.6/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
@ -939,8 +943,8 @@ github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
github.com/minio/minio-go/v7 v7.0.62 h1:qNYsFZHEzl+NfH8UxW4jpmlKav1qUAgfY30YNRneVhc=
github.com/minio/minio-go/v7 v7.0.62/go.mod h1:Q6X7Qjb7WMhvG65qKf4gUgA5XaiSox74kR1uAEjxRS4=
github.com/minio/minio-go/v7 v7.0.63 h1:GbZ2oCvaUdgT5640WJOpyDhhDxvknAJU2/T3yurwcbQ=
github.com/minio/minio-go/v7 v7.0.63/go.mod h1:Q6X7Qjb7WMhvG65qKf4gUgA5XaiSox74kR1uAEjxRS4=
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
@ -1008,8 +1012,8 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108
github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0=
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
github.com/onsi/ginkgo/v2 v2.12.0 h1:UIVDowFPwpg6yMUpPjGkYvf06K3RAiJXUhCxEwQVHRI=
github.com/onsi/ginkgo/v2 v2.12.0/go.mod h1:ZNEzXISYlqpb8S36iN71ifqLi3vVD1rVJGvWRCJOUpQ=
github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
@ -1117,12 +1121,14 @@ github.com/pyroscope-io/client v0.7.2 h1:OX2qdUQsS8RSkn/3C8isD7f/P0YiZQlRbAlecAa
github.com/pyroscope-io/client v0.7.2/go.mod h1:FEocnjn+Ngzxy6EtU9ZxXWRvQ0+pffkrBxHLnPpxwi8=
github.com/pyroscope-io/godeltaprof v0.1.2 h1:MdlEmYELd5w+lvIzmZvXGNMVzW2Qc9jDMuJaPOR75g4=
github.com/pyroscope-io/godeltaprof v0.1.2/go.mod h1:psMITXp90+8pFenXkKIpNhrfmI9saQnPbba27VIaiQE=
github.com/redis/rueidis v1.0.15 h1:KjTaoP4ab6lpxyCwgIEZ3/rqvKfKnbICe83tVaaItxQ=
github.com/redis/rueidis v1.0.15/go.mod h1:8B+r5wdnjwK3lTFml5VtxjzGOQAC+5UmujoD12pDrEo=
github.com/redis/rueidis v1.0.17 h1:RyjiBVnPcKxjgiUpkyqbRw/OFJV5vX2bMM/oMPdz8JE=
github.com/redis/rueidis v1.0.17/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=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
@ -1164,12 +1170,12 @@ github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/smartwalle/alipay/v3 v3.2.15 h1:3fvFJnINKKAOXHR/Iv20k1Z7KJ+nOh3oK214lELPqG8=
github.com/smartwalle/alipay/v3 v3.2.15/go.mod h1:niTNB609KyUYuAx9Bex/MawEjv2yPx4XOjxSAkqmGjE=
github.com/smartwalle/ncrypto v1.0.2 h1:pTAhCqtPCMhpOwFXX+EcMdR6PNzruBNoGQrN2S1GbGI=
github.com/smartwalle/ncrypto v1.0.2/go.mod h1:Dwlp6sfeNaPMnOxMNayMTacvC5JGEVln3CVdiVDgbBk=
github.com/smartwalle/ngx v1.0.6 h1:JPNqNOIj+2nxxFtrSkJO+vKJfeNUSEQueck/Wworjps=
github.com/smartwalle/ngx v1.0.6/go.mod h1:mx/nz2Pk5j+RBs7t6u6k22MPiBG/8CtOMpCnALIG8Y0=
github.com/smartwalle/alipay/v3 v3.2.16 h1:oSzcQgV+kUHH7ko7FjYowU4RIm6chuQjgXeuChUbj0M=
github.com/smartwalle/alipay/v3 v3.2.16/go.mod h1:5EC6QZNr51TjmDAJFHSEJMLLSoTtge7583W2vuNmOYc=
github.com/smartwalle/ncrypto v1.0.3 h1:fnzjoriZt2LZeD8ljEtRe2eU33Au7i8vIF4Gafz5RuI=
github.com/smartwalle/ncrypto v1.0.3/go.mod h1:Dwlp6sfeNaPMnOxMNayMTacvC5JGEVln3CVdiVDgbBk=
github.com/smartwalle/ngx v1.0.7 h1:BIQo6wmAnERehogNKUnthoxwBavTWxbR9oLFcGjWXKQ=
github.com/smartwalle/ngx v1.0.7/go.mod h1:mx/nz2Pk5j+RBs7t6u6k22MPiBG/8CtOMpCnALIG8Y0=
github.com/smartwalle/nsign v1.0.8 h1:78KWtwKPrdt4Xsn+tNEBVxaTLIJBX9YRX0ZSrMUeuHo=
github.com/smartwalle/nsign v1.0.8/go.mod h1:eY6I4CJlyNdVMP+t6z1H6Jpd4m5/V+8xi44ufSTxXgc=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
@ -1239,8 +1245,8 @@ github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG
github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.563/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms v1.0.563/go.mod h1:uom4Nvi9W+Qkom0exYiJ9VWJjXwyxtPYTkKkaLMlfE0=
github.com/tencentyun/cos-go-sdk-v5 v0.7.42 h1:Up1704BJjI5orycXKjpVpvuOInt9GC5pqY4knyE9Uds=
github.com/tencentyun/cos-go-sdk-v5 v0.7.42/go.mod h1:LUFnaqRmGk6pEHOaRmdn2dCZR2j0cSsM5xowWFPTPao=
github.com/tencentyun/cos-go-sdk-v5 v0.7.43 h1:aPCPWy85T3C3Ga3hn7va2DC4c0hAf8Dx0kpKj/uB/vw=
github.com/tencentyun/cos-go-sdk-v5 v0.7.43/go.mod h1:LUFnaqRmGk6pEHOaRmdn2dCZR2j0cSsM5xowWFPTPao=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
@ -1436,8 +1442,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -1538,7 +1544,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sys v0.0.0-20180224232135-f6cff0780e54/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -1774,8 +1780,8 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM=
golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss=
golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM=
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -1902,8 +1908,8 @@ google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ6
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20220111164026-67b88f271998/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 h1:0nDDozoAU19Qb2HwhXadU8OcsiO/09cnTqhUtq2MEOM=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
@ -1937,8 +1943,8 @@ google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9K
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw=
google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo=
google.golang.org/grpc v1.58.0 h1:32JY8YpPMSR45K+c3o6b8VL73V+rR8k+DeMIr4vRH8o=
google.golang.org/grpc v1.58.0/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=

@ -0,0 +1,30 @@
// 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 (
"fmt"
"github.com/alimy/tryst/cache"
)
const (
_defaultKeyPoolSize = 128
)
// 以下包含一些在cache中会用到的池化后的key
var (
KeyUnreadMsg cache.KeyPool[int64]
)
func initCacheKeyPool() {
poolSize := _defaultKeyPoolSize
if poolSize < CacheSetting.KeyPoolSize {
poolSize = CacheSetting.KeyPoolSize
}
KeyUnreadMsg = cache.MustKeyPool[int64](poolSize, func(key int64) string {
return fmt.Sprintf("paopao:unreadmsg:%d", key)
})
}

@ -29,6 +29,8 @@ func MustRedisClient() rueidis.Client {
log.Fatalf("create a redis client failed: %s", err)
}
_redisClient = client
// 顺便初始化一下CacheKeyPool
initCacheKeyPool()
})
return _redisClient
}

@ -35,6 +35,8 @@ var (
DocsServerSetting *httpServerConf
MobileServerSetting *grpcServerConf
AppSetting *appConf
CacheSetting *cacheConf
EventManagerSetting *eventManagerConf
CacheIndexSetting *cacheIndexConf
SimpleCacheIndexSetting *simpleCacheIndexConf
BigCacheIndexSetting *bigCacheIndexConf
@ -69,6 +71,8 @@ func setupSetting(suite []string, noDefault bool) error {
objects := map[string]any{
"App": &AppSetting,
"Cache": &CacheSetting,
"EventManager": &EventManagerSetting,
"PprofServer": &PprofServerSetting,
"WebServer": &WebServerSetting,
"AdminServer": &AdminServerSetting,
@ -115,6 +119,8 @@ func setupSetting(suite []string, noDefault bool) error {
}
}
CacheSetting.CientSideCacheExpire *= time.Second
EventManagerSetting.TickWaitTime *= time.Second
JWTSetting.Expire *= time.Second
SimpleCacheIndexSetting.CheckTickDuration *= time.Second
SimpleCacheIndexSetting.ExpireTickDuration *= time.Second

@ -5,6 +5,16 @@ App: # APP基础设置项
DefaultContextTimeout: 60
DefaultPageSize: 10
MaxPageSize: 100
Cache:
KeyPoolSize: 256 # 键的池大小, 设置范围[128, ++], 默认256
CientSideCacheExpire: 60 # 客户端缓存过期时间 默认60s
UnreadMsgExpire: 60 # 未读消息过期时间,单位秒, 默认60s
EventManager: # 事件管理器的配置参数
MinWorker: 10 # 最小后台工作者, 设置范围[5, ++], 默认10
MaxEventBuf: 100 # 最大log缓存条数, 设置范围[10, ++], 默认100
MaxTempEventBuf: 100 # 最大log缓存条数, 设置范围[10, ++], 默认100
MaxTickCount: 60 # 最大的循环周期, 设置范围[60, ++], 默认60
TickWaitTime: 1 # 一个周期的等待时间,单位:秒 默认1s
Features:
Default: []
WebServer: # Web服务
@ -64,8 +74,9 @@ SmsJuhe:
TplID:
TplVal: "#code#=%s&#m#=%d"
Alipay:
AppID:
AppID: "paopao-ce-app-id"
InProduction: True
PrivateKey: "MIICXAIBAAKBgQCzXV/spaX9+eOjM5f12W6eDTtszU9f9rgpXG4EQwzZI3WM5+Fe+9Bn6NQQILfF1o3Z+3BEzHMMcYwxrQw/toq2o6JPchbUK7eArKc6pl/GV3uIefZdKncz5bZvCFMgiJrpy75lYKhJgotQFEfQd+ks2t0gtC007uOjmY9QDB2EVQIDAQABAoGAMruhi0UbW2gYHCxWuiJDKI9jlJXJ8sHNO126fJgehTiDYlSgKYaeXxW7DcjDUkEqpFJ7YepWTFm9prtksIzIVQFNNjstI6cvowVF2t+lWf7mIB4w0ugarVd+SXssQK830Og3kjtZ84a3BbC6uf3a/qcgoIO8Sj1VnzOJ8fEYl+0CQQDeG6JhauGDOC8oCTwbFs9QPpjwGnp7UkYAJNg7jn4uBSVeg4lwb5uj9TshLSp49geNkPcWeCythuiz1jvoTqEjAkEAzrwIBxUPT1WmcDUXAkVPaQNADDbhMZLdw5nHZEUVwmO3o1FkJky4MLjLjT977400mhsnsQCy4sAWUZs6aEyoJwJARK3U2zy6eOHhqwaYAGRgPJbuoaf+Ya3CGX9LIbdhCwfqUzxnPk40mVFWNF8L+BVTppHB5b/JSOsjf6BqK95McwJBAL+kvUhbdHrV6lmgTXkUaV3u3mO0SCPdgui9WIKSLG6sY+LpI48BlcnMtR12WVyjKL0nKS9Dd5EOAmKaJJXlYgcCQGWbWCn9KUDUqpm4o3wr5nwXzlS74XYZo65UAM7TSzHRpcovfv5uiQ0VRLImWeiSXKK2aTOBGn5eKbevRTxN07k="
RootCertFile: "custom/alipay/RootCert.crt"
PublicCertFile: "custom/alipay/CertPublicKey_RSA2.crt"
AppPublicCertFile: "custom/alipay/AppCertPublicKey.crt"

@ -53,11 +53,11 @@ func newObserveLogHook() *observeLogHook {
Secure: s.Secure,
}
acc := &hx.AsyncClientConf{
MinWorker: s.MinWorker,
MaxRequestInCh: s.MaxLogBuffer,
MaxRequestInTempCh: 100,
MaxTickCount: 60,
TickWaitTime: time.Second,
MinWorker: s.MinWorker,
MaxRequestBuf: s.MaxLogBuffer,
MaxRequestTempBuf: 100,
MaxTickCount: 60,
TickWaitTime: time.Second,
}
return &observeLogHook{
client: obx.NewClient(obc, acc, func(req *http.Request, resp *http.Response, err error) {

@ -96,6 +96,20 @@ type appConf struct {
MaxPageSize int
}
type cacheConf struct {
KeyPoolSize int
CientSideCacheExpire time.Duration
UnreadMsgExpire int64
}
type eventManagerConf struct {
MinWorker int
MaxEventBuf int
MaxTempEventBuf int
MaxTickCount int
TickWaitTime time.Duration
}
type cacheIndexConf struct {
MaxUpdateQPS int
MinWorker int

@ -97,3 +97,9 @@ type RedisCache interface {
SetRechargeStatus(ctx context.Context, tradeNo string) error
DelRechargeStatus(ctx context.Context, tradeNo string) error
}
type WebCache interface {
GetUnreadMsgCountResp(uid int64) ([]byte, error)
PutUnreadMsgCountResp(uid int64, data []byte) error
DelUnreadMsgCountResp(uid int64) error
}

@ -14,6 +14,6 @@ type MessageService interface {
GetUnreadCount(userID int64) (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)
GetMessages(userId int64, offset, limit int) ([]*ms.MessageFormated, error)
GetMessageCount(userId int64) (int64, error)
}

@ -6,6 +6,7 @@ package cache
import (
"context"
"sync"
"time"
"github.com/allegro/bigcache/v3"
@ -14,6 +15,10 @@ import (
"github.com/sirupsen/logrus"
)
var (
_onceInit sync.Once
)
func NewRedisCache() core.RedisCache {
return &redisCache{
c: conf.MustRedisClient(),
@ -48,6 +53,11 @@ func NewRedisCacheIndexService(ips core.IndexPostsService, ams core.Authorizatio
return cacheIndex, cacheIndex
}
func NewWebCache() core.WebCache {
lazyInitial()
return _webCache
}
func NewSimpleCacheIndexService(indexPosts core.IndexPostsService) (core.CacheIndexService, core.VersionInfo) {
s := conf.SimpleCacheIndexSetting
cacheIndex := &simpleCacheIndexServant{
@ -88,3 +98,9 @@ func NewNoneCacheIndexService(indexPosts core.IndexPostsService) (core.CacheInde
}
return obj, obj
}
func lazyInitial() {
_onceInit.Do(func() {
_webCache = newWebCache()
})
}

@ -59,9 +59,22 @@ func (s *redisCacheTweetsCache) delTweets(keys []string) error {
return s.c.Do(context.Background(), cmd).Error()
}
func (s *redisCacheTweetsCache) allKeys() ([]string, error) {
cmd := s.c.B().Keys().Pattern(_cacheIndexKeyPattern).Build()
return s.c.Do(context.Background(), cmd).AsStrSlice()
func (s *redisCacheTweetsCache) allKeys() (res []string, err error) {
cursor := uint64(0)
for {
cmd := s.c.B().Scan().Cursor(cursor).Match(_cacheIndexKeyPattern).Count(50).Build()
entry, err := s.c.Do(context.Background(), cmd).AsScanEntry()
if err != nil {
return nil, err
}
res = append(res, entry.Elements...)
if entry.Cursor != 0 {
cursor = entry.Cursor
continue
}
break
}
return
}
func (s *redisCacheTweetsCache) Name() string {

@ -0,0 +1,66 @@
// 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 cache
import (
"context"
"time"
"github.com/Masterminds/semver/v3"
"github.com/redis/rueidis"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/pkg/utils"
)
var (
_webCache core.WebCache = (*redisWebCache)(nil)
)
type redisWebCache struct {
cscExpire time.Duration
unreadMsgExpire int64
c rueidis.Client
}
func (s *redisWebCache) Name() string {
return "RedisWebCache"
}
func (s *redisWebCache) Version() *semver.Version {
return semver.MustParse("v0.1.0")
}
func (s *redisWebCache) GetUnreadMsgCountResp(uid int64) ([]byte, error) {
key := conf.KeyUnreadMsg.Get(uid)
res, err := rueidis.MGetCache(s.c, context.Background(), s.cscExpire, []string{key})
if err != nil {
return nil, err
}
message := res[key]
return message.AsBytes()
}
func (s *redisWebCache) PutUnreadMsgCountResp(uid int64, data []byte) error {
return s.c.Do(context.Background(), s.c.B().Set().
Key(conf.KeyUnreadMsg.Get(uid)).
Value(utils.String(data)).
ExSeconds(s.unreadMsgExpire).
Build()).
Error()
}
func (s *redisWebCache) DelUnreadMsgCountResp(uid int64) error {
return s.c.Do(context.Background(), s.c.B().Del().Key(conf.KeyUnreadMsg.Get(uid)).Build()).Error()
}
func newWebCache() *redisWebCache {
s := conf.CacheSetting
return &redisWebCache{
cscExpire: s.CientSideCacheExpire,
unreadMsgExpire: s.UnreadMsgExpire,
c: conf.MustRedisClient(),
}
}

@ -38,6 +38,7 @@ type MessageFormated struct {
SenderUserID int64 `json:"sender_user_id"`
SenderUser *UserFormated `json:"sender_user"`
ReceiverUserID int64 `json:"receiver_user_id"`
ReceiverUser *UserFormated `json:"receiver_user,omitempty"`
Type MessageT `json:"type"`
Brief string `json:"brief"`
Content string `json:"content"`
@ -61,6 +62,7 @@ func (m *Message) Format() *MessageFormated {
SenderUserID: m.SenderUserID,
SenderUser: &UserFormated{},
ReceiverUserID: m.ReceiverUserID,
ReceiverUser: &UserFormated{},
Type: m.Type,
Brief: m.Brief,
Content: m.Content,
@ -114,39 +116,20 @@ func (m *Message) FetchBy(db *gorm.DB, predicates Predicates) ([]*Message, error
return messages, nil
}
func (c *Message) List(db *gorm.DB, conditions *ConditionsT, offset, limit int) ([]*Message, error) {
var messages []*Message
var err error
func (c *Message) List(db *gorm.DB, userId int64, offset, limit int) (res []*Message, err error) {
if offset >= 0 && limit > 0 {
db = db.Offset(offset).Limit(limit)
}
for k, v := range *conditions {
if k == "ORDER" {
db = db.Order(v)
} else {
db = db.Where(k, v)
}
}
if err = db.Where("is_del = ?", 0).Find(&messages).Error; err != nil {
return nil, err
}
return messages, nil
err = db.Where("receiver_user_id=? OR (sender_user_id=? AND type=4)", userId, userId).Order("id DESC").Find(&res).Error
return
}
func (m *Message) Count(db *gorm.DB, conditions *ConditionsT) (int64, error) {
var count int64
for k, v := range *conditions {
if k != "ORDER" {
db = db.Where(k, v)
}
}
if err := db.Model(m).Count(&count).Error; err != nil {
return 0, err
}
func (m *Message) Count(db *gorm.DB, userId int64) (res int64, err error) {
err = db.Model(m).Where("receiver_user_id=? OR (sender_user_id=? AND type=4)", userId, userId).Count(&res).Error
return
}
return count, nil
func (m *Message) CountUnread(db *gorm.DB, userId int64) (res int64, err error) {
err = db.Model(m).Where("receiver_user_id=? AND is_read=0", userId).Count(&res).Error
return
}

@ -30,10 +30,7 @@ func (s *messageSrv) CreateMessage(msg *ms.Message) (*ms.Message, error) {
}
func (s *messageSrv) GetUnreadCount(userID int64) (int64, error) {
return (&dbr.Message{}).Count(s.db, &dbr.ConditionsT{
"receiver_user_id": userID,
"is_read": dbr.MsgStatusUnread,
})
return (&dbr.Message{}).CountUnread(s.db, userID)
}
func (s *messageSrv) GetMessageByID(id int64) (*ms.Message, error) {
@ -49,21 +46,19 @@ func (s *messageSrv) ReadMessage(message *ms.Message) error {
return message.Update(s.db)
}
func (s *messageSrv) GetMessages(conditions *ms.ConditionsT, offset, limit int) ([]*ms.MessageFormated, error) {
messages, err := (&dbr.Message{}).List(s.db, conditions, offset, limit)
func (s *messageSrv) GetMessages(userId int64, offset, limit int) ([]*ms.MessageFormated, error) {
messages, err := (&dbr.Message{}).List(s.db, userId, offset, limit)
if err != nil {
return nil, err
}
mfs := []*dbr.MessageFormated{}
for _, message := range messages {
mf := message.Format()
mfs = append(mfs, mf)
}
return mfs, nil
}
func (s *messageSrv) GetMessageCount(conditions *ms.ConditionsT) (int64, error) {
return (&dbr.Message{}).Count(s.db, conditions)
func (s *messageSrv) GetMessageCount(userId int64) (int64, error) {
return (&dbr.Message{}).Count(s.db, userId)
}

@ -140,6 +140,8 @@ func (s *minioServant) DeleteObjects(objectKeys []string) (err error) {
Key: objectKey,
}
}
// 记得一定要close否则会被卡死退出不了函数造成资源泄露
close(objectsCh)
// 宽松处理所有错误,只记录最后一次发生的错误
for result := range resCh {

@ -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 events
import (
"sync"
"github.com/alimy/tryst/cfg"
"github.com/sirupsen/logrus"
)
var (
_onceInitial sync.Once
)
func Initial() {
_onceInitial.Do(func() {
initEventManager()
if cfg.If("JobManager") {
initJobManager()
logrus.Debugln("initial JobManager")
}
})
}

@ -0,0 +1,110 @@
// 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 events
import (
"github.com/robfig/cron/v3"
)
var (
_defaultJobManager JobManager = (*jobManager)(nil)
)
type (
EntryID = cron.EntryID
)
// JobFn job help function that implement cron.Job interface
type JobFn func()
func (fn JobFn) Run() {
fn()
}
// Job job interface
type Job interface {
cron.Schedule
cron.Job
}
type simpleJob struct {
cron.Schedule
cron.Job
}
// JobManager job manger interface
type JobManager interface {
Start()
Stop()
Remove(id EntryID)
Schedule(Job) EntryID
}
type jobManager struct {
m *cron.Cron
}
func (j *jobManager) Start() {
j.m.Start()
}
func (j *jobManager) Stop() {
j.m.Stop()
}
// Remove an entry from being run in the future.
func (j *jobManager) Remove(id EntryID) {
j.m.Remove(id)
}
// Schedule adds a Job to the Cron to be run on the given schedule.
// The job is wrapped with the configured Chain.
func (j *jobManager) Schedule(job Job) EntryID {
return j.m.Schedule(job, job)
}
func initJobManager() {
_defaultJobManager = &jobManager{
m: cron.New(),
}
StartJobManager()
}
func StartJobManager() {
_defaultJobManager.Start()
}
func StopJobManager() {
_defaultJobManager.Stop()
}
// NewJob create new Job instance
func NewJob(s cron.Schedule, fn JobFn) Job {
return &simpleJob{
Schedule: s,
Job: fn,
}
}
// RemoveJob an entry from being run in the future.
func RemoveJob(id EntryID) {
_defaultJobManager.Remove(id)
}
// ScheduleJob adds a Job to the Cron to be run on the given schedule.
// The job is wrapped with the configured Chain.
func ScheduleJob(job Job) EntryID {
return _defaultJobManager.Schedule(job)
}
// Schedule adds a Job to the Cron to be run on the given schedule.
// The job is wrapped with the configured Chain.
func Schedule(s cron.Schedule, fn JobFn) EntryID {
job := &simpleJob{
Schedule: s,
Job: fn,
}
return _defaultJobManager.Schedule(job)
}

@ -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 events
import (
"github.com/alimy/tryst/event"
"github.com/alimy/tryst/pool"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/sirupsen/logrus"
)
var (
_defaultEventManager event.EventManager
)
func initEventManager() {
var opts []pool.Option
s := conf.EventManagerSetting
if s.MinWorker > 5 {
opts = append(opts, pool.MinWorkerOpt(s.MinWorker))
} else {
opts = append(opts, pool.MinWorkerOpt(5))
}
if s.MaxEventBuf > 10 {
opts = append(opts, pool.MaxRequestBufOpt(s.MaxEventBuf))
} else {
opts = append(opts, pool.MaxRequestBufOpt(10))
}
if s.MaxTempEventBuf > 10 {
opts = append(opts, pool.MaxRequestTempBufOpt(s.MaxTempEventBuf))
} else {
opts = append(opts, pool.MaxRequestTempBufOpt(10))
}
opts = append(opts, pool.MaxTickCountOpt(s.MaxTickCount), pool.TickWaitTimeOpt(s.TickWaitTime))
_defaultEventManager = event.NewEventManager(func(req event.Event, err error) {
if err != nil {
logrus.Errorf("handle event[%s] occurs error: %s", req.Name(), err)
}
}, opts...)
}
func StartEventManager() {
_defaultEventManager.Start()
}
func StopEventManager() {
_defaultEventManager.Stop()
}
// OnEvent push event to gorotine pool then handled automatic.
func OnEvent(event event.Event) {
_defaultEventManager.OnEvent(event)
}

@ -5,10 +5,13 @@
package internal
import (
"github.com/rocboss/paopao-ce/internal/events"
"github.com/rocboss/paopao-ce/internal/migration"
)
func Initial() {
// migrate database if needed
migration.Run()
// event manager system initialize
events.Initial()
}

@ -14,3 +14,9 @@ type BasePageInfo struct {
func (r *BasePageInfo) SetPageInfo(page int, pageSize int) {
r.Page, r.PageSize = page, pageSize
}
type JsonResp struct {
Code int `json:"code"`
Msg string `json:"msg,omitempty"`
Data any `json:"data,omitempty"`
}

@ -0,0 +1,15 @@
// 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 joint
import (
stdJson "encoding/json"
"github.com/rocboss/paopao-ce/pkg/json"
)
func RespMarshal(data any) (stdJson.RawMessage, error) {
return json.Marshal(data)
}

@ -40,14 +40,6 @@ type UserInfoResp struct {
Followings int64 `json:"followings"`
}
type GetUnreadMsgCountReq struct {
SimpleInfo `json:"-" binding:"-"`
}
type GetUnreadMsgCountResp struct {
Count int64 `json:"count"`
}
type GetMessagesReq BasePageReq
type GetMessagesResp base.PageResp

@ -0,0 +1,34 @@
// 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 web
import (
"encoding/json"
"net/http"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/model/joint"
)
type GetUnreadMsgCountReq struct {
SimpleInfo `json:"-" binding:"-"`
}
type GetUnreadMsgCountResp struct {
Count int64 `json:"count"`
JsonResp json.RawMessage `json:"-"`
}
func (r *GetUnreadMsgCountResp) Render(c *gin.Context) {
if len(r.JsonResp) != 0 {
c.JSON(http.StatusOK, r.JsonResp)
} else {
c.JSON(http.StatusOK, &joint.JsonResp{
Code: 0,
Msg: "success",
Data: r,
})
}
}

@ -21,9 +21,10 @@ import (
"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/internal/events"
"github.com/rocboss/paopao-ce/internal/model/joint"
"github.com/rocboss/paopao-ce/pkg/app"
"github.com/rocboss/paopao-ce/pkg/xerror"
"github.com/sirupsen/logrus"
)
type BaseServant struct {
@ -39,12 +40,6 @@ type DaoServant struct {
Redis core.RedisCache
}
type JsonResp struct {
Code int `json:"code"`
Msg string `json:"msg,omitempty"`
Data any `json:"data,omitempty"`
}
type SentryHubSetter interface {
SetSentryHub(hub *sentry.Hub)
}
@ -145,13 +140,13 @@ func bindAnySentry(c *gin.Context, obj any) mir.Error {
func RenderAny(c *gin.Context, data any, err mir.Error) {
if err == nil {
c.JSON(http.StatusOK, &JsonResp{
c.JSON(http.StatusOK, &joint.JsonResp{
Code: 0,
Msg: "success",
Data: data,
})
} else {
c.JSON(xerror.HttpStatusCode(err), &JsonResp{
c.JSON(xerror.HttpStatusCode(err), &joint.JsonResp{
Code: err.StatusCode(),
Msg: err.Error(),
})
@ -164,13 +159,13 @@ func (s *BaseServant) Bind(c *gin.Context, obj any) mir.Error {
func (s *BaseServant) Render(c *gin.Context, data any, err mir.Error) {
if err == nil {
c.JSON(http.StatusOK, &JsonResp{
c.JSON(http.StatusOK, &joint.JsonResp{
Code: 0,
Msg: "success",
Data: data,
})
} else {
c.JSON(xerror.HttpStatusCode(err), &JsonResp{
c.JSON(xerror.HttpStatusCode(err), &joint.JsonResp{
Code: err.StatusCode(),
Msg: err.Error(),
})
@ -203,9 +198,16 @@ func (s *DaoServant) GetTweetBy(id int64) (*ms.PostFormated, error) {
return postFormated, nil
}
func (s *DaoServant) PushPostsToSearch(c context.Context) {
if err := s.Redis.SetPushToSearchJob(c); err == nil {
defer s.Redis.DelPushToSearchJob(c)
func (s *DaoServant) PushAllPostToSearch() {
events.OnEvent(&pushAllPostToSearchEvent{
fn: s.pushAllPostToSearch,
})
}
func (s *DaoServant) pushAllPostToSearch() error {
ctx := context.Background()
if err := s.Redis.SetPushToSearchJob(ctx); err == nil {
defer s.Redis.DelPushToSearchJob(ctx)
splitNum := 1000
conditions := ms.ConditionsT{
@ -234,11 +236,19 @@ func (s *DaoServant) PushPostsToSearch(c context.Context) {
}
}
} else {
logrus.Errorf("redis: set JOB_PUSH_TO_SEARCH error: %s", err)
return fmt.Errorf("redis: set JOB_PUSH_TO_SEARCH error: %w", err)
}
return nil
}
func (s *DaoServant) PushPostToSearch(post *ms.Post) {
events.OnEvent(&pushPostToSearchEvent{
fn: s.pushPostToSearch,
post: post,
})
}
func (s *DaoServant) pushPostToSearch(post *ms.Post) {
postFormated := post.Format()
postFormated.User = &ms.UserFormated{
ID: post.UserID,
@ -247,14 +257,12 @@ func (s *DaoServant) PushPostToSearch(post *ms.Post) {
for _, content := range contents {
postFormated.Contents = append(postFormated.Contents, content.Format())
}
contentFormated := ""
for _, content := range postFormated.Contents {
if content.Type == ms.ContentTypeText || content.Type == ms.ContentTypeTitle {
contentFormated = contentFormated + content.Content + "\n"
}
}
docs := []core.TsDocItem{{
Post: post,
Content: contentFormated,

@ -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 base
import (
"github.com/alimy/tryst/event"
"github.com/rocboss/paopao-ce/internal/core/ms"
)
type pushPostToSearchEvent struct {
event.UnimplementedEvent
fn func(*ms.Post)
post *ms.Post
}
type pushAllPostToSearchEvent struct {
event.UnimplementedEvent
fn func() error
}
func (p *pushPostToSearchEvent) Name() string {
return "servants.base.pushPostToSearchEvent"
}
func (p *pushPostToSearchEvent) Action() (err error) {
p.fn(p.post)
return
}
func (p *pushAllPostToSearchEvent) Name() string {
return "servants.base.pushAllPostToSearchEvent"
}
func (p *pushAllPostToSearchEvent) Action() error {
return p.fn()
}

@ -5,10 +5,11 @@
package chain
import (
"errors"
"strings"
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt/v4"
"github.com/golang-jwt/jwt/v5"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/pkg/app"
"github.com/rocboss/paopao-ce/pkg/xerror"
@ -51,10 +52,53 @@ func JWT() gin.HandlerFunc {
ecode = xerror.UnauthorizedAuthNotExist
}
} else {
switch err.(*jwt.ValidationError).Errors {
case jwt.ValidationErrorExpired:
if errors.Is(err, jwt.ErrTokenExpired) {
ecode = xerror.UnauthorizedTokenTimeout
default:
} else {
ecode = xerror.UnauthorizedTokenError
}
}
} else {
ecode = xerror.InvalidParams
}
if ecode != xerror.Success {
response := app.NewResponse(c)
response.ToErrorResponse(ecode)
c.Abort()
return
}
c.Next()
}
}
func JwtSurely() gin.HandlerFunc {
return func(c *gin.Context) {
var (
token string
ecode = xerror.Success
)
if s, exist := c.GetQuery("token"); exist {
token = s
} else {
token = c.GetHeader("Authorization")
// 验证前端传过来的token格式不为空开头为Bearer
if token == "" || !strings.HasPrefix(token, "Bearer ") {
response := app.NewResponse(c)
response.ToErrorResponse(xerror.UnauthorizedTokenError)
c.Abort()
return
}
// 验证通过提取有效部分除去Bearer)
token = token[7:]
}
if token != "" {
if claims, err := app.ParseToken(token); err == nil {
c.Set("UID", claims.UID)
c.Set("USERNAME", claims.Username)
} else {
if errors.Is(err, jwt.ErrTokenExpired) {
ecode = xerror.UnauthorizedTokenTimeout
} else {
ecode = xerror.UnauthorizedTokenError
}
}

@ -37,6 +37,7 @@ type coreSrv struct {
*base.DaoServant
oss core.ObjectStorageService
wc core.WebCache
}
func (s *coreSrv) Chain() gin.HandlersChain {
@ -45,7 +46,7 @@ func (s *coreSrv) Chain() gin.HandlersChain {
func (s *coreSrv) SyncSearchIndex(req *web.SyncSearchIndexReq) mir.Error {
if req.User != nil && req.User.IsAdmin {
go s.PushPostsToSearch(context.Background())
s.PushAllPostToSearch()
} else {
logrus.Warnf("sync search index need admin permision user: %#v", req.User)
}
@ -82,29 +83,20 @@ func (s *coreSrv) GetUserInfo(req *web.UserInfoReq) (*web.UserInfoResp, mir.Erro
return resp, nil
}
func (s *coreSrv) GetUnreadMsgCount(req *web.GetUnreadMsgCountReq) (*web.GetUnreadMsgCountResp, mir.Error) {
count, err := s.Ds.GetUnreadCount(req.Uid)
if err != nil {
return nil, xerror.ServerError
}
return &web.GetUnreadMsgCountResp{
Count: count,
}, nil
}
func (s *coreSrv) GetMessages(req *web.GetMessagesReq) (*web.GetMessagesResp, mir.Error) {
conditions := &ms.ConditionsT{
"receiver_user_id": req.UserId,
"ORDER": "id DESC",
}
messages, err := s.Ds.GetMessages(conditions, (req.Page-1)*req.PageSize, req.PageSize)
messages, err := s.Ds.GetMessages(req.UserId, (req.Page-1)*req.PageSize, req.PageSize)
for _, mf := range messages {
// TODO: 优化处理这里的user获取逻辑以及错误处理
if mf.SenderUserID > 0 {
user, err := s.Ds.GetUserByID(mf.SenderUserID)
if err == nil {
if user, err := s.Ds.GetUserByID(mf.SenderUserID); err == nil {
mf.SenderUser = user.Format()
}
}
if mf.Type == ms.MsgTypeWhisper && mf.ReceiverUserID != req.UserId {
if user, err := s.Ds.GetUserByID(mf.ReceiverUserID); err == nil {
mf.ReceiverUser = user.Format()
}
}
// 好友申请消息不需要获取其他信息
if mf.Type == ms.MsgTypeRequestingFriend {
continue
@ -132,7 +124,7 @@ func (s *coreSrv) GetMessages(req *web.GetMessagesReq) (*web.GetMessagesResp, mi
logrus.Errorf("Ds.GetMessages err: %v\n", err)
return nil, web.ErrGetMessagesFailed
}
totalRows, _ := s.Ds.GetMessageCount(conditions)
totalRows, _ := s.Ds.GetMessageCount(req.UserId)
resp := base.PageRespFrom(messages, req.Page, req.PageSize, totalRows)
return (*web.GetMessagesResp)(resp), nil
}
@ -149,6 +141,8 @@ func (s *coreSrv) ReadMessage(req *web.ReadMessageReq) mir.Error {
logrus.Errorf("Ds.ReadMessage err: %s", err)
return web.ErrReadMessageFailed
}
// 清除未读消息数缓存,不需要处理错误
s.wc.DelUnreadMsgCountResp(req.Uid)
return nil
}
@ -177,6 +171,9 @@ func (s *coreSrv) SendUserWhisper(req *web.SendWhisperReq) mir.Error {
return web.ErrSendWhisperFailed
}
// 清除接收者未读消息缓存, 不需要处理错误
s.wc.DelUnreadMsgCountResp(req.UserID)
// 写入当日(自然日)计数缓存
s.Redis.IncrCountWhisper(ctx, req.Uid)
@ -374,9 +371,10 @@ func (s *coreSrv) TweetStarStatus(req *web.TweetStarStatusReq) (*web.TweetStarSt
return resp, nil
}
func newCoreSrv(s *base.DaoServant, oss core.ObjectStorageService) api.Core {
func newCoreSrv(s *base.DaoServant, oss core.ObjectStorageService, wc core.WebCache) api.Core {
return &coreSrv{
DaoServant: s,
oss: oss,
wc: wc,
}
}

@ -0,0 +1,84 @@
// 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 web
import (
"encoding/json"
"fmt"
"github.com/alimy/tryst/event"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/events"
"github.com/rocboss/paopao-ce/internal/model/joint"
"github.com/rocboss/paopao-ce/internal/model/web"
)
type cacheUnreadMsgEvent struct {
event.UnimplementedEvent
ds core.DataService
wc core.WebCache
uid int64
}
type createMessageEvent struct {
event.UnimplementedEvent
ds core.DataService
wc core.WebCache
message *ms.Message
}
func onCacheUnreadMsgEvent(uid int64) {
events.OnEvent(&cacheUnreadMsgEvent{
ds: _ds,
wc: _wc,
uid: uid,
})
}
func onCreateMessageEvent(data *ms.Message) {
events.OnEvent(&createMessageEvent{
ds: _ds,
wc: _wc,
message: data,
})
}
func (e *cacheUnreadMsgEvent) Name() string {
return "cacheUnreadMsgEvent"
}
func (e *cacheUnreadMsgEvent) Action() error {
count, err := e.ds.GetUnreadCount(e.uid)
if err != nil {
return fmt.Errorf("cacheUnreadMsgEvent action occurs error: %w", err)
}
resp := &joint.JsonResp{
Code: 0,
Msg: "success",
Data: &web.GetUnreadMsgCountResp{
Count: count,
},
}
data, err := json.Marshal(resp)
if err != nil {
return fmt.Errorf("cacheUnreadMsgEvent action marshal resp occurs error: %w", err)
}
if err = e.wc.PutUnreadMsgCountResp(e.uid, data); err != nil {
return fmt.Errorf("cacheUnreadMsgEvent action put resp data to redis cache occurs error: %w", err)
}
return nil
}
func (e *createMessageEvent) Name() string {
return "createMessageEvent"
}
func (e *createMessageEvent) Action() (err error) {
if _, err = e.ds.CreateMessage(e.message); err == nil {
err = e.wc.DelUnreadMsgCountResp(e.message.ReceiverUserID)
}
return
}

@ -286,8 +286,7 @@ func (s *privSrv) CreateTweet(req *web.CreateTweetReq) (_ *web.CreateTweetResp,
}
// 创建消息提醒
// TODO: 优化消息提醒处理机制
go s.Ds.CreateMessage(&ms.Message{
onCreateMessageEvent(&ms.Message{
SenderUserID: req.User.ID,
ReceiverUserID: user.ID,
Type: ms.MsgTypePost,
@ -390,7 +389,7 @@ 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(&ms.Message{
onCreateMessageEvent(&ms.Message{
SenderUserID: req.Uid,
ReceiverUserID: commentMaster.ID,
Type: ms.MsgTypeReply,
@ -402,7 +401,7 @@ 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(&ms.Message{
onCreateMessageEvent(&ms.Message{
SenderUserID: req.Uid,
ReceiverUserID: postMaster.ID,
Type: ms.MsgTypeReply,
@ -416,7 +415,7 @@ 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(&ms.Message{
onCreateMessageEvent(&ms.Message{
SenderUserID: req.Uid,
ReceiverUserID: user.ID,
Type: ms.MsgTypeReply,
@ -522,7 +521,7 @@ 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(&ms.Message{
onCreateMessageEvent(&ms.Message{
SenderUserID: req.Uid,
ReceiverUserID: postMaster.ID,
Type: ms.MsgtypeComment,
@ -538,7 +537,7 @@ func (s *privSrv) CreateComment(req *web.CreateCommentReq) (_ *web.CreateComment
}
// 创建消息提醒
go s.Ds.CreateMessage(&ms.Message{
onCreateMessageEvent(&ms.Message{
SenderUserID: req.Uid,
ReceiverUserID: user.ID,
Type: ms.MsgtypeComment,

@ -0,0 +1,52 @@
// 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 web
import (
"github.com/alimy/mir/v4"
"github.com/gin-gonic/gin"
"github.com/redis/rueidis"
api "github.com/rocboss/paopao-ce/auto/api/v1"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model/web"
"github.com/rocboss/paopao-ce/internal/servants/base"
"github.com/rocboss/paopao-ce/internal/servants/chain"
"github.com/sirupsen/logrus"
)
var (
_ api.Relax = (*relaxSrv)(nil)
)
type relaxSrv struct {
api.UnimplementedRelaxServant
*base.DaoServant
wc core.WebCache
}
func (s *relaxSrv) Chain() gin.HandlersChain {
return gin.HandlersChain{chain.JwtSurely()}
}
func (s *relaxSrv) GetUnreadMsgCount(req *web.GetUnreadMsgCountReq) (*web.GetUnreadMsgCountResp, mir.Error) {
if data, xerr := s.wc.GetUnreadMsgCountResp(req.Uid); xerr == nil && len(data) > 0 {
// logrus.Debugln("GetUnreadMsgCount get resp from cache")
return &web.GetUnreadMsgCountResp{
JsonResp: data,
}, nil
} else if !rueidis.IsRedisNil(xerr) {
logrus.Warnf("GetUnreadMsgCount from cache occurs error: %s", xerr)
}
// 使用缓存机制特殊处理
onCacheUnreadMsgEvent(req.Uid)
return &web.GetUnreadMsgCountResp{}, nil
}
func newRelaxSrv(s *base.DaoServant, wc core.WebCache) api.Relax {
return &relaxSrv{
DaoServant: s,
wc: wc,
}
}

@ -11,27 +11,32 @@ import (
"github.com/gin-gonic/gin"
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/dao"
"github.com/rocboss/paopao-ce/internal/dao/cache"
"github.com/rocboss/paopao-ce/internal/servants/base"
)
var (
_enablePhoneVerify bool
_disallowUserRegister bool
_ds core.DataService
_wc core.WebCache
_oss core.ObjectStorageService
_onceInitial sync.Once
)
// RouteWeb register web route
func RouteWeb(e *gin.Engine) {
lazyInitial()
oss := dao.ObjectStorageService()
ds := base.NewDaoServant()
// aways register servants
api.RegisterAdminServant(e, newAdminSrv(ds))
api.RegisterCoreServant(e, newCoreSrv(ds, oss))
api.RegisterCoreServant(e, newCoreSrv(ds, _oss, _wc))
api.RegisterRelaxServant(e, newRelaxSrv(ds, _wc))
api.RegisterLooseServant(e, newLooseSrv(ds))
api.RegisterPrivServant(e, newPrivSrv(ds, oss))
api.RegisterPubServant(e, newPubSrv(ds, oss))
api.RegisterPrivServant(e, newPrivSrv(ds, _oss))
api.RegisterPubServant(e, newPubSrv(ds, _oss))
api.RegisterKeyQueryServant(e, NewShareKeyServant(ds))
api.RegisterRankServant(e, NewRankServant(ds))
api.RegisterFollowshipServant(e, newFollowshipSrv(ds))
@ -49,5 +54,8 @@ func lazyInitial() {
_onceInitial.Do(func() {
_enablePhoneVerify = cfg.If("Sms")
_disallowUserRegister = cfg.If("Web:DisallowUserRegister")
_oss = dao.ObjectStorageService()
_ds = dao.DataService()
_wc = cache.NewWebCache()
})
}

@ -21,9 +21,6 @@ type Core struct {
// GetUserInfo 获取当前用户信息
GetUserInfo func(Get, web.UserInfoReq) web.UserInfoResp `mir:"/user/info"`
// GetUnreadMsgCount 获取当前用户未读消息数量
GetUnreadMsgCount func(Get, web.GetUnreadMsgCountReq) web.GetUnreadMsgCountResp `mir:"/user/msgcount/unread"`
// GetMessages 获取消息列表
GetMessages func(Get, web.GetMessagesReq) web.GetMessagesResp `mir:"/user/messages"`

@ -0,0 +1,20 @@
package v1
import (
. "github.com/alimy/mir/v4"
. "github.com/alimy/mir/v4/engine"
"github.com/rocboss/paopao-ce/internal/model/web"
)
func init() {
Entry[Relax]()
}
// Relax 放宽授权的服务
type Relax struct {
Chain `mir:"-"`
Group `mir:"v1"`
// GetUnreadMsgCount 获取当前用户未读消息数量
GetUnreadMsgCount func(Get, web.GetUnreadMsgCountReq) web.GetUnreadMsgCountResp `mir:"/user/msgcount/unread"`
}

@ -7,7 +7,7 @@ package app
import (
"time"
"github.com/golang-jwt/jwt/v4"
"github.com/golang-jwt/jwt/v5"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core/ms"
)
@ -38,18 +38,15 @@ func GenerateToken(User *ms.User) (string, error) {
return token, err
}
func ParseToken(token string) (*Claims, error) {
tokenClaims, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (any, error) {
func ParseToken(token string) (res *Claims, err error) {
var tokenClaims *jwt.Token
tokenClaims, err = jwt.ParseWithClaims(token, &Claims{}, func(_ *jwt.Token) (any, error) {
return GetJWTSecret(), nil
})
if err != nil {
return nil, err
if err == nil && tokenClaims != nil && tokenClaims.Valid {
res, _ = tokenClaims.Claims.(*Claims)
} else {
err = jwt.ErrTokenNotValidYet
}
if tokenClaims != nil {
if claims, ok := tokenClaims.Claims.(*Claims); ok && tokenClaims.Valid {
return claims, nil
}
}
return nil, err
return
}

@ -8,7 +8,7 @@ import (
"net/http"
"time"
"github.com/sirupsen/logrus"
gp "github.com/alimy/tryst/pool"
)
var (
@ -16,13 +16,13 @@ var (
)
const (
_minRequestInCh = 10
_minRequestInTmpCh = 10
_minRequestBuf = 10
_minRequestTempBuf = 10
_minWorker = 5
)
// ResponseFn a function used handle the response of http.Client.Do
type ResponseFn = func(req *http.Request, resp *http.Response, err error)
type ResponseFn = gp.ResponseFn[*http.Request, *http.Response]
// AsyncClient asynchronous client interface
type AsyncClient interface {
@ -31,90 +31,44 @@ type AsyncClient interface {
// AsyncClientConf client configure used to create an AsynClient instance
type AsyncClientConf struct {
MinWorker int
MaxRequestInCh int
MaxRequestInTempCh int
MaxTickCount int
TickWaitTime time.Duration
}
type requestItem struct {
request *http.Request
fn ResponseFn
MinWorker int
MaxRequestBuf int
MaxRequestTempBuf int
MaxTickCount int
TickWaitTime time.Duration
}
type wormClient struct {
client *http.Client
requestCh chan *requestItem // 正式工 缓存通道
requestTempCh chan *requestItem // 临时工 缓存通道
maxTickCount int
tickWaitTime time.Duration
pool gp.GoroutinePool[*http.Request, *http.Response]
}
func (s *wormClient) Do(req *http.Request, fn ResponseFn) {
item := &requestItem{req, fn}
select {
case s.requestCh <- item:
// send request item by requestCh chan
default:
select {
case s.requestTempCh <- item:
// send request item by requestTempCh chan"
default:
go func() {
s.do(item)
// watch requestTempCh to continue do work if needed.
// cancel loop if no item had watched in s.maxCyle * s.maxWaitTime.
for count := 0; count < s.maxTickCount; count++ {
select {
case item := <-s.requestTempCh:
// reset count to continue do work
count = 0
s.do(item)
default:
// sleeping to wait request item pass over to do work
time.Sleep(s.tickWaitTime)
}
}
}()
}
}
}
func (s *wormClient) starDotWork() {
for item := range s.requestCh {
s.do(item)
}
}
func (s *wormClient) do(req *requestItem) {
resp, err := s.client.Do(req.request)
req.fn(req.request, resp, err)
s.pool.Do(req, fn)
}
// NewAsyncClient create an AsyncClient instance
func NewAsyncClient(client *http.Client, conf *AsyncClientConf) AsyncClient {
maxRequestInCh := _minRequestInCh
maxRequestInTempCh := _minRequestInTmpCh
if conf.MaxRequestInCh > _minRequestInCh {
maxRequestInCh = conf.MaxRequestInCh
}
if conf.MaxRequestInTempCh > _minRequestInTmpCh {
maxRequestInTempCh = conf.MaxRequestInTempCh
minWorker := _minWorker
maxRequestBuf := _minRequestBuf
maxRequestTempBuf := _minRequestTempBuf
if conf.MaxRequestBuf > _minRequestBuf {
maxRequestBuf = conf.MaxRequestBuf
}
wc := &wormClient{
client: client,
requestCh: make(chan *requestItem, maxRequestInCh),
requestTempCh: make(chan *requestItem, maxRequestInTempCh),
if conf.MaxRequestTempBuf > _minRequestTempBuf {
maxRequestTempBuf = conf.MaxRequestTempBuf
}
numWorker := conf.MinWorker
if numWorker < _minWorker {
numWorker = _minWorker
if conf.MinWorker > _minWorker {
minWorker = conf.MinWorker
}
logrus.Debugf("use %d backend worker to do the http request", numWorker)
// 启动 do work 正式工
for ; numWorker > 0; numWorker-- {
go wc.starDotWork()
return &wormClient{
pool: gp.NewGoroutinePool(func(req *http.Request) (*http.Response, error) {
return client.Do(req)
},
gp.MinWorkerOpt(minWorker),
gp.MaxRequestBufOpt(maxRequestBuf),
gp.MaxRequestTempBufOpt(maxRequestTempBuf),
gp.MaxTickCountOpt(conf.MaxTickCount),
gp.TickWaitTimeOpt(conf.TickWaitTime),
),
}
return wc
}

@ -75,6 +75,7 @@ func NewClient(conf *Config, acc *hx.AsyncClientConf, fn hx.ResponseFn) OpenObse
user: conf.User,
password: conf.Password,
userAgent: userAgent,
respFn: fn,
client: hx.NewAsyncClient(http.DefaultClient, acc),
}
}

@ -7,6 +7,7 @@ package utils
import (
"math/rand"
"time"
"unsafe"
)
type StrType int
@ -41,3 +42,10 @@ func RandStr(size int, kind StrType) []byte {
}
return result
}
func String(data []byte) string {
if size := len(data); size > 0 {
return unsafe.String(unsafe.SliceData(data), size)
}
return ""
}

@ -0,0 +1,43 @@
#!/bin/sh
# eg.1 : sh run.sh
# eg.2, push all release: sh run.sh push
# eg.3, push all release with dev branch: sh run.sh push dev
function push {
if [ -n "$1" ]; then
echo "git push origin $1:$1"
git push origin $1:$1
echo "git push alimy $1:$1"
git push alimy $1:$1
echo "git push bitbus $1:$1"
git push bitbus $1:$1
else
push_all dev r/paopao-ce r/paopao-ce-plus r/paopao-ce-pro r/paopao-ce-xtra
fi
}
function push_all {
if [ $# -eq 0 ]; then
push
else
while [ $# -gt 0 ]; do
push $1
shift
done
fi
}
case $1 in
"push")
shift
push_all $@
;;
"merge")
echo "merge command"
;;
*)
push_all
;;
esac

@ -1,3 +1,3 @@
ALTER TABLE p_post_content ALTER COLUMN content SET DATA TYPE TEXT NOT NULL DEFAULT '';
ALTER TABLE p_comment_content ALTER COLUMN content SET DATA TYPE TEXT NOT NULL DEFAULT '';
ALTER TABLE p_comment_reply ALTER COLUMN content SET DATA TYPE TEXT NOT NULL DEFAULT '';
ALTER TABLE p_post_content ALTER COLUMN content SET DATA TYPE TEXT, ALTER COLUMN content SET NOT NULL, ALTER COLUMN content SET DEFAULT '';
ALTER TABLE p_comment_content ALTER COLUMN content SET DATA TYPE TEXT, ALTER COLUMN content SET NOT NULL, ALTER COLUMN content SET DEFAULT '';
ALTER TABLE p_comment_reply ALTER COLUMN content SET DATA TYPE TEXT, ALTER COLUMN content SET NOT NULL, ALTER COLUMN content SET DEFAULT '';

@ -1,8 +1,12 @@
VITE_HOST=""
# 功能特性开启
VITE_USE_FRIENDSHIP=true
# 模块开启
VITE_ENABLE_ANOUNCEMENT=false
VITE_ENABLE_WALLET=false
VITE_ENABLE_FRIENDS_BAR=true
# 功能开启
VITE_ALLOW_TWEET_ATTACHMENT=true

@ -1 +0,0 @@
import{_ as s}from"./main-nav.vue_vue_type_style_index_0_lang-fa3b58e7.js";import{u as a}from"./vue-router-edf90322.js";import{F as i,e as c,a2 as u}from"./naive-ui-702193c2.js";import{d as l,c as d,V as t,a2 as o,o as f,e as x}from"./@vue-7e1ab0af.js";import{_ as g}from"./index-b4b0f710.js";import"./vuex-f1ee712f.js";import"./vooks-e23078ea.js";import"./evtd-b614532e.js";import"./@vicons-b98681e0.js";import"./seemly-76b7b838.js";import"./vueuc-2fc92f18.js";import"./@css-render-16be7445.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};

@ -0,0 +1 @@
import{_ as s}from"./main-nav.vue_vue_type_style_index_0_lang-5497f713.js";import{u as a}from"./vue-router-e5a2430e.js";import{F as i,e as c,a2 as u}from"./naive-ui-d8de3dda.js";import{d as l,f as d,k as t,w as o,e as f,A as x}from"./@vue-a481fc63.js";import{_ as g}from"./index-d9671de1.js";import"./vuex-44de225f.js";import"./vooks-6d99783e.js";import"./evtd-b614532e.js";import"./@vicons-7a4ef312.js";import"./seemly-76b7b838.js";import"./vueuc-39372edb.js";import"./@css-render-7124a1a5.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};

@ -1,3 +1,3 @@
import{i as d}from"./@vue-7e1ab0af.js";function C(i){let r=".",s="__",m="--",f;if(i){let e=i.blockPrefix;e&&(r=e),e=i.elementPrefix,e&&(s=e),e=i.modifierPrefix,e&&(m=e)}const b={install(e){f=e.c;const l=e.context;l.bem={},l.bem.b=null,l.bem.els=null}};function y(e){let l,n;return{before(t){l=t.bem.b,n=t.bem.els,t.bem.els=null},after(t){t.bem.b=l,t.bem.els=n},$({context:t,props:u}){return e=typeof e=="string"?e:e({context:t,props:u}),t.bem.b=e,`${(u==null?void 0:u.bPrefix)||r}${t.bem.b}`}}}function v(e){let l;return{before(n){l=n.bem.els},after(n){n.bem.els=l},$({context:n,props:t}){return e=typeof e=="string"?e:e({context:n,props:t}),n.bem.els=e.split(",").map(u=>u.trim()),n.bem.els.map(u=>`${(t==null?void 0:t.bPrefix)||r}${n.bem.b}${s}${u}`).join(", ")}}}function P(e){return{$({context:l,props:n}){e=typeof e=="string"?e:e({context:l,props:n});const t=e.split(",").map(o=>o.trim());function u(o){return t.map(x=>`&${(n==null?void 0:n.bPrefix)||r}${l.bem.b}${o!==void 0?`${s}${o}`:""}${m}${x}`).join(", ")}const c=l.bem.els;return c!==null?u(c[0]):u()}}}function _(e){return{$({context:l,props:n}){e=typeof e=="string"?e:e({context:l,props:n});const t=l.bem.els;return`&:not(${(n==null?void 0:n.bPrefix)||r}${l.bem.b}${t!==null&&t.length>0?`${s}${t[0]}`:""}${m}${e})`}}}return Object.assign(b,{cB:(...e)=>f(y(e[0]),e[1],e[2]),cE:(...e)=>f(v(e[0]),e[1],e[2]),cM:(...e)=>f(P(e[0]),e[1],e[2]),cNotM:(...e)=>f(_(e[0]),e[1],e[2])}),b}const $=Symbol("@css-render/vue3-ssr");function M(i,r){return`<style cssr-id="${i}">
import{i as d}from"./@vue-a481fc63.js";function C(i){let r=".",s="__",m="--",f;if(i){let e=i.blockPrefix;e&&(r=e),e=i.elementPrefix,e&&(s=e),e=i.modifierPrefix,e&&(m=e)}const b={install(e){f=e.c;const l=e.context;l.bem={},l.bem.b=null,l.bem.els=null}};function y(e){let l,n;return{before(t){l=t.bem.b,n=t.bem.els,t.bem.els=null},after(t){t.bem.b=l,t.bem.els=n},$({context:t,props:u}){return e=typeof e=="string"?e:e({context:t,props:u}),t.bem.b=e,`${(u==null?void 0:u.bPrefix)||r}${t.bem.b}`}}}function v(e){let l;return{before(n){l=n.bem.els},after(n){n.bem.els=l},$({context:n,props:t}){return e=typeof e=="string"?e:e({context:n,props:t}),n.bem.els=e.split(",").map(u=>u.trim()),n.bem.els.map(u=>`${(t==null?void 0:t.bPrefix)||r}${n.bem.b}${s}${u}`).join(", ")}}}function P(e){return{$({context:l,props:n}){e=typeof e=="string"?e:e({context:l,props:n});const t=e.split(",").map(o=>o.trim());function u(o){return t.map(x=>`&${(n==null?void 0:n.bPrefix)||r}${l.bem.b}${o!==void 0?`${s}${o}`:""}${m}${x}`).join(", ")}const c=l.bem.els;return c!==null?u(c[0]):u()}}}function _(e){return{$({context:l,props:n}){e=typeof e=="string"?e:e({context:l,props:n});const t=l.bem.els;return`&:not(${(n==null?void 0:n.bPrefix)||r}${l.bem.b}${t!==null&&t.length>0?`${s}${t[0]}`:""}${m}${e})`}}}return Object.assign(b,{cB:(...e)=>f(y(e[0]),e[1],e[2]),cE:(...e)=>f(v(e[0]),e[1],e[2]),cM:(...e)=>f(P(e[0]),e[1],e[2]),cNotM:(...e)=>f(_(e[0]),e[1],e[2])}),b}const $=Symbol("@css-render/vue3-ssr");function M(i,r){return`<style cssr-id="${i}">
${r}
</style>`}function S(i,r){const s=d($,null);if(s===null){console.error("[css-render/vue3-ssr]: no ssr context found.");return}const{styles:m,ids:f}=s;f.has(i)||m!==null&&(f.add(i),m.push(M(i,r)))}const j=typeof document<"u";function N(){if(j)return;const i=d($,null);if(i!==null)return{adapter:S,context:i}}export{C as p,N as u};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +0,0 @@
import{_ as F}from"./post-skeleton-3703f541.js";import{_ as N}from"./main-nav.vue_vue_type_style_index_0_lang-fa3b58e7.js";import{u as V}from"./vuex-f1ee712f.js";import{b as z}from"./vue-router-edf90322.js";import{a as A}from"./formatTime-4210fcd1.js";import{F as R,Q as S,H as L,G as M}from"./naive-ui-702193c2.js";import{d as O,r as n,j as P,c as o,V as a,a2 as p,o as e,_ as u,O as l,F as Q,a5 as j,Q as q,a as s,M as _,L as D}from"./@vue-7e1ab0af.js";import{_ as E}from"./index-b4b0f710.js";import"./vooks-e23078ea.js";import"./evtd-b614532e.js";import"./@vicons-b98681e0.js";import"./moment-2ab8298d.js";import"./seemly-76b7b838.js";import"./vueuc-2fc92f18.js";import"./@css-render-16be7445.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"},I={key:1},T={key:0,class:"empty-wrap"},U={class:"bill-line"},$=O({__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 P(()=>{}),(m,K)=>{const y=N,k=S,x=F,w=L,B=M,C=R;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",I,[r.value.length===0?(e(),o("div",T,[a(w,{size:"large",description:"暂无数据"})])):l("",!0),(e(!0),o(Q,null,j(r.value,t=>(e(),q(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:D({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};

@ -0,0 +1 @@
import{_ as F}from"./post-skeleton-73b6be04.js";import{_ as N}from"./main-nav.vue_vue_type_style_index_0_lang-5497f713.js";import{u as z}from"./vuex-44de225f.js";import{b as A}from"./vue-router-e5a2430e.js";import{a as R}from"./formatTime-4210fcd1.js";import{F as S,Q as V,I as q,G as I}from"./naive-ui-d8de3dda.js";import{d as P,H as n,b as j,f as o,k as a,w as p,e,bf as u,Y as l,F as D,u as E,q as G,j as s,x as _,l as H}from"./@vue-a481fc63.js";import{_ as L}from"./index-d9671de1.js";import"./vooks-6d99783e.js";import"./evtd-b614532e.js";import"./@vicons-7a4ef312.js";import"./moment-2ab8298d.js";import"./seemly-76b7b838.js";import"./vueuc-39372edb.js";import"./@css-render-7124a1a5.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 M={key:0,class:"pagination-wrap"},O={key:0,class:"skeleton-wrap"},Q={key:1},T={key:0,class:"empty-wrap"},U={class:"bill-line"},Y=P({__name:"Anouncement",setup($){const d=z(),g=A(),v=n(!1),r=n([]),i=n(+g.query.p||1),f=n(20),m=n(0),h=c=>{i.value=c};return j(()=>{}),(c,J)=>{const k=N,y=V,x=F,w=q,B=I,C=S;return e(),o("div",null,[a(k,{title:"公告"}),a(C,{class:"main-content-wrap",bordered:""},{footer:p(()=>[m.value>1?(e(),o("div",M,[a(y,{page:i.value,"onUpdate:page":h,"page-slot":u(d).state.collapsedRight?5:8,"page-count":m.value},null,8,["page","page-slot","page-count"])])):l("",!0)]),default:p(()=>[v.value?(e(),o("div",O,[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(D,null,E(r.value,t=>(e(),G(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:H({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(R)(t.created_on)),1)])]),_:2},1024))),128))]))]),_:1})])}}});const yt=L(Y,[["__scopeId","data-v-d4d04859"]]);export{yt as default};

@ -1 +0,0 @@
import{_ as N,a as P}from"./post-item.vue_vue_type_style_index_0_lang-ebd1ae42.js";import{_ as S}from"./post-skeleton-3703f541.js";import{_ as V}from"./main-nav.vue_vue_type_style_index_0_lang-fa3b58e7.js";import{u as $}from"./vuex-f1ee712f.js";import{b as Q}from"./vue-router-edf90322.js";import{N as R,_ as j}from"./index-b4b0f710.js";import{d as q,r as s,j as E,c as o,V as e,a2 as c,_ as g,O as v,o as t,F as f,a5 as h,Q as k}from"./@vue-7e1ab0af.js";import{F as G,Q as H,H as I,G as L}from"./naive-ui-702193c2.js";import"./content-1c30deb5.js";import"./@vicons-b98681e0.js";import"./paopao-video-player-66a1a537.js";import"./formatTime-4210fcd1.js";import"./moment-2ab8298d.js";import"./copy-to-clipboard-4ef7d3eb.js";import"./@babel-725317a4.js";import"./toggle-selection-93f4ad84.js";import"./vooks-e23078ea.js";import"./evtd-b614532e.js";import"./axios-4a70c6fc.js";/* empty css */import"./seemly-76b7b838.js";import"./vueuc-2fc92f18.js";import"./@css-render-16be7445.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"},T={key:1},U={key:0,class:"empty-wrap"},A={key:1},D={key:2},J={key:0,class:"pagination-wrap"},K=q({__name:"Collection",setup(W){const m=$(),y=Q(),_=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=V,b=S,x=I,z=N,d=L,B=P,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",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 Nt=j(K,[["__scopeId","data-v-a5302c9b"]]);export{Nt as default};

@ -0,0 +1 @@
import{_ as q}from"./whisper-24717711.js";import{_ as I,a as V}from"./post-item.vue_vue_type_style_index_0_lang-369aa3bd.js";import{_ as W}from"./post-skeleton-73b6be04.js";import{_ as E}from"./main-nav.vue_vue_type_style_index_0_lang-5497f713.js";import{u as G}from"./vuex-44de225f.js";import{b as H}from"./vue-router-e5a2430e.js";import{N as L,_ as Q}from"./index-d9671de1.js";import{d as T,H as s,b as U,f as o,k as n,w as u,bf as h,Y as w,e,F as k,u as y,q as C}from"./@vue-a481fc63.js";import{F as Y,Q as j,I as A,G as D}from"./naive-ui-d8de3dda.js";import"./content-cbd53e51.js";import"./@vicons-7a4ef312.js";import"./paopao-video-player-2fe58954.js";import"./formatTime-4210fcd1.js";import"./moment-2ab8298d.js";import"./copy-to-clipboard-4ef7d3eb.js";import"./@babel-725317a4.js";import"./toggle-selection-93f4ad84.js";import"./vooks-6d99783e.js";import"./evtd-b614532e.js";import"./axios-4a70c6fc.js";/* empty css */import"./seemly-76b7b838.js";import"./vueuc-39372edb.js";import"./@css-render-7124a1a5.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 J={key:0,class:"skeleton-wrap"},K={key:1},O={key:0,class:"empty-wrap"},X={key:1},Z={key:2},ee={key:0,class:"pagination-wrap"},oe=T({__name:"Collection",setup(te){const m=G(),S=H(),_=s(!1),i=s([]),l=s(+S.query.p||1),p=s(20),r=s(0),c=s(!1),d=s({id:0,avatar:"",username:"",nickname:"",is_admin:!1,is_friend:!0,is_following:!1,created_on:0,follows:0,followings:0,status:1}),f=t=>{d.value=t,c.value=!0},b=()=>{c.value=!1},v=()=>{_.value=!0,L({page:l.value,page_size:p.value}).then(t=>{_.value=!1,i.value=t.list,r.value=Math.ceil(t.pager.total_rows/p.value),window.scrollTo(0,0)}).catch(t=>{_.value=!1})},x=t=>{l.value=t,v()};return U(()=>{v()}),(t,ne)=>{const $=E,z=W,B=A,F=I,g=D,M=V,N=q,P=Y,R=j;return e(),o("div",null,[n($,{title:"收藏"}),n(P,{class:"main-content-wrap",bordered:""},{default:u(()=>[_.value?(e(),o("div",J,[n(z,{num:p.value},null,8,["num"])])):(e(),o("div",K,[i.value.length===0?(e(),o("div",O,[n(B,{size:"large",description:"暂无数据"})])):w("",!0),h(m).state.desktopModelShow?(e(),o("div",X,[(e(!0),o(k,null,y(i.value,a=>(e(),C(g,{key:a.id},{default:u(()=>[n(F,{post:a,onSendWhisper:f},null,8,["post"])]),_:2},1024))),128))])):(e(),o("div",Z,[(e(!0),o(k,null,y(i.value,a=>(e(),C(g,{key:a.id},{default:u(()=>[n(M,{post:a,onSendWhisper:f},null,8,["post"])]),_:2},1024))),128))]))])),n(N,{show:c.value,user:d.value,onSuccess:b},null,8,["show","user"])]),_:1}),r.value>0?(e(),o("div",ee,[n(R,{page:l.value,"onUpdate:page":x,"page-slot":h(m).state.collapsedRight?5:8,"page-count":r.value},null,8,["page","page-slot","page-count"])])):w("",!0)])}}});const Ve=Q(oe,[["__scopeId","data-v-760779af"]]);export{Ve as default};

@ -0,0 +1 @@
.pagination-wrap[data-v-760779af]{padding:10px;display:flex;justify-content:center;overflow:hidden}.dark .main-content-wrap[data-v-760779af],.dark .empty-wrap[data-v-760779af],.dark .skeleton-wrap[data-v-760779af]{background-color:#101014bf}

@ -1 +0,0 @@
.pagination-wrap[data-v-a5302c9b]{padding:10px;display:flex;justify-content:center;overflow:hidden}.dark .main-content-wrap[data-v-a5302c9b],.dark .empty-wrap[data-v-a5302c9b],.dark .skeleton-wrap[data-v-a5302c9b]{background-color:#101014bf}

@ -0,0 +1 @@
import{_ as T}from"./whisper-24717711.js";import{d as N,c as j,r as A,e as s,f as c,k as t,w as n,j as i,y as H,A as L,x as v,bf as g,h as I,H as a,b as U,Y as S,F as z,u as W,q as E}from"./@vue-a481fc63.js";import{b as G}from"./formatTime-4210fcd1.js";import{i as Q,p as Y}from"./@vicons-7a4ef312.js";import{j as x,o as J,e as K,O as X,L as Z,F as ee,Q as te,I as ne,G as oe}from"./naive-ui-d8de3dda.js";import{_ as q,b as se}from"./index-d9671de1.js";import{_ as ae}from"./post-skeleton-73b6be04.js";import{_ as ce}from"./main-nav.vue_vue_type_style_index_0_lang-5497f713.js";import{u as ie}from"./vuex-44de225f.js";import{b as _e}from"./vue-router-e5a2430e.js";import"./moment-2ab8298d.js";import"./seemly-76b7b838.js";import"./vueuc-39372edb.js";import"./evtd-b614532e.js";import"./@css-render-7124a1a5.js";import"./vooks-6d99783e.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 re={class:"contact-item"},le={class:"nickname-wrap"},pe={class:"username-wrap"},ue={class:"user-info"},me={class:"info-item"},de={class:"info-item"},fe={class:"item-header-extra"},ve=N({__name:"contact-item",props:{contact:{}},emits:["send-whisper"],setup(b,{emit:h}){const _=b,r=e=>()=>I(x,null,{default:()=>I(e)}),l=j(()=>[{label:"私信",key:"whisper",icon:r(Y)}]),u=e=>{switch(e){case"whisper":const o={id:_.contact.user_id,avatar:_.contact.avatar,username:_.contact.username,nickname:_.contact.nickname,is_admin:!1,is_friend:!0,is_following:!1,created_on:0,follows:0,followings:0,status:1};h("send-whisper",o);break}};return(e,o)=>{const m=J,d=A("router-link"),w=K,k=X,y=Z;return s(),c("div",re,[t(y,{"content-indented":""},{avatar:n(()=>[t(m,{size:54,src:e.contact.avatar},null,8,["src"])]),header:n(()=>[i("span",le,[t(d,{onClick:o[0]||(o[0]=H(()=>{},["stop"])),class:"username-link",to:{name:"user",query:{s:e.contact.username}}},{default:n(()=>[L(v(e.contact.nickname),1)]),_:1},8,["to"])]),i("span",pe," @"+v(e.contact.username),1),i("div",ue,[i("span",me," UID. "+v(e.contact.user_id),1),i("span",de,v(g(G)(e.contact.created_on))+" 加入 ",1)])]),"header-extra":n(()=>[i("div",fe,[t(k,{placement:"bottom-end",trigger:"click",size:"small",options:l.value,onSelect:u},{default:n(()=>[t(w,{quaternary:"",circle:""},{icon:n(()=>[t(g(x),null,{default:n(()=>[t(g(Q))]),_:1})]),_:1})]),_:1},8,["options"])])]),_:1})])}}});const ge=q(ve,[["__scopeId","data-v-d62f19da"]]),he={key:0,class:"skeleton-wrap"},we={key:1},ke={key:0,class:"empty-wrap"},ye={key:0,class:"pagination-wrap"},be=N({__name:"Contacts",setup(b){const h=ie(),_=_e(),r=a(!1),l=a([]),u=a(+_.query.p||1),e=a(20),o=a(0),m=a(!1),d=a({id:0,avatar:"",username:"",nickname:"",is_admin:!1,is_friend:!0,is_following:!1,created_on:0,follows:0,followings:0,status:1}),w=p=>{d.value=p,m.value=!0},k=()=>{m.value=!1},y=p=>{u.value=p,C()};U(()=>{C()});const C=(p=!1)=>{l.value.length===0&&(r.value=!0),se({page:u.value,page_size:e.value}).then(f=>{r.value=!1,l.value=f.list,o.value=Math.ceil(f.pager.total_rows/e.value),p&&setTimeout(()=>{window.scrollTo(0,99999)},50)}).catch(f=>{r.value=!1})};return(p,f)=>{const B=ce,F=ae,M=ne,P=ge,V=oe,D=T,O=ee,R=te;return s(),c(z,null,[i("div",null,[t(B,{title:"好友"}),t(O,{class:"main-content-wrap",bordered:""},{default:n(()=>[r.value?(s(),c("div",he,[t(F,{num:e.value},null,8,["num"])])):(s(),c("div",we,[l.value.length===0?(s(),c("div",ke,[t(M,{size:"large",description:"暂无数据"})])):S("",!0),(s(!0),c(z,null,W(l.value,$=>(s(),E(V,{class:"list-item",key:$.user_id},{default:n(()=>[t(P,{contact:$,onSendWhisper:w},null,8,["contact"])]),_:2},1024))),128))])),t(D,{show:m.value,user:d.value,onSuccess:k},null,8,["show","user"])]),_:1})]),o.value>0?(s(),c("div",ye,[t(R,{page:u.value,"onUpdate:page":y,"page-slot":g(h).state.collapsedRight?5:8,"page-count":o.value},null,8,["page","page-slot","page-count"])])):S("",!0)],64)}}});const Ye=q(be,[["__scopeId","data-v-e20fef94"]]);export{Ye as default};

@ -0,0 +1 @@
.contact-item[data-v-d62f19da]{width:100%;box-sizing:border-box;padding:12px 16px}.contact-item[data-v-d62f19da]:hover{background:#f7f9f9}.contact-item .nickname-wrap[data-v-d62f19da],.contact-item .username-wrap[data-v-d62f19da]{line-height:16px;font-size:16px}.contact-item .top-tag[data-v-d62f19da]{transform:scale(.75)}.contact-item .user-info .info-item[data-v-d62f19da]{font-size:14px;line-height:14px;margin-right:8px;opacity:.75}.contact-item .item-header-extra[data-v-d62f19da]{display:flex;align-items:center;opacity:.75}.dark .contact-item[data-v-d62f19da]{background-color:#101014bf}.dark .contact-item[data-v-d62f19da]:hover{background:#18181c}.pagination-wrap[data-v-e20fef94]{padding:10px;display:flex;justify-content:center;overflow:hidden}.dark .main-content-wrap[data-v-e20fef94],.dark .empty-wrap[data-v-e20fef94],.dark .skeleton-wrap[data-v-e20fef94]{background-color:#101014bf}

@ -1 +0,0 @@
import{u as N,b as P}from"./vue-router-edf90322.js";import{b as Q}from"./formatTime-4210fcd1.js";import{d as k,o,c as s,a as e,V as a,M as l,_ as C,r as c,j as R,a2 as f,O as h,F as y,a5 as S,Q as U}from"./@vue-7e1ab0af.js";import{o as q,F as T,Q as j,H as x,G as E}from"./naive-ui-702193c2.js";import{_ as b,Q as G}from"./index-b4b0f710.js";import{_ as H}from"./post-skeleton-3703f541.js";import{_ as L}from"./main-nav.vue_vue_type_style_index_0_lang-fa3b58e7.js";import{u as O}from"./vuex-f1ee712f.js";import"./moment-2ab8298d.js";import"./seemly-76b7b838.js";import"./vueuc-2fc92f18.js";import"./evtd-b614532e.js";import"./@css-render-16be7445.js";import"./vooks-e23078ea.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-b98681e0.js";/* empty css */const A={class:"avatar"},J={class:"base-info"},K={class:"username"},W={class:"user-info"},X={class:"info-item"},Y={class:"info-item"},Z=k({__name:"contact-item",props:{contact:{}},setup(w){const u=N(),m=t=>{u.push({name:"user",query:{s:t}})};return(t,n)=>{const _=q;return o(),s("div",{class:"contact-item",onClick:n[0]||(n[0]=i=>m(t.contact.username))},[e("div",A,[a(_,{size:54,src:t.contact.avatar},null,8,["src"])]),e("div",J,[e("div",K,[e("strong",null,l(t.contact.nickname),1),e("span",null," @"+l(t.contact.username),1)]),e("div",W,[e("span",X,"UID. "+l(t.contact.user_id),1),e("span",Y,l(C(Q)(t.contact.created_on))+" 加入",1)])])])}}});const tt=b(Z,[["__scopeId","data-v-644d2c15"]]),et={key:0,class:"skeleton-wrap"},ot={key:1},nt={key:0,class:"empty-wrap"},st={key:0,class:"pagination-wrap"},at=k({__name:"Contacts",setup(w){const u=O(),m=P(),t=c(!1),n=c([]),_=c(+m.query.p||1),i=c(20),d=c(0),$=r=>{_.value=r,v()};R(()=>{v()});const v=(r=!1)=>{n.value.length===0&&(t.value=!0),G({page:_.value,page_size:i.value}).then(p=>{t.value=!1,n.value=p.list,d.value=Math.ceil(p.pager.total_rows/i.value),r&&setTimeout(()=>{window.scrollTo(0,99999)},50)}).catch(p=>{t.value=!1})};return(r,p)=>{const z=L,B=H,I=x,V=tt,D=E,F=T,M=j;return o(),s(y,null,[e("div",null,[a(z,{title:"好友"}),a(F,{class:"main-content-wrap",bordered:""},{default:f(()=>[t.value?(o(),s("div",et,[a(B,{num:i.value},null,8,["num"])])):(o(),s("div",ot,[n.value.length===0?(o(),s("div",nt,[a(I,{size:"large",description:"暂无数据"})])):h("",!0),(o(!0),s(y,null,S(n.value,g=>(o(),U(D,{key:g.user_id},{default:f(()=>[a(V,{contact:g},null,8,["contact"])]),_:2},1024))),128))]))]),_:1})]),d.value>0?(o(),s("div",st,[a(M,{page:_.value,"onUpdate:page":$,"page-slot":C(u).state.collapsedRight?5:8,"page-count":d.value},null,8,["page","page-slot","page-count"])])):h("",!0)],64)}}});const Mt=b(at,[["__scopeId","data-v-3b2bf978"]]);export{Mt as default};

@ -1 +0,0 @@
.contact-item[data-v-644d2c15]{display:flex;width:100%;padding:12px 16px}.contact-item[data-v-644d2c15]:hover{background:#f7f9f9;cursor:pointer}.contact-item .avatar[data-v-644d2c15]{width:54px}.contact-item .base-info[data-v-644d2c15]{position:relative;margin-left:12px;padding-top:2px;width:calc(100% - 66px)}.contact-item .base-info .username[data-v-644d2c15]{line-height:16px;font-size:16px}.contact-item .base-info .user-info[data-v-644d2c15]{margin-top:6px}.contact-item .base-info .user-info .info-item[data-v-644d2c15]{font-size:14px;line-height:14px;margin-right:8px;opacity:.75}.dark .contact-item[data-v-644d2c15]{background-color:#101014bf}.dark .contact-item[data-v-644d2c15]:hover{background:#18181c}.pagination-wrap[data-v-3b2bf978]{padding:10px;display:flex;justify-content:center;overflow:hidden}.dark .main-content-wrap[data-v-3b2bf978],.dark .empty-wrap[data-v-3b2bf978],.dark .skeleton-wrap[data-v-3b2bf978]{background-color:#101014bf}

File diff suppressed because one or more lines are too long

@ -1 +0,0 @@
.follow-item[data-v-64f1874c]{display:border-box;width:100%;padding:12px 16px}.follow-item[data-v-64f1874c]:hover{background:#f7f9f9}.follow-item .nickname-wrap[data-v-64f1874c],.follow-item .username-wrap[data-v-64f1874c]{line-height:16px;font-size:16px}.follow-item .top-tag[data-v-64f1874c]{transform:scale(.75)}.follow-item .user-info .info-item[data-v-64f1874c]{font-size:14px;line-height:14px;margin-right:8px;opacity:.75}.follow-item .item-header-extra[data-v-64f1874c]{display:flex;align-items:center;opacity:.75}.dark .follow-item[data-v-64f1874c]{background-color:#101014bf}.dark .follow-item[data-v-64f1874c]:hover{background:#18181c}.main-content-wrap[data-v-1f0f223d]{padding:20px}.pagination-wrap[data-v-1f0f223d]{padding:10px;display:flex;justify-content:center;overflow:hidden}.dark .main-content-wrap[data-v-1f0f223d],.dark .empty-wrap[data-v-1f0f223d],.dark .skeleton-wrap[data-v-1f0f223d]{background-color:#101014bf}

@ -0,0 +1 @@
.follow-item[data-v-1fb7364a]{display:border-box;width:100%;padding:12px 16px}.follow-item[data-v-1fb7364a]:hover{background:#f7f9f9}.follow-item .nickname-wrap[data-v-1fb7364a],.follow-item .username-wrap[data-v-1fb7364a]{line-height:16px;font-size:16px}.follow-item .top-tag[data-v-1fb7364a]{transform:scale(.75)}.follow-item .user-info .info-item[data-v-1fb7364a]{font-size:14px;line-height:14px;margin-right:8px;opacity:.75}.follow-item .item-header-extra[data-v-1fb7364a]{display:flex;align-items:center;opacity:.75}.dark .follow-item[data-v-1fb7364a]{background-color:#101014bf}.dark .follow-item[data-v-1fb7364a]:hover{background:#18181c}.main-content-wrap[data-v-0a10234f]{padding:20px}.pagination-wrap[data-v-0a10234f]{padding:10px;display:flex;justify-content:center;overflow:hidden}.dark .main-content-wrap[data-v-0a10234f],.dark .empty-wrap[data-v-0a10234f],.dark .skeleton-wrap[data-v-0a10234f]{background-color:#101014bf}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
.compose-wrap{width:100%;padding:16px;box-sizing:border-box}.compose-wrap .compose-line{display:flex;flex-direction:row}.compose-wrap .compose-line .compose-user{width:42px;height:42px;display:flex;align-items:center}.compose-wrap .compose-line.compose-options{margin-top:6px;padding-left:42px;display:flex;justify-content:space-between}.compose-wrap .compose-line.compose-options .submit-wrap{display:flex;align-items:center}.compose-wrap .compose-line.compose-options .submit-wrap .text-statistic{margin-right:8px;width:20px;height:20px;transform:rotate(180deg)}.compose-wrap .link-wrap{margin-left:42px;margin-right:42px}.compose-wrap .eye-wrap{margin-left:64px}.compose-wrap .login-only-wrap{display:flex;justify-content:center;width:100%}.compose-wrap .login-only-wrap button{margin:0 4px;width:50%}.compose-wrap .login-wrap{display:flex;justify-content:center;width:100%}.compose-wrap .login-wrap .login-banner{margin-bottom:12px;opacity:.8}.compose-wrap .login-wrap button{margin:0 4px}.attachment-list-wrap{margin-top:12px;margin-left:42px}.attachment-list-wrap .n-upload-file-info__thumbnail{overflow:hidden}.dark .compose-wrap{background-color:#101014bf}.tiny-slide-bar .tiny-slide-bar__list>div.tiny-slide-bar__select .slide-bar-item .slide-bar-item-title[data-v-899c075b]{color:#18a058;opacity:.8}.tiny-slide-bar .tiny-slide-bar__list>div:hover .slide-bar-item[data-v-899c075b]{cursor:pointer}.tiny-slide-bar .tiny-slide-bar__list>div:hover .slide-bar-item .slide-bar-item-avatar[data-v-899c075b]{color:#18a058;opacity:.8}.tiny-slide-bar .tiny-slide-bar__list>div:hover .slide-bar-item .slide-bar-item-title[data-v-899c075b]{color:#18a058;opacity:.8}.tiny-slide-bar[data-v-899c075b]{margin-top:-30px;margin-bottom:-30px}.tiny-slide-bar .slide-bar-item[data-v-899c075b]{min-height:170px;width:64px;display:flex;flex-direction:column;justify-content:center;align-items:center;margin-top:8px}.tiny-slide-bar .slide-bar-item .slide-bar-item-title[data-v-899c075b]{justify-content:center;font-size:12px;margin-top:4px;height:40px}.load-more[data-v-899c075b]{margin:20px}.load-more .load-more-wrap[data-v-899c075b]{display:flex;flex-direction:row;justify-content:center;align-items:center;gap:14px}.load-more .load-more-wrap .load-more-spinner[data-v-899c075b]{font-size:14px;opacity:.65}.dark .main-content-wrap[data-v-899c075b],.dark .pagination-wrap[data-v-899c075b],.dark .empty-wrap[data-v-899c075b],.dark .skeleton-wrap[data-v-899c075b]{background-color:#101014bf}.dark .tiny-slide-bar .tiny-slide-bar__list>div.tiny-slide-bar__select .slide-bar-item .slide-bar-item-title[data-v-899c075b]{color:#63e2b7;opacity:.8}.dark .tiny-slide-bar .tiny-slide-bar__list>div:hover .slide-bar-item .slide-bar-item-title[data-v-899c075b]{color:#63e2b7;opacity:.8}

File diff suppressed because one or more lines are too long

@ -1 +0,0 @@
.compose-wrap{width:100%;padding:16px;box-sizing:border-box}.compose-wrap .compose-line{display:flex;flex-direction:row}.compose-wrap .compose-line .compose-user{width:42px;height:42px;display:flex;align-items:center}.compose-wrap .compose-line.compose-options{margin-top:6px;padding-left:42px;display:flex;justify-content:space-between}.compose-wrap .compose-line.compose-options .submit-wrap{display:flex;align-items:center}.compose-wrap .compose-line.compose-options .submit-wrap .text-statistic{margin-right:8px;width:20px;height:20px;transform:rotate(180deg)}.compose-wrap .link-wrap{margin-left:42px;margin-right:42px}.compose-wrap .eye-wrap{margin-left:64px}.compose-wrap .login-only-wrap{display:flex;justify-content:center;width:100%}.compose-wrap .login-only-wrap button{margin:0 4px;width:50%}.compose-wrap .login-wrap{display:flex;justify-content:center;width:100%}.compose-wrap .login-wrap .login-banner{margin-bottom:12px;opacity:.8}.compose-wrap .login-wrap button{margin:0 4px}.attachment-list-wrap{margin-top:12px;margin-left:42px}.attachment-list-wrap .n-upload-file-info__thumbnail{overflow:hidden}.dark .compose-wrap{background-color:#101014bf}.load-more[data-v-8f151fd6]{margin:20px}.load-more .load-more-wrap[data-v-8f151fd6]{display:flex;flex-direction:row;justify-content:center;align-items:center;gap:14px}.load-more .load-more-wrap .load-more-spinner[data-v-8f151fd6]{font-size:14px;opacity:.65}.dark .main-content-wrap[data-v-8f151fd6],.dark .pagination-wrap[data-v-8f151fd6],.dark .empty-wrap[data-v-8f151fd6],.dark .skeleton-wrap[data-v-8f151fd6]{background-color:#101014bf}

@ -1 +1 @@
var L=(A=>(A[A.TITLE=1]="TITLE",A[A.TEXT=2]="TEXT",A[A.IMAGEURL=3]="IMAGEURL",A[A.VIDEOURL=4]="VIDEOURL",A[A.AUDIOURL=5]="AUDIOURL",A[A.LINKURL=6]="LINKURL",A[A.ATTACHMENT=7]="ATTACHMENT",A[A.CHARGEATTACHMENT=8]="CHARGEATTACHMENT",A))(L||{}),R=(A=>(A[A.PUBLIC=0]="PUBLIC",A[A.PRIVATE=1]="PRIVATE",A[A.FRIEND=2]="FRIEND",A))(R||{}),U=(A=>(A[A.NO=0]="NO",A[A.YES=1]="YES",A))(U||{});export{L as P,R as V,U as Y};
var L=(A=>(A[A.TITLE=1]="TITLE",A[A.TEXT=2]="TEXT",A[A.IMAGEURL=3]="IMAGEURL",A[A.VIDEOURL=4]="VIDEOURL",A[A.AUDIOURL=5]="AUDIOURL",A[A.LINKURL=6]="LINKURL",A[A.ATTACHMENT=7]="ATTACHMENT",A[A.CHARGEATTACHMENT=8]="CHARGEATTACHMENT",A))(L||{}),R=(A=>(A[A.PUBLIC=0]="PUBLIC",A[A.PRIVATE=1]="PRIVATE",A[A.FRIEND=2]="FRIEND",A[A.Following=3]="Following",A))(R||{}),U=(A=>(A[A.NO=0]="NO",A[A.YES=1]="YES",A))(U||{});export{L as P,R as V,U as Y};

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
.message-item[data-v-2e510758]{padding:16px}.message-item.unread[data-v-2e510758]{background:#fcfffc}.message-item .sender-wrap[data-v-2e510758]{display:flex;align-items:center}.message-item .sender-wrap .top-tag[data-v-2e510758]{transform:scale(.75)}.message-item .sender-wrap .username[data-v-2e510758]{opacity:.75;font-size:14px}.message-item .timestamp[data-v-2e510758]{opacity:.75;font-size:12px;display:flex;align-items:center}.message-item .timestamp .timestamp-txt[data-v-2e510758]{margin-left:6px}.message-item .brief-wrap[data-v-2e510758]{margin-top:10px}.message-item .brief-wrap .brief-content[data-v-2e510758],.message-item .brief-wrap .whisper-content-wrap[data-v-2e510758],.message-item .brief-wrap .requesting-friend-wrap[data-v-2e510758]{display:flex;width:100%}.message-item .view-link[data-v-2e510758]{margin-left:8px;display:flex;align-items:center}.message-item .status-info[data-v-2e510758]{margin-left:8px;align-items:center}.dark .message-item[data-v-2e510758]{background-color:#101014bf}.dark .message-item.unread[data-v-2e510758]{background:#0f180b}.dark .message-item .brief-wrap[data-v-2e510758]{background-color:#18181c}.skeleton-item[data-v-01d2e871]{padding:12px;display:flex}.skeleton-item .content[data-v-01d2e871]{width:100%}.dark .skeleton-item[data-v-01d2e871]{background-color:#101014bf}.pagination-wrap[data-v-b40dcbaf]{padding:10px;display:flex;justify-content:center;overflow:hidden}.dark .empty-wrap[data-v-b40dcbaf],.dark .messages-wrap[data-v-b40dcbaf],.dark .pagination-wrap[data-v-b40dcbaf]{background-color:#101014bf}

File diff suppressed because one or more lines are too long

@ -1 +0,0 @@
.message-item[data-v-07fc447f]{padding:16px}.message-item.unread[data-v-07fc447f]{background:#fcfffc}.message-item .sender-wrap[data-v-07fc447f]{display:flex;align-items:center}.message-item .sender-wrap .username[data-v-07fc447f]{opacity:.75;font-size:14px}.message-item .timestamp[data-v-07fc447f]{opacity:.75;font-size:12px;display:flex;align-items:center}.message-item .timestamp .timestamp-txt[data-v-07fc447f]{margin-left:6px}.message-item .brief-wrap[data-v-07fc447f]{margin-top:10px}.message-item .brief-wrap .brief-content[data-v-07fc447f],.message-item .brief-wrap .whisper-content-wrap[data-v-07fc447f],.message-item .brief-wrap .requesting-friend-wrap[data-v-07fc447f]{display:flex;width:100%}.message-item .view-link[data-v-07fc447f]{margin-left:8px;display:flex;align-items:center}.message-item .status-info[data-v-07fc447f]{margin-left:8px;align-items:center}.dark .message-item[data-v-07fc447f]{background-color:#101014bf}.dark .message-item.unread[data-v-07fc447f]{background:#0f180b}.dark .message-item .brief-wrap[data-v-07fc447f]{background-color:#18181c}.skeleton-item[data-v-01d2e871]{padding:12px;display:flex}.skeleton-item .content[data-v-01d2e871]{width:100%}.dark .skeleton-item[data-v-01d2e871]{background-color:#101014bf}.pagination-wrap[data-v-4e7b1342]{padding:10px;display:flex;justify-content:center;overflow:hidden}.dark .empty-wrap[data-v-4e7b1342],.dark .messages-wrap[data-v-4e7b1342],.dark .pagination-wrap[data-v-4e7b1342]{background-color:#101014bf}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
.profile-baseinfo[data-v-756dadd0]{display:flex;padding:16px}.profile-baseinfo .avatar[data-v-756dadd0]{width:72px}.profile-baseinfo .base-info[data-v-756dadd0]{position:relative;margin-left:12px;width:calc(100% - 84px)}.profile-baseinfo .base-info .username[data-v-756dadd0]{line-height:16px;font-size:16px}.profile-baseinfo .base-info .userinfo[data-v-756dadd0]{font-size:14px;line-height:14px;margin-top:10px;opacity:.75}.profile-baseinfo .base-info .userinfo .info-item[data-v-756dadd0]{margin-right:12px}.profile-baseinfo .base-info .top-tag[data-v-756dadd0]{transform:scale(.75)}.profile-tabs-wrap[data-v-756dadd0]{padding:0 16px}.load-more[data-v-756dadd0]{margin:20px}.load-more .load-more-wrap[data-v-756dadd0]{display:flex;flex-direction:row;justify-content:center;align-items:center;gap:14px}.load-more .load-more-wrap .load-more-spinner[data-v-756dadd0]{font-size:14px;opacity:.65}.dark .profile-wrap[data-v-756dadd0],.dark .pagination-wrap[data-v-756dadd0]{background-color:#101014bf}

@ -1 +0,0 @@
.profile-baseinfo[data-v-0542f078]{display:flex;padding:16px}.profile-baseinfo .avatar[data-v-0542f078]{width:72px}.profile-baseinfo .base-info[data-v-0542f078]{position:relative;margin-left:12px;width:calc(100% - 84px)}.profile-baseinfo .base-info .username[data-v-0542f078]{line-height:16px;font-size:16px}.profile-baseinfo .base-info .userinfo[data-v-0542f078]{font-size:14px;line-height:14px;margin-top:10px;opacity:.75}.profile-baseinfo .base-info .userinfo .info-item[data-v-0542f078]{margin-right:12px}.profile-baseinfo .base-info .top-tag[data-v-0542f078]{transform:scale(.75)}.profile-tabs-wrap[data-v-0542f078]{padding:0 16px}.load-more[data-v-0542f078]{margin:20px}.load-more .load-more-wrap[data-v-0542f078]{display:flex;flex-direction:row;justify-content:center;align-items:center;gap:14px}.load-more .load-more-wrap .load-more-spinner[data-v-0542f078]{font-size:14px;opacity:.65}.dark .profile-wrap[data-v-0542f078],.dark .pagination-wrap[data-v-0542f078]{background-color:#101014bf}

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
import{z as $,A as I,B as M,C as O,_ as x}from"./index-d9671de1.js";import{x as U}from"./@vicons-7a4ef312.js";import{d as F,H as i,c as A,b as q,r as j,e as c,f as _,k as n,w as s,q as b,A as B,x as f,Y as p,bf as h,E as D,al as H,F as Y,u as G}from"./@vue-a481fc63.js";import{o as J,M as C,j as K,e as P,O as Q,L as R,F as W,f as X,g as Z,a as ee,k as oe}from"./naive-ui-d8de3dda.js";import{_ as te}from"./main-nav.vue_vue_type_style_index_0_lang-5497f713.js";import{u as ne}from"./vuex-44de225f.js";import"./vue-router-e5a2430e.js";import"./axios-4a70c6fc.js";/* empty css */import"./seemly-76b7b838.js";import"./vueuc-39372edb.js";import"./evtd-b614532e.js";import"./@css-render-7124a1a5.js";import"./vooks-6d99783e.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 se={key:0,class:"tag-item"},ae={key:0,class:"tag-quote"},ce={key:1,class:"tag-quote tag-follow"},le={key:0,class:"options"},ie=F({__name:"tag-item",props:{tag:{},showAction:{type:Boolean},checkFollowing:{type:Boolean}},setup(T){const t=T,r=i(!1),m=A(()=>{let e=[];return t.tag.is_following===0?e.push({label:"关注",key:"follow"}):(t.tag.is_top===0?e.push({label:"置顶",key:"stick"}):e.push({label:"取消置顶",key:"unstick"}),e.push({label:"取消关注",key:"unfollow"})),e}),l=e=>{switch(e){case"follow":M({topic_id:t.tag.id}).then(o=>{t.tag.is_following=1,window.$message.success("关注成功")}).catch(o=>{console.log(o)});break;case"unfollow":I({topic_id:t.tag.id}).then(o=>{t.tag.is_following=0,window.$message.success("取消关注")}).catch(o=>{console.log(o)});break;case"stick":$({topic_id:t.tag.id}).then(o=>{t.tag.is_top=o.top_status,window.$message.success("置顶成功")}).catch(o=>{console.log(o)});break;case"unstick":$({topic_id:t.tag.id}).then(o=>{t.tag.is_top=o.top_status,window.$message.success("取消置顶")}).catch(o=>{console.log(o)});break}};return q(()=>{r.value=!1}),(e,o)=>{const w=j("router-link"),g=J,k=C,a=K,d=P,v=Q,u=R;return!e.checkFollowing||e.checkFollowing&&e.tag.is_following===1?(c(),_("div",se,[n(u,null,{header:s(()=>[(c(),b(k,{type:"success",size:"large",round:"",key:e.tag.id},{avatar:s(()=>[n(g,{src:e.tag.user.avatar},null,8,["src"])]),default:s(()=>[n(w,{class:"hash-link",to:{name:"home",query:{q:e.tag.tag,t:"tag"}}},{default:s(()=>[B(" #"+f(e.tag.tag),1)]),_:1},8,["to"]),e.showAction?p("",!0):(c(),_("span",ae,"("+f(e.tag.quote_num)+")",1)),e.showAction?(c(),_("span",ce,"("+f(e.tag.quote_num)+")",1)):p("",!0)]),_:1}))]),"header-extra":s(()=>[e.showAction?(c(),_("div",le,[n(v,{placement:"bottom-end",trigger:"click",size:"small",options:m.value,onSelect:l},{default:s(()=>[n(d,{type:"success",quaternary:"",circle:"",block:""},{icon:s(()=>[n(a,null,{default:s(()=>[n(h(U))]),_:1})]),_:1})]),_:1},8,["options"])])):p("",!0)]),_:1})])):p("",!0)}}});const _e=F({__name:"Topic",setup(T){const t=ne(),r=i([]),m=i("hot"),l=i(!1),e=i(!1),o=i(!1);D(e,()=>{e.value||(window.$message.success("保存成功"),t.commit("refreshTopicFollow"))});const w=A({get:()=>{let a="编辑";return e.value&&(a="保存"),a},set:a=>{}}),g=()=>{l.value=!0,O({type:m.value,num:50}).then(a=>{r.value=a.topics,l.value=!1}).catch(a=>{console.log(a),l.value=!1})},k=a=>{m.value=a,a=="follow"?o.value=!0:o.value=!1,g()};return q(()=>{g()}),(a,d)=>{const v=te,u=X,L=C,V=Z,N=ie,S=ee,z=oe,E=W;return c(),_("div",null,[n(v,{title:"话题"}),n(E,{class:"main-content-wrap tags-wrap",bordered:""},{default:s(()=>[n(V,{type:"line",animated:"","onUpdate:value":k},H({default:s(()=>[n(u,{name:"hot",tab:"热门"}),n(u,{name:"new",tab:"最新"}),h(t).state.userLogined?(c(),b(u,{key:0,name:"follow",tab:"关注"})):p("",!0)]),_:2},[h(t).state.userLogined?{name:"suffix",fn:s(()=>[n(L,{checked:e.value,"onUpdate:checked":d[0]||(d[0]=y=>e.value=y),checkable:""},{default:s(()=>[B(f(w.value),1)]),_:1},8,["checked"])]),key:"0"}:void 0]),1024),n(z,{show:l.value},{default:s(()=>[n(S,null,{default:s(()=>[(c(!0),_(Y,null,G(r.value,y=>(c(),b(N,{tag:y,showAction:h(t).state.userLogined&&e.value,checkFollowing:o.value},null,8,["tag","showAction","checkFollowing"]))),256))]),_:1})]),_:1},8,["show"])]),_:1})])}}});const Ne=x(_e,[["__scopeId","data-v-1fb31ecf"]]);export{Ne as default};

@ -1 +0,0 @@
import{x as $,y as z,z as I,A as j,_ as E}from"./index-b4b0f710.js";import{v as U}from"./@vicons-b98681e0.js";import{d as F,r as i,n as A,j as q,a4 as x,o as c,c as _,V as n,a2 as s,Q as b,e as V,M as f,O as u,_ as h,w as D,a8 as Q,F as G,a5 as H}from"./@vue-7e1ab0af.js";import{o as J,M as B,j as K,e as P,O as R,L as W,F as X,f as Y,g as Z,a as ee,k as oe}from"./naive-ui-702193c2.js";import{_ as te}from"./main-nav.vue_vue_type_style_index_0_lang-fa3b58e7.js";import{u as ne}from"./vuex-f1ee712f.js";import"./vue-router-edf90322.js";import"./axios-4a70c6fc.js";/* empty css */import"./seemly-76b7b838.js";import"./vueuc-2fc92f18.js";import"./evtd-b614532e.js";import"./@css-render-16be7445.js";import"./vooks-e23078ea.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 se={key:0,class:"tag-item"},ae={key:0,class:"tag-quote"},ce={key:1,class:"tag-quote tag-follow"},le={key:0,class:"options"},ie=F({__name:"tag-item",props:{tag:{},showAction:{type:Boolean},checkFollowing:{type:Boolean}},setup(T){const t=T,r=i(!1),m=A(()=>{let e=[];return t.tag.is_following===0?e.push({label:"关注",key:"follow"}):(t.tag.is_top===0?e.push({label:"置顶",key:"stick"}):e.push({label:"取消置顶",key:"unstick"}),e.push({label:"取消关注",key:"unfollow"})),e}),l=e=>{switch(e){case"follow":I({topic_id:t.tag.id}).then(o=>{t.tag.is_following=1,window.$message.success("关注成功")}).catch(o=>{console.log(o)});break;case"unfollow":z({topic_id:t.tag.id}).then(o=>{t.tag.is_following=0,window.$message.success("取消关注")}).catch(o=>{console.log(o)});break;case"stick":$({topic_id:t.tag.id}).then(o=>{t.tag.is_top=o.top_status,window.$message.success("置顶成功")}).catch(o=>{console.log(o)});break;case"unstick":$({topic_id:t.tag.id}).then(o=>{t.tag.is_top=o.top_status,window.$message.success("取消置顶")}).catch(o=>{console.log(o)});break}};return q(()=>{r.value=!1}),(e,o)=>{const w=x("router-link"),g=J,k=B,a=K,d=P,v=R,p=W;return!e.checkFollowing||e.checkFollowing&&e.tag.is_following===1?(c(),_("div",se,[n(p,null,{header:s(()=>[(c(),b(k,{type:"success",size:"large",round:"",key:e.tag.id},{avatar:s(()=>[n(g,{src:e.tag.user.avatar},null,8,["src"])]),default:s(()=>[n(w,{class:"hash-link",to:{name:"home",query:{q:e.tag.tag,t:"tag"}}},{default:s(()=>[V(" #"+f(e.tag.tag),1)]),_:1},8,["to"]),e.showAction?u("",!0):(c(),_("span",ae,"("+f(e.tag.quote_num)+")",1)),e.showAction?(c(),_("span",ce,"("+f(e.tag.quote_num)+")",1)):u("",!0)]),_:1}))]),"header-extra":s(()=>[e.showAction?(c(),_("div",le,[n(v,{placement:"bottom-end",trigger:"click",size:"small",options:m.value,onSelect:l},{default:s(()=>[n(d,{type:"success",quaternary:"",circle:"",block:""},{icon:s(()=>[n(a,null,{default:s(()=>[n(h(U))]),_:1})]),_:1})]),_:1},8,["options"])])):u("",!0)]),_:1})])):u("",!0)}}});const _e=F({__name:"Topic",setup(T){const t=ne(),r=i([]),m=i("hot"),l=i(!1),e=i(!1),o=i(!1);D(e,()=>{e.value||(window.$message.success("保存成功"),t.commit("refreshTopicFollow"))});const w=A({get:()=>{let a="编辑";return e.value&&(a="保存"),a},set:a=>{}}),g=()=>{l.value=!0,j({type:m.value,num:50}).then(a=>{r.value=a.topics,l.value=!1}).catch(a=>{console.log(a),l.value=!1})},k=a=>{m.value=a,a=="follow"?o.value=!0:o.value=!1,g()};return q(()=>{g()}),(a,d)=>{const v=te,p=Y,C=B,L=Z,M=ie,N=ee,O=oe,S=X;return c(),_("div",null,[n(v,{title:"话题"}),n(S,{class:"main-content-wrap tags-wrap",bordered:""},{default:s(()=>[n(L,{type:"line",animated:"","onUpdate:value":k},Q({default:s(()=>[n(p,{name:"hot",tab:"热门"}),n(p,{name:"new",tab:"最新"}),h(t).state.userLogined?(c(),b(p,{key:0,name:"follow",tab:"关注"})):u("",!0)]),_:2},[h(t).state.userLogined?{name:"suffix",fn:s(()=>[n(C,{checked:e.value,"onUpdate:checked":d[0]||(d[0]=y=>e.value=y),checkable:""},{default:s(()=>[V(f(w.value),1)]),_:1},8,["checked"])]),key:"0"}:void 0]),1024),n(O,{show:l.value},{default:s(()=>[n(N,null,{default:s(()=>[(c(!0),_(G,null,H(r.value,y=>(c(),b(M,{tag:y,showAction:h(t).state.userLogined&&e.value,checkFollowing:o.value},null,8,["tag","showAction","checkFollowing"]))),256))]),_:1})]),_:1},8,["show"])]),_:1})])}}});const Me=E(_e,[["__scopeId","data-v-1fb31ecf"]]);export{Me as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
.whisper-wrap .whisper-line[data-v-60be56a2]{margin-top:10px}.whisper-wrap .whisper-line.send-wrap .n-button[data-v-60be56a2]{width:100%}.dark .whisper-wrap[data-v-60be56a2]{background-color:#101014bf}.profile-tabs-wrap[data-v-ebc19734]{padding:0 16px}.profile-baseinfo[data-v-ebc19734]{display:flex;padding:16px}.profile-baseinfo .avatar[data-v-ebc19734]{width:72px}.profile-baseinfo .base-info[data-v-ebc19734]{position:relative;margin-left:12px;width:calc(100% - 84px)}.profile-baseinfo .base-info .username[data-v-ebc19734]{line-height:16px;font-size:16px}.profile-baseinfo .base-info .userinfo[data-v-ebc19734]{font-size:14px;line-height:14px;margin-top:10px;opacity:.75}.profile-baseinfo .base-info .userinfo .info-item[data-v-ebc19734]{margin-right:12px}.profile-baseinfo .base-info .top-tag[data-v-ebc19734]{transform:scale(.75)}.profile-baseinfo .user-opts[data-v-ebc19734]{position:absolute;top:16px;right:16px;opacity:.75}.load-more[data-v-ebc19734]{margin:20px}.load-more .load-more-wrap[data-v-ebc19734]{display:flex;flex-direction:row;justify-content:center;align-items:center;gap:14px}.load-more .load-more-wrap .load-more-spinner[data-v-ebc19734]{font-size:14px;opacity:.65}.dark .profile-wrap[data-v-ebc19734],.dark .pagination-wrap[data-v-ebc19734]{background-color:#101014bf}

@ -1 +0,0 @@
.whisper-wrap .whisper-line[data-v-0cbfe47c]{margin-top:10px}.whisper-wrap .whisper-line.send-wrap .n-button[data-v-0cbfe47c]{width:100%}.dark .whisper-wrap[data-v-0cbfe47c]{background-color:#101014bf}.whisper-wrap .whisper-line[data-v-60be56a2]{margin-top:10px}.whisper-wrap .whisper-line.send-wrap .n-button[data-v-60be56a2]{width:100%}.dark .whisper-wrap[data-v-60be56a2]{background-color:#101014bf}.profile-tabs-wrap[data-v-17f0dc61]{padding:0 16px}.profile-baseinfo[data-v-17f0dc61]{display:flex;padding:16px}.profile-baseinfo .avatar[data-v-17f0dc61]{width:72px}.profile-baseinfo .base-info[data-v-17f0dc61]{position:relative;margin-left:12px;width:calc(100% - 84px)}.profile-baseinfo .base-info .username[data-v-17f0dc61]{line-height:16px;font-size:16px}.profile-baseinfo .base-info .userinfo[data-v-17f0dc61]{font-size:14px;line-height:14px;margin-top:10px;opacity:.75}.profile-baseinfo .base-info .userinfo .info-item[data-v-17f0dc61]{margin-right:12px}.profile-baseinfo .base-info .top-tag[data-v-17f0dc61]{transform:scale(.75)}.profile-baseinfo .user-opts[data-v-17f0dc61]{position:absolute;top:16px;right:16px;opacity:.75}.load-more[data-v-17f0dc61]{margin:20px}.load-more .load-more-wrap[data-v-17f0dc61]{display:flex;flex-direction:row;justify-content:center;align-items:center;gap:14px}.load-more .load-more-wrap .load-more-spinner[data-v-17f0dc61]{font-size:14px;opacity:.65}.dark .profile-wrap[data-v-17f0dc61],.dark .pagination-wrap[data-v-17f0dc61]{background-color:#101014bf}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

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

Loading…
Cancel
Save