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.
242 lines
6.3 KiB
242 lines
6.3 KiB
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 |
|
}
|
|
|