prepare use mir

pull/196/head
Michael Li 2 years ago
parent fde5173e96
commit 5433eb9e8f

@ -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 {} +

@ -39,6 +39,7 @@ require (
gorm.io/plugin/dbresolver v1.1.0 gorm.io/plugin/dbresolver v1.1.0
gorm.io/plugin/soft_delete v1.1.0 gorm.io/plugin/soft_delete v1.1.0
modernc.org/sqlite v1.17.3 modernc.org/sqlite v1.17.3
github.com/alimy/mir/v3 v3.0.0
) )
require ( require (
@ -131,3 +132,7 @@ require (
modernc.org/strutil v1.1.1 // indirect modernc.org/strutil v1.1.1 // indirect
modernc.org/token v1.0.0 // indirect modernc.org/token v1.0.0 // indirect
) )
replace (
github.com/alimy/mir/v3 => ../../alimy/mir
)

@ -0,0 +1,27 @@
package model
import "gorm.io/gorm"
type AttachmentType int
const (
ATTACHMENT_TYPE_IMAGE AttachmentType = iota + 1
ATTACHMENT_TYPE_VIDEO
ATTACHMENT_TYPE_OTHER
)
type Attachment struct {
*Model
UserID int64 `json:"user_id"`
FileSize int64 `json:"file_size"`
ImgWidth int `json:"img_width"`
ImgHeight int `json:"img_height"`
Type AttachmentType `json:"type"`
Content string `json:"content"`
}
func (a *Attachment) Create(db *gorm.DB) (*Attachment, error) {
err := db.Create(&a).Error
return a, err
}

@ -0,0 +1,38 @@
package model
import "gorm.io/gorm"
type Captcha struct {
*Model
Phone string `json:"phone"`
Captcha string `json:"captcha"`
UseTimes int `json:"use_times"`
ExpiredOn int64 `json:"expired_on"`
}
func (c *Captcha) Create(db *gorm.DB) (*Captcha, error) {
err := db.Create(&c).Error
return c, err
}
func (c *Captcha) Update(db *gorm.DB) error {
return db.Model(&Captcha{}).Where("id = ? AND is_del = ?", c.Model.ID, 0).Save(c).Error
}
func (c *Captcha) Get(db *gorm.DB) (*Captcha, error) {
var captcha Captcha
if c.Model != nil && c.ID > 0 {
db = db.Where("id = ? AND is_del = ?", c.ID, 0)
}
if c.Phone != "" {
db = db.Where("phone = ?", c.Phone)
}
err := db.Last(&captcha).Error
if err != nil {
return &captcha, err
}
return &captcha, nil
}

@ -0,0 +1,127 @@
package model
import (
"time"
"gorm.io/gorm"
)
type Comment struct {
*Model
PostID int64 `json:"post_id"`
UserID int64 `json:"user_id"`
IP string `json:"ip"`
IPLoc string `json:"ip_loc"`
}
type CommentFormated struct {
ID int64 `json:"id"`
PostID int64 `json:"post_id"`
UserID int64 `json:"user_id"`
User *UserFormated `json:"user"`
Contents []*CommentContent `json:"contents"`
Replies []*CommentReplyFormated `json:"replies"`
IPLoc string `json:"ip_loc"`
CreatedOn int64 `json:"created_on"`
ModifiedOn int64 `json:"modified_on"`
}
func (c *Comment) Format() *CommentFormated {
if c.Model == nil {
return &CommentFormated{}
}
return &CommentFormated{
ID: c.Model.ID,
PostID: c.PostID,
UserID: c.UserID,
User: &UserFormated{},
Contents: []*CommentContent{},
Replies: []*CommentReplyFormated{},
IPLoc: c.IPLoc,
CreatedOn: c.CreatedOn,
ModifiedOn: c.ModifiedOn,
}
}
func (c *Comment) Get(db *gorm.DB) (*Comment, error) {
var comment Comment
if c.Model != nil && c.ID > 0 {
db = db.Where("id = ? AND is_del = ?", c.ID, 0)
} else {
return nil, gorm.ErrRecordNotFound
}
err := db.First(&comment).Error
if err != nil {
return &comment, err
}
return &comment, nil
}
func (c *Comment) List(db *gorm.DB, conditions *ConditionsT, offset, limit int) ([]*Comment, error) {
var comments []*Comment
var err error
if offset >= 0 && limit > 0 {
db = db.Offset(offset).Limit(limit)
}
if c.PostID > 0 {
db = db.Where("id = ?", c.PostID)
}
for k, v := range *conditions {
if k == "ORDER" {
db = db.Order(v)
} else {
db = db.Where(k, v)
}
}
if err = db.Where("is_del = ?", 0).Find(&comments).Error; err != nil {
return nil, err
}
return comments, nil
}
func (c *Comment) Count(db *gorm.DB, conditions *ConditionsT) (int64, error) {
var count int64
if c.PostID > 0 {
db = db.Where("post_id = ?", c.PostID)
}
for k, v := range *conditions {
if k != "ORDER" {
db = db.Where(k, v)
}
}
if err := db.Model(c).Count(&count).Error; err != nil {
return 0, err
}
return count, nil
}
func (c *Comment) Create(db *gorm.DB) (*Comment, error) {
err := db.Create(&c).Error
return c, err
}
func (c *Comment) Delete(db *gorm.DB) error {
return db.Model(c).Where("id = ?", c.Model.ID).Updates(map[string]any{
"deleted_on": time.Now().Unix(),
"is_del": 1,
}).Error
}
func (c *Comment) CommentIdsByPostId(db *gorm.DB, postId int64) (ids []int64, err error) {
err = db.Model(c).Where("post_id = ?", postId).Select("id").Find(&ids).Error
return
}
func (c *Comment) DeleteByPostId(db *gorm.DB, postId int64) error {
return db.Model(c).Where("post_id = ?", postId).Updates(map[string]any{
"deleted_on": time.Now().Unix(),
"is_del": 1,
}).Error
}

@ -0,0 +1,59 @@
package model
import (
"time"
"gorm.io/gorm"
)
type CommentContent struct {
*Model
CommentID int64 `json:"comment_id"`
UserID int64 `json:"user_id"`
Content string `json:"content"`
Type PostContentT `json:"type"`
Sort int64 `json:"sort"`
}
func (c *CommentContent) List(db *gorm.DB, conditions *ConditionsT, offset, limit int) ([]*CommentContent, error) {
var comments []*CommentContent
var err error
if offset >= 0 && limit > 0 {
db = db.Offset(offset).Limit(limit)
}
if c.CommentID > 0 {
db = db.Where("id = ?", c.CommentID)
}
for k, v := range *conditions {
if k == "ORDER" {
db = db.Order(v)
} else {
db = db.Where(k, v)
}
}
if err = db.Where("is_del = ?", 0).Find(&comments).Error; err != nil {
return nil, err
}
return comments, nil
}
func (c *CommentContent) Create(db *gorm.DB) (*CommentContent, error) {
err := db.Create(&c).Error
return c, err
}
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
return
}
func (c *CommentContent) DeleteByCommentIds(db *gorm.DB, commentIds []int64) error {
return db.Model(c).Where("comment_id IN ?", commentIds).Updates(map[string]any{
"deleted_on": time.Now().Unix(),
"is_del": 1,
}).Error
}

