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,24 @@
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/service/main/assist/cmd:all-srcs",
"//app/service/main/assist/conf:all-srcs",
"//app/service/main/assist/dao/account:all-srcs",
"//app/service/main/assist/dao/assist:all-srcs",
"//app/service/main/assist/dao/message:all-srcs",
"//app/service/main/assist/http:all-srcs",
"//app/service/main/assist/model:all-srcs",
"//app/service/main/assist/rpc:all-srcs",
"//app/service/main/assist/service:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,127 @@
### 协管服务 (assist-service)
#### 2.0.23
>1.update account api from gorpc to grpc
#### 2.0.22
>1.完善dao层的单元测试
#### 2.0.21
>1.升级中间件值verify和bm
#### 2.0.20
>1.fix bug校验协管个数的时候以Up主的mid为主业务查询
#### 2.0.19
>1.fix bug: syncChannel异步任务超时重新设置,添加缓存清理的日志
#### 2.0.18
>1.merge master 分支since 20180530
#### 2.0.17
>1.更新mc的生成算法前面添加前缀:"assist_relation_mid_"
#### 2.0.16
>1.fix bug: baldemaster默认返回json格式字符串不返回空字符
#### 2.0.15
>1.升级http组件到baldemaster
#### 2.0.14
> 1. 增加register
#### 2.0.13
> 1. 来自space空间产品线的要求: 返回当前被委任为协管的up主列表的时候添加当前up主的vip信息
#### 2.0.12
> 1. 按照服务树的规则将代码目录迁移到service/main下
#### 2.0.11
> 1. protect assist ups cards3 rpc call
#### 2.0.10
> 1. 修改account-service v7
#### 2.0.9
> 1. v2.0.8 => v2.0.9
#### 2.0.8
> 1.去掉无用代码其实Profile2的RPC接口并没有调用也不需要添加
#### 2.0.7
> 1.添加对HttpClient增加key,secret的支持
#### 2.0.6
> 1.business enhancement: 协管服务更新大仓库版本并添加对dapper tracer的支持
#### 2.0.5
> 1.Fix Bug: 取消Sleep 2秒, 会造成连续的延迟消费
#### 2.0.4
> 1.增加关系链的判断逻辑action为update,并且是两个case
> 2.调整fid和mid的顺序fid永远是之前被关注的那个人mid是去关注他人的人
> 3.不关注表取mod的分配表名只关注单向的关系链状态流转
#### 2.0.3
> 1.添加Relation-T Topic消费数据的日志记录
> 2.fix databus sub的bug, 不能直接return
#### 2.0.2
> 1.给空间的 rpc Ups提供官方认证的信息
#### 2.0.1
> 1.rpc server开启Handshake, 支持rpc token
#### 2.0.0
> 1.支持直播的房管功能
> 2.为[空间]提供允许用户主动退出骑士团的HTTP接口/x/internal/assist/exist包括给space空间的rpc接口
> 3.监听DataBus Topic:Relation-T, 在Up主动移除粉丝的同时监听消息异步地接触其对应的骑士团资格
> 4.已经被封禁的协管账号不允许被添加为骑士团
> 5.同理4如果之前是骑士之后账号被封禁那么也不允许进行后续对应的业务操作
> 6.添加协管Model里面支持直播操作的常量type=3; action=8/9
> 7.完善添加协管和增加日志时候的限制规则,如下:
a: 单个协管关系操作同一类型的日志业务每天不得超过100次
b: 协管最多不超过10个
c: 每天单个MID任命上限为100次另外需要给Up主发系统通知 不能超过100次/天
d: 每日任命同一用户不超过2次
> 8.添加接口:按照mid(UP主mid)和assmids(批量协管)返回日志计数信息
> 9.添加接口:获取当前用户是哪个up主的协管的mid集合按照创建时间倒叙排, 添加key为assUps_的Rds缓存加速查询并减轻数据库的查询压力,包括给space空间的rpc接口
#### 1.1.0
> 1.启用新的统一的手机验证实名制限制策略
> 2.更新govendor包 go-business和go-common
> 3.添加任命和卸载协管的时候,发【站内消息-系统通知】的内容
#### 1.0.8
> 1.去掉协管添加时候的实名认证限制
#### 1.0.7
> 1.http /assist/logs 接口添加计数信息, 用于动态计数日志个数
#### 1.0.6
> 1.更新缓存空数组防止空值穿透到db
> 2.fix rpc IDs返回值错误的bug 必须返回指针,必须是指针
#### 1.0.5
> 1.添加Prom的基础组件依赖监控代码
#### 1.0.4
> 1.memcache 判断有误,判断等于并制空
> 2.info接口返回count值, 方便第三方业务自己根据设定的阈值来进行判断操作
#### 1.0.3
> 1.更新vendor包go-business
> 2.协管服务添加业务常量ActCancelDisUser,指代协管可以帮助Up主取消屏蔽用户
> 3.添加协管的RPC接口:RPC.AssistIDs
#### 1.0.2
> 1.go-common升级到6.17.0
> 2.为log-agent做准备
> 3.重构prom的接入方式
#### 1.0.1
> 1.合并到develop分支
#### 1.0.0
> 1.初始化功能

View File

@ -0,0 +1,13 @@
# Owner
shencen
wangzhe01
# Author
shencen
haoguanwei
shaojiatong
# Reviewer
shencen
haoguanwei
shaojiatong

View File

@ -0,0 +1,17 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- haoguanwei
- shaojiatong
- shencen
- wangzhe01
labels:
- main
- service
- service/main/assist
options:
no_parent_owners: true
reviewers:
- haoguanwei
- shaojiatong
- shencen

View File

@ -0,0 +1,13 @@
#### assist-service
##### 项目简介
> 1.协管骑士服务
##### 编译环境
> 请只用golang v1.7.x以上版本编译执行。
##### 依赖包
> 1.公共包go-common
##### 特别说明
> 1.model目录可能会被其他项目引用请谨慎请改并通知各方。

View File

@ -0,0 +1,44 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_binary(
name = "cmd",
embed = [":go_default_library"],
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = ["main.go"],
data = ["assist-service.toml"],
importpath = "go-common/app/service/main/assist/cmd",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/assist/conf:go_default_library",
"//app/service/main/assist/http:go_default_library",
"//app/service/main/assist/rpc/server:go_default_library",
"//app/service/main/assist/service:go_default_library",
"//library/log:go_default_library",
"//library/net/trace: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"],
)

View File

@ -0,0 +1,133 @@
# This is a TOML document. Boom.
tick = "5m"
maxAssCnt = 10
maxTypeCnt = 100
[host]
api = "http://api.bilibili.com"
member = "http://member.bilibili.com"
account = "http://account.bilibili.com"
message = "http://message.bilibili.com"
[xlog]
dir = "/data/log/assist-service/"
[xlog.elk]
project = "assist-service"
addr = "172.18.20.17:8520"
chanSize = 1024
[app]
key = "b8f239ca38a53308"
secret = "5460ef72fe13c10dfb53442b9111427e"
[relationSub]
key = "0QEO9F8JuuIxZzNDvklH"
secret = "0QEO9F8JuuIxZzNDvklI"
group = "Relation-Assist-S"
topic = "Relation-T"
action = "sub"
offset = "old"
buffer = 128
name = "assist-service/relation-sub"
proto = "tcp"
addr = "172.16.33.158:6205"
idle = 100
active = 100
dialTimeout = "1s"
readTimeout = "60s"
writeTimeout = "1s"
idleTimeout = "10s"
[httpClient]
[httpClient.normal]
key = "b8f239ca38a53308"
secret = "5460ef72fe13c10dfb53442b9111427e"
dial = "500ms"
timeout = "1s"
keepAlive = "60s"
timer = 10
[httpClient.normal.breaker]
window = "10s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[httpClient.slow]
key = "b8f239ca38a53308"
secret = "5460ef72fe13c10dfb53442b9111427e"
dial = "500ms"
timeout = "1s"
keepAlive = "60s"
timer = 10
[httpClient.slow.breaker]
window = "10s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[bm]
[bm.inner]
addr = "0.0.0.0:6721"
maxListen = 1000
timeout = "2s"
[bm.local]
addr = "0.0.0.0:6722"
maxListen = 1000
timeout = "1s"
[rpcServer2]
discoverOff = false
token = "123456"
[[rpcServer2.servers]]
proto = "tcp"
addr = "0.0.0.0:6729"
weight = 10
group = "uat"
[rpcServer2.zookeeper]
root = "/microservice/assist-service/"
addrs = ["172.18.33.50:2199","172.18.33.51:2199","172.18.33.52:2199"]
timeout = "30s"
[db]
[db.assist]
name = "[archive]tcp@172.16.33.54:3306"
dsn = "test:test@tcp(172.16.33.54:3306)/bilibili_assist?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 5
idle = 5
idleTimeout ="4h"
queryTimeout = "100ms"
execTimeout = "100ms"
tranTimeout = "200ms"
[db.assist.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[memcache]
[memcache.assist]
name = "assist-service"
proto = "tcp"
addr = "172.16.33.54:11212"
active = 10
idle = 5
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "80s"
[redis]
[redis.assist]
name = "assist/assist"
proto = "tcp"
addr = "172.16.33.54:6381"
idle = 100
active = 100
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "10s"
expire = "24h"

View File

@ -0,0 +1,51 @@
package main
import (
"flag"
"go-common/app/service/main/assist/conf"
"go-common/app/service/main/assist/http"
"go-common/app/service/main/assist/rpc/server"
"go-common/app/service/main/assist/service"
"os"
"os/signal"
"syscall"
"time"
"go-common/library/log"
"go-common/library/net/trace"
)
func main() {
flag.Parse()
if err := conf.Init(); err != nil {
log.Error("conf.Init() error(%v)", err)
panic(err)
}
log.Init(conf.Conf.Xlog)
trace.Init(conf.Conf.Tracer)
defer trace.Close()
defer log.Close()
log.Info("assist-service start")
// service init
svr := service.New(conf.Conf)
rpcSvr := server.New(conf.Conf, svr)
http.Init(conf.Conf, svr)
// signal handler
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
for {
s := <-c
log.Info("assist-service get a signal %s", s.String())
switch s {
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
rpcSvr.Close()
time.Sleep(time.Second * 2)
log.Info("assist-service exit")
return
case syscall.SIGHUP:
// TODO reload
default:
return
}
}
}

View File

@ -0,0 +1,43 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["conf.go"],
importpath = "go-common/app/service/main/assist/conf",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//library/cache/memcache:go_default_library",
"//library/cache/redis:go_default_library",
"//library/conf:go_default_library",
"//library/database/sql:go_default_library",
"//library/ecode/tip:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/rpc:go_default_library",
"//library/net/rpc/warden:go_default_library",
"//library/net/trace:go_default_library",
"//library/queue/databus:go_default_library",
"//library/time:go_default_library",
"//vendor/github.com/BurntSushi/toml: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"],
)

View File

@ -0,0 +1,153 @@
package conf
import (
"errors"
"flag"
"go-common/library/cache/memcache"
"go-common/library/cache/redis"
"go-common/library/conf"
"go-common/library/database/sql"
ecode "go-common/library/ecode/tip"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/rpc"
"go-common/library/net/rpc/warden"
"go-common/library/net/trace"
"go-common/library/queue/databus"
"go-common/library/time"
"github.com/BurntSushi/toml"
)
// Conf info.
var (
confPath string
Conf = &Config{}
client *conf.Client
)
// Config struct.
type Config struct {
// base
// tick
Tick time.Duration
// max assist count
MaxAssCnt int
MaxTypeCnt int64
// app
App *bm.App
// host
Host *Host
// elk
Xlog *log.Config
// tracer
Tracer *trace.Config
BM *bm.ServerConfig
// rpc server2
RPCServer *rpc.ServerConfig
// http client
HTTPClient *HTTPClient
// db
DB *DB
// ecode
Ecode *ecode.Config
// rpc client2
ArchiveRPC *rpc.ClientConfig
// mc
Memcache *Memcache
// redis
Redis *Redis
// databus sub
RelationSub *databus.Config
AccClient *warden.ClientConfig
}
// HTTPServers Http Servers
type HTTPServers struct {
Inner *bm.ServerConfig
}
// Memcache conf
type Memcache struct {
Assist *struct {
*memcache.Config
SubmitExpire time.Duration
}
}
// Redis conf
type Redis struct {
Assist *struct {
*redis.Config
Expire time.Duration
}
}
// Host conf.
type Host struct {
Message string
Account string
}
// DB conf.
type DB struct {
Assist *sql.Config
}
// HTTPClient conf.
type HTTPClient struct {
Normal *bm.ClientConfig
Slow *bm.ClientConfig
}
func init() {
flag.StringVar(&confPath, "conf", "", "default config path")
}
// Init conf.
func Init() (err error) {
if confPath != "" {
return local()
}
return remote()
}
func local() (err error) {
_, err = toml.DecodeFile(confPath, &Conf)
return
}
func remote() (err error) {
if client, err = conf.New(); err != nil {
return
}
if err = load(); err != nil {
return
}
go func() {
for range client.Event() {
log.Info("config reload")
if load() != nil {
log.Error("config reload error (%v)", err)
}
}
}()
return
}
func load() (err error) {
var (
s string
ok bool
tmpConf *Config
)
if s, ok = client.Toml2(); !ok {
return errors.New("load config center error")
}
if _, err = toml.Decode(s, &tmpConf); err != nil {
return errors.New("could not decode config")
}
*Conf = *tmpConf
return
}

View File

@ -0,0 +1,50 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["dao_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/service/main/account/api:go_default_library",
"//app/service/main/assist/conf:go_default_library",
"//library/ecode:go_default_library",
"//vendor/github.com/golang/mock/gomock:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["dao.go"],
importpath = "go-common/app/service/main/assist/dao/account",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/account/api:go_default_library",
"//app/service/main/assist/conf:go_default_library",
"//library/ecode:go_default_library",
"//library/log: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"],
)

View File

@ -0,0 +1,131 @@
package account
import (
"context"
accapi "go-common/app/service/main/account/api"
"go-common/app/service/main/assist/conf"
"go-common/library/ecode"
"go-common/library/log"
)
// Dao is account dao.
type Dao struct {
c *conf.Config
acc accapi.AccountClient
}
// New new a dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
}
var err error
if d.acc, err = accapi.NewClient(c.AccClient); err != nil {
panic(err)
}
return
}
// IsFollow check assist follow up.
func (d *Dao) IsFollow(c context.Context, mid, assistMid int64) (follow bool, err error) {
var arg = &accapi.RelationReq{
Mid: assistMid,
Owner: mid,
}
res, err := d.acc.Relation3(c, arg)
if err != nil {
log.Error("d.acc.Relation2(%d,%d) error(%v)", mid, assistMid, err)
return
}
follow = res.Following
return
}
// IdentifyInfo 获取用户实名认证状态
func (d *Dao) IdentifyInfo(c context.Context, mid int64, ip string) (err error) {
var (
arg = &accapi.MidReq{
Mid: mid,
}
rpcRes *accapi.ProfileReply
mf *accapi.Profile
)
if rpcRes, err = d.acc.Profile3(c, arg); err != nil {
log.Error("d.acc.Profile3 error(%v) | mid(%d) ip(%s) arg(%v)", err, mid, ip, arg)
err = ecode.CreativeAccServiceErr
return
}
if rpcRes != nil {
mf = rpcRes.Profile
}
if mf.Identification == 1 {
return
}
if err = d.switchIDInfoRet(mf.TelStatus); err != nil {
log.Error("switchIDInfoRet res(%v)", mf.TelStatus)
return
}
return
}
func (d *Dao) switchIDInfoRet(phoneRet int32) (err error) {
switch phoneRet {
case 0:
err = ecode.UserCheckNoPhone
case 1:
err = nil
case 2:
err = ecode.UserCheckInvalidPhone
}
return
}
// UserBanned 获取用户封禁状态, disabled when spacesta == 2
func (d *Dao) UserBanned(c context.Context, mid int64) (err error) {
var card *accapi.Card
if card, err = d.Card(c, mid, ""); err != nil {
log.Error("d.Card() error(%v)", err)
err = nil
return
}
if card.Silence == 1 {
err = ecode.UserDisabled
return
}
return
}
// Card get account.
func (d *Dao) Card(c context.Context, mid int64, ip string) (res *accapi.Card, err error) {
var (
rpcRes *accapi.CardReply
arg = &accapi.MidReq{
Mid: mid,
}
)
if rpcRes, err = d.acc.Card3(c, arg); err != nil {
log.Error("s.acc.Card3() error(%v)", err)
err = ecode.CreativeAccServiceErr
}
if rpcRes != nil {
res = rpcRes.Card
}
return
}
// Cards get infos for space
func (d *Dao) Cards(c context.Context, mids []int64) (res map[int64]*accapi.Card, err error) {
var (
arg = &accapi.MidsReq{
Mids: mids,
}
rpcRes *accapi.CardsReply
)
if rpcRes, err = d.acc.Cards3(c, arg); err != nil {
log.Error("s.acc.Cards3() error(%v)", err)
err = ecode.CreativeAccServiceErr
}
if rpcRes != nil {
res = rpcRes.Cards
}
return
}

