go-common/app/admin/main/member/service/review.go
2019-04-22 18:49:16 +08:00

243 lines
6.3 KiB
Go

package service
import (
"context"
"fmt"
"time"
"go-common/app/admin/main/member/model"
"go-common/app/admin/main/member/model/block"
relation "go-common/app/service/main/relation/model"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/metadata"
"go-common/library/queue/databus/report"
xtime "go-common/library/time"
)
const (
_logActionUserPropertyAudit = "user_property_review_audit"
)
// Reviews is.
func (s *Service) Reviews(ctx context.Context, arg *model.ArgReviewList) ([]*model.UserPropertyReview, int, error) {
bySearch := func() ([]*model.UserPropertyReview, int, error) {
stime := arg.STime.Time().Format("2006-01-02 15:04:05")
if arg.ETime == 0 {
arg.ETime = xtime.Time(time.Now().Unix())
}
etime := arg.ETime.Time().Format("2006-01-02 15:04:05")
property := int8ToInt(arg.Property)
state := int8ToInt(arg.State)
result, err := s.dao.SearchUserPropertyReview(ctx, arg.Mid, property, state, arg.IsMonitor, arg.IsDesc, arg.Operator, stime, etime, arg.Pn, arg.Ps)
if err != nil {
return nil, 0, err
}
ids := result.IDs()
rws, err := s.dao.ReviewByIDs(ctx, ids, arg.State)
if err != nil {
return nil, 0, err
}
rws = arrange(rws, ids)
return rws, result.Total(), nil
}
byDB := func() ([]*model.UserPropertyReview, int, error) {
return s.dao.Reviews(ctx, arg.Mid, arg.Property, arg.State, arg.IsMonitor, arg.IsDesc, arg.Operator, arg.STime, arg.ETime, arg.Pn, arg.Ps)
}
rws, total, err := bySearch()
if arg.ForceDB {
log.Info("Force user property review query to db")
rws, total, err = byDB()
}
if err != nil {
return nil, 0, err
}
for _, rw := range rws {
if rw.Property == model.ReviewPropertyFace {
rw.BuildFaceURL()
}
}
s.reviewsName(ctx, rws)
s.reviewsFaceReject(ctx, rws)
s.reviewsRelationStat(ctx, rws)
return rws, total, err
}
func (s *Service) onReviewSuccess(ctx context.Context, waitRws []*model.UserPropertyReview, arg *model.ArgReviewAudit) error {
if !arg.BlockUser {
return nil
}
blockArg := &block.ParamBatchBlock{
MIDs: waitRwMids(waitRws),
AdminName: arg.Operator,
AdminID: arg.OperatorID,
Source: arg.Source,
Area: arg.Area,
Reason: arg.Reason,
Comment: arg.Comment,
Action: arg.Action,
Duration: arg.Duration,
Notify: arg.Notify,
}
if !blockArg.Validate() {
log.Error("Failed to validate block parama, arg: %v", blockArg)
return ecode.RequestErr
}
if err := s.block.BatchBlock(ctx, blockArg); err != nil {
log.Error("Failed to batch block, error: %v, arg: %v", err, blockArg)
return err
}
return nil
}
// ReviewAudit is.
func (s *Service) ReviewAudit(ctx context.Context, arg *model.ArgReviewAudit) error {
waitRws, err := s.dao.ReviewByIDs(ctx, arg.ID, []int8{model.ReviewStateWait})
if err != nil {
return err
}
if err := s.dao.ReviewAudit(ctx, arg.ID, arg.State, arg.Remark, arg.Operator); err != nil {
return err
}
for _, r := range waitRws {
ak := auditKey(r.Property, r.IsMonitor)
handler, ok := s.auditHandlers[ak]
if !ok {
log.Warn("Unable to handle property update: review: %+v audit: %+v", r, arg)
continue
}
if err := handler(ctx, r, arg); err != nil {
log.Error("Failed to trigger review audit event: review: %+v error: %+v", r, err)
remark := fmt.Sprintf("操作异常:%s, 备注: %s", ecode.Cause(err).Message(), arg.Remark)
if err = s.dao.UpdateRemark(ctx, r.ID, remark); err != nil {
log.Error("Failed to update remark error: %v", err)
}
}
report.Manager(&report.ManagerInfo{
Uname: arg.Operator,
UID: arg.OperatorID,
Business: model.ManagerLogID,
Type: 0,
Oid: r.Mid,
Action: _logActionUserPropertyAudit,
Ctime: time.Now(),
// extra
Index: []interface{}{r.ID, arg.State, 0, arg.Remark, "", ""},
Content: map[string]interface{}{
"remark": arg.Remark,
"state": arg.State,
"id": r.ID,
"mid": r.Mid,
},
})
}
s.onReviewSuccess(ctx, waitRws, arg)
return nil
}
// Review is.
func (s *Service) Review(ctx context.Context, arg *model.ArgReview) (*model.UserPropertyReview, error) {
r, err := s.dao.Review(ctx, arg.ID)
if err != nil {
return nil, err
}
r.Block, err = s.block.History(ctx, r.Mid, 2, 1, true)
if err != nil {
log.Error("Failed to get block review info, error: %v, mid: %v", err, r.Mid)
err = nil
}
return r, nil
}
func (s *Service) reviewsName(ctx context.Context, rws []*model.UserPropertyReview) {
mids := make([]int64, 0, len(rws))
for _, rw := range rws {
mids = append(mids, rw.Mid)
}
bs, err := s.dao.Bases(ctx, mids)
if err != nil {
log.Error("Failed to fetch bases with mids: %+v: %+v", mids, err)
return
}
for _, rw := range rws {
b, ok := bs[rw.Mid]
if !ok {
continue
}
rw.Name = b.Name
}
}
func (s *Service) reviewsFaceReject(ctx context.Context, rws []*model.UserPropertyReview) {
mids := make([]int64, 0, len(rws))
for _, rw := range rws {
mids = append(mids, rw.Mid)
}
frs, err := s.dao.BatchUserAddit(ctx, mids)
if err != nil {
log.Error("Failed to fetch FaceRejects with mids: %+v: %+v", mids, err)
return
}
for _, rw := range rws {
if fr, ok := frs[rw.Mid]; ok {
rw.FaceReject = fr.FaceReject
}
}
}
func (s *Service) reviewsRelationStat(ctx context.Context, rws []*model.UserPropertyReview) {
mids := make([]int64, 0, len(rws))
for _, rw := range rws {
mids = append(mids, rw.Mid)
}
stats, err := s.relationRPC.Stats(ctx, &relation.ArgMids{
Mids: mids,
RealIP: metadata.String(ctx, metadata.RemoteIP),
})
if err != nil {
log.Error("Failed to fetch relation stat with mids: %+v: %+v", mids, err)
return
}
for _, rw := range rws {
stat, ok := stats[rw.Mid]
if !ok {
continue
}
rw.Follower = stat.Follower
}
}
func int8ToInt(in []int8) []int {
res := []int{}
for _, i := range in {
res = append(res, int(i))
}
return res
}
func arrange(rws []*model.UserPropertyReview, ids []int64) []*model.UserPropertyReview {
res := []*model.UserPropertyReview{}
tmp := make(map[int64]*model.UserPropertyReview, len(ids))
for _, rw := range rws {
tmp[rw.ID] = rw
}
for _, id := range ids {
if rw, ok := tmp[id]; ok {
res = append(res, rw)
}
}
return res
}
func waitRwMids(waitRws []*model.UserPropertyReview) []int64 {
mids := make([]int64, 0, len(waitRws))
for _, w := range waitRws {
mids = append(mids, w.Mid)
}
return mids
}