@ -0,0 +1,110 @@
package model
import (
"time"
"gorm.io/gorm"
)
type CommentReply struct {
*Model
CommentID int64 `json:"comment_id"`
UserID int64 `json:"user_id"`
AtUserID int64 `json:"at_user_id"`
Content string `json:"content"`
IP string `json:"ip"`
IPLoc string `json:"ip_loc"`
}
type CommentReplyFormated struct {
ID int64 `json:"id"`
CommentID int64 `json:"comment_id"`
UserID int64 `json:"user_id"`
User *UserFormated `json:"user"`
AtUserID int64 `json:"at_user_id"`
AtUser *UserFormated `json:"at_user"`
Content string `json:"content"`
IPLoc string `json:"ip_loc"`
CreatedOn int64 `json:"created_on"`
ModifiedOn int64 `json:"modified_on"`
}
func (c *CommentReply) Format() *CommentReplyFormated {
if c.Model == nil {
return &CommentReplyFormated{}
}
return &CommentReplyFormated{
ID: c.ID,
CommentID: c.CommentID,
UserID: c.UserID,
User: &UserFormated{},
AtUserID: c.AtUserID,
AtUser: &UserFormated{},
Content: c.Content,
IPLoc: c.IPLoc,
CreatedOn: c.CreatedOn,
ModifiedOn: c.ModifiedOn,
}
}
func (c *CommentReply) List(db *gorm.DB, conditions *ConditionsT, offset, limit int) ([]*CommentReply, error) {
var comments []*CommentReply
var err error
if offset >= 0 && limit > 0 {
db = db.Offset(offset).Limit(limit)
}
if c.CommentID > 0 {
db = db.Where("id = ?", c.CommentID)
}
for k, v := range *conditions {
if k == "ORDER" {
db = db.Order(v)
} else {
db = db.Where(k, v)
}
}
if err = db.Where("is_del = ?", 0).Find(&comments).Error; err != nil {
return nil, err
}
return comments, nil
}
func (c *CommentReply) Create(db *gorm.DB) (*CommentReply, error) {
err := db.Create(&c).Error
return c, err
}
func (c *CommentReply) Get(db *gorm.DB) (*CommentReply, error) {
var reply CommentReply
if c.Model != nil && c.ID > 0 {
db = db.Where("id = ? AND is_del = ?", c.ID, 0)
} else {
return nil, gorm.ErrRecordNotFound
}
err := db.First(&reply).Error
if err != nil {
return &reply, err
}
return &reply, nil
}
func (c *CommentReply) Delete(db *gorm.DB) error {
return db.Model(&CommentReply{}).Where("id = ? AND is_del = ?", c.Model.ID, 0).Updates(map[string]any{
"deleted_on": time.Now().Unix(),
"is_del": 1,
}).Error
}
func (c *CommentReply) DeleteByCommentIds(db *gorm.DB, commentIds []int64) error {
return db.Model(c).Where("comment_id IN ?", commentIds).Updates(map[string]any{
"deleted_on": time.Now().Unix(),
"is_del": 1,
}).Error
}

@ -0,0 +1,119 @@
package model
import (
"github.com/sirupsen/logrus"
"gorm.io/gorm"
)
const (
ContactStatusRequesting int8 = iota + 1
ContactStatusAgree
ContactStatusReject
ContactStatusDeleted
)
type Contact struct {
*Model
User *User `json:"-" gorm:"foreignKey:ID;references:FriendId"`
UserId int64 `json:"user_id"`
FriendId int64 `json:"friend_id"`
GroupId int64 `json:"group_id"`
Remark string `json:"remark"`
Status int8 `json:"status"` // 1请求好友, 2已同意好友, 3已拒绝好友, 4已删除好友
IsTop int8 `json:"is_top"`
IsBlack int8 `json:"is_black"`
NoticeEnable int8 `json:"notice_enable"`
}
func (c *Contact) FetchUser(db *gorm.DB) (*Contact, error) {
var contact Contact
err := db.Omit("User").Unscoped().Where("user_id = ? AND friend_id = ?", c.UserId, c.FriendId).First(&contact).Error
if err != nil {
logrus.Debugf("Contact.FetchUser fetch user error:%s", err)
return nil, err
}
return &contact, nil
}
func (c *Contact) GetByUserFriend(db *gorm.DB) (*Contact, error) {
var contact Contact
err := db.Omit("User").Where("user_id = ? AND friend_id = ?", c.UserId, c.FriendId).First(&contact).Error
if err != nil {
return nil, err
}
return &contact, nil
}
func (c *Contact) FetchByUserFriendAll(db *gorm.DB) ([]*Contact, error) {
var contacts []*Contact
if err := db.Omit("User").
Where("(user_id = ? AND friend_id = ?) OR (user_id = ? AND friend_id = ?)",
c.UserId, c.FriendId, c.FriendId, c.UserId).
Find(&contacts).Error; err != nil {
return nil, err
}
return contacts, nil
}
func (c *Contact) List(db *gorm.DB, conditions ConditionsT, offset, limit int) ([]*Contact, error) {
var contacts []*Contact
var err error
tn := db.NamingStrategy.TableName("Contact") + "."
if offset >= 0 && limit > 0 {
db = db.Offset(offset).Limit(limit)
}
for k, v := range conditions {
if k != "ORDER" {
db = db.Where(tn+k, v)
}
}
db.Joins("User").Order("`User`.`nickname` ASC")
if err = db.Find(&contacts).Error; err != nil {
return nil, err
}
return contacts, nil
}
func (c *Contact) BeFriendIds(db *gorm.DB) (ids []int64, err error) {
if err = db.Model(c).Omit("User").Select("user_id").Where("friend_id = ? AND status = ?", c.FriendId, ContactStatusAgree).Find(&ids).Error; err != nil {
return nil, err
}
return
}
func (c *Contact) MyFriendIds(db *gorm.DB) (ids []string, err error) {
if err = db.Model(c).Omit("User").Select("friend_id").Where("user_id = ? AND status = ?", c.UserId, ContactStatusAgree).Find(&ids).Error; err != nil {
return nil, err
}
return
}
func (m *Contact) Count(db *gorm.DB, conditions ConditionsT) (int64, error) {
var count int64
for k, v := range conditions {
if k != "ORDER" {
db = db.Where(k, v)
}
}
if err := db.Model(m).Omit("User").Count(&count).Error; err != nil {
return 0, err
}
return count, nil
}
func (c *Contact) Create(db *gorm.DB) (*Contact, error) {
err := db.Omit("User").Create(&c).Error
return c, err
}
func (c *Contact) Update(db *gorm.DB) error {
return db.Model(&Contact{}).Omit("User").Where("id = ?", c.Model.ID).Save(c).Error
}
func (c *Contact) UpdateInUnscoped(db *gorm.DB) error {
return db.Unscoped().Omit("User").Save(c).Error
}