View File

@ -0,0 +1,131 @@
package account
import (
"context"
"flag"
accapi "go-common/app/service/main/account/api"
"go-common/app/service/main/assist/conf"
"go-common/library/ecode"
"os"
"testing"
"github.com/golang/mock/gomock"
"github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.archive.assist-service")
flag.Set("conf_token", "6e0dae2c95d90ff8d0da53460ef11ae8")
flag.Set("tree_id", "2084")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
} else {
flag.Set("conf", "../cmd/assist-service.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
m.Run()
os.Exit(0)
}
func WithMock(t *testing.T, f func(mock *gomock.Controller)) func() {
return func() {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
f(mockCtrl)
}
}
func TestIdentifyInfo(t *testing.T) {
convey.Convey("1", t, WithMock(t, func(mockCtrl *gomock.Controller) {
var (
c = context.Background()
mid = int64(2089809)
ip = "127.0.0.1"
err error
)
mock := accapi.NewMockAccountClient(mockCtrl)
d.acc = mock
mockReq := &accapi.MidReq{
Mid: mid,
}
mock.EXPECT().Profile3(gomock.Any(), mockReq).Return(nil, ecode.CreativeAccServiceErr)
err = d.IdentifyInfo(c, mid, ip)
convey.So(err, convey.ShouldNotBeNil)
}))
convey.Convey("2", t, WithMock(t, func(mockCtrl *gomock.Controller) {
var (
c = context.Background()
mid = int64(2089809)
ip = "127.0.0.1"
err error
)
mock := accapi.NewMockAccountClient(mockCtrl)
d.acc = mock
mockReq := &accapi.MidReq{
Mid: mid,
}
rpcRes := &accapi.ProfileReply{
Profile: &accapi.Profile{
Identification: 0,
TelStatus: 2,
},
}
mock.EXPECT().Profile3(gomock.Any(), mockReq).Return(rpcRes, nil)
err = d.IdentifyInfo(c, mid, ip)
convey.So(err, convey.ShouldNotBeNil)
}))
}
func TestIsFollow(t *testing.T) {
convey.Convey("1", t, WithMock(t, func(mockCtrl *gomock.Controller) {
var (
c = context.Background()
mid = int64(2089809)
assistMid = int64(11)
err error
follow bool
)
mock := accapi.NewMockAccountClient(mockCtrl)
d.acc = mock
mockReq := &accapi.RelationReq{
Mid: assistMid,
Owner: mid,
}
mock.EXPECT().Relation3(gomock.Any(), mockReq).Return(nil, ecode.CreativeAccServiceErr)
follow, err = d.IsFollow(c, mid, assistMid)
convey.So(err, convey.ShouldNotBeNil)
convey.So(follow, convey.ShouldBeFalse)
}))
}
func TestCard(t *testing.T) {
convey.Convey("TestCard", t, WithMock(t, func(mockCtrl *gomock.Controller) {
var (
c = context.Background()
mid = int64(2089809)
err error
res *accapi.Card
)
mock := accapi.NewMockAccountClient(mockCtrl)
d.acc = mock
mockReq := &accapi.MidReq{
Mid: mid,
}
mock.EXPECT().Card3(gomock.Any(), mockReq).Return(nil, ecode.CreativeAccServiceErr)
res, err = d.Card(c, mid, "")
convey.So(err, convey.ShouldNotBeNil)
convey.So(res, convey.ShouldBeNil)
}))
}

View File

@ -0,0 +1,66 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"assist_redis_test.go",
"assist_test.go",
"dao_test.go",
"log_test.go",
"mc_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/service/main/assist/conf:go_default_library",
"//app/service/main/assist/model/assist:go_default_library",
"//library/ecode:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"assist.go",
"assist_redis.go",
"dao.go",
"log.go",
"mc.go",
],
importpath = "go-common/app/service/main/assist/dao/assist",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/assist/conf:go_default_library",
"//app/service/main/assist/model/assist:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/cache/redis:go_default_library",
"//library/database/sql:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/time:go_default_library",
"//library/xstr: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"],
)

View File

