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.
436 lines
12 KiB
436 lines
12 KiB
package service |
|
|
|
import ( |
|
"context" |
|
"encoding/json" |
|
"strings" |
|
"time" |
|
|
|
"go-common/app/admin/main/member/model" |
|
"go-common/app/service/main/member/model/block" |
|
spymodel "go-common/app/service/main/spy/model" |
|
"go-common/library/ecode" |
|
"go-common/library/log" |
|
"go-common/library/queue/databus/report" |
|
xtime "go-common/library/time" |
|
|
|
"github.com/pkg/errors" |
|
) |
|
|
|
const ( |
|
_logActionAudit = "official_doc_audit" |
|
_logActionEdit = "official_doc_edit" |
|
_logActionEditName = "official_doc_edit_name" |
|
) |
|
|
|
func i64Toi8(in []int64) []int8 { |
|
out := make([]int8, 0, len(in)) |
|
for _, i := range in { |
|
out = append(out, int8(i)) |
|
} |
|
return out |
|
} |
|
|
|
func i8Toi64(in []int8) []int64 { |
|
out := make([]int64, 0, len(in)) |
|
for _, i := range in { |
|
out = append(out, int64(i)) |
|
} |
|
return out |
|
} |
|
|
|
func actOr(act ...string) string { |
|
return strings.Join(act, ",") |
|
} |
|
|
|
func (s *Service) officialName(ctx context.Context, ofs []*model.Official) { |
|
mids := make([]int64, 0, len(ofs)) |
|
for _, o := range ofs { |
|
mids = append(mids, o.Mid) |
|
} |
|
ofds, err := s.dao.OfficialDocsByMids(ctx, mids) |
|
if err != nil { |
|
log.Error("Failed to s.dao.OfficialDocsByMids(%+v): %+v", mids, err) |
|
return |
|
} |
|
for _, o := range ofs { |
|
od, ok := ofds[o.Mid] |
|
if !ok { |
|
continue |
|
} |
|
o.Name = od.Name |
|
} |
|
} |
|
|
|
// Officials is. |
|
func (s *Service) Officials(ctx context.Context, arg *model.ArgOfficial) ([]*model.Official, int, error) { |
|
if len(arg.Role) == 0 { |
|
arg.Role = i8Toi64(model.AllRoles) |
|
} |
|
if arg.ETime == 0 { |
|
arg.ETime = xtime.Time(time.Now().Unix()) |
|
} |
|
ofs, total, err := s.dao.Officials(ctx, arg.Mid, i64Toi8(arg.Role), arg.STime.Time(), arg.ETime.Time(), arg.Pn, arg.Ps) |
|
if err != nil { |
|
return nil, 0, err |
|
} |
|
// 需要展示昵称 |
|
s.officialName(ctx, ofs) |
|
return ofs, total, err |
|
} |
|
|
|
func (s *Service) blockResult(ctx context.Context, mid int64) (*model.BlockResult, error) { |
|
info, err := s.memberRPC.BlockInfo(ctx, &block.RPCArgInfo{MID: mid}) |
|
if err != nil { |
|
err = errors.Wrapf(err, "%v", mid) |
|
return nil, err |
|
} |
|
block := &model.BlockResult{ |
|
MID: info.MID, |
|
BlockStatus: info.BlockStatus, |
|
StartTime: info.StartTime, |
|
EndTime: info.EndTime, |
|
} |
|
return block, nil |
|
} |
|
|
|
// OfficialDoc is. |
|
func (s *Service) OfficialDoc(ctx context.Context, mid int64) (od *model.OfficialDoc, logs *model.SearchLogResult, block *model.BlockResult, spys []*spymodel.Statistics, realname *model.Realname, sameCreditCodeMids []int64, err error) { |
|
if od, err = s.dao.OfficialDoc(ctx, mid); err != nil { |
|
return |
|
} |
|
if od == nil { |
|
od = &model.OfficialDoc{ |
|
Mid: mid, |
|
OfficialExtra: &model.OfficialExtra{}, |
|
} |
|
} |
|
logs, err = s.dao.SearchLog(ctx, 0, mid, "", actOr(_logActionAudit, _logActionEdit)) |
|
if err != nil { |
|
log.Error("Failed to s.dao.SearchLog(%+v): %+v", mid, err) |
|
return |
|
} |
|
block, err = s.blockResult(ctx, mid) |
|
if err != nil { |
|
log.Error("Failed to s.blockResult(%+v): %+v", mid, err) |
|
return |
|
} |
|
arg := &spymodel.ArgStat{Mid: mid} |
|
spys, err = s.spyRPC.StatByID(ctx, arg) |
|
if err != nil { |
|
log.Error("Failed to s.spyRPC.StatByID: mid(%d): %+v", od.Mid, err) |
|
return |
|
} |
|
|
|
realname, err = s.officialRealname(ctx, mid) |
|
if err != nil { |
|
log.Error("Failed to get official realname with mid: %d: %+v", od.Mid, err) |
|
return |
|
} |
|
|
|
// 查询使用相同社会信用代码的mid |
|
sameCreditCodeMids = make([]int64, 0) |
|
if od.OfficialExtra.CreditCode != "" { |
|
func() { |
|
addits, err := s.OfficialDocAddits(ctx, "credit_code", od.OfficialExtra.CreditCode) |
|
if err != nil { |
|
log.Error("Failed to get official addit with mid: %d: %+v", od.Mid, err) |
|
return |
|
} |
|
for _, addit := range addits { |
|
if addit.Mid != od.Mid { |
|
sameCreditCodeMids = append(sameCreditCodeMids, addit.Mid) |
|
} |
|
} |
|
}() |
|
} |
|
|
|
return |
|
} |
|
|
|
func (s *Service) officialRealname(ctx context.Context, mid int64) (*model.Realname, error) { |
|
realname := &model.Realname{ |
|
State: model.RealnameApplyStateNone, |
|
} |
|
dr, err := s.dao.RealnameInfo(ctx, mid) |
|
if err != nil { |
|
log.Error("Failed to get realname info with mid: %d: %+v", mid, err) |
|
return realname, nil |
|
} |
|
if dr != nil { |
|
realname.ParseInfo(dr) |
|
} |
|
|
|
imagesByMain := func() { |
|
apply, err := s.dao.LastPassedRealnameMainApply(ctx, mid) |
|
if err != nil { |
|
log.Error("Failed to get last passed realname main apply with mid: %d: %+v", mid, err) |
|
return |
|
} |
|
|
|
images, err := s.dao.RealnameApplyIMG(ctx, []int64{apply.HandIMG, apply.FrontIMG, apply.BackIMG}) |
|
if err != nil { |
|
log.Error("Failed to get realname apply image by apply: %+v: %+v", apply, err) |
|
return |
|
} |
|
|
|
for _, image := range images { |
|
realname.ParseDBApplyIMG(image.IMGData) |
|
} |
|
} |
|
|
|
imagesByAlipay := func() { |
|
apply, err := s.dao.LastPassedRealnameAlipayApply(ctx, mid) |
|
if err != nil { |
|
log.Error("Failed to get last passed realname alipay apply with mid: %d: %+v", mid, err) |
|
return |
|
} |
|
realname.ParseDBApplyIMG(apply.IMG) |
|
} |
|
|
|
switch dr.Channel { |
|
case model.ChannelMain.DBChannel(): |
|
imagesByMain() |
|
case model.ChannelAlipay.DBChannel(): |
|
imagesByAlipay() |
|
default: |
|
log.Error("Failed to get realname apply images by realname info: %+v", dr) |
|
} |
|
|
|
return realname, nil |
|
} |
|
|
|
// OfficialDocs is. |
|
func (s *Service) OfficialDocs(ctx context.Context, arg *model.ArgOfficialDoc) ([]*model.OfficialDoc, int, error) { |
|
if len(arg.Role) == 0 { |
|
arg.Role = i8Toi64(model.AllRoles) |
|
} |
|
if len(arg.State) == 0 { |
|
arg.State = i8Toi64(model.AllStates) |
|
} |
|
if arg.ETime == 0 { |
|
arg.ETime = xtime.Time(time.Now().Unix()) |
|
} |
|
return s.dao.OfficialDocs(ctx, arg.Mid, i64Toi8(arg.Role), i64Toi8(arg.State), arg.Uname, arg.STime.Time(), arg.ETime.Time(), arg.Pn, arg.Ps) |
|
} |
|
|
|
// OfficialDocAudit is. |
|
func (s *Service) OfficialDocAudit(ctx context.Context, arg *model.ArgOfficialAudit) (err error) { |
|
od, err := s.dao.OfficialDoc(ctx, arg.Mid) |
|
if err != nil { |
|
return |
|
} |
|
if arg.State == model.OfficialStatePass { |
|
if err = s.updateUname(ctx, od.Mid, od.Name, arg.UID, arg.Uname); err != nil { |
|
log.Error("Failed to update uname: mid(%d), name(%s): %+v", od.Mid, od.Name, err) |
|
return |
|
} |
|
} |
|
|
|
if err = s.dao.OfficialDocAudit(ctx, arg.Mid, arg.State, arg.Uname, arg.IsInternal, arg.Reason); err != nil { |
|
return |
|
} |
|
od, err = s.dao.OfficialDoc(ctx, arg.Mid) |
|
if err != nil { |
|
return |
|
} |
|
role := int8(model.OfficialRoleUnauth) |
|
cnt := `对不起,您的官方认证申请未通过,未通过原因:"` + arg.Reason + `,重新申请点#{这里}{"https://account.bilibili.com/account/official/home"}` |
|
if arg.State == model.OfficialStatePass { |
|
role = od.Role |
|
cnt = "恭喜,您的官方认证申请已经通过啦!o(* ̄▽ ̄*)o" |
|
} |
|
if _, err = s.dao.OfficialEdit(ctx, arg.Mid, role, od.Title, od.Desc); err != nil { |
|
return |
|
} |
|
|
|
if err = s.dao.Message(ctx, "官方认证审核通知", cnt, []int64{arg.Mid}); err != nil { |
|
log.Error("Failed to send message: %+v", err) |
|
err = nil |
|
} |
|
report.Manager(&report.ManagerInfo{ |
|
Uname: arg.Uname, |
|
UID: arg.UID, |
|
Business: model.ManagerLogID, |
|
Type: 0, |
|
Oid: arg.Mid, |
|
Action: _logActionAudit, |
|
Ctime: time.Now(), |
|
// extra |
|
Index: []interface{}{arg.State, int64(od.CTime), od.Role, od.Name, od.Title, od.Desc}, |
|
Content: map[string]interface{}{ |
|
"reason": arg.Reason, |
|
"name": od.Name, |
|
"extra": od.Extra, |
|
"role": od.Role, |
|
"title": od.Title, |
|
"desc": od.Desc, |
|
"state": arg.State, |
|
"doc_ctime": int64(od.CTime), |
|
}, |
|
}) |
|
return |
|
} |
|
|
|
// OfficialDocEdit is. |
|
func (s *Service) OfficialDocEdit(ctx context.Context, arg *model.ArgOfficialEdit) (err error) { |
|
od, _ := s.dao.OfficialDoc(ctx, arg.Mid) |
|
if od == nil { |
|
od = &model.OfficialDoc{ |
|
Mid: arg.Mid, |
|
Role: arg.Role, |
|
OfficialExtra: &model.OfficialExtra{}, |
|
} |
|
} |
|
od.State = int8(model.OfficialStatePass) |
|
if arg.Role == model.OfficialRoleUnauth { |
|
od.State = int8(model.OfficialStateNoPass) |
|
} |
|
od.Name = arg.Name |
|
od.Uname = arg.Uname |
|
od.Telephone = arg.Telephone |
|
od.Email = arg.Email |
|
od.Address = arg.Address |
|
od.Supplement = arg.Supplement |
|
od.Company = arg.Company |
|
od.Operator = arg.Operator |
|
od.CreditCode = arg.CreditCode |
|
od.Organization = arg.Organization |
|
od.OrganizationType = arg.OrganizationType |
|
od.BusinessLicense = arg.BusinessLicense |
|
od.BusinessLevel = arg.BusinessLevel |
|
od.BusinessScale = arg.BusinessScale |
|
od.BusinessAuth = arg.BusinessAuth |
|
od.OfficalSite = arg.OfficalSite |
|
od.RegisteredCapital = arg.RegisteredCapital |
|
extra, err := json.Marshal(od.OfficialExtra) |
|
if err != nil { |
|
err = errors.Wrap(err, "official doc edit") |
|
return |
|
} |
|
if err = s.updateUname(ctx, arg.Mid, arg.Name, arg.UID, arg.Uname); err != nil { |
|
log.Error("Failed to update uname: mid(%d), name(%s): %+v", arg.Mid, arg.Name, err) |
|
err = ecode.MemberNameFormatErr |
|
return |
|
} |
|
if err = s.dao.OfficialDocEdit(ctx, arg.Mid, arg.Name, arg.Role, od.State, arg.Title, arg.Desc, string(extra), arg.Uname, arg.IsInternal); err != nil { |
|
log.Error("Failed to update official doc: %+v", err) |
|
err = ecode.RequestErr |
|
return |
|
} |
|
if _, err = s.dao.OfficialEdit(ctx, arg.Mid, arg.Role, arg.Title, arg.Desc); err != nil { |
|
return |
|
} |
|
report.Manager(&report.ManagerInfo{ |
|
Uname: arg.Uname, |
|
UID: arg.UID, |
|
Business: model.ManagerLogID, |
|
Type: 0, |
|
Oid: arg.Mid, |
|
Action: _logActionEdit, |
|
Ctime: time.Now(), |
|
// extra |
|
Index: []interface{}{od.State, int64(od.CTime), arg.Role, arg.Name, arg.Title, arg.Desc}, |
|
Content: map[string]interface{}{ |
|
"extra": string(extra), |
|
"name": arg.Name, |
|
"role": arg.Role, |
|
"title": arg.Title, |
|
"desc": arg.Desc, |
|
"state": od.State, |
|
"doc_ctime": int64(od.CTime), |
|
}, |
|
}) |
|
if arg.SendMessage { |
|
if merr := s.dao.Message(ctx, arg.MessageTitle, arg.MessageContent, []int64{arg.Mid}); merr != nil { |
|
log.Error("Failed to send message: %+v", merr) |
|
} |
|
} |
|
return |
|
} |
|
|
|
// OfficialDocSubmit is. |
|
func (s *Service) OfficialDocSubmit(ctx context.Context, arg *model.ArgOfficialSubmit) (err error) { |
|
od := &model.OfficialDoc{ |
|
Mid: arg.Mid, |
|
Name: arg.Name, |
|
State: int8(model.OfficialStateWait), |
|
Role: arg.Role, |
|
Title: arg.Title, |
|
Desc: arg.Desc, |
|
|
|
Uname: arg.Uname, |
|
IsInternal: arg.IsInternal, |
|
SubmitSource: arg.SubmitSource, |
|
|
|
OfficialExtra: &model.OfficialExtra{ |
|
Realname: arg.Realname, |
|
Operator: arg.Operator, |
|
Telephone: arg.Telephone, |
|
Email: arg.Email, |
|
Address: arg.Address, |
|
Company: arg.Company, |
|
CreditCode: arg.CreditCode, |
|
Organization: arg.Organization, |
|
OrganizationType: arg.OrganizationType, |
|
BusinessLicense: arg.BusinessLicense, |
|
BusinessScale: arg.BusinessScale, |
|
BusinessLevel: arg.BusinessLevel, |
|
BusinessAuth: arg.BusinessAuth, |
|
Supplement: arg.Supplement, |
|
Professional: arg.Professional, |
|
Identification: arg.Identification, |
|
OfficalSite: arg.OfficalSite, |
|
RegisteredCapital: arg.RegisteredCapital, |
|
}, |
|
} |
|
if !od.Validate() { |
|
log.Error("Failed to validate official doc: %+v", od) |
|
err = ecode.RequestErr |
|
return |
|
} |
|
return s.dao.OfficialDocSubmit(ctx, od.Mid, od.Name, od.Role, int8(model.OfficialStateWait), od.Title, od.Desc, od.OfficialExtra.String(), od.Uname, od.IsInternal, od.SubmitSource) |
|
} |
|
|
|
func (s *Service) updateUname(ctx context.Context, mid int64, name string, adminID int64, adminName string) error { |
|
b, err := s.dao.Base(ctx, mid) |
|
if err != nil { |
|
return err |
|
} |
|
if b.Name == name { |
|
return nil |
|
} |
|
if err := s.dao.UpdateUname(ctx, mid, name); err != nil { |
|
log.Error("Failed to update uname to aso: mid(%d), name(%s): %+v", mid, name, err) |
|
return err |
|
} |
|
if err := s.dao.UpName(ctx, mid, name); err != nil { |
|
log.Error("Failed to update uname to member: mid(%d), name(%s): %+v", mid, name, err) |
|
return err |
|
} |
|
report.Manager(&report.ManagerInfo{ |
|
Uname: adminName, |
|
UID: adminID, |
|
Business: model.ManagerLogID, |
|
Type: 0, |
|
Oid: mid, |
|
Action: _logActionEditName, |
|
Ctime: time.Now(), |
|
// extra |
|
Index: []interface{}{0, 0, 0, "", "", ""}, |
|
Content: map[string]interface{}{ |
|
"old_name": b.Name, |
|
"new_name": name, |
|
}, |
|
}) |
|
return nil |
|
} |
|
|
|
// OfficialDocAddits find mids by property and value |
|
func (s *Service) OfficialDocAddits(ctx context.Context, property string, vstring string) ([]*model.OfficialDocAddit, error) { |
|
if property == "" { |
|
return nil, ecode.RequestErr |
|
} |
|
addits, err := s.dao.OfficialDocAddits(ctx, property, vstring) |
|
return addits, err |
|
}
|
|
|