@ -0,0 +1,36 @@
package model
import (
"time"
"gorm.io/gorm"
"gorm.io/plugin/soft_delete"
)
// Model 公共Model
type Model struct {
ID int64 `gorm:"primary_key" json:"id"`
CreatedOn int64 `json:"created_on"`
ModifiedOn int64 `json:"modified_on"`
DeletedOn int64 `json:"deleted_on"`
IsDel soft_delete.DeletedAt `gorm:"softDelete:flag" json:"is_del"`
}
type ConditionsT map[string]any
type Predicates map[string][]any
func (m *Model) BeforeCreate(tx *gorm.DB) (err error) {
nowTime := time.Now().Unix()
tx.Statement.SetColumn("created_on", nowTime)
tx.Statement.SetColumn("modified_on", nowTime)
return
}
func (m *Model) BeforeUpdate(tx *gorm.DB) (err error) {
if !tx.Statement.Changed("modified_on") {
tx.Statement.SetColumn("modified_on", time.Now().Unix())
}
return
}

@ -0,0 +1,148 @@
package model
import "gorm.io/gorm"
type MessageT int8
const (
MsgTypePost MessageT = iota + 1
MsgtypeComment
MsgTypeReply
MsgTypeWhisper
MsgTypeRequestingFriend
MsgTypeSystem MessageT = 99
MsgStatusUnread = 0
MsgStatusReaded = 1
)
type Message struct {
*Model
SenderUserID int64 `json:"sender_user_id"`
ReceiverUserID int64 `json:"receiver_user_id"`
Type MessageT `json:"type"`
Brief string `json:"brief"`
Content string `json:"content"`
PostID int64 `json:"post_id"`
CommentID int64 `json:"comment_id"`
ReplyID int64 `json:"reply_id"`
IsRead int8 `json:"is_read"`
}
type MessageFormated struct {
ID int64 `json:"id"`
SenderUserID int64 `json:"sender_user_id"`
SenderUser *UserFormated `json:"sender_user"`
ReceiverUserID int64 `json:"receiver_user_id"`
Type MessageT `json:"type"`
Brief string `json:"brief"`
Content string `json:"content"`
PostID int64 `json:"post_id"`
Post *PostFormated `json:"post"`
CommentID int64 `json:"comment_id"`
Comment *Comment `json:"comment"`
ReplyID int64 `json:"reply_id"`
Reply *CommentReply `json:"reply"`
IsRead int8 `json:"is_read"`
CreatedOn int64 `json:"created_on"`
ModifiedOn int64 `json:"modified_on"`
}
func (m *Message) Format() *MessageFormated {
if m.Model == nil || m.Model.ID == 0 {
return nil
}
mf := &MessageFormated{
ID: m.ID,
SenderUserID: m.SenderUserID,
SenderUser: &UserFormated{},
ReceiverUserID: m.ReceiverUserID,
Type: m.Type,
Brief: m.Brief,
Content: m.Content,
PostID: m.PostID,
Post: &PostFormated{},
CommentID: m.CommentID,
Comment: &Comment{},
ReplyID: m.ReplyID,
Reply: &CommentReply{},
IsRead: m.IsRead,
CreatedOn: m.CreatedOn,
ModifiedOn: m.ModifiedOn,
}
return mf
}
func (m *Message) Create(db *gorm.DB) (*Message, error) {
err := db.Create(&m).Error
return m, err
}
func (m *Message) Update(db *gorm.DB) error {
return db.Model(&Message{}).Where("id = ? AND is_del = ?", m.Model.ID, 0).Save(m).Error
}
func (m *Message) Get(db *gorm.DB) (*Message, error) {
var message Message
if m.Model != nil && m.ID > 0 {
db = db.Where("id = ? AND is_del = ?", m.ID, 0)
}
if m.ReceiverUserID > 0 {
db = db.Where("receiver_user_id = ?", m.ReceiverUserID)
}
if err := db.First(&message).Error; err != nil {
return nil, err
}
return &message, nil
}
func (m *Message) FetchBy(db *gorm.DB, predicates Predicates) ([]*Message, error) {
var messages []*Message
for k, v := range predicates {
db = db.Where(k, v...)
}
db = db.Where("is_del = 0")
if err := db.Find(&messages).Error; err != nil {
return nil, err
}
return messages, nil
}
func (c *Message) List(db *gorm.DB, conditions *ConditionsT, offset, limit int) ([]*Message, error) {
var messages []*Message
var err error
if offset >= 0 && limit > 0 {
db = db.Offset(offset).Limit(limit)
}
for k, v := range *conditions {
if k == "ORDER" {
db = db.Order(v)
} else {
db = db.Where(k, v)
}
}
if err = db.Where("is_del = ?", 0).Find(&messages).Error; err != nil {
return nil, err
}
return messages, nil
}
func (m *Message) Count(db *gorm.DB, conditions *ConditionsT) (int64, error) {
var count int64
for k, v := range *conditions {
if k != "ORDER" {
db = db.Where(k, v)
}
}
if err := db.Model(m).Count(&count).Error; err != nil {
return 0, err
}
return count, nil
}

