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) @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 @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: clean:
@go clean @go clean
@find ./release -type f -exec rm -r {} + @find ./release -type f -exec rm -r {} +

@ -1,4 +1,5 @@
App: # APP基础设置项 App: # APP基础设置项
RunMode: debug
AttachmentIncomeRate: 0.8 AttachmentIncomeRate: 0.8
MaxCommentCount: 10 MaxCommentCount: 10
DefaultContextTimeout: 60 DefaultContextTimeout: 60
@ -17,8 +18,19 @@ Features:
Slim: ["Base", "Sqlite3", "LocalOSS", "LoggerFile", "OSS:TempDir"] Slim: ["Base", "Sqlite3", "LocalOSS", "LoggerFile", "OSS:TempDir"]
Base: ["Redis", "PhoneBind"] Base: ["Redis", "PhoneBind"]
Docs: ["Docs:OpenAPI"] Docs: ["Docs:OpenAPI"]
Deprecated: ["Deprecated:OldWeb"]
Option: ["SimpleCacheIndex"] Option: ["SimpleCacheIndex"]
Sms: "SmsJuhe" 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: SmsJuhe:
Gateway: https://v.juhe.cn/sms/send Gateway: https://v.juhe.cn/sms/send
Key: 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 //go:build docs
// +build docs // +build docs

