Create & Init Project...

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

21
app/admin/main/spy/BUILD Normal file
View File

@ -0,0 +1,21 @@
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/admin/main/spy/cmd:all-srcs",
"//app/admin/main/spy/conf:all-srcs",
"//app/admin/main/spy/dao:all-srcs",
"//app/admin/main/spy/http:all-srcs",
"//app/admin/main/spy/model:all-srcs",
"//app/admin/main/spy/service:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,62 @@
#反作弊后台
反作弊项目-服务
===============
V1.5.0
1. 添加刷新基础分接口
2. 添加无验证的内部接口
V1.4.0
1. 改为 metadata RemoteIP
V1.3.0
1. bm http server
V1.2.9
1. account v7
V1.2.8
1. remove stastd
V1.2.7
1. 修改事件名
V1.2.6
1. 修改事件名
V1.2.5
1. log v level
V1.2.4
1. 反作弊案件
V1.2.3
1. 优化identify
v1.2.2
1. 作弊时间时区问题兼容
v1.2.1
1. 报表及监控
v1.2.0
1. 因子配置添加
2. 增加封禁时间显示
v1.1.2
1. 修改event msg 参数名
v1.1.1
1. 自动封禁系统中,增加过滤条件
v1.1.0
1. 反作弊二期,自动封禁相关
v1.0.2
1. 迁移大仓库优化record的sql
v1.0.1
1. 发布项目
v1.0.0
1. 初始化项目,更新依赖
2. 完成反作弊一期开发

View File

@ -0,0 +1,10 @@
# Owner
zhaogangtao
# Author
baihai
zhaogangtao
# Reviewer
linmiao
zhaogangtao

15
app/admin/main/spy/OWNERS Normal file
View File

@ -0,0 +1,15 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- baihai
- zhaogangtao
labels:
- admin
- admin/main/spy
- main
options:
no_parent_owners: true
reviewers:
- baihai
- linmiao
- zhaogangtao

View File

@ -0,0 +1,10 @@
#### archive-service
##### 项目简介
> 1.提供反作弊服务
##### 编译环境
> 请只用golang v1.7.x以上版本编译执行。
##### 依赖包
> 1.公共包go-common

View File

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

View File

@ -0,0 +1,53 @@
package main
import (
"flag"
"os"
"time"
"go-common/app/admin/main/spy/conf"
"go-common/app/admin/main/spy/http"
"go-common/app/admin/main/spy/service"
"go-common/library/log"
"go-common/library/os/signal"
"go-common/library/syscall"
)
var (
s *service.Service
)
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()
// service init
http.Init(conf.Conf)
log.Info("spy-admin start")
signalHandler()
}
func signalHandler() {
var (
ch = make(chan os.Signal, 1)
)
signal.Notify(ch, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT, syscall.SIGSTOP)
for {
si := <-ch
switch si {
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGSTOP, syscall.SIGINT:
time.Sleep(time.Second * 2)
log.Info("get a signal %s, stop the spy-admin process", si.String())
s.Wait()
time.Sleep(time.Second)
return
case syscall.SIGHUP:
default:
return
}
}
}

View File

@ -0,0 +1,137 @@
version = "1.0.0"
user = "nobody"
dir = "./"
perf = "0.0.0.0:6330"
family = "spy-admin"
env = "qa"
[log]
dir = "/data/log/spy-admin/"
[db]
[db.spy]
addr= "localhost:3306"
dsn = "root:123456@tcp(localhost:3306)/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
[accountRPC]
pullInterval = "10s"
group = "groupapp"
[accountRPC.client]
timeout = "1s"
timer = 1000
[accountRPC.zookeeper]
root = "/microservice/account-service/"
addrs = ["172.16.33.169:2181"]
timeout = "30s"
[accountRPC.client.breaker]
window ="3s"
sleep ="100ms"
bucket = 10
ratio = 0.5
request = 100
[spyRPC]
policy = "sharding"
pullInterval = "10s"
[spyRPC.client]
timeout = "1s"
timer = 1000
[spyRPC.client.breaker]
window ="3s"
sleep ="100ms"
bucket = 10
ratio = 0.5
request = 100
[spyRPC.zookeeper]
root = "/microservice/spy-service/"
addrs = ["172.16.33.169:2181"]
timeout = "1s"
[memcache]
userExpire = "24h"
[memcache.user]
name = "spy-admin/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?"
userInfoShard = 100
historyShard = 100
loadEventTick = "60s"
[property.score]
baseInit = 100
eventInit = 100
[property.punishment]
scoreThreshold = 30
times = 3
[property.event]
serviceName = "spy_service"
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"
[identify]
WhiteAccessKey = ""
WhiteMid = 0
[identify.app]
key = "e7482d29be4a95b8"
secret = "9e803791cdef756e75faee68e12b7442"
[identify.memcache]
name = "go-business/identify"
proto = "unix"
addr = "/tmp/platform-identify-mc.sock"
active = 5
idle = 5
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "80s"
[identify.host]
auth = "http://passport.bilibili.com"
secret = "http://open.bilibili.com"
[identify.httpClient]
key = "53e2fa226f5ad348"
secret = "3cf6bd1b0ff671021da5f424fea4b04a"
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"}
[bm]
addr = "0.0.0.0:7581"
maxListen = 10
timeout = "1s"

View File

@ -0,0 +1,38 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["conf.go"],
importpath = "go-common/app/admin/main/spy/conf",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//library/cache/memcache: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/time:go_default_library",
"//vendor/github.com/BurntSushi/toml:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,132 @@
package conf
import (
"errors"
"flag"
"go-common/library/cache/memcache"
"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/time"
"github.com/BurntSushi/toml"
)
var (
// config
confPath string
client *conf.Client
// Conf config
Conf = &Config{}
)
// Config def.
type Config struct {
// base
// db
DB *DB
// spy rpc client
SpyRPC *rpc.ClientConfig
AccountRPC *rpc.ClientConfig
// memcache
Memcache *Memcache
// log
Log *log.Config
// customized property
Property *Property
HTTPServer *bm.ServerConfig
}
// DB config.
type DB struct {
Spy *sql.Config
}
// Memcache config.
type Memcache struct {
User *memcache.Config
UserExpire time.Duration
}
// Property config for biz logic.
type Property struct {
TelValidateURL string
BlockAccountURL string
UserInfoShard int64
HistoryShard int64
LoadEventTick time.Duration
Score *struct {
BaseInit int8
EventInit int8
}
Punishment *struct {
ScoreThreshold int8
Times int8
}
Event *struct {
ServiceName string
BindMailAndTelLowRisk string
BindMailOnly string
BindNothing string
BindTelLowRiskOnly string
BindTelMediumRisk string
BindTelHighRisk string
BindTelUnknownRisk string
}
// activity events
ActivityEvents map[int32]struct{}
}
func local() (err error) {
_, err = toml.DecodeFile(confPath, &Conf)
return
}
func remote() (err error) {
if client, err = conf.New(); err != nil {
return
}
if err = load(); err != nil {
return
}
go func() {
for range client.Event() {
log.Info("config reload")
if load() != nil {
log.Error("config reload error (%v)", err)
}
}
}()
return
}
func load() (err error) {
var (
s string
ok bool
tmpConf *Config
)
if s, ok = client.Toml2(); !ok {
return errors.New("load config center error")
}
if _, err = toml.Decode(s, &tmpConf); err != nil {
return errors.New("could not decode config")
}
*Conf = *tmpConf
return
}
func init() {
flag.StringVar(&confPath, "conf", "", "default config path")
}
// Init int config
func Init() error {
if confPath != "" {
return local()
}
return remote()
}

View File

@ -0,0 +1,61 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"dao_test.go",
"mysql_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/admin/main/spy/conf:go_default_library",
"//app/admin/main/spy/model:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"dao.go",
"mysql.go",
"rpc.go",
],
importpath = "go-common/app/admin/main/spy/dao",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/spy/conf:go_default_library",
"//app/admin/main/spy/model:go_default_library",
"//app/service/main/account/model:go_default_library",
"//app/service/main/account/rpc/client:go_default_library",
"//app/service/main/spy/model:go_default_library",
"//app/service/main/spy/rpc/client:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/database/sql:go_default_library",
"//library/log:go_default_library",
"//library/net/metadata:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,72 @@
package dao
import (
"context"
"fmt"
"time"
"go-common/app/admin/main/spy/conf"
account "go-common/app/service/main/account/rpc/client"
spy "go-common/app/service/main/spy/rpc/client"
"go-common/library/cache/memcache"
"go-common/library/database/sql"
)
// Dao struct user of Dao.
type Dao struct {
c *conf.Config
// db
db *sql.DB
getUserInfoStmt []*sql.Stmt
eventStmt *sql.Stmt
factorAllStmt *sql.Stmt
allGroupStmt *sql.Stmt
// cache
mcUser *memcache.Pool
mcUserExpire int32
// rpc
spyRPC *spy.Service
accRPC *account.Service3
}
// New create a instance of Dao and return.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
// conf
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),
// rpc
spyRPC: spy.New(c.SpyRPC),
accRPC: account.New3(c.AccountRPC),
}
if conf.Conf.Property.UserInfoShard <= 0 {
panic("conf.Conf.Property.UserInfoShard <= 0")
}
if conf.Conf.Property.HistoryShard <= 0 {
panic("conf.Conf.Property.HistoryShard <= 0")
}
d.getUserInfoStmt = make([]*sql.Stmt, conf.Conf.Property.UserInfoShard)
for i := int64(0); i < conf.Conf.Property.UserInfoShard; i++ {
d.getUserInfoStmt[i] = d.db.Prepared(fmt.Sprintf(_getUserInfoSQL, i))
}
d.eventStmt = d.db.Prepared(_eventSQL)
d.factorAllStmt = d.db.Prepared(_factorAllSQL)
d.allGroupStmt = d.db.Prepared(_allGroupSQL)
return
}
// Ping check connection of db , mc.
func (d *Dao) Ping(c context.Context) (err error) {
return d.db.Ping(c)
}
// Close close connection of db , mc.
func (d *Dao) Close() {
if d.db != nil {
d.db.Close()
}
}

View File