@ -0,0 +1,208 @@
package model
import (
"strings"
"time"
"gorm.io/gorm"
)
// PostVisibleT 可访问类型0公开1私密2好友
type PostVisibleT uint8
const (
PostVisitPublic PostVisibleT = iota
PostVisitPrivate
PostVisitFriend
PostVisitInvalid
)
type Post struct {
*Model
UserID int64 `json:"user_id"`
CommentCount int64 `json:"comment_count"`
CollectionCount int64 `json:"collection_count"`
UpvoteCount int64 `json:"upvote_count"`
Visibility PostVisibleT `json:"visibility"`
IsTop int `json:"is_top"`
IsEssence int `json:"is_essence"`
IsLock int `json:"is_lock"`
LatestRepliedOn int64 `json:"latest_replied_on"`
Tags string `json:"tags"`
AttachmentPrice int64 `json:"attachment_price"`
IP string `json:"ip"`
IPLoc string `json:"ip_loc"`
}
type PostFormated struct {
ID int64 `json:"id"`
UserID int64 `json:"user_id"`
User *UserFormated `json:"user"`
Contents []*PostContentFormated `json:"contents"`
CommentCount int64 `json:"comment_count"`
CollectionCount int64 `json:"collection_count"`
UpvoteCount int64 `json:"upvote_count"`
Visibility PostVisibleT `json:"visibility"`
IsTop int `json:"is_top"`
IsEssence int `json:"is_essence"`
IsLock int `json:"is_lock"`
LatestRepliedOn int64 `json:"latest_replied_on"`
CreatedOn int64 `json:"created_on"`
ModifiedOn int64 `json:"modified_on"`
Tags map[string]int8 `json:"tags"`
AttachmentPrice int64 `json:"attachment_price"`
IPLoc string `json:"ip_loc"`
}
func (p *Post) Format() *PostFormated {
if p.Model != nil {
tagsMap := map[string]int8{}
for _, tag := range strings.Split(p.Tags, ",") {
tagsMap[tag] = 1
}
return &PostFormated{
ID: p.ID,
UserID: p.UserID,
User: &UserFormated{},
Contents: []*PostContentFormated{},
CommentCount: p.CommentCount,
CollectionCount: p.CollectionCount,
UpvoteCount: p.UpvoteCount,
Visibility: p.Visibility,
IsTop: p.IsTop,
IsEssence: p.IsEssence,
IsLock: p.IsLock,
LatestRepliedOn: p.LatestRepliedOn,
CreatedOn: p.CreatedOn,
ModifiedOn: p.ModifiedOn,
AttachmentPrice: p.AttachmentPrice,
Tags: tagsMap,
IPLoc: p.IPLoc,
}
}
return nil
}
func (p *Post) Create(db *gorm.DB) (*Post, error) {
err := db.Create(&p).Error
return p, err
}
func (s *Post) Delete(db *gorm.DB) error {
return db.Model(s).Where("id = ?", s.Model.ID).Updates(map[string]any{
"deleted_on": time.Now().Unix(),
"is_del": 1,
}).Error
}
func (p *Post) Get(db *gorm.DB) (*Post, error) {
var post Post
if p.Model != nil && p.ID > 0 {
db = db.Where("id = ? AND is_del = ?", p.ID, 0)
} else {
return nil, gorm.ErrRecordNotFound
}
err := db.First(&post).Error
if err != nil {
return &post, err
}
return &post, nil
}
func (p *Post) List(db *gorm.DB, conditions *ConditionsT, offset, limit int) ([]*Post, error) {
var posts []*Post
var err error
if offset >= 0 && limit > 0 {
db = db.Offset(offset).Limit(limit)
}
if p.UserID > 0 {
db = db.Where("user_id = ?", p.UserID)
}
for k, v := range *conditions {
if k == "ORDER" {
db = db.Order(v)
} else {
db = db.Where(k, v)
}
}
if err = db.Where("is_del = ?", 0).Find(&posts).Error; err != nil {
return nil, err
}
return posts, nil
}
func (p *Post) Fetch(db *gorm.DB, predicates Predicates, offset, limit int) ([]*Post, error) {
var posts []*Post
var err error
if offset >= 0 && limit > 0 {
db = db.Offset(offset).Limit(limit)
}
if p.UserID > 0 {
db = db.Where("user_id = ?", p.UserID)
}
for query, args := range predicates {
if query == "ORDER" {
db = db.Order(args[0])
} else {
db = db.Where(query, args...)
}
}
if err = db.Where("is_del = ?", 0).Find(&posts).Error; err != nil {
return nil, err
}
return posts, nil
}
func (p *Post) CountBy(db *gorm.DB, predicates Predicates) (count int64, err error) {
for query, args := range predicates {
if query != "ORDER" {
db = db.Where(query, args...)
}
}
err = db.Model(p).Count(&count).Error
return
}
func (p *Post) Count(db *gorm.DB, conditions *ConditionsT) (int64, error) {
var count int64
if p.UserID > 0 {
db = db.Where("user_id = ?", p.UserID)
}
for k, v := range *conditions {
if k != "ORDER" {
db = db.Where(k, v)
}
}
if err := db.Model(p).Count(&count).Error; err != nil {
return 0, err
}
return count, nil
}
func (p *Post) Update(db *gorm.DB) error {
return db.Model(&Post{}).Where("id = ? AND is_del = ?", p.Model.ID, 0).Save(p).Error
}
func (p PostVisibleT) String() string {
switch p {
case PostVisitPublic:
return "public"
case PostVisitPrivate:
return "private"
case PostVisitFriend:
return "friend"
case PostVisitInvalid:
return "invalid"
default:
return "unknow"
}
}

@ -0,0 +1,36 @@
package model
import "gorm.io/gorm"
type PostAttachmentBill struct {
*Model
PostID int64 `json:"post_id"`
UserID int64 `json:"user_id"`
PaidAmount int64 `json:"paid_amount"`
}
func (p *PostAttachmentBill) Get(db *gorm.DB) (*PostAttachmentBill, error) {
var pas PostAttachmentBill
if p.Model != nil && p.ID > 0 {
db = db.Where("id = ? AND is_del = ?", p.ID, 0)
}
if p.PostID > 0 {
db = db.Where("post_id = ?", p.PostID)
}
if p.UserID > 0 {
db = db.Where("user_id = ?", p.UserID)
}
err := db.First(&pas).Error
if err != nil {
return &pas, err
}
return &pas, nil
}
func (p *PostAttachmentBill) Create(db *gorm.DB) (*PostAttachmentBill, error) {
err := db.Create(&p).Error
return p, err
}

