merge from x/gorm branch

r/paopao-ce-pro
Michael Li 2 years ago
commit 078fdd8437
No known key found for this signature in database

@ -30,6 +30,50 @@ All notable changes to paopao-ce are documented in this file.
# 模块开启 # 模块开启
VITE_ENABLE_FRIENDS_BAR=true VITE_ENABLE_FRIENDS_BAR=true
``` ```
- add Newest/Hots/Following tweets support in friend bar feature.
mirgration database first(sql ddl file in `scripts/migration/**/*_home_timeline.up.sql`):
```sql
CREATE TABLE `p_post_metric` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`post_id` bigint unsigned NOT NULL,
`rank_score` bigint unsigned NOT NULL DEFAULT 0,
`incentive_score` int unsigned NOT NULL DEFAULT 0,
`decay_factor` int unsigned NOT NULL DEFAULT 0,
`motivation_factor` int unsigned NOT NULL DEFAULT 0,
`is_del` tinyint NOT NULL DEFAULT 0, -- 是否删除, 0否, 1是
`created_on` bigint unsigned NOT NULL DEFAULT '0',
`modified_on` bigint unsigned NOT NULL DEFAULT '0',
`deleted_on` bigint unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_post_metric_post_id_rank_score` (`post_id`,`rank_score`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
INSERT INTO p_post_metric (post_id, rank_score, created_on)
SELECT id AS post_id,
comment_count + upvote_count*2 + collection_count*4 AS rank_score,
created_on
FROM p_post
WHERE is_del=0;
-- 原来的可见性: 0公开 1私密 2好友可见 3关注可见
-- 现在的可见性: 0私密 10充电可见 20订阅可见 30保留 40保留 50好友可见 60关注可见 70保留 80保留 90公开
UPDATE p_post a
SET visibility = (
SELECT
CASE visibility
WHEN 0 THEN 90
WHEN 1 THEN 0
WHEN 2 THEN 50
WHEN 3 THEN 60
ELSE 0
END
FROM
p_post b
WHERE
a.ID = b.ID
);
```sql
- add cache support for index/home etc. page.
## 0.4.2 ## 0.4.2
### Fixed ### Fixed

@ -364,8 +364,8 @@ release/paopao serve --no-default-features --features sqlite3,localoss,loggerfil
|`OSS:TempDir` | 对象存储 | 内测 |基于对象存储系统的对象拷贝/移动特性实现 先创建临时对象再持久化的功能| |`OSS:TempDir` | 对象存储 | 内测 |基于对象存储系统的对象拷贝/移动特性实现 先创建临时对象再持久化的功能|
|`Redis` | 缓存 | 稳定 | Redis缓存功能 | |`Redis` | 缓存 | 稳定 | Redis缓存功能 |
|`SimpleCacheIndex` | 缓存 | Deprecated | 提供简单的 广场推文列表 的缓存功能 | |`SimpleCacheIndex` | 缓存 | Deprecated | 提供简单的 广场推文列表 的缓存功能 |
|`BigCacheIndex` | 缓存 | 稳定(推荐) | 使用[BigCache](https://github.com/allegro/bigcache)缓存 广场推文列表,缓存每个用户每一页,简单做到千人千面 | |`BigCacheIndex` | 缓存 | Deprecated | 使用[BigCache](https://github.com/allegro/bigcache)缓存 广场推文列表,缓存每个用户每一页,简单做到千人千面 |
|`RedisCacheIndex` | 缓存 | 内测(推荐) | 使用Redis缓存 广场推文列表,缓存每个用户每一页,简单做到千人千面 | |`RedisCacheIndex` | 缓存 | Deprecated | 使用Redis缓存 广场推文列表,缓存每个用户每一页,简单做到千人千面 |
|`Zinc` | 搜索 | 稳定(推荐) | 基于[Zinc](https://github.com/zinclabs/zinc)搜索引擎提供推文搜索服务 | |`Zinc` | 搜索 | 稳定(推荐) | 基于[Zinc](https://github.com/zinclabs/zinc)搜索引擎提供推文搜索服务 |
|`Meili` | 搜索 | 稳定(推荐) | 基于[Meilisearch](https://github.com/meilisearch/meilisearch)搜索引擎提供推文搜索服务 | |`Meili` | 搜索 | 稳定(推荐) | 基于[Meilisearch](https://github.com/meilisearch/meilisearch)搜索引擎提供推文搜索服务 |
|`Bleve` | 搜索 | WIP | 基于[Bleve](https://github.com/blevesearch/bleve)搜索引擎提供推文搜索服务 | |`Bleve` | 搜索 | WIP | 基于[Bleve](https://github.com/blevesearch/bleve)搜索引擎提供推文搜索服务 |
@ -384,7 +384,7 @@ release/paopao serve --no-default-features --features sqlite3,localoss,loggerfil
|[`Pprof`](docs/proposal/23062905-添加Pprof功能特性用于获取Profile.md)| 性能优化 | 内测 | 开启Pprof功能收集Profile信息 | |[`Pprof`](docs/proposal/23062905-添加Pprof功能特性用于获取Profile.md)| 性能优化 | 内测 | 开启Pprof功能收集Profile信息 |
|`PhoneBind` | 其他 | 稳定 | 手机绑定功能 | |`PhoneBind` | 其他 | 稳定 | 手机绑定功能 |
|`UseAuditHook` | 其他 | 内测 | 使用审核hook功能 | |`UseAuditHook` | 其他 | 内测 | 使用审核hook功能 |
|`UseJobManager` | 其他 | 内测 | 使用JobManager功能 | |`DisableJobManager` | 其他 | 内测 | 禁止使用JobManager功能 |
|`Web:DisallowUserRegister` | 功能特性 | 稳定 | 不允许用户注册 | |`Web:DisallowUserRegister` | 功能特性 | 稳定 | 不允许用户注册 |
> 功能项状态详情参考 [features-status](features-status.md). > 功能项状态详情参考 [features-status](features-status.md).

@ -109,7 +109,12 @@ func RegisterLooseServant(e *gin.Engine, s Loose) {
return return
} }
resp, err := s.Timeline(req) resp, err := s.Timeline(req)
s.Render(c, resp, err) if err != nil {
s.Render(c, nil, err)
return
}
var rv _render_ = resp
rv.Render(c)
}) })
} }

@ -106,11 +106,11 @@
* [ ] 提按文档 * [ ] 提按文档
* [x] 接口定义 * [x] 接口定义
* [x] 业务逻辑实现 * [x] 业务逻辑实现
* `BigCacheIndex` 使用[BigCache](https://github.com/allegro/bigcache)缓存 广场推文列表,缓存每个用户每一页,简单做到千人千面(推荐使用) * `BigCacheIndex` 使用[BigCache](https://github.com/allegro/bigcache)缓存 广场推文列表,缓存每个用户每一页,简单做到千人千面(目前状态: Deprecated)
* [ ] 提按文档 * [ ] 提按文档
* [x] 接口定义 * [x] 接口定义
* [x] 业务逻辑实现 * [x] 业务逻辑实现
* `RedisCacheIndex` 使用Redis缓存 广场推文列表,缓存每个用户每一页,简单做到千人千面(目前状态: 推荐使用) * `RedisCacheIndex` 使用Redis缓存 广场推文列表,缓存每个用户每一页,简单做到千人千面(目前状态: Deprecated)
* [ ] 提按文档 * [ ] 提按文档
* [x] 接口定义 * [x] 接口定义
* [x] 业务逻辑实现 * [x] 业务逻辑实现
@ -208,7 +208,7 @@
* [x] 接口定义 * [x] 接口定义
* [x] 业务逻辑实现 * [x] 业务逻辑实现
* `UseJobManager` 使用JobManager功能 (目前状态: 内测 待完善后将转为Builtin) * `DisableJobManager` 禁止使用JobManager功能 (目前状态: 内测 待完善后将转为Builtin)
* [ ] 提按文档 * [ ] 提按文档
* [x] 接口定义 * [x] 接口定义
* [x] 业务逻辑实现 * [x] 业务逻辑实现

@ -10,14 +10,14 @@ require (
github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible
github.com/allegro/bigcache/v3 v3.1.0 github.com/allegro/bigcache/v3 v3.1.0
github.com/bufbuild/connect-go v1.10.0 github.com/bufbuild/connect-go v1.10.0
github.com/bytedance/sonic v1.10.0 github.com/bytedance/sonic v1.10.1
github.com/cockroachdb/errors v1.11.1 github.com/cockroachdb/errors v1.11.1
github.com/disintegration/imaging v1.6.2 github.com/disintegration/imaging v1.6.2
github.com/fatih/color v1.15.0 github.com/fatih/color v1.15.0
github.com/getsentry/sentry-go v0.24.0 github.com/getsentry/sentry-go v0.24.1
github.com/gin-contrib/cors v1.4.0 github.com/gin-contrib/cors v1.4.0
github.com/gin-gonic/gin v1.9.1 github.com/gin-gonic/gin v1.9.1
github.com/go-resty/resty/v2 v2.7.0 github.com/go-resty/resty/v2 v2.8.0
github.com/goccy/go-json v0.10.2 github.com/goccy/go-json v0.10.2
github.com/gofrs/uuid/v5 v5.0.0 github.com/gofrs/uuid/v5 v5.0.0
github.com/golang-jwt/jwt/v5 v5.0.0 github.com/golang-jwt/jwt/v5 v5.0.0
@ -25,12 +25,12 @@ require (
github.com/huaweicloud/huaweicloud-sdk-go-obs v3.23.4+incompatible github.com/huaweicloud/huaweicloud-sdk-go-obs v3.23.4+incompatible
github.com/jackc/pgx/v5 v5.4.3 github.com/jackc/pgx/v5 v5.4.3
github.com/json-iterator/go v1.1.12 github.com/json-iterator/go v1.1.12
github.com/meilisearch/meilisearch-go v0.25.0 github.com/meilisearch/meilisearch-go v0.25.1
github.com/minio/minio-go/v7 v7.0.63 github.com/minio/minio-go/v7 v7.0.63
github.com/onsi/ginkgo/v2 v2.12.0 github.com/onsi/ginkgo/v2 v2.12.0
github.com/onsi/gomega v1.27.10 github.com/onsi/gomega v1.27.10
github.com/pyroscope-io/client v0.7.2 github.com/pyroscope-io/client v0.7.2
github.com/redis/rueidis v1.0.17 github.com/redis/rueidis v1.0.18
github.com/robfig/cron/v3 v3.0.1 github.com/robfig/cron/v3 v3.0.1
github.com/sirupsen/logrus v1.9.3 github.com/sirupsen/logrus v1.9.3
github.com/smartwalle/alipay/v3 v3.2.16 github.com/smartwalle/alipay/v3 v3.2.16
@ -41,7 +41,7 @@ require (
github.com/tencentyun/cos-go-sdk-v5 v0.7.43 github.com/tencentyun/cos-go-sdk-v5 v0.7.43
github.com/yinheli/mahonia v0.0.0-20131226213531-0eef680515cc github.com/yinheli/mahonia v0.0.0-20131226213531-0eef680515cc
go.uber.org/automaxprocs v1.5.3 go.uber.org/automaxprocs v1.5.3
google.golang.org/grpc v1.58.0 google.golang.org/grpc v1.58.1
google.golang.org/protobuf v1.31.0 google.golang.org/protobuf v1.31.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1 gopkg.in/natefinch/lumberjack.v2 v2.2.1
gopkg.in/resty.v1 v1.12.0 gopkg.in/resty.v1 v1.12.0
@ -142,14 +142,14 @@ require (
go.uber.org/multierr v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect
go.uber.org/zap v1.21.0 // indirect go.uber.org/zap v1.21.0 // indirect
golang.org/x/arch v0.3.0 // indirect golang.org/x/arch v0.3.0 // indirect
golang.org/x/crypto v0.12.0 // indirect golang.org/x/crypto v0.13.0 // indirect
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
golang.org/x/image v0.0.0-20210216034530-4410531fe030 // indirect golang.org/x/image v0.0.0-20210216034530-4410531fe030 // indirect
golang.org/x/mod v0.12.0 // indirect golang.org/x/mod v0.12.0 // indirect
golang.org/x/net v0.14.0 // indirect golang.org/x/net v0.15.0 // indirect
golang.org/x/sync v0.3.0 // indirect golang.org/x/sync v0.3.0 // indirect
golang.org/x/sys v0.11.0 // indirect golang.org/x/sys v0.12.0 // indirect
golang.org/x/text v0.12.0 // indirect golang.org/x/text v0.13.0 // indirect
golang.org/x/time v0.3.0 // indirect golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.12.0 // indirect golang.org/x/tools v0.12.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect

@ -201,8 +201,8 @@ github.com/bytecodealliance/wasmtime-go/v8 v8.0.0 h1:jP4sqm2PHgm3+eQ50zCoCdIyQFk
github.com/bytecodealliance/wasmtime-go/v8 v8.0.0/go.mod h1:tgazNLU7xSC2gfRAM8L4WyE+dgs5yp9FF5/tGebEQyM= github.com/bytecodealliance/wasmtime-go/v8 v8.0.0/go.mod h1:tgazNLU7xSC2gfRAM8L4WyE+dgs5yp9FF5/tGebEQyM=
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM= github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
github.com/bytedance/sonic v1.10.0 h1:qtNZduETEIWJVIyDl01BeNxur2rW9OwTQ/yBqFRkKEk= github.com/bytedance/sonic v1.10.1 h1:7a1wuFXL1cMy7a3f7/VFcEtriuXQnUBhtoVfOZiaysc=
github.com/bytedance/sonic v1.10.0/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4= github.com/bytedance/sonic v1.10.1/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
@ -466,8 +466,8 @@ github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
github.com/getsentry/sentry-go v0.24.0 h1:02b7qEmJ56EHGe9KFgjArjU/vG/aywm7Efgu+iPc01Y= github.com/getsentry/sentry-go v0.24.1 h1:W6/0GyTy8J6ge6lVCc94WB6Gx2ZuLrgopnn9w8Hiwuk=
github.com/getsentry/sentry-go v0.24.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/getsentry/sentry-go v0.24.1/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gin-contrib/cors v1.4.0 h1:oJ6gwtUl3lqV0WEIwM/LxPF1QZ5qe2lGWdY2+bz7y0g= github.com/gin-contrib/cors v1.4.0 h1:oJ6gwtUl3lqV0WEIwM/LxPF1QZ5qe2lGWdY2+bz7y0g=
@ -528,8 +528,8 @@ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= github.com/go-resty/resty/v2 v2.8.0 h1:J29d0JFWwSWrDCysnOK/YjsPMLQTx0TvgJEHVGvf2L8=
github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= github.com/go-resty/resty/v2 v2.8.0/go.mod h1:UCui0cMHekLrSntoMyofdSTaPpinlRHFtPpizuyDW2w=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
@ -951,8 +951,8 @@ github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY=
github.com/meilisearch/meilisearch-go v0.25.0 h1:xIp+8YWterHuDvpdYlwQ4Qp7im3JlRHmSKiP0NvjyXs= github.com/meilisearch/meilisearch-go v0.25.1 h1:D5wY22sn5kkpRH3uYMGlwltdUEq5regIFmO7awHz3Vo=
github.com/meilisearch/meilisearch-go v0.25.0/go.mod h1:SxuSqDcPBIykjWz1PX+KzsYzArNLSCadQodWs8extS0= github.com/meilisearch/meilisearch-go v0.25.1/go.mod h1:SxuSqDcPBIykjWz1PX+KzsYzArNLSCadQodWs8extS0=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= 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 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
@ -1143,8 +1143,8 @@ 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/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 h1:MdlEmYELd5w+lvIzmZvXGNMVzW2Qc9jDMuJaPOR75g4=
github.com/pyroscope-io/godeltaprof v0.1.2/go.mod h1:psMITXp90+8pFenXkKIpNhrfmI9saQnPbba27VIaiQE= github.com/pyroscope-io/godeltaprof v0.1.2/go.mod h1:psMITXp90+8pFenXkKIpNhrfmI9saQnPbba27VIaiQE=
github.com/redis/rueidis v1.0.17 h1:RyjiBVnPcKxjgiUpkyqbRw/OFJV5vX2bMM/oMPdz8JE= github.com/redis/rueidis v1.0.18 h1:yfqQ22QCfIey+w1LHAp006dlJXwATePVUM+1w2ePrIo=
github.com/redis/rueidis v1.0.17/go.mod h1:8B+r5wdnjwK3lTFml5VtxjzGOQAC+5UmujoD12pDrEo= github.com/redis/rueidis v1.0.18/go.mod h1:8B+r5wdnjwK3lTFml5VtxjzGOQAC+5UmujoD12pDrEo=
github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
@ -1324,6 +1324,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
@ -1427,8 +1428,8 @@ golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -1480,6 +1481,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.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/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.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 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-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -1544,14 +1547,16 @@ golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220111093109-d55c255bac03/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220111093109-d55c255bac03/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/oauth2 v0.0.0-20180227000427-d7d64896b5ff/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180227000427-d7d64896b5ff/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@ -1582,6 +1587,8 @@ 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-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-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.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20180224232135-f6cff0780e54/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180224232135-f6cff0780e54/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -1706,18 +1713,24 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220317061510-51cd9980dadf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220317061510-51cd9980dadf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -1727,8 +1740,10 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -1819,6 +1834,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.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.4/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.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss=
golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= 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-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -1984,8 +2001,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.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.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.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
google.golang.org/grpc v1.58.0 h1:32JY8YpPMSR45K+c3o6b8VL73V+rR8k+DeMIr4vRH8o= google.golang.org/grpc v1.58.1 h1:OL+Vz23DTtrrldqHK49FUOPHyY75rvFqJfXC84NYW58=
google.golang.org/grpc v1.58.0/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= google.golang.org/grpc v1.58.1/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/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-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=

@ -23,6 +23,14 @@ const (
PrefixUserTweets = "paopao:usertweets:" PrefixUserTweets = "paopao:usertweets:"
PrefixUnreadmsg = "paopao:unreadmsg:" PrefixUnreadmsg = "paopao:unreadmsg:"
PrefixOnlineUser = "paopao:onlineuser:" PrefixOnlineUser = "paopao:onlineuser:"
PrefixIdxTweetsNewest = "paopao:index:tweets:newest:"
PrefixIdxTweetsHots = "paopao:index:tweets:hots:"
PrefixIdxTweetsFollowing = "paopao:index:tweets:following:"
PrefixUserInfo = "paopao:userinfo:"
PrefixUserInfoById = "paopao:userinfo:id:"
PrefixUserInfoByName = "paopao:userinfo:name:"
KeySiteStatus = "paopao:sitestatus"
KeyHistoryMaxOnline = "history.max.online"
) )
// 以下包含一些在cache中会用到的池化后的key // 以下包含一些在cache中会用到的池化后的key
@ -32,6 +40,8 @@ var (
KeyFollowingTweets cache.KeyPool[string] KeyFollowingTweets cache.KeyPool[string]
KeyUnreadMsg cache.KeyPool[int64] KeyUnreadMsg cache.KeyPool[int64]
KeyOnlineUser cache.KeyPool[int64] KeyOnlineUser cache.KeyPool[int64]
KeyUserInfoById cache.KeyPool[int64]
KeyUserInfoByName cache.KeyPool[string]
) )
func initCacheKeyPool() { func initCacheKeyPool() {
@ -44,6 +54,8 @@ func initCacheKeyPool() {
KeyFollowingTweets = strKeyPool(poolSize, PrefixFollowingTweets) KeyFollowingTweets = strKeyPool(poolSize, PrefixFollowingTweets)
KeyUnreadMsg = intKeyPool[int64](poolSize, PrefixUnreadmsg) KeyUnreadMsg = intKeyPool[int64](poolSize, PrefixUnreadmsg)
KeyOnlineUser = intKeyPool[int64](poolSize, PrefixOnlineUser) KeyOnlineUser = intKeyPool[int64](poolSize, PrefixOnlineUser)
KeyUserInfoById = intKeyPool[int64](poolSize, PrefixUserInfoById)
KeyUserInfoByName = strKeyPool(poolSize, PrefixUserInfoById)
} }
func strKeyPool(size int, prefix string) cache.KeyPool[string] { func strKeyPool(size int, prefix string) cache.KeyPool[string] {

@ -38,6 +38,7 @@ var (
CacheSetting *cacheConf CacheSetting *cacheConf
EventManagerSetting *eventManagerConf EventManagerSetting *eventManagerConf
MetricManagerSetting *metricManagerConf MetricManagerSetting *metricManagerConf
JobManagerSetting *jobManagerConf
CacheIndexSetting *cacheIndexConf CacheIndexSetting *cacheIndexConf
SimpleCacheIndexSetting *simpleCacheIndexConf SimpleCacheIndexSetting *simpleCacheIndexConf
BigCacheIndexSetting *bigCacheIndexConf BigCacheIndexSetting *bigCacheIndexConf
@ -75,6 +76,7 @@ func setupSetting(suite []string, noDefault bool) error {
"Cache": &CacheSetting, "Cache": &CacheSetting,
"EventManager": &EventManagerSetting, "EventManager": &EventManagerSetting,
"MetricManager": &MetricManagerSetting, "MetricManager": &MetricManagerSetting,
"JobManager": &JobManagerSetting,
"PprofServer": &PprofServerSetting, "PprofServer": &PprofServerSetting,
"WebServer": &WebServerSetting, "WebServer": &WebServerSetting,
"AdminServer": &AdminServerSetting, "AdminServer": &AdminServerSetting,

@ -10,7 +10,9 @@ Cache:
CientSideCacheExpire: 60 # 客户端缓存过期时间 默认60s CientSideCacheExpire: 60 # 客户端缓存过期时间 默认60s
UnreadMsgExpire: 60 # 未读消息过期时间,单位秒, 默认60s UnreadMsgExpire: 60 # 未读消息过期时间,单位秒, 默认60s
UserTweetsExpire: 60 # 获取用户推文列表过期时间,单位秒, 默认60s UserTweetsExpire: 60 # 获取用户推文列表过期时间,单位秒, 默认60s
IndexTweetsExpire: 120 # 获取广场推文列表过期时间,单位秒, 默认120s
OnlineUserExpire: 300 # 标记在线用户 过期时间,单位秒, 默认300s OnlineUserExpire: 300 # 标记在线用户 过期时间,单位秒, 默认300s
UserInfoExpire: 300 # 获取用户信息过期时间,单位秒, 默认300s
EventManager: # 事件管理器的配置参数 EventManager: # 事件管理器的配置参数
MinWorker: 64 # 最小后台工作者, 设置范围[5, ++], 默认64 MinWorker: 64 # 最小后台工作者, 设置范围[5, ++], 默认64
MaxEventBuf: 128 # 最大log缓存条数, 设置范围[10, ++], 默认128 MaxEventBuf: 128 # 最大log缓存条数, 设置范围[10, ++], 默认128
@ -23,6 +25,8 @@ MetricManager: # 指标监控管理器的配置参数
MaxTempEventBuf: 256 # 最大log缓存条数, 设置范围[10, ++], 默认256 MaxTempEventBuf: 256 # 最大log缓存条数, 设置范围[10, ++], 默认256
MaxTickCount: 60 # 最大的循环周期, 设置范围[60, ++], 默认60 MaxTickCount: 60 # 最大的循环周期, 设置范围[60, ++], 默认60
TickWaitTime: 1 # 一个周期的等待时间,单位:秒 默认1s TickWaitTime: 1 # 一个周期的等待时间,单位:秒 默认1s
JobManager: # Cron Job理器的配置参数
MaxOnlineInterval: "@every 5m" # 更新最大在线人数默认每5分钟更新一次
Features: Features:
Default: [] Default: []
WebServer: # Web服务 WebServer: # Web服务

@ -30,6 +30,7 @@ const (
TableContactGroup = "contact_group" TableContactGroup = "contact_group"
TableMessage = "message" TableMessage = "message"
TablePost = "post" TablePost = "post"
TablePostMetric = "post_metric"
TablePostByComment = "post_by_comment" TablePostByComment = "post_by_comment"
TablePostByMedia = "post_by_media" TablePostByMedia = "post_by_media"
TablePostAttachmentBill = "post_attachment_bill" TablePostAttachmentBill = "post_attachment_bill"

@ -101,7 +101,9 @@ type cacheConf struct {
CientSideCacheExpire time.Duration CientSideCacheExpire time.Duration
UnreadMsgExpire int64 UnreadMsgExpire int64
UserTweetsExpire int64 UserTweetsExpire int64
IndexTweetsExpire int64
OnlineUserExpire int64 OnlineUserExpire int64
UserInfoExpire int64
} }
type eventManagerConf struct { type eventManagerConf struct {
@ -120,6 +122,10 @@ type metricManagerConf struct {
TickWaitTime time.Duration TickWaitTime time.Duration
} }
type jobManagerConf struct {
MaxOnlineInterval string
}
type cacheIndexConf struct { type cacheIndexConf struct {
MaxUpdateQPS int MaxUpdateQPS int
MinWorker int MinWorker int
@ -345,6 +351,7 @@ func (s *databaseConf) TableNames() (res TableNameMap) {
TableContactGroup, TableContactGroup,
TableMessage, TableMessage,
TablePost, TablePost,
TablePostMetric,
TablePostByComment, TablePostByComment,
TablePostByMedia, TablePostByMedia,
TablePostAttachmentBill, TablePostAttachmentBill,

@ -68,14 +68,14 @@ func NewIndexActionA(act IdxAct, tweet *cs.TweetInfo) *IndexActionA {
// CacheIndexService cache index service interface // CacheIndexService cache index service interface
type CacheIndexService interface { type CacheIndexService interface {
IndexPostsService // IndexPostsService
SendAction(act IdxAct, post *dbr.Post) SendAction(act IdxAct, post *dbr.Post)
} }
// CacheIndexServantA cache index service interface // CacheIndexServantA cache index service interface
type CacheIndexServantA interface { type CacheIndexServantA interface {
IndexPostsServantA // IndexPostsServantA
SendAction(act IdxAct, tweet *cs.TweetInfo) SendAction(act IdxAct, tweet *cs.TweetInfo)
} }
@ -114,4 +114,5 @@ type WebCache interface {
PutUnreadMsgCountResp(uid int64, data []byte) error PutUnreadMsgCountResp(uid int64, data []byte) error
DelUnreadMsgCountResp(uid int64) error DelUnreadMsgCountResp(uid int64) error
ExistUnreadMsgCountResp(uid int64) bool ExistUnreadMsgCountResp(uid int64) bool
PutHistoryMaxOnline(newScore int) (int, error)
} }

@ -16,13 +16,16 @@ type DataService interface {
TopicService TopicService
// 广场泡泡服务 // 广场泡泡服务
IndexPostsService // IndexPostsService
// 推文服务 // 推文服务
TweetService TweetService
TweetManageService TweetManageService
TweetHelpService TweetHelpService
// 推文指标服务
TweetMetricServantA
// 评论服务 // 评论服务
CommentService CommentService
CommentManageService CommentManageService

@ -0,0 +1,25 @@
// Copyright 2023 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
// Package cs contain core data service interface type
// model define
package cs
type TweetMetric struct {
PostId int64
CommentCount int64
UpvoteCount int64
CollectionCount int64
ShareCount int64
ThumbdownCount int64
ThumbupCount int64
}
func (m *TweetMetric) RankScore(motivationFactor int) int64 {
if motivationFactor == 0 {
motivationFactor = 1
}
return (m.CommentCount + m.UpvoteCount*2 + m.CollectionCount*4 + m.ShareCount*8) * int64(motivationFactor)
}

@ -16,10 +16,17 @@ const (
TweetBlockChargeAttachment TweetBlockChargeAttachment
// 推文可见性 // 推文可见性
TweetVisitPublic TweetVisibleType = iota TweetVisitPublic TweetVisibleType = 90
TweetVisitPrivate TweetVisitPrivate TweetVisibleType = 0
TweetVisitFriend TweetVisitFriend TweetVisibleType = 50
TweetVisitInvalid TweetVisitFollowing TweetVisibleType = 60
// 用户推文列表样式
StyleUserTweetsGuest uint8 = iota
StyleUserTweetsSelf
StyleUserTweetsAdmin
StyleUserTweetsFriend
StyleUserTweetsFollowing
// 附件类型 // 附件类型
AttachmentTypeImage AttachmentType = iota + 1 AttachmentTypeImage AttachmentType = iota + 1
@ -32,7 +39,7 @@ type (
// TODO: 优化一下类型为 uint8 需要底层数据库同步修改 // TODO: 优化一下类型为 uint8 需要底层数据库同步修改
TweetBlockType int TweetBlockType int
// TweetVisibleType 推文可见性0公开1私密2好友 // TweetVisibleType 推文可见性: 0私密 10充电可见 20订阅可见 30保留 40保留 50好友可见 60关注可见 70保留 80保留 90公开',
TweetVisibleType uint8 TweetVisibleType uint8
// AttachmentType 附件类型, 1图片 2视频 3其他 // AttachmentType 附件类型, 1图片 2视频 3其他
@ -139,3 +146,19 @@ type NewTweetReq struct {
Visibility TweetVisibleType `json:"visibility"` Visibility TweetVisibleType `json:"visibility"`
ClientIP string `json:"-" binding:"-"` ClientIP string `json:"-" binding:"-"`
} }
func (t TweetVisibleType) ToOutValue() (res uint8) {
switch t {
case TweetVisitPublic:
res = 0
case TweetVisitPrivate:
res = 1
case TweetVisitFriend:
res = 2
case TweetVisitFollowing:
res = 3
default:
res = 1
}
return
}

@ -5,7 +5,7 @@
package cs package cs
const ( const (
RelationUnknow RelationTyp = iota RelationUnknown RelationTyp = iota
RelationSelf RelationSelf
RelationFriend RelationFriend
RelationFollower RelationFollower
@ -51,9 +51,9 @@ func (t RelationTyp) String() string {
return "following" return "following"
case RelationAdmin: case RelationAdmin:
return "admin" return "admin"
case RelationUnknow: case RelationUnknown:
fallthrough fallthrough
default: default:
return "unknow relation" return "unknown"
} }
} }

@ -0,0 +1,15 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package core
import (
"github.com/rocboss/paopao-ce/internal/core/cs"
)
type TweetMetricServantA interface {
UpdateRankScore(metric *cs.TweetMetric) error
AddTweetMetric(postId int64) error
DeleteTweetMetric(postId int64) error
}

@ -25,10 +25,10 @@ const (
) )
const ( const (
PostVisitPublic PostVisibleT = iota PostVisitPublic = dbr.PostVisitPublic
PostVisitPrivate PostVisitPrivate = dbr.PostVisitPrivate
PostVisitFriend PostVisitFriend = dbr.PostVisitFriend
PostVisitInvalid PostVisitFollowing = dbr.PostVisitFollowing
) )
type ( type (

@ -18,11 +18,11 @@ const (
PostVisitPublic = dbr.PostVisitPublic PostVisitPublic = dbr.PostVisitPublic
PostVisitPrivate = dbr.PostVisitPrivate PostVisitPrivate = dbr.PostVisitPrivate
PostVisitFriend = dbr.PostVisitFriend PostVisitFriend = dbr.PostVisitFriend
PostVisitInvalid = dbr.PostVisitInvalid PostVisitFollowing = dbr.PostVisitFollowing
) )
type ( type (
// PostVisibleT 可访问类型,0公开1私密2好友 // PostVisibleT 可访问类型,可见性: 0私密 10充电可见 20订阅可见 30保留 40保留 50好友可见 60关注可见 70保留 80保留 90公开
PostVisibleT = dbr.PostVisibleT PostVisibleT = dbr.PostVisibleT
SearchType string SearchType string

@ -26,6 +26,11 @@ type TweetService interface {
ListUserStarTweets(user *cs.VistUser, limit int, offset int) ([]*ms.PostStar, int64, error) ListUserStarTweets(user *cs.VistUser, limit int, offset int) ([]*ms.PostStar, int64, error)
ListUserMediaTweets(user *cs.VistUser, limit int, offset int) ([]*ms.Post, int64, error) ListUserMediaTweets(user *cs.VistUser, limit int, offset int) ([]*ms.Post, int64, error)
ListUserCommentTweets(user *cs.VistUser, limit int, offset int) ([]*ms.Post, int64, error) ListUserCommentTweets(user *cs.VistUser, limit int, offset int) ([]*ms.Post, int64, error)
ListUserTweets(userId int64, style uint8, justEssence bool, limit, offset int) ([]*ms.Post, int64, error)
ListFollowingTweets(userId int64, limit, offset int) ([]*ms.Post, int64, error)
ListIndexNewestTweets(limit, offset int) ([]*ms.Post, int64, error)
ListIndexHotsTweets(limit, offset int) ([]*ms.Post, int64, error)
ListSyncSearchTweets(limit, offset int) ([]*ms.Post, int64, error)
} }
// TweetManageService 推文管理服务,包括创建/删除/更新推文 // TweetManageService 推文管理服务,包括创建/删除/更新推文
@ -35,7 +40,7 @@ type TweetManageService interface {
LockPost(post *ms.Post) error LockPost(post *ms.Post) error
StickPost(post *ms.Post) error StickPost(post *ms.Post) error
HighlightPost(userId, postId int64) (int, error) HighlightPost(userId, postId int64) (int, error)
VisiblePost(post *ms.Post, visibility PostVisibleT) error VisiblePost(post *ms.Post, visibility cs.TweetVisibleType) error
UpdatePost(post *ms.Post) error UpdatePost(post *ms.Post) error
CreatePostStar(postID, userID int64) (*ms.PostStar, error) CreatePostStar(postID, userID int64) (*ms.PostStar, error)
DeletePostStar(p *ms.PostStar) error DeletePostStar(p *ms.PostStar) error

@ -0,0 +1,61 @@
// 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 (
"bytes"
"encoding/gob"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/ms"
)
type cacheDataService struct {
core.DataService
ac core.AppCache
}
func NewCacheDataService(ds core.DataService) core.DataService {
lazyInitial()
return &cacheDataService{
DataService: ds,
ac: _appCache,
}
}
func (s *cacheDataService) GetUserByID(id int64) (res *ms.User, err error) {
// 先从缓存获取, 不处理错误
key := conf.KeyUserInfoById.Get(id)
if data, xerr := s.ac.Get(key); xerr == nil {
buf := bytes.NewBuffer(data)
res = &ms.User{}
err = gob.NewDecoder(buf).Decode(res)
return
}
// 最后查库
if res, err = s.DataService.GetUserByID(id); err == nil {
// 更新缓存
onCacheUserInfoEvent(key, res)
}
return
}
func (s *cacheDataService) GetUserByUsername(username string) (res *ms.User, err error) {
// 先从缓存获取, 不处理错误
key := conf.KeyUserInfoByName.Get(username)
if data, xerr := s.ac.Get(key); xerr == nil {
buf := bytes.NewBuffer(data)
res = &ms.User{}
err = gob.NewDecoder(buf).Decode(res)
return
}
// 最后查库
if res, err = s.DataService.GetUserByUsername(username); err == nil {
// 更新缓存
onCacheUserInfoEvent(key, res)
}
return
}

@ -0,0 +1,129 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package cache
import (
"bytes"
"encoding/gob"
"fmt"
"github.com/alimy/tryst/event"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/events"
)
type expireIndexTweetsEvent struct {
event.UnimplementedEvent
tweet *ms.Post
ac core.AppCache
keysPattern []string
}
type expireHotsTweetsEvent struct {
event.UnimplementedEvent
tweet *ms.Post
ac core.AppCache
keyPattern string
}
type expireFollowTweetsEvent struct {
event.UnimplementedEvent
tweet *ms.Post
ac core.AppCache
keyPattern string
}
type cacheUserInfoEvent struct {
event.UnimplementedEvent
tweet *ms.Post
ac core.AppCache
key string
data *ms.User
expire int64
}
func onExpireIndexTweetEvent(tweet *ms.Post) {
events.OnEvent(&expireIndexTweetsEvent{
tweet: tweet,
ac: _appCache,
keysPattern: []string{
conf.PrefixIdxTweetsNewest + "*",
conf.PrefixIdxTweetsHots + "*",
fmt.Sprintf("%s%d:*", conf.PrefixUserTweets, tweet.UserID),
},
})
}
func onExpireHotsTweetEvent(tweet *ms.Post) {
events.OnEvent(&expireHotsTweetsEvent{
tweet: tweet,
ac: _appCache,
keyPattern: conf.PrefixHotsTweets + "*",
})
}
func onExpireFollowTweetEvent(tweet *ms.Post) {
events.OnEvent(&expireFollowTweetsEvent{
tweet: tweet,
ac: _appCache,
keyPattern: conf.PrefixFollowingTweets + "*",
})
}
func onCacheUserInfoEvent(key string, data *ms.User) {
events.OnEvent(&cacheUserInfoEvent{
key: key,
data: data,
ac: _appCache,
expire: conf.CacheSetting.UserInfoExpire,
})
}
func (e *expireIndexTweetsEvent) Name() string {
return "expireIndexTweetsEvent"
}
func (e *expireIndexTweetsEvent) Action() (err error) {
// logrus.Debug("expireIndexTweetsEvent action running")
for _, pattern := range e.keysPattern {
e.ac.DelAny(pattern)
}
return
}
func (e *expireHotsTweetsEvent) Name() string {
return "expireHotsTweetsEvent"
}
func (e *expireHotsTweetsEvent) Action() (err error) {
// logrus.Debug("expireHotsTweetsEvent action running")
e.ac.DelAny(e.keyPattern)
return
}
func (e *expireFollowTweetsEvent) Name() string {
return "expireFollowTweetsEvent"
}
func (e *expireFollowTweetsEvent) Action() (err error) {
// logrus.Debug("expireFollowTweetsEvent action running")
e.ac.DelAny(e.keyPattern)
return
}
func (e *cacheUserInfoEvent) Name() string {
return "cacheUserInfoEvent"
}
func (e *cacheUserInfoEvent) Action() (err error) {
buffer := &bytes.Buffer{}
ge := gob.NewEncoder(buffer)
if err = ge.Encode(e.data); err == nil {
e.ac.Set(e.key, buffer.Bytes(), e.expire)
}
return
}

@ -0,0 +1,49 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package cache
import (
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/sirupsen/logrus"
)
type eventCacheIndexSrv struct {
tms core.TweetMetricServantA
}
func (s *eventCacheIndexSrv) SendAction(act core.IdxAct, post *ms.Post) {
err := error(nil)
switch act {
case core.IdxActUpdatePost:
err = s.tms.UpdateRankScore(&cs.TweetMetric{
PostId: post.ID,
CommentCount: post.CommentCount,
UpvoteCount: post.UpvoteCount,
CollectionCount: post.CollectionCount,
ShareCount: post.ShareCount,
})
onExpireIndexTweetEvent(post)
case core.IdxActCreatePost:
err = s.tms.AddTweetMetric(post.ID)
onExpireIndexTweetEvent(post)
case core.IdxActDeletePost:
err = s.tms.DeleteTweetMetric(post.ID)
onExpireIndexTweetEvent(post)
case core.IdxActStickPost, core.IdxActVisiblePost:
onExpireIndexTweetEvent(post)
}
if err != nil {
logrus.Errorf("eventCacheIndexSrv.SendAction(%s) occurs error: %s", act, err)
}
}
func NewEventCacheIndexSrv(tms core.TweetMetricServantA) core.CacheIndexService {
lazyInitial()
return &eventCacheIndexSrv{
tms: tms,
}
}

@ -26,6 +26,7 @@ type appCache struct {
type webCache struct { type webCache struct {
core.AppCache core.AppCache
c rueidis.Client
unreadMsgExpire int64 unreadMsgExpire int64
} }
@ -129,6 +130,23 @@ func (s *webCache) ExistUnreadMsgCountResp(uid int64) bool {
return s.Exist(conf.KeyUnreadMsg.Get(uid)) return s.Exist(conf.KeyUnreadMsg.Get(uid))
} }
func (s *webCache) PutHistoryMaxOnline(newScore int) (int, error) {
ctx := context.Background()
cmd := s.c.B().Zadd().
Key(conf.KeySiteStatus).
Gt().ScoreMember().
ScoreMember(float64(newScore), conf.KeyHistoryMaxOnline).Build()
if err := s.c.Do(ctx, cmd).Error(); err != nil {
return 0, err
}
cmd = s.c.B().Zscore().Key(conf.KeySiteStatus).Member(conf.KeyHistoryMaxOnline).Build()
if score, err := s.c.Do(ctx, cmd).ToFloat64(); err == nil {
return int(score), nil
} else {
return 0, err
}
}
func newAppCache() *appCache { func newAppCache() *appCache {
return &appCache{ return &appCache{
cscExpire: conf.CacheSetting.CientSideCacheExpire, cscExpire: conf.CacheSetting.CientSideCacheExpire,
@ -139,6 +157,7 @@ func newAppCache() *appCache {
func newWebCache(ac core.AppCache) *webCache { func newWebCache(ac core.AppCache) *webCache {
return &webCache{ return &webCache{
AppCache: ac, AppCache: ac,
c: conf.MustRedisClient(),
unreadMsgExpire: conf.CacheSetting.UnreadMsgExpire, unreadMsgExpire: conf.CacheSetting.UnreadMsgExpire,
} }
} }

@ -0,0 +1,32 @@
// 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 dbr
import (
"time"
"gorm.io/gorm"
)
type PostMetric struct {
*Model
PostId int64
RankScore int64
IncentiveScore int
DecayFactor int
MotivationFactor int
}
func (p *PostMetric) Create(db *gorm.DB) (*PostMetric, error) {
err := db.Create(&p).Error
return p, err
}
func (p *PostMetric) Delete(db *gorm.DB) error {
return db.Model(p).Where("post_id", p.PostId).Updates(map[string]any{
"deleted_on": time.Now().Unix(),
"is_del": 1,
}).Error
}

@ -11,14 +11,14 @@ import (
"gorm.io/gorm" "gorm.io/gorm"
) )
// PostVisibleT 可访问类型,0公开1私密2好友 // PostVisibleT 可访问类型,可见性: 0私密 10充电可见 20订阅可见 30保留 40保留 50好友可见 60关注可见 70保留 80保留 90公开',
type PostVisibleT uint8 type PostVisibleT uint8
const ( const (
PostVisitPublic PostVisibleT = iota PostVisitPublic PostVisibleT = 90
PostVisitPrivate PostVisitPrivate PostVisibleT = 0
PostVisitFriend PostVisitFriend PostVisibleT = 50
PostVisitInvalid PostVisitFollowing PostVisibleT = 60
) )
type PostByMedia = Post type PostByMedia = Post
@ -64,6 +64,22 @@ type PostFormated struct {
IPLoc string `json:"ip_loc"` IPLoc string `json:"ip_loc"`
} }
func (t PostVisibleT) ToOutValue() (res uint8) {
switch t {
case PostVisitPublic:
res = 0
case PostVisitPrivate:
res = 1
case PostVisitFriend:
res = 2
case PostVisitFollowing:
res = 3
default:
res = 1
}
return
}
func (p *Post) Format() *PostFormated { func (p *Post) Format() *PostFormated {
if p.Model != nil { if p.Model != nil {
tagsMap := map[string]int8{} tagsMap := map[string]int8{}
@ -211,8 +227,6 @@ func (p PostVisibleT) String() string {
return "private" return "private"
case PostVisitFriend: case PostVisitFriend:
return "friend" return "friend"
case PostVisitInvalid:
return "invalid"
default: default:
return "unknow" return "unknow"
} }

@ -22,6 +22,7 @@ var (
_contactGroup_ string _contactGroup_ string
_message_ string _message_ string
_post_ string _post_ string
_post_metric_ string
_post_by_comment_ string _post_by_comment_ string
_post_by_media_ string _post_by_media_ string
_postAttachmentBill_ string _postAttachmentBill_ string
@ -48,6 +49,7 @@ func initTableName() {
_contactGroup_ = m[conf.TableContactGroup] _contactGroup_ = m[conf.TableContactGroup]
_message_ = m[conf.TableMessage] _message_ = m[conf.TableMessage]
_post_ = m[conf.TablePost] _post_ = m[conf.TablePost]
_post_metric_ = m[conf.TablePostMetric]
_post_by_comment_ = m[conf.TablePostByComment] _post_by_comment_ = m[conf.TablePostByComment]
_post_by_media_ = m[conf.TablePostByMedia] _post_by_media_ = m[conf.TablePostByMedia]
_postAttachmentBill_ = m[conf.TablePostAttachmentBill] _postAttachmentBill_ = m[conf.TablePostAttachmentBill]

@ -12,12 +12,10 @@ import (
"sync" "sync"
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/alimy/tryst/cfg"
"github.com/rocboss/paopao-ce/internal/conf" "github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/dao/cache" "github.com/rocboss/paopao-ce/internal/dao/cache"
"github.com/rocboss/paopao-ce/internal/dao/security" "github.com/rocboss/paopao-ce/internal/dao/security"
"github.com/sirupsen/logrus"
) )
var ( var (
@ -31,13 +29,14 @@ var (
) )
type dataSrv struct { type dataSrv struct {
core.IndexPostsService // core.IndexPostsService
core.WalletService core.WalletService
core.MessageService core.MessageService
core.TopicService core.TopicService
core.TweetService core.TweetService
core.TweetManageService core.TweetManageService
core.TweetHelpService core.TweetHelpService
core.TweetMetricServantA
core.CommentService core.CommentService
core.CommentManageService core.CommentManageService
core.UserManageService core.UserManageService
@ -57,37 +56,13 @@ type webDataSrvA struct {
func NewDataService() (core.DataService, core.VersionInfo) { func NewDataService() (core.DataService, core.VersionInfo) {
lazyInitial() lazyInitial()
var (
v core.VersionInfo
cis core.CacheIndexService
)
db := conf.MustGormDB() db := conf.MustGormDB()
pvs := security.NewPhoneVerifyService() pvs := security.NewPhoneVerifyService()
ams := NewAuthorizationManageService() tms := NewTweetMetricServentA(db)
ths := newTweetHelpService(db) cis := cache.NewEventCacheIndexSrv(tms)
ips := newShipIndexService(db, ams, ths)
// initialize core.CacheIndexService
cfg.On(cfg.Actions{
"SimpleCacheIndex": func() {
// simpleCache use special post index service
ips = newSimpleIndexPostsService(db, ths)
cis, v = cache.NewSimpleCacheIndexService(ips)
},
"BigCacheIndex": func() {
cis, v = cache.NewBigCacheIndexService(ips, ams)
},
"RedisCacheIndex": func() {
cis, v = cache.NewRedisCacheIndexService(ips, ams)
},
}, func() {
// defualt no cache
cis, v = cache.NewNoneCacheIndexService(ips)
})
logrus.Infof("use %s as cache index service by version: %s", v.Name(), v.Version())
ds := &dataSrv{ ds := &dataSrv{
IndexPostsService: cis, TweetMetricServantA: tms,
WalletService: newWalletService(db), WalletService: newWalletService(db),
MessageService: newMessageService(db), MessageService: newMessageService(db),
TopicService: newTopicService(db), TopicService: newTopicService(db),
@ -102,7 +77,7 @@ func NewDataService() (core.DataService, core.VersionInfo) {
SecurityService: newSecurityService(db, pvs), SecurityService: newSecurityService(db, pvs),
AttachmentCheckService: security.NewAttachmentCheckService(), AttachmentCheckService: security.NewAttachmentCheckService(),
} }
return ds, ds return cache.NewCacheDataService(ds), ds
} }
func NewWebDataServantA() (core.WebDataServantA, core.VersionInfo) { func NewWebDataServantA() (core.WebDataServantA, core.VersionInfo) {

@ -0,0 +1,43 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package jinzhu
import (
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"gorm.io/gorm"
)
type tweetMetricSrvA struct {
db *gorm.DB
}
func (s *tweetMetricSrvA) UpdateRankScore(metric *cs.TweetMetric) error {
return s.db.Transaction(func(tx *gorm.DB) (err error) {
postMetric := &dbr.PostMetric{PostId: metric.PostId}
db := s.db.Model(postMetric).Where("post_id=?", metric.PostId)
db.First(postMetric)
postMetric.RankScore = metric.RankScore(postMetric.MotivationFactor)
err = db.Save(postMetric).Error
return
})
}
func (s *tweetMetricSrvA) AddTweetMetric(postId int64) (err error) {
_, err = (&dbr.PostMetric{PostId: postId}).Create(s.db)
return
}
func (s *tweetMetricSrvA) DeleteTweetMetric(postId int64) (err error) {
return (&dbr.PostMetric{PostId: postId}).Delete(s.db)
}
func NewTweetMetricServentA(db *gorm.DB) core.TweetMetricServantA {
return &tweetMetricSrvA{
db: db,
}
}

@ -5,6 +5,7 @@
package jinzhu package jinzhu
import ( import (
"fmt"
"strings" "strings"
"time" "time"
@ -214,7 +215,6 @@ func (s *tweetManageSrv) CreatePost(post *ms.Post) (*ms.Post, error) {
func (s *tweetManageSrv) DeletePost(post *ms.Post) ([]string, error) { func (s *tweetManageSrv) DeletePost(post *ms.Post) ([]string, error) {
var mediaContents []string var mediaContents []string
postId := post.ID postId := post.ID
postContent := &dbr.PostContent{} postContent := &dbr.PostContent{}
err := s.db.Transaction( err := s.db.Transaction(
@ -326,15 +326,15 @@ func (s *tweetManageSrv) HighlightPost(userId int64, postId int64) (res int, err
return post.IsEssence, nil return post.IsEssence, nil
} }
func (s *tweetManageSrv) VisiblePost(post *ms.Post, visibility core.PostVisibleT) (err error) { func (s *tweetManageSrv) VisiblePost(post *ms.Post, visibility cs.TweetVisibleType) (err error) {
oldVisibility := post.Visibility oldVisibility := post.Visibility
post.Visibility = visibility post.Visibility = ms.PostVisibleT(visibility)
// TODO: 这个判断是否可以不要呢 // TODO: 这个判断是否可以不要呢
if oldVisibility == visibility { if oldVisibility == ms.PostVisibleT(visibility) {
return nil return nil
} }
// 私密推文 特殊处理 // 私密推文 特殊处理
if visibility == dbr.PostVisitPrivate { if visibility == cs.TweetVisitPrivate {
// 强制取消置顶 // 强制取消置顶
// TODO: 置顶推文用户是否有权设置成私密? 后续完善 // TODO: 置顶推文用户是否有权设置成私密? 后续完善
post.IsTop = 0 post.IsTop = 0
@ -350,7 +350,7 @@ func (s *tweetManageSrv) VisiblePost(post *ms.Post, visibility core.PostVisibleT
if oldVisibility == dbr.PostVisitPrivate { if oldVisibility == dbr.PostVisitPrivate {
// 从私密转为非私密才需要重新创建tag // 从私密转为非私密才需要重新创建tag
createTags(tx, post.UserID, tags) createTags(tx, post.UserID, tags)
} else if visibility == dbr.PostVisitPrivate { } else if visibility == cs.TweetVisitPrivate {
// 从非私密转为私密才需要删除tag // 从非私密转为私密才需要删除tag
deleteTags(tx, tags) deleteTags(tx, tags)
} }
@ -392,6 +392,131 @@ func (s *tweetSrv) GetPosts(conditions ms.ConditionsT, offset, limit int) ([]*ms
return (&dbr.Post{}).List(s.db, conditions, offset, limit) return (&dbr.Post{}).List(s.db, conditions, offset, limit)
} }
func (s *tweetSrv) ListUserTweets(userId int64, style uint8, justEssence bool, limit, offset int) (res []*ms.Post, total int64, err error) {
db := s.db.Table(_post_).Where("user_id = ?", userId)
switch style {
case cs.StyleUserTweetsAdmin:
fallthrough
case cs.StyleUserTweetsSelf:
db = db.Where("visibility >= ?", cs.TweetVisitPrivate)
case cs.StyleUserTweetsFriend:
db = db.Where("visibility >= ?", cs.TweetVisitFriend)
case cs.StyleUserTweetsFollowing:
db = db.Where("visibility >= ?", cs.TweetVisitFollowing)
case cs.StyleUserTweetsGuest:
fallthrough
default:
db = db.Where("visibility >= ?", cs.TweetVisitPublic)
}
if justEssence {
db = db.Where("is_essence=1")
}
if err = db.Count(&total).Error; err != nil {
return
}
if offset >= 0 && limit > 0 {
db = db.Offset(offset).Limit(limit)
}
if err = db.Order("is_top DESC, latest_replied_on DESC").Find(&res).Error; err != nil {
return
}
return
}
func (s *tweetSrv) ListIndexNewestTweets(limit, offset int) (res []*ms.Post, total int64, err error) {
db := s.db.Table(_post_).Where("visibility >= ?", cs.TweetVisitPublic)
if err = db.Count(&total).Error; err != nil {
return
}
if offset >= 0 && limit > 0 {
db = db.Offset(offset).Limit(limit)
}
if err = db.Order("is_top DESC, latest_replied_on DESC").Find(&res).Error; err != nil {
return
}
return
}
func (s *tweetSrv) ListIndexHotsTweets(limit, offset int) (res []*ms.Post, total int64, err error) {
db := s.db.Table(_post_).Joins(fmt.Sprintf("LEFT JOIN %s metric ON %s.id=metric.post_id", _post_metric_, _post_)).Where("visibility >= ?", cs.TweetVisitPublic)
if err = db.Count(&total).Error; err != nil {
return
}
if offset >= 0 && limit > 0 {
db = db.Offset(offset).Limit(limit)
}
if err = db.Order("is_top DESC, metric.rank_score DESC, latest_replied_on DESC").Find(&res).Error; err != nil {
return
}
return
}
func (s *tweetSrv) ListSyncSearchTweets(limit, offset int) (res []*ms.Post, total int64, err error) {
db := s.db.Table(_post_).Where("visibility >= ?", cs.TweetVisitFriend)
if err = db.Count(&total).Error; err != nil {
return
}
if offset >= 0 && limit > 0 {
db = db.Offset(offset).Limit(limit)
}
if err = db.Find(&res).Error; err != nil {
return
}
return
}
func (s *tweetSrv) ListFollowingTweets(userId int64, limit, offset int) (res []*ms.Post, total int64, err error) {
beFriendIds, beFollowIds, xerr := s.getUserRelation(userId)
if xerr != nil {
return nil, 0, xerr
}
beFriendCount, beFollowCount := len(beFriendIds), len(beFollowIds)
db := s.db.Table(_post_)
//可见性: 0私密 10充电可见 20订阅可见 30保留 40保留 50好友可见 60关注可见 70保留 80保留 90公开',
switch {
case beFriendCount > 0 && beFollowCount > 0:
db = db.Where("user_id=? OR (visibility>=50 AND user_id IN(?)) OR (visibility>=60 AND user_id IN(?))", userId, beFriendIds, beFollowIds)
case beFriendCount > 0 && beFollowCount == 0:
db = db.Where("user_id=? OR (visibility>=50 AND user_id IN(?))", userId, beFriendIds)
case beFriendCount == 0 && beFollowCount > 0:
db = db.Where("user_id=? OR (visibility>=60 AND user_id IN(?))", userId, beFollowIds)
case beFriendCount == 0 && beFollowCount == 0:
db = db.Where("user_id = ?", userId)
}
if err = db.Count(&total).Error; err != nil {
return
}
if offset >= 0 && limit > 0 {
db = db.Offset(offset).Limit(limit)
}
if err = db.Order("is_top DESC, latest_replied_on DESC").Find(&res).Error; err != nil {
return
}
return
}
func (s *tweetSrv) getUserRelation(userId int64) (beFriendIds []int64, beFollowIds []int64, err error) {
if err = s.db.Table(_contact_).Where("friend_id=?", userId).Select("user_id").Find(&beFriendIds).Error; err != nil {
return
}
if err = s.db.Table(_following_).Where("user_id=?", userId).Select("follow_id").Find(&beFollowIds).Error; err != nil {
return
}
// 即是好友又是关注者,保留好友去除关注者
for _, id := range beFriendIds {
for i := 0; i < len(beFollowIds); i++ {
// 找到item即删数据库已经保证唯一性
if beFollowIds[i] == id {
lastIdx := len(beFollowIds) - 1
beFriendIds[i] = beFriendIds[lastIdx]
beFollowIds = beFollowIds[:lastIdx]
break
}
}
}
return
}
func (s *tweetSrv) GetPostCount(conditions ms.ConditionsT) (int64, error) { func (s *tweetSrv) GetPostCount(conditions ms.ConditionsT) (int64, error) {
return (&dbr.Post{}).Count(s.db, conditions) return (&dbr.Post{}).Count(s.db, conditions)
} }

@ -0,0 +1,36 @@
// 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 slonik
import (
"github.com/jackc/pgx/v5"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/cs"
)
type tweetMetricSrvA struct {
*pgxSrv
}
func (s *tweetMetricSrvA) UpdateRankScore(metric *cs.TweetMetric) error {
// TODO
return cs.ErrNotImplemented
}
func (s *tweetMetricSrvA) AddTweetMetric(postId int64) (err error) {
// TODO
return cs.ErrNotImplemented
}
func (s *tweetMetricSrvA) DeleteTweetMetric(postId int64) (err error) {
// TODO
return cs.ErrNotImplemented
}
func NewTweetMetricServentA(db *pgx.Conn) core.TweetMetricServantA {
return &tweetMetricSrvA{
pgxSrv: newPgxSrv(db),
}
}

@ -6,7 +6,6 @@ package slonik
import ( import (
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/alimy/tryst/cfg"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/dao/cache" "github.com/rocboss/paopao-ce/internal/dao/cache"
"github.com/rocboss/paopao-ce/internal/dao/security" "github.com/rocboss/paopao-ce/internal/dao/security"
@ -22,7 +21,6 @@ var (
) )
type dataSrv struct { type dataSrv struct {
core.IndexPostsService
core.WalletService core.WalletService
core.MessageService core.MessageService
core.TopicService core.TopicService
@ -36,6 +34,7 @@ type dataSrv struct {
core.FollowingManageService core.FollowingManageService
core.SecurityService core.SecurityService
core.AttachmentCheckService core.AttachmentCheckService
core.TweetMetricServantA
} }
type webDataSrvA struct { type webDataSrvA struct {
@ -46,38 +45,12 @@ type webDataSrvA struct {
} }
func NewDataService() (core.DataService, core.VersionInfo) { func NewDataService() (core.DataService, core.VersionInfo) {
var (
v core.VersionInfo
cis core.CacheIndexService
)
db := pgxDB() db := pgxDB()
pvs := security.NewPhoneVerifyService() pvs := security.NewPhoneVerifyService()
ams := NewAuthorizationManageService() tms := NewTweetMetricServentA(db)
ths := newTweetHelpService(db) cis := cache.NewEventCacheIndexSrv(tms)
ips := newShipIndexService(db, ams, ths)
// initialize core.CacheIndexService
cfg.On(cfg.Actions{
"SimpleCacheIndex": func() {
// simpleCache use special post index service
ips = newSimpleIndexPostsService(db, ths)
cis, v = cache.NewSimpleCacheIndexService(ips)
},
"BigCacheIndex": func() {
// TODO: make cache index post in different scence like friendship/followship/lightship
cis, v = cache.NewBigCacheIndexService(ips, ams)
},
"RedisCacheIndex": func() {
cis, v = cache.NewRedisCacheIndexService(ips, ams)
},
}, func() {
// defualt no cache
cis, v = cache.NewNoneCacheIndexService(ips)
})
logrus.Infof("use %s as cache index service by version: %s", v.Name(), v.Version())
ds := &dataSrv{ ds := &dataSrv{
IndexPostsService: cis, TweetMetricServantA: tms,
WalletService: newWalletService(db), WalletService: newWalletService(db),
MessageService: newMessageService(db), MessageService: newMessageService(db),
TopicService: newTopicService(db), TopicService: newTopicService(db),
@ -92,7 +65,7 @@ func NewDataService() (core.DataService, core.VersionInfo) {
SecurityService: newSecurityService(db, pvs), SecurityService: newSecurityService(db, pvs),
AttachmentCheckService: security.NewAttachmentCheckService(), AttachmentCheckService: security.NewAttachmentCheckService(),
} }
return ds, ds return cache.NewCacheDataService(ds), ds
} }
func NewWebDataServantA() (core.WebDataServantA, core.VersionInfo) { func NewWebDataServantA() (core.WebDataServantA, core.VersionInfo) {

@ -121,10 +121,9 @@ func (s *tweetManageSrv) HighlightPost(userId, postId int64) (res int, err error
return return
} }
func (s *tweetManageSrv) VisiblePost(post *ms.Post, visibility core.PostVisibleT) error { func (s *tweetManageSrv) VisiblePost(post *ms.Post, visibility cs.TweetVisibleType) error {
// TODO // TODO
debug.NotImplemented() return cs.ErrNotImplemented
return nil
} }
func (s *tweetManageSrv) UpdatePost(post *ms.Post) error { func (s *tweetManageSrv) UpdatePost(post *ms.Post) error {
@ -334,6 +333,31 @@ func (s *tweetSrv) ListUserCommentTweets(user *cs.VistUser, limit int, offset in
return nil, 0, debug.ErrNotImplemented return nil, 0, debug.ErrNotImplemented
} }
func (s *tweetSrv) ListUserTweets(userId int64, style uint8, justEssence bool, limit, offset int) ([]*ms.Post, int64, error) {
// TODO
return nil, 0, cs.ErrNotImplemented
}
func (s *tweetSrv) ListFollowingTweets(userId int64, limit, offset int) ([]*ms.Post, int64, error) {
// TODO
return nil, 0, cs.ErrNotImplemented
}
func (s *tweetSrv) ListIndexNewestTweets(limit, offset int) ([]*ms.Post, int64, error) {
// TODO
return nil, 0, cs.ErrNotImplemented
}
func (s *tweetSrv) ListIndexHotsTweets(limit, offset int) ([]*ms.Post, int64, error) {
// TODO
return nil, 0, cs.ErrNotImplemented
}
func (s *tweetSrv) ListSyncSearchTweets(limit, offset int) ([]*ms.Post, int64, error) {
// TODO
return nil, 0, cs.ErrNotImplemented
}
func newTweetService(db *pgx.Conn) core.TweetService { func newTweetService(db *pgx.Conn) core.TweetService {
return &tweetSrv{ return &tweetSrv{
pgxSrv: newPgxSrv(db), pgxSrv: newPgxSrv(db),

@ -54,15 +54,15 @@ func RemoveJob(id EntryID) {
_defaultJobManager.Remove(id) _defaultJobManager.Remove(id)
} }
// ScheduleJob adds a Job to the Cron to be run on the given schedule. // Schedule adds a Job to the Cron to be run on the given schedule.
// The job is wrapped with the configured Chain. // The job is wrapped with the configured Chain.
func ScheduleJob(job Job) EntryID { func Schedule(job Job) EntryID {
return _defaultJobManager.Schedule(job) return _defaultJobManager.Schedule(job)
} }
// Schedule adds a Job to the Cron to be run on the given schedule. // OnTask adds a Job to the Cron to be run on the given schedule.
// The job is wrapped with the configured Chain. // The job is wrapped with the configured Chain.
func Schedule(s cron.Schedule, fn JobFn) EntryID { func OnTask(s cron.Schedule, fn JobFn) EntryID {
job := &simpleJob{ job := &simpleJob{
Schedule: s, Schedule: s,
Job: fn, Job: fn,
@ -73,10 +73,10 @@ func Schedule(s cron.Schedule, fn JobFn) EntryID {
func Initial() { func Initial() {
_onceInitial.Do(func() { _onceInitial.Do(func() {
initEventManager() initEventManager()
if cfg.If("UseJobManager") { cfg.Not("DisableJobManager", func() {
initJobManager() initJobManager()
logrus.Debugln("initial JobManager") logrus.Debugln("initial JobManager")
} })
}) })
} }

@ -6,10 +6,29 @@ package joint
import ( import (
stdJson "encoding/json" stdJson "encoding/json"
"net/http"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/pkg/json" "github.com/rocboss/paopao-ce/pkg/json"
) )
type CachePageResp struct {
Data *PageResp
JsonResp stdJson.RawMessage
}
func (r *CachePageResp) Render(c *gin.Context) {
if len(r.JsonResp) != 0 {
c.JSON(http.StatusOK, r.JsonResp)
} else {
c.JSON(http.StatusOK, &JsonResp{
Code: 0,
Msg: "success",
Data: r.Data,
})
}
}
func RespMarshal(data any) (stdJson.RawMessage, error) { func RespMarshal(data any) (stdJson.RawMessage, error) {
return json.Marshal(data) return json.Marshal(data)
} }

@ -0,0 +1,27 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package joint
type Pager struct {
Page int `json:"page"`
PageSize int `json:"page_size"`
TotalRows int64 `json:"total_rows"`
}
type PageResp struct {
List any `json:"list"`
Pager Pager `json:"pager"`
}
func PageRespFrom(list any, page int, pageSize int, totalRows int64) *PageResp {
return &PageResp{
List: list,
Pager: Pager{
Page: page,
PageSize: pageSize,
TotalRows: totalRows,
},
}
}

@ -17,4 +17,6 @@ type SiteInfoReq struct {
type SiteInfoResp struct { type SiteInfoResp struct {
RegisterUserCount int64 `json:"register_user_count"` RegisterUserCount int64 `json:"register_user_count"`
OnlineUserCount int `json:"online_user_count"` OnlineUserCount int `json:"online_user_count"`
HistoryMaxOnline int `json:"history_max_online"`
ServerUpTime int64 `json:"server_up_time"`
} }

@ -5,9 +5,6 @@
package web package web
import ( import (
"encoding/json"
"net/http"
"github.com/alimy/mir/v4" "github.com/alimy/mir/v4"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
@ -30,6 +27,10 @@ const (
UserPostsStyleHighlight = "highlight" UserPostsStyleHighlight = "highlight"
UserPostsStyleMedia = "media" UserPostsStyleMedia = "media"
UserPostsStyleStar = "star" UserPostsStyleStar = "star"
StyleTweetsNewest = "newest"
StyleTweetsHots = "hots"
StyleTweetsFollowing = "following"
) )
type TagType = cs.TagType type TagType = cs.TagType
@ -49,11 +50,14 @@ type TimelineReq struct {
Query string `form:"query"` Query string `form:"query"`
Visibility []core.PostVisibleT `form:"query"` Visibility []core.PostVisibleT `form:"query"`
Type string `form:"type"` Type string `form:"type"`
Style string `form:"style"`
Page int `form:"-" binding:"-"` Page int `form:"-" binding:"-"`
PageSize int `form:"-" binding:"-"` PageSize int `form:"-" binding:"-"`
} }
type TimelineResp base.PageResp type TimelineResp struct {
joint.CachePageResp
}
type GetUserTweetsReq struct { type GetUserTweetsReq struct {
BaseInfo `form:"-" binding:"-"` BaseInfo `form:"-" binding:"-"`
@ -64,8 +68,7 @@ type GetUserTweetsReq struct {
} }
type GetUserTweetsResp struct { type GetUserTweetsResp struct {
Data *base.PageResp joint.CachePageResp
JsonResp json.RawMessage
} }
type GetUserProfileReq struct { type GetUserProfileReq struct {
@ -115,18 +118,6 @@ func (r *TimelineReq) Bind(c *gin.Context) mir.Error {
User: user, User: user,
} }
r.Page, r.PageSize = app.GetPageInfo(c) r.Page, r.PageSize = app.GetPageInfo(c)
r.Query, r.Type = c.Query("query"), "search" r.Query, r.Type, r.Style = c.Query("query"), "search", c.Query("style")
return nil return nil
} }
func (r *GetUserTweetsResp) 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.Data,
})
}
}

@ -13,6 +13,7 @@ import (
"github.com/alimy/mir/v4" "github.com/alimy/mir/v4"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/core/ms" "github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/model/joint" "github.com/rocboss/paopao-ce/internal/model/joint"
"github.com/rocboss/paopao-ce/internal/servants/base" "github.com/rocboss/paopao-ce/internal/servants/base"
@ -20,6 +21,17 @@ import (
"github.com/rocboss/paopao-ce/pkg/xerror" "github.com/rocboss/paopao-ce/pkg/xerror"
) )
const (
// 推文可见性
TweetVisitPublic TweetVisibleType = iota
TweetVisitPrivate
TweetVisitFriend
TweetVisitFollowing
TweetVisitInvalid
)
type TweetVisibleType cs.TweetVisibleType
type TweetCommentThumbsReq struct { type TweetCommentThumbsReq struct {
SimpleInfo `json:"-" binding:"-"` SimpleInfo `json:"-" binding:"-"`
TweetId int64 `json:"tweet_id" binding:"required"` TweetId int64 `json:"tweet_id" binding:"required"`
@ -45,7 +57,7 @@ type CreateTweetReq struct {
Tags []string `json:"tags" binding:"required"` Tags []string `json:"tags" binding:"required"`
Users []string `json:"users" binding:"required"` Users []string `json:"users" binding:"required"`
AttachmentPrice int64 `json:"attachment_price"` AttachmentPrice int64 `json:"attachment_price"`
Visibility core.PostVisibleT `json:"visibility"` Visibility TweetVisibleType `json:"visibility"`
ClientIP string `json:"-" binding:"-"` ClientIP string `json:"-" binding:"-"`
} }
@ -104,11 +116,11 @@ type HighlightTweetResp struct {
type VisibleTweetReq struct { type VisibleTweetReq struct {
BaseInfo `json:"-" binding:"-"` BaseInfo `json:"-" binding:"-"`
ID int64 `json:"id"` ID int64 `json:"id"`
Visibility core.PostVisibleT `json:"visibility"` Visibility TweetVisibleType `json:"visibility"`
} }
type VisibleTweetResp struct { type VisibleTweetResp struct {
Visibility core.PostVisibleT `json:"visibility"` Visibility TweetVisibleType `json:"visibility"`
} }
type CreateCommentReq struct { type CreateCommentReq struct {
@ -296,3 +308,22 @@ func (r *CreateTweetResp) Render(c *gin.Context) {
Id: r.ID, Id: r.ID,
}) })
} }
func (t TweetVisibleType) ToVisibleValue() (res cs.TweetVisibleType) {
// 原来的可见性: 0公开 1私密 2好友可见 3关注可见
// 现在的可见性: 0私密 10充电可见 20订阅可见 30保留 40保留 50好友可见 60关注可见 70保留 80保留 90公开
switch t {
case TweetVisitPublic:
res = cs.TweetVisitPublic
case TweetVisitPrivate:
res = cs.TweetVisitPrivate
case TweetVisitFriend:
res = cs.TweetVisitFriend
case TweetVisitFollowing:
res = cs.TweetVisitFollowing
default:
// TODO: 默认私密
res = cs.TweetVisitPrivate
}
return
}

@ -47,6 +47,8 @@ var (
ErrStickPostFailed = xerror.NewError(30011, "动态置顶失败") ErrStickPostFailed = xerror.NewError(30011, "动态置顶失败")
ErrVisblePostFailed = xerror.NewError(30012, "更新可见性失败") ErrVisblePostFailed = xerror.NewError(30012, "更新可见性失败")
ErrHighlightPostFailed = xerror.NewError(30013, "动态设为亮点失败") ErrHighlightPostFailed = xerror.NewError(30013, "动态设为亮点失败")
ErrGetPostsUnknowStyle = xerror.NewError(30014, "使用未知样式参数获取动态列表")
ErrGetPostsNilUser = xerror.NewError(30015, "使用游客账户获取动态详情失败")
ErrGetCommentsFailed = xerror.NewError(40001, "获取评论列表失败") ErrGetCommentsFailed = xerror.NewError(40001, "获取评论列表失败")
ErrCreateCommentFailed = xerror.NewError(40002, "评论发布失败") ErrCreateCommentFailed = xerror.NewError(40002, "评论发布失败")

@ -208,17 +208,15 @@ func (s *DaoServant) pushAllPostToSearch() error {
ctx := context.Background() ctx := context.Background()
if err := s.Redis.SetPushToSearchJob(ctx); err == nil { if err := s.Redis.SetPushToSearchJob(ctx); err == nil {
defer s.Redis.DelPushToSearchJob(ctx) defer s.Redis.DelPushToSearchJob(ctx)
splitNum := 1000 splitNum := 1000
conditions := ms.ConditionsT{ posts, totalRows, err := s.Ds.ListSyncSearchTweets(splitNum, 0)
"visibility IN ?": []core.PostVisibleT{core.PostVisitPublic, core.PostVisitFriend}, if err != nil {
} return fmt.Errorf("get first page tweets push to search failed: %s", err)
totalRows, _ := s.Ds.GetPostCount(conditions) }
pages := math.Ceil(float64(totalRows) / float64(splitNum)) i, nums := 0, int(math.Ceil(float64(totalRows)/float64(splitNum)))
nums := int(pages) for {
for i := 0; i < nums; i++ { postsFormated, xerr := s.Ds.MergePosts(posts)
posts, postsFormated, err := s.GetTweetList(conditions, i*splitNum, splitNum) if xerr != nil || len(posts) != len(postsFormated) {
if err != nil || len(posts) != len(postsFormated) {
continue continue
} }
for i, pf := range postsFormated { for i, pf := range postsFormated {
@ -234,6 +232,12 @@ func (s *DaoServant) pushAllPostToSearch() error {
}} }}
s.Ts.AddDocuments(docs, fmt.Sprintf("%d", posts[i].ID)) s.Ts.AddDocuments(docs, fmt.Sprintf("%d", posts[i].ID))
} }
if i++; i >= nums {
break
}
if posts, _, err = s.Ds.ListSyncSearchTweets(splitNum, i*splitNum); err != nil {
return fmt.Errorf("get tweets push to search failed: %s, limit[%d] offset[%d]", err, splitNum, i*splitNum)
}
} }
} else { } else {
return fmt.Errorf("redis: set JOB_PUSH_TO_SEARCH error: %w", err) return fmt.Errorf("redis: set JOB_PUSH_TO_SEARCH error: %w", err)

@ -5,6 +5,8 @@
package web package web
import ( import (
"time"
"github.com/alimy/mir/v4" "github.com/alimy/mir/v4"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
api "github.com/rocboss/paopao-ce/auto/api/v1" api "github.com/rocboss/paopao-ce/auto/api/v1"
@ -24,7 +26,8 @@ var (
type adminSrv struct { type adminSrv struct {
api.UnimplementedAdminServant api.UnimplementedAdminServant
*base.DaoServant *base.DaoServant
ac core.AppCache wc core.WebCache
serverUpTime int64
} }
func (s *adminSrv) Chain() gin.HandlersChain { func (s *adminSrv) Chain() gin.HandlersChain {
@ -45,24 +48,28 @@ func (s *adminSrv) ChangeUserStatus(req *web.ChangeUserStatusReq) mir.Error {
} }
func (s *adminSrv) SiteInfo(req *web.SiteInfoReq) (*web.SiteInfoResp, mir.Error) { func (s *adminSrv) SiteInfo(req *web.SiteInfoReq) (*web.SiteInfoResp, mir.Error) {
registerUserCount, err := s.Ds.GetRegisterUserCount() res, err := &web.SiteInfoResp{ServerUpTime: s.serverUpTime}, error(nil)
res.RegisterUserCount, err = s.Ds.GetRegisterUserCount()
if err != nil { if err != nil {
logrus.Errorf("get SiteInfo[1] occurs error: %s", err) logrus.Errorf("get SiteInfo[1] occurs error: %s", err)
} }
onlineUserKeys, err := s.ac.Keys(conf.PrefixOnlineUser + "*") onlineUserKeys, xerr := s.wc.Keys(conf.PrefixOnlineUser + "*")
if err != nil { if xerr == nil {
res.OnlineUserCount = len(onlineUserKeys)
if res.HistoryMaxOnline, err = s.wc.PutHistoryMaxOnline(res.OnlineUserCount); err != nil {
logrus.Errorf("get Siteinfo[3] occurs error: %s", err)
}
} else {
logrus.Errorf("get Siteinfo[2] occurs error: %s", err) logrus.Errorf("get Siteinfo[2] occurs error: %s", err)
} }
// 错误进行宽松赦免处理 // 错误进行宽松赦免处理
return &web.SiteInfoResp{ return res, nil
RegisterUserCount: registerUserCount,
OnlineUserCount: len(onlineUserKeys),
}, nil
} }
func newAdminSrv(s *base.DaoServant, ac core.AppCache) api.Admin { func newAdminSrv(s *base.DaoServant, wc core.WebCache) api.Admin {
return &adminSrv{ return &adminSrv{
DaoServant: s, DaoServant: s,
ac: ac, wc: wc,
serverUpTime: time.Now().Unix(),
} }
} }

@ -0,0 +1,39 @@
// 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/tryst/cfg"
"github.com/robfig/cron/v3"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/events"
"github.com/sirupsen/logrus"
)
func onMaxOnlineJob() {
spec := conf.JobManagerSetting.MaxOnlineInterval
schedule, err := cron.ParseStandard(spec)
if err != nil {
panic(err)
}
events.OnTask(schedule, func() {
onlineUserKeys, err := _wc.Keys(conf.PrefixOnlineUser + "*")
if maxOnline := len(onlineUserKeys); err == nil && maxOnline > 0 {
if _, err = _wc.PutHistoryMaxOnline(maxOnline); err != nil {
logrus.Warnf("onMaxOnlineJob[2] occurs error: %s", err)
}
} else if err != nil {
logrus.Warnf("onMaxOnlineJob[1] occurs error: %s", err)
}
})
}
func scheduleJobs() {
cfg.Not("DisableJobManager", func() {
lazyInitial()
onMaxOnlineJob()
logrus.Debug("schedule inner jobs complete")
})
}

@ -8,7 +8,6 @@ import (
"fmt" "fmt"
"github.com/alimy/mir/v4" "github.com/alimy/mir/v4"
"github.com/alimy/tryst/lets"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
api "github.com/rocboss/paopao-ce/auto/api/v1" api "github.com/rocboss/paopao-ce/auto/api/v1"
"github.com/rocboss/paopao-ce/internal/conf" "github.com/rocboss/paopao-ce/internal/conf"
@ -16,6 +15,7 @@ import (
"github.com/rocboss/paopao-ce/internal/core/cs" "github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/core/ms" "github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"github.com/rocboss/paopao-ce/internal/model/joint"
"github.com/rocboss/paopao-ce/internal/model/web" "github.com/rocboss/paopao-ce/internal/model/web"
"github.com/rocboss/paopao-ce/internal/servants/base" "github.com/rocboss/paopao-ce/internal/servants/base"
"github.com/rocboss/paopao-ce/internal/servants/chain" "github.com/rocboss/paopao-ce/internal/servants/chain"
@ -31,7 +31,11 @@ type looseSrv struct {
*base.DaoServant *base.DaoServant
ac core.AppCache ac core.AppCache
userTweetsExpire int64 userTweetsExpire int64
idxTweetsExpire int64
prefixUserTweets string prefixUserTweets string
prefixIdxTweetsNewest string
prefixIdxTweetsHots string
prefixIdxTweetsFollowing string
} }
func (s *looseSrv) Chain() gin.HandlersChain { func (s *looseSrv) Chain() gin.HandlersChain {
@ -39,16 +43,10 @@ func (s *looseSrv) Chain() gin.HandlersChain {
} }
func (s *looseSrv) Timeline(req *web.TimelineReq) (*web.TimelineResp, mir.Error) { func (s *looseSrv) Timeline(req *web.TimelineReq) (*web.TimelineResp, mir.Error) {
var resp *base.PageResp limit, offset := req.PageSize, (req.Page-1)*req.PageSize
offset, limit := (req.Page-1)*req.PageSize, req.PageSize
if req.Query == "" && req.Type == "search" { if req.Query == "" && req.Type == "search" {
res, err := s.Ds.IndexPosts(req.User, offset, limit) return s.getIndexTweets(req, limit, offset)
if err != nil {
logrus.Errorf("Ds.IndexPosts err: %s", err)
return nil, web.ErrGetPostsFailed
} }
resp = base.PageRespFrom(res.Tweets, req.Page, req.PageSize, res.Total)
} else {
q := &core.QueryReq{ q := &core.QueryReq{
Query: req.Query, Query: req.Query,
Type: core.SearchType(req.Type), Type: core.SearchType(req.Type),
@ -63,9 +61,86 @@ func (s *looseSrv) Timeline(req *web.TimelineReq) (*web.TimelineResp, mir.Error)
logrus.Errorf("Ds.RevampPosts err: %s", err) logrus.Errorf("Ds.RevampPosts err: %s", err)
return nil, web.ErrGetPostsFailed return nil, web.ErrGetPostsFailed
} }
resp = base.PageRespFrom(posts, req.Page, req.PageSize, res.Total) // TODO: 暂时处理,需要去掉这个步骤
visbleTansform(posts)
resp := joint.PageRespFrom(posts, req.Page, req.PageSize, res.Total)
return &web.TimelineResp{
CachePageResp: joint.CachePageResp{
Data: resp,
},
}, nil
}
func (s *looseSrv) getIndexTweets(req *web.TimelineReq, limit int, offset int) (res *web.TimelineResp, err mir.Error) {
// 尝试直接从缓存中获取数据
key, ok := "", false
if res, key, ok = s.indexTweetsFromCache(req, limit, offset); ok {
// logrus.Debugf("getIndexTweets from cache key:%s", key)
return
}
var (
posts []*ms.Post
total int64
xerr error
)
switch req.Style {
case web.StyleTweetsFollowing:
if req.User != nil {
posts, total, xerr = s.Ds.ListFollowingTweets(req.User.ID, limit, offset)
} else {
return nil, web.ErrGetPostsNilUser
}
case web.StyleTweetsNewest:
posts, total, xerr = s.Ds.ListIndexNewestTweets(limit, offset)
case web.StyleTweetsHots:
posts, total, xerr = s.Ds.ListIndexHotsTweets(limit, offset)
default:
return nil, web.ErrGetPostsUnknowStyle
}
if xerr != nil {
logrus.Errorf("getIndexTweets occurs error: %s", xerr)
return nil, web.ErrGetPostFailed
}
postsFormated, verr := s.Ds.MergePosts(posts)
if verr != nil {
logrus.Errorf("getIndexTweets in merge posts occurs error: %s", verr)
return nil, web.ErrGetPostFailed
}
// TODO: 暂时处理,需要去掉这个步骤
visbleTansform(postsFormated)
resp := joint.PageRespFrom(postsFormated, req.Page, req.PageSize, total)
// 缓存处理
base.OnCacheRespEvent(s.ac, key, resp, s.idxTweetsExpire)
return &web.TimelineResp{
CachePageResp: joint.CachePageResp{
Data: resp,
},
}, nil
}
func (s *looseSrv) indexTweetsFromCache(req *web.TimelineReq, limit int, offset int) (res *web.TimelineResp, key string, ok bool) {
switch req.Style {
case web.StyleTweetsFollowing:
username := "_"
if req.User != nil {
username = req.User.Username
}
key = fmt.Sprintf("%s%s:%d:%d", s.prefixIdxTweetsFollowing, username, offset, limit)
case web.StyleTweetsNewest:
key = fmt.Sprintf("%s%d:%d", s.prefixIdxTweetsNewest, offset, limit)
case web.StyleTweetsHots:
key = fmt.Sprintf("%s%d:%d", s.prefixIdxTweetsHots, offset, limit)
default:
return
}
if data, err := s.ac.Get(key); err == nil {
ok, res = true, &web.TimelineResp{
CachePageResp: joint.CachePageResp{
JsonResp: data,
},
} }
return (*web.TimelineResp)(resp), nil }
return
} }
func (s *looseSrv) GetUserTweets(req *web.GetUserTweetsReq) (res *web.GetUserTweetsResp, err mir.Error) { func (s *looseSrv) GetUserTweets(req *web.GetUserTweetsReq) (res *web.GetUserTweetsResp, err mir.Error) {
@ -102,13 +177,20 @@ func (s *looseSrv) GetUserTweets(req *web.GetUserTweetsReq) (res *web.GetUserTwe
func (s *looseSrv) userTweetsFromCache(req *web.GetUserTweetsReq, user *cs.VistUser) (res *web.GetUserTweetsResp, key string, ok bool) { func (s *looseSrv) userTweetsFromCache(req *web.GetUserTweetsReq, user *cs.VistUser) (res *web.GetUserTweetsResp, key string, ok bool) {
switch req.Style { switch req.Style {
case web.UserPostsStylePost, web.UserPostsStyleHighlight, web.UserPostsStyleMedia: case web.UserPostsStylePost, web.UserPostsStyleHighlight, web.UserPostsStyleMedia:
key = fmt.Sprintf("%s%s:%s:%s:%d:%d", s.prefixUserTweets, req.Username, req.Style, user.RelTyp, req.Page, req.PageSize) key = fmt.Sprintf("%s%d:%s:%s:%d:%d", s.prefixUserTweets, user.UserId, req.Style, user.RelTyp, req.Page, req.PageSize)
default: default:
visitUserName := lets.If(user.RelTyp != cs.RelationGuest, user.Username, "_") meName := "_"
key = fmt.Sprintf("%s%s:%s:%s:%d:%d", s.prefixUserTweets, req.Username, req.Style, visitUserName, req.Page, req.PageSize) if user.RelTyp != cs.RelationGuest {
meName = req.User.Username
}
key = fmt.Sprintf("%s%d:%s:%s:%d:%d", s.prefixUserTweets, user.UserId, req.Style, meName, req.Page, req.PageSize)
} }
if data, err := s.ac.Get(key); err == nil { if data, err := s.ac.Get(key); err == nil {
ok, res = true, &web.GetUserTweetsResp{JsonResp: data} ok, res = true, &web.GetUserTweetsResp{
CachePageResp: joint.CachePageResp{
JsonResp: data,
},
}
} }
return return
} }
@ -130,8 +212,14 @@ func (s *looseSrv) getUserStarTweets(req *web.GetUserTweetsReq, user *cs.VistUse
logrus.Errorf("Ds.MergePosts err: %s", err) logrus.Errorf("Ds.MergePosts err: %s", err)
return nil, web.ErrGetStarsFailed return nil, web.ErrGetStarsFailed
} }
resp := base.PageRespFrom(postsFormated, req.Page, req.PageSize, totalRows) // TODO: 暂时处理,需要去掉这个步骤
return &web.GetUserTweetsResp{Data: resp}, nil visbleTansform(postsFormated)
resp := joint.PageRespFrom(postsFormated, req.Page, req.PageSize, totalRows)
return &web.GetUserTweetsResp{
CachePageResp: joint.CachePageResp{
Data: resp,
},
}, nil
} }
func (s *looseSrv) listUserTweets(req *web.GetUserTweetsReq, user *cs.VistUser) (*web.GetUserTweetsResp, mir.Error) { func (s *looseSrv) listUserTweets(req *web.GetUserTweetsReq, user *cs.VistUser) (*web.GetUserTweetsResp, mir.Error) {
@ -157,42 +245,50 @@ func (s *looseSrv) listUserTweets(req *web.GetUserTweetsReq, user *cs.VistUser)
logrus.Errorf("s.listUserTweets err: %s", err) logrus.Errorf("s.listUserTweets err: %s", err)
return nil, web.ErrGetPostsFailed return nil, web.ErrGetPostsFailed
} }
resp := base.PageRespFrom(postFormated, req.Page, req.PageSize, total) // TODO: 暂时处理,需要去掉这个步骤
return &web.GetUserTweetsResp{Data: resp}, nil visbleTansform(postFormated)
resp := joint.PageRespFrom(postFormated, req.Page, req.PageSize, total)
return &web.GetUserTweetsResp{
CachePageResp: joint.CachePageResp{
Data: resp,
},
}, nil
} }
func (s *looseSrv) getUserPostTweets(req *web.GetUserTweetsReq, user *cs.VistUser, isHighlight bool) (*web.GetUserTweetsResp, mir.Error) { func (s *looseSrv) getUserPostTweets(req *web.GetUserTweetsReq, user *cs.VistUser, isHighlight bool) (*web.GetUserTweetsResp, mir.Error) {
visibilities := []core.PostVisibleT{core.PostVisitPublic} style := cs.StyleUserTweetsGuest
switch user.RelTyp { switch user.RelTyp {
case cs.RelationAdmin, cs.RelationSelf: case cs.RelationAdmin:
visibilities = append(visibilities, core.PostVisitPrivate, core.PostVisitFriend) style = cs.StyleUserTweetsAdmin
case cs.RelationSelf:
style = cs.StyleUserTweetsSelf
case cs.RelationFriend: case cs.RelationFriend:
visibilities = append(visibilities, core.PostVisitFriend) style = cs.StyleUserTweetsFriend
case cs.RelationFollowing:
style = cs.StyleUserTweetsFollowing
case cs.RelationGuest: case cs.RelationGuest:
fallthrough fallthrough
default: default:
// nothing // nothing
} }
conditions := ms.ConditionsT{ posts, total, err := s.Ds.ListUserTweets(user.UserId, style, isHighlight, req.PageSize, (req.Page-1)*req.PageSize)
"user_id": user.UserId,
"visibility IN ?": visibilities,
"ORDER": "latest_replied_on DESC",
}
if isHighlight {
conditions["is_essence"] = 1
}
_, posts, err := s.GetTweetList(conditions, (req.Page-1)*req.PageSize, req.PageSize)
if err != nil { if err != nil {
logrus.Errorf("s.GetTweetList err: %s", err) logrus.Errorf("s.GetTweetList error[1]: %s", err)
return nil, web.ErrGetPostsFailed return nil, web.ErrGetPostsFailed
} }
totalRows, err := s.Ds.GetPostCount(conditions) postsFormated, xerr := s.Ds.MergePosts(posts)
if err != nil { if xerr != nil {
logrus.Errorf("s.GetPostCount err: %s", err) logrus.Errorf("s.GetTweetList error[2]: %s", err)
return nil, web.ErrGetPostsFailed return nil, web.ErrGetPostsFailed
} }
resp := base.PageRespFrom(posts, req.Page, req.PageSize, totalRows) // TODO: 暂时处理,需要去掉这个步骤
return &web.GetUserTweetsResp{Data: resp}, nil visbleTansform(postsFormated)
resp := joint.PageRespFrom(postsFormated, req.Page, req.PageSize, total)
return &web.GetUserTweetsResp{
CachePageResp: joint.CachePageResp{
Data: resp,
},
}, nil
} }
func (s *looseSrv) GetUserProfile(req *web.GetUserProfileReq) (*web.GetUserProfileResp, mir.Error) { func (s *looseSrv) GetUserProfile(req *web.GetUserProfileReq) (*web.GetUserProfileResp, mir.Error) {
@ -355,10 +451,15 @@ func (s *looseSrv) TweetComments(req *web.TweetCommentsReq) (*web.TweetCommentsR
} }
func newLooseSrv(s *base.DaoServant, ac core.AppCache) api.Loose { func newLooseSrv(s *base.DaoServant, ac core.AppCache) api.Loose {
cs := conf.CacheSetting
return &looseSrv{ return &looseSrv{
DaoServant: s, DaoServant: s,
ac: ac, ac: ac,
userTweetsExpire: conf.CacheSetting.UserTweetsExpire, userTweetsExpire: cs.UserTweetsExpire,
idxTweetsExpire: cs.IndexTweetsExpire,
prefixUserTweets: conf.PrefixUserTweets, prefixUserTweets: conf.PrefixUserTweets,
prefixIdxTweetsNewest: conf.PrefixIdxTweetsNewest,
prefixIdxTweetsHots: conf.PrefixIdxTweetsHots,
prefixIdxTweetsFollowing: conf.PrefixIdxTweetsFollowing,
} }
} }

@ -249,7 +249,7 @@ func (s *privSrv) CreateTweet(req *web.CreateTweetReq) (_ *web.CreateTweetResp,
IP: req.ClientIP, IP: req.ClientIP,
IPLoc: utils.GetIPLoc(req.ClientIP), IPLoc: utils.GetIPLoc(req.ClientIP),
AttachmentPrice: req.AttachmentPrice, AttachmentPrice: req.AttachmentPrice,
Visibility: req.Visibility, Visibility: ms.PostVisibleT(req.Visibility.ToVisibleValue()),
} }
post, err = s.Ds.CreatePost(post) post, err = s.Ds.CreatePost(post)
if err != nil { if err != nil {
@ -598,7 +598,7 @@ func (s *privSrv) StarTweet(req *web.StarTweetReq) (*web.StarTweetResp, mir.Erro
} }
func (s *privSrv) VisibleTweet(req *web.VisibleTweetReq) (*web.VisibleTweetResp, mir.Error) { func (s *privSrv) VisibleTweet(req *web.VisibleTweetReq) (*web.VisibleTweetResp, mir.Error) {
if req.Visibility >= core.PostVisitInvalid { if req.Visibility >= web.TweetVisitInvalid {
return nil, xerror.InvalidParams return nil, xerror.InvalidParams
} }
post, err := s.Ds.GetPostByID(req.ID) post, err := s.Ds.GetPostByID(req.ID)
@ -608,13 +608,13 @@ func (s *privSrv) VisibleTweet(req *web.VisibleTweetReq) (*web.VisibleTweetResp,
if xerr := checkPermision(req.User, post.UserID); xerr != nil { if xerr := checkPermision(req.User, post.UserID); xerr != nil {
return nil, xerr return nil, xerr
} }
if err = s.Ds.VisiblePost(post, req.Visibility); err != nil { if err = s.Ds.VisiblePost(post, req.Visibility.ToVisibleValue()); err != nil {
logrus.Warnf("s.Ds.VisiblePost: %s", err) logrus.Warnf("s.Ds.VisiblePost: %s", err)
return nil, web.ErrVisblePostFailed return nil, web.ErrVisblePostFailed
} }
// 推送Search // 推送Search
post.Visibility = req.Visibility post.Visibility = ms.PostVisibleT(req.Visibility.ToVisibleValue())
s.PushPostToSearch(post) s.PushPostToSearch(post)
return &web.VisibleTweetResp{ return &web.VisibleTweetResp{

@ -65,6 +65,8 @@ func (s *pubSrv) TweetDetail(req *web.TweetDetailReq) (*web.TweetDetailResp, mir
postFormated.Contents = append(postFormated.Contents, content.Format()) postFormated.Contents = append(postFormated.Contents, content.Format())
} }
} }
// TODO: 暂时处理办法,后续需要优化去掉这个步骤
postFormated.Visibility = ms.PostVisibleT(postFormated.Visibility.ToOutValue())
return (*web.TweetDetailResp)(postFormated), nil return (*web.TweetDetailResp)(postFormated), nil
} }

@ -207,3 +207,10 @@ func checkPermision(user *ms.User, targetUserId int64) mir.Error {
} }
return nil return nil
} }
// visbleTansform 可见性等价转换,暂时处理方式,后续需要去掉这个步骤
func visbleTansform(list []*ms.PostFormated) {
for _, post := range list {
post.Visibility = ms.PostVisibleT(post.Visibility.ToOutValue())
}
}

@ -32,7 +32,7 @@ func RouteWeb(e *gin.Engine) {
lazyInitial() lazyInitial()
ds := base.NewDaoServant() ds := base.NewDaoServant()
// aways register servants // aways register servants
api.RegisterAdminServant(e, newAdminSrv(ds, _ac)) api.RegisterAdminServant(e, newAdminSrv(ds, _wc))
api.RegisterCoreServant(e, newCoreSrv(ds, _oss, _wc)) api.RegisterCoreServant(e, newCoreSrv(ds, _oss, _wc))
api.RegisterRelaxServant(e, newRelaxSrv(ds, _wc), newRelaxChain()) api.RegisterRelaxServant(e, newRelaxSrv(ds, _wc), newRelaxChain())
api.RegisterLooseServant(e, newLooseSrv(ds, _ac)) api.RegisterLooseServant(e, newLooseSrv(ds, _ac))
@ -46,6 +46,8 @@ func RouteWeb(e *gin.Engine) {
api.RegisterAlipayPubServant(e, newAlipayPubSrv(ds)) api.RegisterAlipayPubServant(e, newAlipayPubSrv(ds))
api.RegisterAlipayPrivServant(e, newAlipayPrivSrv(ds, client)) api.RegisterAlipayPrivServant(e, newAlipayPrivSrv(ds, client))
}) })
// shedule jobs if need
scheduleJobs()
} }
// lazyInitial do some package lazy initialize for performance // lazyInitial do some package lazy initialize for performance

@ -0,0 +1,15 @@
DROP TABLE IF EXISTS `p_post_metric`;
-- 原来的可见性: 0公开 1私密 2好友可见 3关注可见
-- 现在的可见性: 0私密 10充电可见 20订阅可见 30保留 40保留 50好友可见 60关注可见 70保留 80保留 90公开
UPDATE p_post a, p_post b
SET a.visibility = (
CASE b.visibility
WHEN 90 THEN 0
WHEN 0 THEN 1
WHEN 50 THEN 2
WHEN 60 THEN 3
ELSE 0
END
)
WHERE a.ID = b.ID;

@ -0,0 +1,35 @@
CREATE TABLE `p_post_metric` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`post_id` bigint unsigned NOT NULL,
`rank_score` bigint unsigned NOT NULL DEFAULT 0,
`incentive_score` int unsigned NOT NULL DEFAULT 0,
`decay_factor` int unsigned NOT NULL DEFAULT 0,
`motivation_factor` int unsigned NOT NULL DEFAULT 0,
`is_del` tinyint NOT NULL DEFAULT 0, -- 是否删除, 0否, 1是
`created_on` bigint unsigned NOT NULL DEFAULT '0',
`modified_on` bigint unsigned NOT NULL DEFAULT '0',
`deleted_on` bigint unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_post_metric_post_id_rank_score` (`post_id`,`rank_score`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
INSERT INTO p_post_metric (post_id, rank_score, created_on)
SELECT id AS post_id,
comment_count + upvote_count*2 + collection_count*4 AS rank_score,
created_on
FROM p_post
WHERE is_del=0;
-- 原来的可见性: 0公开 1私密 2好友可见 3关注可见
-- 现在的可见性: 0私密 10充电可见 20订阅可见 30保留 40保留 50好友可见 60关注可见 70保留 80保留 90公开
UPDATE p_post a, p_post b
SET a.visibility = (
CASE b.visibility
WHEN 0 THEN 90
WHEN 1 THEN 0
WHEN 2 THEN 50
WHEN 3 THEN 60
ELSE 0
END
)
WHERE a.ID = b.ID;

@ -0,0 +1,19 @@
DROP TABLE IF EXISTS p_post_metric;
-- 原来的可见性: 0公开 1私密 2好友可见 3关注可见
-- 现在的可见性: 0私密 10充电可见 20订阅可见 30保留 40保留 50好友可见 60关注可见 70保留 80保留 90公开
UPDATE p_post a
SET visibility = (
SELECT
CASE visibility
WHEN 90 THEN 0
WHEN 0 THEN 1
WHEN 50 THEN 2
WHEN 60 THEN 3
ELSE 0
END
FROM
p_post b
WHERE
a.ID = b.ID
);

@ -0,0 +1,40 @@
CREATE TABLE p_post_metric (
ID BIGSERIAL PRIMARY KEY,
post_id BIGINT NOT NULL,
rank_score BIGINT NOT NULL DEFAULT 0,
incentive_score INT NOT NULL DEFAULT 0,
decay_factor INT NOT NULL DEFAULT 0,
motivation_factor INT NOT NULL DEFAULT 0,
is_del SMALLINT NOT NULL DEFAULT 0,
created_on BIGINT NOT NULL DEFAULT 0,
modified_on BIGINT NOT NULL DEFAULT 0,
deleted_on BIGINT NOT NULL DEFAULT 0
);
CREATE INDEX idx_post_metric_post_id_rank_score ON p_post_metric USING btree ( post_id, rank_score );
INSERT INTO p_post_metric ( post_id, rank_score, created_on ) SELECT ID AS
post_id,
comment_count + upvote_count * 2 + collection_count * 4 AS rank_score,
created_on
FROM
p_post
WHERE
is_del = 0;
-- 原来的可见性: 0公开 1私密 2好友可见 3关注可见
-- 现在的可见性: 0私密 10充电可见 20订阅可见 30保留 40保留 50好友可见 60关注可见 70保留 80保留 90公开
UPDATE p_post a
SET visibility = (
SELECT
CASE visibility
WHEN 0 THEN 90
WHEN 1 THEN 0
WHEN 2 THEN 50
WHEN 3 THEN 60
ELSE 0
END
FROM
p_post b
WHERE
a.ID = b.ID
);

@ -0,0 +1,19 @@
DROP TABLE IF EXISTS "p_post_metric";
-- 原来的可见性: 0公开 1私密 2好友可见 3关注可见
-- 现在的可见性: 0私密 10充电可见 20订阅可见 30保留 40保留 50好友可见 60关注可见 70保留 80保留 90公开
UPDATE p_post AS a
SET visibility = (
SELECT
CASE visibility
WHEN 90 THEN 0
WHEN 0 THEN 1
WHEN 50 THEN 2
WHEN 60 THEN 3
ELSE 0
END
FROM
p_post AS b
WHERE
a.ID = b.ID
);

@ -0,0 +1,44 @@
CREATE TABLE "p_post_metric" (
"id" integer NOT NULL,
"post_id" integer NOT NULL,
"rank_score" integer NOT NULL,
"incentive_score" integer NOT NULL DEFAULT 0,
"decay_factor" integer NOT NULL DEFAULT 0,
"motivation_factor" integer NOT NULL DEFAULT 0,
"is_del" integer NOT NULL DEFAULT 0,
"created_on" integer NOT NULL DEFAULT 0,
"modified_on" integer NOT NULL DEFAULT 0,
"deleted_on" integer NOT NULL DEFAULT 0,
PRIMARY KEY ("id")
);
CREATE INDEX "idx_post_metric_post_id_rank_score"
ON "p_post_metric" (
"post_id" ASC,
"rank_score" ASC
);
INSERT INTO p_post_metric (post_id, rank_score, created_on)
SELECT id AS post_id,
comment_count+upvote_count*2+collection_count*4 AS rank_score,
created_on
FROM p_post
WHERE is_del=0;
-- 原来的可见性: 0公开 1私密 2好友可见 3关注可见
-- 现在的可见性: 0私密 10充电可见 20订阅可见 30保留 40保留 50好友可见 60关注可见 70保留 80保留 90公开
UPDATE p_post AS a
SET visibility = (
SELECT
CASE visibility
WHEN 0 THEN 90
WHEN 1 THEN 0
WHEN 2 THEN 50
WHEN 3 THEN 60
ELSE 0
END
FROM
p_post AS b
WHERE
a.ID = b.ID
);

@ -163,7 +163,7 @@ CREATE TABLE `p_post` (
`collection_count` bigint unsigned NOT NULL DEFAULT '0' COMMENT '收藏数', `collection_count` bigint unsigned NOT NULL DEFAULT '0' COMMENT '收藏数',
`upvote_count` bigint unsigned NOT NULL DEFAULT '0' COMMENT '点赞数', `upvote_count` bigint unsigned NOT NULL DEFAULT '0' COMMENT '点赞数',
`share_count` bigint unsigned NOT NULL DEFAULT '0' COMMENT '分享数', `share_count` bigint unsigned NOT NULL DEFAULT '0' COMMENT '分享数',
`visibility` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '可见性 0公开 1私密 2好友可见', `visibility` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '可见性: 0私密 10充电可见 20订阅可见 30保留 40保留 50好友可见 60关注可见 70保留 80保留 90公开',
`is_top` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '是否置顶', `is_top` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '是否置顶',
`is_essence` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '是否精华', `is_essence` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '是否精华',
`is_lock` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '是否锁定', `is_lock` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '是否锁定',
@ -181,6 +181,25 @@ CREATE TABLE `p_post` (
KEY `idx_post_visibility` (`visibility`) USING BTREE KEY `idx_post_visibility` (`visibility`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1080017989 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='冒泡/文章'; ) ENGINE=InnoDB AUTO_INCREMENT=1080017989 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='冒泡/文章';
-- ----------------------------
-- Table structure for p_post_metric
-- ----------------------------
DROP TABLE IF EXISTS `p_post_metric`;
CREATE TABLE `p_post_metric` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`post_id` bigint unsigned NOT NULL,
`rank_score` bigint unsigned NOT NULL DEFAULT 0,
`incentive_score` int unsigned NOT NULL DEFAULT 0,
`decay_factor` int unsigned NOT NULL DEFAULT 0,
`motivation_factor` int unsigned NOT NULL DEFAULT 0,
`is_del` tinyint NOT NULL DEFAULT 0, -- 是否删除, 0否, 1是
`created_on` bigint unsigned NOT NULL DEFAULT '0',
`modified_on` bigint unsigned NOT NULL DEFAULT '0',
`deleted_on` bigint unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_post_metric_post_id_rank_score` (`post_id`,`rank_score`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- ---------------------------- -- ----------------------------
-- Table structure for p_post_attachment_bill -- Table structure for p_post_attachment_bill
-- ---------------------------- -- ----------------------------

@ -158,7 +158,7 @@ CREATE TABLE p_post (
collection_count BIGINT NOT NULL DEFAULT 0, collection_count BIGINT NOT NULL DEFAULT 0,
upvote_count BIGINT NOT NULL DEFAULT 0, upvote_count BIGINT NOT NULL DEFAULT 0,
share_count BIGINT NOT NULL DEFAULT 0, share_count BIGINT NOT NULL DEFAULT 0,
visibility SMALLINT NOT NULL DEFAULT 0, -- 可见性 0公开 1私密 2好友可见 visibility SMALLINT NOT NULL DEFAULT 0, -- 可见性: 0私密 10充电可见 20订阅可见 30保留 40保留 50好友可见 60关注可见 70保留 80保留 90公开
is_top SMALLINT NOT NULL DEFAULT 0, -- 是否置顶 is_top SMALLINT NOT NULL DEFAULT 0, -- 是否置顶
is_essence SMALLINT NOT NULL DEFAULT 0, -- 是否精华 is_essence SMALLINT NOT NULL DEFAULT 0, -- 是否精华
is_lock SMALLINT NOT NULL DEFAULT 0, -- 是否锁定 is_lock SMALLINT NOT NULL DEFAULT 0, -- 是否锁定
@ -176,6 +176,21 @@ CREATE TABLE p_post (
CREATE INDEX idx_post_user_id ON p_post USING btree (user_id); CREATE INDEX idx_post_user_id ON p_post USING btree (user_id);
CREATE INDEX idx_post_visibility ON p_post USING btree (visibility); CREATE INDEX idx_post_visibility ON p_post USING btree (visibility);
DROP TABLE IF EXISTS p_post_metric;
CREATE TABLE p_post_metric (
ID BIGSERIAL PRIMARY KEY,
post_id BIGINT NOT NULL,
rank_score BIGINT NOT NULL DEFAULT 0,
incentive_score INT NOT NULL DEFAULT 0,
decay_factor INT NOT NULL DEFAULT 0,
motivation_factor INT NOT NULL DEFAULT 0,
is_del SMALLINT NOT NULL DEFAULT 0,
created_on BIGINT NOT NULL DEFAULT 0,
modified_on BIGINT NOT NULL DEFAULT 0,
deleted_on BIGINT NOT NULL DEFAULT 0
);
CREATE INDEX idx_post_metric_post_id_rank_score ON p_post_metric USING btree (post_id, rank_score);
DROP TABLE IF EXISTS p_post_attachment_bill; DROP TABLE IF EXISTS p_post_attachment_bill;
CREATE TABLE p_post_attachment_bill ( CREATE TABLE p_post_attachment_bill (
id BIGSERIAL PRIMARY KEY, id BIGSERIAL PRIMARY KEY,

@ -209,7 +209,25 @@ CREATE TABLE "p_post" (
"modified_on" integer NOT NULL, "modified_on" integer NOT NULL,
"deleted_on" integer NOT NULL, "deleted_on" integer NOT NULL,
"is_del" integer NOT NULL, "is_del" integer NOT NULL,
"visibility" integer NOT NULL, "visibility" integer NOT NULL, -- 可见性: 0私密 10充电可见 20订阅可见 30保留 40保留 50好友可见 60关注可见 70保留 80保留 90公开
PRIMARY KEY ("id")
);
-- ----------------------------
-- Table structure for p_post_metric
-- ----------------------------
DROP TABLE IF EXISTS "p_post_metric";
CREATE TABLE "p_post_metric" (
"id" integer NOT NULL,
"post_id" integer NOT NULL,
"rank_score" integer NOT NULL,
"incentive_score" integer NOT NULL DEFAULT 0,
"decay_factor" integer NOT NULL DEFAULT 0,
"motivation_factor" integer NOT NULL DEFAULT 0,
"is_del" integer NOT NULL DEFAULT 0,
"created_on" integer NOT NULL DEFAULT 0,
"modified_on" integer NOT NULL DEFAULT 0,
"deleted_on" integer NOT NULL DEFAULT 0,
PRIMARY KEY ("id") PRIMARY KEY ("id")
); );
@ -531,6 +549,15 @@ ON "p_post" (
"visibility" ASC "visibility" ASC
); );
-- ----------------------------
-- Indexes structure for table idx_post_metric_post_id_rank_score
-- ----------------------------
CREATE INDEX "idx_post_metric_post_id_rank_score"
ON "p_post_metric" (
"post_id" ASC,
"rank_score" ASC
);
-- ---------------------------- -- ----------------------------
-- Indexes structure for table p_post_attachment_bill -- Indexes structure for table p_post_attachment_bill
-- ---------------------------- -- ----------------------------

@ -1 +0,0 @@
import{_ as s}from"./main-nav.vue_vue_type_style_index_0_lang-04907baf.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-6886c40b.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};

@ -0,0 +1 @@
import{_ as s}from"./main-nav.vue_vue_type_style_index_0_lang-96e8e840.js";import{u as i}from"./vue-router-e5a2430e.js";import{F as a,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-fae12ace.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";import"./moment-2ab8298d.js";/* empty css */const v=l({__name:"404",setup(h){const e=i(),_=()=>{e.push({path:"/"})};return(k,w)=>{const n=s,p=c,r=u,m=a;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 O=g(v,[["__scopeId","data-v-e62daa85"]]);export{O as default};

@ -1 +0,0 @@
import{_ as F}from"./post-skeleton-63a82733.js";import{_ as N}from"./main-nav.vue_vue_type_style_index_0_lang-04907baf.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-6886c40b.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};

@ -0,0 +1 @@
import{_ as F}from"./post-skeleton-2311fe04.js";import{_ as N}from"./main-nav.vue_vue_type_style_index_0_lang-96e8e840.js";import{u as z}from"./vuex-44de225f.js";import{b as A}from"./vue-router-e5a2430e.js";import{E as R,_ as S}from"./index-fae12ace.js";import{F as V,Q as q,I as E,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 as t,bf as u,Y as l,F as D,u as G,q as H,j as s,x as _,l as L}from"./@vue-a481fc63.js";import"./vooks-6d99783e.js";import"./evtd-b614532e.js";import"./@vicons-7a4ef312.js";import"./axios-4a70c6fc.js";import"./moment-2ab8298d.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 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),i=n([]),r=n(+g.query.p||1),f=n(20),c=n(0),h=m=>{r.value=m};return j(()=>{}),(m,J)=>{const k=N,y=q,x=F,w=E,B=I,C=V;return t(),o("div",null,[a(k,{title:"公告"}),a(C,{class:"main-content-wrap",bordered:""},{footer:p(()=>[c.value>1?(t(),o("div",M,[a(y,{page:r.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?(t(),o("div",O,[a(x,{num:f.value},null,8,["num"])])):(t(),o("div",Q,[i.value.length===0?(t(),o("div",T,[a(w,{size:"large",description:"暂无数据"})])):l("",!0),(t(!0),o(D,null,G(i.value,e=>(t(),H(B,{key:e.id},{default:p(()=>[s("div",U,[s("div",null,"NO."+_(e.id),1),s("div",null,_(e.reason),1),s("div",{class:L({income:e.change_amount>=0,out:e.change_amount<0})},_((e.change_amount>0?"+":"")+(e.change_amount/100).toFixed(2)),3),s("div",null,_(u(R)(e.created_on)),1)])]),_:2},1024))),128))]))]),_:1})])}}});const ke=S(Y,[["__scopeId","data-v-d4d04859"]]);export{ke as default};

@ -0,0 +1 @@
import{_ as I}from"./whisper-e51c17fc.js";import{_ as N,a as Q}from"./post-item.vue_vue_type_style_index_0_lang-eaa0dff0.js";import{_ as V}from"./post-skeleton-2311fe04.js";import{_ as W}from"./main-nav.vue_vue_type_style_index_0_lang-96e8e840.js";import{u as E}from"./vuex-44de225f.js";import{b as G}from"./vue-router-e5a2430e.js";import{Q as H,_ as L}from"./index-fae12ace.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-1a1bcb51.js";import"./@vicons-7a4ef312.js";import"./paopao-video-player-2fe58954.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";import"./moment-2ab8298d.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=E(),S=G(),_=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,H({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 $=W,z=V,B=A,F=N,g=D,M=Q,P=I,R=Y,q=j;return e(),o("div",null,[n($,{title:"收藏"}),n(R,{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(P,{show:c.value,user:d.value,onSuccess:b},null,8,["show","user"])]),_:1}),r.value>0?(e(),o("div",ee,[n(q,{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 Ne=L(oe,[["__scopeId","data-v-760779af"]]);export{Ne as default};

@ -1 +0,0 @@
import{_ as q}from"./whisper-ccc06a56.js";import{_ as I,a as V}from"./post-item.vue_vue_type_style_index_0_lang-8624318f.js";import{_ as W}from"./post-skeleton-63a82733.js";import{_ as E}from"./main-nav.vue_vue_type_style_index_0_lang-04907baf.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-6886c40b.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-e5b2b63d.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 @@
import{_ as T}from"./whisper-e51c17fc.js";import{d as F,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{F as G,_ as N,b as Q}from"./index-fae12ace.js";import{i as Y,p as J}from"./@vicons-7a4ef312.js";import{j as x,o as K,e as X,O as Z,L as ee,F as te,Q as ne,I as oe,G as se}from"./naive-ui-d8de3dda.js";import{_ as ae}from"./post-skeleton-2311fe04.js";import{_ as ce}from"./main-nav.vue_vue_type_style_index_0_lang-96e8e840.js";import{u as ie}from"./vuex-44de225f.js";import{b as _e}from"./vue-router-e5a2430e.js";import"./axios-4a70c6fc.js";import"./moment-2ab8298d.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 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=F({__name:"contact-item",props:{contact:{}},emits:["send-whisper"],setup(C,{emit:h}){const _=C,r=e=>()=>I(x,null,{default:()=>I(e)}),l=j(()=>[{label:"私信",key:"whisper",icon:r(J)}]),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=K,d=A("router-link"),w=X,k=Z,y=ee;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(Y))]),_:1})]),_:1})]),_:1},8,["options"])])]),_:1})])}}});const ge=N(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"},Ce=F({__name:"Contacts",setup(C){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,$()};U(()=>{$()});const $=(p=!1)=>{l.value.length===0&&(r.value=!0),Q({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 q=ce,B=ae,M=oe,P=ge,V=se,D=T,O=te,R=ne;return s(),c(z,null,[i("div",null,[t(q,{title:"好友"}),t(O,{class:"main-content-wrap",bordered:""},{default:n(()=>[r.value?(s(),c("div",he,[t(B,{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,b=>(s(),E(V,{class:"list-item",key:b.user_id},{default:n(()=>[t(P,{contact:b,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 Qe=N(Ce,[["__scopeId","data-v-e20fef94"]]);export{Qe as default};

@ -1 +0,0 @@
import{_ as T}from"./whisper-ccc06a56.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-6886c40b.js";import{_ as ae}from"./post-skeleton-63a82733.js";import{_ as ce}from"./main-nav.vue_vue_type_style_index_0_lang-04907baf.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};

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 +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} .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-b0cbbdc2]{color:#18a058;opacity:.8}.tiny-slide-bar .tiny-slide-bar__list>div:hover .slide-bar-item[data-v-b0cbbdc2]{cursor:pointer}.tiny-slide-bar .tiny-slide-bar__list>div:hover .slide-bar-item .slide-bar-item-avatar[data-v-b0cbbdc2]{color:#18a058;opacity:.8}.tiny-slide-bar .tiny-slide-bar__list>div:hover .slide-bar-item .slide-bar-item-title[data-v-b0cbbdc2]{color:#18a058;opacity:.8}.tiny-slide-bar[data-v-b0cbbdc2]{margin-top:-30px;margin-bottom:-30px}.tiny-slide-bar .slide-bar-item[data-v-b0cbbdc2]{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-b0cbbdc2]{justify-content:center;font-size:12px;margin-top:4px;height:40px}.load-more[data-v-b0cbbdc2]{margin:20px}.load-more .load-more-wrap[data-v-b0cbbdc2]{display:flex;flex-direction:row;justify-content:center;align-items:center;gap:14px}.load-more .load-more-wrap .load-more-spinner[data-v-b0cbbdc2]{font-size:14px;opacity:.65}.dark .main-content-wrap[data-v-b0cbbdc2],.dark .pagination-wrap[data-v-b0cbbdc2],.dark .empty-wrap[data-v-b0cbbdc2],.dark .skeleton-wrap[data-v-b0cbbdc2]{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-b0cbbdc2]{color:#63e2b7;opacity:.8}.dark .tiny-slide-bar .tiny-slide-bar__list>div:hover .slide-bar-item .slide-bar-item-title[data-v-b0cbbdc2]{color:#63e2b7;opacity:.8}

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

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 @@
import{A as $,B as M,C as O,D as x,_ as z}from"./index-fae12ace.js";import{x as D}from"./@vicons-7a4ef312.js";import{d as F,H as i,c as A,b as q,r as U,e as c,f as _,k as n,w as s,q as b,A as B,x as f,Y as u,bf as h,E as j,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-96e8e840.js";import{u as ne}from"./vuex-44de225f.js";import"./vue-router-e5a2430e.js";import"./axios-4a70c6fc.js";import"./moment-2ab8298d.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":O({topic_id:t.tag.id}).then(o=>{t.tag.is_following=1,window.$message.success("关注成功")}).catch(o=>{console.log(o)});break;case"unfollow":M({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=U("router-link"),g=J,k=C,a=K,d=P,v=Q,p=R;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(()=>[B(" #"+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(D))]),_: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);j(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,x({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=X,L=C,V=Z,N=ie,S=ee,E=oe,I=W;return c(),_("div",null,[n(v,{title:"话题"}),n(I,{class:"main-content-wrap tags-wrap",bordered:""},{default:s(()=>[n(V,{type:"line",animated:"","onUpdate:value":k},H({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(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(E,{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 Se=z(_e,[["__scopeId","data-v-1fb31ecf"]]);export{Se as default};

@ -1 +0,0 @@
import{z as $,A as I,B as M,C as O,_ as x}from"./index-6886c40b.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-04907baf.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};

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

@ -1 +0,0 @@
import{h as r}from"./moment-2ab8298d.js";r.locale("zh-cn");const a=e=>r.unix(e).fromNow(),f=e=>{let t=r.unix(e),o=r();return t.year()!=o.year()?t.utc(!0).format("YYYY-MM-DD HH:mm"):r().diff(t,"month")>3?t.utc(!0).format("MM-DD HH:mm"):t.fromNow()},u=e=>{let t=r.unix(e),o=r();return t.year()!=o.year()?t.utc(!0).format("YYYY-MM-DD"):r().diff(t,"month")>3?t.utc(!0).format("MM-DD"):t.fromNow()},n=e=>r.unix(e).utc(!0).format("YYYY年MM月");export{a,n as b,u as c,f};

File diff suppressed because one or more lines are too long

@ -1 +0,0 @@
.auth-wrap[data-v-053dfa44]{margin-top:-30px}.dark .auth-wrap[data-v-053dfa44]{background-color:#101014bf}.rightbar-wrap[data-v-ec9d8d25]::-webkit-scrollbar{width:0;height:0}.rightbar-wrap[data-v-ec9d8d25]{width:240px;position:fixed;left:calc(50% + var(--content-main) / 2 + 10px);max-height:100vh;overflow:auto}.rightbar-wrap .search-wrap[data-v-ec9d8d25]{margin:12px 0}.rightbar-wrap .hot-tag-item[data-v-ec9d8d25]{line-height:2;position:relative}.rightbar-wrap .hot-tag-item .hash-link[data-v-ec9d8d25]{width:calc(100% - 60px);text-overflow:ellipsis;white-space:nowrap;overflow:hidden;display:block}.rightbar-wrap .hot-tag-item .post-num[data-v-ec9d8d25]{position:absolute;right:0;top:0;width:60px;text-align:right;line-height:2;opacity:.5}.rightbar-wrap .hottopic-wrap[data-v-ec9d8d25]{margin-bottom:10px}.rightbar-wrap .copyright-wrap .copyright[data-v-ec9d8d25]{font-size:12px;opacity:.75}.rightbar-wrap .copyright-wrap .hash-link[data-v-ec9d8d25]{font-size:12px}.dark .hottopic-wrap[data-v-ec9d8d25],.dark .copyright-wrap[data-v-ec9d8d25]{background-color:#18181c}.sidebar-wrap::-webkit-scrollbar{width:0;height:0}.sidebar-wrap{z-index:99;width:200px;height:100vh;position:fixed;right:calc(50% + var(--content-main) / 2 + 10px);padding:12px 0;box-sizing:border-box;max-height:100vh;overflow:auto}.sidebar-wrap .n-menu .n-menu-item-content:before{border-radius:21px}.sidebar-wrap .logo-wrap{display:flex;justify-content:flex-start;margin-bottom:12px}.sidebar-wrap .logo-wrap .logo-img{margin-left:24px}.sidebar-wrap .logo-wrap .logo-img:hover{cursor:pointer}.sidebar-wrap .user-wrap{display:flex;align-items:center;position:absolute;bottom:12px;left:12px;right:12px}.sidebar-wrap .user-wrap .user-mini-wrap{display:none}.sidebar-wrap .user-wrap .user-avatar{margin-right:8px}.sidebar-wrap .user-wrap .user-info{display:flex;flex-direction:column}.sidebar-wrap .user-wrap .user-info .nickname{font-size:16px;font-weight:700;line-height:16px;height:16px;margin-bottom:2px;display:flex;align-items:center}.sidebar-wrap .user-wrap .user-info .nickname .nickname-txt{max-width:90px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.sidebar-wrap .user-wrap .user-info .nickname .logout{margin-left:6px}.sidebar-wrap .user-wrap .user-info .username{font-size:14px;line-height:16px;height:16px;width:120px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;opacity:.75}.sidebar-wrap .user-wrap .login-only-wrap{display:flex;justify-content:center;width:100%}.sidebar-wrap .user-wrap .login-only-wrap button{margin:0 4px;width:80%}.sidebar-wrap .user-wrap .login-wrap{display:flex;justify-content:center;width:100%}.sidebar-wrap .user-wrap .login-wrap button{margin:0 4px}.auth-card .n-card-header{z-index:999}@media screen and (max-width: 821px){.sidebar-wrap{width:200px;right:calc(100% - 200px)}.logo-wrap .logo-img{margin-left:12px!important}.user-wrap .user-avatar,.user-wrap .user-info,.user-wrap .login-only-wrap,.user-wrap .login-wrap{margin-bottom:32px}}:root{--content-main: 600px}.app-container{margin:0}.app-container .app-wrap{width:100%;margin:0 auto}.main-wrap{min-height:100vh;display:flex;flex-direction:row;justify-content:center}.main-wrap .content-wrap{width:100%;max-width:var(--content-main);position:relative}.main-wrap .main-content-wrap{margin:0;border-top:none;border-radius:0}.main-wrap .main-content-wrap .n-list-item{padding:0}.empty-wrap{min-height:300px;display:flex;align-items:center;justify-content:center}.following-link{color:#000;color:none;text-decoration:none;cursor:pointer;opacity:.75}.following-link:hover{opacity:.8}.slide-bar-user-link{text-decoration:none;cursor:pointer}.slide-bar-user-link:hover{color:#18a058;opacity:.8}.hash-link,.user-link{color:#18a058;text-decoration:none;cursor:pointer}.hash-link:hover,.user-link:hover{opacity:.8}.beian-link{color:#333;text-decoration:none}.beian-link:hover{opacity:.75}.username-link{color:#000;color:none;text-decoration:none;cursor:pointer}.username-link:hover{text-decoration:underline}.dark .hash-link,.dark .user-link{color:#63e2b7}.dark .following-link,.dark .username-link{color:#eee}.dark .beian-link{color:#ddd}@media screen and (max-width: 821px){.content-wrap{top:0;position:absolute!important}}

@ -0,0 +1 @@
.auth-wrap[data-v-053dfa44]{margin-top:-30px}.dark .auth-wrap[data-v-053dfa44]{background-color:#101014bf}.rightbar-wrap[data-v-0a6cd0b6]::-webkit-scrollbar{width:0;height:0}.rightbar-wrap[data-v-0a6cd0b6]{width:240px;position:fixed;left:calc(50% + var(--content-main) / 2 + 10px);max-height:100vh;overflow:auto}.rightbar-wrap .search-wrap[data-v-0a6cd0b6]{margin:12px 0}.rightbar-wrap .hot-tag-item[data-v-0a6cd0b6]{line-height:2;position:relative}.rightbar-wrap .hot-tag-item .hash-link[data-v-0a6cd0b6]{width:calc(100% - 60px);text-overflow:ellipsis;white-space:nowrap;overflow:hidden;display:block}.rightbar-wrap .hot-tag-item .post-num[data-v-0a6cd0b6]{position:absolute;right:0;top:0;width:60px;text-align:right;line-height:2;opacity:.5}.rightbar-wrap .hottopic-wrap[data-v-0a6cd0b6]{margin-bottom:10px}.rightbar-wrap .site-info[data-v-0a6cd0b6]{margin-top:8px;padding-left:16px;padding-right:16px}.rightbar-wrap .site-info .site-info-item[data-v-0a6cd0b6]{font-size:10px;opacity:.75}.rightbar-wrap .copyright-wrap .copyright[data-v-0a6cd0b6]{font-size:12px;opacity:.75}.rightbar-wrap .copyright-wrap .hash-link[data-v-0a6cd0b6]{font-size:12px}.dark .hottopic-wrap[data-v-0a6cd0b6],.dark .copyright-wrap[data-v-0a6cd0b6]{background-color:#18181c}.sidebar-wrap::-webkit-scrollbar{width:0;height:0}.sidebar-wrap{z-index:99;width:200px;height:100vh;position:fixed;right:calc(50% + var(--content-main) / 2 + 10px);padding:12px 0;box-sizing:border-box;max-height:100vh;overflow:auto}.sidebar-wrap .n-menu .n-menu-item-content:before{border-radius:21px}.sidebar-wrap .logo-wrap{display:flex;justify-content:flex-start;margin-bottom:12px}.sidebar-wrap .logo-wrap .logo-img{margin-left:24px}.sidebar-wrap .logo-wrap .logo-img:hover{cursor:pointer}.sidebar-wrap .user-wrap{display:flex;align-items:center;position:absolute;bottom:12px;left:12px;right:12px}.sidebar-wrap .user-wrap .user-mini-wrap{display:none}.sidebar-wrap .user-wrap .user-avatar{margin-right:8px}.sidebar-wrap .user-wrap .user-info{display:flex;flex-direction:column}.sidebar-wrap .user-wrap .user-info .nickname{font-size:16px;font-weight:700;line-height:16px;height:16px;margin-bottom:2px;display:flex;align-items:center}.sidebar-wrap .user-wrap .user-info .nickname .nickname-txt{max-width:90px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.sidebar-wrap .user-wrap .user-info .nickname .logout{margin-left:6px}.sidebar-wrap .user-wrap .user-info .username{font-size:14px;line-height:16px;height:16px;width:120px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;opacity:.75}.sidebar-wrap .user-wrap .login-only-wrap{display:flex;justify-content:center;width:100%}.sidebar-wrap .user-wrap .login-only-wrap button{margin:0 4px;width:80%}.sidebar-wrap .user-wrap .login-wrap{display:flex;justify-content:center;width:100%}.sidebar-wrap .user-wrap .login-wrap button{margin:0 4px}.auth-card .n-card-header{z-index:999}@media screen and (max-width: 821px){.sidebar-wrap{width:200px;right:calc(100% - 200px)}.logo-wrap .logo-img{margin-left:12px!important}.user-wrap .user-avatar,.user-wrap .user-info,.user-wrap .login-only-wrap,.user-wrap .login-wrap{margin-bottom:32px}}:root{--content-main: 600px}.app-container{margin:0}.app-container .app-wrap{width:100%;margin:0 auto}.main-wrap{min-height:100vh;display:flex;flex-direction:row;justify-content:center}.main-wrap .content-wrap{width:100%;max-width:var(--content-main);position:relative}.main-wrap .main-content-wrap{margin:0;border-top:none;border-radius:0}.main-wrap .main-content-wrap .n-list-item{padding:0}.empty-wrap{min-height:300px;display:flex;align-items:center;justify-content:center}.following-link{color:#000;color:none;text-decoration:none;cursor:pointer;opacity:.75}.following-link:hover{opacity:.8}.slide-bar-user-link{text-decoration:none;cursor:pointer}.slide-bar-user-link:hover{color:#18a058;opacity:.8}.hash-link,.user-link{color:#18a058;text-decoration:none;cursor:pointer}.hash-link:hover,.user-link:hover{opacity:.8}.beian-link{color:#333;text-decoration:none}.beian-link:hover{opacity:.75}.username-link{color:#000;color:none;text-decoration:none;cursor:pointer}.username-link:hover{text-decoration:underline}.dark .hash-link,.dark .user-link{color:#63e2b7}.dark .following-link,.dark .username-link{color:#eee}.dark .beian-link{color:#ddd}@media screen and (max-width: 821px){.content-wrap{top:0;position:absolute!important}}

File diff suppressed because one or more lines are too long

@ -1 +1 @@
import{a3 as A}from"./index-6886c40b.js";import{u as B}from"./vuex-44de225f.js";import{u as E}from"./vue-router-e5a2430e.js";import{j as z}from"./vooks-6d99783e.js";import{Z as C,_ as N,$ as P,a0 as D}from"./@vicons-7a4ef312.js";import{u as R,a3 as $,a4 as x,j as H,e as I,a5 as V,h as j}from"./naive-ui-d8de3dda.js";import{d as q,H as h,b as F,e as n,f,bf as a,k as e,w as t,Y as c,j as L,q as _,A as U,x as Y,F as Z}from"./@vue-a481fc63.js";const G={key:0},J={class:"navbar"},ae=q({__name:"main-nav",props:{title:{default:""},back:{type:Boolean,default:!1},theme:{type:Boolean,default:!0}},setup(w){const i=w,o=B(),m=E(),l=h(!1),g=h("left"),u=s=>{s?(localStorage.setItem("PAOPAO_THEME","dark"),o.commit("triggerTheme","dark")):(localStorage.setItem("PAOPAO_THEME","light"),o.commit("triggerTheme","light"))},k=()=>{window.history.length<=1?m.push({path:"/"}):m.go(-1)},v=()=>{l.value=!0};return F(()=>{localStorage.getItem("PAOPAO_THEME")||u(z()==="dark"),o.state.desktopModelShow||(window.$store=o,window.$message=R())}),(s,d)=>{const b=A,y=$,M=x,r=H,p=I,O=V,S=j;return n(),f(Z,null,[a(o).state.drawerModelShow?(n(),f("div",G,[e(M,{show:l.value,"onUpdate:show":d[0]||(d[0]=T=>l.value=T),width:212,placement:g.value,resizable:""},{default:t(()=>[e(y,null,{default:t(()=>[e(b)]),_:1})]),_:1},8,["show","placement"])])):c("",!0),e(S,{size:"small",bordered:!0,class:"nav-title-card"},{header:t(()=>[L("div",J,[a(o).state.drawerModelShow&&!s.back?(n(),_(p,{key:0,class:"drawer-btn",onClick:v,quaternary:"",circle:"",size:"medium"},{icon:t(()=>[e(r,null,{default:t(()=>[e(a(C))]),_:1})]),_:1})):c("",!0),s.back?(n(),_(p,{key:1,class:"back-btn",onClick:k,quaternary:"",circle:"",size:"small"},{icon:t(()=>[e(r,null,{default:t(()=>[e(a(N))]),_:1})]),_:1})):c("",!0),U(" "+Y(i.title)+" ",1),i.theme?(n(),_(O,{key:2,value:a(o).state.theme==="dark","onUpdate:value":u,size:"small",class:"theme-switch-wrap"},{"checked-icon":t(()=>[e(r,{component:a(P)},null,8,["component"])]),"unchecked-icon":t(()=>[e(r,{component:a(D)},null,8,["component"])]),_:1},8,["value"])):c("",!0)])]),_:1})],64)}}});export{ae as _}; import{a7 as A}from"./index-fae12ace.js";import{u as B}from"./vuex-44de225f.js";import{u as E}from"./vue-router-e5a2430e.js";import{j as z}from"./vooks-6d99783e.js";import{Z as C,_ as N,$ as P,a0 as D}from"./@vicons-7a4ef312.js";import{u as R,a3 as $,a4 as x,j as H,e as I,a5 as V,h as j}from"./naive-ui-d8de3dda.js";import{d as q,H as h,b as F,e as n,f,bf as a,k as e,w as t,Y as c,j as L,q as _,A as U,x as Y,F as Z}from"./@vue-a481fc63.js";const G={key:0},J={class:"navbar"},ae=q({__name:"main-nav",props:{title:{default:""},back:{type:Boolean,default:!1},theme:{type:Boolean,default:!0}},setup(w){const i=w,o=B(),m=E(),l=h(!1),g=h("left"),u=s=>{s?(localStorage.setItem("PAOPAO_THEME","dark"),o.commit("triggerTheme","dark")):(localStorage.setItem("PAOPAO_THEME","light"),o.commit("triggerTheme","light"))},k=()=>{window.history.length<=1?m.push({path:"/"}):m.go(-1)},v=()=>{l.value=!0};return F(()=>{localStorage.getItem("PAOPAO_THEME")||u(z()==="dark"),o.state.desktopModelShow||(window.$store=o,window.$message=R())}),(s,d)=>{const b=A,y=$,M=x,r=H,p=I,O=V,S=j;return n(),f(Z,null,[a(o).state.drawerModelShow?(n(),f("div",G,[e(M,{show:l.value,"onUpdate:show":d[0]||(d[0]=T=>l.value=T),width:212,placement:g.value,resizable:""},{default:t(()=>[e(y,null,{default:t(()=>[e(b)]),_:1})]),_:1},8,["show","placement"])])):c("",!0),e(S,{size:"small",bordered:!0,class:"nav-title-card"},{header:t(()=>[L("div",J,[a(o).state.drawerModelShow&&!s.back?(n(),_(p,{key:0,class:"drawer-btn",onClick:v,quaternary:"",circle:"",size:"medium"},{icon:t(()=>[e(r,null,{default:t(()=>[e(a(C))]),_:1})]),_:1})):c("",!0),s.back?(n(),_(p,{key:1,class:"back-btn",onClick:k,quaternary:"",circle:"",size:"small"},{icon:t(()=>[e(r,null,{default:t(()=>[e(a(N))]),_:1})]),_:1})):c("",!0),U(" "+Y(i.title)+" ",1),i.theme?(n(),_(O,{key:2,value:a(o).state.theme==="dark","onUpdate:value":u,size:"small",class:"theme-switch-wrap"},{"checked-icon":t(()=>[e(r,{component:a(P)},null,8,["component"])]),"unchecked-icon":t(()=>[e(r,{component:a(D)},null,8,["component"])]),_:1},8,["value"])):c("",!0)])]),_:1})],64)}}});export{ae as _};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +1 @@
import{U as r}from"./naive-ui-d8de3dda.js";import{d as c,e as s,f as n,u as p,j as o,k as t,F as l}from"./@vue-a481fc63.js";import{_ as i}from"./index-6886c40b.js";const m={class:"user"},u={class:"content"},d=c({__name:"post-skeleton",props:{num:{default:1}},setup(f){return(_,k)=>{const e=r;return s(!0),n(l,null,p(new Array(_.num),a=>(s(),n("div",{class:"skeleton-item",key:a},[o("div",m,[t(e,{circle:"",size:"small"})]),o("div",u,[t(e,{text:"",repeat:3}),t(e,{text:"",style:{width:"60%"}})])]))),128)}}});const b=i(d,[["__scopeId","data-v-ab0015b4"]]);export{b as _}; import{U as r}from"./naive-ui-d8de3dda.js";import{d as c,e as s,f as n,u as p,j as o,k as t,F as l}from"./@vue-a481fc63.js";import{_ as i}from"./index-fae12ace.js";const m={class:"user"},u={class:"content"},d=c({__name:"post-skeleton",props:{num:{default:1}},setup(f){return(_,k)=>{const e=r;return s(!0),n(l,null,p(new Array(_.num),a=>(s(),n("div",{class:"skeleton-item",key:a},[o("div",m,[t(e,{circle:"",size:"small"})]),o("div",u,[t(e,{text:"",repeat:3}),t(e,{text:"",style:{width:"60%"}})])]))),128)}}});const b=i(d,[["__scopeId","data-v-ab0015b4"]]);export{b as _};

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

Loading…
Cancel
Save