mirror of https://github.com/rocboss/paopao-ce
parent
17d5e0f55c
commit
a269ad87a7
@ -0,0 +1,268 @@
|
||||
package jinzhu
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/rocboss/paopao-ce/internal/core"
|
||||
"github.com/rocboss/paopao-ce/internal/model"
|
||||
"github.com/rocboss/paopao-ce/internal/model/rest"
|
||||
"github.com/sirupsen/logrus"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var (
|
||||
_ core.ContactManageService = (*contactManageServant)(nil)
|
||||
)
|
||||
|
||||
type contactManageServant struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func newContactManageService(db *gorm.DB) core.ContactManageService {
|
||||
return &contactManageServant{
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *contactManageServant) fetchOrNewContact(db *gorm.DB, userId int64, friendId int64, status int8) (*model.Contact, error) {
|
||||
contact := &model.Contact{
|
||||
UserId: userId,
|
||||
FriendId: friendId,
|
||||
}
|
||||
contact, err := contact.FetchUser(db)
|
||||
if err != nil {
|
||||
contact = &model.Contact{
|
||||
UserId: userId,
|
||||
FriendId: friendId,
|
||||
Status: status,
|
||||
}
|
||||
if contact, err = contact.Create(db); err != nil {
|
||||
logrus.Errorf("contactManageServant.fetchOrNewContact create new contact err:%s", err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return contact, nil
|
||||
}
|
||||
|
||||
func (s *contactManageServant) RequestingFriend(userId int64, friendId int64, greetings string) (err error) {
|
||||
db := s.db.Begin()
|
||||
defer func() {
|
||||
if err == nil {
|
||||
db.Commit()
|
||||
} else {
|
||||
db.Rollback()
|
||||
}
|
||||
}()
|
||||
|
||||
contact, e := s.fetchOrNewContact(db, userId, friendId, model.ContactStatusRequesting)
|
||||
if e != nil {
|
||||
err = e
|
||||
return
|
||||
}
|
||||
|
||||
// 如果已经好友,啥也不干
|
||||
if contact.Status == model.ContactStatusAgree {
|
||||
return nil
|
||||
} else if contact.Status == model.ContactStatusReject || contact.Status == model.ContactStatusDeleted {
|
||||
contact.Status = model.ContactStatusRequesting
|
||||
contact.IsDel = 0 // remove deleted flag if needed
|
||||
if err = contact.UpdateInUnscoped(db); err != nil {
|
||||
logrus.Errorf("contactManageServant.RequestingFriend update exsit contact err:%s", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
msg := &model.Message{
|
||||
SenderUserID: userId,
|
||||
ReceiverUserID: friendId,
|
||||
Type: model.MsgTypeRequestingFriend,
|
||||
Brief: "请求添加好友,并附言:",
|
||||
Content: greetings,
|
||||
ReplyID: int64(model.ContactStatusRequesting),
|
||||
}
|
||||
if _, err = msg.Create(db); err != nil {
|
||||
logrus.Errorf("contactManageServant.RequestingFriend create message err:%s", err)
|
||||
return
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *contactManageServant) AddFriend(userId int64, friendId int64) (err error) {
|
||||
db := s.db.Begin()
|
||||
defer func() {
|
||||
if err == nil {
|
||||
db.Commit()
|
||||
} else {
|
||||
db.Rollback()
|
||||
}
|
||||
}()
|
||||
|
||||
contact := &model.Contact{
|
||||
UserId: friendId,
|
||||
FriendId: userId,
|
||||
}
|
||||
if contact, err = contact.GetByUserFriend(db); err != nil {
|
||||
return
|
||||
}
|
||||
// 如果还不是请求好友,啥也不干
|
||||
if contact.Status != model.ContactStatusRequesting {
|
||||
logrus.Debugf("contactManageServant.AddFriend not reuesting status now so skip")
|
||||
return nil
|
||||
}
|
||||
contact.Status = model.ContactStatusAgree
|
||||
if err = contact.Update(db); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
contact, err = s.fetchOrNewContact(db, userId, friendId, model.ContactStatusAgree)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 如果已经好友,啥也不干
|
||||
if contact.Status != model.ContactStatusAgree {
|
||||
contact.Status = model.ContactStatusAgree
|
||||
contact.IsDel = 0 // remove deleted flag
|
||||
if err = contact.UpdateInUnscoped(db); err != nil {
|
||||
logrus.Errorf("contactManageServant.AddFriend update contact err:%s", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
args := []any{userId, friendId, friendId, userId, model.MsgTypeRequestingFriend, model.ContactStatusRequesting}
|
||||
msgs, e := (&model.Message{}).FetchBy(db, model.Predicates{
|
||||
"((sender_user_id = ? AND receiver_user_id = ?) OR (sender_user_id = ? AND receiver_user_id = ?)) AND type = ? AND reply_id = ?": args,
|
||||
})
|
||||
if e != nil {
|
||||
err = e
|
||||
return
|
||||
}
|
||||
for _, msg := range msgs {
|
||||
msg.ReplyID = int64(model.ContactStatusAgree)
|
||||
if err = msg.Update(db); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *contactManageServant) RejectFriend(userId int64, friendId int64) (err error) {
|
||||
db := s.db.Begin()
|
||||
defer func() {
|
||||
if err == nil {
|
||||
db.Commit()
|
||||
} else {
|
||||
db.Rollback()
|
||||
}
|
||||
}()
|
||||
|
||||
contact := &model.Contact{
|
||||
UserId: friendId,
|
||||
FriendId: userId,
|
||||
}
|
||||
if contact, err = contact.GetByUserFriend(db); err != nil {
|
||||
return
|
||||
}
|
||||
// 如果还不是请求好友,啥也不干
|
||||
if contact.Status != model.ContactStatusRequesting {
|
||||
return nil
|
||||
}
|
||||
contact.Status = model.ContactStatusReject
|
||||
if err = contact.Update(db); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
args := []any{friendId, userId, model.MsgTypeRequestingFriend, model.ContactStatusRequesting}
|
||||
msgs, e := (&model.Message{}).FetchBy(db, model.Predicates{
|
||||
"sender_user_id = ? AND receiver_user_id = ? AND type = ? AND reply_id = ?": args,
|
||||
})
|
||||
if e != nil {
|
||||
err = e
|
||||
return
|
||||
}
|
||||
for _, msg := range msgs {
|
||||
msg.ReplyID = int64(model.ContactStatusReject)
|
||||
if err = msg.Update(db); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *contactManageServant) DeleteFriend(userId int64, friendId int64) (err error) {
|
||||
db := s.db.Begin()
|
||||
defer func() {
|
||||
if err == nil {
|
||||
db.Commit()
|
||||
} else {
|
||||
db.Rollback()
|
||||
}
|
||||
}()
|
||||
|
||||
contact := &model.Contact{
|
||||
UserId: userId,
|
||||
FriendId: friendId,
|
||||
}
|
||||
contacts, e := contact.FetchByUserFriendAll(db)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
for _, contact := range contacts {
|
||||
// 如果还不是好友,啥也不干
|
||||
if contact.Status != model.ContactStatusAgree {
|
||||
continue
|
||||
}
|
||||
contact.Status = model.ContactStatusDeleted
|
||||
contact.DeletedOn = time.Now().Unix()
|
||||
contact.IsDel = 1
|
||||
if err = contact.Update(db); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *contactManageServant) GetContacts(userId int64, offset int, limit int) (*rest.ContactsResp, error) {
|
||||
contact := &model.Contact{}
|
||||
condition := model.ConditionsT{
|
||||
"user_id": userId,
|
||||
"status": model.ContactStatusAgree,
|
||||
}
|
||||
contacts, err := contact.List(s.db, condition, offset, limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
total, err := contact.Count(s.db, condition)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp := &rest.ContactsResp{
|
||||
Contacts: make([]rest.ContactItem, 0, len(contacts)),
|
||||
Total: total,
|
||||
}
|
||||
for _, c := range contacts {
|
||||
if c.User != nil {
|
||||
resp.Contacts = append(resp.Contacts, rest.ContactItem{
|
||||
UserId: c.FriendId,
|
||||
UserName: c.User.Username,
|
||||
Nickname: c.User.Nickname,
|
||||
Avatar: c.User.Avatar,
|
||||
Phone: c.User.Phone,
|
||||
})
|
||||
}
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (s *contactManageServant) IsFriend(userId int64, friendId int64) bool {
|
||||
contact := &model.Contact{
|
||||
UserId: friendId,
|
||||
FriendId: userId,
|
||||
}
|
||||
contact, err := contact.GetByUserFriend(s.db)
|
||||
if err == nil && contact.Status == model.ContactStatusAgree {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
@ -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,31 @@
|
||||
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"`
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
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"`
|
||||
}
|
Loading…
Reference in new issue