@ -0,0 +1,159 @@
package dao
import (
"context"
"flag"
"fmt"
"os"
"testing"
"time"
"go-common/app/admin/main/spy/conf"
"go-common/app/admin/main/spy/model"
. "github.com/smartystreets/goconvey/convey"
)
var (
dataMID = int64(15555180)
noDataMID = int64(1)
d *Dao
)
const (
_cleanFactorSQL = "delete from spy_factor where nick_name = ? AND service_id = ? AND event_id = ? AND risk_level = ?"
_cleanEventSQL = "delete from spy_event where name = ? AND service_id = ? AND status = ?"
_cleanServiceSQL = "delete from spy_service where name = ? AND status = ?"
_cleanGroupSQL = "delete from spy_factor_group where name = ?"
)
func CleanMysql() {
ctx := context.Background()
d.db.Exec(ctx, _cleanFactorSQL, "test", 1, 1, 2)
d.db.Exec(ctx, _cleanEventSQL, "test", 1, 1)
d.db.Exec(ctx, _cleanServiceSQL, "test", 1)
d.db.Exec(ctx, _cleanGroupSQL, "test")
}
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.account-law.spy-admin")
flag.Set("conf_token", "bc3d60c2bb2b08a1b690b004a1953d3c")
flag.Set("tree_id", "2857")
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-admin-test.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
CleanMysql()
m.Run()
os.Exit(0)
}
func WithMysql(f func(d *Dao)) func() {
return func() {
f(d)
}
}
func Test_Mysql(t *testing.T) {
Convey("get user info", t, WithMysql(func(d *Dao) {
res, err := d.Info(context.TODO(), dataMID)
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
}))
Convey("get user info no data ", t, WithMysql(func(d *Dao) {
res, err := d.Info(context.TODO(), noDataMID)
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
}))
Convey("get event history", t, WithMysql(func(d *Dao) {
hpConf := &model.HisParamReq{
Mid: 46333,
Ps: 10,
Pn: 1,
}
res, err := d.HistoryPage(context.TODO(), hpConf)
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
}))
Convey("get event history count", t, WithMysql(func(d *Dao) {
hpConf := &model.HisParamReq{
Mid: 46333,
Ps: 10,
Pn: 1,
}
res, err := d.HistoryPageTotalC(context.TODO(), hpConf)
So(err, ShouldBeNil)
fmt.Printf("history count : %d\n", res)
So(res, ShouldNotBeEmpty)
}))
Convey("get setting list", t, WithMysql(func(d *Dao) {
res, err := d.SettingList(context.TODO())
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
}))
Convey("update setting", t, WithMysql(func(d *Dao) {
list, err := d.SettingList(context.TODO())
So(err, ShouldBeNil)
setting := list[0]
res, err := d.UpdateSetting(context.TODO(), setting.Val, setting.Property)
So(err, ShouldBeNil)
fmt.Println(res)
}))
Convey(" add factor ", t, WithMysql(func(d *Dao) {
res, err := d.AddFactor(context.TODO(), &model.Factor{
NickName: "test",
ServiceID: int64(1),
EventID: int64(1),
GroupID: int64(1),
RiskLevel: int8(2),
FactorVal: float32(1),
CategoryID: int8(1),
CTime: time.Now(),
MTime: time.Now(),
})
So(err, ShouldBeNil)
So(res == 1, ShouldBeTrue)
}))
Convey(" add event ", t, WithMysql(func(d *Dao) {
res, err := d.AddEvent(context.TODO(), &model.Event{
Name: "test",
NickName: "nickname",
ServiceID: 1,
Status: 1,
CTime: time.Now(),
MTime: time.Now(),
})
So(err, ShouldBeNil)
So(res == 1, ShouldBeTrue)
}))
Convey(" add service ", t, WithMysql(func(d *Dao) {
res, err := d.AddService(context.TODO(), &model.Service{
Name: "test",
NickName: "nickname",
Status: 1,
CTime: time.Now(),
MTime: time.Now(),
})
So(err, ShouldBeNil)
So(res == 1, ShouldBeTrue)
}))
Convey(" add group ", t, WithMysql(func(d *Dao) {
res, err := d.AddGroup(context.TODO(), &model.FactorGroup{
Name: "test",
CTime: time.Now(),
})
So(err, ShouldBeNil)
So(res == 1, ShouldBeTrue)
}))
}

View File