@ -5,6 +5,7 @@ go 1.18
require ( require (
github.com/Masterminds/semver/v3 v3.1.1 github.com/Masterminds/semver/v3 v3.1.1
github.com/afocus/captcha v0.0.0-20191010092841-4bd1f21c8868 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/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible
github.com/allegro/bigcache/v3 v3.0.2 github.com/allegro/bigcache/v3 v3.0.2
github.com/bytedance/sonic v1.5.0 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/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 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/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 h1:9gWa46nstkJ9miBReJcN8Gq34cBFbzSpQZVVT9N09TM=
github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= 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= 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 package conf
import ( import (
@ -20,6 +24,8 @@ var (
PostgresSetting *PostgresSettingS PostgresSetting *PostgresSettingS
Sqlite3Setting *Sqlite3SettingS Sqlite3Setting *Sqlite3SettingS
ServerSetting *ServerSettingS ServerSetting *ServerSettingS
WebServerSetting *ServerSettingS
DocsServerSetting *ServerSettingS
AppSetting *AppSettingS AppSetting *AppSettingS
CacheIndexSetting *CacheIndexSettingS CacheIndexSetting *CacheIndexSettingS
SimpleCacheIndexSetting *SimpleCacheIndexSettingS SimpleCacheIndexSetting *SimpleCacheIndexSettingS
@ -56,6 +62,8 @@ func setupSetting(suite []string, noDefault bool) error {
objects := map[string]any{ objects := map[string]any{
"App": &AppSetting, "App": &AppSetting,
"Server": &ServerSetting, "Server": &ServerSetting,
"WebServer": &WebServerSetting,
"DocsServer": &DocsServerSetting,
"CacheIndex": &CacheIndexSetting, "CacheIndex": &CacheIndexSetting,
"SimpleCacheIndex": &SimpleCacheIndexSetting, "SimpleCacheIndex": &SimpleCacheIndexSetting,
"BigCacheIndex": &BigCacheIndexSetting, "BigCacheIndex": &BigCacheIndexSetting,
@ -134,3 +142,10 @@ func GetOssDomain() string {
} }
return uri + AliOSSSetting.Domain + "/" 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 package conf
import ( 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 //go:build cgo
// +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 //go:build !cgo
// +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 package conf
import ( 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 package conf
import ( 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 package conf
import ( 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 package conf
import ( import (
@ -50,6 +54,7 @@ type ServerSettingS struct {
} }
type AppSettingS struct { type AppSettingS struct {
RunMode string
MaxCommentCount int64 MaxCommentCount int64
AttachmentIncomeRate float64 AttachmentIncomeRate float64
DefaultContextTimeout time.Duration 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 package core
import ( import (
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/pkg/types" "github.com/rocboss/paopao-ce/pkg/types"
) )
@ -33,23 +36,17 @@ const (
ActCreateActivationCode ActCreateActivationCode
) )
type act uint8 type (
act uint8
type FriendFilter map[int64]types.Empty
type FriendSet map[string]types.Empty
type Action struct { FriendFilter map[int64]types.Empty
Act act FriendSet map[string]types.Empty
UserId int64
}
// AuthorizationManageService 授权管理服务 Action struct {
type AuthorizationManageService interface { Act act
IsAllow(user *model.User, action *Action) bool UserId int64
BeFriendFilter(userId int64) FriendFilter }
BeFriendIds(userId int64) ([]int64, error) )
MyFriendSet(userId int64) FriendSet
}
func (f FriendFilter) IsFriend(userId int64) bool { func (f FriendFilter) IsFriend(userId int64) bool {
_, yeah := f[userId] _, yeah := f[userId]
@ -57,7 +54,7 @@ func (f FriendFilter) IsFriend(userId int64) bool {
} }
// IsAllow default true if user is admin // 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 { if user.IsAdmin {
return true return true
} }
@ -116,3 +113,11 @@ func (a act) IsAllow(user *model.User, userId int64, isFriend bool, isActivation
return false 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 package core
import "github.com/rocboss/paopao-ce/internal/model" import (
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
)
const ( const (
IdxActNop IdxAct = iota + 1 IdxActNop IdxAct = iota + 1
@ -15,7 +21,7 @@ type IdxAct uint8
type IndexAction struct { type IndexAction struct {
Act IdxAct Act IdxAct
Post *model.Post Post *dbr.Post
} }
func (a IdxAct) String() string { 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{ return &IndexAction{
Act: act, Act: act,
Post: post, Post: post,
@ -48,5 +54,5 @@ func NewIndexAction(act IdxAct, post *model.Post) *IndexAction {
type CacheIndexService interface { type CacheIndexService interface {
IndexPostsService 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 package core
import ( 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 评论检索服务 // CommentService 评论检索服务
type CommentService interface { type CommentService interface {
GetComments(conditions *model.ConditionsT, offset, limit int) ([]*model.Comment, error) GetComments(conditions *ConditionsT, offset, limit int) ([]*Comment, error)
GetCommentByID(id int64) (*model.Comment, error) GetCommentByID(id int64) (*Comment, error)
GetCommentCount(conditions *model.ConditionsT) (int64, error) GetCommentCount(conditions *ConditionsT) (int64, error)
GetCommentReplyByID(id int64) (*model.CommentReply, error) GetCommentReplyByID(id int64) (*CommentReply, error)
GetCommentContentsByIDs(ids []int64) ([]*model.CommentContent, error) GetCommentContentsByIDs(ids []int64) ([]*CommentContent, error)
GetCommentRepliesByID(ids []int64) ([]*model.CommentReplyFormated, error) GetCommentRepliesByID(ids []int64) ([]*CommentReplyFormated, error)
} }
// CommentManageService 评论管理服务 // CommentManageService 评论管理服务
type CommentManageService interface { type CommentManageService interface {
DeleteComment(comment *model.Comment) error DeleteComment(comment *Comment) error
CreateComment(comment *model.Comment) (*model.Comment, error) CreateComment(comment *Comment) (*Comment, error)
CreateCommentReply(reply *model.CommentReply) (*model.CommentReply, error) CreateCommentReply(reply *CommentReply) (*CommentReply, error)
DeleteCommentReply(reply *model.CommentReply) error DeleteCommentReply(reply *CommentReply) error
CreateCommentContent(content *model.CommentContent) (*model.CommentContent, 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 package core
// DataService 数据服务集成 // 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 package core
import ( 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 消息服务 // MessageService 消息服务
type MessageService interface { type MessageService interface {
CreateMessage(msg *model.Message) (*model.Message, error) CreateMessage(msg *Message) (*Message, error)
GetUnreadCount(userID int64) (int64, error) GetUnreadCount(userID int64) (int64, error)
GetMessageByID(id int64) (*model.Message, error) GetMessageByID(id int64) (*Message, error)
ReadMessage(message *model.Message) error ReadMessage(message *Message) error
GetMessages(conditions *model.ConditionsT, offset, limit int) ([]*model.MessageFormated, error) GetMessages(conditions *ConditionsT, offset, limit int) ([]*MessageFormated, error)
GetMessageCount(conditions *model.ConditionsT) (int64, 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 package core
import ( import (
"github.com/rocboss/paopao-ce/internal/model" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
) )
const ( const (
@ -9,28 +13,39 @@ const (
SearchTypeTag SearchType = "tag" SearchTypeTag SearchType = "tag"
) )
type SearchType string const (
PostVisitPublic = dbr.PostVisitPublic
PostVisitPrivate = dbr.PostVisitPrivate
PostVisitFriend = dbr.PostVisitFriend
PostVisitInvalid = dbr.PostVisitInvalid
)
type QueryReq struct { type (
Query string PostVisibleT = dbr.PostVisibleT
Visibility []model.PostVisibleT
Type SearchType
}
type QueryResp struct { SearchType string
Items []*model.PostFormated
Total int64
}
type TsDocItem struct { QueryReq struct {
Post *model.Post Query string
Content string Visibility []PostVisibleT
} Type SearchType
}
QueryResp struct {
Items []*PostFormated
Total int64
}
TsDocItem struct {
Post *Post
Content string
}
)
// TweetSearchService tweet search service interface // TweetSearchService tweet search service interface
type TweetSearchService interface { type TweetSearchService interface {
IndexName() string IndexName() string
AddDocuments(data []TsDocItem, primaryKey ...string) (bool, error) AddDocuments(data []TsDocItem, primaryKey ...string) (bool, error)
DeleteDocuments(identifiers []string) 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 package core
import ( import (
"github.com/rocboss/paopao-ce/internal/model" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
)
type (
Captcha = dbr.Captcha
) )
// SecurityService 安全相关服务 // SecurityService 安全相关服务
type SecurityService interface { type SecurityService interface {
GetLatestPhoneCaptcha(phone string) (*model.Captcha, error) GetLatestPhoneCaptcha(phone string) (*Captcha, error)
UsePhoneCaptcha(captcha *model.Captcha) error UsePhoneCaptcha(captcha *Captcha) error
SendPhoneCaptcha(phone string) 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 package core
import ( 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 package core
import ( 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 话题服务 // TopicService 话题服务
type TopicService interface { type TopicService interface {
CreateTag(tag *model.Tag) (*model.Tag, error) CreateTag(tag *Tag) (*Tag, error)
DeleteTag(tag *model.Tag) error DeleteTag(tag *Tag) error
GetTags(conditions *model.ConditionsT, offset, limit int) ([]*model.Tag, error) GetTags(conditions *ConditionsT, offset, limit int) ([]*Tag, error)
GetTagsByKeyword(keyword string) ([]*model.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 package core
import ( import (
"github.com/rocboss/paopao-ce/internal/model" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"github.com/rocboss/paopao-ce/internal/model/rest" )
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 推文检索服务 // TweetService 推文检索服务
type TweetService interface { type TweetService interface {
GetPostByID(id int64) (*model.Post, error) GetPostByID(id int64) (*Post, error)
GetPosts(conditions *model.ConditionsT, offset, limit int) ([]*model.Post, error) GetPosts(conditions *ConditionsT, offset, limit int) ([]*Post, error)
GetPostCount(conditions *model.ConditionsT) (int64, error) GetPostCount(conditions *ConditionsT) (int64, error)
GetUserPostStar(postID, userID int64) (*model.PostStar, error) GetUserPostStar(postID, userID int64) (*PostStar, error)
GetUserPostStars(userID int64, offset, limit int) ([]*model.PostStar, error) GetUserPostStars(userID int64, offset, limit int) ([]*PostStar, error)
GetUserPostStarCount(userID int64) (int64, error) GetUserPostStarCount(userID int64) (int64, error)
GetUserPostCollection(postID, userID int64) (*model.PostCollection, error) GetUserPostCollection(postID, userID int64) (*PostCollection, error)
GetUserPostCollections(userID int64, offset, limit int) ([]*model.PostCollection, error) GetUserPostCollections(userID int64, offset, limit int) ([]*PostCollection, error)
GetUserPostCollectionCount(userID int64) (int64, error) GetUserPostCollectionCount(userID int64) (int64, error)
GetPostAttatchmentBill(postID, userID int64) (*model.PostAttachmentBill, error) GetPostAttatchmentBill(postID, userID int64) (*PostAttachmentBill, error)
GetPostContentsByIDs(ids []int64) ([]*model.PostContent, error) GetPostContentsByIDs(ids []int64) ([]*PostContent, error)
GetPostContentByID(id int64) (*model.PostContent, error) GetPostContentByID(id int64) (*PostContent, error)
} }
// TweetManageService 推文管理服务,包括创建/删除/更新推文 // TweetManageService 推文管理服务,包括创建/删除/更新推文
type TweetManageService interface { type TweetManageService interface {
CreateAttachment(attachment *model.Attachment) (*model.Attachment, error) CreateAttachment(attachment *Attachment) (*Attachment, error)
CreatePost(post *model.Post) (*model.Post, error) CreatePost(post *Post) (*Post, error)
DeletePost(post *model.Post) ([]string, error) DeletePost(post *Post) ([]string, error)
LockPost(post *model.Post) error LockPost(post *Post) error
StickPost(post *model.Post) error StickPost(post *Post) error
VisiblePost(post *model.Post, visibility model.PostVisibleT) error VisiblePost(post *Post, visibility PostVisibleT) error
UpdatePost(post *model.Post) error UpdatePost(post *Post) error
CreatePostStar(postID, userID int64) (*model.PostStar, error) CreatePostStar(postID, userID int64) (*PostStar, error)
DeletePostStar(p *model.PostStar) error DeletePostStar(p *PostStar) error
CreatePostCollection(postID, userID int64) (*model.PostCollection, error) CreatePostCollection(postID, userID int64) (*PostCollection, error)
DeletePostCollection(p *model.PostCollection) error DeletePostCollection(p *PostCollection) error
CreatePostContent(content *model.PostContent) (*model.PostContent, error) CreatePostContent(content *PostContent) (*PostContent, error)
} }
// TweetHelpService 推文辅助服务 // TweetHelpService 推文辅助服务
type TweetHelpService interface { type TweetHelpService interface {
RevampPosts(posts []*model.PostFormated) ([]*model.PostFormated, error) RevampPosts(posts []*PostFormated) ([]*PostFormated, error)
MergePosts(posts []*model.Post) ([]*model.PostFormated, error) MergePosts(posts []*Post) ([]*PostFormated, error)
} }
// IndexPostsService 广场首页推文列表服务 // IndexPostsService 广场首页推文列表服务
type IndexPostsService interface { 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 package core
import ( type (
"github.com/rocboss/paopao-ce/internal/model" ContactItem struct {
"github.com/rocboss/paopao-ce/internal/model/rest" 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 用户管理服务 // UserManageService 用户管理服务
type UserManageService interface { type UserManageService interface {
GetUserByID(id int64) (*model.User, error) GetUserByID(id int64) (*User, error)
GetUserByUsername(username string) (*model.User, error) GetUserByUsername(username string) (*User, error)
GetUserByPhone(phone string) (*model.User, error) GetUserByPhone(phone string) (*User, error)
GetUsersByIDs(ids []int64) ([]*model.User, error) GetUsersByIDs(ids []int64) ([]*User, error)
GetUsersByKeyword(keyword string) ([]*model.User, error) GetUsersByKeyword(keyword string) ([]*User, error)
CreateUser(user *model.User) (*model.User, error) CreateUser(user *User) (*User, error)
UpdateUser(user *model.User) error UpdateUser(user *User) error
} }
// ContactManageService 联系人管理服务 // ContactManageService 联系人管理服务
@ -22,6 +36,6 @@ type ContactManageService interface {
AddFriend(userId int64, friendId int64) error AddFriend(userId int64, friendId int64) error
RejectFriend(userId int64, friendId int64) error RejectFriend(userId int64, friendId int64) error
DeleteFriend(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 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 package core
import ( 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 package core
import ( 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 // WalletService wallet service interface
type WalletService 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) GetUserWalletBillCount(userID int64) (int64, error)
GetRechargeByID(id int64) (*model.WalletRecharge, error) GetRechargeByID(id int64) (*WalletRecharge, error)
CreateRecharge(userId, amount int64) (*model.WalletRecharge, error) CreateRecharge(userId, amount int64) (*WalletRecharge, error)
HandleRechargeSuccess(recharge *model.WalletRecharge, tradeNo string) error HandleRechargeSuccess(recharge *WalletRecharge, tradeNo string) error
HandlePostAttachmentBought(post *model.Post, user *model.User) 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 package cache
import ( import (
@ -11,8 +15,6 @@ import (
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/allegro/bigcache/v3" "github.com/allegro/bigcache/v3"
"github.com/rocboss/paopao-ce/internal/core" "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/rocboss/paopao-ce/pkg/types"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -24,7 +26,7 @@ var (
type postsEntry struct { type postsEntry struct {
key string key string
tweets *rest.IndexTweetsResp tweets *core.IndexTweetList
} }
type bigCacheIndexServant struct { type bigCacheIndexServant struct {
@ -38,7 +40,7 @@ type bigCacheIndexServant struct {
preventDuration time.Duration 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) key := s.keyFrom(user, offset, limit)
posts, err := s.getPosts(key) posts, err := s.getPosts(key)
if err == nil { if err == nil {
@ -54,7 +56,7 @@ func (s *bigCacheIndexServant) IndexPosts(user *model.User, offset int, limit in
return posts, nil 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) data, err := s.cache.Get(key)
if err != nil { if err != nil {
logrus.Debugf("bigCacheIndexServant.getPosts get posts by key: %s from cache err: %v", key, err) 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) buf := bytes.NewBuffer(data)
dec := gob.NewDecoder(buf) dec := gob.NewDecoder(buf)
var resp rest.IndexTweetsResp var resp core.IndexTweetList
if err := dec.Decode(&resp); err != nil { if err := dec.Decode(&resp); err != nil {
logrus.Debugf("bigCacheIndexServant.getPosts get posts from cache in decode err: %v", err) logrus.Debugf("bigCacheIndexServant.getPosts get posts from cache in decode err: %v", err)
return nil, err return nil, err
@ -70,7 +72,7 @@ func (s *bigCacheIndexServant) getPosts(key string) (*rest.IndexTweetsResp, erro
return &resp, nil 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} entry := &postsEntry{key: key, tweets: tweets}
select { select {
case s.cachePostsCh <- entry: 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) 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 var userId int64 = -1
if user != nil { if user != nil {
userId = user.ID 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) 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) action := core.NewIndexAction(act, post)
select { select {
case s.indexActionCh <- action: case s.indexActionCh <- action:
@ -134,7 +136,7 @@ func (s *bigCacheIndexServant) handleIndexAction(action *core.IndexAction) {
// 创建/删除 私密推文特殊处理 // 创建/删除 私密推文特殊处理
switch act { switch act {
case core.IdxActCreatePost, core.IdxActDeletePost: case core.IdxActCreatePost, core.IdxActDeletePost:
if post.Visibility == model.PostVisitPrivate { if post.Visibility == core.PostVisitPrivate {
s.deleteCacheByUserId(post.UserID, true) s.deleteCacheByUserId(post.UserID, true)
return 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 package cache
import ( 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 package cache
import ( import (
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/internal/model/rest"
) )
var ( var (
@ -16,11 +18,11 @@ type noneCacheIndexServant struct {
ips core.IndexPostsService 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) 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 // 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 package cache
import ( import (
@ -6,8 +10,6 @@ import (
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/rocboss/paopao-ce/internal/core" "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" "github.com/sirupsen/logrus"
) )
@ -20,21 +22,21 @@ type simpleCacheIndexServant struct {
ips core.IndexPostsService ips core.IndexPostsService
indexActionCh chan core.IdxAct indexActionCh chan core.IdxAct
indexPosts *rest.IndexTweetsResp indexPosts *core.IndexTweetList
atomicIndex atomic.Value atomicIndex atomic.Value
maxIndexSize int maxIndexSize int
checkTick *time.Ticker checkTick *time.Ticker
expireIndexTick *time.Ticker expireIndexTick *time.Ticker
} }
func (s *simpleCacheIndexServant) IndexPosts(user *model.User, offset int, limit int) (*rest.IndexTweetsResp, error) { func (s *simpleCacheIndexServant) IndexPosts(user *core.User, offset int, limit int) (*core.IndexTweetList, error) {
cacheResp := s.atomicIndex.Load().(*rest.IndexTweetsResp) cacheResp := s.atomicIndex.Load().(*core.IndexTweetList)
end := offset + limit end := offset + limit
if cacheResp != nil { if cacheResp != nil {
size := len(cacheResp.Tweets) 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) 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 { if size >= end {
return &rest.IndexTweetsResp{ return &core.IndexTweetList{
Tweets: cacheResp.Tweets[offset:end], Tweets: cacheResp.Tweets[offset:end],
Total: cacheResp.Total, Total: cacheResp.Total,
}, nil }, nil
@ -45,7 +47,7 @@ func (s *simpleCacheIndexServant) IndexPosts(user *model.User, offset int, limit
return s.ips.IndexPosts(user, offset, 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 { select {
case s.indexActionCh <- act: case s.indexActionCh <- act:
logrus.Debugf("simpleCacheIndexServant.SendAction send indexAction by chan: %s", 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 package dao
import ( 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 package jinzhu
import ( import (
"github.com/rocboss/paopao-ce/internal/core" "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" "github.com/rocboss/paopao-ce/pkg/types"
"gorm.io/gorm" "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 // user is activation if had bind phone
isActivation := (len(user.Phone) != 0) isActivation := (len(user.Phone) != 0)
isFriend := s.isFriend(user.ID, action.UserId) 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 { 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 { if err != nil {
return core.FriendSet{} return core.FriendSet{}
} }
@ -43,7 +47,7 @@ func (s *authorizationManageServant) MyFriendSet(userId int64) core.FriendSet {
} }
func (s *authorizationManageServant) BeFriendFilter(userId int64) core.FriendFilter { 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 { if err != nil {
return core.FriendFilter{} return core.FriendFilter{}
} }
@ -56,12 +60,12 @@ func (s *authorizationManageServant) BeFriendFilter(userId int64) core.FriendFil
} }
func (s *authorizationManageServant) BeFriendIds(userId int64) ([]int64, error) { 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 { func (s *authorizationManageServant) isFriend(userId int64, friendId int64) bool {
contact, err := (&model.Contact{UserId: friendId, FriendId: userId}).GetByUserFriend(s.db) contact, err := (&dbr.Contact{UserId: friendId, FriendId: userId}).GetByUserFriend(s.db)
if err == nil || contact.Status == model.ContactStatusAgree { if err == nil || contact.Status == dbr.ContactStatusAgree {
return true return true
} }
return false 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 package jinzhu
import ( import (
"github.com/rocboss/paopao-ce/internal/core" "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" "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) { func (s *commentServant) GetComments(conditions *core.ConditionsT, offset, limit int) ([]*core.Comment, error) {
return (&model.Comment{}).List(s.db, conditions, offset, limit) return (&dbr.Comment{}).List(s.db, conditions, offset, limit)
} }
func (s *commentServant) GetCommentByID(id int64) (*model.Comment, error) { func (s *commentServant) GetCommentByID(id int64) (*core.Comment, error) {
comment := &model.Comment{ comment := &dbr.Comment{
Model: &model.Model{ Model: &dbr.Model{
ID: id, ID: id,
}, },
} }
return comment.Get(s.db) return comment.Get(s.db)
} }
func (s *commentServant) GetCommentReplyByID(id int64) (*model.CommentReply, error) { func (s *commentServant) GetCommentReplyByID(id int64) (*core.CommentReply, error) {
reply := &model.CommentReply{ reply := &dbr.CommentReply{
Model: &model.Model{ Model: &dbr.Model{
ID: id, ID: id,
}, },
} }
return reply.Get(s.db) return reply.Get(s.db)
} }
func (s *commentServant) GetCommentCount(conditions *model.ConditionsT) (int64, error) { func (s *commentServant) GetCommentCount(conditions *core.ConditionsT) (int64, error) {
return (&model.Comment{}).Count(s.db, conditions) return (&dbr.Comment{}).Count(s.db, conditions)
} }
func (s *commentServant) GetCommentContentsByIDs(ids []int64) ([]*model.CommentContent, error) { func (s *commentServant) GetCommentContentsByIDs(ids []int64) ([]*core.CommentContent, error) {
commentContent := &model.CommentContent{} commentContent := &dbr.CommentContent{}
return commentContent.List(s.db, &model.ConditionsT{ return commentContent.List(s.db, &dbr.ConditionsT{
"comment_id IN ?": ids, "comment_id IN ?": ids,
}, 0, 0) }, 0, 0)
} }
func (s *commentServant) GetCommentRepliesByID(ids []int64) ([]*model.CommentReplyFormated, error) { func (s *commentServant) GetCommentRepliesByID(ids []int64) ([]*core.CommentReplyFormated, error) {
CommentReply := &model.CommentReply{} CommentReply := &dbr.CommentReply{}
replies, err := CommentReply.List(s.db, &model.ConditionsT{ replies, err := CommentReply.List(s.db, &dbr.ConditionsT{
"comment_id IN ?": ids, "comment_id IN ?": ids,
}, 0, 0) }, 0, 0)
@ -83,7 +87,7 @@ func (s *commentServant) GetCommentRepliesByID(ids []int64) ([]*model.CommentRep
if err != nil { if err != nil {
return nil, err return nil, err
} }
repliesFormated := []*model.CommentReplyFormated{} repliesFormated := []*core.CommentReplyFormated{}
for _, reply := range replies { for _, reply := range replies {
replyFormated := reply.Format() replyFormated := reply.Format()
for _, user := range users { for _, user := range users {
@ -101,22 +105,22 @@ func (s *commentServant) GetCommentRepliesByID(ids []int64) ([]*model.CommentRep
return repliesFormated, nil return repliesFormated, nil
} }
func (s *commentManageServant) DeleteComment(comment *model.Comment) error { func (s *commentManageServant) DeleteComment(comment *core.Comment) error {
return comment.Delete(s.db) 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) 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) 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) 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) 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 package jinzhu
import ( import (
"time" "time"
"github.com/rocboss/paopao-ce/internal/core" "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/internal/model/rest"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"gorm.io/gorm" "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) { func (s *contactManageServant) fetchOrNewContact(db *gorm.DB, userId int64, friendId int64, status int8) (*dbr.Contact, error) {
contact := &model.Contact{ contact := &dbr.Contact{
UserId: userId, UserId: userId,
FriendId: friendId, FriendId: friendId,
} }
contact, err := contact.FetchUser(db) contact, err := contact.FetchUser(db)
if err != nil { if err != nil {
contact = &model.Contact{ contact = &dbr.Contact{
UserId: userId, UserId: userId,
FriendId: friendId, FriendId: friendId,
Status: status, 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 { if e != nil {
err = e err = e
return return
} }
// 如果已经好友,啥也不干 // 如果已经好友,啥也不干
if contact.Status == model.ContactStatusAgree { if contact.Status == dbr.ContactStatusAgree {
return nil return nil
} else if contact.Status == model.ContactStatusReject || contact.Status == model.ContactStatusDeleted { } else if contact.Status == dbr.ContactStatusReject || contact.Status == dbr.ContactStatusDeleted {
contact.Status = model.ContactStatusRequesting contact.Status = dbr.ContactStatusRequesting
contact.IsDel = 0 // remove deleted flag if needed contact.IsDel = 0 // remove deleted flag if needed
if err = contact.UpdateInUnscoped(db); err != nil { if err = contact.UpdateInUnscoped(db); err != nil {
logrus.Errorf("contactManageServant.RequestingFriend update exsit contact err:%s", err) 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, SenderUserID: userId,
ReceiverUserID: friendId, ReceiverUserID: friendId,
Type: model.MsgTypeRequestingFriend, Type: dbr.MsgTypeRequestingFriend,
Brief: "请求添加好友,并附言:", Brief: "请求添加好友,并附言:",
Content: greetings, Content: greetings,
ReplyID: int64(model.ContactStatusRequesting), ReplyID: int64(dbr.ContactStatusRequesting),
} }
if _, err = msg.Create(db); err != nil { if _, err = msg.Create(db); err != nil {
logrus.Errorf("contactManageServant.RequestingFriend create message err:%s", err) 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, UserId: friendId,
FriendId: userId, FriendId: userId,
} }
@ -105,23 +108,23 @@ func (s *contactManageServant) AddFriend(userId int64, friendId int64) (err erro
return return
} }
// 如果还不是请求好友,啥也不干 // 如果还不是请求好友,啥也不干
if contact.Status != model.ContactStatusRequesting { if contact.Status != dbr.ContactStatusRequesting {
logrus.Debugf("contactManageServant.AddFriend not reuesting status now so skip") logrus.Debugf("contactManageServant.AddFriend not reuesting status now so skip")
return nil return nil
} }
contact.Status = model.ContactStatusAgree contact.Status = dbr.ContactStatusAgree
if err = contact.Update(db); err != nil { if err = contact.Update(db); err != nil {
return err return err
} }
contact, err = s.fetchOrNewContact(db, userId, friendId, model.ContactStatusAgree) contact, err = s.fetchOrNewContact(db, userId, friendId, dbr.ContactStatusAgree)
if err != nil { if err != nil {
return return
} }
// 如果已经好友,啥也不干 // 如果已经好友,啥也不干
if contact.Status != model.ContactStatusAgree { if contact.Status != dbr.ContactStatusAgree {
contact.Status = model.ContactStatusAgree contact.Status = dbr.ContactStatusAgree
contact.IsDel = 0 // remove deleted flag contact.IsDel = 0 // remove deleted flag
if err = contact.UpdateInUnscoped(db); err != nil { if err = contact.UpdateInUnscoped(db); err != nil {
logrus.Errorf("contactManageServant.AddFriend update contact err:%s", err) 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} args := []any{userId, friendId, friendId, userId, dbr.MsgTypeRequestingFriend, dbr.ContactStatusRequesting}
msgs, e := (&model.Message{}).FetchBy(db, model.Predicates{ 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, "((sender_user_id = ? AND receiver_user_id = ?) OR (sender_user_id = ? AND receiver_user_id = ?)) AND type = ? AND reply_id = ?": args,
}) })
if e != nil { if e != nil {
@ -138,7 +141,7 @@ func (s *contactManageServant) AddFriend(userId int64, friendId int64) (err erro
return return
} }
for _, msg := range msgs { for _, msg := range msgs {
msg.ReplyID = int64(model.ContactStatusAgree) msg.ReplyID = int64(dbr.ContactStatusAgree)
if err = msg.Update(db); err != nil { if err = msg.Update(db); err != nil {
return return
} }
@ -156,7 +159,7 @@ func (s *contactManageServant) RejectFriend(userId int64, friendId int64) (err e
} }
}() }()
contact := &model.Contact{ contact := &dbr.Contact{
UserId: friendId, UserId: friendId,
FriendId: userId, FriendId: userId,
} }
@ -164,16 +167,16 @@ func (s *contactManageServant) RejectFriend(userId int64, friendId int64) (err e
return return
} }
// 如果还不是请求好友,啥也不干 // 如果还不是请求好友,啥也不干
if contact.Status != model.ContactStatusRequesting { if contact.Status != dbr.ContactStatusRequesting {
return nil return nil
} }
contact.Status = model.ContactStatusReject contact.Status = dbr.ContactStatusReject
if err = contact.Update(db); err != nil { if err = contact.Update(db); err != nil {
return err return err
} }
args := []any{friendId, userId, model.MsgTypeRequestingFriend, model.ContactStatusRequesting} args := []any{friendId, userId, dbr.MsgTypeRequestingFriend, dbr.ContactStatusRequesting}
msgs, e := (&model.Message{}).FetchBy(db, model.Predicates{ msgs, e := (&dbr.Message{}).FetchBy(db, dbr.Predicates{
"sender_user_id = ? AND receiver_user_id = ? AND type = ? AND reply_id = ?": args, "sender_user_id = ? AND receiver_user_id = ? AND type = ? AND reply_id = ?": args,
}) })
if e != nil { if e != nil {
@ -181,7 +184,7 @@ func (s *contactManageServant) RejectFriend(userId int64, friendId int64) (err e
return return
} }
for _, msg := range msgs { for _, msg := range msgs {
msg.ReplyID = int64(model.ContactStatusReject) msg.ReplyID = int64(dbr.ContactStatusReject)
if err = msg.Update(db); err != nil { if err = msg.Update(db); err != nil {
return return
} }
@ -199,7 +202,7 @@ func (s *contactManageServant) DeleteFriend(userId int64, friendId int64) (err e
} }
}() }()
contact := &model.Contact{ contact := &dbr.Contact{
UserId: userId, UserId: userId,
FriendId: friendId, FriendId: friendId,
} }
@ -210,10 +213,10 @@ func (s *contactManageServant) DeleteFriend(userId int64, friendId int64) (err e
for _, contact := range contacts { for _, contact := range contacts {
// 如果还不是好友,啥也不干 // 如果还不是好友,啥也不干
if contact.Status != model.ContactStatusAgree { if contact.Status != dbr.ContactStatusAgree {
continue continue
} }
contact.Status = model.ContactStatusDeleted contact.Status = dbr.ContactStatusDeleted
contact.DeletedOn = time.Now().Unix() contact.DeletedOn = time.Now().Unix()
contact.IsDel = 1 contact.IsDel = 1
if err = contact.Update(db); err != nil { if err = contact.Update(db); err != nil {
@ -223,11 +226,11 @@ func (s *contactManageServant) DeleteFriend(userId int64, friendId int64) (err e
return nil return nil
} }
func (s *contactManageServant) GetContacts(userId int64, offset int, limit int) (*rest.ContactsResp, error) { func (s *contactManageServant) GetContacts(userId int64, offset int, limit int) (*core.ContactList, error) {
contact := &model.Contact{} contact := &dbr.Contact{}
condition := model.ConditionsT{ condition := dbr.ConditionsT{
"user_id": userId, "user_id": userId,
"status": model.ContactStatusAgree, "status": dbr.ContactStatusAgree,
} }
contacts, err := contact.List(s.db, condition, offset, limit) contacts, err := contact.List(s.db, condition, offset, limit)
if err != nil { if err != nil {
@ -237,13 +240,13 @@ func (s *contactManageServant) GetContacts(userId int64, offset int, limit int)
if err != nil { if err != nil {
return nil, err return nil, err
} }
resp := &rest.ContactsResp{ resp := &core.ContactList{
Contacts: make([]rest.ContactItem, 0, len(contacts)), Contacts: make([]core.ContactItem, 0, len(contacts)),
Total: total, Total: total,
} }
for _, c := range contacts { for _, c := range contacts {
if c.User != nil { if c.User != nil {
resp.Contacts = append(resp.Contacts, rest.ContactItem{ resp.Contacts = append(resp.Contacts, core.ContactItem{
UserId: c.FriendId, UserId: c.FriendId,
UserName: c.User.Username, UserName: c.User.Username,
Nickname: c.User.Nickname, 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 { func (s *contactManageServant) IsFriend(userId int64, friendId int64) bool {
contact := &model.Contact{ contact := &dbr.Contact{
UserId: friendId, UserId: friendId,
FriendId: userId, FriendId: userId,
} }
contact, err := contact.GetByUserFriend(s.db) contact, err := contact.GetByUserFriend(s.db)
if err == nil && contact.Status == model.ContactStatusAgree { if err == nil && contact.Status == dbr.ContactStatusAgree {
return true return true
} }
return false 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" import "gorm.io/gorm"
type AttachmentType int type AttachmentType int
const ( const (
ATTACHMENT_TYPE_IMAGE AttachmentType = iota + 1 AttachmentTypeImage AttachmentType = iota + 1
ATTACHMENT_TYPE_VIDEO AttachmentTypeVideo
ATTACHMENT_TYPE_OTHER AttachmentTypeOther
) )
type Attachment struct { 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" 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 ( import (
"time" "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 ( import (
"time" "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) { 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 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 ( import (
"time" "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 ( import (
"github.com/sirupsen/logrus" "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" 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 ( import (
"time" "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 ( import (
"strings" "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" 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 ( import (
"time" "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 ( import (
"time" "time"
@ -7,27 +11,26 @@ import (
) )
// 类型1标题2文字段落3图片地址4视频地址5语音地址6链接地址7附件资源 // 类型1标题2文字段落3图片地址4视频地址5语音地址6链接地址7附件资源
type PostContentT int type PostContentT int
const ( const (
CONTENT_TYPE_TITLE PostContentT = iota + 1 ContentTypeTitle PostContentT = iota + 1
CONTENT_TYPE_TEXT ContentTypeText
CONTENT_TYPE_IMAGE ContentTypeImage
CONTENT_TYPE_VIDEO ContentTypeVideo
CONTENT_TYPE_AUDIO ContentTypeAudio
CONTENT_TYPE_LINK ContentTypeLink
CONTENT_TYPE_ATTACHMENT ContentTypeAttachment
CONTENT_TYPE_CHARGE_ATTACHMENT ContentTypeChargeAttachment
) )
var ( var (
mediaContentType = []PostContentT{ mediaContentType = []PostContentT{
CONTENT_TYPE_IMAGE, ContentTypeImage,
CONTENT_TYPE_VIDEO, ContentTypeVideo,
CONTENT_TYPE_AUDIO, ContentTypeAudio,
CONTENT_TYPE_ATTACHMENT, ContentTypeAttachment,
CONTENT_TYPE_CHARGE_ATTACHMENT, 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 ( import (
"time" "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 ( import (
"time" "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" 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" 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" 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 package jinzhu
import ( import (
"github.com/rocboss/paopao-ce/internal/core" "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/internal/model/rest"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"gorm.io/gorm" "gorm.io/gorm"
) )
@ -40,20 +43,20 @@ func newSimpleIndexPostsService(db *gorm.DB) core.IndexPostsService {
} }
// IndexPosts 根据userId查询广场推文列表简单做到不同用户的主页都是不同的 // IndexPosts 根据userId查询广场推文列表简单做到不同用户的主页都是不同的
func (s *indexPostsServant) IndexPosts(user *model.User, offset int, limit int) (*rest.IndexTweetsResp, error) { func (s *indexPostsServant) IndexPosts(user *core.User, offset int, limit int) (*core.IndexTweetList, error) {
predicates := model.Predicates{ predicates := dbr.Predicates{
"ORDER": []any{"is_top DESC, latest_replied_on DESC"}, "ORDER": []any{"is_top DESC, latest_replied_on DESC"},
} }
if user == nil { if user == nil {
predicates["visibility = ?"] = []any{model.PostVisitPublic} predicates["visibility = ?"] = []any{dbr.PostVisitPublic}
} else if !user.IsAdmin { } else if !user.IsAdmin {
friendIds, _ := s.ams.BeFriendIds(user.ID) friendIds, _ := s.ams.BeFriendIds(user.ID)
friendIds = append(friendIds, 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 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 { if err != nil {
logrus.Debugf("gormIndexPostsServant.IndexPosts err: %v", err) logrus.Debugf("gormIndexPostsServant.IndexPosts err: %v", err)
return nil, err return nil, err
@ -63,25 +66,25 @@ func (s *indexPostsServant) IndexPosts(user *model.User, offset int, limit int)
return nil, err return nil, err
} }
total, err := (&model.Post{}).CountBy(s.db, predicates) total, err := (&dbr.Post{}).CountBy(s.db, predicates)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &rest.IndexTweetsResp{ return &core.IndexTweetList{
Tweets: formatPosts, Tweets: formatPosts,
Total: total, Total: total,
}, nil }, nil
} }
// simpleCacheIndexGetPosts simpleCacheIndex 专属获取广场推文列表函数 // simpleCacheIndexGetPosts simpleCacheIndex 专属获取广场推文列表函数
func (s *simpleIndexPostsServant) IndexPosts(_user *model.User, offset int, limit int) (*rest.IndexTweetsResp, error) { func (s *simpleIndexPostsServant) IndexPosts(_user *core.User, offset int, limit int) (*core.IndexTweetList, error) {
predicates := model.Predicates{ predicates := dbr.Predicates{
"visibility = ?": []any{model.PostVisitPublic}, "visibility = ?": []any{dbr.PostVisitPublic},
"ORDER": []any{"is_top DESC, latest_replied_on DESC"}, "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 { if err != nil {
logrus.Debugf("gormSimpleIndexPostsServant.IndexPosts err: %v", err) logrus.Debugf("gormSimpleIndexPostsServant.IndexPosts err: %v", err)
return nil, err return nil, err
@ -92,12 +95,12 @@ func (s *simpleIndexPostsServant) IndexPosts(_user *model.User, offset int, limi
return nil, err return nil, err
} }
total, err := (&model.Post{}).CountBy(s.db, predicates) total, err := (&dbr.Post{}).CountBy(s.db, predicates)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &rest.IndexTweetsResp{ return &core.IndexTweetList{
Tweets: formatPosts, Tweets: formatPosts,
Total: total, Total: total,
}, nil }, 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. // Core service implement base gorm+mysql/postgresql/sqlite3.
// Jinzhu is the primary developer of gorm so use his name as // Jinzhu is the primary developer of gorm so use his name as
// package name as a saluter. // 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 package jinzhu
import ( import (
"github.com/rocboss/paopao-ce/internal/core" "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" "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) return msg.Create(d.db)
} }
func (d *messageServant) GetUnreadCount(userID int64) (int64, error) { 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, "receiver_user_id": userID,
"is_read": model.MsgStatusUnread, "is_read": dbr.MsgStatusUnread,
}) })
} }
func (d *messageServant) GetMessageByID(id int64) (*model.Message, error) { func (d *messageServant) GetMessageByID(id int64) (*core.Message, error) {
return (&model.Message{ return (&dbr.Message{
Model: &model.Model{ Model: &dbr.Model{
ID: id, ID: id,
}, },
}).Get(d.db) }).Get(d.db)
} }
func (d *messageServant) ReadMessage(message *model.Message) error { func (d *messageServant) ReadMessage(message *core.Message) error {
message.IsRead = 1 message.IsRead = 1
return message.Update(d.db) return message.Update(d.db)
} }
func (d *messageServant) GetMessages(conditions *model.ConditionsT, offset, limit int) ([]*model.MessageFormated, error) { func (d *messageServant) GetMessages(conditions *core.ConditionsT, offset, limit int) ([]*core.MessageFormated, error) {
messages, err := (&model.Message{}).List(d.db, conditions, offset, limit) messages, err := (&dbr.Message{}).List(d.db, conditions, offset, limit)
if err != nil { if err != nil {
return nil, err return nil, err
} }
mfs := []*model.MessageFormated{} mfs := []*dbr.MessageFormated{}
for _, message := range messages { for _, message := range messages {
mf := message.Format() mf := message.Format()
mfs = append(mfs, mf) mfs = append(mfs, mf)
@ -59,6 +63,6 @@ func (d *messageServant) GetMessages(conditions *model.ConditionsT, offset, limi
return mfs, nil return mfs, nil
} }
func (d *messageServant) GetMessageCount(conditions *model.ConditionsT) (int64, error) { func (d *messageServant) GetMessageCount(conditions *core.ConditionsT) (int64, error) {
return (&model.Message{}).Count(d.db, conditions) 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 package jinzhu
import ( import (
@ -10,7 +14,7 @@ import (
"github.com/rocboss/paopao-ce/internal/conf" "github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"github.com/rocboss/paopao-ce/pkg/json" "github.com/rocboss/paopao-ce/pkg/json"
"gopkg.in/resty.v1" "gopkg.in/resty.v1"
"gorm.io/gorm" "gorm.io/gorm"
@ -36,14 +40,14 @@ type juhePhoneCaptchaRsp struct {
} }
// 获取最新短信验证码 // 获取最新短信验证码
func (s *securityServant) GetLatestPhoneCaptcha(phone string) (*model.Captcha, error) { func (s *securityServant) GetLatestPhoneCaptcha(phone string) (*core.Captcha, error) {
return (&model.Captcha{ return (&dbr.Captcha{
Phone: phone, Phone: phone,
}).Get(s.db) }).Get(s.db)
} }
// 更新短信验证码 // 更新短信验证码
func (s *securityServant) UsePhoneCaptcha(captcha *model.Captcha) error { func (s *securityServant) UsePhoneCaptcha(captcha *core.Captcha) error {
captcha.UseTimes++ captcha.UseTimes++
return captcha.Update(s.db) return captcha.Update(s.db)
} }
@ -82,7 +86,7 @@ func (s *securityServant) SendPhoneCaptcha(phone string) error {
} }
// 写入表 // 写入表
captchaModel := &model.Captcha{ captchaModel := &dbr.Captcha{
Phone: phone, Phone: phone,
Captcha: strconv.Itoa(captcha), Captcha: strconv.Itoa(captcha),
ExpiredOn: time.Now().Add(time.Minute * time.Duration(m)).Unix(), 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 package jinzhu
import ( import (
"strings" "strings"
"github.com/rocboss/paopao-ce/internal/core" "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" "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) 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) return deleteTag(s.db, tag)
} }
func (s *topicServant) GetTags(conditions *model.ConditionsT, offset, limit int) ([]*model.Tag, error) { func (s *topicServant) GetTags(conditions *core.ConditionsT, offset, limit int) ([]*core.Tag, error) {
return (&model.Tag{}).List(s.db, conditions, offset, limit) return (&dbr.Tag{}).List(s.db, conditions, offset, limit)
} }
func (s *topicServant) GetTagsByKeyword(keyword string) ([]*model.Tag, error) { func (s *topicServant) GetTagsByKeyword(keyword string) ([]*core.Tag, error) {
tag := &model.Tag{} tag := &dbr.Tag{}
keyword = "%" + strings.Trim(keyword, " ") + "%" keyword = "%" + strings.Trim(keyword, " ") + "%"
if keyword == "%%" { if keyword == "%%" {
return tag.List(s.db, &model.ConditionsT{ return tag.List(s.db, &dbr.ConditionsT{
"ORDER": "quote_num DESC", "ORDER": "quote_num DESC",
}, 0, 6) }, 0, 6)
} else { } else {
return tag.List(s.db, &model.ConditionsT{ return tag.List(s.db, &dbr.ConditionsT{
"tag LIKE ?": keyword, "tag LIKE ?": keyword,
"ORDER": "quote_num DESC", "ORDER": "quote_num DESC",
}, 0, 6) }, 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 package jinzhu
import ( import (
@ -5,7 +9,7 @@ import (
"time" "time"
"github.com/rocboss/paopao-ce/internal/core" "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" "gorm.io/gorm"
) )
@ -48,7 +52,7 @@ func newTweetHelpService(db *gorm.DB) core.TweetHelpService {
} }
// MergePosts post数据整合 // 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)) postIds := make([]int64, 0, len(posts))
userIds := make([]int64, 0, len(posts)) userIds := make([]int64, 0, len(posts))
for _, post := range posts { for _, post := range posts {
@ -66,18 +70,18 @@ func (s *tweetHelpServant) MergePosts(posts []*model.Post) ([]*model.PostFormate
return nil, err return nil, err
} }
userMap := make(map[int64]*model.UserFormated, len(users)) userMap := make(map[int64]*dbr.UserFormated, len(users))
for _, user := range users { for _, user := range users {
userMap[user.ID] = user.Format() 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 { for _, content := range postContents {
contentMap[content.PostID] = append(contentMap[content.PostID], content.Format()) 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 { for _, post := range posts {
postFormated := post.Format() postFormated := post.Format()
postFormated.User = userMap[post.UserID] postFormated.User = userMap[post.UserID]
@ -88,7 +92,7 @@ func (s *tweetHelpServant) MergePosts(posts []*model.Post) ([]*model.PostFormate
} }
// RevampPosts post数据整形修复 // 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)) postIds := make([]int64, 0, len(posts))
userIds := make([]int64, 0, len(posts)) userIds := make([]int64, 0, len(posts))
for _, post := range posts { for _, post := range posts {
@ -106,12 +110,12 @@ func (s *tweetHelpServant) RevampPosts(posts []*model.PostFormated) ([]*model.Po
return nil, err return nil, err
} }
userMap := make(map[int64]*model.UserFormated, len(users)) userMap := make(map[int64]*dbr.UserFormated, len(users))
for _, user := range users { for _, user := range users {
userMap[user.ID] = user.Format() 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 { for _, content := range postContents {
contentMap[content.PostID] = append(contentMap[content.PostID], content.Format()) 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 return posts, nil
} }
func (s *tweetHelpServant) getPostContentsByIDs(ids []int64) ([]*model.PostContent, error) { func (s *tweetHelpServant) getPostContentsByIDs(ids []int64) ([]*dbr.PostContent, error) {
return (&model.PostContent{}).List(s.db, &model.ConditionsT{ return (&dbr.PostContent{}).List(s.db, &dbr.ConditionsT{
"post_id IN ?": ids, "post_id IN ?": ids,
"ORDER": "sort ASC", "ORDER": "sort ASC",
}, 0, 0) }, 0, 0)
} }
func (s *tweetHelpServant) getUsersByIDs(ids []int64) ([]*model.User, error) { func (s *tweetHelpServant) getUsersByIDs(ids []int64) ([]*dbr.User, error) {
user := &model.User{} user := &dbr.User{}
return user.List(s.db, &model.ConditionsT{ return user.List(s.db, &dbr.ConditionsT{
"id IN ?": ids, "id IN ?": ids,
}, 0, 0) }, 0, 0)
} }
func (s *tweetManageServant) CreatePostCollection(postID, userID int64) (*model.PostCollection, error) { func (s *tweetManageServant) CreatePostCollection(postID, userID int64) (*core.PostCollection, error) {
collection := &model.PostCollection{ collection := &dbr.PostCollection{
PostID: postID, PostID: postID,
UserID: userID, UserID: userID,
} }
@ -148,19 +152,19 @@ func (s *tweetManageServant) CreatePostCollection(postID, userID int64) (*model.
return collection.Create(s.db) 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) 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) 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) 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() post.LatestRepliedOn = time.Now().Unix()
p, err := post.Create(s.db) p, err := post.Create(s.db)
if err != nil { if err != nil {
@ -170,11 +174,11 @@ func (s *tweetManageServant) CreatePost(post *model.Post) (*model.Post, error) {
return p, nil return p, nil
} }
func (s *tweetManageServant) DeletePost(post *model.Post) ([]string, error) { func (s *tweetManageServant) DeletePost(post *core.Post) ([]string, error) {
var mediaContents []string var mediaContents []string
postId := post.ID postId := post.ID
postContent := &model.PostContent{} postContent := &dbr.PostContent{}
err := s.db.Transaction( err := s.db.Transaction(
func(tx *gorm.DB) error { func(tx *gorm.DB) error {
if contents, err := postContent.MediaContentsByPostId(tx, postId); err == nil { 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) { func (s *tweetManageServant) deleteCommentByPostId(db *gorm.DB, postId int64) ([]string, error) {
comment := &model.Comment{} comment := &dbr.Comment{}
commentContent := &model.CommentContent{} commentContent := &dbr.CommentContent{}
// 获取推文的所有评论id // 获取推文的所有评论id
commentIds, err := comment.CommentIdsByPostId(db, postId) 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 nil, err
} }
return mediaContents, nil return mediaContents, nil
} }
func (s *tweetManageServant) LockPost(post *model.Post) error { func (s *tweetManageServant) LockPost(post *core.Post) error {
post.IsLock = 1 - post.IsLock post.IsLock = 1 - post.IsLock
return post.Update(s.db) 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 post.IsTop = 1 - post.IsTop
if err := post.Update(s.db); err != nil { if err := post.Update(s.db); err != nil {
return err return err
@ -265,7 +269,7 @@ func (s *tweetManageServant) StickPost(post *model.Post) error {
return nil 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 oldVisibility := post.Visibility
post.Visibility = visibility post.Visibility = visibility
// TODO: 这个判断是否可以不要呢 // TODO: 这个判断是否可以不要呢
@ -273,7 +277,7 @@ func (s *tweetManageServant) VisiblePost(post *model.Post, visibility model.Post
return nil return nil
} }
// 私密推文 特殊处理 // 私密推文 特殊处理
if visibility == model.PostVisitPrivate { if visibility == dbr.PostVisitPrivate {
// 强制取消置顶 // 强制取消置顶
// TODO: 置顶推文用户是否有权设置成私密? 后续完善 // TODO: 置顶推文用户是否有权设置成私密? 后续完善
post.IsTop = 0 post.IsTop = 0
@ -288,14 +292,14 @@ func (s *tweetManageServant) VisiblePost(post *model.Post, visibility model.Post
// tag处理 // tag处理
tags := strings.Split(post.Tags, ",") tags := strings.Split(post.Tags, ",")
for _, t := range tags { for _, t := range tags {
tag := &model.Tag{ tag := &dbr.Tag{
Tag: t, Tag: t,
} }
// TODO: 暂时宽松不处理错误,这里或许可以有优化,后续完善 // TODO: 暂时宽松不处理错误,这里或许可以有优化,后续完善
if oldVisibility == model.PostVisitPrivate { if oldVisibility == dbr.PostVisitPrivate {
// 从私密转为非私密才需要重新创建tag // 从私密转为非私密才需要重新创建tag
createTag(db, tag) createTag(db, tag)
} else if visibility == model.PostVisitPrivate { } else if visibility == dbr.PostVisitPrivate {
// 从非私密转为私密才需要删除tag // 从非私密转为私密才需要删除tag
deleteTag(db, tag) deleteTag(db, tag)
} }
@ -305,7 +309,7 @@ func (s *tweetManageServant) VisiblePost(post *model.Post, visibility model.Post
return nil 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 { if err := post.Update(s.db); err != nil {
return err return err
} }
@ -313,104 +317,104 @@ func (s *tweetManageServant) UpdatePost(post *model.Post) error {
return nil return nil
} }
func (s *tweetManageServant) CreatePostStar(postID, userID int64) (*model.PostStar, error) { func (s *tweetManageServant) CreatePostStar(postID, userID int64) (*core.PostStar, error) {
star := &model.PostStar{ star := &dbr.PostStar{
PostID: postID, PostID: postID,
UserID: userID, UserID: userID,
} }
return star.Create(s.db) 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) return p.Delete(s.db)
} }
func (s *tweetServant) GetPostByID(id int64) (*model.Post, error) { func (s *tweetServant) GetPostByID(id int64) (*core.Post, error) {
post := &model.Post{ post := &dbr.Post{
Model: &model.Model{ Model: &dbr.Model{
ID: id, ID: id,
}, },
} }
return post.Get(s.db) return post.Get(s.db)
} }
func (s *tweetServant) GetPosts(conditions *model.ConditionsT, offset, limit int) ([]*model.Post, error) { func (s *tweetServant) GetPosts(conditions *core.ConditionsT, offset, limit int) ([]*core.Post, error) {
return (&model.Post{}).List(s.db, conditions, offset, limit) return (&dbr.Post{}).List(s.db, conditions, offset, limit)
} }
func (s *tweetServant) GetPostCount(conditions *model.ConditionsT) (int64, error) { func (s *tweetServant) GetPostCount(conditions *core.ConditionsT) (int64, error) {
return (&model.Post{}).Count(s.db, conditions) return (&dbr.Post{}).Count(s.db, conditions)
} }
func (s *tweetServant) GetUserPostStar(postID, userID int64) (*model.PostStar, error) { func (s *tweetServant) GetUserPostStar(postID, userID int64) (*core.PostStar, error) {
star := &model.PostStar{ star := &dbr.PostStar{
PostID: postID, PostID: postID,
UserID: userID, UserID: userID,
} }
return star.Get(s.db) return star.Get(s.db)
} }
func (s *tweetServant) GetUserPostStars(userID int64, offset, limit int) ([]*model.PostStar, error) { func (s *tweetServant) GetUserPostStars(userID int64, offset, limit int) ([]*core.PostStar, error) {
star := &model.PostStar{ star := &dbr.PostStar{
UserID: userID, UserID: userID,
} }
return star.List(s.db, &model.ConditionsT{ return star.List(s.db, &dbr.ConditionsT{
"ORDER": s.db.NamingStrategy.TableName("PostStar") + ".id DESC", "ORDER": s.db.NamingStrategy.TableName("PostStar") + ".id DESC",
}, offset, limit) }, offset, limit)
} }
func (s *tweetServant) GetUserPostStarCount(userID int64) (int64, error) { func (s *tweetServant) GetUserPostStarCount(userID int64) (int64, error) {
star := &model.PostStar{ star := &dbr.PostStar{
UserID: userID, 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) { func (s *tweetServant) GetUserPostCollection(postID, userID int64) (*core.PostCollection, error) {
star := &model.PostCollection{ star := &dbr.PostCollection{
PostID: postID, PostID: postID,
UserID: userID, UserID: userID,
} }
return star.Get(s.db) return star.Get(s.db)
} }
func (s *tweetServant) GetUserPostCollections(userID int64, offset, limit int) ([]*model.PostCollection, error) { func (s *tweetServant) GetUserPostCollections(userID int64, offset, limit int) ([]*core.PostCollection, error) {
collection := &model.PostCollection{ collection := &dbr.PostCollection{
UserID: userID, UserID: userID,
} }
return collection.List(s.db, &model.ConditionsT{ return collection.List(s.db, &dbr.ConditionsT{
"ORDER": s.db.NamingStrategy.TableName("PostCollection") + ".id DESC", "ORDER": s.db.NamingStrategy.TableName("PostCollection") + ".id DESC",
}, offset, limit) }, offset, limit)
} }
func (s *tweetServant) GetUserPostCollectionCount(userID int64) (int64, error) { func (s *tweetServant) GetUserPostCollectionCount(userID int64) (int64, error) {
collection := &model.PostCollection{ collection := &dbr.PostCollection{
UserID: userID, 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) { func (s *tweetServant) GetUserWalletBills(userID int64, offset, limit int) ([]*core.WalletStatement, error) {
statement := &model.WalletStatement{ statement := &dbr.WalletStatement{
UserID: userID, UserID: userID,
} }
return statement.List(s.db, &model.ConditionsT{ return statement.List(s.db, &dbr.ConditionsT{
"ORDER": "id DESC", "ORDER": "id DESC",
}, offset, limit) }, offset, limit)
} }
func (s *tweetServant) GetUserWalletBillCount(userID int64) (int64, error) { func (s *tweetServant) GetUserWalletBillCount(userID int64) (int64, error) {
statement := &model.WalletStatement{ statement := &dbr.WalletStatement{
UserID: userID, 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) { func (s *tweetServant) GetPostAttatchmentBill(postID, userID int64) (*core.PostAttachmentBill, error) {
bill := &model.PostAttachmentBill{ bill := &dbr.PostAttachmentBill{
PostID: postID, PostID: postID,
UserID: userID, UserID: userID,
} }
@ -418,16 +422,16 @@ func (s *tweetServant) GetPostAttatchmentBill(postID, userID int64) (*model.Post
return bill.Get(s.db) return bill.Get(s.db)
} }
func (s *tweetServant) GetPostContentsByIDs(ids []int64) ([]*model.PostContent, error) { func (s *tweetServant) GetPostContentsByIDs(ids []int64) ([]*core.PostContent, error) {
return (&model.PostContent{}).List(s.db, &model.ConditionsT{ return (&dbr.PostContent{}).List(s.db, &dbr.ConditionsT{
"post_id IN ?": ids, "post_id IN ?": ids,
"ORDER": "sort ASC", "ORDER": "sort ASC",
}, 0, 0) }, 0, 0)
} }
func (s *tweetServant) GetPostContentByID(id int64) (*model.PostContent, error) { func (s *tweetServant) GetPostContentByID(id int64) (*core.PostContent, error) {
return (&model.PostContent{ return (&dbr.PostContent{
Model: &model.Model{ Model: &dbr.Model{
ID: id, ID: id,
}, },
}).Get(s.db) }).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 package jinzhu
import ( import (
"strings" "strings"
"github.com/rocboss/paopao-ce/internal/core" "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" "gorm.io/gorm"
) )
@ -22,69 +26,69 @@ func newUserManageService(db *gorm.DB) core.UserManageService {
} }
} }
func (s *userManageServant) GetUserByID(id int64) (*model.User, error) { func (s *userManageServant) GetUserByID(id int64) (*core.User, error) {
user := &model.User{ user := &dbr.User{
Model: &model.Model{ Model: &dbr.Model{
ID: id, ID: id,
}, },
} }
return user.Get(s.db) return user.Get(s.db)
} }
func (s *userManageServant) GetUserByUsername(username string) (*model.User, error) { func (s *userManageServant) GetUserByUsername(username string) (*core.User, error) {
user := &model.User{ user := &dbr.User{
Username: username, Username: username,
} }
return user.Get(s.db) return user.Get(s.db)
} }
func (s *userManageServant) GetUserByPhone(phone string) (*model.User, error) { func (s *userManageServant) GetUserByPhone(phone string) (*core.User, error) {
user := &model.User{ user := &dbr.User{
Phone: phone, Phone: phone,
} }
return user.Get(s.db) return user.Get(s.db)
} }
func (s *userManageServant) GetUsersByIDs(ids []int64) ([]*model.User, error) { func (s *userManageServant) GetUsersByIDs(ids []int64) ([]*core.User, error) {
user := &model.User{} user := &dbr.User{}
return user.List(s.db, &model.ConditionsT{ return user.List(s.db, &dbr.ConditionsT{
"id IN ?": ids, "id IN ?": ids,
}, 0, 0) }, 0, 0)
} }
func (s *userManageServant) GetUsersByKeyword(keyword string) ([]*model.User, error) { func (s *userManageServant) GetUsersByKeyword(keyword string) ([]*core.User, error) {
user := &model.User{} user := &dbr.User{}
keyword = strings.Trim(keyword, " ") + "%" keyword = strings.Trim(keyword, " ") + "%"
if keyword == "%" { if keyword == "%" {
return user.List(s.db, &model.ConditionsT{ return user.List(s.db, &dbr.ConditionsT{
"ORDER": "id ASC", "ORDER": "id ASC",
}, 0, 6) }, 0, 6)
} else { } else {
return user.List(s.db, &model.ConditionsT{ return user.List(s.db, &dbr.ConditionsT{
"username LIKE ?": keyword, "username LIKE ?": keyword,
}, 0, 6) }, 0, 6)
} }
} }
func (s *userManageServant) GetTagsByKeyword(keyword string) ([]*model.Tag, error) { func (s *userManageServant) GetTagsByKeyword(keyword string) ([]*core.Tag, error) {
tag := &model.Tag{} tag := &dbr.Tag{}
keyword = "%" + strings.Trim(keyword, " ") + "%" keyword = "%" + strings.Trim(keyword, " ") + "%"
if keyword == "%%" { if keyword == "%%" {
return tag.List(s.db, &model.ConditionsT{ return tag.List(s.db, &dbr.ConditionsT{
"ORDER": "quote_num DESC", "ORDER": "quote_num DESC",
}, 0, 6) }, 0, 6)
} else { } else {
return tag.List(s.db, &model.ConditionsT{ return tag.List(s.db, &dbr.ConditionsT{
"tag LIKE ?": keyword, "tag LIKE ?": keyword,
"ORDER": "quote_num DESC", "ORDER": "quote_num DESC",
}, 0, 6) }, 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) 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) 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 package jinzhu
import ( import (
"github.com/rocboss/paopao-ce/internal/model" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"gorm.io/gorm" "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) t, err := tag.Get(db)
if err != nil { if err != nil {
tag.QuoteNum = 1 tag.QuoteNum = 1
@ -23,7 +27,7 @@ func createTag(db *gorm.DB, tag *model.Tag) (*model.Tag, error) {
return t, nil 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) tag, err := tag.Get(db)
if err != nil { if err != nil {
return err return err
@ -33,7 +37,7 @@ func deleteTag(db *gorm.DB, tag *model.Tag) error {
} }
func deleteTags(db *gorm.DB, tags []string) 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 { if err != nil {
return err return err
} }
@ -51,9 +55,9 @@ func deleteTags(db *gorm.DB, tags []string) error {
} }
// 根据IDs获取用户列表 // 根据IDs获取用户列表
func getUsersByIDs(db *gorm.DB, ids []int64) ([]*model.User, error) { func getUsersByIDs(db *gorm.DB, ids []int64) ([]*dbr.User, error) {
user := &model.User{} user := &dbr.User{}
return user.List(db, &model.ConditionsT{ return user.List(db, &dbr.ConditionsT{
"id IN ?": ids, "id IN ?": ids,
}, 0, 0) }, 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 package jinzhu
import ( import (
"github.com/rocboss/paopao-ce/internal/conf" "github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"gorm.io/gorm" "gorm.io/gorm"
) )
@ -21,17 +25,17 @@ func newWalletService(db *gorm.DB) core.WalletService {
} }
} }
func (d *walletServant) GetRechargeByID(id int64) (*model.WalletRecharge, error) { func (d *walletServant) GetRechargeByID(id int64) (*core.WalletRecharge, error) {
recharge := &model.WalletRecharge{ recharge := &dbr.WalletRecharge{
Model: &model.Model{ Model: &dbr.Model{
ID: id, ID: id,
}, },
} }
return recharge.Get(d.db) return recharge.Get(d.db)
} }
func (d *walletServant) CreateRecharge(userId, amount int64) (*model.WalletRecharge, error) { func (d *walletServant) CreateRecharge(userId, amount int64) (*core.WalletRecharge, error) {
recharge := &model.WalletRecharge{ recharge := &dbr.WalletRecharge{
UserID: userId, UserID: userId,
Amount: amount, Amount: amount,
} }
@ -39,26 +43,26 @@ func (d *walletServant) CreateRecharge(userId, amount int64) (*model.WalletRecha
return recharge.Create(d.db) return recharge.Create(d.db)
} }
func (d *walletServant) GetUserWalletBills(userID int64, offset, limit int) ([]*model.WalletStatement, error) { func (d *walletServant) GetUserWalletBills(userID int64, offset, limit int) ([]*core.WalletStatement, error) {
statement := &model.WalletStatement{ statement := &dbr.WalletStatement{
UserID: userID, UserID: userID,
} }
return statement.List(d.db, &model.ConditionsT{ return statement.List(d.db, &dbr.ConditionsT{
"ORDER": "id DESC", "ORDER": "id DESC",
}, offset, limit) }, offset, limit)
} }
func (d *walletServant) GetUserWalletBillCount(userID int64) (int64, error) { func (d *walletServant) GetUserWalletBillCount(userID int64) (int64, error) {
statement := &model.WalletStatement{ statement := &dbr.WalletStatement{
UserID: userID, 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 { func (d *walletServant) HandleRechargeSuccess(recharge *core.WalletRecharge, tradeNo string) error {
user, _ := (&model.User{ user, _ := (&dbr.User{
Model: &model.Model{ Model: &dbr.Model{
ID: recharge.UserID, ID: recharge.UserID,
}, },
}).Get(d.db) }).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, UserID: user.ID,
ChangeAmount: recharge.Amount, ChangeAmount: recharge.Amount,
BalanceSnapshot: user.Balance + 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 { return d.db.Transaction(func(tx *gorm.DB) error {
// 扣除金额 // 扣除金额
if err := tx.Model(user).Update("balance", gorm.Expr("balance - ?", post.AttachmentPrice)).Error; err != nil { 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, PostID: post.ID,
UserID: user.ID, UserID: user.ID,
ChangeAmount: -post.AttachmentPrice, 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, PostID: post.ID,
UserID: user.ID, UserID: user.ID,
PaidAmount: post.AttachmentPrice, PaidAmount: post.AttachmentPrice,
@ -124,8 +128,8 @@ func (d *walletServant) HandlePostAttachmentBought(post *model.Post, user *model
// 对附件主新增账单 // 对附件主新增账单
income := int64(float64(post.AttachmentPrice) * conf.AppSetting.AttachmentIncomeRate) income := int64(float64(post.AttachmentPrice) * conf.AppSetting.AttachmentIncomeRate)
if income > 0 { if income > 0 {
master := &model.User{ master := &dbr.User{
Model: &model.Model{ Model: &dbr.Model{
ID: post.UserID, 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, PostID: post.ID,
UserID: master.ID, UserID: master.ID,
ChangeAmount: income, 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 // Core service implement base sqlx+mysql. All sub-service
// will declare here and provide initial function. // 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 package search
import ( import (
"time" "time"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -43,7 +46,7 @@ func (s *bridgeTweetSearchServant) DeleteDocuments(identifiers []string) error {
return nil 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) 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 package search
import ( import (
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/pkg/types" "github.com/rocboss/paopao-ce/pkg/types"
) )
@ -10,19 +13,19 @@ type tweetSearchFilter struct {
ams core.AuthorizationManageService 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 { if user != nil && user.IsAdmin {
return return
} }
var item *model.PostFormated var item *core.PostFormated
items := resp.Items items := resp.Items
latestIndex := len(items) - 1 latestIndex := len(items) - 1
if user == nil { if user == nil {
for i := 0; i <= latestIndex; i++ { for i := 0; i <= latestIndex; i++ {
item = items[i] item = items[i]
if item.Visibility != model.PostVisitPublic { if item.Visibility != core.PostVisitPublic {
items[i] = items[latestIndex] items[i] = items[latestIndex]
items = items[:latestIndex] items = items[:latestIndex]
resp.Total-- resp.Total--
@ -36,8 +39,8 @@ func (s *tweetSearchFilter) filterResp(user *model.User, resp *core.QueryResp) {
friendFilter[user.ID] = types.Empty{} friendFilter[user.ID] = types.Empty{}
for i := 0; i <= latestIndex; i++ { for i := 0; i <= latestIndex; i++ {
item = items[i] item = items[i]
cutFriend = (item.Visibility == model.PostVisitFriend && !friendFilter.IsFriend(item.UserID)) cutFriend = (item.Visibility == core.PostVisitFriend && !friendFilter.IsFriend(item.UserID))
cutPrivate = (item.Visibility == model.PostVisitPrivate && user.ID != item.UserID) cutPrivate = (item.Visibility == core.PostVisitPrivate && user.ID != item.UserID)
if cutFriend || cutPrivate { if cutFriend || cutPrivate {
items[i] = items[latestIndex] items[i] = items[latestIndex]
items = 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 package search
import ( import (
@ -7,7 +11,6 @@ import (
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/meilisearch/meilisearch-go" "github.com/meilisearch/meilisearch-go"
"github.com/rocboss/paopao-ce/internal/core" "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/json"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -28,20 +31,20 @@ type meiliTweetSearchServant struct {
} }
type postInfo struct { type postInfo struct {
ID int64 `json:"id"` ID int64 `json:"id"`
UserID int64 `json:"user_id"` UserID int64 `json:"user_id"`
CommentCount int64 `json:"comment_count"` CommentCount int64 `json:"comment_count"`
CollectionCount int64 `json:"collection_count"` CollectionCount int64 `json:"collection_count"`
UpvoteCount int64 `json:"upvote_count"` UpvoteCount int64 `json:"upvote_count"`
Visibility model.PostVisibleT `json:"visibility"` Visibility core.PostVisibleT `json:"visibility"`
IsTop int `json:"is_top"` IsTop int `json:"is_top"`
IsEssence int `json:"is_essence"` IsEssence int `json:"is_essence"`
IsLock int `json:"is_lock"` IsLock int `json:"is_lock"`
LatestRepliedOn int64 `json:"latest_replied_on"` LatestRepliedOn int64 `json:"latest_replied_on"`
CreatedOn int64 `json:"created_on"` CreatedOn int64 `json:"created_on"`
ModifiedOn int64 `json:"modified_on"` ModifiedOn int64 `json:"modified_on"`
AttachmentPrice int64 `json:"attachment_price"` AttachmentPrice int64 `json:"attachment_price"`
IPLoc string `json:"ip_loc"` IPLoc string `json:"ip_loc"`
} }
func (s *meiliTweetSearchServant) Name() string { func (s *meiliTweetSearchServant) Name() string {
@ -78,7 +81,7 @@ func (s *meiliTweetSearchServant) DeleteDocuments(identifiers []string) error {
return nil 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 != "" { if q.Type == core.SearchTypeDefault && q.Query != "" {
resp, err = s.queryByContent(user, q, offset, limit) resp, err = s.queryByContent(user, q, offset, limit)
} else if q.Type == core.SearchTypeTag && q.Query != "" { } else if q.Type == core.SearchTypeTag && q.Query != "" {
@ -96,7 +99,7 @@ func (s *meiliTweetSearchServant) Search(user *model.User, q *core.QueryReq, off
return 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{ request := &meilisearch.SearchRequest{
Offset: int64(offset), Offset: int64(offset),
Limit: int64(limit), Limit: int64(limit),
@ -117,7 +120,7 @@ func (s *meiliTweetSearchServant) queryByContent(user *model.User, q *core.Query
return s.postsFrom(resp) 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{ request := &meilisearch.SearchRequest{
Offset: int64(offset), Offset: int64(offset),
Limit: int64(limit), Limit: int64(limit),
@ -141,7 +144,7 @@ func (s *meiliTweetSearchServant) queryByTag(user *model.User, q *core.QueryReq,
return s.postsFrom(resp) 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{ request := &meilisearch.SearchRequest{
Offset: int64(offset), Offset: int64(offset),
Limit: int64(limit), Limit: int64(limit),
@ -161,7 +164,7 @@ func (s *meiliTweetSearchServant) queryAny(user *model.User, offset, limit int)
return s.postsFrom(resp) return s.postsFrom(resp)
} }
func (s *meiliTweetSearchServant) filterList(user *model.User) string { func (s *meiliTweetSearchServant) filterList(user *core.User) string {
if user == nil { if user == nil {
return s.publicFilter 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) { 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 { for _, hit := range resp.Hits {
raw, err := json.Marshal(hit) raw, err := json.Marshal(hit)
if err != nil { if err != nil {
@ -184,7 +187,7 @@ func (s *meiliTweetSearchServant) postsFrom(resp *meilisearch.SearchResponse) (*
if err = json.Unmarshal(raw, p); err != nil { if err = json.Unmarshal(raw, p); err != nil {
return nil, err return nil, err
} }
posts = append(posts, &model.PostFormated{ posts = append(posts, &core.PostFormated{
ID: p.ID, ID: p.ID,
UserID: p.UserID, UserID: p.UserID,
CommentCount: p.CommentCount, 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 package search
import ( import (
@ -6,7 +10,6 @@ import (
"github.com/meilisearch/meilisearch-go" "github.com/meilisearch/meilisearch-go"
"github.com/rocboss/paopao-ce/internal/conf" "github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/pkg/zinc" "github.com/rocboss/paopao-ce/pkg/zinc"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -40,9 +43,9 @@ func NewMeiliTweetSearchService(ams core.AuthorizationManageService) (core.Tweet
}, },
client: client, client: client,
index: client.Index(s.Index), index: client.Index(s.Index),
publicFilter: fmt.Sprintf("visibility=%d", model.PostVisitPublic), publicFilter: fmt.Sprintf("visibility=%d", core.PostVisitPublic),
privateFilter: fmt.Sprintf("visibility=%d AND user_id=", model.PostVisitPrivate), privateFilter: fmt.Sprintf("visibility=%d AND user_id=", core.PostVisitPrivate),
friendFilter: fmt.Sprintf("visibility=%d", model.PostVisitFriend), friendFilter: fmt.Sprintf("visibility=%d", core.PostVisitFriend),
} }
return mts, mts return mts, mts
} }
@ -55,9 +58,9 @@ func NewZincTweetSearchService(ams core.AuthorizationManageService) (core.TweetS
}, },
indexName: s.Index, indexName: s.Index,
client: zinc.NewClient(s), client: zinc.NewClient(s),
publicFilter: fmt.Sprintf("visibility:%d", model.PostVisitPublic), publicFilter: fmt.Sprintf("visibility:%d", core.PostVisitPublic),
privateFilter: fmt.Sprintf("visibility:%d AND user_id:%%d", model.PostVisitPrivate), privateFilter: fmt.Sprintf("visibility:%d AND user_id:%%d", core.PostVisitPrivate),
friendFilter: fmt.Sprintf("visibility:%d", model.PostVisitFriend), friendFilter: fmt.Sprintf("visibility:%d", core.PostVisitFriend),
} }
zts.createIndex() 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 package search
import ( import (
@ -5,7 +9,6 @@ import (
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/rocboss/paopao-ce/internal/core" "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/json"
"github.com/rocboss/paopao-ce/pkg/zinc" "github.com/rocboss/paopao-ce/pkg/zinc"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -73,7 +76,7 @@ func (s *zincTweetSearchServant) DeleteDocuments(identifiers []string) error {
return nil 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 != "" { if q.Type == core.SearchTypeDefault && q.Query != "" {
resp, err = s.queryByContent(user, q, offset, limit) resp, err = s.queryByContent(user, q, offset, limit)
} else if q.Type == core.SearchTypeTag && q.Query != "" { } else if q.Type == core.SearchTypeTag && q.Query != "" {
@ -91,7 +94,7 @@ func (s *zincTweetSearchServant) Search(user *model.User, q *core.QueryReq, offs
return 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{ resp, err := s.client.EsQuery(s.indexName, map[string]any{
"query": map[string]any{ "query": map[string]any{
"match_phrase": 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) 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{ resp, err := s.client.ApiQuery(s.indexName, map[string]any{
"search_type": "querystring", "search_type": "querystring",
"query": map[string]any{ "query": map[string]any{
@ -124,7 +127,7 @@ func (s *zincTweetSearchServant) queryByTag(user *model.User, q *core.QueryReq,
return s.postsFrom(resp) 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{ queryMap := map[string]any{
"query": map[string]any{ "query": map[string]any{
"match_all": map[string]string{}, "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) { 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 { for _, hit := range resp.Hits.Hits {
item := &model.PostFormated{} item := &core.PostFormated{}
raw, err := json.Marshal(hit.Source) raw, err := json.Marshal(hit.Source)
if err != nil { if err != nil {
return nil, err 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 package security
import ( 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 // Core service implement base sqlx+postgresql. All sub-service
// will declare here and provide initial function. // 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 package storage
import ( 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 package storage
import ( 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 package storage
import ( 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 package storage
import ( 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 package storage
import ( 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 package storage
import ( 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 package internal
import ( import (
"github.com/rocboss/paopao-ce/internal/migration" "github.com/rocboss/paopao-ce/internal/migration"
"github.com/rocboss/paopao-ce/internal/routers/api" "github.com/rocboss/paopao-ce/internal/servants/web/broker"
"github.com/rocboss/paopao-ce/internal/service" "github.com/rocboss/paopao-ce/internal/servants/web/routers/api"
) )
func Initialize() { func Initialize() {
@ -11,6 +15,6 @@ func Initialize() {
migration.Run() migration.Run()
// initialize service // initialize service
service.Initialize() broker.Initialize()
api.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 //go:build !migration
// +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 //go:build migration
// +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 ( import (
"github.com/gin-gonic/gin" "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/app"
"github.com/rocboss/paopao-ce/pkg/errcode" "github.com/rocboss/paopao-ce/pkg/errcode"
) )
@ -10,8 +14,8 @@ import (
func Admin() gin.HandlerFunc { func Admin() gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
if user, exist := c.Get("USER"); exist { if user, exist := c.Get("USER"); exist {
if userModel, ok := user.(*model.User); ok { if userModel, ok := user.(*core.User); ok {
if userModel.Status == model.UserStatusNormal && userModel.IsAdmin { if userModel.Status == core.UserStatusNormal && userModel.IsAdmin {
c.Next() c.Next()
return 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 ( import (
"strings" "strings"
@ -6,7 +10,7 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt/v4" "github.com/golang-jwt/jwt/v4"
"github.com/rocboss/paopao-ce/internal/conf" "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/app"
"github.com/rocboss/paopao-ce/pkg/errcode" "github.com/rocboss/paopao-ce/pkg/errcode"
) )
@ -51,8 +55,8 @@ func JWT() gin.HandlerFunc {
c.Set("USERNAME", claims.Username) c.Set("USERNAME", claims.Username)
// 加载用户信息 // 加载用户信息
user := &model.User{ user := &core.User{
Model: &model.Model{ Model: &core.Model{
ID: claims.UID, ID: claims.UID,
}, },
} }
@ -97,8 +101,8 @@ func JwtLoose() gin.HandlerFunc {
c.Set("UID", claims.UID) c.Set("UID", claims.UID)
c.Set("USERNAME", claims.Username) c.Set("USERNAME", claims.Username)
// 加载用户信息 // 加载用户信息
user := &model.User{ user := &core.User{
Model: &model.Model{ Model: &core.Model{
ID: claims.UID, ID: claims.UID,
}, },
} }

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

Loading…
Cancel
Save