Merge branch 'feature/mir-prepare' into feature/mir

pull/196/head
Michael Li 2 years ago
commit 8921655de5
No known key found for this signature in database

@ -68,6 +68,11 @@ windows-x64:
@echo Build paopao-ce [windows-x64] CGO_ENABLED=$(CGO_ENABLED)
@CGO_ENABLED=$(CGO_ENABLED) GOOS=windows GOARCH=amd64 go build -trimpath -tags '$(TAGS)' -ldflags '$(LDFLAGS)' -o $(RELEASE_WINDOWS_AMD64)/$(basename $(TARGET)).exe
.PHONY: generate
generate:
@go generate internal/mirc/main.go
@go fmt ./internal/mirc/...
clean:
@go clean
@find ./release -type f -exec rm -r {} +

@ -1,4 +1,5 @@
App: # APP基础设置项
RunMode: debug
AttachmentIncomeRate: 0.8
MaxCommentCount: 10
DefaultContextTimeout: 60
@ -17,8 +18,19 @@ Features:
Slim: ["Base", "Sqlite3", "LocalOSS", "LoggerFile", "OSS:TempDir"]
Base: ["Redis", "PhoneBind"]
Docs: ["Docs:OpenAPI"]
Deprecated: ["Deprecated:OldWeb"]
Option: ["SimpleCacheIndex"]
Sms: "SmsJuhe"
WebServer: # Web服务
HttpIp: 0.0.0.0
HttpPort: 8010
ReadTimeout: 60
WriteTimeout: 60
DocsServer: # 开发文档服务
HttpIp: 0.0.0.0
HttpPort: 8011
ReadTimeout: 60
WriteTimeout: 60
SmsJuhe:
Gateway: https://v.juhe.cn/sms/send
Key:

@ -1,3 +1,7 @@
// 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.
//go:build docs
// +build docs