@ -0,0 +1,584 @@
package dao
import (
"context"
"database/sql"
"encoding/json"
"fmt"
"time"
"go-common/app/admin/main/spy/conf"
"go-common/app/admin/main/spy/model"
xsql "go-common/library/database/sql"
"go-common/library/log"
)
const (
_eventSQL = "SELECT id,name,nick_name,service_id,ctime,mtime FROM spy_event WHERE name=? AND deleted = 0 LIMIT 1;"
_allGroupSQL = "SELECT id, name, ctime FROM spy_factor_group;"
_updateFactorSQL = "UPDATE spy_factor SET factor_val = ? WHERE id = ?;"
_factorAllSQL = "SELECT id,nick_name,service_id,event_id,group_id,risk_level,factor_val,ctime,mtime FROM spy_factor WHERE group_id = ? ORDER BY factor_val;"
_getList = "SELECT id,mid,event_id,score,base_score,event_score,remark,reason,factor_val,ctime FROM spy_user_event_history_%02d WHERE %s ORDER BY id DESC LIMIT %d,%d;"
_getListTc = "SELECT COUNT(1) FROM spy_user_event_history_%02d WHERE %s;"
_addLogSQL = "INSERT INTO `spy_log`(`name`,`module`,`context`,`ref_id`,`ctime`)VALUES(?,?,?,?,?);"
_getSettingListSQL = "SELECT id,property,name,val,ctime,mtime FROM spy_system_config"
_updateSettingSQL = "UPDATE spy_system_config SET val=? WHERE property=?"
_getUserInfoSQL = "SELECT id,mid,score,base_score,event_score,state,relive_times,mtime FROM spy_user_info_%02d WHERE mid=?"
_addFactorSQL = "INSERT INTO `spy_factor`(`nick_name`,`service_id`,`event_id`,`group_id`,`risk_level`,`factor_val`,`category_id`,`ctime`)VALUES(?,?,?,?,?,?,?,?);"
_addEventSQL = "INSERT INTO `spy_event`(`name`,`nick_name`,`service_id`,`status`,`ctime`,`mtime`)VALUES(?,?,?,?,?,?);"
_addServiceSQL = "INSERT INTO `spy_service`(`name`,`nick_name`,`status`,`ctime`,`mtime`)VALUES(?,?,?,?,?);"
_addGroupSQL = "INSERT INTO `spy_factor_group`(`name`,`ctime`)VALUES(?,?);"
_getReportList = "SELECT id, name, date_version, val, ctime FROM spy_report limit ?,?;"
_getReportCount = "SELECT COUNT(1) FROM spy_report;"
_updateStatStateSQL = "UPDATE spy_statistics SET state=? WHERE id=?"
_updateStatQuantitySQL = "UPDATE spy_statistics SET quantity=? WHERE id=?"
_updateStatDeleteSQL = "UPDATE spy_statistics SET isdel=? WHERE id=?"
_statByIDSQL = "SELECT id,target_mid,target_id,event_id,state,type,quantity,isdel,ctime,mtime FROM spy_statistics WHERE id = ?;"
_logListSQL = "SELECT id,ref_id,name,module,context,ctime FROM spy_log WHERE ref_id = ? AND module = ?;"
_statListByMidSQL = "SELECT id,target_mid,target_id,event_id,state,type,quantity,isdel,ctime,mtime FROM spy_statistics WHERE target_mid = ? AND isdel = 0 ORDER BY id desc limit ?,?;"
_statListByIDSQL = "SELECT id,target_mid,target_id,event_id,state,type,quantity,isdel,ctime,mtime FROM spy_statistics WHERE target_id = ? AND type = ? AND isdel = 0 ORDER BY id desc limit ?,?;"
_statCountByMidSQL = "SELECT COUNT(1) FROM spy_statistics WHERE target_mid = ? AND isdel = 0;"
_statCountByIDSQL = "SELECT COUNT(1) FROM spy_statistics WHERE target_id = ? AND type = ? AND isdel = 0;"
_allEventSQL = "SELECT id,name,nick_name,service_id,status,ctime,mtime FROM spy_event WHERE status<>0"
_updateEventNameSQL = "UPDATE spy_event SET nick_name = ? WHERE id = ?;"
)
// Event get event from db.
func (d *Dao) Event(ctx context.Context, eventName string) (event *model.Event, err error) {
var (
row *xsql.Row
)
event = &model.Event{}
row = d.eventStmt.QueryRow(ctx, eventName)
if err = row.Scan(&event.ID, &event.Name, &event.NickName, &event.ServiceID, &event.CTime, &event.MTime); err != nil {
if err == sql.ErrNoRows {
err = nil
return
}
log.Error("row.Scan() error(%v)", err)
}
return
}
// Factors get all factor info by group id.
func (d *Dao) Factors(c context.Context, gid int64) (res []*model.Factor, err error) {
var rows *xsql.Rows
if rows, err = d.factorAllStmt.Query(c, gid); err != nil {
log.Error("d.allTypesStmt.Query(%d) error(%v)", gid, err)
return
}
defer rows.Close()
for rows.Next() {
r := new(model.Factor)
if err = rows.Scan(&r.ID, &r.NickName, &r.ServiceID, &r.EventID, &r.GroupID, &r.RiskLevel, &r.FactorVal, &r.CTime, &r.MTime); err != nil {
log.Error("row.Scan() error(%v)", err)
res = nil
return
}
res = append(res, r)
}
err = rows.Err()
return
}
// Groups get all group info.
func (d *Dao) Groups(c context.Context) (res []*model.FactorGroup, err error) {
var rows *xsql.Rows
if rows, err = d.allGroupStmt.Query(c); err != nil {
log.Error("d.allGroupStmt.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
r := new(model.FactorGroup)
if err = rows.Scan(&r.ID, &r.Name, &r.CTime); err != nil {
log.Error("row.Scan() error(%v)", err)
res = nil
return
}
res = append(res, r)
}
err = rows.Err()
return
}
// UpdateFactor update factor.
func (d *Dao) UpdateFactor(c context.Context, factorVal float32, id int64) (affected int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _updateFactorSQL, factorVal, id); err != nil {
log.Error("_updateFactorSQL: db.Exec(%v, %d) error(%v)", factorVal, id, err)
return
}
return res.RowsAffected()
}
func hitHistory(id int64) int64 {
return id % conf.Conf.Property.HistoryShard
}
// genListSQL get history sql
func (d *Dao) genListSQL(SQLType string, h *model.HisParamReq) (SQL string, values []interface{}) {
values = make([]interface{}, 0, 1)
cond := " mid = ?"
values = append(values, h.Mid)
switch SQLType {
case "list":
SQL = fmt.Sprintf(_getList, hitHistory(h.Mid), cond, (h.Pn-1)*h.Ps, h.Ps)
case "count":
SQL = fmt.Sprintf(_getListTc, hitHistory(h.Mid), cond)
}
return
}
//HistoryPage user event history.
func (d *Dao) HistoryPage(c context.Context, h *model.HisParamReq) (hs []*model.EventHistoryDto, err error) {
SQL, values := d.genListSQL("list", h)
rows, err := d.db.Query(c, SQL, values...)
if err != nil {
log.Error("dao.QuestionPage(%v,%v) error(%v)", SQL, values, err)
return
}
defer rows.Close()
hs = make([]*model.EventHistoryDto, 0, h.Ps)
for rows.Next() {
hdb := &model.EventHistory{}
err = rows.Scan(&hdb.ID, &hdb.Mid, &hdb.EventID, &hdb.Score, &hdb.BaseScore, &hdb.EventScore,
&hdb.Remark, &hdb.Reason, &hdb.FactorVal, &hdb.Ctime)
eventMSG := &model.EventMessage{}
if err = json.Unmarshal([]byte(hdb.Remark), eventMSG); err != nil {
log.Error("json.Unmarshal(%s) error(%v)", hdb.Remark, err)
} else {
hdb.TargetID = eventMSG.TargetID
hdb.TargetMid = eventMSG.TargetMid
}
if err != nil {
log.Error("rows.Scan error(%v)", err)
return
}
h := &model.EventHistoryDto{
ID: hdb.ID,
Score: hdb.Score,
BaseScore: hdb.BaseScore,
EventScore: hdb.EventScore,
Reason: hdb.Reason,
Ctime: hdb.Ctime.Unix(),
TargetID: hdb.TargetID,
TargetMid: hdb.TargetMid,
}
if eventMSG.Time != 0 {
_, offset := time.Now().Zone()
t := time.Unix(eventMSG.Time, 0).Add(-time.Duration(offset) * time.Second)
h.SpyTime = t.Unix()
}
hs = append(hs, h)
}
return
}
// HistoryPageTotalC user ecent history page.
func (d *Dao) HistoryPageTotalC(c context.Context, h *model.HisParamReq) (totalCount int, err error) {
SQL, values := d.genListSQL("count", h)
row := d.db.QueryRow(c, SQL, values...)
if err = row.Scan(&totalCount); err != nil {
if err == sql.ErrNoRows {
row = nil
err = nil
} else {
log.Error("row.Scan error(%v)", err)
}
}
return
}
//AddLog add log.
func (d *Dao) AddLog(c context.Context, l *model.Log) (affected int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _addLogSQL, l.Name, l.Module, l.Context, l.RefID, l.Ctime); err != nil {
fmt.Println("add log ", err)
log.Error("add question: d.db.Exec(%v) error(%v)", l, err)
return
}
return res.RowsAffected()
}
// SettingList get all setting list
func (d *Dao) SettingList(c context.Context) (list []*model.Setting, err error) {
var (
rows *xsql.Rows
)
list = make([]*model.Setting, 0)
if rows, err = d.db.Query(c, _getSettingListSQL); err != nil {
log.Error("d.db.Query(%s) error(%v)", _getSettingListSQL, err)
return
}
defer rows.Close()
for rows.Next() {
var setting = &model.Setting{}
if err = rows.Scan(&setting.ID, &setting.Property, &setting.Name, &setting.Val, &setting.CTime, &setting.MTime); err != nil {
log.Error("rows.Scan() error(%v)", err)
return
}
list = append(list, setting)
}
return
}
// UpdateSetting update setting
func (d *Dao) UpdateSetting(c context.Context, property string, val string) (affected int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _updateSettingSQL, val, property); err != nil {
log.Error("d.db.Exec(%s,%d,%s) error(%v)", _updateSettingSQL, val, property)
return
}
if affected, err = res.RowsAffected(); err != nil {
log.Error("res.RowsAffected() error(%v)", err)
return
}
return
}
func hitInfo(id int64) int64 {
return id % conf.Conf.Property.UserInfoShard
}
// Info get lastest user info by mid.
func (d *Dao) Info(c context.Context, mid int64) (res *model.UserInfo, err error) {
res = &model.UserInfo{}
hitIndex := hitInfo(mid)
row := d.getUserInfoStmt[hitIndex].QueryRow(c, mid)
if err = row.Scan(&res.ID, &res.Mid, &res.Score, &res.BaseScore, &res.EventScore, &res.State, &res.ReliveTimes,
&res.Mtime); err != nil {
if err == sql.ErrNoRows {
err = nil
res = nil
return
}
log.Error("Info:row.Scan() error(%v)", err)
}
return
}
//AddFactor add factor.
func (d *Dao) AddFactor(c context.Context, f *model.Factor) (ret int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _addFactorSQL, f.NickName, f.ServiceID, f.EventID, f.GroupID, f.RiskLevel, f.FactorVal, f.CategoryID, f.CTime); err != nil {
log.Error("d.db AddFactor: d.db.Exec(%v) error(%v)", f, err)
return
}
ret, err = res.RowsAffected()
return
}
//AddEvent add event.
func (d *Dao) AddEvent(c context.Context, f *model.Event) (ret int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _addEventSQL, f.Name, f.NickName, f.ServiceID, f.Status, f.CTime, f.MTime); err != nil {
log.Error("d.db AddEvent: d.db.Exec(%v) error(%v)", f, err)
return
}
ret, err = res.RowsAffected()
return
}
//AddService add service.
func (d *Dao) AddService(c context.Context, f *model.Service) (ret int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _addServiceSQL, f.Name, f.NickName, f.Status, f.CTime, f.MTime); err != nil {
log.Error("d.db AddService: d.db.Exec(%v) error(%v)", f, err)
return
}
ret, err = res.RowsAffected()
return
}
//AddGroup add group.
func (d *Dao) AddGroup(c context.Context, f *model.FactorGroup) (ret int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _addGroupSQL, f.Name, f.CTime); err != nil {
log.Error("d.db AddGroup: d.db.Exec(%v) error(%v)", f, err)
return
}
ret, err = res.RowsAffected()
return
}
// ReportList report list.
func (d *Dao) ReportList(c context.Context, ps, pn int) (list []*model.ReportDto, err error) {
var (
rows *xsql.Rows
)
if ps == 0 || pn == 0 {
ps = 8
pn = 1
}
list = make([]*model.ReportDto, 0)
if rows, err = d.db.Query(c, _getReportList, (pn-1)*ps, ps); err != nil {
log.Error("d.db.Query(%s) error(%v)", _getReportList, err)
return
}
defer rows.Close()
for rows.Next() {
var r = &model.Report{}
if err = rows.Scan(&r.ID, &r.Name, &r.DateVersion, &r.Val, &r.Ctime); err != nil {
log.Error("rows.Scan() error(%v)", err)
return
}
list = append(list, &model.ReportDto{
ID: r.ID,
Name: r.Name,
DateVersion: r.DateVersion,
Val: r.Val,
Ctime: r.Ctime.Unix(),
})
}
return
}
// ReportCount get repoet total count.
func (d *Dao) ReportCount(c context.Context) (totalCount int, err error) {
var row = d.db.QueryRow(c, _getReportCount)
if err = row.Scan(&totalCount); err != nil {
if err == sql.ErrNoRows {
row = nil
err = nil
} else {
log.Error("row.Scan error(%v)", err)
}
}
return
}
// UpdateStatState update stat state.
func (d *Dao) UpdateStatState(c context.Context, state int8, id int64) (affected int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _updateStatStateSQL, state, id); err != nil {
log.Error("d.db.Exec(%s,%d,%s) error(%v)", _updateStatStateSQL, state, id)
return
}
if affected, err = res.RowsAffected(); err != nil {
log.Error("res.RowsAffected() error(%v)", err)
return
}
return
}
// UpdateStatQuantity update stat quantity
func (d *Dao) UpdateStatQuantity(c context.Context, count int64, id int64) (affected int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _updateStatQuantitySQL, count, id); err != nil {
log.Error("d.db.Exec(%s,%d,%s) error(%v)", _updateStatQuantitySQL, count, id)
return
}
if affected, err = res.RowsAffected(); err != nil {
log.Error("res.RowsAffected() error(%v)", err)
return
}
return
}
// DeleteStat delete stat.
func (d *Dao) DeleteStat(c context.Context, isdel int8, id int64) (affected int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _updateStatDeleteSQL, isdel, id); err != nil {
log.Error("d.db.Exec(%s,%d,%s) error(%v)", _updateStatDeleteSQL, isdel, id)
return
}
if affected, err = res.RowsAffected(); err != nil {
log.Error("res.RowsAffected() error(%v)", err)
return
}
return
}
// Statistics get stat info by id from db.
func (d *Dao) Statistics(c context.Context, id int64) (stat *model.Statistics, err error) {
var (
row *xsql.Row
)
stat = &model.Statistics{}
row = d.db.QueryRow(c, _statByIDSQL, id)
if err = row.Scan(&stat.ID, &stat.TargetMid, &stat.TargetID, &stat.EventID, &stat.State, &stat.Type, &stat.Quantity, &stat.Isdel, &stat.Ctime, &stat.Mtime); err != nil {
if err == sql.ErrNoRows {
err = nil
stat = nil
return
}
log.Error("row.Scan() error(%v)", err)
}
return
}
//LogList log list.
func (d *Dao) LogList(c context.Context, refID int64, module int8) (list []*model.Log, err error) {
var (
rows *xsql.Rows
)
list = make([]*model.Log, 0)
if rows, err = d.db.Query(c, _logListSQL, refID, module); err != nil {
log.Error("d.db.Query(%s) error(%v)", _logListSQL, err)
return
}
defer rows.Close()
for rows.Next() {
var r = &model.Log{}
if err = rows.Scan(&r.ID, &r.RefID, &r.Name, &r.Module, &r.Context, &r.Ctime); err != nil {
log.Error("rows.Scan() error(%v)", err)
return
}
list = append(list, &model.Log{
ID: r.ID,
RefID: r.RefID,
Name: r.Name,
Module: r.Module,
Context: r.Context,
CtimeUnix: r.Ctime.Unix(),
})
}
return
}
//StatListByMid stat list by mid.
func (d *Dao) StatListByMid(c context.Context, mid int64, pn, ps int) (list []*model.Statistics, err error) {
var (
rows *xsql.Rows
)
if ps == 0 || pn == 0 {
ps = 8
pn = 1
}
list = make([]*model.Statistics, 0)
if rows, err = d.db.Query(c, _statListByMidSQL, mid, (pn-1)*ps, ps); err != nil {
log.Error("d.db.Query(%s) error(%v)", _statListByMidSQL, err)
return
}
defer rows.Close()
for rows.Next() {
var stat = &model.Statistics{}
if err = rows.Scan(&stat.ID, &stat.TargetMid, &stat.TargetID, &stat.EventID, &stat.State, &stat.Type, &stat.Quantity, &stat.Isdel, &stat.Ctime, &stat.Mtime); err != nil {
log.Error("rows.Scan() error(%v)", err)
return
}
list = append(list, &model.Statistics{
ID: stat.ID,
TargetMid: stat.TargetMid,
TargetID: stat.TargetID,
EventID: stat.EventID,
Type: stat.Type,
State: stat.State,
Quantity: stat.Quantity,
Isdel: stat.Isdel,
Ctime: stat.Ctime,
Mtime: stat.Mtime,
CtimeUnix: stat.Ctime.Unix(),
MtimeUnix: stat.Mtime.Unix(),
})
}
return
}
//StatListByID stat list by id.
func (d *Dao) StatListByID(c context.Context, id int64, t int8, pn, ps int) (list []*model.Statistics, err error) {
var (
rows *xsql.Rows
)
if ps == 0 || pn == 0 {
ps = 8
pn = 1
}
list = make([]*model.Statistics, 0)
if rows, err = d.db.Query(c, _statListByIDSQL, id, t, (pn-1)*ps, ps); err != nil {
log.Error("d.db.Query(%s) error(%v)", _statListByIDSQL, err)
return
}
defer rows.Close()
for rows.Next() {
var stat = &model.Statistics{}
if err = rows.Scan(&stat.ID, &stat.TargetMid, &stat.TargetID, &stat.EventID, &stat.State, &stat.Type, &stat.Quantity, &stat.Isdel, &stat.Ctime, &stat.Mtime); err != nil {
log.Error("rows.Scan() error(%v)", err)
return
}
list = append(list, &model.Statistics{
ID: stat.ID,
TargetMid: stat.TargetMid,
TargetID: stat.TargetID,
EventID: stat.EventID,
Type: stat.Type,
State: stat.State,
Quantity: stat.Quantity,
Isdel: stat.Isdel,
Ctime: stat.Ctime,
Mtime: stat.Mtime,
CtimeUnix: stat.Ctime.Unix(),
MtimeUnix: stat.Mtime.Unix(),
})
}
return
}
// StatCountByMid count by mid.
func (d *Dao) StatCountByMid(c context.Context, mid int64) (totalCount int64, err error) {
row := d.db.QueryRow(c, _statCountByMidSQL, mid)
if err = row.Scan(&totalCount); err != nil {
if err == sql.ErrNoRows {
row = nil
err = nil
} else {
log.Error("row.Scan error(%v)", err)
}
}
return
}
// StatCountByID count by id.
func (d *Dao) StatCountByID(c context.Context, id int64, t int8) (totalCount int64, err error) {
row := d.db.QueryRow(c, _statCountByIDSQL, id, t)
if err = row.Scan(&totalCount); err != nil {
if err == sql.ErrNoRows {
row = nil
err = nil
} else {
log.Error("row.Scan error(%v)", err)
}
}
return
}
//AllEvent all event.
func (d *Dao) AllEvent(c context.Context) (list []*model.Event, err error) {
var (
rows *xsql.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
}
// UpdateEventName update event name.
func (d *Dao) UpdateEventName(c context.Context, e *model.Event) (affected int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _updateEventNameSQL, e.NickName, e.ID); err != nil {
log.Error("_updateEventNameSQL: db.Exec(%v, %d) error(%v)", e.NickName, e.ID, err)
return
}
return res.RowsAffected()
}