@ -0,0 +1,102 @@
package model
import (
"time"
"gorm.io/gorm"
)
type PostCollection struct {
*Model
Post *Post `json:"-"`
PostID int64 `json:"post_id"`
UserID int64 `json:"user_id"`
}
func (p *PostCollection) Get(db *gorm.DB) (*PostCollection, error) {
var star PostCollection
tn := db.NamingStrategy.TableName("PostCollection") + "."
if p.Model != nil && p.ID > 0 {
db = db.Where(tn+"id = ? AND "+tn+"is_del = ?", p.ID, 0)
}
if p.PostID > 0 {
db = db.Where(tn+"post_id = ?", p.PostID)
}
if p.UserID > 0 {
db = db.Where(tn+"user_id = ?", p.UserID)
}
db = db.Joins("Post").Where("Post.visibility <> ?", PostVisitPrivate).Order("Post.id DESC")
err := db.First(&star).Error
if err != nil {
return &star, err
}
return &star, nil
}
func (p *PostCollection) Create(db *gorm.DB) (*PostCollection, error) {
err := db.Omit("Post").Create(&p).Error
return p, err
}
func (p *PostCollection) Delete(db *gorm.DB) error {
return db.Model(&PostCollection{}).Omit("Post").Where("id = ? AND is_del = ?", p.Model.ID, 0).Updates(map[string]any{
"deleted_on": time.Now().Unix(),
"is_del": 1,
}).Error
}
func (p *PostCollection) List(db *gorm.DB, conditions *ConditionsT, offset, limit int) ([]*PostCollection, error) {
var collections []*PostCollection
var err error
tn := db.NamingStrategy.TableName("PostCollection") + "."
if offset >= 0 && limit > 0 {
db = db.Offset(offset).Limit(limit)
}
if p.UserID > 0 {
db = db.Where(tn+"user_id = ?", p.UserID)
}
for k, v := range *conditions {
if k == "ORDER" {
db = db.Order(v)
} else {
db = db.Where(tn+k, v)
}
}
db = db.Joins("Post").Where("Post.visibility <> ?", PostVisitPrivate).Order("Post.id DESC")
if err = db.Where(tn+"is_del = ?", 0).Find(&collections).Error; err != nil {
return nil, err
}
return collections, nil
}
func (p *PostCollection) Count(db *gorm.DB, conditions *ConditionsT) (int64, error) {
var count int64
tn := db.NamingStrategy.TableName("PostCollection") + "."
if p.PostID > 0 {
db = db.Where(tn+"post_id = ?", p.PostID)
}
if p.UserID > 0 {
db = db.Where(tn+"user_id = ?", p.UserID)
}
for k, v := range *conditions {
if k != "ORDER" {
db = db.Where(tn+k, v)
}
}
db = db.Joins("Post").Where("Post.visibility <> ?", PostVisitPrivate)
if err := db.Model(p).Count(&count).Error; err != nil {
return 0, err
}
return count, nil
}

@ -0,0 +1,121 @@
package model
import (
"time"
"gorm.io/gorm"
)
// 类型1标题2文字段落3图片地址4视频地址5语音地址6链接地址7附件资源
type PostContentT int
const (
CONTENT_TYPE_TITLE PostContentT = iota + 1
CONTENT_TYPE_TEXT
CONTENT_TYPE_IMAGE
CONTENT_TYPE_VIDEO
CONTENT_TYPE_AUDIO
CONTENT_TYPE_LINK
CONTENT_TYPE_ATTACHMENT
CONTENT_TYPE_CHARGE_ATTACHMENT
)
var (
mediaContentType = []PostContentT{
CONTENT_TYPE_IMAGE,
CONTENT_TYPE_VIDEO,
CONTENT_TYPE_AUDIO,
CONTENT_TYPE_ATTACHMENT,
CONTENT_TYPE_CHARGE_ATTACHMENT,
}
)
type PostContent struct {
*Model
PostID int64 `json:"post_id"`
UserID int64 `json:"user_id"`
Content string `json:"content"`
Type PostContentT `json:"type"`
Sort int64 `json:"sort"`
}
type PostContentFormated struct {
ID int64 `json:"id"`
PostID int64 `json:"post_id"`
Content string `json:"content"`
Type PostContentT `json:"type"`
Sort int64 `json:"sort"`
}
func (p *PostContent) DeleteByPostId(db *gorm.DB, postId int64) error {
return db.Model(p).Where("post_id = ?", postId).Updates(map[string]any{
"deleted_on": time.Now().Unix(),
"is_del": 1,
}).Error
}
func (p *PostContent) MediaContentsByPostId(db *gorm.DB, postId int64) (contents []string, err error) {
err = db.Model(p).Where("post_id = ? AND type IN ?", postId, mediaContentType).Select("content").Find(&contents).Error
return
}
func (p *PostContent) Create(db *gorm.DB) (*PostContent, error) {
err := db.Create(&p).Error
return p, err
}
func (p *PostContent) Format() *PostContentFormated {
if p.Model == nil {
return nil
}
return &PostContentFormated{
ID: p.ID,
PostID: p.PostID,
Content: p.Content,
Type: p.Type,
Sort: p.Sort,
}
}
func (p *PostContent) List(db *gorm.DB, conditions *ConditionsT, offset, limit int) ([]*PostContent, error) {
var contents []*PostContent
var err error
if offset >= 0 && limit > 0 {
db = db.Offset(offset).Limit(limit)
}
if p.PostID > 0 {
db = db.Where("id = ?", p.PostID)
}
for k, v := range *conditions {
if k == "ORDER" {
db = db.Order(v)
} else {
db = db.Where(k, v)
}
}
if err = db.Where("is_del = ?", 0).Find(&contents).Error; err != nil {
return nil, err
}
return contents, nil
}
func (p *PostContent) Get(db *gorm.DB) (*PostContent, error) {
var content PostContent
if p.Model != nil && p.ID > 0 {
db = db.Where("id = ? AND is_del = ?", p.ID, 0)
} else {
return nil, gorm.ErrRecordNotFound
}
err := db.First(&content).Error
if err != nil {
return &content, err
}
return &content, nil
}

