You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
paopao-ce/internal/dao/sakila/contacts.go

196 lines
5.8 KiB

// Copyright 2023 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package sakila
import (
"time"
"github.com/jmoiron/sqlx"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/core/cs"
"github.com/rocboss/paopao-ce/internal/core/ms"
"github.com/rocboss/paopao-ce/internal/dao/sakila/yesql/cc"
"github.com/sirupsen/logrus"
)
var (
_ core.ContactManageService = (*contactManageSrv)(nil)
)
type contact struct {
UserId int64 `db:"user_id" json:"user_id"`
FriendId int64 `db:"friend_id" json:"friend_id"`
Status int8 `json:"status"` // 1请求好友, 2已同意好友, 3已拒绝好友, 4已删除好友
IsBlack int8 `json:"is_black"`
NoticeEnable int8 `json:"notice_enable"`
}
type contactManageSrv struct {
*sqlxSrv
q *cc.ContactManager
}
func (s *contactManageSrv) RequestingFriend(userId int64, friendId int64, greetings string) error {
return s.with(func(tx *sqlx.Tx) error {
contact, err := s.fetchOrNewContact(tx, userId, friendId, cs.ContactStatusRequesting)
if err != nil {
return err
}
now := time.Now().Unix()
// 如果已经好友,啥也不干
if contact.Status == cs.ContactStatusAgree {
return nil
} else if contact.Status == cs.ContactStatusReject || contact.Status == cs.ContactStatusDeleted {
contact.Status = cs.ContactStatusRequesting
contact.IsDel = 0 // remove deleted flag if needed
args := []any{cs.ContactStatusRequesting, now, contact.ID}
if _, err = tx.Stmtx(s.q.FreshContactStatus).Exec(args...); err != nil {
return err
}
}
msg := &ms.Message{
SenderUserID: userId,
ReceiverUserID: friendId,
Type: ms.MsgTypeRequestingFriend,
Brief: "请求添加好友,并附言:",
Content: greetings,
ReplyID: int64(cs.ContactStatusRequesting),
Model: &ms.Model{
CreatedOn: now,
},
}
if _, err = tx.NamedStmt(s.q.CreateMessage).Exec(msg); err != nil {
logrus.Errorf("contactManageSrv.RequestingFriend create message err:%s", err)
return err
}
return nil
})
}
func (s *contactManageSrv) AddFriend(userId int64, friendId int64) error {
return s.with(func(tx *sqlx.Tx) error {
contact := &cs.Contact{}
err := tx.Stmtx(s.q.GetUserFriend).Get(contact, userId, friendId)
if err != nil {
return err
}
// 如果还不是请求好友,啥也不干
if contact.Status != cs.ContactStatusRequesting {
logrus.Debugf("contactManageSrv.AddFriend not reuesting status now so skip")
return nil
}
now := time.Now().Unix()
args := []any{cs.ContactStatusAgree, now, contact.ID}
if _, err = tx.Stmtx(s.q.FreshContactStatus).Exec(args...); err != nil {
return err
}
contact, err = s.fetchOrNewContact(tx, userId, friendId, cs.ContactStatusAgree)
if err != nil {
return err
}
// 如果已经好友,啥也不干
if contact.Status != cs.ContactStatusAgree {
args = []any{cs.ContactStatusAgree, now, contact.ID}
if _, err = tx.Stmtx(s.q.FreshContactStatus).Exec(args); err != nil {
return err
}
}
args = []any{cs.ContactStatusAgree, now, userId, friendId, friendId, userId, ms.MsgTypeRequestingFriend, cs.ContactStatusRequesting}
if _, err = tx.Stmtx(s.q.AddFriendMsgsUpdate).Exec(args...); err != nil {
return err
}
return nil
})
}
func (s *contactManageSrv) RejectFriend(userId int64, friendId int64) error {
return s.with(func(tx *sqlx.Tx) error {
contact := &cs.Contact{}
err := tx.Stmtx(s.q.GetUserFriend).Get(contact, userId, friendId)
if err != nil {
return err
}
// 如果还不是请求好友,啥也不干
if contact.Status != cs.ContactStatusRequesting {
return nil
}
now := time.Now().Unix()
args := []any{cs.ContactStatusReject, now, contact.ID}
if _, err = tx.Stmtx(s.q.FreshContactStatus).Exec(args...); err != nil {
return err
}
args = []any{cs.ContactStatusReject, now, friendId, userId, ms.MsgTypeRequestingFriend, cs.ContactStatusRequesting}
if _, err = tx.Stmtx(s.q.RejectFriendMsgsUpdate).Exec(args...); err != nil {
return err
}
return nil
})
}
func (s *contactManageSrv) DeleteFriend(userId int64, friendId int64) error {
return s.with(func(tx *sqlx.Tx) error {
var contacts []cs.Contact
err := tx.Stmtx(s.q.GetContacts).Select(&contacts, userId, friendId, friendId, userId)
if err != nil {
return err
}
for _, contact := range contacts {
// 如果还不是好友,啥也不干
if contact.Status != cs.ContactStatusAgree {
continue
}
if _, err = tx.Stmtx(s.q.DelFriend).Exec(time.Now().Unix(), contact.ID); err != nil {
return err
}
}
return nil
})
}
func (s *contactManageSrv) GetContacts(userId int64, offset int, limit int) (res *ms.ContactList, err error) {
res = &ms.ContactList{
Contacts: []ms.ContactItem{},
}
if err = s.q.ListFriend.Select(&res.Contacts, userId, limit, offset); err != nil {
return
}
if err = s.q.TotalFriendsById.Get(&res.Total, userId); err != nil {
return
}
return
}
func (s *contactManageSrv) IsFriend(userId int64, friendId int64) (res bool) {
s.q.IsFriend.Get(&res, userId, friendId)
return
}
func (s *contactManageSrv) fetchOrNewContact(tx *sqlx.Tx, userId int64, friendId int64, status int8) (res *cs.Contact, err error) {
if err = tx.Stmtx(s.q.GetContact).Get(res, userId, friendId); err == nil {
return
}
result, xerr := tx.Stmtx(s.q.CreateContact).Exec(userId, friendId, status, time.Now().Unix())
if xerr != nil {
return nil, xerr
}
id, xerr := result.LastInsertId()
if xerr != nil {
return nil, xerr
}
return &cs.Contact{
ID: id,
UserId: userId,
FriendId: friendId,
Status: status,
}, nil
}
func newContactManageService(db *sqlx.DB) core.ContactManageService {
return &contactManageSrv{
sqlxSrv: newSqlxSrv(db),
q: mustBuild(db, cc.BuildContactManager),
}
}