View File

@ -0,0 +1,74 @@
package dao
import (
"context"
"fmt"
"testing"
"go-common/app/admin/main/spy/model"
. "github.com/smartystreets/goconvey/convey"
)
var (
statID int64 = 3
statState int8 = 1
statCount int64 = 1
statIsdel int8 = 1
statMid int64 = 1
statType int8 = 2
pn = 1
ps = 8
)
// go test -test.v -test.run TestDB
func TestDB(t *testing.T) {
Convey(" UpdateStatState ", t, WithMysql(func(d *Dao) {
_, err := d.UpdateStatState(context.TODO(), statState, statID)
So(err, ShouldBeNil)
}))
Convey(" UpdateStatQuantity ", t, WithMysql(func(d *Dao) {
_, err := d.UpdateStatQuantity(context.TODO(), statCount, statID)
So(err, ShouldBeNil)
}))
Convey(" DeleteStat ", t, WithMysql(func(d *Dao) {
_, err := d.DeleteStat(context.TODO(), statIsdel, statID)
So(err, ShouldBeNil)
}))
Convey(" Statistics ", t, WithMysql(func(d *Dao) {
stat, err := d.Statistics(context.TODO(), statID)
So(err, ShouldBeNil)
fmt.Println("stat", stat)
}))
Convey(" LogList ", t, WithMysql(func(d *Dao) {
logs, err := d.LogList(context.TODO(), statID, model.UpdateStat)
So(err, ShouldBeNil)
for _, l := range logs {
fmt.Println(l.Context)
}
}))
Convey(" StatListByMid ", t, WithMysql(func(d *Dao) {
stat, err := d.StatListByMid(context.TODO(), statMid, pn, ps)
So(err, ShouldBeNil)
for _, s := range stat {
fmt.Println(s.EventID)
}
}))
Convey(" StatListByID ", t, WithMysql(func(d *Dao) {
stat, err := d.StatListByID(context.TODO(), statID, statType, pn, ps)
So(err, ShouldBeNil)
for _, s := range stat {
fmt.Println(s.EventID)
}
}))
Convey(" StatCountByMid ", t, WithMysql(func(d *Dao) {
stat, err := d.StatCountByMid(context.TODO(), statMid)
So(err, ShouldBeNil)
fmt.Println("count ", stat)
}))
Convey(" StatCountByID ", t, WithMysql(func(d *Dao) {
stat, err := d.StatCountByID(context.TODO(), statID, statType)
So(err, ShouldBeNil)
fmt.Println("count ", stat)
}))
}

View File

@ -0,0 +1,88 @@
package dao
import (
"context"
accmdl "go-common/app/service/main/account/model"
spymdl "go-common/app/service/main/spy/model"
"go-common/library/log"
"go-common/library/net/metadata"
)
// UserScore get userscore by id , will init score if score not exist.
func (d *Dao) UserScore(c context.Context, mid int64) (userScore *spymdl.UserScore, err error) {
var argUserScore = &spymdl.ArgUserScore{
Mid: mid,
IP: metadata.String(c, metadata.RemoteIP),
}
if userScore, err = d.spyRPC.UserScore(c, argUserScore); err != nil {
log.Error("dao.spyRPC.UserScore(%v) error(%v)", argUserScore, err)
return
}
return
}
// AccInfo get account info by mid
func (d *Dao) AccInfo(c context.Context, mid int64) (ai *accmdl.Info, err error) {
arg := &accmdl.ArgMid{Mid: mid}
if ai, err = d.accRPC.Info3(c, arg); err != nil || ai == nil {
log.Error("s.accRPC.Info(%d) error(%v)", mid, err)
}
return
}
// ResetBase reset user base score.
func (d *Dao) ResetBase(c context.Context, mid int64, operator string) (err error) {
arg := &spymdl.ArgReset{
Mid: mid,
BaseScore: true,
Operator: operator,
}
if err = d.spyRPC.UpdateBaseScore(c, arg); err != nil {
log.Error("s.spyRPC.UpdateBaseScore(%v) error(%v)", arg, err)
return
}
return
}
// RefreshBase reset user base score.
func (d *Dao) RefreshBase(c context.Context, mid int64, operator string) (err error) {
arg := &spymdl.ArgReset{
Mid: mid,
BaseScore: true,
Operator: operator,
}
if err = d.spyRPC.RefreshBaseScore(c, arg); err != nil {
log.Error("s.spyRPC.RefreshBaseScore(%v) error(%v)", arg, err)
return
}
return
}
// ResetEvent reset user event score.
func (d *Dao) ResetEvent(c context.Context, mid int64, operator string) (err error) {
arg := &spymdl.ArgReset{
Mid: mid,
EventScore: true,
Operator: operator,
}
if err = d.spyRPC.UpdateEventScore(c, arg); err != nil {
log.Error("s.spyRPC.UpdateEventScore(%v) error(%v)", arg, err)
return
}
return
}
// ClearCount clear count.
func (d *Dao) ClearCount(c context.Context, mid int64, operator string) (err error) {
arg := &spymdl.ArgReset{
Mid: mid,
ReLiveTime: true,
Operator: operator,
}
if err = d.spyRPC.ClearReliveTimes(c, arg); err != nil {
log.Error("d.spyRPC.ClearReliveTimes(%v) error(%v)", arg, err)
return
}
return
}

View File

@ -0,0 +1,44 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"factor.go",
"http.go",
"report.go",
"setting.go",
"stat.go",
"user.go",
],
importpath = "go-common/app/admin/main/spy/http",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/spy/conf:go_default_library",
"//app/admin/main/spy/model:go_default_library",
"//app/admin/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"],
)

View File

