719 lines
18 KiB
Go
719 lines
18 KiB
Go
package service
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/csv"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"sort"
|
|
"strconv"
|
|
"time"
|
|
|
|
"go-common/app/admin/main/member/model"
|
|
"go-common/app/admin/main/member/model/bom"
|
|
coin "go-common/app/service/main/coin/model"
|
|
member "go-common/app/service/main/member/model"
|
|
"go-common/library/ecode"
|
|
"go-common/library/log"
|
|
"go-common/library/net/metadata"
|
|
"go-common/library/queue/databus/report"
|
|
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
const (
|
|
_logActionBaseAudit = "base_audit"
|
|
_logActionDeleteSign = "delete_sign"
|
|
_logActionRankUpdate = "rank_set"
|
|
_logActionCoinUpdate = "coin_set"
|
|
_logActionExpUpdate = "exp_set"
|
|
_logActionMoralUpdate = "moral_set"
|
|
)
|
|
|
|
func (s *Service) batchBase(ctx context.Context, mids []int64) (map[int64]*model.Base, error) {
|
|
bs := make(map[int64]*model.Base, len(mids))
|
|
for _, mid := range mids {
|
|
b, err := s.dao.Base(ctx, mid)
|
|
if err != nil {
|
|
log.Error("Failed to retrive user base by mid: %d: %+v", mid, err)
|
|
continue
|
|
}
|
|
bs[b.Mid] = b
|
|
}
|
|
return bs, nil
|
|
}
|
|
|
|
// BaseReview is.
|
|
func (s *Service) BaseReview(ctx context.Context, arg *model.ArgBaseReview) ([]*model.BaseReview, error) {
|
|
mids := arg.Mids()
|
|
if len(mids) == 0 {
|
|
return nil, ecode.RequestErr
|
|
}
|
|
if len(mids) > 200 {
|
|
//mids = mids[:200]
|
|
return nil, ecode.SearchMidOverLimit
|
|
}
|
|
var mrs []*model.BaseReview
|
|
for _, mid := range mids {
|
|
base, err := s.dao.Base(ctx, mid)
|
|
if err != nil {
|
|
log.Error("Failed to retrive user base by mid: %d: %+v", mid, err)
|
|
continue
|
|
}
|
|
logs, err := s.dao.SearchUserAuditLog(ctx, mid)
|
|
if err != nil {
|
|
log.Error("Failed to search user audit log, mid: %d error: %v", mid, err)
|
|
continue
|
|
}
|
|
|
|
fixFaceLogs(logs.Result)
|
|
|
|
mr := &model.BaseReview{
|
|
Base: *base,
|
|
Logs: logs.Result,
|
|
}
|
|
mrs = append(mrs, mr)
|
|
}
|
|
if err := s.reviewAddit(ctx, mids, mrs); err != nil {
|
|
log.Error("Failed to fetch review violation count with mids: %+v: %+v", mids, err)
|
|
}
|
|
return mrs, nil
|
|
}
|
|
|
|
func fixFaceLogs(auditLogs []model.AuditLog) {
|
|
for i, v := range auditLogs {
|
|
if v.Type != model.BaseAuditTypeFace {
|
|
continue
|
|
}
|
|
// 对头像进行重新签名
|
|
ext := new(struct {
|
|
Old string `json:"old"`
|
|
New string `json:"new"`
|
|
})
|
|
if err := json.Unmarshal([]byte(v.Extra), &ext); err != nil {
|
|
log.Error("Failed to unmarshal extra, additLog: %+v error: %v", v, err)
|
|
continue
|
|
}
|
|
ext.New = model.BuildFaceURL(ext.New)
|
|
extraDataBytes, err := json.Marshal(ext)
|
|
if err != nil {
|
|
log.Error("FaceExtra (%+v) json marshal err(%v)", ext, err)
|
|
continue
|
|
}
|
|
auditLogs[i].Extra = string(extraDataBytes)
|
|
}
|
|
}
|
|
|
|
// ClearFace is
|
|
func (s *Service) ClearFace(ctx context.Context, arg *model.ArgMids) error {
|
|
for _, mid := range arg.Mid {
|
|
b, err := s.dao.Base(ctx, mid)
|
|
if err != nil {
|
|
log.Error("Failed to retrive user base by mid: %d: %+v", mid, err)
|
|
continue
|
|
}
|
|
if err = s.dao.UpFace(ctx, mid, ""); err != nil {
|
|
log.Error("Failed to clear face mid %d error: %+v", mid, err)
|
|
continue
|
|
}
|
|
privFace, err := s.mvToPrivate(ctx, urlPath(b.Face))
|
|
if err != nil {
|
|
log.Error("Failed to mv face To private bucket, mid: %d error: %+v", mid, err)
|
|
err = nil
|
|
}
|
|
if err = s.dao.Message(ctx, "违规头像处理通知", "抱歉,由于你的头像涉嫌违规,已被修改。如有疑问请联系客服。", []int64{mid}); err != nil {
|
|
log.Error("Failed to send message, mid: %d error: %+v", mid, err)
|
|
err = nil
|
|
}
|
|
if err = s.dao.IncrViolationCount(ctx, mid); err != nil {
|
|
log.Error("Failed to increase violation count mid: %d error: %+v", mid, err)
|
|
err = nil
|
|
}
|
|
report.Manager(&report.ManagerInfo{
|
|
Uname: arg.Operator,
|
|
UID: arg.OperatorID,
|
|
Business: model.ManagerLogID,
|
|
Type: model.BaseAuditTypeFace,
|
|
Oid: mid,
|
|
Action: _logActionBaseAudit,
|
|
Ctime: time.Now(),
|
|
// extra
|
|
Index: []interface{}{0, 0, 0, "", "", ""},
|
|
Content: map[string]interface{}{
|
|
"old": b.Face,
|
|
"new": model.BuildFaceURL(privFace),
|
|
},
|
|
})
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ClearSign is
|
|
func (s *Service) ClearSign(ctx context.Context, arg *model.ArgMids) error {
|
|
for _, mid := range arg.Mid {
|
|
b, err := s.dao.Base(ctx, mid)
|
|
if err != nil {
|
|
log.Error("Failed to retrive user base by mid: %d: %+v", mid, err)
|
|
continue
|
|
}
|
|
if err = s.dao.UpSign(ctx, mid, ""); err != nil {
|
|
log.Error("Failed to clear sign mid %d error: %+v", mid, err)
|
|
continue
|
|
}
|
|
if err = s.dao.Message(ctx, "违规签名处理通知", "抱歉,由于你的签名涉嫌违规,已被修改。如有疑问请联系客服。", []int64{mid}); err != nil {
|
|
log.Error("Failed to send message, mid: %d error: %+v", mid, err)
|
|
err = nil
|
|
}
|
|
if err = s.dao.IncrViolationCount(ctx, mid); err != nil {
|
|
log.Error("Failed to increase violation count mid: %d error: %+v", mid, err)
|
|
err = nil
|
|
}
|
|
report.Manager(&report.ManagerInfo{
|
|
Uname: arg.Operator,
|
|
UID: arg.OperatorID,
|
|
Business: model.ManagerLogID,
|
|
Type: model.BaseAuditTypeSign,
|
|
Oid: mid,
|
|
Action: _logActionBaseAudit,
|
|
Ctime: time.Now(),
|
|
// extra
|
|
Index: []interface{}{0, 0, 0, "", "", ""},
|
|
Content: map[string]interface{}{
|
|
"old": b.Sign,
|
|
"new": "",
|
|
},
|
|
})
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ClearName is
|
|
func (s *Service) ClearName(ctx context.Context, arg *model.ArgMids) error {
|
|
for _, mid := range arg.Mid {
|
|
b, err := s.dao.Base(ctx, mid)
|
|
if err != nil {
|
|
log.Error("Failed to retrive user base by mid: %d: %+v", mid, err)
|
|
continue
|
|
}
|
|
defaultName := fmt.Sprintf("bili_%d", mid)
|
|
if err = s.dao.UpdateUname(ctx, mid, defaultName); err != nil {
|
|
log.Error("Failed to clear name mid %d error: %+v", mid, err)
|
|
continue
|
|
}
|
|
if err = s.dao.Message(ctx, "违规昵称处理通知", "抱歉,由于你的昵称涉嫌违规,已被修改。如有疑问请联系客服。", []int64{mid}); err != nil {
|
|
log.Error("Failed to send message, mid: %d error: %+v", mid, err)
|
|
err = nil
|
|
}
|
|
if err = s.dao.IncrViolationCount(ctx, mid); err != nil {
|
|
log.Error("Failed to increase violation count mid: %d error: %+v", mid, err)
|
|
err = nil
|
|
}
|
|
report.Manager(&report.ManagerInfo{
|
|
Uname: arg.Operator,
|
|
UID: arg.OperatorID,
|
|
Business: model.ManagerLogID,
|
|
Type: model.BaseAuditTypeName,
|
|
Oid: mid,
|
|
Action: _logActionBaseAudit,
|
|
Ctime: time.Now(),
|
|
// extra
|
|
Index: []interface{}{0, 0, 0, "", "", ""},
|
|
Content: map[string]interface{}{
|
|
"old": b.Name,
|
|
"new": defaultName,
|
|
},
|
|
})
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Members is.
|
|
func (s *Service) Members(ctx context.Context, arg *model.ArgList) (*model.MemberPagination, error) {
|
|
searched, err := s.dao.SearchMember(ctx, arg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
mids := searched.Mids()
|
|
|
|
bs, err := s.batchBase(ctx, mids)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
result := make([]*model.Base, 0, len(mids))
|
|
for _, mid := range mids {
|
|
if b, ok := bs[mid]; ok {
|
|
result = append(result, b)
|
|
}
|
|
}
|
|
|
|
page := &model.MemberPagination{
|
|
CommonPagination: searched.Pagination(),
|
|
Members: result,
|
|
}
|
|
return page, nil
|
|
}
|
|
|
|
// MemberProfile is.
|
|
func (s *Service) MemberProfile(ctx context.Context, mid int64) (*model.Profile, error) {
|
|
p := model.NewProfile()
|
|
|
|
// base
|
|
b, err := s.dao.Base(ctx, mid)
|
|
if err != nil {
|
|
log.Error("Failed to retrive user base with mid: %d: %+v", mid, err)
|
|
return nil, err
|
|
}
|
|
p.Base = *b
|
|
|
|
// detail
|
|
// remove later
|
|
p.Detail = model.Detail{
|
|
Mid: b.Mid,
|
|
Birthday: b.Birthday,
|
|
}
|
|
|
|
// exp
|
|
e, err := s.dao.Exp(ctx, mid)
|
|
if err != nil {
|
|
log.Error("Failed to retrive user exp with mid: %d: %+v", mid, err)
|
|
}
|
|
if e != nil {
|
|
p.Exp = *e
|
|
p.Level.FromExp(e)
|
|
}
|
|
|
|
// moral
|
|
mo, err := s.dao.Moral(ctx, mid)
|
|
if err != nil {
|
|
log.Error("Failed to retrive user moral with mid: %d: %+v", mid, err)
|
|
}
|
|
if mo != nil {
|
|
p.Moral = *mo
|
|
}
|
|
|
|
// official
|
|
of, err := s.dao.Official(ctx, mid)
|
|
if err != nil {
|
|
log.Error("Failed to retrive user official with mid: %d: %+v", mid, err)
|
|
}
|
|
if of != nil {
|
|
p.Official = *of
|
|
}
|
|
|
|
// coin
|
|
co, err := s.coinRPC.UserCoins(ctx, &coin.ArgCoinInfo{Mid: mid})
|
|
if err != nil {
|
|
log.Error("Failed to retrive user coins with mid: %d: %+v", mid, err)
|
|
}
|
|
p.Coin = model.Coin{Coins: co}
|
|
|
|
// addit
|
|
ad, err := s.dao.UserAddit(ctx, mid)
|
|
if err != nil {
|
|
log.Error("Failed to retrive user addit with mid: %d: %+v", mid, err)
|
|
}
|
|
if ad != nil {
|
|
p.Addit = *ad
|
|
}
|
|
|
|
// realname
|
|
dr, err := s.dao.RealnameInfo(ctx, mid)
|
|
if err != nil {
|
|
log.Error("Failed to retrive user realname with mid: %d: %+v", mid, err)
|
|
}
|
|
if dr != nil {
|
|
p.Realanme.ParseInfo(dr)
|
|
} else {
|
|
p.Realanme.State = model.RealnameApplyStateNone
|
|
}
|
|
return p, nil
|
|
}
|
|
|
|
// DelSign is.
|
|
func (s *Service) DelSign(ctx context.Context, arg *model.ArgMids) error {
|
|
for _, mid := range arg.Mid {
|
|
err := s.dao.UpSign(ctx, mid, "")
|
|
if err != nil {
|
|
log.Error("Failed to delete sign mid: %d: %+v", mid, err)
|
|
continue
|
|
}
|
|
if err := s.dao.Message(ctx, "违规签名处理通知", "抱歉,由于你的个性签名内容涉嫌违规,我们已将你的个性签名清空,如有问题请联系客服。", []int64{mid}); err != nil {
|
|
log.Error("Failed to send message: mid: %d: %+v", mid, err)
|
|
}
|
|
report.Manager(&report.ManagerInfo{
|
|
Uname: arg.Operator,
|
|
UID: arg.OperatorID,
|
|
Business: model.ManagerLogID,
|
|
Type: 0,
|
|
Oid: mid,
|
|
Action: _logActionDeleteSign,
|
|
Ctime: time.Now(),
|
|
})
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// SetMoral is.
|
|
func (s *Service) SetMoral(ctx context.Context, arg *model.ArgMoralSet) error {
|
|
moral, err := s.dao.Moral(ctx, arg.Mid)
|
|
if err != nil {
|
|
return errors.WithStack(err)
|
|
}
|
|
newMoral := int64(arg.Moral * 100)
|
|
delta := newMoral - moral.Moral
|
|
if err = s.memberRPC.AddMoral(ctx,
|
|
&member.ArgUpdateMoral{
|
|
Mid: arg.Mid,
|
|
Delta: delta,
|
|
Operator: arg.Operator,
|
|
Reason: arg.Reason,
|
|
Remark: "管理后台",
|
|
Origin: member.ManualChangeType,
|
|
IP: arg.IP}); err != nil {
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
report.Manager(&report.ManagerInfo{
|
|
Uname: arg.Operator,
|
|
UID: arg.OperatorID,
|
|
Business: model.ManagerLogID,
|
|
Type: 0,
|
|
Oid: arg.Mid,
|
|
Action: _logActionMoralUpdate,
|
|
Ctime: time.Now(),
|
|
// extra
|
|
Index: []interface{}{0, 0, 0, "", "", ""},
|
|
Content: map[string]interface{}{
|
|
"new_moral": newMoral,
|
|
"delta": delta,
|
|
},
|
|
})
|
|
return nil
|
|
}
|
|
|
|
// SetExp is.
|
|
func (s *Service) SetExp(ctx context.Context, arg *model.ArgExpSet) error {
|
|
exp, err := func() (*model.Exp, error) {
|
|
exp, err := s.dao.Exp(ctx, arg.Mid)
|
|
if err != nil {
|
|
if err == ecode.NothingFound {
|
|
return &model.Exp{Mid: arg.Mid}, nil
|
|
}
|
|
return nil, errors.WithStack(err)
|
|
}
|
|
return exp, nil
|
|
}()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
delta := arg.Exp - float64(exp.Exp/100)
|
|
if err = s.memberRPC.UpdateExp(ctx,
|
|
&member.ArgAddExp{
|
|
Mid: arg.Mid,
|
|
Count: delta,
|
|
Operate: arg.Operator,
|
|
Reason: arg.Reason,
|
|
IP: arg.IP}); err != nil {
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
report.Manager(&report.ManagerInfo{
|
|
Uname: arg.Operator,
|
|
UID: arg.OperatorID,
|
|
Business: model.ManagerLogID,
|
|
Type: 0,
|
|
Oid: arg.Mid,
|
|
Action: _logActionExpUpdate,
|
|
Ctime: time.Now(),
|
|
// extra
|
|
Index: []interface{}{0, 0, 0, "", "", ""},
|
|
Content: map[string]interface{}{
|
|
"new_exp": arg.Exp,
|
|
"delta": delta,
|
|
},
|
|
})
|
|
return nil
|
|
}
|
|
|
|
// SetRank is.
|
|
func (s *Service) SetRank(ctx context.Context, arg *model.ArgRankSet) error {
|
|
if err := s.memberRPC.SetRank(ctx,
|
|
&member.ArgUpdateRank{
|
|
Mid: arg.Mid,
|
|
Rank: arg.Rank,
|
|
RemoteIP: arg.IP}); err != nil {
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
report.Manager(&report.ManagerInfo{
|
|
Uname: arg.Operator,
|
|
UID: arg.OperatorID,
|
|
Business: model.ManagerLogID,
|
|
Type: 0,
|
|
Oid: arg.Mid,
|
|
Action: _logActionRankUpdate,
|
|
Ctime: time.Now(),
|
|
// extra
|
|
Index: []interface{}{0, 0, 0, "", "", ""},
|
|
Content: map[string]interface{}{
|
|
"new_rank": arg.Rank,
|
|
"reason": arg.Reason,
|
|
},
|
|
})
|
|
return nil
|
|
}
|
|
|
|
// SetCoin is.
|
|
func (s *Service) SetCoin(ctx context.Context, arg *model.ArgCoinSet) error {
|
|
coins, err := s.coinRPC.UserCoins(ctx, &coin.ArgCoinInfo{Mid: arg.Mid, RealIP: arg.IP})
|
|
if err != nil {
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
reason := "系统操作"
|
|
if arg.Reason != "" {
|
|
reason = fmt.Sprintf("系统操作:%s", arg.Reason)
|
|
}
|
|
delta := arg.Coins - coins
|
|
if _, err = s.coinRPC.ModifyCoin(ctx,
|
|
&coin.ArgModifyCoin{
|
|
Mid: arg.Mid,
|
|
Operator: arg.Operator,
|
|
Reason: reason,
|
|
Count: delta,
|
|
IP: arg.IP}); err != nil {
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
report.Manager(&report.ManagerInfo{
|
|
Uname: arg.Operator,
|
|
UID: arg.OperatorID,
|
|
Business: model.ManagerLogID,
|
|
Type: 0,
|
|
Oid: arg.Mid,
|
|
Action: _logActionCoinUpdate,
|
|
Ctime: time.Now(),
|
|
// extra
|
|
Index: []interface{}{0, 0, 0, "", "", ""},
|
|
Content: map[string]interface{}{
|
|
"new_coins": arg.Coins,
|
|
"delta": delta,
|
|
"reason": reason,
|
|
},
|
|
})
|
|
return nil
|
|
}
|
|
|
|
// SetAdditRemark is.
|
|
func (s *Service) SetAdditRemark(ctx context.Context, arg *model.ArgAdditRemarkSet) error {
|
|
return s.dao.UpAdditRemark(ctx, arg.Mid, arg.Remark)
|
|
}
|
|
|
|
// PubExpMsg is.
|
|
func (s *Service) PubExpMsg(ctx context.Context, arg *model.ArgPubExpMsg) (err error) {
|
|
msg := &model.AddExpMsg{
|
|
Event: arg.Event,
|
|
Mid: arg.Mid,
|
|
IP: arg.IP,
|
|
Ts: arg.Ts,
|
|
}
|
|
return s.dao.PubExpMsg(ctx, msg)
|
|
}
|
|
|
|
// ExpLog is.
|
|
func (s *Service) ExpLog(ctx context.Context, mid int64) ([]*model.UserLog, error) {
|
|
return nil, ecode.MethodNotAllowed
|
|
}
|
|
|
|
func filterByStatus(status ...int8) func(*model.FaceRecord) bool {
|
|
ss := make(map[int8]struct{}, len(status))
|
|
for _, s := range status {
|
|
ss[s] = struct{}{}
|
|
}
|
|
return func(fr *model.FaceRecord) bool {
|
|
_, ok := ss[fr.Status]
|
|
return ok
|
|
}
|
|
}
|
|
|
|
func filterByMid(mid int64) func(*model.FaceRecord) bool {
|
|
return func(fr *model.FaceRecord) bool {
|
|
return fr.Mid == mid
|
|
}
|
|
}
|
|
|
|
func filterByOP(operator string) func(*model.FaceRecord) bool {
|
|
return func(fr *model.FaceRecord) bool {
|
|
return fr.Operator == operator
|
|
}
|
|
}
|
|
|
|
// FaceHistory is.
|
|
func (s *Service) FaceHistory(ctx context.Context, arg *model.ArgFaceHistory) (*model.FaceRecordPagination, error) {
|
|
list, err := s.faceHistory(ctx, arg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
plist := list.Paginate(arg.PS*(arg.PN-1), arg.PS)
|
|
|
|
page := &model.FaceRecordPagination{
|
|
Records: plist,
|
|
CommonPagination: &model.CommonPagination{
|
|
Page: model.Page{
|
|
Num: arg.PN,
|
|
Size: arg.PS,
|
|
Total: len(list),
|
|
},
|
|
},
|
|
}
|
|
return page, nil
|
|
}
|
|
|
|
func (s *Service) faceHistory(ctx context.Context, arg *model.ArgFaceHistory) (res model.FaceRecordList, err error) {
|
|
switch arg.Mode() {
|
|
case "op":
|
|
res, err = s.dao.FaceHistoryByOP(ctx, arg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if arg.Mid > 0 {
|
|
res = res.Filter(filterByMid(arg.Mid))
|
|
}
|
|
case "mid":
|
|
res, err = s.dao.FaceHistoryByMid(ctx, arg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if arg.Operator != "" {
|
|
res = res.Filter(filterByOP(arg.Operator))
|
|
}
|
|
}
|
|
res = res.Filter(filterByStatus(arg.Status...))
|
|
sort.Slice(res, func(i, j int) bool {
|
|
return res[i].ModifyTime > res[j].ModifyTime
|
|
})
|
|
for _, r := range res {
|
|
r.BuildFaceURL()
|
|
}
|
|
return
|
|
}
|
|
|
|
// MoralLog is.
|
|
func (s *Service) MoralLog(ctx context.Context, mid int64) ([]*model.UserLog, error) {
|
|
return nil, ecode.MethodNotAllowed
|
|
}
|
|
|
|
func (s *Service) reviewAddit(ctx context.Context, mids []int64, mrs []*model.BaseReview) error {
|
|
uas, err := s.dao.BatchUserAddit(ctx, mids)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, mr := range mrs {
|
|
if ua, ok := uas[mr.Mid]; ok {
|
|
mr.Addit = *ua
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// BatchFormal is
|
|
func (s *Service) BatchFormal(ctx context.Context, arg *model.ArgBatchFormal) error {
|
|
fp := bom.NewReader(bytes.NewReader(arg.FileData))
|
|
reader := csv.NewReader(fp)
|
|
ip := metadata.String(ctx, metadata.RemoteIP)
|
|
|
|
columns, err := reader.Read()
|
|
if err != nil {
|
|
log.Error("Failed to read columns from csv: %+v", err)
|
|
return ecode.RequestErr
|
|
}
|
|
|
|
findMidPositon := func() (int, error) {
|
|
for i, col := range columns {
|
|
if col == "mid" {
|
|
return i, nil
|
|
}
|
|
}
|
|
return 0, errors.New("No mid column")
|
|
}
|
|
|
|
midPosition, err := findMidPositon()
|
|
if err != nil {
|
|
log.Error("Failed to find mid column: %+v", err)
|
|
return ecode.RequestErr
|
|
}
|
|
|
|
mids := make([]int64, 0)
|
|
for {
|
|
record, rerr := reader.Read()
|
|
if rerr == io.EOF {
|
|
break
|
|
}
|
|
if rerr != nil {
|
|
log.Error("Failed to parse csv: %+v", errors.WithStack(rerr))
|
|
return ecode.RequestErr
|
|
}
|
|
|
|
if len(record) < midPosition {
|
|
log.Warn("Skip record due to no suitable position: %+v", record)
|
|
continue
|
|
}
|
|
|
|
mid, perr := strconv.ParseInt(record[midPosition], 10, 64)
|
|
if perr != nil {
|
|
log.Warn("Failed to parse mid on data: %+v: %+v", record[midPosition], perr)
|
|
continue
|
|
}
|
|
|
|
mids = append(mids, mid)
|
|
}
|
|
|
|
bases, err := s.batchBase(ctx, mids)
|
|
if err != nil {
|
|
log.Error("Failed to query bases with mids: %+v: %+v", mids, err)
|
|
return ecode.RequestErr
|
|
}
|
|
|
|
for _, mid := range mids {
|
|
base, ok := bases[mid]
|
|
if !ok {
|
|
log.Warn("No such user with mid: %d", mid)
|
|
continue
|
|
}
|
|
if base.Rank >= 10000 {
|
|
log.Warn("Rank already exceeded 10000 on mid: %d: %+v", mid, base)
|
|
continue
|
|
}
|
|
|
|
rankArg := &model.ArgRankSet{
|
|
Mid: mid,
|
|
Rank: 10000,
|
|
Operator: arg.Operator,
|
|
OperatorID: arg.OperatorID,
|
|
IP: ip,
|
|
}
|
|
if err := s.SetRank(ctx, rankArg); err != nil {
|
|
log.Warn("Failed to set rank with mid: %d: %+v", mid, err)
|
|
continue
|
|
}
|
|
|
|
// 通过发放一次每日登录的经验奖励消息来使用户等级直升 lv1
|
|
expArg := &model.ArgPubExpMsg{
|
|
Mid: mid,
|
|
IP: ip,
|
|
Ts: time.Now().Unix(),
|
|
Event: "login",
|
|
}
|
|
if err := s.PubExpMsg(ctx, expArg); err != nil {
|
|
log.Warn("Failed to pub exp message with mid: %d: %+v", mid, err)
|
|
continue
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|