@ -5,6 +5,7 @@ go 1.18
require (
github.com/Masterminds/semver/v3 v3.1.1
github.com/afocus/captcha v0.0.0-20191010092841-4bd1f21c8868
github.com/alimy/mir/v3 v3.0.0-alpha.3
github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible
github.com/allegro/bigcache/v3 v3.0.2
github.com/bytedance/sonic v1.5.0

@ -142,6 +142,8 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY9UnI16Z+UJqRyk=
github.com/alimy/mir/v3 v3.0.0-alpha.3 h1:/GyBC0G041NIP3W62im8DtAwxRPSfSaivSQK6MV9fFc=
github.com/alimy/mir/v3 v3.0.0-alpha.3/go.mod h1:ybhT2ijOiDn0lLwWzIY6vXdv+uzZrctS7VFfczcXBWU=
github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible h1:9gWa46nstkJ9miBReJcN8Gq34cBFbzSpQZVVT9N09TM=
github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package conf
import (
@ -20,6 +24,8 @@ var (
PostgresSetting *PostgresSettingS
Sqlite3Setting *Sqlite3SettingS
ServerSetting *ServerSettingS
WebServerSetting *ServerSettingS
DocsServerSetting *ServerSettingS
AppSetting *AppSettingS
CacheIndexSetting *CacheIndexSettingS
SimpleCacheIndexSetting *SimpleCacheIndexSettingS
@ -56,6 +62,8 @@ func setupSetting(suite []string, noDefault bool) error {
objects := map[string]any{
"App": &AppSetting,
"Server": &ServerSetting,
"WebServer": &WebServerSetting,
"DocsServer": &DocsServerSetting,
"CacheIndex": &CacheIndexSetting,
"SimpleCacheIndex": &SimpleCacheIndexSetting,
"BigCacheIndex": &BigCacheIndexSetting,
@ -134,3 +142,10 @@ func GetOssDomain() string {
}
return uri + AliOSSSetting.Domain + "/"
}
func RunMode() string {
if !cfg.If("Deprecated:OldWeb") {
return ServerSetting.RunMode
}
return AppSetting.RunMode
}

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package conf
import (

@ -1,3 +1,7 @@
// 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.
//go:build cgo
// +build cgo

@ -1,3 +1,7 @@
// 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.
//go:build !cgo
// +build !cgo

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package conf
import (

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package conf
import (

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package conf
import (

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package conf
import (
@ -50,6 +54,7 @@ type ServerSettingS struct {
}
type AppSettingS struct {
RunMode string
MaxCommentCount int64
AttachmentIncomeRate float64
DefaultContextTimeout time.Duration

@ -1,7 +1,10 @@
// 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/model"
"github.com/rocboss/paopao-ce/pkg/types"
)
@ -33,23 +36,17 @@ const (
ActCreateActivationCode
)
type act uint8
type (
act uint8
type FriendFilter map[int64]types.Empty
type FriendSet map[string]types.Empty
FriendFilter map[int64]types.Empty
FriendSet map[string]types.Empty
type Action struct {
Action struct {
Act act
UserId int64
}
// AuthorizationManageService 授权管理服务
type AuthorizationManageService interface {
IsAllow(user *model.User, action *Action) bool
BeFriendFilter(userId int64) FriendFilter
BeFriendIds(userId int64) ([]int64, error)
MyFriendSet(userId int64) FriendSet
}
}
)
func (f FriendFilter) IsFriend(userId int64) bool {
_, yeah := f[userId]
@ -57,7 +54,7 @@ func (f FriendFilter) IsFriend(userId int64) bool {
}
// IsAllow default true if user is admin
func (a act) IsAllow(user *model.User, userId int64, isFriend bool, isActivation bool) bool {
func (a act) IsAllow(user *User, userId int64, isFriend bool, isActivation bool) bool {
if user.IsAdmin {
return true
}
@ -116,3 +113,11 @@ func (a act) IsAllow(user *model.User, userId int64, isFriend bool, isActivation
return false
}
// AuthorizationManageService 授权管理服务
type AuthorizationManageService interface {
IsAllow(user *User, action *Action) bool
BeFriendFilter(userId int64) FriendFilter
BeFriendIds(userId int64) ([]int64, error)
MyFriendSet(userId int64) FriendSet
}

@ -1,6 +1,12 @@
// 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/model"
import (
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
)
const (
IdxActNop IdxAct = iota + 1
@ -15,7 +21,7 @@ type IdxAct uint8
type IndexAction struct {
Act IdxAct
Post *model.Post
Post *dbr.Post
}
func (a IdxAct) String() string {
@ -37,7 +43,7 @@ func (a IdxAct) String() string {
}
}
func NewIndexAction(act IdxAct, post *model.Post) *IndexAction {
func NewIndexAction(act IdxAct, post *dbr.Post) *IndexAction {
return &IndexAction{
Act: act,
Post: post,
@ -48,5 +54,5 @@ func NewIndexAction(act IdxAct, post *model.Post) *IndexAction {
type CacheIndexService interface {
IndexPostsService
SendAction(act IdxAct, post *model.Post)
SendAction(act IdxAct, post *dbr.Post)
}

@ -1,24 +1,36 @@
// 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/model"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
)
type (
Comment = dbr.Comment
CommentFormated = dbr.CommentFormated
CommentReply = dbr.CommentReply
CommentContent = dbr.CommentContent
CommentReplyFormated = dbr.CommentReplyFormated
)
// CommentService 评论检索服务
type CommentService interface {
GetComments(conditions *model.ConditionsT, offset, limit int) ([]*model.Comment, error)
GetCommentByID(id int64) (*model.Comment, error)
GetCommentCount(conditions *model.ConditionsT) (int64, error)
GetCommentReplyByID(id int64) (*model.CommentReply, error)
GetCommentContentsByIDs(ids []int64) ([]*model.CommentContent, error)
GetCommentRepliesByID(ids []int64) ([]*model.CommentReplyFormated, error)
GetComments(conditions *ConditionsT, offset, limit int) ([]*Comment, error)
GetCommentByID(id int64) (*Comment, error)
GetCommentCount(conditions *ConditionsT) (int64, error)
GetCommentReplyByID(id int64) (*CommentReply, error)
GetCommentContentsByIDs(ids []int64) ([]*CommentContent, error)
GetCommentRepliesByID(ids []int64) ([]*CommentReplyFormated, error)
}
// CommentManageService 评论管理服务
type CommentManageService interface {
DeleteComment(comment *model.Comment) error
CreateComment(comment *model.Comment) (*model.Comment, error)
CreateCommentReply(reply *model.CommentReply) (*model.CommentReply, error)
DeleteCommentReply(reply *model.CommentReply) error
CreateCommentContent(content *model.CommentContent) (*model.CommentContent, error)
DeleteComment(comment *Comment) error
CreateComment(comment *Comment) (*Comment, error)
CreateCommentReply(reply *CommentReply) (*CommentReply, error)
DeleteCommentReply(reply *CommentReply) error
CreateCommentContent(content *CommentContent) (*CommentContent, error)
}

@ -1,3 +1,7 @@
// 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
// DataService 数据服务集成

@ -1,15 +1,36 @@
// 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/model"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
)
const (
MsgTypePost = dbr.MsgTypePost
MsgtypeComment = dbr.MsgtypeComment
MsgTypeReply = dbr.MsgTypeReply
MsgTypeWhisper = dbr.MsgTypeWhisper
MsgTypeRequestingFriend = dbr.MsgTypeRequestingFriend
MsgTypeSystem = dbr.MsgTypeSystem
MsgStatusUnread = dbr.MsgStatusUnread
MsgStatusReaded = dbr.MsgStatusReaded
)
type (
Message = dbr.Message
MessageFormated = dbr.MessageFormated
)
// MessageService 消息服务
type MessageService interface {
CreateMessage(msg *model.Message) (*model.Message, error)
CreateMessage(msg *Message) (*Message, error)
GetUnreadCount(userID int64) (int64, error)
GetMessageByID(id int64) (*model.Message, error)
ReadMessage(message *model.Message) error
GetMessages(conditions *model.ConditionsT, offset, limit int) ([]*model.MessageFormated, error)
GetMessageCount(conditions *model.ConditionsT) (int64, error)
GetMessageByID(id int64) (*Message, error)
ReadMessage(message *Message) error
GetMessages(conditions *ConditionsT, offset, limit int) ([]*MessageFormated, error)
GetMessageCount(conditions *ConditionsT) (int64, error)
}

@ -1,7 +1,11 @@
// 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/model"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
)
const (
@ -9,28 +13,39 @@ const (
SearchTypeTag SearchType = "tag"
)
type SearchType string
const (
PostVisitPublic = dbr.PostVisitPublic
PostVisitPrivate = dbr.PostVisitPrivate
PostVisitFriend = dbr.PostVisitFriend
PostVisitInvalid = dbr.PostVisitInvalid
)
type (
PostVisibleT = dbr.PostVisibleT
SearchType string
type QueryReq struct {
QueryReq struct {
Query string
Visibility []model.PostVisibleT
Visibility []PostVisibleT
Type SearchType
}
}
type QueryResp struct {
Items []*model.PostFormated
QueryResp struct {
Items []*PostFormated
Total int64
}
}
type TsDocItem struct {
Post *model.Post
TsDocItem struct {
Post *Post
Content string
}
}
)
// TweetSearchService tweet search service interface
type TweetSearchService interface {
IndexName() string
AddDocuments(data []TsDocItem, primaryKey ...string) (bool, error)
DeleteDocuments(identifiers []string) error
Search(user *model.User, q *QueryReq, offset, limit int) (*QueryResp, error)
Search(user *User, q *QueryReq, offset, limit int) (*QueryResp, error)
}

@ -1,13 +1,21 @@
// 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/model"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
)
type (
Captcha = dbr.Captcha
)
// SecurityService 安全相关服务
type SecurityService interface {
GetLatestPhoneCaptcha(phone string) (*model.Captcha, error)
UsePhoneCaptcha(captcha *model.Captcha) error
GetLatestPhoneCaptcha(phone string) (*Captcha, error)
UsePhoneCaptcha(captcha *Captcha) error
SendPhoneCaptcha(phone string) error
}

@ -1,3 +1,7 @@
// 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 (

@ -1,13 +1,22 @@
// 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/model"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
)
type (
Tag = dbr.Tag
TagFormated = dbr.TagFormated
)
// TopicService 话题服务
type TopicService interface {
CreateTag(tag *model.Tag) (*model.Tag, error)
DeleteTag(tag *model.Tag) error
GetTags(conditions *model.ConditionsT, offset, limit int) ([]*model.Tag, error)
GetTagsByKeyword(keyword string) ([]*model.Tag, error)
CreateTag(tag *Tag) (*Tag, error)
DeleteTag(tag *Tag) error
GetTags(conditions *ConditionsT, offset, limit int) ([]*Tag, error)
GetTagsByKeyword(keyword string) ([]*Tag, error)
}

@ -1,49 +1,83 @@
// 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/model"
"github.com/rocboss/paopao-ce/internal/model/rest"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
)
const (
AttachmentTypeImage = dbr.AttachmentTypeImage
AttachmentTypeVideo = dbr.AttachmentTypeVideo
AttachmentTypeOther = dbr.AttachmentTypeOther
// 类型1标题2文字段落3图片地址4视频地址5语音地址6链接地址7附件资源
ContentTypeTitle = dbr.ContentTypeTitle
ContentTypeText = dbr.ContentTypeText
ContentTypeImage = dbr.ContentTypeImage
ContentTypeVideo = dbr.ContentTypeVideo
ContentTypeAudio = dbr.ContentTypeAudio
ContentTypeLink = dbr.ContentTypeLink
ContentTypeAttachment = dbr.ContentTypeAttachment
ContentTypeChargeAttachment = dbr.ContentTypeChargeAttachment
)
type (
PostStar = dbr.PostStar
PostCollection = dbr.PostCollection
PostAttachmentBill = dbr.PostAttachmentBill
PostContent = dbr.PostContent
Attachment = dbr.Attachment
AttachmentType = dbr.AttachmentType
PostContentT = dbr.PostContentT
IndexTweetList struct {
Tweets []*PostFormated
Total int64
}
)
// TweetService 推文检索服务
type TweetService interface {
GetPostByID(id int64) (*model.Post, error)
GetPosts(conditions *model.ConditionsT, offset, limit int) ([]*model.Post, error)
GetPostCount(conditions *model.ConditionsT) (int64, error)
GetUserPostStar(postID, userID int64) (*model.PostStar, error)
GetUserPostStars(userID int64, offset, limit int) ([]*model.PostStar, error)
GetPostByID(id int64) (*Post, error)
GetPosts(conditions *ConditionsT, offset, limit int) ([]*Post, error)
GetPostCount(conditions *ConditionsT) (int64, error)
GetUserPostStar(postID, userID int64) (*PostStar, error)
GetUserPostStars(userID int64, offset, limit int) ([]*PostStar, error)
GetUserPostStarCount(userID int64) (int64, error)
GetUserPostCollection(postID, userID int64) (*model.PostCollection, error)
GetUserPostCollections(userID int64, offset, limit int) ([]*model.PostCollection, error)
GetUserPostCollection(postID, userID int64) (*PostCollection, error)
GetUserPostCollections(userID int64, offset, limit int) ([]*PostCollection, error)
GetUserPostCollectionCount(userID int64) (int64, error)
GetPostAttatchmentBill(postID, userID int64) (*model.PostAttachmentBill, error)
GetPostContentsByIDs(ids []int64) ([]*model.PostContent, error)
GetPostContentByID(id int64) (*model.PostContent, error)
GetPostAttatchmentBill(postID, userID int64) (*PostAttachmentBill, error)
GetPostContentsByIDs(ids []int64) ([]*PostContent, error)
GetPostContentByID(id int64) (*PostContent, error)
}
// TweetManageService 推文管理服务,包括创建/删除/更新推文
type TweetManageService interface {
CreateAttachment(attachment *model.Attachment) (*model.Attachment, error)
CreatePost(post *model.Post) (*model.Post, error)
DeletePost(post *model.Post) ([]string, error)
LockPost(post *model.Post) error
StickPost(post *model.Post) error
VisiblePost(post *model.Post, visibility model.PostVisibleT) error
UpdatePost(post *model.Post) error
CreatePostStar(postID, userID int64) (*model.PostStar, error)
DeletePostStar(p *model.PostStar) error
CreatePostCollection(postID, userID int64) (*model.PostCollection, error)
DeletePostCollection(p *model.PostCollection) error
CreatePostContent(content *model.PostContent) (*model.PostContent, error)
CreateAttachment(attachment *Attachment) (*Attachment, error)
CreatePost(post *Post) (*Post, error)
DeletePost(post *Post) ([]string, error)
LockPost(post *Post) error
StickPost(post *Post) error
VisiblePost(post *Post, visibility PostVisibleT) error
UpdatePost(post *Post) error
CreatePostStar(postID, userID int64) (*PostStar, error)
DeletePostStar(p *PostStar) error
CreatePostCollection(postID, userID int64) (*PostCollection, error)
DeletePostCollection(p *PostCollection) error
CreatePostContent(content *PostContent) (*PostContent, error)
}
// TweetHelpService 推文辅助服务
type TweetHelpService interface {
RevampPosts(posts []*model.PostFormated) ([]*model.PostFormated, error)
MergePosts(posts []*model.Post) ([]*model.PostFormated, error)
RevampPosts(posts []*PostFormated) ([]*PostFormated, error)
MergePosts(posts []*Post) ([]*PostFormated, error)
}
// IndexPostsService 广场首页推文列表服务
type IndexPostsService interface {
IndexPosts(user *model.User, offset int, limit int) (*rest.IndexTweetsResp, error)
IndexPosts(user *User, offset int, limit int) (*IndexTweetList, error)
}

@ -0,0 +1,24 @@
// 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/dao/jinzhu/dbr"
)
const (
UserStatusNormal = dbr.UserStatusNormal
UserStatusClosed = dbr.UserStatusClosed
)
type (
User = dbr.User
Post = dbr.Post
ConditionsT = dbr.ConditionsT
PostFormated = dbr.PostFormated
UserFormated = dbr.UserFormated
PostContentFormated = dbr.PostContentFormated
Model = dbr.Model
)

@ -1,19 +1,33 @@
// 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/model"
"github.com/rocboss/paopao-ce/internal/model/rest"
type (
ContactItem struct {
UserId int64 `json:"user_id"`
UserName string `json:"username"`
Nickname string `json:"nickname"`
Avatar string `json:"avatar"`
Phone string `json:"phone"`
}
ContactList struct {
Contacts []ContactItem `json:"contacts"`
Total int64 `json:"total"`
}
)
// UserManageService 用户管理服务
type UserManageService interface {
GetUserByID(id int64) (*model.User, error)
GetUserByUsername(username string) (*model.User, error)
GetUserByPhone(phone string) (*model.User, error)
GetUsersByIDs(ids []int64) ([]*model.User, error)
GetUsersByKeyword(keyword string) ([]*model.User, error)
CreateUser(user *model.User) (*model.User, error)
UpdateUser(user *model.User) error
GetUserByID(id int64) (*User, error)
GetUserByUsername(username string) (*User, error)
GetUserByPhone(phone string) (*User, error)
GetUsersByIDs(ids []int64) ([]*User, error)
GetUsersByKeyword(keyword string) ([]*User, error)
CreateUser(user *User) (*User, error)
UpdateUser(user *User) error
}
// ContactManageService 联系人管理服务
@ -22,6 +36,6 @@ type ContactManageService interface {
AddFriend(userId int64, friendId int64) error
RejectFriend(userId int64, friendId int64) error
DeleteFriend(userId int64, friendId int64) error
GetContacts(userId int64, offset int, limit int) (*rest.ContactsResp, error)
GetContacts(userId int64, offset int, limit int) (*ContactList, error)
IsFriend(userID int64, friendID int64) bool
}

@ -1,3 +1,7 @@
// 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 (

@ -1,15 +1,24 @@
// 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/model"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
)
type (
WalletStatement = dbr.WalletStatement
WalletRecharge = dbr.WalletRecharge
)
// WalletService wallet service interface
type WalletService interface {
GetUserWalletBills(userID int64, offset, limit int) ([]*model.WalletStatement, error)
GetUserWalletBills(userID int64, offset, limit int) ([]*WalletStatement, error)
GetUserWalletBillCount(userID int64) (int64, error)
GetRechargeByID(id int64) (*model.WalletRecharge, error)
CreateRecharge(userId, amount int64) (*model.WalletRecharge, error)
HandleRechargeSuccess(recharge *model.WalletRecharge, tradeNo string) error
HandlePostAttachmentBought(post *model.Post, user *model.User) error
GetRechargeByID(id int64) (*WalletRecharge, error)
CreateRecharge(userId, amount int64) (*WalletRecharge, error)
HandleRechargeSuccess(recharge *WalletRecharge, tradeNo string) error
HandlePostAttachmentBought(post *Post, user *User) error
}

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package cache
import (
@ -11,8 +15,6 @@ import (
"github.com/Masterminds/semver/v3"
"github.com/allegro/bigcache/v3"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/internal/model/rest"
"github.com/rocboss/paopao-ce/pkg/types"
"github.com/sirupsen/logrus"
)
@ -24,7 +26,7 @@ var (
type postsEntry struct {
key string
tweets *rest.IndexTweetsResp
tweets *core.IndexTweetList
}
type bigCacheIndexServant struct {
@ -38,7 +40,7 @@ type bigCacheIndexServant struct {
preventDuration time.Duration
}
func (s *bigCacheIndexServant) IndexPosts(user *model.User, offset int, limit int) (*rest.IndexTweetsResp, error) {
func (s *bigCacheIndexServant) IndexPosts(user *core.User, offset int, limit int) (*core.IndexTweetList, error) {
key := s.keyFrom(user, offset, limit)
posts, err := s.getPosts(key)
if err == nil {
@ -54,7 +56,7 @@ func (s *bigCacheIndexServant) IndexPosts(user *model.User, offset int, limit in
return posts, nil
}
func (s *bigCacheIndexServant) getPosts(key string) (*rest.IndexTweetsResp, error) {
func (s *bigCacheIndexServant) getPosts(key string) (*core.IndexTweetList, error) {
data, err := s.cache.Get(key)
if err != nil {
logrus.Debugf("bigCacheIndexServant.getPosts get posts by key: %s from cache err: %v", key, err)
@ -62,7 +64,7 @@ func (s *bigCacheIndexServant) getPosts(key string) (*rest.IndexTweetsResp, erro
}
buf := bytes.NewBuffer(data)
dec := gob.NewDecoder(buf)
var resp rest.IndexTweetsResp
var resp core.IndexTweetList
if err := dec.Decode(&resp); err != nil {
logrus.Debugf("bigCacheIndexServant.getPosts get posts from cache in decode err: %v", err)
return nil, err
@ -70,7 +72,7 @@ func (s *bigCacheIndexServant) getPosts(key string) (*rest.IndexTweetsResp, erro
return &resp, nil
}
func (s *bigCacheIndexServant) cachePosts(key string, tweets *rest.IndexTweetsResp) {
func (s *bigCacheIndexServant) cachePosts(key string, tweets *core.IndexTweetList) {
entry := &postsEntry{key: key, tweets: tweets}
select {
case s.cachePostsCh <- entry:
@ -96,7 +98,7 @@ func (s *bigCacheIndexServant) setPosts(entry *postsEntry) {
logrus.Debugf("bigCacheIndexServant.setPosts setPosts set cache by key: %s", entry.key)
}
func (s *bigCacheIndexServant) keyFrom(user *model.User, offset int, limit int) string {
func (s *bigCacheIndexServant) keyFrom(user *core.User, offset int, limit int) string {
var userId int64 = -1
if user != nil {
userId = user.ID
@ -104,7 +106,7 @@ func (s *bigCacheIndexServant) keyFrom(user *model.User, offset int, limit int)
return fmt.Sprintf("index:%d:%d:%d", userId, offset, limit)
}
func (s *bigCacheIndexServant) SendAction(act core.IdxAct, post *model.Post) {
func (s *bigCacheIndexServant) SendAction(act core.IdxAct, post *core.Post) {
action := core.NewIndexAction(act, post)
select {
case s.indexActionCh <- action:
@ -134,7 +136,7 @@ func (s *bigCacheIndexServant) handleIndexAction(action *core.IndexAction) {
// 创建/删除 私密推文特殊处理
switch act {
case core.IdxActCreatePost, core.IdxActDeletePost:
if post.Visibility == model.PostVisitPrivate {
if post.Visibility == core.PostVisitPrivate {
s.deleteCacheByUserId(post.UserID, true)
return
}

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package cache
import (

@ -1,10 +1,12 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package cache
import (
"github.com/Masterminds/semver/v3"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/internal/model/rest"
)
var (
@ -16,11 +18,11 @@ type noneCacheIndexServant struct {
ips core.IndexPostsService
}
func (s *noneCacheIndexServant) IndexPosts(user *model.User, offset int, limit int) (*rest.IndexTweetsResp, error) {
func (s *noneCacheIndexServant) IndexPosts(user *core.User, offset int, limit int) (*core.IndexTweetList, error) {
return s.ips.IndexPosts(user, offset, limit)
}
func (s *noneCacheIndexServant) SendAction(_act core.IdxAct, _post *model.Post) {
func (s *noneCacheIndexServant) SendAction(_act core.IdxAct, _post *core.Post) {
// empty
}

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package cache
import (
@ -6,8 +10,6 @@ import (
"github.com/Masterminds/semver/v3"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/internal/model/rest"
"github.com/sirupsen/logrus"
)
@ -20,21 +22,21 @@ type simpleCacheIndexServant struct {
ips core.IndexPostsService
indexActionCh chan core.IdxAct
indexPosts *rest.IndexTweetsResp
indexPosts *core.IndexTweetList
atomicIndex atomic.Value
maxIndexSize int
checkTick *time.Ticker
expireIndexTick *time.Ticker
}
func (s *simpleCacheIndexServant) IndexPosts(user *model.User, offset int, limit int) (*rest.IndexTweetsResp, error) {
cacheResp := s.atomicIndex.Load().(*rest.IndexTweetsResp)
func (s *simpleCacheIndexServant) IndexPosts(user *core.User, offset int, limit int) (*core.IndexTweetList, error) {
cacheResp := s.atomicIndex.Load().(*core.IndexTweetList)
end := offset + limit
if cacheResp != nil {
size := len(cacheResp.Tweets)
logrus.Debugf("simpleCacheIndexServant.IndexPosts get index posts from cache posts: %d offset:%d limit:%d start:%d, end:%d", size, offset, limit, offset, end)
if size >= end {
return &rest.IndexTweetsResp{
return &core.IndexTweetList{
Tweets: cacheResp.Tweets[offset:end],
Total: cacheResp.Total,
}, nil
@ -45,7 +47,7 @@ func (s *simpleCacheIndexServant) IndexPosts(user *model.User, offset int, limit
return s.ips.IndexPosts(user, offset, limit)
}
func (s *simpleCacheIndexServant) SendAction(act core.IdxAct, _post *model.Post) {
func (s *simpleCacheIndexServant) SendAction(act core.IdxAct, _post *core.Post) {
select {
case s.indexActionCh <- act:
logrus.Debugf("simpleCacheIndexServant.SendAction send indexAction by chan: %s", act)

@ -1,3 +1,7 @@
// 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 dao
import (

@ -1,8 +1,12 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package jinzhu
import (
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"github.com/rocboss/paopao-ce/pkg/types"
"gorm.io/gorm"
)
@ -21,7 +25,7 @@ func newAuthorizationManageService(db *gorm.DB) core.AuthorizationManageService
}
}
func (s *authorizationManageServant) IsAllow(user *model.User, action *core.Action) bool {
func (s *authorizationManageServant) IsAllow(user *core.User, action *core.Action) bool {
// user is activation if had bind phone
isActivation := (len(user.Phone) != 0)
isFriend := s.isFriend(user.ID, action.UserId)
@ -30,7 +34,7 @@ func (s *authorizationManageServant) IsAllow(user *model.User, action *core.Acti
}
func (s *authorizationManageServant) MyFriendSet(userId int64) core.FriendSet {
ids, err := (&model.Contact{UserId: userId}).MyFriendIds(s.db)
ids, err := (&dbr.Contact{UserId: userId}).MyFriendIds(s.db)
if err != nil {
return core.FriendSet{}
}
@ -43,7 +47,7 @@ func (s *authorizationManageServant) MyFriendSet(userId int64) core.FriendSet {
}
func (s *authorizationManageServant) BeFriendFilter(userId int64) core.FriendFilter {
ids, err := (&model.Contact{FriendId: userId}).BeFriendIds(s.db)
ids, err := (&dbr.Contact{FriendId: userId}).BeFriendIds(s.db)
if err != nil {
return core.FriendFilter{}
}
@ -56,12 +60,12 @@ func (s *authorizationManageServant) BeFriendFilter(userId int64) core.FriendFil
}
func (s *authorizationManageServant) BeFriendIds(userId int64) ([]int64, error) {
return (&model.Contact{FriendId: userId}).BeFriendIds(s.db)
return (&dbr.Contact{FriendId: userId}).BeFriendIds(s.db)
}
func (s *authorizationManageServant) isFriend(userId int64, friendId int64) bool {
contact, err := (&model.Contact{UserId: friendId, FriendId: userId}).GetByUserFriend(s.db)
if err == nil || contact.Status == model.ContactStatusAgree {
contact, err := (&dbr.Contact{UserId: friendId, FriendId: userId}).GetByUserFriend(s.db)
if err == nil || contact.Status == dbr.ContactStatusAgree {
return true
}
return false

@ -1,8 +1,12 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package jinzhu
import (
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"gorm.io/gorm"
)
@ -31,42 +35,42 @@ func newCommentManageService(db *gorm.DB) core.CommentManageService {
}
}
func (s *commentServant) GetComments(conditions *model.ConditionsT, offset, limit int) ([]*model.Comment, error) {
return (&model.Comment{}).List(s.db, conditions, offset, limit)
func (s *commentServant) GetComments(conditions *core.ConditionsT, offset, limit int) ([]*core.Comment, error) {
return (&dbr.Comment{}).List(s.db, conditions, offset, limit)
}
func (s *commentServant) GetCommentByID(id int64) (*model.Comment, error) {
comment := &model.Comment{
Model: &model.Model{
func (s *commentServant) GetCommentByID(id int64) (*core.Comment, error) {
comment := &dbr.Comment{
Model: &dbr.Model{
ID: id,
},
}
return comment.Get(s.db)
}
func (s *commentServant) GetCommentReplyByID(id int64) (*model.CommentReply, error) {
reply := &model.CommentReply{
Model: &model.Model{
func (s *commentServant) GetCommentReplyByID(id int64) (*core.CommentReply, error) {
reply := &dbr.CommentReply{
Model: &dbr.Model{
ID: id,
},
}
return reply.Get(s.db)
}
func (s *commentServant) GetCommentCount(conditions *model.ConditionsT) (int64, error) {
return (&model.Comment{}).Count(s.db, conditions)
func (s *commentServant) GetCommentCount(conditions *core.ConditionsT) (int64, error) {
return (&dbr.Comment{}).Count(s.db, conditions)
}
func (s *commentServant) GetCommentContentsByIDs(ids []int64) ([]*model.CommentContent, error) {
commentContent := &model.CommentContent{}
return commentContent.List(s.db, &model.ConditionsT{
func (s *commentServant) GetCommentContentsByIDs(ids []int64) ([]*core.CommentContent, error) {
commentContent := &dbr.CommentContent{}
return commentContent.List(s.db, &dbr.ConditionsT{
"comment_id IN ?": ids,
}, 0, 0)
}
func (s *commentServant) GetCommentRepliesByID(ids []int64) ([]*model.CommentReplyFormated, error) {
CommentReply := &model.CommentReply{}
replies, err := CommentReply.List(s.db, &model.ConditionsT{
func (s *commentServant) GetCommentRepliesByID(ids []int64) ([]*core.CommentReplyFormated, error) {
CommentReply := &dbr.CommentReply{}
replies, err := CommentReply.List(s.db, &dbr.ConditionsT{
"comment_id IN ?": ids,
}, 0, 0)
@ -83,7 +87,7 @@ func (s *commentServant) GetCommentRepliesByID(ids []int64) ([]*model.CommentRep
if err != nil {
return nil, err
}
repliesFormated := []*model.CommentReplyFormated{}
repliesFormated := []*core.CommentReplyFormated{}
for _, reply := range replies {
replyFormated := reply.Format()
for _, user := range users {
@ -101,22 +105,22 @@ func (s *commentServant) GetCommentRepliesByID(ids []int64) ([]*model.CommentRep
return repliesFormated, nil
}
func (s *commentManageServant) DeleteComment(comment *model.Comment) error {
func (s *commentManageServant) DeleteComment(comment *core.Comment) error {
return comment.Delete(s.db)
}
func (s *commentManageServant) CreateComment(comment *model.Comment) (*model.Comment, error) {
func (s *commentManageServant) CreateComment(comment *core.Comment) (*core.Comment, error) {
return comment.Create(s.db)
}
func (s *commentManageServant) CreateCommentReply(reply *model.CommentReply) (*model.CommentReply, error) {
func (s *commentManageServant) CreateCommentReply(reply *core.CommentReply) (*core.CommentReply, error) {
return reply.Create(s.db)
}
func (s *commentManageServant) DeleteCommentReply(reply *model.CommentReply) error {
func (s *commentManageServant) DeleteCommentReply(reply *core.CommentReply) error {
return reply.Delete(s.db)
}
func (s *commentManageServant) CreateCommentContent(content *model.CommentContent) (*model.CommentContent, error) {
func (s *commentManageServant) CreateCommentContent(content *core.CommentContent) (*core.CommentContent, error) {
return content.Create(s.db)
}

@ -1,11 +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 jinzhu
import (
"time"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/internal/model/rest"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"github.com/sirupsen/logrus"
"gorm.io/gorm"
)
@ -24,14 +27,14 @@ func newContactManageService(db *gorm.DB) core.ContactManageService {
}
}
func (s *contactManageServant) fetchOrNewContact(db *gorm.DB, userId int64, friendId int64, status int8) (*model.Contact, error) {
contact := &model.Contact{
func (s *contactManageServant) fetchOrNewContact(db *gorm.DB, userId int64, friendId int64, status int8) (*dbr.Contact, error) {
contact := &dbr.Contact{
UserId: userId,
FriendId: friendId,
}
contact, err := contact.FetchUser(db)
if err != nil {
contact = &model.Contact{
contact = &dbr.Contact{
UserId: userId,
FriendId: friendId,
Status: status,
@ -54,17 +57,17 @@ func (s *contactManageServant) RequestingFriend(userId int64, friendId int64, gr
}
}()
contact, e := s.fetchOrNewContact(db, userId, friendId, model.ContactStatusRequesting)
contact, e := s.fetchOrNewContact(db, userId, friendId, dbr.ContactStatusRequesting)
if e != nil {
err = e
return
}
// 如果已经好友,啥也不干
if contact.Status == model.ContactStatusAgree {
if contact.Status == dbr.ContactStatusAgree {
return nil
} else if contact.Status == model.ContactStatusReject || contact.Status == model.ContactStatusDeleted {
contact.Status = model.ContactStatusRequesting
} else if contact.Status == dbr.ContactStatusReject || contact.Status == dbr.ContactStatusDeleted {
contact.Status = dbr.ContactStatusRequesting
contact.IsDel = 0 // remove deleted flag if needed
if err = contact.UpdateInUnscoped(db); err != nil {
logrus.Errorf("contactManageServant.RequestingFriend update exsit contact err:%s", err)
@ -72,13 +75,13 @@ func (s *contactManageServant) RequestingFriend(userId int64, friendId int64, gr
}
}
msg := &model.Message{
msg := &dbr.Message{
SenderUserID: userId,
ReceiverUserID: friendId,
Type: model.MsgTypeRequestingFriend,
Type: dbr.MsgTypeRequestingFriend,
Brief: "请求添加好友,并附言:",
Content: greetings,
ReplyID: int64(model.ContactStatusRequesting),
ReplyID: int64(dbr.ContactStatusRequesting),
}
if _, err = msg.Create(db); err != nil {
logrus.Errorf("contactManageServant.RequestingFriend create message err:%s", err)
@ -97,7 +100,7 @@ func (s *contactManageServant) AddFriend(userId int64, friendId int64) (err erro
}
}()
contact := &model.Contact{
contact := &dbr.Contact{
UserId: friendId,
FriendId: userId,
}
@ -105,23 +108,23 @@ func (s *contactManageServant) AddFriend(userId int64, friendId int64) (err erro
return
}
// 如果还不是请求好友,啥也不干
if contact.Status != model.ContactStatusRequesting {
if contact.Status != dbr.ContactStatusRequesting {
logrus.Debugf("contactManageServant.AddFriend not reuesting status now so skip")
return nil
}
contact.Status = model.ContactStatusAgree
contact.Status = dbr.ContactStatusAgree
if err = contact.Update(db); err != nil {
return err
}
contact, err = s.fetchOrNewContact(db, userId, friendId, model.ContactStatusAgree)
contact, err = s.fetchOrNewContact(db, userId, friendId, dbr.ContactStatusAgree)
if err != nil {
return
}
// 如果已经好友,啥也不干
if contact.Status != model.ContactStatusAgree {
contact.Status = model.ContactStatusAgree
if contact.Status != dbr.ContactStatusAgree {
contact.Status = dbr.ContactStatusAgree
contact.IsDel = 0 // remove deleted flag
if err = contact.UpdateInUnscoped(db); err != nil {
logrus.Errorf("contactManageServant.AddFriend update contact err:%s", err)
@ -129,8 +132,8 @@ func (s *contactManageServant) AddFriend(userId int64, friendId int64) (err erro
}
}
args := []any{userId, friendId, friendId, userId, model.MsgTypeRequestingFriend, model.ContactStatusRequesting}
msgs, e := (&model.Message{}).FetchBy(db, model.Predicates{
args := []any{userId, friendId, friendId, userId, dbr.MsgTypeRequestingFriend, dbr.ContactStatusRequesting}
msgs, e := (&dbr.Message{}).FetchBy(db, dbr.Predicates{
"((sender_user_id = ? AND receiver_user_id = ?) OR (sender_user_id = ? AND receiver_user_id = ?)) AND type = ? AND reply_id = ?": args,
})
if e != nil {
@ -138,7 +141,7 @@ func (s *contactManageServant) AddFriend(userId int64, friendId int64) (err erro
return
}
for _, msg := range msgs {
msg.ReplyID = int64(model.ContactStatusAgree)
msg.ReplyID = int64(dbr.ContactStatusAgree)
if err = msg.Update(db); err != nil {
return
}
@ -156,7 +159,7 @@ func (s *contactManageServant) RejectFriend(userId int64, friendId int64) (err e
}
}()
contact := &model.Contact{
contact := &dbr.Contact{
UserId: friendId,
FriendId: userId,
}
@ -164,16 +167,16 @@ func (s *contactManageServant) RejectFriend(userId int64, friendId int64) (err e
return
}
// 如果还不是请求好友,啥也不干
if contact.Status != model.ContactStatusRequesting {
if contact.Status != dbr.ContactStatusRequesting {
return nil
}
contact.Status = model.ContactStatusReject
contact.Status = dbr.ContactStatusReject
if err = contact.Update(db); err != nil {
return err
}
args := []any{friendId, userId, model.MsgTypeRequestingFriend, model.ContactStatusRequesting}
msgs, e := (&model.Message{}).FetchBy(db, model.Predicates{
args := []any{friendId, userId, dbr.MsgTypeRequestingFriend, dbr.ContactStatusRequesting}
msgs, e := (&dbr.Message{}).FetchBy(db, dbr.Predicates{
"sender_user_id = ? AND receiver_user_id = ? AND type = ? AND reply_id = ?": args,
})
if e != nil {
@ -181,7 +184,7 @@ func (s *contactManageServant) RejectFriend(userId int64, friendId int64) (err e
return
}
for _, msg := range msgs {
msg.ReplyID = int64(model.ContactStatusReject)
msg.ReplyID = int64(dbr.ContactStatusReject)
if err = msg.Update(db); err != nil {
return
}
@ -199,7 +202,7 @@ func (s *contactManageServant) DeleteFriend(userId int64, friendId int64) (err e
}
}()
contact := &model.Contact{
contact := &dbr.Contact{
UserId: userId,
FriendId: friendId,
}
@ -210,10 +213,10 @@ func (s *contactManageServant) DeleteFriend(userId int64, friendId int64) (err e
for _, contact := range contacts {
// 如果还不是好友,啥也不干
if contact.Status != model.ContactStatusAgree {
if contact.Status != dbr.ContactStatusAgree {
continue
}
contact.Status = model.ContactStatusDeleted
contact.Status = dbr.ContactStatusDeleted
contact.DeletedOn = time.Now().Unix()
contact.IsDel = 1
if err = contact.Update(db); err != nil {
@ -223,11 +226,11 @@ func (s *contactManageServant) DeleteFriend(userId int64, friendId int64) (err e
return nil
}
func (s *contactManageServant) GetContacts(userId int64, offset int, limit int) (*rest.ContactsResp, error) {
contact := &model.Contact{}
condition := model.ConditionsT{
func (s *contactManageServant) GetContacts(userId int64, offset int, limit int) (*core.ContactList, error) {
contact := &dbr.Contact{}
condition := dbr.ConditionsT{
"user_id": userId,
"status": model.ContactStatusAgree,
"status": dbr.ContactStatusAgree,
}
contacts, err := contact.List(s.db, condition, offset, limit)
if err != nil {
@ -237,13 +240,13 @@ func (s *contactManageServant) GetContacts(userId int64, offset int, limit int)
if err != nil {
return nil, err
}
resp := &rest.ContactsResp{
Contacts: make([]rest.ContactItem, 0, len(contacts)),
resp := &core.ContactList{
Contacts: make([]core.ContactItem, 0, len(contacts)),
Total: total,
}
for _, c := range contacts {
if c.User != nil {
resp.Contacts = append(resp.Contacts, rest.ContactItem{
resp.Contacts = append(resp.Contacts, core.ContactItem{
UserId: c.FriendId,
UserName: c.User.Username,
Nickname: c.User.Nickname,
@ -256,12 +259,12 @@ func (s *contactManageServant) GetContacts(userId int64, offset int, limit int)
}
func (s *contactManageServant) IsFriend(userId int64, friendId int64) bool {
contact := &model.Contact{
contact := &dbr.Contact{
UserId: friendId,
FriendId: userId,
}
contact, err := contact.GetByUserFriend(s.db)
if err == nil && contact.Status == model.ContactStatusAgree {
if err == nil && contact.Status == dbr.ContactStatusAgree {
return true
}
return false

@ -1,13 +1,17 @@
package model
// 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 dbr
import "gorm.io/gorm"
type AttachmentType int
const (
ATTACHMENT_TYPE_IMAGE AttachmentType = iota + 1
ATTACHMENT_TYPE_VIDEO
ATTACHMENT_TYPE_OTHER
AttachmentTypeImage AttachmentType = iota + 1
AttachmentTypeVideo
AttachmentTypeOther
)
type Attachment struct {

@ -1,4 +1,8 @@
package model
// 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 dbr
import "gorm.io/gorm"

@ -1,4 +1,8 @@
package model
// 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 dbr
import (
"time"

@ -1,4 +1,8 @@
package model
// 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 dbr
import (
"time"
@ -47,7 +51,7 @@ func (c *CommentContent) Create(db *gorm.DB) (*CommentContent, error) {
}
func (c *CommentContent) MediaContentsByCommentId(db *gorm.DB, commentIds []int64) (contents []string, err error) {
err = db.Model(c).Where("comment_id IN ? AND type = ?", commentIds, CONTENT_TYPE_IMAGE).Select("content").Find(&contents).Error
err = db.Model(c).Where("comment_id IN ? AND type = ?", commentIds, ContentTypeImage).Select("content").Find(&contents).Error
return
}

@ -1,4 +1,8 @@
package model
// 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 dbr
import (
"time"

@ -1,4 +1,8 @@
package model
// 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 dbr
import (
"github.com/sirupsen/logrus"

@ -1,4 +1,8 @@
package model
// 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 dbr
import "gorm.io/gorm"

@ -1,4 +1,8 @@
package model
// 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 dbr
import (
"time"

@ -1,4 +1,8 @@
package model
// 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 dbr
import (
"strings"

@ -1,4 +1,8 @@
package model
// 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 dbr
import "gorm.io/gorm"

@ -1,4 +1,8 @@
package model
// 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 dbr
import (
"time"

@ -1,4 +1,8 @@
package model
// 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 dbr
import (
"time"
@ -7,27 +11,26 @@ import (
)
// 类型1标题2文字段落3图片地址4视频地址5语音地址6链接地址7附件资源
type PostContentT int
const (
CONTENT_TYPE_TITLE PostContentT = iota + 1
CONTENT_TYPE_TEXT
CONTENT_TYPE_IMAGE
CONTENT_TYPE_VIDEO
CONTENT_TYPE_AUDIO
CONTENT_TYPE_LINK
CONTENT_TYPE_ATTACHMENT
CONTENT_TYPE_CHARGE_ATTACHMENT
ContentTypeTitle PostContentT = iota + 1
ContentTypeText
ContentTypeImage
ContentTypeVideo
ContentTypeAudio
ContentTypeLink
ContentTypeAttachment
ContentTypeChargeAttachment
)
var (
mediaContentType = []PostContentT{
CONTENT_TYPE_IMAGE,
CONTENT_TYPE_VIDEO,
CONTENT_TYPE_AUDIO,
CONTENT_TYPE_ATTACHMENT,
CONTENT_TYPE_CHARGE_ATTACHMENT,
ContentTypeImage,
ContentTypeVideo,
ContentTypeAudio,
ContentTypeAttachment,
ContentTypeChargeAttachment,
}
)

@ -1,4 +1,8 @@
package model
// 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 dbr
import (
"time"

@ -1,4 +1,8 @@
package model
// 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 dbr
import (
"time"

@ -1,4 +1,8 @@
package model
// 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 dbr
import "gorm.io/gorm"

@ -1,4 +1,8 @@
package model
// 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 dbr
import "gorm.io/gorm"

@ -1,4 +1,8 @@
package model
// 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 dbr
import "gorm.io/gorm"

@ -1,9 +1,12 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package jinzhu
import (
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/internal/model/rest"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"github.com/sirupsen/logrus"
"gorm.io/gorm"
)
@ -40,20 +43,20 @@ func newSimpleIndexPostsService(db *gorm.DB) core.IndexPostsService {
}
// IndexPosts 根据userId查询广场推文列表简单做到不同用户的主页都是不同的
func (s *indexPostsServant) IndexPosts(user *model.User, offset int, limit int) (*rest.IndexTweetsResp, error) {
predicates := model.Predicates{
func (s *indexPostsServant) IndexPosts(user *core.User, offset int, limit int) (*core.IndexTweetList, error) {
predicates := dbr.Predicates{
"ORDER": []any{"is_top DESC, latest_replied_on DESC"},
}
if user == nil {
predicates["visibility = ?"] = []any{model.PostVisitPublic}
predicates["visibility = ?"] = []any{dbr.PostVisitPublic}
} else if !user.IsAdmin {
friendIds, _ := s.ams.BeFriendIds(user.ID)
friendIds = append(friendIds, user.ID)
args := []any{model.PostVisitPublic, model.PostVisitPrivate, user.ID, model.PostVisitFriend, friendIds}
args := []any{dbr.PostVisitPublic, dbr.PostVisitPrivate, user.ID, dbr.PostVisitFriend, friendIds}
predicates["visibility = ? OR (visibility = ? AND user_id = ?) OR (visibility = ? AND user_id IN ?)"] = args
}
posts, err := (&model.Post{}).Fetch(s.db, predicates, offset, limit)
posts, err := (&dbr.Post{}).Fetch(s.db, predicates, offset, limit)
if err != nil {
logrus.Debugf("gormIndexPostsServant.IndexPosts err: %v", err)
return nil, err
@ -63,25 +66,25 @@ func (s *indexPostsServant) IndexPosts(user *model.User, offset int, limit int)
return nil, err
}
total, err := (&model.Post{}).CountBy(s.db, predicates)
total, err := (&dbr.Post{}).CountBy(s.db, predicates)
if err != nil {
return nil, err
}
return &rest.IndexTweetsResp{
return &core.IndexTweetList{
Tweets: formatPosts,
Total: total,
}, nil
}
// simpleCacheIndexGetPosts simpleCacheIndex 专属获取广场推文列表函数
func (s *simpleIndexPostsServant) IndexPosts(_user *model.User, offset int, limit int) (*rest.IndexTweetsResp, error) {
predicates := model.Predicates{
"visibility = ?": []any{model.PostVisitPublic},
func (s *simpleIndexPostsServant) IndexPosts(_user *core.User, offset int, limit int) (*core.IndexTweetList, error) {
predicates := dbr.Predicates{
"visibility = ?": []any{dbr.PostVisitPublic},
"ORDER": []any{"is_top DESC, latest_replied_on DESC"},
}
posts, err := (&model.Post{}).Fetch(s.db, predicates, offset, limit)
posts, err := (&dbr.Post{}).Fetch(s.db, predicates, offset, limit)
if err != nil {
logrus.Debugf("gormSimpleIndexPostsServant.IndexPosts err: %v", err)
return nil, err
@ -92,12 +95,12 @@ func (s *simpleIndexPostsServant) IndexPosts(_user *model.User, offset int, limi
return nil, err
}
total, err := (&model.Post{}).CountBy(s.db, predicates)
total, err := (&dbr.Post{}).CountBy(s.db, predicates)
if err != nil {
return nil, err
}
return &rest.IndexTweetsResp{
return &core.IndexTweetList{
Tweets: formatPosts,
Total: total,
}, nil

@ -1,3 +1,7 @@
// 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.
// Core service implement base gorm+mysql/postgresql/sqlite3.
// Jinzhu is the primary developer of gorm so use his name as
// package name as a saluter.

@ -1,8 +1,12 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package jinzhu
import (
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"gorm.io/gorm"
)
@ -20,37 +24,37 @@ func newMessageService(db *gorm.DB) core.MessageService {
}
}
func (d *messageServant) CreateMessage(msg *model.Message) (*model.Message, error) {
func (d *messageServant) CreateMessage(msg *core.Message) (*core.Message, error) {
return msg.Create(d.db)
}
func (d *messageServant) GetUnreadCount(userID int64) (int64, error) {
return (&model.Message{}).Count(d.db, &model.ConditionsT{
return (&dbr.Message{}).Count(d.db, &dbr.ConditionsT{
"receiver_user_id": userID,
"is_read": model.MsgStatusUnread,
"is_read": dbr.MsgStatusUnread,
})
}
func (d *messageServant) GetMessageByID(id int64) (*model.Message, error) {
return (&model.Message{
Model: &model.Model{
func (d *messageServant) GetMessageByID(id int64) (*core.Message, error) {
return (&dbr.Message{
Model: &dbr.Model{
ID: id,
},
}).Get(d.db)
}
func (d *messageServant) ReadMessage(message *model.Message) error {
func (d *messageServant) ReadMessage(message *core.Message) error {
message.IsRead = 1
return message.Update(d.db)
}
func (d *messageServant) GetMessages(conditions *model.ConditionsT, offset, limit int) ([]*model.MessageFormated, error) {
messages, err := (&model.Message{}).List(d.db, conditions, offset, limit)
func (d *messageServant) GetMessages(conditions *core.ConditionsT, offset, limit int) ([]*core.MessageFormated, error) {
messages, err := (&dbr.Message{}).List(d.db, conditions, offset, limit)
if err != nil {
return nil, err
}
mfs := []*model.MessageFormated{}
mfs := []*dbr.MessageFormated{}
for _, message := range messages {
mf := message.Format()
mfs = append(mfs, mf)
@ -59,6 +63,6 @@ func (d *messageServant) GetMessages(conditions *model.ConditionsT, offset, limi
return mfs, nil
}
func (d *messageServant) GetMessageCount(conditions *model.ConditionsT) (int64, error) {
return (&model.Message{}).Count(d.db, conditions)
func (d *messageServant) GetMessageCount(conditions *core.ConditionsT) (int64, error) {
return (&dbr.Message{}).Count(d.db, conditions)
}

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package jinzhu
import (
@ -10,7 +14,7 @@ import (
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"github.com/rocboss/paopao-ce/pkg/json"
"gopkg.in/resty.v1"
"gorm.io/gorm"
@ -36,14 +40,14 @@ type juhePhoneCaptchaRsp struct {
}
// 获取最新短信验证码
func (s *securityServant) GetLatestPhoneCaptcha(phone string) (*model.Captcha, error) {
return (&model.Captcha{
func (s *securityServant) GetLatestPhoneCaptcha(phone string) (*core.Captcha, error) {
return (&dbr.Captcha{
Phone: phone,
}).Get(s.db)
}
// 更新短信验证码
func (s *securityServant) UsePhoneCaptcha(captcha *model.Captcha) error {
func (s *securityServant) UsePhoneCaptcha(captcha *core.Captcha) error {
captcha.UseTimes++
return captcha.Update(s.db)
}
@ -82,7 +86,7 @@ func (s *securityServant) SendPhoneCaptcha(phone string) error {
}
// 写入表
captchaModel := &model.Captcha{
captchaModel := &dbr.Captcha{
Phone: phone,
Captcha: strconv.Itoa(captcha),
ExpiredOn: time.Now().Add(time.Minute * time.Duration(m)).Unix(),

@ -1,10 +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 jinzhu
import (
"strings"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"gorm.io/gorm"
)
@ -22,28 +26,28 @@ func newTopicService(db *gorm.DB) core.TopicService {
}
}
func (s *topicServant) CreateTag(tag *model.Tag) (*model.Tag, error) {
func (s *topicServant) CreateTag(tag *core.Tag) (*core.Tag, error) {
return createTag(s.db, tag)
}
func (s *topicServant) DeleteTag(tag *model.Tag) error {
func (s *topicServant) DeleteTag(tag *core.Tag) error {
return deleteTag(s.db, tag)
}
func (s *topicServant) GetTags(conditions *model.ConditionsT, offset, limit int) ([]*model.Tag, error) {
return (&model.Tag{}).List(s.db, conditions, offset, limit)
func (s *topicServant) GetTags(conditions *core.ConditionsT, offset, limit int) ([]*core.Tag, error) {
return (&dbr.Tag{}).List(s.db, conditions, offset, limit)
}
func (s *topicServant) GetTagsByKeyword(keyword string) ([]*model.Tag, error) {
tag := &model.Tag{}
func (s *topicServant) GetTagsByKeyword(keyword string) ([]*core.Tag, error) {
tag := &dbr.Tag{}
keyword = "%" + strings.Trim(keyword, " ") + "%"
if keyword == "%%" {
return tag.List(s.db, &model.ConditionsT{
return tag.List(s.db, &dbr.ConditionsT{
"ORDER": "quote_num DESC",
}, 0, 6)
} else {
return tag.List(s.db, &model.ConditionsT{
return tag.List(s.db, &dbr.ConditionsT{
"tag LIKE ?": keyword,
"ORDER": "quote_num DESC",
}, 0, 6)

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package jinzhu
import (
@ -5,7 +9,7 @@ import (
"time"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"gorm.io/gorm"
)
@ -48,7 +52,7 @@ func newTweetHelpService(db *gorm.DB) core.TweetHelpService {
}
// MergePosts post数据整合
func (s *tweetHelpServant) MergePosts(posts []*model.Post) ([]*model.PostFormated, error) {
func (s *tweetHelpServant) MergePosts(posts []*core.Post) ([]*core.PostFormated, error) {
postIds := make([]int64, 0, len(posts))
userIds := make([]int64, 0, len(posts))
for _, post := range posts {
@ -66,18 +70,18 @@ func (s *tweetHelpServant) MergePosts(posts []*model.Post) ([]*model.PostFormate
return nil, err
}
userMap := make(map[int64]*model.UserFormated, len(users))
userMap := make(map[int64]*dbr.UserFormated, len(users))
for _, user := range users {
userMap[user.ID] = user.Format()
}
contentMap := make(map[int64][]*model.PostContentFormated, len(postContents))
contentMap := make(map[int64][]*dbr.PostContentFormated, len(postContents))
for _, content := range postContents {
contentMap[content.PostID] = append(contentMap[content.PostID], content.Format())
}
// 数据整合
postsFormated := make([]*model.PostFormated, 0, len(posts))
postsFormated := make([]*dbr.PostFormated, 0, len(posts))
for _, post := range posts {
postFormated := post.Format()
postFormated.User = userMap[post.UserID]
@ -88,7 +92,7 @@ func (s *tweetHelpServant) MergePosts(posts []*model.Post) ([]*model.PostFormate
}
// RevampPosts post数据整形修复
func (s *tweetHelpServant) RevampPosts(posts []*model.PostFormated) ([]*model.PostFormated, error) {
func (s *tweetHelpServant) RevampPosts(posts []*core.PostFormated) ([]*core.PostFormated, error) {
postIds := make([]int64, 0, len(posts))
userIds := make([]int64, 0, len(posts))
for _, post := range posts {
@ -106,12 +110,12 @@ func (s *tweetHelpServant) RevampPosts(posts []*model.PostFormated) ([]*model.Po
return nil, err
}
userMap := make(map[int64]*model.UserFormated, len(users))
userMap := make(map[int64]*dbr.UserFormated, len(users))
for _, user := range users {
userMap[user.ID] = user.Format()
}
contentMap := make(map[int64][]*model.PostContentFormated, len(postContents))
contentMap := make(map[int64][]*dbr.PostContentFormated, len(postContents))
for _, content := range postContents {
contentMap[content.PostID] = append(contentMap[content.PostID], content.Format())
}
@ -124,23 +128,23 @@ func (s *tweetHelpServant) RevampPosts(posts []*model.PostFormated) ([]*model.Po
return posts, nil
}
func (s *tweetHelpServant) getPostContentsByIDs(ids []int64) ([]*model.PostContent, error) {
return (&model.PostContent{}).List(s.db, &model.ConditionsT{
func (s *tweetHelpServant) getPostContentsByIDs(ids []int64) ([]*dbr.PostContent, error) {
return (&dbr.PostContent{}).List(s.db, &dbr.ConditionsT{
"post_id IN ?": ids,
"ORDER": "sort ASC",
}, 0, 0)
}
func (s *tweetHelpServant) getUsersByIDs(ids []int64) ([]*model.User, error) {
user := &model.User{}
func (s *tweetHelpServant) getUsersByIDs(ids []int64) ([]*dbr.User, error) {
user := &dbr.User{}
return user.List(s.db, &model.ConditionsT{
return user.List(s.db, &dbr.ConditionsT{
"id IN ?": ids,
}, 0, 0)
}
func (s *tweetManageServant) CreatePostCollection(postID, userID int64) (*model.PostCollection, error) {
collection := &model.PostCollection{
func (s *tweetManageServant) CreatePostCollection(postID, userID int64) (*core.PostCollection, error) {
collection := &dbr.PostCollection{
PostID: postID,
UserID: userID,
}
@ -148,19 +152,19 @@ func (s *tweetManageServant) CreatePostCollection(postID, userID int64) (*model.
return collection.Create(s.db)
}
func (s *tweetManageServant) DeletePostCollection(p *model.PostCollection) error {
func (s *tweetManageServant) DeletePostCollection(p *core.PostCollection) error {
return p.Delete(s.db)
}
func (s *tweetManageServant) CreatePostContent(content *model.PostContent) (*model.PostContent, error) {
func (s *tweetManageServant) CreatePostContent(content *core.PostContent) (*core.PostContent, error) {
return content.Create(s.db)
}
func (s *tweetManageServant) CreateAttachment(attachment *model.Attachment) (*model.Attachment, error) {
func (s *tweetManageServant) CreateAttachment(attachment *core.Attachment) (*core.Attachment, error) {
return attachment.Create(s.db)
}
func (s *tweetManageServant) CreatePost(post *model.Post) (*model.Post, error) {
func (s *tweetManageServant) CreatePost(post *core.Post) (*core.Post, error) {
post.LatestRepliedOn = time.Now().Unix()
p, err := post.Create(s.db)
if err != nil {
@ -170,11 +174,11 @@ func (s *tweetManageServant) CreatePost(post *model.Post) (*model.Post, error) {
return p, nil
}
func (s *tweetManageServant) DeletePost(post *model.Post) ([]string, error) {
func (s *tweetManageServant) DeletePost(post *core.Post) ([]string, error) {
var mediaContents []string
postId := post.ID
postContent := &model.PostContent{}
postContent := &dbr.PostContent{}
err := s.db.Transaction(
func(tx *gorm.DB) error {
if contents, err := postContent.MediaContentsByPostId(tx, postId); err == nil {
@ -218,8 +222,8 @@ func (s *tweetManageServant) DeletePost(post *model.Post) ([]string, error) {
}
func (s *tweetManageServant) deleteCommentByPostId(db *gorm.DB, postId int64) ([]string, error) {
comment := &model.Comment{}
commentContent := &model.CommentContent{}
comment := &dbr.Comment{}
commentContent := &dbr.CommentContent{}
// 获取推文的所有评论id
commentIds, err := comment.CommentIdsByPostId(db, postId)
@ -244,19 +248,19 @@ func (s *tweetManageServant) deleteCommentByPostId(db *gorm.DB, postId int64) ([
}
// 删评论的评论
if err = (&model.CommentReply{}).DeleteByCommentIds(db, commentIds); err != nil {
if err = (&dbr.CommentReply{}).DeleteByCommentIds(db, commentIds); err != nil {
return nil, err
}
return mediaContents, nil
}
func (s *tweetManageServant) LockPost(post *model.Post) error {
func (s *tweetManageServant) LockPost(post *core.Post) error {
post.IsLock = 1 - post.IsLock
return post.Update(s.db)
}
func (s *tweetManageServant) StickPost(post *model.Post) error {
func (s *tweetManageServant) StickPost(post *core.Post) error {
post.IsTop = 1 - post.IsTop
if err := post.Update(s.db); err != nil {
return err
@ -265,7 +269,7 @@ func (s *tweetManageServant) StickPost(post *model.Post) error {
return nil
}
func (s *tweetManageServant) VisiblePost(post *model.Post, visibility model.PostVisibleT) error {
func (s *tweetManageServant) VisiblePost(post *core.Post, visibility core.PostVisibleT) error {
oldVisibility := post.Visibility
post.Visibility = visibility
// TODO: 这个判断是否可以不要呢
@ -273,7 +277,7 @@ func (s *tweetManageServant) VisiblePost(post *model.Post, visibility model.Post
return nil
}
// 私密推文 特殊处理
if visibility == model.PostVisitPrivate {
if visibility == dbr.PostVisitPrivate {
// 强制取消置顶
// TODO: 置顶推文用户是否有权设置成私密? 后续完善
post.IsTop = 0
@ -288,14 +292,14 @@ func (s *tweetManageServant) VisiblePost(post *model.Post, visibility model.Post
// tag处理
tags := strings.Split(post.Tags, ",")
for _, t := range tags {
tag := &model.Tag{
tag := &dbr.Tag{
Tag: t,
}
// TODO: 暂时宽松不处理错误,这里或许可以有优化,后续完善
if oldVisibility == model.PostVisitPrivate {
if oldVisibility == dbr.PostVisitPrivate {
// 从私密转为非私密才需要重新创建tag
createTag(db, tag)
} else if visibility == model.PostVisitPrivate {
} else if visibility == dbr.PostVisitPrivate {
// 从非私密转为私密才需要删除tag
deleteTag(db, tag)
}
@ -305,7 +309,7 @@ func (s *tweetManageServant) VisiblePost(post *model.Post, visibility model.Post
return nil
}
func (s *tweetManageServant) UpdatePost(post *model.Post) error {
func (s *tweetManageServant) UpdatePost(post *core.Post) error {
if err := post.Update(s.db); err != nil {
return err
}
@ -313,104 +317,104 @@ func (s *tweetManageServant) UpdatePost(post *model.Post) error {
return nil
}
func (s *tweetManageServant) CreatePostStar(postID, userID int64) (*model.PostStar, error) {
star := &model.PostStar{
func (s *tweetManageServant) CreatePostStar(postID, userID int64) (*core.PostStar, error) {
star := &dbr.PostStar{
PostID: postID,
UserID: userID,
}
return star.Create(s.db)
}
func (s *tweetManageServant) DeletePostStar(p *model.PostStar) error {
func (s *tweetManageServant) DeletePostStar(p *core.PostStar) error {
return p.Delete(s.db)
}
func (s *tweetServant) GetPostByID(id int64) (*model.Post, error) {
post := &model.Post{
Model: &model.Model{
func (s *tweetServant) GetPostByID(id int64) (*core.Post, error) {
post := &dbr.Post{
Model: &dbr.Model{
ID: id,
},
}
return post.Get(s.db)
}
func (s *tweetServant) GetPosts(conditions *model.ConditionsT, offset, limit int) ([]*model.Post, error) {
return (&model.Post{}).List(s.db, conditions, offset, limit)
func (s *tweetServant) GetPosts(conditions *core.ConditionsT, offset, limit int) ([]*core.Post, error) {
return (&dbr.Post{}).List(s.db, conditions, offset, limit)
}
func (s *tweetServant) GetPostCount(conditions *model.ConditionsT) (int64, error) {
return (&model.Post{}).Count(s.db, conditions)
func (s *tweetServant) GetPostCount(conditions *core.ConditionsT) (int64, error) {
return (&dbr.Post{}).Count(s.db, conditions)
}
func (s *tweetServant) GetUserPostStar(postID, userID int64) (*model.PostStar, error) {
star := &model.PostStar{
func (s *tweetServant) GetUserPostStar(postID, userID int64) (*core.PostStar, error) {
star := &dbr.PostStar{
PostID: postID,
UserID: userID,
}
return star.Get(s.db)
}
func (s *tweetServant) GetUserPostStars(userID int64, offset, limit int) ([]*model.PostStar, error) {
star := &model.PostStar{
func (s *tweetServant) GetUserPostStars(userID int64, offset, limit int) ([]*core.PostStar, error) {
star := &dbr.PostStar{
UserID: userID,
}
return star.List(s.db, &model.ConditionsT{
return star.List(s.db, &dbr.ConditionsT{
"ORDER": s.db.NamingStrategy.TableName("PostStar") + ".id DESC",
}, offset, limit)
}
func (s *tweetServant) GetUserPostStarCount(userID int64) (int64, error) {
star := &model.PostStar{
star := &dbr.PostStar{
UserID: userID,
}
return star.Count(s.db, &model.ConditionsT{})
return star.Count(s.db, &dbr.ConditionsT{})
}
func (s *tweetServant) GetUserPostCollection(postID, userID int64) (*model.PostCollection, error) {
star := &model.PostCollection{
func (s *tweetServant) GetUserPostCollection(postID, userID int64) (*core.PostCollection, error) {
star := &dbr.PostCollection{
PostID: postID,
UserID: userID,
}
return star.Get(s.db)
}
func (s *tweetServant) GetUserPostCollections(userID int64, offset, limit int) ([]*model.PostCollection, error) {
collection := &model.PostCollection{
func (s *tweetServant) GetUserPostCollections(userID int64, offset, limit int) ([]*core.PostCollection, error) {
collection := &dbr.PostCollection{
UserID: userID,
}
return collection.List(s.db, &model.ConditionsT{
return collection.List(s.db, &dbr.ConditionsT{
"ORDER": s.db.NamingStrategy.TableName("PostCollection") + ".id DESC",
}, offset, limit)
}
func (s *tweetServant) GetUserPostCollectionCount(userID int64) (int64, error) {
collection := &model.PostCollection{
collection := &dbr.PostCollection{
UserID: userID,
}
return collection.Count(s.db, &model.ConditionsT{})
return collection.Count(s.db, &dbr.ConditionsT{})
}
func (s *tweetServant) GetUserWalletBills(userID int64, offset, limit int) ([]*model.WalletStatement, error) {
statement := &model.WalletStatement{
func (s *tweetServant) GetUserWalletBills(userID int64, offset, limit int) ([]*core.WalletStatement, error) {
statement := &dbr.WalletStatement{
UserID: userID,
}
return statement.List(s.db, &model.ConditionsT{
return statement.List(s.db, &dbr.ConditionsT{
"ORDER": "id DESC",
}, offset, limit)
}
func (s *tweetServant) GetUserWalletBillCount(userID int64) (int64, error) {
statement := &model.WalletStatement{
statement := &dbr.WalletStatement{
UserID: userID,
}
return statement.Count(s.db, &model.ConditionsT{})
return statement.Count(s.db, &dbr.ConditionsT{})
}
func (s *tweetServant) GetPostAttatchmentBill(postID, userID int64) (*model.PostAttachmentBill, error) {
bill := &model.PostAttachmentBill{
func (s *tweetServant) GetPostAttatchmentBill(postID, userID int64) (*core.PostAttachmentBill, error) {
bill := &dbr.PostAttachmentBill{
PostID: postID,
UserID: userID,
}
@ -418,16 +422,16 @@ func (s *tweetServant) GetPostAttatchmentBill(postID, userID int64) (*model.Post
return bill.Get(s.db)
}
func (s *tweetServant) GetPostContentsByIDs(ids []int64) ([]*model.PostContent, error) {
return (&model.PostContent{}).List(s.db, &model.ConditionsT{
func (s *tweetServant) GetPostContentsByIDs(ids []int64) ([]*core.PostContent, error) {
return (&dbr.PostContent{}).List(s.db, &dbr.ConditionsT{
"post_id IN ?": ids,
"ORDER": "sort ASC",
}, 0, 0)
}
func (s *tweetServant) GetPostContentByID(id int64) (*model.PostContent, error) {
return (&model.PostContent{
Model: &model.Model{
func (s *tweetServant) GetPostContentByID(id int64) (*core.PostContent, error) {
return (&dbr.PostContent{
Model: &dbr.Model{
ID: id,
},
}).Get(s.db)

@ -1,10 +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 jinzhu
import (
"strings"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"gorm.io/gorm"
)
@ -22,69 +26,69 @@ func newUserManageService(db *gorm.DB) core.UserManageService {
}
}
func (s *userManageServant) GetUserByID(id int64) (*model.User, error) {
user := &model.User{
Model: &model.Model{
func (s *userManageServant) GetUserByID(id int64) (*core.User, error) {
user := &dbr.User{
Model: &dbr.Model{
ID: id,
},
}
return user.Get(s.db)
}
func (s *userManageServant) GetUserByUsername(username string) (*model.User, error) {
user := &model.User{
func (s *userManageServant) GetUserByUsername(username string) (*core.User, error) {
user := &dbr.User{
Username: username,
}
return user.Get(s.db)
}
func (s *userManageServant) GetUserByPhone(phone string) (*model.User, error) {
user := &model.User{
func (s *userManageServant) GetUserByPhone(phone string) (*core.User, error) {
user := &dbr.User{
Phone: phone,
}
return user.Get(s.db)
}
func (s *userManageServant) GetUsersByIDs(ids []int64) ([]*model.User, error) {
user := &model.User{}
return user.List(s.db, &model.ConditionsT{
func (s *userManageServant) GetUsersByIDs(ids []int64) ([]*core.User, error) {
user := &dbr.User{}
return user.List(s.db, &dbr.ConditionsT{
"id IN ?": ids,
}, 0, 0)
}
func (s *userManageServant) GetUsersByKeyword(keyword string) ([]*model.User, error) {
user := &model.User{}
func (s *userManageServant) GetUsersByKeyword(keyword string) ([]*core.User, error) {
user := &dbr.User{}
keyword = strings.Trim(keyword, " ") + "%"
if keyword == "%" {
return user.List(s.db, &model.ConditionsT{
return user.List(s.db, &dbr.ConditionsT{
"ORDER": "id ASC",
}, 0, 6)
} else {
return user.List(s.db, &model.ConditionsT{
return user.List(s.db, &dbr.ConditionsT{
"username LIKE ?": keyword,
}, 0, 6)
}
}
func (s *userManageServant) GetTagsByKeyword(keyword string) ([]*model.Tag, error) {
tag := &model.Tag{}
func (s *userManageServant) GetTagsByKeyword(keyword string) ([]*core.Tag, error) {
tag := &dbr.Tag{}
keyword = "%" + strings.Trim(keyword, " ") + "%"
if keyword == "%%" {
return tag.List(s.db, &model.ConditionsT{
return tag.List(s.db, &dbr.ConditionsT{
"ORDER": "quote_num DESC",
}, 0, 6)
} else {
return tag.List(s.db, &model.ConditionsT{
return tag.List(s.db, &dbr.ConditionsT{
"tag LIKE ?": keyword,
"ORDER": "quote_num DESC",
}, 0, 6)
}
}
func (s *userManageServant) CreateUser(user *model.User) (*model.User, error) {
func (s *userManageServant) CreateUser(user *dbr.User) (*core.User, error) {
return user.Create(s.db)
}
func (s *userManageServant) UpdateUser(user *model.User) error {
func (s *userManageServant) UpdateUser(user *core.User) error {
return user.Update(s.db)
}

@ -1,11 +1,15 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package jinzhu
import (
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"gorm.io/gorm"
)
func createTag(db *gorm.DB, tag *model.Tag) (*model.Tag, error) {
func createTag(db *gorm.DB, tag *dbr.Tag) (*dbr.Tag, error) {
t, err := tag.Get(db)
if err != nil {
tag.QuoteNum = 1
@ -23,7 +27,7 @@ func createTag(db *gorm.DB, tag *model.Tag) (*model.Tag, error) {
return t, nil
}
func deleteTag(db *gorm.DB, tag *model.Tag) error {
func deleteTag(db *gorm.DB, tag *dbr.Tag) error {
tag, err := tag.Get(db)
if err != nil {
return err
@ -33,7 +37,7 @@ func deleteTag(db *gorm.DB, tag *model.Tag) error {
}
func deleteTags(db *gorm.DB, tags []string) error {
allTags, err := (&model.Tag{}).TagsFrom(db, tags)
allTags, err := (&dbr.Tag{}).TagsFrom(db, tags)
if err != nil {
return err
}
@ -51,9 +55,9 @@ func deleteTags(db *gorm.DB, tags []string) error {
}
// 根据IDs获取用户列表
func getUsersByIDs(db *gorm.DB, ids []int64) ([]*model.User, error) {
user := &model.User{}
return user.List(db, &model.ConditionsT{
func getUsersByIDs(db *gorm.DB, ids []int64) ([]*dbr.User, error) {
user := &dbr.User{}
return user.List(db, &dbr.ConditionsT{
"id IN ?": ids,
}, 0, 0)
}

@ -1,9 +1,13 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package jinzhu
import (
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"gorm.io/gorm"
)
@ -21,17 +25,17 @@ func newWalletService(db *gorm.DB) core.WalletService {
}
}
func (d *walletServant) GetRechargeByID(id int64) (*model.WalletRecharge, error) {
recharge := &model.WalletRecharge{
Model: &model.Model{
func (d *walletServant) GetRechargeByID(id int64) (*core.WalletRecharge, error) {
recharge := &dbr.WalletRecharge{
Model: &dbr.Model{
ID: id,
},
}
return recharge.Get(d.db)
}
func (d *walletServant) CreateRecharge(userId, amount int64) (*model.WalletRecharge, error) {
recharge := &model.WalletRecharge{
func (d *walletServant) CreateRecharge(userId, amount int64) (*core.WalletRecharge, error) {
recharge := &dbr.WalletRecharge{
UserID: userId,
Amount: amount,
}
@ -39,26 +43,26 @@ func (d *walletServant) CreateRecharge(userId, amount int64) (*model.WalletRecha
return recharge.Create(d.db)
}
func (d *walletServant) GetUserWalletBills(userID int64, offset, limit int) ([]*model.WalletStatement, error) {
statement := &model.WalletStatement{
func (d *walletServant) GetUserWalletBills(userID int64, offset, limit int) ([]*core.WalletStatement, error) {
statement := &dbr.WalletStatement{
UserID: userID,
}
return statement.List(d.db, &model.ConditionsT{
return statement.List(d.db, &dbr.ConditionsT{
"ORDER": "id DESC",
}, offset, limit)
}
func (d *walletServant) GetUserWalletBillCount(userID int64) (int64, error) {
statement := &model.WalletStatement{
statement := &dbr.WalletStatement{
UserID: userID,
}
return statement.Count(d.db, &model.ConditionsT{})
return statement.Count(d.db, &dbr.ConditionsT{})
}
func (d *walletServant) HandleRechargeSuccess(recharge *model.WalletRecharge, tradeNo string) error {
user, _ := (&model.User{
Model: &model.Model{
func (d *walletServant) HandleRechargeSuccess(recharge *core.WalletRecharge, tradeNo string) error {
user, _ := (&dbr.User{
Model: &dbr.Model{
ID: recharge.UserID,
},
}).Get(d.db)
@ -71,7 +75,7 @@ func (d *walletServant) HandleRechargeSuccess(recharge *model.WalletRecharge, tr
}
// 新增账单
if err := tx.Create(&model.WalletStatement{
if err := tx.Create(&dbr.WalletStatement{
UserID: user.ID,
ChangeAmount: recharge.Amount,
BalanceSnapshot: user.Balance + recharge.Amount,
@ -93,7 +97,7 @@ func (d *walletServant) HandleRechargeSuccess(recharge *model.WalletRecharge, tr
})
}
func (d *walletServant) HandlePostAttachmentBought(post *model.Post, user *model.User) error {
func (d *walletServant) HandlePostAttachmentBought(post *core.Post, user *core.User) error {
return d.db.Transaction(func(tx *gorm.DB) error {
// 扣除金额
if err := tx.Model(user).Update("balance", gorm.Expr("balance - ?", post.AttachmentPrice)).Error; err != nil {
@ -102,7 +106,7 @@ func (d *walletServant) HandlePostAttachmentBought(post *model.Post, user *model
}
// 新增账单
if err := tx.Create(&model.WalletStatement{
if err := tx.Create(&dbr.WalletStatement{
PostID: post.ID,
UserID: user.ID,
ChangeAmount: -post.AttachmentPrice,
@ -113,7 +117,7 @@ func (d *walletServant) HandlePostAttachmentBought(post *model.Post, user *model
}
// 新增附件购买记录
if err := tx.Create(&model.PostAttachmentBill{
if err := tx.Create(&dbr.PostAttachmentBill{
PostID: post.ID,
UserID: user.ID,
PaidAmount: post.AttachmentPrice,
@ -124,8 +128,8 @@ func (d *walletServant) HandlePostAttachmentBought(post *model.Post, user *model
// 对附件主新增账单
income := int64(float64(post.AttachmentPrice) * conf.AppSetting.AttachmentIncomeRate)
if income > 0 {
master := &model.User{
Model: &model.Model{
master := &dbr.User{
Model: &dbr.Model{
ID: post.UserID,
},
}
@ -137,7 +141,7 @@ func (d *walletServant) HandlePostAttachmentBought(post *model.Post, user *model
}
// 新增账单
if err := tx.Create(&model.WalletStatement{
if err := tx.Create(&dbr.WalletStatement{
PostID: post.ID,
UserID: master.ID,
ChangeAmount: income,

@ -1,3 +1,7 @@
// 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.
// Core service implement base sqlx+mysql. All sub-service
// will declare here and provide initial function.

@ -1,10 +1,13 @@
// 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 search
import (
"time"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/sirupsen/logrus"
)
@ -43,7 +46,7 @@ func (s *bridgeTweetSearchServant) DeleteDocuments(identifiers []string) error {
return nil
}
func (s *bridgeTweetSearchServant) Search(user *model.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) {
func (s *bridgeTweetSearchServant) Search(user *core.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) {
return s.ts.Search(user, q, offset, limit)
}

@ -1,8 +1,11 @@
// 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 search
import (
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/pkg/types"
)
@ -10,19 +13,19 @@ type tweetSearchFilter struct {
ams core.AuthorizationManageService
}
func (s *tweetSearchFilter) filterResp(user *model.User, resp *core.QueryResp) {
func (s *tweetSearchFilter) filterResp(user *core.User, resp *core.QueryResp) {
// 管理员不过滤
if user != nil && user.IsAdmin {
return
}
var item *model.PostFormated
var item *core.PostFormated
items := resp.Items
latestIndex := len(items) - 1
if user == nil {
for i := 0; i <= latestIndex; i++ {
item = items[i]
if item.Visibility != model.PostVisitPublic {
if item.Visibility != core.PostVisitPublic {
items[i] = items[latestIndex]
items = items[:latestIndex]
resp.Total--
@ -36,8 +39,8 @@ func (s *tweetSearchFilter) filterResp(user *model.User, resp *core.QueryResp) {
friendFilter[user.ID] = types.Empty{}
for i := 0; i <= latestIndex; i++ {
item = items[i]
cutFriend = (item.Visibility == model.PostVisitFriend && !friendFilter.IsFriend(item.UserID))
cutPrivate = (item.Visibility == model.PostVisitPrivate && user.ID != item.UserID)
cutFriend = (item.Visibility == core.PostVisitFriend && !friendFilter.IsFriend(item.UserID))
cutPrivate = (item.Visibility == core.PostVisitPrivate && user.ID != item.UserID)
if cutFriend || cutPrivate {
items[i] = items[latestIndex]
items = items[:latestIndex]

@ -1,3 +1,7 @@
// 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 search
import (
@ -7,7 +11,6 @@ import (
"github.com/Masterminds/semver/v3"
"github.com/meilisearch/meilisearch-go"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/pkg/json"
"github.com/sirupsen/logrus"
)
@ -33,7 +36,7 @@ type postInfo struct {
CommentCount int64 `json:"comment_count"`
CollectionCount int64 `json:"collection_count"`
UpvoteCount int64 `json:"upvote_count"`
Visibility model.PostVisibleT `json:"visibility"`
Visibility core.PostVisibleT `json:"visibility"`
IsTop int `json:"is_top"`
IsEssence int `json:"is_essence"`
IsLock int `json:"is_lock"`
@ -78,7 +81,7 @@ func (s *meiliTweetSearchServant) DeleteDocuments(identifiers []string) error {
return nil
}
func (s *meiliTweetSearchServant) Search(user *model.User, q *core.QueryReq, offset, limit int) (resp *core.QueryResp, err error) {
func (s *meiliTweetSearchServant) Search(user *core.User, q *core.QueryReq, offset, limit int) (resp *core.QueryResp, err error) {
if q.Type == core.SearchTypeDefault && q.Query != "" {
resp, err = s.queryByContent(user, q, offset, limit)
} else if q.Type == core.SearchTypeTag && q.Query != "" {
@ -96,7 +99,7 @@ func (s *meiliTweetSearchServant) Search(user *model.User, q *core.QueryReq, off
return
}
func (s *meiliTweetSearchServant) queryByContent(user *model.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) {
func (s *meiliTweetSearchServant) queryByContent(user *core.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) {
request := &meilisearch.SearchRequest{
Offset: int64(offset),
Limit: int64(limit),
@ -117,7 +120,7 @@ func (s *meiliTweetSearchServant) queryByContent(user *model.User, q *core.Query
return s.postsFrom(resp)
}
func (s *meiliTweetSearchServant) queryByTag(user *model.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) {
func (s *meiliTweetSearchServant) queryByTag(user *core.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) {
request := &meilisearch.SearchRequest{
Offset: int64(offset),
Limit: int64(limit),
@ -141,7 +144,7 @@ func (s *meiliTweetSearchServant) queryByTag(user *model.User, q *core.QueryReq,
return s.postsFrom(resp)
}
func (s *meiliTweetSearchServant) queryAny(user *model.User, offset, limit int) (*core.QueryResp, error) {
func (s *meiliTweetSearchServant) queryAny(user *core.User, offset, limit int) (*core.QueryResp, error) {
request := &meilisearch.SearchRequest{
Offset: int64(offset),
Limit: int64(limit),
@ -161,7 +164,7 @@ func (s *meiliTweetSearchServant) queryAny(user *model.User, offset, limit int)
return s.postsFrom(resp)
}
func (s *meiliTweetSearchServant) filterList(user *model.User) string {
func (s *meiliTweetSearchServant) filterList(user *core.User) string {
if user == nil {
return s.publicFilter
}
@ -174,7 +177,7 @@ func (s *meiliTweetSearchServant) filterList(user *model.User) string {
}
func (s *meiliTweetSearchServant) postsFrom(resp *meilisearch.SearchResponse) (*core.QueryResp, error) {
posts := make([]*model.PostFormated, 0, len(resp.Hits))
posts := make([]*core.PostFormated, 0, len(resp.Hits))
for _, hit := range resp.Hits {
raw, err := json.Marshal(hit)
if err != nil {
@ -184,7 +187,7 @@ func (s *meiliTweetSearchServant) postsFrom(resp *meilisearch.SearchResponse) (*
if err = json.Unmarshal(raw, p); err != nil {
return nil, err
}
posts = append(posts, &model.PostFormated{
posts = append(posts, &core.PostFormated{
ID: p.ID,
UserID: p.UserID,
CommentCount: p.CommentCount,

@ -1,3 +1,7 @@
// 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 search
import (
@ -6,7 +10,6 @@ import (
"github.com/meilisearch/meilisearch-go"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/pkg/zinc"
"github.com/sirupsen/logrus"
)
@ -40,9 +43,9 @@ func NewMeiliTweetSearchService(ams core.AuthorizationManageService) (core.Tweet
},
client: client,
index: client.Index(s.Index),
publicFilter: fmt.Sprintf("visibility=%d", model.PostVisitPublic),
privateFilter: fmt.Sprintf("visibility=%d AND user_id=", model.PostVisitPrivate),
friendFilter: fmt.Sprintf("visibility=%d", model.PostVisitFriend),
publicFilter: fmt.Sprintf("visibility=%d", core.PostVisitPublic),
privateFilter: fmt.Sprintf("visibility=%d AND user_id=", core.PostVisitPrivate),
friendFilter: fmt.Sprintf("visibility=%d", core.PostVisitFriend),
}
return mts, mts
}
@ -55,9 +58,9 @@ func NewZincTweetSearchService(ams core.AuthorizationManageService) (core.TweetS
},
indexName: s.Index,
client: zinc.NewClient(s),
publicFilter: fmt.Sprintf("visibility:%d", model.PostVisitPublic),
privateFilter: fmt.Sprintf("visibility:%d AND user_id:%%d", model.PostVisitPrivate),
friendFilter: fmt.Sprintf("visibility:%d", model.PostVisitFriend),
publicFilter: fmt.Sprintf("visibility:%d", core.PostVisitPublic),
privateFilter: fmt.Sprintf("visibility:%d AND user_id:%%d", core.PostVisitPrivate),
friendFilter: fmt.Sprintf("visibility:%d", core.PostVisitFriend),
}
zts.createIndex()

@ -1,3 +1,7 @@
// 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 search
import (
@ -5,7 +9,6 @@ import (
"github.com/Masterminds/semver/v3"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/pkg/json"
"github.com/rocboss/paopao-ce/pkg/zinc"
"github.com/sirupsen/logrus"
@ -73,7 +76,7 @@ func (s *zincTweetSearchServant) DeleteDocuments(identifiers []string) error {
return nil
}
func (s *zincTweetSearchServant) Search(user *model.User, q *core.QueryReq, offset, limit int) (resp *core.QueryResp, err error) {
func (s *zincTweetSearchServant) Search(user *core.User, q *core.QueryReq, offset, limit int) (resp *core.QueryResp, err error) {
if q.Type == core.SearchTypeDefault && q.Query != "" {
resp, err = s.queryByContent(user, q, offset, limit)
} else if q.Type == core.SearchTypeTag && q.Query != "" {
@ -91,7 +94,7 @@ func (s *zincTweetSearchServant) Search(user *model.User, q *core.QueryReq, offs
return
}
func (s *zincTweetSearchServant) queryByContent(user *model.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) {
func (s *zincTweetSearchServant) queryByContent(user *core.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) {
resp, err := s.client.EsQuery(s.indexName, map[string]any{
"query": map[string]any{
"match_phrase": map[string]any{
@ -108,7 +111,7 @@ func (s *zincTweetSearchServant) queryByContent(user *model.User, q *core.QueryR
return s.postsFrom(resp)
}
func (s *zincTweetSearchServant) queryByTag(user *model.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) {
func (s *zincTweetSearchServant) queryByTag(user *core.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) {
resp, err := s.client.ApiQuery(s.indexName, map[string]any{
"search_type": "querystring",
"query": map[string]any{
@ -124,7 +127,7 @@ func (s *zincTweetSearchServant) queryByTag(user *model.User, q *core.QueryReq,
return s.postsFrom(resp)
}
func (s *zincTweetSearchServant) queryAny(user *model.User, offset, limit int) (*core.QueryResp, error) {
func (s *zincTweetSearchServant) queryAny(user *core.User, offset, limit int) (*core.QueryResp, error) {
queryMap := map[string]any{
"query": map[string]any{
"match_all": map[string]string{},
@ -141,9 +144,9 @@ func (s *zincTweetSearchServant) queryAny(user *model.User, offset, limit int) (
}
func (s *zincTweetSearchServant) postsFrom(resp *zinc.QueryResultT) (*core.QueryResp, error) {
posts := make([]*model.PostFormated, 0, len(resp.Hits.Hits))
posts := make([]*core.PostFormated, 0, len(resp.Hits.Hits))
for _, hit := range resp.Hits.Hits {
item := &model.PostFormated{}
item := &core.PostFormated{}
raw, err := json.Marshal(hit.Source)
if err != nil {
return nil, err

@ -1,3 +1,7 @@
// 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 security
import (

@ -1,3 +1,7 @@
// 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.
// Core service implement base sqlx+postgresql. All sub-service
// will declare here and provide initial function.

@ -1,3 +1,7 @@
// 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 storage
import (

@ -1,3 +1,7 @@
// 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 storage
import (

@ -1,3 +1,7 @@
// 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 storage
import (

@ -1,3 +1,7 @@
// 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 storage
import (

@ -1,3 +1,7 @@
// 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 storage
import (

@ -1,3 +1,7 @@
// 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 storage
import (

@ -1,9 +1,13 @@
// 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 internal
import (
"github.com/rocboss/paopao-ce/internal/migration"
"github.com/rocboss/paopao-ce/internal/routers/api"
"github.com/rocboss/paopao-ce/internal/service"
"github.com/rocboss/paopao-ce/internal/servants/web/broker"
"github.com/rocboss/paopao-ce/internal/servants/web/routers/api"
)
func Initialize() {
@ -11,6 +15,6 @@ func Initialize() {
migration.Run()
// initialize service
service.Initialize()
broker.Initialize()
api.Initialize()
}

@ -1,3 +1,7 @@
// 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.
//go:build !migration
// +build !migration

@ -1,3 +1,7 @@
// 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.
//go:build migration
// +build migration

@ -0,0 +1 @@
### RESTful API for paopao-ce use [go-mir](https://github.com/alimy/mir) to generate service interface code automatic.

@ -0,0 +1,159 @@
// Code generated by go-mir. DO NOT EDIT.
package v1
import (
"net/http"
"github.com/alimy/mir/v3"
gin "github.com/gin-gonic/gin"
)
type LoginReq struct {
AgentInfo AgentInfo `json:"agent_info"`
Name string `json:"name"`
Passwd string `json:"passwd"`
}
type AgentInfo struct {
Platform string `json:"platform"`
UserAgent string `json:"user_agent"`
}
type LoginResp struct {
UserInfo
ServerInfo ServerInfo `json:"server_info"`
JwtToken string `json:"jwt_token"`
}
type ServerInfo struct {
ApiVer string `json:"api_ver"`
}
type UserInfo struct {
Name string `json:"name"`
}
type WebCore interface {
// Chain provide handlers chain for gin
Chain() gin.HandlersChain
Logout(c *gin.Context) mir.Error
Login(c *gin.Context, req *LoginReq) (*LoginResp, mir.Error)
Articles(c *gin.Context) mir.Error
Index(c *gin.Context) mir.Error
mustEmbedUnimplementedWebCoreServant()
}
type WebCoreBinding interface {
BindLogin(c *gin.Context) (*LoginReq, mir.Error)
mustEmbedUnimplementedWebCoreBinding()
}
type WebCoreRender interface {
RenderLogout(c *gin.Context, err mir.Error)
RenderLogin(c *gin.Context, data *LoginResp, err mir.Error)
RenderArticles(c *gin.Context, err mir.Error)
RenderIndex(c *gin.Context, err mir.Error)
mustEmbedUnimplementedWebCoreRender()
}
// RegisterWebCoreServant register WebCore servant to gin
func RegisterWebCoreServant(e *gin.Engine, s WebCore, b WebCoreBinding, r WebCoreRender) {
router := e.Group("v1")
// use chain for router
middlewares := s.Chain()
router.Use(middlewares...)
// register routes info to router
router.Handle("POST", "/user/logout/", func(c *gin.Context) {
r.RenderLogout(c, s.Logout(c))
})
router.Handle("POST", "/user/login/", func(c *gin.Context) {
req, err := b.BindLogin(c)
if err != nil {
r.RenderLogin(c, nil, err)
}
resp, err := s.Login(c, req)
r.RenderLogin(c, resp, err)
})
{
h := func(c *gin.Context) {
r.RenderArticles(c, s.Articles(c))
}
router.Handle("HEAD", "/articles/:category/", h)
router.Handle("GET", "/articles/:category/", h)
}
router.Handle("GET", "/index/", func(c *gin.Context) {
r.RenderIndex(c, s.Index(c))
})
}
// UnimplementedWebCoreServant can be embedded to have forward compatible implementations.
type UnimplementedWebCoreServant struct {
}
func (UnimplementedWebCoreServant) Chain() gin.HandlersChain {
return nil
}
func (UnimplementedWebCoreServant) Logout(c *gin.Context) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedWebCoreServant) Login(c *gin.Context, req *LoginReq) (*LoginResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedWebCoreServant) Articles(c *gin.Context) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedWebCoreServant) Index(c *gin.Context) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedWebCoreServant) mustEmbedUnimplementedWebCoreServant() {}
// UnimplementedWebCoreRender can be embedded to have forward compatible implementations.
type UnimplementedWebCoreRender struct {
RenderAny func(*gin.Context, any, mir.Error)
}
func (r *UnimplementedWebCoreRender) RenderLogout(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedWebCoreRender) RenderLogin(c *gin.Context, data *LoginResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedWebCoreRender) RenderArticles(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedWebCoreRender) RenderIndex(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedWebCoreRender) mustEmbedUnimplementedWebCoreRender() {}
// UnimplementedWebCoreBinding can be embedded to have forward compatible implementations.
type UnimplementedWebCoreBinding struct {
BindAny func(*gin.Context, any) mir.Error
}
func (b *UnimplementedWebCoreBinding) BindLogin(c *gin.Context) (*LoginReq, mir.Error) {
obj := new(LoginReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedWebCoreBinding) mustEmbedUnimplementedWebCoreBinding() {}

@ -0,0 +1,28 @@
// 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 main
import (
"log"
. "github.com/alimy/mir/v3/core"
. "github.com/alimy/mir/v3/engine"
_ "github.com/rocboss/paopao-ce/internal/mirc/routes/v1"
)
//go:generate go run main.go
func main() {
log.Println("generate code start")
opts := Options{
RunMode(InSerialDebugMode),
GeneratorName(GeneratorGin),
SinkPath("auto"),
}
if err := Generate(opts); err != nil {
log.Fatal(err)
}
log.Println("generate code finish")
}

@ -0,0 +1 @@
### RESTful API for paopao-ce

@ -0,0 +1,15 @@
package v1
import (
. "github.com/alimy/mir/v3"
. "github.com/alimy/mir/v3/engine"
)
func init() {
AddEntry(new(LocalOSS))
}
type LocalOSS struct {
Chain Chain `mir:"-"`
Group Group `mir:"v1"`
}

@ -0,0 +1,15 @@
package v1
import (
. "github.com/alimy/mir/v3"
. "github.com/alimy/mir/v3/engine"
)
func init() {
AddEntry(new(WebAdmin))
}
type WebAdmin struct {
Chain Chain `mir:"-"`
Group Group `mir:"v1"`
}

@ -0,0 +1,15 @@
package v1
import (
. "github.com/alimy/mir/v3"
. "github.com/alimy/mir/v3/engine"
)
func init() {
AddEntry(new(WebAlipay))
}
type WebAlipay struct {
Chain Chain `mir:"-"`
Group Group `mir:"v1"`
}

@ -0,0 +1,44 @@
package v1
import (
. "github.com/alimy/mir/v3"
. "github.com/alimy/mir/v3/engine"
)
func init() {
AddEntry(new(WebCore))
}
type AgentInfo struct {
Platform string `json:"platform"`
UserAgent string `json:"user_agent"`
}
type ServerInfo struct {
ApiVer string `json:"api_ver"`
}
type UserInfo struct {
Name string `json:"name"`
}
type LoginReq struct {
AgentInfo AgentInfo `json:"agent_info"`
Name string `json:"name"`
Passwd string `json:"passwd"`
}
type LoginResp struct {
UserInfo
ServerInfo ServerInfo `json:"server_info"`
JwtToken string `json:"jwt_token"`
}
type WebCore struct {
Chain Chain `mir:"-"`
Group Group `mir:"v1"`
Index func(Get) `mir:"/index/"`
Articles func(Get, Head) `mir:"/articles/:category/"`
Login func(Post, LoginReq) LoginResp `mir:"/user/login/"`
Logout func(Post) `mir:"/user/logout/"`
}

@ -0,0 +1,15 @@
package v1
import (
. "github.com/alimy/mir/v3"
. "github.com/alimy/mir/v3/engine"
)
func init() {
AddEntry(new(WebFollowship))
}
type WebFollowship struct {
Chain Chain `mir:"-"`
Group Group `mir:"v1"`
}

@ -0,0 +1,15 @@
package v1
import (
. "github.com/alimy/mir/v3"
. "github.com/alimy/mir/v3/engine"
)
func init() {
AddEntry(new(WebFriendship))
}
type WebFriendship struct {
Chain Chain `mir:"-"`
Group Group `mir:"v1"`
}

@ -0,0 +1,15 @@
package v1
import (
. "github.com/alimy/mir/v3"
. "github.com/alimy/mir/v3/engine"
)
func init() {
AddEntry(new(WebLoose))
}
type WebLoose struct {
Chain Chain `mir:"-"`
Group Group `mir:"v1"`
}

@ -0,0 +1,15 @@
package v1
import (
. "github.com/alimy/mir/v3"
. "github.com/alimy/mir/v3/engine"
)
func init() {
AddEntry(new(WebPriv))
}
type WebPriv struct {
Chain Chain `mir:"-"`
Group Group `mir:"v1"`
}

@ -0,0 +1,15 @@
package v1
import (
. "github.com/alimy/mir/v3"
. "github.com/alimy/mir/v3/engine"
)
func init() {
AddEntry(new(WebPub))
}
type WebPub struct {
Chain Chain `mir:"-"`
Group Group `mir:"v1"`
}

@ -1,31 +0,0 @@
package rest
type RequestingFriendReq struct {
UserId int64 `json:"user_id" binding:"required"`
Greetings string `json:"greetings" binding:"required"`
}
type AddFriendReq struct {
UserId int64 `json:"user_id" binding:"required"`
}
type RejectFriendReq struct {
UserId int64 `json:"user_id" binding:"required"`
}
type DeleteFriendReq struct {
UserId int64 `json:"user_id"`
}
type ContactItem struct {
UserId int64 `json:"user_id"`
UserName string `json:"username"`
Nickname string `json:"nickname"`
Avatar string `json:"avatar"`
Phone string `json:"phone"`
}
type ContactsResp struct {
Contacts []ContactItem `json:"contacts"`
Total int64 `json:"total"`
}

@ -1,8 +0,0 @@
package rest
import "github.com/rocboss/paopao-ce/internal/model"
type IndexTweetsResp struct {
Tweets []*model.PostFormated
Total int64
}

@ -1,11 +0,0 @@
package rest
type UserProfileResp struct {
ID int64 `json:"id"`
Nickname string `json:"nickname"`
Username string `json:"username"`
Status int `json:"status"`
Avatar string `json:"avatar"`
IsAdmin bool `json:"is_admin"`
IsFriend bool `json:"is_friend"`
}

@ -0,0 +1,2 @@
### gRPC API
This directory contain some gRPC API define files.

@ -0,0 +1,5 @@
// 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 proto

@ -0,0 +1,10 @@
syntax = "proto3";
package paopao;
option go_package = "proto";
message Tag {
string name = 1;
int32 type = 2;
}

@ -0,0 +1,77 @@
// 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 base
import (
"net/http"
"os"
"github.com/alimy/mir/v3"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/pkg/xerror"
)
type BaseServant struct {
// TODO
}
type BaseBinding struct {
// TODO
}
type BaseRender struct {
// TODO
}
func (BaseServant) userFrom(c *gin.Context) (*core.User, bool) {
if u, exists := c.Get("USER"); exists {
user, ok := u.(*core.User)
return user, ok
}
return nil, false
}
func BindAny(c *gin.Context, obj any) mir.Error {
var errs xerror.ValidErrors
err := c.ShouldBind(obj)
if err != nil {
return mir.NewError(xerror.InvalidParams.Code(), xerror.InvalidParams.WithDetails(errs.Error()))
}
return nil
}
func RenderAny(c *gin.Context, data any, err mir.Error) {
if err == nil {
hostname, _ := os.Hostname()
if data == nil {
data = gin.H{
"code": 0,
"msg": "success",
"tracehost": hostname,
}
} else {
data = gin.H{
"code": 0,
"msg": "success",
"data": data,
"tracehost": hostname,
}
}
c.JSON(http.StatusOK, data)
} else {
// TODO: error process logic
resp := gin.H{"code": err.StatusCode(), "msg": err.Error()}
// xerr := &xerror.Error{}
// if errors.As(err, xerr) {
// resp["code"], resp["msg"] = xerr.Code(), xerr.Msg()
// details := xerr.Details()
// if len(details) > 0 {
// resp["details"] = details
// }
// }
c.JSON(http.StatusInternalServerError, resp)
}
}

@ -1,8 +1,12 @@
package middleware
// 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 chain
import (
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/pkg/app"
"github.com/rocboss/paopao-ce/pkg/errcode"
)
@ -10,8 +14,8 @@ import (
func Admin() gin.HandlerFunc {
return func(c *gin.Context) {
if user, exist := c.Get("USER"); exist {
if userModel, ok := user.(*model.User); ok {
if userModel.Status == model.UserStatusNormal && userModel.IsAdmin {
if userModel, ok := user.(*core.User); ok {
if userModel.Status == core.UserStatusNormal && userModel.IsAdmin {
c.Next()
return
}

@ -1,4 +1,8 @@
package middleware
// 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 chain
import (
"strings"
@ -6,7 +10,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt/v4"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/pkg/app"
"github.com/rocboss/paopao-ce/pkg/errcode"
)
@ -51,8 +55,8 @@ func JWT() gin.HandlerFunc {
c.Set("USERNAME", claims.Username)
// 加载用户信息
user := &model.User{
Model: &model.Model{
user := &core.User{
Model: &core.Model{
ID: claims.UID,
},
}
@ -97,8 +101,8 @@ func JwtLoose() gin.HandlerFunc {
c.Set("UID", claims.UID)
c.Set("USERNAME", claims.Username)
// 加载用户信息
user := &model.User{
Model: &model.Model{
user := &core.User{
Model: &core.Model{
ID: claims.UID,
},
}

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

Loading…
Cancel
Save