@ -0,0 +1,230 @@
package http
import (
"strconv"
"strings"
"time"
"go-common/app/admin/main/spy/model"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
func factors(c *bm.Context) {
var (
data []*model.Factors
err error
)
data, err = spySrv.Factors(c)
if err != nil {
log.Error("spySrv.Factors error(%v)", err)
c.JSON(data, err)
return
}
c.JSON(data, err)
}
func updateFactor(c *bm.Context) {
var (
params = c.Request.Form
idsStr = params.Get("ids")
name = params.Get("name")
fs []*model.Factor
err error
)
if name == "" {
c.JSON(nil, ecode.RequestErr)
return
}
idsArr := strings.Split(idsStr, ",")
for _, idStr := range idsArr {
id, theErr := strconv.ParseInt(idStr, 10, 64)
if theErr != nil {
c.JSON(nil, ecode.RequestErr)
return
}
factorVal, theErr := strconv.ParseFloat(params.Get("id_"+idStr), 32)
if theErr != nil || factorVal < 0 || factorVal > 1 {
c.JSON(nil, ecode.RequestErr)
return
}
fs = append(fs, &model.Factor{ID: id, FactorVal: float32(factorVal)})
}
err = spySrv.UpdateFactor(c, fs, name)
if err != nil {
log.Error("spySrv.UpdateFactor(%v) error(%v)", fs, err)
c.JSON(nil, err)
return
}
c.JSON(nil, nil)
}
func addFactor(c *bm.Context) {
var (
params = c.Request.Form
nickname = params.Get("nick_name")
serviceID int64
eventID int64
groupID int64
riskLevel int64
factorVal float64
categoryID int64
err error
)
if serviceID, err = strconv.ParseInt(params.Get("service_id"), 10, 64); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
if eventID, err = strconv.ParseInt(params.Get("event_id"), 10, 64); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
if groupID, err = strconv.ParseInt(params.Get("group_id"), 10, 64); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
if riskLevel, err = strconv.ParseInt(params.Get("risk_level"), 10, 8); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
if factorVal, err = strconv.ParseFloat(params.Get("factor_val"), 32); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
if categoryID, err = strconv.ParseInt(params.Get("category_id"), 10, 8); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
if factorVal > 1 || factorVal <= 0 {
c.JSON(nil, ecode.RequestErr)
return
}
if riskLevel < 1 || riskLevel > 10 {
c.JSON(nil, ecode.RequestErr)
return
}
err = spySrv.AddFactor(c, &model.Factor{
NickName: nickname,
ServiceID: serviceID,
EventID: eventID,
GroupID: groupID,
RiskLevel: int8(riskLevel),
FactorVal: float32(factorVal),
CTime: time.Now(),
CategoryID: int8(categoryID),
})
if err != nil {
log.Error("spySrv.AddFactor error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(nil, nil)
}
func addEvent(c *bm.Context) {
var (
params = c.Request.Form
name = params.Get("name")
nickName = params.Get("nick_name")
err error
serviceID int64
status int64
)
if serviceID, err = strconv.ParseInt(params.Get("service_id"), 10, 64); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
if status, err = strconv.ParseInt(params.Get("status"), 10, 8); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
err = spySrv.AddEvent(c, &model.Event{
Name: name,
NickName: nickName,
ServiceID: serviceID,
Status: int8(status),
CTime: time.Now(),
MTime: time.Now(),
})
if err != nil {
log.Error("spySrv.AddEvent error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(nil, nil)
}
func addService(c *bm.Context) {
var (
params = c.Request.Form
name = params.Get("name")
nickName = params.Get("nick_name")
err error
status int64
)
if status, err = strconv.ParseInt(params.Get("status"), 10, 8); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
err = spySrv.AddService(c, &model.Service{
Name: name,
NickName: nickName,
Status: int8(status),
CTime: time.Now(),
MTime: time.Now(),
})
if err != nil {
log.Error("spySrv.AddService error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(nil, nil)
}
func addGroup(c *bm.Context) {
var (
params = c.Request.Form
name = params.Get("name")
err error
)
err = spySrv.AddGroup(c, &model.FactorGroup{
Name: name,
CTime: time.Now(),
})
if err != nil {
log.Error("spySrv.AddGroup error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(nil, nil)
}
func updateEventName(c *bm.Context) {
var (
params = c.Request.Form
nickname string
id int64
err error
)
nickname = params.Get("nickname")
if err != nil || len(nickname) > model.MaxRemarkLen {
c.JSON(nil, ecode.RequestErr)
return
}
id, err = strconv.ParseInt(params.Get("id"), 10, 64)
if err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
err = spySrv.UpdateEventName(c, &model.Event{
ID: id,
NickName: nickname,
})
if err != nil {
log.Error("spySrv.UpdateEventName error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(nil, nil)
}

View File

@ -0,0 +1,99 @@
package http
import (
"net/http"
"go-common/app/admin/main/spy/conf"
"go-common/app/admin/main/spy/service"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/middleware/verify"
)
var (
spySrv *service.Service
vfySvc *verify.Verify
)
// Init init http sever instance.
func Init(c *conf.Config) {
initService(c)
// init inner router
engine := bm.DefaultServer(c.HTTPServer)
innerRouter(engine)
// init inner server
if err := engine.Start(); err != nil {
log.Error("engine.Start error(%v)", err)
panic(err)
}
}
// innerRouter init inner router.
func innerRouter(e *bm.Engine) {
// health check
e.Ping(ping)
spy := e.Group("/x/admin/spy", vfySvc.Verify)
score := spy.Group("/score")
score.GET("/query", userInfo)
score.GET("/record", historyPage)
score.POST("/base/reset", resetBase)
score.POST("/base/refresh", refreshBase)
score.POST("/event/reset", resetEvent)
spy.POST("/stat/clear", clearCount)
factor := spy.Group("/factor")
factor.GET("/list", factors)
factor.POST("/add", addFactor)
factor.POST("/modify", updateFactor)
spy.POST("/event/add", addEvent)
spy.POST("/event/modify", updateEventName)
spy.POST("/service/add", addService)
spy.POST("/group/add", addGroup)
setting := spy.Group("/setting")
setting.GET("/list", settingList)
setting.POST("/add", updateSetting)
sin := spy.Group("/sin")
sin.POST("/state/update", updateStatState)
sin.POST("/quantity/update", updateStatQuantity)
sin.POST("/delete", deleteStat)
sin.POST("/remark/add", addRemark)
sin.GET("/remark/list", remarkList)
sin.GET("/page", statPage)
spy.GET("/report", report)
spyWithoutAuth := e.Group("/x/admin/spy/internal")
spyWithoutAuth.POST("/event/add", addEvent)
spyWithoutAuth.POST("/event/modify", updateEventName)
scoreWithoutAuth := spyWithoutAuth.Group("/score")
scoreWithoutAuth.GET("/query", userInfo)
scoreWithoutAuth.GET("/record", historyPage)
scoreWithoutAuth.POST("/base/reset", resetBase)
scoreWithoutAuth.POST("/base/refresh", refreshBase)
scoreWithoutAuth.POST("/event/reset", resetEvent)
factorWithoutAuth := spyWithoutAuth.Group("/factor")
factorWithoutAuth.GET("/list", factors)
factorWithoutAuth.POST("/add", addFactor)
factorWithoutAuth.POST("/modify", updateFactor)
}
// ping check server ok.
func ping(c *bm.Context) {
if err := spySrv.Ping(c); err != nil {
log.Error("spy admin ping error(%v)", err)
c.JSON(nil, err)
c.AbortWithStatus(http.StatusServiceUnavailable)
}
}
func initService(c *conf.Config) {
spySrv = service.New(c)
vfySvc = verify.New(nil)
}

View File

@ -0,0 +1,31 @@
package http
import (
"strconv"
"go-common/app/admin/main/spy/model"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
func report(c *bm.Context) {
var (
params = c.Request.Form
pn, ps int
err error
data *model.ReportPage
)
if ps, err = strconv.Atoi(params.Get("ps")); err != nil {
ps = model.DefPs
}
if pn, err = strconv.Atoi(params.Get("pn")); err != nil {
pn = model.DefPn
}
data, err = spySrv.ReportList(c, ps, pn)
if err != nil {
log.Error("spySrv.ReportList error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, err)
}

View File

@ -0,0 +1,40 @@
package http
import (
"go-common/app/admin/main/spy/model"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
func settingList(c *bm.Context) {
var (
err error
data []*model.Setting
)
if data, err = spySrv.SettingList(c); err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, err)
}
func updateSetting(c *bm.Context) {
var (
err error
params = c.Request.Form
name = params.Get("name")
prop = params.Get("prop")
val = params.Get("val")
)
if name == "" || prop == "" || val == "" {
c.JSON(nil, ecode.RequestErr)
return
}
if err = spySrv.UpdateSetting(c, name, prop, val); err != nil {
log.Error("s.UpdateSetting(%s,%s,%s) error(%v)", name, prop, val, err)
c.JSON(nil, err)
return
}
c.JSON(nil, nil)
}

View File

@ -0,0 +1,197 @@
package http
import (
"strconv"
"go-common/app/admin/main/spy/model"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
func updateStatState(c *bm.Context) {
var (
params = c.Request.Form
state int64
id int64
operater string
err error
)
state, err = strconv.ParseInt(params.Get("state"), 10, 8)
if err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
id, err = strconv.ParseInt(params.Get("id"), 10, 64)
if err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
operater = params.Get("operater")
if operater == "" {
c.JSON(nil, ecode.RequestErr)
return
}
err = spySrv.UpdateState(c, int8(state), id, operater)
if err != nil {
log.Error("spySrv.UpdateState error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(nil, nil)
}
func updateStatQuantity(c *bm.Context) {
var (
params = c.Request.Form
count int64
id int64
operater string
err error
)
count, err = strconv.ParseInt(params.Get("count"), 10, 64)
if err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
id, err = strconv.ParseInt(params.Get("id"), 10, 64)
if err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
operater = params.Get("operater")
if operater == "" {
c.JSON(nil, ecode.RequestErr)
return
}
err = spySrv.UpdateStatQuantity(c, count, id, operater)
if err != nil {
log.Error("spySrv.UpdateStatQuantity error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(nil, err)
}
func deleteStat(c *bm.Context) {
var (
params = c.Request.Form
id int64
operater string
err error
)
id, err = strconv.ParseInt(params.Get("id"), 10, 64)
if err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
operater = params.Get("operater")
if operater == "" {
c.JSON(nil, ecode.RequestErr)
return
}
err = spySrv.DeleteStat(c, 1, id, operater)
if err != nil {
log.Error("spySrv.DeleteStat error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(nil, err)
}
func addRemark(c *bm.Context) {
var (
params = c.Request.Form
remark string
id int64
operater string
err error
)
remark = params.Get("remark")
if err != nil || len(remark) > model.MaxRemarkLen {
c.JSON(nil, ecode.RequestErr)
return
}
id, err = strconv.ParseInt(params.Get("id"), 10, 64)
if err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
operater = params.Get("operater")
if operater == "" {
c.JSON(nil, ecode.RequestErr)
return
}
err = spySrv.AddLog2(c, &model.Log{
RefID: id,
Name: operater,
Module: model.UpdateStat,
Context: remark,
})
if err != nil {
log.Error("spySrv.AddLog2 error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(nil, err)
}
func remarkList(c *bm.Context) {
var (
params = c.Request.Form
id int64
err error
data []*model.Log
)
id, err = strconv.ParseInt(params.Get("id"), 10, 64)
if err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
data, err = spySrv.LogList(c, id, model.UpdateStat)
if err != nil {
log.Error("spySrv.logList error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, err)
}
func statPage(c *bm.Context) {
var (
params = c.Request.Form
id int64
mid int64
t int64
ps, pn int
err error
data *model.StatPage
)
id, err = strconv.ParseInt(params.Get("id"), 10, 64)
if err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
t, err = strconv.ParseInt(params.Get("type"), 10, 8)
if err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
if int8(t) == model.AccountType {
mid = id
id = 0
}
if ps, err = strconv.Atoi(params.Get("ps")); err != nil {
ps = model.DefPs
}
if pn, err = strconv.Atoi(params.Get("pn")); err != nil {
pn = model.DefPn
}
data, err = spySrv.StatPage(c, mid, id, int8(t), pn, ps)
if err != nil {
log.Error("spySrv.StatPage error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, err)
}

View File

@ -0,0 +1,160 @@
package http
import (
"strconv"
"go-common/app/admin/main/spy/model"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
func userInfo(c *bm.Context) {
var (
params = c.Request.Form
mid int64
err error
)
mid, err = strconv.ParseInt(params.Get("mid"), 10, 64)
if err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := spySrv.UserInfo(c, mid)
if err != nil {
log.Error("spySrv.UserInfo error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, err)
}
func historyPage(c *bm.Context) {
var (
params = c.Request.Form
mid int64
pn, ps int
err error
data *model.HistoryPage
)
mid, err = strconv.ParseInt(params.Get("mid"), 10, 64)
if err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
if ps, err = strconv.Atoi(params.Get("ps")); err != nil {
ps = model.DefPs
}
if pn, err = strconv.Atoi(params.Get("pn")); err != nil {
pn = model.DefPn
}
q := &model.HisParamReq{Mid: mid, Pn: pn, Ps: ps}
data, err = spySrv.HisoryPage(c, q)
if err != nil {
log.Error("spySrv.HisoryPage error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, err)
}
func resetBase(c *bm.Context) {
var (
params = c.Request.Form
name = params.Get("name")
mid int64
err error
)
if name == "" {
c.JSON(nil, ecode.RequestErr)
return
}
mid, err = strconv.ParseInt(params.Get("mid"), 10, 64)
if err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
err = spySrv.ResetBase(c, mid, name)
if err != nil {
log.Error("spySrv.ResetBase error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(nil, err)
}
func refreshBase(c *bm.Context) {
var (
params = c.Request.Form
name = params.Get("name")
mid int64
err error
)
if name == "" {
c.JSON(nil, ecode.RequestErr)
return
}
mid, err = strconv.ParseInt(params.Get("mid"), 10, 64)
if err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
err = spySrv.RefreshBase(c, mid, name)
if err != nil {
log.Error("spySrv.RefreshBase error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(nil, err)
}
func resetEvent(c *bm.Context) {
var (
params = c.Request.Form
name = params.Get("name")
mid int64
err error
)
if name == "" {
c.JSON(nil, ecode.RequestErr)
return
}
mid, err = strconv.ParseInt(params.Get("mid"), 10, 64)
if err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
err = spySrv.ResetEvent(c, mid, name)
if err != nil {
log.Error("spySrv.ResetEvent error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(nil, err)
}
func clearCount(c *bm.Context) {
var (
params = c.Request.Form
name = params.Get("name")
mid int64
err error
)
if name == "" {
c.JSON(nil, ecode.RequestErr)
return
}
mid, err = strconv.ParseInt(params.Get("mid"), 10, 64)
if err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
err = spySrv.ClearCount(c, mid, name)
if err != nil {
log.Error("spySrv.ClearCount error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(nil, err)
}

View File

@ -0,0 +1,44 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"config.go",
"event.go",
"eventhistory.go",
"eventmsg.go",
"factor.go",
"factor_group.go",
"log.go",
"page.go",
"punishment.go",
"report.go",
"service.go",
"setting.go",
"stat.go",
"userinfo.go",
],
importpath = "go-common/app/admin/main/spy/model",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = ["//library/time:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,7 @@
package model
const (
LimitBlockCount = "limitBlockCount"
LessBlockScore = "lessBlockScore"
AutoBlock = "autoBlock"
)

View File

@ -0,0 +1,16 @@
package model
import (
"time"
)
// Event def.
type Event struct {
ID int64
Name string // 事件标示
NickName string // 事件可读昵称
ServiceID int64
Status int8 // 0:删除 1:未删除
CTime time.Time
MTime time.Time
}

View File

@ -0,0 +1,49 @@
package model
import (
"time"
)
// EventHistory def.
type EventHistory struct {
ID int64
Mid int64 // 用户ID
EventID int64 // 事件ID
Score int8 // 用户真实分
BaseScore int8 // 基础信息得分
EventScore int8 // 事件得分
Remark string // 备注
Reason string // 原因
FactorVal float32 // 风险因子
Ctime time.Time // 创建时间
TargetID int64 // 目标id
TargetMid int64 // 目标mid
SpyTime time.Time // 作弊时间
}
// EventHistoryDto dto.
type EventHistoryDto struct {
ID int64 `json:"id"`
Score int8 `json:"score"` // 用户真实分
BaseScore int8 `json:"base_score"` // 基础信息得分
EventScore int8 `json:"event_score"` // 事件得分
Reason string `json:"reason"` // 原因
Ctime int64 `json:"ctime"` // 创建时间
TargetID int64 `json:"target_id"` // 目标id
TargetMid int64 `json:"target_mid"` // 目标mid
SpyTime int64 `json:"spy_time"` // 作弊时间
}
// HisParamReq def.
type HisParamReq struct {
Mid int64
Pn, Ps int
}
// HistoryPage def.
type HistoryPage struct {
TotalCount int `json:"total_count"`
Pn int `json:"pn"`
Ps int `json:"ps"`
Items []*EventHistoryDto `json:"items"`
}

View File

@ -0,0 +1,16 @@
package model
// EventMessage event from bigdata def.
type EventMessage struct {
Time int64 `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"`
}

View File

@ -0,0 +1,28 @@
package model
import (
"time"
)
// Factor def.
type Factor struct {
ID int64 `json:"id"`
NickName string `json:"nick_name"` //风险因子名字
ServiceID int64 `json:"service_id"` //服务ID
EventID int64 `json:"event_id"` //事件ID
GroupID int64 `json:"group_id"` //分组ID
RiskLevel int8 `json:"risk_level"` //风险等级1-9
FactorVal float32 `json:"factor_val"` //因子值
CTime time.Time `json:"ctime"` //创建时间
MTime time.Time `json:"mtime"` //修改时间
CategoryID int8 `json:"category_id"` //CategoryID
}
// Factors etc.
type Factors struct {
ID int64 `json:"id"`
GroupID int64 `json:"group_id"` //分组ID
GroupName string `json:"group_name"` //分组名称
NickName string `json:"nick_name"` //风险因子名字
FactorVal float32 `json:"factor_val"` //因子值
}

View File

@ -0,0 +1,12 @@
package model
import (
"time"
)
// FactorGroup etc.
type FactorGroup struct {
ID int64
Name string //风险因子组名
CTime time.Time
}

View File

@ -0,0 +1,29 @@
package model
import "time"
// Module etc.
const (
UpdateFactor int8 = iota + 1 // 修改因子操作
UpdateSetting
UpdateStat
)
// stat check text.
const (
WaiteCheck = "待确认"
HadCheck = "已确认"
MaxRemarkLen = 100
)
// Log def.
type Log struct {
ID int64 `json:"id"`
RefID int64 `json:"ref_id"` // 关联ID
Name string `json:"name"` //操作用户
Module int8 `json:"module"` //操作名称
Context string `json:"context"` //操作内容
Ctime time.Time `json:"ctime"` //创建时间
CtimeUnix int64 `json:"ctime_unix"` //创建时间
}

View File

@ -0,0 +1,8 @@
package model
// page etc.
const (
DefPn = 1
DefPs = 10
NoParam = -1
)

View File

@ -0,0 +1,14 @@
package model
import (
"go-common/library/time"
)
// Punishment def.
type Punishment struct {
ID int64
Mid int64
Type int8 //惩罚类型 1.自动封禁
Reason string //惩罚原因
CTime time.Time
}

View File

@ -0,0 +1,36 @@
package model
import "time"
// Report etc.
type Report struct {
ID int64
Name string
DateVersion string
Val int64
Ctime time.Time
}
// ReportDto etc.
type ReportDto struct {
ID int64 `json:"id"`
Name string `json:"name"`
DateVersion string `json:"date_version"`
Val int64 `json:"val"`
Ctime int64 `json:"ctime"`
}
// ReportPage def.
type ReportPage struct {
TotalCount int `json:"total_count"`
Pn int `json:"pn"`
Ps int `json:"ps"`
Items []*ReportDto `json:"items"`
}
const (
//BlockCount block count
BlockCount = "封禁总数"
// SecurityLoginCount security login count
SecurityLoginCount = "二次验证总数"
)

View File

@ -0,0 +1,15 @@
package model
import (
"time"
)
// Service def.
type Service struct {
ID int64
Name string //服务标识
NickName string //服务可读昵称
Status int8
CTime time.Time
MTime time.Time
}

View File

@ -0,0 +1,15 @@
package model
import (
"go-common/library/time"
)
// Setting def.
type Setting struct {
ID int64 `json:"id"`
Property string `json:"property"`
Name string `json:"name"`
Val string `json:"val"`
CTime time.Time `json:"ctime"`
MTime time.Time `json:"mtime"`
}

View File

@ -0,0 +1,35 @@
package model
import "time"
// type def.
const (
AccountType = iota
ArchiveType
ActivityType
)
// Statistics def.
type Statistics struct {
ID int64 `json:"id"`
TargetMid int64 `json:"target_mid"`
TargetID int64 `json:"target_id"`
EventID int64 `json:"event_id"`
State int8 `json:"state"`
Type int8 `json:"type"`
Isdel int8 `json:"is_del"`
Quantity int64 `json:"quantity"`
EventName string `json:"event_name"`
Ctime time.Time `json:"ctime"`
Mtime time.Time `json:"mtime"`
CtimeUnix int64 `json:"ctimeunix"`
MtimeUnix int64 `json:"mtimeunix"`
}
// StatPage def.
type StatPage struct {
TotalCount int64 `json:"total_count"`
Pn int `json:"pn"`
Ps int `json:"ps"`
Items []*Statistics `json:"items"`
}

View File

@ -0,0 +1,30 @@
package model
import (
"time"
)
// UserInfo def.
type UserInfo struct {
ID int64 `json:"id"`
Mid int64 `json:"mid"`
State int8 `json:"state"` //状态 0.正常 1.封禁
Score int8 `json:"score"` //真实分值
BaseScore int8 `json:"base_score"` //基础信息得分
EventScore int8 `json:"event_score"` //事件得分
ReliveTimes int8 `json:"relive_times"` //累计重绘次数
Mtime time.Time `json:"mtime"`
}
// UserInfoDto dto.
type UserInfoDto struct {
ID int64 `json:"id"`
Mid int64 `json:"mid"`
Name string `json:"name"` //昵称
State int8 `json:"state"` //状态 0.正常 1.封禁
Score int8 `json:"score"` //真实分值
BaseScore int8 `json:"base_score"` //基础信息得分
EventScore int8 `json:"event_score"` //事件得分
ReliveTimes int8 `json:"relive_times"` //累计重绘次数
Mtime int64 `json:"mtime"` //更新时间
}

View File

@ -0,0 +1,57 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["service_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/admin/main/spy/conf:go_default_library",
"//app/admin/main/spy/model:go_default_library",
"//library/ecode:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"factor.go",
"log.go",
"service.go",
"setting.go",
"stat.go",
"user.go",
],
importpath = "go-common/app/admin/main/spy/service",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/spy/conf:go_default_library",
"//app/admin/main/spy/dao:go_default_library",
"//app/admin/main/spy/model:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,103 @@
package service
import (
"context"
"go-common/library/log"
"go-common/app/admin/main/spy/model"
)
// Factors get all factor.
func (s *Service) Factors(c context.Context) (fs []*model.Factors, err error) {
var (
fds []*model.Factor
)
gs, err := s.spyDao.Groups(c)
if err != nil {
log.Error("spyDao.Groups error(%v)", err)
return
}
if len(gs) == 0 {
return
}
for _, v := range gs {
fds, err = s.spyDao.Factors(c, v.ID)
if err != nil {
log.Error("spyDao.Groups error(%v)", err)
return
}
if len(fds) == 0 {
continue
}
for _, f := range fds {
f := &model.Factors{
GroupID: v.ID,
GroupName: v.Name,
NickName: f.NickName,
FactorVal: f.FactorVal,
ID: f.ID,
}
fs = append(fs, f)
}
}
return
}
// UpdateFactor update factor.
func (s *Service) UpdateFactor(c context.Context, fs []*model.Factor, name string) (err error) {
for _, f := range fs {
_, err = s.spyDao.UpdateFactor(c, f.FactorVal, f.ID)
if err != nil {
log.Error("spyDao.UpdateFactor(%v,%d) error(%v)", f.FactorVal, f.ID, err)
return
}
s.AddLog(c, name, model.UpdateFactor, f)
}
return
}
// AddFactor add factor
func (s *Service) AddFactor(c context.Context, f *model.Factor) (err error) {
ret, err := s.spyDao.AddFactor(c, f)
if err != nil || ret != 1 {
log.Error("s.spyDao.AddFactor(%v) error(%v,%d)", f, err, ret)
}
return
}
// AddEvent add event
func (s *Service) AddEvent(c context.Context, f *model.Event) (err error) {
ret, err := s.spyDao.AddEvent(c, f)
if err != nil || ret != 1 {
log.Error("s.spyDao.AddEvent(%v) error(%v,%d)", f, err, ret)
}
return
}
// AddService add service
func (s *Service) AddService(c context.Context, f *model.Service) (err error) {
ret, err := s.spyDao.AddService(c, f)
if err != nil || ret != 1 {
log.Error("s.spyDao.AddService(%v) error(%v,%d)", f, err, ret)
}
return
}
// AddGroup add group
func (s *Service) AddGroup(c context.Context, f *model.FactorGroup) (err error) {
ret, err := s.spyDao.AddGroup(c, f)
if err != nil || ret != 1 {
log.Error("s.spyDao.AddGroup(%v) error(%v,%d)", f, err, ret)
}
return
}
// UpdateEventName update event name.
func (s *Service) UpdateEventName(c context.Context, event *model.Event) (err error) {
ret, err := s.spyDao.UpdateEventName(c, event)
if err != nil || ret != 1 {
log.Error("s.spyDao.UpdateEventName(%v) error(%v,%d)", event, err, ret)
}
return
}

View File

@ -0,0 +1,64 @@
package service
import (
"context"
"encoding/json"
"fmt"
"time"
"go-common/app/admin/main/spy/model"
"go-common/library/log"
)
// AddLog add log.
func (s *Service) AddLog(c context.Context, name string, m int8, v interface{}) (err error) {
b, err := json.Marshal(v)
if err != nil {
log.Error("AddLog json.Marshal(%v) error(%v)", v, err)
return
}
l := &model.Log{Name: name, Module: m, Context: string(b)}
_, err = s.spyDao.AddLog(c, l)
if err != nil {
log.Error("userDao spyDao.AddLog(%v) error(%v)", l, err)
return
}
return
}
// AddLog2 add log.
func (s *Service) AddLog2(c context.Context, l *model.Log) (err error) {
l.Ctime = time.Now()
_, err = s.spyDao.AddLog(c, l)
return
}
// LogList add log.
func (s *Service) LogList(c context.Context, refID int64, module int8) (list []*model.Log, err error) {
list, err = s.spyDao.LogList(c, refID, module)
return
}
// UpdateStateLog get log.
func (s *Service) UpdateStateLog(refID int64, state string) (log string) {
log = fmt.Sprintf("%d : 状态修改为[%s]", refID, state)
return
}
// AddRemarkLog add reamrk log.
func (s *Service) AddRemarkLog(refID int64, remark string) (log string) {
log = fmt.Sprintf("%d : [备注]%s", refID, remark)
return
}
// DeleteStatLog delete log .
func (s *Service) DeleteStatLog(refID int64) (log string) {
log = fmt.Sprintf("%d 删除记录", refID)
return
}
// UpdateStatCountLog update stat count log.
func (s *Service) UpdateStatCountLog(refID int64, old int64, new int64) (log string) {
log = fmt.Sprintf("%d [修正数值] %d -> %d", refID, old, new)
return
}

View File

@ -0,0 +1,72 @@
package service
import (
"context"
"time"
"go-common/app/admin/main/spy/conf"
spydao "go-common/app/admin/main/spy/dao"
"go-common/app/admin/main/spy/model"
"go-common/library/log"
)
// Service biz service def.
type Service struct {
c *conf.Config
spyDao *spydao.Dao
allEventName map[int64]string
loadEventTick time.Duration
}
// New new a Service and return.
func New(c *conf.Config) (s *Service) {
s = &Service{
c: c,
spyDao: spydao.New(c),
allEventName: make(map[int64]string),
loadEventTick: time.Duration(c.Property.LoadEventTick),
}
s.loadeventname()
go s.loadeventproc()
return
}
// Ping check dao health.
func (s *Service) Ping(c context.Context) (err error) {
return s.spyDao.Ping(c)
}
// Wait wait all closed.
func (s *Service) Wait() {
}
// Close close all dao.
func (s *Service) Close() {
s.spyDao.Close()
}
func (s *Service) loadeventname() (err error) {
var (
c = context.TODO()
es []*model.Event
)
es, err = s.spyDao.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.V(2).Info("loadeventname (%v) load success", tmp)
return
}
func (s *Service) loadeventproc() {
for {
time.Sleep(s.loadEventTick)
s.loadeventname()
}
}

View File

@ -0,0 +1,106 @@
package service
import (
"context"
"flag"
"fmt"
"path/filepath"
"testing"
"go-common/app/admin/main/spy/conf"
"go-common/app/admin/main/spy/model"
"go-common/library/ecode"
. "github.com/smartystreets/goconvey/convey"
)
var (
s *Service
c = context.TODO()
)
func init() {
var err error
dir, _ := filepath.Abs("../cmd/spy-admin-test.toml")
flag.Set("conf", dir)
if err = conf.Init(); err != nil {
panic(err)
}
s = New(conf.Conf)
}
func TestSetting(t *testing.T) {
Convey("test checkSettingVal", t, func() {
var err = s.checkSettingVal(model.AutoBlock, "abc")
So(err, ShouldEqual, ecode.SpySettingValTypeError)
err = s.checkSettingVal(model.AutoBlock, "3")
So(err, ShouldEqual, ecode.SpySettingValueOutOfRange)
err = s.checkSettingVal(model.AutoBlock, "1")
So(err, ShouldBeNil)
err = s.checkSettingVal(model.LessBlockScore, "abc")
So(err, ShouldEqual, ecode.SpySettingValTypeError)
err = s.checkSettingVal(model.LessBlockScore, "45")
So(err, ShouldEqual, ecode.SpySettingValueOutOfRange)
err = s.checkSettingVal(model.LessBlockScore, "1")
So(err, ShouldBeNil)
err = s.checkSettingVal(model.LimitBlockCount, "abc")
So(err, ShouldEqual, ecode.SpySettingValTypeError)
err = s.checkSettingVal(model.LimitBlockCount, "-2")
So(err, ShouldEqual, ecode.SpySettingValueOutOfRange)
err = s.checkSettingVal(model.LimitBlockCount, "20000")
So(err, ShouldBeNil)
err = s.checkSettingVal("unknown prop", "abc")
So(err, ShouldEqual, ecode.SpySettingUnknown)
})
Convey("test Setting", t, func() {
var (
list []*model.Setting
err error
)
list, err = s.SettingList(c)
So(err, ShouldBeNil)
So(list, ShouldNotBeEmpty)
var (
name = "go test"
prop = list[0].Property
val = list[0].Val
)
err = s.UpdateSetting(c, name, prop, val)
So(err, ShouldBeNil)
err = s.UpdateSetting(c, name, model.LessBlockScore, "100")
So(err, ShouldEqual, ecode.SpySettingValueOutOfRange)
})
}
// go test -test.v -test.run TestStat
func TestStat(t *testing.T) {
var (
state int8 = 1
id int64 = 3
isdel int8 = 1
tid int64 = 1
tmid int64 = 1
ty int8 = 1
count int64 = 10
operater = "admin"
pn = 1
ps = 8
)
Convey("test UpdateState", t, func() {
err := s.UpdateState(c, state, id, operater)
So(err, ShouldBeNil)
})
Convey("test UpdateStatQuantity", t, func() {
err := s.UpdateStatQuantity(c, count, id, operater)
So(err, ShouldBeNil)
})
Convey("test DeleteStat", t, func() {
err := s.DeleteStat(c, isdel, id, operater)
So(err, ShouldBeNil)
})
Convey("test StatPage", t, func() {
page, err := s.StatPage(c, tmid, tid, ty, pn, ps)
So(err, ShouldBeNil)
fmt.Println("page", page)
})
}

View File

@ -0,0 +1,76 @@
package service
import (
"context"
"strconv"
"go-common/app/admin/main/spy/model"
"go-common/library/ecode"
"go-common/library/log"
)
// SettingList get all setting
func (s *Service) SettingList(c context.Context) (list []*model.Setting, err error) {
if list, err = s.spyDao.SettingList(c); err != nil {
log.Error("s.spyDao.SettingList() error(%v)", err)
return
}
return
}
// UpdateSetting update setting
func (s *Service) UpdateSetting(c context.Context, name string, property string, val string) (err error) {
if err = s.checkSettingVal(property, val); err != nil {
return
}
var effected int64
if effected, err = s.spyDao.UpdateSetting(c, property, val); err != nil {
log.Error("s.spyDao.UpdateSetting(%s,%d) error(%v)", property, val, err)
return
}
if effected > 0 {
updatedSetting := &model.Setting{Property: property, Val: val}
if err := s.AddLog(c, name, model.UpdateSetting, updatedSetting); err != nil {
log.Error("s.AddLog(%s,%d,%+v) error(%v)", name, model.UpdateSetting, updatedSetting, err)
}
}
return
}
func (s *Service) checkSettingVal(prop string, val string) (err error) {
switch prop {
case model.AutoBlock:
var block int64
if block, err = strconv.ParseInt(val, 10, 64); err != nil {
err = ecode.SpySettingValTypeError
return
}
if block != 1 && block != 0 {
err = ecode.SpySettingValueOutOfRange
return
}
case model.LimitBlockCount:
var count int64
if count, err = strconv.ParseInt(val, 10, 64); err != nil {
err = ecode.SpySettingValTypeError
return
}
if count < 0 {
err = ecode.SpySettingValueOutOfRange
return
}
case model.LessBlockScore:
var score int64
if score, err = strconv.ParseInt(val, 10, 64); err != nil {
err = ecode.SpySettingValTypeError
return
}
if score < 0 || score > 30 {
err = ecode.SpySettingValueOutOfRange
return
}
default:
err = ecode.SpySettingUnknown
}
return err
}

View File

@ -0,0 +1,95 @@
package service
import (
"context"
"time"
"go-common/app/admin/main/spy/model"
)
// UpdateState update spy state.
func (s *Service) UpdateState(c context.Context, state int8, id int64, operater string) (err error) {
var (
context string
)
if _, err = s.spyDao.UpdateStatState(c, state, id); err != nil {
return
}
if state == 0 {
context = model.WaiteCheck
} else {
context = model.HadCheck
}
s.AddLog2(c, &model.Log{
Name: operater,
RefID: id,
Module: model.UpdateStat,
Context: s.UpdateStateLog(id, context),
Ctime: time.Now(),
})
return
}
// UpdateStatQuantity update stat quantity.
func (s *Service) UpdateStatQuantity(c context.Context, count, id int64, operater string) (err error) {
var (
olds *model.Statistics
)
if olds, err = s.spyDao.Statistics(c, id); err != nil || olds == nil {
return
}
if _, err = s.spyDao.UpdateStatQuantity(c, count, id); err != nil {
return
}
s.AddLog2(c, &model.Log{
Name: operater,
RefID: id,
Module: model.UpdateStat,
Context: s.UpdateStatCountLog(id, olds.Quantity, count),
Ctime: time.Now(),
})
return
}
// DeleteStat delete stat.
func (s *Service) DeleteStat(c context.Context, isdel int8, id int64, operater string) (err error) {
if _, err = s.spyDao.DeleteStat(c, isdel, id); err != nil {
return
}
s.AddLog2(c, &model.Log{
Name: operater,
RefID: id,
Module: model.UpdateStat,
Context: s.DeleteStatLog(id),
Ctime: time.Now(),
})
return
}
// StatPage get stat list.
func (s *Service) StatPage(c context.Context, mid, id int64, t int8, pn, ps int) (page *model.StatPage, err error) {
var (
list []*model.Statistics
count int64
)
page = &model.StatPage{Ps: ps, Pn: pn}
if t == model.AccountType {
count, err = s.spyDao.StatCountByMid(c, mid)
if err != nil || count == 0 {
return
}
list, err = s.spyDao.StatListByMid(c, mid, pn, ps)
} else {
count, err = s.spyDao.StatCountByID(c, id, t)
if err != nil || count == 0 {
return
}
list, err = s.spyDao.StatListByID(c, id, t, pn, ps)
}
for _, st := range list {
st.EventName = s.allEventName[st.EventID]
}
page.Items = list
page.TotalCount = count
return
}

View File

@ -0,0 +1,126 @@
package service
import (
"context"
"go-common/app/admin/main/spy/model"
"go-common/library/log"
)
// UserInfo get UserInfo by mid , from cache or db or generate.
func (s *Service) UserInfo(c context.Context, mid int64) (u *model.UserInfoDto, err error) {
var (
udb *model.UserInfo
)
if udb, err = s.spyDao.Info(c, mid); err != nil {
log.Error("s.spyDao.Info(%d) error(%v)", mid, err)
return
}
// init user score by rpc call
if udb == nil {
if _, err = s.spyDao.UserScore(c, mid); err != nil {
log.Error("s.spyDao.UserScore(%d) error(%v)", mid, err)
return
}
if udb, err = s.spyDao.Info(c, mid); err != nil {
log.Error("s.spyDao.Info(%d) error(%v)", mid, err)
return
}
}
if udb == nil {
log.Error("UserInfo init failed , still nil")
return
}
u = &model.UserInfoDto{
ID: udb.ID,
Mid: udb.Mid,
Score: udb.Score,
BaseScore: udb.BaseScore,
EventScore: udb.EventScore,
State: udb.State,
ReliveTimes: udb.ReliveTimes,
Mtime: udb.Mtime.Unix(),
}
if m, err1 := s.spyDao.AccInfo(c, mid); err1 == nil && m != nil {
u.Name = m.Name
}
return
}
// HisoryPage history page.
func (s *Service) HisoryPage(c context.Context, h *model.HisParamReq) (page *model.HistoryPage, err error) {
totalCount, err := s.spyDao.HistoryPageTotalC(c, h)
if err != nil {
log.Error("userDao HistoryPageTotalC(%v) error(%v)", h, err)
return
}
page = &model.HistoryPage{}
items, err := s.spyDao.HistoryPage(c, h)
if err != nil {
log.Error("spyDao.HistoryPage(%v) error(%v)", h, err)
return
}
page.TotalCount = totalCount
page.Items = items
page.Pn = h.Pn
page.Ps = h.Ps
return
}
// ResetBase reset user base score.
func (s *Service) ResetBase(c context.Context, mid int64, operator string) (err error) {
if err = s.spyDao.ResetBase(c, mid, operator); err != nil {
log.Error("s.spyDao.ResetBase(%d,%s) error(%v)", mid, operator, err)
return
}
return
}
// Refresh reset user base score.
func (s *Service) RefreshBase(c context.Context, mid int64, operator string) (err error) {
if err = s.spyDao.RefreshBase(c, mid, operator); err != nil {
log.Error("s.spyDao.RefreshBase(%d,%s) error(%v)", mid, operator, err)
return
}
return
}
// ResetEvent reset user event score.
func (s *Service) ResetEvent(c context.Context, mid int64, operator string) (err error) {
if err = s.spyDao.ResetEvent(c, mid, operator); err != nil {
log.Error("s.spyDao.ResetEvent(%d,%s) error(%v)", mid, operator, err)
return
}
return
}
// ClearCount clear count.
func (s *Service) ClearCount(c context.Context, mid int64, operator string) (err error) {
if err = s.spyDao.ClearCount(c, mid, operator); err != nil {
log.Error("s.spyDao.ClearCount(%d, %s) error(%v)", mid, operator, err)
return
}
return
}
// ReportList report list.
func (s *Service) ReportList(c context.Context, ps, pn int) (page *model.ReportPage, err error) {
count, err := s.spyDao.ReportCount(c)
if err != nil {
log.Error("s.spyDao.ReportCount error(%v)", err)
return
}
page = &model.ReportPage{}
items, err := s.spyDao.ReportList(c, ps, pn)
if err != nil {
log.Error("s.spyDao.ReportPage(%d,%d) error(%v)", ps, pn, err)
return
}
page.TotalCount = count
page.Items = items
page.Pn = pn
page.Ps = ps
return
}