@ -0,0 +1,98 @@
package model
import (
"time"
"gorm.io/gorm"
)
type PostStar struct {
*Model
Post *Post `json:"-"`
PostID int64 `json:"post_id"`
UserID int64 `json:"user_id"`
}
func (p *PostStar) Get(db *gorm.DB) (*PostStar, error) {
var star PostStar
tn := db.NamingStrategy.TableName("PostStar") + "."
if p.Model != nil && p.ID > 0 {
db = db.Where(tn+"id = ? AND "+tn+"is_del = ?", p.ID, 0)
}
if p.PostID > 0 {
db = db.Where(tn+"post_id = ?", p.PostID)
}
if p.UserID > 0 {
db = db.Where(tn+"user_id = ?", p.UserID)
}
db = db.Joins("Post").Where("Post.visibility <> ?", PostVisitPrivate).Order("Post.id DESC")
if err := db.First(&star).Error; err != nil {
return nil, err
}
return &star, nil
}
func (p *PostStar) Create(db *gorm.DB) (*PostStar, error) {
err := db.Omit("Post").Create(&p).Error
return p, err
}
func (p *PostStar) Delete(db *gorm.DB) error {
return db.Model(&PostStar{}).Omit("Post").Where("id = ? AND is_del = ?", p.Model.ID, 0).Updates(map[string]any{
"deleted_on": time.Now().Unix(),
"is_del": 1,
}).Error
}
func (p *PostStar) List(db *gorm.DB, conditions *ConditionsT, offset, limit int) ([]*PostStar, error) {
var stars []*PostStar
var err error
tn := db.NamingStrategy.TableName("PostStar") + "."
if offset >= 0 && limit > 0 {
db = db.Offset(offset).Limit(limit)
}
if p.UserID > 0 {
db = db.Where(tn+"user_id = ?", p.UserID)
}
for k, v := range *conditions {
if k == "ORDER" {
db = db.Order(v)
} else {
db = db.Where(tn+k, v)
}
}
db = db.Joins("Post").Where("Post.visibility <> ?", PostVisitPrivate).Order("Post.id DESC")
if err = db.Find(&stars).Error; err != nil {
return nil, err
}
return stars, nil
}
func (p *PostStar) Count(db *gorm.DB, conditions *ConditionsT) (int64, error) {
var count int64
tn := db.NamingStrategy.TableName("PostStar") + "."
if p.PostID > 0 {
db = db.Where(tn+"post_id = ?", p.PostID)
}
if p.UserID > 0 {
db = db.Where(tn+"user_id = ?", p.UserID)
}
for k, v := range *conditions {
if k != "ORDER" {
db = db.Where(tn+k, v)
}
}
db = db.Joins("Post").Where("Post.visibility <> ?", PostVisitPrivate)
if err := db.Model(p).Count(&count).Error; err != nil {
return 0, err
}
return count, nil
}

@ -0,0 +1,97 @@
package model
import (
"time"
"gorm.io/gorm"
)
type Tag struct {
*Model
UserID int64 `json:"user_id"`
Tag string `json:"tag"`
QuoteNum int64 `json:"quote_num"`
}
type TagFormated struct {
ID int64 `json:"id"`
UserID int64 `json:"user_id"`
User *UserFormated `json:"user"`
Tag string `json:"tag"`
QuoteNum int64 `json:"quote_num"`
}
func (t *Tag) Format() *TagFormated {
if t.Model == nil {
return &TagFormated{}
}
return &TagFormated{
ID: t.ID,
UserID: t.UserID,
User: &UserFormated{},
Tag: t.Tag,
QuoteNum: t.QuoteNum,
}
}
func (t *Tag) Get(db *gorm.DB) (*Tag, error) {
var tag Tag
if t.Model != nil && t.Model.ID > 0 {
db = db.Where("id= ? AND is_del = ?", t.Model.ID, 0)
} else {
db = db.Where("tag = ? AND is_del = ?", t.Tag, 0)
}
err := db.First(&tag).Error
if err != nil {
return &tag, err
}
return &tag, nil
}
func (t *Tag) Create(db *gorm.DB) (*Tag, error) {
err := db.Create(&t).Error
return t, err
}
func (t *Tag) Update(db *gorm.DB) error {
return db.Model(&Tag{}).Where("id = ? AND is_del = ?", t.Model.ID, 0).Save(t).Error
}
func (t *Tag) Delete(db *gorm.DB) error {
return db.Model(t).Where("id = ?", t.Model.ID).Updates(map[string]any{
"deleted_on": time.Now().Unix(),
"is_del": 1,
}).Error
}
func (t *Tag) List(db *gorm.DB, conditions *ConditionsT, offset, limit int) ([]*Tag, error) {
var tags []*Tag
var err error
if offset >= 0 && limit > 0 {
db = db.Offset(offset).Limit(limit)
}
if t.UserID > 0 {
db = db.Where("user_id = ?", t.UserID)
}
for k, v := range *conditions {
if k == "ORDER" {
db = db.Order(v)
} else {
db = db.Where(k, v)
}
}
if err = db.Where("is_del = ?", 0).Find(&tags).Error; err != nil {
return nil, err
}
return tags, nil
}
func (t *Tag) TagsFrom(db *gorm.DB, tags []string) (res []*Tag, err error) {
err = db.Where("tag IN ?", tags).Find(&res).Error
return
}

@ -0,0 +1,94 @@
package model
import "gorm.io/gorm"
const (
UserStatusNormal int = iota + 1
UserStatusClosed
)
type User struct {
*Model
Nickname string `json:"nickname"`
Username string `json:"username"`
Phone string `json:"phone"`
Password string `json:"password"`
Salt string `json:"salt"`
Status int `json:"status"`
Avatar string `json:"avatar"`
Balance int64 `json:"balance"`
IsAdmin bool `json:"is_admin"`
}
type UserFormated 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"`
}
func (u *User) Format() *UserFormated {
if u.Model != nil {
return &UserFormated{
ID: u.ID,
Nickname: u.Nickname,
Username: u.Username,
Status: u.Status,
Avatar: u.Avatar,
IsAdmin: u.IsAdmin,
}
}
return nil
}
func (u *User) Get(db *gorm.DB) (*User, error) {
var user User
if u.Model != nil && u.Model.ID > 0 {
db = db.Where("id= ? AND is_del = ?", u.Model.ID, 0)
} else if u.Phone != "" {
db = db.Where("phone = ? AND is_del = ?", u.Phone, 0)
} else {
db = db.Where("username = ? AND is_del = ?", u.Username, 0)
}
err := db.First(&user).Error
if err != nil {
return &user, err
}
return &user, nil
}
func (u *User) List(db *gorm.DB, conditions *ConditionsT, offset, limit int) ([]*User, error) {
var users []*User
var err error
if offset >= 0 && limit > 0 {
db = db.Offset(offset).Limit(limit)
}
for k, v := range *conditions {
if k == "ORDER" {
db = db.Order(v)
} else {
db = db.Where(k, v)
}
}
if err = db.Where("is_del = ?", 0).Find(&users).Error; err != nil {
return nil, err
}
return users, nil
}
func (u *User) Create(db *gorm.DB) (*User, error) {
err := db.Create(&u).Error
return u, err
}
func (u *User) Update(db *gorm.DB) error {
return db.Model(&User{}).Where("id = ? AND is_del = ?", u.Model.ID, 0).Save(u).Error
}

