Create & Init Project...

This commit is contained in:
2019-04-22 18:49:16 +08:00
commit fc4fa37393
25440 changed files with 4054998 additions and 0 deletions

View File

@@ -0,0 +1,89 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = [
"account.go",
"api.go",
"cmd.go",
"creative.go",
"data.go",
"mcn.go",
"msg.go",
"rank.go",
"service.go",
"uniquecheck.go",
"upload.go",
],
importpath = "go-common/app/interface/main/mcn/service",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/mcn/model:go_default_library",
"//app/interface/main/mcn/conf:go_default_library",
"//app/interface/main/mcn/dao/bfs:go_default_library",
"//app/interface/main/mcn/dao/cache:go_default_library",
"//app/interface/main/mcn/dao/datadao:go_default_library",
"//app/interface/main/mcn/dao/global:go_default_library",
"//app/interface/main/mcn/dao/mcndao:go_default_library",
"//app/interface/main/mcn/dao/msg:go_default_library",
"//app/interface/main/mcn/model:go_default_library",
"//app/interface/main/mcn/model/datamodel:go_default_library",
"//app/interface/main/mcn/model/mcnmodel:go_default_library",
"//app/interface/main/mcn/tool/worker:go_default_library",
"//app/service/main/account/api:go_default_library",
"//app/service/main/member/api:go_default_library",
"//app/service/main/member/model:go_default_library",
"//app/service/main/member/model/block:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/metadata:go_default_library",
"//library/time:go_default_library",
"//vendor/github.com/bluele/gcache:go_default_library",
"//vendor/github.com/jinzhu/gorm:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
go_test(
name = "go_default_test",
srcs = [
"account_test.go",
"cmd_test.go",
"mcn_test.go",
"msg_test.go",
"rank_test.go",
"service_test.go",
"uniquecheck_test.go",
"upload_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/admin/main/mcn/model:go_default_library",
"//app/interface/main/mcn/conf:go_default_library",
"//app/interface/main/mcn/model:go_default_library",
"//app/interface/main/mcn/model/mcnmodel:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)

View File

@@ -0,0 +1,25 @@
package service
import (
"context"
"go-common/app/interface/main/mcn/dao/global"
"go-common/app/interface/main/mcn/model/mcnmodel"
"go-common/library/log"
)
//GetUpAccountInfo get account info
func (s *Service) GetUpAccountInfo(c context.Context, arg *mcnmodel.McnGetAccountReq) (result *mcnmodel.McnGetAccountReply, err error) {
var data, e = global.GetInfo(c, arg.Mid)
err = e
if err != nil || data == nil {
log.Error("get info fail, req=%+v, err=%+v", arg, err)
return
}
result = new(mcnmodel.McnGetAccountReply)
result.Mid = data.Mid
result.Name = data.Name
log.Info("query acount info ok, req=%+v, result=%+v", arg, result)
return
}

View File

@@ -0,0 +1,26 @@
package service
import (
"context"
"testing"
"go-common/app/interface/main/mcn/model/mcnmodel"
"github.com/smartystreets/goconvey/convey"
)
func TestServiceGetUpAccountInfo(t *testing.T) {
convey.Convey("GetUpAccountInfo", t, func(ctx convey.C) {
var (
c = context.Background()
arg = &mcnmodel.McnGetAccountReq{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
result, err := s.GetUpAccountInfo(c, arg)
ctx.Convey("Then err should be nil.result should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(result, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,89 @@
package service
import (
"context"
"go-common/app/interface/main/mcn/dao/mcndao"
"go-common/app/interface/main/mcn/model/datamodel"
"go-common/app/interface/main/mcn/model/mcnmodel"
"go-common/library/log"
)
// McnGetRankArchiveLikesAPI get rank archive likes
func (s *Service) McnGetRankArchiveLikesAPI(c context.Context, arg *mcnmodel.McnGetRankAPIReq) (res *mcnmodel.McnGetRankUpFansReply, err error) {
res, err = s.getRankResultAPI(c, arg, s.mcndao.GetRankArchiveLikes)
return
}
func (s *Service) getRankResultAPI(c context.Context, arg *mcnmodel.McnGetRankAPIReq, rankFunc mcndao.RankFunc) (res *mcnmodel.McnGetRankUpFansReply, err error) {
v, err := rankFunc(arg.SignID)
if err != nil || v == nil {
log.Error("get rank fail, sign id=%d, err=%s", arg.SignID, err)
return
}
res = new(mcnmodel.McnGetRankUpFansReply)
res.Result = v.GetList(arg.Tid, arg.DataType)
res.TypeList = v.GetTypeList(arg.DataType)
return
}
// GetMcnSummaryAPI .
func (s *Service) GetMcnSummaryAPI(c context.Context, arg *mcnmodel.McnGetDataSummaryReq) (res *mcnmodel.McnGetDataSummaryReply, err error) {
return s.datadao.GetMcnSummaryCache(c, arg.SignID, datamodel.GetLastDay())
}
// GetIndexIncAPI .
func (s *Service) GetIndexIncAPI(c context.Context, arg *mcnmodel.McnGetIndexIncReq) (res *mcnmodel.McnGetIndexIncReply, err error) {
return s.datadao.GetIndexIncCache(c, arg.SignID, datamodel.GetLastDay(), arg.Type)
}
// GetIndexSourceAPI .
func (s *Service) GetIndexSourceAPI(c context.Context, arg *mcnmodel.McnGetIndexSourceReq) (res *mcnmodel.McnGetIndexSourceReply, err error) {
return s.datadao.GetIndexSourceCache(c, arg.SignID, datamodel.GetLastDay(), arg.Type)
}
// GetPlaySourceAPI .
func (s *Service) GetPlaySourceAPI(c context.Context, arg *mcnmodel.McnGetPlaySourceReq) (res *mcnmodel.McnGetPlaySourceReply, err error) {
return s.datadao.GetPlaySourceCache(c, arg.SignID, datamodel.GetLastDay())
}
// GetMcnFansAPI .
func (s *Service) GetMcnFansAPI(c context.Context, arg *mcnmodel.McnGetMcnFansReq) (res *mcnmodel.McnGetMcnFansReply, err error) {
return s.datadao.GetMcnFansCache(c, arg.SignID, datamodel.GetLastDay())
}
// GetMcnFansIncAPI .
func (s *Service) GetMcnFansIncAPI(c context.Context, arg *mcnmodel.McnGetMcnFansIncReq) (res *mcnmodel.McnGetMcnFansIncReply, err error) {
return s.datadao.GetMcnFansIncCache(c, arg.SignID, datamodel.GetLastDay())
}
// GetMcnFansDecAPI .
func (s *Service) GetMcnFansDecAPI(c context.Context, arg *mcnmodel.McnGetMcnFansDecReq) (res *mcnmodel.McnGetMcnFansDecReply, err error) {
return s.datadao.GetMcnFansDecCache(c, arg.SignID, datamodel.GetLastDay())
}
// GetMcnFansAttentionWayAPI .
func (s *Service) GetMcnFansAttentionWayAPI(c context.Context, arg *mcnmodel.McnGetMcnFansAttentionWayReq) (res *mcnmodel.McnGetMcnFansAttentionWayReply, err error) {
return s.datadao.GetMcnFansAttentionWayCache(c, arg.SignID, datamodel.GetLastDay())
}
// GetFansBaseFansAttrAPI .
func (s *Service) GetFansBaseFansAttrAPI(c context.Context, arg *mcnmodel.McnGetBaseFansAttrReq) (res *mcnmodel.McnGetBaseFansAttrReply, err error) {
return s.datadao.GetFansBaseFansAttrCache(c, arg.SignID, datamodel.GetLastWeek(), arg.UserType)
}
// GetFansAreaAPI .
func (s *Service) GetFansAreaAPI(c context.Context, arg *mcnmodel.McnGetFansAreaReq) (res *mcnmodel.McnGetFansAreaReply, err error) {
return s.datadao.GetFansAreaCache(c, arg.SignID, datamodel.GetLastWeek(), arg.UserType)
}
// GetFansTypeAPI .
func (s *Service) GetFansTypeAPI(c context.Context, arg *mcnmodel.McnGetFansTypeReq) (res *mcnmodel.McnGetFansTypeReply, err error) {
return s.datadao.GetFansTypeCache(c, arg.SignID, datamodel.GetLastWeek(), arg.UserType)
}
// GetFansTagAPI .
func (s *Service) GetFansTagAPI(c context.Context, arg *mcnmodel.McnGetFansTagReq) (res *mcnmodel.McnGetFansTagReply, err error) {
return s.datadao.GetFansTagCache(c, arg.SignID, datamodel.GetLastWeek(), arg.UserType)
}

View File

@@ -0,0 +1,13 @@
package service
import (
"context"
"go-common/app/interface/main/mcn/model/mcnmodel"
)
//CmdReloadRankCache reload cache
func (s *Service) CmdReloadRankCache(c context.Context, arg *mcnmodel.CmdReloadRank) (res *mcnmodel.CommonReply, err error) {
err = s.mcndao.ReloadRank(arg.SignID)
return
}

View File

@@ -0,0 +1,26 @@
package service
import (
"context"
"testing"
"go-common/app/interface/main/mcn/model/mcnmodel"
"github.com/smartystreets/goconvey/convey"
)
func TestServiceCmdReloadRankCache(t *testing.T) {
convey.Convey("CmdReloadRankCache", t, func(ctx convey.C) {
var (
c = context.Background()
arg = &mcnmodel.CmdReloadRank{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := s.CmdReloadRankCache(c, arg)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,21 @@
package service
import (
"context"
"net/url"
adminmodel "go-common/app/admin/main/mcn/model"
"go-common/app/interface/main/mcn/model/mcnmodel"
"go-common/library/ecode"
"go-common/library/log"
)
// CreativeHandle .
func (s *Service) CreativeHandle(c context.Context, arg *mcnmodel.CreativeCommonReq, params url.Values, key string) (res interface{}, err error) {
if !s.checkPermission(c, arg.McnMid, arg.UpMid, adminmodel.AttrDataPermitBit) {
log.Warn("mcn permission insufficient, upmid=%d, mcnmid=%d", arg.UpMid, arg.McnMid)
err = ecode.MCNPermissionInsufficient
return
}
return s.datadao.HTTPDataHandle(c, params, key)
}

View File

@@ -0,0 +1,198 @@
package service
import (
"context"
"go-common/app/interface/main/mcn/model"
"go-common/app/interface/main/mcn/model/datamodel"
"go-common/app/interface/main/mcn/model/mcnmodel"
"go-common/library/ecode"
"go-common/library/log"
)
//GetMcnGetIndexInc .
func (s *Service) GetMcnGetIndexInc(c context.Context, arg *mcnmodel.McnGetIndexIncReq) (res *mcnmodel.McnGetIndexIncReply, err error) {
mcnSign, err := s.getMcnWithState(c, arg.McnMid, model.MCNSignStateOnSign)
if err != nil {
if err != ecode.NothingFound {
log.Error("error get state, err=%s", err)
}
return
}
if res, err = s.datadao.GetIndexIncCache(c, mcnSign.ID, datamodel.GetLastDay(), arg.Type); err != nil {
log.Error("get data fail, err=%v", err)
return
}
return
}
// GetMcnGetIndexSource .
func (s *Service) GetMcnGetIndexSource(c context.Context, arg *mcnmodel.McnGetIndexSourceReq) (res *mcnmodel.McnGetIndexSourceReply, err error) {
mcnSign, err := s.getMcnWithState(c, arg.McnMid, model.MCNSignStateOnSign)
if err != nil {
if err != ecode.NothingFound {
log.Error("error get state, err=%s", err)
}
return
}
if res, err = s.datadao.GetIndexSourceCache(c, mcnSign.ID, datamodel.GetLastDay(), arg.Type); err != nil {
log.Error("get data fail, err=%v", err)
return
}
return
}
// GetPlaySource .
func (s *Service) GetPlaySource(c context.Context, arg *mcnmodel.McnGetPlaySourceReq) (res *mcnmodel.McnGetPlaySourceReply, err error) {
mcnSign, err := s.getMcnWithState(c, arg.McnMid, model.MCNSignStateOnSign)
if err != nil {
if err != ecode.NothingFound {
log.Error("error get state, err=%s", err)
}
return
}
if res, err = s.datadao.GetPlaySourceCache(c, mcnSign.ID, datamodel.GetLastDay()); err != nil {
log.Error("get data fail, err=%v", err)
}
return
}
// GetMcnFans .
func (s *Service) GetMcnFans(c context.Context, arg *mcnmodel.McnGetMcnFansReq) (res *mcnmodel.McnGetMcnFansReply, err error) {
mcnSign, err := s.getMcnWithState(c, arg.McnMid, model.MCNSignStateOnSign)
if err != nil {
if err != ecode.NothingFound {
log.Error("error get state, err=%s", err)
}
return
}
if res, err = s.datadao.GetMcnFansCache(c, mcnSign.ID, datamodel.GetLastDay()); err != nil {
log.Error("get data fail, err=%v", err)
}
return
}
// GetMcnFansInc .
func (s *Service) GetMcnFansInc(c context.Context, arg *mcnmodel.McnGetMcnFansIncReq) (res *mcnmodel.McnGetMcnFansIncReply, err error) {
mcnSign, err := s.getMcnWithState(c, arg.McnMid, model.MCNSignStateOnSign)
if err != nil {
if err != ecode.NothingFound {
log.Error("error get state, err=%s", err)
}
return
}
if res, err = s.datadao.GetMcnFansIncCache(c, mcnSign.ID, datamodel.GetLastDay()); err != nil {
log.Error("get data fail, err=%v", err)
}
return
}
// GetMcnFansDec .
func (s *Service) GetMcnFansDec(c context.Context, arg *mcnmodel.McnGetMcnFansDecReq) (res *mcnmodel.McnGetMcnFansDecReply, err error) {
mcnSign, err := s.getMcnWithState(c, arg.McnMid, model.MCNSignStateOnSign)
if err != nil {
if err != ecode.NothingFound {
log.Error("error get state, err=%s", err)
}
return
}
if res, err = s.datadao.GetMcnFansDecCache(c, mcnSign.ID, datamodel.GetLastDay()); err != nil {
log.Error("get data fail, err=%v", err)
}
return
}
// GetMcnFansAttentionWay .
func (s *Service) GetMcnFansAttentionWay(c context.Context, arg *mcnmodel.McnGetMcnFansAttentionWayReq) (res *mcnmodel.McnGetMcnFansAttentionWayReply, err error) {
mcnSign, err := s.getMcnWithState(c, arg.McnMid, model.MCNSignStateOnSign)
if err != nil {
if err != ecode.NothingFound {
log.Error("error get state, err=%s", err)
}
return
}
if res, err = s.datadao.GetMcnFansAttentionWayCache(c, mcnSign.ID, datamodel.GetLastDay()); err != nil {
log.Error("get data fail, err=%v", err)
}
return
}
// GetBaseFansAttrReq .
func (s *Service) GetBaseFansAttrReq(c context.Context, arg *mcnmodel.McnGetBaseFansAttrReq) (res *mcnmodel.McnGetBaseFansAttrReply, err error) {
mcnSign, err := s.getMcnWithState(c, arg.McnMid, model.MCNSignStateOnSign)
if err != nil {
if err != ecode.NothingFound {
log.Error("error get state, err=%s", err)
}
return
}
if res, err = s.datadao.GetFansBaseFansAttrCache(c, mcnSign.ID, datamodel.GetLastWeek(), arg.UserType); err != nil {
log.Error("get data fail, err=%v", err)
}
return
}
// GetFansArea .
func (s *Service) GetFansArea(c context.Context, arg *mcnmodel.McnGetFansAreaReq) (res *mcnmodel.McnGetFansAreaReply, err error) {
mcnSign, err := s.getMcnWithState(c, arg.McnMid, model.MCNSignStateOnSign)
if err != nil {
if err != ecode.NothingFound {
log.Error("error get state, err=%s", err)
}
return
}
if res, err = s.datadao.GetFansAreaCache(c, mcnSign.ID, datamodel.GetLastWeek(), arg.UserType); err != nil {
log.Error("get data fail, err=%v", err)
}
return
}
// GetFansType .
func (s *Service) GetFansType(c context.Context, arg *mcnmodel.McnGetFansTypeReq) (res *mcnmodel.McnGetFansTypeReply, err error) {
mcnSign, err := s.getMcnWithState(c, arg.McnMid, model.MCNSignStateOnSign)
if err != nil {
if err != ecode.NothingFound {
log.Error("error get state, err=%s", err)
}
return
}
if res, err = s.datadao.GetFansTypeCache(c, mcnSign.ID, datamodel.GetLastWeek(), arg.UserType); err != nil {
log.Error("get data fail, err=%v", err)
}
return
}
// GetFansTag .
func (s *Service) GetFansTag(c context.Context, arg *mcnmodel.McnGetFansTagReq) (res *mcnmodel.McnGetFansTagReply, err error) {
mcnSign, err := s.getMcnWithState(c, arg.McnMid, model.MCNSignStateOnSign)
if err != nil {
if err != ecode.NothingFound {
log.Error("error get state, err=%s", err)
}
return
}
if res, err = s.datadao.GetFansTagCache(c, mcnSign.ID, datamodel.GetLastWeek(), arg.UserType); err != nil {
log.Error("get data fail, err=%v", err)
}
return
}

View File

@@ -0,0 +1,799 @@
package service
import (
"context"
"time"
adminmodel "go-common/app/admin/main/mcn/model"
"go-common/app/interface/main/mcn/dao/cache"
"go-common/app/interface/main/mcn/dao/global"
"go-common/app/interface/main/mcn/model"
"go-common/app/interface/main/mcn/model/mcnmodel"
accgrpc "go-common/app/service/main/account/api"
memgrpc "go-common/app/service/main/member/api"
memmdl "go-common/app/service/main/member/model"
"go-common/app/service/main/member/model/block"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/metadata"
"go-common/app/interface/main/mcn/conf"
"go-common/app/interface/main/mcn/dao/mcndao"
"strings"
"github.com/jinzhu/gorm"
)
// getMcnWithState
// if state is nil, state is not checked
func (s *Service) getMcnWithState(c context.Context, mcnmid int64, state ...model.MCNSignState) (mcnSign *mcnmodel.McnSign, err error) {
mcnSign, err = s.mcndao.McnSign(c, mcnmid)
if err != nil {
if err != ecode.NothingFound {
log.Error("error get state, err=%s", err)
}
return
}
if mcnSign == nil {
err = ecode.NothingFound
return
}
var ok = false
if state == nil {
ok = true
} else {
for _, s := range state {
if mcnSign.State == s {
ok = true
break
}
}
}
if !ok {
log.Info("mcnmid=%d, mcn is in %d, should in (%v)", mcnmid, mcnSign.State, state)
err = ecode.MCNNotAllowed
return
}
return
}
func (s *Service) checkPermission(c context.Context, mcnMid, upMid int64, permissions ...adminmodel.AttrBasePermit) (res bool) {
var permLen = len(permissions)
if permLen == 0 {
return
} else if permLen == 1 {
// 基础权限直接放过
if permissions[0] == adminmodel.AttrBasePermitBit {
return true
}
}
mcnSign, err := s.getMcnWithState(c, mcnMid, model.MCNSignStateOnSign)
if err != nil {
log.Error("get mcn fail, mcnmid=%d, err=%v", mcnMid, err)
return
}
permForUp, err := s.mcndao.UpPermission(c, mcnSign.ID, upMid)
if err != nil || permForUp == nil {
log.Error("get up permission fail, signID=%d, upmid=%d, err=%v or up not found", mcnSign.ID, upMid, err)
return
}
// 比较mcn与up的权限
var wantPermission uint32
for _, v := range permissions {
wantPermission = wantPermission | (1 << v)
}
var resultPermission = wantPermission & mcnSign.Permission & permForUp.Permission
if resultPermission != wantPermission {
log.Warn("mcn doesnt have permission, mcn perm=0x%x, up perm=0x%x, want=0x%x, lack=0x%x", mcnSign.Permission, permForUp.Permission, wantPermission, resultPermission^wantPermission)
return
}
res = true
return
}
//McnGetState mcn state
func (s *Service) McnGetState(c context.Context, arg *mcnmodel.GetStateReq) (res *mcnmodel.McnGetStateReply, err error) {
mcnSign, err := s.getMcnWithState(c, arg.McnMid)
if err != nil {
if err != ecode.NothingFound {
log.Error("error get state, err=%s", err)
}
return
}
res = new(mcnmodel.McnGetStateReply)
res.State = int8(mcnSign.State)
if mcnSign.State == model.MCNSignStateOnReject {
res.RejectReason = mcnSign.RejectReason
}
log.Info("mcn_state=%d, mcn_id=%d", res.State, arg.McnMid)
return
}
//McnExist .
func (s *Service) McnExist(c context.Context, arg *mcnmodel.GetStateReq) (res *mcnmodel.McnExistReply, err error) {
res = new(mcnmodel.McnExistReply)
_, err = s.getMcnWithState(c, arg.McnMid)
if err == ecode.NothingFound {
res.Exist = 0
return
} else if err != nil {
log.Error("error get state, err=%s", err)
return
}
res.Exist = 1
return
}
// McnBaseInfo .
func (s *Service) McnBaseInfo(c context.Context, arg *mcnmodel.GetStateReq) (res *mcnmodel.McnBaseInfoReply, err error) {
res = new(mcnmodel.McnBaseInfoReply)
mcnSign, err := s.getMcnWithState(c, arg.McnMid)
if err != nil {
if err != ecode.NothingFound {
log.Error("error get state, err=%s", err)
}
return
}
res.CopyFromMcnInfo(mcnSign)
return
}
//McnApply .
func (s *Service) McnApply(c context.Context, arg *mcnmodel.McnApplyReq) (res *mcnmodel.CommonReply, err error) {
mcnSign, err := s.getMcnWithState(c, arg.McnMid, model.MCNSignStateOnReject, model.MCNSignStateNoApply)
if err != nil {
if err != ecode.NothingFound {
log.Error("error get state, err=%s", err)
}
return
}
var sign mcnmodel.McnSign
if err = s.uniqueChecker.CheckIsUniqe(arg); err != nil {
log.Info("check unique fail, err=%s, arg=%v", err, arg)
return
}
arg.CopyTo(&sign)
sign.ID = mcnSign.ID
sign.State = model.MCNSignStateOnReview
var db = s.mcndao.GetMcnDB()
if err = db.Table(sign.TableName()).Where("id=?", sign.ID).Updates(map[string]interface{}{
"company_name": sign.CompanyName,
"company_license_id": sign.CompanyLicenseID,
"contact_name": sign.ContactName,
"contact_title": sign.ContactTitle,
"contact_idcard": sign.ContactIdcard,
"contact_phone": sign.ContactPhone,
"company_license_link": sign.CompanyLicenseLink,
"contract_link": sign.ContractLink,
"state": sign.State,
}).Error; err != nil {
log.Error("save mcn fail, mcn mid=%d, row id=%d", sign.McnMid, sign.ID)
err = ecode.ServerErr
return
}
s.mcndao.DelCacheMcnSign(c, arg.McnMid)
s.worker.Add(func() {
s.loadMcnUniqueCache()
})
return
}
//McnBindUpApply .
func (s *Service) McnBindUpApply(c context.Context, arg *mcnmodel.McnBindUpApplyReq) (res *mcnmodel.McnBindUpApplyReply, err error) {
if arg.BeginDate > arg.EndDate {
err = ecode.MCNUpBindUpSTimeLtETime
return
}
// 查询mcn状态
mcnSign, err := s.getMcnWithState(c, arg.McnMid, model.MCNSignStateOnSign)
if err != nil {
if err != ecode.NothingFound {
log.Error("error get state, err=%s", err)
}
return
}
// 0.检查是否封禁
var blockArg = memgrpc.MemberMidReq{Mid: arg.UpMid, RemoteIP: metadata.String(c, metadata.RemoteIP)}
var blockInfo, e = global.GetMemGRPC().BlockInfo(c, &blockArg)
if e == nil {
if blockInfo.BlockStatus > int32(block.BlockStatusFalse) {
log.Info("up is blocked, mid=%d, blockstatus=%d", arg.UpMid, blockInfo.BlockStatus)
err = ecode.MCNUpBindUpIsBlocked
return
}
} else {
log.Error("get block info error, err=%s", e)
}
// 1.检查是否是蓝V用户
var (
memberInfo *memgrpc.MemberInfoReply
memberArg = memgrpc.MemberMidReq{Mid: arg.UpMid, RemoteIP: metadata.String(c, metadata.RemoteIP)}
)
if memberInfo, err = global.GetMemGRPC().Member(c, &memberArg); err != nil {
log.Error("get member info error, err=%s", err)
} else {
if memberInfo.OfficialInfo != nil &&
(memberInfo.OfficialInfo.Role == memmdl.OfficialRoleBusiness ||
memberInfo.OfficialInfo.Role == memmdl.OfficialRoleGov ||
memberInfo.OfficialInfo.Role == memmdl.OfficialRoleMedia ||
memberInfo.OfficialInfo.Role == memmdl.OfficialRoleOther) {
err = ecode.MCNUpBindUpIsBlueUser
return
}
}
// 2.查询当前up状态
upList, err := s.mcndao.GetUpBind("up_mid=?", arg.UpMid)
if err != nil {
log.Error("get up bind fail, err=%s", err)
err = ecode.ServerErr
return
}
// 3.可以申请绑定的up主才能绑定
var mcnUp *mcnmodel.McnUp
for _, v := range upList {
if !v.IsBindable() {
log.Info("up is in state(%d), cannot be bind again. id=%d, upmid=%d, signid=%d, mcnSign=%d", v.State, v.ID, v.UpMid, v.SignID, v.McnMid)
err = ecode.MCNUpCannotBind
return
}
if v.IsBeingBindedWithMcn(mcnSign) {
log.Info("up is being binded with mcnSign, state=%d, id=%d, signid=%d, mcnSign=%d, mcn_mid=%d", v.State, v.State, v.ID, v.SignID, v.McnMid)
err = ecode.MCNUpBindUpAlreadyInProgress
return
}
if v.SignID == mcnSign.ID {
mcnUp = v
}
}
if arg.UpType == 1 {
// 站外up主需要满足条件
// 1.粉丝数≤100 或 2. 投稿数2及90天内未投稿 12并列关系满足其一即可申请
baseInfoMap, e := s.mcndao.GetUpBaseInfo("article_count_accumulate, activity, fans_count, mid", []int64{arg.UpMid})
if e == nil {
var upInfo, ok = baseInfoMap[arg.UpMid]
if ok && upInfo != nil {
//upInfo.Activity 1高2中3低4流失
//高=30天内有投稿
//中=31~90天内有投稿
//低=91~180天内有投稿
//流失=180内以上未投稿
if !(upInfo.FansCount <= 100 || (upInfo.ArticleCountAccumulate < 2 && upInfo.Activity > 2)) {
err = ecode.MCNUpOutSiteIsNotQualified
log.Error("outsite cannot bind, up fans count(%d) > 100", upInfo.FansCount)
return
}
} else {
log.Warn("up info is not found in up base info, up=%d", arg.UpMid)
}
}
}
// 站外信息是否OK
if !arg.IsSiteInfoOk() {
err = ecode.MCNUpBindInvalidURL
log.Warn("arg error, up is out site up, but site url is not valid, arg=%v", arg)
return
}
// 只能设置mcn自己有的权限如果要设置其他权限返回错误。
// 只有mcn有的权限才可以申请up主的权限
_, err = mcnShouldContainUpPermission(mcnSign.Permission, arg.GetAttrPermitVal())
if err != nil {
return
}
// 3.绑定Up主如果已有记录则更新记录
bindup, affectedRow, err := s.mcndao.BindUp(mcnUp, mcnSign, arg)
if err != nil {
log.Error("fail to bind up, mcnmid=%d, upmid=%d err=%s", arg.McnMid, arg.UpMid, err)
return
}
res = new(mcnmodel.McnBindUpApplyReply)
res.BindID = bindup.ID
// 4.发送站内信息
if arg.UpMid != arg.McnMid {
var nickname = global.GetName(c, arg.McnMid)
var msg = adminmodel.ArgMsg{
MSGType: adminmodel.McnUpBindAuthApply,
MIDs: []int64{arg.UpMid},
McnName: nickname,
McnMid: arg.McnMid,
CompanyName: mcnSign.CompanyName,
SignUpID: bindup.ID,
}
s.sendMsg(&msg)
}
log.Info("bind up apply success, mcn=%d, upmid=%d, rowaffected=%d", arg.McnMid, arg.UpMid, affectedRow)
return
}
//McnUpConfirm .
func (s *Service) McnUpConfirm(c context.Context, arg *mcnmodel.McnUpConfirmReq) (res *mcnmodel.CommonReply, err error) {
// 1.查询当前up状态
upList, err := s.mcndao.GetUpBind("id=? and up_mid=? and state=?", arg.BindID, arg.UpMid, model.MCNUPStateNoAuthorize)
if err != nil {
log.Error("get up bind fail, err=%s", err)
err = ecode.ServerErr
return
}
// 不存在
if len(upList) == 0 {
log.Info("bind id not found, id=%d", arg.BindID)
err = ecode.MCNNotAllowed
return
}
var upBind = upList[0]
// 查询mcn状态
mcnSign, err := s.getMcnWithState(c, upBind.McnMid, model.MCNSignStateOnSign)
if err != nil {
if err != ecode.MCNStateInvalid {
log.Error("error get state, err=%s", err)
}
return
}
if mcnSign.ID != upBind.SignID {
log.Error("bind id not same with mcn signid, bind id=%d, signid=%d", upBind.ID, upBind.SignID)
err = ecode.MCNUpBindInvalid
return
}
var state = model.MCNUPStateOnRefuse
if arg.Choice {
state = model.MCNUPStateOnReview
}
// 更新状态
err = s.mcndao.UpConfirm(arg, state)
if err != nil {
log.Error("fail to update up bind, bind id=%d, upmid=%d, err=%s", arg.BindID, arg.UpMid, err)
err = ecode.ServerErr
return
}
// 同意
if arg.Choice {
var mcnName = global.GetName(c, mcnSign.McnMid)
var msg = adminmodel.ArgMsg{
MSGType: adminmodel.McnUpBindAuthReview,
MIDs: []int64{arg.UpMid},
McnName: mcnName,
McnMid: mcnSign.McnMid,
CompanyName: mcnSign.CompanyName,
}
s.sendMsg(&msg)
} else {
var upName = global.GetName(c, arg.UpMid)
var msg = adminmodel.ArgMsg{
MSGType: adminmodel.McnUpBindAuthApplyRefuse,
MIDs: []int64{mcnSign.McnMid},
UpMid: arg.UpMid,
UpName: upName,
}
s.sendMsg(&msg)
}
log.Info("up bind change, bind id=%d, upmid=%d, isaccept=%t", arg.BindID, arg.UpMid, arg.Choice)
return
}
//McnUpGetBind .
func (s *Service) McnUpGetBind(c context.Context, arg *mcnmodel.McnUpGetBindReq) (res *mcnmodel.McnGetBindReply, err error) {
res, err = s.mcndao.GetBindInfo(arg)
if err != nil {
log.Error("fail to get bind info, err=%s", err)
return
}
accInfo, err := global.GetInfo(c, int64(res.McnMid))
if err == nil && accInfo != nil {
res.McnName = accInfo.Name
}
res.Finish()
res.UpAuthLink = model.BuildBfsURL(res.UpAuthLink, s.c.BFS.Key, s.c.BFS.Secret, s.c.BFS.Bucket, model.BfsEasyPath)
return
}
//McnDataSummary .
func (s *Service) McnDataSummary(c context.Context, arg *mcnmodel.McnGetDataSummaryReq) (res *mcnmodel.McnGetDataSummaryReply, err error) {
mcnSign, err := s.getMcnWithState(c, arg.McnMid, model.MCNSignStateOnSign)
if err != nil {
if err != ecode.NothingFound {
log.Error("error get state, err=%s", err)
}
return
}
var today = time.Now().Add(-12 * time.Hour)
res, err = s.datadao.GetMcnSummaryCache(c, mcnSign.ID, today)
if err != nil {
log.Error("fail to get mcn data, sign id=%d, mcnmid=%d, err=%s", mcnSign.ID, mcnSign.McnMid, err)
return
}
// today is not found, try yesterday
if res == nil {
res, err = s.mcndao.McnDataSummary(c, mcnSign.ID, today.AddDate(0, 0, -1))
if err != nil {
log.Error("fail to get mcn data, sign id=%d, mcnmid=%d, err=%s", mcnSign.ID, mcnSign.McnMid, err)
return
}
}
if res == nil {
log.Error("fail to get mcn data, res = nil, sign id=%d", mcnSign.ID)
res = new(mcnmodel.McnGetDataSummaryReply)
}
return
}
//McnDataUpList .
func (s *Service) McnDataUpList(c context.Context, arg *mcnmodel.McnGetUpListReq) (res *mcnmodel.McnGetUpListReply, err error) {
mcnSign, err := s.getMcnWithState(c, arg.McnMid, model.MCNSignStateOnSign)
if err != nil {
if err != ecode.NothingFound {
log.Error("error get state, err=%s", err)
}
return
}
generateDate, err := s.mcndao.GetDataUpLatestDate(mcnmodel.DataTypeAccumulate, mcnSign.ID)
if err != nil {
if err == gorm.ErrRecordNotFound {
err = nil
log.Warn("no data list found for mcn=%d, sign id=%d", mcnSign.McnMid, mcnSign.ID)
var now = time.Now()
generateDate = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local)
} else {
log.Error("fail to get latest generate up date, err=%s", err)
return
}
}
// 获取数据
upData, err := s.mcndao.GetAllUpData(int64(mcnSign.ID), arg.UpMid, generateDate)
// 在正式数据出来之前,临时使用
//upData, err := s.mcndao.GetAllUpDataTemp(int64(mcnSign.ID), arg.UpMid, time.Now())
var mids []int64
for _, v := range upData {
mids = append(mids, v.UpMid)
v.Permission = v.Permission & mcnSign.Permission
}
var infosReply *accgrpc.InfosReply
var midtidmap map[int64]int64
var accInfos map[int64]*accgrpc.Info
if len(mids) > 0 {
var e error
infosReply, e = global.GetAccGRPC().Infos3(c, &accgrpc.MidsReq{Mids: mids})
if e != nil {
log.Warn("fail to get info, err=%s", e)
} else {
accInfos = infosReply.Infos
}
midtidmap, e = s.mcndao.GetActiveTid(mids)
if e != nil {
log.Warn("fail to get activit, err=%s", e)
}
}
res = new(mcnmodel.McnGetUpListReply)
for _, v := range upData {
var info, ok = accInfos[v.UpMid]
if ok {
v.Name = info.Name
}
if v.State != int8(model.MCNUPStateOnSign) {
// MCNUPStateOnSign 与 MCNUPStateOnPreOpen 状态下 不隐藏时间
v.HideData(!(v.State == int8(model.MCNUPStateOnSign) ||
v.State == int8(model.MCNUPStateOnPreOpen)))
}
tid, ok := midtidmap[v.UpMid]
if ok {
v.TidName = cache.GetTidName(tid)
v.ActiveTid = int16(tid)
}
res.Result = append(res.Result, v)
}
res.Finish()
return
}
//McnGetOldInfo .
func (s *Service) McnGetOldInfo(c context.Context, arg *mcnmodel.McnGetMcnOldInfoReq) (res *mcnmodel.McnGetMcnOldInfoReply, err error) {
mcnSign, err := s.getMcnWithState(c, arg.McnMid, model.MCNSignStateNoApply)
if err != nil {
if err != ecode.NothingFound {
log.Error("error get state, err=%s", err)
}
return
}
info, err := s.mcndao.GetMcnOldInfo(mcnSign.McnMid)
if err != nil {
if err == ecode.NothingFound {
err = nil
} else {
log.Error("fail get mcn old info err=%s", err)
return
}
}
res = new(mcnmodel.McnGetMcnOldInfoReply)
res.Copy(info)
return
}
func getUpPermitString(permission uint32) (ps []string) {
for permit := range adminmodel.PermitMap {
var p = adminmodel.AttrVal(permission, uint(permit))
if p <= 0 {
continue
}
ps = append(ps, permit.String())
}
return
}
// 检查up主权限是否是mcn的子集
// mcnPermission mcn自己的permission
// upPermission up的permission
// return finalPermission = mcnPermission &upPermission
func mcnShouldContainUpPermission(mcnPermission, upPermission uint32) (finalPermission uint32, err error) {
// 3.只能设置mcn自己有的权限如果要设置其他权限返回错误。
// 只有mcn有的权限才可以申请up主的权限
finalPermission = mcnPermission & upPermission
if finalPermission != upPermission {
log.Error("mcn has no permission to change, mcn=0x%x, wantup=0x%x, notallowd=0x%x", mcnPermission, upPermission, finalPermission^upPermission)
err = ecode.MCNChangePermissionLackPermission
return
}
return
}
//McnChangePermit change up's permission
func (s *Service) McnChangePermit(c context.Context, arg *mcnmodel.McnChangePermitReq) (res *mcnmodel.McnChangePermitReply, err error) {
mcnSign, err := s.getMcnWithState(c, arg.McnMid, model.MCNSignStateOnSign)
if err != nil {
if err != ecode.NothingFound {
log.Error("error get state, err=%s", err)
}
return
}
// 1.检查Up主关系只有“已签约”,“待开启”状态的Up主可以修改
// 2.查询当前up状态
upList, err := s.mcndao.GetUpBind("up_mid=? and sign_id=? and state in (?)", arg.UpMid, mcnSign.ID, mcndao.UpSignedStates)
if err != nil {
log.Error("get up bind fail, err=%v", err)
err = ecode.ServerErr
return
}
if len(upList) == 0 {
log.Error("up is not in signed state with mcn, up_mid=%d and sign_id=%d , need state in (%v)", arg.UpMid, mcnSign.ID, mcndao.UpSignedStates)
err = ecode.MCNUpSignStateInvalid
return
}
var oldUp = upList[0]
var newPermission = arg.GetAttrPermitVal()
if oldUp.Permission == uint32(newPermission) {
log.Error("permission not changed, arg=%+v", arg)
err = ecode.MCNChangePermissionSamePermission
return
}
// 2.只能设置mcn自己有的权限如果要设置其他权限返回错误。
// 只有mcn有的权限才可以申请up主的权限
maskedPermission, err := mcnShouldContainUpPermission(mcnSign.Permission, newPermission)
if err != nil {
return
}
// 如果是自己,则直接进行修改
if arg.UpMid == mcnSign.McnMid {
var _, e = s.mcndao.UpdateBindUp(map[string]interface{}{
"permission": maskedPermission,
}, "up_mid=? and sign_id=?", arg.UpMid, mcnSign.ID)
if e != nil {
err = e
log.Error("fail to change up permission, err=%v, arg=%v", err, arg)
return
}
return
}
// 3.检查是否有对应up主的修改请求,如果有就拒绝这次修改
existedApply, _ := s.mcndao.GetUpPermissionApply("id", "sign_id=? and up_mid=? and state in (?)", mcnSign.ID, arg.UpMid, mcndao.UpPermissionApplyCannotApplyStates)
if len(existedApply) > 0 {
log.Error("apply already exist, id=%d, sign id=%d, mid=%d", existedApply[0].ID, existedApply[0].SignID, existedApply[0].UpMid)
err = ecode.MCNChangePermissionAlreadyInProgress
return
}
// 真的去增加permission
var permissionApply = mcnmodel.McnUpPermissionApply{
SignID: mcnSign.ID,
McnMid: mcnSign.McnMid,
UpMid: arg.UpMid,
NewPermission: maskedPermission,
OldPermission: oldUp.Permission,
UpAuthLink: arg.UpAuthLink,
}
var db = s.mcndao.GetMcnDB()
err = db.Create(&permissionApply).Error
if err != nil {
log.Error("create permission apply fail, err=%v, arg=%+v", err, arg)
return
}
// 返回bind_id
res = &mcnmodel.McnChangePermitReply{BindID: permissionApply.ID}
// 4.发送站内信息
if arg.UpMid != arg.McnMid {
var nickname = global.GetName(c, arg.McnMid)
var msg = adminmodel.ArgMsg{
MSGType: adminmodel.McnApplyUpChangePermit,
MIDs: []int64{arg.UpMid},
McnName: nickname,
McnMid: arg.McnMid,
CompanyName: mcnSign.CompanyName,
SignUpID: permissionApply.ID,
Permission: strings.Join(getUpPermitString(maskedPermission), "、"),
}
s.sendMsg(&msg)
}
return
}
//McnPermitApplyGetBind get permit apply bind
func (s *Service) McnPermitApplyGetBind(c context.Context, arg *mcnmodel.McnUpGetBindReq) (res *mcnmodel.McnGetBindReply, err error) {
res, err = s.mcndao.GetUpPermissionBindInfo(arg)
if err != nil {
log.Error("fail to get bind info, err=%s", err)
return
}
accInfo, err := global.GetInfo(c, int64(res.McnMid))
if err == nil && accInfo != nil {
res.McnName = accInfo.Name
}
res.Finish()
res.UpAuthLink = model.BuildBfsURL(res.UpAuthLink, s.c.BFS.Key, s.c.BFS.Secret, s.c.BFS.Bucket, model.BfsEasyPath)
return
}
//McnUpPermitApplyConfirm permit apply confirm
func (s *Service) McnUpPermitApplyConfirm(c context.Context, arg *mcnmodel.McnUpConfirmReq) (res *mcnmodel.CommonReply, err error) {
// 1.查询当前up状态
upList, err := s.mcndao.GetUpPermissionApply("*", "id=? and up_mid=? and state=?", arg.BindID, arg.UpMid, adminmodel.MCNUPPermissionStateNoAuthorize)
if err != nil {
log.Error("get up bind fail, err=%s", err)
err = ecode.ServerErr
return
}
// 不存在
if len(upList) == 0 {
log.Info("bind id not found, id=%d", arg.BindID)
err = ecode.MCNNotAllowed
return
}
var upBind = upList[0]
// 查询mcn状态
mcnSign, err := s.getMcnWithState(c, upBind.McnMid, model.MCNSignStateOnSign)
if err != nil {
if err != ecode.MCNStateInvalid {
log.Error("error get state, err=%s", err)
}
return
}
if mcnSign.ID != upBind.SignID {
log.Error("bind id not same with mcn signid, bind id=%d, signid=%d", upBind.ID, upBind.SignID)
err = ecode.MCNUpBindInvalid
return
}
var state = adminmodel.MCNUPPermissionStateOnRefuse
if arg.Choice {
state = adminmodel.MCNUPPermissionStateReview
}
// 更新状态
err = s.mcndao.UpPermissionConfirm(arg, state)
if err != nil {
log.Error("fail to update up bind, bind id=%d, upmid=%d, err=%s", arg.BindID, arg.UpMid, err)
err = ecode.ServerErr
return
}
// 同意
if arg.Choice {
// do nothing.
} else {
var upName = global.GetName(c, arg.UpMid)
var msg = adminmodel.ArgMsg{
MSGType: adminmodel.McnUpNotAgreeChangePermit,
MIDs: []int64{mcnSign.McnMid},
UpMid: arg.UpMid,
UpName: upName,
}
s.sendMsg(&msg)
}
log.Info("up permission bind change, bind id=%d, upmid=%d, isaccept=%t", arg.BindID, arg.UpMid, arg.Choice)
return
}
//McnPublicationPriceChange .
func (s *Service) McnPublicationPriceChange(c context.Context, arg *mcnmodel.McnPublicationPriceChangeReq) (res *mcnmodel.McnPublicationPriceChangeReply, err error) {
mcnSign, err := s.getMcnWithState(c, arg.McnMid, model.MCNSignStateOnSign)
if err != nil {
if err != ecode.NothingFound {
log.Error("error get state, err=%s", err)
}
return
}
// 1.检查上次刊例价修改时间,如果时间内不能修改返回错误
publicationPriceCache, e := s.mcndao.CachePublicationPrice(c, mcnSign.ID, arg.UpMid)
if e != nil {
log.Warn("get modify time from cache fail, arg=%+v, err=%v", arg, err)
}
if publicationPriceCache == nil {
// 初始化为0值
publicationPriceCache = &mcnmodel.PublicationPriceCache{}
}
var lastModifyTime = publicationPriceCache.ModifyTime // 从缓存中获取
var now = time.Now()
if now.Before(lastModifyTime.Add(time.Duration(conf.Conf.Other.PublicationPriceChangeLimit))) {
log.Error("publication change fail, last modify time=%s, timelimit=%+v, arg=%+v", lastModifyTime, conf.Conf.Other.PublicationPriceChangeLimit, arg)
err = ecode.MCNPublicationFailTimeLimit
return
}
// 2.检查Up主关系只有“已签约”,“待开启”状态的Up主可以修改
upList, err := s.mcndao.GetUpBind("up_mid=? and sign_id=? and state in (?)", arg.UpMid, mcnSign.ID, mcndao.UpSignedStates)
if err != nil {
log.Error("get up bind fail, err=%v", err)
err = ecode.ServerErr
return
}
if len(upList) == 0 {
log.Error("up is not in signed state with mcn, up_mid=%d and sign_id=%d , need state in (%v)", arg.UpMid, mcnSign.ID, mcndao.UpSignedStates)
err = ecode.MCNUpSignStateInvalid
return
}
var up = upList[0]
// 3.修改刊例价,更新上次修改时间
var db = s.mcndao.GetMcnDB()
err = db.Table(mcnmodel.TableNameMcnUp).Where("id=?", up.ID).Update("publication_price", arg.Price).Error
if err != nil {
log.Error("change publication price fail, err=%v, arg=%+v", err, arg)
return
}
publicationPriceCache.ModifyTime = now
e = s.mcndao.AddCachePublicationPrice(c, mcnSign.ID, publicationPriceCache, arg.UpMid)
if e != nil {
log.Warn("fail to add cache, arg=%+v, err=%v", arg, e)
}
return
}

View File

@@ -0,0 +1,189 @@
package service
import (
"context"
"testing"
adminmodel "go-common/app/admin/main/mcn/model"
"go-common/app/interface/main/mcn/model"
"go-common/app/interface/main/mcn/model/mcnmodel"
"github.com/smartystreets/goconvey/convey"
)
func TestServicegetMcnWithState(t *testing.T) {
convey.Convey("getMcnWithState", t, func(ctx convey.C) {
var (
c = context.Background()
mcnmid = int64(0)
state = model.MCNSignState(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
mcnSign, err := s.getMcnWithState(c, mcnmid, state)
ctx.Convey("Then err should be nil.mcnSign should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(mcnSign, convey.ShouldNotBeNil)
})
})
})
}
func TestServiceMcnGetState(t *testing.T) {
convey.Convey("McnGetState", t, func(ctx convey.C) {
var (
c = context.Background()
arg = &mcnmodel.GetStateReq{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := s.McnGetState(c, arg)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestServiceMcnExist(t *testing.T) {
convey.Convey("McnExist", t, func(ctx convey.C) {
var (
c = context.Background()
arg = &mcnmodel.GetStateReq{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := s.McnExist(c, arg)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestServiceMcnApply(t *testing.T) {
convey.Convey("McnApply", t, func(ctx convey.C) {
var (
c = context.Background()
arg = &mcnmodel.McnApplyReq{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := s.McnApply(c, arg)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestServiceMcnBindUpApply(t *testing.T) {
convey.Convey("McnBindUpApply", t, func(ctx convey.C) {
var (
c = context.Background()
arg = &mcnmodel.McnBindUpApplyReq{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := s.McnBindUpApply(c, arg)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestServiceMcnUpConfirm(t *testing.T) {
convey.Convey("McnUpConfirm", t, func(ctx convey.C) {
var (
c = context.Background()
arg = &mcnmodel.McnUpConfirmReq{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := s.McnUpConfirm(c, arg)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestServiceMcnUpGetBind(t *testing.T) {
convey.Convey("McnUpGetBind", t, func(ctx convey.C) {
var (
c = context.Background()
arg = &mcnmodel.McnUpGetBindReq{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := s.McnUpGetBind(c, arg)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestServiceMcnDataSummary(t *testing.T) {
convey.Convey("McnDataSummary", t, func(ctx convey.C) {
var (
c = context.Background()
arg = &mcnmodel.McnGetDataSummaryReq{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := s.McnDataSummary(c, arg)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestServiceMcnDataUpList(t *testing.T) {
convey.Convey("McnDataUpList", t, func(ctx convey.C) {
var (
c = context.Background()
arg = &mcnmodel.McnGetUpListReq{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := s.McnDataUpList(c, arg)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestServiceMcnGetOldInfo(t *testing.T) {
convey.Convey("McnGetOldInfo", t, func(ctx convey.C) {
var (
c = context.Background()
arg = &mcnmodel.McnGetMcnOldInfoReq{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := s.McnGetOldInfo(c, arg)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestCheckPermission(t *testing.T) {
convey.Convey("checkPermission", t, func(ctx convey.C) {
var (
c = context.Background()
mcnMid, upMid int64 = 15555180, 27515410
permissions = []adminmodel.AttrBasePermit{adminmodel.AttrBasePermitBit, adminmodel.AttrDataPermitBit}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res := s.checkPermission(c, mcnMid, upMid, permissions...)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(res, convey.ShouldBeTrue)
})
})
})
}

View File

@@ -0,0 +1,30 @@
package service
import (
"context"
"go-common/app/admin/main/mcn/model"
"go-common/library/log"
)
// sendMsg send msg
func (s *Service) sendMsg(arg *model.ArgMsg) {
s.worker.Add(func() {
var err error
mids, title, content, code := arg.MsgInfo(s.msgMap[arg.MSGType])
if len(mids) == 0 || title == "" || content == "" || code == "" {
log.Warn("mid(%+v) title(%s) content(%s) code(%s) sth is empty!", mids, title, content, code)
return
}
if err = s.msg.MutliSendSysMsg(context.Background(), mids, code, title, content, ""); err != nil {
log.Error("s.msg.MutliSendSysMsg(%+v,%s,%s,%s,%s) error(%+v)", mids, code, title, content, "", err)
}
})
}
func (s *Service) setMsgTypeMap() {
s.msgMap = make(map[model.MSGType]*model.MSG, len(s.c.Property.MSG))
for _, msg := range s.c.Property.MSG {
s.msgMap[msg.MSGType] = msg
}
}

View File

@@ -0,0 +1,32 @@
package service
import (
"testing"
"go-common/app/admin/main/mcn/model"
"github.com/smartystreets/goconvey/convey"
)
func TestServicesendMsg(t *testing.T) {
convey.Convey("sendMsg", t, func(ctx convey.C) {
var (
arg = &model.ArgMsg{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
s.sendMsg(arg)
ctx.Convey("No return values", func(ctx convey.C) {
})
})
})
}
func TestServicesetMsgTypeMap(t *testing.T) {
convey.Convey("setMsgTypeMap", t, func(ctx convey.C) {
ctx.Convey("When everything goes positive", func(ctx convey.C) {
s.setMsgTypeMap()
ctx.Convey("No return values", func(ctx convey.C) {
})
})
})
}

View File

@@ -0,0 +1,155 @@
package service
import (
"context"
"sort"
"go-common/app/interface/main/mcn/dao/mcndao"
"go-common/app/interface/main/mcn/model"
"go-common/app/interface/main/mcn/model/mcnmodel"
"go-common/library/ecode"
"go-common/library/log"
)
const (
//SortFieldFans by fans
SortFieldFans = "fans_count"
//SortFieldMonthFans by month increase
SortFieldMonthFans = "fans_count_increase_month"
//SortFieldArchiveCount by archive count
SortFieldArchiveCount = "archive_count"
)
var (
sortFieldMap = map[string]mcndao.RecommendSortFunc{
SortFieldFans: mcndao.RecommendSortByFansDesc,
SortFieldMonthFans: mcndao.RecommendSortByMonthFansDesc,
SortFieldArchiveCount: mcndao.RecommendSortByArchiveCountDesc,
}
)
//McnGetRankUpFans get up rank fans
func (s *Service) McnGetRankUpFans(c context.Context, arg *mcnmodel.McnGetRankReq) (res *mcnmodel.McnGetRankUpFansReply, err error) {
res, err = s.getRankResult(c, arg, s.mcndao.GetRankUpFans)
return
}
//McnGetRankArchiveLikes get rank archive likes
func (s *Service) McnGetRankArchiveLikes(c context.Context, arg *mcnmodel.McnGetRankReq) (res *mcnmodel.McnGetRankUpFansReply, err error) {
res, err = s.getRankResult(c, arg, s.mcndao.GetRankArchiveLikes)
return
}
func (s *Service) getRankResult(c context.Context, arg *mcnmodel.McnGetRankReq, rankFunc mcndao.RankFunc) (res *mcnmodel.McnGetRankUpFansReply, err error) {
mcnSign, err := s.getMcnWithState(c, arg.McnMid, model.MCNSignStateOnSign)
if err != nil {
if err != ecode.NothingFound {
log.Error("error get state, err=%s", err)
}
return
}
v, err := rankFunc(mcnSign.ID)
if err != nil || v == nil {
log.Error("get rank fail, sign id=%d, err=%s", mcnSign.ID, err)
return
}
res = new(mcnmodel.McnGetRankUpFansReply)
res.Result = v.GetList(arg.Tid, arg.DataType)
res.TypeList = v.GetTypeList(arg.DataType)
return
}
//GetRecommendPool get recommend pool reply
func (s *Service) GetRecommendPool(c context.Context, arg *mcnmodel.McnGetRecommendPoolReq) (res *mcnmodel.McnGetRecommendPoolReply, err error) {
mcnSign, err := s.getMcnWithState(c, arg.McnMid, model.MCNSignStateOnSign)
if err != nil {
if err != ecode.NothingFound {
log.Error("error get state, err=%s", err)
}
return
}
var limit, offset = arg.CheckPageValidation()
recommendCache, err := s.mcndao.GetRecommendPool()
if err != nil {
log.Error("get recommend pool fail, err=%s, mcn=%d", err, mcnSign.McnMid)
return
}
if recommendCache == nil {
log.Warn("recommend cache is nil, mcn=%d", mcnSign.McnMid)
res.PageResult = arg.ToPageResult(0)
return
}
res = new(mcnmodel.McnGetRecommendPoolReply)
var upList = recommendCache.UpTidMap[arg.Tid]
var listLen = len(upList)
if offset >= listLen {
return
}
res.PageResult = arg.ToPageResult(listLen)
if upList == nil {
return
}
var end = limit + offset
if end >= listLen {
end = listLen
}
var sortFunc mcndao.RecommendSortFunc
switch arg.OrderField {
case SortFieldMonthFans, SortFieldArchiveCount:
sortFunc = sortFieldMap[arg.OrderField]
}
if sortFunc != nil {
sort.Sort(&mcndao.RecommendDataSorter{Datas: upList, By: sortFunc})
}
var dest = make([]*mcnmodel.McnGetRecommendPoolInfo, listLen)
// 如果是升序,那么把他们倒过来
if arg.Sort == "asc" {
copy(dest, upList)
for left, right := 0, len(dest)-1; left < right; left, right = left+1, right-1 {
dest[left], dest[right] = dest[right], dest[left]
}
} else {
dest = upList
}
log.Info("offset, limit=%d,%d", offset, limit)
dest = dest[offset:end]
res.Result = dest
return
}
//GetRecommendPoolTidList get tid list
func (s *Service) GetRecommendPoolTidList(c context.Context, arg *mcnmodel.McnGetRecommendPoolTidListReq) (res *mcnmodel.McnGetRecommendPoolTidListReply, err error) {
mcnSign, err := s.getMcnWithState(c, arg.McnMid, model.MCNSignStateOnSign)
if err != nil {
if err != ecode.NothingFound {
log.Error("error get state, err=%s", err)
}
return
}
recommendCache, err := s.mcndao.GetRecommendPool()
if err != nil {
log.Error("get recommend pool fail, err=%s, mcn=%d", err, mcnSign.McnMid)
return
}
if recommendCache == nil {
log.Warn("recommend cache is nil, mcn=%d", mcnSign.McnMid)
return
}
res = new(mcnmodel.McnGetRecommendPoolTidListReply)
res.Result = recommendCache.TidTypeList
return
}

View File

@@ -0,0 +1,42 @@
package service
import (
"context"
"testing"
"go-common/app/interface/main/mcn/model/mcnmodel"
"github.com/smartystreets/goconvey/convey"
)
func TestServiceMcnGetRankUpFans(t *testing.T) {
convey.Convey("McnGetRankUpFans", t, func(ctx convey.C) {
var (
c = context.Background()
arg = &mcnmodel.McnGetRankReq{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := s.McnGetRankUpFans(c, arg)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestServiceMcnGetRankArchiveLikes(t *testing.T) {
convey.Convey("McnGetRankArchiveLikes", t, func(ctx convey.C) {
var (
c = context.Background()
arg = &mcnmodel.McnGetRankReq{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := s.McnGetRankArchiveLikes(c, arg)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,77 @@
package service
import (
"context"
"time"
"go-common/app/admin/main/mcn/model"
"go-common/app/interface/main/mcn/conf"
"go-common/app/interface/main/mcn/dao/bfs"
"go-common/app/interface/main/mcn/dao/cache"
"go-common/app/interface/main/mcn/dao/global"
"go-common/app/interface/main/mcn/dao/mcndao"
"go-common/app/interface/main/mcn/dao/msg"
"go-common/app/interface/main/mcn/tool/worker"
"go-common/app/interface/main/mcn/dao/datadao"
"github.com/bluele/gcache"
)
// Service struct
type Service struct {
c *conf.Config
mcndao *mcndao.Dao
bfsdao *bfs.Dao
notifych chan func()
msg *msg.Dao
msgMap map[model.MSGType]*model.MSG
worker *worker.Pool
uniqueChecker *UniqueCheck
datadao *datadao.Dao
}
// New init
func New(c *conf.Config) (s *Service) {
var localcache = gcache.New(c.RankCache.Size).Simple().Build()
global.Init(c)
s = &Service{
c: c,
mcndao: mcndao.New(c, localcache),
bfsdao: bfs.New(c),
notifych: make(chan func(), 10240),
msg: msg.New(c),
worker: worker.New(nil),
uniqueChecker: NewUniqueCheck(),
datadao: datadao.New(c),
}
s.datadao.Client.Debug = true
s.refreshCache()
s.setMsgTypeMap()
go s.cacheproc()
return s
}
// Ping Service
func (s *Service) Ping(c context.Context) (err error) {
return nil
}
// Close Service
func (s *Service) Close() {
s.worker.Close()
s.worker.Wait()
s.mcndao.Close()
}
func (s *Service) refreshCache() {
cache.LoadCache()
s.loadMcnUniqueCache()
}
func (s *Service) cacheproc() {
for {
time.Sleep(5 * time.Minute)
s.refreshCache()
}
}

View File

@@ -0,0 +1,24 @@
package service
import (
"flag"
"os"
"testing"
"go-common/app/interface/main/mcn/conf"
)
var (
s *Service
)
func TestMain(m *testing.M) {
flag.Set("conf", "../cmd/mcn-interface.toml")
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
s = New(conf.Conf)
m.Run()
os.Exit(m.Run())
}

View File

@@ -0,0 +1,100 @@
package service
import (
"sync"
"go-common/app/interface/main/mcn/model/mcnmodel"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/time"
)
var (
lastLoadMcnUniqueTime time.Time
)
//UniqueCheck check unique
type UniqueCheck struct {
// all the values is mcn id
PhoneMap map[string]int64
IDCardMap map[string]int64
CompanyNameMap map[string]int64
CompanyLicenseIDMap map[string]int64
lock sync.Mutex
}
//NewUniqueCheck new checker
func NewUniqueCheck() *UniqueCheck {
return &UniqueCheck{
PhoneMap: make(map[string]int64),
IDCardMap: make(map[string]int64),
CompanyNameMap: make(map[string]int64),
CompanyLicenseIDMap: make(map[string]int64),
}
}
//CheckIsUniqe check is unique
func (u *UniqueCheck) CheckIsUniqe(req *mcnmodel.McnApplyReq) (err error) {
if req == nil {
return
}
u.lock.Lock()
defer u.lock.Unlock()
if v, ok := u.PhoneMap[req.ContactPhone]; ok {
if req.McnMid != v {
err = ecode.MCNUpBindUpDuplicatePhone
return
}
}
if v, ok := u.IDCardMap[req.ContactIdcard]; ok {
if req.McnMid != v {
err = ecode.MCNUpBindUpDuplicateIDCard
return
}
}
if v, ok := u.CompanyNameMap[req.CompanyName]; ok {
if req.McnMid != v {
err = ecode.MCNUpBindUpDuplicateCompanyName
return
}
}
if v, ok := u.CompanyLicenseIDMap[req.CompanyLicenseID]; ok {
if req.McnMid != v {
err = ecode.MCNUpBindUpDuplicateCompanyLicenseID
return
}
}
return
}
//AddItem add item from db
func (u *UniqueCheck) AddItem(sign *mcnmodel.McnSign) {
u.lock.Lock()
defer u.lock.Unlock()
u.PhoneMap[sign.ContactPhone] = sign.McnMid
u.IDCardMap[sign.ContactIdcard] = sign.McnMid
u.CompanyNameMap[sign.CompanyName] = sign.McnMid
u.CompanyLicenseIDMap[sign.CompanyLicenseID] = sign.McnMid
}
func (s *Service) loadMcnUniqueCache() {
var list []*mcnmodel.McnSign
var err = s.mcndao.GetMcnDB().
Select("mcn_mid, company_name, company_license_id, contact_idcard, contact_phone, mtime").
Where("mtime>?", lastLoadMcnUniqueTime).
Find(&list).Error
if err != nil {
log.Warn("cannot get unique, err=%s", err)
return
}
for _, v := range list {
s.uniqueChecker.AddItem(v)
if lastLoadMcnUniqueTime < v.Mtime {
lastLoadMcnUniqueTime = v.Mtime
}
}
}

View File

@@ -0,0 +1,28 @@
package service
import (
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestServiceNewUniqueCheck(t *testing.T) {
convey.Convey("NewUniqueCheck", t, func(ctx convey.C) {
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := NewUniqueCheck()
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestServiceloadMcnUniqueCache(t *testing.T) {
convey.Convey("loadMcnUniqueCache", t, func(ctx convey.C) {
ctx.Convey("When everything goes positive", func(ctx convey.C) {
s.loadMcnUniqueCache()
ctx.Convey("No return values", func(ctx convey.C) {
})
})
})
}

View File

@@ -0,0 +1,11 @@
package service
import (
"context"
"io"
)
// Upload http upload file.
func (s *Service) Upload(c context.Context, fileName, fileType string, expire int64, body io.Reader) (location string, err error) {
return s.bfsdao.Upload(c, fileName, fileType, expire, body)
}

View File

@@ -0,0 +1,28 @@
package service
import (
"context"
"io"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestServiceUpload(t *testing.T) {
convey.Convey("Upload", t, func(ctx convey.C) {
var (
c = context.Background()
fileName = ""
fileType = ""
expire = int64(0)
body io.Reader
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
location, err := s.Upload(c, fileName, fileType, expire, body)
ctx.Convey("Then err should be nil.location should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(location, convey.ShouldNotBeNil)
})
})
})
}