@ -0,0 +1,125 @@
package assist
import (
"context"
"go-common/app/service/main/assist/model/assist"
"go-common/library/database/sql"
"go-common/library/log"
)
const (
// insert
_inAssSQL = "INSERT INTO assist (mid,assist_mid) VALUE (?,?) ON DUPLICATE KEY UPDATE state=0"
// update
_delAssSQL = "UPDATE assist SET state=1 WHERE mid=? AND assist_mid=?"
// select
_assSQL = "SELECT mid,assist_mid,ctime,mtime FROM assist WHERE mid=? AND assist_mid=? AND state=0"
_asssSQL = "SELECT mid,assist_mid,ctime,mtime FROM assist WHERE mid=? AND state=0"
_assCntSQL = "SELECT count(*) FROM assist WHERE mid=? AND state=0"
_assUpsSQL = "SELECT mid, ctime FROM assist WHERE assist_mid=? AND state=0 limit ?,?"
_assUpsCntSQL = "SELECT count(*) as total FROM assist WHERE assist_mid=? AND state=0"
)
// AddAssist add assist
func (d *Dao) AddAssist(c context.Context, mid, assistMid int64) (id int64, err error) {
res, err := d.db.Exec(c, _inAssSQL, mid, assistMid)
if err != nil {
log.Error("d.inAss.Exec error(%v)", err)
return
}
id, err = res.LastInsertId()
return
}
// DelAssist del assist
func (d *Dao) DelAssist(c context.Context, mid, assistMid int64) (row int64, err error) {
res, err := d.db.Exec(c, _delAssSQL, mid, assistMid)
if err != nil {
log.Error("d.delAss.Exec error(%v)", err)
return
}
row, err = res.RowsAffected()
return
}
// Assist get one Assist from assist database.
func (d *Dao) Assist(c context.Context, mid, assistMid int64) (a *assist.Assist, err error) {
row := d.db.QueryRow(c, _assSQL, mid, assistMid)
a = &assist.Assist{}
if err = row.Scan(&a.Mid, &a.AssistMid, &a.CTime, &a.MTime); err != nil {
if err == sql.ErrNoRows {
a = nil
err = nil
} else {
log.Error("row.Scan error(%v)", err)
}
}
return
}
// Assists get all Assists from assist database.
func (d *Dao) Assists(c context.Context, mid int64) (as []*assist.Assist, err error) {
as = make([]*assist.Assist, 0)
rows, err := d.db.Query(c, _asssSQL, mid)
if err != nil {
log.Error("db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
a := &assist.Assist{}
if err = rows.Scan(&a.Mid, &a.AssistMid, &a.CTime, &a.MTime); err != nil {
log.Error("row.Scan error(%v)", err)
return
}
as = append(as, a)
}
return
}
// AssistCnt get assist count.
func (d *Dao) AssistCnt(c context.Context, mid int64) (count int, err error) {
row := d.db.QueryRow(c, _assCntSQL, mid)
if err = row.Scan(&count); err != nil {
if err == sql.ErrNoRows {
count = 0
err = nil
} else {
log.Error("row.Scan error(%v)", err)
}
}
return
}
// Ups get ups who already sign me as assist.
func (d *Dao) Ups(c context.Context, assistMid, pn, ps int64) (mids []int64, ups map[int64]*assist.Up, total int64, err error) {
mids = make([]int64, 0)
ups = make(map[int64]*assist.Up, ps)
// default is empty json array
rows, err := d.db.Query(c, _assUpsSQL, assistMid, (pn-1)*ps, pn*ps)
if err != nil {
log.Error("db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
up := &assist.Up{}
if err = rows.Scan(&up.Mid, &up.CTime); err != nil {
log.Error("row.Scan error(%v)", err)
return
}
ups[up.Mid] = up
mids = append(mids, up.Mid)
}
row := d.db.QueryRow(c, _assUpsCntSQL, assistMid)
if err = row.Scan(&total); err != nil {
if err == sql.ErrNoRows {
total = 0
err = nil
} else {
log.Error("row.Scan error(%v)", err)
}
}
return
}

View File

@ -0,0 +1,261 @@
package assist
import (
"context"
"go-common/app/service/main/assist/model/assist"
"go-common/library/cache/redis"
"go-common/library/log"
xtime "go-common/library/time"
"strconv"
"time"
)
func (d *Dao) logCountKey(mid, assistMid int64) string {
datetime := time.Now().Format("20060102")
return datetime + strconv.FormatInt(mid, 10) + "_" + strconv.FormatInt(assistMid, 10)
}
func (d *Dao) assTotalKey(mid int64) string {
datetime := time.Now().Format("20060102")
return "ass_" + datetime + "_" + strconv.FormatInt(mid, 10)
}
func (d *Dao) assSameKey(mid int64) string {
datetime := time.Now().Format("20060102")
return "assSame_" + datetime + "_" + strconv.FormatInt(mid, 10)
}
func (d *Dao) assUpKey(assistMid int64) string {
datetime := time.Now().Format("20060102")
return "assUps_" + datetime + "_" + strconv.FormatInt(assistMid, 10)
}
// DailyLogCount get daily count by type
func (d *Dao) DailyLogCount(c context.Context, mid, assistMid, tp int64) (count int64, err error) {
var (
conn = d.redis.Get(c)
key = d.logCountKey(mid, assistMid)
field = strconv.FormatInt(tp, 10)
)
defer conn.Close()
if err = conn.Send("HGET", key, field); err != nil {
log.Error("conn.Send HGET (%s) error(%v)", key, err)
return
}
if err = conn.Flush(); err != nil {
log.Error("conn.Flush error(%v)", err)
return
}
count, err = redis.Int64(conn.Receive())
if err != nil {
if err == redis.ErrNil {
err = nil
count = 0
log.Info("conn.Receive(HGET, %d) error(%v)", mid, err)
} else {
log.Error("conn.Receive(HGET, %d) error(%v)", mid, err)
}
return
}
return
}
// IncrLogCount incr daily count
func (d *Dao) IncrLogCount(c context.Context, mid, assistMid, tp int64) (err error) {
var (
conn = d.redis.Get(c)
key = d.logCountKey(mid, assistMid)
field = strconv.FormatInt(tp, 10)
)
defer conn.Close()
_ = conn.Send("EXPIRE", key, d.redisExpire)
if err = conn.Send("HINCRBY", key, field, 1); err != nil {
log.Error("conn.Send HINCRBY (%s) error(%v)", key, err)
return
}
if err = conn.Flush(); err != nil {
log.Error("conn.Flush error(%v)", err)
return
}
return
}
// TotalAssCnt get daily total add count
func (d *Dao) TotalAssCnt(c context.Context, mid int64) (count int64, err error) {
var (
conn = d.redis.Get(c)
key = d.assTotalKey(mid)
field = strconv.FormatInt(mid, 10)
)
defer conn.Close()
if err = conn.Send("HGET", key, field); err != nil {
log.Error("conn.Send HGET (%s) error(%v)", key, err)
return
}
if err = conn.Flush(); err != nil {
log.Error("conn.Flush error(%v)", err)
return
}
count, err = redis.Int64(conn.Receive())
if err != nil {
if err == redis.ErrNil {
err = nil
count = 0
log.Info("conn.Receive(HGET, %d) error(%v)", mid, err)
} else {
log.Error("conn.Receive(HGET, %d) error(%v)", mid, err)
}
return
}
return
}
// SameAssCnt get add same user count
func (d *Dao) SameAssCnt(c context.Context, mid, assistMid int64) (count int64, err error) {
var (
conn = d.redis.Get(c)
key = d.assSameKey(mid)
field = strconv.FormatInt(assistMid, 10)
)
defer conn.Close()
if err = conn.Send("HGET", key, field); err != nil {
log.Error("conn.Send HGET (%s) error(%v)", key, err)
return
}
if err = conn.Flush(); err != nil {
log.Error("conn.Flush error(%v)", err)
return
}
count, err = redis.Int64(conn.Receive())
if err != nil {
if err == redis.ErrNil {
err = nil
count = 0
log.Info("conn.Receive(HGET, %d) error(%v)", mid, err)
} else {
log.Error("conn.Receive(HGET, %d) error(%v)", mid, err)
}
return
}
return
}
// IncrAssCnt called when assis added, incr both same and total count
func (d *Dao) IncrAssCnt(c context.Context, mid, assistMid int64) (err error) {
var (
conn = d.redis.Get(c)
keyAll = d.assTotalKey(mid)
fieldAll = strconv.FormatInt(mid, 10)
keySame = d.assSameKey(mid)
fieldSame = strconv.FormatInt(assistMid, 10)
)
defer conn.Close()
_ = conn.Send("EXPIRE", keyAll, d.redisExpire)
if err = conn.Send("HINCRBY", keyAll, fieldAll, 1); err != nil {
log.Error("conn.Send HINCRBY (%s) error(%v)", keyAll, err)
return
}
_ = conn.Send("EXPIRE", keySame, d.redisExpire)
if err = conn.Send("HINCRBY", keySame, fieldSame, 1); err != nil {
log.Error("conn.Send HINCRBY (%s) error(%v)", keySame, err)
return
}
if err = conn.Flush(); err != nil {
log.Error("conn.Flush error(%v)", err)
return
}
return
}
// DelAssUpAllCache del AssUpAllCache when delete assist relation
func (d *Dao) DelAssUpAllCache(c context.Context, assistMid int64) (err error) {
var (
key = d.assUpKey(assistMid)
conn = d.redis.Get(c)
)
defer conn.Close()
if _, err = conn.Do("DEL", key); err != nil {
log.Error("conn.Do(ZERM, %s, %d) error(%v)", key, assistMid, err)
return
}
return
}
// AddAssUpAllCache add AssUpAllCache when add assist relation
func (d *Dao) AddAssUpAllCache(c context.Context, assistMid int64, ups map[int64]*assist.Up) (err error) {
var (
key = d.assUpKey(assistMid)
conn = d.redis.Get(c)
)
defer conn.Close()
for _, up := range ups {
if err = conn.Send("ZADD", key, up.CTime, up.Mid); err != nil {
log.Error("conn.Send(ZADD, %s, %v, %d) error(%v)", key, up.CTime, up.Mid, err)
return
}
}
if err = conn.Send("EXPIRE", key, -1); err != nil {
log.Error("conn.Send(Expire, %s, %d) error(%v)", key, 0, err)
return
}
if err = conn.Flush(); err != nil {
log.Error("conn.Flush error(%v)", err)
return
}
for i := 0; i < len(ups); i++ {
if _, err = conn.Receive(); err != nil {
log.Error("conn.Receive error(%v)", err)
return
}
}
return
}
// AssUpCacheWithScore get uppers passed mids from cache with scores
func (d *Dao) AssUpCacheWithScore(c context.Context, assistMid int64, start, end int64) (mids []int64, ups map[int64]*assist.Up, total int64, err error) {
conn := d.redis.Get(c)
defer conn.Close()
ups = make(map[int64]*assist.Up, end-start)
key := d.assUpKey(assistMid)
if err = conn.Send("ZREVRANGE", key, start, end, "WITHSCORES"); err != nil {
log.Error("conn.Send(ZREVRANGE, %s) error(%v)", key, err)
return
}
if err = conn.Flush(); err != nil {
log.Error("conn.Flush error(%v)", err)
return
}
upsWithScore, err := redis.Int64s(conn.Receive())
if err != nil {
log.Error("conn.Do(GET, %d, %d, %d) error(%v)", assistMid, start, end, err)
}
for i := 0; i < len(upsWithScore); i += 2 {
mids = append(mids, upsWithScore[i])
var t xtime.Time
t.Scan(strconv.FormatInt(upsWithScore[i+1], 10))
up := &assist.Up{
Mid: upsWithScore[i],
CTime: t,
}
ups[upsWithScore[i]] = up
}
if err = conn.Send("ZLEXCOUNT", key, "-", "+"); err != nil {
log.Error("conn.Send(ZLEXCOUNT, %s) error(%v)", key, err)
return
}
if err = conn.Flush(); err != nil {
log.Error("conn.Flush error(%v)", err)
return
}
total, err = redis.Int64(conn.Receive())
if err != nil {
if err == redis.ErrNil {
err = nil
log.Info("conn.Receive(ZLEXCOUNT, %d) error(%v)", assistMid, err)
} else {
log.Error("conn.Receive(ZLEXCOUNT, %d) error(%v)", assistMid, err)
}
return
}
return
}

View File

@ -0,0 +1,174 @@
package assist
import (
"context"
"go-common/app/service/main/assist/model/assist"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestAssistlogCountKey(t *testing.T) {
var (
mid = int64(0)
assistMid = int64(0)
)
convey.Convey("logCountKey", t, func(ctx convey.C) {
p1 := d.logCountKey(mid, assistMid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestAssistassTotalKey(t *testing.T) {
var (
mid = int64(0)
)
convey.Convey("assTotalKey", t, func(ctx convey.C) {
p1 := d.assTotalKey(mid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestAssistassSameKey(t *testing.T) {
var (
mid = int64(0)
)
convey.Convey("assSameKey", t, func(ctx convey.C) {
p1 := d.assSameKey(mid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestAssistassUpKey(t *testing.T) {
var (
assistMid = int64(0)
)
convey.Convey("assUpKey", t, func(ctx convey.C) {
p1 := d.assUpKey(assistMid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestAssistDailyLogCount(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
assistMid = int64(0)
tp = int64(0)
)
convey.Convey("DailyLogCount", t, func(ctx convey.C) {
count, err := d.DailyLogCount(c, mid, assistMid, tp)
ctx.Convey("Then err should be nil.count should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(count, convey.ShouldNotBeNil)
})
})
}
func TestAssistIncrLogCount(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
assistMid = int64(0)
tp = int64(0)
)
convey.Convey("IncrLogCount", t, func(ctx convey.C) {
err := d.IncrLogCount(c, mid, assistMid, tp)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestAssistTotalAssCnt(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
)
convey.Convey("TotalAssCnt", t, func(ctx convey.C) {
count, err := d.TotalAssCnt(c, mid)
ctx.Convey("Then err should be nil.count should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(count, convey.ShouldNotBeNil)
})
})
}
func TestAssistSameAssCnt(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
assistMid = int64(0)
)
convey.Convey("SameAssCnt", t, func(ctx convey.C) {
count, err := d.SameAssCnt(c, mid, assistMid)
ctx.Convey("Then err should be nil.count should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(count, convey.ShouldNotBeNil)
})
})
}
func TestAssistIncrAssCnt(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
assistMid = int64(0)
)
convey.Convey("IncrAssCnt", t, func(ctx convey.C) {
err := d.IncrAssCnt(c, mid, assistMid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestAssistDelAssUpAllCache(t *testing.T) {
var (
c = context.Background()
assistMid = int64(0)
)
convey.Convey("DelAssUpAllCache", t, func(ctx convey.C) {
err := d.DelAssUpAllCache(c, assistMid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestAssistAddAssUpAllCache(t *testing.T) {
var (
c = context.Background()
assistMid = int64(0)
ups map[int64]*assist.Up
)
convey.Convey("AddAssUpAllCache", t, func(ctx convey.C) {
err := d.AddAssUpAllCache(c, assistMid, ups)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestAssistAssUpCacheWithScore(t *testing.T) {
var (
c = context.Background()
assistMid = int64(0)
start = int64(0)
end = int64(0)
)
convey.Convey("AssUpCacheWithScore", t, func(ctx convey.C) {
_, _, _, err := d.AssUpCacheWithScore(c, assistMid, start, end)
ctx.Convey("Then err should be nil.mids,ups,total should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}

View File

@ -0,0 +1,99 @@
package assist
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestAssistAddAssist(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
assistMid = int64(0)
)
convey.Convey("AddAssist", t, func(ctx convey.C) {
id, err := d.AddAssist(c, mid, assistMid)
ctx.Convey("Then err should be nil.id should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(id, convey.ShouldNotBeNil)
})
})
}
func TestAssistDelAssist(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
assistMid = int64(0)
)
convey.Convey("DelAssist", t, func(ctx convey.C) {
row, err := d.DelAssist(c, mid, assistMid)
ctx.Convey("Then err should be nil.row should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(row, convey.ShouldNotBeNil)
})
})
}
func TestAssistAssist(t *testing.T) {
var (
c = context.Background()
mid = int64(27515409)
assistMid = int64(27515235)
err error
)
convey.Convey("Assist", t, func(ctx convey.C) {
_, err = d.Assist(c, mid, assistMid)
ctx.Convey("Then err should be nil.a should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestAssistAssists(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
)
convey.Convey("Assists", t, func(ctx convey.C) {
as, err := d.Assists(c, mid)
ctx.Convey("Then err should be nil.as should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(as, convey.ShouldNotBeNil)
})
})
}
func TestAssistAssistCnt(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
)
convey.Convey("AssistCnt", t, func(ctx convey.C) {
count, err := d.AssistCnt(c, mid)
ctx.Convey("Then err should be nil.count should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(count, convey.ShouldNotBeNil)
})
})
}
func TestAssistUps(t *testing.T) {
var (
c = context.Background()
assistMid = int64(0)
pn = int64(0)
ps = int64(0)
)
convey.Convey("Ups", t, func(ctx convey.C) {
mids, ups, total, err := d.Ups(c, assistMid, pn, ps)
ctx.Convey("Then err should be nil.mids,ups,total should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(total, convey.ShouldNotBeNil)
ctx.So(ups, convey.ShouldNotBeNil)
ctx.So(mids, convey.ShouldNotBeNil)
})
})
}

View File

@ -0,0 +1,64 @@
package assist
import (
"context"
"time"
"go-common/app/service/main/assist/conf"
"go-common/library/cache/memcache"
"go-common/library/cache/redis"
"go-common/library/database/sql"
)
// Dao is assist dao.
type Dao struct {
// config
c *conf.Config
// db
db *sql.DB
// mc
mc *memcache.Pool
mcSubExp int32
// redis
redis *redis.Pool
redisExpire int32
}
// New init api url
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
db: sql.NewMySQL(c.DB.Assist),
mc: memcache.NewPool(c.Memcache.Assist.Config),
mcSubExp: int32(time.Duration(c.Memcache.Assist.SubmitExpire) / time.Second),
// redis
redis: redis.NewPool(c.Redis.Assist.Config),
redisExpire: int32(time.Duration(c.Redis.Assist.Expire) / time.Second),
}
return
}
// Ping include db, mc, redis
func (d *Dao) Ping(c context.Context) (err error) {
if err = d.db.Ping(c); err != nil {
return
}
if err = d.pingMemcache(c); err != nil {
return
}
return
}
// Close include db, mc, redis
func (d *Dao) Close() (err error) {
if d.db != nil {
d.db.Close()
}
if d.mc != nil {
d.mc.Close()
}
if d.redis != nil {
d.redis.Close()
}
return
}

View File

@ -0,0 +1,35 @@
package assist
import (
"flag"
"go-common/app/service/main/assist/conf"
"os"
"testing"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.archive.assist-service")
flag.Set("conf_token", "6e0dae2c95d90ff8d0da53460ef11ae8")
flag.Set("tree_id", "2084")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
} else {
flag.Set("conf", "../cmd/assist-service.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
m.Run()
os.Exit(0)
}

View File

@ -0,0 +1,293 @@
package assist
import (
"context"
"database/sql"
"fmt"
"time"
"go-common/app/service/main/assist/model/assist"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/xstr"
)
const (
// insert
_inLogSQL = "INSERT IGNORE INTO assist_log (mid,assist_mid,type,action,subject_id,object_id,detail) VALUES (?,?,?,?,?,?,?)"
// update
_cancelLogSQL = "UPDATE assist_log SET state=1 WHERE id=? AND mid=? AND assist_mid=?"
// info
_logInfoSQL = "SELECT id,mid,assist_mid,type,action,subject_id,object_id,detail,state,ctime,mtime FROM assist_log WHERE id=? AND mid=? AND assist_mid=?"
// obj
_logObjSQL = "SELECT id,mid,assist_mid,type,action,subject_id,object_id,detail,state,ctime,mtime FROM assist_log WHERE mid=? AND object_id=? AND type=? AND action=? limit 1"
// select
_logsSQL = "SELECT id,mid,assist_mid,type,action,subject_id,object_id,detail,state,ctime,mtime FROM assist_log WHERE mid=? ORDER BY id DESC LIMIT ?,?"
_logsByAssSQL = "SELECT id,mid,assist_mid,type,action,subject_id,object_id,detail,state,ctime,mtime FROM assist_log WHERE mid=? AND assist_mid=? ORDER BY id DESC LIMIT ?,?"
_logsByCtimeSQL = "SELECT id,mid,assist_mid,type,action,subject_id,object_id,detail,state,ctime,mtime FROM assist_log WHERE mid=? AND ctime>=? AND ctime<=? ORDER BY id DESC LIMIT ?,?"
_logsByAssCtimeSQL = "SELECT id,mid,assist_mid,type,action,subject_id,object_id,detail,state,ctime,mtime FROM assist_log WHERE mid=? AND assist_mid=? AND ctime>=? AND ctime<=? ORDER BY id DESC LIMIT ?,?"
_logCntGroupBySQL = "SELECT assist_mid,type,action,count(*) FROM assist_log WHERE mid=? GROUP BY assist_mid,type,action"
_logAssMidCntGroupBySQL = "SELECT assist_mid,type,action,count(*) FROM assist_log WHERE mid=%d and assist_mid IN (%s) GROUP BY assist_mid,type,action"
// LogCntBy*SQL
_logCntSQL = "SELECT count(*) FROM assist_log WHERE mid=?"
_logCntByAssSQL = "SELECT count(*) FROM assist_log WHERE mid=? AND assist_mid=?"
_logCntByCtimeSQL = "SELECT count(*) FROM assist_log WHERE mid=? AND ctime>=? AND ctime<=?"
_logCntByAssCtimeSQL = "SELECT count(*) FROM assist_log WHERE mid=? AND assist_mid=? AND ctime>=? AND ctime<=?"
)
// AddLog add one assist log.
func (d *Dao) AddLog(c context.Context, mid, assistMid, tp, act, subID int64, objIDStr string, detail string) (id int64, err error) {
res, err := d.db.Exec(c, _inLogSQL, mid, assistMid, tp, act, subID, objIDStr, detail)
if err != nil {
log.Error("d.inLog error(%v)|(%d,%d,%d,%d,%d,%s,%d)", err, mid, assistMid, tp, act, subID, objIDStr, detail)
return
}
id, err = res.LastInsertId()
return
}
// CancelLog cancel assist oper log.
func (d *Dao) CancelLog(c context.Context, logID, mid, assistMid int64) (rows int64, err error) {
res, err := d.db.Exec(c, _cancelLogSQL, logID, mid, assistMid)
if err != nil {
log.Error("d.db.Exec error(%v)", err)
return
}
rows, err = res.RowsAffected()
return
}
// LogInfo log Info
func (d *Dao) LogInfo(c context.Context, id, mid, assistMid int64) (a *assist.Log, err error) {
row := d.db.QueryRow(c, _logInfoSQL, id, mid, assistMid)
a = &assist.Log{}
if err = row.Scan(&a.ID, &a.Mid, &a.AssistMid, &a.Type, &a.Action, &a.SubjectID, &a.ObjectID, &a.Detail, &a.State, &a.CTime, &a.MTime); err != nil {
if err == sql.ErrNoRows {
a = nil
err = ecode.AssistLogNotExist
} else {
log.Error("row.Scan error(%v)", err)
}
}
return
}
// Logs get logs from assist db.
func (d *Dao) Logs(c context.Context, mid int64, start, offset int) (logs []*assist.Log, err error) {
logs = make([]*assist.Log, 0)
rows, err := d.db.Query(c, _logsSQL, mid, start, offset)
if err != nil {
log.Error("db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
lg := &assist.Log{}
if err = rows.Scan(&lg.ID, &lg.Mid, &lg.AssistMid, &lg.Type, &lg.Action, &lg.SubjectID, &lg.ObjectID, &lg.Detail, &lg.State, &lg.CTime, &lg.MTime); err != nil {
log.Error("row.Scan error(%v)", err)
return
}
logs = append(logs, lg)
}
return
}
// LogsByAssist get logs from assist db by assist mid.
func (d *Dao) LogsByAssist(c context.Context, mid, assistMid int64, start, offset int) (logs []*assist.Log, err error) {
logs = make([]*assist.Log, 0)
rows, err := d.db.Query(c, _logsByAssSQL, mid, assistMid, start, offset)
if err != nil {
log.Error("db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
lg := &assist.Log{}
if err = rows.Scan(&lg.ID, &lg.Mid, &lg.AssistMid, &lg.Type, &lg.Action, &lg.SubjectID, &lg.ObjectID, &lg.Detail, &lg.State, &lg.CTime, &lg.MTime); err != nil {
log.Error("row.Scan error(%v)", err)
return
}
logs = append(logs, lg)
}
return
}
// LogsByCtime get logs from assist db by ctime.
func (d *Dao) LogsByCtime(c context.Context, mid int64, stime, etime time.Time, start, offset int) (logs []*assist.Log, err error) {
logs = make([]*assist.Log, 0)
rows, err := d.db.Query(c, _logsByCtimeSQL, mid, stime, etime, start, offset)
if err != nil {
log.Error("db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
lg := &assist.Log{}
if err = rows.Scan(&lg.ID, &lg.Mid, &lg.AssistMid, &lg.Type, &lg.Action, &lg.SubjectID, &lg.ObjectID, &lg.Detail, &lg.State, &lg.CTime, &lg.MTime); err != nil {
log.Error("row.Scan error(%v)", err)
return
}
logs = append(logs, lg)
}
return
}
// LogsByAssistCtime get logs from assist db by assist oper ctime.
func (d *Dao) LogsByAssistCtime(c context.Context, mid, assistMid int64, stime, etime time.Time, start, offset int) (logs []*assist.Log, err error) {
logs = make([]*assist.Log, 0)
rows, err := d.db.Query(c, _logsByAssCtimeSQL, mid, assistMid, stime, etime, start, offset)
if err != nil {
log.Error("db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
lg := &assist.Log{}
if err = rows.Scan(&lg.ID, &lg.Mid, &lg.AssistMid, &lg.Type, &lg.Action, &lg.SubjectID, &lg.ObjectID, &lg.Detail, &lg.State, &lg.CTime, &lg.MTime); err != nil {
log.Error("row.Scan error(%v)", err)
return
}
logs = append(logs, lg)
}
return
}
// LogCount count by group from db.
func (d *Dao) LogCount(c context.Context, mid int64) (totalm map[int64]map[int8]map[int8]int, err error) {
rows, err := d.db.Query(c, _logCntGroupBySQL, mid)
if err != nil {
log.Error("db.Query err(%v)", err)
return
}
defer rows.Close()
totalm = map[int64]map[int8]map[int8]int{}
for rows.Next() {
var (
assMid int64
tp, act int8
cnt int
)
if err = rows.Scan(&assMid, &tp, &act, &cnt); err != nil {
log.Error("row.Scan err(%v)", err)
return
}
if tassMap, ok := totalm[assMid]; !ok {
totalm[assMid] = map[int8]map[int8]int{
tp: {act: cnt},
}
} else {
if tpMap, ok := tassMap[tp]; !ok {
tassMap[tp] = map[int8]int{act: cnt}
} else {
tpMap[act] = cnt
}
}
}
return
}
// LogCnt fn
func (d *Dao) LogCnt(c context.Context, mid int64) (count int64, err error) {
row := d.db.QueryRow(c, _logCntSQL, mid)
if err = row.Scan(&count); err != nil {
if err == sql.ErrNoRows {
err = nil
count = 0
} else {
log.Error("row.Scan error(%v)", err)
}
}
return
}
// LogCntAssist fn
func (d *Dao) LogCntAssist(c context.Context, mid, assistMid int64) (count int64, err error) {
row := d.db.QueryRow(c, _logCntByAssSQL, mid, assistMid)
if err = row.Scan(&count); err != nil {
if err == sql.ErrNoRows {
err = nil
count = 0
} else {
log.Error("row.Scan error(%v)", err)
}
}
return
}
// LogCntCtime fn
func (d *Dao) LogCntCtime(c context.Context, mid int64, stime, etime time.Time) (count int64, err error) {
row := d.db.QueryRow(c, _logCntByCtimeSQL, mid, stime, etime)
if err = row.Scan(&count); err != nil {
if err == sql.ErrNoRows {
err = nil
count = 0
} else {
log.Error("row.Scan error(%v)", err)
}
}
return
}
// LogCntAssistCtime fn
func (d *Dao) LogCntAssistCtime(c context.Context, mid, assistMid int64, stime, etime time.Time) (count int64, err error) {
row := d.db.QueryRow(c, _logCntByAssCtimeSQL, mid, assistMid, stime, etime)
if err = row.Scan(&count); err != nil {
if err == sql.ErrNoRows {
err = nil
count = 0
} else {
log.Error("row.Scan error(%v)", err)
}
}
return
}
// AssistsMidsTotal get all Assists from assist database.
func (d *Dao) AssistsMidsTotal(c context.Context, mid int64, assmids []int64) (totalm map[int64]map[int8]map[int8]int, err error) {
query := fmt.Sprintf(_logAssMidCntGroupBySQL, mid, xstr.JoinInts(assmids))
rows, err := d.db.Query(c, query)
if err != nil {
log.Error("db.Query err(%v)", err)
return
}
defer rows.Close()
totalm = map[int64]map[int8]map[int8]int{}
for rows.Next() {
var (
assMid int64
tp, act int8
cnt int
)
if err = rows.Scan(&assMid, &tp, &act, &cnt); err != nil {
log.Error("row.Scan err(%v)", err)
return
}
if tassMap, ok := totalm[assMid]; !ok {
totalm[assMid] = map[int8]map[int8]int{
tp: {act: cnt},
}
} else {
if tpMap, ok := tassMap[tp]; !ok {
tassMap[tp] = map[int8]int{act: cnt}
} else {
tpMap[act] = cnt
}
}
}
return
}
// LogObj log Obj
func (d *Dao) LogObj(c context.Context, mid, objID, tp, act int64) (a *assist.Log, err error) {
row := d.db.QueryRow(c, _logObjSQL, mid, objID, tp, act)
a = &assist.Log{}
if err = row.Scan(&a.ID, &a.Mid, &a.AssistMid, &a.Type, &a.Action, &a.SubjectID, &a.ObjectID, &a.Detail, &a.State, &a.CTime, &a.MTime); err != nil {
if err == sql.ErrNoRows {
a = nil
err = ecode.AssistLogNotExist
} else {
log.Error("row.Scan error(%v)", err)
}
}
return
}

View File

@ -0,0 +1,240 @@
package assist
import (
"context"
"go-common/library/ecode"
"testing"
"time"
"github.com/smartystreets/goconvey/convey"
)
func TestAssistAddLog(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
assistMid = int64(0)
tp = int64(0)
act = int64(0)
subID = int64(0)
objIDStr = ""
detail = ""
)
convey.Convey("AddLog", t, func(ctx convey.C) {
id, err := d.AddLog(c, mid, assistMid, tp, act, subID, objIDStr, detail)
ctx.Convey("Then err should be nil.id should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(id, convey.ShouldNotBeNil)
})
})
}
func TestAssistCancelLog(t *testing.T) {
var (
c = context.Background()
logID = int64(0)
mid = int64(0)
assistMid = int64(0)
)
convey.Convey("CancelLog", t, func(ctx convey.C) {
rows, err := d.CancelLog(c, logID, mid, assistMid)
ctx.Convey("Then err should be nil.rows should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(rows, convey.ShouldNotBeNil)
})
})
}
func TestAssistLogInfo(t *testing.T) {
var (
c = context.Background()
id = int64(1)
mid = int64(27515256)
assistMid = int64(27515243)
)
convey.Convey("LogInfo", t, func(ctx convey.C) {
a, err := d.LogInfo(c, id, mid, assistMid)
ctx.Convey("Then err should be nil.a should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(err, convey.ShouldEqual, ecode.AssistLogNotExist)
ctx.So(a, convey.ShouldBeNil)
})
})
}
func TestAssistLogs(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
start = int(0)
offset = int(0)
)
convey.Convey("Logs", t, func(ctx convey.C) {
logs, err := d.Logs(c, mid, start, offset)
ctx.Convey("Then err should be nil.logs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(logs, convey.ShouldNotBeNil)
})
})
}
func TestAssistLogsByAssist(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
assistMid = int64(0)
start = int(0)
offset = int(0)
)
convey.Convey("LogsByAssist", t, func(ctx convey.C) {
logs, err := d.LogsByAssist(c, mid, assistMid, start, offset)
ctx.Convey("Then err should be nil.logs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(logs, convey.ShouldNotBeNil)
})
})
}
func TestAssistLogsByCtime(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
stime = time.Now()
etime = time.Now()
start = int(0)
offset = int(0)
)
convey.Convey("LogsByCtime", t, func(ctx convey.C) {
logs, err := d.LogsByCtime(c, mid, stime, etime, start, offset)
ctx.Convey("Then err should be nil.logs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(logs, convey.ShouldNotBeNil)
})
})
}
func TestAssistLogsByAssistCtime(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
assistMid = int64(0)
stime = time.Now()
etime = time.Now()
start = int(0)
offset = int(0)
)
convey.Convey("LogsByAssistCtime", t, func(ctx convey.C) {
logs, err := d.LogsByAssistCtime(c, mid, assistMid, stime, etime, start, offset)
ctx.Convey("Then err should be nil.logs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(logs, convey.ShouldNotBeNil)
})
})
}
func TestAssistLogCount(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
)
convey.Convey("LogCount", t, func(ctx convey.C) {
totalm, err := d.LogCount(c, mid)
ctx.Convey("Then err should be nil.totalm should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(totalm, convey.ShouldNotBeNil)
})
})
}
func TestAssistLogCnt(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
)
convey.Convey("LogCnt", t, func(ctx convey.C) {
count, err := d.LogCnt(c, mid)
ctx.Convey("Then err should be nil.count should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(count, convey.ShouldNotBeNil)
})
})
}
func TestAssistLogCntAssist(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
assistMid = int64(0)
)
convey.Convey("LogCntAssist", t, func(ctx convey.C) {
count, err := d.LogCntAssist(c, mid, assistMid)
ctx.Convey("Then err should be nil.count should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(count, convey.ShouldNotBeNil)
})
})
}
func TestAssistLogCntCtime(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
stime = time.Now()
etime = time.Now()
)
convey.Convey("LogCntCtime", t, func(ctx convey.C) {
count, err := d.LogCntCtime(c, mid, stime, etime)
ctx.Convey("Then err should be nil.count should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(count, convey.ShouldNotBeNil)
})
})
}
func TestAssistLogCntAssistCtime(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
assistMid = int64(0)
stime = time.Now()
etime = time.Now()
)
convey.Convey("LogCntAssistCtime", t, func(ctx convey.C) {
count, err := d.LogCntAssistCtime(c, mid, assistMid, stime, etime)
ctx.Convey("Then err should be nil.count should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(count, convey.ShouldNotBeNil)
})
})
}
func TestAssistAssistsMidsTotal(t *testing.T) {
var (
c = context.Background()
mid = int64(27515409)
assmids = []int64{27515235, 27515233}
)
convey.Convey("AssistsMidsTotal", t, func(ctx convey.C) {
_, err := d.AssistsMidsTotal(c, mid, assmids)
ctx.Convey("Then err should be nil.totalm should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestAssistLogObj(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
objID = int64(0)
tp = int64(0)
act = int64(0)
)
convey.Convey("LogObj", t, func(ctx convey.C) {
a, err := d.LogObj(c, mid, objID, tp, act)
ctx.Convey("Then err should be nil.a should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(a, convey.ShouldNotBeNil)
})
})
}

View File

@ -0,0 +1,75 @@
package assist
import (
"context"
"go-common/library/cache/memcache"
"go-common/library/log"
"strconv"
)
func assistKey(mid int64) string {
return "assist_relation_mid_" + strconv.FormatInt(mid, 10)
}
// SetCacheAss fn
func (d *Dao) SetCacheAss(c context.Context, mid int64, assistMids []int64) (err error) {
conn := d.mc.Get(c)
defer conn.Close()
key := assistKey(mid)
if err = conn.Set(&memcache.Item{Key: key, Object: assistMids, Flags: memcache.FlagJSON, Expiration: 0}); err != nil {
log.Error("conn.Store error(%v) | key(%s) mid(%d) assistMids(%s)", err, key, mid, assistMids)
}
conn.Close()
return
}
// GetCacheAss GetCacheAss
func (d *Dao) GetCacheAss(c context.Context, mid int64) (assistMids []int64, err error) {
var (
key = assistKey(mid)
rp *memcache.Item
conn = d.mc.Get(c)
)
defer conn.Close()
rp, err = conn.Get(key)
if err != nil {
if err == memcache.ErrNotFound {
log.Info("memcache.Get(%s) ErrNotFound(%v)", key, err)
err = nil
} else {
log.Error("conn.Get error(%v) | key(%s)", err, key)
}
return
}
if err = conn.Scan(rp, &assistMids); err != nil {
log.Error("json.Unmarshal(%s) error(%v)", rp.Value, err)
assistMids = nil
}
return
}
// DelCacheAss fn
func (d *Dao) DelCacheAss(c context.Context, mid int64) (err error) {
conn := d.mc.Get(c)
defer conn.Close()
key := assistKey(mid)
if err = conn.Delete(key); err != nil {
if err == memcache.ErrNotFound {
log.Warn("DelCacheAss memcache.ErrNotFound key(%s)|(%+v)", key, err)
err = nil
} else {
log.Error("DelCacheAss key(%s)|err(%+v)", key, err)
}
}
return
}
func (d *Dao) pingMemcache(c context.Context) (err error) {
conn := d.mc.Get(c)
defer conn.Close()
if err = conn.Set(&memcache.Item{Key: "ping", Value: []byte("pong"), Expiration: 0}); err != nil {
log.Error("mc.ping.Store error(%v)", err)
return
}
return
}

View File

@ -0,0 +1,73 @@
package assist
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestAssistassistKey(t *testing.T) {
var (
mid = int64(0)
)
convey.Convey("assistKey", t, func(ctx convey.C) {
p1 := assistKey(mid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestAssistSetCacheAss(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
assistMids = []int64{}
)
convey.Convey("SetCacheAss", t, func(ctx convey.C) {
err := d.SetCacheAss(c, mid, assistMids)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestAssistGetCacheAss(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
)
convey.Convey("GetCacheAss", t, func(ctx convey.C) {
assistMids, err := d.GetCacheAss(c, mid)
ctx.Convey("Then err should be nil.assistMids should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(assistMids, convey.ShouldNotBeNil)
})
})
}
func TestAssistDelCacheAss(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
)
convey.Convey("DelCacheAss", t, func(ctx convey.C) {
err := d.DelCacheAss(c, mid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestAssistpingMemcache(t *testing.T) {
var (
c = context.Background()
)
convey.Convey("pingMemcache", t, func(ctx convey.C) {
err := d.pingMemcache(c)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}

View File

@ -0,0 +1,43 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["dao_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = ["//app/service/main/assist/conf:go_default_library"],
)
go_library(
name = "go_default_library",
srcs = ["dao.go"],
importpath = "go-common/app/service/main/assist/dao/message",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/assist/conf:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster: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"],
)

View File

@ -0,0 +1,57 @@
package message
import (
"context"
"fmt"
"go-common/app/service/main/assist/conf"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"net/url"
"strconv"
)
const (
_messageURI = "/api/notify/send.user.notify.do"
)
// Dao is message dao.
type Dao struct {
c *conf.Config
client *bm.Client
uri string
}
// New new a message dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
client: bm.NewClient(c.HTTPClient.Slow),
uri: c.Host.Message + _messageURI,
}
return d
}
// Send send message form uper to assistMid.
func (d *Dao) Send(c context.Context, mc, title, msg string, mid int64) (err error) {
params := url.Values{}
params.Set("type", "json")
params.Set("source", "1")
params.Set("data_type", "4")
params.Set("mc", mc)
params.Set("title", title)
params.Set("context", msg)
params.Set("mid_list", strconv.FormatInt(mid, 10))
var res struct {
Code int `json:"code"`
}
if err = d.client.Post(c, d.uri, "", params, &res); err != nil {
log.Error("message url(%s) error(%v)", d.uri+"?"+params.Encode(), err)
return
}
log.Info("SendSysNotify url: (%s)", d.uri+"?"+params.Encode())
if res.Code != 0 {
log.Error("message url(%s) error(%v)", d.uri+"?"+params.Encode(), res.Code)
err = fmt.Errorf("message send failed")
}
return
}

View File

@ -0,0 +1,35 @@
package message
import (
"flag"
"go-common/app/service/main/assist/conf"
"os"
"testing"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.archive.assist-service")
flag.Set("conf_token", "6e0dae2c95d90ff8d0da53460ef11ae8")
flag.Set("tree_id", "2084")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
} else {
flag.Set("conf", "../cmd/assist-service.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
m.Run()
os.Exit(0)
}

View File

@ -0,0 +1,43 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"assist.go",
"http.go",
"local.go",
],
importpath = "go-common/app/service/main/assist/http",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/assist/conf:go_default_library",
"//app/service/main/assist/model/assist:go_default_library",
"//app/service/main/assist/service:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/http/blademaster/middleware/verify:go_default_library",
"//library/net/http/blademaster/render:go_default_library",
"//library/xstr: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"],
)

View File

@ -0,0 +1,450 @@
package http
//assist 创作中心协管相关
import (
"go-common/app/service/main/assist/model/assist"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/render"
"go-common/library/xstr"
"net/http"
"strconv"
"time"
)
func assists(c *bm.Context) {
midStr := c.Request.Form.Get("mid")
mid, err := strconv.ParseInt(midStr, 10, 64)
if err != nil {
log.Error("strconv.ParseInt(%s) error(%v)", midStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
assists, err := assSvc.Assists(c, mid)
if err != nil {
log.Error("assistSvc.Assists(%v) error(%v)", assists, mid)
return
}
c.JSON(assists, nil)
}
func assistsMids(c *bm.Context) {
params := c.Request.Form
midStr := params.Get("mid")
mid, err := strconv.ParseInt(midStr, 10, 64)
if err != nil {
log.Error("strconv.ParseInt(%s) error(%v)", midStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
assmidsStr := params.Get("assmids")
assmids, err := xstr.SplitInts(assmidsStr)
if err != nil {
log.Error("strconv.ParseInt(%s) error(%v)", assmidsStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
if len(assmids) > 20 {
log.Error("assmids(%d) number gt 20", len(assmids))
c.JSON(nil, ecode.RequestErr)
return
}
asByMids, err := assSvc.AssistsMidsTotal(c, mid, assmids)
if err != nil {
log.Error("assistSvc.AssistsMidsTotal(%v), mids(%v), assmids(%v), error(%v)", asByMids, mid, assmids, err)
c.JSON(nil, err)
return
}
c.JSON(asByMids, nil)
}
func assistInfo(c *bm.Context) {
params := c.Request.Form
midStr := params.Get("mid")
mid, err := strconv.ParseInt(midStr, 10, 64)
if err != nil {
log.Error("strconv.ParseInt(%s) error(%v)", midStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
assistMidStr := params.Get("assist_mid")
assistMid, err := strconv.ParseInt(assistMidStr, 10, 64)
if err != nil {
log.Error("strconv.ParseInt(%s) error(%v)", assistMidStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
typeStr := params.Get("type")
tp, err := strconv.ParseInt(typeStr, 10, 64)
if err != nil {
log.Error("strconv.ParseInt(%s) error(%v)", typeStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
assist, err := assSvc.Assist(c, mid, assistMid, tp)
if err != nil {
c.JSON(nil, err)
log.Error("assSvc.Assist(%s) error(%v)|mid(%d)|assistMid(%d)", assist, err, mid, assistMid)
return
}
c.JSON(assist, nil)
}
func assistIDs(c *bm.Context) {
params := c.Request.Form
midStr := params.Get("mid")
mid, err := strconv.ParseInt(midStr, 10, 64)
if err != nil {
log.Error("strconv.ParseInt(%s) error(%v)", midStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
ids, err := assSvc.AssistIDs(c, mid)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(ids, nil)
}
func assistAdd(c *bm.Context) {
params := c.Request.Form
midStr := params.Get("mid")
// mid
mid, err := strconv.ParseInt(midStr, 10, 64)
if err != nil {
log.Error("strconv.ParseInt(%s) error(%v)", midStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
assistMidStr := params.Get("assist_mid")
assistMid, err := strconv.ParseInt(assistMidStr, 10, 64)
if err != nil || assistMid == 0 {
log.Error("strconv.ParseInt(%s) error(%v)", assistMidStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
if err = assSvc.AddAssist(c, mid, assistMid); err != nil {
c.JSON(nil, err)
return
}
c.JSON(map[string]interface{}{
"mid": mid,
"assist_mid": assistMid,
}, nil)
}
func assistDel(c *bm.Context) {
params := c.Request.Form
midStr := params.Get("mid")
mid, err := strconv.ParseInt(midStr, 10, 64)
if err != nil {
log.Error("strconv.ParseInt(%s) error(%v)", midStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
assistMidStr := params.Get("assist_mid")
assistMid, err := strconv.ParseInt(assistMidStr, 10, 64)
if err != nil {
log.Error("strconv.ParseInt(%s) error(%v)", assistMidStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
if err := assSvc.DelAssist(c, mid, assistMid); err != nil {
c.JSON(nil, err)
return
}
c.JSON(map[string]interface{}{
"mid": mid,
"assist_mid": assistMid,
}, nil)
}
// exist to be assist from follower
func assistExit(c *bm.Context) {
params := c.Request.Form
midStr := params.Get("mid")
mid, err := strconv.ParseInt(midStr, 10, 64)
if err != nil {
log.Error("strconv.ParseInt(%s) error(%v)", midStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
assistMidStr := params.Get("assist_mid")
assistMid, err := strconv.ParseInt(assistMidStr, 10, 64)
if err != nil {
log.Error("strconv.ParseInt(%s) error(%v)", assistMidStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
if err := assSvc.Exit(c, mid, assistMid); err != nil {
c.JSON(nil, err)
return
}
c.JSON(map[string]interface{}{
"mid": mid,
"assist_mid": assistMid,
}, nil)
}
func assistLogs(c *bm.Context) {
params := c.Request.Form
midStr := params.Get("mid")
var (
err error
mid, assistMid, ps, pn, total, bgnCtime, endCtime int64
assistLogs []*assist.Log
)
mid, err = strconv.ParseInt(midStr, 10, 64)
if err != nil {
log.Error("strconv.ParseInt(%s) error(%v)", midStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
assistMidStr := params.Get("assist_mid")
assistMid, _ = strconv.ParseInt(assistMidStr, 10, 64)
pnStr := params.Get("pn")
psStr := params.Get("ps")
ps, err = strconv.ParseInt(psStr, 10, 64)
if err != nil || ps <= 10 {
ps = 10
}
pn, err = strconv.ParseInt(pnStr, 10, 64)
if err != nil || pn < 1 {
pn = 1
}
bgnCtimeStr := params.Get("stime")
bgnCtime, err = strconv.ParseInt(bgnCtimeStr, 10, 64)
if err != nil || bgnCtime <= 0 {
bgnCtime = time.Now().Add(-time.Hour * 72).Unix()
}
endCtimeStr := params.Get("etime")
endCtime, err = strconv.ParseInt(endCtimeStr, 10, 64)
if err != nil || endCtime <= 0 {
endCtime = time.Now().Unix()
}
formatedBgnCtime := time.Unix(bgnCtime, 0)
formatedEndCtime := time.Unix(endCtime, 0)
assistLogs, err = assSvc.Logs(c, mid, assistMid, formatedBgnCtime, formatedEndCtime, int((pn-1)*ps), int(ps))
if err != nil {
log.Error("assistSvc.AssistLogs(%v) error(%v)", assistLogs, err)
return
}
total, err = assSvc.LogCnt(c, mid, assistMid, formatedBgnCtime, formatedEndCtime)
if err != nil {
log.Error("assSvc.LogCnt: mid (%d),assistMid (%d),bgnctime (%v),endctime (%v):error(%v)", mid, assistMid, formatedBgnCtime, formatedEndCtime, err)
return
}
c.Render(http.StatusOK, render.MapJSON(map[string]interface{}{
"code": 0,
"message": "0",
"data": assistLogs,
"pager": map[string]int64{
"current": pn,
"size": ps,
"total": total,
},
}))
}
func assistLogAdd(c *bm.Context) {
params := c.Request.Form
midStr := params.Get("mid")
mid, err := strconv.ParseInt(midStr, 10, 64)
if err != nil {
log.Error("strconv.ParseInt(%s) error(%v)", midStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
assistMidStr := params.Get("assist_mid")
assistMid, err := strconv.ParseInt(assistMidStr, 10, 64)
if err != nil {
log.Error("strconv.ParseInt(%s) error(%v)", assistMidStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
tpStr := params.Get("type")
tp, err := strconv.ParseInt(tpStr, 10, 64)
if err != nil {
log.Error("strconv.ParseInt(%s) error(%v)", tpStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
actStr := params.Get("action")
act, err := strconv.ParseInt(actStr, 10, 64)
if err != nil {
log.Error("strconv.ParseInt(%s) error(%v)", act, err)
c.JSON(nil, ecode.RequestErr)
return
}
subIDStr := params.Get("subject_id")
subID, err := strconv.ParseInt(subIDStr, 10, 64)
if err != nil || subID <= 0 {
log.Error("strconv.ParseInt(%s) error(%v)", subIDStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
objIDStr := params.Get("object_id")
if len(objIDStr) == 0 {
log.Error("objIDStr length eq zero(%s)", objIDStr)
c.JSON(nil, ecode.RequestErr)
return
}
detail := params.Get("detail")
if len(detail) == 0 {
log.Error("detail len is zero (%s) error(%v)", detail, err)
c.JSON(nil, ecode.RequestErr)
return
}
if err = assSvc.AddLog(c, mid, assistMid, tp, act, subID, objIDStr, detail); err != nil {
c.JSON(nil, err)
return
}
c.JSON(map[string]interface{}{
"mid": mid,
"assist_mid": assistMid,
"type": tp,
"action": act,
"subject_id": subID,
"object_id": objIDStr,
}, nil)
}
func assistLogCancel(c *bm.Context) {
params := c.Request.Form
midStr := params.Get("mid")
mid, err := strconv.ParseInt(midStr, 10, 64)
if err != nil {
log.Error("strconv.ParseInt(%s) error(%v)", midStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
logIDStr := params.Get("log_id")
logID, err := strconv.ParseInt(logIDStr, 10, 64)
if err != nil || logID <= 0 {
log.Error("strconv.ParseInt(%s) error(%v)", logIDStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
assistMidStr := params.Get("assist_mid")
assistMid, _ := strconv.ParseInt(assistMidStr, 10, 64)
if assistMid < 1 {
log.Error("strconv.ParseInt(%s) error(%v)", assistMid, err)
c.JSON(nil, ecode.RequestErr)
return
}
if err := assSvc.CancelLog(c, mid, assistMid, logID); err != nil {
c.JSON(nil, err)
return
}
c.JSON(map[string]interface{}{
"mid": mid,
"assist_mid": assistMid,
"log_id": logID,
}, nil)
}
func assistLogInfo(c *bm.Context) {
params := c.Request.Form
logIDStr := params.Get("log_id")
logID, err := strconv.ParseInt(logIDStr, 10, 64)
if err != nil || logID <= 0 {
log.Error("strconv.ParseInt(%s) error(%v)", logIDStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
midStr := params.Get("mid")
mid, err := strconv.ParseInt(midStr, 10, 64)
if err != nil {
log.Error("strconv.ParseInt(%s) error(%v)", midStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
assistMidStr := params.Get("assist_mid")
assistMid, _ := strconv.ParseInt(assistMidStr, 10, 64)
if assistMid < 1 {
log.Error("strconv.ParseInt(%s) error(%v)", assistMid, err)
c.JSON(nil, ecode.RequestErr)
return
}
logInfo, err := assSvc.LogInfo(c, logID, mid, assistMid)
if err != nil {
c.JSON(nil, err)
log.Error("assSvc.Assist(%s) error(%v)|logId(%d)|mid(%d)|assistMid(%d)", logInfo, err, logID, mid, assistMid)
return
}
c.JSON(logInfo, nil)
}
func assistUps(c *bm.Context) {
params := c.Request.Form
assistMidStr := params.Get("assist_mid")
assistMid, err := strconv.ParseInt(assistMidStr, 10, 64)
if err != nil {
log.Error("strconv.ParseInt(%s) error(%v)", assistMidStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
pnStr := params.Get("pn")
psStr := params.Get("ps")
pn, err := strconv.ParseInt(pnStr, 10, 64)
if err != nil || pn < 1 {
pn = 1
}
ps, err := strconv.ParseInt(psStr, 10, 64)
if err != nil || ps <= 20 {
ps = 20
}
assistUpsPager, err := assSvc.AssistUps(c, assistMid, pn, ps)
if err != nil {
c.JSON(nil, err)
return
}
c.Render(http.StatusOK, render.MapJSON(map[string]interface{}{
"code": 0,
"message": "",
"data": assistUpsPager.Data,
"pager": assistUpsPager.Pager,
}))
}
func assistLogObj(c *bm.Context) {
params := c.Request.Form
objIDStr := params.Get("object_id")
objID, err := strconv.ParseInt(objIDStr, 10, 64)
if err != nil || objID <= 0 {
log.Error("strconv.ParseInt(%s) error(%v)", objIDStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
midStr := params.Get("mid")
mid, err := strconv.ParseInt(midStr, 10, 64)
if err != nil || mid <= 0 {
log.Error("strconv.ParseInt(%s) error(%v)", midStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
tpStr := params.Get("type")
tp, err := strconv.ParseInt(tpStr, 10, 64)
if err != nil {
log.Error("strconv.ParseInt(%s) error(%v)", tpStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
actStr := params.Get("action")
act, _ := strconv.ParseInt(actStr, 10, 64)
if act < 1 {
log.Error("strconv.ParseInt(%s) error(%v)", act, err)
c.JSON(nil, ecode.RequestErr)
return
}
logInfo, err := assSvc.LogObj(c, mid, objID, tp, act)
if err != nil {
c.JSON(nil, err)
log.Error("assSvc.LogObj(%s) error(%v)|mid(%d)|logId(%d)|tp(%d)|act(%d)", logInfo, err, mid, objID, tp, act)
return
}
c.JSON(logInfo, nil)
}

View File

@ -0,0 +1,47 @@
package http
import (
"go-common/app/service/main/assist/conf"
"go-common/app/service/main/assist/service"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/middleware/verify"
)
var (
assSvc *service.Service
verifySvc *verify.Verify
)
// Init init account service.
func Init(c *conf.Config, s *service.Service) {
assSvc = service.New(c)
verifySvc = verify.New(nil)
engineInner := bm.DefaultServer(c.BM)
innerRouter(engineInner)
if err := engineInner.Start(); err != nil {
log.Error("engineInner.Start() error(%v) | config(%v)", err, c)
panic(err)
}
}
// innerRouter init inner router.
func innerRouter(e *bm.Engine) {
e.GET("/monitor/ping", ping)
cr := e.Group("/x/internal/assist", verifySvc.Verify)
{
cr.GET("/assists", assists)
cr.GET("/ups", assistUps)
cr.GET("/stat", assistsMids)
cr.GET("/info", assistInfo)
cr.GET("/ids", assistIDs)
cr.POST("/add", assistAdd)
cr.POST("/del", assistDel)
cr.POST("/exit", assistExit)
cr.GET("/logs", assistLogs)
cr.GET("/log/info", assistLogInfo)
cr.POST("/log/add", assistLogAdd)
cr.POST("/log/cancel", assistLogCancel)
cr.GET("/log/obj", assistLogObj)
}
}

View File

@ -0,0 +1,17 @@
package http
import (
"net/http"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
// ping check server ok.
func ping(c *bm.Context) {
var err error
if err = assSvc.Ping(c); err != nil {
log.Error("assist-service ping error(%v)", err)
c.AbortWithStatus(http.StatusServiceUnavailable)
}
}

View File

@ -0,0 +1,20 @@
package(default_visibility = ["//visibility:public"])
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/service/main/assist/model/assist:all-srcs",
"//app/service/main/assist/model/message:all-srcs",
"//app/service/main/assist/model/notify:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,37 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"assist.go",
"rpc.go",
],
importpath = "go-common/app/service/main/assist/model/assist",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/account/api:go_default_library",
"//app/service/main/account/model:go_default_library",
"//library/ecode:go_default_library",
"//library/time: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"],
)

View File

@ -0,0 +1,121 @@
package assist
import (
accv1 "go-common/app/service/main/account/api"
accmdl "go-common/app/service/main/account/model"
"go-common/library/ecode"
"go-common/library/time"
)
var (
// ActEnum action enum
ActEnum = map[int64]string{
1: "delete", // 删除
2: "shield/hide", // 屏蔽或隐藏
3: "protect", // 保护
4: "disUser", // 拉黑用户
5: "dmPoolMove", // 移动弹幕到字幕池
6: "dmPoolIgnore", // 忽略字幕池的弹幕
7: "cancelDisUser", // 取消拉黑用户 reverse of disUser
8: "silence", // 直播禁言用户
9: "cancelSilence", // 直播取消禁言用户 reverse of silence
}
// TypeEnum type enum
TypeEnum = map[int64]string{
1: "arc_com", // 稿件的评论
2: "arc_dm", // 稿件的弹幕
3: "live", // 直播的禁言
}
// IdentifyEnum map
IdentifyEnum = map[int]error{
1: ecode.UserIDCheckInvalidCard,
2: ecode.UserIDCheckInvalidPhone,
}
)
const (
//Act Enum
ActDelete = 1 // 删除
ActShieldOrHide = 2 // 屏蔽或隐藏
ActProtect = 3 // 保护
ActDisUser = 4 // 拉黑用户
ActDmPoolMove = 5 // 移动弹幕到字幕池
ActDmPoolIgnore = 6 // 移动弹幕到字幕池
ActCancelDisUser = 7 // 取消拉黑用户 reverse of ActDisUser
ActSilence = 8 // 直播禁言用户
ActCancelSilence = 9 // 直播取消禁言用户 reverse of ActCancelSilence
//TypeEnum
TypeComment = 1
TypeDm = 2
TypeLive = 3
)
// Assist is Assists model.
type Assist struct {
Mid int64 `json:"mid"`
AssistMid int64 `json:"assist_mid"`
State int8 `json:"state"`
CTime time.Time `json:"ctime"`
MTime time.Time `json:"mtime"`
Total map[int8]map[int8]int `json:"total"`
}
// Log is single record for assist done
type Log struct {
ID int64 `json:"id"`
Mid int64 `json:"mid"`
AssistMid int64 `json:"assist_mid"`
Type int8 `json:"type"`
Action int8 `json:"action"`
SubjectID int64 `json:"subject_id"`
ObjectID string `json:"object_id"`
Detail string `json:"detail"`
State int8 `json:"state"`
CTime time.Time `json:"ctime"`
MTime time.Time `json:"-"`
}
// AssistRes is Assists model.
type AssistRes struct {
Allow int64 `json:"allow"`
Assist int64 `json:"assist"`
Count int64 `json:"count"`
}
// Up is AssitUp model for space
type Up struct {
Mid int64 `json:"mid"`
CTime time.Time `json:"-"`
}
// AssistUp is AssitUp model for space
type AssistUp struct {
Mid int64 `json:"mid"`
Name string `json:"uname"`
Sign string `json:"sign"`
Avatar string `json:"face"`
OfficialVerify accv1.OfficialInfo `json:"official_verify"`
CTime time.Time `json:"-"`
Vip accmdl.VipInfo `json:"vip"`
}
// Pager struct
type Pager struct {
Pn int64 `json:"current"`
Ps int64 `json:"size"`
Total int64 `json:"total"`
}
type AssistUpsPager struct {
Data []*AssistUp `json:"data"`
Pager Pager `json:"pager"`
}
// SortUpsByCtime .
type SortUpsByCtime []*AssistUp
func (as SortUpsByCtime) Len() int { return len(as) }
func (as SortUpsByCtime) Less(i, j int) bool {
return as[i].CTime > as[j].CTime
}
func (as SortUpsByCtime) Swap(i, j int) { as[i], as[j] = as[j], as[i] }

View File

@ -0,0 +1,51 @@
package assist
import "time"
type ArgAssists struct {
Mid int64
RealIP string
}
type ArgAssist struct {
Mid int64
AssistMid int64
Type int64
RealIP string
}
// ArgAssistLogAdd add log
type ArgAssistLogAdd struct {
Mid int64
AssistMid int64
Type int64
Action int64
SubjectID int64
ObjectID string
Detail string
RealIP string
}
type ArgAssistLog struct {
Mid int64
AssistMid int64
LogID int64
RealIP string
}
type ArgAssistLogs struct {
Mid int64
AssistMid int64
Stime time.Time
Etime time.Time
Pn int
Ps int
RealIP string
}
type ArgAssistUps struct {
AssistMid int64
Pn int64
Ps int64
RealIP string
}

View File

@ -0,0 +1,28 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["message.go"],
importpath = "go-common/app/service/main/assist/model/message",
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,17 @@
package message
// Relation str map to databus message
type Relation struct {
Action string `json:"action"`
Table string `json:"table"`
New struct {
Attr int `json:"attribute"`
FID int64 `json:"fid"`
MID int64 `json:"mid"`
} `json:"new"`
Old struct {
Attr int `json:"attribute"`
FID int64 `json:"fid"`
MID int64 `json:"mid"`
}
}

View File

@ -0,0 +1,28 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["notify.go"],
importpath = "go-common/app/service/main/assist/model/notify",
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,15 @@
package notify
// AddTitle
const (
AddTitle = "骑士任命"
DelTitle = "解除骑士"
DelFollowerTitle = "拒绝加入您的骑士团"
AddContent = `你已经被up主#{%s>>}{"http://space.bilibili.com/%d/#!/"} 任命为骑士, 若想取消任命, 可前往关注列表处退出up主#{%s>>}{"http://space.bilibili.com/%d/#!/fans/follow"}的骑士团`
DelContent = `你已经被up主#{%s>>}{"http://space.bilibili.com/%d/#!/"} 取消了骑士权限`
DelFollowerContent = `#{%s>>}{"http://space.bilibili.com/%d/#!/"} 拒绝成为你的骑士团。退出成功!`
Mc = "1_8_1"
AddAssNotifyAct = 1
DelAssNotifyAct = 2
DelAssNotifyFollowerAct = 3
)

View File

@ -0,0 +1,17 @@
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/service/main/assist/rpc/client:all-srcs",
"//app/service/main/assist/rpc/server:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,45 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["assist_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/service/main/assist/model/assist:go_default_library",
"//vendor/github.com/davecgh/go-spew/spew:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["assist.go"],
importpath = "go-common/app/service/main/assist/rpc/client",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/assist/model/assist:go_default_library",
"//library/net/rpc: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"],
)

View File

@ -0,0 +1,112 @@
package client
import (
"context"
"go-common/library/net/rpc"
model "go-common/app/service/main/assist/model/assist"
)
const (
_assists = "RPC.Assists"
_assistIDs = "RPC.AssistIDs"
_assist = "RPC.Assist"
_assistExit = "RPC.AssistExit"
_addAssist = "RPC.AddAssist"
_delAssist = "RPC.DelAssist"
_assistLogs = "RPC.AssistLogs"
_assistLogInfo = "RPC.AssistLogInfo"
_assistLogAdd = "RPC.AssistLogAdd"
_assistLogCancel = "RPC.AssistLogCancel"
_assistUps = "RPC.AssistUps"
)
const (
_appid = "archive.service.assist"
)
var (
_noArg = &struct{}{}
)
// Service def
type Service struct {
client *rpc.Client2
}
// New def
func New(c *rpc.ClientConfig) (s *Service) {
s = &Service{}
s.client = rpc.NewDiscoveryCli(_appid, c)
return s
}
// Assists def
func (s *Service) Assists(c context.Context, arg *model.ArgAssists) (res []*model.Assist, err error) {
err = s.client.Call(c, _assists, arg, &res)
return
}
// AssistIDs def
func (s *Service) AssistIDs(c context.Context, arg *model.ArgAssists) (res []int64, err error) {
err = s.client.Call(c, _assistIDs, arg, &res)
return
}
// Assist def
func (s *Service) Assist(c context.Context, arg *model.ArgAssist) (res *model.AssistRes, err error) {
res = new(model.AssistRes)
err = s.client.Call(c, _assist, arg, &res)
return
}
// AddAssist def
func (s *Service) AddAssist(c context.Context, arg *model.ArgAssist) (err error) {
err = s.client.Call(c, _addAssist, arg, _noArg)
return
}
// DelAssist def
func (s *Service) DelAssist(c context.Context, arg *model.ArgAssist) (err error) {
err = s.client.Call(c, _delAssist, arg, _noArg)
return
}
// AssistLogs def
func (s *Service) AssistLogs(c context.Context, arg *model.ArgAssistLogs) (res []*model.Log, err error) {
err = s.client.Call(c, _assistLogs, arg, &res)
return
}
// AssistLogInfo def
func (s *Service) AssistLogInfo(c context.Context, arg *model.ArgAssistLog) (res *model.Log, err error) {
res = new(model.Log)
err = s.client.Call(c, _assistLogInfo, arg, &res)
return
}
// AssistLogAdd def
func (s *Service) AssistLogAdd(c context.Context, arg *model.ArgAssistLogAdd) (err error) {
err = s.client.Call(c, _assistLogAdd, arg, _noArg)
return
}
// AssistLogCancel def
func (s *Service) AssistLogCancel(c context.Context, arg *model.ArgAssistLog) (err error) {
err = s.client.Call(c, _assistLogCancel, arg, _noArg)
return
}
// AssistUps def
func (s *Service) AssistUps(c context.Context, arg *model.ArgAssistUps) (res *model.AssistUpsPager, err error) {
res = new(model.AssistUpsPager)
err = s.client.Call(c, _assistUps, arg, &res)
return
}
// AssistExit def
func (s *Service) AssistExit(c context.Context, arg *model.ArgAssist) (err error) {
err = s.client.Call(c, _assistExit, arg, _noArg)
return
}

View File

@ -0,0 +1,175 @@
package client
import (
"context"
"testing"
"time"
model "go-common/app/service/main/assist/model/assist"
"github.com/davecgh/go-spew/spew"
)
const (
mid = 27515256
assistMid = 27515255
realIP = "127.0.0.1"
logID = 692
subjectID = 111
objectID = "222"
detail = "testing"
pn = 1
ps = 20
)
func TestAssistRpcService(t *testing.T) {
s := New(nil)
time.Sleep(1 * time.Second)
// test assist relation
delAssist(t, s)
addAssist(t, s)
assist(t, s)
assists(t, s)
assistIDs(t, s)
assistUps(t, s)
assistExit(t, s)
// test assistlog
assistLogAdd(t, s)
assistLogInfo(t, s)
assistLogCancel(t, s)
assistLogs(t, s)
}
func delAssist(t *testing.T, s *Service) {
arg := &model.ArgAssist{
Mid: mid,
AssistMid: assistMid,
RealIP: realIP,
}
if err := s.DelAssist(context.TODO(), arg); err != nil {
t.Logf("call error(%v)", err)
}
}
func addAssist(t *testing.T, s *Service) {
arg := &model.ArgAssist{
Mid: mid,
AssistMid: assistMid,
RealIP: realIP,
}
if err := s.AddAssist(context.TODO(), arg); err != nil {
t.Logf("call error(%v)", err)
}
}
func assistLogAdd(t *testing.T, s *Service) {
arg := &model.ArgAssistLogAdd{
Mid: mid,
AssistMid: assistMid,
Type: model.TypeComment,
Action: model.ActDelete,
SubjectID: subjectID,
ObjectID: objectID,
Detail: detail,
RealIP: realIP,
}
if err := s.AssistLogAdd(context.TODO(), arg); err != nil {
t.Logf("call error(%v)", err)
}
}
func assists(t *testing.T, s *Service) {
arg := &model.ArgAssists{
Mid: mid,
RealIP: realIP,
}
if res, err := s.Assists(context.TODO(), arg); err != nil && res != nil {
t.Logf("call error(%v)", err)
}
}
func assistIDs(t *testing.T, s *Service) {
arg := &model.ArgAssists{
Mid: mid,
RealIP: realIP,
}
if res, err := s.AssistIDs(context.TODO(), arg); err != nil && res != nil {
t.Logf("call error(%v)", err)
}
}
func assistUps(t *testing.T, s *Service) {
arg := &model.ArgAssistUps{
AssistMid: assistMid,
Ps: 20,
Pn: 1,
RealIP: realIP,
}
if res, err := s.AssistUps(context.TODO(), arg); err != nil && res != nil {
spew.Dump(res)
t.Logf("call error(%v)", err)
}
}
func assistExit(t *testing.T, s *Service) {
arg := &model.ArgAssist{
AssistMid: assistMid,
Mid: mid,
RealIP: realIP,
}
if err := s.AssistExit(context.TODO(), arg); err != nil {
t.Logf("call error(%v)", err)
}
}
func assistLogInfo(t *testing.T, s *Service) {
arg := &model.ArgAssistLog{
Mid: mid,
AssistMid: assistMid,
LogID: logID,
RealIP: realIP,
}
if res, err := s.AssistLogInfo(context.TODO(), arg); err != nil && res != nil {
t.Logf("call error(%v)", err)
}
}
func assist(t *testing.T, s *Service) {
arg := &model.ArgAssist{
Mid: mid,
AssistMid: assistMid,
RealIP: realIP,
}
if res, err := s.Assist(context.TODO(), arg); err != nil && res != nil {
spew.Dump(res)
t.Logf("call error(%v)", err)
}
}
func assistLogs(t *testing.T, s *Service) {
arg := &model.ArgAssistLogs{
Mid: mid,
AssistMid: assistMid,
Stime: time.Unix(time.Now().Unix(), 0),
Etime: time.Unix(time.Now().Add(48*time.Hour).Unix(), 0),
Pn: ps,
Ps: pn,
RealIP: realIP,
}
if res, err := s.AssistLogs(context.TODO(), arg); err != nil && res != nil {
t.Logf("call error(%v)", err)
}
}
func assistLogCancel(t *testing.T, s *Service) {
arg := &model.ArgAssistLog{
Mid: mid,
AssistMid: assistMid,
LogID: logID,
RealIP: realIP,
}
if err := s.AssistLogCancel(context.TODO(), arg); err != nil {
t.Logf("call error(%v)", err)
}
}

View File

@ -0,0 +1,54 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["rpc_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/service/main/assist/conf:go_default_library",
"//app/service/main/assist/model/assist:go_default_library",
"//app/service/main/assist/service:go_default_library",
"//vendor/github.com/davecgh/go-spew/spew:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"rpc.go",
"rpc_assist.go",
"rpc_log.go",
],
importpath = "go-common/app/service/main/assist/rpc/server",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/assist/conf:go_default_library",
"//app/service/main/assist/model/assist:go_default_library",
"//app/service/main/assist/service:go_default_library",
"//library/net/rpc:go_default_library",
"//library/net/rpc/context: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"],
)

View File

@ -0,0 +1,33 @@
package server
import (
"go-common/app/service/main/assist/conf"
"go-common/app/service/main/assist/service"
"go-common/library/net/rpc"
"go-common/library/net/rpc/context"
)
// RPC rpc.
type RPC struct {
s *service.Service
}
// New new rpc server.
func New(c *conf.Config, s *service.Service) (svr *rpc.Server) {
r := &RPC{s: s}
svr = rpc.NewServer(c.RPCServer)
if err := svr.Register(r); err != nil {
panic(err)
}
return
}
// Auth check connection success.
func (r *RPC) Auth(c context.Context, arg *rpc.Auth, res *struct{}) (err error) {
return
}
// Ping check connection success.
func (r *RPC) Ping(c context.Context, arg *struct{}, res *struct{}) (err error) {
return
}

View File

@ -0,0 +1,49 @@
package server
import (
"go-common/app/service/main/assist/model/assist"
"go-common/library/net/rpc/context"
)
func (r *RPC) Assists(c context.Context, arg *assist.ArgAssists, res *[]*assist.Assist) (err error) {
*res, err = r.s.Assists(c, arg.Mid)
return
}
func (r *RPC) AssistIDs(c context.Context, arg *assist.ArgAssists, res *[]int64) (err error) {
*res, err = r.s.AssistIDs(c, arg.Mid)
return
}
func (r *RPC) Assist(c context.Context, arg *assist.ArgAssist, res *assist.AssistRes) (err error) {
var info *assist.AssistRes
if info, err = r.s.Assist(c, arg.Mid, arg.AssistMid, arg.Type); err == nil && info != nil {
*res = *info
}
return
}
func (r *RPC) AddAssist(c context.Context, arg *assist.ArgAssist, res *struct{}) (err error) {
err = r.s.AddAssist(c, arg.Mid, arg.AssistMid)
return
}
func (r *RPC) DelAssist(c context.Context, arg *assist.ArgAssist, res *struct{}) (err error) {
err = r.s.DelAssist(c, arg.Mid, arg.AssistMid)
return
}
func (r *RPC) AssistUps(c context.Context, arg *assist.ArgAssistUps, res *assist.AssistUpsPager) (err error) {
var info *assist.AssistUpsPager
if info, err = r.s.AssistUps(c, arg.AssistMid, arg.Pn, arg.Ps); err == nil && info != nil {
*res = *info
}
return
}
// AssistExit notice: reuse arg *assist.ArgAssist, except Type field
func (r *RPC) AssistExit(c context.Context, arg *assist.ArgAssist, res *struct{}) (err error) {
err = r.s.Exit(c, arg.Mid, arg.AssistMid)
return
}

View File

@ -0,0 +1,30 @@
package server
import (
"go-common/app/service/main/assist/model/assist"
"go-common/library/net/rpc/context"
)
func (r *RPC) AssistLogAdd(c context.Context, arg *assist.ArgAssistLogAdd, res *struct{}) (err error) {
err = r.s.AddLog(c, arg.Mid, arg.AssistMid, arg.Type, arg.Action, arg.SubjectID, arg.ObjectID, arg.Detail)
return
}
func (r *RPC) AssistLogCancel(c context.Context, arg *assist.ArgAssistLog, res *struct{}) (err error) {
err = r.s.CancelLog(c, arg.Mid, arg.AssistMid, arg.LogID)
return
}
func (r *RPC) AssistLogs(c context.Context, arg *assist.ArgAssistLogs, res *[]*assist.Log) (err error) {
*res, err = r.s.Logs(c, arg.Mid, arg.AssistMid, arg.Stime, arg.Etime, arg.Pn, arg.Ps)
return
}
func (r *RPC) AssistLogInfo(c context.Context, arg *assist.ArgAssistLog, res *assist.Log) (err error) {
var info *assist.Log
if info, err = r.s.LogInfo(c, arg.LogID, arg.Mid, arg.AssistMid); err == nil && info != nil {
*res = *info
}
return
}

View File

@ -0,0 +1,342 @@
package server
import (
"go-common/app/service/main/assist/conf"
"go-common/app/service/main/assist/model/assist"
model "go-common/app/service/main/assist/model/assist"
"go-common/app/service/main/assist/service"
"net/rpc"
"testing"
"time"
"github.com/davecgh/go-spew/spew"
)
const (
addr = "127.0.0.1:6729"
_assists = "RPC.Assists"
_assist = "RPC.Assist"
_addAssist = "RPC.AddAssist"
_delAssist = "RPC.DelAssist"
_assistExit = "RPC.AssistExit"
_assistLogInfo = "RPC.AssistLogInfo"
_assistLogs = "RPC.AssistLogs"
_assistLogAdd = "RPC.AssistLogAdd"
_assistLogCancel = "RPC.AssistLogCancel"
_assistUps = "RPC.AssistUps"
)
func TestAssistExit(t *testing.T) {
if err := conf.Init(); err != nil {
t.Errorf("conf.Init() error(%v)", err)
t.FailNow()
}
svr := service.New(conf.Conf)
New(conf.Conf, svr)
client, err := rpc.Dial("tcp", addr)
defer client.Close()
if err != nil {
t.Errorf("rpc.Dial(tcp, \"%s\") error(%v)", addr, err)
t.FailNow()
}
assistExit(client, t)
}
func assistExit(client *rpc.Client, t *testing.T) {
assistInfo := new(struct{})
arg := &model.ArgAssist{
Mid: 254386,
AssistMid: 2,
RealIP: "127.0.0.1",
}
err := client.Call(_assistExit, arg, assistInfo)
if err != nil {
t.Logf("err:%v.", err)
}
spew.Dump(assistInfo)
}
func TestAssistUps(t *testing.T) {
if err := conf.Init(); err != nil {
t.Errorf("conf.Init() error(%v)", err)
t.FailNow()
}
svr := service.New(conf.Conf)
New(conf.Conf, svr)
client, err := rpc.Dial("tcp", addr)
defer client.Close()
if err != nil {
t.Errorf("rpc.Dial(tcp, \"%s\") error(%v)", addr, err)
t.FailNow()
}
assistUps(client, t)
}
func assistUps(client *rpc.Client, t *testing.T) {
var res = &assist.AssistUpsPager{}
arg := &model.ArgAssistUps{
AssistMid: 88889017,
Pn: 1,
Ps: 20,
RealIP: "127.0.0.1",
}
err := client.Call(_assistUps, arg, &res)
if err != nil {
t.Logf("err:%v.", err)
}
t.Logf("%+v", res)
spew.Dump(res)
}
func TestAssists(t *testing.T) {
if err := conf.Init(); err != nil {
t.Errorf("conf.Init() error(%v)", err)
t.FailNow()
}
svr := service.New(conf.Conf)
New(conf.Conf, svr)
client, err := rpc.Dial("tcp", addr)
defer client.Close()
if err != nil {
t.Errorf("rpc.Dial(tcp, \"%s\") error(%v)", addr, err)
t.FailNow()
}
assists(client, t)
}
func TestAssistInfo(t *testing.T) {
if err := conf.Init(); err != nil {
t.Errorf("conf.Init() error(%v)", err)
t.FailNow()
}
svr := service.New(conf.Conf)
New(conf.Conf, svr)
client, err := rpc.Dial("tcp", addr)
defer client.Close()
if err != nil {
t.Errorf("rpc.Dial(tcp, \"%s\") error(%v)", addr, err)
t.FailNow()
}
assistInfo(client, t)
}
func TestAddAssist(t *testing.T) {
if err := conf.Init(); err != nil {
t.Errorf("conf.Init() error(%v)", err)
t.FailNow()
}
svr := service.New(conf.Conf)
New(conf.Conf, svr)
client, err := rpc.Dial("tcp", addr)
defer client.Close()
if err != nil {
t.Errorf("rpc.Dial(tcp, \"%s\") error(%v)", addr, err)
t.FailNow()
}
addAssist(client, t)
}
func TestDelAssist(t *testing.T) {
if err := conf.Init(); err != nil {
t.Errorf("conf.Init() error(%v)", err)
t.FailNow()
}
svr := service.New(conf.Conf)
New(conf.Conf, svr)
client, err := rpc.Dial("tcp", addr)
defer client.Close()
if err != nil {
t.Errorf("rpc.Dial(tcp, \"%s\") error(%v)", addr, err)
t.FailNow()
}
delAssist(client, t)
}
func TestAssistLogInfo(t *testing.T) {
if err := conf.Init(); err != nil {
t.Errorf("conf.Init() error(%v)", err)
t.FailNow()
}
svr := service.New(conf.Conf)
New(conf.Conf, svr)
client, err := rpc.Dial("tcp", addr)
defer client.Close()
if err != nil {
t.Errorf("rpc.Dial(tcp, \"%s\") error(%v)", addr, err)
t.FailNow()
}
assistLogInfo(client, t)
}
func TestAssistLogAdd(t *testing.T) {
if err := conf.Init(); err != nil {
t.Errorf("conf.Init() error(%v)", err)
t.FailNow()
}
svr := service.New(conf.Conf)
New(conf.Conf, svr)
client, err := rpc.Dial("tcp", addr)
defer client.Close()
if err != nil {
t.Errorf("rpc.Dial(tcp, \"%s\") error(%v)", addr, err)
t.FailNow()
}
assistLogAdd(client, t)
}
func TestAssistLogCancel(t *testing.T) {
if err := conf.Init(); err != nil {
t.Errorf("conf.Init() error(%v)", err)
t.FailNow()
}
svr := service.New(conf.Conf)
New(conf.Conf, svr)
client, err := rpc.Dial("tcp", addr)
defer client.Close()
if err != nil {
t.Errorf("rpc.Dial(tcp, \"%s\") error(%v)", addr, err)
t.FailNow()
}
assistLogCancel(client, t)
}
func TestAssistLogs(t *testing.T) {
if err := conf.Init(); err != nil {
t.Errorf("conf.Init() error(%v)", err)
t.FailNow()
}
svr := service.New(conf.Conf)
New(conf.Conf, svr)
client, err := rpc.Dial("tcp", addr)
defer client.Close()
if err != nil {
t.Errorf("rpc.Dial(tcp, \"%s\") error(%v)", addr, err)
t.FailNow()
}
assistLogs(client, t)
}
func assistLogCancel(client *rpc.Client, t *testing.T) {
res := new(struct{})
arg := &model.ArgAssistLog{
Mid: 254386,
AssistMid: 2089809,
LogID: 670,
RealIP: "127.0.0.1",
}
err := client.Call(_assistLogCancel, arg, &res)
if err != nil {
t.Logf("err:%v.", err)
}
t.Logf("%+v", res)
}
func assistLogAdd(client *rpc.Client, t *testing.T) {
res := new(struct{})
arg := &model.ArgAssistLogAdd{
Mid: 254386,
AssistMid: 2089809,
Type: model.TypeComment,
Action: model.ActDelete,
SubjectID: 111,
ObjectID: "444",
Detail: "testing",
RealIP: "127.0.0.1",
}
err := client.Call(_assistLogAdd, arg, &res)
if err != nil {
t.Logf("err:%v.", err)
}
t.Logf("%+v", res)
}
func assistInfo(client *rpc.Client, t *testing.T) {
var res = &assist.AssistRes{}
arg := &model.ArgAssist{
Mid: 27515256,
AssistMid: 27515255,
RealIP: "127.0.0.1",
}
err := client.Call(_assist, arg, &res)
if err != nil {
t.Logf("err:%v.", err)
}
t.Logf("%+v", res)
}
func addAssist(client *rpc.Client, t *testing.T) {
assistInfo := new(struct{})
arg := &model.ArgAssist{
Mid: 27515256,
AssistMid: 27515255,
RealIP: "127.0.0.1",
}
err := client.Call(_addAssist, arg, assistInfo)
if err != nil {
t.Logf("err:%v.", err)
}
spew.Dump(assistInfo)
}
func delAssist(client *rpc.Client, t *testing.T) {
assistInfo := new(struct{})
arg := &model.ArgAssist{
Mid: 27515256,
AssistMid: 27515255,
RealIP: "127.0.0.1",
}
err := client.Call(_delAssist, arg, assistInfo)
if err != nil {
t.Logf("err:%v.", err)
}
spew.Dump(assistInfo)
}
func assists(client *rpc.Client, t *testing.T) {
var res = make([]*assist.Assist, 0)
arg := &model.ArgAssists{
Mid: 254386,
RealIP: "127.0.0.1",
}
err := client.Call(_assists, arg, &res)
if err != nil {
t.Logf("err:%v.", err)
}
t.Logf("%+v", res)
spew.Dump(res)
}
func assistLogs(client *rpc.Client, t *testing.T) {
var res = make([]*assist.Log, 0)
arg := &model.ArgAssistLogs{
Mid: 254386,
AssistMid: 2089809,
Stime: time.Unix(1496205563, 0),
Etime: time.Unix(1496291963, 0),
Pn: 1,
Ps: 30,
RealIP: "127.0.0.1",
}
err := client.Call(_assistLogs, arg, &res)
if err != nil {
t.Logf("err:%v.", err)
}
t.Logf("%+v", res)
spew.Dump(res)
}
func assistLogInfo(client *rpc.Client, t *testing.T) {
var res = &assist.Log{}
arg := &model.ArgAssistLog{
Mid: 254386,
AssistMid: 2089809,
LogID: 15,
RealIP: "127.0.0.1",
}
err := client.Call(_assistLogInfo, arg, &res)
if err != nil {
t.Logf("err:%v.", err)
}
t.Logf("%+v", res)
spew.Dump(res)
}

View File

@ -0,0 +1,62 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["service_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/service/main/assist/conf:go_default_library",
"//app/service/main/assist/model/assist:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"assist.go",
"check.go",
"limit.go",
"log.go",
"relation.go",
"service.go",
],
importpath = "go-common/app/service/main/assist/service",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/account/model:go_default_library",
"//app/service/main/assist/conf:go_default_library",
"//app/service/main/assist/dao/account:go_default_library",
"//app/service/main/assist/dao/assist:go_default_library",
"//app/service/main/assist/dao/message:go_default_library",
"//app/service/main/assist/model/assist:go_default_library",
"//app/service/main/assist/model/message:go_default_library",
"//app/service/main/assist/model/notify:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/queue/databus: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"],
)

View File

@ -0,0 +1,288 @@
package service
import (
"context"
"fmt"
"sort"
"go-common/app/service/main/account/model"
"go-common/app/service/main/assist/model/assist"
"go-common/app/service/main/assist/model/notify"
"go-common/library/log"
)
// AddAssist add assist.
func (s *Service) AddAssist(c context.Context, mid, assistMid int64) (err error) {
if err = s.checkFollow(c, mid, assistMid); err != nil {
log.Error("s.checkFollow(%d,%d) error(%v)", mid, assistMid, err)
return
}
if err = s.checkIdentify(c, assistMid); err != nil {
log.Error("s.checkIdentify err: (%d,%d) error(%v)", mid, assistMid, err)
return
}
if err = s.checkBanned(c, assistMid); err != nil {
log.Error("s.checkBanned err: (%d,%d) error(%v)", mid, assistMid, err)
return
}
if err = s.checkIsAssist(c, mid, assistMid); err != nil {
log.Error("s.checkIsAssist err: (%d,%d) error(%v)", mid, assistMid, err)
return
}
if err = s.checkTotalLimit(c, mid); err != nil {
log.Error("s.limitDailyCntAddAllAss err: (%d,%d) error(%v)", mid, assistMid, err)
return
}
if err = s.checkSameLimit(c, mid, assistMid); err != nil {
log.Error("s.limitDailyCntAddSameAss err: (%d,%d) error(%v)", mid, assistMid, err)
return
}
if err = s.checkMaxAssistCnt(c, mid); err != nil {
log.Error("s.limitAssistCnt err: (%d,%d) error(%v)", mid, assistMid, err)
return
}
if _, err = s.ass.AddAssist(c, mid, assistMid); err != nil {
log.Error("s.ass.AddAssist(%d,%d) error(%v)", mid, assistMid, err)
return
}
var card *model.Card
if card, err = s.acc.Card(c, mid, ""); err != nil {
log.Error("s.acc.Card(%d,%d) error(%v)", mid, assistMid, err)
return
}
_ = s.SendSysNotify(c, notify.AddAssNotifyAct, mid, assistMid, card.Name, "")
// set cache async
s.asyncCache(func() {
_ = s.ass.DelCacheAss(context.TODO(), mid)
_ = s.ass.DelAssUpAllCache(context.TODO(), assistMid)
_ = s.ass.IncrAssCnt(context.TODO(), mid, assistMid)
})
return
}
// DelAssist delete assist.
func (s *Service) DelAssist(c context.Context, mid, assistMid int64) (err error) {
if err = s.checkIsNotAssist(c, mid, assistMid); err != nil {
log.Error("s.checkIsNotAssist err: (%d,%d) error(%v)", mid, assistMid, err)
return
}
if _, err = s.ass.DelAssist(c, mid, assistMid); err != nil {
log.Error("s.ass.DelAssist(%d,%d) error(%v)", mid, assistMid, err)
return
}
// del cache
s.asyncCache(func() {
_ = s.ass.DelCacheAss(context.TODO(), mid)
_ = s.ass.DelAssUpAllCache(context.TODO(), assistMid)
})
var card *model.Card
if card, err = s.acc.Card(c, mid, ""); err != nil {
log.Error("s.acc.Card(%d,%d) error(%v)", mid, assistMid, err)
return
}
log.Info("s.SendSysNotify (%d,%d,%s)", mid, assistMid, card.Name)
_ = s.SendSysNotify(c, notify.DelAssNotifyAct, mid, assistMid, card.Name, "")
return
}
// Assists get assists
func (s *Service) Assists(c context.Context, mid int64) (as []*assist.Assist, err error) {
if as, err = s.ass.Assists(c, mid); err != nil {
log.Error("s.ass.Assists(%d) error(%v)", mid, err)
return
}
totalm, err := s.ass.LogCount(c, mid)
if err != nil {
log.Error("s.ass.LogCount(%d) error(%v)", mid, err)
return
}
if len(totalm) == 0 {
return
}
for _, a := range as {
a.Total = totalm[a.AssistMid]
}
return
}
// AssistsMidsTotal get multi mids assists group by mid
func (s *Service) AssistsMidsTotal(c context.Context, mid int64, assmids []int64) (totalm map[int64]map[int8]map[int8]int, err error) {
if totalm, err = s.ass.AssistsMidsTotal(c, mid, assmids); err != nil {
log.Error("s.ass.AssistsMidsTotal(%d) error(%v)", mid, err)
return
}
return
}
// Assist get assist allow default value is 1
func (s *Service) Assist(c context.Context, mid, assistMid, tp int64) (ar *assist.AssistRes, err error) {
assistMids := []int64{}
ar = &assist.AssistRes{Assist: 0, Allow: 0, Count: 0}
if assistMids, err = s.ass.GetCacheAss(c, mid); err != nil {
return
}
if assistMids == nil {
assistMids = []int64{} // for set [] cache
// no cache, and get from db
var assists []*assist.Assist
if assists, err = s.ass.Assists(c, mid); err != nil {
return
}
for _, a := range assists {
assistMids = append(assistMids, a.AssistMid)
}
// set cache async
s.asyncCache(func() {
_ = s.ass.SetCacheAss(context.TODO(), mid, assistMids)
})
}
// check up has assist
if len(assistMids) == 0 {
return
}
// check is assist
isAss := false
for _, v := range assistMids {
if v == assistMid {
isAss = true
break
}
}
if !isAss {
return
}
ar.Assist = 1
// get daily count
var cnt int64
if cnt, err = s.ass.DailyLogCount(c, mid, assistMid, tp); err != nil {
return
}
if cnt < s.c.MaxTypeCnt {
ar.Allow = 1
}
ar.Count = cnt
return
}
// AssistIDs get assists list for others.
func (s *Service) AssistIDs(c context.Context, mid int64) (assistMids []int64, err error) {
if assistMids, err = s.ass.GetCacheAss(c, mid); err != nil {
// cache failed, return
err = nil
return
}
// no cache, and get from db
if assistMids == nil {
assistMids = []int64{} // for set [] cache
var assists []*assist.Assist
if assists, err = s.ass.Assists(c, mid); err != nil {
return
}
for _, a := range assists {
assistMids = append(assistMids, a.AssistMid)
}
// set cache async
s.asyncCache(func() {
_ = s.ass.SetCacheAss(context.TODO(), mid, assistMids)
})
}
return
}
// SendSysNotify fn
func (s *Service) SendSysNotify(c context.Context, action int, mid, assistMid int64, upUname, assistUname string) (err error) {
if action == notify.AddAssNotifyAct {
err = s.msg.Send(c, notify.Mc, notify.AddTitle, fmt.Sprintf(notify.AddContent, upUname, mid, upUname, assistMid), assistMid)
}
if action == notify.DelAssNotifyAct {
err = s.msg.Send(c, notify.Mc, notify.DelTitle, fmt.Sprintf(notify.DelContent, upUname, mid), assistMid)
}
if action == notify.DelAssNotifyFollowerAct {
err = s.msg.Send(c, notify.Mc, notify.DelFollowerTitle, fmt.Sprintf(notify.DelFollowerContent, assistUname, assistMid), mid)
}
log.Info("action(%d), mid(%d), assistMid(%d), upUname(%s), assistUname(%s)", action, mid, assistMid, upUname, assistUname)
return
}
// Exit delete assist from follower.
func (s *Service) Exit(c context.Context, mid, assistMid int64) (err error) {
if _, err = s.ass.DelAssist(c, mid, assistMid); err != nil {
log.Error("s.ass.DelAssist(%d,%d) error(%v)", mid, assistMid, err)
}
log.Info("s.DelAssForRLFollower (%d,%d,%s)", mid, assistMid)
// del cache
s.asyncCache(func() {
_ = s.ass.DelCacheAss(context.TODO(), mid)
_ = s.ass.DelAssUpAllCache(context.TODO(), assistMid)
})
var (
card = &model.Card{}
)
if card, err = s.acc.Card(c, assistMid, ""); err != nil {
return
}
if assistUname := card.Name; len(assistUname) != 0 {
log.Info("s.SendSysNotify (%d,%d,%s)", mid, assistMid, assistUname)
_ = s.SendSysNotify(c, notify.DelAssNotifyFollowerAct, mid, assistMid, "", assistUname)
}
return
}
// AssistUps get ups who already sign me as assist.
func (s *Service) AssistUps(c context.Context, assistMid, pn, ps int64) (assistUpsPager *assist.AssistUpsPager, err error) {
var (
total int64
upMids = []int64{}
assUps = []*assist.AssistUp{}
ups = make(map[int64]*assist.Up, ps)
)
assistUpsPager = &assist.AssistUpsPager{
Data: []*assist.AssistUp{},
Pager: assist.Pager{
Pn: pn,
Ps: ps,
Total: total,
},
}
if upMids, ups, total, err = s.ass.AssUpCacheWithScore(c, assistMid, (pn-1)*ps, pn*ps); err != nil {
// cache failed, return
log.Error("s.ass.AssUpCacheWithScore, (upMids %v), (ps,pn: %d, %d) err:%v", upMids, ps, pn, err)
err = nil
return
}
// no cache, and get from db
if total == 0 {
upMids, ups, total, err = s.ass.Ups(c, assistMid, pn, ps)
if err != nil {
log.Error("s.ass.Ups assistMid:(%d) error(%v)", assistMid, err)
return
}
s.asyncCache(func() {
_ = s.ass.AddAssUpAllCache(context.TODO(), assistMid, ups)
})
}
if len(upMids) > 0 {
var cards map[int64]*model.Card
if cards, err = s.acc.Cards(c, upMids); err != nil {
log.Error("s.ass.Cards(%d) error(%v)", ups, err)
return
}
for _, card := range cards {
if _, ok := ups[card.Mid]; ok {
assUps = append(assUps, &assist.AssistUp{
Mid: card.Mid,
Name: card.Name,
Sign: card.Sign,
Avatar: card.Face,
OfficialVerify: card.Official,
CTime: ups[card.Mid].CTime,
Vip: card.Vip,
})
}
}
sort.Sort(assist.SortUpsByCtime(assUps))
}
assistUpsPager.Pager.Total = total
assistUpsPager.Data = assUps
return
}

View File

@ -0,0 +1,67 @@
package service
import (
"context"
"go-common/library/ecode"
"go-common/library/log"
)
func (s *Service) checkFollow(c context.Context, mid, assistMid int64) (err error) {
follow, err := s.acc.IsFollow(c, mid, assistMid)
if err != nil {
log.Error("s.ass.IsFollow(%d,%d) error(%v)", mid, assistMid, err)
return
}
if !follow {
log.Error("s.ass.IsFollow AssistNotFollowUp(%d,%d) error(%v)", mid, assistMid, err)
err = ecode.AssistNotFollowUp
return
}
return
}
// checkIdentify func
func (s *Service) checkIdentify(c context.Context, assistMid int64) (err error) {
if err = s.acc.IdentifyInfo(c, assistMid, ""); err != nil {
log.Error("s.acc.IdentifyInfo IdentifyInfoFailed assistMid(%d)", assistMid)
return
}
return
}
func (s *Service) checkBanned(c context.Context, assistMid int64) (err error) {
if err = s.acc.UserBanned(c, assistMid); err != nil {
log.Error("s.UserBanned err: (%d) error(%v)", assistMid, err)
return
}
return
}
func (s *Service) checkIsAssist(c context.Context, mid, assistMid int64) (err error) {
assist, err := s.ass.Assist(c, mid, assistMid)
if err != nil {
log.Error("s.ass.Assist(%d,%d) error(%v)", mid, assistMid, err)
return
}
if assist != nil {
log.Error("s.ass.Assist(%d,%d) assist is not nil error(%v)", mid, assistMid, err)
err = ecode.AssistAlreadyExist
return
}
return
}
func (s *Service) checkIsNotAssist(c context.Context, mid, assistMid int64) (err error) {
assist, err := s.ass.Assist(c, mid, assistMid)
if err != nil {
log.Error("s.ass.Assist(%d,%d) error(%v)", mid, assistMid, err)
return
}
if assist == nil {
err = ecode.AssistNotExist
log.Error("s.ass.Assist(%d,%d) assist is nil error(%v)", mid, assistMid, err)
return
}
return
}

View File

@ -0,0 +1,51 @@
package service
import (
"context"
"go-common/library/ecode"
"go-common/library/log"
)
func (s *Service) checkMaxAssistCnt(c context.Context, mid int64) (err error) {
cnt, err := s.ass.AssistCnt(c, mid)
if err != nil {
log.Error("s.ass.AssistCnt(%d) error(%v)", mid, err)
return
}
if cnt >= s.c.MaxAssCnt {
err = ecode.AssistOverMaxLimit
log.Error("ecode.AssistOverMaxLimit(%d) error(%v)", mid, err)
return
}
return
}
func (s *Service) checkTotalLimit(c context.Context, mid int64) (err error) {
cnt, err := s.ass.TotalAssCnt(c, mid)
if err != nil {
log.Error("s.ass.DailyCntAddAllAss(%d) error(%v)", mid, err)
return
}
// 100
if cnt >= 100 {
err = ecode.AssistOverMaxLimitDailyAddAll
log.Error("ecode.AssistOverMaxLimitDailyAddAll(%d) error(%v)", mid, err)
return
}
return
}
func (s *Service) checkSameLimit(c context.Context, mid, assistMid int64) (err error) {
cnt, err := s.ass.SameAssCnt(c, mid, assistMid)
if err != nil {
log.Error("s.ass.DailyCntAddSameAss(%d),(%d) error(%v)", mid, assistMid, err)
return
}
// 2
if cnt >= 2 {
err = ecode.AssistOverMaxLimitDailyAddSame
log.Error("ecode.AssistOverMaxLimitDailyAddSame(%d) error(%v)", mid, err)
return
}
return
}

View File

@ -0,0 +1,127 @@
package service
import (
"context"
"time"
"go-common/app/service/main/assist/model/assist"
"go-common/library/ecode"
"go-common/library/log"
)
const typeLive = 3
// Logs get assist logs.
func (s *Service) Logs(c context.Context, mid, assistMid int64, stime, etime time.Time, pn, ps int) (logs []*assist.Log, err error) {
if assistMid > 0 && stime.IsZero() && etime.IsZero() {
logs, err = s.ass.LogsByAssist(c, mid, assistMid, pn, ps)
} else if assistMid == 0 && !stime.IsZero() && !etime.IsZero() {
logs, err = s.ass.LogsByCtime(c, mid, stime, etime, pn, ps)
} else if assistMid > 0 && !stime.IsZero() && !etime.IsZero() {
logs, err = s.ass.LogsByAssistCtime(c, mid, assistMid, stime, etime, pn, ps)
} else {
logs, err = s.ass.Logs(c, mid, pn, ps)
}
if err != nil {
log.Error("s.ass.Logs(%d,%d,%v,%v,%d,%d) error(%v)", mid, assistMid, stime, etime, pn, ps, err)
return
}
return
}
// LogCnt count by mid, assistMid, etime,stime
func (s *Service) LogCnt(c context.Context, mid, assistMid int64, stime, etime time.Time) (cnt int64, err error) {
if assistMid > 0 && stime.IsZero() && etime.IsZero() {
cnt, err = s.ass.LogCntAssist(c, mid, assistMid)
} else if assistMid == 0 && !stime.IsZero() && !etime.IsZero() {
cnt, err = s.ass.LogCntCtime(c, mid, stime, etime)
} else if assistMid > 0 && !stime.IsZero() && !etime.IsZero() {
cnt, err = s.ass.LogCntAssistCtime(c, mid, assistMid, stime, etime)
} else {
cnt, err = s.ass.LogCnt(c, mid)
}
if err != nil {
log.Error("s.ass.LogCnt(%d,%d,%v,%v,%d,%d) error(%v)", mid, assistMid, stime, etime, err)
return
}
return
}
// AddLog add assist log.
func (s *Service) AddLog(c context.Context, mid, assistMid, tp, act, subID int64, objIDStr string, detail string) (err error) {
if mid == assistMid {
log.Info("s.ass.AddLog mid eq assistMid (%d,%d,%d,%d,%s,%d,%s)", mid, assistMid, tp, act, subID, objIDStr, detail)
return nil
}
//get assist info and check field, just except live type
if tp != typeLive {
ar := &assist.AssistRes{Assist: 0, Allow: 0}
if ar, err = s.Assist(c, mid, assistMid, tp); err != nil {
log.Error("s.Assist(%d,%d,%d,%d,%s,%d,%s) error(%v)", mid, assistMid, tp, act, subID, objIDStr, detail, err)
return
}
if ar.Assist == 0 {
err = ecode.AssistNotExist
return
}
}
//check type and act
if _, ok := assist.TypeEnum[tp]; !ok {
err = ecode.AssistForbidType
return
}
if _, ok := assist.ActEnum[act]; !ok {
err = ecode.AssistForbidAction
return
}
if _, err = s.ass.AddLog(c, mid, assistMid, tp, act, subID, objIDStr, detail); err != nil {
log.Error("s.ass.AddLog(%d,%d,%d,%d,%s,%d,%s) error(%v)", mid, assistMid, tp, act, subID, objIDStr, detail, err)
return
}
if err = s.ass.IncrLogCount(c, mid, assistMid, tp); err != nil {
log.Error("s.ass.IncrCount(%d,%d,%d,%d,%s,%d,%s) error(%v)", mid, assistMid, tp, act, subID, objIDStr, detail, err)
return
}
return
}
// CancelLog cancel this asssist action.
func (s *Service) CancelLog(c context.Context, mid, assistMid, logID int64) (err error) {
var logInfo *assist.Log
logInfo, err = s.ass.LogInfo(c, logID, mid, assistMid)
if err != nil {
err = ecode.AssistLogNotExist
log.Error("s.ass.LogInfo(%d,%d,%d) error(%v)", logID, mid, assistMid, err)
return
}
if logInfo.State == 1 {
err = ecode.AssistAlreadyCancel
return
}
rows, err := s.ass.CancelLog(c, logID, mid, assistMid)
if err != nil {
log.Error("s.ass.CancelLog(%d,%d,%d,%v) error(%v)", logID, mid, assistMid, rows, err)
return
}
return
}
// LogInfo get one log info.
func (s *Service) LogInfo(c context.Context, id, mid, assistMid int64) (logInfo *assist.Log, err error) {
logInfo, err = s.ass.LogInfo(c, id, mid, assistMid)
if err != nil {
log.Error("s.ass.LogInfo(%d,%d,%d) error(%v)", id, mid, assistMid, err)
return
}
return
}
// LogObj get one log info.
func (s *Service) LogObj(c context.Context, mid, objID, tp, act int64) (logInfo *assist.Log, err error) {
logInfo, err = s.ass.LogObj(c, mid, objID, tp, act)
if err != nil {
log.Error("s.ass.LogInfo(%d,%d,%d,%d) error(%v)", mid, objID, tp, act, err)
return
}
return
}

View File

@ -0,0 +1,44 @@
package service
import (
"context"
"encoding/json"
"go-common/app/service/main/assist/model/message"
"go-common/library/log"
)
func (s *Service) relationConsumer() {
defer s.wg.Done()
var (
msgs = s.relationSub.Messages()
err error
c = context.TODO()
)
for {
msg, ok := <-msgs
log.Info("relationConsumer msg info |Key(%+v)|Topic(%+v)|Partition(%+v)", msg.Key, msg.Topic, msg.Partition)
if !ok {
log.Error("s.relationSub.Message closed")
return
}
msg.Commit()
rm := &message.Relation{}
if err = json.Unmarshal(msg.Value, rm); err != nil {
log.Error("json.Unmarshal(%v) error(%v)", string(msg.Value), err)
err = nil
continue
}
// 不关注表取mod的分配表名只关注单向的关系链状态流转
breakOnDirection := (rm.Old.Attr == 2 && rm.New.Attr == 0) || (rm.Old.Attr == 6 && rm.New.Attr == 0)
if rm.Action == "update" && breakOnDirection {
log.Info("relationConsumer rm.Action(%s) OldAttr(%d),NewAttr(%d) mid(%d) fid(%d) table(%s)", rm.Action, rm.Old.Attr, rm.New.Attr, rm.New.MID, rm.New.FID, rm.Table)
if err = s.DelAssist(c, rm.New.FID, rm.New.MID); err != nil {
log.Error("DelAssist(%v), mid(%d),fid(%d) error(%v)", string(msg.Value), rm.New.MID, rm.New.FID, err)
err = nil
continue
}
}
log.Info("relationConsumer key(%s) partition(%d) offset(%d) commit", msg.Key, msg.Partition, msg.Offset)
}
}

View File

@ -0,0 +1,77 @@
package service
import (
"context"
"sync"
"go-common/app/service/main/assist/conf"
"go-common/app/service/main/assist/dao/account"
"go-common/app/service/main/assist/dao/assist"
"go-common/app/service/main/assist/dao/message"
"go-common/library/log"
"go-common/library/queue/databus"
)
// Service assist.
type Service struct {
c *conf.Config
ass *assist.Dao
acc *account.Dao
msg *message.Dao
// databus sub
relationSub *databus.Databus
// chan
cacheChan chan func()
// wait group
wg sync.WaitGroup
}
// New get assist service.
func New(c *conf.Config) *Service {
s := &Service{
c: c,
ass: assist.New(c),
acc: account.New(c),
msg: message.New(c),
// chan
cacheChan: make(chan func(), 1024),
// databus
relationSub: databus.New(c.RelationSub),
}
s.wg.Add(1)
go s.relationConsumer()
s.wg.Add(1)
go s.cacheproc()
return s
}
// Ping service.
func (s *Service) Ping(c context.Context) (err error) {
if err = s.ass.Ping(c); err != nil {
log.Error("s.ass.Dao.Ping err(%v)", err)
}
return
}
// asyncCache add to chan for cache
func (s *Service) asyncCache(f func()) {
select {
case s.cacheChan <- f:
default:
log.Warn("assist cacheproc chan full")
}
}
// cacheproc is a routine for execute closure.
func (s *Service) cacheproc() {
for {
f := <-s.cacheChan
f()
}
}
// Close func
func (s *Service) Close() {
s.relationSub.Close()
s.wg.Wait()
}

View File

@ -0,0 +1,132 @@
package service
import (
"context"
"flag"
"go-common/app/service/main/assist/conf"
"go-common/app/service/main/assist/model/assist"
"path/filepath"
"testing"
"time"
. "github.com/smartystreets/goconvey/convey"
)
var (
s *Service
)
func init() {
dir, _ := filepath.Abs("../../cmd/assist-service.toml")
flag.Set("conf", dir)
conf.Init()
s = New(conf.Conf)
time.Sleep(time.Second)
}
func WithService(f func(s *Service)) func() {
return func() {
Reset(func() {})
f(s)
}
}
func Test_Check(t *testing.T) {
var (
c = context.TODO()
err error
MID = int64(2089809)
assistMid = int64(2089810)
)
Convey("checkBanned", t, WithService(func(s *Service) {
err = s.checkBanned(c, MID)
So(err, ShouldBeNil)
}))
Convey("checkFollow", t, WithService(func(s *Service) {
err = s.checkFollow(c, MID, assistMid)
So(err, ShouldBeNil)
}))
Convey("checkIdentify", t, WithService(func(s *Service) {
err = s.checkIdentify(c, assistMid)
So(err, ShouldBeNil)
}))
Convey("checkIsAssist", t, WithService(func(s *Service) {
err = s.checkIsAssist(c, MID, assistMid)
So(err, ShouldBeNil)
}))
Convey("checkIsNotAssist", t, WithService(func(s *Service) {
err = s.checkIsNotAssist(c, MID, assistMid)
So(err, ShouldBeNil)
}))
}
func Test_Limit(t *testing.T) {
var (
c = context.TODO()
err error
MID = int64(2089809)
assistMid = int64(2089810)
)
Convey("checkMaxAssistCnt", t, WithService(func(s *Service) {
err = s.checkMaxAssistCnt(c, MID)
So(err, ShouldBeNil)
}))
Convey("checkTotalLimit", t, WithService(func(s *Service) {
err = s.checkTotalLimit(c, MID)
So(err, ShouldBeNil)
}))
Convey("checkSameLimit", t, WithService(func(s *Service) {
err = s.checkSameLimit(c, MID, assistMid)
So(err, ShouldBeNil)
}))
}
func Test_Log(t *testing.T) {
var (
c = context.TODO()
err error
MID = int64(2089809)
assistMid = int64(2089810)
logID = int64(123)
objID = int64(1)
tp = int64(2)
act = int64(3)
subID = int64(4)
logInfo = &assist.Log{}
logs = []*assist.Log{}
cnt int64
stime = time.Now().Add(-time.Hour * 72)
etime = time.Now()
objIDStr = "hash_object_id"
detail = "detail string info"
)
Convey("CancelLog", t, WithService(func(s *Service) {
err = s.CancelLog(c, MID, assistMid, logID)
So(err, ShouldBeNil)
}))
Convey("LogInfo", t, WithService(func(s *Service) {
logInfo, err = s.LogInfo(c, logID, MID, assistMid)
So(err, ShouldBeNil)
So(logInfo, ShouldNotBeNil)
}))
Convey("LogObj", t, WithService(func(s *Service) {
logInfo, err = s.LogObj(c, MID, objID, tp, act)
So(err, ShouldBeNil)
So(logInfo, ShouldNotBeNil)
}))
Convey("LogCnt", t, WithService(func(s *Service) {
cnt, err = s.LogCnt(c, MID, assistMid, stime, etime)
So(err, ShouldBeNil)
So(cnt, ShouldNotBeNil)
So(cnt, ShouldBeGreaterThanOrEqualTo, 0)
}))
Convey("AddLog", t, WithService(func(s *Service) {
err = s.AddLog(c, MID, assistMid, tp, act, subID, objIDStr, detail)
So(err, ShouldBeNil)
}))
Convey("Logs", t, WithService(func(s *Service) {
logs, err = s.Logs(c, MID, assistMid, stime, etime, 1, 20)
So(err, ShouldBeNil)
So(len(logs), ShouldBeGreaterThanOrEqualTo, 0)
}))
}