bilibili-backup/app/admin/main/member/service/official.go

437 lines
12 KiB
Go
Raw Normal View History

2019-04-22 10:59:20 +08:00
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
}