Merge branch 'r/paopao-ce-plus' into r/paopao-ce-xtra

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

@ -147,6 +147,7 @@ All notable changes to paopao-ce are documented in this file.
WHERE is_del=0
GROUP BY user_id;
```
- add message filter support for message page.
## 0.4.2
### Fixed

@ -220,13 +220,17 @@ func RegisterCoreServant(e *gin.Engine, s Core) {
default:
}
req := new(web.GetMessagesReq)
var bv _binding_ = req
if err := bv.Bind(c); err != nil {
if err := s.Bind(c, req); err != nil {
s.Render(c, nil, err)
return
}
resp, err := s.GetMessages(req)
s.Render(c, resp, err)
if err != nil {
s.Render(c, nil, err)
return
}
var rv _render_ = resp
rv.Render(c)
})
router.Handle("GET", "/user/info", func(c *gin.Context) {
select {

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

@ -29,6 +29,8 @@ const (
PrefixIdxTweetsNewest = "paopao:index:tweets:newest:"
PrefixIdxTweetsHots = "paopao:index:tweets:hots:"
PrefixIdxTweetsFollowing = "paopao:index:tweets:following:"
PrefixIdxTrends = "paopao:index:trends:"
PrefixMessages = "paopao:messages:"
PrefixUserInfo = "paopao:userinfo:"
PrefixUserInfoById = "paopao:userinfo:id:"
PrefixUserInfoByName = "paopao:userinfo:name:"

@ -12,9 +12,11 @@ Cache:
UserTweetsExpire: 60 # 获取用户推文列表过期时间,单位秒, 默认60s
IndexTweetsExpire: 120 # 获取广场推文列表过期时间,单位秒, 默认120s
TweetCommentsExpire: 180 # 获取推文评论过期时间,单位秒, 默认180s
IndexTrendsExpire: 300 # 获取广场动态信息过期时间,单位秒, 默认300s
OnlineUserExpire: 300 # 标记在线用户 过期时间,单位秒, 默认300s
UserInfoExpire: 300 # 获取用户信息过期时间,单位秒, 默认300s
UserRelationExpire: 600 # 用户关系信息过期时间,单位秒, 默认600s
MessagesExpire: 60 # 消息列表过期时间,单位秒, 默认60s
EventManager: # 事件管理器的配置参数
MinWorker: 64 # 最小后台工作者, 设置范围[5, ++], 默认64
MaxEventBuf: 128 # 最大log缓存条数, 设置范围[10, ++], 默认128

@ -102,6 +102,8 @@ type cacheConf struct {
UnreadMsgExpire int64
UserTweetsExpire int64
IndexTweetsExpire int64
MessagesExpire int64
IndexTrendsExpire int64
TweetCommentsExpire int64
OnlineUserExpire int64
UserInfoExpire int64

@ -21,9 +21,13 @@ type DataService interface {
TweetHelpService
// 推文指标服务
UserMetricServantA
TweetMetricServantA
CommentMetricServantA
// 动态信息相关服务
TrendsManageServantA
// 评论服务
CommentService
CommentManageService

@ -0,0 +1,16 @@
// Copyright 2023 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package cs
const (
// 消息列表样式
StyleMsgAll MessageStyle = "all"
StyleMsgSystem MessageStyle = "system"
StyleMsgWhisper MessageStyle = "whisper"
StyleMsgRequesting MessageStyle = "requesting"
StyleMsgUnread MessageStyle = "unread"
)
type MessageStyle string

@ -2,11 +2,13 @@
// 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
const (
MetricActionCreateTweet uint8 = iota
MetricActionDeleteTweet
)
type TweetMetric struct {
PostId int64
CommentCount int64

@ -0,0 +1,12 @@
// Copyright 2023 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package cs
type TrendsItem struct {
Username string `json:"username"`
Nickname string `json:"nickname"`
Avatar string `json:"avatar"`
IsFresh bool `json:"is_fresh" gorm:"-" db:"-"`
}

@ -5,6 +5,7 @@
package core
import (
"github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/core/ms"
)
@ -14,6 +15,5 @@ type MessageService interface {
GetUnreadCount(userID int64) (int64, error)
GetMessageByID(id int64) (*ms.Message, error)
ReadMessage(message *ms.Message) error
GetMessages(userId int64, offset, limit int) ([]*ms.MessageFormated, error)
GetMessageCount(userId int64) (int64, error)
GetMessages(userId int64, style cs.MessageStyle, limit, offset int) ([]*ms.MessageFormated, int64, error)
}

@ -0,0 +1,14 @@
// 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"
)
// TrendsManageServantA 动态信息管理服务
type TrendsManageServantA interface {
GetIndexTrends(userId int64, limit int, offset int) ([]*cs.TrendsItem, int64, error)
}

@ -4,7 +4,9 @@
package core
import "github.com/rocboss/paopao-ce/internal/core/ms"
import (
"github.com/rocboss/paopao-ce/internal/core/ms"
)
// UserManageService 用户管理服务
type UserManageService interface {

@ -39,7 +39,9 @@ type dataSrv struct {
core.CommentService
core.CommentManageService
core.CommentMetricServantA
core.TrendsManageServantA
core.UserManageService
core.UserMetricServantA
core.ContactManageService
core.FollowingManageService
core.UserRelationService
@ -59,11 +61,13 @@ func NewDataService() (core.DataService, core.VersionInfo) {
db := conf.MustGormDB()
pvs := security.NewPhoneVerifyService()
tms := newTweetMetricServentA(db)
ums := newUserMetricServentA(db)
cms := newCommentMetricServentA(db)
cis := cache.NewEventCacheIndexSrv(tms)
ds := &dataSrv{
TweetMetricServantA: tms,
CommentMetricServantA: cms,
UserMetricServantA: ums,
WalletService: newWalletService(db),
MessageService: newMessageService(db),
TopicService: newTopicService(db),
@ -72,7 +76,8 @@ func NewDataService() (core.DataService, core.VersionInfo) {
TweetHelpService: newTweetHelpService(db),
CommentService: newCommentService(db),
CommentManageService: newCommentManageService(db),
UserManageService: newUserManageService(db),
TrendsManageServantA: newTrendsManageServentA(db),
UserManageService: newUserManageService(db, ums),
ContactManageService: newContactManageService(db),
FollowingManageService: newFollowingManageService(db),
UserRelationService: newUserRelationService(db),

@ -6,6 +6,7 @@ package jinzhu
import (
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"gorm.io/gorm"
@ -46,19 +47,35 @@ func (s *messageSrv) ReadMessage(message *ms.Message) error {
return message.Update(s.db)
}
func (s *messageSrv) GetMessages(userId int64, offset, limit int) ([]*ms.MessageFormated, error) {
messages, err := (&dbr.Message{}).List(s.db, userId, offset, limit)
if err != nil {
return nil, err
func (s *messageSrv) GetMessages(userId int64, style cs.MessageStyle, limit int, offset int) (res []*ms.MessageFormated, total int64, err error) {
var messages []*dbr.Message
db := s.db.Table(_message_)
// 1动态2评论3回复4私信5好友申请99系统通知'
switch style {
case cs.StyleMsgSystem:
db = db.Where("receiver_user_id=? AND type IN (1, 2, 3, 99)", userId)
case cs.StyleMsgWhisper:
db = db.Where("(receiver_user_id=? OR sender_user_id=?) AND type=4", userId, userId)
case cs.StyleMsgRequesting:
db = db.Where("receiver_user_id=? AND type=5", userId)
case cs.StyleMsgUnread:
db = db.Where("receiver_user_id=? AND is_read=0", userId)
case cs.StyleMsgAll:
fallthrough
default:
db = db.Where("receiver_user_id=? OR (sender_user_id=? AND type=4)", userId, userId)
}
if err = db.Count(&total).Error; err != nil || total == 0 {
return
}
if offset >= 0 && limit > 0 {
db = db.Limit(limit).Offset(offset)
}
if err = db.Order("id DESC").Find(&messages).Error; err != nil {
return
}
mfs := []*dbr.MessageFormated{}
for _, message := range messages {
mf := message.Format()
mfs = append(mfs, mf)
res = append(res, message.Format())
}
return mfs, nil
}
func (s *messageSrv) GetMessageCount(userId int64) (int64, error) {
return (&dbr.Message{}).Count(s.db, userId)
return
}

@ -63,9 +63,23 @@ func (s *commentMetricSrvA) DeleteCommentMetric(commentId int64) (err error) {
return (&dbr.CommentMetric{CommentId: commentId}).Delete(s.db)
}
func (s *userMetricSrvA) UpdateUserMetric(userId int64, action uint8) error {
// TODO
return cs.ErrNotImplemented
func (s *userMetricSrvA) UpdateUserMetric(userId int64, action uint8) (err error) {
metric := &dbr.UserMetric{}
db := s.db.Model(metric)
if err = db.Where("user_id=?", userId).First(metric).Error; err != nil {
metric = &dbr.UserMetric{
UserId: userId,
}
}
switch action {
case cs.MetricActionCreateTweet:
metric.TweetsCount++
case cs.MetricActionDeleteTweet:
if metric.TweetsCount > 0 {
metric.TweetsCount--
}
}
return db.Save(metric).Error
}
func (s *userMetricSrvA) AddUserMetric(userId int64) (err error) {

@ -0,0 +1,38 @@
// Copyright 2023 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package jinzhu
import (
"fmt"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/cs"
"gorm.io/gorm"
)
type trendsSrvA struct {
db *gorm.DB
}
func (s *trendsSrvA) GetIndexTrends(userId int64, limit int, offset int) (res []*cs.TrendsItem, total int64, err error) {
db := s.db.Table(_user_).
Joins(fmt.Sprintf("JOIN %s c ON c.friend_id=%s.id AND c.user_id=? AND c.is_del=0", _contact_, _user_), userId).
Joins(fmt.Sprintf("JOIN %s m ON c.friend_id=m.user_id AND m.tweets_count>0 AND m.is_del=0", _userMetric_)).
Where(fmt.Sprintf("%s.is_del=0", _user_))
if err = db.Count(&total).Error; err != nil || total == 0 {
return
}
if offset >= 0 && limit > 0 {
db = db.Limit(limit).Offset(offset)
}
err = db.Find(&res).Error
return
}
func newTrendsManageServentA(db *gorm.DB) core.TrendsManageServantA {
return &trendsSrvA{
db: db,
}
}

@ -508,7 +508,7 @@ func (s *tweetSrv) getUserRelation(userId int64) (beFriendIds []int64, beFollowI
// 找到item即删数据库已经保证唯一性
if beFollowIds[i] == id {
lastIdx := len(beFollowIds) - 1
beFriendIds[i] = beFriendIds[lastIdx]
beFollowIds[i] = beFollowIds[lastIdx]
beFollowIds = beFollowIds[:lastIdx]
break
}

@ -18,16 +18,18 @@ var (
)
type userManageSrv struct {
db *gorm.DB
db *gorm.DB
ums core.UserMetricServantA
}
type userRelationSrv struct {
db *gorm.DB
}
func newUserManageService(db *gorm.DB) core.UserManageService {
func newUserManageService(db *gorm.DB, ums core.UserMetricServantA) core.UserManageService {
return &userManageSrv{
db: db,
ums: ums,
}
}
@ -81,8 +83,12 @@ func (s *userManageSrv) GetUsersByKeyword(keyword string) ([]*ms.User, error) {
}
}
func (s *userManageSrv) CreateUser(user *dbr.User) (*ms.User, error) {
return user.Create(s.db)
func (s *userManageSrv) CreateUser(user *dbr.User) (res *ms.User, err error) {
if res, err = user.Create(s.db); err == nil {
// 宽松处理错误
s.ums.AddUserMetric(res.ID)
}
return
}
func (s *userManageSrv) UpdateUser(user *ms.User) error {

@ -26,23 +26,30 @@ const (
_Comment_GetCommentReplyById = `SELECT * FROM @comment_reply WHERE id=? AND is_del=0`
_Comment_GetCommentThumbs = `SELECT user_id, tweet_id, comment_id, reply_id, comment_type, is_thumbs_up, is_thumbs_down FROM @tweet_comment_thumbs WHERE user_id=? AND tweet_id=?`
_Comment_GetCommmentRepliesByIds = `SELECT * FROM @comment_reply WHERE comment_id IN (?) ORDER BY id ASC`
_Comment_GetDefaultComments = `SELECT * FROM @comment WHERE post_id=? AND is_del=0 ORDER BY id ASC LIMIT ? OFFSET ?`
_Comment_GetHotsComments = `SELECT * FROM @comment WHERE post_id=? AND is_del=0 ORDER BY thumbs_up_count DESC, id DESC LIMIT ? OFFSET ?`
_Comment_GetNewestComments = `SELECT * FROM @comment WHERE post_id=? AND is_del=0 ORDER BY id DESC LIMIT ? OFFSET ?`
_Comment_GetDefaultComments = `SELECT * FROM @comment WHERE post_id=? AND is_del=0 ORDER BY is_essence DESC, id ASC LIMIT ? OFFSET ?`
_Comment_GetHotsComments = `SELECT c.* FROM @comment c LEFT JOIN @comment_metric m ON c.id=m.comment_id WHERE c.post_id=? AND c.is_del=0 AND m.is_del=0 ORDER BY is_essence DESC, m.rank_score DESC, id DESC LIMIT ? OFFSET ?`
_Comment_GetNewestComments = `SELECT * FROM @comment WHERE post_id=? AND is_del=0 ORDER BY is_essence DESC, id DESC LIMIT ? OFFSET ?`
_Comment_GetUsersByIds = `SELECT id, nickname, username, status, avatar, is_admin FROM @user WHERE id IN (?)`
_CommentManage_CreateComment = `INSERT INTO @comment (post_id, user_id, ip, ip_loc, created_on) VALUES (?, ?, ?, ?, ?)`
_CommentManage_CreateCommentContent = `INSERT INTO @comment_content (comment_id, user_id, content, type, sort, created_on) VALUES (?, ?, ?, ?, ?, ?)`
_CommentManage_CreateCommentReply = `INSERT INTO @comment_reply (comment_id, user_id, content, at_user_id, ip, ip_loc, created_on) VALUES (?, ?, ?, ?, ?, ?, ?)`
_CommentManage_CreateThumbsUpdownComment = `INSERT INTO @tweet_comment_thumbs (user_id, tweet_id, comment_id, reply_id, is_thumbs_up, is_thumbs_down, comment_type, created_on) VALUES (:user_id, :tweet_id, :comment_id, :reply_id, :is_thumbs_up, :is_thumbs_down, :comment_type, :created_on)`
_CommentManage_DecrCommentReplyCount = `UPDATE @comment SET reply_count=reply_count-1, modified_on=? WHERE id=? AND is_del=0`
_CommentManage_DeleteComment = `UPDATE @comment SET deleted_on=?, is_del=1 WHERE id=? AND is_del=0`
_CommentManage_DeleteCommentReply = `UPDATE @comment_reply SET deleted_on=?, is_del=1 WHERE id=? AND is_del=0`
_CommentManage_DeleteCommentThumbs = `UPDATE @tweet_comment_thumbs SET deleted_on=?, is_del=1 WHERE user_id=? AND tweet_id=? AND comment_id=? AND is_del=0`
_CommentManage_DeleteReplyThumbs = `UPDATE @tweet_comment_thumbs SET deleted_on=?, is_del=1 WHERE user_id=? AND comment_id=? AND reply_id=? AND is_del=0`
_CommentManage_GetCommentReplyThumb = `SELECT * FROM @tweet_comment_thumbs WHERE user_id=? AND tweet_id=? AND comment_id=? AND reply_id=? AND comment_type=1 AND is_del=0`
_CommentManage_GetTweetCommentThumb = `SELECT * FROM @tweet_comment_thumbs WHERE user_id=? AND tweet_id=? AND comment_id=? AND comment_type=0 AND is_del=0`
_CommentManage_IncrCommentReplyCount = `UPDATE @comment SET reply_count=reply_count+1, modified_on=? WHERE id=? AND is_del=0`
_CommentManage_UpdateCommentThumbsCount = `UPDATE @comment SET thumbs_up_count=?, thumbs_down_count=?, modified_on=? WHERE id=? AND is_del=0`
_CommentManage_UpdateReplyThumbsCount = `UPDATE @comment_reply SET thumbs_up_count=?, thumbs_down_count=?, modified_on=? WHERE id=? AND is_del=0`
_CommentManage_UpdateThumbsUpdownComment = `UPDATE @tweet_comment_thumbs SET is_thumbs_up=:is_thumbs_up, is_thumbs_down=:is_thumbs_down, modified_on=:modified_on WHERE id=:id AND is_del=0`
_CommentMetrics_AddCommentMetric = `INSERT INTO @comment_metric (comment_id, created_on) VALUES (?, ?)`
_CommentMetrics_DeleteCommentMetric = `UPDATE @comment_metric SET is_del=1, deleted_on=? WHERE comment_id=? AND is_del=0`
_CommentMetrics_GetMotivationFactor = `SELECT motivation_factor FROM @comment_metric WHERE comment_id=? AND is_del=0`
_CommentMetrics_UpdateRankScore = `UPDATE @comment_metric SET rank_score=?, modified_on=? WHERE comment_id=? AND is_del=0`
_CommentMetrics_UpsertCommentMetric = `INSERT INTO @comment_metric (comment_id, rank_score, created_on) VALUES (?, ?, ?)`
_ContactManager_AddFriendMsgsUpdate = `UPDATE @message SET reply_id=?, modified_on=? WHERE ((sender_user_id = ? AND receiver_user_id = ?) OR (sender_user_id = ? AND receiver_user_id = ?)) AND type = ? AND reply_id = ?`
_ContactManager_CreateContact = `INSERT INTO @contact (user_id, friend_id, status, created_on) VALUES (?, ?, ?, ?)`
_ContactManager_CreateMessage = `INSERT INTO @message (sender_user_id, receiver_user_id, type, brief, content, reply_id, created_on) VALUES (:sender_user_id, :receiver_user_id, :type, :brief, :content, :reply_id, :created_on)`
@ -62,11 +69,19 @@ const (
_FollowingManager_ExistFollowing = `SELECT 1 FROM @following WHERE user_id=? AND follow_id=? AND is_del=0`
_FollowingManager_ListFollowings = `SELECT u.id user_id, u.username username, u.nickname nickname, u.avatar avatar, u.created_on created_on FROM @following f JOIN @user u ON f.user_id=u.id WHERE f.follow_id=? AND f.is_del=0 ORDER BY u.nickname ASC LIMIT ? OFFSET ?`
_FollowingManager_ListFollows = `SELECT u.id user_id, u.username username, u.nickname nickname, u.avatar avatar, u.created_on created_on FROM @following f JOIN @user u ON f.follow_id=u.id WHERE f.user_id=? AND f.is_del=0 ORDER BY u.nickname ASC LIMIT ? OFFSET ?`
_Message_CountAllMessages = `SELECT count(*) FROM @message WHERE (receiver_user_id=? OR (sender_user_id=? AND type=4)) AND is_del=0`
_Message_CountRequestingMessages = `SELECT count(*) FROM @message WHERE receiver_user_id=? AND type=5 AND is_del=0`
_Message_CountSystemMessages = `SELECT count(*) FROM @message WHERE receiver_user_id=? AND type IN (1, 2, 3, 99) AND is_del=0`
_Message_CountUnreadMessages = `SELECT count(*) FROM @message WHERE receiver_user_id=? AND is_read=0 AND is_del=0`
_Message_CountWhisperMessages = `SELECT count(*) FROM @message WHERE ((receiver_user_id=? OR sender_user_id=?) AND type=4) AND is_del=0`
_Message_CreateMessage = `INSERT INTO @message (sender_user_id, receiver_user_id, type, brief, content, post_id, comment_id, reply_id, created_on) VALUES (:sender_user_id, :receiver_user_id, :type, :brief, :content, :post_id, :comment_id, :reply_id, :created_on)`
_Message_GetAllMessages = `SELECT * FROM @message WHERE (receiver_user_id=? OR (sender_user_id=? AND type=4)) AND is_del=0 ORDER BY id DESC LIMIT ? OFFSET ?`
_Message_GetMessageById = `SELECT * FROM @message WHERE id=? AND is_del=0`
_Message_GetMessageCount = `SELECT count(*) FROM @message WHERE (receiver_user_id=? OR (sender_user_id=? AND type=4)) AND is_del=0`
_Message_GetMessages = `SELECT * FROM @message WHERE (receiver_user_id=? OR (sender_user_id=? AND type=4)) AND is_del=0 ORDER BY id DESC LIMIT ? OFFSET ?`
_Message_GetRequestingMessages = `SELECT * FROM @message WHERE receiver_user_id=? AND type=5 AND is_del=0 ORDER BY id DESC LIMIT ? OFFSET ?`
_Message_GetSystemMessages = `SELECT * FROM @message WHERE receiver_user_id=? AND type IN (1, 2, 3, 99) AND is_del=0 ORDER BY id DESC LIMIT ? OFFSET ?`
_Message_GetUnreadCount = `SELECT count(*) FROM @message WHERE receiver_user_id=? AND is_read=0 AND is_del=0`
_Message_GetUnreadMessages = `SELECT * FROM @message WHERE receiver_user_id=? AND is_read=0 AND is_del=0 ORDER BY id DESC LIMIT ? OFFSET ?`
_Message_GetWhisperMessages = `SELECT * FROM @message WHERE ((receiver_user_id=? OR sender_user_id=?) AND type=4) AND is_del=0 ORDER BY id DESC LIMIT ? OFFSET ?`
_Message_ReadMessage = `UPDATE @message SET is_read=1, modified_on=? WHERE id=?`
_Security_CreatePhoneCaptcha = `INSERT INTO @captcha (phone, captcha, expired_on, created_on) VALUES (:phone, :captcha, :expired_on, :created_on)`
_Security_GetLatestPhoneCaptcha = `SELECT * FROM @captcha WHERE phone=? AND is_del=0`
@ -79,6 +94,8 @@ const (
_ShipIndex_IndexCountBySelf = `SELECT count(*) FROM @post WHERE is_del=0 AND (visibility=90 OR (visibility=0 AND user_id=?) OR (visibility=50 AND user_id IN (?)))`
_SimpleIndex_Index = `SELECT * FROM @post WHERE visibility=90 ORDER BY is_top DESC, latest_replied_on DESC LIMIT ? OFFSET ?`
_SimpleIndex_IndexCount = `SELECT count(*) FROM @post WHERE visibility=90`
_TrendsManager_CountIndexTrends = `SELECT count(*) FROM @contact c JOIN @user u ON c.friend_id=u.id JOIN @user_metric m ON c.friend_id=m.user_id WHERE c.user_id=? AND c.is_del=0 AND u.is_del=0 AND m.is_del=0 AND m.tweets_count>0`
_TrendsManager_GetIndexTrends = `SELECT u.username username, u.nickname nickname, u.avatar avatar FROM @contact c JOIN @user u ON c.friend_id=u.id JOIN @user_metric m ON c.friend_id=m.user_id WHERE c.user_id=? AND c.is_del=0 AND u.is_del=0 AND m.is_del=0 AND m.tweets_count>0 LIMIT ? OFFSET ?`
_Tweet_CountFollowingTweets = `SELECT count(*) FROM @post WHERE user_id=? AND is_del=0`
_Tweet_CountFollowingTweetsFollow = `SELECT count(*) FROM @post WHERE (user_id=? OR (visibility>=60 AND user_id IN(?))) AND is_del=0`
_Tweet_CountFollowingTweetsFriend = `SELECT count(*) FROM @post WHERE (user_id=? OR (visibility>=50 AND user_id IN(?))) AND is_del=0`
@ -137,6 +154,7 @@ const (
_TweetMetrics_DeleteTweetMetric = `UPDATE @post_metric SET is_del=1, deleted_on=? WHERE post_id=? AND is_del=0`
_TweetMetrics_GetMotivationFactor = `SELECT motivation_factor FROM @post_metric WHERE post_id=? AND is_del=0`
_TweetMetrics_UpdateRankScore = `UPDATE @post_metric SET rank_score=?, modified_on=? WHERE post_id=? AND is_del=0`
_TweetMetrics_UpsertTweetMetric = `INSERT INTO @post_metric (post_id, rank_score, created_on) VALUES (?, ?, ?)`
_Tweet_UserCommentTweetsByFriend = `SELECT id, user_id, comment_count, collection_count, upvote_count, share_count, visibility, is_top, is_essence, is_lock, latest_replied_on, tags, attachment_price, ip, ip_loc, created_on, modified_on, deleted_on, is_del FROM @post_by_comment WHERE is_del=0 AND comment_user_id=? AND visibility>=50 ORDER BY latest_replied_on DESC LIMIT ? OFFSET ?`
_Tweet_UserCommentTweetsByGuest = `SELECT id, user_id, comment_count, collection_count, upvote_count, share_count, visibility, is_top, is_essence, is_lock, latest_replied_on, tags, attachment_price, ip, ip_loc, created_on, modified_on, deleted_on, is_del FROM @post_by_comment WHERE is_del=0 AND comment_user_id=? AND visibility>=90 ORDER BY latest_replied_on DESC LIMIT ? OFFSET ?`
_Tweet_UserCommentTweetsBySelf = `SELECT id, user_id, comment_count, collection_count, upvote_count, share_count, visibility, is_top, is_essence, is_lock, latest_replied_on, tags, attachment_price, ip, ip_loc, created_on, modified_on, deleted_on, is_del FROM @post_by_comment WHERE is_del=0 AND comment_user_id=? ORDER BY latest_replied_on DESC LIMIT ? OFFSET ?`
@ -166,6 +184,12 @@ const (
_UserManage_GetUsersByIds = `SELECT * FROM @user WHERE id IN (?) AND is_del=0`
_UserManage_GetUsersByKeyword = `SELECT * FROM @user WHERE username LIKE ? AND is_del=0 limit 6`
_UserManage_UpdateUser = `UPDATE @user SET username=:username, nickname=:nickname, phone=:phone, password=:password, salt=:salt, status=:status, avatar=:avatar, balance=:balance, is_admin=:is_admin, modified_on=:modified_on WHERE id=? AND is_del=0`
_UserMetrics_AddUserMetric = `INSERT INTO @user_metric (user_id, created_on) VALUES (?, ?)`
_UserMetrics_DeleteUserMetric = `UPDATE @user_metric SET is_del=1, deleted_on=? WHERE user_id=? AND is_del=0`
_UserMetrics_GetTweetsCount = `SELECT tweets_count FROM @user_metric WHERE user_id=? AND is_del=0`
_UserMetrics_UpdateUserMetric = `UPDATE @user_metric SET tweets_count=?, modified_on=? WHERE user_id=? AND is_del=0`
_UserRelation_MyFollowIds = `SELECT follow_id FROM @following WHERE user_id=? AND is_del=0`
_UserRelation_MyFriendIds = `SELECT friend_id FROM @contact WHERE user_id=? AND is_del=0`
_Wallet_AddUserBalance = `UPDATE @user SET balance=balance+?, modified_on=? WHERE id=? AND is_del=0`
_Wallet_CreateRecharge = `INSERT INTO @wallet_recharge (user_id, amount, created_on) VALUES (?, ?, ?)`
_Wallet_CreateWalletStatement = `INSERT INTO @wallet_statement (user_id, change_amount, balance_snapshot, reason, created_on) VALUES (?, ?, ?, ?, ?)`
@ -226,18 +250,29 @@ type CommentManage struct {
CreateComment *sqlx.Stmt `yesql:"create_comment"`
CreateCommentContent *sqlx.Stmt `yesql:"create_comment_content"`
CreateCommentReply *sqlx.Stmt `yesql:"create_comment_reply"`
DecrCommentReplyCount *sqlx.Stmt `yesql:"decr_comment_reply_count"`
DeleteComment *sqlx.Stmt `yesql:"delete_comment"`
DeleteCommentReply *sqlx.Stmt `yesql:"delete_comment_reply"`
DeleteCommentThumbs *sqlx.Stmt `yesql:"delete_comment_thumbs"`
DeleteReplyThumbs *sqlx.Stmt `yesql:"delete_reply_thumbs"`
GetCommentReplyThumb *sqlx.Stmt `yesql:"get_comment_reply_thumb"`
GetTweetCommentThumb *sqlx.Stmt `yesql:"get_tweet_comment_thumb"`
IncrCommentReplyCount *sqlx.Stmt `yesql:"incr_comment_reply_count"`
UpdateCommentThumbsCount *sqlx.Stmt `yesql:"update_comment_thumbs_count"`
UpdateReplyThumbsCount *sqlx.Stmt `yesql:"update_reply_thumbs_count"`
CreateThumbsUpdownComment *sqlx.NamedStmt `yesql:"create_thumbs_updown_comment"`
UpdateThumbsUpdownComment *sqlx.NamedStmt `yesql:"update_thumbs_updown_comment"`
}
type CommentMetrics struct {
yesql.Namespace `yesql:"comment_metrics"`
AddCommentMetric *sqlx.Stmt `yesql:"add_comment_metric"`
DeleteCommentMetric *sqlx.Stmt `yesql:"delete_comment_metric"`
GetMotivationFactor *sqlx.Stmt `yesql:"get_motivation_factor"`
UpdateRankScore *sqlx.Stmt `yesql:"update_rank_score"`
UpsertCommentMetric *sqlx.Stmt `yesql:"upsert_comment_metric"`
}
type ContactManager struct {
yesql.Namespace `yesql:"contact_manager"`
AddFriendMsgsUpdate *sqlx.Stmt `yesql:"add_friend_msgs_update"`
@ -266,13 +301,21 @@ type FollowingManager struct {
}
type Message struct {
yesql.Namespace `yesql:"message"`
GetMessageById *sqlx.Stmt `yesql:"get_message_by_id"`
GetMessageCount *sqlx.Stmt `yesql:"get_message_count"`
GetMessages *sqlx.Stmt `yesql:"get_messages"`
GetUnreadCount *sqlx.Stmt `yesql:"get_unread_count"`
ReadMessage *sqlx.Stmt `yesql:"read_message"`
CreateMessage *sqlx.NamedStmt `yesql:"create_message"`
yesql.Namespace `yesql:"message"`
CountAllMessages *sqlx.Stmt `yesql:"count_all_messages"`
CountRequestingMessages *sqlx.Stmt `yesql:"count_requesting_messages"`
CountSystemMessages *sqlx.Stmt `yesql:"count_system_messages"`
CountUnreadMessages *sqlx.Stmt `yesql:"count_unread_messages"`
CountWhisperMessages *sqlx.Stmt `yesql:"count_whisper_messages"`
GetAllMessages *sqlx.Stmt `yesql:"get_all_messages"`
GetMessageById *sqlx.Stmt `yesql:"get_message_by_id"`
GetRequestingMessages *sqlx.Stmt `yesql:"get_requesting_messages"`
GetSystemMessages *sqlx.Stmt `yesql:"get_system_messages"`
GetUnreadCount *sqlx.Stmt `yesql:"get_unread_count"`
GetUnreadMessages *sqlx.Stmt `yesql:"get_unread_messages"`
GetWhisperMessages *sqlx.Stmt `yesql:"get_whisper_messages"`
ReadMessage *sqlx.Stmt `yesql:"read_message"`
CreateMessage *sqlx.NamedStmt `yesql:"create_message"`
}
type Security struct {
@ -298,6 +341,12 @@ type SimpleIndex struct {
IndexCount *sqlx.Stmt `yesql:"index_count"`
}
type TrendsManager struct {
yesql.Namespace `yesql:"trends_manager"`
CountIndexTrends *sqlx.Stmt `yesql:"count_index_trends"`
GetIndexTrends *sqlx.Stmt `yesql:"get_index_trends"`
}
type Tweet struct {
yesql.Namespace `yesql:"tweet"`
CountFollowingTweetsFollow string `yesql:"count_following_tweets_follow"`
@ -390,6 +439,7 @@ type TweetMetrics struct {
DeleteTweetMetric *sqlx.Stmt `yesql:"delete_tweet_metric"`
GetMotivationFactor *sqlx.Stmt `yesql:"get_motivation_factor"`
UpdateRankScore *sqlx.Stmt `yesql:"update_rank_score"`
UpsertTweetMetric *sqlx.Stmt `yesql:"upsert_tweet_metric"`
}
type UserManage struct {
@ -405,6 +455,20 @@ type UserManage struct {
UpdateUser *sqlx.NamedStmt `yesql:"update_user"`
}
type UserMetrics struct {
yesql.Namespace `yesql:"user_metrics"`
AddUserMetric *sqlx.Stmt `yesql:"add_user_metric"`
DeleteUserMetric *sqlx.Stmt `yesql:"delete_user_metric"`
GetTweetsCount *sqlx.Stmt `yesql:"get_tweets_count"`
UpdateUserMetric *sqlx.Stmt `yesql:"update_user_metric"`
}
type UserRelation struct {
yesql.Namespace `yesql:"user_relation"`
MyFollowIds *sqlx.Stmt `yesql:"my_follow_ids"`
MyFriendIds *sqlx.Stmt `yesql:"my_friend_ids"`
}
type Wallet struct {
yesql.Namespace `yesql:"wallet"`
AddUserBalance *sqlx.Stmt `yesql:"add_user_balance"`
@ -494,6 +558,9 @@ func BuildCommentManage(p PreparexBuilder, ctx ...context.Context) (obj *Comment
if obj.CreateCommentReply, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_CommentManage_CreateCommentReply))); err != nil {
return nil, fmt.Errorf("prepare _CommentManage_CreateCommentReply error: %w", err)
}
if obj.DecrCommentReplyCount, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_CommentManage_DecrCommentReplyCount))); err != nil {
return nil, fmt.Errorf("prepare _CommentManage_DecrCommentReplyCount error: %w", err)
}
if obj.DeleteComment, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_CommentManage_DeleteComment))); err != nil {
return nil, fmt.Errorf("prepare _CommentManage_DeleteComment error: %w", err)
}
@ -512,6 +579,9 @@ func BuildCommentManage(p PreparexBuilder, ctx ...context.Context) (obj *Comment
if obj.GetTweetCommentThumb, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_CommentManage_GetTweetCommentThumb))); err != nil {
return nil, fmt.Errorf("prepare _CommentManage_GetTweetCommentThumb error: %w", err)
}
if obj.IncrCommentReplyCount, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_CommentManage_IncrCommentReplyCount))); err != nil {
return nil, fmt.Errorf("prepare _CommentManage_IncrCommentReplyCount error: %w", err)
}
if obj.UpdateCommentThumbsCount, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_CommentManage_UpdateCommentThumbsCount))); err != nil {
return nil, fmt.Errorf("prepare _CommentManage_UpdateCommentThumbsCount error: %w", err)
}
@ -527,6 +597,32 @@ func BuildCommentManage(p PreparexBuilder, ctx ...context.Context) (obj *Comment
return
}
func BuildCommentMetrics(p PreparexBuilder, ctx ...context.Context) (obj *CommentMetrics, err error) {
var c context.Context
if len(ctx) > 0 && ctx[0] != nil {
c = ctx[0]
} else {
c = context.Background()
}
obj = &CommentMetrics{}
if obj.AddCommentMetric, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_CommentMetrics_AddCommentMetric))); err != nil {
return nil, fmt.Errorf("prepare _CommentMetrics_AddCommentMetric error: %w", err)
}
if obj.DeleteCommentMetric, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_CommentMetrics_DeleteCommentMetric))); err != nil {
return nil, fmt.Errorf("prepare _CommentMetrics_DeleteCommentMetric error: %w", err)
}
if obj.GetMotivationFactor, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_CommentMetrics_GetMotivationFactor))); err != nil {
return nil, fmt.Errorf("prepare _CommentMetrics_GetMotivationFactor error: %w", err)
}
if obj.UpdateRankScore, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_CommentMetrics_UpdateRankScore))); err != nil {
return nil, fmt.Errorf("prepare _CommentMetrics_UpdateRankScore error: %w", err)
}
if obj.UpsertCommentMetric, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_CommentMetrics_UpsertCommentMetric))); err != nil {
return nil, fmt.Errorf("prepare _CommentMetrics_UpsertCommentMetric error: %w", err)
}
return
}
func BuildContactManager(p PreparexBuilder, ctx ...context.Context) (obj *ContactManager, err error) {
var c context.Context
if len(ctx) > 0 && ctx[0] != nil {
@ -614,18 +710,42 @@ func BuildMessage(p PreparexBuilder, ctx ...context.Context) (obj *Message, err
c = context.Background()
}
obj = &Message{}
if obj.CountAllMessages, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_Message_CountAllMessages))); err != nil {
return nil, fmt.Errorf("prepare _Message_CountAllMessages error: %w", err)
}
if obj.CountRequestingMessages, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_Message_CountRequestingMessages))); err != nil {
return nil, fmt.Errorf("prepare _Message_CountRequestingMessages error: %w", err)
}
if obj.CountSystemMessages, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_Message_CountSystemMessages))); err != nil {
return nil, fmt.Errorf("prepare _Message_CountSystemMessages error: %w", err)
}
if obj.CountUnreadMessages, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_Message_CountUnreadMessages))); err != nil {
return nil, fmt.Errorf("prepare _Message_CountUnreadMessages error: %w", err)
}
if obj.CountWhisperMessages, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_Message_CountWhisperMessages))); err != nil {
return nil, fmt.Errorf("prepare _Message_CountWhisperMessages error: %w", err)
}
if obj.GetAllMessages, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_Message_GetAllMessages))); err != nil {
return nil, fmt.Errorf("prepare _Message_GetAllMessages error: %w", err)
}
if obj.GetMessageById, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_Message_GetMessageById))); err != nil {
return nil, fmt.Errorf("prepare _Message_GetMessageById error: %w", err)
}
if obj.GetMessageCount, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_Message_GetMessageCount))); err != nil {
return nil, fmt.Errorf("prepare _Message_GetMessageCount error: %w", err)
if obj.GetRequestingMessages, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_Message_GetRequestingMessages))); err != nil {
return nil, fmt.Errorf("prepare _Message_GetRequestingMessages error: %w", err)
}
if obj.GetMessages, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_Message_GetMessages))); err != nil {
return nil, fmt.Errorf("prepare _Message_GetMessages error: %w", err)
if obj.GetSystemMessages, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_Message_GetSystemMessages))); err != nil {
return nil, fmt.Errorf("prepare _Message_GetSystemMessages error: %w", err)
}
if obj.GetUnreadCount, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_Message_GetUnreadCount))); err != nil {
return nil, fmt.Errorf("prepare _Message_GetUnreadCount error: %w", err)
}
if obj.GetUnreadMessages, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_Message_GetUnreadMessages))); err != nil {
return nil, fmt.Errorf("prepare _Message_GetUnreadMessages error: %w", err)
}
if obj.GetWhisperMessages, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_Message_GetWhisperMessages))); err != nil {
return nil, fmt.Errorf("prepare _Message_GetWhisperMessages error: %w", err)
}
if obj.ReadMessage, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_Message_ReadMessage))); err != nil {
return nil, fmt.Errorf("prepare _Message_ReadMessage error: %w", err)
}
@ -698,6 +818,23 @@ func BuildSimpleIndex(p PreparexBuilder, ctx ...context.Context) (obj *SimpleInd
return
}
func BuildTrendsManager(p PreparexBuilder, ctx ...context.Context) (obj *TrendsManager, err error) {
var c context.Context
if len(ctx) > 0 && ctx[0] != nil {
c = ctx[0]
} else {
c = context.Background()
}
obj = &TrendsManager{}
if obj.CountIndexTrends, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_TrendsManager_CountIndexTrends))); err != nil {
return nil, fmt.Errorf("prepare _TrendsManager_CountIndexTrends error: %w", err)
}
if obj.GetIndexTrends, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_TrendsManager_GetIndexTrends))); err != nil {
return nil, fmt.Errorf("prepare _TrendsManager_GetIndexTrends error: %w", err)
}
return
}
func BuildTweet(p PreparexBuilder, ctx ...context.Context) (obj *Tweet, err error) {
var c context.Context
if len(ctx) > 0 && ctx[0] != nil {
@ -938,6 +1075,9 @@ func BuildTweetMetrics(p PreparexBuilder, ctx ...context.Context) (obj *TweetMet
if obj.UpdateRankScore, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_TweetMetrics_UpdateRankScore))); err != nil {
return nil, fmt.Errorf("prepare _TweetMetrics_UpdateRankScore error: %w", err)
}
if obj.UpsertTweetMetric, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_TweetMetrics_UpsertTweetMetric))); err != nil {
return nil, fmt.Errorf("prepare _TweetMetrics_UpsertTweetMetric error: %w", err)
}
return
}
@ -978,6 +1118,46 @@ func BuildUserManage(p PreparexBuilder, ctx ...context.Context) (obj *UserManage
return
}
func BuildUserMetrics(p PreparexBuilder, ctx ...context.Context) (obj *UserMetrics, err error) {
var c context.Context
if len(ctx) > 0 && ctx[0] != nil {
c = ctx[0]
} else {
c = context.Background()
}
obj = &UserMetrics{}
if obj.AddUserMetric, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_UserMetrics_AddUserMetric))); err != nil {
return nil, fmt.Errorf("prepare _UserMetrics_AddUserMetric error: %w", err)
}
if obj.DeleteUserMetric, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_UserMetrics_DeleteUserMetric))); err != nil {
return nil, fmt.Errorf("prepare _UserMetrics_DeleteUserMetric error: %w", err)
}
if obj.GetTweetsCount, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_UserMetrics_GetTweetsCount))); err != nil {
return nil, fmt.Errorf("prepare _UserMetrics_GetTweetsCount error: %w", err)
}
if obj.UpdateUserMetric, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_UserMetrics_UpdateUserMetric))); err != nil {
return nil, fmt.Errorf("prepare _UserMetrics_UpdateUserMetric error: %w", err)
}
return
}
func BuildUserRelation(p PreparexBuilder, ctx ...context.Context) (obj *UserRelation, err error) {
var c context.Context
if len(ctx) > 0 && ctx[0] != nil {
c = ctx[0]
} else {
c = context.Background()
}
obj = &UserRelation{}
if obj.MyFollowIds, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_UserRelation_MyFollowIds))); err != nil {
return nil, fmt.Errorf("prepare _UserRelation_MyFollowIds error: %w", err)
}
if obj.MyFriendIds, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_UserRelation_MyFriendIds))); err != nil {
return nil, fmt.Errorf("prepare _UserRelation_MyFriendIds error: %w", err)
}
return
}
func BuildWallet(p PreparexBuilder, ctx ...context.Context) (obj *Wallet, err error) {
var c context.Context
if len(ctx) > 0 && ctx[0] != nil {

@ -17,6 +17,7 @@ var (
)
const (
_Comment_GetHotsComments = `SELECT c.* FROM @comment c LEFT JOIN @comment_metric m ON c.id=m.comment_id WHERE c.post_id=? AND c.is_del=0 AND m.is_del=0 ORDER BY is_essence DESC, m.rank_score DESC NULLS LAST, id DESC LIMIT ? OFFSET ?`
_CommentManage_CreateComment = `INSERT INTO @comment (post_id, user_id, ip, ip_loc, created_on) VALUES (?, ?, ?, ?, ?) RETURNING *`
_CommentManage_CreateCommentContent = `INSERT INTO @comment_content (comment_id, user_id, content, type, sort, created_on) VALUES (?, ?, ?, ?, ?, ?) RETURNING *`
_CommentManage_CreateCommentReply = `INSERT INTO @comment_reply (comment_id, user_id, content, at_user_id, ip, ip_loc, created_on) VALUES (?, ?, ?, ?, ?, ?, ?) RETURNING *`
@ -52,6 +53,11 @@ type PreparexBuilder interface {
QueryHook(query string) string
}
type Comment struct {
yesql.Namespace `yesql:"comment"`
GetHotsComments *sqlx.Stmt `yesql:"get_hots_comments"`
}
type CommentManage struct {
yesql.Namespace `yesql:"comment_manage"`
CreateComment *sqlx.Stmt `yesql:"create_comment"`
@ -93,6 +99,20 @@ type Wallet struct {
CreateRecharge *sqlx.Stmt `yesql:"create_recharge"`
}
func BuildComment(p PreparexBuilder, ctx ...context.Context) (obj *Comment, err error) {
var c context.Context
if len(ctx) > 0 && ctx[0] != nil {
c = ctx[0]
} else {
c = context.Background()
}
obj = &Comment{}
if obj.GetHotsComments, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_Comment_GetHotsComments))); err != nil {
return nil, fmt.Errorf("prepare _Comment_GetHotsComments error: %w", err)
}
return
}
func BuildCommentManage(p PreparexBuilder, ctx ...context.Context) (obj *CommentManage, err error) {
var c context.Context
if len(ctx) > 0 && ctx[0] != nil {

@ -156,8 +156,9 @@ func (s *commentManageSrv) CreateComment(r *ms.Comment) (*ms.Comment, error) {
}
func (s *commentManageSrv) CreateCommentReply(r *ms.CommentReply) (*ms.CommentReply, error) {
now := time.Now().Unix()
res, err := s.q.CreateCommentReply.Exec(r.CommentID, r.UserID, r.Content,
r.AtUserID, r.IP, r.IPLoc, time.Now().Unix())
r.AtUserID, r.IP, r.IPLoc, now)
if err != nil {
return nil, err
}
@ -166,17 +167,22 @@ func (s *commentManageSrv) CreateCommentReply(r *ms.CommentReply) (*ms.CommentRe
return nil, err
}
r.Model = &ms.Model{ID: id}
// 宽松处理错误
s.q.IncrCommentReplyCount.Exec(now, r.CommentID)
return r, nil
}
func (s *commentManageSrv) DeleteCommentReply(r *ms.CommentReply) error {
return s.db.Withx(func(tx *sqlx.Tx) error {
return s.db.Withx(func(tx *sqlx.Tx) (err error) {
now := time.Now().Unix()
if _, err := tx.Stmtx(s.q.DeleteCommentReply).Exec(now, r.ID); err != nil {
return err
if _, err = tx.Stmtx(s.q.DeleteCommentReply).Exec(now, r.ID); err != nil {
return
}
_, err := tx.Stmtx(s.q.DeleteCommentThumbs).Exec(now, r.UserID, r.CommentID, r.ID)
return err
if _, err = tx.Stmtx(s.q.DeleteCommentThumbs).Exec(now, r.UserID, r.CommentID, r.ID); err == nil {
// 宽松处理错误
tx.Stmtx(s.q.DecrCommentReplyCount).Exec(now, r.CommentID)
}
return
})
}
@ -393,11 +399,20 @@ func (s *commentManageSrv) HighlightComment(userId, commentId int64) (int8, erro
return 0, cs.ErrNotImplemented
}
func newCommentService(db *sqlx.DB) core.CommentService {
return &commentSrv{
func newCommentService(db *sqlx.DB) (s core.CommentService) {
cs := &commentSrv{
sqlxSrv: newSqlxSrv(db),
q: ccBuild(db, cc.BuildComment),
}
s = cs
if cfg.Any("PostgreSQL", "PgSQL", "Postgres") {
s = &pgcCommentSrv{
commentSrv: cs,
p: pgcBuild(db, pgc.BuildComment),
}
}
return
}
func newCommentManageService(db *sqlx.DB) (s core.CommentManageService) {

@ -9,6 +9,7 @@ import (
"github.com/bitbus/sqlx/db"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/dao/sakila/auto/pgc"
)
@ -22,19 +23,48 @@ type pgcCommentManageSrv struct {
p *pgc.CommentManage
}
type pgcCommentSrv struct {
*commentSrv
p *pgc.Comment
}
func (s *pgcCommentManageSrv) CreateComment(r *ms.Comment) (*ms.Comment, error) {
return db.Get[ms.Comment](s.p.CreateComment, r.PostID, r.UserID, r.IP, r.IPLoc, time.Now().Unix())
}
func (s *pgcCommentManageSrv) CreateCommentReply(r *ms.CommentReply) (*ms.CommentReply, error) {
return db.Get[ms.CommentReply](s.p.CreateCommentReply, r.CommentID,
func (s *pgcCommentManageSrv) CreateCommentReply(r *ms.CommentReply) (res *ms.CommentReply, err error) {
now := time.Now().Unix()
if res, err = db.Get[ms.CommentReply](s.p.CreateCommentReply, r.CommentID,
r.UserID, r.Content, r.AtUserID,
r.IP, r.IPLoc, time.Now().Unix())
r.IP, r.IPLoc, now); err == nil {
// 宽松处理错误
s.q.IncrCommentReplyCount.Exec(now, r.CommentID)
}
return
}
func (s *pgcCommentManageSrv) CreateCommentContent(r *ms.CommentContent) (*ms.CommentContent, error) {
return db.Get[ms.CommentContent](s.p.CreateCommentContent,
r.CommentID, r.UserID, r.Content,
r.Type, r.Sort, time.Now().Unix())
}
func (s *pgcCommentSrv) GetComments(tweetId int64, style cs.StyleCommentType, limit int, offset int) (res []*ms.Comment, total int64, err error) {
switch style {
case cs.StyleCommentHots:
if err = s.p.GetHotsComments.Select(&res, tweetId, limit, offset); err == nil {
err = s.q.GetCommentCount.Get(&total, tweetId)
}
case cs.StyleCommentNewest:
if err = s.q.GetNewestComments.Select(&res, tweetId, limit, offset); err == nil {
err = s.q.GetCommentCount.Get(&total, tweetId)
}
case cs.StyleCommentDefault:
fallthrough
default:
if err = s.q.GetDefaultComments.Select(&res, tweetId, limit, offset); err == nil {
err = s.q.GetCommentCount.Get(&total, tweetId)
}
}
return
}

@ -11,10 +11,10 @@ import (
"github.com/bitbus/sqlx"
"github.com/bitbus/sqlx/db"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/dao/sakila/auto/cc"
"github.com/rocboss/paopao-ce/internal/dao/sakila/auto/pgc"
"github.com/sirupsen/logrus"
)
var (
@ -55,24 +55,40 @@ func (s *messageSrv) ReadMessage(r *ms.Message) (err error) {
return
}
func (s *messageSrv) GetMessages(userId int64, offset, limit int) ([]*ms.MessageFormated, error) {
func (s *messageSrv) GetMessages(userId int64, style cs.MessageStyle, limit, offset int) (res []*ms.MessageFormated, total int64, err error) {
var messages []*ms.Message
if err := s.q.GetMessages.Select(&messages, userId, userId, limit, offset); err != nil {
return nil, err
}
mfs := make([]*ms.MessageFormated, 0, len(messages))
for _, message := range messages {
mf := message.Format()
mfs = append(mfs, mf)
// 1动态2评论3回复4私信5好友申请99系统通知
switch style {
case cs.StyleMsgSystem:
if err = s.q.CountSystemMessages.Get(&total, userId); err == nil && total > 0 {
err = s.q.GetSystemMessages.Select(&messages, userId, limit, offset)
}
case cs.StyleMsgWhisper:
if err = s.q.CountWhisperMessages.Get(&total, userId, userId); err == nil && total > 0 {
err = s.q.GetWhisperMessages.Select(&messages, userId, userId, limit, offset)
}
case cs.StyleMsgRequesting:
if err = s.q.CountRequestingMessages.Get(&total, userId); err == nil && total > 0 {
err = s.q.GetRequestingMessages.Select(&messages, userId, limit, offset)
}
case cs.StyleMsgUnread:
if err = s.q.CountUnreadMessages.Get(&total, userId); err == nil && total > 0 {
err = s.q.GetUnreadMessages.Select(&messages, userId, limit, offset)
}
case cs.StyleMsgAll:
fallthrough
default:
if err = s.q.CountAllMessages.Get(&total, userId, userId); err == nil && total > 0 {
err = s.q.GetAllMessages.Select(&messages, userId, userId, limit, offset)
}
}
return mfs, nil
}
func (s *messageSrv) GetMessageCount(userId int64) (res int64, err error) {
if err = s.q.GetMessageCount.Get(&res, userId, userId); err != nil {
logrus.Errorf("get message count error: %s", err)
if err == nil {
for _, message := range messages {
res = append(res, message.Format())
}
}
return
}
func newMessageService(db *sqlx.DB) (s core.MessageService) {

@ -20,17 +20,24 @@ type tweetMetricSrvA struct {
type commentMetricSrvA struct {
*sqlxSrv
q *cc.CommentMetrics
}
type userMetricSrvA struct {
*sqlxSrv
q *cc.UserMetrics
}
func (s *tweetMetricSrvA) UpdateTweetMetric(metric *cs.TweetMetric) error {
return s.db.Withx(func(tx *sqlx.Tx) error {
var motivationFactor int
tx.Stmtx(s.q.GetMotivationFactor).Get(&motivationFactor, metric.PostId)
_, err := tx.Stmtx(s.q.UpdateRankScore).Exec(metric.RankScore(motivationFactor), time.Now().Unix(), metric.PostId)
now := time.Now().Unix()
err := tx.Stmtx(s.q.GetMotivationFactor).Get(&motivationFactor, metric.PostId)
if err == nil {
_, err = tx.Stmtx(s.q.UpdateRankScore).Exec(metric.RankScore(motivationFactor), now, metric.PostId)
} else {
_, err = tx.Stmtx(s.q.UpsertTweetMetric).Exec(metric.PostId, metric.RankScore(motivationFactor), now)
}
return err
})
}
@ -46,33 +53,56 @@ func (s *tweetMetricSrvA) DeleteTweetMetric(postId int64) error {
}
func (s *commentMetricSrvA) UpdateCommentMetric(metric *cs.CommentMetric) error {
// TDOO
return cs.ErrNotImplemented
return s.db.Withx(func(tx *sqlx.Tx) error {
var motivationFactor int
now := time.Now().Unix()
err := tx.Stmtx(s.q.GetMotivationFactor).Get(&motivationFactor, metric.CommentId)
if err == nil {
_, err = tx.Stmtx(s.q.UpdateRankScore).Exec(metric.RankScore(motivationFactor), now, metric.CommentId)
} else {
_, err = tx.Stmtx(s.q.UpsertCommentMetric).Exec(metric.CommentId, metric.RankScore(motivationFactor), now)
}
return err
})
}
func (s *commentMetricSrvA) AddCommentMetric(commentId int64) (err error) {
// TDOO
return cs.ErrNotImplemented
func (s *commentMetricSrvA) AddCommentMetric(commentId int64) error {
_, err := s.q.AddCommentMetric.Exec(commentId, time.Now().Unix())
return err
}
func (s *commentMetricSrvA) DeleteCommentMetric(commentId int64) (err error) {
// TDOO
return cs.ErrNotImplemented
func (s *commentMetricSrvA) DeleteCommentMetric(commentId int64) error {
_, err := s.q.DeleteCommentMetric.Exec(time.Now().Unix(), commentId)
return err
}
func (s *userMetricSrvA) UpdateUserMetric(userId int64, action uint8) error {
// TODO
return cs.ErrNotImplemented
func (s *userMetricSrvA) UpdateUserMetric(userId int64, action uint8) (err error) {
var tweets_count int
now := time.Now().Unix()
if err = s.q.GetTweetsCount.Get(&tweets_count, userId); err != nil {
_, err = s.q.AddUserMetric.Exec(userId, now)
return
}
switch action {
case cs.MetricActionCreateTweet:
tweets_count++
case cs.MetricActionDeleteTweet:
if tweets_count > 0 {
tweets_count--
}
}
_, err = s.q.UpdateUserMetric.Exec(userId, tweets_count)
return
}
func (s *userMetricSrvA) AddUserMetric(userId int64) (err error) {
// TDOO
return cs.ErrNotImplemented
func (s *userMetricSrvA) AddUserMetric(userId int64) error {
_, err := s.q.AddUserMetric.Exec(userId, time.Now().Unix())
return err
}
func (s *userMetricSrvA) DeleteUserMetric(userId int64) (err error) {
// TDOO
return cs.ErrNotImplemented
func (s *userMetricSrvA) DeleteUserMetric(userId int64) error {
_, err := s.q.DeleteUserMetric.Exec(time.Now().Unix(), userId)
return err
}
func newTweetMetricServentA(db *sqlx.DB) core.TweetMetricServantA {
@ -85,11 +115,13 @@ func newTweetMetricServentA(db *sqlx.DB) core.TweetMetricServantA {
func newCommentMetricServentA(db *sqlx.DB) core.CommentMetricServantA {
return &commentMetricSrvA{
sqlxSrv: newSqlxSrv(db),
q: ccBuild(db, cc.BuildCommentMetrics),
}
}
func newUserMetricServentA(db *sqlx.DB) core.UserMetricServantA {
return &userMetricSrvA{
sqlxSrv: newSqlxSrv(db),
q: ccBuild(db, cc.BuildUserMetrics),
}
}

@ -39,7 +39,9 @@ type dataSrv struct {
core.SecurityService
core.AttachmentCheckService
core.TweetMetricServantA
core.UserMetricServantA
core.CommentMetricServantA
core.TrendsManageServantA
}
type webDataSrvA struct {
@ -54,10 +56,13 @@ func NewDataService() (core.DataService, core.VersionInfo) {
pvs := security.NewPhoneVerifyService()
cms := newCommentMetricServentA(_db)
tms := newTweetMetricServentA(_db)
ums := newUserMetricServentA(_db)
cis := cache.NewEventCacheIndexSrv(tms)
ds := &dataSrv{
TweetMetricServantA: tms,
CommentMetricServantA: cms,
UserMetricServantA: ums,
TrendsManageServantA: newTrendsManageServentA(_db),
WalletService: newWalletService(_db),
MessageService: newMessageService(_db),
TopicService: newTopicService(_db),
@ -66,7 +71,7 @@ func NewDataService() (core.DataService, core.VersionInfo) {
TweetHelpService: newTweetHelpService(_db),
CommentService: newCommentService(_db),
CommentManageService: newCommentManageService(_db),
UserManageService: newUserManageService(_db),
UserManageService: newUserManageService(_db, ums),
ContactManageService: newContactManageService(_db),
UserRelationService: newUserRelationService(_db),
FollowingManageService: newFollowingManageService(_db),

@ -0,0 +1,31 @@
// 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 sakila
import (
"github.com/bitbus/sqlx"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/dao/sakila/auto/cc"
)
type trendsSrvA struct {
*sqlxSrv
q *cc.TrendsManager
}
func (s *trendsSrvA) GetIndexTrends(userId int64, limit int, offset int) (res []*cs.TrendsItem, total int64, err error) {
if err = s.q.CountIndexTrends.Get(&total, userId); err == nil && total > 0 {
err = s.q.GetIndexTrends.Select(&res, userId, limit, offset)
}
return
}
func newTrendsManageServentA(db *sqlx.DB) core.TrendsManageServantA {
return &trendsSrvA{
sqlxSrv: newSqlxSrv(db),
q: ccBuild(db, cc.BuildTrendsManager),
}
}

@ -519,7 +519,7 @@ func (s *tweetSrv) getUserRelation(userId int64) (beFriendIds []int64, beFollowI
// 找到item即删数据库已经保证唯一性
if beFollowIds[i] == id {
lastIdx := len(beFollowIds) - 1
beFriendIds[i] = beFriendIds[lastIdx]
beFollowIds[i] = beFollowIds[lastIdx]
beFollowIds = beFollowIds[:lastIdx]
break
}

@ -12,7 +12,6 @@ import (
"github.com/bitbus/sqlx"
"github.com/bitbus/sqlx/db"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/dao/sakila/auto/cc"
"github.com/rocboss/paopao-ce/internal/dao/sakila/auto/pgc"
@ -24,11 +23,13 @@ var (
type userManageSrv struct {
*sqlxSrv
q *cc.UserManage
q *cc.UserManage
ums core.UserMetricServantA
}
type userRelationSrv struct {
*sqlxSrv
q *cc.UserRelation
}
func (s *userManageSrv) GetUserByID(id int64) (*ms.User, error) {
@ -69,7 +70,10 @@ func (s *userManageSrv) CreateUser(r *ms.User) (*ms.User, error) {
if err != nil {
return nil, err
}
r.ID, err = res.LastInsertId()
if r.ID, err = res.LastInsertId(); err == nil {
// 宽松处理错误
s.ums.AddUserMetric(r.ID)
}
return r, err
}
@ -84,29 +88,64 @@ func (s *userManageSrv) GetRegisterUserCount() (res int64, err error) {
}
func (s *userRelationSrv) MyFriendIds(userId int64) (res []int64, err error) {
// TODO
err = s.q.MyFriendIds.Select(&res, userId)
return
}
func (s *userRelationSrv) MyFollowIds(userId int64) (res []int64, err error) {
// TODO
err = s.q.MyFollowIds.Select(&res, userId)
return
}
func (s *userRelationSrv) IsMyFriend(userId int64, friendIds ...int64) (map[int64]bool, error) {
// TODO
return nil, cs.ErrNotImplemented
size := len(friendIds)
res := make(map[int64]bool, size)
if size == 0 {
return res, nil
}
myFriendIds, err := s.MyFriendIds(userId)
if err != nil {
return nil, err
}
for _, friendId := range friendIds {
res[friendId] = false
for _, myFriendId := range myFriendIds {
if friendId == myFriendId {
res[friendId] = true
break
}
}
}
return res, nil
}
func (s *userRelationSrv) IsMyFollow(userId int64, followIds ...int64) (map[int64]bool, error) {
// TODO
return nil, cs.ErrNotImplemented
size := len(followIds)
res := make(map[int64]bool, size)
if size == 0 {
return res, nil
}
myFollowIds, err := s.MyFollowIds(userId)
if err != nil {
return nil, err
}
for _, followId := range followIds {
res[followId] = false
for _, myFollowId := range myFollowIds {
if followId == myFollowId {
res[followId] = true
break
}
}
}
return res, nil
}
func newUserManageService(db *sqlx.DB) (s core.UserManageService) {
func newUserManageService(db *sqlx.DB, userMetric core.UserMetricServantA) (s core.UserManageService) {
ums := &userManageSrv{
sqlxSrv: newSqlxSrv(db),
q: ccBuild(db, cc.BuildUserManage),
ums: userMetric,
}
s = ums
if cfg.Any("PostgreSQL", "PgSQL", "Postgres") {
@ -121,5 +160,6 @@ func newUserManageService(db *sqlx.DB) (s core.UserManageService) {
func newUserRelationService(db *sqlx.DB) core.UserRelationService {
return &userRelationSrv{
sqlxSrv: newSqlxSrv(db),
q: ccBuild(db, cc.BuildUserRelation),
}
}

@ -21,10 +21,11 @@ type pgcUserManageSrv struct {
p *pgc.UserManage
}
func (s *pgcUserManageSrv) CreateUser(r *ms.User) (*ms.User, error) {
r.Model = &ms.Model{CreatedOn: time.Now().Unix()}
if err := s.p.CreateUser.Get(&r.ID, r); err != nil {
return nil, err
func (s *pgcUserManageSrv) CreateUser(r *ms.User) (res *ms.User, err error) {
res, r.Model = r, &ms.Model{CreatedOn: time.Now().Unix()}
if err = s.p.CreateUser.Get(&r.ID, r); err == nil {
// 宽松处理错误
s.ums.AddUserMetric(r.ID)
}
return r, nil
return
}

@ -25,15 +25,29 @@ SELECT status FROM @contact WHERE user_id=? AND friend_id=? AND is_del=0;
-- name: get_newest_comments@comment
-- prepare: stmt
SELECT * FROM @comment WHERE post_id=? AND is_del=0 ORDER BY id DESC LIMIT ? OFFSET ?;
SELECT *
FROM @comment
WHERE post_id=? AND is_del=0
ORDER BY is_essence DESC, id DESC
LIMIT ? OFFSET ?;
-- name: get_hots_comments@comment
-- prepare: stmt
SELECT * FROM @comment WHERE post_id=? AND is_del=0 ORDER BY thumbs_up_count DESC, id DESC LIMIT ? OFFSET ?;
SELECT c.*
FROM @comment c
LEFT JOIN @comment_metric m
ON c.id=m.comment_id
WHERE c.post_id=? AND c.is_del=0 AND m.is_del=0
ORDER BY is_essence DESC, m.rank_score DESC, id DESC
LIMIT ? OFFSET ?;
-- name: get_default_comments@comment
-- prepare: stmt
SELECT * FROM @comment WHERE post_id=? AND is_del=0 ORDER BY id ASC LIMIT ? OFFSET ?;
SELECT *
FROM @comment
WHERE post_id=? AND is_del=0
ORDER BY is_essence DESC, id ASC
LIMIT ? OFFSET ?;
-- name: get_comment_by_id@comment
-- prepare: stmt
@ -97,6 +111,20 @@ VALUES (?, ?, ?, ?, ?);
INSERT INTO @comment_reply (comment_id, user_id, content, at_user_id, ip, ip_loc, created_on)
VALUES (?, ?, ?, ?, ?, ?, ?);
-- name: incr_comment_reply_count@comment_manage
-- prepare: stmt
UPDATE @comment
SET reply_count=reply_count+1,
modified_on=?
WHERE id=? AND is_del=0;
-- name: decr_comment_reply_count@comment_manage
-- prepare: stmt
UPDATE @comment
SET reply_count=reply_count-1,
modified_on=?
WHERE id=? AND is_del=0;
-- name: delete_comment_reply@comment_manage
-- prepare: stmt
UPDATE @comment_reply SET deleted_on=?, is_del=1 WHERE id=? AND is_del=0;
@ -197,6 +225,41 @@ LIMIT ? OFFSET ?;
-- prepare: stmt
SELECT count(*) FROM @following WHERE follow_id=? AND is_del=0;
--------------------------------------------------------------------------------
-- trends_manager sql dml
--------------------------------------------------------------------------------
-- name: get_index_trends@trends_manager
-- prepare: stmt
SELECT u.username username,
u.nickname nickname,
u.avatar avatar
FROM @contact c
JOIN @user u
ON c.friend_id=u.id
JOIN @user_metric m
ON c.friend_id=m.user_id
WHERE c.user_id=?
AND c.is_del=0
AND u.is_del=0
AND m.is_del=0
AND m.tweets_count>0
LIMIT ? OFFSET ?;
-- name: count_index_trends@trends_manager
-- prepare: stmt
SELECT count(*)
FROM @contact c
JOIN @user u
ON c.friend_id=u.id
JOIN @user_metric m
ON c.friend_id=m.user_id
WHERE c.user_id=?
AND c.is_del=0
AND u.is_del=0
AND m.is_del=0
AND m.tweets_count>0;
--------------------------------------------------------------------------------
-- contact_manager sql dml
--------------------------------------------------------------------------------
@ -288,17 +351,75 @@ SELECT * FROM @message WHERE id=? AND is_del=0;
-- prepare: stmt
UPDATE @message SET is_read=1, modified_on=? WHERE id=?;
-- name: get_messages@message
-- name: get_system_messages@message
-- prepare: stmt
SELECT *
FROM @message
WHERE receiver_user_id=? AND type IN (1, 2, 3, 99) AND is_del=0
ORDER BY id DESC
LIMIT ? OFFSET ?;
-- name: count_system_messages@message
-- prepare: stmt
SELECT count(*)
FROM @message
WHERE receiver_user_id=? AND type IN (1, 2, 3, 99) AND is_del=0;
-- name: get_whisper_messages@message
-- prepare: stmt
SELECT *
FROM @message
WHERE ((receiver_user_id=? OR sender_user_id=?) AND type=4) AND is_del=0
ORDER BY id DESC
LIMIT ? OFFSET ?;
-- name: count_whisper_messages@message
-- prepare: stmt
SELECT count(*)
FROM @message
WHERE ((receiver_user_id=? OR sender_user_id=?) AND type=4) AND is_del=0;
-- name: get_requesting_messages@message
-- prepare: stmt
SELECT *
FROM @message
WHERE receiver_user_id=? AND type=5 AND is_del=0
ORDER BY id DESC
LIMIT ? OFFSET ?;
-- name: count_requesting_messages@message
-- prepare: stmt
SELECT count(*)
FROM @message
WHERE receiver_user_id=? AND type=5 AND is_del=0;
-- name: get_unread_messages@message
-- prepare: stmt
SELECT *
FROM @message
WHERE receiver_user_id=? AND is_read=0 AND is_del=0
ORDER BY id DESC
LIMIT ? OFFSET ?;
-- name: count_unread_messages@message
-- prepare: stmt
SELECT count(*)
FROM @message
WHERE receiver_user_id=? AND is_read=0 AND is_del=0;
-- name: get_all_messages@message
-- prepare: stmt
SELECT *
FROM @message
WHERE (receiver_user_id=? OR (sender_user_id=? AND type=4)) AND is_del=0
ORDER BY id DESC
LIMIT ? OFFSET ?
LIMIT ? OFFSET ?;
-- name: get_message_count@message
-- name: count_all_messages@message
-- prepare: stmt
SELECT count(*) FROM @message WHERE (receiver_user_id=? OR (sender_user_id=? AND type=4)) AND is_del=0
SELECT count(*)
FROM @message
WHERE (receiver_user_id=? OR (sender_user_id=? AND type=4)) AND is_del=0;
--------------------------------------------------------------------------------
-- security sql dml
@ -1191,6 +1312,7 @@ WHERE id IN (?) AND is_del=0;
--------------------------------------------------------------------------------
-- tweet_metrics sql dml
--------------------------------------------------------------------------------
-- name: update_rank_score@tweet_metrics
-- prepare: stmt
UPDATE @post_metric SET rank_score=?, modified_on=? WHERE post_id=? AND is_del=0;
@ -1203,10 +1325,58 @@ SELECT motivation_factor FROM @post_metric WHERE post_id=? AND is_del=0;
-- prepare: stmt
INSERT INTO @post_metric (post_id, created_on) VALUES (?, ?);
-- name: upsert_tweet_metric@tweet_metrics
-- prepare: stmt
INSERT INTO @post_metric (post_id, rank_score, created_on) VALUES (?, ?, ?);
-- name: delete_tweet_metric@tweet_metrics
-- prepare: stmt
UPDATE @post_metric SET is_del=1, deleted_on=? WHERE post_id=? AND is_del=0;
--------------------------------------------------------------------------------
-- comment_metrics sql dml
--------------------------------------------------------------------------------
-- name: update_rank_score@comment_metrics
-- prepare: stmt
UPDATE @comment_metric SET rank_score=?, modified_on=? WHERE comment_id=? AND is_del=0;
-- name: get_motivation_factor@comment_metrics
-- prepare: stmt
SELECT motivation_factor FROM @comment_metric WHERE comment_id=? AND is_del=0;
-- name: add_comment_metric@comment_metrics
-- prepare: stmt
INSERT INTO @comment_metric (comment_id, created_on) VALUES (?, ?);
-- name: upsert_comment_metric@comment_metrics
-- prepare: stmt
INSERT INTO @comment_metric (comment_id, rank_score, created_on) VALUES (?, ?, ?);
-- name: delete_comment_metric@comment_metrics
-- prepare: stmt
UPDATE @comment_metric SET is_del=1, deleted_on=? WHERE comment_id=? AND is_del=0;
--------------------------------------------------------------------------------
-- user_metrics sql dml
--------------------------------------------------------------------------------
-- name: update_user_metric@user_metrics
-- prepare: stmt
UPDATE @user_metric SET tweets_count=?, modified_on=? WHERE user_id=? AND is_del=0;
-- name: get_tweets_count@user_metrics
-- prepare: stmt
SELECT tweets_count FROM @user_metric WHERE user_id=? AND is_del=0;
-- name: add_user_metric@user_metrics
-- prepare: stmt
INSERT INTO @user_metric (user_id, created_on) VALUES (?, ?);
-- name: delete_user_metric@user_metrics
-- prepare: stmt
UPDATE @user_metric SET is_del=1, deleted_on=? WHERE user_id=? AND is_del=0;
--------------------------------------------------------------------------------
-- user_manage sql dml
--------------------------------------------------------------------------------
@ -1260,6 +1430,18 @@ SET username=:username,
modified_on=:modified_on
WHERE id=? AND is_del=0;
--------------------------------------------------------------------------------
-- user_relation sql dml
--------------------------------------------------------------------------------
-- name: my_friend_ids@user_relation
-- prepare: stmt
SELECT friend_id FROM @contact WHERE user_id=? AND is_del=0;
-- name: my_follow_ids@user_relation
-- prepare: stmt
SELECT follow_id FROM @following WHERE user_id=? AND is_del=0;
--------------------------------------------------------------------------------
-- wallet sql dml
--------------------------------------------------------------------------------

@ -52,6 +52,20 @@ INSERT INTO @post_collection (post_id, user_id, created_on)
VALUES (?, ?, ?)
RETURNING *;
--------------------------------------------------------------------------------
-- comment sql dml
--------------------------------------------------------------------------------
-- name: get_hots_comments@comment
-- prepare: stmt
SELECT c.*
FROM @comment c
LEFT JOIN @comment_metric m
ON c.id=m.comment_id
WHERE c.post_id=? AND c.is_del=0 AND m.is_del=0
ORDER BY is_essence DESC, m.rank_score DESC NULLS LAST, id DESC
LIMIT ? OFFSET ?;
--------------------------------------------------------------------------------
-- user_manage sql dml
--------------------------------------------------------------------------------

@ -7,11 +7,15 @@ package web
import (
"github.com/alimy/mir/v4"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/model/joint"
"github.com/rocboss/paopao-ce/internal/servants/base"
"github.com/rocboss/paopao-ce/pkg/convert"
"github.com/rocboss/paopao-ce/pkg/xerror"
)
type MessageStyle = cs.MessageStyle
type ChangeAvatarReq struct {
BaseInfo `json:"-" binding:"-"`
Avatar string `json:"avatar" form:"avatar" binding:"required"`
@ -40,9 +44,15 @@ type UserInfoResp struct {
Followings int64 `json:"followings"`
}
type GetMessagesReq BasePageReq
type GetMessagesReq struct {
SimpleInfo `json:"-" binding:"-"`
joint.BasePageInfo
Style MessageStyle `form:"style" binding:"required"`
}
type GetMessagesResp base.PageResp
type GetMessagesResp struct {
joint.CachePageResp
}
type ReadMessageReq struct {
SimpleInfo `json:"-" binding:"-"`
@ -120,10 +130,6 @@ func (r *UserInfoReq) Bind(c *gin.Context) mir.Error {
return nil
}
func (r *GetMessagesReq) Bind(c *gin.Context) mir.Error {
return (*BasePageReq)(r).Bind(c)
}
func (r *GetCollectionsReq) Bind(c *gin.Context) mir.Error {
return (*BasePageReq)(r).Bind(c)
}

@ -4,7 +4,9 @@
package web
import "github.com/rocboss/paopao-ce/internal/servants/base"
import (
"github.com/rocboss/paopao-ce/internal/servants/base"
)
type RequestingFriendReq struct {
BaseInfo `json:"-" binding:"-"`

@ -0,0 +1,18 @@
// 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/rocboss/paopao-ce/internal/model/joint"
)
type GetIndexTrendsReq struct {
SimpleInfo `json:"-" binding:"-"`
joint.BasePageInfo
}
type GetIndexTrendsResp struct {
joint.CachePageResp
}

@ -90,6 +90,8 @@ var (
ErrNotAllowFollowSelf = xerror.NewError(80105, "不能关注自己")
ErrNotAllowUnfollowSelf = xerror.NewError(80106, "不能取消关注自己")
ErrGetIndexTrendsFailed = xerror.NewError(802001, "获取动态条栏信息失败")
ErrFollowTopicFailed = xerror.NewError(90001, "关注话题失败")
ErrUnfollowTopicFailed = xerror.NewError(90002, "取消关注话题失败")
ErrStickTopicFailed = xerror.NewError(90003, "更行话题置顶状态失败")

@ -6,6 +6,7 @@ package web
import (
"context"
"fmt"
"time"
"unicode/utf8"
@ -13,8 +14,10 @@ import (
"github.com/alimy/mir/v4"
"github.com/gin-gonic/gin"
api "github.com/rocboss/paopao-ce/auto/api/v1"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/model/joint"
"github.com/rocboss/paopao-ce/internal/model/web"
"github.com/rocboss/paopao-ce/internal/servants/base"
"github.com/rocboss/paopao-ce/internal/servants/chain"
@ -35,9 +38,10 @@ var (
type coreSrv struct {
api.UnimplementedCoreServant
*base.DaoServant
oss core.ObjectStorageService
wc core.WebCache
oss core.ObjectStorageService
wc core.WebCache
messagesExpire int64
prefixMessages string
}
func (s *coreSrv) Chain() gin.HandlersChain {
@ -84,8 +88,19 @@ func (s *coreSrv) GetUserInfo(req *web.UserInfoReq) (*web.UserInfoResp, mir.Erro
return resp, nil
}
func (s *coreSrv) GetMessages(req *web.GetMessagesReq) (*web.GetMessagesResp, mir.Error) {
messages, err := s.Ds.GetMessages(req.UserId, (req.Page-1)*req.PageSize, req.PageSize)
func (s *coreSrv) GetMessages(req *web.GetMessagesReq) (res *web.GetMessagesResp, _ mir.Error) {
limit, offset := req.PageSize, (req.Page-1)*req.PageSize
// 尝试直接从缓存中获取数据
key, ok := "", false
if res, key, ok = s.messagesFromCache(req, limit, offset); ok {
// logrus.Debugf("coreSrv.GetMessages from cache key:%s", key)
return
}
messages, totalRows, err := s.Ds.GetMessages(req.Uid, req.Style, limit, offset)
if err != nil {
logrus.Errorf("Ds.GetMessages err[1]: %s", err)
return nil, web.ErrGetMessagesFailed
}
for _, mf := range messages {
// TODO: 优化处理这里的user获取逻辑以及错误处理
if mf.SenderUserID > 0 {
@ -93,7 +108,7 @@ func (s *coreSrv) GetMessages(req *web.GetMessagesReq) (*web.GetMessagesResp, mi
mf.SenderUser = user.Format()
}
}
if mf.Type == ms.MsgTypeWhisper && mf.ReceiverUserID != req.UserId {
if mf.Type == ms.MsgTypeWhisper && mf.ReceiverUserID != req.Uid {
if user, err := s.Ds.GetUserByID(mf.ReceiverUserID); err == nil {
mf.ReceiverUser = user.Format()
}
@ -122,16 +137,21 @@ func (s *coreSrv) GetMessages(req *web.GetMessagesReq) (*web.GetMessagesResp, mi
}
}
if err != nil {
logrus.Errorf("Ds.GetMessages err: %v\n", err)
logrus.Errorf("Ds.GetMessages err[2]: %s", err)
return nil, web.ErrGetMessagesFailed
}
if err = s.PrepareMessages(req.UserId, messages); err != nil {
logrus.Errorf("get messages err[2]: %v\n", err)
if err = s.PrepareMessages(req.Uid, messages); err != nil {
logrus.Errorf("get messages err[3]: %s", err)
return nil, web.ErrGetMessagesFailed
}
totalRows, _ := s.Ds.GetMessageCount(req.UserId)
resp := base.PageRespFrom(messages, req.Page, req.PageSize, totalRows)
return (*web.GetMessagesResp)(resp), nil
resp := joint.PageRespFrom(messages, req.Page, req.PageSize, totalRows)
// 缓存处理
base.OnCacheRespEvent(s.wc, key, resp, s.messagesExpire)
return &web.GetMessagesResp{
CachePageResp: joint.CachePageResp{
Data: resp,
},
}, nil
}
func (s *coreSrv) ReadMessage(req *web.ReadMessageReq) mir.Error {
@ -146,8 +166,8 @@ func (s *coreSrv) ReadMessage(req *web.ReadMessageReq) mir.Error {
logrus.Errorf("Ds.ReadMessage err: %s", err)
return web.ErrReadMessageFailed
}
// 清除未读消息数缓存,不需要处理错误
s.wc.DelUnreadMsgCountResp(req.Uid)
// 缓存处理
onMessageActionEvent(_messageActionRead, req.Uid)
return nil
}
@ -378,10 +398,25 @@ func (s *coreSrv) TweetStarStatus(req *web.TweetStarStatusReq) (*web.TweetStarSt
return resp, nil
}
func (s *coreSrv) messagesFromCache(req *web.GetMessagesReq, limit int, offset int) (res *web.GetMessagesResp, key string, ok bool) {
key = fmt.Sprintf("%s%d:%s:%d:%d", s.prefixMessages, req.Uid, req.Style, limit, offset)
if data, err := s.wc.Get(key); err == nil {
ok, res = true, &web.GetMessagesResp{
CachePageResp: joint.CachePageResp{
JsonResp: data,
},
}
}
return
}
func newCoreSrv(s *base.DaoServant, oss core.ObjectStorageService, wc core.WebCache) api.Core {
cs := conf.CacheSetting
return &coreSrv{
DaoServant: s,
oss: oss,
wc: wc,
DaoServant: s,
oss: oss,
wc: wc,
messagesExpire: cs.MessagesExpire,
prefixMessages: conf.PrefixMessages,
}
}

@ -16,6 +16,7 @@ import (
"github.com/rocboss/paopao-ce/internal/events"
"github.com/rocboss/paopao-ce/internal/model/joint"
"github.com/rocboss/paopao-ce/internal/model/web"
"github.com/sirupsen/logrus"
)
const (
@ -27,6 +28,18 @@ const (
_commentActionReplyDelete
_commentActionReplyThumbsUp
_commentActionReplyThumbsDown
_commentActionHighlight
)
const (
_messageActionCreate uint8 = iota
_messageActionRead
_messageActionFollow
)
const (
_trendsActionCreateTweet uint8 = iota
_trendsActionDeleteTweet
)
type cacheUnreadMsgEvent struct {
@ -52,6 +65,38 @@ type commentActionEvent struct {
action uint8
}
type messageActionEvent struct {
event.UnimplementedEvent
wc core.WebCache
action uint8
userId []int64
}
type trendsActionEvent struct {
event.UnimplementedEvent
ac core.AppCache
ds core.DataService
action uint8
userId int64
}
func onTrendsActionEvent(action uint8, userId int64) {
events.OnEvent(&trendsActionEvent{
ac: _ac,
ds: _ds,
action: action,
userId: userId,
})
}
func onMessageActionEvent(action uint8, userIds ...int64) {
events.OnEvent(&messageActionEvent{
wc: _wc,
action: action,
userId: userIds,
})
}
func onCommentActionEvent(tweetId int64, commentId int64, action uint8) {
events.OnEvent(&commentActionEvent{
ds: _ds,
@ -138,6 +183,8 @@ func (e *commentActionEvent) Action() (err error) {
case _commentActionThumbsUp, _commentActionThumbsDown:
err = e.updateCommentMetric()
e.expireHotsComments()
case _commentActionHighlight:
e.expireAllStyleComments()
default:
// nothing
}
@ -166,3 +213,54 @@ func (e *commentActionEvent) updateCommentMetric() error {
})
return nil
}
func (e *messageActionEvent) Name() string {
return "expireMessagesEvent"
}
func (e *messageActionEvent) Action() (err error) {
for _, userId := range e.userId {
switch e.action {
case _messageActionRead:
// 清除未读消息数缓存,不需要处理错误
e.wc.DelUnreadMsgCountResp(userId)
case _messageActionCreate,
_messageActionFollow:
fallthrough
default:
// TODO
}
//清除该用户所有消息缓存
err = e.wc.DelAny(fmt.Sprintf("%s%d:*", conf.PrefixMessages, userId))
}
return
}
func (e *trendsActionEvent) Name() string {
return "trendsActionEvent"
}
func (e *trendsActionEvent) Action() (err error) {
switch e.action {
case _trendsActionCreateTweet:
logrus.Debug("trigger trendsActionEvent by create tweet ")
e.ds.UpdateUserMetric(e.userId, cs.MetricActionCreateTweet)
goto ExpireTrends
case _trendsActionDeleteTweet:
logrus.Debug("trigger trendsActionEvent by delete tweet ")
e.ds.UpdateUserMetric(e.userId, cs.MetricActionDeleteTweet)
goto ExpireTrends
default:
// nothing
goto JustReturn
}
ExpireTrends:
if friendIds, err := e.ds.MyFriendIds(e.userId); err == nil {
for _, id := range friendIds {
e.ac.DelAny(fmt.Sprintf("%s%d:*", conf.PrefixIdxTrends, id))
}
return err
}
JustReturn:
return
}

@ -86,8 +86,10 @@ func (s *followshipSrv) UnfollowUser(r *web.UnfollowUserReq) mir.Error {
return web.ErrUnfollowUserFailed
}
// 触发缓存更新事件
// TODO: 合并成一个事件
cache.OnCacheMyFollowIdsEvent(s.Ds, r.User.ID)
cache.OnExpireIndexTweetEvent(r.User.ID)
onMessageActionEvent(_messageActionFollow, r.User.ID)
return nil
}
@ -102,8 +104,10 @@ func (s *followshipSrv) FollowUser(r *web.FollowUserReq) mir.Error {
return web.ErrUnfollowUserFailed
}
// 触发缓存更新事件
// TODO: 合并成一个事件
cache.OnCacheMyFollowIdsEvent(s.Ds, r.User.ID)
cache.OnExpireIndexTweetEvent(r.User.ID)
onMessageActionEvent(_messageActionFollow, r.User.ID)
return nil
}

@ -313,6 +313,8 @@ func (s *privSrv) CreateTweet(req *web.CreateTweetReq) (_ *web.CreateTweetResp,
logrus.Infof("Ds.RevampPosts err: %s", err)
return nil, web.ErrCreatePostFailed
}
// 缓存处理
onTrendsActionEvent(_trendsActionCreateTweet, req.User.ID)
return (*web.CreateTweetResp)(formatedPosts[0]), nil
}
@ -341,6 +343,8 @@ func (s *privSrv) DeleteTweet(req *web.DeleteTweetReq) mir.Error {
logrus.Errorf("s.DeleteSearchPost failed: %s", err)
return web.ErrDeletePostFailed
}
// 缓存处理
onTrendsActionEvent(_trendsActionDeleteTweet, req.User.ID)
return nil
}
@ -484,6 +488,10 @@ func (s *privSrv) HighlightComment(req *web.HighlightCommentReq) (*web.Highlight
} else if err != nil {
return nil, web.ErrHighlightCommentFailed
}
// 缓存处理, 宽松处理错误
if comment, err := s.Ds.GetCommentByID(req.CommentId); err == nil {
onCommentActionEvent(comment.PostID, comment.ID, _commentActionHighlight)
}
return &web.HighlightCommentResp{
HighlightStatus: status,
}, nil

@ -0,0 +1,81 @@
// 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 web
import (
"fmt"
"github.com/alimy/mir/v4"
"github.com/gin-gonic/gin"
api "github.com/rocboss/paopao-ce/auto/api/v1"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model/joint"
"github.com/rocboss/paopao-ce/internal/model/web"
"github.com/rocboss/paopao-ce/internal/servants/base"
"github.com/rocboss/paopao-ce/internal/servants/chain"
"github.com/sirupsen/logrus"
)
var (
_ api.Trends = (*trendsSrv)(nil)
)
type trendsSrv struct {
api.UnimplementedTrendsServant
*base.DaoServant
ac core.AppCache
indexTrendsExpire int64
prefixTrends string
}
func (s *trendsSrv) Chain() gin.HandlersChain {
return gin.HandlersChain{chain.JWT()}
}
func (s *trendsSrv) GetIndexTrends(req *web.GetIndexTrendsReq) (res *web.GetIndexTrendsResp, _ mir.Error) {
limit, offset := req.PageSize, (req.Page-1)*req.PageSize
// 尝试直接从缓存中获取数据
key, ok := "", false
if res, key, ok = s.trendsFromCache(req, limit, offset); ok {
// logrus.Debugf("trendsSrv.GetIndexTrends from cache key:%s", key)
return
}
trends, totalRows, err := s.Ds.GetIndexTrends(req.Uid, limit, offset)
if err != nil {
logrus.Errorf("Ds.GetIndexTrends err[1]: %s", err)
return nil, web.ErrGetIndexTrendsFailed
}
resp := joint.PageRespFrom(trends, req.Page, req.PageSize, totalRows)
// 缓存处理
base.OnCacheRespEvent(s.ac, key, resp, s.indexTrendsExpire)
return &web.GetIndexTrendsResp{
CachePageResp: joint.CachePageResp{
Data: resp,
},
}, nil
}
func (s *trendsSrv) trendsFromCache(req *web.GetIndexTrendsReq, limit int, offset int) (res *web.GetIndexTrendsResp, key string, ok bool) {
key = fmt.Sprintf("%s%d:%d:%d", s.prefixTrends, req.Uid, limit, offset)
if data, err := s.ac.Get(key); err == nil {
ok, res = true, &web.GetIndexTrendsResp{
CachePageResp: joint.CachePageResp{
JsonResp: data,
},
}
}
return
}
func newTrendsSrv(s *base.DaoServant) api.Trends {
cs := conf.CacheSetting
return &trendsSrv{
DaoServant: s,
ac: _ac,
indexTrendsExpire: cs.IndexTrendsExpire,
prefixTrends: conf.PrefixIdxTrends,
}
}

@ -38,6 +38,7 @@ func RouteWeb(e *gin.Engine) {
api.RegisterLooseServant(e, newLooseSrv(ds, _ac))
api.RegisterPrivServant(e, newPrivSrv(ds, _oss), newPrivChain())
api.RegisterPubServant(e, newPubSrv(ds))
api.RegisterTrendsServant(e, newTrendsSrv(ds))
api.RegisterFollowshipServant(e, newFollowshipSrv(ds))
api.RegisterFriendshipServant(e, newFriendshipSrv(ds))
// regster servants if needed by configure

@ -0,0 +1,20 @@
package v1
import (
. "github.com/alimy/mir/v4"
. "github.com/alimy/mir/v4/engine"
"github.com/rocboss/paopao-ce/internal/model/web"
)
func init() {
Entry[Trends]()
}
// Trends 动态相关 服务
type Trends struct {
Chain `mir:"-"`
Group `mir:"v1"`
// GetIndexTrends 获取广场页面动态条栏的索引item
GetIndexTrends func(Get, web.GetIndexTrendsReq) web.GetIndexTrendsResp `mir:"/trends/index"`
}

@ -1 +1 @@
import{_ as s}from"./main-nav.vue_vue_type_style_index_0_lang-93352cc4.js";import{u as i}from"./vue-router-e5a2430e.js";import{G as a,e as c,a2 as u}from"./naive-ui-defd0b2d.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-daff1b26.js";import"./vuex-44de225f.js";import"./vooks-6d99783e.js";import"./evtd-b614532e.js";import"./@vicons-c265fba6.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};
import{_ as s}from"./main-nav.vue_vue_type_style_index_0_lang-65b365f0.js";import{u as i}from"./vue-router-e5a2430e.js";import{G as a,e as c,a2 as u}from"./naive-ui-eecf2ec3.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-83d7d999.js";import"./vuex-44de225f.js";import"./vooks-6d99783e.js";import"./evtd-b614532e.js";import"./@vicons-f0266f88.js";import"./seemly-76b7b838.js";import"./vueuc-7c8d4b48.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};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +1 @@
import{_ as N}from"./post-skeleton-8434d30b.js";import{_ as R}from"./main-nav.vue_vue_type_style_index_0_lang-93352cc4.js";import{u as z}from"./vuex-44de225f.js";import{b as A}from"./vue-router-e5a2430e.js";import{I as F,_ as S}from"./index-daff1b26.js";import{G as V,R as q,J as H,H as I}from"./naive-ui-defd0b2d.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 E,q as G,j as s,x as _,l as J}from"./@vue-a481fc63.js";import"./vooks-6d99783e.js";import"./evtd-b614532e.js";import"./@vicons-c265fba6.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 L={key:0,class:"pagination-wrap"},M={key:0,class:"skeleton-wrap"},O={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,K)=>{const k=R,y=q,x=N,w=H,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",L,[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",M,[a(x,{num:f.value},null,8,["num"])])):(t(),o("div",O,[i.value.length===0?(t(),o("div",T,[a(w,{size:"large",description:"暂无数据"})])):l("",!0),(t(!0),o(D,null,E(i.value,e=>(t(),G(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:J({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(F)(e.created_on)),1)])]),_:2},1024))),128))]))]),_:1})])}}});const ke=S(Y,[["__scopeId","data-v-d4d04859"]]);export{ke as default};
import{_ as N}from"./post-skeleton-63a5a4f0.js";import{_ as R}from"./main-nav.vue_vue_type_style_index_0_lang-65b365f0.js";import{u as z}from"./vuex-44de225f.js";import{b as A}from"./vue-router-e5a2430e.js";import{J as F,_ as S}from"./index-83d7d999.js";import{G as V,R as q,J as H,H as J}from"./naive-ui-eecf2ec3.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 E,q as G,j as s,x as _,l as I}from"./@vue-a481fc63.js";import"./vooks-6d99783e.js";import"./evtd-b614532e.js";import"./@vicons-f0266f88.js";import"./axios-4a70c6fc.js";import"./moment-2ab8298d.js";/* empty css */import"./seemly-76b7b838.js";import"./vueuc-7c8d4b48.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 L={key:0,class:"pagination-wrap"},M={key:0,class:"skeleton-wrap"},O={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,K)=>{const k=R,y=q,x=N,w=H,B=J,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",L,[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",M,[a(x,{num:f.value},null,8,["num"])])):(t(),o("div",O,[i.value.length===0?(t(),o("div",T,[a(w,{size:"large",description:"暂无数据"})])):l("",!0),(t(!0),o(D,null,E(i.value,e=>(t(),G(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:I({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(F)(e.created_on)),1)])]),_:2},1024))),128))]))]),_:1})])}}});const ke=S(Y,[["__scopeId","data-v-d4d04859"]]);export{ke as default};

@ -1 +0,0 @@
import{_ as T}from"./whisper-9b4eeceb.js";import{_ as U,a as q}from"./post-item.vue_vue_type_style_index_0_lang-c2092e3d.js";import{_ as N}from"./post-skeleton-8434d30b.js";import{_ as V}from"./main-nav.vue_vue_type_style_index_0_lang-93352cc4.js";import{u as W}from"./vuex-44de225f.js";import{b as D}from"./vue-router-e5a2430e.js";import{R as E,u as G,f as J,_ as L}from"./index-daff1b26.js";import{d as Y,H as a,b as j,f as t,k as s,w as f,bf as c,Y as y,e as o,F as C,u as x,q as F}from"./@vue-a481fc63.js";import{F as K,G as Q,R as X,J as Z,H as ee}from"./naive-ui-defd0b2d.js";import"./content-64a02a2f.js";import"./@vicons-c265fba6.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 oe={key:0,class:"skeleton-wrap"},te={key:1},se={key:0,class:"empty-wrap"},ne={key:1},ae={key:2},ie={key:0,class:"pagination-wrap"},le=Y({__name:"Collection",setup(re){const i=W(),S=D(),$=K(),l=a(!1),r=a([]),u=a(+S.query.p||1),p=a(20),m=a(0),d=a(!1),g=a({id:0,avatar:"",username:"",nickname:"",is_admin:!1,is_friend:!0,is_following:!1,created_on:0,follows:0,followings:0,status:1}),v=e=>{g.value=e,d.value=!0},b=()=>{d.value=!1},w=e=>{$.success({title:"提示",content:"确定"+(e.user.is_following?"取消关注":"关注")+"该用户吗?",positiveText:"确定",negativeText:"取消",onPositiveClick:()=>{e.user.is_following?G({user_id:e.user.id}).then(_=>{window.$message.success("操作成功"),e.user.is_following=!1}).catch(_=>{}):J({user_id:e.user.id}).then(_=>{window.$message.success("关注成功"),e.user.is_following=!0}).catch(_=>{})}})},h=()=>{l.value=!0,E({page:u.value,page_size:p.value}).then(e=>{l.value=!1,r.value=e.list,m.value=Math.ceil(e.pager.total_rows/p.value),window.scrollTo(0,0)}).catch(e=>{l.value=!1})},R=e=>{u.value=e,h()};return j(()=>{h()}),(e,_)=>{const O=V,P=N,z=Z,A=U,k=ee,B=q,H=T,I=Q,M=X;return o(),t("div",null,[s(O,{title:"收藏"}),s(I,{class:"main-content-wrap",bordered:""},{default:f(()=>[l.value?(o(),t("div",oe,[s(P,{num:p.value},null,8,["num"])])):(o(),t("div",te,[r.value.length===0?(o(),t("div",se,[s(z,{size:"large",description:"暂无数据"})])):y("",!0),c(i).state.desktopModelShow?(o(),t("div",ne,[(o(!0),t(C,null,x(r.value,n=>(o(),F(k,{key:n.id},{default:f(()=>[s(A,{post:n,isOwner:c(i).state.userInfo.id==n.user_id,addFollowAction:!0,onSendWhisper:v,onHandleFollowAction:w},null,8,["post","isOwner"])]),_:2},1024))),128))])):(o(),t("div",ae,[(o(!0),t(C,null,x(r.value,n=>(o(),F(k,{key:n.id},{default:f(()=>[s(B,{post:n,isOwner:c(i).state.userInfo.id==n.user_id,addFollowAction:!0,onSendWhisper:v,onHandleFollowAction:w},null,8,["post","isOwner"])]),_:2},1024))),128))]))])),s(H,{show:d.value,user:g.value,onSuccess:b},null,8,["show","user"])]),_:1}),m.value>0?(o(),t("div",ie,[s(M,{page:u.value,"onUpdate:page":R,"page-slot":c(i).state.collapsedRight?5:8,"page-count":m.value},null,8,["page","page-slot","page-count"])])):y("",!0)])}}});const Ne=L(le,[["__scopeId","data-v-c8f8eee7"]]);export{Ne as default};

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

@ -0,0 +1 @@
import{_ as j}from"./whisper-7277e566.js";import{_ as q,a as D}from"./post-item.vue_vue_type_style_index_0_lang-32efb38a.js";import{_ as R}from"./post-skeleton-63a5a4f0.js";import{_ as U}from"./main-nav.vue_vue_type_style_index_0_lang-65b365f0.js";import{u as E}from"./vuex-44de225f.js";import{b as G}from"./vue-router-e5a2430e.js";import{W as J}from"./v3-infinite-loading-2c58ec2f.js";import{S as L,u as Y,f as K,_ as Q}from"./index-83d7d999.js";import{d as X,H as s,b as Z,f as t,k as n,w as _,q as m,Y as g,e as o,bf as d,F as S,u as F,j as $,x as ee}from"./@vue-a481fc63.js";import{F as oe,G as se,a as te,J as ne,k as ae,H as ie}from"./naive-ui-eecf2ec3.js";import"./content-d0e46162.js";import"./@vicons-f0266f88.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-7c8d4b48.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 le={key:0,class:"skeleton-wrap"},re={key:1},_e={key:0,class:"empty-wrap"},ue={key:1},ce={key:2},pe={class:"load-more-wrap"},me={class:"load-more-spinner"},de=X({__name:"Collection",setup(fe){const f=E(),b=G(),z=oe(),u=s(!1),r=s(!1),a=s([]),l=s(+b.query.p||1),v=s(20),c=s(0),w=s(!1),h=s({id:0,avatar:"",username:"",nickname:"",is_admin:!1,is_friend:!0,is_following:!1,created_on:0,follows:0,followings:0,status:1}),k=e=>{h.value=e,w.value=!0},B=()=>{w.value=!1},y=e=>{z.success({title:"提示",content:"确定"+(e.user.is_following?"取消关注":"关注")+"该用户吗?",positiveText:"确定",negativeText:"取消",onPositiveClick:()=>{e.user.is_following?Y({user_id:e.user.id}).then(p=>{window.$message.success("操作成功"),e.user.is_following=!1}).catch(p=>{}):K({user_id:e.user.id}).then(p=>{window.$message.success("关注成功"),e.user.is_following=!0}).catch(p=>{})}})},x=()=>{u.value=!0,L({page:l.value,page_size:v.value}).then(e=>{u.value=!1,e.list.length===0&&(r.value=!0),l.value>1?a.value=a.value.concat(e.list):(a.value=e.list,window.scrollTo(0,0)),c.value=Math.ceil(e.pager.total_rows/v.value)}).catch(e=>{u.value=!1,l.value>1&&l.value--})},I=()=>{l.value<c.value||c.value==0?(r.value=!1,l.value++,x()):r.value=!0};return Z(()=>{x()}),(e,p)=>{const M=U,O=R,P=ne,A=q,C=ie,H=D,N=j,T=se,V=ae,W=te;return o(),t("div",null,[n(M,{title:"收藏"}),n(T,{class:"main-content-wrap",bordered:""},{default:_(()=>[u.value&&a.value.length===0?(o(),t("div",le,[n(O,{num:v.value},null,8,["num"])])):(o(),t("div",re,[a.value.length===0?(o(),t("div",_e,[n(P,{size:"large",description:"暂无数据"})])):g("",!0),d(f).state.desktopModelShow?(o(),t("div",ue,[(o(!0),t(S,null,F(a.value,i=>(o(),m(C,{key:i.id},{default:_(()=>[n(A,{post:i,isOwner:d(f).state.userInfo.id==i.user_id,addFollowAction:!0,onSendWhisper:k,onHandleFollowAction:y},null,8,["post","isOwner"])]),_:2},1024))),128))])):(o(),t("div",ce,[(o(!0),t(S,null,F(a.value,i=>(o(),m(C,{key:i.id},{default:_(()=>[n(H,{post:i,isOwner:d(f).state.userInfo.id==i.user_id,addFollowAction:!0,onSendWhisper:k,onHandleFollowAction:y},null,8,["post","isOwner"])]),_:2},1024))),128))]))])),n(N,{show:w.value,user:h.value,onSuccess:B},null,8,["show","user"])]),_:1}),c.value>0?(o(),m(W,{key:0,justify:"center"},{default:_(()=>[n(d(J),{class:"load-more",slots:{complete:"没有更多收藏了",error:"加载出错"},onInfinite:I},{spinner:_(()=>[$("div",pe,[r.value?g("",!0):(o(),m(V,{key:0,size:14})),$("span",me,ee(r.value?"没有更多收藏了":"加载更多"),1)])]),_:1})]),_:1})):g("",!0)])}}});const Le=Q(de,[["__scopeId","data-v-02747f0a"]]);export{Le as default};

@ -0,0 +1 @@
.load-more[data-v-02747f0a]{margin:20px}.load-more .load-more-wrap[data-v-02747f0a]{display:flex;flex-direction:row;justify-content:center;align-items:center;gap:14px}.load-more .load-more-wrap .load-more-spinner[data-v-02747f0a]{font-size:14px;opacity:.65}.dark .main-content-wrap[data-v-02747f0a],.dark .empty-wrap[data-v-02747f0a],.dark .skeleton-wrap[data-v-02747f0a]{background-color:#101014bf}

@ -0,0 +1 @@
import{_ as T}from"./whisper-7277e566.js";import{d as N,c as A,r as R,e as c,f as p,k as t,w as n,j as _,y as E,A as G,x as d,bf as h,h as x,H as l,b as J,q as $,Y as C,F as S,u as K}from"./@vue-a481fc63.js";import{K as L,_ as P,W as U}from"./index-83d7d999.js";import{k as Y,r as Q}from"./@vicons-f0266f88.js";import{j as M,o as X,e as Z,P as ee,O as te,G as ne,a as oe,J as se,k as ae,H as ce}from"./naive-ui-eecf2ec3.js";import{_ as _e}from"./post-skeleton-63a5a4f0.js";import{_ as ie}from"./main-nav.vue_vue_type_style_index_0_lang-65b365f0.js";import{W as le}from"./v3-infinite-loading-2c58ec2f.js";import{b as re}from"./vue-router-e5a2430e.js";import"./vuex-44de225f.js";import"./axios-4a70c6fc.js";import"./moment-2ab8298d.js";/* empty css */import"./seemly-76b7b838.js";import"./vueuc-7c8d4b48.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 ue={class:"contact-item"},pe={class:"nickname-wrap"},me={class:"username-wrap"},de={class:"user-info"},fe={class:"info-item"},ve={class:"info-item"},he={class:"item-header-extra"},ge=N({__name:"contact-item",props:{contact:{}},emits:["send-whisper"],setup(b,{emit:g}){const o=b,r=e=>()=>x(M,null,{default:()=>x(e)}),s=A(()=>[{label:"私信",key:"whisper",icon:r(Q)}]),i=e=>{switch(e){case"whisper":const a={id:o.contact.user_id,avatar:o.contact.avatar,username:o.contact.username,nickname:o.contact.nickname,is_admin:!1,is_friend:!0,is_following:!1,created_on:0,follows:0,followings:0,status:1};g("send-whisper",a);break}};return(e,a)=>{const m=X,f=R("router-link"),w=Z,k=ee,y=te;return c(),p("div",ue,[t(y,{"content-indented":""},{avatar:n(()=>[t(m,{size:54,src:e.contact.avatar},null,8,["src"])]),header:n(()=>[_("span",pe,[t(f,{onClick:a[0]||(a[0]=E(()=>{},["stop"])),class:"username-link",to:{name:"user",query:{s:e.contact.username}}},{default:n(()=>[G(d(e.contact.nickname),1)]),_:1},8,["to"])]),_("span",me," @"+d(e.contact.username),1),_("div",de,[_("span",fe," UID. "+d(e.contact.user_id),1),_("span",ve,d(h(L)(e.contact.created_on))+" 加入 ",1)])]),"header-extra":n(()=>[_("div",he,[t(k,{placement:"bottom-end",trigger:"click",size:"small",options:s.value,onSelect:i},{default:n(()=>[t(w,{quaternary:"",circle:""},{icon:n(()=>[t(h(M),null,{default:n(()=>[t(h(Y))]),_:1})]),_:1})]),_:1},8,["options"])])]),_:1})])}}});const we=P(ge,[["__scopeId","data-v-d62f19da"]]),ke={key:0,class:"skeleton-wrap"},ye={key:1},$e={key:0,class:"empty-wrap"},Ce={class:"load-more-wrap"},be={class:"load-more-spinner"},ze=N({__name:"Contacts",setup(b){const g=re(),o=l(!1),r=l(!1),s=l([]),i=l(+g.query.p||1),e=l(20),a=l(0),m=l(!1),f=l({id:0,avatar:"",username:"",nickname:"",is_admin:!1,is_friend:!0,is_following:!1,created_on:0,follows:0,followings:0,status:1}),w=v=>{f.value=v,m.value=!0},k=()=>{m.value=!1},y=()=>{i.value<a.value||a.value==0?(r.value=!1,i.value++,z()):r.value=!0};J(()=>{z()});const z=(v=!1)=>{s.value.length===0&&(o.value=!0),U({page:i.value,page_size:e.value}).then(u=>{o.value=!1,u.list.length===0&&(r.value=!0),i.value>1?s.value=s.value.concat(u.list):(s.value=u.list,v&&setTimeout(()=>{window.scrollTo(0,99999)},50)),a.value=Math.ceil(u.pager.total_rows/e.value)}).catch(u=>{o.value=!1,i.value>1&&i.value--})};return(v,u)=>{const q=ie,B=_e,V=se,W=we,j=ce,D=T,F=ne,H=ae,O=oe;return c(),p(S,null,[_("div",null,[t(q,{title:"好友"}),t(F,{class:"main-content-wrap",bordered:""},{default:n(()=>[o.value&&s.value.length===0?(c(),p("div",ke,[t(B,{num:e.value},null,8,["num"])])):(c(),p("div",ye,[s.value.length===0?(c(),p("div",$e,[t(V,{size:"large",description:"暂无数据"})])):C("",!0),(c(!0),p(S,null,K(s.value,I=>(c(),$(j,{class:"list-item",key:I.user_id},{default:n(()=>[t(W,{contact:I,onSendWhisper:w},null,8,["contact"])]),_:2},1024))),128))])),t(D,{show:m.value,user:f.value,onSuccess:k},null,8,["show","user"])]),_:1})]),a.value>0?(c(),$(O,{key:0,justify:"center"},{default:n(()=>[t(h(le),{class:"load-more",slots:{complete:"没有更多好友了",error:"加载出错"},onInfinite:y},{spinner:n(()=>[_("div",Ce,[r.value?C("",!0):(c(),$(H,{key:0,size:14})),_("span",be,d(r.value?"没有更多好友了":"加载更多"),1)])]),_:1})]),_:1})):C("",!0)],64)}}});const Xe=P(ze,[["__scopeId","data-v-69277f0c"]]);export{Xe as default};

@ -1 +0,0 @@
import{_ as O}from"./whisper-9b4eeceb.js";import{d as N,c as T,r as j,e as s,f as c,k as t,w as n,j as _,y as A,A as J,x as v,bf as g,h as S,H as a,b as U,Y as z,F as I,u as W,q as E}from"./@vue-a481fc63.js";import{J as G,_ as P,b as L}from"./index-daff1b26.js";import{k as Y,r as K}from"./@vicons-c265fba6.js";import{j as x,o as Q,e as X,P as Z,O as ee,G as te,R as ne,J as oe,H as se}from"./naive-ui-defd0b2d.js";import{_ as ae}from"./post-skeleton-8434d30b.js";import{_ as ce}from"./main-nav.vue_vue_type_style_index_0_lang-93352cc4.js";import{u as _e}from"./vuex-44de225f.js";import{b as ie}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=N({__name:"contact-item",props:{contact:{}},emits:["send-whisper"],setup(C,{emit:h}){const i=C,r=e=>()=>S(x,null,{default:()=>S(e)}),l=T(()=>[{label:"私信",key:"whisper",icon:r(K)}]),u=e=>{switch(e){case"whisper":const o={id:i.contact.user_id,avatar:i.contact.avatar,username:i.contact.username,nickname:i.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=Q,d=j("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(()=>[_("span",le,[t(d,{onClick:o[0]||(o[0]=A(()=>{},["stop"])),class:"username-link",to:{name:"user",query:{s:e.contact.username}}},{default:n(()=>[J(v(e.contact.nickname),1)]),_:1},8,["to"])]),_("span",pe," @"+v(e.contact.username),1),_("div",ue,[_("span",me," UID. "+v(e.contact.user_id),1),_("span",de,v(g(G)(e.contact.created_on))+" 加入 ",1)])]),"header-extra":n(()=>[_("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=P(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=N({__name:"Contacts",setup(C){const h=_e(),i=ie(),r=a(!1),l=a([]),u=a(+i.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),L({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,R=ge,V=se,D=O,F=te,H=ne;return s(),c(I,null,[_("div",null,[t(q,{title:"好友"}),t(F,{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:"暂无数据"})])):z("",!0),(s(!0),c(I,null,W(l.value,b=>(s(),E(V,{class:"list-item",key:b.user_id},{default:n(()=>[t(R,{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(H,{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"])])):z("",!0)],64)}}});const Le=P(Ce,[["__scopeId","data-v-e20fef94"]]);export{Le as default};

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

File diff suppressed because one or more lines are too long

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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

@ -0,0 +1 @@
.message-item[data-v-2507cd8e]{padding:16px}.message-item.unread[data-v-2507cd8e]{background:#fcfffc}.message-item .sender-wrap[data-v-2507cd8e]{display:flex;align-items:center}.message-item .sender-wrap .top-tag[data-v-2507cd8e]{transform:scale(.75)}.message-item .sender-wrap .username[data-v-2507cd8e]{opacity:.75;font-size:14px}.message-item .timestamp[data-v-2507cd8e]{opacity:.75;font-size:12px;display:flex;align-items:center}.message-item .timestamp .timestamp-txt[data-v-2507cd8e]{margin-left:6px}.message-item .brief-wrap[data-v-2507cd8e]{margin-top:10px}.message-item .brief-wrap .brief-content[data-v-2507cd8e],.message-item .brief-wrap .whisper-content-wrap[data-v-2507cd8e],.message-item .brief-wrap .requesting-friend-wrap[data-v-2507cd8e]{display:flex;width:100%}.message-item .view-link[data-v-2507cd8e]{margin-left:8px;display:flex;align-items:center}.message-item .status-info[data-v-2507cd8e]{margin-left:8px;align-items:center}.dark .message-item[data-v-2507cd8e]{background-color:#101014bf}.dark .message-item.unread[data-v-2507cd8e]{background:#0f180b}.dark .message-item .brief-wrap[data-v-2507cd8e]{background-color:#18181c}.skeleton-item[data-v-01d2e871]{padding:12px;display:flex}.skeleton-item .content[data-v-01d2e871]{width:100%}.dark .skeleton-item[data-v-01d2e871]{background-color:#101014bf}.load-more[data-v-7b84a068]{margin:20px}.load-more .load-more-wrap[data-v-7b84a068]{display:flex;flex-direction:row;justify-content:center;align-items:center;gap:14px}.load-more .load-more-wrap .load-more-spinner[data-v-7b84a068]{font-size:14px;opacity:.65}.title[data-v-7b84a068]{padding-top:4px;opacity:.9}.title-action[data-v-7b84a068]{display:flex;align-items:center;margin-left:20px}.title-filter[data-v-7b84a068]{margin-right:20px}.dark .empty-wrap[data-v-7b84a068],.dark .messages-wrap[data-v-7b84a068],.dark .pagination-wrap[data-v-7b84a068]{background-color:#101014bf}

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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

@ -1 +0,0 @@
import{E as $,F as M,G as O,H as z,_ as D}from"./index-daff1b26.js";import{D as G}from"./@vicons-c265fba6.js";import{d as F,H as i,c as q,b as A,r as H,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 U,al as j,F as x,u as P}from"./@vue-a481fc63.js";import{o as Y,M as C,j as J,e as K,P as Q,O as R,G as W,f as X,g as Z,a as ee,k as oe}from"./naive-ui-defd0b2d.js";import{_ as te}from"./main-nav.vue_vue_type_style_index_0_lang-93352cc4.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=q(()=>{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 A(()=>{r.value=!1}),(e,o)=>{const w=H("router-link"),g=Y,k=C,a=J,d=K,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(G))]),_: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);U(e,()=>{e.value||(window.$message.success("保存成功"),t.commit("refreshTopicFollow"))});const w=q({get:()=>{let a="编辑";return e.value&&(a="保存"),a},set:a=>{}}),g=()=>{l.value=!0,z({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 A(()=>{g()}),(a,d)=>{const v=te,p=X,V=C,E=Z,L=ie,N=ee,S=oe,I=W;return c(),_("div",null,[n(v,{title:"话题"}),n(I,{class:"main-content-wrap tags-wrap",bordered:""},{default:s(()=>[n(E,{type:"line",animated:"","onUpdate:value":k},j({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(V,{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(S,{show:l.value},{default:s(()=>[n(N,null,{default:s(()=>[(c(!0),_(x,null,P(r.value,y=>(c(),b(L,{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=D(_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

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{aa as A}from"./index-83d7d999.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{a3 as C,a4 as N,a5 as P,a6 as D}from"./@vicons-f0266f88.js";import{u as R,a3 as x,a4 as H,j as I,e as V,a5 as $,h as j}from"./naive-ui-eecf2ec3.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 G}from"./@vue-a481fc63.js";const J={key:0},K={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=x,M=H,r=I,p=V,O=$,S=j;return n(),f(G,null,[a(o).state.drawerModelShow?(n(),f("div",J,[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",K,[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 _};

@ -1 +0,0 @@
import{a8 as A}from"./index-daff1b26.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{$ as C,a0 as N,a1 as P,a2 as D}from"./@vicons-c265fba6.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-defd0b2d.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 G}from"./@vue-a481fc63.js";const J={key:0},K={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(G,null,[a(o).state.drawerModelShow?(n(),f("div",J,[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",K,[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

@ -1 +1 @@
import{U as r}from"./naive-ui-defd0b2d.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-daff1b26.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-eecf2ec3.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-83d7d999.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 _};

File diff suppressed because one or more lines are too long

@ -1 +1 @@
import{X as b,_ as k}from"./index-daff1b26.js";import{d as B,H as p,e as C,q as N,w as s,j as a,k as n,A as _,x as i}from"./@vue-a481fc63.js";import{S as U,I as V,T as z,b as I,e as R,i as S}from"./naive-ui-defd0b2d.js";const T={class:"whisper-wrap"},W={class:"whisper-line"},$={class:"whisper-line send-wrap"},j=B({__name:"whisper",props:{show:{type:Boolean,default:!1},user:{}},emits:["success"],setup(r,{emit:u}){const d=r,o=p(""),t=p(!1),c=()=>{u("success")},m=()=>{t.value=!0,b({user_id:d.user.id,content:o.value}).then(e=>{window.$message.success("发送成功"),t.value=!1,o.value="",c()}).catch(e=>{t.value=!1})};return(e,l)=>{const h=U,w=V,f=z,v=I,g=R,y=S;return C(),N(y,{show:e.show,"onUpdate:show":c,class:"whisper-card",preset:"card",size:"small",title:"私信","mask-closable":!1,bordered:!1,style:{width:"360px"}},{default:s(()=>[a("div",T,[n(f,{"show-icon":!1},{default:s(()=>[_(" 即将发送私信给: "),n(w,{style:{"max-width":"100%"}},{default:s(()=>[n(h,{type:"success"},{default:s(()=>[_(i(e.user.nickname)+"@"+i(e.user.username),1)]),_:1})]),_:1})]),_:1}),a("div",W,[n(v,{type:"textarea",placeholder:"请输入私信内容(请勿发送不和谐内容,否则将会被封号)",autosize:{minRows:5,maxRows:10},value:o.value,"onUpdate:value":l[0]||(l[0]=x=>o.value=x),maxlength:"200","show-count":""},null,8,["value"])]),a("div",$,[n(g,{strong:"",secondary:"",type:"primary",loading:t.value,onClick:m},{default:s(()=>[_(" 发送 ")]),_:1},8,["loading"])])])]),_:1},8,["show"])}}});const H=k(j,[["__scopeId","data-v-0cbfe47c"]]);export{H as _};
import{Z as b,_ as k}from"./index-83d7d999.js";import{d as B,H as p,e as C,q as N,w as s,j as a,k as n,A as _,x as i}from"./@vue-a481fc63.js";import{S as U,I as V,T as z,b as I,e as R,i as S}from"./naive-ui-eecf2ec3.js";const T={class:"whisper-wrap"},W={class:"whisper-line"},$={class:"whisper-line send-wrap"},j=B({__name:"whisper",props:{show:{type:Boolean,default:!1},user:{}},emits:["success"],setup(r,{emit:u}){const d=r,o=p(""),t=p(!1),c=()=>{u("success")},m=()=>{t.value=!0,b({user_id:d.user.id,content:o.value}).then(e=>{window.$message.success("发送成功"),t.value=!1,o.value="",c()}).catch(e=>{t.value=!1})};return(e,l)=>{const h=U,w=V,f=z,v=I,g=R,y=S;return C(),N(y,{show:e.show,"onUpdate:show":c,class:"whisper-card",preset:"card",size:"small",title:"私信","mask-closable":!1,bordered:!1,style:{width:"360px"}},{default:s(()=>[a("div",T,[n(f,{"show-icon":!1},{default:s(()=>[_(" 即将发送私信给: "),n(w,{style:{"max-width":"100%"}},{default:s(()=>[n(h,{type:"success"},{default:s(()=>[_(i(e.user.nickname)+"@"+i(e.user.username),1)]),_:1})]),_:1})]),_:1}),a("div",W,[n(v,{type:"textarea",placeholder:"请输入私信内容(请勿发送不和谐内容,否则将会被封号)",autosize:{minRows:5,maxRows:10},value:o.value,"onUpdate:value":l[0]||(l[0]=x=>o.value=x),maxlength:"200","show-count":""},null,8,["value"])]),a("div",$,[n(g,{strong:"",secondary:"",type:"primary",loading:t.value,onClick:m},{default:s(()=>[_(" 发送 ")]),_:1},8,["loading"])])])]),_:1},8,["show"])}}});const H=k(j,[["__scopeId","data-v-0cbfe47c"]]);export{H as _};

@ -1 +1 @@
import{M as b,_ as k}from"./index-daff1b26.js";import{S as B,I as A,T as C,b as F,e as N,i as V}from"./naive-ui-defd0b2d.js";import{d as W,H as i,e as q,q as z,w as s,j as a,k as n,A as _,x as r}from"./@vue-a481fc63.js";const I={class:"whisper-wrap"},M={class:"whisper-line"},R={class:"whisper-line send-wrap"},S=W({__name:"whisper-add-friend",props:{show:{type:Boolean,default:!1},user:{}},emits:["success"],setup(p,{emit:d}){const u=p,o=i(""),t=i(!1),l=()=>{d("success")},m=()=>{t.value=!0,b({user_id:u.user.id,greetings:o.value}).then(e=>{window.$message.success("发送成功"),t.value=!1,o.value="",l()}).catch(e=>{t.value=!1})};return(e,c)=>{const h=B,w=A,f=C,g=F,v=N,y=V;return q(),z(y,{show:e.show,"onUpdate:show":l,class:"whisper-card",preset:"card",size:"small",title:"申请添加朋友","mask-closable":!1,bordered:!1,style:{width:"360px"}},{default:s(()=>[a("div",I,[n(f,{"show-icon":!1},{default:s(()=>[_(" 发送添加朋友申请给: "),n(w,{style:{"max-width":"100%"}},{default:s(()=>[n(h,{type:"success"},{default:s(()=>[_(r(e.user.nickname)+"@"+r(e.user.username),1)]),_:1})]),_:1})]),_:1}),a("div",M,[n(g,{type:"textarea",placeholder:"请输入真挚的问候语",autosize:{minRows:5,maxRows:10},value:o.value,"onUpdate:value":c[0]||(c[0]=x=>o.value=x),maxlength:"120","show-count":""},null,8,["value"])]),a("div",R,[n(v,{strong:"",secondary:"",type:"primary",loading:t.value,onClick:m},{default:s(()=>[_(" 发送 ")]),_:1},8,["loading"])])])]),_:1},8,["show"])}}});const D=k(S,[["__scopeId","data-v-60be56a2"]]);export{D as W};
import{N as b,_ as k}from"./index-83d7d999.js";import{S as B,I as N,T as A,b as C,e as F,i as V}from"./naive-ui-eecf2ec3.js";import{d as W,H as i,e as q,q as z,w as s,j as a,k as n,A as _,x as r}from"./@vue-a481fc63.js";const I={class:"whisper-wrap"},R={class:"whisper-line"},S={class:"whisper-line send-wrap"},T=W({__name:"whisper-add-friend",props:{show:{type:Boolean,default:!1},user:{}},emits:["success"],setup(p,{emit:d}){const u=p,o=i(""),t=i(!1),l=()=>{d("success")},m=()=>{t.value=!0,b({user_id:u.user.id,greetings:o.value}).then(e=>{window.$message.success("发送成功"),t.value=!1,o.value="",l()}).catch(e=>{t.value=!1})};return(e,c)=>{const h=B,w=N,f=A,g=C,v=F,y=V;return q(),z(y,{show:e.show,"onUpdate:show":l,class:"whisper-card",preset:"card",size:"small",title:"申请添加朋友","mask-closable":!1,bordered:!1,style:{width:"360px"}},{default:s(()=>[a("div",I,[n(f,{"show-icon":!1},{default:s(()=>[_(" 发送添加朋友申请给: "),n(w,{style:{"max-width":"100%"}},{default:s(()=>[n(h,{type:"success"},{default:s(()=>[_(r(e.user.nickname)+"@"+r(e.user.username),1)]),_:1})]),_:1})]),_:1}),a("div",R,[n(g,{type:"textarea",placeholder:"请输入真挚的问候语",autosize:{minRows:5,maxRows:10},value:o.value,"onUpdate:value":c[0]||(c[0]=x=>o.value=x),maxlength:"120","show-count":""},null,8,["value"])]),a("div",S,[n(v,{strong:"",secondary:"",type:"primary",loading:t.value,onClick:m},{default:s(()=>[_(" 发送 ")]),_:1},8,["loading"])])])]),_:1},8,["show"])}}});const H=k(T,[["__scopeId","data-v-60be56a2"]]);export{H as W};

@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0" />
<link rel="manifest" href="/manifest.json" />
<title></title>
<script type="module" crossorigin src="/assets/index-daff1b26.js"></script>
<script type="module" crossorigin src="/assets/index-83d7d999.js"></script>
<link rel="modulepreload" crossorigin href="/assets/@vue-a481fc63.js">
<link rel="modulepreload" crossorigin href="/assets/vue-router-e5a2430e.js">
<link rel="modulepreload" crossorigin href="/assets/vuex-44de225f.js">
@ -21,14 +21,14 @@
<link rel="modulepreload" crossorigin href="/assets/@juggle-41516555.js">
<link rel="modulepreload" crossorigin href="/assets/@emotion-8a8e73f6.js">
<link rel="modulepreload" crossorigin href="/assets/css-render-6a5c5852.js">
<link rel="modulepreload" crossorigin href="/assets/vueuc-39372edb.js">
<link rel="modulepreload" crossorigin href="/assets/vueuc-7c8d4b48.js">
<link rel="modulepreload" crossorigin href="/assets/lodash-es-8412e618.js">
<link rel="modulepreload" crossorigin href="/assets/treemate-25c27bff.js">
<link rel="modulepreload" crossorigin href="/assets/async-validator-dee29e8b.js">
<link rel="modulepreload" crossorigin href="/assets/date-fns-975a2d8f.js">
<link rel="modulepreload" crossorigin href="/assets/naive-ui-defd0b2d.js">
<link rel="modulepreload" crossorigin href="/assets/naive-ui-eecf2ec3.js">
<link rel="modulepreload" crossorigin href="/assets/moment-2ab8298d.js">
<link rel="modulepreload" crossorigin href="/assets/@vicons-c265fba6.js">
<link rel="modulepreload" crossorigin href="/assets/@vicons-f0266f88.js">
<link rel="stylesheet" href="/assets/index-c337d1db.css">
<link rel="stylesheet" href="/assets/vfonts-7afd136d.css">
</head>

@ -99,6 +99,17 @@ export const getContacts = (
});
};
/** 获取联系人列表 */
export const getIndexTrends = (
params: NetParams.IndexTrendsReq
): Promise<NetReq.IndexTrendsResp> => {
return request({
method: "get",
url: "/v1/trends/index",
params,
});
};
/** 发布动态 */
export const createPost = (
data: NetParams.PostCreatePost

@ -22,7 +22,7 @@
}">
{{ message.sender_user.nickname }}
</router-link>
<span class="username">
<span v-if="store.state.desktopModelShow" class="username">
@{{ message.sender_user.username }}
</span>
</span>
@ -35,29 +35,11 @@
}">
{{ message.receiver_user.nickname }}
</router-link>
<span class="username">
<span v-if="store.state.desktopModelShow" class="username">
@{{ message.receiver_user.username }}
</span>
</span>
<span class="nickname" v-else> </span>
<n-tag
v-if="message.type == 4"
class="top-tag"
type="success"
size="small"
round
>
</n-tag>
<!-- <n-tag
v-if="message.type != 4"
class="top-tag"
type="info"
size="small"
round
>
</n-tag> -->
<n-tag
v-if="isWhisperSender"
class="top-tag"
@ -65,7 +47,7 @@
size="small"
round
>
<template #icon>
<n-icon :component="CheckmarkCircle" />
</template>
@ -77,7 +59,7 @@
size="small"
round
>
<template #icon>
<n-icon :component="CheckmarkCircle" />
</template>

@ -303,7 +303,7 @@ const whisperSuccess = () => {
};
const emit = defineEmits<{
(e: 'reload'): void;
(e: 'reload', post_id: number): void;
}>();
const post = computed({
@ -606,7 +606,7 @@ const execLockAction = () => {
id: post.value.id,
})
.then((res) => {
emit('reload');
emit('reload', post.value.id);
if (res.lock_status === 1) {
window.$message.success('');
} else {
@ -622,7 +622,7 @@ const execStickAction = () => {
id: post.value.id,
})
.then((res) => {
emit('reload');
emit('reload', post.value.id);
if (res.top_status === 1) {
window.$message.success('');
} else {
@ -658,7 +658,7 @@ const execVisibilityAction = () => {
visibility: tempVisibility.value
})
.then((_res) => {
emit('reload');
emit('reload', post.value.id);
window.$message.success('');
})
.catch((_err) => {

@ -23,7 +23,7 @@
<span v-if="!showAction" class="tag-quote">({{ tag.quote_num }})</span>
<span v-if="showAction" class="tag-quote tag-follow">({{ tag.quote_num }})</span>
<template #avatar>
<n-avatar :src="tag.user.avatar" />
<n-avatar :src="tagUserAvatar" />
</template>
</n-tag>
</template>
@ -57,6 +57,7 @@ import { ref, onMounted, computed } from 'vue';
import { MoreVertOutlined } from '@vicons/material';
import type { DropdownOption } from 'naive-ui';
import { stickTopic, followTopic, unfollowTopic } from '@/api/post';
import defaultUserAvatar from '@/assets/img/logo.png';
const hasFollowing= ref(false);
const props = withDefaults(
@ -68,6 +69,15 @@ const props = withDefaults(
{}
);
const tagUserAvatar = computed(() => {
if (props.tag.user) {
return props.tag.user.avatar
} else {
return defaultUserAvatar
}
})
const tagOptions = computed(() => {
let options: DropdownOption[] = [];
if (props.tag.is_following === 0) {

@ -142,6 +142,13 @@ declare module Item {
created_on: number;
}
interface IndexTrendsItem {
nickname: string;
username: string;
avatar: string;
is_fresh: boolean;
}
/** slide bar item */
interface SlideBarItem {
title: string;

@ -38,6 +38,7 @@ declare module NetParams {
interface UserGetUnreadMsgCount {}
interface UserGetMessages {
style: "all" | "system" | "whisper" | "requesting" | "unread";
page: number;
page_size: number;
}
@ -121,6 +122,11 @@ declare module NetParams {
page_size: number;
}
interface IndexTrendsReq {
page: number;
page_size: number;
}
interface GetUserFollows {
username: string;
page: number;

@ -189,6 +189,11 @@ declare module NetReq {
pager: Item.PagerProps;
}
interface IndexTrendsResp {
list: Item.IndexTrendsItem[];
pager: Item.PagerProps;
}
interface PostStickTopic {
/** 置顶状态0为未置顶1为置顶 */
top_status: 0 | 1;

@ -3,7 +3,7 @@
<main-nav title="收藏" />
<n-list class="main-content-wrap" bordered>
<div v-if="loading" class="skeleton-wrap">
<div v-if="loading && list.length === 0" class="skeleton-wrap">
<post-skeleton :num="pageSize" />
</div>
<div v-else>
@ -33,14 +33,16 @@
<!-- -->
<whisper :show="showWhisper" :user="whisperReceiver" @success="whisperSuccess" />
</n-list>
<div class="pagination-wrap" v-if="totalPage > 0">
<n-pagination
:page="page"
@update:page="updatePage"
:page-slot="!store.state.collapsedRight ? 8 : 5"
:page-count="totalPage" />
</div>
<n-space v-if="totalPage > 0" justify="center">
<InfiniteLoading class="load-more" :slots="{ complete: '没有更多收藏了', error: '加载出错' }" @infinite="nextPage">
<template #spinner>
<div class="load-more-wrap">
<n-spin :size="14" v-if="!noMore" />
<span class="load-more-spinner">{{ noMore ? '' : '' }}</span>
</div>
</template>
</InfiniteLoading>
</n-space>
</div>
</template>
@ -49,6 +51,7 @@ import { ref, onMounted } from 'vue';
import { useStore } from 'vuex';
import { useRoute } from 'vue-router';
import { useDialog } from 'naive-ui';
import InfiniteLoading from "v3-infinite-loading";
import { getCollections, followUser, unfollowUser } from '@/api/user';
const store = useStore();
@ -56,6 +59,7 @@ const route = useRoute();
const dialog = useDialog();
const loading = ref(false);
const noMore = ref(false);
const list = ref<any[]>([]);
const page = ref(+(route.query.p as any) || 1);
const pageSize = ref(20);
@ -118,21 +122,34 @@ const loadPosts = () => {
getCollections({
page: page.value,
page_size: pageSize.value,
})
.then((rsp) => {
loading.value = false;
list.value = rsp.list;
totalPage.value = Math.ceil(rsp.pager.total_rows / pageSize.value);
}).then((res) => {
loading.value = false;
if (res.list.length === 0) {
noMore.value = true
}
if (page.value > 1) {
list.value = list.value.concat(res.list);
} else {
list.value = res.list;
window.scrollTo(0, 0);
})
.catch((err) => {
loading.value = false;
});
}
totalPage.value = Math.ceil(res.pager.total_rows / pageSize.value);
})
.catch((_err) => {
loading.value = false;
if (page.value > 1) {
page.value--
}
});
};
const updatePage = (p: number) => {
page.value = p;
loadPosts();
const nextPage = () => {
if (page.value < totalPage.value || totalPage.value == 0) {
noMore.value = false;
page.value++;
loadPosts();
} else {
noMore.value = true;
}
};
onMounted(() => {
loadPosts();
@ -140,11 +157,21 @@ onMounted(() => {
</script>
<style lang="less" scoped>
.pagination-wrap {
padding: 10px;
display: flex;
justify-content: center;
overflow: hidden;
.load-more {
margin: 20px;
.load-more-wrap {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
gap: 14px;
.load-more-spinner {
font-size: 14px;
opacity: 0.65;
}
}
}
.dark {
.main-content-wrap, .empty-wrap, .skeleton-wrap {

@ -3,7 +3,7 @@
<main-nav title="好友" />
<n-list class="main-content-wrap" bordered>
<div v-if="loading" class="skeleton-wrap">
<div v-if="loading && list.length === 0" class="skeleton-wrap">
<post-skeleton :num="pageSize" />
</div>
<div v-else>
@ -19,26 +19,27 @@
<whisper :show="showWhisper" :user="whisperReceiver" @success="whisperSuccess" />
</n-list>
</div>
<div class="pagination-wrap" v-if="totalPage > 0">
<n-pagination
:page="page"
@update:page="updatePage"
:page-slot="!store.state.collapsedRight ? 8 : 5"
:page-count="totalPage" />
</div>
<n-space v-if="totalPage > 0" justify="center">
<InfiniteLoading class="load-more" :slots="{ complete: '没有更多好友了', error: '加载出错' }" @infinite="nextPage">
<template #spinner>
<div class="load-more-wrap">
<n-spin :size="14" v-if="!noMore" />
<span class="load-more-spinner">{{ noMore ? '' : '' }}</span>
</div>
</template>
</InfiniteLoading>
</n-space>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { getContacts } from '@/api/post';
import { useStore } from 'vuex';
import InfiniteLoading from "v3-infinite-loading";
import { useRoute } from 'vue-router';
const store = useStore();
const route = useRoute();
const loading = ref(false);
const noMore = ref(false);
const list = ref<Item.ContactItemProps[]>([]);
const page = ref(+(route.query.p as string) || 1);
const pageSize = ref(20);
@ -67,9 +68,14 @@ const whisperSuccess = () => {
showWhisper.value = false;
};
const updatePage = (p: number) => {
page.value = p;
loadContacts();
const nextPage = () => {
if (page.value < totalPage.value || totalPage.value == 0) {
noMore.value = false;
page.value++;
loadContacts();
} else {
noMore.value = true;
}
};
onMounted(() => {
@ -83,30 +89,48 @@ const loadContacts = (scrollToBottom: boolean = false) => {
getContacts({
page: page.value,
page_size: pageSize.value,
})
.then((res) => {
loading.value = false;
}).then((res) => {
loading.value = false;
if (res.list.length === 0) {
noMore.value = true
}
if (page.value > 1) {
list.value = list.value.concat(res.list);
} else {
list.value = res.list;
totalPage.value = Math.ceil(res.pager.total_rows / pageSize.value);
if (scrollToBottom) {
setTimeout(() => {
window.scrollTo(0, 99999);
}, 50);
}
})
.catch((err) => {
loading.value = false;
});
};
}
totalPage.value = Math.ceil(res.pager.total_rows / pageSize.value);
})
.catch((_err) => {
loading.value = false;
if (page.value > 1) {
page.value--;
}
});
}
</script>
<style lang="less" scoped>
.pagination-wrap {
padding: 10px;
display: flex;
justify-content: center;
overflow: hidden;
.load-more {
margin: 20px;
.load-more-wrap {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
gap: 14px;
.load-more-spinner {
font-size: 14px;
opacity: 0.65;
}
}
}
.dark {
.main-content-wrap, .empty-wrap, .skeleton-wrap {

@ -7,7 +7,7 @@
<n-tab-pane name="follows" tab="正在关注" />
<n-tab-pane name="followings" tab="我的粉丝" />
</n-tabs>
<div v-if="loading" class="skeleton-wrap">
<div v-if="loading && list.length === 0" class="skeleton-wrap">
<post-skeleton :num="pageSize" />
</div>
<div v-else>
@ -23,26 +23,27 @@
<whisper :show="showWhisper" :user="whisperReceiver" @success="whisperSuccess" />
</n-list>
</div>
<div class="pagination-wrap" v-if="totalPage > 0">
<n-pagination
:page="page"
@update:page="updatePage"
:page-slot="!store.state.collapsedRight ? 8 : 5"
:page-count="totalPage" />
</div>
<n-space v-if="totalPage > 0" justify="center">
<InfiniteLoading class="load-more" :slots="{ complete: completeStr, error: '加载出错' }" @infinite="nextPage">
<template #spinner>
<div class="load-more-wrap">
<n-spin :size="14" v-if="!noMore" />
<span class="load-more-spinner">{{ noMore ? completeStr : '' }}</span>
</div>
</template>
</InfiniteLoading>
</n-space>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { ref, onMounted, computed } from 'vue';
import { getUserFollows, getUserFollowings } from '@/api/user';
import { useStore } from 'vuex';
import InfiniteLoading from "v3-infinite-loading";
import { useRoute } from 'vue-router';
const store = useStore();
const route = useRoute();
const loading = ref(false);
const noMore = ref(false);
const list = ref<Item.ContactItemProps[]>([]);
const nickname= route.query.n as string || "粉丝详情";
const username = route.query.s as string || "";
@ -65,6 +66,14 @@ const whisperReceiver = ref<Item.UserInfo>({
status: 1,
});
const completeStr = computed(() => {
if (tabler.value == "follows") {
return ''
} else {
return ''
}
});
const onSendWhisper = (user: Item.UserInfo) => {
whisperReceiver.value = user;
showWhisper.value = true;
@ -74,9 +83,14 @@ const whisperSuccess = () => {
showWhisper.value = false;
};
const updatePage = (p: number) => {
page.value = p;
loadPage();
const nextPage = () => {
if (page.value < totalPage.value || totalPage.value == 0) {
noMore.value = false;
page.value++;
loadPage();
} else {
noMore.value = true;
}
};
const changeTab = (tab: "follows" | "followings") => {
@ -100,21 +114,29 @@ const loadFollows = (username: string, scrollToBottom: boolean = false) => {
username: username,
page: page.value,
page_size: pageSize.value,
})
.then((res) => {
loading.value = false;
list.value = res.list || [];
totalPage.value = Math.ceil(res.pager.total_rows / pageSize.value);
}).then((res) => {
loading.value = false;
if (res.list.length === 0) {
noMore.value = true
}
if (page.value > 1) {
list.value = list.value.concat(res.list);
} else {
list.value = res.list;
if (scrollToBottom) {
setTimeout(() => {
window.scrollTo(0, 99999);
}, 50);
}
})
.catch((err) => {
loading.value = false;
});
}
totalPage.value = Math.ceil(res.pager.total_rows / pageSize.value);
})
.catch((_err) => {
loading.value = false;
if (page.value > 1) {
page.value--;
}
});
};
const loadFollowings = (username: string, scrollToBottom: boolean = false) => {
@ -125,21 +147,29 @@ const loadFollowings = (username: string, scrollToBottom: boolean = false) => {
username: username,
page: page.value,
page_size: pageSize.value,
})
.then((res) => {
loading.value = false;
list.value = res.list || [];
totalPage.value = Math.ceil(res.pager.total_rows / pageSize.value);
}).then((res) => {
loading.value = false;
if (res.list.length === 0) {
noMore.value = true
}
if (page.value > 1) {
list.value = list.value.concat(res.list);
} else {
list.value = res.list;
if (scrollToBottom) {
setTimeout(() => {
window.scrollTo(0, 99999);
}, 50);
}
})
.catch((err) => {
loading.value = false;
});
}
totalPage.value = Math.ceil(res.pager.total_rows / pageSize.value);
})
.catch((_err) => {
loading.value = false;
if (page.value > 1) {
page.value--;
}
});
};
onMounted(() => {
@ -153,11 +183,21 @@ onMounted(() => {
padding: 20px;
}
.pagination-wrap {
padding: 10px;
display: flex;
justify-content: center;
overflow: hidden;
.load-more {
margin: 20px;
.load-more-wrap {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
gap: 14px;
.load-more-spinner {
font-size: 14px;
opacity: 0.65;
}
}
}
.dark {

@ -84,7 +84,7 @@ import { useStore } from 'vuex';
import { useRoute, useRouter } from 'vue-router';
import { useDialog } from 'naive-ui';
import InfiniteLoading from "v3-infinite-loading";
import { getPosts, getContacts } from '@/api/post';
import { getPosts, getIndexTrends } from '@/api/post';
import { getUserPosts, deleteFriend, followUser, unfollowUser } from '@/api/user';
import SlideBar from '@opentiny/vue-slide-bar';
import allTweets from '@/assets/img/fresh-tweets.png';
@ -289,7 +289,7 @@ const loadContacts = () => {
if (!useFriendship || !enableFriendsBar || store.state.userInfo.id === 0) {
return
}
getContacts({
getIndexTrends({
page: 1,
page_size: 50,
}).then((res) => {
@ -297,13 +297,13 @@ const loadContacts = () => {
const list = res.list || []
let barItems: Item.SlideBarItem[] = []
for (; i < list.length; i++) {
let item: Item.ContactItemProps = list[i];
let item: Item.IndexTrendsItem = list[i];
barItems.push({
title: item.nickname,
style: 21,
username: item.username,
avatar: item.avatar,
show: false
show: item.is_fresh,
});
}
if (barItems.length > 0) {

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

Loading…
Cancel
Save