319 lines
8.2 KiB
Go
319 lines
8.2 KiB
Go
package service
|
||
|
||
import (
|
||
"context"
|
||
"sync"
|
||
"time"
|
||
|
||
"go-common/app/admin/main/block/model"
|
||
xsql "go-common/library/database/sql"
|
||
"go-common/library/log"
|
||
"go-common/library/sync/errgroup"
|
||
|
||
"github.com/pkg/errors"
|
||
)
|
||
|
||
// Search .
|
||
func (s *Service) Search(c context.Context, mids []int64) (infos []*model.BlockInfo, err error) {
|
||
var (
|
||
users []*model.DBUser
|
||
userDetails []*model.DBUserDetail
|
||
eg errgroup.Group
|
||
mapMu sync.Mutex
|
||
userMap = make(map[int64]*model.BlockInfo)
|
||
)
|
||
if users, err = s.dao.Users(c, mids); err != nil {
|
||
return
|
||
}
|
||
if userDetails, err = s.dao.UserDetails(c, mids); err != nil {
|
||
return
|
||
}
|
||
infos = make([]*model.BlockInfo, 0, len(mids))
|
||
for _, m := range mids {
|
||
mid := m
|
||
eg.Go(func() (err error) {
|
||
info := &model.BlockInfo{
|
||
MID: mid,
|
||
}
|
||
// 1. account 数据
|
||
if info.Nickname, info.TelStatus, info.Level, info.RegTime, err = s.dao.AccountInfo(context.TODO(), mid); err != nil {
|
||
log.Error("%+v", err)
|
||
err = nil
|
||
}
|
||
if info.Nickname == "" {
|
||
log.Info("user mid(%d) not found", info.MID)
|
||
return
|
||
}
|
||
// 2. 封禁状态
|
||
for i := range users {
|
||
if users[i].MID == mid {
|
||
info.ParseStatus(users[i])
|
||
break
|
||
}
|
||
}
|
||
// 3. 封禁次数
|
||
for i := range userDetails {
|
||
if userDetails[i].MID == mid {
|
||
info.BlockCount = userDetails[i].BlockCount
|
||
break
|
||
}
|
||
}
|
||
// 4. spy 分值
|
||
if info.SpyScore, err = s.dao.SpyScore(context.TODO(), mid); err != nil {
|
||
log.Error("%+v", err)
|
||
err = nil
|
||
info.SpyScore = -1
|
||
}
|
||
// 5. figure 排名
|
||
if info.FigureRank, err = s.dao.FigureRank(context.TODO(), mid); err != nil {
|
||
log.Error("%+v", err)
|
||
err = nil
|
||
info.FigureRank = -1
|
||
}
|
||
// 6. extra 额外账号信息
|
||
if info.Tel, err = s.telInfo(context.TODO(), mid); err != nil {
|
||
log.Error("%+v", err)
|
||
err = nil
|
||
info.Tel = "N/A"
|
||
}
|
||
if info.Mail, err = s.mailInfo(context.TODO(), mid); err != nil {
|
||
log.Error("%+v", err)
|
||
err = nil
|
||
info.Mail = "N/A"
|
||
}
|
||
if info.Username, err = s.userID(context.TODO(), mid); err != nil {
|
||
log.Error("%+v", err)
|
||
err = nil
|
||
info.Username = "N/A"
|
||
}
|
||
|
||
mapMu.Lock()
|
||
userMap[info.MID] = info
|
||
mapMu.Unlock()
|
||
return
|
||
})
|
||
}
|
||
eg.Wait()
|
||
for _, mid := range mids {
|
||
if info, ok := userMap[mid]; ok {
|
||
infos = append(infos, info)
|
||
}
|
||
}
|
||
return
|
||
}
|
||
|
||
// History .
|
||
func (s *Service) History(c context.Context, mid int64, ps, pn int) (status model.BlockStatus, total int, history []*model.BlockHistory, err error) {
|
||
var (
|
||
start = (pn - 1) * ps
|
||
limit = ps
|
||
dbHistory []*model.DBHistory
|
||
dbUser *model.DBUser
|
||
)
|
||
if dbUser, err = s.dao.User(c, mid); err != nil {
|
||
return
|
||
}
|
||
if dbUser != nil {
|
||
status = dbUser.Status
|
||
}
|
||
if total, err = s.dao.HistoryCount(c, mid); err != nil {
|
||
return
|
||
}
|
||
if dbHistory, err = s.dao.History(c, mid, start, limit); err != nil {
|
||
return
|
||
}
|
||
for i := range dbHistory {
|
||
his := &model.BlockHistory{}
|
||
his.ParseDB(dbHistory[i])
|
||
history = append(history, his)
|
||
}
|
||
return
|
||
}
|
||
|
||
// BatchBlock .
|
||
func (s *Service) BatchBlock(c context.Context, p *model.ParamBatchBlock) (err error) {
|
||
var (
|
||
tx *xsql.Tx
|
||
duration = time.Duration(p.Duration) * time.Hour * 24
|
||
source model.BlockSource
|
||
mids []int64
|
||
stime = time.Now()
|
||
)
|
||
if tx, err = s.dao.BeginTX(c); err != nil {
|
||
return
|
||
}
|
||
if p.Source == 1 {
|
||
// 系统封禁
|
||
source = model.BlockSourceSys
|
||
} else if p.Source == 2 {
|
||
// 小黑屋封禁
|
||
source = model.BlockSourceBlackHouse
|
||
if err = s.dao.BlackhouseBlock(context.TODO(), p); err != nil {
|
||
return
|
||
}
|
||
}
|
||
for _, mid := range p.MIDs {
|
||
mids = append(mids, mid)
|
||
theMID := mid
|
||
s.cache.Save(func() {
|
||
if cacheErr := s.dao.DeleteUserCache(context.TODO(), theMID); cacheErr != nil {
|
||
log.Error("%+v", cacheErr)
|
||
}
|
||
if databusErr := s.accountNotify(context.TODO(), theMID); databusErr != nil {
|
||
log.Error("%+v", databusErr)
|
||
}
|
||
})
|
||
if err = s.action(c, tx, mid, p.AdminID, p.AdminName, source, p.Area, p.Reason, p.Comment, p.Action, duration, p.Notify, stime); err != nil {
|
||
tx.Rollback()
|
||
return
|
||
}
|
||
}
|
||
// 发送站内信
|
||
if p.Notify {
|
||
s.mission(func() {
|
||
if notifyErr := s.notifyMSG(context.TODO(), p.MIDs, source, p.Action, p.Area, p.Reason, p.Duration); notifyErr != nil {
|
||
log.Error("%+v", notifyErr)
|
||
return
|
||
}
|
||
})
|
||
}
|
||
s.mission(func() {
|
||
s.AddAuditLog(context.TODO(), p.Action, p.AdminID, p.AdminName, mids, duration, source, p.Area, p.Reason, p.Comment, p.Notify, stime)
|
||
})
|
||
err = tx.Commit()
|
||
return
|
||
}
|
||
|
||
// BatchRemove .
|
||
func (s *Service) BatchRemove(c context.Context, p *model.ParamBatchRemove) (err error) {
|
||
var (
|
||
tx *xsql.Tx
|
||
mids []int64
|
||
stime = time.Now()
|
||
)
|
||
if tx, err = s.dao.BeginTX(c); err != nil {
|
||
return
|
||
}
|
||
|
||
for _, mid := range p.MIDs {
|
||
mids = append(mids, mid)
|
||
theMID := mid
|
||
s.cache.Save(func() {
|
||
if cacheErr := s.dao.DeleteUserCache(context.TODO(), theMID); cacheErr != nil {
|
||
log.Error("%+v", cacheErr)
|
||
}
|
||
if databusErr := s.accountNotify(context.TODO(), theMID); databusErr != nil {
|
||
log.Error("%+v", databusErr)
|
||
}
|
||
})
|
||
if err = s.action(c, tx, mid, p.AdminID, p.AdminName, model.BlockSourceRemove, model.BlockAreaNone, "", p.Comment, model.BlockActionAdminRemove, 0, p.Notify, stime); err != nil {
|
||
tx.Rollback()
|
||
return
|
||
}
|
||
}
|
||
// 发送站内信
|
||
if p.Notify {
|
||
s.mission(func() {
|
||
if notifyErr := s.notifyMSG(context.TODO(), p.MIDs, model.BlockSourceRemove, model.BlockActionAdminRemove, model.BlockAreaNone, "", 0); notifyErr != nil {
|
||
log.Error("%+v", notifyErr)
|
||
return
|
||
}
|
||
})
|
||
}
|
||
s.mission(func() {
|
||
s.AddAuditLog(context.TODO(), model.BlockActionAdminRemove, p.AdminID, p.AdminName, mids, 0, model.BlockSourceRemove, model.BlockAreaNone, "", p.Comment, p.Notify, stime)
|
||
})
|
||
err = tx.Commit()
|
||
return
|
||
}
|
||
|
||
// notifyMSG .
|
||
func (s *Service) notifyMSG(c context.Context, mids []int64, source model.BlockSource, action model.BlockAction, area model.BlockArea, reason string, days int64) (err error) {
|
||
code, title, content := s.MSGInfo(source, action, area, reason, days)
|
||
log.Info("block admin title : %s , content : %s , mids : %+v", title, content, mids)
|
||
if err = s.dao.SendSysMsg(context.TODO(), code, mids, title, content, ""); err != nil {
|
||
return
|
||
}
|
||
return
|
||
}
|
||
|
||
func (s *Service) action(c context.Context, tx *xsql.Tx, mid int64, adminID int64, adminName string, source model.BlockSource, area model.BlockArea, reason, comment string, action model.BlockAction, duration time.Duration, notify bool, stime time.Time) (err error) {
|
||
var (
|
||
db = &model.DBHistory{
|
||
MID: mid,
|
||
AdminID: adminID,
|
||
AdminName: adminName,
|
||
Source: source,
|
||
Area: area,
|
||
Reason: reason,
|
||
Comment: comment,
|
||
Action: action,
|
||
StartTime: stime,
|
||
Duration: int64(duration / time.Second),
|
||
Notify: notify,
|
||
}
|
||
blockStatus model.BlockStatus
|
||
)
|
||
if err = s.dao.TxInsertHistory(c, tx, db); err != nil {
|
||
return
|
||
}
|
||
switch action {
|
||
case model.BlockActionAdminRemove, model.BlockActionSelfRemove:
|
||
blockStatus = model.BlockStatusFalse
|
||
case model.BlockActionLimit:
|
||
switch source {
|
||
case model.BlockSourceBlackHouse:
|
||
blockStatus = model.BlockStatusCredit
|
||
default:
|
||
blockStatus = model.BlockStatusLimit
|
||
}
|
||
s.mission(func() {
|
||
if err = s.dao.UpdateAddBlockCount(context.TODO(), mid); err != nil {
|
||
log.Error("%+v", err)
|
||
}
|
||
})
|
||
case model.BlockActionForever:
|
||
blockStatus = model.BlockStatusForever
|
||
s.mission(func() {
|
||
if err = s.dao.UpdateAddBlockCount(context.TODO(), mid); err != nil {
|
||
log.Error("%+v", err)
|
||
}
|
||
})
|
||
default:
|
||
err = errors.Errorf("unknown block action [%d]", action)
|
||
return
|
||
}
|
||
if err = s.dao.TxUpdateUser(c, tx, mid, blockStatus); err != nil {
|
||
return
|
||
}
|
||
return
|
||
}
|
||
|
||
func (s *Service) userID(c context.Context, mid int64) (id string, err error) {
|
||
return "N/A", nil
|
||
}
|
||
|
||
func (s *Service) mailInfo(c context.Context, mid int64) (mail string, err error) {
|
||
if mail, err = s.dao.MailInfo(c, mid); mail == "" {
|
||
mail = "N/A"
|
||
}
|
||
return
|
||
}
|
||
|
||
// TelInfo .
|
||
func (s *Service) telInfo(c context.Context, mid int64) (tel string, err error) {
|
||
if tel, err = s.dao.TelInfo(c, mid); err != nil {
|
||
return
|
||
}
|
||
if len(tel) == 0 {
|
||
tel = "N/A"
|
||
return
|
||
}
|
||
if len(tel) < 4 {
|
||
tel = tel[:1] + "****"
|
||
return
|
||
}
|
||
tel = tel[:3] + "****" + tel[len(tel)-4:]
|
||
return
|
||
}
|