Create & Init Project...
This commit is contained in:
25
app/service/main/spy/BUILD
Normal file
25
app/service/main/spy/BUILD
Normal file
@ -0,0 +1,25 @@
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//app/service/main/spy/api:all-srcs",
|
||||
"//app/service/main/spy/cmd:all-srcs",
|
||||
"//app/service/main/spy/conf:all-srcs",
|
||||
"//app/service/main/spy/dao:all-srcs",
|
||||
"//app/service/main/spy/model:all-srcs",
|
||||
"//app/service/main/spy/rpc/client:all-srcs",
|
||||
"//app/service/main/spy/rpc/server:all-srcs",
|
||||
"//app/service/main/spy/server/grpc:all-srcs",
|
||||
"//app/service/main/spy/server/http:all-srcs",
|
||||
"//app/service/main/spy/service:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
117
app/service/main/spy/CHANGELOG.md
Normal file
117
app/service/main/spy/CHANGELOG.md
Normal file
@ -0,0 +1,117 @@
|
||||
反作弊项目-服务
|
||||
|
||||
v1.7.2
|
||||
1. update http server pkg
|
||||
|
||||
v1.7.1
|
||||
1. 添加grpc接口
|
||||
|
||||
v1.7.0
|
||||
1. 更新基础分计算策略,支持实名认证和福利社绑定检查
|
||||
2. 支持基础分刷新操作
|
||||
|
||||
v1.6.1
|
||||
1. dao unit test
|
||||
|
||||
v1.6.0
|
||||
1. 改为 metadata RemoteIP
|
||||
|
||||
v1.5.3
|
||||
1. stat rpc group by event
|
||||
|
||||
v1.5.2
|
||||
1. 添加stat rpc接口
|
||||
|
||||
v1.5.0
|
||||
1. purgeUser v2
|
||||
|
||||
v1.4.5
|
||||
1. add register
|
||||
|
||||
v1.4.4
|
||||
1. 异步更新基础分
|
||||
|
||||
v1.4.3
|
||||
1. refined log
|
||||
|
||||
v1.4.2
|
||||
1. add tel white list
|
||||
2. mv repo path
|
||||
|
||||
v1.4.1
|
||||
1. update account info to card
|
||||
|
||||
v1.4.0
|
||||
1. http bm
|
||||
2. code refined
|
||||
|
||||
v1.3.2
|
||||
1. remove account-service
|
||||
2. use account audit
|
||||
|
||||
v1.3.1
|
||||
1. remove stastd
|
||||
|
||||
v1.3.0
|
||||
1. 腾讯天域手机号验证
|
||||
|
||||
v1.2.5
|
||||
1. update handle event logic
|
||||
|
||||
v1.2.4
|
||||
1. 修改用户初始化SQL
|
||||
|
||||
v1.2.3
|
||||
1. 反作弊案件
|
||||
|
||||
v1.2.2
|
||||
1. 优化identify
|
||||
|
||||
v1.2.1
|
||||
1. add mc,db,httpclient prom
|
||||
|
||||
v1.2.0
|
||||
1. 真实分信息接口异步化
|
||||
|
||||
v1.1.9
|
||||
1. 增加二次登陆验证的cd期
|
||||
|
||||
v1.1.8
|
||||
1. 报表及监控
|
||||
|
||||
v1.1.7
|
||||
1. 加入dapper
|
||||
|
||||
v1.1.6
|
||||
1. 二次验证获取账号信息的重试
|
||||
|
||||
v1.1.5
|
||||
1. 反作弊变更databus
|
||||
|
||||
v1.1.4
|
||||
1. asyn 初始化用户信息
|
||||
|
||||
v1.1.3
|
||||
1. 修改event msg 参数名
|
||||
|
||||
v1.1.2
|
||||
1. 导入二次登陆,备注调整
|
||||
|
||||
v1.1.1
|
||||
1. 自动封禁系统中,增加过滤条件
|
||||
|
||||
v1.1.0
|
||||
1. 反作弊二期,自动封禁相关
|
||||
|
||||
v1.0.3
|
||||
1. 修复mc ping
|
||||
|
||||
v1.0.2
|
||||
1. 迁移大仓库
|
||||
|
||||
v1.0.1
|
||||
1. 更改purge method
|
||||
|
||||
v1.0.0
|
||||
1. 初始化项目,更新依赖
|
||||
2. 完成反作弊一期开发
|
11
app/service/main/spy/CONTRIBUTORS.md
Normal file
11
app/service/main/spy/CONTRIBUTORS.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Owner
|
||||
zhaogangtao
|
||||
|
||||
# Author
|
||||
zhaogangtao
|
||||
yubaihai
|
||||
muyang
|
||||
|
||||
# Reviewer
|
||||
linmiao
|
||||
zhaogangtao
|
17
app/service/main/spy/OWNERS
Normal file
17
app/service/main/spy/OWNERS
Normal file
@ -0,0 +1,17 @@
|
||||
# See the OWNERS docs at https://go.k8s.io/owners
|
||||
|
||||
approvers:
|
||||
- muyang
|
||||
- yubaihai
|
||||
- zhaogangtao
|
||||
labels:
|
||||
- main
|
||||
- service
|
||||
- service/main/spy
|
||||
options:
|
||||
no_parent_owners: true
|
||||
reviewers:
|
||||
- linmiao
|
||||
- muyang
|
||||
- yubaihai
|
||||
- zhaogangtao
|
13
app/service/main/spy/README.md
Normal file
13
app/service/main/spy/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
#### archive-service
|
||||
|
||||
##### 项目简介
|
||||
> 1.提供反作弊服务
|
||||
|
||||
##### 编译环境
|
||||
> 请只用golang v1.7.x以上版本编译执行。
|
||||
|
||||
##### 依赖包
|
||||
> 1.公共包go-common
|
||||
|
||||
##### 特别说明
|
||||
> 1.model目录可能会被其他项目引用,请谨慎请改并通知各方。
|
60
app/service/main/spy/api/BUILD
Normal file
60
app/service/main/spy/api/BUILD
Normal file
@ -0,0 +1,60 @@
|
||||
load(
|
||||
"@io_bazel_rules_go//proto:def.bzl",
|
||||
"go_proto_library",
|
||||
)
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "v1_proto",
|
||||
srcs = ["api.proto"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_proto_library(
|
||||
name = "v1_go_proto",
|
||||
compilers = ["@io_bazel_rules_go//proto:go_grpc"],
|
||||
importpath = "go-common/app/service/main/spy/api",
|
||||
proto = ":v1_proto",
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"client.go",
|
||||
"copy.go",
|
||||
"doc.go",
|
||||
],
|
||||
embed = [":v1_go_proto"],
|
||||
importpath = "go-common/app/service/main/spy/api",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/service/main/spy/model:go_default_library",
|
||||
"//library/net/rpc/warden:go_default_library",
|
||||
"//library/time:go_default_library",
|
||||
"@com_github_gogo_protobuf//proto:go_default_library",
|
||||
"@org_golang_google_grpc//:go_default_library",
|
||||
"@org_golang_x_net//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"],
|
||||
)
|
6916
app/service/main/spy/api/api.pb.go
Normal file
6916
app/service/main/spy/api/api.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
186
app/service/main/spy/api/api.proto
Normal file
186
app/service/main/spy/api/api.proto
Normal file
@ -0,0 +1,186 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package account.spy;
|
||||
|
||||
|
||||
option go_package = "v1";
|
||||
|
||||
message ClearReliveTimesReply {
|
||||
}
|
||||
|
||||
message ClearReliveTimesReq {
|
||||
ModelArgReset arg = 1;
|
||||
}
|
||||
|
||||
message HandleEventReply {
|
||||
}
|
||||
|
||||
message HandleEventReq {
|
||||
ModelEventMessage event_msg = 1;
|
||||
}
|
||||
|
||||
message ModelArgReset {
|
||||
int64 mid = 1;
|
||||
bool re_live_time = 2;
|
||||
bool event_score = 3;
|
||||
bool base_score = 4;
|
||||
string operator = 5;
|
||||
}
|
||||
|
||||
message ModelEventMessage {
|
||||
int64 time = 1;
|
||||
string ip = 2;
|
||||
string service = 3;
|
||||
string event = 4;
|
||||
int64 active_mid = 5;
|
||||
int64 target_mid = 6;
|
||||
int64 target_id = 7;
|
||||
//FIXME type model. args = 8;
|
||||
string result = 9;
|
||||
string effect = 10;
|
||||
int32 risk_level = 11;
|
||||
}
|
||||
|
||||
message ModelStatistics {
|
||||
int64 quantity = 1;
|
||||
int64 event_id = 2;
|
||||
string event_name = 3;
|
||||
}
|
||||
|
||||
message ModelUserInfo {
|
||||
int64 id = 1;
|
||||
int64 mid = 2;
|
||||
int32 score = 3;
|
||||
int32 base_score = 4;
|
||||
int32 event_score = 5;
|
||||
int32 state = 6;
|
||||
int32 relive_times = 7;
|
||||
int64 ctime = 8;
|
||||
int64 mtime = 9;
|
||||
}
|
||||
|
||||
message PingReply {
|
||||
}
|
||||
|
||||
message PingReq {
|
||||
}
|
||||
|
||||
message PurgeUserReply {
|
||||
}
|
||||
|
||||
message PurgeUserReq {
|
||||
int64 mid = 1;
|
||||
string action = 2;
|
||||
}
|
||||
|
||||
message ReBuildPortraitReply {
|
||||
}
|
||||
|
||||
message ReBuildPortraitReq {
|
||||
int64 mid = 1;
|
||||
string reason = 2;
|
||||
}
|
||||
|
||||
message RefreshBaseScoreReply {
|
||||
}
|
||||
|
||||
message RefreshBaseScoreReq {
|
||||
ModelArgReset arg = 1;
|
||||
}
|
||||
|
||||
message StatByIDGroupEventReply {
|
||||
repeated ModelStatistics res = 1;
|
||||
}
|
||||
|
||||
message StatByIDGroupEventReq {
|
||||
int64 mid = 1;
|
||||
int64 id = 2;
|
||||
}
|
||||
|
||||
message StatByIDReply {
|
||||
repeated ModelStatistics stat = 1;
|
||||
}
|
||||
|
||||
message StatByIDReq {
|
||||
int64 mid = 1;
|
||||
int64 id = 2;
|
||||
}
|
||||
|
||||
message UpdateBaseScoreReply {
|
||||
}
|
||||
|
||||
message UpdateBaseScoreReq {
|
||||
ModelArgReset arg = 1;
|
||||
}
|
||||
|
||||
message UpdateEventScoreReply {
|
||||
}
|
||||
|
||||
message UpdateEventScoreReq {
|
||||
ModelArgReset arg = 1;
|
||||
}
|
||||
|
||||
message UpdateUserScoreReply {
|
||||
}
|
||||
|
||||
message UpdateUserScoreReq {
|
||||
int64 mid = 1;
|
||||
string ip = 2;
|
||||
string effect = 3;
|
||||
}
|
||||
|
||||
message UserInfoAsynReply {
|
||||
ModelUserInfo ui = 1;
|
||||
}
|
||||
|
||||
message UserInfoAsynReq {
|
||||
int64 mid = 1;
|
||||
}
|
||||
|
||||
message UserInfoReply {
|
||||
ModelUserInfo ui = 1;
|
||||
}
|
||||
|
||||
message UserInfoReq {
|
||||
int64 mid = 1;
|
||||
string ip = 2;
|
||||
}
|
||||
|
||||
message InfoReq {
|
||||
int64 mid = 1;
|
||||
}
|
||||
|
||||
message InfoReply {
|
||||
ModelUserInfo ui = 1;
|
||||
}
|
||||
|
||||
service Spy {
|
||||
// Ping check dao health.
|
||||
rpc Ping(PingReq) returns(PingReply);
|
||||
// Info get user info by mid.
|
||||
rpc Info(InfoReq) returns(InfoReply);
|
||||
// StatByID spy stat by id or mid.
|
||||
rpc StatByID(StatByIDReq) returns(StatByIDReply);
|
||||
// StatByIDGroupEvent spy stat by id or mid.
|
||||
rpc StatByIDGroupEvent(StatByIDGroupEventReq) returns(StatByIDGroupEventReply);
|
||||
// PurgeUser purge user info
|
||||
rpc PurgeUser(PurgeUserReq) returns(PurgeUserReply);
|
||||
// HandleEvent handle spy-event.
|
||||
rpc HandleEvent(HandleEventReq) returns(HandleEventReply);
|
||||
// UserInfo get UserInfo by mid , from cache or db or generate.
|
||||
rpc UserInfo(UserInfoReq) returns(UserInfoReply);
|
||||
// UserInfoAsyn get UserInfo by mid , from cache or db or asyn generate.
|
||||
rpc UserInfoAsyn(UserInfoAsynReq) returns(UserInfoAsynReply);
|
||||
// ReBuildPortrait reBuild user info.
|
||||
rpc ReBuildPortrait(ReBuildPortraitReq) returns(ReBuildPortraitReply);
|
||||
// UpdateUserScore update user score
|
||||
rpc UpdateUserScore(UpdateUserScoreReq) returns(UpdateUserScoreReply);
|
||||
// RefreshBaseScore refresh base score.
|
||||
rpc RefreshBaseScore(RefreshBaseScoreReq) returns(RefreshBaseScoreReply);
|
||||
// UpdateBaseScore update base score.
|
||||
rpc UpdateBaseScore(UpdateBaseScoreReq) returns(UpdateBaseScoreReply);
|
||||
// UpdateEventScore update event score.
|
||||
rpc UpdateEventScore(UpdateEventScoreReq) returns(UpdateEventScoreReply);
|
||||
// ClearReliveTimes clear times.
|
||||
rpc ClearReliveTimes(ClearReliveTimesReq) returns(ClearReliveTimesReply);
|
||||
}
|
22
app/service/main/spy/api/client.go
Normal file
22
app/service/main/spy/api/client.go
Normal file
@ -0,0 +1,22 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"go-common/library/net/rpc/warden"
|
||||
)
|
||||
|
||||
// AppID unique app id for service discovery
|
||||
const AppID = "account.service.spy"
|
||||
|
||||
// NewClient new identify grpc client
|
||||
func NewClient(cfg *warden.ClientConfig, opts ...grpc.DialOption) (SpyClient, error) {
|
||||
client := warden.NewClient(cfg, opts...)
|
||||
conn, err := client.Dial(context.Background(), "discovery://default/"+AppID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewSpyClient(conn), nil
|
||||
}
|
961
app/service/main/spy/api/copy.go
Normal file
961
app/service/main/spy/api/copy.go
Normal file
@ -0,0 +1,961 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
model "go-common/app/service/main/spy/model"
|
||||
"go-common/library/time"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClearReliveTimesReply) DeepCopyInto(out *ClearReliveTimesReply) {
|
||||
*out = *in
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClearReliveTimesReply.
|
||||
func (in *ClearReliveTimesReply) DeepCopy() *ClearReliveTimesReply {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClearReliveTimesReply)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClearReliveTimesReq) DeepCopyInto(out *ClearReliveTimesReq) {
|
||||
*out = *in
|
||||
if in.Arg != nil {
|
||||
in, out := &in.Arg, &out.Arg
|
||||
*out = new(ModelArgReset)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClearReliveTimesReq.
|
||||
func (in *ClearReliveTimesReq) DeepCopy() *ClearReliveTimesReq {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClearReliveTimesReq)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
func (in *ClearReliveTimesReq) DeepCopyAsIntoArgReset(out *model.ArgReset) {
|
||||
if out == nil {
|
||||
return
|
||||
}
|
||||
out.Mid = in.Arg.Mid
|
||||
out.BaseScore = in.Arg.BaseScore
|
||||
out.EventScore = in.Arg.EventScore
|
||||
out.Operator = in.Arg.Operator
|
||||
out.ReLiveTime = in.Arg.ReLiveTime
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HandleEventReply) DeepCopyInto(out *HandleEventReply) {
|
||||
*out = *in
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HandleEventReply.
|
||||
func (in *HandleEventReply) DeepCopy() *HandleEventReply {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HandleEventReply)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HandleEventReq) DeepCopyInto(out *HandleEventReq) {
|
||||
*out = *in
|
||||
if in.EventMsg != nil {
|
||||
in, out := &in.EventMsg, &out.EventMsg
|
||||
*out = new(ModelEventMessage)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (in *HandleEventReq) DeepCopyAsIntoEventMessage(out *model.EventMessage) {
|
||||
if out == nil {
|
||||
return
|
||||
}
|
||||
out.Time = time.Time(in.EventMsg.Time)
|
||||
out.IP = in.EventMsg.Ip
|
||||
out.Service = in.EventMsg.Service
|
||||
out.Event = in.EventMsg.Event
|
||||
out.ActiveMid = in.EventMsg.ActiveMid
|
||||
out.TargetMid = in.EventMsg.TargetMid
|
||||
out.TargetID = in.EventMsg.TargetId
|
||||
out.Result = in.EventMsg.Result
|
||||
out.Effect = in.EventMsg.Effect
|
||||
out.RiskLevel = int8(in.EventMsg.RiskLevel)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HandleEventReq.
|
||||
func (in *HandleEventReq) DeepCopy() *HandleEventReq {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HandleEventReq)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ModelArgReset) DeepCopyInto(out *ModelArgReset) {
|
||||
*out = *in
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ModelArgReset.
|
||||
func (in *ModelArgReset) DeepCopy() *ModelArgReset {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ModelArgReset)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ModelEventMessage) DeepCopyInto(out *ModelEventMessage) {
|
||||
*out = *in
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ModelEventMessage.
|
||||
func (in *ModelEventMessage) DeepCopy() *ModelEventMessage {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ModelEventMessage)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ModelStatistics) DeepCopyInto(out *ModelStatistics) {
|
||||
*out = *in
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ModelStatistics.
|
||||
func (in *ModelStatistics) DeepCopy() *ModelStatistics {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ModelStatistics)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyAsIntoStatistics is an autogenerated deepcopy function, copying the receiver, writing into model.Statistics.
|
||||
func (in *ModelStatistics) DeepCopyAsIntoStatistics(out *model.Statistics) {
|
||||
out.Quantity = in.Quantity
|
||||
out.EventName = in.EventName
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopyFromStatistics is an autogenerated deepcopy function, copying the receiver, writing into model.Statistics.
|
||||
func (out *ModelStatistics) DeepCopyFromStatistics(in *model.Statistics) {
|
||||
out.Quantity = in.Quantity
|
||||
out.EventId = in.EventID
|
||||
out.EventName = in.EventName
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopyAsStatistics is an autogenerated deepcopy function, copying the receiver, creating a new model.Statistics.
|
||||
func (in *ModelStatistics) DeepCopyAsStatistics() *model.Statistics {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(model.Statistics)
|
||||
in.DeepCopyAsIntoStatistics(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ModelUserInfo) DeepCopyInto(out *ModelUserInfo) {
|
||||
*out = *in
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ModelUserInfo.
|
||||
func (in *ModelUserInfo) DeepCopy() *ModelUserInfo {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ModelUserInfo)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyAsIntoUserInfo is an autogenerated deepcopy function, copying the receiver, writing into model.UserInfo.
|
||||
func (in *ModelUserInfo) DeepCopyAsIntoUserInfo(out *model.UserInfo) {
|
||||
out.Mid = in.Mid
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopyFromUserInfo is an autogenerated deepcopy function, copying the receiver, writing into model.UserInfo.
|
||||
func (out *ModelUserInfo) DeepCopyFromUserInfo(in *model.UserInfo) {
|
||||
if in == nil {
|
||||
return
|
||||
}
|
||||
out.Mid = in.Mid
|
||||
out.Id = in.ID
|
||||
out.Score = int32(in.Score)
|
||||
out.BaseScore = int32(in.BaseScore)
|
||||
out.EventScore = int32(in.EventScore)
|
||||
out.State = int32(in.State)
|
||||
out.ReliveTimes = int32(in.ReliveTimes)
|
||||
out.Ctime = int64(in.CTime)
|
||||
out.Mtime = int64(in.MTime)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopyAsUserInfo is an autogenerated deepcopy function, copying the receiver, creating a new model.UserInfo.
|
||||
func (in *ModelUserInfo) DeepCopyAsUserInfo() *model.UserInfo {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(model.UserInfo)
|
||||
in.DeepCopyAsIntoUserInfo(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PingReply) DeepCopyInto(out *PingReply) {
|
||||
*out = *in
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PingReply.
|
||||
func (in *PingReply) DeepCopy() *PingReply {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PingReply)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PingReq) DeepCopyInto(out *PingReq) {
|
||||
*out = *in
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PingReq.
|
||||
func (in *PingReq) DeepCopy() *PingReq {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PingReq)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PurgeUserReply) DeepCopyInto(out *PurgeUserReply) {
|
||||
*out = *in
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PurgeUserReply.
|
||||
func (in *PurgeUserReply) DeepCopy() *PurgeUserReply {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PurgeUserReply)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PurgeUserReq) DeepCopyInto(out *PurgeUserReq) {
|
||||
*out = *in
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PurgeUserReq.
|
||||
func (in *PurgeUserReq) DeepCopy() *PurgeUserReq {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PurgeUserReq)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ReBuildPortraitReply) DeepCopyInto(out *ReBuildPortraitReply) {
|
||||
*out = *in
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReBuildPortraitReply.
|
||||
func (in *ReBuildPortraitReply) DeepCopy() *ReBuildPortraitReply {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ReBuildPortraitReply)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ReBuildPortraitReq) DeepCopyInto(out *ReBuildPortraitReq) {
|
||||
*out = *in
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReBuildPortraitReq.
|
||||
func (in *ReBuildPortraitReq) DeepCopy() *ReBuildPortraitReq {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ReBuildPortraitReq)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RefreshBaseScoreReply) DeepCopyInto(out *RefreshBaseScoreReply) {
|
||||
*out = *in
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RefreshBaseScoreReply.
|
||||
func (in *RefreshBaseScoreReply) DeepCopy() *RefreshBaseScoreReply {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(RefreshBaseScoreReply)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RefreshBaseScoreReq) DeepCopyInto(out *RefreshBaseScoreReq) {
|
||||
*out = *in
|
||||
if in.Arg != nil {
|
||||
in, out := &in.Arg, &out.Arg
|
||||
*out = new(ModelArgReset)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RefreshBaseScoreReq.
|
||||
func (in *RefreshBaseScoreReq) DeepCopy() *RefreshBaseScoreReq {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(RefreshBaseScoreReq)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
func (in *RefreshBaseScoreReq) DeepCopyAsIntoArgReset(out *model.ArgReset) {
|
||||
if out == nil {
|
||||
return
|
||||
}
|
||||
out.Mid = in.Arg.Mid
|
||||
out.BaseScore = in.Arg.BaseScore
|
||||
out.EventScore = in.Arg.EventScore
|
||||
out.Operator = in.Arg.Operator
|
||||
out.ReLiveTime = in.Arg.ReLiveTime
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StatByIDGroupEventReply) DeepCopyInto(out *StatByIDGroupEventReply) {
|
||||
*out = *in
|
||||
if in.Res != nil {
|
||||
in, out := &in.Res, &out.Res
|
||||
*out = make([]*ModelStatistics, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = new(ModelStatistics)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
}
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatByIDGroupEventReply.
|
||||
func (in *StatByIDGroupEventReply) DeepCopy() *StatByIDGroupEventReply {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StatByIDGroupEventReply)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyAsIntoStatistics is an autogenerated deepcopy function, copying the receiver, writing into model.Statistics.
|
||||
func (in *StatByIDGroupEventReply) DeepCopyAsIntoStatistics(out *model.Statistics) {
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopyFromStatistics is an autogenerated deepcopy function, copying the receiver, writing into model.Statistics.
|
||||
func (out *StatByIDGroupEventReply) DeepCopyFromStatistics(in []*model.Statistics) {
|
||||
out.Res = make([]*ModelStatistics, 0, len(in))
|
||||
for _, v := range in {
|
||||
statistic := new(ModelStatistics)
|
||||
statistic.DeepCopyFromStatistics(v)
|
||||
out.Res = append(out.Res, statistic)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopyAsStatistics is an autogenerated deepcopy function, copying the receiver, creating a new model.Statistics.
|
||||
func (in *StatByIDGroupEventReply) DeepCopyAsStatistics() *model.Statistics {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(model.Statistics)
|
||||
in.DeepCopyAsIntoStatistics(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StatByIDGroupEventReq) DeepCopyInto(out *StatByIDGroupEventReq) {
|
||||
*out = *in
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatByIDGroupEventReq.
|
||||
func (in *StatByIDGroupEventReq) DeepCopy() *StatByIDGroupEventReq {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StatByIDGroupEventReq)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StatByIDReply) DeepCopyInto(out *StatByIDReply) {
|
||||
*out = *in
|
||||
if in.Stat != nil {
|
||||
in, out := &in.Stat, &out.Stat
|
||||
*out = make([]*ModelStatistics, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = new(ModelStatistics)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
}
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatByIDReply.
|
||||
func (in *StatByIDReply) DeepCopy() *StatByIDReply {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StatByIDReply)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyAsIntoStatistics is an autogenerated deepcopy function, copying the receiver, writing into model.Statistics.
|
||||
func (in *StatByIDReply) DeepCopyAsIntoStatistics(out *model.Statistics) {
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopyFromStatistics is an autogenerated deepcopy function, copying the receiver, writing into model.Statistics.
|
||||
func (out *StatByIDReply) DeepCopyFromStatistics(in []*model.Statistics) {
|
||||
out.Stat = make([]*ModelStatistics, 0, len(in))
|
||||
for _, v := range in {
|
||||
statistic := new(ModelStatistics)
|
||||
statistic.DeepCopyFromStatistics(v)
|
||||
out.Stat = append(out.Stat, statistic)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopyAsStatistics is an autogenerated deepcopy function, copying the receiver, creating a new model.Statistics.
|
||||
func (in *StatByIDReply) DeepCopyAsStatistics() *model.Statistics {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(model.Statistics)
|
||||
in.DeepCopyAsIntoStatistics(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StatByIDReq) DeepCopyInto(out *StatByIDReq) {
|
||||
*out = *in
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatByIDReq.
|
||||
func (in *StatByIDReq) DeepCopy() *StatByIDReq {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StatByIDReq)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *UpdateBaseScoreReply) DeepCopyInto(out *UpdateBaseScoreReply) {
|
||||
*out = *in
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpdateBaseScoreReply.
|
||||
func (in *UpdateBaseScoreReply) DeepCopy() *UpdateBaseScoreReply {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(UpdateBaseScoreReply)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *UpdateBaseScoreReq) DeepCopyInto(out *UpdateBaseScoreReq) {
|
||||
*out = *in
|
||||
if in.Arg != nil {
|
||||
in, out := &in.Arg, &out.Arg
|
||||
*out = new(ModelArgReset)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpdateBaseScoreReq.
|
||||
func (in *UpdateBaseScoreReq) DeepCopy() *UpdateBaseScoreReq {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(UpdateBaseScoreReq)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
func (in *UpdateBaseScoreReq) DeepCopyAsIntoArgReset(out *model.ArgReset) {
|
||||
if out == nil {
|
||||
return
|
||||
}
|
||||
out.Mid = in.Arg.Mid
|
||||
out.BaseScore = in.Arg.BaseScore
|
||||
out.EventScore = in.Arg.EventScore
|
||||
out.Operator = in.Arg.Operator
|
||||
out.ReLiveTime = in.Arg.ReLiveTime
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *UpdateEventScoreReply) DeepCopyInto(out *UpdateEventScoreReply) {
|
||||
*out = *in
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpdateEventScoreReply.
|
||||
func (in *UpdateEventScoreReply) DeepCopy() *UpdateEventScoreReply {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(UpdateEventScoreReply)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *UpdateEventScoreReq) DeepCopyInto(out *UpdateEventScoreReq) {
|
||||
*out = *in
|
||||
if in.Arg != nil {
|
||||
in, out := &in.Arg, &out.Arg
|
||||
*out = new(ModelArgReset)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpdateEventScoreReq.
|
||||
func (in *UpdateEventScoreReq) DeepCopy() *UpdateEventScoreReq {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(UpdateEventScoreReq)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
func (in *UpdateEventScoreReq) DeepCopyAsIntoArgReset(out *model.ArgReset) {
|
||||
if out == nil {
|
||||
return
|
||||
}
|
||||
out.Mid = in.Arg.Mid
|
||||
out.BaseScore = in.Arg.BaseScore
|
||||
out.EventScore = in.Arg.EventScore
|
||||
out.Operator = in.Arg.Operator
|
||||
out.ReLiveTime = in.Arg.ReLiveTime
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *UpdateUserScoreReply) DeepCopyInto(out *UpdateUserScoreReply) {
|
||||
*out = *in
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpdateUserScoreReply.
|
||||
func (in *UpdateUserScoreReply) DeepCopy() *UpdateUserScoreReply {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(UpdateUserScoreReply)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *UpdateUserScoreReq) DeepCopyInto(out *UpdateUserScoreReq) {
|
||||
*out = *in
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpdateUserScoreReq.
|
||||
func (in *UpdateUserScoreReq) DeepCopy() *UpdateUserScoreReq {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(UpdateUserScoreReq)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *UserInfoAsynReply) DeepCopyInto(out *UserInfoAsynReply) {
|
||||
*out = *in
|
||||
if in.Ui != nil {
|
||||
in, out := &in.Ui, &out.Ui
|
||||
*out = new(ModelUserInfo)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserInfoAsynReply.
|
||||
func (in *UserInfoAsynReply) DeepCopy() *UserInfoAsynReply {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(UserInfoAsynReply)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyAsIntoUserInfo is an autogenerated deepcopy function, copying the receiver, writing into model.UserInfo.
|
||||
func (in *UserInfoAsynReply) DeepCopyAsIntoUserInfo(out *model.UserInfo) {
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopyFromUserInfo is an autogenerated deepcopy function, copying the receiver, writing into model.UserInfo.
|
||||
func (out *UserInfoAsynReply) DeepCopyFromUserInfo(in *model.UserInfo) {
|
||||
if in == nil {
|
||||
return
|
||||
}
|
||||
out.Ui = new(ModelUserInfo)
|
||||
out.Ui.DeepCopyFromUserInfo(in)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopyAsUserInfo is an autogenerated deepcopy function, copying the receiver, creating a new model.UserInfo.
|
||||
func (in *UserInfoAsynReply) DeepCopyAsUserInfo() *model.UserInfo {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(model.UserInfo)
|
||||
in.DeepCopyAsIntoUserInfo(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *UserInfoAsynReq) DeepCopyInto(out *UserInfoAsynReq) {
|
||||
*out = *in
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserInfoAsynReq.
|
||||
func (in *UserInfoAsynReq) DeepCopy() *UserInfoAsynReq {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(UserInfoAsynReq)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *UserInfoReply) DeepCopyInto(out *UserInfoReply) {
|
||||
*out = *in
|
||||
if in.Ui != nil {
|
||||
in, out := &in.Ui, &out.Ui
|
||||
*out = new(ModelUserInfo)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserInfoReply.
|
||||
func (in *UserInfoReply) DeepCopy() *UserInfoReply {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(UserInfoReply)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyAsIntoUserInfo is an autogenerated deepcopy function, copying the receiver, writing into model.UserInfo.
|
||||
func (in *UserInfoReply) DeepCopyAsIntoUserInfo(out *model.UserInfo) {
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopyFromUserInfo is an autogenerated deepcopy function, copying the receiver, writing into model.UserInfo.
|
||||
func (out *UserInfoReply) DeepCopyFromUserInfo(in *model.UserInfo) {
|
||||
if in == nil {
|
||||
return
|
||||
}
|
||||
out.Ui = new(ModelUserInfo)
|
||||
out.Ui.DeepCopyFromUserInfo(in)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopyAsUserInfo is an autogenerated deepcopy function, copying the receiver, creating a new model.UserInfo.
|
||||
func (in *UserInfoReply) DeepCopyAsUserInfo() *model.UserInfo {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(model.UserInfo)
|
||||
in.DeepCopyAsIntoUserInfo(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *UserInfoReq) DeepCopyInto(out *UserInfoReq) {
|
||||
*out = *in
|
||||
out.XXX_NoUnkeyedLiteral = in.XXX_NoUnkeyedLiteral
|
||||
if in.XXX_unrecognized != nil {
|
||||
in, out := &in.XXX_unrecognized, &out.XXX_unrecognized
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserInfoReq.
|
||||
func (in *UserInfoReq) DeepCopy() *UserInfoReq {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(UserInfoReq)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
func (out *InfoReply) DeepCopyFromUserInfo(in *model.UserInfo) {
|
||||
if in == nil {
|
||||
return
|
||||
}
|
||||
out.Ui = new(ModelUserInfo)
|
||||
out.Ui.DeepCopyFromUserInfo(in)
|
||||
return
|
||||
}
|
2
app/service/main/spy/api/doc.go
Normal file
2
app/service/main/spy/api/doc.go
Normal file
@ -0,0 +1,2 @@
|
||||
// +bili:deepcopy-gen=package
|
||||
package v1
|
49
app/service/main/spy/cmd/BUILD
Normal file
49
app/service/main/spy/cmd/BUILD
Normal file
@ -0,0 +1,49 @@
|
||||
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 = ["spy-service-test.toml"],
|
||||
importpath = "go-common/app/service/main/spy/cmd",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/service/main/spy/conf:go_default_library",
|
||||
"//app/service/main/spy/rpc/server:go_default_library",
|
||||
"//app/service/main/spy/server/grpc:go_default_library",
|
||||
"//app/service/main/spy/server/http:go_default_library",
|
||||
"//app/service/main/spy/service:go_default_library",
|
||||
"//library/log:go_default_library",
|
||||
"//library/net/rpc:go_default_library",
|
||||
"//library/net/rpc/warden:go_default_library",
|
||||
"//library/net/trace:go_default_library",
|
||||
"//library/os/signal:go_default_library",
|
||||
"//library/syscall: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"],
|
||||
)
|
61
app/service/main/spy/cmd/main.go
Normal file
61
app/service/main/spy/cmd/main.go
Normal file
@ -0,0 +1,61 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"go-common/app/service/main/spy/conf"
|
||||
rpc "go-common/app/service/main/spy/rpc/server"
|
||||
grpc "go-common/app/service/main/spy/server/grpc"
|
||||
"go-common/app/service/main/spy/server/http"
|
||||
"go-common/app/service/main/spy/service"
|
||||
"go-common/library/log"
|
||||
xrpc "go-common/library/net/rpc"
|
||||
"go-common/library/net/rpc/warden"
|
||||
"go-common/library/net/trace"
|
||||
"go-common/library/os/signal"
|
||||
"go-common/library/syscall"
|
||||
)
|
||||
|
||||
var (
|
||||
svr *service.Service
|
||||
rpcSvr *xrpc.Server
|
||||
grpcSvr *warden.Server
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
if err := conf.Init(); err != nil {
|
||||
log.Error("conf.Init() error(%v)", err)
|
||||
panic(err)
|
||||
}
|
||||
log.Init(conf.Conf.Log)
|
||||
defer log.Close()
|
||||
trace.Init(conf.Conf.Tracer)
|
||||
defer trace.Close()
|
||||
// service init
|
||||
svr = service.New(conf.Conf)
|
||||
http.Init(conf.Conf, svr)
|
||||
rpcSvr = rpc.New(conf.Conf, svr)
|
||||
grpcSvr = grpc.New(conf.Conf.GRPC, svr)
|
||||
log.Info("spy-service start")
|
||||
// init signal
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT, syscall.SIGSTOP)
|
||||
for {
|
||||
s := <-c
|
||||
log.Info("spy-service get a signal %s", s.String())
|
||||
switch s {
|
||||
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGSTOP, syscall.SIGINT:
|
||||
rpcSvr.Close()
|
||||
time.Sleep(time.Second * 2)
|
||||
log.Info("spy-service exit")
|
||||
return
|
||||
case syscall.SIGHUP:
|
||||
// TODO reload
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
182
app/service/main/spy/cmd/spy-service-test.toml
Normal file
182
app/service/main/spy/cmd/spy-service-test.toml
Normal file
@ -0,0 +1,182 @@
|
||||
version = "1.0.0"
|
||||
user = "nobody"
|
||||
pid = "/tmp/spy-service.pid"
|
||||
dir = "./"
|
||||
checkFile = "/data/www/spy-service.html"
|
||||
family = "spy-service"
|
||||
|
||||
account = "http://passport.bilibili.co"
|
||||
|
||||
[xlog]
|
||||
dir = "/data/log/spy-service"
|
||||
|
||||
[db]
|
||||
[db.spy]
|
||||
addr= "172.16.33.205:3308"
|
||||
dsn = "test:test@tcp(172.16.33.205:3308)/bilibili_spy?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
|
||||
active = 5
|
||||
idle = 2
|
||||
idleTimeout ="4h"
|
||||
queryTimeout = "100ms"
|
||||
execTimeout = "100ms"
|
||||
tranTimeout = "200ms"
|
||||
[db.spy.breaker]
|
||||
window = "3s"
|
||||
sleep = "100ms"
|
||||
bucket = 10
|
||||
ratio = 0.5
|
||||
request = 100
|
||||
|
||||
[rpc]
|
||||
[rpc.account]
|
||||
|
||||
[bm]
|
||||
[bm.inner]
|
||||
addr = "0.0.0.0:7651"
|
||||
maxListen = 10
|
||||
timeout = "1s"
|
||||
|
||||
[httpClient]
|
||||
dial = "1s"
|
||||
timeout = "3s"
|
||||
keepAlive = "60s"
|
||||
timer = 1000
|
||||
key = "zxnh4k92dwe61t27"
|
||||
secret = "dnu3bwpxyswqwf1ixpsczthury1nqiew"
|
||||
[httpClient.breaker]
|
||||
window = "3s"
|
||||
sleep = "500ms"
|
||||
bucket = 10
|
||||
ratio = 0.5
|
||||
request = 100
|
||||
switchoff = false
|
||||
|
||||
[identify]
|
||||
[identify.host]
|
||||
auth = "http://passport.bilibili.co"
|
||||
secret = "http://open.bilibili.co"
|
||||
[identify.httpClient]
|
||||
key = "zxnh4k92dwe61t27"
|
||||
secret = "dnu3bwpxyswqwf1ixpsczthury1nqiew"
|
||||
dial = "30ms"
|
||||
timeout = "100ms"
|
||||
keepAlive = "60s"
|
||||
[identify.httpClient.breaker]
|
||||
window = "10s"
|
||||
sleep = "100ms"
|
||||
bucket = 10
|
||||
ratio = 0.5
|
||||
request = 100
|
||||
[identify.httpClient.url]
|
||||
"http://passport.bilibili.co/intranet/auth/tokenInfo" = {timeout = "100ms"}
|
||||
"http://passport.bilibili.co/intranet/auth/cookieInfo" = {timeout = "100ms"}
|
||||
"http://open.bilibili.co/api/getsecret" = {timeout = "500ms"}
|
||||
|
||||
[rpcServer2]
|
||||
[[rpcServer2.servers]]
|
||||
proto = "tcp"
|
||||
addr = "0.0.0.0:6869"
|
||||
weight = 10
|
||||
[rpcServer2.zookeeper]
|
||||
root = "/microservice/spy-service/"
|
||||
addrs = ["172.18.33.172:2181"]
|
||||
timeout = "30s"
|
||||
|
||||
[memcache]
|
||||
userExpire = "1m"
|
||||
[memcache.user]
|
||||
name = "spy-service/user"
|
||||
proto = "tcp"
|
||||
addr = "172.16.33.22:21211"
|
||||
idle = 5
|
||||
active = 10
|
||||
dialTimeout = "1s"
|
||||
readTimeout = "1s"
|
||||
writeTimeout = "1s"
|
||||
idleTimeout = "10s"
|
||||
|
||||
[property]
|
||||
telValidateURL = "http://passport.bilibili.co/intranet/acc/validateTel"
|
||||
blockAccountURL = "https://account.bilibili.com/api/member/blockAccount"
|
||||
securityLoginURL = "http://passport.bilibili.co/intranet/acc/security/mid"
|
||||
telInfoByMidURL = "http://passport.bilibili.co/intranet/acc/telInfo/mid"
|
||||
profileInfoByMidURL = "http://api.bilibili.co/x/internal/v3/account/profile"
|
||||
unicomGiftStateURL = "http://app.bilibili.com/x/wall/unicom/bind/state"
|
||||
loadEventTick = "60s"
|
||||
doubleCheckLevel = 4
|
||||
configLoadTick = "60s"
|
||||
userInfoShard = 100
|
||||
historyShard = 100
|
||||
autoBlockSwitch = true
|
||||
[property.score]
|
||||
baseInit = 100
|
||||
eventInit = 100
|
||||
[property.punishment]
|
||||
scoreThreshold = 30
|
||||
times = 3
|
||||
[property.event]
|
||||
serviceName = "spy_service"
|
||||
initEventID = 1
|
||||
bindMailAndTelLowRisk = "bind_mail_and_tel_low_risk"
|
||||
bindMailOnly = "bind_mail_only"
|
||||
bindNothing = "bind_nothing"
|
||||
bindTelLowRiskOnly = "bind_tel_low_risk_only"
|
||||
bindTelMediumRisk = "bind_tel_medium_risk"
|
||||
bindTelHighRisk = "bind_tel_high_risk"
|
||||
bindTelUnknownRisk = "bind_tel_unknown_risk"
|
||||
bindTelLowRiskAndIdenAuth = "bind_tel_low_risk_and_iden_auth"
|
||||
bindTelLowRiskAndIdenUnauth = "bind_tel_low_risk_and_iden_unauth"
|
||||
bindTelUnknownRiskAndIdenAuth = "bind_tel_unknown_risk_and_iden_auth"
|
||||
bindTelMediumRiskAndIdenAuth = "bind_tel_medium_risk_and_iden_auth"
|
||||
bindTelUnknownRiskAndIdenUnauth = "bind_tel_unknown_risk_and_iden_unauth"
|
||||
bindTelMediumRiskAndIdenUnauth = "bind_tel_medium_risk_and_iden_unauth"
|
||||
bindMailAndIdenUnknown = "bind_mail_and_iden_unknown"
|
||||
bindTelHighRiskAndIdenAuth = "bind_tel_high_risk_and_iden_auth"
|
||||
bindNothingV2 = "bind_nothing_v2"
|
||||
bindNothingAndIdenAuth = "bind_nothing_and_iden_auth"
|
||||
bindTelHighRiskAndIdenUnauth = "bind_tel_high_risk_and_iden_unauth"
|
||||
[property.block]
|
||||
cycleTimes = 3600
|
||||
[property.white]
|
||||
[[property.white.tels]]
|
||||
from = 23333330000
|
||||
to = 23333340000
|
||||
|
||||
|
||||
[redis]
|
||||
name = "spy-service"
|
||||
proto = "tcp"
|
||||
addr = "172.16.33.54:6379"
|
||||
idle = 100
|
||||
active = 100
|
||||
dialTimeout = "1s"
|
||||
readTimeout = "1s"
|
||||
writeTimeout = "1s"
|
||||
idleTimeout = "10s"
|
||||
expire = "24h"
|
||||
verifyCdTimes = "2h"
|
||||
|
||||
[dBScoreChange]
|
||||
key = "0QNB0ZgFozbKUCQhbTq8"
|
||||
secret= "0QNB0ZgFozbKUCQhbTq9"
|
||||
group= "SpyFigure-UGC-P"
|
||||
topic= "SpyFigure-T"
|
||||
action="pub"
|
||||
name = "spy-service/databus"
|
||||
proto = "tcp"
|
||||
addr = "172.16.33.158:6205"
|
||||
idle = 2
|
||||
active = 10
|
||||
dialTimeout = "1s"
|
||||
readTimeout = "60s"
|
||||
writeTimeout = "1s"
|
||||
idleTimeout = "10s"
|
||||
expire = "1h"
|
||||
|
||||
[qcloud]
|
||||
path = "RegisterProtection"
|
||||
region = "sh"
|
||||
secretID = ""
|
||||
secretKey = ""
|
||||
charset = "utf-8"
|
||||
baseURL = "csec.api.qcloud.com/v2/index.php"
|
51
app/service/main/spy/conf/BUILD
Normal file
51
app/service/main/spy/conf/BUILD
Normal file
@ -0,0 +1,51 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_test",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["conf_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
rundir = ".",
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["conf.go"],
|
||||
importpath = "go-common/app/service/main/spy/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/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"],
|
||||
)
|
196
app/service/main/spy/conf/conf.go
Normal file
196
app/service/main/spy/conf/conf.go
Normal file
@ -0,0 +1,196 @@
|
||||
package conf
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
|
||||
"go-common/library/cache/memcache"
|
||||
"go-common/library/cache/redis"
|
||||
"go-common/library/conf"
|
||||
"go-common/library/database/sql"
|
||||
"go-common/library/log"
|
||||
bm "go-common/library/net/http/blademaster"
|
||||
"go-common/library/net/rpc"
|
||||
"go-common/library/net/trace"
|
||||
"go-common/library/queue/databus"
|
||||
"go-common/library/time"
|
||||
xtime "go-common/library/time"
|
||||
|
||||
"go-common/library/net/rpc/warden"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
)
|
||||
|
||||
var (
|
||||
confPath string
|
||||
client *conf.Client
|
||||
// Conf represents a config for spy service.
|
||||
Conf = &Config{}
|
||||
)
|
||||
|
||||
// Config def.
|
||||
type Config struct {
|
||||
Account string
|
||||
// tracer
|
||||
Tracer *trace.Config
|
||||
// http client
|
||||
HTTPClient *bm.ClientConfig
|
||||
// db
|
||||
DB *DB
|
||||
// rpc server2
|
||||
RPCServer *rpc.ServerConfig
|
||||
// memcache
|
||||
Memcache *Memcache
|
||||
// log
|
||||
Log *log.Config
|
||||
// rpc clients
|
||||
RPC *RPC
|
||||
// biz property.
|
||||
Property *Property
|
||||
// redis
|
||||
Redis *Redis
|
||||
// databus
|
||||
DBScoreChange *databus.Config
|
||||
// qcloud
|
||||
Qcloud *Qcloud
|
||||
// bm
|
||||
BM *bm.ServerConfig
|
||||
// grpc
|
||||
GRPC *warden.ServerConfig
|
||||
}
|
||||
|
||||
// DB config.
|
||||
type DB struct {
|
||||
Spy *sql.Config
|
||||
}
|
||||
|
||||
// Redis redis.
|
||||
type Redis struct {
|
||||
*redis.Config
|
||||
Expire xtime.Duration
|
||||
VerifyCdTimes xtime.Duration
|
||||
}
|
||||
|
||||
// RPC clients config.
|
||||
type RPC struct {
|
||||
Account *rpc.ClientConfig
|
||||
}
|
||||
|
||||
// Memcache config.
|
||||
type Memcache struct {
|
||||
User *memcache.Config
|
||||
UserExpire time.Duration
|
||||
}
|
||||
|
||||
// Property config for biz logic.
|
||||
type Property struct {
|
||||
TelValidateURL string
|
||||
BlockAccountURL string
|
||||
SecurityLoginURL string
|
||||
TelInfoByMidURL string
|
||||
ProfileInfoByMidURL string
|
||||
UnicomGiftStateURL string
|
||||
LoadEventTick xtime.Duration
|
||||
DoubleCheckLevel int32
|
||||
ConfigLoadTick xtime.Duration
|
||||
UserInfoShard int64
|
||||
HistoryShard int64
|
||||
AutoBlockSwitch bool
|
||||
Score *struct {
|
||||
BaseInit int8
|
||||
EventInit int8
|
||||
}
|
||||
Punishment *struct {
|
||||
ScoreThreshold int8
|
||||
Times int8
|
||||
}
|
||||
Event *struct {
|
||||
ServiceName string
|
||||
InitEventID int64
|
||||
BindMailAndTelLowRisk string
|
||||
BindMailOnly string
|
||||
BindNothing string
|
||||
BindTelLowRiskOnly string
|
||||
BindTelMediumRisk string
|
||||
BindTelHighRisk string
|
||||
BindTelUnknownRisk string
|
||||
|
||||
BindTelLowRiskAndIdenAuth string
|
||||
BindTelLowRiskAndIdenUnauth string
|
||||
BindTelUnknownRiskAndIdenAuth string
|
||||
BindTelMediumRiskAndIdenAuth string
|
||||
BindTelUnknownRiskAndIdenUnauth string
|
||||
BindTelMediumRiskAndIdenUnauth string
|
||||
BindMailAndIdenUnknown string
|
||||
BindTelHighRiskAndIdenAuth string
|
||||
BindNothingV2 string
|
||||
BindNothingAndIdenAuth string
|
||||
BindTelHighRiskAndIdenUnauth string
|
||||
}
|
||||
Block *struct {
|
||||
CycleTimes int64 // unit per seconds
|
||||
}
|
||||
White *struct {
|
||||
Tels []struct {
|
||||
From int64 // <= from
|
||||
To int64 // >= to
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Qcloud def.
|
||||
type Qcloud struct {
|
||||
Path string
|
||||
Region string
|
||||
SecretID string
|
||||
SecretKey string
|
||||
Charset string
|
||||
BaseURL string
|
||||
}
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&confPath, "conf", "", "config path")
|
||||
}
|
||||
|
||||
// Init init conf.
|
||||
func Init() (err error) {
|
||||
if confPath == "" {
|
||||
return configCenter()
|
||||
}
|
||||
_, err = toml.DecodeFile(confPath, &Conf)
|
||||
return
|
||||
}
|
||||
|
||||
func configCenter() (err error) {
|
||||
if client, err = conf.New(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
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
|
||||
}
|
27
app/service/main/spy/conf/conf_test.go
Normal file
27
app/service/main/spy/conf/conf_test.go
Normal file
@ -0,0 +1,27 @@
|
||||
package conf
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestInit(t *testing.T) {
|
||||
flag.Set("conf", "../cmd/spy-service-test.toml")
|
||||
flag.Parse()
|
||||
var err error
|
||||
if err = Init(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if Conf == nil {
|
||||
t.Fatal()
|
||||
}
|
||||
if Conf.Property.Punishment == nil {
|
||||
t.Fatal()
|
||||
}
|
||||
if Conf.Property.Score == nil {
|
||||
t.Fatal()
|
||||
}
|
||||
t.Log(Conf.Property.AutoBlockSwitch)
|
||||
|
||||
t.Log(Conf.Property.White.Tels)
|
||||
}
|
74
app/service/main/spy/dao/BUILD
Normal file
74
app/service/main/spy/dao/BUILD
Normal file
@ -0,0 +1,74 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_test",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"account_test.go",
|
||||
"audit_test.go",
|
||||
"bilibili_card_test.go",
|
||||
"dao_test.go",
|
||||
"databus_test.go",
|
||||
"memcache_test.go",
|
||||
"mysql_test.go",
|
||||
"qcloud_test.go",
|
||||
"redis_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
rundir = ".",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//app/service/main/spy/conf:go_default_library",
|
||||
"//app/service/main/spy/model:go_default_library",
|
||||
"//library/time:go_default_library",
|
||||
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"account.go",
|
||||
"audit.go",
|
||||
"bilibili_card.go",
|
||||
"dao.go",
|
||||
"databus.go",
|
||||
"memcache.go",
|
||||
"mysql.go",
|
||||
"qcloud.go",
|
||||
"redis.go",
|
||||
],
|
||||
importpath = "go-common/app/service/main/spy/dao",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/service/main/spy/conf:go_default_library",
|
||||
"//app/service/main/spy/model: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/net/http/blademaster: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"],
|
||||
)
|
132
app/service/main/spy/dao/account.go
Normal file
132
app/service/main/spy/dao/account.go
Normal file
@ -0,0 +1,132 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"go-common/app/service/main/spy/model"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
// tel level.
|
||||
const (
|
||||
TelRiskLevelLow = 1
|
||||
TelRiskLevelMedium = 2
|
||||
TelRiskLevelHigh = 3
|
||||
TelRiskLevelUnknown = 4
|
||||
)
|
||||
|
||||
// TelRiskLevel tel risk level.
|
||||
func (d *Dao) TelRiskLevel(c context.Context, mid int64) (riskLevel int8, err error) {
|
||||
params := url.Values{}
|
||||
params.Set("mid", fmt.Sprintf("%d", mid))
|
||||
params.Set("type", "123")
|
||||
var resp struct {
|
||||
TS int64 `json:"ts"`
|
||||
Code int64 `json:"code"`
|
||||
Data struct {
|
||||
Level int8 `json:"level"`
|
||||
Mid int64 `json:"mid"`
|
||||
Score int64 `json:"score"`
|
||||
} `json:"data"`
|
||||
}
|
||||
if err = d.httpClient.Get(c, d.c.Property.TelValidateURL, "", params, &resp); err != nil {
|
||||
log.Error("d.httpClient.Do() error(%v) , riskLevel = TelRiskLevelUnknown", err)
|
||||
riskLevel = TelRiskLevelUnknown
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
if resp.Code != 0 {
|
||||
err = fmt.Errorf("GET TelRiskLevel url resp(%v)", resp)
|
||||
return
|
||||
}
|
||||
log.Info("GET TelValidateURL suc url(%s) resp(%v)", d.c.Property.TelValidateURL+"?"+params.Encode(), resp)
|
||||
riskLevel = resp.Data.Level
|
||||
return
|
||||
}
|
||||
|
||||
// BlockAccount block account.
|
||||
func (d *Dao) BlockAccount(c context.Context, mid int64) (err error) {
|
||||
params := url.Values{}
|
||||
params.Set("mid", fmt.Sprintf("%d", mid))
|
||||
params.Set("admin_reason", "spy")
|
||||
params.Set("blockType", "3")
|
||||
params.Set("operator", "spy")
|
||||
params.Set("type", "json")
|
||||
var resp struct {
|
||||
Code int64 `json:"code"`
|
||||
}
|
||||
if err = d.httpClient.Get(c, d.c.Property.BlockAccountURL, "", params, &resp); err != nil {
|
||||
log.Error("httpClient.Do() error(%v)", err)
|
||||
return
|
||||
}
|
||||
if resp.Code != 0 {
|
||||
err = fmt.Errorf("GET block account url resp(%v)", resp)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// SecurityLogin security login
|
||||
func (d *Dao) SecurityLogin(c context.Context, mid int64, reason string) (err error) {
|
||||
params := url.Values{}
|
||||
params.Set("mids", fmt.Sprintf("%d", mid))
|
||||
params.Set("operator", "spy")
|
||||
params.Set("desc", reason)
|
||||
params.Set("type", "json")
|
||||
var resp struct {
|
||||
Code int64 `json:"code"`
|
||||
}
|
||||
if err = d.httpClient.Post(c, d.c.Property.SecurityLoginURL, "", params, &resp); err != nil {
|
||||
log.Error("message url(%s) error(%v)", d.c.Property.SecurityLoginURL+"?"+params.Encode(), err)
|
||||
return
|
||||
}
|
||||
if resp.Code != 0 {
|
||||
err = fmt.Errorf("POST SecurityLogin url resp(%v)", resp)
|
||||
return
|
||||
}
|
||||
log.Info("POST SecurityLogin suc url(%s) resp(%v)", resp)
|
||||
return
|
||||
}
|
||||
|
||||
// TelInfo tel info.
|
||||
func (d *Dao) TelInfo(c context.Context, mid int64) (tel *model.TelInfo, err error) {
|
||||
params := url.Values{}
|
||||
params.Set("mid", fmt.Sprintf("%d", mid))
|
||||
var resp struct {
|
||||
Code int64 `json:"code"`
|
||||
Data model.TelInfo `json:"data"`
|
||||
}
|
||||
if err = d.httpClient.Get(c, d.c.Property.TelInfoByMidURL, "", params, &resp); err != nil {
|
||||
log.Error("d.httpClient.Do() error(%v) ,TelInfo", err)
|
||||
return
|
||||
}
|
||||
if resp.Code != 0 {
|
||||
err = fmt.Errorf("GET TelRiskLevel url resp(%v)", resp)
|
||||
return
|
||||
}
|
||||
tel = &resp.Data
|
||||
log.Info("GET TelInfoByMidURL suc url(%s) resp(%v)", d.c.Property.TelInfoByMidURL+"?"+params.Encode(), resp)
|
||||
return
|
||||
}
|
||||
|
||||
// ProfileInfo get user profile info from account service.
|
||||
func (d *Dao) ProfileInfo(c context.Context, mid int64, remoteIP string) (profile *model.ProfileInfo, err error) {
|
||||
params := url.Values{}
|
||||
params.Set("mid", fmt.Sprintf("%d", mid))
|
||||
var resp struct {
|
||||
Code int64 `json:"code"`
|
||||
Data model.ProfileInfo `json:"data"`
|
||||
}
|
||||
if err = d.httpClient.Get(c, d.c.Property.ProfileInfoByMidURL, remoteIP, params, &resp); err != nil {
|
||||
log.Error("d.httpClient.Do() error(%v), ProfileInfo", err)
|
||||
return
|
||||
}
|
||||
if resp.Code != 0 {
|
||||
err = fmt.Errorf("GET ProfileInfo url resp(%v)", resp)
|
||||
return
|
||||
}
|
||||
profile = &resp.Data
|
||||
log.Info("GET ProfileInfoByMidURL suc url(%s) resp(%v)", d.c.Property.ProfileInfoByMidURL+"?"+params.Encode(), resp)
|
||||
return
|
||||
}
|
87
app/service/main/spy/dao/account_test.go
Normal file
87
app/service/main/spy/dao/account_test.go
Normal file
@ -0,0 +1,87 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestDaoTelRiskLevel(t *testing.T) {
|
||||
convey.Convey("TelRiskLevel", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(1)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
riskLevel, err := d.TelRiskLevel(c, mid)
|
||||
ctx.Convey("Then err should be nil.riskLevel should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(riskLevel, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoBlockAccount(t *testing.T) {
|
||||
convey.Convey("BlockAccount", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(1)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
err := d.BlockAccount(c, mid)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoSecurityLogin(t *testing.T) {
|
||||
convey.Convey("SecurityLogin", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(1)
|
||||
reason = "unit test"
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
err := d.SecurityLogin(c, mid, reason)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoTelInfo(t *testing.T) {
|
||||
convey.Convey("TelInfo", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(1)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
tel, err := d.TelInfo(c, mid)
|
||||
ctx.Convey("Then err should be nil.tel should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(tel, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestProfileInfo(t *testing.T) {
|
||||
convey.Convey("ProfileInfo", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(1)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
tel, err := d.ProfileInfo(c, mid, "")
|
||||
ctx.Convey("Then err should be nil.tel should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(tel, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
37
app/service/main/spy/dao/audit.go
Normal file
37
app/service/main/spy/dao/audit.go
Normal file
@ -0,0 +1,37 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"go-common/app/service/main/spy/model"
|
||||
"go-common/library/ecode"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
const (
|
||||
_auditInfo = "/api/member/audit"
|
||||
)
|
||||
|
||||
// AuditInfo get user audit info
|
||||
func (d *Dao) AuditInfo(c context.Context, mid int64, remoteIP string) (rs *model.AuditInfo, err error) {
|
||||
params := url.Values{}
|
||||
params.Set("mid", strconv.FormatInt(mid, 10))
|
||||
var res struct {
|
||||
Code int `json:"code"`
|
||||
Data model.AuditInfo `json:"data"`
|
||||
}
|
||||
if err = d.httpClient.Get(c, d.auditInfoURI, remoteIP, params, &res); err != nil {
|
||||
log.Error("account get audit info url(%s) error(%v)", d.auditInfoURI+"?"+params.Encode(), err)
|
||||
return
|
||||
}
|
||||
if res.Code != 0 {
|
||||
log.Error("account get audit info url(%s) error(%v)", d.auditInfoURI+"?"+params.Encode(), res.Code)
|
||||
err = ecode.Int(res.Code)
|
||||
return
|
||||
}
|
||||
rs = &res.Data
|
||||
log.Info("GET AuditInfoURL suc url(%s) resp(%v)", d.auditInfoURI+"?"+params.Encode(), res)
|
||||
return
|
||||
}
|
24
app/service/main/spy/dao/audit_test.go
Normal file
24
app/service/main/spy/dao/audit_test.go
Normal file
@ -0,0 +1,24 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestDaoAuditInfo(t *testing.T) {
|
||||
convey.Convey("AuditInfo", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(1)
|
||||
remoteIP = ""
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.AuditInfo(c, mid, remoteIP)
|
||||
ctx.Convey("Then err should be nil.rs should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
31
app/service/main/spy/dao/bilibili_card.go
Normal file
31
app/service/main/spy/dao/bilibili_card.go
Normal file
@ -0,0 +1,31 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"go-common/app/service/main/spy/model"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
// UnicomGiftState get unicom gift state by mid from account service.
|
||||
func (d *Dao) UnicomGiftState(c context.Context, mid int64) (state int, err error) {
|
||||
params := url.Values{}
|
||||
params.Set("mid", fmt.Sprintf("%d", mid))
|
||||
var resp struct {
|
||||
Code int64 `json:"code"`
|
||||
Data *model.UnicomGiftState `json:"data"`
|
||||
}
|
||||
if err = d.httpClient.Get(c, d.c.Property.UnicomGiftStateURL, "", params, &resp); err != nil {
|
||||
log.Error("message url(%s) error(%v)", d.c.Property.UnicomGiftStateURL+"?"+params.Encode(), err)
|
||||
return
|
||||
}
|
||||
if resp.Code != 0 {
|
||||
err = fmt.Errorf("GET UnicomGiftStateURL url resp(%v)", resp)
|
||||
return
|
||||
}
|
||||
log.Info("GET UnicomGiftStateURL suc url(%s) resp(%v)", d.c.Property.UnicomGiftStateURL+"?"+params.Encode(), resp)
|
||||
state = resp.Data.State
|
||||
return
|
||||
}
|
24
app/service/main/spy/dao/bilibili_card_test.go
Normal file
24
app/service/main/spy/dao/bilibili_card_test.go
Normal file
@ -0,0 +1,24 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestDaoUnicomGiftState(t *testing.T) {
|
||||
convey.Convey("UnicomGiftState", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(27515247)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
state, err := d.UnicomGiftState(c, mid)
|
||||
ctx.Convey("Then err should be nil.state should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(state, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
87
app/service/main/spy/dao/dao.go
Normal file
87
app/service/main/spy/dao/dao.go
Normal file
@ -0,0 +1,87 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"go-common/app/service/main/spy/conf"
|
||||
"go-common/library/cache/memcache"
|
||||
"go-common/library/cache/redis"
|
||||
"go-common/library/database/sql"
|
||||
bm "go-common/library/net/http/blademaster"
|
||||
"go-common/library/queue/databus"
|
||||
)
|
||||
|
||||
// Dao event dao def.
|
||||
type Dao struct {
|
||||
c *conf.Config
|
||||
// db
|
||||
db *sql.DB
|
||||
// mc
|
||||
mcUser *memcache.Pool
|
||||
mcUserExpire int32
|
||||
// redis
|
||||
redis *redis.Pool
|
||||
expire int
|
||||
verifyExpire int
|
||||
// http client
|
||||
httpClient *bm.Client
|
||||
auditInfoURI string
|
||||
// databus for spy score change
|
||||
dbScoreChange *databus.Databus
|
||||
r *rand.Rand
|
||||
}
|
||||
|
||||
// New create instance of dao and return.
|
||||
func New(c *conf.Config) (d *Dao) {
|
||||
d = &Dao{
|
||||
c: c,
|
||||
// db
|
||||
db: sql.NewMySQL(c.DB.Spy),
|
||||
// mc
|
||||
mcUser: memcache.NewPool(c.Memcache.User),
|
||||
mcUserExpire: int32(time.Duration(c.Memcache.UserExpire) / time.Second),
|
||||
// redis
|
||||
redis: redis.NewPool(c.Redis.Config),
|
||||
expire: int(time.Duration(c.Redis.Expire) / time.Second),
|
||||
verifyExpire: int(time.Duration(c.Redis.VerifyCdTimes) / time.Second),
|
||||
// http client
|
||||
httpClient: bm.NewClient(c.HTTPClient),
|
||||
auditInfoURI: c.Account + _auditInfo,
|
||||
// databus
|
||||
dbScoreChange: databus.New(c.DBScoreChange),
|
||||
r: rand.New(rand.NewSource(time.Now().Unix())),
|
||||
}
|
||||
if conf.Conf.Property.UserInfoShard <= 0 {
|
||||
panic("conf.Conf.Property.UserInfoShard <= 0")
|
||||
}
|
||||
if conf.Conf.Property.HistoryShard <= 0 {
|
||||
panic("conf.Conf.Property.HistoryShard <= 0")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Ping check db health.
|
||||
func (d *Dao) Ping(c context.Context) (err error) {
|
||||
if err = d.pingMC(c); err != nil {
|
||||
return
|
||||
}
|
||||
if err = d.PingRedis(c); err != nil {
|
||||
return
|
||||
}
|
||||
return d.db.Ping(c)
|
||||
}
|
||||
|
||||
// Close close all db connections.
|
||||
func (d *Dao) Close() {
|
||||
if d.mcUser != nil {
|
||||
d.mcUser.Close()
|
||||
}
|
||||
if d.redis != nil {
|
||||
d.redis.Close()
|
||||
}
|
||||
if d.db != nil {
|
||||
d.db.Close()
|
||||
}
|
||||
}
|
35
app/service/main/spy/dao/dao_test.go
Normal file
35
app/service/main/spy/dao/dao_test.go
Normal file
@ -0,0 +1,35 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"go-common/app/service/main/spy/conf"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var (
|
||||
d *Dao
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
if os.Getenv("DEPLOY_ENV") != "" {
|
||||
flag.Set("app_id", "main.account.spy-service")
|
||||
flag.Set("conf_token", "22741f7d4338595a152f282062e4e2fa")
|
||||
flag.Set("tree_id", "2855")
|
||||
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/spy-service.toml")
|
||||
}
|
||||
flag.Parse()
|
||||
if err := conf.Init(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
d = New(conf.Conf)
|
||||
m.Run()
|
||||
os.Exit(0)
|
||||
}
|
17
app/service/main/spy/dao/databus.go
Normal file
17
app/service/main/spy/dao/databus.go
Normal file
@ -0,0 +1,17 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
// PubScoreChange pub spy score change msg into databus.
|
||||
func (d *Dao) PubScoreChange(c context.Context, mid int64, msg interface{}) (err error) {
|
||||
key := strconv.FormatInt(mid, 10)
|
||||
if err = d.dbScoreChange.Send(c, key, msg); err != nil {
|
||||
log.Error("d.dbScoreChange.Send(%s, %v) error (%v)", key, msg, err)
|
||||
}
|
||||
return
|
||||
}
|
24
app/service/main/spy/dao/databus_test.go
Normal file
24
app/service/main/spy/dao/databus_test.go
Normal file
@ -0,0 +1,24 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestDaoPubScoreChange(t *testing.T) {
|
||||
convey.Convey("PubScoreChange", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(1)
|
||||
msg = interface{}(0)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
err := d.PubScoreChange(c, mid, msg)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
103
app/service/main/spy/dao/memcache.go
Normal file
103
app/service/main/spy/dao/memcache.go
Normal file
@ -0,0 +1,103 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"go-common/app/service/main/spy/model"
|
||||
"go-common/library/cache/memcache"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
const (
|
||||
_userKey = "u_%d"
|
||||
)
|
||||
|
||||
// pingMC ping memcache.
|
||||
func (d *Dao) pingMC(c context.Context) (err error) {
|
||||
conn := d.mcUser.Get(c)
|
||||
defer conn.Close()
|
||||
if err = conn.Set(&memcache.Item{Key: "ping", Value: []byte{1}, Expiration: 0}); err != nil {
|
||||
log.Error("conn.Store(set,ping,1) error(%v)", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func userInfoCacheKey(mid int64) string {
|
||||
return fmt.Sprintf(_userKey, mid)
|
||||
}
|
||||
|
||||
// UserInfoCache get user info to cache.
|
||||
func (d *Dao) UserInfoCache(c context.Context, mid int64) (ui *model.UserInfo, err error) {
|
||||
var (
|
||||
key = userInfoCacheKey(mid)
|
||||
conn = d.mcUser.Get(c)
|
||||
)
|
||||
defer conn.Close()
|
||||
reply, err := conn.Get(key)
|
||||
if err != nil {
|
||||
if err == memcache.ErrNotFound {
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
log.Error("conn.Get(get, %s) error(%v)", key, err)
|
||||
return
|
||||
}
|
||||
ui = &model.UserInfo{}
|
||||
if err = conn.Scan(reply, ui); err != nil {
|
||||
log.Error("reply.Scan(%s) error(%v)", string(reply.Value), err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// AddUserInfoCache add info to cache , return err if key is exist already.
|
||||
func (d *Dao) AddUserInfoCache(c context.Context, ui *model.UserInfo) (err error) {
|
||||
if ui == nil {
|
||||
return fmt.Errorf("AddUserInfoCache got nil *model.UserInfo")
|
||||
}
|
||||
var (
|
||||
key = userInfoCacheKey(ui.Mid)
|
||||
conn = d.mcUser.Get(c)
|
||||
)
|
||||
defer conn.Close()
|
||||
|
||||
if err = conn.Add(&memcache.Item{Key: key, Object: ui, Expiration: d.mcUserExpire, Flags: memcache.FlagJSON}); err != nil {
|
||||
log.Error("conn.Add(%s, %v) error(%v)", key, ui, err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// SetUserInfoCache set info cache.
|
||||
func (d *Dao) SetUserInfoCache(c context.Context, ui *model.UserInfo) (err error) {
|
||||
if ui == nil {
|
||||
return fmt.Errorf("SetUserInfoCache got nil *model.UserInfo")
|
||||
}
|
||||
var (
|
||||
key = userInfoCacheKey(ui.Mid)
|
||||
conn = d.mcUser.Get(c)
|
||||
)
|
||||
defer conn.Close()
|
||||
|
||||
if err = conn.Set(&memcache.Item{Key: key, Object: ui, Expiration: d.mcUserExpire, Flags: memcache.FlagJSON}); err != nil {
|
||||
log.Error("conn.Set(%s, %v) error(%v)", key, ui, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DelInfoCache delete info cache.
|
||||
func (d *Dao) DelInfoCache(c context.Context, mid int64) (err error) {
|
||||
var (
|
||||
key = userInfoCacheKey(mid)
|
||||
conn = d.mcUser.Get(c)
|
||||
)
|
||||
defer conn.Close()
|
||||
if err = conn.Delete(key); err != nil {
|
||||
if err == memcache.ErrNotFound {
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
log.Error("conn.Delete(%s) error(%v)", key, err)
|
||||
}
|
||||
return
|
||||
}
|
97
app/service/main/spy/dao/memcache_test.go
Normal file
97
app/service/main/spy/dao/memcache_test.go
Normal file
@ -0,0 +1,97 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"go-common/app/service/main/spy/model"
|
||||
"testing"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestDaopingMC(t *testing.T) {
|
||||
convey.Convey("pingMC", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
err := d.pingMC(c)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaouserInfoCacheKey(t *testing.T) {
|
||||
convey.Convey("userInfoCacheKey", t, func(ctx convey.C) {
|
||||
var (
|
||||
mid = int64(1)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
p1 := userInfoCacheKey(mid)
|
||||
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(p1, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoUserInfoCache(t *testing.T) {
|
||||
convey.Convey("UserInfoCache", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(1)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.UserInfoCache(c, mid)
|
||||
ctx.Convey("Then err should be nil.ui should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoAddUserInfoCache(t *testing.T) {
|
||||
convey.Convey("AddUserInfoCache", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
ui = &model.UserInfo{}
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
err := d.AddUserInfoCache(c, ui)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoSetUserInfoCache(t *testing.T) {
|
||||
convey.Convey("SetUserInfoCache", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
ui = &model.UserInfo{}
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
err := d.SetUserInfoCache(c, ui)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoDelInfoCache(t *testing.T) {
|
||||
convey.Convey("DelInfoCache", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(1)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
err := d.DelInfoCache(c, mid)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
475
app/service/main/spy/dao/mysql.go
Normal file
475
app/service/main/spy/dao/mysql.go
Normal file
@ -0,0 +1,475 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
xsql "database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"go-common/app/service/main/spy/conf"
|
||||
"go-common/app/service/main/spy/model"
|
||||
"go-common/library/database/sql"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
const (
|
||||
_serviceSQL = "SELECT id,name,nick_name,status,ctime,mtime FROM spy_service WHERE name=? AND status<>0 LIMIT 1"
|
||||
_addServiceSQL = "INSERT INTO spy_service (name,nick_name,status,ctime) VALUES (?,?,?,?)"
|
||||
_eventSQL = "SELECT id,name,nick_name,service_id,status,ctime,mtime FROM spy_event WHERE name=? AND status<>0 LIMIT 1"
|
||||
_addEventSQL = "INSERT INTO spy_event (name,nick_name,service_id,status,ctime) VALUES (?,?,?,?,?)"
|
||||
_factorSQL = "SELECT id,nick_name,service_id,event_id,group_id,risk_level,factor_val,ctime,mtime FROM spy_factor WHERE service_id=? AND event_id=? AND risk_level=? LIMIT 1"
|
||||
_factorGroupSQL = "SELECT id,name,ctime FROM spy_factor_group WHERE name=? LIMIT 1"
|
||||
_userInfoSQL = "SELECT id,mid,score,base_score,event_score,state,relive_times,ctime,mtime FROM spy_user_info_%02d WHERE mid=? LIMIT 1"
|
||||
_addUserInfoSQL = "INSERT IGNORE INTO spy_user_info_%02d (mid,score,base_score,event_score,state,ctime,mtime) VALUES (?,?,?,?,?,?,?)"
|
||||
_updateEventScoreSQL = "UPDATE spy_user_info_%02d SET event_score=?, score=? WHERE mid=?"
|
||||
_updateInfoSQL = "UPDATE spy_user_info_%02d SET base_score=?, event_score=?, score=?, state=? WHERE mid=?;"
|
||||
_updateBaseScoreSQL = "UPDATE spy_user_info_%02d SET base_score=?, score=? WHERE mid=?;"
|
||||
_addEventHistorySQL = "INSERT INTO spy_user_event_history_%02d (mid,event_id,score,base_score,event_score,remark,reason,factor_val,ctime) VALUES (?,?,?,?,?,?,?,?,?);"
|
||||
_getEventHistoryByMidAndEventSQL = "SELECT mid, event_id FROM spy_user_event_history_%02d WHERE mid = ? and event_id = ? limit 1"
|
||||
_addPunishmentSQL = "INSERT INTO spy_punishment (mid,type,reason,ctime) VALUES (?,?,?,?);"
|
||||
_addPunishmentQueueSQL = "INSERT INTO spy_punishment_queue (mid,batch_no,ctime) VALUES (?,?,?) ON DUPLICATE KEY UPDATE mtime=?;"
|
||||
_getAllConfigSQL = "SELECT id, property,name,val,ctime FROM spy_system_config;"
|
||||
_clearReliveTimesSQL = "UPDATE spy_user_info_%02d SET relive_times=? WHERE mid=?;"
|
||||
_getHistoryListSQL = "SELECT remark,reason FROM spy_user_event_history_%02d WHERE mid= ? ORDER BY id DESC LIMIT ?;"
|
||||
_updateEventScoreReLiveSQL = "UPDATE spy_user_info_%02d SET event_score=?, score=?, relive_times=relive_times+1 WHERE mid=?"
|
||||
_statListByMidSQL = "SELECT event_id,quantity FROM spy_statistics WHERE target_mid = ? AND isdel = 0 ORDER BY id desc LIMIT 100;"
|
||||
_statListByIDSQL = "SELECT event_id,quantity FROM spy_statistics WHERE target_id = ? AND isdel = 0 ORDER BY id desc LIMIT 100;"
|
||||
_statListByIDAndMidSQL = "SELECT event_id,quantity FROM spy_statistics WHERE target_mid = ? AND target_id = ? AND isdel = 0 ORDER BY id desc LIMIT 100;"
|
||||
_allEventSQL = "SELECT id,name,nick_name,service_id,status,ctime,mtime FROM spy_event WHERE status<>0"
|
||||
_telLevelSQL = "SELECT id,mid,level,origin,ctime,mtime FROM spy_tel_risk_level WHERE mid = ? LIMIT 1;"
|
||||
_addTelLevelSQL = "INSERT INTO spy_tel_risk_level (mid,level,origin,ctime) VALUES (?,?,?,?) "
|
||||
)
|
||||
|
||||
// Service get service from db.
|
||||
func (d *Dao) Service(c context.Context, serviceName string) (service *model.Service, err error) {
|
||||
var (
|
||||
row *sql.Row
|
||||
)
|
||||
service = &model.Service{}
|
||||
row = d.db.QueryRow(c, _serviceSQL, serviceName)
|
||||
if err = row.Scan(&service.ID, &service.Name, &service.NickName, &service.Status, &service.CTime, &service.MTime); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
err = nil
|
||||
service = nil
|
||||
return
|
||||
}
|
||||
log.Error("row.Scan() error(%v)", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Event get event from db.
|
||||
func (d *Dao) Event(c context.Context, eventName string) (event *model.Event, err error) {
|
||||
var row *sql.Row
|
||||
event = &model.Event{}
|
||||
row = d.db.QueryRow(c, _eventSQL, eventName)
|
||||
if err = row.Scan(&event.ID, &event.Name, &event.NickName, &event.ServiceID, &event.Status, &event.CTime, &event.MTime); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
err = nil
|
||||
event = nil
|
||||
return
|
||||
}
|
||||
log.Error("row.Scan() error(%v)", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// AddService insert service to db.
|
||||
func (d *Dao) AddService(c context.Context, service *model.Service) (id int64, err error) {
|
||||
var (
|
||||
res xsql.Result
|
||||
)
|
||||
if res, err = d.db.Exec(c, _addServiceSQL, service.Name, service.NickName, service.Status, time.Now()); err != nil {
|
||||
log.Error("d.db.Exec(%s, %s, %d) error(%v)", _addServiceSQL, service.Name, service.Status, err)
|
||||
return
|
||||
}
|
||||
if id, err = res.LastInsertId(); err != nil {
|
||||
log.Error("res.LastInsertId() error(%v)", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// AddEvent insert service to db.
|
||||
func (d *Dao) AddEvent(c context.Context, event *model.Event) (id int64, err error) {
|
||||
var (
|
||||
res xsql.Result
|
||||
)
|
||||
if res, err = d.db.Exec(c, _addEventSQL, event.Name, event.NickName, event.ServiceID, event.Status, time.Now()); err != nil {
|
||||
log.Error("d.db.Exec(%s, %s, %s, %d, %d) error(%v)", _addEventSQL, event.Name, event.NickName, event.ServiceID, event.Status, err)
|
||||
return
|
||||
}
|
||||
if id, err = res.LastInsertId(); err != nil {
|
||||
log.Error("res.LastInsertId() error(%v)", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Factor get factor from db.
|
||||
func (d *Dao) Factor(c context.Context, serviceID, eventID int64, riskLevel int8) (factor *model.Factor, err error) {
|
||||
var (
|
||||
row *sql.Row
|
||||
)
|
||||
factor = &model.Factor{}
|
||||
row = d.db.QueryRow(c, _factorSQL, serviceID, eventID, riskLevel)
|
||||
if err = row.Scan(&factor.ID, &factor.NickName, &factor.ServiceID, &factor.EventID, &factor.GroupID, &factor.RiskLevel, &factor.FactorVal, &factor.CTime, &factor.MTime); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
err = nil
|
||||
factor = nil
|
||||
return
|
||||
}
|
||||
log.Error("row.Scan() error(%v)", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// FactorGroup get factor group from db.
|
||||
func (d *Dao) FactorGroup(c context.Context, groupName string) (factorGroup *model.FactorGroup, err error) {
|
||||
var (
|
||||
row *sql.Row
|
||||
)
|
||||
factorGroup = &model.FactorGroup{}
|
||||
row = d.db.QueryRow(c, _factorGroupSQL, groupName)
|
||||
if err = row.Scan(&factorGroup.ID, &factorGroup.Name, &factorGroup.CTime); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
err = nil
|
||||
factorGroup = nil
|
||||
return
|
||||
}
|
||||
log.Error("row.Scan() error(%v)", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func hitInfo(id int64) int64 {
|
||||
return id % conf.Conf.Property.UserInfoShard
|
||||
}
|
||||
|
||||
func hitHistory(id int64) int64 {
|
||||
return id % conf.Conf.Property.HistoryShard
|
||||
}
|
||||
|
||||
// BeginTran begin transaction.
|
||||
func (d *Dao) BeginTran(c context.Context) (*sql.Tx, error) {
|
||||
return d.db.Begin(c)
|
||||
}
|
||||
|
||||
// UserInfo get info by mid.
|
||||
func (d *Dao) UserInfo(c context.Context, mid int64) (res *model.UserInfo, err error) {
|
||||
var (
|
||||
row *sql.Row
|
||||
)
|
||||
res = &model.UserInfo{}
|
||||
row = d.db.QueryRow(c, fmt.Sprintf(_userInfoSQL, hitInfo(mid)), mid)
|
||||
if err = row.Scan(&res.ID, &res.Mid, &res.Score, &res.BaseScore, &res.EventScore, &res.State, &res.ReliveTimes, &res.CTime, &res.MTime); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
err = nil
|
||||
res = nil
|
||||
return
|
||||
}
|
||||
log.Error("row.Scan() error(%v)", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// TxUpdateInfo insert or update user info by mid.
|
||||
func (d *Dao) TxUpdateInfo(c context.Context, tx *sql.Tx, info *model.UserInfo) (err error) {
|
||||
if _, err = d.db.Exec(c, fmt.Sprintf(_updateInfoSQL, hitInfo(info.Mid)), info.BaseScore, info.EventScore, info.Score, info.State, info.Mid); err != nil {
|
||||
log.Error("db.Exec(%d, %+v) error(%v)", info.Mid, info, err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// TxAddInfo add user info.
|
||||
func (d *Dao) TxAddInfo(c context.Context, tx *sql.Tx, info *model.UserInfo) (id int64, err error) {
|
||||
var (
|
||||
res xsql.Result
|
||||
now = time.Now()
|
||||
)
|
||||
if res, err = tx.Exec(fmt.Sprintf(_addUserInfoSQL, hitInfo(info.Mid)), info.Mid, info.Score, info.BaseScore, info.EventScore, info.State, now, now); err != nil {
|
||||
log.Error("db.Exec(%d, %v) error(%v)", info.Mid, *info, err)
|
||||
return
|
||||
}
|
||||
return res.LastInsertId()
|
||||
}
|
||||
|
||||
// TxAddEventHistory insert user_event_history.
|
||||
func (d *Dao) TxAddEventHistory(c context.Context, tx *sql.Tx, ueh *model.UserEventHistory) (err error) {
|
||||
var (
|
||||
now = time.Now()
|
||||
)
|
||||
if _, err = tx.Exec(fmt.Sprintf(_addEventHistorySQL, hitHistory(ueh.Mid)), ueh.Mid, ueh.EventID, ueh.Score, ueh.BaseScore, ueh.EventScore, ueh.Remark, ueh.Reason, ueh.FactorVal, now); err != nil {
|
||||
log.Error("db.Exec(%v) error(%v)", ueh, err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// EventHistoryByMidAndEvent get one event history with mid and eventID from db.
|
||||
func (d *Dao) EventHistoryByMidAndEvent(c context.Context, mid int64, eventID int64) (res *model.UserEventHistory, err error) {
|
||||
var (
|
||||
row *sql.Row
|
||||
)
|
||||
res = &model.UserEventHistory{}
|
||||
row = d.db.QueryRow(c, fmt.Sprintf(_getEventHistoryByMidAndEventSQL, hitHistory(mid)), mid, eventID)
|
||||
if err = row.Scan(&res.Mid, &res.EventID); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, nil
|
||||
}
|
||||
log.Error("row.Scan() error:(%v)", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// TxAddPunishment insert punishment.
|
||||
func (d *Dao) TxAddPunishment(c context.Context, tx *sql.Tx, mid int64, t int8, reason string) (err error) {
|
||||
var (
|
||||
now = time.Now()
|
||||
)
|
||||
if _, err = tx.Exec(_addPunishmentSQL, mid, t, reason, now); err != nil {
|
||||
log.Error("db.Exec(%d, %d, %s) error(%v)", mid, t, reason, err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// TxAddPunishmentQueue insert punishment queue.
|
||||
func (d *Dao) TxAddPunishmentQueue(c context.Context, tx *sql.Tx, mid int64, blockNo int64) (err error) {
|
||||
var (
|
||||
now = time.Now()
|
||||
)
|
||||
if _, err = tx.Exec(_addPunishmentQueueSQL, mid, blockNo, now, now); err != nil {
|
||||
log.Error("TxAddPunishmentQueue:db.Exec(%d) error(%v)", mid, err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// AddPunishmentQueue insert punishment queue.
|
||||
func (d *Dao) AddPunishmentQueue(c context.Context, mid int64, blockNo int64) (err error) {
|
||||
var (
|
||||
now = time.Now()
|
||||
)
|
||||
if _, err = d.db.Exec(c, _addPunishmentQueueSQL, mid, blockNo, now, now); err != nil {
|
||||
log.Error("AddPunishmentQueue:db.Exec(%d) error(%v)", mid, err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// TxUpdateEventScore update user event score.
|
||||
func (d *Dao) TxUpdateEventScore(c context.Context, tx *sql.Tx, mid int64, escore, score int8) (err error) {
|
||||
if _, err = tx.Exec(fmt.Sprintf(_updateEventScoreSQL, hitInfo(mid)), escore, score, mid); err != nil {
|
||||
log.Error("db.TxUpdateEventScore(%s, %d, %d, %d) error(%v)", _updateEventScoreSQL, escore, score, mid, err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//TxUpdateBaseScore do update user base score.
|
||||
func (d *Dao) TxUpdateBaseScore(c context.Context, tx *sql.Tx, ui *model.UserInfo) (err error) {
|
||||
if _, err = tx.Exec(fmt.Sprintf(_updateBaseScoreSQL, hitInfo(ui.Mid)), ui.BaseScore, ui.Score, ui.Mid); err != nil {
|
||||
log.Error("db.TxUpdateBaseScore(%d, %d, %d) error(%v)", ui.BaseScore, ui.Score, ui.Mid, err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//TxClearReliveTimes do clear user relivetimes.
|
||||
func (d *Dao) TxClearReliveTimes(c context.Context, tx *sql.Tx, ui *model.UserInfo) (err error) {
|
||||
if _, err = tx.Exec(fmt.Sprintf(_clearReliveTimesSQL, hitInfo(ui.Mid)), ui.ReliveTimes, ui.Mid); err != nil {
|
||||
log.Error("db.TxClearReliveTimes(%d, %d) error(%v)", ui.ReliveTimes, ui.Mid, err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Configs spy system configs.
|
||||
func (d *Dao) Configs(c context.Context) (res map[string]string, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = d.db.Query(c, _getAllConfigSQL); err != nil {
|
||||
log.Error("d.getAllConfigSQL.Query error(%v)", err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
res = make(map[string]string)
|
||||
for rows.Next() {
|
||||
var r model.Config
|
||||
if err = rows.Scan(&r.ID, &r.Property, &r.Name, &r.Val, &r.Ctime); err != nil {
|
||||
log.Error("row.Scan() error(%v)", err)
|
||||
res = nil
|
||||
return
|
||||
}
|
||||
res[r.Property] = r.Val
|
||||
}
|
||||
err = rows.Err()
|
||||
return
|
||||
}
|
||||
|
||||
// HistoryList query .
|
||||
func (d *Dao) HistoryList(c context.Context, mid int64, size int) (res []*model.UserEventHistory, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = d.db.Query(c, fmt.Sprintf(_getHistoryListSQL, hitHistory(mid)), mid, size); err != nil {
|
||||
log.Error("d.HistoryList.Query(%d, %d) error(%v)", mid, size, err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
r := &model.UserEventHistory{}
|
||||
if err = rows.Scan(&r.Remark, &r.Reason); err != nil {
|
||||
log.Error("row.Scan() error(%v)", err)
|
||||
res = nil
|
||||
return
|
||||
}
|
||||
res = append(res, r)
|
||||
}
|
||||
err = rows.Err()
|
||||
return
|
||||
}
|
||||
|
||||
// TxUpdateEventScoreReLive update event score and times
|
||||
func (d *Dao) TxUpdateEventScoreReLive(c context.Context, tx *sql.Tx, mid int64, escore, score int8) (err error) {
|
||||
if _, err = tx.Exec(fmt.Sprintf(_updateEventScoreReLiveSQL, hitInfo(mid)), escore, score, mid); err != nil {
|
||||
log.Error("db.TxUpdateEventScoreReLive(%s, %d, %d, %d) error(%v)", _updateEventScoreReLiveSQL, escore, score, mid, err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//StatListByMid stat list by mid.
|
||||
func (d *Dao) StatListByMid(c context.Context, mid int64) (list []*model.Statistics, err error) {
|
||||
var (
|
||||
rows *sql.Rows
|
||||
)
|
||||
list = make([]*model.Statistics, 0)
|
||||
if rows, err = d.db.Query(c, _statListByMidSQL, mid); err != nil {
|
||||
log.Error("d.db.Query(%s) error(%v)", _statListByMidSQL, err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var r = &model.Statistics{}
|
||||
if err = rows.Scan(&r.EventID, &r.Quantity); err != nil {
|
||||
log.Error("rows.Scan() error(%v)", err)
|
||||
return
|
||||
}
|
||||
list = append(list, &model.Statistics{
|
||||
EventID: r.EventID,
|
||||
Quantity: r.Quantity,
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//StatListByIDAndMid stat list by id.
|
||||
func (d *Dao) StatListByIDAndMid(c context.Context, mid, id int64) (list []*model.Statistics, err error) {
|
||||
var (
|
||||
rows *sql.Rows
|
||||
)
|
||||
list = make([]*model.Statistics, 0)
|
||||
if rows, err = d.db.Query(c, _statListByIDAndMidSQL, mid, id); err != nil {
|
||||
log.Error("d.db.Query(%s) error(%v)", _statListByIDAndMidSQL, err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var r = &model.Statistics{}
|
||||
if err = rows.Scan(&r.EventID, &r.Quantity); err != nil {
|
||||
log.Error("rows.Scan() error(%v)", err)
|
||||
return
|
||||
}
|
||||
list = append(list, &model.Statistics{
|
||||
EventID: r.EventID,
|
||||
Quantity: r.Quantity,
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//StatListByID stat list by id.
|
||||
func (d *Dao) StatListByID(c context.Context, id int64) (list []*model.Statistics, err error) {
|
||||
var (
|
||||
rows *sql.Rows
|
||||
)
|
||||
list = make([]*model.Statistics, 0)
|
||||
if rows, err = d.db.Query(c, _statListByIDSQL, id); err != nil {
|
||||
log.Error("d.db.Query(%s) error(%v)", _statListByIDSQL, err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var r = &model.Statistics{}
|
||||
if err = rows.Scan(&r.EventID, &r.Quantity); err != nil {
|
||||
log.Error("rows.Scan() error(%v)", err)
|
||||
return
|
||||
}
|
||||
list = append(list, &model.Statistics{
|
||||
EventID: r.EventID,
|
||||
Quantity: r.Quantity,
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//AllEvent all event.
|
||||
func (d *Dao) AllEvent(c context.Context) (list []*model.Event, err error) {
|
||||
var (
|
||||
rows *sql.Rows
|
||||
)
|
||||
list = make([]*model.Event, 0)
|
||||
if rows, err = d.db.Query(c, _allEventSQL); err != nil {
|
||||
log.Error("d.db.Query(%s) error(%v)", _allEventSQL, err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var event = &model.Event{}
|
||||
if err = rows.Scan(&event.ID, &event.Name, &event.NickName, &event.ServiceID, &event.Status, &event.CTime, &event.MTime); err != nil {
|
||||
log.Error("rows.Scan() error(%v)", err)
|
||||
return
|
||||
}
|
||||
list = append(list, &model.Event{
|
||||
ID: event.ID,
|
||||
Name: event.Name,
|
||||
NickName: event.NickName,
|
||||
ServiceID: event.ServiceID,
|
||||
Status: event.Status,
|
||||
CTime: event.CTime,
|
||||
MTime: event.MTime,
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// TelLevel tel level.
|
||||
func (d *Dao) TelLevel(c context.Context, mid int64) (res *model.TelRiskLevel, err error) {
|
||||
var (
|
||||
row *sql.Row
|
||||
)
|
||||
res = &model.TelRiskLevel{}
|
||||
row = d.db.QueryRow(c, _telLevelSQL, mid)
|
||||
if err = row.Scan(&res.ID, &res.Mid, &res.Level, &res.Origin, &res.Ctime, &res.Mtime); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
err = nil
|
||||
res = nil
|
||||
return
|
||||
}
|
||||
log.Error("row.Scan() error(%v)", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// AddTelLevelInfo add tel level info.
|
||||
func (d *Dao) AddTelLevelInfo(c context.Context, t *model.TelRiskLevel) (id int64, err error) {
|
||||
var (
|
||||
res xsql.Result
|
||||
)
|
||||
if res, err = d.db.Exec(c, _addTelLevelSQL, t.Mid, t.Level, t.Origin, time.Now()); err != nil {
|
||||
log.Error("d.db.Exec(%s, %v) error(%v)", _addTelLevelSQL, t, err)
|
||||
return
|
||||
}
|
||||
if id, err = res.LastInsertId(); err != nil {
|
||||
log.Error("res.LastInsertId() error(%v)", err)
|
||||
}
|
||||
return
|
||||
}
|
498
app/service/main/spy/dao/mysql_test.go
Normal file
498
app/service/main/spy/dao/mysql_test.go
Normal file
@ -0,0 +1,498 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"go-common/app/service/main/spy/model"
|
||||
xtime "go-common/library/time"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestDaoService(t *testing.T) {
|
||||
convey.Convey("Service", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
serviceName = "account-service"
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
service, err := d.Service(c, serviceName)
|
||||
ctx.Convey("Then err should be nil.service should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(service, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoEvent(t *testing.T) {
|
||||
convey.Convey("Event", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
eventName = "init_user_info"
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.Event(c, eventName)
|
||||
ctx.Convey("Then err should be nil.event should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoAddService(t *testing.T) {
|
||||
convey.Convey("AddService", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
service = &model.Service{
|
||||
Name: fmt.Sprintf("ut_%d", time.Now().Unix()),
|
||||
NickName: "test",
|
||||
Status: 0,
|
||||
CTime: xtime.Time(time.Now().Unix()),
|
||||
MTime: xtime.Time(time.Now().Unix()),
|
||||
}
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
id, err := d.AddService(c, service)
|
||||
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 TestDaoAddEvent(t *testing.T) {
|
||||
convey.Convey("AddEvent", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
event = &model.Event{
|
||||
Name: fmt.Sprintf("ut_%d", time.Now().Unix()),
|
||||
NickName: "test",
|
||||
Status: 1,
|
||||
CTime: xtime.Time(time.Now().Unix()),
|
||||
MTime: xtime.Time(time.Now().Unix()),
|
||||
}
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
id, err := d.AddEvent(c, event)
|
||||
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 TestDaoFactor(t *testing.T) {
|
||||
convey.Convey("Factor", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
serviceID = int64(1)
|
||||
eventID = int64(1)
|
||||
riskLevel = int8(1)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
factor, err := d.Factor(c, serviceID, eventID, riskLevel)
|
||||
ctx.Convey("Then err should be nil.factor should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(factor, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoFactorGroup(t *testing.T) {
|
||||
convey.Convey("FactorGroup", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
groupName = "基础资料分值"
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.FactorGroup(c, groupName)
|
||||
ctx.Convey("Then err should be nil.factorGroup should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaohitInfo(t *testing.T) {
|
||||
convey.Convey("hitInfo", t, func(ctx convey.C) {
|
||||
var (
|
||||
id = int64(0)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
p1 := hitInfo(id)
|
||||
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(p1, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaohitHistory(t *testing.T) {
|
||||
convey.Convey("hitHistory", t, func(ctx convey.C) {
|
||||
var (
|
||||
id = int64(0)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
p1 := hitHistory(id)
|
||||
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(p1, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoBeginTran(t *testing.T) {
|
||||
convey.Convey("BeginTran", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
p1, err := d.BeginTran(c)
|
||||
ctx.Convey("Then err should be nil.p1 should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(p1, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoUserInfo(t *testing.T) {
|
||||
convey.Convey("UserInfo", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(1)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
res, err := d.UserInfo(c, mid)
|
||||
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(res, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoTxUpdateInfo(t *testing.T) {
|
||||
convey.Convey("TxUpdateInfo", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
info = &model.UserInfo{
|
||||
Mid: 1,
|
||||
}
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
tx, err := d.BeginTran(c)
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
err = d.TxUpdateInfo(c, tx, info)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoTxAddInfo(t *testing.T) {
|
||||
convey.Convey("TxAddInfo", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
info = &model.UserInfo{
|
||||
Mid: time.Now().Unix(),
|
||||
}
|
||||
id int64
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
tx, err := d.BeginTran(c)
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
id, err = d.TxAddInfo(c, tx, info)
|
||||
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 TestDaoTxAddEventHistory(t *testing.T) {
|
||||
convey.Convey("TxAddEventHistory", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
ueh = &model.UserEventHistory{
|
||||
Mid: 1,
|
||||
Remark: "un_test",
|
||||
}
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
tx, err := d.BeginTran(c)
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
err = d.TxAddEventHistory(c, tx, ueh)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoTxAddPunishment(t *testing.T) {
|
||||
convey.Convey("TxAddPunishment", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(1)
|
||||
no = int8(0)
|
||||
reason = "unit test"
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
tx, err := d.BeginTran(c)
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
err = d.TxAddPunishment(c, tx, mid, no, reason)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoTxAddPunishmentQueue(t *testing.T) {
|
||||
convey.Convey("TxAddPunishmentQueue", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(1)
|
||||
blockNo = int64(1)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
tx, err := d.BeginTran(c)
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
err = d.TxAddPunishmentQueue(c, tx, mid, blockNo)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoAddPunishmentQueue(t *testing.T) {
|
||||
convey.Convey("AddPunishmentQueue", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(1)
|
||||
blockNo = int64(0)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
err := d.AddPunishmentQueue(c, mid, blockNo)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoTxUpdateEventScore(t *testing.T) {
|
||||
convey.Convey("TxUpdateEventScore", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(0)
|
||||
escore = int8(0)
|
||||
score = int8(0)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
tx, err := d.BeginTran(c)
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
err = d.TxUpdateEventScore(c, tx, mid, escore, score)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoTxUpdateBaseScore(t *testing.T) {
|
||||
convey.Convey("TxUpdateBaseScore", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
ui = &model.UserInfo{Mid: 1}
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
tx, err := d.BeginTran(c)
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
err = d.TxUpdateBaseScore(c, tx, ui)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoTxClearReliveTimes(t *testing.T) {
|
||||
convey.Convey("TxClearReliveTimes", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
ui = &model.UserInfo{Mid: 1}
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
tx, err := d.BeginTran(c)
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
err = d.TxClearReliveTimes(c, tx, ui)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoConfigs(t *testing.T) {
|
||||
convey.Convey("Configs", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
res, err := d.Configs(c)
|
||||
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(res, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoHistoryList(t *testing.T) {
|
||||
convey.Convey("HistoryList", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(1)
|
||||
size = int(10)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
res, err := d.HistoryList(c, mid, size)
|
||||
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(res, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoTxUpdateEventScoreReLive(t *testing.T) {
|
||||
convey.Convey("TxUpdateEventScoreReLive", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(1)
|
||||
escore = int8(0)
|
||||
score = int8(0)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
tx, err := d.BeginTran(c)
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
err = d.TxUpdateEventScoreReLive(c, tx, mid, escore, score)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoStatListByMid(t *testing.T) {
|
||||
convey.Convey("StatListByMid", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(1)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
list, err := d.StatListByMid(c, mid)
|
||||
ctx.Convey("Then err should be nil.list should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(list, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoStatListByIDAndMid(t *testing.T) {
|
||||
convey.Convey("StatListByIDAndMid", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(1)
|
||||
id = int64(0)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
list, err := d.StatListByIDAndMid(c, mid, id)
|
||||
ctx.Convey("Then err should be nil.list should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(list, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoStatListByID(t *testing.T) {
|
||||
convey.Convey("StatListByID", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
id = int64(0)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
list, err := d.StatListByID(c, id)
|
||||
ctx.Convey("Then err should be nil.list should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(list, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoAllEvent(t *testing.T) {
|
||||
convey.Convey("AllEvent", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
list, err := d.AllEvent(c)
|
||||
ctx.Convey("Then err should be nil.list should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(list, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoTelLevel(t *testing.T) {
|
||||
convey.Convey("TelLevel", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(1)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.TelLevel(c, mid)
|
||||
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoAddTelLevelInfo(t *testing.T) {
|
||||
convey.Convey("AddTelLevelInfo", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
no = &model.TelRiskLevel{
|
||||
Mid: time.Now().Unix(),
|
||||
Level: 1,
|
||||
Origin: 1,
|
||||
Ctime: time.Now(),
|
||||
Mtime: time.Now(),
|
||||
}
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
id, err := d.AddTelLevelInfo(c, no)
|
||||
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)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
85
app/service/main/spy/dao/qcloud.go
Normal file
85
app/service/main/spy/dao/qcloud.go
Normal file
@ -0,0 +1,85 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/hmac"
|
||||
"crypto/sha1"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"go-common/app/service/main/spy/model"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
func (d *Dao) hmacsha1(key, text string) (h string) {
|
||||
mac := hmac.New(sha1.New, []byte(key))
|
||||
mac.Write([]byte(text))
|
||||
h = base64.StdEncoding.EncodeToString(mac.Sum(nil))
|
||||
return
|
||||
}
|
||||
|
||||
func (d *Dao) makeURL(method string, action string, region string, secretID string, secretKey string,
|
||||
args url.Values, charset string, URL string) (req string) {
|
||||
args.Set("Nonce", fmt.Sprintf("%d", d.r.Uint32()))
|
||||
args.Set("Action", action)
|
||||
args.Set("Region", region)
|
||||
args.Set("SecretId", secretID)
|
||||
args.Set("Timestamp", fmt.Sprintf("%d", time.Now().Unix()))
|
||||
args.Set("Signature", d.hmacsha1(secretKey, fmt.Sprintf("%s%s?%s", method, URL, d.makeQueryString(args))))
|
||||
req = args.Encode()
|
||||
return
|
||||
}
|
||||
|
||||
func (d *Dao) makeQueryString(v url.Values) (str string) {
|
||||
if v == nil {
|
||||
return ""
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
keys := make([]string, 0, len(v))
|
||||
for k := range v {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, k := range keys {
|
||||
vs := v[k]
|
||||
prefix := k + "="
|
||||
for _, v := range vs {
|
||||
if buf.Len() > 0 {
|
||||
buf.WriteString("&")
|
||||
}
|
||||
buf.WriteString(prefix)
|
||||
buf.WriteString(v)
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// RegisterProtection register protection.
|
||||
func (d *Dao) RegisterProtection(c context.Context, args url.Values, ip string) (level int8, err error) {
|
||||
query := d.makeURL("GET", d.c.Qcloud.Path, d.c.Qcloud.Region, d.c.Qcloud.SecretID,
|
||||
d.c.Qcloud.SecretKey, args, d.c.Qcloud.Charset, d.c.Qcloud.BaseURL)
|
||||
req, err := http.NewRequest("GET", "https://"+d.c.Qcloud.BaseURL+"?"+query, nil)
|
||||
if err != nil {
|
||||
log.Error("d.RegisterProtection uri(%s) error(%v)", query, err)
|
||||
return
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
res := &model.QcloudRegProResp{}
|
||||
if err = d.httpClient.Do(c, req, res); err != nil {
|
||||
log.Error("d.client.Do error(%v) | uri(%s)) res(%v)", err, query, res)
|
||||
return
|
||||
}
|
||||
if res.Code != 0 {
|
||||
err = fmt.Errorf("GET RegisterProtection req faild query(%s) resp(%v)", d.c.Qcloud.BaseURL+"?"+query, res)
|
||||
log.Error(" RegisterProtection fail res(%v)", res)
|
||||
return
|
||||
}
|
||||
level = res.Level
|
||||
log.Info("GET RegisterProtection suc query(%s) resp(%v)", query, res)
|
||||
return
|
||||
}
|
89
app/service/main/spy/dao/qcloud_test.go
Normal file
89
app/service/main/spy/dao/qcloud_test.go
Normal file
@ -0,0 +1,89 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"go-common/app/service/main/spy/model"
|
||||
"net/url"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestDaohmacsha1(t *testing.T) {
|
||||
convey.Convey("hmacsha1", t, func(ctx convey.C) {
|
||||
var (
|
||||
key = ""
|
||||
text = ""
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
h := d.hmacsha1(key, text)
|
||||
ctx.Convey("Then h should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(h, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaomakeURL(t *testing.T) {
|
||||
convey.Convey("makeURL", t, func(ctx convey.C) {
|
||||
var (
|
||||
method = "1"
|
||||
action = "1"
|
||||
region = "1"
|
||||
secretID = "1"
|
||||
secretKey = "1"
|
||||
charset = "1"
|
||||
URL = "1"
|
||||
)
|
||||
args := url.Values{}
|
||||
args.Set("accountType", fmt.Sprintf("%d", model.AccountType))
|
||||
args.Set("uid", fmt.Sprintf("%d", 1))
|
||||
args.Set("phoneNumber", "13262609601")
|
||||
args.Set("registerTime", fmt.Sprintf("%d", time.Now().Unix()))
|
||||
args.Set("registerIp", "127.0.0.1")
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
req := d.makeURL(method, action, region, secretID, secretKey, args, charset, URL)
|
||||
ctx.Convey("Then req should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(req, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaomakeQueryString(t *testing.T) {
|
||||
convey.Convey("makeQueryString", t, func(ctx convey.C) {
|
||||
var (
|
||||
v url.Values
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
str := d.makeQueryString(v)
|
||||
ctx.Convey("Then str should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(str, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoRegisterProtection(t *testing.T) {
|
||||
convey.Convey("RegisterProtection", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
ip = "127.0.0.1"
|
||||
)
|
||||
args := url.Values{}
|
||||
args.Set("accountType", fmt.Sprintf("%d", model.AccountType))
|
||||
args.Set("uid", fmt.Sprintf("%d", 1))
|
||||
args.Set("phoneNumber", "13262609601")
|
||||
args.Set("registerTime", fmt.Sprintf("%d", time.Now().Unix()))
|
||||
args.Set("registerIp", ip)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
level, err := d.RegisterProtection(c, args, ip)
|
||||
ctx.Convey("Then err should be nil.level should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(level, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
96
app/service/main/spy/dao/redis.go
Normal file
96
app/service/main/spy/dao/redis.go
Normal file
@ -0,0 +1,96 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"go-common/library/cache/redis"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
const (
|
||||
_keyWaitBlock = "wb_" // b_batch_no wait block
|
||||
_preLock = "lk_"
|
||||
)
|
||||
|
||||
// keyWaitBlock return block cache key.
|
||||
func keyWaitBlock(batchNo int64) string {
|
||||
return _keyWaitBlock + fmt.Sprintf("%d", batchNo)
|
||||
}
|
||||
|
||||
func lockKey(key int64) string {
|
||||
return fmt.Sprintf("%s%d", _preLock, key)
|
||||
}
|
||||
|
||||
// AddBlockCache add block cache.
|
||||
func (d *Dao) AddBlockCache(c context.Context, mid int64, score int8, blockNo int64) (err error) {
|
||||
var (
|
||||
key = keyWaitBlock(blockNo)
|
||||
)
|
||||
conn := d.redis.Get(c)
|
||||
defer conn.Close()
|
||||
if err = conn.Send("ZADD", key, score, mid); err != nil {
|
||||
log.Error("conn.Send(ZADD %s,%d,%d) error(%v)", key, score, mid, err)
|
||||
return
|
||||
}
|
||||
if err = conn.Send("EXPIRE", key, d.expire); err != nil {
|
||||
log.Error("conn.Send(EXPIRE) error(%v)", err)
|
||||
return
|
||||
}
|
||||
if err = conn.Flush(); err != nil {
|
||||
log.Error("conn.Flush() error(%v)", err)
|
||||
return
|
||||
}
|
||||
for i := 0; i < 2; i++ {
|
||||
if _, err = conn.Receive(); err != nil {
|
||||
log.Error("conn.Receive() error(%v)", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// BlockMidCache get wait block mids.
|
||||
func (d *Dao) BlockMidCache(c context.Context, batchNo int64, num int64) (res []int64, err error) {
|
||||
var (
|
||||
conn = d.redis.Get(c)
|
||||
key = keyWaitBlock(batchNo)
|
||||
)
|
||||
defer conn.Close()
|
||||
if res, err = redis.Int64s(conn.Do("ZREVRANGEBYSCORE", key, "+inf", "-inf", "LIMIT", 0, num)); err != nil {
|
||||
log.Error("redis(ZREVRANGEBYSCORE %s,%d) error(%v)", key, num, err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SetNXLockCache redis lock.
|
||||
func (d *Dao) SetNXLockCache(c context.Context, k int64) (res bool, err error) {
|
||||
var (
|
||||
key = lockKey(k)
|
||||
conn = d.redis.Get(c)
|
||||
)
|
||||
defer conn.Close()
|
||||
if res, err = redis.Bool(conn.Do("SETNX", key, "1")); err != nil {
|
||||
if err == redis.ErrNil {
|
||||
err = nil
|
||||
} else {
|
||||
log.Error("conn.Do(SETNX(%d)) error(%v)", key, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
if res {
|
||||
if _, err = redis.Bool(conn.Do("EXPIRE", key, d.verifyExpire)); err != nil {
|
||||
log.Error("conn.Do(EXPIRE, %s, %d) error(%v)", key, d.verifyExpire, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// PingRedis check redis connection
|
||||
func (d *Dao) PingRedis(c context.Context) (err error) {
|
||||
conn := d.redis.Get(c)
|
||||
_, err = conn.Do("SET", "PING", "PONG")
|
||||
conn.Close()
|
||||
return
|
||||
}
|
99
app/service/main/spy/dao/redis_test.go
Normal file
99
app/service/main/spy/dao/redis_test.go
Normal file
@ -0,0 +1,99 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestDaokeyWaitBlock(t *testing.T) {
|
||||
convey.Convey("keyWaitBlock", t, func(ctx convey.C) {
|
||||
var (
|
||||
batchNo = int64(0)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
p1 := keyWaitBlock(batchNo)
|
||||
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(p1, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaolockKey(t *testing.T) {
|
||||
convey.Convey("lockKey", t, func(ctx convey.C) {
|
||||
var (
|
||||
key = int64(0)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
p1 := lockKey(key)
|
||||
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(p1, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoAddBlockCache(t *testing.T) {
|
||||
convey.Convey("AddBlockCache", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(0)
|
||||
score = int8(0)
|
||||
blockNo = int64(0)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
err := d.AddBlockCache(c, mid, score, blockNo)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoBlockMidCache(t *testing.T) {
|
||||
convey.Convey("BlockMidCache", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
batchNo = int64(0)
|
||||
num = int64(0)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.BlockMidCache(c, batchNo, num)
|
||||
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoSetNXLockCache(t *testing.T) {
|
||||
convey.Convey("SetNXLockCache", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
k = int64(0)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
res, err := d.SetNXLockCache(c, k)
|
||||
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(res, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoPingRedis(t *testing.T) {
|
||||
convey.Convey("PingRedis", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
err := d.PingRedis(c)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
50
app/service/main/spy/model/BUILD
Normal file
50
app/service/main/spy/model/BUILD
Normal file
@ -0,0 +1,50 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"account.go",
|
||||
"config.go",
|
||||
"databus.go",
|
||||
"event.go",
|
||||
"eventmsg.go",
|
||||
"factor.go",
|
||||
"factor_group.go",
|
||||
"params.go",
|
||||
"punishment.go",
|
||||
"qcloud.go",
|
||||
"risk.go",
|
||||
"rpc.go",
|
||||
"service.go",
|
||||
"spy.go",
|
||||
"stat.go",
|
||||
"user_event_history.go",
|
||||
"user_info.go",
|
||||
],
|
||||
importpath = "go-common/app/service/main/spy/model",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/service/main/account/model: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"],
|
||||
)
|
35
app/service/main/spy/model/account.go
Normal file
35
app/service/main/spy/model/account.go
Normal file
@ -0,0 +1,35 @@
|
||||
package model
|
||||
|
||||
import accmdl "go-common/app/service/main/account/model"
|
||||
|
||||
// TelInfo def.
|
||||
type TelInfo struct {
|
||||
Mid int64 `json:"mid"`
|
||||
Tel string `json:"tel"`
|
||||
JoinIP string `json:"join_ip"`
|
||||
JoinTime int64 `json:"join_time"`
|
||||
}
|
||||
|
||||
// AuditInfo is.
|
||||
type AuditInfo struct {
|
||||
Mid int64 `json:"mid"`
|
||||
BindTel bool `json:"bind_tel"`
|
||||
BindMail bool `json:"bind_mail"`
|
||||
Rank int64 `json:"rank"`
|
||||
SpaceSta int64 `json:"spacesta"`
|
||||
}
|
||||
|
||||
// ProfileInfo profile info.
|
||||
type ProfileInfo = accmdl.Profile
|
||||
|
||||
// TelRiskInfo tel risk info.
|
||||
type TelRiskInfo struct {
|
||||
TelRiskLevel int8
|
||||
RestoreHistory *UserEventHistory
|
||||
UnicomGiftState int
|
||||
}
|
||||
|
||||
// UnicomGiftState unicom gift state.
|
||||
type UnicomGiftState struct {
|
||||
State int `json:"state"`
|
||||
}
|
39
app/service/main/spy/model/config.go
Normal file
39
app/service/main/spy/model/config.go
Normal file
@ -0,0 +1,39 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
// config properties.
|
||||
const (
|
||||
LimitBlockCount = "limitBlockCount"
|
||||
LessBlockScore = "lessBlockScore"
|
||||
AutoBlock = "autoBlock"
|
||||
AutoBlockOpen = 1
|
||||
)
|
||||
|
||||
const (
|
||||
//BlockReasonSize block reason size
|
||||
BlockReasonSize = 4
|
||||
//BlockLockKey cycle block
|
||||
BlockLockKey = "cycleblock"
|
||||
//VipEnableStatus enable status
|
||||
VipEnableStatus int32 = 1
|
||||
//VipNonType non vip
|
||||
VipNonType int32 = 0
|
||||
// ReliveCheckTimes relive check times
|
||||
ReliveCheckTimes = 1
|
||||
// DoubleCheckRemake double check remake
|
||||
DoubleCheckRemake = "导入二次验证,恢复行为得分"
|
||||
// RetryTimes retry times
|
||||
RetryTimes = 3
|
||||
// SpyInitScore spy init score
|
||||
SpyInitScore = 100
|
||||
)
|
||||
|
||||
// Config def.
|
||||
type Config struct {
|
||||
ID int64
|
||||
Property string
|
||||
Name string
|
||||
Val string
|
||||
Ctime time.Time
|
||||
}
|
20
app/service/main/spy/model/databus.go
Normal file
20
app/service/main/spy/model/databus.go
Normal file
@ -0,0 +1,20 @@
|
||||
package model
|
||||
|
||||
// ScoreChange DataBus spy score change.
|
||||
type ScoreChange struct {
|
||||
Mid int64 `json:"mid"`
|
||||
Score int8 `json:"score"`
|
||||
BaseScore int8 `json:"base_score"`
|
||||
EventScore int8 `json:"event_score"`
|
||||
TS int64 `json:"ts"`
|
||||
Reason string `json:"reason"`
|
||||
RiskLevel int8 `json:"risk_level"`
|
||||
}
|
||||
|
||||
const (
|
||||
//CoinReason coin reason ref update score
|
||||
CoinReason = "coin-service"
|
||||
|
||||
//CoinHighRisk coin high risk
|
||||
CoinHighRisk = 7
|
||||
)
|
16
app/service/main/spy/model/event.go
Normal file
16
app/service/main/spy/model/event.go
Normal file
@ -0,0 +1,16 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"go-common/library/time"
|
||||
)
|
||||
|
||||
// Event def.
|
||||
type Event struct {
|
||||
ID int64
|
||||
Name string // 事件标示
|
||||
NickName string // 事件可读昵称
|
||||
ServiceID int64
|
||||
Status int8 // 0:删除 1:未删除
|
||||
CTime time.Time
|
||||
MTime time.Time
|
||||
}
|
20
app/service/main/spy/model/eventmsg.go
Normal file
20
app/service/main/spy/model/eventmsg.go
Normal file
@ -0,0 +1,20 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"go-common/library/time"
|
||||
)
|
||||
|
||||
// EventMessage event from bigdata def.
|
||||
type EventMessage struct {
|
||||
Time time.Time `json:"time"`
|
||||
IP string `json:"ip"`
|
||||
Service string `json:"service"`
|
||||
Event string `json:"event"`
|
||||
ActiveMid int64 `json:"active_mid"`
|
||||
TargetMid int64 `json:"target_mid"`
|
||||
TargetID int64 `json:"target_id"`
|
||||
Args interface{} `json:"args"`
|
||||
Result string `json:"result"`
|
||||
Effect string `json:"effect"`
|
||||
RiskLevel int8 `json:"risk_level"`
|
||||
}
|
18
app/service/main/spy/model/factor.go
Normal file
18
app/service/main/spy/model/factor.go
Normal file
@ -0,0 +1,18 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"go-common/library/time"
|
||||
)
|
||||
|
||||
// Factor def.
|
||||
type Factor struct {
|
||||
ID int64
|
||||
NickName string //风险因子名字
|
||||
ServiceID int64
|
||||
EventID int64
|
||||
GroupID int64
|
||||
RiskLevel int8 //风险等级:1-9
|
||||
FactorVal float64 //风险得分
|
||||
CTime time.Time
|
||||
MTime time.Time
|
||||
}
|
12
app/service/main/spy/model/factor_group.go
Normal file
12
app/service/main/spy/model/factor_group.go
Normal file
@ -0,0 +1,12 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"go-common/library/time"
|
||||
)
|
||||
|
||||
// FactorGroup is.
|
||||
type FactorGroup struct {
|
||||
ID int64
|
||||
Name string //风险因子组名
|
||||
CTime time.Time
|
||||
}
|
7
app/service/main/spy/model/params.go
Normal file
7
app/service/main/spy/model/params.go
Normal file
@ -0,0 +1,7 @@
|
||||
package model
|
||||
|
||||
// NotifyInfo notify.
|
||||
type NotifyInfo struct {
|
||||
Mid int64 `json:"mid"`
|
||||
Action string `json:"action"`
|
||||
}
|
20
app/service/main/spy/model/punishment.go
Normal file
20
app/service/main/spy/model/punishment.go
Normal file
@ -0,0 +1,20 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"go-common/library/time"
|
||||
)
|
||||
|
||||
const (
|
||||
//PunishmentTypeBlock 封禁
|
||||
PunishmentTypeBlock = 1
|
||||
)
|
||||
|
||||
// Punishment def.
|
||||
type Punishment struct {
|
||||
ID int64
|
||||
Mid int64
|
||||
Type int8 //封禁原因
|
||||
Reason string //惩罚原因
|
||||
CTime time.Time
|
||||
MTime time.Time
|
||||
}
|
23
app/service/main/spy/model/qcloud.go
Normal file
23
app/service/main/spy/model/qcloud.go
Normal file
@ -0,0 +1,23 @@
|
||||
package model
|
||||
|
||||
// Reg Pro args.
|
||||
const (
|
||||
AccountType = 4
|
||||
)
|
||||
|
||||
// Tel level .
|
||||
const (
|
||||
Nomal int8 = iota
|
||||
LevelOne
|
||||
LevelTwo
|
||||
LevelThree
|
||||
LevelFour
|
||||
)
|
||||
|
||||
// QcloudRegProResp def.
|
||||
type QcloudRegProResp struct {
|
||||
Code int `json:"code"`
|
||||
CodeDesc string `json:"codeDesc"`
|
||||
Message string `json:"message"`
|
||||
Level int8 `json:"level"`
|
||||
}
|
19
app/service/main/spy/model/risk.go
Normal file
19
app/service/main/spy/model/risk.go
Normal file
@ -0,0 +1,19 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
// Tel Expire
|
||||
const (
|
||||
TelExpireMonth = 3
|
||||
QcloudType = 1
|
||||
)
|
||||
|
||||
// TelRiskLevel def.
|
||||
type TelRiskLevel struct {
|
||||
ID int64 `json:"id"`
|
||||
Mid int64 `json:"mid"`
|
||||
Level int8 `json:"level"`
|
||||
Origin int8 `json:"origin"`
|
||||
Ctime time.Time `json:"ctime"`
|
||||
Mtime time.Time `json:"mtime"`
|
||||
}
|
53
app/service/main/spy/model/rpc.go
Normal file
53
app/service/main/spy/model/rpc.go
Normal file
@ -0,0 +1,53 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"go-common/library/time"
|
||||
)
|
||||
|
||||
// ArgReBuild rebuild args
|
||||
type ArgReBuild struct {
|
||||
Mid int64
|
||||
Reason string
|
||||
}
|
||||
|
||||
// ArgReset is.
|
||||
type ArgReset struct {
|
||||
Mid int64
|
||||
ReLiveTime bool
|
||||
EventScore bool
|
||||
BaseScore bool
|
||||
Operator string
|
||||
}
|
||||
|
||||
// ArgUserScore rpc arg for getting user score.
|
||||
type ArgUserScore struct {
|
||||
Mid int64
|
||||
IP string
|
||||
}
|
||||
|
||||
// ArgHandleEvent rpc arg for handling spy event.
|
||||
type ArgHandleEvent struct {
|
||||
Time time.Time
|
||||
IP string `json:"ip"`
|
||||
Service string `json:"service"`
|
||||
Event string `json:"event"`
|
||||
ActiveMid int64 `json:"active_mid"`
|
||||
TargetMid int64 `json:"target_mid"`
|
||||
TargetID int64 `json:"target_id"`
|
||||
Args interface{} `json:"args"`
|
||||
Result string `json:"result"`
|
||||
Effect string `json:"effect"`
|
||||
RiskLevel int8 `json:"risk_level"`
|
||||
}
|
||||
|
||||
// ArgUser rpc arg for getting user info.
|
||||
type ArgUser struct {
|
||||
Mid int64
|
||||
IP string
|
||||
}
|
||||
|
||||
// ArgStat rpc arg for getting user stat.
|
||||
type ArgStat struct {
|
||||
ID int64
|
||||
Mid int64
|
||||
}
|
15
app/service/main/spy/model/service.go
Normal file
15
app/service/main/spy/model/service.go
Normal file
@ -0,0 +1,15 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"go-common/library/time"
|
||||
)
|
||||
|
||||
// Service def.
|
||||
type Service struct {
|
||||
ID int64
|
||||
Name string //服务标识
|
||||
NickName string //服务可读昵称
|
||||
Status int8
|
||||
CTime time.Time
|
||||
MTime time.Time
|
||||
}
|
7
app/service/main/spy/model/spy.go
Normal file
7
app/service/main/spy/model/spy.go
Normal file
@ -0,0 +1,7 @@
|
||||
package model
|
||||
|
||||
// UserScore rpc return for getting user score.
|
||||
type UserScore struct {
|
||||
Mid int64 `json:"mid"`
|
||||
Score int8 `json:"score"`
|
||||
}
|
8
app/service/main/spy/model/stat.go
Normal file
8
app/service/main/spy/model/stat.go
Normal file
@ -0,0 +1,8 @@
|
||||
package model
|
||||
|
||||
// Statistics def.
|
||||
type Statistics struct {
|
||||
Quantity int64 `json:"quantity"`
|
||||
EventID int64 `json:"event_id"`
|
||||
EventName string `json:"event_name"`
|
||||
}
|
19
app/service/main/spy/model/user_event_history.go
Normal file
19
app/service/main/spy/model/user_event_history.go
Normal file
@ -0,0 +1,19 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"go-common/library/time"
|
||||
)
|
||||
|
||||
// UserEventHistory history of user event def.
|
||||
type UserEventHistory struct {
|
||||
ID int64
|
||||
Mid int64
|
||||
EventID int64
|
||||
Score int8
|
||||
BaseScore int8
|
||||
EventScore int8
|
||||
Remark string
|
||||
Reason string // 事件原因 == eventmsg.Effect
|
||||
FactorVal float64
|
||||
CTime time.Time
|
||||
}
|
25
app/service/main/spy/model/user_info.go
Normal file
25
app/service/main/spy/model/user_info.go
Normal file
@ -0,0 +1,25 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"go-common/library/time"
|
||||
)
|
||||
|
||||
const (
|
||||
// StateNormal UserInfo 正常状态
|
||||
StateNormal = 0
|
||||
// StateBlock UserInfo 封禁状态
|
||||
StateBlock = 1
|
||||
)
|
||||
|
||||
// UserInfo def.
|
||||
type UserInfo struct {
|
||||
ID int64 `json:"id"`
|
||||
Mid int64 `json:"mid"`
|
||||
Score int8 `json:"score"` //真实得分
|
||||
BaseScore int8 `json:"base_score"` //基础信息得分
|
||||
EventScore int8 `json:"event_score"` //事件得分
|
||||
State int8 `json:"state"` //状态 : 正常/封禁
|
||||
ReliveTimes int8 `json:"relive_times"` //画像得分恢复次数
|
||||
CTime time.Time `json:"ctime"`
|
||||
MTime time.Time `json:"mtime"`
|
||||
}
|
42
app/service/main/spy/rpc/client/BUILD
Normal file
42
app/service/main/spy/rpc/client/BUILD
Normal file
@ -0,0 +1,42 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_test",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["spy_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
rundir = ".",
|
||||
tags = ["automanaged"],
|
||||
deps = ["//app/service/main/spy/model:go_default_library"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["spy.go"],
|
||||
importpath = "go-common/app/service/main/spy/rpc/client",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/service/main/spy/model: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"],
|
||||
)
|
96
app/service/main/spy/rpc/client/spy.go
Normal file
96
app/service/main/spy/rpc/client/spy.go
Normal file
@ -0,0 +1,96 @@
|
||||
package spy
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go-common/app/service/main/spy/model"
|
||||
"go-common/library/net/rpc"
|
||||
)
|
||||
|
||||
const (
|
||||
_addEvent = "RPC.HandleEvent"
|
||||
_userScore = "RPC.UserScore"
|
||||
_reBuildPortrait = "RPC.ReBuildPortrait"
|
||||
//_resetManually = "RPC.ResetManually"
|
||||
_updateBaseScore = "RPC.UpdateBaseScore"
|
||||
_refreshBaseScore = "RPC.RefreshBaseScore"
|
||||
_updateEventScore = "RPC.UpdateEventScore"
|
||||
_userInfo = "RPC.UserInfo"
|
||||
_clearReliveTimes = "RPC.ClearReliveTimes"
|
||||
_statByID = "RPC.StatByID"
|
||||
)
|
||||
|
||||
const (
|
||||
_appid = "account.service.spy"
|
||||
)
|
||||
|
||||
var (
|
||||
_noRes = &struct{}{}
|
||||
)
|
||||
|
||||
// Service struct info.
|
||||
type Service struct {
|
||||
client *rpc.Client2
|
||||
}
|
||||
|
||||
// New create instance of service and return.
|
||||
func New(c *rpc.ClientConfig) (s *Service) {
|
||||
s = &Service{}
|
||||
s.client = rpc.NewDiscoveryCli(_appid, c)
|
||||
return
|
||||
}
|
||||
|
||||
// HandleEvent add spy event to user.
|
||||
func (s *Service) HandleEvent(c context.Context, arg *model.ArgHandleEvent) (err error) {
|
||||
err = s.client.Call(c, _addEvent, arg, _noRes)
|
||||
return
|
||||
}
|
||||
|
||||
// UserScore archive get user spy score.
|
||||
func (s *Service) UserScore(c context.Context, arg *model.ArgUserScore) (res *model.UserScore, err error) {
|
||||
res = &model.UserScore{}
|
||||
err = s.client.Call(c, _userScore, arg, res)
|
||||
return
|
||||
}
|
||||
|
||||
// ReBuildPortrait rebuild user risk portrait by task.
|
||||
func (s *Service) ReBuildPortrait(c context.Context, arg *model.ArgReBuild) (err error) {
|
||||
err = s.client.Call(c, _reBuildPortrait, arg, _noRes)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateBaseScore cli.
|
||||
func (s *Service) UpdateBaseScore(c context.Context, arg *model.ArgReset) (err error) {
|
||||
err = s.client.Call(c, _updateBaseScore, arg, _noRes)
|
||||
return
|
||||
}
|
||||
|
||||
// RefreshBaseScore cli.
|
||||
func (s *Service) RefreshBaseScore(c context.Context, arg *model.ArgReset) (err error) {
|
||||
err = s.client.Call(c, _refreshBaseScore, arg, _noRes)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateEventScore cli.
|
||||
func (s *Service) UpdateEventScore(c context.Context, arg *model.ArgReset) (err error) {
|
||||
err = s.client.Call(c, _updateEventScore, arg, _noRes)
|
||||
return
|
||||
}
|
||||
|
||||
// UserInfo cli.
|
||||
func (s *Service) UserInfo(c context.Context, arg *model.ArgUser) (res *model.UserInfo, err error) {
|
||||
err = s.client.Call(c, _userInfo, arg, res)
|
||||
return
|
||||
}
|
||||
|
||||
// ClearReliveTimes cli.
|
||||
func (s *Service) ClearReliveTimes(c context.Context, arg *model.ArgReset) (err error) {
|
||||
err = s.client.Call(c, _clearReliveTimes, arg, _noRes)
|
||||
return
|
||||
}
|
||||
|
||||
// StatByID cli.
|
||||
func (s *Service) StatByID(c context.Context, arg *model.ArgStat) (stat []*model.Statistics, err error) {
|
||||
err = s.client.Call(c, _statByID, arg, &stat)
|
||||
return
|
||||
}
|
47
app/service/main/spy/rpc/client/spy_test.go
Normal file
47
app/service/main/spy/rpc/client/spy_test.go
Normal file
@ -0,0 +1,47 @@
|
||||
package spy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
model "go-common/app/service/main/spy/model"
|
||||
)
|
||||
|
||||
func TestSpy(t *testing.T) {
|
||||
s := New(nil)
|
||||
time.Sleep(2 * time.Second)
|
||||
testUpdateEventScore(t, s)
|
||||
testUpdateBaseScore(t, s)
|
||||
testUserScore(t, s)
|
||||
testHandleEvent(t, s)
|
||||
testReBuildPortrait(t, s)
|
||||
}
|
||||
|
||||
func testUpdateEventScore(t *testing.T, s *Service) {
|
||||
t.Log(s.UpdateEventScore(context.TODO(), &model.ArgReset{Mid: 23333, Operator: "admin test"}))
|
||||
}
|
||||
|
||||
func testUpdateBaseScore(t *testing.T, s *Service) {
|
||||
t.Log(s.UpdateBaseScore(context.TODO(), &model.ArgReset{Mid: 23333, Operator: "admin test"}))
|
||||
}
|
||||
|
||||
func testUserScore(t *testing.T, s *Service) {
|
||||
t.Log(s.UserScore(context.TODO(), &model.ArgUserScore{Mid: 23333, IP: "127.0.0.1"}))
|
||||
}
|
||||
|
||||
func testHandleEvent(t *testing.T, s *Service) {
|
||||
t.Log(s.HandleEvent(context.TODO(), &model.ArgHandleEvent{
|
||||
IP: "127.0.0.1",
|
||||
Service: "spy_service",
|
||||
Event: "bind_mail_only",
|
||||
ActiveMid: 23333,
|
||||
TargetMid: 23333,
|
||||
Effect: "",
|
||||
RiskLevel: 1,
|
||||
}))
|
||||
}
|
||||
|
||||
func testReBuildPortrait(t *testing.T, s *Service) {
|
||||
t.Log(s.ReBuildPortrait(context.TODO(), &model.ArgReBuild{Mid: 23333}))
|
||||
}
|
35
app/service/main/spy/rpc/server/BUILD
Normal file
35
app/service/main/spy/rpc/server/BUILD
Normal file
@ -0,0 +1,35 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["rpc.go"],
|
||||
importpath = "go-common/app/service/main/spy/rpc/server",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/service/main/spy/conf:go_default_library",
|
||||
"//app/service/main/spy/model:go_default_library",
|
||||
"//app/service/main/spy/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"],
|
||||
)
|
107
app/service/main/spy/rpc/server/rpc.go
Normal file
107
app/service/main/spy/rpc/server/rpc.go
Normal file
@ -0,0 +1,107 @@
|
||||
package rpc
|
||||
|
||||
import (
|
||||
cmmdl "go-common/app/service/main/spy/model"
|
||||
"go-common/library/net/rpc"
|
||||
"go-common/library/net/rpc/context"
|
||||
|
||||
"go-common/app/service/main/spy/conf"
|
||||
"go-common/app/service/main/spy/model"
|
||||
"go-common/app/service/main/spy/service"
|
||||
)
|
||||
|
||||
// RPC server def.
|
||||
type RPC struct {
|
||||
s *service.Service
|
||||
}
|
||||
|
||||
// New create instance of rpc server2 and return.
|
||||
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
|
||||
}
|
||||
|
||||
// Ping check rpc server health.
|
||||
func (r *RPC) Ping(c context.Context, arg *struct{}, res *struct{}) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// UserScore rpc req for getting user spy score.
|
||||
func (r *RPC) UserScore(c context.Context, arg *cmmdl.ArgUserScore, res *cmmdl.UserScore) (err error) {
|
||||
var (
|
||||
ui *model.UserInfo
|
||||
)
|
||||
if ui, err = r.s.UserInfo(c, arg.Mid, arg.IP); ui != nil && err == nil {
|
||||
*res = cmmdl.UserScore{Mid: ui.Mid, Score: ui.Score}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// HandleEvent rpc req for handling spy event , maybe from spy-job.
|
||||
func (r *RPC) HandleEvent(c context.Context, arg *cmmdl.ArgHandleEvent, res *struct{}) (err error) {
|
||||
var event = &model.EventMessage{
|
||||
Time: arg.Time,
|
||||
IP: arg.IP,
|
||||
Service: arg.Service,
|
||||
Event: arg.Event,
|
||||
ActiveMid: arg.ActiveMid,
|
||||
TargetMid: arg.TargetMid,
|
||||
TargetID: arg.TargetID,
|
||||
Args: arg.Args,
|
||||
Result: arg.Result,
|
||||
Effect: arg.Effect,
|
||||
RiskLevel: arg.RiskLevel,
|
||||
}
|
||||
return r.s.HandleEvent(c, event)
|
||||
}
|
||||
|
||||
// ReBuildPortrait rpc.
|
||||
func (r *RPC) ReBuildPortrait(c context.Context, arg *cmmdl.ArgReBuild, res *struct{}) (err error) {
|
||||
return r.s.ReBuildPortrait(c, arg.Mid, arg.Reason)
|
||||
}
|
||||
|
||||
// UpdateBaseScore rpc.
|
||||
func (r *RPC) UpdateBaseScore(c context.Context, arg *cmmdl.ArgReset, res *struct{}) (err error) {
|
||||
return r.s.UpdateBaseScore(c, arg)
|
||||
}
|
||||
|
||||
// UpdateEventScore rpc.
|
||||
func (r *RPC) UpdateEventScore(c context.Context, arg *cmmdl.ArgReset, res *struct{}) (err error) {
|
||||
return r.s.UpdateEventScore(c, arg)
|
||||
}
|
||||
|
||||
// UserInfo rpc.
|
||||
func (r *RPC) UserInfo(c context.Context, arg *cmmdl.ArgUser, res *cmmdl.UserInfo) (err error) {
|
||||
var (
|
||||
ui *model.UserInfo
|
||||
)
|
||||
if ui, err = r.s.UserInfo(c, arg.Mid, arg.IP); ui != nil && err == nil {
|
||||
*res = *ui
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ClearReliveTimes rpc.
|
||||
func (r *RPC) ClearReliveTimes(c context.Context, arg *cmmdl.ArgReset, res *struct{}) (err error) {
|
||||
return r.s.ClearReliveTimes(c, arg)
|
||||
}
|
||||
|
||||
// StatByID rpc.
|
||||
func (r *RPC) StatByID(c context.Context, arg *cmmdl.ArgStat, res *[]*cmmdl.Statistics) (err error) {
|
||||
var (
|
||||
stat []*model.Statistics
|
||||
)
|
||||
if stat, err = r.s.StatByIDGroupEvent(c, arg.Mid, arg.ID); stat != nil && err == nil {
|
||||
*res = stat
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// RefreshBaseScore rpc.
|
||||
func (r *RPC) RefreshBaseScore(c context.Context, arg *cmmdl.ArgReset, res *struct{}) (err error) {
|
||||
return r.s.RefreshBaseScore(c, arg)
|
||||
}
|
34
app/service/main/spy/server/grpc/BUILD
Normal file
34
app/service/main/spy/server/grpc/BUILD
Normal file
@ -0,0 +1,34 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["server.go"],
|
||||
importpath = "go-common/app/service/main/spy/server/grpc",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/service/main/spy/api:go_default_library",
|
||||
"//app/service/main/spy/model:go_default_library",
|
||||
"//app/service/main/spy/service:go_default_library",
|
||||
"//library/net/rpc/warden: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"],
|
||||
)
|
138
app/service/main/spy/server/grpc/server.go
Normal file
138
app/service/main/spy/server/grpc/server.go
Normal file
@ -0,0 +1,138 @@
|
||||
// Package server generate by warden_gen
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
pb "go-common/app/service/main/spy/api"
|
||||
"go-common/app/service/main/spy/model"
|
||||
service "go-common/app/service/main/spy/service"
|
||||
"go-common/library/net/rpc/warden"
|
||||
)
|
||||
|
||||
// New Spy warden rpc server
|
||||
func New(c *warden.ServerConfig, svr *service.Service) *warden.Server {
|
||||
ws := warden.NewServer(c)
|
||||
pb.RegisterSpyServer(ws.Server(), &server{svr})
|
||||
_, err := ws.Start()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return ws
|
||||
}
|
||||
|
||||
type server struct {
|
||||
svr *service.Service
|
||||
}
|
||||
|
||||
var _ pb.SpyServer = &server{}
|
||||
|
||||
// Ping check dao health.
|
||||
func (s *server) Ping(ctx context.Context, req *pb.PingReq) (*pb.PingReply, error) {
|
||||
return &pb.PingReply{}, nil
|
||||
}
|
||||
|
||||
// StatByID spy stat by id or mid.
|
||||
func (s *server) StatByID(ctx context.Context, req *pb.StatByIDReq) (*pb.StatByIDReply, error) {
|
||||
statistics, err := s.svr.StatByID(ctx, req.Mid, req.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reply := new(pb.StatByIDReply)
|
||||
reply.DeepCopyFromStatistics(statistics)
|
||||
return reply, nil
|
||||
}
|
||||
|
||||
// StatByIDGroupEvent spy stat by id or mid.
|
||||
func (s *server) StatByIDGroupEvent(ctx context.Context, req *pb.StatByIDGroupEventReq) (*pb.StatByIDGroupEventReply, error) {
|
||||
statistics, err := s.svr.StatByIDGroupEvent(ctx, req.Mid, req.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reply := new(pb.StatByIDGroupEventReply)
|
||||
reply.DeepCopyFromStatistics(statistics)
|
||||
return reply, nil
|
||||
}
|
||||
|
||||
// PurgeUser purge user info
|
||||
func (s *server) PurgeUser(ctx context.Context, req *pb.PurgeUserReq) (*pb.PurgeUserReply, error) {
|
||||
return &pb.PurgeUserReply{}, s.svr.PurgeUser(ctx, req.Mid, req.Action)
|
||||
}
|
||||
|
||||
// HandleEvent handle spy-event.
|
||||
func (s *server) HandleEvent(ctx context.Context, req *pb.HandleEventReq) (*pb.HandleEventReply, error) {
|
||||
eventMsg := new(model.EventMessage)
|
||||
req.DeepCopyAsIntoEventMessage(eventMsg)
|
||||
return &pb.HandleEventReply{}, s.svr.HandleEvent(ctx, eventMsg)
|
||||
}
|
||||
|
||||
// UserInfo get UserInfo by mid , from cache or db or generate.
|
||||
func (s *server) UserInfo(ctx context.Context, req *pb.UserInfoReq) (*pb.UserInfoReply, error) {
|
||||
ui, err := s.svr.UserInfo(ctx, req.Mid, req.Ip)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reply := new(pb.UserInfoReply)
|
||||
reply.DeepCopyFromUserInfo(ui)
|
||||
return reply, nil
|
||||
}
|
||||
|
||||
// UserInfoAsyn get UserInfo by mid , from cache or db or asyn generate.
|
||||
func (s *server) UserInfoAsyn(ctx context.Context, req *pb.UserInfoAsynReq) (*pb.UserInfoAsynReply, error) {
|
||||
ui, err := s.svr.UserInfoAsyn(ctx, req.Mid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reply := new(pb.UserInfoAsynReply)
|
||||
reply.DeepCopyFromUserInfo(ui)
|
||||
return reply, nil
|
||||
}
|
||||
|
||||
// ReBuildPortrait reBuild user info.
|
||||
func (s *server) ReBuildPortrait(ctx context.Context, req *pb.ReBuildPortraitReq) (*pb.ReBuildPortraitReply, error) {
|
||||
return &pb.ReBuildPortraitReply{}, s.svr.ReBuildPortrait(ctx, req.Mid, req.Reason)
|
||||
}
|
||||
|
||||
// UpdateUserScore update user score
|
||||
func (s *server) UpdateUserScore(ctx context.Context, req *pb.UpdateUserScoreReq) (*pb.UpdateUserScoreReply, error) {
|
||||
return &pb.UpdateUserScoreReply{}, s.svr.UpdateUserScore(ctx, req.Mid, req.Ip, req.Effect)
|
||||
}
|
||||
|
||||
// RefreshBaseScore refresh base score.
|
||||
func (s *server) RefreshBaseScore(ctx context.Context, req *pb.RefreshBaseScoreReq) (*pb.RefreshBaseScoreReply, error) {
|
||||
argReset := new(model.ArgReset)
|
||||
req.DeepCopyAsIntoArgReset(argReset)
|
||||
return &pb.RefreshBaseScoreReply{}, s.svr.RefreshBaseScore(ctx, argReset)
|
||||
}
|
||||
|
||||
// UpdateBaseScore update base score.
|
||||
func (s *server) UpdateBaseScore(ctx context.Context, req *pb.UpdateBaseScoreReq) (*pb.UpdateBaseScoreReply, error) {
|
||||
argReset := new(model.ArgReset)
|
||||
req.DeepCopyAsIntoArgReset(argReset)
|
||||
return &pb.UpdateBaseScoreReply{}, s.svr.UpdateBaseScore(ctx, argReset)
|
||||
}
|
||||
|
||||
// UpdateEventScore update event score.
|
||||
func (s *server) UpdateEventScore(ctx context.Context, req *pb.UpdateEventScoreReq) (*pb.UpdateEventScoreReply, error) {
|
||||
argReset := new(model.ArgReset)
|
||||
req.DeepCopyAsIntoArgReset(argReset)
|
||||
return &pb.UpdateEventScoreReply{}, s.svr.UpdateEventScore(ctx, argReset)
|
||||
}
|
||||
|
||||
// ClearReliveTimes clear times.
|
||||
func (s *server) ClearReliveTimes(ctx context.Context, req *pb.ClearReliveTimesReq) (*pb.ClearReliveTimesReply, error) {
|
||||
argReset := new(model.ArgReset)
|
||||
req.DeepCopyAsIntoArgReset(argReset)
|
||||
return &pb.ClearReliveTimesReply{}, s.svr.ClearReliveTimes(ctx, argReset)
|
||||
}
|
||||
|
||||
// Info get user info by mid.
|
||||
func (s *server) Info(ctx context.Context, req *pb.InfoReq) (*pb.InfoReply, error) {
|
||||
ui, err := s.svr.Info(ctx, req.Mid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reply := new(pb.InfoReply)
|
||||
reply.DeepCopyFromUserInfo(ui)
|
||||
return reply, nil
|
||||
}
|
40
app/service/main/spy/server/http/BUILD
Normal file
40
app/service/main/spy/server/http/BUILD
Normal file
@ -0,0 +1,40 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"http.go",
|
||||
"spy.go",
|
||||
],
|
||||
importpath = "go-common/app/service/main/spy/server/http",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/service/main/spy/conf:go_default_library",
|
||||
"//app/service/main/spy/model:go_default_library",
|
||||
"//app/service/main/spy/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",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
58
app/service/main/spy/server/http/http.go
Normal file
58
app/service/main/spy/server/http/http.go
Normal file
@ -0,0 +1,58 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"go-common/app/service/main/spy/conf"
|
||||
"go-common/app/service/main/spy/service"
|
||||
"go-common/library/log"
|
||||
bm "go-common/library/net/http/blademaster"
|
||||
"go-common/library/net/http/blademaster/middleware/verify"
|
||||
)
|
||||
|
||||
var (
|
||||
spySvc *service.Service
|
||||
verifyN *verify.Verify
|
||||
)
|
||||
|
||||
// Init init http server.
|
||||
func Init(c *conf.Config, s *service.Service) {
|
||||
spySvc = s
|
||||
verifyN = verify.New(nil)
|
||||
// init inner router
|
||||
engineInner := bm.DefaultServer(c.BM)
|
||||
innerRouter(engineInner)
|
||||
// init local server
|
||||
if err := engineInner.Start(); err != nil {
|
||||
log.Error("xhttp.Serve error(%v)", err)
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// innerRouter init inner router.
|
||||
func innerRouter(e *bm.Engine) {
|
||||
// health check
|
||||
e.Ping(ping)
|
||||
e.Register(register)
|
||||
//new defined api lists
|
||||
group := e.Group("/x/internal/v1/spy", verifyN.Verify)
|
||||
{
|
||||
group.GET("/info", info)
|
||||
group.GET("/purge", purgeUser)
|
||||
group.POST("/purge2", purgeUser2)
|
||||
group.GET("/stat", stat)
|
||||
}
|
||||
}
|
||||
|
||||
// ping check server ok.
|
||||
func ping(c *bm.Context) {
|
||||
if spySvc.Ping(c) != nil {
|
||||
log.Error("spy-service service ping error")
|
||||
c.AbortWithStatus(http.StatusServiceUnavailable)
|
||||
}
|
||||
}
|
||||
|
||||
// register check server ok.
|
||||
func register(c *bm.Context) {
|
||||
c.JSON(map[string]interface{}{}, nil)
|
||||
}
|
105
app/service/main/spy/server/http/spy.go
Normal file
105
app/service/main/spy/server/http/spy.go
Normal file
@ -0,0 +1,105 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
|
||||
"go-common/app/service/main/spy/model"
|
||||
"go-common/library/ecode"
|
||||
"go-common/library/log"
|
||||
bm "go-common/library/net/http/blademaster"
|
||||
)
|
||||
|
||||
func info(c *bm.Context) {
|
||||
var (
|
||||
err error
|
||||
mid int64
|
||||
midStr = c.Request.Form.Get("mid")
|
||||
)
|
||||
if mid, err = strconv.ParseInt(midStr, 10, 64); err != nil {
|
||||
c.JSON(nil, ecode.RequestErr)
|
||||
return
|
||||
}
|
||||
ui, err := spySvc.Info(c, mid)
|
||||
if err != nil {
|
||||
log.Error("spySvc.UserInfo(%d), ui(%v), err(%v)", mid, ui, err)
|
||||
c.JSON(nil, ecode.ServerErr)
|
||||
return
|
||||
}
|
||||
c.JSON(&model.UserScore{Mid: ui.Mid, Score: ui.Score}, nil)
|
||||
}
|
||||
|
||||
func purgeUser(c *bm.Context) {
|
||||
var (
|
||||
err error
|
||||
mid int64
|
||||
params = c.Request.Form
|
||||
midStr = params.Get("mid")
|
||||
action = params.Get("modifiedAttr")
|
||||
)
|
||||
if mid, err = strconv.ParseInt(midStr, 10, 64); err != nil {
|
||||
c.JSON(nil, ecode.RequestErr)
|
||||
return
|
||||
}
|
||||
if action == "" {
|
||||
c.JSON(nil, ecode.RequestErr)
|
||||
return
|
||||
}
|
||||
err = spySvc.PurgeUser(c, mid, action)
|
||||
c.JSON(nil, err)
|
||||
}
|
||||
|
||||
func purgeUser2(c *bm.Context) {
|
||||
var (
|
||||
err error
|
||||
params = c.Request.Form
|
||||
msg = params.Get("msg")
|
||||
info = new(model.NotifyInfo)
|
||||
)
|
||||
if err = json.Unmarshal([]byte(msg), &info); err != nil {
|
||||
log.Error("purgeUser2 (%s) json.Unmarshal error(%v)", msg, err)
|
||||
c.JSON(nil, ecode.RequestErr)
|
||||
return
|
||||
}
|
||||
if info == nil {
|
||||
c.JSON(nil, ecode.RequestErr)
|
||||
return
|
||||
}
|
||||
if info.Action == "" || info.Mid == 0 {
|
||||
c.JSON(nil, ecode.RequestErr)
|
||||
return
|
||||
}
|
||||
if err = spySvc.PurgeUser(c, info.Mid, info.Action); err != nil {
|
||||
log.Error("purgeUser2 (%+v) error(%v)", info, err)
|
||||
}
|
||||
c.JSON(nil, err)
|
||||
}
|
||||
|
||||
func stat(c *bm.Context) {
|
||||
var (
|
||||
err error
|
||||
mid, id int64
|
||||
params = c.Request.Form
|
||||
midStr = params.Get("mid")
|
||||
idStr = params.Get("id")
|
||||
)
|
||||
if mid, err = strconv.ParseInt(midStr, 10, 64); midStr != "" && err != nil {
|
||||
c.JSON(nil, ecode.RequestErr)
|
||||
return
|
||||
}
|
||||
if id, err = strconv.ParseInt(idStr, 10, 64); idStr != "" && err != nil {
|
||||
c.JSON(nil, ecode.RequestErr)
|
||||
return
|
||||
}
|
||||
if id == 0 && mid == 0 {
|
||||
c.JSON(nil, ecode.RequestErr)
|
||||
return
|
||||
}
|
||||
stat, err := spySvc.StatByID(c, mid, id)
|
||||
if err != nil {
|
||||
log.Error("spySvc.StatByID err(%v)", err)
|
||||
c.JSON(nil, ecode.ServerErr)
|
||||
return
|
||||
}
|
||||
c.JSON(stat, nil)
|
||||
}
|
73
app/service/main/spy/service/BUILD
Normal file
73
app/service/main/spy/service/BUILD
Normal file
@ -0,0 +1,73 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_test",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"block_test.go",
|
||||
"rule_test.go",
|
||||
"service_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
rundir = ".",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//app/service/main/spy/conf:go_default_library",
|
||||
"//app/service/main/spy/dao:go_default_library",
|
||||
"//app/service/main/spy/model:go_default_library",
|
||||
"//library/cache/redis:go_default_library",
|
||||
"//library/ecode:go_default_library",
|
||||
"//library/log:go_default_library",
|
||||
"//library/net/ip:go_default_library",
|
||||
"//vendor/github.com/bouk/monkey:go_default_library",
|
||||
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"account.go",
|
||||
"block.go",
|
||||
"rule.go",
|
||||
"service.go",
|
||||
"spy.go",
|
||||
"stat.go",
|
||||
],
|
||||
importpath = "go-common/app/service/main/spy/service",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/service/main/account/model:go_default_library",
|
||||
"//app/service/main/account/rpc/client:go_default_library",
|
||||
"//app/service/main/spy/conf:go_default_library",
|
||||
"//app/service/main/spy/dao:go_default_library",
|
||||
"//app/service/main/spy/model:go_default_library",
|
||||
"//library/database/sql:go_default_library",
|
||||
"//library/ecode:go_default_library",
|
||||
"//library/log:go_default_library",
|
||||
"//library/net/ip:go_default_library",
|
||||
"//library/net/metadata:go_default_library",
|
||||
"//library/stat/prom:go_default_library",
|
||||
"//vendor/github.com/pkg/errors: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"],
|
||||
)
|
51
app/service/main/spy/service/account.go
Normal file
51
app/service/main/spy/service/account.go
Normal file
@ -0,0 +1,51 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go-common/library/log"
|
||||
"go-common/library/net/metadata"
|
||||
)
|
||||
|
||||
const (
|
||||
_banned = 1
|
||||
_unBindTel = "unBindTel"
|
||||
_updateTel = "updateTel"
|
||||
_updateEmail = "updateEmail"
|
||||
_updateUname = "updateUname"
|
||||
_updateFace = "updateFace"
|
||||
_updateIDEN = "updateIDEN"
|
||||
)
|
||||
|
||||
// PurgeUser purge user info
|
||||
func (s *Service) PurgeUser(c context.Context, mid int64, action string) (err error) {
|
||||
ui, err := s.UserInfoAsyn(c, mid)
|
||||
if err != nil {
|
||||
log.Error("purge user(%d) failed", mid)
|
||||
return
|
||||
}
|
||||
if ui == nil || ui.State == _banned {
|
||||
log.Error("ui not fund or banned:%v", ui)
|
||||
return
|
||||
}
|
||||
var effect string
|
||||
switch action {
|
||||
case _unBindTel:
|
||||
effect = "解除绑定手机"
|
||||
case _updateTel:
|
||||
effect = "更新绑定手机"
|
||||
case _updateEmail:
|
||||
effect = "更新绑定邮箱"
|
||||
case _updateUname, _updateFace:
|
||||
effect = "修改账号资料"
|
||||
case _updateIDEN:
|
||||
effect = "完成实名认证"
|
||||
default:
|
||||
log.Error("unhandle action(%s) for mid(%d)", action, mid)
|
||||
}
|
||||
ip := metadata.String(c, metadata.RemoteIP)
|
||||
s.updatescore(func() {
|
||||
s.UpdateUserScore(context.TODO(), mid, ip, effect)
|
||||
})
|
||||
return
|
||||
}
|
164
app/service/main/spy/service/block.go
Normal file
164
app/service/main/spy/service/block.go
Normal file
@ -0,0 +1,164 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
accmdl "go-common/app/service/main/account/model"
|
||||
"go-common/app/service/main/spy/model"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
// HandlerFunc block filter handler function.
|
||||
type HandlerFunc func(af *Args)
|
||||
|
||||
// Args filter args.
|
||||
type Args struct {
|
||||
block bool
|
||||
ui *model.UserInfo
|
||||
}
|
||||
|
||||
//BlockNo block no.
|
||||
func (s *Service) BlockNo(seconds int64) int64 {
|
||||
return time.Now().Unix() / seconds
|
||||
}
|
||||
|
||||
func (s *Service) scoreLessHandler(af *Args) {
|
||||
v, ok := s.Config(model.LessBlockScore)
|
||||
if !ok {
|
||||
log.Error("scoreLessHandler get config error(%s,%v)", model.LessBlockScore, s.spyConfig)
|
||||
return
|
||||
}
|
||||
if af.ui.Score <= v.(int8) {
|
||||
af.block = true
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
//reVerifyHandler double check user lv and vip info
|
||||
func (s *Service) reVerifyHandler(c context.Context, ui *model.UserInfo) (b bool, err error) {
|
||||
b = true
|
||||
account, err := s.accInfoRetry(c, ui.Mid)
|
||||
if err != nil || account == nil {
|
||||
return
|
||||
}
|
||||
// vip or lv4
|
||||
if (account.Level < s.c.Property.DoubleCheckLevel) &&
|
||||
(account.Vip.Status != model.VipEnableStatus || account.Vip.Type == model.VipNonType) {
|
||||
return
|
||||
}
|
||||
udb, err := s.dao.UserInfo(c, ui.Mid)
|
||||
if err != nil {
|
||||
log.Error(" s.dao.UserInfo(%d) err(%v)", ui.Mid, err)
|
||||
return
|
||||
}
|
||||
if udb.ReliveTimes > model.ReliveCheckTimes {
|
||||
s.promBlockInfo.Incr("security_login_times_out_count")
|
||||
return
|
||||
}
|
||||
b = false
|
||||
l, err := s.dao.SetNXLockCache(c, ui.Mid)
|
||||
if !l || err != nil {
|
||||
log.Error("cycleblock had run (%v,%v)", l, err)
|
||||
return
|
||||
}
|
||||
if err = s.ReBuildPortrait(c, ui.Mid, model.DoubleCheckRemake); err != nil {
|
||||
log.Error(" s.ReBuildPortrait(%d) err(%v)", ui.Mid, err)
|
||||
return
|
||||
}
|
||||
reason, _ := s.blockReason(c, ui.Mid)
|
||||
if err = s.dao.SecurityLogin(c, ui.Mid, reason); err != nil {
|
||||
log.Error(" s.dao.SecurityLogin(%d) err(%v)", ui.Mid, err)
|
||||
return
|
||||
}
|
||||
s.promBlockInfo.Incr("security_login_count")
|
||||
return
|
||||
}
|
||||
|
||||
// Verify block filter.
|
||||
func (s *Service) Verify(c context.Context, af *Args, handlers ...HandlerFunc) (b bool) {
|
||||
v, ok := s.Config(model.AutoBlock)
|
||||
if !ok {
|
||||
log.Error("Verfiy get config error(%s,%v)", model.AutoBlock, s.spyConfig)
|
||||
return
|
||||
}
|
||||
if v.(int8) != model.AutoBlockOpen {
|
||||
log.Info("autoBlock Close(%v)", af)
|
||||
return
|
||||
}
|
||||
for _, h := range handlers {
|
||||
h(af)
|
||||
if b = af.block; b {
|
||||
break
|
||||
}
|
||||
}
|
||||
// double check
|
||||
if b {
|
||||
s.promBlockInfo.Incr("expect_block_count")
|
||||
b, _ = s.reVerifyHandler(c, af.ui)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// BlockFilter do user block.
|
||||
func (s *Service) BlockFilter(c context.Context, ui *model.UserInfo) (state int8, err error) {
|
||||
var (
|
||||
args = &Args{ui: ui}
|
||||
hs = []HandlerFunc{s.scoreLessHandler}
|
||||
blockNo = s.BlockNo(s.c.Property.Block.CycleTimes)
|
||||
)
|
||||
state = ui.State
|
||||
if b := s.Verify(c, args, hs...); !b {
|
||||
return
|
||||
}
|
||||
state = model.StateBlock
|
||||
s.dao.AddBlockCache(c, ui.Mid, ui.Score, blockNo)
|
||||
if err = s.dao.AddPunishmentQueue(c, ui.Mid, blockNo); err != nil {
|
||||
log.Error("s.dao.AddPunishmentQueue(%d) error(%v)", ui.Mid, err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) blockReason(c context.Context, mid int64) (reason string, remake string) {
|
||||
var (
|
||||
err error
|
||||
hs []*model.UserEventHistory
|
||||
buf bytes.Buffer
|
||||
)
|
||||
if hs, err = s.dao.HistoryList(c, mid, model.BlockReasonSize); err != nil || len(hs) == 0 {
|
||||
log.Error("s.dao.HistoryList(%d) err(%v)", mid, err)
|
||||
return
|
||||
}
|
||||
m := make(map[string]int)
|
||||
for _, v := range hs {
|
||||
if v.Reason == model.DoubleCheckRemake {
|
||||
continue
|
||||
}
|
||||
if m[v.Reason] == 0 {
|
||||
m[v.Reason] = 1
|
||||
} else {
|
||||
m[v.Reason] = m[v.Reason] + 1
|
||||
}
|
||||
}
|
||||
for k, v := range m {
|
||||
buf.WriteString(k)
|
||||
buf.WriteString("x")
|
||||
buf.WriteString(fmt.Sprintf("%d ", v))
|
||||
}
|
||||
reason = buf.String()
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) accInfoRetry(c context.Context, mid int64) (account *accmdl.Card, err error) {
|
||||
for i := 1; i <= model.RetryTimes; i++ {
|
||||
account, err = s.accRPC.Card3(c, &accmdl.ArgMid{Mid: mid})
|
||||
if account == nil || err != nil {
|
||||
log.Error(" s.accRPC.Infos2(%d) err(%v)", mid, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
129
app/service/main/spy/service/block_test.go
Normal file
129
app/service/main/spy/service/block_test.go
Normal file
@ -0,0 +1,129 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"go-common/app/service/main/spy/model"
|
||||
spy "go-common/app/service/main/spy/model"
|
||||
"go-common/library/net/ip"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
var (
|
||||
testLowMid int64 = 59999
|
||||
testLowScore int8 = 5
|
||||
testHighScore int8 = 90
|
||||
testLv5Mid int64 = 15555180
|
||||
testNoLv5Mid int64 = 200
|
||||
)
|
||||
|
||||
func Test_Verfiy(t *testing.T) {
|
||||
Convey("Test_Verfiy block ", t, WithService(func(s *Service) {
|
||||
ui, err := s.UserInfo(c, testLowMid, "")
|
||||
fmt.Println(ui)
|
||||
So(ui, ShouldNotBeEmpty)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
hs := []HandlerFunc{s.scoreLessHandler}
|
||||
Convey("Test_Verfiy scoreLessHandler low score ", WithService(func(s *Service) {
|
||||
ui.Score = testLowScore
|
||||
args := &Args{ui: ui}
|
||||
b := s.Verify(c, args, hs...)
|
||||
fmt.Println("b", b, ui.Score)
|
||||
So(b, ShouldBeTrue)
|
||||
}))
|
||||
Convey("Test_Verfiy scoreLessHandler high score ", WithService(func(s *Service) {
|
||||
ui.Score = testHighScore
|
||||
args := &Args{ui: ui}
|
||||
b := s.Verify(c, args, hs...)
|
||||
fmt.Println("b", b, ui.Score)
|
||||
So(b, ShouldBeFalse)
|
||||
}))
|
||||
}))
|
||||
}
|
||||
|
||||
func Test_BlockFilter(t *testing.T) {
|
||||
Convey("Test_BlockFilter filter ", t, WithService(func(s *Service) {
|
||||
var (
|
||||
c = context.TODO()
|
||||
)
|
||||
ui, err := s.UserInfo(c, testLowMid, "")
|
||||
fmt.Println(ui)
|
||||
So(ui, ShouldNotBeEmpty)
|
||||
So(err, ShouldBeNil)
|
||||
tx, err := s.dao.BeginTran(c)
|
||||
So(err, ShouldBeNil)
|
||||
Convey("Test_BlockFilter block ", WithService(func(s *Service) {
|
||||
ret, err := s.dao.BlockMidCache(c, s.BlockNo(s.c.Property.Block.CycleTimes), 10)
|
||||
So(err, ShouldBeNil)
|
||||
So(ret, ShouldBeNil)
|
||||
|
||||
ui.Score = testLowScore
|
||||
state, err := s.BlockFilter(context.TODO(), ui)
|
||||
So(err, ShouldBeNil)
|
||||
So(state == model.StateBlock, ShouldBeTrue)
|
||||
err = tx.Commit()
|
||||
So(err, ShouldBeNil)
|
||||
Convey("Test_BlockFilter cache had mid ", WithService(func(s *Service) {
|
||||
ret, err := s.dao.BlockMidCache(c, s.BlockNo(s.c.Property.Block.CycleTimes), 10)
|
||||
fmt.Println("ret", ret)
|
||||
So(err, ShouldBeNil)
|
||||
So(ret, ShouldContain, ui.Mid)
|
||||
}))
|
||||
}))
|
||||
Convey("Test_BlockFilter bo block ", WithService(func(s *Service) {
|
||||
ui.Score = testHighScore
|
||||
state, err := s.BlockFilter(context.TODO(), ui)
|
||||
So(err, ShouldBeNil)
|
||||
So(state == model.StateBlock, ShouldBeFalse)
|
||||
err = tx.Commit()
|
||||
So(err, ShouldBeNil)
|
||||
}))
|
||||
|
||||
}))
|
||||
}
|
||||
|
||||
func Test_ReVerify(t *testing.T) {
|
||||
Convey("Test_ReVerify user lv check ", t, WithService(func(s *Service) {
|
||||
var (
|
||||
c = context.TODO()
|
||||
)
|
||||
Convey("test vip user ", WithService(func(s *Service) {
|
||||
err := s.ClearReliveTimes(c, &spy.ArgReset{Mid: testLv5Mid, Operator: "yubaihai"})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
ui, err := s.UserInfo(c, testLv5Mid, ip.InternalIP())
|
||||
So(err, ShouldBeNil)
|
||||
So(ui, ShouldNotBeEmpty)
|
||||
fmt.Println("ui", ui)
|
||||
|
||||
b, err := s.reVerifyHandler(c, ui)
|
||||
So(err, ShouldBeNil)
|
||||
So(b, ShouldBeFalse)
|
||||
|
||||
// two
|
||||
b, err = s.reVerifyHandler(c, ui)
|
||||
So(err, ShouldBeNil)
|
||||
So(b, ShouldBeFalse)
|
||||
|
||||
// three
|
||||
b, err = s.reVerifyHandler(c, ui)
|
||||
So(err, ShouldBeNil)
|
||||
So(b, ShouldBeTrue)
|
||||
}))
|
||||
Convey("test no lv vip user ", WithService(func(s *Service) {
|
||||
|
||||
ui, err := s.UserInfo(c, testNoLv5Mid, ip.InternalIP())
|
||||
So(err, ShouldBeNil)
|
||||
So(ui, ShouldNotBeEmpty)
|
||||
fmt.Println("ui", ui)
|
||||
|
||||
b, err := s.reVerifyHandler(c, ui)
|
||||
So(err, ShouldBeNil)
|
||||
So(b, ShouldBeTrue)
|
||||
}))
|
||||
}))
|
||||
}
|
439
app/service/main/spy/service/rule.go
Normal file
439
app/service/main/spy/service/rule.go
Normal file
@ -0,0 +1,439 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go-common/app/service/main/spy/conf"
|
||||
"go-common/app/service/main/spy/dao"
|
||||
"go-common/app/service/main/spy/model"
|
||||
"go-common/library/ecode"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
const (
|
||||
// RestoreBaseScoreEvent represents a event triggered when user resets base score.
|
||||
RestoreBaseScoreEvent = "restore_base_score"
|
||||
)
|
||||
|
||||
const (
|
||||
_defaultService = ""
|
||||
_defaultRiskLevel = 1
|
||||
|
||||
_telIsBound = "_telIsBound"
|
||||
_telIsNotBound = "_telIsNotBound"
|
||||
_telIsLowRisk = "_telIsLowRisk"
|
||||
_telIsMediumRisk = "_telIsMediumRisk"
|
||||
_telIsHighRisk = "_telIsHighRisk"
|
||||
_telIsUnknownRisk = "_telIsUnknownRisk"
|
||||
_mailIsBound = "_mailIsBound"
|
||||
_mailIsNotBound = "_mailIsNotBound"
|
||||
_idenIsAuthed = "_idenIsAuthed"
|
||||
_idenIsNotAuthed = "_idenIsNotAuthed"
|
||||
)
|
||||
|
||||
const (
|
||||
// IterFail represents iteration failure.
|
||||
IterFail IterState = iota
|
||||
// IterSuccess represents iteration success.
|
||||
IterSuccess
|
||||
)
|
||||
|
||||
// Rule represents a rule.
|
||||
type Rule = string
|
||||
|
||||
// Rules represents an array of rules.
|
||||
type Rules = []Rule
|
||||
|
||||
// IterState represents the state of iteration.
|
||||
type IterState = int
|
||||
|
||||
// RuleFunc represents a judgement function.
|
||||
type RuleFunc func(info *JudgementInfo) (result bool, err error)
|
||||
|
||||
var ruleToFuncMaps = map[string]RuleFunc{
|
||||
_telIsBound: telIsBound,
|
||||
_telIsNotBound: telIsNotBound,
|
||||
_telIsLowRisk: telIsLowRisk,
|
||||
_telIsMediumRisk: telIsMediumRisk,
|
||||
_telIsHighRisk: telIsHighRisk,
|
||||
_telIsUnknownRisk: telIsUnknownRisk,
|
||||
_mailIsBound: mailIsBound,
|
||||
_mailIsNotBound: mailIsNotBound,
|
||||
_idenIsAuthed: idenIsAuthed,
|
||||
_idenIsNotAuthed: idenIsNotAuthed,
|
||||
}
|
||||
|
||||
// FactoryMeta includes details to find a factor.
|
||||
type FactoryMeta struct {
|
||||
serviceName string
|
||||
eventName string
|
||||
riskLevel int8
|
||||
}
|
||||
|
||||
// JudgementInfo includes all needed information to judge factor.
|
||||
type JudgementInfo struct {
|
||||
mid int64
|
||||
ip string
|
||||
ctx context.Context
|
||||
s *Service
|
||||
auditInfo *model.AuditInfo
|
||||
profileInfo *model.ProfileInfo
|
||||
telRiskInfo *model.TelRiskInfo
|
||||
}
|
||||
|
||||
// RuleMap represents a map-like struct which contains rules and factoryMeta.
|
||||
type RuleMap struct {
|
||||
rules Rules
|
||||
factoryMeta FactoryMeta
|
||||
}
|
||||
|
||||
// NewJudgementInfo returns a new judgement info.
|
||||
func NewJudgementInfo(c context.Context, s *Service, mid int64, ip string) *JudgementInfo {
|
||||
return &JudgementInfo{
|
||||
s: s,
|
||||
mid: mid,
|
||||
ctx: c,
|
||||
ip: ip,
|
||||
}
|
||||
}
|
||||
|
||||
func (ji *JudgementInfo) getAuditInfo() (auditInfo *model.AuditInfo, err error) {
|
||||
if ji.auditInfo != nil {
|
||||
return ji.auditInfo, nil
|
||||
}
|
||||
auditInfo, err = ji.s.dao.AuditInfo(ji.ctx, ji.mid, ji.ip)
|
||||
if err != nil {
|
||||
log.Error("s.dao.AuditInfo(%d, %s) error(%v)", ji.mid, ji.ip, err)
|
||||
return
|
||||
}
|
||||
ji.auditInfo = auditInfo
|
||||
return
|
||||
}
|
||||
|
||||
func (ji *JudgementInfo) getProfileInfo() (profileInfo *model.ProfileInfo, err error) {
|
||||
if ji.profileInfo != nil {
|
||||
return ji.profileInfo, nil
|
||||
}
|
||||
profileInfo, err = ji.s.dao.ProfileInfo(ji.ctx, ji.mid, ji.ip)
|
||||
if err != nil {
|
||||
log.Error("s.dao.ProfileInfo(%d, %s) error(%v)", ji.mid, ji.ip, err)
|
||||
return
|
||||
}
|
||||
ji.profileInfo = profileInfo
|
||||
return ji.profileInfo, nil
|
||||
}
|
||||
|
||||
func (ji *JudgementInfo) getTelRiskInfo() (telRiskInfo *model.TelRiskInfo, err error) {
|
||||
var (
|
||||
telRiskLevel int8
|
||||
event *model.Event
|
||||
eventHistory *model.UserEventHistory
|
||||
unicomGiftState int
|
||||
)
|
||||
if ji.telRiskInfo != nil {
|
||||
return ji.telRiskInfo, nil
|
||||
}
|
||||
telRiskLevel, err = ji.s.TelRiskLevel(ji.ctx, ji.mid, "")
|
||||
if err != nil {
|
||||
log.Error("s.dao.TelRiskLevel(%d) error:(%v)", ji.mid, err)
|
||||
return
|
||||
}
|
||||
if event, err = ji.s.dao.Event(ji.ctx, RestoreBaseScoreEvent); err != nil {
|
||||
return
|
||||
}
|
||||
if eventHistory, err = ji.s.dao.EventHistoryByMidAndEvent(ji.ctx, ji.mid, event.ID); err != nil {
|
||||
return
|
||||
}
|
||||
if unicomGiftState, err = ji.s.dao.UnicomGiftState(ji.ctx, ji.mid); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ji.telRiskInfo = &model.TelRiskInfo{
|
||||
TelRiskLevel: telRiskLevel,
|
||||
RestoreHistory: eventHistory,
|
||||
UnicomGiftState: unicomGiftState,
|
||||
}
|
||||
return ji.telRiskInfo, nil
|
||||
}
|
||||
|
||||
func (s *Service) getRulesMap() []RuleMap {
|
||||
return []RuleMap{
|
||||
// 绑定手机状态:绑定手机,且天御认定为低风险 邮箱绑定状态:any 实名认证状态:通过认证无论人工还是芝麻
|
||||
{
|
||||
factoryMeta: FactoryMeta{
|
||||
serviceName: _defaultService,
|
||||
eventName: conf.Conf.Property.Event.BindTelLowRiskAndIdenAuth,
|
||||
riskLevel: _defaultRiskLevel,
|
||||
},
|
||||
rules: Rules{
|
||||
_telIsBound, _telIsLowRisk, _idenIsAuthed,
|
||||
}},
|
||||
// 绑定手机状态:绑定手机,且天域认定为低风险 邮箱绑定状态:any 实名认证状态:无
|
||||
{
|
||||
factoryMeta: FactoryMeta{
|
||||
serviceName: _defaultService,
|
||||
eventName: conf.Conf.Property.Event.BindTelLowRiskAndIdenUnauth,
|
||||
riskLevel: _defaultRiskLevel,
|
||||
},
|
||||
rules: Rules{
|
||||
_telIsBound, _telIsLowRisk, _idenIsNotAuthed,
|
||||
}},
|
||||
// 绑定手机状态:绑定手机,且天域认定为未知风险 邮箱绑定状态:any 实名认证状态:通过认证无论人工还是芝麻
|
||||
{
|
||||
factoryMeta: FactoryMeta{
|
||||
serviceName: _defaultService,
|
||||
eventName: conf.Conf.Property.Event.BindTelUnknownRiskAndIdenAuth,
|
||||
riskLevel: _defaultRiskLevel,
|
||||
},
|
||||
rules: Rules{
|
||||
_telIsBound, _telIsUnknownRisk, _idenIsAuthed,
|
||||
}},
|
||||
// 绑定手机状态:绑定手机,且天域认定为中风险 邮箱绑定状态:any 实名认证状态:通过认证无论人工还是芝麻
|
||||
{
|
||||
factoryMeta: FactoryMeta{
|
||||
serviceName: _defaultService,
|
||||
eventName: conf.Conf.Property.Event.BindTelMediumRiskAndIdenAuth,
|
||||
riskLevel: _defaultRiskLevel,
|
||||
},
|
||||
|
||||
rules: Rules{
|
||||
_telIsBound, _telIsMediumRisk, _idenIsAuthed,
|
||||
}},
|
||||
// 绑定手机状态:绑定手机,且天域认定为未知风险 邮箱绑定状态:any 实名认证状态:无
|
||||
{
|
||||
factoryMeta: FactoryMeta{
|
||||
serviceName: _defaultService,
|
||||
eventName: conf.Conf.Property.Event.BindTelUnknownRiskAndIdenUnauth,
|
||||
riskLevel: _defaultRiskLevel,
|
||||
},
|
||||
rules: Rules{
|
||||
_telIsBound, _telIsUnknownRisk, _idenIsNotAuthed,
|
||||
}},
|
||||
// 绑定手机状态:绑定手机,且天域认定为中风险 邮箱绑定状态:any 实名认证状态:无
|
||||
{
|
||||
factoryMeta: FactoryMeta{
|
||||
serviceName: _defaultService,
|
||||
eventName: conf.Conf.Property.Event.BindTelMediumRiskAndIdenUnauth,
|
||||
riskLevel: _defaultRiskLevel,
|
||||
},
|
||||
rules: Rules{
|
||||
_telIsBound, _telIsMediumRisk, _idenIsNotAuthed,
|
||||
}},
|
||||
// 绑定手机状态:无 绑定邮箱状态:有 实名认证状态:any
|
||||
{
|
||||
factoryMeta: FactoryMeta{
|
||||
serviceName: _defaultService,
|
||||
eventName: conf.Conf.Property.Event.BindMailAndIdenUnknown,
|
||||
riskLevel: _defaultRiskLevel,
|
||||
},
|
||||
rules: Rules{
|
||||
_telIsNotBound, _mailIsBound,
|
||||
}},
|
||||
// 绑定手机状态:绑定手机,且天域认定为高风险 邮箱绑定状态:any 实名认证状态:实名认证,无论人工还是芝麻
|
||||
{
|
||||
factoryMeta: FactoryMeta{
|
||||
serviceName: _defaultService,
|
||||
eventName: conf.Conf.Property.Event.BindTelHighRiskAndIdenAuth,
|
||||
riskLevel: _defaultRiskLevel,
|
||||
},
|
||||
rules: Rules{
|
||||
_telIsBound, _telIsHighRisk, _idenIsAuthed,
|
||||
}},
|
||||
// 无绑定手机状态:绑定手机 绑定邮箱状态:无 实名认证状态:无
|
||||
{
|
||||
factoryMeta: FactoryMeta{
|
||||
serviceName: _defaultService,
|
||||
eventName: conf.Conf.Property.Event.BindNothingV2,
|
||||
riskLevel: _defaultRiskLevel,
|
||||
},
|
||||
rules: Rules{
|
||||
_telIsNotBound, _mailIsNotBound, _idenIsNotAuthed,
|
||||
}},
|
||||
// 无绑定手机状态:绑定手机 绑定邮箱状态:无 实名认证状态:有
|
||||
{
|
||||
factoryMeta: FactoryMeta{
|
||||
serviceName: _defaultService,
|
||||
eventName: conf.Conf.Property.Event.BindNothingAndIdenAuth,
|
||||
riskLevel: _defaultRiskLevel,
|
||||
},
|
||||
rules: Rules{
|
||||
_telIsNotBound, _mailIsNotBound, _idenIsAuthed,
|
||||
}},
|
||||
// 绑定手机状态:绑定手机,且天域认定为高风险 邮箱绑定状态:any 实名认证状态:无
|
||||
{
|
||||
factoryMeta: FactoryMeta{
|
||||
serviceName: _defaultService,
|
||||
eventName: conf.Conf.Property.Event.BindTelHighRiskAndIdenUnauth,
|
||||
riskLevel: _defaultRiskLevel,
|
||||
},
|
||||
rules: Rules{
|
||||
_telIsBound, _telIsHighRisk, _idenIsNotAuthed,
|
||||
}},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) getJudgementInfo(c context.Context, mid int64, ip string) (judgementInfo *JudgementInfo, err error) {
|
||||
return NewJudgementInfo(c, s, mid, ip), nil
|
||||
}
|
||||
|
||||
func (s *Service) getRuleFunc(rule Rule) (ruleFunc RuleFunc, err error) {
|
||||
ruleFunc, ok := ruleToFuncMaps[rule]
|
||||
if !ok {
|
||||
err = ecode.SpyRuleNotExist
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) iterRules(info *JudgementInfo, rules Rules) (state IterState, err error) {
|
||||
var (
|
||||
counter int
|
||||
ruleFunc RuleFunc
|
||||
result bool
|
||||
)
|
||||
for _, rule := range rules {
|
||||
if ruleFunc, err = s.getRuleFunc(rule); err != nil {
|
||||
return
|
||||
}
|
||||
if result, err = ruleFunc(info); err != nil {
|
||||
return
|
||||
}
|
||||
if !result {
|
||||
log.Info("s.iterRules mid(%d) rules(%v) counter(%d) state(%d)", info.mid, rules, counter, IterFail)
|
||||
return IterFail, nil
|
||||
}
|
||||
counter++
|
||||
}
|
||||
log.Info("s.iterRules mid(%d) rules(%v) counter(%d) state(%d)", info.mid, rules, counter, IterSuccess)
|
||||
return IterSuccess, nil
|
||||
}
|
||||
|
||||
func (s *Service) getBaseScoreFactor(info *JudgementInfo) (meta FactoryMeta, err error) {
|
||||
var (
|
||||
ruleMap RuleMap
|
||||
state IterState
|
||||
)
|
||||
for _, ruleMap = range s.getRulesMap() {
|
||||
if state, err = s.iterRules(info, ruleMap.rules); err != nil {
|
||||
log.Error("s.iterRules(%v, %v) err(%v)", info, ruleMap.rules, err)
|
||||
return
|
||||
}
|
||||
if state == IterSuccess {
|
||||
return ruleMap.factoryMeta, nil
|
||||
}
|
||||
}
|
||||
err = ecode.SpyRulesNotMatch
|
||||
return
|
||||
}
|
||||
|
||||
func telIsBound(info *JudgementInfo) (result bool, err error) {
|
||||
var (
|
||||
auditInfo *model.AuditInfo
|
||||
)
|
||||
if auditInfo, err = info.getAuditInfo(); err != nil {
|
||||
return
|
||||
}
|
||||
return auditInfo.BindTel, nil
|
||||
}
|
||||
|
||||
func telIsNotBound(info *JudgementInfo) (result bool, err error) {
|
||||
var (
|
||||
auditInfo *model.AuditInfo
|
||||
)
|
||||
if auditInfo, err = info.getAuditInfo(); err != nil {
|
||||
return
|
||||
}
|
||||
return !auditInfo.BindTel, nil
|
||||
}
|
||||
|
||||
func telIsLowRisk(info *JudgementInfo) (result bool, err error) {
|
||||
var (
|
||||
telRiskInfo *model.TelRiskInfo
|
||||
)
|
||||
if telRiskInfo, err = info.getTelRiskInfo(); err != nil {
|
||||
return
|
||||
}
|
||||
if telRiskInfo.RestoreHistory != nil || telRiskInfo.UnicomGiftState == 1 {
|
||||
return true, nil
|
||||
}
|
||||
return telRiskInfo.TelRiskLevel == dao.TelRiskLevelLow, nil
|
||||
}
|
||||
|
||||
func telIsMediumRisk(info *JudgementInfo) (result bool, err error) {
|
||||
var (
|
||||
telRiskInfo *model.TelRiskInfo
|
||||
)
|
||||
if telRiskInfo, err = info.getTelRiskInfo(); err != nil {
|
||||
return
|
||||
}
|
||||
if telRiskInfo.RestoreHistory != nil || telRiskInfo.UnicomGiftState == 1 {
|
||||
return false, nil
|
||||
}
|
||||
return telRiskInfo.TelRiskLevel == dao.TelRiskLevelMedium, nil
|
||||
}
|
||||
|
||||
func telIsHighRisk(info *JudgementInfo) (result bool, err error) {
|
||||
var (
|
||||
telRiskInfo *model.TelRiskInfo
|
||||
)
|
||||
if telRiskInfo, err = info.getTelRiskInfo(); err != nil {
|
||||
return
|
||||
}
|
||||
if telRiskInfo.RestoreHistory != nil || telRiskInfo.UnicomGiftState == 1 {
|
||||
return false, nil
|
||||
}
|
||||
return telRiskInfo.TelRiskLevel == dao.TelRiskLevelHigh, nil
|
||||
}
|
||||
|
||||
func telIsUnknownRisk(info *JudgementInfo) (result bool, err error) {
|
||||
var (
|
||||
telRiskInfo *model.TelRiskInfo
|
||||
)
|
||||
if telRiskInfo, err = info.getTelRiskInfo(); err != nil {
|
||||
return
|
||||
}
|
||||
if telRiskInfo.RestoreHistory != nil || telRiskInfo.UnicomGiftState == 1 {
|
||||
return false, nil
|
||||
}
|
||||
return telRiskInfo.TelRiskLevel == dao.TelRiskLevelUnknown, nil
|
||||
}
|
||||
|
||||
func mailIsBound(info *JudgementInfo) (result bool, err error) {
|
||||
var (
|
||||
auditInfo *model.AuditInfo
|
||||
)
|
||||
if auditInfo, err = info.getAuditInfo(); err != nil {
|
||||
return
|
||||
}
|
||||
return auditInfo.BindMail, nil
|
||||
}
|
||||
|
||||
func mailIsNotBound(info *JudgementInfo) (result bool, err error) {
|
||||
var (
|
||||
auditInfo *model.AuditInfo
|
||||
)
|
||||
if auditInfo, err = info.getAuditInfo(); err != nil {
|
||||
return
|
||||
}
|
||||
return !auditInfo.BindMail, nil
|
||||
}
|
||||
|
||||
func idenIsNotAuthed(info *JudgementInfo) (result bool, err error) {
|
||||
var (
|
||||
profileInfo *model.ProfileInfo
|
||||
)
|
||||
if profileInfo, err = info.getProfileInfo(); err != nil {
|
||||
return
|
||||
}
|
||||
return profileInfo.Identification == 0, nil
|
||||
}
|
||||
|
||||
func idenIsAuthed(info *JudgementInfo) (result bool, err error) {
|
||||
var (
|
||||
profileInfo *model.ProfileInfo
|
||||
)
|
||||
if profileInfo, err = info.getProfileInfo(); err != nil {
|
||||
return
|
||||
}
|
||||
return profileInfo.Identification == 1, nil
|
||||
}
|
763
app/service/main/spy/service/rule_test.go
Normal file
763
app/service/main/spy/service/rule_test.go
Normal file
@ -0,0 +1,763 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"go-common/app/service/main/spy/conf"
|
||||
"go-common/app/service/main/spy/dao"
|
||||
"go-common/app/service/main/spy/model"
|
||||
"go-common/library/ecode"
|
||||
|
||||
"github.com/bouk/monkey"
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestServiceNewJudgementInfo(t *testing.T) {
|
||||
convey.Convey("NewJudgementInfo", t, func(ctx convey.C) {
|
||||
var (
|
||||
s = &Service{}
|
||||
c = context.Background()
|
||||
mid = int64(0)
|
||||
ip = ""
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
p1 := NewJudgementInfo(c, s, mid, ip)
|
||||
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(p1, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestServicegetAuditInfo(t *testing.T) {
|
||||
var (
|
||||
mid = int64(0)
|
||||
ip = ""
|
||||
ji = NewJudgementInfo(context.TODO(), s, mid, ip)
|
||||
auditInfo = &model.AuditInfo{
|
||||
Mid: mid,
|
||||
BindTel: true,
|
||||
BindMail: false,
|
||||
}
|
||||
)
|
||||
|
||||
convey.Convey("getAuditInfo", t, func(ctx convey.C) {
|
||||
var testCases = []struct {
|
||||
jiAuditInfo *model.AuditInfo
|
||||
daoAuditInfo *model.AuditInfo
|
||||
expectAuditInfo *model.AuditInfo
|
||||
}{
|
||||
{
|
||||
jiAuditInfo: auditInfo,
|
||||
daoAuditInfo: nil,
|
||||
expectAuditInfo: auditInfo,
|
||||
},
|
||||
{
|
||||
jiAuditInfo: nil,
|
||||
daoAuditInfo: auditInfo,
|
||||
expectAuditInfo: auditInfo,
|
||||
},
|
||||
{
|
||||
jiAuditInfo: nil,
|
||||
daoAuditInfo: nil,
|
||||
expectAuditInfo: nil,
|
||||
},
|
||||
}
|
||||
for idx, testCase := range testCases {
|
||||
ctx.Convey(fmt.Sprintf("Iterating Case%d", idx), func(ctx convey.C) {
|
||||
monkey.PatchInstanceMethod(reflect.TypeOf(s.dao), "AuditInfo", func(_ *dao.Dao, _ context.Context, _ int64, _ string) (*model.AuditInfo, error) {
|
||||
if testCase.daoAuditInfo == nil {
|
||||
return nil, errors.New("s.dao.AuditInfo error")
|
||||
}
|
||||
return testCase.daoAuditInfo, nil
|
||||
})
|
||||
ji.auditInfo = testCase.jiAuditInfo
|
||||
ai, err := ji.getAuditInfo()
|
||||
if testCase.expectAuditInfo == nil {
|
||||
ctx.So(err, convey.ShouldBeError)
|
||||
ctx.So(ai, convey.ShouldBeNil)
|
||||
} else {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(ai, convey.ShouldEqual, testCase.expectAuditInfo)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
func TestServicegetProfileInfo(t *testing.T) {
|
||||
var (
|
||||
mid = int64(0)
|
||||
ip = ""
|
||||
ji = NewJudgementInfo(context.TODO(), s, mid, ip)
|
||||
profileInfo = &model.ProfileInfo{
|
||||
Mid: mid,
|
||||
Identification: 0,
|
||||
}
|
||||
)
|
||||
|
||||
convey.Convey("getProfileInfo", t, func(ctx convey.C) {
|
||||
var testCases = []struct {
|
||||
jiProfileInfo *model.ProfileInfo
|
||||
daoProfileInfo *model.ProfileInfo
|
||||
expectProfileInfo *model.ProfileInfo
|
||||
}{
|
||||
{
|
||||
jiProfileInfo: profileInfo,
|
||||
daoProfileInfo: nil,
|
||||
expectProfileInfo: profileInfo,
|
||||
},
|
||||
{
|
||||
jiProfileInfo: nil,
|
||||
daoProfileInfo: profileInfo,
|
||||
expectProfileInfo: profileInfo,
|
||||
},
|
||||
{
|
||||
jiProfileInfo: nil,
|
||||
daoProfileInfo: nil,
|
||||
expectProfileInfo: nil,
|
||||
},
|
||||
}
|
||||
for idx, testCase := range testCases {
|
||||
ctx.Convey(fmt.Sprintf("Iterating Case%d", idx), func(ctx convey.C) {
|
||||
monkey.PatchInstanceMethod(reflect.TypeOf(s.dao), "ProfileInfo", func(_ *dao.Dao, _ context.Context, _ int64, _ string) (*model.ProfileInfo, error) {
|
||||
if testCase.daoProfileInfo == nil {
|
||||
return nil, errors.New("s.dao.ProfileInfo error")
|
||||
}
|
||||
return testCase.daoProfileInfo, nil
|
||||
})
|
||||
ji.profileInfo = testCase.jiProfileInfo
|
||||
pi, err := ji.getProfileInfo()
|
||||
if testCase.expectProfileInfo == nil {
|
||||
ctx.So(err, convey.ShouldBeError)
|
||||
ctx.So(pi, convey.ShouldBeNil)
|
||||
} else {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(pi, convey.ShouldEqual, testCase.expectProfileInfo)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
func TestServicegetTelRiskInfo(t *testing.T) {
|
||||
var (
|
||||
mid = int64(0)
|
||||
ip = ""
|
||||
ji = NewJudgementInfo(context.TODO(), s, mid, ip)
|
||||
telRiskLevel = int8(1)
|
||||
restoreEventHistory = &model.UserEventHistory{
|
||||
Mid: mid,
|
||||
EventID: 1024,
|
||||
}
|
||||
telRiskInfo = &model.TelRiskInfo{
|
||||
TelRiskLevel: telRiskLevel,
|
||||
RestoreHistory: restoreEventHistory,
|
||||
}
|
||||
)
|
||||
|
||||
convey.Convey("getTelRiskInfo", t, func(ctx convey.C) {
|
||||
var testCases = []struct {
|
||||
jiTelRiskInfo *model.TelRiskInfo
|
||||
daoTelRiskLevel int8
|
||||
daoRestoreEventHistory *model.UserEventHistory
|
||||
expectTelRiskInfo *model.TelRiskInfo
|
||||
}{
|
||||
{
|
||||
jiTelRiskInfo: telRiskInfo,
|
||||
daoTelRiskLevel: int8(0),
|
||||
daoRestoreEventHistory: nil,
|
||||
expectTelRiskInfo: telRiskInfo,
|
||||
},
|
||||
{
|
||||
jiTelRiskInfo: nil,
|
||||
daoTelRiskLevel: telRiskLevel,
|
||||
daoRestoreEventHistory: restoreEventHistory,
|
||||
expectTelRiskInfo: telRiskInfo,
|
||||
},
|
||||
{
|
||||
jiTelRiskInfo: nil,
|
||||
daoTelRiskLevel: int8(0),
|
||||
daoRestoreEventHistory: nil,
|
||||
expectTelRiskInfo: nil,
|
||||
},
|
||||
}
|
||||
for idx, testCase := range testCases {
|
||||
ctx.Convey(fmt.Sprintf("Iterating Case%d", idx), func(ctx convey.C) {
|
||||
monkey.PatchInstanceMethod(reflect.TypeOf(s.dao), "TelRiskLevel", func(_ *dao.Dao, _ context.Context, _ int64) (int8, error) {
|
||||
return testCase.daoTelRiskLevel, nil
|
||||
})
|
||||
monkey.PatchInstanceMethod(reflect.TypeOf(s.dao), "Event", func(_ *dao.Dao, _ context.Context, _ string) (*model.Event, error) {
|
||||
return &model.Event{
|
||||
ID: mid,
|
||||
}, nil
|
||||
})
|
||||
|
||||
monkey.PatchInstanceMethod(reflect.TypeOf(s.dao), "EventHistoryByMidAndEvent", func(_ *dao.Dao, _ context.Context, _ int64, _ int64) (*model.UserEventHistory, error) {
|
||||
if testCase.daoRestoreEventHistory == nil {
|
||||
return nil, errors.New("s.dao.EventHistoryByMidAndEvent error")
|
||||
}
|
||||
return testCase.daoRestoreEventHistory, nil
|
||||
})
|
||||
|
||||
ji.telRiskInfo = testCase.jiTelRiskInfo
|
||||
tri, err := ji.getTelRiskInfo()
|
||||
if testCase.expectTelRiskInfo == nil {
|
||||
ctx.So(err, convey.ShouldBeError)
|
||||
ctx.So(tri, convey.ShouldBeNil)
|
||||
} else {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(tri, convey.ShouldResemble, testCase.expectTelRiskInfo)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
func TestServicegetRulesMap(t *testing.T) {
|
||||
convey.Convey("getRulesMap", t, func(ctx convey.C) {
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
p1 := s.getRulesMap()
|
||||
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(p1, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestServicegetJudgementInfo(t *testing.T) {
|
||||
convey.Convey("getJudgementInfo", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(0)
|
||||
ip = ""
|
||||
)
|
||||
convey.Convey("getJudgementInfo", func(ctx convey.C) {
|
||||
ji, err := s.getJudgementInfo(c, mid, ip)
|
||||
ctx.So(ji, convey.ShouldNotBeNil)
|
||||
ctx.So(ji.auditInfo, convey.ShouldBeNil)
|
||||
ctx.So(ji.profileInfo, convey.ShouldBeNil)
|
||||
ctx.So(ji.telRiskInfo, convey.ShouldBeNil)
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
func TestServicegetRuleFunc(t *testing.T) {
|
||||
convey.Convey("getRuleFunc", t, func(ctx convey.C) {
|
||||
var testCases = []struct {
|
||||
rule Rule
|
||||
expectedResp RuleFunc
|
||||
}{
|
||||
{
|
||||
rule: _telIsBound,
|
||||
expectedResp: telIsBound,
|
||||
},
|
||||
{
|
||||
rule: "Anything",
|
||||
expectedResp: nil,
|
||||
},
|
||||
}
|
||||
for idx, testCase := range testCases {
|
||||
ctx.Convey(fmt.Sprintf("Iterating Case%d..,", idx), func(ctx convey.C) {
|
||||
ruleFunc, err := s.getRuleFunc(testCase.rule)
|
||||
if testCase.expectedResp == nil {
|
||||
ctx.So(err, convey.ShouldBeError, ecode.SpyRuleNotExist)
|
||||
ctx.So(ruleFunc, convey.ShouldBeNil)
|
||||
} else {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(ruleFunc, convey.ShouldEqual, testCase.expectedResp)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
func TestServiceiterRules(t *testing.T) {
|
||||
var (
|
||||
rules = Rules{
|
||||
_telIsBound, _mailIsBound,
|
||||
}
|
||||
)
|
||||
|
||||
convey.Convey("iterRules", t, func(ctx convey.C) {
|
||||
var testCases = []struct {
|
||||
judgementInfo *JudgementInfo
|
||||
expectRes IterState
|
||||
}{
|
||||
{
|
||||
judgementInfo: &JudgementInfo{
|
||||
auditInfo: &model.AuditInfo{
|
||||
BindTel: true,
|
||||
BindMail: true,
|
||||
},
|
||||
},
|
||||
expectRes: IterSuccess,
|
||||
},
|
||||
{
|
||||
judgementInfo: &JudgementInfo{
|
||||
auditInfo: &model.AuditInfo{
|
||||
BindTel: true,
|
||||
BindMail: false,
|
||||
},
|
||||
},
|
||||
expectRes: IterFail,
|
||||
},
|
||||
}
|
||||
for idx, testCase := range testCases {
|
||||
ctx.Convey(fmt.Sprintf("Iterating Case%d...", idx), func(ctx convey.C) {
|
||||
state, err := s.iterRules(testCase.judgementInfo, rules)
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(state, convey.ShouldEqual, testCase.expectRes)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestServicegetBaseScoreFactor(t *testing.T) {
|
||||
convey.Convey("getBaseScoreFactor", t, func(ctx convey.C) {
|
||||
var (
|
||||
testCases = []struct {
|
||||
judgementInfo *JudgementInfo
|
||||
expectRest FactoryMeta
|
||||
}{
|
||||
{
|
||||
judgementInfo: &JudgementInfo{
|
||||
auditInfo: &model.AuditInfo{
|
||||
BindTel: false,
|
||||
BindMail: true,
|
||||
},
|
||||
telRiskInfo: &model.TelRiskInfo{
|
||||
RestoreHistory: &model.UserEventHistory{
|
||||
Mid: int64(0),
|
||||
},
|
||||
},
|
||||
},
|
||||
expectRest: FactoryMeta{
|
||||
serviceName: _defaultService,
|
||||
eventName: conf.Conf.Property.Event.BindMailAndIdenUnknown,
|
||||
riskLevel: _defaultRiskLevel,
|
||||
},
|
||||
},
|
||||
{
|
||||
judgementInfo: &JudgementInfo{
|
||||
auditInfo: &model.AuditInfo{
|
||||
BindTel: false,
|
||||
BindMail: false,
|
||||
},
|
||||
profileInfo: &model.ProfileInfo{
|
||||
Identification: 1,
|
||||
},
|
||||
telRiskInfo: &model.TelRiskInfo{
|
||||
RestoreHistory: &model.UserEventHistory{
|
||||
Mid: int64(0),
|
||||
},
|
||||
},
|
||||
},
|
||||
expectRest: FactoryMeta{},
|
||||
},
|
||||
}
|
||||
)
|
||||
for idx, testCase := range testCases {
|
||||
ctx.Convey(fmt.Sprintf("Iterating Case%d...", idx), func(ctx convey.C) {
|
||||
meta, err := s.getBaseScoreFactor(testCase.judgementInfo)
|
||||
if testCase.expectRest == (FactoryMeta{}) {
|
||||
ctx.So(err, convey.ShouldBeError, ecode.SpyRulesNotMatch)
|
||||
ctx.So(meta, convey.ShouldResemble, FactoryMeta{})
|
||||
} else {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(meta, convey.ShouldResemble, testCase.expectRest)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestServicetelIsBound(t *testing.T) {
|
||||
convey.Convey("telIsBound", t, func(ctx convey.C) {
|
||||
var testCases = []struct {
|
||||
judgementInfo *JudgementInfo
|
||||
expectResp bool
|
||||
}{
|
||||
{
|
||||
judgementInfo: &JudgementInfo{
|
||||
auditInfo: &model.AuditInfo{
|
||||
BindTel: true,
|
||||
},
|
||||
},
|
||||
expectResp: true,
|
||||
}, {
|
||||
judgementInfo: &JudgementInfo{
|
||||
auditInfo: &model.AuditInfo{
|
||||
BindTel: false,
|
||||
},
|
||||
},
|
||||
expectResp: false,
|
||||
},
|
||||
}
|
||||
for idx, testCase := range testCases {
|
||||
ctx.Convey(fmt.Sprintf("Iterating Case%d...", idx), func(ctx convey.C) {
|
||||
result, err := telIsBound(testCase.judgementInfo)
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(result, convey.ShouldEqual, testCase.expectResp)
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
func TestServicetelIsNotBound(t *testing.T) {
|
||||
convey.Convey("telIsNotBound", t, func(ctx convey.C) {
|
||||
var testCases = []struct {
|
||||
judgementInfo *JudgementInfo
|
||||
expectResp bool
|
||||
}{
|
||||
{
|
||||
judgementInfo: &JudgementInfo{
|
||||
auditInfo: &model.AuditInfo{
|
||||
BindTel: true,
|
||||
},
|
||||
},
|
||||
expectResp: false,
|
||||
}, {
|
||||
judgementInfo: &JudgementInfo{
|
||||
auditInfo: &model.AuditInfo{
|
||||
BindTel: false,
|
||||
},
|
||||
},
|
||||
expectResp: true,
|
||||
},
|
||||
}
|
||||
for idx, testCase := range testCases {
|
||||
ctx.Convey(fmt.Sprintf("Iterating Case%d...", idx), func(ctx convey.C) {
|
||||
result, err := telIsNotBound(testCase.judgementInfo)
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(result, convey.ShouldEqual, testCase.expectResp)
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
func TestServicetelIsLowRisk(t *testing.T) {
|
||||
convey.Convey("telIsLowRisk", t, func(ctx convey.C) {
|
||||
var testCases = []struct {
|
||||
judgementInfo *JudgementInfo
|
||||
expectResp bool
|
||||
}{
|
||||
{
|
||||
judgementInfo: &JudgementInfo{
|
||||
telRiskInfo: &model.TelRiskInfo{
|
||||
TelRiskLevel: dao.TelRiskLevelLow,
|
||||
RestoreHistory: nil,
|
||||
},
|
||||
},
|
||||
expectResp: true,
|
||||
},
|
||||
{
|
||||
judgementInfo: &JudgementInfo{
|
||||
telRiskInfo: &model.TelRiskInfo{
|
||||
TelRiskLevel: dao.TelRiskLevelHigh,
|
||||
RestoreHistory: &model.UserEventHistory{
|
||||
Mid: int64(0),
|
||||
},
|
||||
},
|
||||
},
|
||||
expectResp: true,
|
||||
},
|
||||
{
|
||||
judgementInfo: &JudgementInfo{
|
||||
telRiskInfo: &model.TelRiskInfo{
|
||||
TelRiskLevel: dao.TelRiskLevelHigh,
|
||||
RestoreHistory: nil,
|
||||
},
|
||||
},
|
||||
expectResp: false,
|
||||
},
|
||||
{
|
||||
judgementInfo: &JudgementInfo{
|
||||
telRiskInfo: &model.TelRiskInfo{
|
||||
TelRiskLevel: dao.TelRiskLevelHigh,
|
||||
RestoreHistory: nil,
|
||||
UnicomGiftState: 1,
|
||||
},
|
||||
},
|
||||
expectResp: true,
|
||||
},
|
||||
}
|
||||
for idx, testCase := range testCases {
|
||||
ctx.Convey(fmt.Sprintf("Iterating Case%d...", idx), func(ctx convey.C) {
|
||||
result, err := telIsLowRisk(testCase.judgementInfo)
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(result, convey.ShouldEqual, testCase.expectResp)
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
func TestServicetelIsMediumRisk(t *testing.T) {
|
||||
convey.Convey("telIsMediumRisk", t, func(ctx convey.C) {
|
||||
var testCases = []struct {
|
||||
judgementInfo *JudgementInfo
|
||||
expectResp bool
|
||||
}{
|
||||
{
|
||||
judgementInfo: &JudgementInfo{
|
||||
telRiskInfo: &model.TelRiskInfo{
|
||||
TelRiskLevel: dao.TelRiskLevelMedium,
|
||||
RestoreHistory: nil,
|
||||
},
|
||||
},
|
||||
expectResp: true,
|
||||
},
|
||||
{
|
||||
judgementInfo: &JudgementInfo{
|
||||
telRiskInfo: &model.TelRiskInfo{
|
||||
TelRiskLevel: dao.TelRiskLevelMedium,
|
||||
RestoreHistory: &model.UserEventHistory{
|
||||
Mid: int64(0),
|
||||
},
|
||||
},
|
||||
},
|
||||
expectResp: false,
|
||||
},
|
||||
}
|
||||
for idx, testCase := range testCases {
|
||||
ctx.Convey(fmt.Sprintf("Iterating Case%d...", idx), func(ctx convey.C) {
|
||||
result, err := telIsMediumRisk(testCase.judgementInfo)
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(result, convey.ShouldEqual, testCase.expectResp)
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
func TestServicetelIsHighRisk(t *testing.T) {
|
||||
convey.Convey("telIsHighRisk", t, func(ctx convey.C) {
|
||||
var testCases = []struct {
|
||||
judgementInfo *JudgementInfo
|
||||
expectResp bool
|
||||
}{
|
||||
{
|
||||
judgementInfo: &JudgementInfo{
|
||||
telRiskInfo: &model.TelRiskInfo{
|
||||
TelRiskLevel: dao.TelRiskLevelHigh,
|
||||
RestoreHistory: nil,
|
||||
},
|
||||
},
|
||||
expectResp: true,
|
||||
},
|
||||
{
|
||||
judgementInfo: &JudgementInfo{
|
||||
telRiskInfo: &model.TelRiskInfo{
|
||||
TelRiskLevel: dao.TelRiskLevelHigh,
|
||||
RestoreHistory: nil,
|
||||
UnicomGiftState: 1,
|
||||
},
|
||||
},
|
||||
expectResp: false,
|
||||
},
|
||||
{
|
||||
judgementInfo: &JudgementInfo{
|
||||
telRiskInfo: &model.TelRiskInfo{
|
||||
TelRiskLevel: dao.TelRiskLevelMedium,
|
||||
},
|
||||
},
|
||||
expectResp: false,
|
||||
},
|
||||
}
|
||||
for idx, testCase := range testCases {
|
||||
ctx.Convey(fmt.Sprintf("Iterating Case%d...", idx), func(ctx convey.C) {
|
||||
result, err := telIsHighRisk(testCase.judgementInfo)
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(result, convey.ShouldEqual, testCase.expectResp)
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestServicetelIsUnknownRisk(t *testing.T) {
|
||||
|
||||
convey.Convey("telIsUnknownRisk", t, func(ctx convey.C) {
|
||||
var testCases = []struct {
|
||||
judgementInfo *JudgementInfo
|
||||
expectResp bool
|
||||
}{
|
||||
{
|
||||
judgementInfo: &JudgementInfo{
|
||||
telRiskInfo: &model.TelRiskInfo{
|
||||
TelRiskLevel: dao.TelRiskLevelUnknown,
|
||||
RestoreHistory: nil,
|
||||
},
|
||||
},
|
||||
expectResp: true,
|
||||
},
|
||||
{
|
||||
judgementInfo: &JudgementInfo{
|
||||
telRiskInfo: &model.TelRiskInfo{
|
||||
TelRiskLevel: dao.TelRiskLevelMedium,
|
||||
},
|
||||
},
|
||||
expectResp: false,
|
||||
},
|
||||
}
|
||||
for idx, testCase := range testCases {
|
||||
ctx.Convey(fmt.Sprintf("Iterating Case%d...", idx), func(ctx convey.C) {
|
||||
result, err := telIsUnknownRisk(testCase.judgementInfo)
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(result, convey.ShouldEqual, testCase.expectResp)
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestServicemailIsBound(t *testing.T) {
|
||||
convey.Convey("mailIsBound", t, func(ctx convey.C) {
|
||||
var testCases = []struct {
|
||||
judgementInfo *JudgementInfo
|
||||
expectResp bool
|
||||
}{
|
||||
{
|
||||
judgementInfo: &JudgementInfo{
|
||||
auditInfo: &model.AuditInfo{
|
||||
BindMail: true,
|
||||
},
|
||||
},
|
||||
expectResp: true,
|
||||
}, {
|
||||
judgementInfo: &JudgementInfo{
|
||||
auditInfo: &model.AuditInfo{
|
||||
BindMail: false,
|
||||
},
|
||||
},
|
||||
expectResp: false,
|
||||
},
|
||||
}
|
||||
for idx, testCase := range testCases {
|
||||
ctx.Convey(fmt.Sprintf("Iterating Case%d...", idx), func(ctx convey.C) {
|
||||
result, err := mailIsBound(testCase.judgementInfo)
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(result, convey.ShouldEqual, testCase.expectResp)
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestServicemailIsNotBound(t *testing.T) {
|
||||
convey.Convey("mailIsNotBound", t, func(ctx convey.C) {
|
||||
var testCases = []struct {
|
||||
judgementInfo *JudgementInfo
|
||||
expectResp bool
|
||||
}{
|
||||
{
|
||||
judgementInfo: &JudgementInfo{
|
||||
auditInfo: &model.AuditInfo{
|
||||
BindMail: true,
|
||||
},
|
||||
},
|
||||
expectResp: false,
|
||||
}, {
|
||||
judgementInfo: &JudgementInfo{
|
||||
auditInfo: &model.AuditInfo{
|
||||
BindMail: false,
|
||||
},
|
||||
},
|
||||
expectResp: true,
|
||||
},
|
||||
}
|
||||
for idx, testCase := range testCases {
|
||||
ctx.Convey(fmt.Sprintf("Iterating Case%d...", idx), func(ctx convey.C) {
|
||||
result, err := mailIsNotBound(testCase.judgementInfo)
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(result, convey.ShouldEqual, testCase.expectResp)
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestServiceidenIsNotAuthed(t *testing.T) {
|
||||
convey.Convey("idenIsNotAuthed", t, func(ctx convey.C) {
|
||||
var testCases = []struct {
|
||||
judgementInfo *JudgementInfo
|
||||
expectResp bool
|
||||
}{
|
||||
{
|
||||
judgementInfo: &JudgementInfo{
|
||||
profileInfo: &model.ProfileInfo{
|
||||
Identification: 0,
|
||||
},
|
||||
},
|
||||
expectResp: true,
|
||||
}, {
|
||||
judgementInfo: &JudgementInfo{
|
||||
profileInfo: &model.ProfileInfo{
|
||||
Identification: 1,
|
||||
},
|
||||
},
|
||||
expectResp: false,
|
||||
},
|
||||
}
|
||||
for idx, testCase := range testCases {
|
||||
ctx.Convey(fmt.Sprintf("Iterating Case%d...", idx), func(ctx convey.C) {
|
||||
result, err := idenIsNotAuthed(testCase.judgementInfo)
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(result, convey.ShouldEqual, testCase.expectResp)
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestServiceidenIsAuthed(t *testing.T) {
|
||||
convey.Convey("idenIsAuthed", t, func(ctx convey.C) {
|
||||
var testCases = []struct {
|
||||
judgementInfo *JudgementInfo
|
||||
expectResp bool
|
||||
}{
|
||||
{
|
||||
judgementInfo: &JudgementInfo{
|
||||
profileInfo: &model.ProfileInfo{
|
||||
Identification: 0,
|
||||
},
|
||||
},
|
||||
expectResp: false,
|
||||
}, {
|
||||
judgementInfo: &JudgementInfo{
|
||||
profileInfo: &model.ProfileInfo{
|
||||
Identification: 1,
|
||||
},
|
||||
},
|
||||
expectResp: true,
|
||||
},
|
||||
}
|
||||
for idx, testCase := range testCases {
|
||||
ctx.Convey(fmt.Sprintf("Iterating Case%d...", idx), func(ctx convey.C) {
|
||||
result, err := idenIsAuthed(testCase.judgementInfo)
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(result, convey.ShouldEqual, testCase.expectResp)
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
}
|
253
app/service/main/spy/service/service.go
Normal file
253
app/service/main/spy/service/service.go
Normal file
@ -0,0 +1,253 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
accrpc "go-common/app/service/main/account/rpc/client"
|
||||
"go-common/app/service/main/spy/conf"
|
||||
"go-common/app/service/main/spy/dao"
|
||||
"go-common/app/service/main/spy/model"
|
||||
"go-common/library/log"
|
||||
"go-common/library/stat/prom"
|
||||
)
|
||||
|
||||
const (
|
||||
_score = 100
|
||||
)
|
||||
|
||||
// Service biz service def.
|
||||
type Service struct {
|
||||
c *conf.Config
|
||||
dao *dao.Dao
|
||||
missch chan func()
|
||||
scorech chan func()
|
||||
infomissch chan func()
|
||||
spyConfig map[string]interface{}
|
||||
configLoadTick time.Duration
|
||||
promBaseScore *prom.Prom
|
||||
promEventScore *prom.Prom
|
||||
promBlockInfo *prom.Prom
|
||||
accRPC *accrpc.Service3
|
||||
allEventName map[int64]string
|
||||
loadEventTick time.Duration
|
||||
}
|
||||
|
||||
// New new a Service and return.
|
||||
func New(c *conf.Config) (s *Service) {
|
||||
s = &Service{
|
||||
c: c,
|
||||
dao: dao.New(c),
|
||||
missch: make(chan func(), 10240),
|
||||
scorech: make(chan func(), 10240),
|
||||
infomissch: make(chan func(), 10240),
|
||||
spyConfig: make(map[string]interface{}),
|
||||
configLoadTick: time.Duration(c.Property.ConfigLoadTick),
|
||||
promBaseScore: prom.New().WithCounter("spy_basescore", []string{"name"}),
|
||||
promEventScore: prom.New().WithCounter("spy_eventscore", []string{"name"}),
|
||||
promBlockInfo: prom.New().WithCounter("spy_block_info", []string{"name"}),
|
||||
accRPC: accrpc.New3(c.RPC.Account),
|
||||
allEventName: make(map[int64]string),
|
||||
loadEventTick: time.Duration(c.Property.LoadEventTick),
|
||||
}
|
||||
if err := s.loadSystemConfig(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
s.loadeventname()
|
||||
|
||||
go s.missproc()
|
||||
go s.infomissproc()
|
||||
go s.loadconfigproc()
|
||||
go s.loadeventproc()
|
||||
go s.updatescoreproc()
|
||||
return s
|
||||
}
|
||||
|
||||
// Ping check dao health.
|
||||
func (s *Service) Ping(c context.Context) (err error) {
|
||||
return s.dao.Ping(c)
|
||||
}
|
||||
|
||||
// Close close all dao.
|
||||
func (s *Service) Close() {
|
||||
s.dao.Close()
|
||||
}
|
||||
|
||||
func (s *Service) missproc() {
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("service.missproc panic(%v)", x)
|
||||
go s.missproc()
|
||||
log.Info("service.missproc recover")
|
||||
}
|
||||
}()
|
||||
for {
|
||||
f := <-s.missch
|
||||
f()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) mission(f func()) {
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("service.mission panic(%v)", x)
|
||||
}
|
||||
}()
|
||||
select {
|
||||
case s.missch <- f:
|
||||
default:
|
||||
log.Error("service.missproc chan full")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) updatescoreproc() {
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("service.updatescoreproc panic(%v)", x)
|
||||
go s.updatescoreproc()
|
||||
log.Info("service.updatescoreproc recover")
|
||||
}
|
||||
}()
|
||||
for {
|
||||
f := <-s.scorech
|
||||
f()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) updatescore(f func()) {
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("service.updatescore panic(%v)", x)
|
||||
}
|
||||
}()
|
||||
select {
|
||||
case s.scorech <- f:
|
||||
default:
|
||||
log.Error("service.updatescore chan full")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) infomissproc() {
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("service.infomissproc panic(%v)", x)
|
||||
go s.infomissproc()
|
||||
log.Info("service.infomissproc recover")
|
||||
}
|
||||
}()
|
||||
for {
|
||||
f := <-s.infomissch
|
||||
f()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) infomission(f func()) {
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("service.infomission panic(%v)", x)
|
||||
}
|
||||
}()
|
||||
select {
|
||||
case s.infomissch <- f:
|
||||
default:
|
||||
log.Error("service.infomissch chan full")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) loadconfigproc() {
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("service.loadconfig panic(%v)", x)
|
||||
}
|
||||
}()
|
||||
for {
|
||||
time.Sleep(s.configLoadTick)
|
||||
s.loadSystemConfig()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) loadSystemConfig() (err error) {
|
||||
var (
|
||||
cdb map[string]string
|
||||
)
|
||||
cdb, err = s.dao.Configs(context.TODO())
|
||||
if err != nil {
|
||||
log.Error("sys config db get data err(%v)", err)
|
||||
return
|
||||
}
|
||||
if len(cdb) == 0 {
|
||||
err = errors.New("sys config no data")
|
||||
return
|
||||
}
|
||||
cs := make(map[string]interface{}, len(cdb))
|
||||
for k, v := range cdb {
|
||||
switch k {
|
||||
case model.LimitBlockCount:
|
||||
t, err1 := strconv.ParseInt(v, 10, 64)
|
||||
if err1 != nil {
|
||||
log.Error("sys config err(%s,%v,%v)", model.LimitBlockCount, t, err1)
|
||||
err = err1
|
||||
return
|
||||
}
|
||||
cs[k] = t
|
||||
case model.LessBlockScore:
|
||||
tmp, err1 := strconv.ParseInt(v, 10, 8)
|
||||
if err1 != nil {
|
||||
log.Error("sys config err(%s,%v,%v)", model.LessBlockScore, tmp, err1)
|
||||
err = err1
|
||||
return
|
||||
}
|
||||
cs[k] = int8(tmp)
|
||||
case model.AutoBlock:
|
||||
tmp, err1 := strconv.ParseInt(v, 10, 8)
|
||||
if err1 != nil {
|
||||
log.Error("sys config err(%s,%v,%v)", model.AutoBlock, tmp, err1)
|
||||
err = err1
|
||||
return
|
||||
}
|
||||
cs[k] = int8(tmp)
|
||||
default:
|
||||
cs[k] = v
|
||||
}
|
||||
}
|
||||
s.spyConfig = cs
|
||||
log.Info("loadSystemConfig success(%v)", cs)
|
||||
return
|
||||
}
|
||||
|
||||
//Config get config.
|
||||
func (s *Service) Config(key string) (interface{}, bool) {
|
||||
if s.spyConfig == nil {
|
||||
return nil, false
|
||||
}
|
||||
v, ok := s.spyConfig[key]
|
||||
return v, ok
|
||||
}
|
||||
|
||||
func (s *Service) loadeventname() (err error) {
|
||||
var (
|
||||
c = context.Background()
|
||||
es []*model.Event
|
||||
)
|
||||
es, err = s.dao.AllEvent(c)
|
||||
if err != nil {
|
||||
log.Error("loadeventname allevent error(%v)", err)
|
||||
return
|
||||
}
|
||||
tmp := make(map[int64]string, len(es))
|
||||
for _, e := range es {
|
||||
tmp[e.ID] = e.NickName
|
||||
}
|
||||
s.allEventName = tmp
|
||||
log.Info("loadeventname (%v) load success", tmp)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) loadeventproc() {
|
||||
for {
|
||||
time.Sleep(s.loadEventTick)
|
||||
s.loadeventname()
|
||||
}
|
||||
}
|
195
app/service/main/spy/service/service_test.go
Normal file
195
app/service/main/spy/service/service_test.go
Normal file
@ -0,0 +1,195 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"go-common/app/service/main/spy/conf"
|
||||
"go-common/app/service/main/spy/model"
|
||||
"go-common/library/cache/redis"
|
||||
"go-common/library/log"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
var (
|
||||
s *Service
|
||||
c = context.TODO()
|
||||
// 35858 : bind nothing
|
||||
// 22333 : bind mail only
|
||||
// 46333 : bind both
|
||||
// 27515232 : bind both
|
||||
mids = []int64{27515232}
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
flag.Parse()
|
||||
var err error
|
||||
if err = conf.Init(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
log.Init(conf.Conf.Log)
|
||||
if s == nil {
|
||||
s = New(conf.Conf)
|
||||
}
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
func TestDelCache(t *testing.T) {
|
||||
var err error
|
||||
for _, mid := range mids {
|
||||
if err = s.dao.DelInfoCache(c, mid); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserInfo(t *testing.T) {
|
||||
var (
|
||||
ip = "127.0.0.1"
|
||||
err error
|
||||
ui *model.UserInfo
|
||||
)
|
||||
|
||||
for _, mid := range mids {
|
||||
if ui, err = s.UserInfo(c, mid, ip); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if ui == nil {
|
||||
t.Fatal()
|
||||
}
|
||||
t.Logf("userinfo (%+v)", ui)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleEvent(t *testing.T) {
|
||||
var (
|
||||
arg struct {
|
||||
Test string
|
||||
}
|
||||
err error
|
||||
ui *model.UserInfo
|
||||
preEventScore int8
|
||||
preBaseScore int8
|
||||
fac *model.Factor
|
||||
)
|
||||
arg.Test = "test arg"
|
||||
|
||||
for _, mid := range mids {
|
||||
var fakeEventMsg = &model.EventMessage{
|
||||
IP: "127.0.0.1",
|
||||
Service: "spy_service",
|
||||
Event: "bind_nothing",
|
||||
ActiveMid: mid,
|
||||
TargetMid: mid,
|
||||
Result: "test_result",
|
||||
Effect: "test_effect",
|
||||
RiskLevel: 1,
|
||||
}
|
||||
fakeEventMsg.Args = arg
|
||||
if ui, err = s.UserInfo(c, fakeEventMsg.ActiveMid, fakeEventMsg.IP); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if ui == nil {
|
||||
t.Fatal()
|
||||
}
|
||||
preBaseScore = ui.BaseScore
|
||||
preEventScore = ui.EventScore
|
||||
|
||||
if err = s.HandleEvent(c, fakeEventMsg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if ui, err = s.UserInfo(c, fakeEventMsg.ActiveMid, fakeEventMsg.IP); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if ui.State == model.StateBlock {
|
||||
continue
|
||||
}
|
||||
if ui.BaseScore != preBaseScore {
|
||||
t.Fatal()
|
||||
}
|
||||
if fac, err = s.factor(c, fakeEventMsg.Service, fakeEventMsg.Event, 1); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if ui.EventScore != int8(float64(preEventScore)*fac.FactorVal) {
|
||||
t.Fatal()
|
||||
}
|
||||
if ui.Score != int8(float64(ui.BaseScore)*float64(ui.EventScore)/float64(100)) {
|
||||
t.Fatal()
|
||||
}
|
||||
if err = s.dao.DelInfoCache(c, mid); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
time.Sleep(time.Second * 1)
|
||||
}
|
||||
|
||||
func CleanCache() {
|
||||
pool := redis.NewPool(conf.Conf.Redis.Config)
|
||||
pool.Get(c).Do("FLUSHDB")
|
||||
}
|
||||
|
||||
func init() {
|
||||
dir, _ := filepath.Abs("../cmd/spy-service-test.toml")
|
||||
flag.Set("conf", dir)
|
||||
conf.Init()
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
|
||||
func WithService(f func(s *Service)) func() {
|
||||
return func() {
|
||||
Reset(func() { CleanCache() })
|
||||
f(s)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_LoadSystemConfig(t *testing.T) {
|
||||
Convey("Test_LoadSystemConfig had data", t, WithService(func(s *Service) {
|
||||
fmt.Println(s.spyConfig)
|
||||
So(s.spyConfig, ShouldContainKey, model.LimitBlockCount)
|
||||
So(s.spyConfig, ShouldContainKey, model.LessBlockScore)
|
||||
So(s.spyConfig, ShouldContainKey, model.AutoBlock)
|
||||
}))
|
||||
}
|
||||
|
||||
// go test -test.v -test.run TestStatList
|
||||
func TestStatList(t *testing.T) {
|
||||
var (
|
||||
mid int64 = 1
|
||||
id int64 = 1
|
||||
)
|
||||
Convey("TestStatList ", t, WithService(func(s *Service) {
|
||||
stat, err := s.StatByID(c, mid, id)
|
||||
So(err, ShouldBeNil)
|
||||
fmt.Println("stat", stat)
|
||||
}))
|
||||
}
|
||||
|
||||
// go test -test.v -test.run TestTelLevel
|
||||
func TestTelLevel(t *testing.T) {
|
||||
var (
|
||||
mid int64 = 15555180
|
||||
)
|
||||
Convey("TestTelLevel no err", t, WithService(func(s *Service) {
|
||||
level, err := s.TelRiskLevel(c, mid, "127.0.0.1")
|
||||
fmt.Println("level", level)
|
||||
So(err, ShouldBeNil)
|
||||
}))
|
||||
}
|
||||
|
||||
// go test -test.v -test.run TestTelLevel
|
||||
func TestService_StatByIDGroupEvent(t *testing.T) {
|
||||
var (
|
||||
mid int64 = 7455
|
||||
)
|
||||
Convey("StatByIDGroupEvent no err", t, WithService(func(s *Service) {
|
||||
res, err := s.StatByIDGroupEvent(c, mid, 0)
|
||||
So(res, ShouldNotBeNil)
|
||||
So(err, ShouldBeNil)
|
||||
}))
|
||||
}
|
682
app/service/main/spy/service/spy.go
Normal file
682
app/service/main/spy/service/spy.go
Normal file
@ -0,0 +1,682 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"go-common/app/service/main/spy/conf"
|
||||
"go-common/app/service/main/spy/dao"
|
||||
"go-common/app/service/main/spy/model"
|
||||
spy "go-common/app/service/main/spy/model"
|
||||
"go-common/library/database/sql"
|
||||
"go-common/library/ecode"
|
||||
"go-common/library/log"
|
||||
"go-common/library/net/ip"
|
||||
"go-common/library/net/metadata"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// HandleEvent handle spy-event.
|
||||
func (s *Service) HandleEvent(c context.Context, eventMsg *model.EventMessage) (err error) {
|
||||
var (
|
||||
factor *model.Factor
|
||||
mid = eventMsg.ActiveMid
|
||||
)
|
||||
ui, err := s.UserInfo(c, mid, ip.InternalIP())
|
||||
if err != nil {
|
||||
log.Error("s.UserInfo(%d) err(%v)", mid, err)
|
||||
return
|
||||
}
|
||||
// if blocked already , return
|
||||
// if ui.State == model.StateBlock {
|
||||
// return
|
||||
// }
|
||||
// get factor by servieName , eventName , riskLevel
|
||||
if factor, err = s.factor(c, eventMsg.Service, eventMsg.Event, eventMsg.RiskLevel); err != nil {
|
||||
log.Error("s.factor(%s, %s, %d) error(%v)", eventMsg.Service, eventMsg.Event, eventMsg.RiskLevel, err)
|
||||
return
|
||||
}
|
||||
s.promEventScore.Incr("change")
|
||||
// mark eventScore decrease
|
||||
if factor.FactorVal < 1.0 {
|
||||
s.promEventScore.Incr("decrease")
|
||||
}
|
||||
// calc all score
|
||||
ui.EventScore = s.calcFactorScore(ui.EventScore, factor)
|
||||
ui.Score = s.calcScore(ui.BaseScore, ui.EventScore)
|
||||
if err = s.updateEventInfo(c, ui, factor, eventMsg); err != nil {
|
||||
log.Error("s.updateEventInfo(%v, %v, %v) error(%v)", ui, factor, eventMsg, err)
|
||||
return
|
||||
}
|
||||
s.updateInfoCache(c, ui)
|
||||
// check punishment.
|
||||
_, err = s.BlockFilter(c, ui)
|
||||
if err != nil {
|
||||
log.Error("s.BlockFilter(%v) error(%v)", ui, err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) updateEventInfo(c context.Context, ui *model.UserInfo, factor *model.Factor, eventMsg *model.EventMessage) (err error) {
|
||||
var (
|
||||
tx *sql.Tx
|
||||
)
|
||||
if tx, err = s.dao.BeginTran(c); err != nil {
|
||||
log.Error("s.dao.BeginTran() err(%v)", err)
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if err1 := tx.Rollback(); err1 != nil {
|
||||
log.Error("tx.Rollback() error(%v)", err1)
|
||||
}
|
||||
return
|
||||
}
|
||||
if err = tx.Commit(); err != nil {
|
||||
log.Error("tx.Commit() error(%v)", err)
|
||||
}
|
||||
}()
|
||||
// update info.
|
||||
if err = s.dao.TxUpdateInfo(c, tx, ui); err != nil {
|
||||
log.Error("s.dao.UpsertInfo(%v) error(%v)", ui, err)
|
||||
return
|
||||
}
|
||||
if err = s.txAddHistory(c, tx, ui, factor, eventMsg); err != nil {
|
||||
log.Error("s.addHistory(%v, %v, %v) error(%v)", ui, factor, eventMsg, err)
|
||||
return
|
||||
}
|
||||
s.dao.PubScoreChange(c, ui.Mid, &model.ScoreChange{
|
||||
Mid: ui.Mid,
|
||||
Score: ui.Score,
|
||||
TS: time.Now().Unix(),
|
||||
Reason: eventMsg.Service,
|
||||
RiskLevel: eventMsg.RiskLevel,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// factor get facory by serviceName , eventName , riskLevel.
|
||||
func (s *Service) factor(c context.Context, serviceName, eventName string, riskLevel int8) (factor *model.Factor, err error) {
|
||||
var (
|
||||
event *model.Event
|
||||
)
|
||||
if event, err = s.dao.Event(c, eventName); err != nil {
|
||||
log.Error("s.dao.Event(%s) error(%v)", eventName, err)
|
||||
return
|
||||
}
|
||||
if event == nil {
|
||||
log.Error("event(%s) not support", eventName)
|
||||
err = ecode.SpyEventNotExist
|
||||
return
|
||||
}
|
||||
if factor, err = s.dao.Factor(c, event.ServiceID, event.ID, riskLevel); err != nil {
|
||||
log.Error("s.dao.Factor(%d, %d, %d) error(%v)", event.ServiceID, event.ID, riskLevel, err)
|
||||
return
|
||||
}
|
||||
if factor == nil {
|
||||
log.Warn("factor(service=%d,event=%d,risklevel=%d) not support", event.ServiceID, event.ID, riskLevel)
|
||||
err = ecode.SpyFactorNotExist
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// UserInfo get UserInfo by mid , from cache or db or generate.
|
||||
func (s *Service) UserInfo(c context.Context, mid int64, ip string) (ui *model.UserInfo, err error) {
|
||||
ui, err = s.userInfo(c, mid)
|
||||
if ui != nil {
|
||||
return
|
||||
}
|
||||
// user info not generated , so let's do it.
|
||||
if ui, err = s.initUserInfo(c, mid, ip); err != nil {
|
||||
log.Error("s.generateUserInfo(%d) error(%v)", mid, err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// UserInfoAsyn get UserInfo by mid , from cache or db or asyn generate.
|
||||
func (s *Service) UserInfoAsyn(c context.Context, mid int64) (ui *model.UserInfo, err error) {
|
||||
ui, err = s.userInfo(c, mid)
|
||||
if ui != nil {
|
||||
return
|
||||
}
|
||||
ip := metadata.String(c, metadata.RemoteIP)
|
||||
s.infomission(func() {
|
||||
if _, err1 := s.initUserInfo(context.TODO(), mid, ip); err1 != nil {
|
||||
log.Error("s.generateUserInfo(%d) error(%v)", mid, err1)
|
||||
return
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// UserInfo get UserInfo by mid , from cache or db.
|
||||
func (s *Service) userInfo(c context.Context, mid int64) (ui *model.UserInfo, err error) {
|
||||
var cacheFlag = true
|
||||
// get info from cache.
|
||||
if ui, err = s.dao.UserInfoCache(c, mid); err != nil {
|
||||
cacheFlag = false
|
||||
err = nil
|
||||
log.Error("s.dao.InfoCache(%d) error(%v)", mid, err)
|
||||
}
|
||||
// return if cache exist.
|
||||
if ui != nil {
|
||||
return
|
||||
}
|
||||
// get info from db.
|
||||
if ui, err = s.dao.UserInfo(c, mid); err != nil {
|
||||
log.Error("s.dao.Info(%d) error(%v)", mid, err)
|
||||
return
|
||||
}
|
||||
if ui != nil {
|
||||
// reload to cache
|
||||
if cacheFlag {
|
||||
s.updateInfoCache(c, ui)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Info returns user info.
|
||||
func (s *Service) Info(c context.Context, mid int64) (ui *model.UserInfo, err error){
|
||||
ui, err = s.UserInfoAsyn(c, mid)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if ui == nil {
|
||||
// asyn init user score , return def score.
|
||||
ui = &model.UserInfo{Mid: mid, Score: model.SpyInitScore}
|
||||
}
|
||||
return ui, nil
|
||||
}
|
||||
|
||||
// initUserInfo .
|
||||
func (s *Service) initUserInfo(c context.Context, mid int64, ip string) (ui *model.UserInfo, err error) {
|
||||
var (
|
||||
tx *sql.Tx
|
||||
// init default info
|
||||
fakeFactor = &model.Factor{
|
||||
NickName: "initialization",
|
||||
ServiceID: -1,
|
||||
EventID: conf.Conf.Property.Event.InitEventID,
|
||||
GroupID: -1,
|
||||
RiskLevel: 1,
|
||||
FactorVal: 1.0,
|
||||
}
|
||||
fakeEventMsg = &model.EventMessage{
|
||||
IP: "127.0.0.1",
|
||||
ActiveMid: mid,
|
||||
TargetMid: mid,
|
||||
Effect: "initialization",
|
||||
RiskLevel: 1,
|
||||
}
|
||||
)
|
||||
// start generate logic.
|
||||
ui = &model.UserInfo{
|
||||
Mid: mid,
|
||||
EventScore: conf.Conf.Property.Score.EventInit,
|
||||
State: model.StateNormal,
|
||||
}
|
||||
if ui.BaseScore, err = s.getBaseScore(c, mid, ip); err != nil {
|
||||
log.Error("s.calcBaseScore(%d, %s) error(%v)", mid, ip, err)
|
||||
return
|
||||
}
|
||||
ui.Score = s.calcScore(ui.BaseScore, ui.EventScore)
|
||||
// add new info into db.
|
||||
if tx, err = s.dao.BeginTran(c); err != nil {
|
||||
log.Error("s.dao.BeginTran() err(%v)", err)
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if err1 := tx.Rollback(); err1 != nil {
|
||||
log.Error("tx.Rollback() error(%v)", err1)
|
||||
}
|
||||
return
|
||||
}
|
||||
if err = tx.Commit(); err != nil {
|
||||
log.Error("tx.Commit() error(%v)", err)
|
||||
}
|
||||
}()
|
||||
if ui.ID, err = s.dao.TxAddInfo(c, tx, ui); err != nil {
|
||||
log.Error("s.userDao.NewInfo(%d, %v) error(%v)", mid, ui, err)
|
||||
return
|
||||
}
|
||||
if err = s.txAddHistory(c, tx, ui, fakeFactor, fakeEventMsg); err != nil {
|
||||
log.Error("s.addHistory(%v, %v, %v) error(%v)", ui, fakeFactor, fakeEventMsg, err)
|
||||
return
|
||||
}
|
||||
s.updateInfoCache(c, ui)
|
||||
s.dao.PubScoreChange(c, mid, &model.ScoreChange{
|
||||
Mid: mid,
|
||||
Score: ui.Score,
|
||||
TS: time.Now().Unix(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) calcFactorScore(preScore int8, factor *model.Factor) (score int8) {
|
||||
return int8(float64(preScore) * factor.FactorVal)
|
||||
}
|
||||
|
||||
// calc real score.
|
||||
func (s *Service) calcScore(baseScore, eventScore int8) (score int8) {
|
||||
return int8(float64(baseScore) * float64(eventScore) / float64(_score))
|
||||
}
|
||||
|
||||
// getBaseScore get base score.
|
||||
func (s *Service) getBaseScore(c context.Context, mid int64, ip string) (score int8, err error) {
|
||||
var (
|
||||
judgementInfo *JudgementInfo
|
||||
factorMeta FactoryMeta
|
||||
factor *model.Factor
|
||||
)
|
||||
if judgementInfo, err = s.getJudgementInfo(c, mid, ip); err != nil {
|
||||
return
|
||||
}
|
||||
if factorMeta, err = s.getBaseScoreFactor(judgementInfo); err != nil {
|
||||
return
|
||||
}
|
||||
log.Info("getBaseScoreFactor mid(%d) meta(%v)", mid, factorMeta)
|
||||
if factor, err = s.factor(c, factorMeta.serviceName, factorMeta.eventName, factorMeta.riskLevel); err != nil {
|
||||
log.Error("s.factor(%s, %s) error(%v)", conf.Conf.Property.Event.ServiceName, conf.Conf.Property.Event.BindMailOnly, 1)
|
||||
return
|
||||
}
|
||||
score = s.calcFactorScore(conf.Conf.Property.Score.BaseInit, factor)
|
||||
return
|
||||
}
|
||||
|
||||
// ReBuildPortrait reBuild user info.
|
||||
func (s *Service) ReBuildPortrait(c context.Context, mid int64, reason string) (err error) {
|
||||
var (
|
||||
tx *sql.Tx
|
||||
)
|
||||
ui, err := s.UserInfo(c, mid, ip.InternalIP())
|
||||
if err != nil || ui == nil {
|
||||
log.Error("user portrait not fund, mid(%d, %v), err(%v)", mid, ui, err)
|
||||
return
|
||||
}
|
||||
s.promEventScore.Incr("change")
|
||||
s.resetScore(c, ui, ui.BaseScore, _score)
|
||||
if tx, err = s.dao.BeginTran(c); err != nil {
|
||||
log.Error("s.dao.BeginTran() err(%v)", err)
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if err1 := tx.Rollback(); err1 != nil {
|
||||
log.Error("tx.Rollback() error(%v)", err1)
|
||||
}
|
||||
return
|
||||
}
|
||||
if err = tx.Commit(); err != nil {
|
||||
log.Error("tx.Commit() error(%v)", err)
|
||||
}
|
||||
}()
|
||||
if err = s.dao.TxUpdateEventScoreReLive(c, tx, ui.Mid, ui.EventScore, ui.Score); err != nil {
|
||||
log.Error("s.dao.TxUpdateEventScoreReLive(%d, %d, %d), err(%v)", ui.Mid, ui.EventScore, ui.Score, err)
|
||||
return
|
||||
}
|
||||
if err = s.txAddHistory(c, tx, ui, &model.Factor{}, &model.EventMessage{Effect: reason}); err != nil {
|
||||
log.Error("s.addHistory(%+v), err(%v)", ui, err)
|
||||
return
|
||||
}
|
||||
s.updateInfoCache(c, ui)
|
||||
s.dao.PubScoreChange(c, mid, &model.ScoreChange{
|
||||
Mid: mid,
|
||||
Score: ui.Score,
|
||||
TS: time.Now().Unix(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateUserScore update user score
|
||||
func (s *Service) UpdateUserScore(c context.Context, mid int64, ip, effect string) (err error) {
|
||||
var (
|
||||
tx *sql.Tx
|
||||
factor = &model.Factor{}
|
||||
eventMsg = &model.EventMessage{Effect: effect}
|
||||
preBaseScore int8
|
||||
)
|
||||
ui, err := s.UserInfo(c, mid, ip)
|
||||
if err != nil || ui == nil {
|
||||
log.Error("user portrait not found, mid(%d, %v), err(%v)", mid, ui, err)
|
||||
return
|
||||
}
|
||||
preBaseScore = ui.BaseScore
|
||||
if ui.BaseScore, err = s.getBaseScore(c, mid, ip); err != nil {
|
||||
log.Error("s.calcBaseScore(%d, %s) error(%v)", mid, ip, err)
|
||||
return
|
||||
}
|
||||
s.promBaseScore.Incr("change")
|
||||
if ui.BaseScore < preBaseScore {
|
||||
s.promBaseScore.Incr("decrease")
|
||||
}
|
||||
s.resetScore(c, ui, ui.BaseScore, ui.EventScore)
|
||||
if tx, err = s.dao.BeginTran(c); err != nil {
|
||||
log.Error("s.dao.BeginTran() err(%v)", err)
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if err1 := tx.Rollback(); err1 != nil {
|
||||
log.Error("tx.Rollback() error(%v)", err1)
|
||||
}
|
||||
return
|
||||
}
|
||||
if err = tx.Commit(); err != nil {
|
||||
log.Error("tx.Commit() error(%v)", err)
|
||||
}
|
||||
}()
|
||||
if err = s.dao.TxUpdateBaseScore(c, tx, ui); err != nil {
|
||||
log.Error("s.dao.UpdateBaseScore(%v), err(%v)", ui, err)
|
||||
return
|
||||
}
|
||||
if err = s.txAddHistory(c, tx, ui, factor, eventMsg); err != nil {
|
||||
log.Error("s.addHistory(%v, %v, %v) error(%v)", ui, factor, eventMsg, err)
|
||||
return
|
||||
}
|
||||
s.updateInfoCache(c, ui)
|
||||
s.dao.PubScoreChange(c, mid, &model.ScoreChange{
|
||||
Mid: mid,
|
||||
Score: ui.Score,
|
||||
TS: time.Now().Unix(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// RefreshBaseScore refresh base score.
|
||||
func (s *Service) RefreshBaseScore(c context.Context, arg *spy.ArgReset) (err error) {
|
||||
var (
|
||||
tx *sql.Tx
|
||||
mid = arg.Mid
|
||||
ip = "ip"
|
||||
eventMsg = &model.EventMessage{Effect: "手动更新基础分值"}
|
||||
preBaseScore int8
|
||||
)
|
||||
ui, err := s.UserInfo(c, mid, "ip")
|
||||
if err != nil || ui == nil {
|
||||
log.Error("user portrait not found, mid(%d, %v), err(%v)", mid, ui, err)
|
||||
return
|
||||
}
|
||||
preBaseScore = ui.BaseScore
|
||||
if ui.BaseScore, err = s.getBaseScore(c, mid, ip); err != nil {
|
||||
log.Error("s.calcBaseScore(%d, %s) error(%v)", mid, ip, err)
|
||||
return
|
||||
}
|
||||
s.promBaseScore.Incr("change")
|
||||
if ui.BaseScore < preBaseScore {
|
||||
s.promBaseScore.Incr("decrease")
|
||||
}
|
||||
s.resetScore(c, ui, ui.BaseScore, ui.EventScore)
|
||||
if tx, err = s.dao.BeginTran(c); err != nil {
|
||||
log.Error("s.dao.BeginTran() err(%v)", err)
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if err1 := tx.Rollback(); err1 != nil {
|
||||
log.Error("tx.Rollback() error(%v)", err1)
|
||||
}
|
||||
return
|
||||
}
|
||||
if err = tx.Commit(); err != nil {
|
||||
log.Error("tx.Commit() error(%v)", err)
|
||||
}
|
||||
}()
|
||||
if err = s.dao.TxUpdateBaseScore(c, tx, ui); err != nil {
|
||||
log.Error("s.dao.UpdateBaseScore(%v), err(%v)", ui, err)
|
||||
return
|
||||
}
|
||||
if err = s.txAddHistory(c, tx, ui, &model.Factor{}, eventMsg); err != nil {
|
||||
log.Error("s.addHistory(%v, %v) error(%v)", ui, eventMsg, err)
|
||||
return
|
||||
}
|
||||
s.updateInfoCache(c, ui)
|
||||
s.dao.PubScoreChange(c, mid, &model.ScoreChange{
|
||||
Mid: mid,
|
||||
Score: ui.Score,
|
||||
TS: time.Now().Unix(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
//UpdateBaseScore update base score.
|
||||
func (s *Service) UpdateBaseScore(c context.Context, arg *spy.ArgReset) (err error) {
|
||||
var (
|
||||
tx *sql.Tx
|
||||
event *model.Event
|
||||
eventMsg = &model.EventMessage{}
|
||||
)
|
||||
ui, err := s.UserInfo(c, arg.Mid, "ip")
|
||||
if err != nil || ui == nil {
|
||||
log.Error("user portrait not fund, mid(%d, %v), err(%v)", arg.Mid, ui, err)
|
||||
return
|
||||
}
|
||||
s.resetScore(c, ui, _score, ui.EventScore)
|
||||
eventMsg.Effect = fmt.Sprintf("人工恢复基础得分(%s)", arg.Operator)
|
||||
if tx, err = s.dao.BeginTran(c); err != nil {
|
||||
log.Error("s.dao.BeginTran() err(%v)", err)
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if err1 := tx.Rollback(); err1 != nil {
|
||||
log.Error("tx.Rollback() error(%v)", err1)
|
||||
}
|
||||
return
|
||||
}
|
||||
if err = tx.Commit(); err != nil {
|
||||
log.Error("tx.Commit() error(%v)", err)
|
||||
}
|
||||
}()
|
||||
if err = s.dao.TxUpdateBaseScore(c, tx, ui); err != nil {
|
||||
log.Error("s.dao.UpdateBaseScore(%v), err(%v)", ui, err)
|
||||
return
|
||||
}
|
||||
if event, err = s.dao.Event(c, RestoreBaseScoreEvent); err != nil {
|
||||
log.Error("s.dao.Event(%s), err(%v)", RestoreBaseScoreEvent, err)
|
||||
return
|
||||
}
|
||||
if err = s.txAddHistory(c, tx, ui, &model.Factor{EventID: event.ID}, eventMsg); err != nil {
|
||||
log.Error("s.addHistory(%v), err(%v)", ui, err)
|
||||
return
|
||||
}
|
||||
s.dao.DelInfoCache(c, arg.Mid)
|
||||
s.dao.PubScoreChange(c, arg.Mid, &model.ScoreChange{
|
||||
Mid: arg.Mid,
|
||||
Score: ui.Score,
|
||||
TS: time.Now().Unix(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
//UpdateEventScore update event score.
|
||||
func (s *Service) UpdateEventScore(c context.Context, arg *spy.ArgReset) (err error) {
|
||||
var (
|
||||
tx *sql.Tx
|
||||
eventMsg = &model.EventMessage{}
|
||||
)
|
||||
ui, err := s.UserInfo(c, arg.Mid, "ip")
|
||||
if err != nil || ui == nil {
|
||||
log.Error("user portrait not fund, mid(%d, %v), err(%v)", arg.Mid, ui, err)
|
||||
return
|
||||
}
|
||||
s.resetScore(c, ui, ui.BaseScore, _score)
|
||||
eventMsg.Effect = fmt.Sprintf("人工恢复行为得分(%s)", arg.Operator)
|
||||
if tx, err = s.dao.BeginTran(c); err != nil {
|
||||
log.Error("s.dao.BeginTran() err(%v)", err)
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if err1 := tx.Rollback(); err1 != nil {
|
||||
log.Error("tx.Rollback() error(%v)", err1)
|
||||
}
|
||||
return
|
||||
}
|
||||
if err = tx.Commit(); err != nil {
|
||||
log.Error("tx.Commit() error(%v)", err)
|
||||
}
|
||||
}()
|
||||
if err = s.dao.TxUpdateEventScore(c, tx, ui.Mid, ui.EventScore, ui.Score); err != nil {
|
||||
log.Error("s.dao.UpdateEventScore(%v), err(%v)", ui, err)
|
||||
return
|
||||
}
|
||||
if err = s.txAddHistory(c, tx, ui, &model.Factor{}, eventMsg); err != nil {
|
||||
log.Error("s.addHistory(%v), err(%v)", ui, err)
|
||||
return
|
||||
}
|
||||
s.dao.DelInfoCache(c, arg.Mid)
|
||||
s.dao.PubScoreChange(c, arg.Mid, &model.ScoreChange{
|
||||
Mid: arg.Mid,
|
||||
Score: ui.Score,
|
||||
TS: time.Now().Unix(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) txAddHistory(c context.Context, tx *sql.Tx, ui *model.UserInfo, factor *model.Factor, eventMsg *model.EventMessage) (err error) {
|
||||
// append event history
|
||||
var (
|
||||
ueh = &model.UserEventHistory{
|
||||
Mid: ui.Mid,
|
||||
EventID: factor.EventID,
|
||||
Score: ui.Score,
|
||||
BaseScore: ui.BaseScore,
|
||||
EventScore: ui.EventScore,
|
||||
Reason: eventMsg.Effect,
|
||||
FactorVal: factor.FactorVal,
|
||||
}
|
||||
remarkBytes []byte
|
||||
)
|
||||
if remarkBytes, err = json.Marshal(eventMsg); err != nil {
|
||||
log.Error("json.Marshal(%v) error(%v)", eventMsg, err)
|
||||
ueh.Remark = "{}"
|
||||
} else {
|
||||
ueh.Remark = string(remarkBytes)
|
||||
}
|
||||
if err = s.dao.TxAddEventHistory(c, tx, ueh); err != nil {
|
||||
log.Error("s.dao.AddEventHistory(%v) error(%v)", ueh, err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) resetScore(c context.Context, ui *model.UserInfo, baseScore, eventScore int8) (err error) {
|
||||
ui.BaseScore = baseScore
|
||||
ui.EventScore = eventScore
|
||||
ui.Score = int8(int(ui.EventScore) * int(ui.BaseScore) / _score)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) updateInfoCache(c context.Context, ui *model.UserInfo) (err error) {
|
||||
s.mission(func() {
|
||||
if err = s.dao.SetUserInfoCache(context.TODO(), ui); err != nil {
|
||||
log.Error("s.dao.SetInfoCache(%v) error(%v)", ui, err)
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
//ClearReliveTimes clear times.
|
||||
func (s *Service) ClearReliveTimes(c context.Context, arg *spy.ArgReset) (err error) {
|
||||
var (
|
||||
tx *sql.Tx
|
||||
eventMsg = &model.EventMessage{}
|
||||
)
|
||||
ui, err := s.UserInfo(c, arg.Mid, "ip")
|
||||
if err != nil || ui == nil {
|
||||
log.Error("user portrait not fund, mid(%d, %v), err(%v)", arg.Mid, ui, err)
|
||||
return
|
||||
}
|
||||
ui.ReliveTimes = 0
|
||||
eventMsg.Effect = fmt.Sprintf("清除封号记次(%s)", arg.Operator)
|
||||
if tx, err = s.dao.BeginTran(c); err != nil {
|
||||
log.Error("s.dao.BeginTran() err(%v)", err)
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if err1 := tx.Rollback(); err1 != nil {
|
||||
log.Error("tx.Rollback() error(%v)", err1)
|
||||
}
|
||||
return
|
||||
}
|
||||
if err = tx.Commit(); err != nil {
|
||||
log.Error("tx.Commit() error(%v)", err)
|
||||
}
|
||||
}()
|
||||
if err = s.dao.TxClearReliveTimes(c, tx, ui); err != nil {
|
||||
log.Error("s.dao.ClearReliveTimes(%v), err(%v)", ui, err)
|
||||
return
|
||||
}
|
||||
if err = s.txAddHistory(c, tx, ui, &model.Factor{}, eventMsg); err != nil {
|
||||
log.Error("s.addHistory(%v), err(%v)", ui, err)
|
||||
return
|
||||
}
|
||||
s.dao.DelInfoCache(c, arg.Mid)
|
||||
return
|
||||
}
|
||||
|
||||
// TelRiskLevel tel risk level.
|
||||
func (s *Service) TelRiskLevel(c context.Context, mid int64, ip string) (riskLevel int8, err error) {
|
||||
var (
|
||||
tel *model.TelInfo
|
||||
level int8
|
||||
)
|
||||
riskLevel = dao.TelRiskLevelUnknown
|
||||
if tel, err = s.dao.TelInfo(c, mid); err != nil {
|
||||
log.Error("s.dao.TelInfo error(%v)", err)
|
||||
return
|
||||
}
|
||||
if len(tel.Tel) == 0 {
|
||||
log.Warn("mid(%d) no tel info", mid)
|
||||
return
|
||||
}
|
||||
// white tel
|
||||
if telnum, theErr := strconv.ParseInt(tel.Tel, 10, 64); theErr == nil {
|
||||
for _, whiteTel := range s.c.Property.White.Tels {
|
||||
if telnum >= whiteTel.From && telnum <= whiteTel.To {
|
||||
log.Info("spy hit tel white from [%d] to [%d]", whiteTel.From, whiteTel.To)
|
||||
riskLevel = dao.TelRiskLevelLow
|
||||
return
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.Error("+v", errors.WithStack(theErr))
|
||||
}
|
||||
|
||||
args := url.Values{}
|
||||
args.Set("accountType", fmt.Sprintf("%d", model.AccountType))
|
||||
args.Set("uid", fmt.Sprintf("%d", mid))
|
||||
args.Set("phoneNumber", tel.Tel)
|
||||
args.Set("registerTime", fmt.Sprintf("%d", tel.JoinTime))
|
||||
args.Set("registerIp", tel.JoinIP)
|
||||
if level, err = s.dao.RegisterProtection(c, args, ip); err != nil {
|
||||
log.Error("s.dao.RegisterProtection error(%v)", err)
|
||||
return
|
||||
}
|
||||
switch level {
|
||||
case model.Nomal:
|
||||
riskLevel = dao.TelRiskLevelLow
|
||||
case model.LevelOne:
|
||||
riskLevel = dao.TelRiskLevelMedium
|
||||
case model.LevelTwo:
|
||||
riskLevel = dao.TelRiskLevelMedium
|
||||
case model.LevelThree:
|
||||
riskLevel = dao.TelRiskLevelHigh
|
||||
case model.LevelFour:
|
||||
riskLevel = dao.TelRiskLevelHigh
|
||||
default:
|
||||
log.Error(" RegisterProtection not found level (%d)", level)
|
||||
}
|
||||
return
|
||||
}
|
59
app/service/main/spy/service/stat.go
Normal file
59
app/service/main/spy/service/stat.go
Normal file
@ -0,0 +1,59 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go-common/app/service/main/spy/model"
|
||||
)
|
||||
|
||||
// StatByID spy stat by id or mid.
|
||||
func (s *Service) StatByID(c context.Context, mid, id int64) (stat []*model.Statistics, err error) {
|
||||
if mid != 0 && id != 0 {
|
||||
stat, err = s.dao.StatListByIDAndMid(c, mid, id)
|
||||
} else {
|
||||
if id == 0 {
|
||||
stat, err = s.dao.StatListByMid(c, mid)
|
||||
} else {
|
||||
stat, err = s.dao.StatListByID(c, id)
|
||||
}
|
||||
}
|
||||
if len(stat) == 0 {
|
||||
return
|
||||
}
|
||||
for _, st := range stat {
|
||||
st.EventName = s.allEventName[st.EventID]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// StatByIDGroupEvent spy stat by id or mid.
|
||||
func (s *Service) StatByIDGroupEvent(c context.Context, mid, id int64) (res []*model.Statistics, err error) {
|
||||
var (
|
||||
stat []*model.Statistics
|
||||
em = make(map[int64]*model.Statistics)
|
||||
)
|
||||
if mid != 0 && id != 0 {
|
||||
stat, err = s.dao.StatListByIDAndMid(c, mid, id)
|
||||
} else {
|
||||
if id == 0 {
|
||||
stat, err = s.dao.StatListByMid(c, mid)
|
||||
} else {
|
||||
stat, err = s.dao.StatListByID(c, id)
|
||||
}
|
||||
}
|
||||
if len(stat) == 0 {
|
||||
return
|
||||
}
|
||||
for _, st := range stat {
|
||||
item, ok := em[st.EventID]
|
||||
if !ok {
|
||||
item = &model.Statistics{EventID: st.EventID, EventName: st.EventName}
|
||||
}
|
||||
item.Quantity += st.Quantity
|
||||
em[st.EventID] = item
|
||||
}
|
||||
for _, val := range em {
|
||||
res = append(res, val)
|
||||
}
|
||||
return
|
||||
}
|
Reference in New Issue
Block a user