@ -0,0 +1,34 @@
package model
import "gorm.io/gorm"
type WalletRecharge struct {
*Model
UserID int64 `json:"user_id"`
Amount int64 `json:"amount"`
TradeNo string `json:"trade_no"`
TradeStatus string `json:"trade_status"`
}
func (p *WalletRecharge) Get(db *gorm.DB) (*WalletRecharge, error) {
var pas WalletRecharge
if p.Model != nil && p.ID > 0 {
db = db.Where("id = ? AND is_del = ?", p.ID, 0)
}
if p.UserID > 0 {
db = db.Where("user_id = ?", p.UserID)
}
err := db.First(&pas).Error
if err != nil {
return &pas, err
}
return &pas, nil
}
func (p *WalletRecharge) Create(db *gorm.DB) (*WalletRecharge, error) {
err := db.Create(&p).Error
return p, err
}

@ -0,0 +1,83 @@
package model
import "gorm.io/gorm"
type WalletStatement struct {
*Model
UserID int64 `json:"user_id"`
ChangeAmount int64 `json:"change_amount"`
BalanceSnapshot int64 `json:"balance_snapshot"`
Reason string `json:"reason"`
PostID int64 `json:"post_id"`
}
func (w *WalletStatement) Get(db *gorm.DB) (*WalletStatement, error) {
var ws WalletStatement
if w.Model != nil && w.ID > 0 {
db = db.Where("id = ? AND is_del = ?", w.ID, 0)
}
if w.PostID > 0 {
db = db.Where("post_id = ?", w.PostID)
}
if w.UserID > 0 {
db = db.Where("user_id = ?", w.UserID)
}
err := db.First(&ws).Error
if err != nil {
return &ws, err
}
return &ws, nil
}
func (w *WalletStatement) Create(db *gorm.DB) (*WalletStatement, error) {
err := db.Create(&w).Error
return w, err
}
func (w *WalletStatement) List(db *gorm.DB, conditions *ConditionsT, offset, limit int) ([]*WalletStatement, error) {
var records []*WalletStatement
var err error
if offset >= 0 && limit > 0 {
db = db.Offset(offset).Limit(limit)
}
if w.UserID > 0 {
db = db.Where("user_id = ?", w.UserID)
}
for k, v := range *conditions {
if k == "ORDER" {
db = db.Order(v)
} else {
db = db.Where(k, v)
}
}
if err = db.Where("is_del = ?", 0).Find(&records).Error; err != nil {
return nil, err
}
return records, nil
}
func (w *WalletStatement) Count(db *gorm.DB, conditions *ConditionsT) (int64, error) {
var count int64
if w.PostID > 0 {
db = db.Where("post_id = ?", w.PostID)
}
if w.UserID > 0 {
db = db.Where("user_id = ?", w.UserID)
}
for k, v := range *conditions {
if k != "ORDER" {
db = db.Where(k, v)
}
}
if err := db.Model(w).Count(&count).Error; err != nil {
return 0, err
}
return count, nil
}

@ -0,0 +1,144 @@
// Code generated by go-mir. DO NOT EDIT.
package v1
import (
"errors"
"net/http"
gin "github.com/gin-gonic/gin"
)
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 interface {
// Chain provide handlers chain for gin
Chain() gin.HandlersChain
Index(c *gin.Context) error
Articles(c *gin.Context) error
Login(c *gin.Context, req *LoginReq) (*LoginResp, error)
Logout(c *gin.Context) error
mustEmbedUnimplementedWebCoreServant()
}
type WebCoreBinding interface {
BindLogin(c *gin.Context) (*LoginReq, error)
mustEmbedUnimplementedWebCoreBinding()
}
type WebCoreRender interface {
RenderIndex(c *gin.Context, err error)
RenderArticles(c *gin.Context, err error)
RenderLogin(c *gin.Context, data *LoginResp, err error)
RenderLogout(c *gin.Context, err 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("GET", "/index/", func(c *gin.Context) {
r.RenderIndex(c, s.Index(c))
})
router.Handle("GET", "/articles/:category/", func(c *gin.Context) {
r.RenderArticles(c, s.Articles(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)
})
router.Handle("POST", "/user/logout/", func(c *gin.Context) {
r.RenderLogout(c, s.Logout(c))
})
}
// UnimplementedWebCoreServant can be embedded to have forward compatible implementations.
type UnimplementedWebCoreServant struct{}
// UnimplementedWebCoreBinding can be embedded to have forward compatible implementations.
type UnimplementedWebCoreBinding struct{}
// UnimplementedWebCoreRender can be embedded to have forward compatible implementations.
type UnimplementedWebCoreRender struct{}
func (UnimplementedWebCoreServant) Chain() gin.HandlersChain {
return nil
}
func (UnimplementedWebCoreServant) Index(c *gin.Context) error {
return errors.New("method Index not implemented")
}
func (UnimplementedWebCoreServant) Articles(c *gin.Context) error {
return errors.New("method Index not implemented")
}
func (UnimplementedWebCoreServant) Login(c *gin.Context, req *LoginReq) (*LoginResp, error) {
return nil, errors.New("method Login not implemented")
}
func (UnimplementedWebCoreServant) Logout(c *gin.Context) error {
return errors.New("method Logout not implemented")
}
func (UnimplementedWebCoreServant) mustEmbedUnimplementedWebCoreServant() {}
func (UnimplementedWebCoreBinding) BindLogin(c *gin.Context) (*LoginReq, error) {
return nil, errors.New("method BindLogin not implemented")
}
func (UnimplementedWebCoreBinding) mustEmbedUnimplementedWebCoreBinding() {}
func (UnimplementedWebCoreRender) RenderIndex(c *gin.Context, err error) {
c.String(http.StatusInternalServerError, "method RenderLogout not implemented")
}
func (UnimplementedWebCoreRender) RenderArticles(c *gin.Context, err error) {
c.String(http.StatusInternalServerError, "method RenderLogout not implemented")
}
func (UnimplementedWebCoreRender) RenderLogin(c *gin.Context, data *LoginResp, err error) {
c.String(http.StatusInternalServerError, "method RenderLogin not implemented")
}
func (UnimplementedWebCoreRender) RenderLogout(c *gin.Context, err error) {
c.String(http.StatusInternalServerError, "method RenderLogout not implemented")
}
func (UnimplementedWebCoreRender) mustEmbedUnimplementedWebCoreRender() {}

@ -0,0 +1,24 @@
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(InSerialMode),
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) `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"`
}

@ -0,0 +1,25 @@
package chain
import (
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/pkg/app"
"github.com/rocboss/paopao-ce/pkg/errcode"
)
func Admin() gin.HandlerFunc {
return func(c *gin.Context) {
if user, exist := c.Get("USER"); exist {
if userModel, ok := user.(*model.User); ok {
if userModel.Status == model.UserStatusNormal && userModel.IsAdmin {
c.Next()
return
}
}
}
response := app.NewResponse(c)
response.ToErrorResponse(errcode.NoAdminPermission)
c.Abort()
}
}

@ -0,0 +1,113 @@
package chain
import (
"strings"
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt/v4"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/pkg/app"
"github.com/rocboss/paopao-ce/pkg/errcode"
)
func JWT() gin.HandlerFunc {
// TODO: optimize get user from a simple service that provide fetch a user info interface.
db := conf.MustGormDB()
return func(c *gin.Context) {
var (
token string
ecode = errcode.Success
)
if s, exist := c.GetQuery("token"); exist {
token = s
} else {
token = c.GetHeader("Authorization")
// 验证前端传过来的token格式不为空开头为Bearer
if token == "" || !strings.HasPrefix(token, "Bearer ") {
response := app.NewResponse(c)
response.ToErrorResponse(errcode.UnauthorizedTokenError)
c.Abort()
return
}
// 验证通过提取有效部分除去Bearer)
token = token[7:]
}
if token == "" {
ecode = errcode.InvalidParams
} else {
claims, err := app.ParseToken(token)
if err != nil {
switch err.(*jwt.ValidationError).Errors {
case jwt.ValidationErrorExpired:
ecode = errcode.UnauthorizedTokenTimeout
default:
ecode = errcode.UnauthorizedTokenError
}
} else {
c.Set("UID", claims.UID)
c.Set("USERNAME", claims.Username)
// 加载用户信息
user := &model.User{
Model: &model.Model{
ID: claims.UID,
},
}
user, _ = user.Get(db)
c.Set("USER", user)
// 强制下线机制
if (conf.JWTSetting.Issuer + ":" + user.Salt) != claims.Issuer {
ecode = errcode.UnauthorizedTokenTimeout
}
}
}
if ecode != errcode.Success {
response := app.NewResponse(c)
response.ToErrorResponse(ecode)
c.Abort()
return
}
c.Next()
}
}
func JwtLoose() gin.HandlerFunc {
// TODO: optimize get user from a simple service that provide fetch a user info interface.
db := conf.MustGormDB()
return func(c *gin.Context) {
token, exist := c.GetQuery("token")
if !exist {
token = c.GetHeader("Authorization")
// 验证前端传过来的token格式不为空开头为Bearer
if strings.HasPrefix(token, "Bearer ") {
// 验证通过提取有效部分除去Bearer)
token = token[7:]
} else {
c.Next()
}
}
if len(token) > 0 {
if claims, err := app.ParseToken(token); err == nil {
c.Set("UID", claims.UID)
c.Set("USERNAME", claims.Username)
// 加载用户信息
user := &model.User{
Model: &model.Model{
ID: claims.UID,
},
}
user, err := user.Get(db)
if err == nil && (conf.JWTSetting.Issuer+":"+user.Salt) == claims.Issuer {
c.Set("USER", user)
}
}
}
c.Next()
}
}

@ -0,0 +1,45 @@
package chain
import (
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/pkg/app"
"github.com/rocboss/paopao-ce/pkg/errcode"
)
func Priv() gin.HandlerFunc {
if conf.CfgIf("PhoneBind") {
return func(c *gin.Context) {
if u, exist := c.Get("USER"); exist {
if user, ok := u.(*model.User); ok {
if user.Status == model.UserStatusNormal {
if user.Phone == "" {
response := app.NewResponse(c)
response.ToErrorResponse(errcode.AccountNoPhoneBind)
c.Abort()
return
}
c.Next()
return
}
}
}
response := app.NewResponse(c)
response.ToErrorResponse(errcode.UserHasBeenBanned)
c.Abort()
}
} else {
return func(c *gin.Context) {
if u, exist := c.Get("USER"); exist {
if user, ok := u.(*model.User); ok && user.Status == model.UserStatusNormal {
c.Next()
return
}
}
response := app.NewResponse(c)
response.ToErrorResponse(errcode.UserHasBeenBanned)
c.Abort()
}
}
}

@ -0,0 +1,26 @@
package servants
import (
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/model"
)
type baseServant struct {
// TODO
}
type baseBinding struct {
// TODO
}
type baseRender struct {
// TODO
}
func (baseServant) userFrom(c *gin.Context) (*model.User, bool) {
if u, exists := c.Get("USER"); exists {
user, ok := u.(*model.User)
return user, ok
}
return nil, false
}

@ -0,0 +1,5 @@
package servants
type localossSrv struct {
// TODO
}

@ -0,0 +1,12 @@
package servants
import (
"github.com/gin-gonic/gin"
api "github.com/rocboss/paopao-ce/internal/mirc/auto/api/v1"
)
// RegisterServants register all the servants to gin.Engine
func RegisterServants(e *gin.Engine) {
api.RegisterWebCoreServant(e, newWebCoreSrv(), newWebCoreBinding(), newWebCoreRender())
}

@ -0,0 +1,5 @@
package servants
type webAdminSrv struct {
// TODO
}

@ -0,0 +1,5 @@
package servants
type webAlipaySrv struct {
// TODO
}

@ -0,0 +1,32 @@
package servants
import (
api "github.com/rocboss/paopao-ce/internal/mirc/auto/api/v1"
)
type webCoreSrv struct {
baseServant
api.UnimplementedWebCoreServant
}
type webCoreBinding struct {
baseBinding
api.UnimplementedWebCoreBinding
}
type webCoreRender struct {
baseRender
api.UnimplementedWebCoreRender
}
func newWebCoreSrv() api.WebCore {
return &webCoreSrv{}
}
func newWebCoreBinding() api.WebCoreBinding {
return &webCoreBinding{}
}
func newWebCoreRender() api.WebCoreRender {
return &webCoreRender{}
}

@ -0,0 +1,5 @@
package servants
type webFollowshipSrv struct {
// TODO
}

@ -0,0 +1,5 @@
package servants
type webFriendshipSrv struct {
// TODO
}

@ -0,0 +1,5 @@
package servants
type webLooseSrv struct {
// TODO
}

@ -0,0 +1,5 @@
package servants
type webPrivSrv struct {
// TODO
}

@ -0,0 +1,5 @@
package servants
type webPubSrv struct {
// TODO
}
Loading…
Cancel
Save