Create & Init Project...

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

View File

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

View File

@@ -0,0 +1,394 @@
### member service
### Version 3.32.0
> 1. 官方认证增加最后提交审核时间
> 2. 官方认证是社会信用代码写入新表user_official_doc_addit中
> 3. 增加批量查询用户封禁详情接口
> 4. 删除 user_detail表相关代码
### Version 3.31.0
> 1. 官方认证增加官网地址与注册资金字段
### Version 3.30.0
> 1. 升级grpc
### Version 3.29.0
> 1. 注册用户昵称先审后发
### Version 3.28.0
> 1. 查询用户 base 信息强制从主库查询
> 2. 增加实名认证非敏感信息的聚合接口
> 3. 增加通过身份证号查询用户 mid 的接口
### Version 3.26.0
> 1. 增加官方认证提交来源字段
### Version 3.25.0
> 1. 新增grpc接口 /BlockInfo 和 /BlockBatchInfo
### Version 3.24.2
> 1. RealnameCheck校验证件时统一转换为大写进行比较
> 2. 实名认证空数据
### Version 3.24.1
> 1. 优化芝麻认证
### Version 3.24.0
> 1. 增加芝麻实名认证
### Version 3.23.0
Added
- 新增grpc接口 /RealnameDetail
### Version 3.22.0
Changed
- 优化并新增 block source : bplus
- 优化并新增 bplus block notify msg
### Version 3.21.0
> 1. 优化 /realname/apply 接口
> 2. 优化 /realname/check 接口
> 3. 新增 /realname/tel/capture/check 接口,检查短信验证码
### Version 3.20.0
> 1. 增加 /realanme/check 接口,用户申诉验证实名证件
### Version 3.19.1
> 1. 优化block ut
### Version 3.19.0
> 1. remote ip from context metadata
### Version 3.18.4
> 1. fix block db tx
### Version 3.18.3
> 1. 增加 report manager 的初始化
### Version 3.18.2
> 1. 添加 block goRPC client 接口
### Version 3.18.1
> 1. 添加 block goRPC 接口
### Version 3.18.0
> 1. 嵌入 block service
### Version 3.17.1
> 1.添加member dao层test
### Version 3.17.1
> 1. 修正官方认证被取消时的清缓存通知
### Version 3.17.0
> 1. 删除 hbase
> 2. 删除无用配置
> 3. 修正 gorpc, bm 框架
> 4. 实名信息读主库
> 5. 规范缓存时间配置
### Version 3.16
> 1. 添加grpc支持
### Version 3.15.6
> 1. add notify sender mark.
### Version 3.15.5
> 1. 再次修复节操参数校验
### Version 3.15.4
> 1. 修复节操参数校验
### Version 3.15.3
> 1. 增加节操修改rpc方法
### Version 3.15.2
> 1. 修改拼写bug
### Version 3.15.1
> 1. 删除老的参数绑定方式,改成新的参数绑定方式
#### Version 3.15.0
> 1. 改为 bm 内置参数解析工具
#### Version 3.14.4
> 1. 审核表增加extra 字段
#### Version 3.14.3
> 1. 修改/realname/adult 返回值
#### Version 3.14.2
> 1. 修改/realname/nonage --> /realname/adult
#### Version 3.14.1
> 1. 增加通过身份证号码,判断是否成年接口
#### Version 3.14.0
> 1. 根据节操行为日志撤回
#### Version 3.13.0
> 1. realname 提供实名详情接口
#### Version 3.12.4
> 1. 节操行为日志补充
#### Version 3.12.3
> 1. 经验日志输出 logid 字段
#### Version 3.12.2
> 1. 行为日志增加 log_id 字段
#### Version 3.12.1
> 1. 正常用户重复待审核状态归档
#### Version 3.12.0
> 1. 经验日志直接用行为日志
#### Version 3.11.1
> 1. 修改审核列表添加逻辑
#### Version 3.11.0
> 1. 节操日志进 report
#### Version 3.10.1
> 1. realname 移动端优化
#### Version 3.10.0
> 1. 去除 reload 配置文件
#### Version 3.9.2
> 1. 修复realname配置
#### Version 3.9.1
> 1. fix AddPropertyReview
#### Version 3.9.0
> 1. 迁移到 bm
#### Version 3.8.1
> 1. 节操日志rowkey加入uuid防止日志覆写
#### Version 3.8.0
> 1. 允许设置为空签名
#### Version 3.7.0
> 1. 加入添加监控用户和签名审核功能
#### Version 3.6.9
> 1. setBase del cache.
#### Version 3.6.8
> 1. update recover date when moral decrease.
#### Version 3.6.7
> 1. fix moral notice.
#### Version 3.6.6
> 1. fix moral log status.
#### Version 3.6.5
> 1. fix moral change sql
#### Version 3.6.4
> 1. 增加节操修改和批量修改接口
#### Version 3.6.3
> 1. restruct proto file
#### Version 3.6.2
> 1. optimize realname
#### Version 3.6.1
> 1. expLog limit 7 day
#### Version 3.6.0
> 1. fix official api and moralLog limit 7 day
#### Version 3.5.9
> 1. fix official api
#### Version 3.5.8
> 1. official submit
#### Version 3.5.7
> 1. add realname api
#### Version 3.5.6
> 1. 使用单个httpserver
#### Version 3.5.5
> 1. add base/set interface.
#### Version 3.5.4
> 1. fix moral protobuf.
#### Version 3.5.3
> 1. fix moral default moral.
#### Version 3.5.2
> 1. fix moral read.
#### Version 3.5.1
> 1. member个人信息修改删除自己缓存和通知业务方缓存
> 2. 删除没有使用的代码
> 3. 节操加缓存
#### Version 3.5.0
> 1. remove notify/close logic to account.
> 2. super super clean code.
#### Version 3.4.0
> 1. 增加member 个人信息修改接口
#### Version 3.3.0
> 1. 官方认证读新库
#### Version 3.2.4
> 1. fix moral.
#### Version 3.2.3
> 1. remove add&set exp check&init logic.
> 2. super clean code.
#### Version 3.2.2
> 1. add identify apply status check for notive v2.
#### Version 3.2.1
> 1. add moral&log interface.
> 2. add moral&log rpc client.
#### Version 3.2.0
> 1. add NickUpdated and SetNickUpdated rpc interface.
用户账号会员系统的服务层。
#### Version 3.1.0
> 1. 添加实名认证通知
> 2. 添加实名认证RPC API
#### Version 3.0.0
> 1. update path
#### Version 2.10.3
> 1. using parent context in errgroup directly.
#### Version 2.10.2
> 1. add BaseExp rpc interface.
#### Version 2.10.1
> 1. remove login watch shareClick
> 2. move project to main path
> 3. clean code
#### Version 2.10.0
> 1. 删除无用info card等
> 2. 移除对account-service的依赖
> 3. watch_ac typo
#### Version 2.9.6
> 1. 用户经验日志加 json tag
#### Version 2.9.5
> 1. 修复 exps 缓存出错
#### Version 2.9.4
> 1. MyInfo 继续使用 member 库中的经验值
> 2. remove statsd
#### Version 2.9.1-ooc
> 1. 因数据同步问题MyInfo 直接用 account-java 的经验信息
#### Version 2.9.1
> 1. 修改经验接口参数ts名称改为ptime
#### Version 2.9.0
> 1. 提供base,detail,batchbase 的rpc接口
> 2. detail接口增加level信息
#### Version 2.8.1
> 1. 提供等级批量接口
> 2. 修改经验缓存为mc
#### Version 2.7.1
> 1.add rpc service
#### Version 2.7.0
> 1.补充单元测试
#### Version 2.6.2
> 1.hbase scan日志修复
#### Version 2.6.1
> 1.修复空经验值
#### Version 2.6.0
> 1.pb格式兼容
> 2.exp 经验值转发
#### Version 2.5.0
> 1.经验重构
#### Version 2.4.3
> 1.无头像返回默认头像
#### Version 2.4.0
> 1.会员信息基础接口上线
#### Version 2.3.2
> 1.删除upInfo接口逻辑
#### Version 2.3.1
> 1.修复移动端关闭实名认证、异地登录提醒接口关闭异地登录提醒不成功
#### Version 2.3.0
> 1.update http client conf and usage
#### Version 2.2.0
> 1.移动端获取及关闭异地登录、实名制提醒
#### Version 2.1.0
> 1.myinfo接口调用account-java的获取用户信息myinfo内网接口
#### Version 2.0.0
> 1.增加info card等信息
#### Version 1.4.2
> 1.fix upinfo cache error
#### Version 1.4.1
> 1.添加upinfo容错信息
#### Version 1.4.0
> 1.新增up infos: pic and blink
#### Version 1.3.0
> 1.剔除答题逻辑
#### Version 1.2.0
> 1.实名制提示
> 2.获取UP主权限
#### Version 1.1.0
> 1.merge member-service into Kratos
#### Version 1.0.7
> 1.排行榜昵称
#### Version 1.0.6
> 1.答题转正重试
#### Version 1.0.5
> 1.新增异地登录功能
#### Version 1.0.4
> 1.修复h5不显示答题
#### Version 1.0.3
> 1.答题图片bfs
#### Version 1.0.2
> 1.接入prom
#### Version 1.0.1
> 1.修复封禁时长
#### Version 1.0.0
> 1.基础api

View File

@@ -0,0 +1,21 @@
# Owner
zhaogangtao
wanghuan01
zhoujiahui
chenjianrong
zhoujixiang
# Author
zhaogangtao
wanghuan01
zhoujiahui
chenjianrong
zhoujixiang
# Reviewer
zhaogangtao
wanghuan01
zhoujiahui
zhoujiahui
chenjianrong
zhoujixiang

View File

@@ -0,0 +1,20 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- chenjianrong
- wanghuan01
- zhaogangtao
- zhoujiahui
- zhoujixiang
labels:
- main
- service
- service/main/member
options:
no_parent_owners: true
reviewers:
- chenjianrong
- wanghuan01
- zhaogangtao
- zhoujiahui
- zhoujixiang

View File

@@ -0,0 +1,2 @@
### member service
用户账号会员系统的服务层。

View File

@@ -0,0 +1,75 @@
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
load(
"@io_bazel_rules_go//proto:def.bzl",
"go_proto_library",
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/service/main/member/api/gorpc:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
proto_library(
name = "api_proto",
srcs = ["api.proto"],
tags = ["automanaged"],
deps = ["@gogo_special_proto//github.com/gogo/protobuf/gogoproto"],
)
go_proto_library(
name = "api_go_proto",
compilers = ["@io_bazel_rules_go//proto:gogofast_grpc"],
importpath = "go-common/app/service/main/member/api",
proto = ":api_proto",
tags = ["automanaged"],
deps = [
"//library/time:go_default_library",
"@com_github_gogo_protobuf//gogoproto:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"client.go",
"copy.go",
],
embed = [":api_go_proto"],
importpath = "go-common/app/service/main/member/api",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/member/model:go_default_library",
"//app/service/main/member/model/block:go_default_library",
"//library/net/rpc/warden:go_default_library",
"//library/time:go_default_library",
"@com_github_gogo_protobuf//gogoproto: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",
],
)
go_test(
name = "go_default_test",
srcs = ["client_test.go"],
embed = [":go_default_library"],
tags = ["automanaged"],
deps = ["//vendor/github.com/smartystreets/goconvey/convey:go_default_library"],
)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,589 @@
syntax = "proto3";
package account.service.member.v1;
option go_package = "api";
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
message MidReq {
// mid
int64 mid = 1 [ (gogoproto.jsontag) = "mid" ];
// 真实ip
string realIP = 3 [ (gogoproto.jsontag) = "realIP" ];
}
message MemberMidReq {
// mid
int64 mid = 1 [ (gogoproto.jsontag) = "mid" ];
// 远端ip
string remoteIP = 2 [ (gogoproto.jsontag) = "remoteIP" ];
}
message MemberMidsReq {
// mid 列表
repeated int64 mids = 1 [ (gogoproto.jsontag) = "mids" ];
// 远端ip
string remoteIP = 2 [ (gogoproto.jsontag) = "remoteIP" ];
}
message MidByRealnameCardsReq {
// 身份证号
repeated string card_code = 1
[ (gogoproto.moretags) = "form:\"card_code\" validate:\"required\"" ];
// 国家
int32 country = 2 [
(gogoproto.jsontag) = "country",
(gogoproto.casttype) = "int16",
(gogoproto.moretags) = "form:\"country\""
];
// 证件类型
int32 card_type = 3 [
(gogoproto.jsontag) = "card_type",
(gogoproto.casttype) = "int8",
(gogoproto.moretags) = "form:\"card_type\""
];
}
// 空的message对应真实service只返回error没有具体返回值
message EmptyStruct {}
message LevelInfoReply {
// 当前的等级信息
int32 cur = 1 [ (gogoproto.jsontag) = "current_level" ];
// 当前等级的经验阀值
int32 min = 2 [ (gogoproto.jsontag) = "current_min" ];
// 当前的经验值
int32 now_exp = 3 [ (gogoproto.jsontag) = "current_exp" ];
// 下个等级的经验阀值
int32 next_exp = 4 [ (gogoproto.jsontag) = "next_exp" ];
}
message UserLogReply {
// mid
int64 mid = 1 [ (gogoproto.jsontag) = "mid" ];
// ip
string ip = 2 [ (gogoproto.jsontag) = "ip" ];
// 时间戳
int64 ts = 3 [ (gogoproto.jsontag) = "ts" ];
// logId
string log_id = 4 [ (gogoproto.jsontag) = "log_id" ];
// 具体内容
map<string, string> content = 5 [ (gogoproto.jsontag) = "content" ];
}
message UserLogsReply {
// UserLog的集合
repeated UserLogReply user_logs = 1 [ (gogoproto.jsontag) = "user_logs" ];
}
message AddExpReq {
// mid
int64 mid = 1 [ (gogoproto.jsontag) = "mid" ];
// 增量
double count = 2 [ (gogoproto.jsontag) = "count" ];
// 修改原因
string reason = 3 [ (gogoproto.jsontag) = "reason" ];
// 操作类型
string operate = 4 [ (gogoproto.jsontag) = "operate" ];
// ip
string ip = 5 [ (gogoproto.jsontag) = "ip" ];
}
message ExpStatReply {
// 是否获取过登陆奖励
bool login = 1 [ (gogoproto.jsontag) = "login" ];
// 是否获取过看视频的奖励
bool watch = 2 [ (gogoproto.jsontag) = "watch_av" ];
// 是否获得投币奖励
int64 coin = 3 [ (gogoproto.jsontag) = "coins_av" ];
// 是否获得分享过视频的奖励
bool share = 4 [ (gogoproto.jsontag) = "share_av" ];
}
// member
message BaseInfoReply {
// mid
int64 mid = 1 [ (gogoproto.jsontag) = "mid" ];
// 名称
string name = 2 [ (gogoproto.jsontag) = "name" ];
// 性别
int64 sex = 3 [ (gogoproto.jsontag) = "sex" ];
// 头像
string face = 4 [ (gogoproto.jsontag) = "face" ];
// 签名
string sign = 5 [ (gogoproto.jsontag) = "sign" ];
// 排名
int64 rank = 6 [ (gogoproto.jsontag) = "rank" ];
// 生日
int64 birthday = 7 [
(gogoproto.jsontag) = "birthday",
(gogoproto.casttype) = "go-common/library/time.Time"
];
}
message OfficialInfoReply {
// 角色类别
int32 role = 1
[ (gogoproto.jsontag) = "role", (gogoproto.casttype) = "int8" ];
// 标题
string title = 2 [ (gogoproto.jsontag) = "title" ];
// 描述
string desc = 3 [ (gogoproto.jsontag) = "desc" ];
}
message BaseInfosReply {
// member基本信息集合
map<int64, BaseInfoReply> base_infos = 1;
}
message MemberInfoReply {
// 基本信息
BaseInfoReply base_info = 1;
// 等级信息
LevelInfoReply level_info = 2;
// 官方认证信息
OfficialInfoReply official_info = 3;
}
message MemberInfosReply { map<int64, MemberInfoReply> member_infos = 1; }
message NickUpdatedReply {
// 昵称是否修改过
bool nick_updated = 1 [ (gogoproto.jsontag) = "nick_updated" ];
}
message OfficialDocReq {
// mid
int64 mid = 1 [ (gogoproto.jsontag) = "mid" ];
// 名称
string name = 2 [ (gogoproto.jsontag) = "name" ];
// 审核状态
int32 state = 3
[ (gogoproto.jsontag) = "state", (gogoproto.casttype) = "int8" ];
// 角色
int32 role = 4
[ (gogoproto.jsontag) = "role", (gogoproto.casttype) = "int8" ];
// 标题
string title = 5 [ (gogoproto.jsontag) = "title" ];
// 描述
string desc = 6 [ (gogoproto.jsontag) = "desc" ];
// 拒绝原因
string reject_reason = 7 [ (gogoproto.jsontag) = "reject_reason" ];
// 真实名字
int32 realname = 8
[ (gogoproto.jsontag) = "realname", (gogoproto.casttype) = "int8" ];
// 操作人
string operator = 9 [ (gogoproto.jsontag) = "operator" ];
// 电话
string telephone = 10 [ (gogoproto.jsontag) = "telephone" ];
// 邮箱
string email = 11 [ (gogoproto.jsontag) = "email" ];
// 地址
string address = 12 [ (gogoproto.jsontag) = "address" ];
// 公司
string company = 13 [ (gogoproto.jsontag) = "company" ];
// 统一信用代码
string credit_code = 14 [ (gogoproto.jsontag) = "credit_code" ];
// 组织机构
string organization = 15 [ (gogoproto.jsontag) = "organization" ];
// 组织机构类型
string organization_type = 16 [ (gogoproto.jsontag) = "organization_type" ];
// 营业执照
string business_license = 17 [ (gogoproto.jsontag) = "business_license" ];
// 企业规模
string business_scale = 18 [ (gogoproto.jsontag) = "business_scale" ];
// 企业等级
string business_level = 19 [ (gogoproto.jsontag) = "business_level" ];
// 企业授权函
string business_auth = 20 [ (gogoproto.jsontag) = "business_auth" ];
// 其他补充资料
string supplement = 21 [ (gogoproto.jsontag) = "supplement" ];
// 专业资质
string professional = 22 [ (gogoproto.jsontag) = "professional" ];
// 身份证明
string identification = 23 [ (gogoproto.jsontag) = "identification" ];
// 提交来源
string submit_source = 24 [ (gogoproto.jsontag) = "submit_source" ];
}
message UpdateSexReq {
// mid
int64 mid = 1 [ (gogoproto.jsontag) = "mid" ];
// 性别
int64 sex = 2 [ (gogoproto.jsontag) = "sex" ];
// 远端ip
string remote_IP = 3 [ (gogoproto.jsontag) = "remoteIP" ];
}
message UpdateUnameReq {
// mid
int64 mid = 1 [ (gogoproto.jsontag) = "mid" ];
// 名称
string name = 2 [ (gogoproto.jsontag) = "name" ];
// 远端ip
string remote_IP = 3 [ (gogoproto.jsontag) = "remoteIP" ];
}
message UpdateFaceReq {
// mid
int64 mid = 1 [ (gogoproto.jsontag) = "mid" ];
// 头像
string face = 2 [ (gogoproto.jsontag) = "face" ];
// 远端ip
string remote_IP = 3 [ (gogoproto.jsontag) = "remoteIP" ];
}
message UpdateRankReq {
// mid
int64 mid = 1 [ (gogoproto.jsontag) = "mid" ];
// 排行
int64 rank = 2 [ (gogoproto.jsontag) = "rank" ];
// 远端ip
string remote_IP = 3 [ (gogoproto.jsontag) = "remoteIP" ];
}
message UpdateBirthdayReq {
// mid
int64 mid = 1 [ (gogoproto.jsontag) = "mid" ];
// 生日
int64 birthday = 2 [
(gogoproto.jsontag) = "birthday",
(gogoproto.casttype) = "go-common/library/time.Time"
];
// 远端ip
string remote_IP = 3 [ (gogoproto.jsontag) = "remoteIP" ];
}
message UpdateSignReq {
// mid
int64 mid = 1 [ (gogoproto.jsontag) = "mid" ];
// 签名
string sign = 2 [ (gogoproto.jsontag) = "sign" ];
// 远端ip
string remote_IP = 3 [ (gogoproto.jsontag) = "remoteIP" ];
}
message OfficialDocInfoReply {
// mid
int64 mid = 1 [ (gogoproto.jsontag) = "mid" ];
// 名称
string name = 2 [ (gogoproto.jsontag) = "name" ];
// 审核状态
int32 state = 3 [ (gogoproto.jsontag) = "state" ];
// 角色类型
int32 role = 4
[ (gogoproto.jsontag) = "role", (gogoproto.casttype) = "int8" ];
// 认证称号
string title = 5 [ (gogoproto.jsontag) = "title" ];
// 认证后缀
string desc = 6 [ (gogoproto.jsontag) = "desc" ];
// 被拒绝原因
string reject_reason = 7 [ (gogoproto.jsontag) = "reject_reason" ];
// 真实姓名
int32 realname = 8
[ (gogoproto.jsontag) = "realname", (gogoproto.casttype) = "int8" ];
// 经营人
string operator = 9 [ (gogoproto.jsontag) = "operator" ];
// 电话好吗
string telephone = 10 [ (gogoproto.jsontag) = "telephone" ];
// 邮箱
string email = 11 [ (gogoproto.jsontag) = "email" ];
// 地址
string address = 12 [ (gogoproto.jsontag) = "address" ];
// 公司
string company = 13 [ (gogoproto.jsontag) = "company" ];
// 社会信用代码
string credit_code = 14 [ (gogoproto.jsontag) = "credit_code" ];
// 政府或组织机构名称
string organization = 15 [ (gogoproto.jsontag) = "organization" ];
// 组织或机构类型
string organization_type = 16 [ (gogoproto.jsontag) = "organization_type" ];
// 营业执照
string business_license = 17 [ (gogoproto.jsontag) = "business_license" ];
// 企业规模
string business_scale = 18 [ (gogoproto.jsontag) = "business_scale" ];
// 企业等级
string business_level = 19 [ (gogoproto.jsontag) = "business_level" ];
// 企业授权函
string business_auth = 20 [ (gogoproto.jsontag) = "business_auth" ];
// 其他补充资料
string supplement = 21 [ (gogoproto.jsontag) = "supplement" ];
// 专业资质
string professional = 22 [ (gogoproto.jsontag) = "professional" ];
// 身份证明
string identification = 23 [ (gogoproto.jsontag) = "identification" ];
}
// moral
message MoralReply {
// mid
int64 mid = 1 [ (gogoproto.jsontag) = "mid" ];
// 节操值
int64 moral = 2 [ (gogoproto.jsontag) = "moral" ];
// 增量
int64 added = 3 [ (gogoproto.jsontag) = "added" ];
// 减量
int64 deducted = 4 [ (gogoproto.jsontag) = "deducted" ];
// 上一次节操低于70时的恢复时间
int64 last_recover_date = 5 [
(gogoproto.jsontag) = "last_recover_date",
(gogoproto.casttype) = "go-common/library/time.Time"
];
}
message UpdateMoralReq {
// mid
int64 mid = 1 [ (gogoproto.jsontag) = "mid" ];
// 增量
int64 delta = 2 [ (gogoproto.jsontag) = "delta" ];
// 类型
int64 origin = 3 [ (gogoproto.jsontag) = "origin" ];
// 操作原因
string reason = 4 [ (gogoproto.jsontag) = "reason" ];
// 操纵原因类型
int64 reason_type = 5 [ (gogoproto.jsontag) = "reason_type" ];
// 操作人
string operator = 6 [ (gogoproto.jsontag) = "operator" ];
// 备注
string remark = 7 [ (gogoproto.jsontag) = "remark" ];
// 状态
int64 status = 8 [ (gogoproto.jsontag) = "status" ];
// 是否通知
bool is_notify = 9 [ (gogoproto.jsontag) = "is_notify" ];
// ip地址
string ip = 10 [ (gogoproto.jsontag) = "ip" ];
}
message UpdateMoralsReq {
// mid 列表
repeated int64 mids = 1 [ (gogoproto.jsontag) = "mid" ];
// 增量
int64 delta = 2 [ (gogoproto.jsontag) = "delta" ];
// 类型
int64 origin = 3 [ (gogoproto.jsontag) = "origin" ];
// 操作原因
string reason = 4 [ (gogoproto.jsontag) = "reason" ];
// 操纵原因类型
int64 reason_type = 5 [ (gogoproto.jsontag) = "reason_type" ];
// 操作人
string operator = 6 [ (gogoproto.jsontag) = "operator" ];
// 备注
string remark = 7 [ (gogoproto.jsontag) = "remark" ];
// 状态
int64 status = 8 [ (gogoproto.jsontag) = "status" ];
// 是否通知
bool is_notify = 9 [ (gogoproto.jsontag) = "is_notify" ];
// ip
string ip = 10 [ (gogoproto.jsontag) = "ip" ];
}
message UpdateMoralsReply {
// 批量更新后节操值
map<int64, int64> after_morals = 1 [ (gogoproto.jsontag) = "after_morals" ];
}
// property_review
message AddUserMonitorReq {
// mid
int64 mid = 1 [ (gogoproto.jsontag) = "mid" ];
// 操作人
string operator = 2 [ (gogoproto.jsontag) = "operator" ];
// 备注
string remark = 3 [ (gogoproto.jsontag) = "remark" ];
}
// AddPropertyReview (暂时不开放调用)
// message AddPropertyReviewReq {
// // mid
// int64 mid = 1 [(gogoproto.jsontag) = "mid"];
// // 属性新的值
// string new = 2 [(gogoproto.jsontag) = "new"];
// // 状态
// int32 state = 3 [(gogoproto.jsontag) = "state",(gogoproto.casttype) =
// "int8"];
// // 属性
// int32 property = 4 [(gogoproto.jsontag) = "property",(gogoproto.casttype)
// = "int8"];
// // 额外的一些信息
// map<string, string> extra = 5 [(gogoproto.jsontag) = "extra"];
// }
message IsInMonitorReply {
// member是否处在受监控列表中
bool is_in_monitor = 1 [ (gogoproto.jsontag) = "is_in_monitor" ];
}
// realname
message RealnameStatusReply {
// 实名认证状态
int32 realname_status = 1 [
(gogoproto.jsontag) = "realname_status",
(gogoproto.casttype) = "int8"
];
}
message RealnameApplyInfoReply {
// 认证流程状态
int32 status = 1
[ (gogoproto.jsontag) = "status", (gogoproto.casttype) = "int8" ];
// 备注
string remark = 2 [ (gogoproto.jsontag) = "remark" ];
}
message ArgRealnameApplyReq {
// mid
int64 mid = 1 [ (gogoproto.jsontag) = "mid" ];
// 验证码
int64 capture_code = 2 [ (gogoproto.jsontag) = "capture_code" ];
// 真实的名字
string realname = 3 [ (gogoproto.jsontag) = "realname" ];
// 证件类型
int32 card_type = 4
[ (gogoproto.jsontag) = "card_type", (gogoproto.casttype) = "int8" ];
// 证件码
string card_code = 5 [ (gogoproto.jsontag) = "card_code" ];
// 国家
int32 country = 6
[ (gogoproto.jsontag) = "country", (gogoproto.casttype) = "int16" ];
// 手持照的路径
string handIMG_token = 7;
// 证件照的前面
string frontIMG_token = 8;
// 证件照的后面
string backIMG_token = 9;
}
message RealnameDetailReply {
// 实名姓名
string realname = 1 [ (gogoproto.jsontag) = "realname" ];
// 证件码
string card = 2 [ (gogoproto.jsontag) = "card" ];
// 证件类型
int32 card_type = 3
[ (gogoproto.jsontag) = "card_type", (gogoproto.casttype) = "int8" ];
// 实名状态
int32 status = 4
[ (gogoproto.jsontag) = "status", (gogoproto.casttype) = "int8" ];
// 性别
string gender = 5 [ (gogoproto.jsontag) = "gender" ];
// 手持照IMG User
string hand_img = 6 [ (gogoproto.jsontag) = "hand_img" ];
}
message RealnameStrippedInfoReply {
int64 mid = 1 [ (gogoproto.jsontag) = "mid" ];
int32 status = 2
[ (gogoproto.jsontag) = "status", (gogoproto.casttype) = "int8" ];
int32 channel = 3
[ (gogoproto.jsontag) = "channel", (gogoproto.casttype) = "int8" ];
int32 country = 4
[ (gogoproto.jsontag) = "country", (gogoproto.casttype) = "int16" ];
int32 card_type = 5
[ (gogoproto.jsontag) = "card_type", (gogoproto.casttype) = "int8" ];
int32 adult_type = 6
[ (gogoproto.jsontag) = "adult_type", (gogoproto.casttype) = "int8" ];
}
message MidByRealnameCardReply {
map<string, int64> code_to_mid = 5 [ (gogoproto.jsontag) = "code_to_mid" ];
}
message BlockInfoReply {
int64 MID = 1 [ (gogoproto.jsontag) = "mid" ];
int32 BlockStatus = 2 [ (gogoproto.jsontag) = "status" ];
int64 StartTime = 3 [ (gogoproto.jsontag) = "start_time" ];
int64 EndTime = 4 [ (gogoproto.jsontag) = "end_time" ];
}
message BlockDetailReply {
int64 MID = 1 [ (gogoproto.jsontag) = "mid" ];
int64 BlockCount = 2 [ (gogoproto.jsontag) = "block_count" ];
}
message BlockBatchDetailReply {
map<int64, BlockDetailReply> BlockDetails = 1 [ (gogoproto.jsontag) = "block_details" ];
}
message BlockBatchInfoReply {
repeated BlockInfoReply BlockInfos = 1
[ (gogoproto.jsontag) = "block_infos" ];
}
service Member {
// 得到member的基本信息
rpc Base(MemberMidReq) returns (BaseInfoReply);
// 批量得到一批member的基本信息
rpc Bases(MemberMidsReq) returns (BaseInfosReply);
// 得到member的全量信息
rpc Member(MemberMidReq) returns (MemberInfoReply);
// 批量得到一批member的全量信息
rpc Members(MemberMidsReq) returns (MemberInfosReply);
// 查看member是否更新过昵称
rpc NickUpdated(MemberMidReq) returns (NickUpdatedReply);
// 标记member已经更新过昵称
rpc SetNickUpdated(MemberMidReq) returns (EmptyStruct);
// 设置官方文档资料
rpc SetOfficialDoc(OfficialDocReq) returns (EmptyStruct);
// 设置member的性别
rpc SetSex(UpdateSexReq) returns (EmptyStruct);
// 设置member的名字
rpc SetName(UpdateUnameReq) returns (EmptyStruct);
// 设置member的头像
rpc SetFace(UpdateFaceReq) returns (EmptyStruct);
// 设置member的头像
rpc SetRank(UpdateRankReq) returns (EmptyStruct);
// 设置member的生日
rpc SetBirthday(UpdateBirthdayReq) returns (EmptyStruct);
// 设置member的签名
rpc SetSign(UpdateSignReq) returns (EmptyStruct);
// 得到member的官方信息
rpc OfficialDoc(MidReq) returns (OfficialDocInfoReply);
// 得到member的节操值
rpc Moral(MemberMidReq) returns (MoralReply);
// 得到member的节操日志
rpc MoralLog(MemberMidReq) returns (UserLogsReply);
// 给member添加节操值
rpc AddMoral(UpdateMoralReq) returns (EmptyStruct);
// 给一批member批量添加节操值
rpc BatchAddMoral(UpdateMoralsReq) returns (UpdateMoralsReply);
// 得到member的经验值
rpc Exp(MidReq) returns (LevelInfoReply);
// 得到member的等级
rpc Level(MidReq) returns (LevelInfoReply);
// 更新member的经验值
rpc UpdateExp(AddExpReq) returns (EmptyStruct);
// 得到membe的经验日志
rpc ExpLog(MidReq) returns (UserLogsReply);
// 得到member的经验统计
rpc ExpStat(MidReq) returns (ExpStatReply);
// 得到member的实名认证状态
rpc RealnameStatus(MemberMidReq) returns (RealnameStatusReply);
// 得到member 实名认证流程的状态
rpc RealnameApplyStatus(MemberMidReq) returns (RealnameApplyInfoReply);
// 手机号实名认证发送验证码
rpc RealnameTelCapture(MemberMidReq) returns (EmptyStruct);
// 进行实名认证
rpc RealnameApply(ArgRealnameApplyReq) returns (EmptyStruct);
// 实名详情
rpc RealnameDetail(MemberMidReq) returns (RealnameDetailReply);
// 所有非敏感实名认证信息
rpc RealnameStrippedInfo(MemberMidReq) returns (RealnameStrippedInfoReply);
// 通过身份证号查询 mid
rpc MidByRealnameCard(MidByRealnameCardsReq) returns (MidByRealnameCardReply);
// 添加用户为受监控
rpc AddUserMonitor(AddUserMonitorReq) returns (EmptyStruct);
// 查看member是否在监控状态
rpc IsInMonitor(MidReq) returns (IsInMonitorReply);
// 添加属性审核 (暂时不开放调用)
// rpc AddPropertyReview(AddPropertyReviewReq) returns (EmptyStruct);
// block
// 获取用户封禁信息数据
rpc BlockInfo(MemberMidReq) returns (BlockInfoReply);
// 批量获取用户封禁信息数据
rpc BlockBatchInfo(MemberMidsReq) returns (BlockBatchInfoReply);
//批量获取用户封禁详细数据
rpc BlockBatchDetail(MemberMidsReq) returns (BlockBatchDetailReply);
}

View File

@@ -0,0 +1,22 @@
package api
import (
"context"
"go-common/library/net/rpc/warden"
"google.golang.org/grpc"
)
// AppID unique app id for service discovery
const AppID = "account.service.member"
// NewClient new member grpc client
func NewClient(cfg *warden.ClientConfig, opts ...grpc.DialOption) (MemberClient, error) {
client := warden.NewClient(cfg, opts...)
conn, err := client.Dial(context.Background(), "discovery://default/"+AppID)
if err != nil {
return nil, err
}
return NewMemberClient(conn), nil
}

View File

@@ -0,0 +1,40 @@
package api
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
var client MemberClient
func init() {
var err error
client, err = NewClient(nil)
if err != nil {
panic(err)
}
}
func TestUserDetails(t *testing.T) {
convey.Convey("Block User Details", t, func(ctx convey.C) {
var c = context.Background()
ctx.Convey("When get block user details", func(ctx convey.C) {
details, err := client.BlockBatchDetail(c, &MemberMidsReq{Mids: []int64{2, 3}})
ctx.So(err, convey.ShouldBeNil)
ctx.So(details, convey.ShouldNotBeNil)
})
})
}
func TestUserInfo(t *testing.T) {
convey.Convey("Block User Infos", t, func(ctx convey.C) {
var c = context.Background()
ctx.Convey("When get block user infos", func(ctx convey.C) {
infos, err := client.BlockBatchInfo(c, &MemberMidsReq{Mids: []int64{2}})
ctx.So(err, convey.ShouldBeNil)
ctx.So(infos, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,177 @@
package api
import (
"go-common/app/service/main/member/model"
block "go-common/app/service/main/member/model/block"
)
// FromBaseInfo convert from model.BaseInfo to v1.BaseInfoReply
func FromBaseInfo(model *model.BaseInfo) *BaseInfoReply {
baseInfoReply := &BaseInfoReply{
Mid: model.Mid,
Name: model.Name,
Sex: model.Sex,
Face: model.Face,
Sign: model.Sign,
Rank: model.Rank,
Birthday: model.Birthday,
}
return baseInfoReply
}
// FromLevelInfo convert from model.LevelInfo to v1.LevelInfoReply
func FromLevelInfo(model *model.LevelInfo) *LevelInfoReply {
levelInfoReply := &LevelInfoReply{
Cur: model.Cur,
Min: model.Min,
NowExp: model.NowExp,
NextExp: model.NextExp,
}
return levelInfoReply
}
// FromOfficialInfo convert from model.OfficialInfo to v1.OfficialInfoReply
func FromOfficialInfo(model *model.OfficialInfo) *OfficialInfoReply {
officialInfoReply := &OfficialInfoReply{
Role: model.Role,
Title: model.Title,
Desc: model.Desc,
}
return officialInfoReply
}
// FromMember convert from model.Member to v1.MemberInfoReply
func FromMember(res *model.Member) *MemberInfoReply {
var baseInfo *BaseInfoReply
var levelInfo *LevelInfoReply
var officialInfo *OfficialInfoReply
if res.BaseInfo != nil {
baseInfo = FromBaseInfo(res.BaseInfo)
}
if res.LevelInfo != nil {
levelInfo = FromLevelInfo(res.LevelInfo)
}
if res.OfficialInfo != nil {
officialInfo = FromOfficialInfo(res.OfficialInfo)
}
memberInfoReply := &MemberInfoReply{
BaseInfo: baseInfo,
LevelInfo: levelInfo,
OfficialInfo: officialInfo,
}
return memberInfoReply
}
// FromOfficialDoc convert from model.OfficalDoc to v1.OfficialDocInfoReply
func FromOfficialDoc(model *model.OfficialDoc) *OfficialDocInfoReply {
officalDocInfoReply := &OfficialDocInfoReply{
Mid: model.Mid,
Name: model.Name,
State: int32(model.State),
Role: int8(model.Role),
Title: model.Title,
Desc: model.Desc,
RejectReason: model.RejectReason,
Realname: int8(model.Realname),
Operator: model.Operator,
Telephone: model.Telephone,
Email: model.Email,
Address: model.Address,
Company: model.Company,
CreditCode: model.CreditCode,
Organization: model.Organization,
OrganizationType: model.OrganizationType,
BusinessLicense: model.BusinessLicense,
BusinessScale: model.BusinessScale,
BusinessLevel: model.BusinessLevel,
BusinessAuth: model.BusinessAuth,
Supplement: model.Supplement,
Professional: model.Professional,
Identification: model.Identification,
}
return officalDocInfoReply
}
// FromBlockInfo convert from model.BlockInfo to v1.OfficialDocInfoReply
func FromBlockInfo(model *block.BlockInfo) *BlockInfoReply {
blockInfoReply := &BlockInfoReply{
MID: model.MID,
BlockStatus: int32(model.BlockStatus),
StartTime: model.StartTime,
EndTime: model.EndTime,
}
return blockInfoReply
}
// FromBlockUserDetail convert from model.BlockUserDetail v1.OfficialDocInfoReply
func FromBlockUserDetail(model *block.BlockUserDetail) *BlockDetailReply {
blockDetailReply := &BlockDetailReply{
MID: model.MID,
BlockCount: model.BlockCount,
}
return blockDetailReply
}
// ToArgOfficialDoc convert from v1.officalDocReq to model.AragsOfficalDoc
func ToArgOfficialDoc(req *OfficialDocReq) *model.ArgOfficialDoc {
argOfficialDoc := &model.ArgOfficialDoc{
Mid: req.Mid,
Name: req.Name,
Role: req.Role,
Title: req.Title,
Desc: req.Desc,
Realname: int8(req.Realname),
Operator: req.Operator,
Telephone: req.Telephone,
Email: req.Email,
Address: req.Address,
Company: req.Company,
CreditCode: req.CreditCode,
Organization: req.Organization,
OrganizationType: req.OrganizationType,
BusinessLicense: req.BusinessLicense,
BusinessScale: req.BusinessScale,
BusinessLevel: req.BusinessLevel,
BusinessAuth: req.BusinessAuth,
Supplement: req.Supplement,
Professional: req.Professional,
Identification: req.Identification,
SubmitSource: req.SubmitSource,
}
return argOfficialDoc
}
// ToArgUpdateMoral convert from v1.UpdateMoralReq to model.ArgUpdateMoral
func ToArgUpdateMoral(req *UpdateMoralReq) *model.ArgUpdateMoral {
updateMoral := &model.ArgUpdateMoral{
Mid: req.Mid,
Delta: req.Delta,
Origin: req.Origin,
Reason: req.Reason,
ReasonType: req.ReasonType,
Operator: req.Operator,
Remark: req.Remark,
Status: req.Status,
IsNotify: req.IsNotify,
IP: req.Ip,
}
return updateMoral
}
// ToArgUpdateMorals convert from v1.UpdateMoralsReq to model.ArgUpdateMorals
func ToArgUpdateMorals(req *UpdateMoralsReq) *model.ArgUpdateMorals {
updateMorals := &model.ArgUpdateMorals{
Mids: req.Mids,
Delta: req.Delta,
Origin: req.Origin,
Reason: req.Reason,
ReasonType: req.ReasonType,
Operator: req.Operator,
Remark: req.Remark,
Status: req.Status,
IsNotify: req.IsNotify,
IP: req.Ip,
}
return updateMorals
}

View File

@@ -0,0 +1,41 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"block.go",
"member.go",
"moral.go",
"property_review.go",
"realname.go",
"rpc.go",
],
importpath = "go-common/app/service/main/member/api/gorpc",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/member/model:go_default_library",
"//app/service/main/member/model/block:go_default_library",
"//library/ecode:go_default_library",
"//library/net/rpc:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,33 @@
package gorpc
import (
"context"
rpcmodel "go-common/app/service/main/member/model/block"
"go-common/library/ecode"
)
const (
_blockInfo = "RPC.BlockInfo"
_blockBatchInfo = "RPC.BlockBatchInfo"
)
// BlockInfo is
func (s *Service) BlockInfo(c context.Context, arg *rpcmodel.RPCArgInfo) (res *rpcmodel.RPCResInfo, err error) {
res = new(rpcmodel.RPCResInfo)
err = s.client.Call(c, _blockInfo, arg, res)
return
}
// BlockBatchInfo len(mids) <= 50
func (s *Service) BlockBatchInfo(c context.Context, arg *rpcmodel.RPCArgBatchInfo) (res []*rpcmodel.RPCResInfo, err error) {
if len(arg.MIDs) == 0 {
return
}
if len(arg.MIDs) > 50 {
err = ecode.RequestErr
return
}
err = s.client.Call(c, _blockBatchInfo, arg, &res)
return
}

View File

@@ -0,0 +1,152 @@
package gorpc
import (
"context"
"go-common/app/service/main/member/model"
)
const (
_Base = "RPC.Base"
_Bases = "RPC.Bases"
_Member = "RPC.Member"
_Members = "RPC.Members"
_UpdateExp = "RPC.UpdateExp"
_Exp = "RPC.Exp"
_Level = "RPC.Level"
_Log = "RPC.Log"
_Stat = "RPC.Stat"
_NickUpdated = "RPC.NickUpdated"
_SetNickUpdated = "RPC.SetNickUpdated"
_Moral = "RPC.Moral"
_MoralLog = "RPC.MoralLog"
_SetOfficialDoc = "RPC.SetOfficialDoc"
_OfficialDoc = "RPC.OfficialDoc"
_setName = "RPC.SetName"
_setSign = "RPC.SetSign"
_setRank = "RPC.SetRank"
_setFace = "RPC.SetFace"
_setSex = "RPC.SetSex"
_setBirthday = "RPC.SetBirthday"
_addMoral = "RPC.AddMoral"
_batchAddMoral = "RPC.BatchAddMoral"
)
// Exp rpc user exp.
func (s *Service) Exp(c context.Context, arg *model.ArgMid2) (res *model.LevelInfo, err error) {
res = new(model.LevelInfo)
err = s.client.Call(c, _Exp, arg, res)
return
}
// Level user level.
func (s *Service) Level(c context.Context, arg *model.ArgMid2) (res *model.LevelInfo, err error) {
res = new(model.LevelInfo)
err = s.client.Call(c, _Level, arg, res)
return
}
// Log user exp log.
func (s *Service) Log(c context.Context, arg *model.ArgMid2) (res []*model.UserLog, err error) {
err = s.client.Call(c, _Log, arg, &res)
return
}
// Stat user exp log.
func (s *Service) Stat(c context.Context, arg *model.ArgMid2) (res *model.ExpStat, err error) {
err = s.client.Call(c, _Stat, arg, &res)
return
}
// UpdateExp update user exp.
func (s *Service) UpdateExp(c context.Context, arg *model.ArgAddExp) (err error) {
err = s.client.Call(c, _UpdateExp, arg, &_noRes)
return
}
// Base get user base info.
func (s *Service) Base(c context.Context, arg *model.ArgMemberMid) (res *model.BaseInfo, err error) {
err = s.client.Call(c, _Base, arg, &res)
return
}
// Bases get batch base info.
func (s *Service) Bases(c context.Context, arg *model.ArgMemberMids) (res map[int64]*model.BaseInfo, err error) {
err = s.client.Call(c, _Bases, arg, &res)
return
}
// Member get the full information within member-service.
func (s *Service) Member(c context.Context, arg *model.ArgMemberMid) (res *model.Member, err error) {
err = s.client.Call(c, _Member, arg, &res)
return
}
// Members get batch the full information within member-service.
func (s *Service) Members(c context.Context, arg *model.ArgMemberMids) (res map[int64]*model.Member, err error) {
err = s.client.Call(c, _Members, arg, &res)
return
}
// NickUpdated get nickUpdated.
func (s *Service) NickUpdated(c context.Context, arg *model.ArgMemberMid) (res bool, err error) {
err = s.client.Call(c, _NickUpdated, arg, &res)
return
}
// SetNickUpdated set nickUpdated.
func (s *Service) SetNickUpdated(c context.Context, arg *model.ArgMemberMid) (err error) {
err = s.client.Call(c, _SetNickUpdated, arg, &_noRes)
return
}
// SetOfficialDoc set official doc.
func (s *Service) SetOfficialDoc(c context.Context, arg *model.ArgOfficialDoc) (err error) {
err = s.client.Call(c, _SetOfficialDoc, arg, &_noRes)
return
}
// SetName set name.
func (s *Service) SetName(c context.Context, arg *model.ArgUpdateUname) (err error) {
err = s.client.Call(c, _setName, arg, &_noRes)
return
}
// SetSign set sign.
func (s *Service) SetSign(c context.Context, arg *model.ArgUpdateSign) (err error) {
err = s.client.Call(c, _setSign, arg, &_noRes)
return
}
// SetBirthday set birthday.
func (s *Service) SetBirthday(c context.Context, arg *model.ArgUpdateBirthday) (err error) {
err = s.client.Call(c, _setBirthday, arg, &_noRes)
return
}
// SetFace set face.
func (s *Service) SetFace(c context.Context, arg *model.ArgUpdateFace) (err error) {
err = s.client.Call(c, _setFace, arg, &_noRes)
return
}
// SetSex set sex.
func (s *Service) SetSex(c context.Context, arg *model.ArgUpdateSex) (err error) {
err = s.client.Call(c, _setSex, arg, &_noRes)
return
}
// SetRank set rank.
func (s *Service) SetRank(c context.Context, arg *model.ArgUpdateRank) (err error) {
err = s.client.Call(c, _setRank, arg, &_noRes)
return
}
// OfficialDoc is.
func (s *Service) OfficialDoc(c context.Context, arg *model.ArgMid) (res *model.OfficialDoc, err error) {
res = new(model.OfficialDoc)
err = s.client.Call(c, _OfficialDoc, arg, res)
return
}

View File

@@ -0,0 +1,31 @@
package gorpc
import (
"context"
"go-common/app/service/main/member/model"
)
// Moral get user moral.
func (s *Service) Moral(c context.Context, arg *model.ArgMemberMid) (res *model.Moral, err error) {
err = s.client.Call(c, _Moral, arg, &res)
return
}
// MoralLog get user moral log.
func (s *Service) MoralLog(c context.Context, arg *model.ArgMemberMid) (res []*model.UserLog, err error) {
err = s.client.Call(c, _MoralLog, arg, &res)
return
}
// AddMoral add moral .
func (s *Service) AddMoral(c context.Context, arg *model.ArgUpdateMoral) (err error) {
err = s.client.Call(c, _addMoral, arg, &_noRes)
return
}
// BatchAddMoral get user moral log.
func (s *Service) BatchAddMoral(c context.Context, arg *model.ArgUpdateMorals) (res map[int64]int64, err error) {
err = s.client.Call(c, _batchAddMoral, arg, &res)
return
}

View File

@@ -0,0 +1,31 @@
package gorpc
import (
"context"
"go-common/app/service/main/member/model"
)
const (
_AddUserMonitor = "RPC.AddUserMonitor"
_IsInMonitor = "RPC.IsInMonitor"
_AddPropertyReview = "RPC.AddPropertyReview"
)
// AddUserMonitor is
func (s *Service) AddUserMonitor(c context.Context, arg *model.ArgAddUserMonitor) error {
return s.client.Call(c, _AddUserMonitor, arg, &_noRes)
}
// IsInMonitor is
func (s *Service) IsInMonitor(c context.Context, arg *model.ArgMid) (bool, error) {
isInMonitor := false
if err := s.client.Call(c, _IsInMonitor, arg, &isInMonitor); err != nil {
return false, err
}
return isInMonitor, nil
}
// AddPropertyReview is
func (s *Service) AddPropertyReview(c context.Context, arg *model.ArgAddPropertyReview) error {
return s.client.Call(c, _AddPropertyReview, arg, &_noRes)
}

View File

@@ -0,0 +1,67 @@
package gorpc
import (
"context"
"go-common/app/service/main/member/model"
)
const (
_RealnameStatus = "RPC.RealnameStatus"
_RealnameApplyStatus = "RPC.RealnameApplyStatus"
_RealnameTelCapture = "RPC.RealnameTelCapture"
_RealnameApply = "RPC.RealnameApply"
_RealnameDetail = "RPC.RealnameDetail"
_RealnameAlipayApply = "RPC.RealnameAlipayApply"
_RealnameAlipayConfirm = "RPC.RealnameAlipayConfirm"
_RealnameAlipayBizno = "RPC.RealnameAlipayBizno"
)
// RealnameStatus get realname current status by mid
func (s *Service) RealnameStatus(c context.Context, arg *model.ArgMemberMid) (res *model.RealnameStatus, err error) {
err = s.client.Call(c, _RealnameStatus, arg, &res)
return
}
// RealnameApplyStatus get user realname apply status
func (s *Service) RealnameApplyStatus(c context.Context, arg *model.ArgMemberMid) (res *model.RealnameApplyStatusInfo, err error) {
err = s.client.Call(c, _RealnameApplyStatus, arg, &res)
return
}
// RealnameTelCapture get user telphone capture
func (s *Service) RealnameTelCapture(c context.Context, arg *model.ArgMemberMid) (err error) {
err = s.client.Call(c, _RealnameTelCapture, arg, &_noRes)
return
}
// RealnameApply put a realname apply
func (s *Service) RealnameApply(c context.Context, arg *model.ArgRealnameApply) (err error) {
err = s.client.Call(c, _RealnameApply, arg, &_noRes)
return
}
// RealnameAlipayApply put a alipay realname apply
func (s *Service) RealnameAlipayApply(c context.Context, arg *model.ArgRealnameAlipayApply) (err error) {
err = s.client.Call(c, _RealnameAlipayApply, arg, &_noRes)
return
}
// RealnameAlipayConfirm confirm a alipay realname apply positivly
func (s *Service) RealnameAlipayConfirm(c context.Context, arg *model.ArgRealnameAlipayConfirm) (err error) {
err = s.client.Call(c, _RealnameAlipayConfirm, arg, &_noRes)
return
}
// RealnameAlipayBizno get alipay realname certify bizno by mid
func (s *Service) RealnameAlipayBizno(c context.Context, arg *model.ArgMemberMid) (res *model.RealnameAlipayInfo, err error) {
err = s.client.Call(c, _RealnameAlipayBizno, arg, &res)
return
}
// RealnameDetail is
func (s *Service) RealnameDetail(c context.Context, arg *model.ArgMemberMid) (res *model.RealnameDetail, err error) {
res = new(model.RealnameDetail)
err = s.client.Call(c, _RealnameDetail, arg, res)
return
}

View File

@@ -0,0 +1,65 @@
package gorpc
import (
"context"
"go-common/app/service/main/member/model"
"go-common/library/net/rpc"
)
const (
_appid = "account.service.member"
)
var (
_noRes = &struct{}{}
_ RPC = &Service{}
)
// Service is a question service.
type Service struct {
client *rpc.Client2
}
// New new a question service.
func New(c *rpc.ClientConfig) (s *Service) {
s = &Service{}
s.client = rpc.NewDiscoveryCli(_appid, c)
return
}
//go:generate mockgen -source member.go -destination mock.go -package member
// RPC is
type RPC interface {
Exp(c context.Context, arg *model.ArgMid2) (res *model.LevelInfo, err error)
Level(c context.Context, arg *model.ArgMid2) (res *model.LevelInfo, err error)
Log(c context.Context, arg *model.ArgMid2) (res []*model.UserLog, err error)
Stat(c context.Context, arg *model.ArgMid2) (res *model.ExpStat, err error)
UpdateExp(c context.Context, arg *model.ArgAddExp) (err error)
Base(c context.Context, arg *model.ArgMemberMid) (res *model.BaseInfo, err error)
Bases(c context.Context, arg *model.ArgMemberMids) (res map[int64]*model.BaseInfo, err error)
Member(c context.Context, arg *model.ArgMemberMid) (res *model.Member, err error)
Members(c context.Context, arg *model.ArgMemberMids) (res map[int64]*model.Member, err error)
NickUpdated(c context.Context, arg *model.ArgMemberMid) (res bool, err error)
SetNickUpdated(c context.Context, arg *model.ArgMemberMid) (err error)
SetOfficialDoc(c context.Context, arg *model.ArgOfficialDoc) (err error)
SetName(c context.Context, arg *model.ArgUpdateUname) (err error)
SetSign(c context.Context, arg *model.ArgUpdateSign) (err error)
SetBirthday(c context.Context, arg *model.ArgUpdateBirthday) (err error)
SetFace(c context.Context, arg *model.ArgUpdateFace) (err error)
SetSex(c context.Context, arg *model.ArgUpdateSex) (err error)
SetRank(c context.Context, arg *model.ArgUpdateRank) (err error)
OfficialDoc(c context.Context, arg *model.ArgMid) (res *model.OfficialDoc, err error)
Moral(c context.Context, arg *model.ArgMemberMid) (res *model.Moral, err error)
MoralLog(c context.Context, arg *model.ArgMemberMid) (res []*model.UserLog, err error)
AddMoral(c context.Context, arg *model.ArgUpdateMoral) (err error)
BatchAddMoral(c context.Context, arg *model.ArgUpdateMorals) (res map[int64]int64, err error)
AddUserMonitor(c context.Context, arg *model.ArgAddUserMonitor) error
IsInMonitor(c context.Context, arg *model.ArgMid) (bool, error)
AddPropertyReview(c context.Context, arg *model.ArgAddPropertyReview) error
RealnameStatus(c context.Context, arg *model.ArgMemberMid) (res *model.RealnameStatus, err error)
RealnameApplyStatus(c context.Context, arg *model.ArgMemberMid) (res *model.RealnameApplyStatusInfo, err error)
RealnameTelCapture(c context.Context, arg *model.ArgMemberMid) (err error)
RealnameApply(c context.Context, arg *model.ArgRealnameApply) (err error)
}

View File

@@ -0,0 +1,46 @@
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 = ["member-service-example.toml"],
importpath = "go-common/app/service/main/member/cmd",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/member/conf:go_default_library",
"//app/service/main/member/server/gorpc:go_default_library",
"//app/service/main/member/server/grpc:go_default_library",
"//app/service/main/member/server/http:go_default_library",
"//app/service/main/member/service:go_default_library",
"//library/log:go_default_library",
"//library/net/trace:go_default_library",
"//library/queue/databus/report: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,56 @@
package main
import (
"context"
"flag"
"os"
"os/signal"
"syscall"
"time"
"go-common/app/service/main/member/conf"
"go-common/app/service/main/member/server/gorpc"
"go-common/app/service/main/member/server/grpc"
"go-common/app/service/main/member/server/http"
"go-common/app/service/main/member/service"
"go-common/library/log"
"go-common/library/net/trace"
"go-common/library/queue/databus/report"
)
func main() {
flag.Parse()
// init conf,log,trace,stat,perf.
if err := conf.Init(); err != nil {
panic(err)
}
log.Init(conf.Conf.Log)
defer log.Close()
trace.Init(conf.Conf.Tracer)
defer trace.Close()
report.InitUser(conf.Conf.ReportUser)
report.InitManager(conf.Conf.ReportManager)
svr := service.New(conf.Conf)
rpcSvr := gorpc.New(conf.Conf, svr)
ws := grpc.New(conf.Conf.WardenServer, svr)
http.Init(conf.Conf, svr)
// signal handler
log.Info("member-service start")
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
for {
s := <-c
log.Info("member-service get a signal %s", s.String())
switch s {
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
ws.Shutdown(context.Background())
rpcSvr.Close()
time.Sleep(time.Second * 2)
log.Info("member-service exit")
return
case syscall.SIGHUP:
default:
return
}
}
}

View File

@@ -0,0 +1,157 @@
# This is a TOML document. Boom.
[xlog]
stdout=true
[rpcServer2]
[mysql]
addr = "172.16.33.205"
dsn = "test:test@tcp(172.16.33.205:3308)/bilibili_member?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"
[mysql.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[accMysql]
addr = "172.16.33.205:3306"
dsn = "account:wx2U1MwXRyWEuURw@tcp(172.16.33.205:3306)/account?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 50
idle = 5
idleTimeout = "4h"
queryTimeout = "2s"
execTimeout = "2s"
tranTimeout = "2s"
[accMysql.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[memcache]
name = "member-service"
proto = "tcp"
addr = "172.18.33.61:11219"
idle = 5
active = 10
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "10s"
[cacheTTL]
baseTTL = "24h"
moralTTL = "24h"
captureTimesTTL = "1h"
captureCodeTTL = "5m"
captureErrTimesTTL = "5m"
applyInfoTTL = "5m"
[redis]
name = "member-service"
proto = "tcp"
addr = "127.0.0.1:6379"
idle = 100
active = 100
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "10s"
[httpClient]
key="7d9f6f6fe2a898e8"
secret= "4de2ccdbd9db69be0c2c6437bfe6eb69"
dial = "500ms"
timeout = "1s"
keepAlive = "60s"
timer = 10
[httpClient.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[databus]
key = "4ba46ba31f9a44ef"
secret = "e4c5a7fce28695209e6b4f0af8cf91c5"
group = "AccountLog-MainAccount-P"
topic = "AccountLog-T"
action = "pub"
name = "member-service/databus"
proto = "tcp"
addr = "172.18.33.50:6205"
idle = 100
active = 100
dialTimeout = "1s"
readTimeout = "60s"
writeTimeout = "1s"
idleTimeout = "10s"
[accountnotify]
key = "4ba46ba31f9a44ef"
secret = "e4c5a7fce28695209e6b4f0af8cf91c5"
group = "AccountNotify-MainAccount-P"
topic = "AccountNotify-T"
action = "pub"
buffer = 2048
name = "account-notify-job/databus"
proto = "tcp"
addr = "172.18.33.50:6205"
idle = 1
active = 1
dialTimeout = "1s"
readTimeout = "60s"
writeTimeout = "1s"
idleTimeout = "10s"
[wardenServer]
addr = "0.0.0.0:9000"
timeout = "1s"
[host]
search="http://uat-bili-search.bilibili.co"
[realnameProperty]
imgURLTemplate = "http://uat-manager.bilibili.co/x/admin/member/realname/image/preview?token=%s&border_size=800"
# block
[BlockMySQL]
addr = "172.16.33.205:3306"
dsn = "bilibili_block:NfAKk5h6ZMkx9o3EZPO2BIX3doCqXy6H@tcp(172.16.33.205:3306)/bilibili_block?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 20
idle = 10
idleTimeout ="4h"
queryTimeout = "1s"
execTimeout = "1s"
tranTimeout = "1s"
[BlockMemcache]
name = "block-service"
proto = "tcp"
addr = "172.18.33.60:11233"
idle = 5
active = 10
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "10s"
[blockCacheTTL]
userTTL = "80m"
userMaxRate = 20.0
# 越大延长概率越小
userT = 0.7
[BlockProperty]
msgURL = "http://message.bilibili.co/api/notify/send.user.notify.do"
whiteList = [2, 46333]

View File

@@ -0,0 +1,43 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["conf.go"],
importpath = "go-common/app/service/main/member/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/http/blademaster/middleware/verify:go_default_library",
"//library/net/rpc:go_default_library",
"//library/net/rpc/warden:go_default_library",
"//library/net/trace:go_default_library",
"//library/queue/databus:go_default_library",
"//library/time:go_default_library",
"//vendor/github.com/BurntSushi/toml:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,159 @@
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"
v "go-common/library/net/http/blademaster/middleware/verify"
"go-common/library/net/rpc"
"go-common/library/net/rpc/warden"
"go-common/library/net/trace"
"go-common/library/queue/databus"
"go-common/library/time"
"github.com/BurntSushi/toml"
)
// Conf global variable.
var (
Conf = &Config{}
client *conf.Client
confPath string
)
// Config struct of conf.
type Config struct {
Log *log.Config
BM *bm.ServerConfig
HTTPClient *bm.ClientConfig
RPCServer *rpc.ServerConfig
WardenServer *warden.ServerConfig
AccMysql *sql.Config
Mysql *sql.Config
Memcache *memcache.Config
CacheTTL *CacheTTL
Tracer *trace.Config
Databus *databus.Config
Redis *redis.Config
AccountNotify *databus.Config
ReportUser *databus.Config
ReportManager *databus.Config
Host *Host
Verify *v.Config
// realname
RealnameProperty *RealnameProperty
// block
BlockMySQL *sql.Config
BlockMemcache *memcache.Config
BlockProperty *BlockProperty
BlockCacheTTL *BlockCacheTTL
}
// Host is
type Host struct {
Search string
}
// CacheTTL cache live time.
type CacheTTL struct {
BaseTTL time.Duration
MoralTTL time.Duration
CaptureTimesTTL time.Duration
CaptureCodeTTL time.Duration
CaptureErrTimesTTL time.Duration
ApplyInfoTTL time.Duration
}
// RealnameProperty .
type RealnameProperty struct {
IMGURLTemplate string
}
// BlockProperty .
type BlockProperty struct {
MSGURL string
WhiteList []int64
}
// BlockCacheTTL is
type BlockCacheTTL struct {
UserTTL time.Duration
UserMaxRate float64
UserT float64
}
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()
}
// RsaPub is realname rsa pub key
func RsaPub() (key string) {
if client == nil {
return ""
}
key, _ = client.Value("realname.rsa.pub")
return
}
// RsaPriv is realname rsa priv key
func RsaPriv() (key string) {
if client == nil {
return ""
}
key, _ = client.Value("realname.rsa.priv")
return
}

View File

@@ -0,0 +1,92 @@
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",
"databus_test.go",
"exp_test.go",
"hbase_test.go",
"member_log_test.go",
"memcache_test.go",
"message_test.go",
"moral_test.go",
"mysql_test.go",
"property_review_test.go",
"realname_test.go",
"redis_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/service/main/member/conf:go_default_library",
"//app/service/main/member/model:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/time:go_default_library",
"//vendor/github.com/bouk/monkey:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
"//vendor/gopkg.in/h2non/gock.v1:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"dao.go",
"databus.go",
"exp.go",
"hbase.go",
"member_log.go",
"memcache.go",
"message.go",
"moral.go",
"mysql.go",
"property_review.go",
"realname.go",
"redis.go",
],
importpath = "go-common/app/service/main/member/dao",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/member/conf:go_default_library",
"//app/service/main/member/dao/block:go_default_library",
"//app/service/main/member/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/net/metadata:go_default_library",
"//library/queue/databus:go_default_library",
"//library/queue/databus/report:go_default_library",
"//library/sync/pipeline/fanout:go_default_library",
"//library/time: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",
"//app/service/main/member/dao/block:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,67 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = [
"dao.go",
"http.go",
"mc.go",
"mysql.go",
],
importpath = "go-common/app/service/main/member/dao/block",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/member/conf:go_default_library",
"//app/service/main/member/model/block:go_default_library",
"//library/cache/memcache: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/time:go_default_library",
"//library/xstr: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"],
)
go_test(
name = "go_default_test",
srcs = [
"dao_test.go",
"http_test.go",
"mc_test.go",
"mysql_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/service/main/member/conf:go_default_library",
"//app/service/main/member/model/block:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/database/sql:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)

View File

@@ -0,0 +1,97 @@
package block
import (
"context"
"math"
"math/rand"
"time"
"go-common/app/service/main/member/conf"
"go-common/library/cache/memcache"
"go-common/library/database/sql"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
xtime "go-common/library/time"
"github.com/pkg/errors"
)
type notifyFunc func(context.Context, int64, string) error
// Dao is
type Dao struct {
*cacheTTL
c *conf.Config
mc *memcache.Pool
db *sql.DB
client *bm.Client
NotifyPurgeCache notifyFunc
}
type cacheTTL struct {
UserTTL int32
UserMaxRate float64
UserT float64
}
// New is
func New(conf *conf.Config, db *sql.DB, mc *memcache.Pool, client *bm.Client, notifyFunc notifyFunc) *Dao {
d := &Dao{
c: conf,
mc: mc,
db: db,
client: client,
NotifyPurgeCache: notifyFunc,
}
d.cacheTTL = newCacheTTL(conf.BlockCacheTTL)
return d
}
// BeginTran is
func (d *Dao) BeginTran(c context.Context) (tx *sql.Tx, err error) {
if tx, err = d.db.Begin(c); err != nil {
err = errors.WithStack(err)
}
return
}
func durationToSeconds(expire xtime.Duration) int32 {
return int32(time.Duration(expire) / time.Second)
}
func newCacheTTL(c *conf.BlockCacheTTL) *cacheTTL {
return &cacheTTL{
UserTTL: durationToSeconds(c.UserTTL),
UserMaxRate: c.UserMaxRate,
UserT: c.UserT,
}
}
func (ttl *cacheTTL) mcUserExpire(key string) (sec int32) {
if ttl.UserT == 0.0 {
return ttl.UserTTL
}
// rate = -log(1-x)/t
rate := -math.Log(1-rand.Float64()) / ttl.UserT
if rate <= 1.0 {
return ttl.UserTTL
}
if rate > ttl.UserMaxRate {
rate = ttl.UserMaxRate
}
sec = int32(rate * float64(ttl.UserTTL))
if rate >= 5.0 {
log.Info("mc hotkey : %s, expire rate : %.2f , time : %d", key, rate, sec)
}
return
}
// Close close the resource.
func (d *Dao) Close() {
if d.mc != nil {
d.mc.Close()
}
if d.db != nil {
d.db.Close()
}
}

View File

@@ -0,0 +1,43 @@
package block
import (
"flag"
"os"
"testing"
"go-common/app/service/main/member/conf"
"go-common/library/cache/memcache"
"go-common/library/database/sql"
bm "go-common/library/net/http/blademaster"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.account.member-service")
flag.Set("conf_token", "ef70dbff7ee115ce242c67e633b21c29")
flag.Set("tree_id", "2137")
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")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
c := conf.Conf
d = New(c,
sql.NewMySQL(c.BlockMySQL),
memcache.NewPool(c.BlockMemcache),
bm.NewClient(c.HTTPClient),
nil,
)
m.Run()
os.Exit(0)
}

View File

@@ -0,0 +1,46 @@
package block
import (
"context"
"fmt"
"net/url"
"strings"
"go-common/library/ecode"
"github.com/pkg/errors"
)
// SendSysMsg send sys msg.
func (d *Dao) SendSysMsg(c context.Context, code string, mids []int64, title string, content string, remoteIP string) (err error) {
params := url.Values{}
params.Set("mc", code)
params.Set("title", title)
params.Set("data_type", "4")
params.Set("context", content)
params.Set("mid_list", midsToParam(mids))
var res struct {
Code int `json:"code"`
Data *struct {
Status int8 `json:"status"`
Remark string `json:"remark"`
} `json:"data"`
}
if err = d.client.Post(c, d.c.BlockProperty.MSGURL, remoteIP, params, &res); err != nil {
err = errors.WithStack(err)
return
}
if res.Code != 0 {
err = errors.WithStack(ecode.Int(res.Code))
return
}
return
}
func midsToParam(mids []int64) (str string) {
strs := make([]string, 0, len(mids))
for _, mid := range mids {
strs = append(strs, fmt.Sprintf("%d", mid))
}
return strings.Join(strs, ",")
}

View File

@@ -0,0 +1,41 @@
package block
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoSendSysMsg(t *testing.T) {
convey.Convey("SendSysMsg", t, func(ctx convey.C) {
var (
c = context.Background()
mids = []int64{1, 2, 3}
content = "账号违规处理通知-test-content"
remoteIP = "127.0.0.1"
code = "2_3_2"
title = "账号违规处理通知-test"
)
ctx.Convey("When everything right", func(ctx convey.C) {
err := d.SendSysMsg(c, code, mids, title, content, remoteIP)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaomidsToParam(t *testing.T) {
convey.Convey("midsToParam", t, func(ctx convey.C) {
var (
mids = []int64{46333, 35858}
)
ctx.Convey("When everything right", func(ctx convey.C) {
str := midsToParam(mids)
ctx.Convey("Then str should equal mids[0],mids[1],....", func(ctx convey.C) {
ctx.So(str, convey.ShouldEqual, "46333,35858")
})
})
})
}

View File

@@ -0,0 +1,171 @@
package block
import (
"context"
"fmt"
model "go-common/app/service/main/member/model/block"
"go-common/library/cache/memcache"
"go-common/library/log"
"github.com/pkg/errors"
)
func userKey(mid int64) (key string) {
key = fmt.Sprintf("u_%d", mid)
return
}
func userDetailKey(mid int64) (key string) {
key = fmt.Sprintf("ud_%d", mid)
return
}
// UsersCache get block info by mids
func (d *Dao) UsersCache(c context.Context, mids []int64) (res map[int64]*model.MCBlockInfo, err error) {
res = make(map[int64]*model.MCBlockInfo, len(mids))
if len(mids) == 0 {
return
}
var (
keys = make([]string, 0, len(mids))
keyMap = make(map[string]int64, len(mids))
key string
conn = d.mc.Get(c)
rs map[string]*memcache.Item
)
defer conn.Close()
for _, mid := range mids {
key = userKey(mid)
if _, ok := keyMap[key]; !ok {
keyMap[key] = mid
keys = append(keys, key)
}
}
if rs, err = conn.GetMulti(keys); err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
err = errors.Wrapf(err, "keys : %+v", keys)
return
}
for k, r := range rs {
info := &model.MCBlockInfo{}
if err = conn.Scan(r, info); err != nil {
err = errors.Wrapf(err, "key : %s", k)
log.Error("%+v", err)
err = nil
continue
}
res[keyMap[k]] = info
}
return
}
// SetUserCache set user block info to cache
func (d *Dao) SetUserCache(c context.Context, mid int64, status model.BlockStatus, startTime, endTime int64) (err error) {
var (
key = userKey(mid)
conn = d.mc.Get(c)
info = &model.MCBlockInfo{
BlockStatus: status,
StartTime: startTime,
EndTime: endTime,
}
)
log.Info("Set User Cache key (%s) obj (%+v)", key, info)
defer conn.Close()
if err = conn.Set(&memcache.Item{
Key: key,
Object: info,
Expiration: d.mcUserExpire(key),
Flags: memcache.FlagJSON,
}); err != nil {
err = (err)
return
}
return
}
// DeleteUserCache delete user cache
func (d *Dao) DeleteUserCache(c context.Context, mid int64) (err error) {
var (
key = userKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Delete(key); err != nil {
err = (err)
return
}
return
}
// SetUserDetailCache set user detail to cache
func (d *Dao) SetUserDetailCache(c context.Context, mid int64, detail *model.MCUserDetail) (err error) {
var (
key = userDetailKey(mid)
conn = d.mc.Get(c)
)
log.Info("Set User Detail Cache key (%s) obj (%+v)", key, detail)
defer conn.Close()
if err = conn.Set(&memcache.Item{
Key: key,
Object: detail,
Expiration: d.mcUserExpire(key),
Flags: memcache.FlagJSON,
}); err != nil {
return
}
return
}
// DeleteUserDetailCache delete user detail cache
func (d *Dao) DeleteUserDetailCache(c context.Context, mid int64) (err error) {
var (
key = userDetailKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
err = conn.Delete(key)
return
}
// UserDetailsCache .
func (d *Dao) UserDetailsCache(c context.Context, mids []int64) (res map[int64]*model.MCUserDetail, err error) {
res = make(map[int64]*model.MCUserDetail)
if len(mids) == 0 {
return
}
var (
keys = make([]string, 0, len(mids))
keyMap = make(map[string]int64, len(mids))
key string
conn = d.mc.Get(c)
rs map[string]*memcache.Item
)
defer conn.Close()
for _, mid := range mids {
key = userDetailKey(mid)
if _, ok := keyMap[key]; !ok {
keyMap[key] = mid
keys = append(keys, key)
}
}
if rs, err = conn.GetMulti(keys); err != nil {
err = errors.Wrapf(err, "keys : %+v", keys)
return
}
for k, r := range rs {
detail := &model.MCUserDetail{}
if err = conn.Scan(r, detail); err != nil {
err = errors.Wrapf(err, "key : %+v", k)
log.Error("%+v", err)
err = nil
continue
}
res[keyMap[k]] = detail
}
return
}

View File

@@ -0,0 +1,99 @@
package block
import (
"context"
"testing"
"time"
"go-common/app/service/main/member/conf"
model "go-common/app/service/main/member/model/block"
"github.com/smartystreets/goconvey/convey"
)
func TestDaouserKey(t *testing.T) {
convey.Convey("userKey", t, func(ctx convey.C) {
var (
mid = int64(46333)
)
ctx.Convey("When everything right", func(ctx convey.C) {
key := userKey(mid)
ctx.Convey("Then key should equal u_mid.", func(ctx convey.C) {
ctx.So(key, convey.ShouldEqual, "u_46333")
})
})
})
}
func TestDaoSetUserCache(t *testing.T) {
convey.Convey("SetUserCache", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(46333)
status = model.BlockStatusForever
startTime = time.Now().Unix()
endTime = time.Now().Add(time.Minute).Unix()
)
ctx.Convey("When SetUserCache", func(ctx convey.C) {
err := d.SetUserCache(c, mid, status, startTime, endTime)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.Convey("When get UsersCache", func(ctx convey.C) {
res, err := d.UsersCache(c, []int64{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)
})
})
ctx.Convey("When delete UsersCache", func(ctx convey.C) {
err := d.DeleteUserCache(c, mid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
})
})
}
func TestDaomcUserExpire(t *testing.T) {
convey.Convey("mcUserExpire", t, func(ctx convey.C) {
ctx.Convey("When everything right", func(ctx convey.C) {
sec := d.mcUserExpire("ut_key")
ctx.Convey("Then sec should >=mcUserExpireBase and <=mcUserExpireBase*conf.Conf.Memcache.Expire.UserMaxRate .", func(ctx convey.C) {
ctx.So(d.UserTTL, convey.ShouldBeGreaterThan, 0)
ctx.So(conf.Conf.BlockCacheTTL.UserMaxRate, convey.ShouldBeGreaterThan, 0)
ctx.So(sec, convey.ShouldBeGreaterThanOrEqualTo, d.UserTTL)
ctx.So(sec, convey.ShouldBeLessThanOrEqualTo, int32(conf.Conf.BlockCacheTTL.UserMaxRate*float64(d.UserTTL)))
})
})
})
}
func TestDaoSetUserDetailCache(t *testing.T) {
convey.Convey("SetUserDetailCache", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(46333)
)
ctx.Convey("When SetUserDetailCache", func(ctx convey.C) {
err := d.SetUserDetailCache(c, mid, &model.MCUserDetail{BlockCount: 12})
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.Convey("When get UserDetailCache", func(ctx convey.C) {
res, err := d.UserDetailsCache(c, []int64{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)
})
})
ctx.Convey("When delete UsersDetailCache", func(ctx convey.C) {
err := d.DeleteUserDetailCache(c, mid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
})
})
}

View File

@@ -0,0 +1,184 @@
package block
import (
"context"
"fmt"
model "go-common/app/service/main/member/model/block"
xsql "go-common/library/database/sql"
"go-common/library/xstr"
"github.com/pkg/errors"
)
const (
_user = `SELECT id,mid,status,ctime,mtime FROM block_user WHERE mid=? LIMIT 1`
_upsertUser = `INSERT INTO block_user (mid,status) VALUES (?,?) ON DUPLICATE KEY UPDATE status=?`
_userStatusList = `SELECT id,mid FROM block_user WHERE status=? AND id >= 0 LIMIT ?`
_userStatusListWithMIDs = `SELECT mid FROM block_user WHERE status=? AND mid IN (%s)`
_userLastHistory = `SELECT id,mid,action,start_time,duration FROM block_history_%d WHERE mid=? ORDER BY id DESC LIMIT 1`
_addAddBlockCount = `INSERT INTO block_user_detail (mid,block_count) VALUES (?,1) ON DUPLICATE KEY UPDATE block_count=block_count+1`
_insertHistory = `INSERT INTO block_history_%d (mid,admin_id,admin_name,source,area,reason,comment,action,start_time,duration,notify) VALUES (?,?,?,?,?,?,?,?,?,?,?)`
_userDetails = `SELECT id,mid,block_count,ctime,mtime FROM block_user_detail WHERE mid IN (%s)`
)
func historyIdx(mid int64) int64 {
return mid % 10
}
// User get block user from db
func (d *Dao) User(c context.Context, mid int64) (user *model.DBUser, err error) {
user = &model.DBUser{}
row := d.db.QueryRow(c, _user, mid)
if err = row.Scan(&user.ID, &user.MID, &user.Status, &user.CTime, &user.MTime); err != nil {
if err == xsql.ErrNoRows {
err = nil
user = nil
return
}
err = errors.WithStack(err)
return
}
return
}
// UserLastHistory get lastest block history
func (d *Dao) UserLastHistory(c context.Context, mid int64) (his *model.DBHistory, err error) {
var (
sql = fmt.Sprintf(_userLastHistory, historyIdx(mid))
)
row := d.db.QueryRow(c, sql, mid)
his = &model.DBHistory{}
if err = row.Scan(&his.ID, &his.MID, &his.Action, &his.StartTime, &his.Duration); err != nil {
if err == xsql.ErrNoRows {
err = nil
his = nil
return
}
err = errors.WithStack(err)
return
}
return
}
// UserStatusList get user status list
func (d *Dao) UserStatusList(c context.Context, status model.BlockStatus, startID int64, limit int) (maxID int64, mids []int64, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, _userStatusList, status, startID, limit); err != nil {
err = errors.WithStack(err)
return
}
defer rows.Close()
for rows.Next() {
var (
id, mid int64
)
if err = rows.Scan(&id, &mid); err != nil {
err = errors.WithStack(err)
return
}
if maxID < id {
maxID = id
}
mids = append(mids, mid)
}
if err = rows.Err(); err != nil {
err = errors.WithStack(err)
return
}
return
}
// UserStatusMapWithMIDs get user block status map by mids
func (d *Dao) UserStatusMapWithMIDs(c context.Context, status model.BlockStatus, mids []int64) (midMap map[int64]struct{}, err error) {
var (
rows *xsql.Rows
)
url := fmt.Sprintf(_userStatusListWithMIDs, xstr.JoinInts(mids))
if rows, err = d.db.Query(c, url, status); err != nil {
err = errors.WithStack(err)
return
}
defer rows.Close()
midMap = make(map[int64]struct{})
for rows.Next() {
var (
mid int64
)
if err = rows.Scan(&mid); err != nil {
err = errors.WithStack(err)
return
}
midMap[mid] = struct{}{}
}
if err = rows.Err(); err != nil {
err = errors.WithStack(err)
return
}
return
}
// TxUpdateUser is
func (d *Dao) TxUpdateUser(c context.Context, tx *xsql.Tx, mid int64, status model.BlockStatus) (err error) {
if _, err = tx.Exec(_upsertUser, mid, status, status); err != nil {
err = errors.WithStack(err)
return
}
return
}
// UpdateAddBlockCount is
func (d *Dao) UpdateAddBlockCount(c context.Context, mid int64) (err error) {
if _, err = d.db.Exec(c, _addAddBlockCount, mid); err != nil {
err = errors.WithStack(err)
return
}
return
}
// TxInsertHistory is
func (d *Dao) TxInsertHistory(c context.Context, tx *xsql.Tx, h *model.DBHistory) (err error) {
var (
sql = fmt.Sprintf(_insertHistory, historyIdx(h.MID))
)
if _, err = tx.Exec(sql, h.MID, h.AdminID, h.AdminName, h.Source, h.Area, h.Reason, h.Comment, h.Action, h.StartTime, h.Duration, h.Notify); err != nil {
err = errors.WithStack(err)
return
}
return
}
// UserDetails .
func (d *Dao) UserDetails(c context.Context, mids []int64) (midMap map[int64]*model.DBUserDetail, err error) {
var (
rows *xsql.Rows
)
sql := fmt.Sprintf(_userDetails, xstr.JoinInts(mids))
if rows, err = d.db.Query(c, sql); err != nil {
err = errors.WithStack(err)
return
}
defer rows.Close()
midMap = make(map[int64]*model.DBUserDetail, len(mids))
for rows.Next() {
detail := &model.DBUserDetail{}
if err = rows.Scan(&detail.ID, &detail.MID, &detail.BlockCount, &detail.CTime, &detail.MTime); err != nil {
err = errors.WithStack(err)
return
}
midMap[detail.MID] = detail
}
if err = rows.Err(); err != nil {
err = errors.WithStack(err)
return
}
return
}

View File

@@ -0,0 +1,150 @@
package block
import (
"context"
"testing"
"time"
model "go-common/app/service/main/member/model/block"
"github.com/smartystreets/goconvey/convey"
)
func TestDaohistoryIdx(t *testing.T) {
convey.Convey("historyIdx", t, func(ctx convey.C) {
var (
mid = int64(46333)
)
ctx.Convey("When everything right", func(ctx convey.C) {
shard := historyIdx(mid)
ctx.Convey("Then shard should equal mid % 10.", func(ctx convey.C) {
ctx.So(shard, convey.ShouldEqual, 3)
})
})
})
}
func TestDaoUser(t *testing.T) {
convey.Convey("User", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(46333)
)
ctx.Convey("When everything right", func(ctx convey.C) {
user, err := d.User(c, mid)
ctx.Convey("Then err should be nil.user should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(user, convey.ShouldNotBeNil)
ctx.So(user.MID, convey.ShouldEqual, mid)
})
})
})
}
func TestDaoTxInsertHistory(t *testing.T) {
convey.Convey("TxInsertHistory", t, func(ctx convey.C) {
var (
c = context.Background()
tx, _ = d.db.Begin(c)
his = &model.DBHistory{
MID: 46333,
AdminID: 2333,
AdminName: "ut",
Source: model.BlockSourceBlackHouse,
Area: model.BlockAreaAlbum,
Reason: "ut reason",
Comment: "ut comment",
Action: model.BlockActionLimit,
StartTime: time.Now(),
Duration: 60,
Notify: false,
CTime: time.Now(),
MTime: time.Now(),
}
)
ctx.Convey("When everything right", func(ctx convey.C) {
err := d.TxInsertHistory(c, tx, his)
ctx.So(err, convey.ShouldBeNil)
err = tx.Commit()
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.Convey("When get UserLastHistory", func(ctx convey.C) {
his2, err := d.UserLastHistory(c, his.MID)
ctx.Convey("Then err should be nil.his2 should resemble his.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(his2.MID, convey.ShouldEqual, his.MID)
ctx.So(his2.Action, convey.ShouldEqual, his.Action)
ctx.So(his2.StartTime.Unix(), convey.ShouldEqual, his.StartTime.Unix())
ctx.So(his2.Duration, convey.ShouldEqual, his.Duration)
})
})
})
})
})
}
func TestDaoTxUpdateUser(t *testing.T) {
var (
c = context.Background()
tx, _ = d.db.Begin(c)
mid = int64(46333)
status = model.BlockStatusFalse
)
convey.Convey("TxUpdateUser", t, func(ctx convey.C) {
ctx.Convey("When everything right", func(ctx convey.C) {
err := d.TxUpdateUser(c, tx, mid, status)
ctx.So(err, convey.ShouldBeNil)
err = tx.Commit()
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoUserStatusMapWithMIDs(t *testing.T) {
convey.Convey("UserStatusMapWithMIDs", t, func(ctx convey.C) {
var (
c = context.Background()
status = model.BlockStatusFalse
mids = []int64{46333, 2, 35858}
)
ctx.Convey("When everything right", func(ctx convey.C) {
midMap, err := d.UserStatusMapWithMIDs(c, status, mids)
ctx.Convey("Then err should be nil.midMap should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(midMap, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoUpdateAddBlockCount(t *testing.T) {
convey.Convey("UpdateAddBlockCount", t, func(ctx convey.C) {
var (
c = context.TODO()
mid = int64(46333)
)
ctx.Convey("When everything right", func(ctx convey.C) {
err := d.UpdateAddBlockCount(c, mid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestUserDetails(t *testing.T) {
convey.Convey("get user details", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(46333)
)
ctx.Convey("When get user details from db", func(ctx convey.C) {
_, err := d.UserDetails(c, []int64{mid})
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}

View File

@@ -0,0 +1,114 @@
package dao
import (
"context"
"time"
"go-common/app/service/main/member/conf"
"go-common/app/service/main/member/dao/block"
"go-common/library/cache/memcache"
"go-common/library/cache/redis"
"go-common/library/database/sql"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/queue/databus"
"go-common/library/sync/pipeline/fanout"
xtime "go-common/library/time"
)
const (
_searchLogURI = "/x/admin/search/log"
_deleteLogURI = "/x/admin/search/log/delete"
)
// Dao struct info of Dao.
type Dao struct {
*cacheTTL
accdb *sql.DB
db *sql.DB
mc *memcache.Pool
c *conf.Config
client *bm.Client
redis *redis.Pool
cache *fanout.Fanout
// databus
logDatabus *databus.Databus
accNotify *databus.Databus
block *block.Dao
}
type cacheTTL struct {
baseTTL int32
moralTTL int32
captureTimesTTL int32
captureCodeTTL int32
captureErrTimesTTL int32
applyInfoTTL int32
}
// New new a Dao and return.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
accdb: sql.NewMySQL(c.AccMysql),
db: sql.NewMySQL(c.Mysql),
mc: memcache.NewPool(c.Memcache),
client: bm.NewClient(c.HTTPClient),
redis: redis.NewPool(c.Redis),
cache: fanout.New("memberServiceCache", fanout.Worker(1), fanout.Buffer(10240)),
logDatabus: databus.New(c.Databus),
accNotify: databus.New(c.AccountNotify),
}
d.block = block.New(
c,
sql.NewMySQL(c.BlockMySQL),
memcache.NewPool(c.BlockMemcache),
d.client,
d.NotifyPurgeCache,
)
d.cacheTTL = newCacheTTL(c.CacheTTL)
return
}
// Ping ping health.
func (d *Dao) Ping(c context.Context) error {
if err := d.db.Ping(c); err != nil {
log.Error("Failed to ping database: %+v", err)
return err
}
return d.pingMC(c)
}
// Close close connections of mc, redis, db.
func (d *Dao) Close() {
if d.mc != nil {
d.mc.Close()
}
if d.db != nil {
d.db.Close()
}
if d.block != nil {
d.block.Close()
}
}
func durationToSeconds(expire xtime.Duration) int32 {
return int32(time.Duration(expire) / time.Second)
}
func newCacheTTL(c *conf.CacheTTL) *cacheTTL {
return &cacheTTL{
baseTTL: durationToSeconds(c.BaseTTL),
moralTTL: durationToSeconds(c.MoralTTL),
captureTimesTTL: durationToSeconds(c.CaptureErrTimesTTL),
captureCodeTTL: durationToSeconds(c.CaptureCodeTTL),
captureErrTimesTTL: durationToSeconds(c.CaptureErrTimesTTL),
applyInfoTTL: durationToSeconds(c.ApplyInfoTTL),
}
}
// BlockImpl is
func (d *Dao) BlockImpl() *block.Dao {
return d.block
}

View File

@@ -0,0 +1,40 @@
package dao
import (
"flag"
"os"
"testing"
"go-common/app/service/main/member/conf"
"gopkg.in/h2non/gock.v1"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.account.member-service")
flag.Set("conf_token", "ef70dbff7ee115ce242c67e633b21c29")
flag.Set("tree_id", "2137")
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/member-service-example.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
d.client.SetTransport(gock.DefaultTransport)
m.Run()
os.Exit(0)
}

View File

@@ -0,0 +1,42 @@
package dao
import (
"context"
"fmt"
"strconv"
"time"
"go-common/app/service/main/member/model"
)
func notifyKey(mid int64) string {
return fmt.Sprintf("MemberService-AccountNotify-T%d", mid)
}
// AddExplog add exp log with databus
func (d *Dao) AddExplog(c context.Context, mid, exp, toExp int64, oper, reason, ip string) (err error) {
log := &model.UserLog{
Mid: mid,
IP: ip,
TS: time.Now().Unix(),
LogID: model.UUID4(),
Content: map[string]string{
"from_exp": strconv.FormatInt(exp, 10),
"to_exp": strconv.FormatInt(toExp, 10),
"operater": oper,
"reason": reason,
},
}
err = d.logDatabus.Send(c, strconv.FormatInt(mid, 10), log)
return
}
// NotifyPurgeCache is
func (d *Dao) NotifyPurgeCache(c context.Context, mid int64, action string) error {
msg := &model.NotifyInfo{
Mid: mid,
Action: action,
}
key := notifyKey(mid)
return d.accNotify.Send(c, key, msg)
}

View File

@@ -0,0 +1,52 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaonotifyKey(t *testing.T) {
var (
mid = int64(4780461)
)
convey.Convey("notifyKey", t, func(ctx convey.C) {
p1 := notifyKey(mid)
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaoAddExplog(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
exp = int64(0)
toExp = int64(0)
oper = ""
reason = ""
ip = ""
)
convey.Convey("AddExplog", t, func(ctx convey.C) {
err := d.AddExplog(c, mid, exp, toExp, oper, reason, ip)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoNotifyPurgeCache(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
action = ""
)
convey.Convey("NotifyPurgeCache", t, func(ctx convey.C) {
p1 := d.NotifyPurgeCache(c, mid, action)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldBeNil)
})
})
}

View File

@@ -0,0 +1,113 @@
package dao
import (
"context"
"encoding/json"
"net/url"
"strconv"
"time"
"go-common/app/service/main/member/model"
"go-common/library/cache/memcache"
"go-common/library/ecode"
"go-common/library/log"
)
const (
_expLogID = 11
)
// Exp get user exp from cache,if miss get from db.
func (d *Dao) Exp(c context.Context, mid int64) (exp int64, err error) {
if exp, err = d.expCache(c, mid); err == nil {
return
}
if err != nil && err != memcache.ErrNotFound {
return
}
if exp, err = d.ExpDB(c, mid); err != nil {
return
}
d.SetExpCache(c, mid, exp)
return
}
// Exps get exps by mids.
func (d *Dao) Exps(c context.Context, mids []int64) (exps map[int64]int64, err error) {
exps, miss, err := d.expsCache(c, mids)
if err != nil {
return
}
if len(miss) == 0 {
return
}
for _, mid := range miss {
mid := mid
exp, err := d.ExpDB(c, mid)
if err != nil {
log.Error("exp mid %d err %v", mid, err)
err = nil
continue
}
exps[mid] = exp
d.cache.Do(c, func(ctx context.Context) {
d.SetExpCache(ctx, mid, exp)
})
}
return
}
// ExpLog is
func (d *Dao) ExpLog(ctx context.Context, mid int64, ip string) ([]*model.UserLog, error) {
t := time.Now().Add(-time.Hour * 24 * 7)
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
params.Set("appid", "log_user_action")
params.Set("business", strconv.FormatInt(_expLogID, 10))
params.Set("pn", "1")
params.Set("ps", "1000")
params.Set("ctime_from", t.Format("2006-01-02 00:00:00"))
params.Set("sort", "desc")
params.Set("order", "ctime")
res := &model.SearchResult{}
if err := d.client.Get(ctx, d.c.Host.Search+_searchLogURI, ip, params, res); err != nil {
return nil, err
}
if res.Code != 0 {
return nil, ecode.Int(res.Code)
}
logs := asExpLog(res)
return logs, nil
}
func asExpLog(res *model.SearchResult) []*model.UserLog {
logs := make([]*model.UserLog, 0, len(res.Data.Result))
for _, r := range res.Data.Result {
ts, err := time.ParseInLocation("2006-01-02 15:04:05", r.Ctime, time.Local)
if err != nil {
log.Warn("Failed to parse log ctime: ctime: %s: %+v", r.Ctime, err)
continue
}
content := map[string]string{
"from_exp": "",
"operater": "",
"reason": "",
"to_exp": "",
"log_id": "",
}
if err := json.Unmarshal([]byte(r.ExtraData), &content); err != nil {
log.Warn("Failed to parse extra data in exp log: mid: %d, extra_data: %s: %+v", r.Mid, r.ExtraData, err)
continue
}
l := &model.UserLog{
Mid: r.Mid,
IP: r.IP,
TS: ts.Unix(),
LogID: content["log_id"],
Content: content,
}
logs = append(logs, l)
}
return logs
}

View File

@@ -0,0 +1,78 @@
package dao
import (
"context"
"testing"
"go-common/app/service/main/member/model"
"github.com/smartystreets/goconvey/convey"
"gopkg.in/h2non/gock.v1"
)
func TestDaoExp(t *testing.T) {
var (
c = context.TODO()
mid = int64(4780461)
)
convey.Convey("Exp", t, func(ctx convey.C) {
exp, err := d.Exp(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("exp should not be nil", func(ctx convey.C) {
t.Logf("exp:%+v", exp)
ctx.So(exp, convey.ShouldNotBeNil)
})
})
}
func TestDaoExps(t *testing.T) {
var (
c = context.TODO()
mids = []int64{4780461, 2}
)
convey.Convey("Exps", t, func(ctx convey.C) {
exps, err := d.Exps(c, mids)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("exps should not be nil", func(ctx convey.C) {
ctx.So(exps, convey.ShouldNotBeNil)
})
})
}
func TestDaoExpLog(t *testing.T) {
var (
c = context.TODO()
mid = int64(0)
ip = ""
searchLogUrl = "http://uat-bili-search.bilibili.co/x/admin/search/log"
)
convey.Convey("ExpLog", t, func(ctx convey.C) {
d.client.SetTransport(gock.DefaultTransport)
defer gock.OffAll()
httpMock("GET", searchLogUrl).Reply(200).JSON(`{"code":0,"message":"0"}`)
l, err := d.ExpLog(c, mid, ip)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(l, convey.ShouldNotBeNil)
})
})
}
func TestDaoasExpLog(t *testing.T) {
var (
res = &model.SearchResult{}
)
convey.Convey("asExpLog", t, func(ctx convey.C) {
p1 := asExpLog(res)
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
t.Logf("log:%+v", p1)
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,49 @@
package dao
var (
// tableMoralLog = "ugc:MoralLog"
// familyDetail = "detail"
// familyDetailB = []byte(familyDetail)
// columnIP = "ip"
// columnTs = "ts"
// columnMid = "mid"
// columnLogID = "log_id"
// _logDuration = int64(7 * 24 * 3600)
)
// func rowKey(mid, ts int64) string {
// return fmt.Sprintf("%d%d_%d", mid%10, mid, math.MaxInt64-ts)
// }
// func moralRowKey(mid, ts int64, tid uint64) string {
// return fmt.Sprintf("%d%d_%d_%d", mid%10, mid, math.MaxInt64-ts, tid)
// }
// AddMoralLog add moral modify log.
// func (d *Dao) AddMoralLog(c context.Context, mid, ts int64, content map[string][]byte) (err error) {
// var (
// mutate *hrpc.Mutate
// key = moralRowKey(mid, ts, genID())
// tsB = make([]byte, 8)
// ctx, cancel = context.WithTimeout(c, time.Duration(d.c.HBase.WriteTimeout))
// )
// defer cancel()
// binary.BigEndian.PutUint64(tsB, uint64(ts))
// content[columnTs] = tsB
// values := map[string]map[string][]byte{familyDetail: content}
// if mutate, err = hrpc.NewPutStr(ctx, tableMoralLog, key, values); err != nil {
// log.Error("hrpc.NewPutStr(%s, %s, %v) error(%v)", tableMoralLog, key, values, err)
// return
// }
// if _, err = d.hbase.Put(c, mutate); err != nil {
// log.Error("hbase.Put mid %d,error(%v) value(%v)", mid, err, values)
// return
// }
// log.Info("hbase.Put moral log success mid: %d,value(%v)", mid, values)
// return
// }
// func genID() uint64 {
// i := [16]byte(uuid.NewV1())
// return farm.Hash64(i[:]) % math.MaxInt64
// }

View File

@@ -0,0 +1,47 @@
package dao
//import (
// "context"
// "testing"
//
// "github.com/smartystreets/goconvey/convey"
//)
//
//func TestDaomoralRowKey(t *testing.T) {
// var (
// mid = int64(0)
// ts = int64(0)
// tid uint64
// )
// convey.Convey("moralRowKey", t, func(ctx convey.C) {
// p1 := moralRowKey(mid, ts, tid)
// ctx.Convey("p1 should not be nil", func(ctx convey.C) {
// ctx.So(p1, convey.ShouldNotBeNil)
// })
// })
//}
//
//func TestDaoAddMoralLog(t *testing.T) {
// var (
// c = context.Background()
// mid = int64(0)
// ts = int64(0)
// s = []byte("abcd")
// content = map[string][]byte{"ts": s}
// )
// convey.Convey("AddMoralLog", t, func(ctx convey.C) {
// err := d.AddMoralLog(c, mid, ts, content)
// ctx.Convey("Error should be nil", func(ctx convey.C) {
// ctx.So(err, convey.ShouldBeNil)
// })
// })
//}
//
//func TestDaogenID(t *testing.T) {
// convey.Convey("genID", t, func(ctx convey.C) {
// p1 := genID()
// ctx.Convey("p1 should not be nil", func(ctx convey.C) {
// ctx.So(p1, convey.ShouldNotBeNil)
// })
// })
//}

View File

@@ -0,0 +1,50 @@
package dao
import (
"context"
"go-common/app/service/main/member/model"
"go-common/library/log"
"go-common/library/queue/databus/report"
"go-common/library/time"
)
// consts
const (
MoralLogID = 12
)
// AddMoralLogReport is
func (d *Dao) AddMoralLogReport(ctx context.Context, ul *model.UserLog) {
d.addLogReport(ctx, MoralLogID, "log_moral_change", ul)
}
// addLogReport is
func (d *Dao) addLogReport(ctx context.Context, business int, action string, ul *model.UserLog) {
t := time.Time(ul.TS)
content := make(map[string]interface{}, len(ul.Content))
for k, v := range ul.Content {
content[k] = v
}
if ul.LogID == "" {
ul.LogID = model.UUID4()
}
content["log_id"] = ul.LogID
ui := &report.UserInfo{
Mid: ul.Mid,
Platform: "",
Build: 0,
Buvid: "",
Business: business,
Type: 0,
Oid: 0,
Action: action,
Ctime: t.Time(),
IP: ul.IP,
// extra
Index: []interface{}{ul.LogID},
Content: content,
}
report.User(ui)
log.Info("add log to report: userlog: %+v userinfo: %+v", ul, ui)
}

View File

@@ -0,0 +1,38 @@
package dao
import (
"context"
"testing"
"go-common/app/service/main/member/model"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoAddMoralLogReport(t *testing.T) {
var (
c = context.Background()
ul = &model.UserLog{
Mid: 4780461,
}
)
convey.Convey("AddMoralLogReport", t, func(ctx convey.C) {
d.AddMoralLogReport(c, ul)
t.Logf("log:%+v", ul)
})
}
func TestDaoaddLogReport(t *testing.T) {
var (
c = context.Background()
business = int(0)
action = ""
ul = &model.UserLog{
Mid: 4780461,
}
)
convey.Convey("addLogReport", t, func(ctx convey.C) {
d.addLogReport(c, business, action, ul)
t.Logf("log:%+v", ul)
})
}

View File

@@ -0,0 +1,498 @@
package dao
import (
"context"
"fmt"
"strconv"
"go-common/app/service/main/member/model"
"go-common/library/cache/memcache"
"go-common/library/log"
"github.com/pkg/errors"
)
const (
_expPrefix = "exp_%d"
_moralPrefix = "moral_%d"
_expExpire = 86400
)
func expKey(mid int64) string {
return fmt.Sprintf(_expPrefix, mid)
}
func moralKey(mid int64) string {
return fmt.Sprintf(_moralPrefix, mid)
}
// pingMC ping memcache.
func (d *Dao) pingMC(c context.Context) (err error) {
conn := d.mc.Get(c)
defer conn.Close()
if err = conn.Set(&memcache.Item{
Key: "ping",
Value: []byte{1},
Expiration: 86400,
}); err != nil {
log.Error("conn.Set(ping, 1) error(%v)", err)
}
return
}
// -------- base --------- //
// BaseInfoCache get base info from mc.
func (d *Dao) BaseInfoCache(c context.Context, mid int64) (info *model.BaseInfo, err error) {
key := fmt.Sprintf(model.CacheKeyBase, mid)
conn := d.mc.Get(c)
defer conn.Close()
item, err := conn.Get(key)
if err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
log.Error("conn.Get(%s) error(%v)", key, err)
return
}
info = &model.BaseInfo{}
if err = conn.Scan(item, info); err != nil {
log.Error("conn.Scan(%s) error(%v)", string(item.Value), err)
}
return
}
// BatchBaseInfoCache get batch base info from mc.
func (d *Dao) BatchBaseInfoCache(c context.Context, mids []int64) (cached map[int64]*model.BaseInfo, missed []int64, err error) {
cached = make(map[int64]*model.BaseInfo, len(mids))
if len(mids) == 0 {
return
}
keys := make([]string, 0, len(mids))
midmap := make(map[string]int64, len(mids))
for _, mid := range mids {
k := fmt.Sprintf(model.CacheKeyBase, mid)
keys = append(keys, k)
midmap[k] = mid
}
conn := d.mc.Get(c)
defer conn.Close()
bases, err := conn.GetMulti(keys)
if err != nil {
log.Error("conn.Gets(%v) error(%v)", keys, err)
return
}
for _, base := range bases {
b := &model.BaseInfo{}
if err = conn.Scan(base, b); err != nil {
log.Error("json.Unmarshal(%v) error(%v)", base.Value, err)
return
}
cached[midmap[base.Key]] = b
delete(midmap, base.Key)
}
missed = make([]int64, 0, len(midmap))
for _, bid := range midmap {
missed = append(missed, bid)
}
return
}
// SetBatchBaseInfoCache set batch base info to mc.
func (d *Dao) SetBatchBaseInfoCache(c context.Context, bs []*model.BaseInfo) (err error) {
for _, info := range bs {
d.SetBaseInfoCache(c, info.Mid, info)
}
return
}
// SetBaseInfoCache set base info to mc
func (d *Dao) SetBaseInfoCache(c context.Context, mid int64, info *model.BaseInfo) (err error) {
key := fmt.Sprintf(model.CacheKeyBase, mid)
conn := d.mc.Get(c)
defer conn.Close()
if err = conn.Set(&memcache.Item{
Key: key,
Object: info,
Flags: memcache.FlagProtobuf,
Expiration: d.baseTTL,
}); err != nil {
log.Error("conn.Set(%s, %v) error(%v)", key, info, err)
}
return
}
// DelBaseInfoCache delete baseInfo cache.
func (d *Dao) DelBaseInfoCache(c context.Context, mid int64) (err error) {
key := fmt.Sprintf(model.CacheKeyBase, mid)
conn := d.mc.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
}
// -------- base --------- //
// ----- exp ------ //
// Exp get user exp from cache,if miss get from db.
func (d *Dao) expCache(c context.Context, mid int64) (exp int64, err error) {
key := expKey(mid)
conn := d.mc.Get(c)
res, err := conn.Get(key)
defer conn.Close()
if err != nil {
return
}
exp, _ = strconv.ParseInt(string(res.Value), 10, 64)
return
}
// ExpsCache get users exp cache.
func (d *Dao) expsCache(c context.Context, mids []int64) (exps map[int64]int64, miss []int64, err error) {
var keys []string
for _, mid := range mids {
keys = append(keys, expKey(mid))
}
conn := d.mc.Get(c)
defer conn.Close()
its, err := conn.GetMulti(keys)
if err != nil {
return
}
exps = make(map[int64]int64)
for _, mid := range mids {
if it, ok := its[expKey(mid)]; ok {
exp, _ := strconv.ParseInt(string(it.Value), 10, 64)
exps[mid] = exp
} else {
miss = append(miss, mid)
}
}
return
}
// SetExpCache set user exp cache.
func (d *Dao) SetExpCache(c context.Context, mid, exp int64) (err error) {
conn := d.mc.Get(c)
defer conn.Close()
if err = conn.Set(&memcache.Item{
Key: expKey(mid),
Value: []byte(strconv.FormatInt(exp, 10)),
Expiration: _expExpire,
}); err != nil {
err = errors.WithStack(err)
return
}
return
}
// moralCache get moral from cache.
func (d *Dao) moralCache(c context.Context, mid int64) (moral *model.Moral, err error) {
key := moralKey(mid)
conn := d.mc.Get(c)
item, err := conn.Get(key)
defer conn.Close()
if err != nil {
return
}
moral = &model.Moral{}
if err = conn.Scan(item, moral); err != nil {
log.Error("conn.Scan(%s) error(%v)", string(item.Value), err)
}
return
}
// SetMoralCache set moral to mc
func (d *Dao) SetMoralCache(c context.Context, mid int64, moral *model.Moral) (err error) {
key := moralKey(mid)
conn := d.mc.Get(c)
defer conn.Close()
if conn.Set(&memcache.Item{
Key: key,
Object: moral,
Flags: memcache.FlagProtobuf,
Expiration: d.moralTTL,
}); err != nil {
log.Error("conn.Set(%s, %v) error(%v)", key, moral, err)
}
return
}
// DelMoralCache delete moral cache.
func (d *Dao) DelMoralCache(c context.Context, mid int64) (err error) {
key := moralKey(mid)
conn := d.mc.Get(c)
defer conn.Close()
if err = conn.Delete(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
log.Error("DelMoralCache conn.Delete(%s) error(%v)", key, err)
}
return
}
// ------realname------
func realnameInfoKey(mid int64) string {
return fmt.Sprintf("realname_info_%d", mid)
}
func realnameCaptureTimesKey(mid int64) string {
return fmt.Sprintf("realname_cap_times_%d", mid)
}
func realnameCaptureCodeKey(mid int64) string {
return fmt.Sprintf("realname_cap_code_%d", mid)
}
func realnameCaptureErrTimesKey(mid int64) string {
return fmt.Sprintf("realname_cap_err_times%d", mid)
}
// RealnameCaptureTimesCache is
func (d *Dao) RealnameCaptureTimesCache(c context.Context, mid int64) (times int, err error) {
var (
key = realnameCaptureTimesKey(mid)
conn = d.mc.Get(c)
item *memcache.Item
)
defer conn.Close()
if item, err = conn.Get(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
times = -1
return
}
err = errors.Wrapf(err, "conn.Get(%s)", key)
return
}
if err = conn.Scan(item, &times); err != nil {
err = errors.Wrapf(err, "conn.Scan(%+v)", item)
return
}
return
}
// IncreaseRealnameCaptureTimes is
func (d *Dao) IncreaseRealnameCaptureTimes(c context.Context, mid int64) (err error) {
var (
key = realnameCaptureTimesKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
if _, err = conn.Increment(key, 1); err != nil {
err = errors.Wrapf(err, "conn.Increment(%s,1)", key)
return
}
return
}
// SetRealnameCaptureTimes is
func (d *Dao) SetRealnameCaptureTimes(c context.Context, mid int64, times int) (err error) {
var (
key = realnameCaptureTimesKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Set(&memcache.Item{Key: key, Object: times, Flags: memcache.FlagJSON, Expiration: d.captureTimesTTL}); err != nil {
err = errors.Wrapf(err, "conn.Set(%s,%+v)", key, times)
return
}
return
}
// RealnameCaptureCodeCache .
// return code : -1 , if code not found
// RealnameCaptureCodeCache is
func (d *Dao) RealnameCaptureCodeCache(c context.Context, mid int64) (code int, err error) {
var (
key = realnameCaptureCodeKey(mid)
conn = d.mc.Get(c)
item *memcache.Item
)
defer conn.Close()
if item, err = conn.Get(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
code = -1
return
}
err = errors.Wrapf(err, "conn.Get(%s)", key)
return
}
if err = conn.Scan(item, &code); err != nil {
err = errors.Wrapf(err, "conn.Scan(%+v)", item)
return
}
return
}
// RealnameInfoCache is.
func (d *Dao) RealnameInfoCache(c context.Context, mid int64) (info *model.RealnameCacheInfo, err error) {
var (
key = realnameInfoKey(mid)
conn = d.mc.Get(c)
item *memcache.Item
)
defer conn.Close()
if item, err = conn.Get(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
info = nil
return
}
err = errors.Wrapf(err, "conn.Get(%s)", key)
return
}
info = &model.RealnameCacheInfo{}
if err = conn.Scan(item, &info); err != nil {
err = errors.Wrapf(err, "conn.Scan(%+v)", item)
return
}
return
}
// SetRealnameInfo is.
func (d *Dao) SetRealnameInfo(c context.Context, mid int64, info *model.RealnameCacheInfo) (err error) {
var (
key = realnameInfoKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Set(&memcache.Item{Key: key, Object: info, Flags: memcache.FlagJSON, Expiration: d.applyInfoTTL}); err != nil {
err = errors.Wrapf(err, "conn.Set(%s,%+v)", key, info)
return
}
return
}
// SetRealnameCaptureCode is
func (d *Dao) SetRealnameCaptureCode(c context.Context, mid int64, code int) (err error) {
var (
key = realnameCaptureCodeKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Set(&memcache.Item{Key: key, Object: code, Flags: memcache.FlagJSON, Expiration: d.captureCodeTTL}); err != nil {
err = errors.Wrapf(err, "conn.Set(%s,%+v)", key, code)
return
}
return
}
// DeleteRealnameCaptureCode is
func (d *Dao) DeleteRealnameCaptureCode(c context.Context, mid int64) (err error) {
var (
key = realnameCaptureCodeKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Delete(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
err = errors.Wrapf(err, "conn.Delete(%s)", key)
return
}
return
}
// DeleteRealnameInfo is
func (d *Dao) DeleteRealnameInfo(c context.Context, mid int64) (err error) {
var (
key = realnameInfoKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Delete(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
err = errors.Wrapf(err, "conn.Delete(%s)", key)
return
}
return
}
// RealnameCaptureErrTimesCache is
func (d *Dao) RealnameCaptureErrTimesCache(c context.Context, mid int64) (times int, err error) {
var (
key = realnameCaptureErrTimesKey(mid)
conn = d.mc.Get(c)
item *memcache.Item
)
defer conn.Close()
if item, err = conn.Get(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
times = -1
return
}
err = errors.Wrapf(err, "conn.Get(%s)", key)
return
}
if err = conn.Scan(item, &times); err != nil {
err = errors.Wrapf(err, "conn.Scan(%+v)", item)
return
}
return
}
// SetRealnameCaptureErrTimes is
func (d *Dao) SetRealnameCaptureErrTimes(c context.Context, mid int64, times int) (err error) {
var (
key = realnameCaptureErrTimesKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Set(&memcache.Item{Key: key, Object: times, Flags: memcache.FlagJSON, Expiration: d.captureErrTimesTTL}); err != nil {
err = errors.Wrapf(err, "conn.Set(%s,%+v)", key, times)
return
}
return
}
// IncreaseRealnameCaptureErrTimes is
func (d *Dao) IncreaseRealnameCaptureErrTimes(c context.Context, mid int64) (err error) {
var (
key = realnameCaptureErrTimesKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
if _, err = conn.Increment(key, 1); err != nil {
err = errors.Wrapf(err, "conn.Increment(%s,1)", key)
return
}
return
}
// DeleteRealnameCaptureErrTimes is
func (d *Dao) DeleteRealnameCaptureErrTimes(c context.Context, mid int64) (err error) {
var (
key = realnameCaptureErrTimesKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Delete(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
err = nil
return
}
err = errors.Wrapf(err, "conn.Delete(%s)", key)
return
}
return
}

View File

@@ -0,0 +1,475 @@
package dao
import (
"context"
"reflect"
"testing"
"github.com/bouk/monkey"
"go-common/app/service/main/member/model"
"go-common/library/cache/memcache"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoexpKey(t *testing.T) {
var (
mid = int64(111001740)
)
convey.Convey("expKey", t, func(ctx convey.C) {
p1 := expKey(mid)
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaomoralKey(t *testing.T) {
var (
mid = int64(111001740)
)
convey.Convey("moralKey", t, func(ctx convey.C) {
p1 := moralKey(mid)
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaopingMC(t *testing.T) {
var (
c = context.Background()
)
convey.Convey("pingMC", t, func(ctx convey.C) {
err := d.pingMC(c)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoSetBaseInfoCache(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
info = &model.BaseInfo{
Mid: 19476037,
Name: "lala",
Sign: "We are the world!",
}
)
convey.Convey("SetBaseInfoCache", t, func(ctx convey.C) {
err := d.SetBaseInfoCache(c, mid, info)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoBaseInfoCache(t *testing.T) {
convey.Convey("BaseInfoCache", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(19476037)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
info, err := d.BaseInfoCache(c, mid)
ctx.Convey("Error should be nil. info should not be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(info, convey.ShouldNotBeNil)
})
})
ctx.Convey("When conn.Get gets error", func(ctx convey.C) {
guard := monkey.PatchInstanceMethod(reflect.TypeOf(d.mc), "Get", func(_ *memcache.Pool,
_ context.Context) memcache.Conn {
return memcache.MockWith(memcache.ErrItemObject)
})
defer guard.Unpatch()
_, err := d.BaseInfoCache(c, mid)
ctx.Convey("Error should be equal to memcache.ErrItemObject", func(ctx convey.C) {
ctx.So(err, convey.ShouldEqual, memcache.ErrItemObject)
})
})
})
}
func TestDaoSetBatchBaseInfoCache(t *testing.T) {
var (
c = context.Background()
bi1 = &model.BaseInfo{
Mid: 19476037,
Name: "lala",
Sign: "We are the world!",
}
bi2 = &model.BaseInfo{
Mid: 4780461,
Name: "lala",
Sign: "We are the world!",
}
bs = []*model.BaseInfo{bi1, bi2}
)
convey.Convey("SetBatchBaseInfoCache", t, func(ctx convey.C) {
err := d.SetBatchBaseInfoCache(c, bs)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoBatchBaseInfoCache(t *testing.T) {
var (
c = context.Background()
mids = []int64{19476037, 1}
)
convey.Convey("BatchBaseInfoCache", t, func(ctx convey.C) {
cached, missed, err := d.BatchBaseInfoCache(c, mids)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("missed should not be nil", func(ctx convey.C) {
ctx.So(missed, convey.ShouldNotBeNil)
})
ctx.Convey("cached should not be nil", func(ctx convey.C) {
ctx.So(cached, convey.ShouldNotBeNil)
})
})
}
func TestDaoDelBaseInfoCache(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
)
convey.Convey("DelBaseInfoCache", t, func(ctx convey.C) {
err := d.DelBaseInfoCache(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoSetExpCache(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
exp = int64(10)
)
convey.Convey("SetExpCache", t, func(ctx convey.C) {
err := d.SetExpCache(c, mid, exp)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoexpCache(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
)
convey.Convey("expCache", t, func(ctx convey.C) {
exp, err := d.expCache(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("exp should not be nil", func(ctx convey.C) {
ctx.So(exp, convey.ShouldNotBeNil)
})
})
}
func TestDaoexpsCache(t *testing.T) {
var (
c = context.Background()
mids = []int64{19476037, 4780461}
)
convey.Convey("expsCache", t, func(ctx convey.C) {
exps, miss, err := d.expsCache(c, mids)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("miss should not be nil", func(ctx convey.C) {
ctx.So(miss, convey.ShouldBeNil)
})
ctx.Convey("exps should not be nil", func(ctx convey.C) {
ctx.So(exps, convey.ShouldNotBeNil)
})
})
}
func TestDaoSetMoralCache(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
moral = &model.Moral{}
)
convey.Convey("SetMoralCache", t, func(ctx convey.C) {
err := d.SetMoralCache(c, mid, moral)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaomoralCache(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
)
convey.Convey("moralCache", t, func(ctx convey.C) {
moral, err := d.moralCache(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("moral should not be nil", func(ctx convey.C) {
ctx.So(moral, convey.ShouldNotBeNil)
})
})
}
func TestDaoDelMoralCache(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
)
convey.Convey("DelMoralCache", t, func(ctx convey.C) {
err := d.DelMoralCache(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaorealnameInfoKey(t *testing.T) {
var (
mid = int64(19476037)
)
convey.Convey("realnameApplyKey", t, func(ctx convey.C) {
key := realnameInfoKey(mid)
ctx.Convey("p1 should equal realname_info_<mid>", func(ctx convey.C) {
ctx.So(key, convey.ShouldEqual, "realname_info_19476037")
})
})
}
func TestDaorealnameCaptureTimesKey(t *testing.T) {
var (
mid = int64(19476037)
)
convey.Convey("realnameCaptureTimesKey", t, func(ctx convey.C) {
p1 := realnameCaptureTimesKey(mid)
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaorealnameCaptureCodeKey(t *testing.T) {
var (
mid = int64(19476037)
)
convey.Convey("realnameCaptureCodeKey", t, func(ctx convey.C) {
p1 := realnameCaptureCodeKey(mid)
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaorealnameCaptureErrTimesKey(t *testing.T) {
var (
mid = int64(19476037)
)
convey.Convey("realnameCaptureErrTimesKey", t, func(ctx convey.C) {
p1 := realnameCaptureErrTimesKey(mid)
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaoSetRealnameCaptureTimes(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
times = int(0)
)
convey.Convey("SetRealnameCaptureTimes", t, func(ctx convey.C) {
err := d.SetRealnameCaptureTimes(c, mid, times)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoRealnameCaptureTimesCache(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
)
convey.Convey("RealnameCaptureTimesCache", t, func(ctx convey.C) {
times, err := d.RealnameCaptureTimesCache(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("times should not be nil", func(ctx convey.C) {
ctx.So(times, convey.ShouldNotBeNil)
})
})
}
func TestDaoIncreaseRealnameCaptureTimes(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
)
convey.Convey("IncreaseRealnameCaptureTimes", t, func(ctx convey.C) {
err := d.IncreaseRealnameCaptureTimes(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoRealnameCaptureCodeCache(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
)
convey.Convey("RealnameCaptureCodeCache", t, func(ctx convey.C) {
code, err := d.RealnameCaptureCodeCache(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("code should not be nil", func(ctx convey.C) {
ctx.So(code, convey.ShouldNotBeNil)
})
})
}
func TestDaoSetRealnameInfo(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
info = &model.RealnameCacheInfo{}
)
convey.Convey("SetRealnameApplyInfo", t, func(ctx convey.C) {
err := d.SetRealnameInfo(c, mid, info)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoRealnameInfoCache(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
)
convey.Convey("RealnameApplyInfoCache", t, func(ctx convey.C) {
info, err := d.RealnameInfoCache(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("info should not be nil", func(ctx convey.C) {
ctx.So(info, convey.ShouldNotBeNil)
})
})
}
func TestDaoDeleteRealnameInfo(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
)
convey.Convey("DeleteRealnameApplyInfo", t, func(ctx convey.C) {
err := d.DeleteRealnameInfo(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoSetRealnameCaptureCode(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
code = int(0)
)
convey.Convey("SetRealnameCaptureCode", t, func(ctx convey.C) {
err := d.SetRealnameCaptureCode(c, mid, code)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoDeleteRealnameCaptureCode(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
)
convey.Convey("DeleteRealnameCaptureCode", t, func(ctx convey.C) {
err := d.DeleteRealnameCaptureCode(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoSetRealnameCaptureErrTimes(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
times = int(0)
)
convey.Convey("SetRealnameCaptureErrTimes", t, func(ctx convey.C) {
err := d.SetRealnameCaptureErrTimes(c, mid, times)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoRealnameCaptureErrTimesCache(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
)
convey.Convey("RealnameCaptureErrTimesCache", t, func(ctx convey.C) {
times, err := d.RealnameCaptureErrTimesCache(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("times should not be nil", func(ctx convey.C) {
ctx.So(times, convey.ShouldNotBeNil)
})
})
}
func TestDaoIncreaseRealnameCaptureErrTimes(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
)
convey.Convey("IncreaseRealnameCaptureErrTimes", t, func(ctx convey.C) {
err := d.IncreaseRealnameCaptureErrTimes(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoDeleteRealnameCaptureErrTimes(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
)
convey.Convey("DeleteRealnameCaptureErrTimes", t, func(ctx convey.C) {
err := d.DeleteRealnameCaptureErrTimes(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}

View File

@@ -0,0 +1,43 @@
package dao
import (
"context"
"fmt"
"net/url"
"go-common/library/ecode"
"go-common/library/log"
)
// consts
const (
notifyURL = "http://message.bilibili.co/api/notify/send.user.notify.do"
dataType = "4"
source = "2"
)
// SendMessage is
func (d *Dao) SendMessage(c context.Context, mid int64, title, msg, mc string) (err error) {
var (
params = url.Values{}
)
params.Set("mid_list", fmt.Sprintf("%d", mid))
params.Set("mc", mc)
params.Set("data_type", dataType)
params.Set("source", source)
params.Set("context", msg)
params.Set("title", title)
var resp struct {
Code int `json:"code"`
}
log.Info("SendMessage() params(%v)", params)
if err = d.client.Post(c, notifyURL, "", params, &resp); err != nil {
log.Error("d.client.Post(%s,%+v) error(%v)", notifyURL, params, err)
return
}
if resp.Code != 0 {
err = ecode.Int(resp.Code)
log.Error("d.client.Post(%s,%+v) resp.Code(%d)", notifyURL, params, resp.Code)
}
return
}

View File

@@ -0,0 +1,34 @@
package dao
import (
"context"
"strings"
"testing"
"github.com/smartystreets/goconvey/convey"
"gopkg.in/h2non/gock.v1"
)
func httpMock(method, url string) *gock.Request {
r := gock.New(url)
r.Method = strings.ToUpper(method)
return r
}
func TestDaoSendMessage(t *testing.T) {
var (
c = context.Background()
mid = int64(123)
title = "test"
msg = "test"
mc = "test"
)
convey.Convey("SendMessage", t, func(ctx convey.C) {
d.client.SetTransport(gock.DefaultTransport)
defer gock.OffAll()
httpMock("POST", notifyURL).Reply(200).JSON(`{"code":0,"message":"0"}`)
err := d.SendMessage(c, mid, title, msg, mc)
ctx.So(err, convey.ShouldBeNil)
})
}

View File

@@ -0,0 +1,157 @@
package dao
import (
"context"
"encoding/json"
"net/url"
"strconv"
"time"
"go-common/app/service/main/member/model"
"go-common/library/cache/memcache"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/metadata"
"github.com/pkg/errors"
)
const (
_moralLogID = 12
)
// Moral get user moral from cache,if miss get from db.
func (d *Dao) Moral(c context.Context, mid int64) (moral *model.Moral, err error) {
if moral, err = d.moralCache(c, mid); err == nil {
return
}
if err != nil && err != memcache.ErrNotFound {
log.Error("Failed to get moral from cache, mid: %d, error:%v", mid, err)
return
}
if moral, err = d.MoralDB(c, mid); err != nil {
return
}
if moral == nil {
moral = &model.Moral{Mid: mid, Moral: model.DefaultMoral}
}
d.SetMoralCache(c, mid, moral)
return
}
// MoralLog is
func (d *Dao) MoralLog(ctx context.Context, mid int64) ([]*model.UserLog, error) {
ip := metadata.String(ctx, metadata.RemoteIP)
t := time.Now().Add(-time.Hour * 24 * 7)
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
params.Set("appid", "log_user_action")
params.Set("business", strconv.FormatInt(_moralLogID, 10))
params.Set("pn", "1")
params.Set("ps", "1000")
params.Set("ctime_from", t.Format("2006-01-02 00:00:00"))
params.Set("sort", "desc")
params.Set("order", "ctime")
res := &model.SearchResult{}
if err := d.client.Get(ctx, d.c.Host.Search+_searchLogURI, ip, params, res); err != nil {
return nil, err
}
if res.Code != 0 {
return nil, ecode.Int(res.Code)
}
logs := asMoralLog(res)
return logs, nil
}
// MoralLogByID get distinct log by log id
func (d *Dao) MoralLogByID(ctx context.Context, logID string) (*model.UserLog, error) {
ip := metadata.String(ctx, metadata.RemoteIP)
params := url.Values{}
params.Set("str_0", logID)
params.Set("appid", "log_user_action")
params.Set("business", strconv.FormatInt(_moralLogID, 10))
params.Set("pn", "1")
params.Set("ps", "1")
params.Set("sort", "desc")
params.Set("order", "ctime")
res := &model.SearchResult{}
if err := d.client.Get(ctx, d.c.Host.Search+_searchLogURI, ip, params, res); err != nil {
return nil, err
}
if res.Code != 0 {
return nil, ecode.Int(res.Code)
}
logs := asMoralLog(res)
if len(logs) == 0 {
return nil, ecode.NothingFound
}
return logs[0], nil
}
// DeleteMoralLog is
func (d *Dao) DeleteMoralLog(ctx context.Context, logID string) error {
ip := metadata.String(ctx, metadata.RemoteIP)
return d.deleteLogReport(ctx, _moralLogID, logID, ip)
}
// DeleteLogReport is
func (d *Dao) deleteLogReport(ctx context.Context, business int, logID string, ip string) error {
if logID == "" {
return errors.New("Failed to delete log with empty logID")
}
params := url.Values{}
params.Set("str_0", logID)
params.Set("appid", "log_user_action")
params.Set("business", strconv.FormatInt(int64(business), 10))
res := &model.SearchResult{}
if err := d.client.Post(ctx, d.c.Host.Search+_deleteLogURI, ip, params, res); err != nil {
return err
}
if res.Code != 0 {
return ecode.Int(res.Code)
}
return nil
}
func asMoralLog(res *model.SearchResult) []*model.UserLog {
logs := make([]*model.UserLog, 0, len(res.Data.Result))
for _, r := range res.Data.Result {
ts, err := time.ParseInLocation("2006-01-02 15:04:05", r.Ctime, time.Local)
if err != nil {
log.Warn("Failed to parse log ctime: ctime: %s: %+v", r.Ctime, err)
continue
}
content := map[string]string{
"from_moral": "",
"log_id": "",
"mid": "",
"operater": "",
"origin": "",
"reason": "",
"remark": "",
"status": "",
"to_moral": "",
}
if err := json.Unmarshal([]byte(r.ExtraData), &content); err != nil {
log.Warn("Failed to parse extra data in moral log: mid: %d, extra_data: %s: %+v", r.Mid, r.ExtraData, err)
continue
}
if content["mid"] == "" {
content["mid"] = strconv.FormatInt(r.Mid, 10)
}
l := &model.UserLog{
Mid: r.Mid,
IP: r.IP,
TS: ts.Unix(),
LogID: content["log_id"],
Content: content,
}
logs = append(logs, l)
}
return logs
}

View File

@@ -0,0 +1,100 @@
package dao
import (
"context"
"testing"
"go-common/app/service/main/member/model"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoMoralLog(t *testing.T) {
var (
c = context.Background()
mid = int64(4780461)
// ip = ""
)
convey.Convey("MoralLog", t, func(ctx convey.C) {
p1, p2 := d.MoralLog(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(p2, convey.ShouldBeNil)
})
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaoMoralLogByID(t *testing.T) {
var (
c = context.Background()
logID = "test"
// ip = ""
)
convey.Convey("MoralLogByID", t, func(ctx convey.C) {
p1, p2 := d.MoralLogByID(c, logID)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(p2, convey.ShouldEqual, -404)
})
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldBeNil)
})
})
}
func TestDaoDeleteMoralLog(t *testing.T) {
var (
c = context.Background()
logID = "test"
// ip = ""
)
convey.Convey("DeleteMoralLog", t, func(ctx convey.C) {
p1 := d.DeleteMoralLog(c, logID)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldBeNil)
})
})
}
func TestDaodeleteLogReport(t *testing.T) {
var (
c = context.Background()
business = int(0)
logID = "test"
ip = ""
)
convey.Convey("deleteLogReport", t, func(ctx convey.C) {
p1 := d.deleteLogReport(c, business, logID, ip)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldBeNil)
})
})
}
func TestDaoasMoralLog(t *testing.T) {
var (
res = &model.SearchResult{}
)
convey.Convey("asMoralLog", t, func(ctx convey.C) {
p1 := asMoralLog(res)
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaoMoral(t *testing.T) {
var (
c = context.Background()
mid = int64(4780461)
)
convey.Convey("Moral", t, func(ctx convey.C) {
moral, err := d.Moral(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("moral should not be nil", func(ctx convey.C) {
ctx.So(moral, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,544 @@
package dao
import (
"context"
"database/sql"
"fmt"
"strings"
"go-common/app/service/main/member/model"
xsql "go-common/library/database/sql"
"go-common/library/log"
"go-common/library/time"
"github.com/pkg/errors"
)
const (
_shard = 100
// base
_selBaseInfo = "SELECT mid,name,sex,face,sign,rank,birthday FROM user_base_%02d WHERE mid=? "
_setSex = "INSERT INTO user_base_%02d(mid,sex) VALUES (?,?) ON DUPLICATE KEY UPDATE sex=?"
_setName = "INSERT INTO user_base_%02d(mid,name) VALUES (?,?) ON DUPLICATE KEY UPDATE name=?"
_setRank = "INSERT INTO user_base_%02d(mid,rank) VALUES (?,?) ON DUPLICATE KEY UPDATE rank=?"
_setSign = "INSERT INTO user_base_%02d(mid,sign) VALUES (?,?) ON DUPLICATE KEY UPDATE sign=?"
_setBirthday = "INSERT INTO user_base_%02d(mid,birthday) VALUES (?,?) ON DUPLICATE KEY UPDATE birthday=?"
_setFace = "INSERT INTO user_base_%02d(mid,face) VALUES (?,?) ON DUPLICATE KEY UPDATE face=?"
_setBase = `INSERT INTO user_base_%02d(mid,name,sex,face,sign,rank,birthday) VALUES (?,?,?,?,?,?,?)
ON DUPLICATE KEY UPDATE name=?,sex=?,face=?,sign=?,rank=?,birthday=?`
// _exp
_setExp = "INSERT INTO user_exp_%02d (mid,exp) VALUES(?,?) ON DUPLICATE KEY UPDATE exp=VALUES(exp)"
_updateExp = "UPDATE user_exp_%02d SET exp=exp+? WHERE mid=?"
_selExp = "SELECT exp FROM user_exp_%02d where mid=?"
//user_flag
_selUserAttr = "SELECT flag FROM user_flag where mid =? and flag & ?= ?"
_updateUserAttr = "INSERT INTO user_flag(mid,flag) VALUES(?,?) ON DUPLICATE KEY UPDATE flag=flag|?"
// user_official
_selOfficials = "SELECT mid,role,title,description FROM user_official WHERE role>0"
// moral
_selMoral = "SELECT moral,added,deducted,last_recover_date from user_moral where mid=?"
_initMoral = `INSERT IGNORE INTO user_moral (mid,moral,added,deducted,last_recover_date) VALUES(?,?,?,?,?)`
_updateMoral = `update user_moral set moral=moral+?,added=added+?, deducted=deducted + ? where mid = ?`
_updateMoralRecoverDate = `update user_moral set last_recover_date = ? where mid = ?`
// official
_setOfficialDoc = `INSERT INTO user_official_doc (mid,name,state,role,title,description,extra,submit_source,submit_time) VALUES (?,?,?,?,?,?,?,?,?)
ON DUPLICATE KEY UPDATE name=VALUES(name), state=VALUES(state), role=VALUES(role), title=VALUES(title), description=VALUES(description), extra=VALUES(extra), submit_source=VALUES(submit_source), submit_time=VALUES(submit_time)`
_selOfficialDoc = "SELECT mid,name,state,role,title,description,reject_reason,extra FROM user_official_doc WHERE mid=?"
_selOfficial = "SELECT role,title,description FROM user_official WHERE mid=? AND role>0"
//official addit
_setOfficialDocAddit = `INSERT INTO user_official_doc_addit (mid,property,vstring) VALUES (?,?,?) ON DUPLICATE KEY UPDATE vstring=VALUES(vstring)`
// realname
_selRealnameInfo = `SELECT id,mid,channel,realname,country,card_type,card,card_md5,status,reason,ctime,mtime FROM realname_info WHERE mid = ? LIMIT 1`
_selRealnameInfoByCard = `SELECT id,mid,channel,realname,country,card_type,card,card_md5,status,reason,ctime,mtime FROM realname_info WHERE card_md5=? AND status in (0,1) LIMIT 1`
_selRealnameInfoMidByCards = `SELECT mid,card_md5 FROM realname_info WHERE card_md5 IN (%s) AND status in (0,1)`
_upsertRealnameInfo = `INSERT INTO realname_info (mid,channel,realname,country,card_type,card,card_md5,status,reason) VALUES (?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE channel=?,realname=?,country=?,card_type=?,card=?,card_md5=?,status=?,reason=?`
_updateRealnameInfo = `UPDATE realname_info SET status=?,reason=? WHERE mid=?`
_selRealnameApply = "SELECT id,mid,realname,country,card_type,card_num,card_md5,hand_img,front_img,back_img,status,operator,operator_id,operator_time,remark,remark_status,ctime,mtime FROM realname_apply WHERE mid = ? ORDER BY ID DESC LIMIT 1"
_insertRealnameApply = `INSERT INTO realname_apply (mid,realname,country,card_type,card_num,card_md5,hand_img,front_img,back_img,status) VALUES (?,?,?,?,?,?,?,?,?,?)`
_selRealnameApplyImg = "SELECT id,img_data,ctime,mtime FROM realname_apply_img WHERE id = ? LIMIT 1"
_insertRealnameApplyImg = `INSERT INTO realname_apply_img (img_data) VALUES (?)`
// alipay
_selRealnameAlipayApply = "SELECT id,mid,realname,card,img,status,reason,bizno,ctime,mtime FROM realname_alipay_apply WHERE mid = ? ORDER BY ID DESC LIMIT 1"
_insertRealnameAlipayApply = `INSERT INTO realname_alipay_apply (mid,realname,card,img,status,reason,bizno) VALUES (?,?,?,?,?,?,?)`
_updateRealnameAlipayApply = `UPDATE realname_alipay_apply SET status=?,reason=? WHERE id=?`
// realname old
_insertOldRealnameApply = `INSERT INTO dede_identification_card_apply (mid,realname,type,card_data,card_for_search,front_img,front_img2,back_img,apply_time,status) VALUES (?,?,?,?,?,?,?,?,?,?)`
_insertOldRealnameApplyImg = `INSERT INTO dede_identification_card_apply_img (img_data,add_time) VALUES (?,?)`
)
func hit(id int64) int64 {
return id % _shard
}
// BeginTran begin transcation.
func (d *Dao) BeginTran(c context.Context) (tx *xsql.Tx, err error) {
return d.db.Begin(c)
}
// BaseInfo base info of user.
func (d *Dao) BaseInfo(c context.Context, mid int64) (r *model.BaseInfo, err error) {
r = &model.BaseInfo{}
row := d.db.Master().QueryRow(c, fmt.Sprintf(_selBaseInfo, hit(mid)), mid)
if err = row.Scan(&r.Mid, &r.Name, &r.Sex, &r.Face, &r.Sign, &r.Rank, &r.Birthday); err != nil {
if err == xsql.ErrNoRows {
r = nil
err = nil
return
}
err = errors.Wrapf(err, "dao base mid(%d)", mid)
}
r.RandFaceURL()
return
}
// SetBase set base.
func (d *Dao) SetBase(c context.Context, base *model.BaseInfo) (err error) {
if _, err = d.db.Exec(c, fmt.Sprintf(_setBase, hit(base.Mid)), base.Mid, base.Name, base.Sex, base.Face, base.Sign,
base.Rank, base.Birthday, base.Name, base.Sex, base.Face, base.Sign, base.Rank, base.Birthday); err != nil {
err = errors.Wrapf(err, "dao set base(%v)", base)
}
return
}
// SetSign set user sign.
func (d *Dao) SetSign(c context.Context, mid int64, sign string) (err error) {
if _, err = d.db.Exec(c, fmt.Sprintf(_setSign, hit(mid)), mid, sign, sign); err != nil {
err = errors.Wrapf(err, "dao set sign mid(%d)", mid)
}
return
}
// SetName set user name.
func (d *Dao) SetName(c context.Context, mid int64, name string) (err error) {
if _, err = d.db.Exec(c, fmt.Sprintf(_setName, hit(mid)), mid, name, name); err != nil {
err = errors.Wrapf(err, "dao set name mid(%d) name(%s)", mid, name)
}
return
}
// SetRank set user rank.
func (d *Dao) SetRank(c context.Context, mid, rank int64) (err error) {
if _, err = d.db.Exec(c, fmt.Sprintf(_setRank, hit(mid)), mid, rank, rank); err != nil {
err = errors.Wrapf(err, "dao set rank mid(%d) rank(%d)", mid, rank)
}
return
}
// SetSex set sex.
func (d *Dao) SetSex(c context.Context, mid, sex int64) (err error) {
if _, err = d.db.Exec(c, fmt.Sprintf(_setSex, hit(mid)), mid, sex, sex); err != nil {
err = errors.Wrapf(err, "dao set sex mid(%d) sex(%d)", mid, sex)
}
return
}
// SetBirthday set birthday.
func (d *Dao) SetBirthday(c context.Context, mid int64, birthday time.Time) (err error) {
if _, err = d.db.Exec(c, fmt.Sprintf(_setBirthday, hit(mid)), mid, birthday, birthday); err != nil {
err = errors.Wrapf(err, "dao set birthday mid(%d) birthday(%d)", mid, birthday)
}
return
}
// SetFace set face.
func (d *Dao) SetFace(c context.Context, mid int64, face string) (err error) {
if _, err = d.db.Exec(c, fmt.Sprintf(_setFace, hit(mid)), mid, face, face); err != nil {
err = errors.Wrapf(err, "dao set face mid(%d) face(%v)", mid, face)
}
return
}
// ExpDB get user exp from db.
func (d *Dao) ExpDB(c context.Context, mid int64) (count int64, err error) {
row := d.db.QueryRow(c, fmt.Sprintf(_selExp, hit(mid)), mid)
if err = row.Scan(&count); err != nil {
if err == xsql.ErrNoRows {
err = nil
return
}
err = errors.Wrapf(err, "dao exp mid(%d)", mid)
}
return
}
// SetExp set user exp to count.
func (d *Dao) SetExp(c context.Context, mid, count int64) (affect int64, err error) {
row, err := d.db.Exec(c, fmt.Sprintf(_setExp, hit(mid)), mid, count)
if err != nil {
err = errors.Wrapf(err, "dao set exp mid(%d) exp(%d)", mid, count)
return
}
return row.RowsAffected()
}
// UpdateExp incr user exp by delta.
func (d *Dao) UpdateExp(c context.Context, mid, delta int64) (affect int64, err error) {
row, err := d.db.Exec(c, fmt.Sprintf(_updateExp, hit(mid)), delta, mid)
if err != nil {
err = errors.Wrapf(err, "dao update exp mid(%d) exp(%d)", mid, delta)
return
}
return row.RowsAffected()
}
// ------------- exp ---------------- //
// UserAttrDB get attr.
func (d *Dao) UserAttrDB(c context.Context, mid int64, attr uint) (hasAttr bool, err error) {
var flag int8
row := d.db.QueryRow(c, _selUserAttr, mid, attr, attr)
if err = row.Scan(&flag); err != nil {
if err == xsql.ErrNoRows {
err = nil
return
}
err = errors.Wrapf(err, "dao attr mid(%d) attr(%d)", mid, attr)
}
hasAttr = true
return
}
// SetUserAttr update attr .
func (d *Dao) SetUserAttr(c context.Context, mid int64, attr uint) (err error) {
if _, err = d.db.Exec(c, _updateUserAttr, mid, attr, attr); err != nil {
err = errors.Wrapf(err, "dao attr mid(%d) attr(%d)", mid, attr)
return
}
return
}
// Officials all officials info of user.
func (d *Dao) Officials(c context.Context) (om map[int64]*model.OfficialInfo, err error) {
om = make(map[int64]*model.OfficialInfo)
rows, err := d.db.Query(c, _selOfficials)
if err != nil {
err = errors.Wrap(err, "dao officials")
return
}
defer rows.Close()
for rows.Next() {
var mid int64
o := &model.OfficialInfo{}
if err = rows.Scan(&mid, &o.Role, &o.Title, &o.Desc); err != nil {
err = errors.Wrap(err, "dao officials scan")
return
}
om[mid] = o
}
return
}
// Official is.
func (d *Dao) Official(c context.Context, mid int64) (*model.OfficialInfo, error) {
row := d.db.QueryRow(c, _selOfficial, mid)
o := &model.OfficialInfo{}
if err := row.Scan(&o.Role, &o.Title, &o.Desc); err != nil {
if err == sql.ErrNoRows {
return nil, nil
}
return nil, errors.Wrap(err, "dao official scan")
}
return o, nil
}
// MoralDB get user moral from db.
func (d *Dao) MoralDB(c context.Context, mid int64) (moral *model.Moral, err error) {
moral = &model.Moral{}
row := d.db.QueryRow(c, _selMoral, mid)
if err = row.Scan(&moral.Moral, &moral.Added, &moral.Deducted, &moral.LastRecoverDate); err != nil {
if err == sql.ErrNoRows {
moral = nil
err = nil
return
}
log.Error(" SelMoral row.Scan() error(%v) mid(%v)", err, mid)
err = errors.Wrapf(err, "dao moral mid(%d)", mid)
return
}
return
}
// TxMoralDB get user moral from db.
func (d *Dao) TxMoralDB(tx *xsql.Tx, mid int64) (moral *model.Moral, err error) {
moral = &model.Moral{}
row := tx.QueryRow(_selMoral, mid)
if err = row.Scan(&moral.Moral, &moral.Added, &moral.Deducted, &moral.LastRecoverDate); err != nil {
if err == sql.ErrNoRows {
moral = nil
err = nil
return
}
log.Error(" SelMoral row.Scan() error(%v) mid(%v)", err, mid)
err = errors.Wrapf(err, "dao moral mid(%d)", mid)
return
}
return
}
// TxUpdateMoral set user moral.
func (d *Dao) TxUpdateMoral(tx *xsql.Tx, mid, moral, added, deducted int64) (err error) {
if _, err = tx.Exec(_updateMoral, moral, added, deducted, mid); err != nil {
err = errors.Wrapf(err, "TxUpdateMoral mid(%d) moralAdded(%v)", mid, moral)
return
}
return
}
// TxUpdateMoralRecoverDate update moral recover date.
func (d *Dao) TxUpdateMoralRecoverDate(tx *xsql.Tx, mid int64, recoverDate time.Time) (err error) {
if _, err = tx.Exec(_updateMoralRecoverDate, recoverDate, mid); err != nil {
err = errors.Wrapf(err, "TxUpdateMoralRecoverDate mid(%d) recoverDate(%v)", mid, recoverDate)
return
}
return
}
// TxInitMoral set user moral.
func (d *Dao) TxInitMoral(tx *xsql.Tx, mid, moral, added, deducted int64, lastRecoverDate time.Time) (err error) {
if _, err = tx.Exec(_initMoral, mid, moral, added, deducted, lastRecoverDate); err != nil {
err = errors.Wrapf(err, "TxInitMoral mid(%d) moral(%v)", mid, moral)
return
}
return
}
// SetOfficialDoc add official doc.
func (d *Dao) SetOfficialDoc(c context.Context, od *model.OfficialDoc) (err error) {
_, err = d.db.Exec(c, _setOfficialDoc, od.Mid, od.Name, model.OfficialStateWait, od.Role,
od.Title, od.Desc, od.OfficialExtra.String(), od.SubmitSource, od.SubmitTime)
if err != nil {
err = errors.Wrapf(err, "dao add official doc")
return
}
return
}
// SetOfficialDocAddit add official doc addit.
func (d *Dao) SetOfficialDocAddit(c context.Context, mid int64, property, vstring string) error {
_, err := d.db.Exec(c, _setOfficialDocAddit, mid, property, vstring)
if err != nil {
err = errors.Wrapf(err, "dao add official doc addit")
return err
}
return nil
}
// OfficialDoc get official doc.
func (d *Dao) OfficialDoc(c context.Context, mid int64) (*model.OfficialDoc, error) {
od := new(model.OfficialDoc)
row := d.db.QueryRow(c, _selOfficialDoc, mid)
if err := row.Scan(&od.Mid, &od.Name, &od.State, &od.Role, &od.Title, &od.Desc, &od.RejectReason, &od.Extra); err != nil {
err = errors.Wrapf(err, "official doc")
return nil, err
}
od.ParseExtra()
return od, nil
}
// Realname
// RealnameInfo is.
func (d *Dao) RealnameInfo(c context.Context, mid int64) (info *model.RealnameInfo, err error) {
row := d.db.QueryRow(c, _selRealnameInfo, mid)
info = &model.RealnameInfo{}
if err = row.Scan(&info.ID, &info.MID, &info.Channel, &info.Realname, &info.Country, &info.CardType, &info.Card, &info.CardMD5, &info.Status, &info.Reason, &info.CTime, &info.MTime); err != nil {
if err == xsql.ErrNoRows {
err = nil
info = nil
return
}
err = errors.Wrapf(err, "dao RealnameInfo mid(%d)", mid)
return
}
return
}
// RealnameInfoByCard is.
func (d *Dao) RealnameInfoByCard(c context.Context, cardMD5 string) (info *model.RealnameInfo, err error) {
row := d.db.QueryRow(c, _selRealnameInfoByCard, cardMD5)
info = &model.RealnameInfo{}
if err = row.Scan(&info.ID, &info.MID, &info.Channel, &info.Realname, &info.Country, &info.CardType, &info.Card, &info.CardMD5, &info.Status, &info.Reason, &info.CTime, &info.MTime); err != nil {
if err == xsql.ErrNoRows {
err = nil
info = nil
return
}
err = errors.Wrapf(err, "dao RealnameInfo cardMD5(%s)", cardMD5)
return
}
return
}
// UpsertTxRealnameInfo is.
func (d *Dao) UpsertTxRealnameInfo(c context.Context, tx *xsql.Tx, info *model.RealnameInfo) (err error) {
if _, err = tx.Exec(_upsertRealnameInfo, info.MID, info.Channel, info.Realname, info.Country, info.CardType, info.Card, info.CardMD5, info.Status, info.Reason, info.Channel, info.Realname, info.Country, info.CardType, info.Card, info.CardMD5, info.Status, info.Reason); err != nil {
err = errors.WithStack(err)
return
}
return
}
// UpdateTxRealnameInfo is.
func (d *Dao) UpdateTxRealnameInfo(c context.Context, tx *xsql.Tx, mid int64, status model.RealnameApplyStatus, reason string) (err error) {
if _, err = tx.Exec(_updateRealnameInfo, status, reason, mid); err != nil {
err = errors.WithStack(err)
return
}
return
}
// RealnameApply realname
func (d *Dao) RealnameApply(c context.Context, mid int64) (apply *model.RealnameApply, err error) {
row := d.db.Master().QueryRow(c, _selRealnameApply, mid)
apply = &model.RealnameApply{}
if err = row.Scan(&apply.ID, &apply.MID, &apply.Realname, &apply.Country, &apply.CardType, &apply.CardNum, &apply.CardMD5, &apply.HandIMG, &apply.FrontIMG, &apply.BackIMG, &apply.Status, &apply.Operator, &apply.OperatorID, &apply.OperatorTime, &apply.Remark, &apply.RemarkStatus, &apply.CTime, &apply.MTime); err != nil {
if err == xsql.ErrNoRows {
err = nil
apply = nil
return
}
err = errors.Wrapf(err, "dao RealnameApply mid(%d)", mid)
return
}
return
}
// InsertRealnameApply is
func (d *Dao) InsertRealnameApply(c context.Context, data *model.RealnameApply) (err error) {
if _, err = d.db.Exec(c, _insertRealnameApply, data.MID, data.Realname, data.Country, data.CardType, data.CardNum, data.CardMD5, data.HandIMG, data.FrontIMG, data.BackIMG, data.Status); err != nil {
err = errors.WithStack(err)
return
}
return
}
// RealnameApplyIMG is
func (d *Dao) RealnameApplyIMG(c context.Context, id int) (img *model.RealnameApplyImage, err error) {
row := d.db.Master().QueryRow(c, _selRealnameApplyImg, id)
img = &model.RealnameApplyImage{}
if err = row.Scan(&img.ID, &img.IMGData, &img.CTime, &img.MTime); err != nil {
if err == xsql.ErrNoRows {
err = nil
img = nil
return
}
err = errors.Wrapf(err, "dao RealnameApplyIMG mid(%d)", id)
return
}
return
}
// InsertRealnameApplyImg is
func (d *Dao) InsertRealnameApplyImg(c context.Context, data *model.RealnameApplyImage) (id int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _insertRealnameApplyImg, data.IMGData); err != nil {
err = errors.WithStack(err)
return
}
if id, err = res.LastInsertId(); err != nil {
err = errors.WithStack(err)
return
}
return
}
// InsertOldRealnameApply is
func (d *Dao) InsertOldRealnameApply(c context.Context, data *model.RealnameApply) (id int64, err error) {
var (
res sql.Result
cardType = int16(data.CardType)
)
if data.Country > 0 {
cardType = data.Country
}
if res, err = d.accdb.Exec(c, _insertOldRealnameApply, data.MID, data.Realname, cardType, data.CardNum, data.CardMD5, data.FrontIMG, data.HandIMG, data.BackIMG, data.CTime.Unix(), data.Status); err != nil {
err = errors.WithStack(err)
return
}
if id, err = res.LastInsertId(); err != nil {
err = errors.WithStack(err)
return
}
return
}
// InsertOldRealnameApplyImg is
func (d *Dao) InsertOldRealnameApplyImg(c context.Context, data *model.RealnameApplyImage) (id int64, err error) {
var res sql.Result
if res, err = d.accdb.Exec(c, _insertOldRealnameApplyImg, data.IMGData, data.CTime); err != nil {
err = errors.WithStack(err)
return
}
if id, err = res.LastInsertId(); err != nil {
err = errors.WithStack(err)
return
}
return
}
// InsertTxRealnameAlipayApply .
func (d *Dao) InsertTxRealnameAlipayApply(c context.Context, tx *xsql.Tx, data *model.RealnameAlipayApply) (err error) {
if _, err = tx.Exec(_insertRealnameAlipayApply, data.MID, data.Realname, data.Card, data.IMG, data.Status, data.Reason, data.Bizno); err != nil {
err = errors.WithStack(err)
return
}
return
}
// UpdateTxRealnameAlipayApply is.
func (d *Dao) UpdateTxRealnameAlipayApply(c context.Context, tx *xsql.Tx, id int64, status model.RealnameApplyStatus, reason string) (err error) {
if _, err = tx.Exec(_updateRealnameAlipayApply, status, reason, id); err != nil {
err = errors.WithStack(err)
return
}
return
}
// RealnameAlipayApply .
func (d *Dao) RealnameAlipayApply(c context.Context, mid int64) (apply *model.RealnameAlipayApply, err error) {
row := d.db.QueryRow(c, _selRealnameAlipayApply, mid)
apply = &model.RealnameAlipayApply{}
if err = row.Scan(&apply.ID, &apply.MID, &apply.Realname, &apply.Card, &apply.IMG, &apply.Status, &apply.Reason, &apply.Bizno, &apply.CTime, &apply.MTime); err != nil {
if err == xsql.ErrNoRows {
err = nil
apply = nil
return
}
err = errors.Wrapf(err, "dao RealnameAlipayApply mid(%d)", mid)
return
}
return
}
func prepareStringArray(in []string) string {
surrounded := make([]string, 0, len(in))
for _, s := range in {
surrounded = append(surrounded, fmt.Sprintf(`'%s'`, s))
}
return strings.Join(surrounded, ",")
}
// MidByRealnameCards is
func (d *Dao) MidByRealnameCards(ctx context.Context, cardMD5s []string) (map[string]int64, error) {
rows, err := d.db.Query(ctx, fmt.Sprintf(_selRealnameInfoMidByCards, prepareStringArray(cardMD5s)))
if err != nil {
return nil, err
}
defer rows.Close()
result := make(map[string]int64, len(cardMD5s))
for rows.Next() {
mid, cardMD5 := int64(0), ""
if err := rows.Scan(&mid, &cardMD5); err != nil {
log.Warn("Failed to scan realname info: %+v", err)
continue
}
result[cardMD5] = mid
}
return result, nil
}

View File

@@ -0,0 +1,521 @@
package dao
import (
"context"
"testing"
"go-common/app/service/main/member/model"
"go-common/library/time"
"github.com/smartystreets/goconvey/convey"
)
func TestDaohit(t *testing.T) {
var (
id = int64(0)
)
convey.Convey("hit", t, func(ctx convey.C) {
p1 := hit(id)
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaoBeginTran(t *testing.T) {
var (
c = context.Background()
)
convey.Convey("BeginTran", t, func(ctx convey.C) {
tx, err := d.BeginTran(c)
defer tx.Commit()
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("tx should not be nil", func(ctx convey.C) {
ctx.So(tx, convey.ShouldNotBeNil)
})
})
}
func TestDaoBaseInfo(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
)
convey.Convey("BaseInfo", t, func(ctx convey.C) {
r, err := d.BaseInfo(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("r should not be nil", func(ctx convey.C) {
ctx.So(r, convey.ShouldNotBeNil)
})
})
}
func TestDaoSetBase(t *testing.T) {
var (
c = context.Background()
base = &model.BaseInfo{
Mid: 0,
}
)
convey.Convey("SetBase", t, func(ctx convey.C) {
err := d.SetBase(c, base)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoSetSign(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
sign = "test"
)
convey.Convey("SetSign", t, func(ctx convey.C) {
err := d.SetSign(c, mid, sign)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoSetName(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
name = "test"
)
convey.Convey("SetName", t, func(ctx convey.C) {
err := d.SetName(c, mid, name)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoSetRank(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
rank = int64(100)
)
convey.Convey("SetRank", t, func(ctx convey.C) {
err := d.SetRank(c, mid, rank)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoSetSex(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
sex = int64(1)
)
convey.Convey("SetSex", t, func(ctx convey.C) {
err := d.SetSex(c, mid, sex)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoSetBirthday(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
birthday = time.Time(946656000)
)
convey.Convey("SetBirthday", t, func(ctx convey.C) {
err := d.SetBirthday(c, mid, birthday)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoSetFace(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
face = "test"
)
convey.Convey("SetFace", t, func(ctx convey.C) {
err := d.SetFace(c, mid, face)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoExpDB(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
)
convey.Convey("ExpDB", t, func(ctx convey.C) {
count, err := d.ExpDB(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("count should not be nil", func(ctx convey.C) {
ctx.So(count, convey.ShouldNotBeNil)
})
})
}
func TestDaoSetExp(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
count = int64(10)
)
convey.Convey("SetExp", t, func(ctx convey.C) {
affect, err := d.SetExp(c, mid, count)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("affect should not be nil", func(ctx convey.C) {
ctx.So(affect, convey.ShouldNotBeNil)
})
})
}
func TestDaoUpdateExp(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
delta = int64(6)
)
convey.Convey("UpdateExp", t, func(ctx convey.C) {
affect, err := d.UpdateExp(c, mid, delta)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("affect should not be nil", func(ctx convey.C) {
ctx.So(affect, convey.ShouldNotBeNil)
})
})
}
func TestDaoUserAttrDB(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
attr uint
)
convey.Convey("UserAttrDB", t, func(ctx convey.C) {
hasAttr, err := d.UserAttrDB(c, mid, attr)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("hasAttr should not be nil", func(ctx convey.C) {
ctx.So(hasAttr, convey.ShouldNotBeNil)
})
})
}
func TestDaoSetUserAttr(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
attr uint
)
convey.Convey("SetUserAttr", t, func(ctx convey.C) {
err := d.SetUserAttr(c, mid, attr)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoOfficials(t *testing.T) {
var (
c = context.Background()
)
convey.Convey("Officials", t, func(ctx convey.C) {
om, err := d.Officials(c)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("om should not be nil", func(ctx convey.C) {
ctx.So(om, convey.ShouldNotBeNil)
})
})
}
func TestDaoOfficial(t *testing.T) {
var (
c = context.Background()
mid = int64(1)
)
convey.Convey("Official", t, func(ctx convey.C) {
p1, p2 := d.Official(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(p2, convey.ShouldBeNil)
})
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaoMoralDB(t *testing.T) {
var (
c = context.Background()
mid = int64(4780461)
)
convey.Convey("MoralDB", t, func(ctx convey.C) {
moral, err := d.MoralDB(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("moral should not be nil", func(ctx convey.C) {
ctx.So(moral, convey.ShouldNotBeNil)
})
})
}
func TestDaoTxMoralDB(t *testing.T) {
var (
c = context.Background()
tx, _ = d.db.Begin(c)
mid = int64(8)
)
defer tx.Commit()
convey.Convey("TxMoralDB", t, func(ctx convey.C) {
moral, err := d.TxMoralDB(tx, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("moral should not be nil", func(ctx convey.C) {
ctx.So(moral, convey.ShouldNotBeNil)
})
})
}
func TestDaoTxUpdateMoral(t *testing.T) {
var (
c = context.Background()
tx, _ = d.db.Begin(c)
mid = int64(0)
moral = int64(0)
added = int64(0)
deducted = int64(0)
)
defer tx.Commit()
convey.Convey("TxUpdateMoral", t, func(ctx convey.C) {
err := d.TxUpdateMoral(tx, mid, moral, added, deducted)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoTxUpdateMoralRecoverDate(t *testing.T) {
var (
c = context.Background()
tx, _ = d.db.Begin(c)
mid = int64(0)
recoverDate = time.Time(946656000)
)
defer tx.Commit()
convey.Convey("TxUpdateMoralRecoverDate", t, func(ctx convey.C) {
err := d.TxUpdateMoralRecoverDate(tx, mid, recoverDate)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoTxInitMoral(t *testing.T) {
var (
c = context.Background()
tx, _ = d.db.Begin(c)
mid = int64(10)
moral = int64(0)
added = int64(0)
deducted = int64(0)
lastRecoverDate = time.Time(946656000)
)
defer tx.Commit()
convey.Convey("TxInitMoral", t, func(ctx convey.C) {
err := d.TxInitMoral(tx, mid, moral, added, deducted, lastRecoverDate)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoSetOfficialDoc(t *testing.T) {
var (
c = context.Background()
od = &model.OfficialDoc{
Mid: 4780461,
}
)
convey.Convey("SetOfficialDoc", t, func(ctx convey.C) {
err := d.SetOfficialDoc(c, od)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoOfficialDoc(t *testing.T) {
var (
c = context.Background()
mid = int64(4780461)
)
convey.Convey("OfficialDoc", t, func(ctx convey.C) {
p1, p2 := d.OfficialDoc(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(p2, convey.ShouldBeNil)
})
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaoRealnameInfo(t *testing.T) {
var (
c = context.Background()
mid = int64(46333)
)
convey.Convey("TestDaoRealnameInfo", t, func(ctx convey.C) {
info, err := d.RealnameInfo(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("info should not be nil", func(ctx convey.C) {
t.Logf("info:%+v", info)
ctx.So(info, convey.ShouldNotBeNil)
})
})
}
func TestDaoRealnameInfoByCard(t *testing.T) {
var (
c = context.Background()
cardMD5 = "0088bdb8af58d25c1d9864e568a3cfb8"
)
convey.Convey("TestDaoRealnameInfoByCard", t, func(ctx convey.C) {
info, err := d.RealnameInfoByCard(c, cardMD5)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("info should not be nil", func(ctx convey.C) {
t.Logf("info:%+v", info)
ctx.So(info, convey.ShouldNotBeNil)
})
})
}
func TestDaoRealnameApply(t *testing.T) {
var (
c = context.Background()
mid = int64(4780461)
)
convey.Convey("RealnameApply", t, func(ctx convey.C) {
apply, err := d.RealnameApply(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("apply should not be nil", func(ctx convey.C) {
ctx.So(apply, convey.ShouldNotBeNil)
})
})
}
func TestDaoInsertRealnameApply(t *testing.T) {
var (
c = context.Background()
data = &model.RealnameApply{
MID: 4780461,
}
)
convey.Convey("InsertRealnameApply", t, func(ctx convey.C) {
err := d.InsertRealnameApply(c, data)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoInsertRealnameApplyImg(t *testing.T) {
var (
c = context.Background()
data = &model.RealnameApplyImage{
ID: 1,
IMGData: "1234",
}
)
convey.Convey("InsertRealnameApplyImg", t, func(ctx convey.C) {
id, err := d.InsertRealnameApplyImg(c, data)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("id should not be nil", func(ctx convey.C) {
ctx.So(id, convey.ShouldNotBeNil)
})
})
}
func TestDaoRealnameApplyIMG(t *testing.T) {
var (
c = context.Background()
id = int(1)
)
convey.Convey("RealnameApplyIMG", t, func(ctx convey.C) {
img, err := d.RealnameApplyIMG(c, id)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("img should not be nil", func(ctx convey.C) {
ctx.So(img, convey.ShouldNotBeNil)
})
})
}
func TestDaoInsertOldRealnameApply(t *testing.T) {
var (
c = context.Background()
data = &model.RealnameApply{
ID: 1,
}
)
convey.Convey("InsertOldRealnameApply", t, func(ctx convey.C) {
id, err := d.InsertOldRealnameApply(c, data)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("id should not be nil", func(ctx convey.C) {
ctx.So(id, convey.ShouldNotBeNil)
})
})
}
func TestDaoInsertOldRealnameApplyImg(t *testing.T) {
var (
c = context.Background()
data = &model.RealnameApplyImage{
ID: 1,
IMGData: "1234",
}
)
convey.Convey("InsertOldRealnameApplyImg", t, func(ctx convey.C) {
id, err := d.InsertOldRealnameApplyImg(c, data)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("id should not be nil", func(ctx convey.C) {
ctx.So(id, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,50 @@
package dao
import (
"context"
"go-common/app/service/main/member/model"
"github.com/pkg/errors"
)
const (
_addUserMonitor = "INSERT INTO user_monitor(mid, operator, remark) VALUES(?,?,?) ON DUPLICATE KEY UPDATE operator=VALUES(operator), remark=VALUES(remark), is_deleted=0"
_isInUserMonitor = "SELECT count(1) FROM user_monitor WHERE mid=? and is_deleted=0"
_addPropertyReview = "INSERT INTO user_property_review(mid, old, new, state, property, is_monitor, extra) VALUES (?,?,?,?,?,?,?)"
_archivePropertyReview = "UPDATE user_property_review SET state=?, operator=?, remark=? WHERE mid=? AND property=? AND state=0"
)
// AddUserMonitor is.
func (d *Dao) AddUserMonitor(ctx context.Context, mid int64, operator, remark string) error {
if _, err := d.db.Exec(ctx, _addUserMonitor, mid, operator, remark); err != nil {
return errors.Wrapf(err, "dao add user monitor")
}
return nil
}
// IsInUserMonitor is.
func (d *Dao) IsInUserMonitor(ctx context.Context, mid int64) (bool, error) {
row := d.db.QueryRow(ctx, _isInUserMonitor, mid)
inMonitor := false
if err := row.Scan(&inMonitor); err != nil {
return false, errors.Wrapf(err, "dao is in user monitor")
}
return inMonitor, nil
}
// AddPropertyReview is.
func (d *Dao) AddPropertyReview(ctx context.Context, r *model.UserPropertyReview) error {
if _, err := d.db.Exec(ctx, _addPropertyReview, r.Mid, r.Old, r.New, r.State, r.Property, r.IsMonitor, r.Extra); err != nil {
return errors.Wrapf(err, "dao add user property review")
}
return nil
}
// ArchivePropertyReview is.
func (d *Dao) ArchivePropertyReview(ctx context.Context, mid int64, property int8) error {
if _, err := d.db.Exec(ctx, _archivePropertyReview, model.ReviewStateArchived, "system", "已存在待审核单,本条归档处理", mid, property); err != nil {
return errors.Wrapf(err, "dao archive property review")
}
return nil
}

View File

@@ -0,0 +1,76 @@
package dao
import (
"context"
"testing"
"go-common/app/service/main/member/model"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoAddUserMonitor(t *testing.T) {
var (
c = context.TODO()
mid = int64(1)
operator = "zhoujiahui"
remark = "test"
)
convey.Convey("AddUserMonitor", t, func(ctx convey.C) {
p1 := d.AddUserMonitor(c, mid, operator, remark)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldBeNil)
})
})
}
func TestDaoIsInUserMonitor(t *testing.T) {
var (
c = context.TODO()
mid = int64(1)
)
convey.Convey("IsInUserMonitor", t, func(ctx convey.C) {
p1, p2 := d.IsInUserMonitor(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(p2, convey.ShouldBeNil)
})
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaoAddPropertyReview(t *testing.T) {
var (
c = context.TODO()
r = &model.UserPropertyReview{
Mid: 2231365,
Old: "hahhah",
New: "dangerou",
State: model.ReviewStateWait,
Property: model.ReviewPropertySign,
IsMonitor: true,
Extra: "{}",
}
)
convey.Convey("AddPropertyReview", t, func(ctx convey.C) {
p1 := d.AddPropertyReview(c, r)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldBeNil)
})
})
}
func TestDaoArchivePropertyReview(t *testing.T) {
var (
c = context.TODO()
mid = int64(3)
property = int8(1)
)
convey.Convey("ArchivePropertyReview", t, func(ctx convey.C) {
p1 := d.ArchivePropertyReview(c, mid, property)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldBeNil)
})
})
}

View File

@@ -0,0 +1,40 @@
package dao
import (
"context"
"fmt"
"net/url"
"go-common/library/ecode"
"go-common/library/log"
)
// http client
const (
smsURL = "http://api.bilibili.co/x/internal/sms/send"
)
// SendCapture is
func (d *Dao) SendCapture(c context.Context, mid int64, code int) (err error) {
var (
params = url.Values{}
)
params.Set("mid", fmt.Sprintf("%d", mid))
params.Set("tcode", "acc_01")
params.Set("tparam", fmt.Sprintf(`{"identify_code":"%d"}`, code))
var resp struct {
Code int `json:"code"`
}
for i := 0; i < 3; i++ {
err = d.client.Post(c, smsURL, "", params, &resp)
if err != nil || resp.Code != 0 {
log.Error("d.client.Post(%s,%+v) resp.Code(%d)", smsURL, params, resp.Code)
err = ecode.RealnameCaptureErr
} else {
break
}
}
return
}

View File

@@ -0,0 +1,22 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoSendCapture(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
code = int(0)
)
convey.Convey("SendCapture", t, func(ctx convey.C) {
err := d.SendCapture(c, mid, code)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldEqual, 74001)
})
})
}

View File

@@ -0,0 +1,64 @@
package dao
import (
"context"
"fmt"
"go-common/app/service/main/member/model"
"go-common/library/cache/redis"
)
const (
_expShard = 10000
_expAddedPrefix = "ea_%s_%d_%d"
_expCoinPrefix = "ecoin_%d_%d"
)
const (
_share = "shareClick"
_view = "watch"
_login = "login"
)
func expCoinKey(mid, day int64) string {
return fmt.Sprintf(_expCoinPrefix, day, mid)
}
func expAddedKey(tp string, mid, day int64) string {
return fmt.Sprintf(_expAddedPrefix, tp, day, mid/_expShard)
}
// StatCache get exp stat cache.
func (d *Dao) StatCache(c context.Context, mid, day int64) (st *model.ExpStat, err error) {
conn := d.redis.Get(c)
defer conn.Close()
conn.Send("GETBIT", expAddedKey(_login, mid, day), mid%_expShard)
conn.Send("GETBIT", expAddedKey(_view, mid, day), mid%_expShard)
conn.Send("GETBIT", expAddedKey(_share, mid, day), mid%_expShard)
conn.Send("GET", expCoinKey(mid, day))
err = conn.Flush()
if err != nil {
return
}
st = new(model.ExpStat)
st.Login, err = redis.Bool(conn.Receive())
if err != nil && err != redis.ErrNil {
return
}
st.Watch, err = redis.Bool(conn.Receive())
if err != nil && err != redis.ErrNil {
return
}
st.Share, err = redis.Bool(conn.Receive())
if err != nil && err != redis.ErrNil {
return
}
st.Coin, err = redis.Int64(conn.Receive())
if err != nil && err != redis.ErrNil {
return
}
if err == redis.ErrNil {
err = nil
}
return
}

View File

@@ -0,0 +1,52 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoexpCoinKey(t *testing.T) {
var (
mid = int64(0)
day = int64(0)
)
convey.Convey("expCoinKey", t, func(ctx convey.C) {
p1 := expCoinKey(mid, day)
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaoexpAddedKey(t *testing.T) {
var (
tp = ""
mid = int64(0)
day = int64(0)
)
convey.Convey("expAddedKey", t, func(ctx convey.C) {
p1 := expAddedKey(tp, mid, day)
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaoStatCache(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
day = int64(0)
)
convey.Convey("StatCache", t, func(ctx convey.C) {
st, err := d.StatCache(c, mid, day)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("st should not be nil", func(ctx convey.C) {
ctx.So(st, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,74 @@
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 = "model_proto",
srcs = ["model.proto"],
tags = ["automanaged"],
deps = ["@gogo_special_proto//github.com/gogo/protobuf/gogoproto"],
)
go_proto_library(
name = "model_go_proto",
compilers = ["@io_bazel_rules_go//proto:gogofast_proto"],
importpath = "go-common/app/service/main/member/model",
proto = ":model_proto",
tags = ["automanaged"],
deps = [
"//library/time:go_default_library",
"@com_github_gogo_protobuf//gogoproto:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"base.go",
"log.go",
"member.go",
"moral.go",
"official.go",
"property_review.go",
"realname.go",
"rpc.go",
"search.go",
"user_flag.go",
],
embed = [":model_go_proto"],
importpath = "go-common/app/service/main/member/model",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//library/log:go_default_library",
"//library/time:go_default_library",
"//vendor/github.com/satori/go.uuid:go_default_library",
"@com_github_gogo_protobuf//gogoproto:go_default_library",
"@com_github_golang_protobuf//proto:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/service/main/member/model/block:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,72 @@
package model
import (
"fmt"
"math/rand"
)
// consts
const (
URLNoFace = "http://static.hdslb.com/images/member/noface.gif"
ActUpdateByAdmin = "updateByAdmin"
ActUpdatePersonInfo = "updatePersonInfo"
ActUpdateFace = "updateFace"
ActUpdateUname = "updateUname"
ActBlockUser = "blockUser"
CertNO = -1 // 未认证
DefaultRank = 5000 // default rank
DefaultTime = -28800 // default time
DefaultMoral = 7000 // default moral
MaxMoral = 10000 // max moral
CacheKeyBase = "bs_%d" // key of baseInfo
)
// RandFaceURL get face URL
func (b *BaseInfo) RandFaceURL() {
if b.Face == "" {
b.Face = URLNoFace
return
}
b.Face = fmt.Sprintf("http://i%d.hdslb.com%s", rand.Int63n(3), b.Face)
}
// SexStr get sex str
func (b *BaseInfo) SexStr() string {
switch b.Sex {
case 0:
return "保密"
case 1:
return "男"
case 2:
return "女"
default:
return "保密"
}
}
// NotifyInfo notify info.
type NotifyInfo struct {
Uname string `json:"uname"`
Mid int64 `json:"mid"`
Type string `json:"type"`
NewName string `json:"newName"`
Action string `json:"action"`
}
// Equal is.
func (of *OfficialInfo) Equal(cof *OfficialInfo) bool {
return of.Role == cof.Role && of.Title == cof.Title && of.Desc == cof.Desc
}
// BaseExp exp and base info.
type BaseExp struct {
*BaseInfo
*LevelInfo
}
// Member is the full information within member-service.
type Member struct {
*BaseInfo
*LevelInfo
*OfficialInfo
}

View File

@@ -0,0 +1,33 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"dao.go",
"http.go",
"model.go",
"notify.go",
"rpc.go",
],
importpath = "go-common/app/service/main/member/model/block",
tags = ["automanaged"],
)
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 block
import (
"time"
)
// DBUser .
type DBUser struct {
ID int64
MID int64
Status BlockStatus
CTime time.Time
MTime time.Time
}
// DBUserDetail .
type DBUserDetail struct {
ID int64
MID int64
BlockCount int64
CTime time.Time
MTime time.Time
}
// DBHistory .
type DBHistory struct {
ID int64
MID int64
AdminID int64
AdminName string
Source BlockSource
Area BlockArea
Reason string
Comment string
Action BlockAction
StartTime time.Time
Duration int64
Notify bool
CTime time.Time
MTime time.Time
}
// MCBlockInfo .
type MCBlockInfo struct {
BlockStatus BlockStatus `json:"bs"`
StartTime int64 `json:"st"`
EndTime int64 `json:"et"`
}
// MCUserDetail .
type MCUserDetail struct {
BlockCount int64 `json:"block_count"`
}

View File

@@ -0,0 +1,160 @@
package block
// ParamValidator .
type ParamValidator interface {
Validate() bool
}
// ParamInfo .
type ParamInfo struct {
MID int64 `form:"mid"`
}
// Validate .
func (p *ParamInfo) Validate() bool {
return p.MID > 0
}
// ParamBatchInfo .
type ParamBatchInfo struct {
MIDs []int64 `form:"mids,split"`
}
// Validate .
func (p *ParamBatchInfo) Validate() bool {
if len(p.MIDs) == 0 || len(p.MIDs) > 20 {
return false
}
return true
}
// ParamBatchDetail .
type ParamBatchDetail struct {
MIDs []int64 `form:"mids,split"`
}
// Validate .
func (p *ParamBatchDetail) Validate() bool {
if len(p.MIDs) == 0 || len(p.MIDs) > 20 {
return false
}
return true
}
// ParamBlock .
type ParamBlock struct {
MID int64 `form:"mid"`
Source BlockSource `form:"source"`
Area BlockArea `form:"area"`
Action BlockAction `form:"action"`
Duration int64 `form:"duration"` // unix time
StartTime int64 `form:"start_time"`
OperatorID int `form:"op_id"`
Operator string `form:"operator"`
Reason string `form:"reason"`
Comment string `form:"comment"`
Notify bool `form:"notify"`
}
// Validate .
func (p *ParamBlock) Validate() bool {
if p.MID <= 0 {
return false
}
if !p.Source.Contain() {
return false
}
if p.Action != BlockActionLimit && p.Action != BlockActionForever {
return false
}
if p.StartTime <= 0 {
return false
}
if p.Action == BlockActionLimit {
if p.Duration <= 0 {
return false
}
}
return true
}
// ParamBatchBlock .
type ParamBatchBlock struct {
MIDs []int64 `form:"mids,split"`
Source BlockSource `form:"source"`
Area BlockArea `form:"area"`
Action BlockAction `form:"action"`
Duration int64 `form:"duration"` // unix time
StartTime int64 `form:"start_time"`
OperatorID int `form:"op_id"`
Operator string `form:"operator"`
Reason string `form:"reason"`
Comment string `form:"comment"`
Notify bool `form:"notify"`
}
// Validate .
func (p *ParamBatchBlock) Validate() bool {
if len(p.MIDs) == 0 || len(p.MIDs) > 20 {
return false
}
if !p.Source.Contain() {
return false
}
if p.Action != BlockActionLimit && p.Action != BlockActionForever {
return false
}
if p.StartTime <= 0 {
return false
}
if p.Action == BlockActionLimit {
if p.Duration <= 0 {
return false
}
}
return true
}
// ParamRemove .
type ParamRemove struct {
MID int64 `form:"mid"`
Source BlockSource `form:"source"`
OperatorID int `form:"op_id"`
Operator string `form:"operator"`
Reason string `form:"reason"`
Comment string `form:"comment"`
Notify bool `form:"notify"`
}
// Validate .
func (p *ParamRemove) Validate() bool {
if p.MID <= 0 {
return false
}
if !p.Source.Contain() {
return false
}
return true
}
// ParamBatchRemove .
type ParamBatchRemove struct {
MIDs []int64 `form:"mids,split"`
Source BlockSource `form:"source"`
OperatorID int `form:"op_id"`
Operator string `form:"operator"`
Reason string `form:"reason"`
Comment string `form:"comment"`
Notify bool `form:"notify"`
}
// Validate .
func (p *ParamBatchRemove) Validate() bool {
if len(p.MIDs) == 0 || len(p.MIDs) > 20 {
return false
}
if !p.Source.Contain() {
return false
}
return true
}

View File

@@ -0,0 +1,231 @@
package block
import (
"time"
)
// BlockStatus 封禁状态 0. 未封禁 1. 永久封禁 2. 限时封禁
type BlockStatus uint8
const (
// BlockStatusFalse 未封禁
BlockStatusFalse BlockStatus = iota
// BlockStatusForever 永久封禁
BlockStatusForever
// BlockStatusLimit 限时封禁
BlockStatusLimit
// BlockStatusCredit 小黑屋封禁
BlockStatusCredit
)
// BlockSource 封禁来源 1. 小黑屋(小黑屋和manager后台封禁) 2. 系统封禁(反作弊及监控系统上报) 3.管理后台 4.B+
type BlockSource uint8
// Contain .
func (b BlockSource) Contain() bool {
switch b {
case BlockSourceBlackHouse, BlockSourceSys, BlockSourceManager, BlockSourceBplus:
return true
default:
return false
}
}
const (
// BlockSourceBlackHouse 小黑屋封禁
BlockSourceBlackHouse BlockSource = iota + 1
// BlockSourceSys 系统封禁
BlockSourceSys
// BlockSourceManager 管理后台
BlockSourceManager
// BlockSourceBplus B+相关(动态、im、小视频)
BlockSourceBplus
)
// String .
func (b BlockSource) String() string {
switch b {
case BlockSourceBlackHouse:
return "小黑屋"
case BlockSourceSys:
return "系统封禁"
case BlockSourceManager:
return "管理后台"
case BlockSourceBplus:
return "Bplus"
default:
return ""
}
}
const (
// BlockLogBizID 用户审核日志
BlockLogBizID int = 122
)
// BlockArea 封禁业务
type BlockArea uint8
// Contain .
func (b BlockArea) Contain() bool {
switch b {
case BlockAreaNone, BlockAreaReply, BlockAreaDanmaku, BlockAreaMessage, BlockAreaTag, BlockAreaProfile, BlockAreaArchive, BlockAreaMusic, BlockAreaArticle, BlockAreaSpaceBanner, BlockAreaDynamic, BlockAreaAlbum, BlockAreaQuickVideo:
return true
default:
return false
}
}
func (b BlockArea) String() string {
switch b {
case BlockAreaReply:
return "评论"
case BlockAreaDanmaku:
return "弹幕"
case BlockAreaMessage:
return "私信"
case BlockAreaTag:
return "标签"
case BlockAreaProfile:
return "个人资料"
case BlockAreaArchive:
return "投稿"
case BlockAreaMusic:
return "音频"
case BlockAreaArticle:
return "专栏"
case BlockAreaSpaceBanner:
return "空间头图"
case BlockAreaDynamic:
return "动态"
case BlockAreaAlbum:
return "相册"
case BlockAreaQuickVideo:
return "小视频"
default:
return ""
}
}
// const .
const (
BlockAreaNone BlockArea = iota
BlockAreaReply
BlockAreaDanmaku
BlockAreaMessage
BlockAreaTag
BlockAreaProfile // 个人资料
BlockAreaArchive
BlockAreaMusic
BlockAreaArticle
BlockAreaSpaceBanner // 空间头图
BlockAreaDynamic // 动态
BlockAreaAlbum // 相册
BlockAreaQuickVideo //小视频
)
// BlockAction .
type BlockAction uint8
const (
// BlockActionLimit 限时封禁
BlockActionLimit BlockAction = iota + 1
// BlockActionForever 永久封禁
BlockActionForever
// BlockActionAdminRemove 后台解封
BlockActionAdminRemove
// BlockActionSelfRemove 自助解封
BlockActionSelfRemove
)
// String .
func (b BlockAction) String() string {
switch b {
case BlockActionLimit:
return "限时封禁"
case BlockActionForever:
return "永久封禁"
case BlockActionAdminRemove:
return "后台解封"
case BlockActionSelfRemove:
return "自动解封"
default:
return ""
}
}
// BlockInfo 封禁信息
type BlockInfo struct {
MID int64 `json:"mid"`
BlockStatus BlockStatus `json:"status"` // status 封禁状态 0. 未封禁 1. 永久封禁 2. 限时封禁
StartTime int64 `json:"start_time"` // 开始封禁时间 unix time 未封禁为 -1
EndTime int64 `json:"end_time"` // 结束封禁时间 unix time 永久封禁为 -1
}
// ParseDB .
func (b *BlockInfo) ParseDB(data *DBHistory) {
b.MID = data.MID
switch data.Action {
case BlockActionForever:
b.BlockStatus = BlockStatusForever
case BlockActionLimit:
b.BlockStatus = BlockStatusLimit
default:
b.BlockStatus = BlockStatusFalse
}
switch b.BlockStatus {
case BlockStatusForever:
b.StartTime = data.StartTime.Unix()
b.EndTime = -1
case BlockStatusLimit:
b.StartTime = data.StartTime.Unix()
b.EndTime = data.StartTime.Add(time.Duration(data.Duration) * time.Second).Unix()
default:
b.StartTime = -1
b.EndTime = -1
}
}
// ParseMC .
func (b *BlockInfo) ParseMC(data *MCBlockInfo, mid int64) {
b.MID = mid
b.BlockStatus = data.BlockStatus
b.StartTime = data.StartTime
b.EndTime = data.EndTime
}
// BlockHistory 封禁历史
type BlockHistory struct {
Area BlockArea `json:"type"`
Operator string `json:"operator"` // 操作人
Reason string `json:"reason"` // 封禁原因
Action BlockAction `json:"action"` // 操作类型
ActionTime int64 `json:"action_time"` // 操作时间
RemoveTime int64 `json:"remove_time"` // 解封时间
Comment string `json:"comment"`
}
// ParseDB .
func (b *BlockHistory) ParseDB(data *DBHistory) {
b.Area = data.Area
b.Operator = data.AdminName
b.Reason = data.Reason
b.Action = data.Action
b.ActionTime = data.StartTime.Unix()
b.RemoveTime = data.StartTime.Add(time.Second * time.Duration(data.Duration)).Unix()
b.Comment = data.Comment
}
// BlockMessage 通知消息体
type BlockMessage struct {
MID int64 `json:"mid"` // 用户mid
Area BlockArea `json:"area"` // BlockArea 封禁类型 1. 小黑屋(小黑屋和manager后台封禁) 2. 系统封禁(反作弊及监控系统上报) 3.解封 (所有后台,用户前台自助的解封)
Status BlockStatus `json:"status"` // blockStatus 封禁状态 0. 未封禁 1. 永久封禁 2. 限时封禁
}
// BlockUserDetail .
type BlockUserDetail struct {
MID int64 `json:"mid"` // 用户mid
BlockCount int64 `json:"block_count"` // 封禁次数
}

View File

@@ -0,0 +1,8 @@
package block
// AccountNotify .
type AccountNotify struct {
UID int64 `json:"mid"`
Type string `json:"type"`
Action string `json:"action"`
}

View File

@@ -0,0 +1,43 @@
package block
// RPCArgInfo .
type RPCArgInfo struct {
MID int64
}
// RPCArgBatchInfo .
type RPCArgBatchInfo struct {
MIDs []int64
}
// RPCResInfo .
type RPCResInfo struct {
MID int64
BlockStatus BlockStatus
StartTime int64
EndTime int64
}
// Parse .
func (r *RPCResInfo) Parse(b *BlockInfo) {
r.MID = b.MID
r.BlockStatus = b.BlockStatus
r.StartTime = b.StartTime
r.EndTime = b.EndTime
}
// RPCArgBlock .
// type RPCArgBlock struct {
// }
// RPCArgBatchBlock .
// type RPCArgBatchBlock struct {
// }
// RPCArgRemove .
// type RPCArgRemove struct {
// }
// RPCArgBatchRemove .RPCArgBatchRemove
// type RPCArgBatchRemove struct {
// }

View File

@@ -0,0 +1,19 @@
package model
import (
"github.com/satori/go.uuid"
)
// UserLog log info.
type UserLog struct {
Mid int64 `json:"mid"`
IP string `json:"ip"`
TS int64 `json:"ts"`
LogID string `json:"log_id"`
Content map[string]string `json:"content"`
}
// UUID4 is generate uuid
func UUID4() string {
return uuid.NewV4().String()
}

View File

@@ -0,0 +1,52 @@
package model
const (
// ExpMulti exp multi
ExpMulti = 100
// level floor conf.
level1 = 1
level2 = 200
level3 = 1500
level4 = 4500
level5 = 10800
level6 = 28800
levelMax = -1
)
// BuildLevel build level by LevelInfo
func (lv *LevelInfo) BuildLevel(exp int64, sexp bool) {
exp = exp / ExpMulti
switch {
case exp < level1:
lv.Cur = 0
lv.Min = 0
lv.NextExp = level1
case exp < level2:
lv.Cur = 1
lv.Min = level1
lv.NextExp = level2
case exp < level3:
lv.Cur = 2
lv.Min = level2
lv.NextExp = level3
case exp < level4:
lv.Cur = 3
lv.Min = level3
lv.NextExp = level4
case exp < level5:
lv.Cur = 4
lv.Min = level4
lv.NextExp = level5
case exp < level6:
lv.Cur = 5
lv.Min = level5
lv.NextExp = level6
default:
lv.Cur = 6
lv.Min = level6
lv.NextExp = levelMax
}
if sexp {
lv.NowExp = int32(exp)
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,37 @@
syntax = "proto3";
package account.service.member;
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
option go_package = "model";
message BaseInfo {
int64 mid = 1 [(gogoproto.jsontag) = "mid"];
string name = 2 [(gogoproto.jsontag) = "name"];
int64 sex = 3 [(gogoproto.jsontag) = "sex"];
string face = 4 [(gogoproto.jsontag) = "face"];
string sign = 5 [(gogoproto.jsontag) = "sign"];
int64 rank = 6 [(gogoproto.jsontag) = "rank"];
int64 birthday = 7 [(gogoproto.jsontag) = "birthday", (gogoproto.casttype) = "go-common/library/time.Time"];
}
message LevelInfo {
int32 cur = 1 [(gogoproto.jsontag) = "current_level"];
int32 min = 2 [(gogoproto.jsontag) = "current_min"];
int32 now_exp = 3 [(gogoproto.jsontag) = "current_exp"];
int32 next_exp = 4 [(gogoproto.jsontag) = "next_exp"];
}
message OfficialInfo {
int32 role = 1 [(gogoproto.jsontag) = "role",(gogoproto.casttype) = "int8"];
string title = 2 [(gogoproto.jsontag) = "title"];
string desc = 3 [(gogoproto.jsontag) = "desc"];
}
message Moral {
int64 mid = 1 [(gogoproto.jsontag) = "mid"];
int64 moral = 2 [(gogoproto.jsontag) = "moral"];
int64 added = 3 [(gogoproto.jsontag) = "added"];
int64 deducted = 4 [(gogoproto.jsontag) = "deducted"];
int64 last_recover_date = 5 [(gogoproto.jsontag) = "last_recover_date", (gogoproto.casttype) = "go-common/library/time.Time"];
}

View File

@@ -0,0 +1,123 @@
package model
const (
// DMReasonType is.
DMReasonType = 1
// ReplyReasonType is.
ReplyReasonType = 2
// TagReasonType is.
TagReasonType = 3
// ElecReasonType is.
ElecReasonType = 4
// AccountReasonType is.
AccountReasonType = 5
// SysReasonType is.
SysReasonType = 6
// RevocableMoralStatus is.
RevocableMoralStatus = 0
// RevokedMoralStatus is.
RevokedMoralStatus = 1
// IrrevocableMoralStatus is.
IrrevocableMoralStatus = 2
// ReportRewardType is.
ReportRewardType = 1
// PunishmentType is.
PunishmentType = 2
// CancelRewardType is.
CancelRewardType = 3
// CancelPunishType is.
CancelPunishType = 4
// ManualRecoveryType is.
ManualRecoveryType = 5
// ManualChangeType is.
ManualChangeType = 6
)
//ArgUpdateMorals argUpdateMorals.
type ArgUpdateMorals struct {
Mids []int64 `form:"mids,split" validate:"required"`
Delta int64 `form:"delta" validate:"required"`
Origin int64 `form:"origin" validate:"required"`
Reason string `form:"reason" validate:"required"`
ReasonType int64 `form:"reason_type"`
Operator string `form:"operator" validate:"required"`
Remark string `form:"remark" validate:"required"`
Status int64 `form:"status"`
IsNotify bool `form:"is_notify"`
IP string `form:"ip"`
}
//ArgUpdateMoral argUpdateMoral.
type ArgUpdateMoral struct {
Mid int64 `form:"mid" validate:"required"`
Delta int64 `form:"delta" validate:"required"`
Origin int64 `form:"origin" validate:"required"`
Reason string `form:"reason" validate:"required"`
ReasonType int64 `form:"reason_type"`
Operator string `form:"operator" validate:"required"`
Remark string `form:"remark" validate:"required"`
Status int64 `form:"status"`
IsNotify bool `form:"is_notify"`
IP string `form:"ip"`
}
//ArgUndo argUndo.
type ArgUndo struct {
LogID string `form:"log_id" validate:"required"`
Remark string `form:"remark" validate:"required"`
Operator string `form:"operator" validate:"required"`
}
//ReasonType reasonType
type ReasonType struct {
Name string
NotifyType string
}
//OriginType originType
type OriginType struct {
Name string
NeedReason bool
}
//Notice notice
type Notice struct {
Title string
Message string
NoticeType string
}
var (
// ReasonTypes ...
ReasonTypes = map[int64]*ReasonType{
DMReasonType: {"弹幕", "2_1_4"},
ReplyReasonType: {"评论", "2_1_3"},
TagReasonType: {"TAG", ""},
ElecReasonType: {"电波", ""},
AccountReasonType: {"账号", ""},
SysReasonType: {"管理系统", ""},
}
// OriginTypes ...
OriginTypes = map[int64]*OriginType{
ReportRewardType: {"举报奖励", true},
PunishmentType: {"违规惩罚", true},
CancelRewardType: {"撤销奖励", true},
CancelPunishType: {"撤销惩罚", true},
ManualRecoveryType: {"自动恢复", true},
ManualChangeType: {"手动修改", false},
}
// Less6000Notice is.
Less6000Notice = &Notice{Title: "你的节操值已低于60", Message: "抱歉你的节操值已低于60社交类功能将不能正常使用更多加减明细请查看 #{节操记录}{\"https://account.bilibili.com/site/record?type=moral\"}", NoticeType: "2_1_5"}
// Less3000Notice is.
Less3000Notice = &Notice{Title: "你的节操值已低于30", Message: "抱歉你的节操值已低于30社交类功能将不能正常使用更多加减明细请查看 #{节操记录}{\"https://account.bilibili.com/site/record?type=moral\"}", NoticeType: "2_1_6"}
// Greater6000Notice is .
Greater6000Notice = &Notice{Title: "你的节操值已恢复至60以上", Message: "恭喜你的节操值已恢复至60以上所有功能将回复正常使用更多加减明细请查看 #{节操记录}{\"https://account.bilibili.com/site/record?type=moral\"}", NoticeType: "2_1_7"}
// PunishmentNotice is.
PunishmentNotice = &Notice{Title: "你被举报处理扣除了%s节操值", Message: "由于发布了违规内容,你被举报处理扣除了%s节操值具体原因请看 #{节操记录}{\"https://account.bilibili.com/site/record?type=moral\"}"}
// SysPunishmentNotice is.
SysPunishmentNotice = &Notice{Title: "你被举报处理扣除了%s节操值", Message: "由于发布了违规内容,你被系统处理扣除了%s节操值具体原因请看 #{节操记录}{\"https://account.bilibili.com/site/record?type=moral\"}"}
// RewardNotice is.
RewardNotice = &Notice{Title: "你举报的%s已被处理", Message: "您举报的%s已被管理员处理获得了%s节操值奖励具体详情请看 #{节操记录}{\"https://account.bilibili.com/site/record?type=moral\"}"}
)

View File

@@ -0,0 +1,93 @@
package model
import (
"encoding/json"
xtime "go-common/library/time"
)
// official state const.
const (
OfficialStateWait = iota
OfficialStatePass
OfficialStateNoPass
OfficialStateReWait
)
// official role const.
const (
OfficialRoleUnauth = iota
OfficialRoleUp
OfficialRoleIdentify
OfficialRoleBusiness
OfficialRoleGov
OfficialRoleMedia
OfficialRoleOther
)
// OfficialDoc official doc.
type OfficialDoc struct {
Mid int64 `json:"mid"`
Name string `json:"name"`
State int8 `json:"state"`
Role int8 `json:"role"`
Title string `json:"title"`
Desc string `json:"desc"`
Extra string `json:"-"`
RejectReason string `json:"reject_reason"` // 被拒绝理由
SubmitSource string `json:"submit_source"` // 提交来源
SubmitTime xtime.Time `json:"submit_time"` // 最后提交时间
OfficialExtra
}
// OfficialExtra official extra.
type OfficialExtra struct {
Realname int8 `json:"realname"`
Operator string `json:"operator"` // 经营人
Telephone string `json:"telephone"` // 电话号码
Email string `json:"email"` // 邮箱
Address string `json:"address"` // 地址
Company string `json:"company"` // 公司
CreditCode string `json:"credit_code"` // 社会信用代码
Organization string `json:"organization"` // 政府或组织名称
OrganizationType string `json:"organization_type"` // 组织或机构类型
BusinessLicense string `json:"business_license"` // 企业营业执照
BusinessScale string `json:"business_scale"` // 企业规模
BusinessLevel string `json:"business_level"` // 企业登记
BusinessAuth string `json:"business_auth"` // 企业授权函
Supplement string `json:"supplement"` // 其他补充材料
Professional string `json:"professional"` // 专业资质
Identification string `json:"identification"` // 身份证明
OfficialSite string `json:"official_site"` // 官网地址
RegisteredCapital string `json:"registered_capital"` // 注册资金
}
// ParseExtra parse extra.
func (oc *OfficialDoc) ParseExtra() {
oe := OfficialExtra{}
if len(oc.Extra) > 0 {
json.Unmarshal([]byte(oc.Extra), &oe)
}
oc.OfficialExtra = oe
}
// String is
func (oe OfficialExtra) String() string {
bs, _ := json.Marshal(oe)
if len(bs) == 0 {
bs = []byte("{}")
}
return string(bs)
}
// Validate is.
func (oc OfficialDoc) Validate() bool {
if oc.Mid <= 0 ||
oc.Name == "" ||
oc.Role <= 0 ||
oc.Title == "" {
return false
}
return true
}

View File

@@ -0,0 +1,7 @@
#! /bin/sh
# proto.sh https://github.com/google/protobuf/releases 下载release包解压后将include中的文件夹拖到/usr/local/include即可
gopath=$GOPATH/src
gogopath=$GOPATH/src/go-common/vendor/github.com/gogo/protobuf
protoc --gofast_out=. --proto_path=/usr/local/include:$gopath:$gogopath:. *.proto

View File

@@ -0,0 +1,29 @@
package model
// review state const.
const (
ReviewStateWait = iota
ReviewStatePass
ReviewStateNoPass
ReviewStateArchived
ReviewStateQueuing = 10
)
// review property const.
const (
ReviewProperty = iota
ReviewPropertyFace
ReviewPropertySign
ReviewPropertyName
)
// UserPropertyReview is.
type UserPropertyReview struct {
Mid int64
Old string
New string
State int8
Property int8
IsMonitor bool
Extra string
}

View File

@@ -0,0 +1,208 @@
package model
import (
"time"
)
// RealnameStatus is.
type RealnameStatus int8
const (
// RealnameStatusFalse is.
RealnameStatusFalse RealnameStatus = 0
// RealnameStatusTrue is.
RealnameStatusTrue RealnameStatus = 1
)
// RealnameApplyStatus is.
type RealnameApplyStatus int8
const (
// RealnameApplyStatusPending is.
RealnameApplyStatusPending RealnameApplyStatus = iota
// RealnameApplyStatusPass is.
RealnameApplyStatusPass
// RealnameApplyStatusBack is.
RealnameApplyStatusBack
// RealnameApplyStatusNone is.
RealnameApplyStatusNone
)
// IsPass return is apply passed
func (r RealnameApplyStatus) IsPass() bool {
switch r {
case RealnameApplyStatusPass:
return true
default:
return false
}
}
// RealnameChannel is
type RealnameChannel int8
// RealnameChannel enum
const (
RealnameChannelMain RealnameChannel = iota
RealnameChannelAlipay
)
// RealnameApplyStatusInfo is.
type RealnameApplyStatusInfo struct {
Status RealnameApplyStatus `json:"status"`
Remark string `json:"remark"`
Realname string `json:"realname"`
Card string `json:"card"`
}
// RealnameCacheInfo model in cache
type RealnameCacheInfo struct {
*RealnameInfo
RealCard string `json:"real_card"`
}
// RealnameBrief is.
type RealnameBrief struct {
Realname string `json:"realname"`
Card string `json:"card"`
CardType int `json:"card_type"`
Status RealnameStatus `json:"status"`
}
// RealnameInfo is.
type RealnameInfo struct {
ID int64 `json:"id"`
MID int64 `json:"mid"`
Channel RealnameChannel `json:"channel"`
Realname string `json:"realname"`
Country int `json:"country"`
CardType int `json:"card_type"`
Card string `json:"card"`
CardMD5 string `json:"card_md5"`
Status RealnameApplyStatus `json:"status"`
Reason string `json:"reason"`
CTime time.Time `json:"ctime"`
MTime time.Time `json:"mtime"`
}
// RealnameDetail is.
type RealnameDetail struct {
*RealnameBrief
Gender string `json:"gender"`
HandIMG string `json:"hand_img"`
}
// RealnameApply is.
type RealnameApply struct {
ID int64 `json:"id"`
MID int64 `json:"mid"`
Realname string `json:"realname"`
Country int16 `json:"country"`
CardType int8 `json:"card_type"`
CardNum string `json:"card_num"`
CardMD5 string `json:"card_md5"`
HandIMG int `json:"hand_img"`
FrontIMG int `json:"front_img"`
BackIMG int `json:"back_img"`
Status RealnameApplyStatus `json:"status"`
Operator string `json:"operator"`
OperatorID int64 `json:"operator_id"`
OperatorTime time.Time `json:"operator_time"`
Remark string `json:"remark"`
RemarkStatus int8 `json:"remark_status"`
CTime time.Time `json:"ctime"`
MTime time.Time `json:"mtime"`
}
// IsPass is.
func (r *RealnameApply) IsPass() bool {
switch r.Status {
case RealnameApplyStatusPass:
return true
default:
return false
}
}
// RealnameApplyImage is.
type RealnameApplyImage struct {
ID int64
IMGData string
CTime time.Time
MTime time.Time
}
// RealnameCapture is.
type RealnameCapture struct {
Code int
CodeCTime time.Time
Times []time.Time
}
// RealnameAlipayApply is
type RealnameAlipayApply struct {
ID int64 `json:"id"`
MID int64 `json:"mid"`
Realname string `json:"realname"`
Card string `json:"card"`
IMG string `json:"img"`
Status RealnameApplyStatus `json:"status"`
Reason string `json:"reason"`
Bizno string `json:"bizno"`
CTime time.Time `json:"ctime"`
MTime time.Time `json:"mtime"`
}
// IsPass is.
func (r *RealnameAlipayApply) IsPass() bool {
switch r.Status {
case RealnameApplyStatusPass:
return true
default:
return false
}
}
// RealnameAlipayInfo is
type RealnameAlipayInfo struct {
Bizno string
}
const (
// RealnameCountryChina is.
RealnameCountryChina = 0
// RealnameCardTypeIdentity is.
RealnameCardTypeIdentity = 0
)
// RealnameAdultType is.
type RealnameAdultType uint8
const (
// RealnameAdultTypeFalse is.
RealnameAdultTypeFalse RealnameAdultType = iota // 未成年
// RealnameAdultTypeTrue is.
RealnameAdultTypeTrue // 已成年
//RealnameAdultTypeUnknown is.
RealnameAdultTypeUnknown // 未知(未绑定身份证)
)
// http param
// ParamRealnameCheck is.
type ParamRealnameCheck struct {
MID int64 `form:"mid" validate:"required"`
CardType int8 `form:"card_type" default:"-1"`
CardCode string `form:"card_code" validate:"required"`
}
// ParamRealnameSyncImage is.
type ParamRealnameSyncImage struct {
Data string `form:"data" validate:"required"`
}
// ParamRealnameTelCaptureCheck is.
type ParamRealnameTelCaptureCheck struct {
MID int64 `form:"mid" validate:"required"`
Capture int `form:"capture" validate:"required"`
}

View File

@@ -0,0 +1,196 @@
package model
import (
"encoding/json"
"go-common/library/log"
"go-common/library/time"
)
// ArgMid arg mid.
type ArgMid struct {
Mid int64
RealIP string
}
// ArgMid2 arg mid2.
type ArgMid2 struct {
Mid int64 `form:"mid" validate:"min=1,required"` // 用户mid
RealIP string
}
// ArgMemberMid is.
type ArgMemberMid struct {
Mid int64 `json:"mid"`
RemoteIP string `json:"remoteIP"`
}
// ArgMemberMids are.
type ArgMemberMids struct {
Mids []int64 `json:"mids"`
RemoteIP string `json:"remoteIP"`
}
// ArgOfficialDoc arg official doc
type ArgOfficialDoc struct {
Mid int64 `json:"mid"`
Name string `json:"name"`
Role int8 `json:"role"`
Title string `json:"title"`
Desc string `json:"desc"`
Realname int8 `json:"realname"`
Operator string `json:"operator"`
Telephone string `json:"telephone"`
Email string `json:"email"`
Address string `json:"address"`
Company string `json:"company"`
CreditCode string `json:"credit_code"` // 社会信用代码
Organization string `json:"organization"` // 政府或组织名称
OrganizationType string `json:"organization_type"` // 组织或机构类型
BusinessLicense string `json:"business_license"` // 企业营业执照
BusinessScale string `json:"business_scale"` // 企业规模
BusinessLevel string `json:"business_level"` // 企业登记
BusinessAuth string `json:"business_auth"` // 企业授权函
Supplement string `json:"supplement"` // 其他补充材料
Professional string `json:"professional"` // 专业资质
Identification string `json:"identification"` // 身份证明
OfficialSite string `json:"official_site"` // 官网地址
RegisteredCapital string `json:"registered_capital"` // 注册资金
SubmitSource string `json:"submit_source"` // 提交来源
}
// Log define user login log.
type Log struct {
Mid int64 `json:"mid,omitempty"`
IP uint32 `json:"loginip"`
Location string `json:"location"`
LocationID int64 `json:"location_id,omitempty"`
Time time.Time `json:"timestamp,omitempty"`
Type int8 `json:"type,omitempty"`
}
// Msg is user login status msg.
type Msg struct {
Notify bool `json:"notify"`
Log *Log `json:"log"`
}
// ArgUpdateSex is.
type ArgUpdateSex struct {
Mid int64 `json:"mid"`
Sex int64 `json:"sex"`
RemoteIP string `json:"remoteIP"`
}
// ArgUpdateFace is.
type ArgUpdateFace struct {
Mid int64 `json:"mid"`
Face string `json:"face"`
RemoteIP string `json:"remoteIP"`
}
// ArgUpdateRank is.
type ArgUpdateRank struct {
Mid int64 `json:"mid"`
Rank int64 `json:"rank"`
RemoteIP string `json:"remoteIP"`
}
// ArgUpdateBirthday is.
type ArgUpdateBirthday struct {
Mid int64 `json:"mid"`
Birthday time.Time `json:"birthday"`
RemoteIP string `json:"remoteIP"`
}
// ArgUpdateUname arg for update uname.
type ArgUpdateUname struct {
Mid int64 `json:"mid"`
Name string `json:"name"`
RemoteIP string `json:"remoteIP"`
}
// ArgUpdateSign arg for udpate sign.
type ArgUpdateSign struct {
Mid int64 `json:"mid"`
Sign string `json:"sign"`
RemoteIP string `json:"remoteIP"`
}
// ArgAddExp addexp arg.
type ArgAddExp struct {
Mid int64 `json:"mid,omitempty" form:"mid" validate:"min=1,required"` // 用户mid
Count float64 `json:"count,omitempty" form:"count" validate:"required"` // 修改数量
Reason string `json:"reason,omitempty" form:"reason" validate:"required"` // 修改原因
Operate string `json:"operate,omitempty" form:"operate" validate:"required"` // 操作类型
IP string `json:"ip" form:"ip"`
}
// ExpStat user exp stat.
type ExpStat struct {
Login bool `json:"login"`
Watch bool `json:"watch_av"`
Coin int64 `json:"coins_av"`
Share bool `json:"share_av"`
}
// ArgRealnameApply realname apply
type ArgRealnameApply struct {
MID int64
CaptureCode int
Realname string
CardType int8
CardCode string
Country int16
HandIMGToken string
FrontIMGToken string
BackIMGToken string
}
// ArgRealnameAlipayConfirm is
type ArgRealnameAlipayConfirm struct {
MID int64
Pass bool
Reason string
}
// ArgRealnameAlipayApply is
type ArgRealnameAlipayApply struct {
MID int64
CaptureCode int
Realname string
CardCode string
IMGToken string
Bizno string
}
// ArgAddUserMonitor is
type ArgAddUserMonitor struct {
Mid int64
Operator string
Remark string
}
// ArgAddPropertyReview is.
type ArgAddPropertyReview struct {
Mid int64 `form:"mid" validate:"min=1,required"` // 用户mid
New string `form:"new"` // 新的值
State int8 `form:"state"` // 0 待审核1 通过2 驳回10 自动审核中
Property int8 `form:"property"` // 0 无意义1 头像2 签名3 昵称
Extra map[string]interface{} // 审核扩展字段 extra
}
// ExtraStr is.
func (arg *ArgAddPropertyReview) ExtraStr() string {
if arg.Extra == nil {
return "{}"
}
bs, err := json.Marshal(arg.Extra)
if err != nil {
log.Error("Failed to marshal extra: %+v, error: %+v", arg.Extra, err)
return "{}"
}
return string(bs)
}

View File

@@ -0,0 +1,31 @@
package model
// SearchResult is
type SearchResult struct {
Code int `json:"code"`
Data struct {
Debug string `json:"debug"`
Order string `json:"order"`
Page struct {
Num int64 `json:"num"`
Size int64 `json:"size"`
Total int64 `json:"total"`
} `json:"page"`
Result []struct {
Action string `json:"action"`
Build int64 `json:"build"`
Business int64 `json:"business"`
Buvid string `json:"buvid"`
Ctime string `json:"ctime"`
ExtraData string `json:"extra_data"`
IP string `json:"ip"`
Mid int64 `json:"mid"`
Oid int64 `json:"oid"`
Platform string `json:"platform"`
Type int64 `json:"type"`
} `json:"result"`
Sort string `json:"sort"`
} `json:"data"`
Message string `json:"message"`
TTL int64 `json:"ttl"`
}

View File

@@ -0,0 +1,16 @@
package model
const (
// NickUpdated 首次改昵称
NickUpdated = uint(1)
)
// HasAttr get attr.
func HasAttr(flag uint, bit uint) bool {
return flag&bit == bit
}
// SetAttr set attr.
func SetAttr(flag uint, bit uint) uint {
return flag | bit
}

View File

@@ -0,0 +1,18 @@
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/service/main/member/server/gorpc:all-srcs",
"//app/service/main/member/server/grpc:all-srcs",
"//app/service/main/member/server/http:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,59 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["rpc_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/service/main/member/conf:go_default_library",
"//app/service/main/member/model:go_default_library",
"//app/service/main/member/service:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"block.go",
"member.go",
"moral.go",
"property_review.go",
"realname.go",
"rpc.go",
],
importpath = "go-common/app/service/main/member/server/gorpc",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/member/conf:go_default_library",
"//app/service/main/member/model:go_default_library",
"//app/service/main/member/model/block:go_default_library",
"//app/service/main/member/service:go_default_library",
"//app/service/main/member/service/block:go_default_library",
"//library/net/rpc:go_default_library",
"//library/net/rpc/context:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,37 @@
package gorpc
import (
rpcmodel "go-common/app/service/main/member/model/block"
"go-common/library/net/rpc/context"
)
// BlockInfo is
func (r *RPC) BlockInfo(c context.Context, arg *rpcmodel.RPCArgInfo, res *rpcmodel.RPCResInfo) (err error) {
var (
blockInfos []*rpcmodel.BlockInfo
)
if blockInfos, err = r.block.Infos(c, []int64{arg.MID}); err != nil {
return
}
if len(blockInfos) < 1 {
res.Parse(r.block.DefaultUser(arg.MID))
}
res.Parse(blockInfos[0])
return
}
// BlockBatchInfo is
func (r *RPC) BlockBatchInfo(c context.Context, arg *rpcmodel.RPCArgBatchInfo, res *[]*rpcmodel.RPCResInfo) (err error) {
var (
blockInfos []*rpcmodel.BlockInfo
)
if blockInfos, err = r.block.Infos(c, arg.MIDs); err != nil {
return
}
for _, info := range blockInfos {
r := &rpcmodel.RPCResInfo{}
r.Parse(info)
*res = append(*res, r)
}
return
}

View File

@@ -0,0 +1,99 @@
package gorpc
import (
"go-common/app/service/main/member/model"
"go-common/library/net/rpc/context"
)
// Base get user base info.
func (r *RPC) Base(c context.Context, arg *model.ArgMemberMid, res *model.BaseInfo) (err error) {
var v *model.BaseInfo
if v, err = r.s.BaseInfo(c, arg.Mid); err == nil && res != nil {
*res = *v
}
return
}
// Bases get batch user base info.
func (r *RPC) Bases(c context.Context, arg *model.ArgMemberMids, res *map[int64]*model.BaseInfo) (err error) {
*res, err = r.s.BatchBaseInfo(c, arg.Mids)
return
}
// Member get member info.
func (r *RPC) Member(c context.Context, arg *model.ArgMemberMid, res *model.Member) (err error) {
var v *model.Member
if v, err = r.s.Member(c, arg.Mid); err == nil && res != nil {
*res = *v
}
return
}
// Members get batch member info.
func (r *RPC) Members(c context.Context, arg *model.ArgMemberMids, res *map[int64]*model.Member) (err error) {
*res, err = r.s.Members(c, arg.Mids)
return
}
// NickUpdated get nickUpdated.
func (r *RPC) NickUpdated(c context.Context, arg *model.ArgMemberMid, res *bool) (err error) {
*res, err = r.s.NickUpdated(c, arg.Mid)
return
}
// SetNickUpdated set nickUpdated.
func (r *RPC) SetNickUpdated(c context.Context, arg *model.ArgMemberMid, res *struct{}) (err error) {
err = r.s.SetNickUpdated(c, arg.Mid)
return
}
// SetOfficialDoc set official doc.
func (r *RPC) SetOfficialDoc(c context.Context, arg *model.ArgOfficialDoc, res *struct{}) (err error) {
err = r.s.SetOfficialDoc(c, arg)
return
}
// SetSex set sex.
func (r *RPC) SetSex(c context.Context, arg *model.ArgUpdateSex, res *struct{}) (err error) {
err = r.s.SetSex(c, arg.Mid, arg.Sex)
return
}
// SetName set name.
func (r *RPC) SetName(c context.Context, arg *model.ArgUpdateUname, res *struct{}) (err error) {
err = r.s.SetName(c, arg.Mid, arg.Name)
return
}
// SetFace set face.
func (r *RPC) SetFace(c context.Context, arg *model.ArgUpdateFace, res *struct{}) (err error) {
err = r.s.SetFace(c, arg.Mid, arg.Face)
return
}
// SetRank set rank.
func (r *RPC) SetRank(c context.Context, arg *model.ArgUpdateRank, res *struct{}) (err error) {
err = r.s.SetRank(c, arg.Mid, arg.Rank)
return
}
// SetBirthday set birthday.
func (r *RPC) SetBirthday(c context.Context, arg *model.ArgUpdateBirthday, res *struct{}) (err error) {
err = r.s.SetBirthday(c, arg.Mid, arg.Birthday)
return
}
// SetSign set sign.
func (r *RPC) SetSign(c context.Context, arg *model.ArgUpdateSign, res *struct{}) (err error) {
err = r.s.SetSign(c, arg.Mid, arg.Sign)
return
}
// OfficialDoc is.
func (r *RPC) OfficialDoc(c context.Context, arg *model.ArgMid, res *model.OfficialDoc) (err error) {
var od *model.OfficialDoc
if od, err = r.s.OfficialDoc(c, arg.Mid); err == nil && od != nil {
*res = *od
}
return
}

View File

@@ -0,0 +1,32 @@
package gorpc
import (
"go-common/app/service/main/member/model"
"go-common/library/net/rpc/context"
)
// Moral get user moral.
func (r *RPC) Moral(c context.Context, arg *model.ArgMemberMid, res *model.Moral) (err error) {
var v *model.Moral
if v, err = r.s.Moral(c, arg.Mid); err == nil && res != nil {
*res = *v
}
return
}
// MoralLog get user moral log.
func (r *RPC) MoralLog(c context.Context, arg *model.ArgMemberMid, res *[]*model.UserLog) (err error) {
*res, err = r.s.MoralLog(c, arg.Mid)
return
}
// AddMoral add moral.
func (r *RPC) AddMoral(c context.Context, arg *model.ArgUpdateMoral, res *struct{}) (err error) {
return r.s.UpdateMoral(c, arg)
}
// BatchAddMoral batch add moral.
func (r *RPC) BatchAddMoral(c context.Context, arg *model.ArgUpdateMorals, res *map[int64]int64) (err error) {
*res, err = r.s.UpdateMorals(c, arg)
return
}

View File

@@ -0,0 +1,26 @@
package gorpc
import (
"go-common/app/service/main/member/model"
"go-common/library/net/rpc/context"
)
// AddUserMonitor is add user into monitor
func (r *RPC) AddUserMonitor(ctx context.Context, arg *model.ArgAddUserMonitor, res *struct{}) error {
return r.s.AddUserMonitor(ctx, arg)
}
// IsInMonitor check user is in monitor
func (r *RPC) IsInMonitor(ctx context.Context, arg *model.ArgMid, res *bool) error {
isInMonitor, err := r.s.IsInMonitor(ctx, arg)
if err != nil {
return err
}
*res = isInMonitor
return nil
}
// AddPropertyReview add user property update review.
func (r *RPC) AddPropertyReview(ctx context.Context, arg *model.ArgAddPropertyReview, res *struct{}) error {
return r.s.AddPropertyReview(ctx, arg)
}

View File

@@ -0,0 +1,67 @@
package gorpc
import (
"go-common/app/service/main/member/model"
"go-common/library/net/rpc/context"
)
// RealnameStatus is
func (r *RPC) RealnameStatus(c context.Context, arg *model.ArgMemberMid, res *model.RealnameStatus) (err error) {
var v model.RealnameStatus
if v, err = r.s.RealnameStatus(c, arg.Mid); err == nil && res != nil {
*res = v
}
return
}
// RealnameApplyStatus is
func (r *RPC) RealnameApplyStatus(c context.Context, arg *model.ArgMemberMid, res *model.RealnameApplyStatusInfo) (err error) {
var v *model.RealnameApplyStatusInfo
if v, err = r.s.RealnameApplyStatus(c, arg.Mid); err == nil && v != nil {
*res = *v
}
return
}
// RealnameTelCapture is
func (r *RPC) RealnameTelCapture(c context.Context, arg *model.ArgMemberMid, res *struct{}) (err error) {
_, err = r.s.RealnameTelCapture(c, arg.Mid)
return
}
// RealnameApply is
func (r *RPC) RealnameApply(c context.Context, arg *model.ArgRealnameApply, res *struct{}) (err error) {
err = r.s.RealnameApply(c, arg.MID, arg.CaptureCode, arg.Realname, arg.CardType, arg.CardCode, arg.Country, arg.HandIMGToken, arg.FrontIMGToken, arg.BackIMGToken)
return
}
// RealnameAlipayApply commit a alipay realname apply
func (r *RPC) RealnameAlipayApply(c context.Context, arg *model.ArgRealnameAlipayApply, res *struct{}) (err error) {
err = r.s.RealnameAlipayApply(c, arg.MID, arg.CaptureCode, arg.Realname, arg.CardCode, arg.IMGToken, arg.Bizno)
return
}
// RealnameAlipayConfirm confirm a alipay realname apply
func (r *RPC) RealnameAlipayConfirm(c context.Context, arg *model.ArgRealnameAlipayConfirm, res *struct{}) (err error) {
err = r.s.RealnameAlipayConfirm(c, arg.MID, arg.Pass, arg.Reason)
return
}
// RealnameAlipayBizno get alipay realname certify bizno by mid
func (r *RPC) RealnameAlipayBizno(c context.Context, arg *model.ArgMemberMid, res *model.RealnameAlipayInfo) (err error) {
var bizno string
if bizno, err = r.s.RealnameAlipayBizno(c, arg.Mid); err == nil {
(*res).Bizno = bizno
}
return
}
// RealnameDetail detail about realname by mid
func (r *RPC) RealnameDetail(ctx context.Context, arg *model.ArgMemberMid, res *model.RealnameDetail) error {
detail, err := r.s.RealnameDetail(ctx, arg.Mid)
if err != nil {
return err
}
*res = *detail
return nil
}

View File

@@ -0,0 +1,75 @@
package gorpc
import (
"go-common/app/service/main/member/conf"
"go-common/app/service/main/member/model"
"go-common/app/service/main/member/service"
"go-common/app/service/main/member/service/block"
"go-common/library/net/rpc"
"go-common/library/net/rpc/context"
)
// RPC is.
type RPC struct {
s *service.Service
block *block.Service
}
// New new rpc server.
func New(c *conf.Config, s *service.Service) *rpc.Server {
r := &RPC{
s: s,
block: s.BlockImpl(),
}
svr := rpc.NewServer(c.RPCServer)
if err := svr.Register(r); err != nil {
panic(err)
}
return svr
}
// Ping check connection success.
func (r *RPC) Ping(c context.Context, arg *struct{}, res *struct{}) (err error) {
return
}
// --- exp --- //
// Exp get user exp.
func (r *RPC) Exp(c context.Context, arg *model.ArgMid2, res *model.LevelInfo) (err error) {
v, err := r.s.Exp(c, arg.Mid)
if err == nil && v != nil {
*res = *v
}
return
}
// Level get user exp.
func (r *RPC) Level(c context.Context, arg *model.ArgMid2, res *model.LevelInfo) (err error) {
v, err := r.s.Level(c, arg.Mid)
if err == nil && v != nil {
*res = *v
}
return
}
// UpdateExp user exp.
func (r *RPC) UpdateExp(c context.Context, arg *model.ArgAddExp, res *struct{}) (err error) {
err = r.s.UpdateExp(c, arg)
return
}
// Log get user exp log.
func (r *RPC) Log(c context.Context, arg *model.ArgMid2, res *[]*model.UserLog) (err error) {
*res, err = r.s.ExpLog(c, arg.Mid, arg.RealIP)
return
}
// Stat get user exp stat.
func (r *RPC) Stat(c context.Context, arg *model.ArgMid2, res *model.ExpStat) (err error) {
v, err := r.s.Stat(c, arg.Mid)
if err == nil && v != nil {
*res = *v
}
return
}

View File

@@ -0,0 +1,89 @@
package gorpc
import (
"flag"
"net/rpc"
"testing"
"time"
"go-common/app/service/main/member/conf"
"go-common/app/service/main/member/model"
"go-common/app/service/main/member/service"
. "github.com/smartystreets/goconvey/convey"
)
func init() {
flag.Set("conf", "../../cmd/member-service-example.toml")
startService()
}
const (
addr = "127.0.0.1:6689"
_testPing = "RPC.Ping"
)
var (
_noArg = &struct{}{}
svr *service.Service
client *rpc.Client
)
func startService() {
if err := conf.Init(); err != nil {
panic(err)
}
svr = service.New(conf.Conf)
New(conf.Conf, svr)
time.Sleep(time.Second * 3)
var err error
client, err = rpc.Dial("tcp", addr)
if err != nil {
panic(err)
}
}
func TestAccountRpc(t *testing.T) {
Convey("ping", t, func() {
err := client.Call(_testPing, &_noArg, &_noArg)
So(err, ShouldBeNil)
})
}
func TestExp(t *testing.T) {
Convey("update", t, func() {
err := client.Call("RPC.UpdateExp", &model.ArgAddExp{
Mid: 1,
Count: 2,
Reason: "test",
Operate: "other",
IP: "111",
}, &_noArg)
So(err, ShouldBeNil)
})
Convey("exp", t, func() {
res := new(model.LevelInfo)
err := client.Call("RPC.Exp", &model.ArgMid{Mid: 1}, res)
So(err, ShouldBeNil)
So(res.NextExp, ShouldNotEqual, 0)
})
}
func TestLevel(t *testing.T) {
Convey("level", t, func() {
res := new(model.LevelInfo)
err := client.Call("RPC.Level", &model.ArgMid{
Mid: 1,
}, res)
So(err, ShouldNotBeNil)
So(res.NextExp, ShouldNotEqual, 0)
})
}
func TestLog(t *testing.T) {
Convey("log", t, func() {
var res []*model.UserLog
err := client.Call("RPC.Log", &model.ArgMid{Mid: 1}, &res)
So(err, ShouldNotBeNil)
})
}

View File

@@ -0,0 +1,42 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"block.go",
"exp.go",
"member.go",
"moral.go",
"property_review.go",
"realname.go",
],
importpath = "go-common/app/service/main/member/server/grpc",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/member/api:go_default_library",
"//app/service/main/member/model:go_default_library",
"//app/service/main/member/service:go_default_library",
"//app/service/main/member/service/block: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"],
)

View File

@@ -0,0 +1,52 @@
package grpc
import (
"context"
"go-common/app/service/main/member/api"
)
// BlockInfo 查询封禁信息
func (s *MemberServer) BlockInfo(ctx context.Context, req *api.MemberMidReq) (*api.BlockInfoReply, error) {
res, err := s.blockSvr.Infos(ctx, []int64{req.Mid})
if err != nil {
return nil, err
}
if len(res) == 0 {
return api.FromBlockInfo(s.blockSvr.DefaultUser(req.Mid)), nil
}
blockInfoReply := api.FromBlockInfo(res[0])
return blockInfoReply, nil
}
// BlockBatchInfo 批量查询封禁信息
func (s *MemberServer) BlockBatchInfo(ctx context.Context, req *api.MemberMidsReq) (*api.BlockBatchInfoReply, error) {
res, err := s.blockSvr.Infos(ctx, req.Mids)
if err != nil {
return nil, err
}
blockInfos := make([]*api.BlockInfoReply, 0, len(res))
for i := range res {
blockInfos = append(blockInfos, api.FromBlockInfo(res[i]))
}
blockInfosReply := &api.BlockBatchInfoReply{
BlockInfos: blockInfos,
}
return blockInfosReply, nil
}
// BlockBatchDetail 批量查询封禁信息
func (s *MemberServer) BlockBatchDetail(ctx context.Context, req *api.MemberMidsReq) (reply *api.BlockBatchDetailReply, err error) {
res, err := s.blockSvr.UserDetails(ctx, req.Mids)
if err != nil {
return nil, err
}
userDetails := make(map[int64]*api.BlockDetailReply, len(res))
for mid := range res {
userDetails[mid] = api.FromBlockUserDetail(res[mid])
}
blockUserDetailsReply := &api.BlockBatchDetailReply{
BlockDetails: userDetails,
}
return blockUserDetailsReply, nil
}

View File

@@ -0,0 +1,97 @@
package grpc
import (
"context"
"go-common/app/service/main/member/api"
"go-common/app/service/main/member/model"
)
// Exp get member exp info
func (s *MemberServer) Exp(ctx context.Context, req *api.MidReq) (*api.LevelInfoReply, error) {
res, err := s.svr.Exp(ctx, req.Mid)
if err != nil {
return nil, err
}
var levelInfoReply = &api.LevelInfoReply{
Cur: res.Cur,
Min: res.Min,
NowExp: res.NowExp,
NextExp: res.NextExp,
}
return levelInfoReply, nil
}
// Level get member lebel info
func (s *MemberServer) Level(ctx context.Context, req *api.MidReq) (*api.LevelInfoReply, error) {
res, err := s.svr.Level(ctx, req.Mid)
if err != nil {
return nil, err
}
var levelInfoReply = &api.LevelInfoReply{
Cur: res.Cur,
Min: res.Min,
NowExp: res.NowExp,
NextExp: res.NextExp,
}
return levelInfoReply, nil
}
// UpdateExp update member exp value
func (s *MemberServer) UpdateExp(ctx context.Context, req *api.AddExpReq) (*api.EmptyStruct, error) {
err := s.svr.UpdateExp(ctx, &model.ArgAddExp{
Mid: req.Mid,
Count: req.Count,
Reason: req.Reason,
Operate: req.Operate,
IP: req.Ip,
})
if err != nil {
return nil, err
}
return &api.EmptyStruct{}, nil
}
// ExpLog get member exp logs
func (s *MemberServer) ExpLog(ctx context.Context, req *api.MidReq) (*api.UserLogsReply, error) {
res, err := s.svr.ExpLog(ctx, req.Mid, req.RealIP)
if err != nil {
return nil, err
}
userLogs := make([]*api.UserLogReply, 0, len(res))
for _, v := range res {
var userLog = &api.UserLogReply{
Mid: v.Mid,
Ip: v.IP,
Ts: v.TS,
LogId: v.LogID,
Content: v.Content,
}
userLogs = append(userLogs, userLog)
}
userLogsReply := &api.UserLogsReply{
UserLogs: userLogs,
}
return userLogsReply, nil
}
// ExpStat get exp status
func (s *MemberServer) ExpStat(ctx context.Context, req *api.MidReq) (*api.ExpStatReply, error) {
res, err := s.svr.Stat(ctx, req.Mid)
if err != nil {
return nil, err
}
expStatReply := &api.ExpStatReply{
Login: res.Login,
Watch: res.Watch,
Coin: res.Coin,
Share: res.Share,
}
return expStatReply, nil
}

View File

@@ -0,0 +1,190 @@
package grpc
import (
"context"
"go-common/app/service/main/member/api"
"go-common/app/service/main/member/service"
"go-common/app/service/main/member/service/block"
"go-common/library/net/rpc/warden"
)
// New Member warden rpc server
func New(cfg *warden.ServerConfig, s *service.Service) *warden.Server {
w := warden.NewServer(cfg)
api.RegisterMemberServer(w.Server(), &MemberServer{svr: s, blockSvr: s.BlockImpl()})
ws, err := w.Start()
if err != nil {
panic(err)
}
return ws
}
// MemberServer define member Service
type MemberServer struct {
svr *service.Service
blockSvr *block.Service
}
var _ api.MemberServer = &MemberServer{}
// Base get member base info
func (s *MemberServer) Base(ctx context.Context, req *api.MemberMidReq) (*api.BaseInfoReply, error) {
res, err := s.svr.BaseInfo(ctx, req.Mid)
if err != nil {
return nil, err
}
return api.FromBaseInfo(res), nil
}
// Bases batch get members base info
func (s *MemberServer) Bases(ctx context.Context, req *api.MemberMidsReq) (*api.BaseInfosReply, error) {
res, err := s.svr.BatchBaseInfo(ctx, req.Mids)
if err != nil {
return nil, err
}
baseInfos := make(map[int64]*api.BaseInfoReply, len(res))
baseInfosReply := &api.BaseInfosReply{
BaseInfos: baseInfos,
}
for k, v := range res {
baseInfos[k] = api.FromBaseInfo(v)
}
return baseInfosReply, nil
}
// Member get member full information
func (s *MemberServer) Member(ctx context.Context, req *api.MemberMidReq) (*api.MemberInfoReply, error) {
res, err := s.svr.Member(ctx, req.Mid)
if err != nil {
return nil, err
}
memberInfoReply := api.FromMember(res)
return memberInfoReply, nil
}
// Members Batch get members info
func (s *MemberServer) Members(ctx context.Context, req *api.MemberMidsReq) (*api.MemberInfosReply, error) {
res, err := s.svr.Members(ctx, req.Mids)
if err != nil {
return nil, err
}
memberInfos := make(map[int64]*api.MemberInfoReply, len(res))
for k, v := range res {
memberInfoReply := api.FromMember(v)
memberInfos[k] = memberInfoReply
}
memberInfosReply := &api.MemberInfosReply{
MemberInfos: memberInfos,
}
return memberInfosReply, nil
}
// NickUpdated Whether the member's nickname has been updated
func (s *MemberServer) NickUpdated(ctx context.Context, req *api.MemberMidReq) (*api.NickUpdatedReply, error) {
res, err := s.svr.NickUpdated(ctx, req.Mid)
if err != nil {
return nil, err
}
nickUpdatedReply := &api.NickUpdatedReply{
NickUpdated: res,
}
return nickUpdatedReply, nil
}
// SetNickUpdated Mark nickname as updated
func (s *MemberServer) SetNickUpdated(ctx context.Context, req *api.MemberMidReq) (*api.EmptyStruct, error) {
err := s.svr.SetNickUpdated(ctx, req.Mid)
if err != nil {
return nil, err
}
emptyStruct := &api.EmptyStruct{}
return emptyStruct, nil
}
// SetOfficialDoc Set offical document
func (s *MemberServer) SetOfficialDoc(ctx context.Context, req *api.OfficialDocReq) (*api.EmptyStruct, error) {
err := s.svr.SetOfficialDoc(ctx, api.ToArgOfficialDoc(req))
if err != nil {
return nil, err
}
emptyStruct := &api.EmptyStruct{}
return emptyStruct, nil
}
// SetSex Set member's sex
func (s *MemberServer) SetSex(ctx context.Context, req *api.UpdateSexReq) (*api.EmptyStruct, error) {
err := s.svr.SetSex(ctx, req.Mid, req.Sex)
if err != nil {
return nil, err
}
emptyStruct := &api.EmptyStruct{}
return emptyStruct, nil
}
// SetName Set member's name
func (s *MemberServer) SetName(ctx context.Context, req *api.UpdateUnameReq) (*api.EmptyStruct, error) {
err := s.svr.SetName(ctx, req.Mid, req.Name)
if err != nil {
return nil, err
}
emptyStruct := &api.EmptyStruct{}
return emptyStruct, nil
}
// SetFace Set member's face
func (s *MemberServer) SetFace(ctx context.Context, req *api.UpdateFaceReq) (*api.EmptyStruct, error) {
err := s.svr.SetFace(ctx, req.Mid, req.Face)
if err != nil {
return nil, err
}
emptyStruct := &api.EmptyStruct{}
return emptyStruct, nil
}
// SetRank Set member's rank
func (s *MemberServer) SetRank(ctx context.Context, req *api.UpdateRankReq) (*api.EmptyStruct, error) {
err := s.svr.SetRank(ctx, req.Mid, req.Rank)
if err != nil {
return nil, err
}
emptyStruct := &api.EmptyStruct{}
return emptyStruct, nil
}
// SetBirthday Set member's birthday
func (s *MemberServer) SetBirthday(ctx context.Context, req *api.UpdateBirthdayReq) (*api.EmptyStruct, error) {
err := s.svr.SetBirthday(ctx, req.Mid, req.Birthday)
if err != nil {
return nil, err
}
emptyStruct := &api.EmptyStruct{}
return emptyStruct, nil
}
// SetSign Set member's sign
func (s *MemberServer) SetSign(ctx context.Context, req *api.UpdateSignReq) (*api.EmptyStruct, error) {
err := s.svr.SetSign(ctx, req.Mid, req.Sign)
if err != nil {
return nil, err
}
emptyStruct := &api.EmptyStruct{}
return emptyStruct, nil
}
// OfficialDoc Get member's offical doc
func (s *MemberServer) OfficialDoc(ctx context.Context, req *api.MidReq) (*api.OfficialDocInfoReply, error) {
res, err := s.svr.OfficialDoc(ctx, req.Mid)
if err != nil {
return nil, err
}
officialDocInfoReply := api.FromOfficialDoc(res)
return officialDocInfoReply, nil
}

View File

@@ -0,0 +1,70 @@
package grpc
import (
"context"
"go-common/app/service/main/member/api"
)
// Moral Get member moral info
func (s *MemberServer) Moral(ctx context.Context, req *api.MemberMidReq) (*api.MoralReply, error) {
res, err := s.svr.Moral(ctx, req.Mid)
if err != nil {
return nil, err
}
moralReply := &api.MoralReply{
Mid: res.Mid,
Moral: res.Moral,
Added: res.Added,
Deducted: res.Deducted,
LastRecoverDate: res.LastRecoverDate,
}
return moralReply, nil
}
// MoralLog Get member moral logs
func (s *MemberServer) MoralLog(ctx context.Context, req *api.MemberMidReq) (*api.UserLogsReply, error) {
res, err := s.svr.MoralLog(ctx, req.Mid)
if err != nil {
return nil, err
}
userLogs := make([]*api.UserLogReply, 0, len(res))
for _, v := range res {
userLog := &api.UserLogReply{
Mid: v.Mid,
Ip: v.IP,
Ts: v.TS,
LogId: v.LogID,
Content: v.Content,
}
userLogs = append(userLogs, userLog)
}
userLogsReply := &api.UserLogsReply{
UserLogs: userLogs,
}
return userLogsReply, nil
}
// AddMoral Add member's moral value
func (s *MemberServer) AddMoral(ctx context.Context, req *api.UpdateMoralReq) (*api.EmptyStruct, error) {
err := s.svr.UpdateMoral(ctx, api.ToArgUpdateMoral(req))
if err != nil {
return nil, err
}
return &api.EmptyStruct{}, nil
}
// BatchAddMoral Batch add member's moral value
func (s *MemberServer) BatchAddMoral(ctx context.Context, req *api.UpdateMoralsReq) (*api.UpdateMoralsReply, error) {
res, err := s.svr.UpdateMorals(ctx, api.ToArgUpdateMorals(req))
if err != nil {
return nil, err
}
updateMoralsReply := &api.UpdateMoralsReply{
AfterMorals: res,
}
return updateMoralsReply, nil
}

View File

@@ -0,0 +1,39 @@
package grpc
import (
"context"
"go-common/app/service/main/member/api"
"go-common/app/service/main/member/model"
)
// AddUserMonitor add user monitor
func (s *MemberServer) AddUserMonitor(ctx context.Context, req *api.AddUserMonitorReq) (*api.EmptyStruct, error) {
argAddUserMonitor := &model.ArgAddUserMonitor{
Mid: req.Mid,
Operator: req.Operator,
Remark: req.Remark,
}
err := s.svr.AddUserMonitor(ctx, argAddUserMonitor)
if err != nil {
return nil, err
}
emptyStruct := &api.EmptyStruct{}
return emptyStruct, nil
}
// IsInMonitor check whether the member is in monitored status
func (s *MemberServer) IsInMonitor(ctx context.Context, req *api.MidReq) (*api.IsInMonitorReply, error) {
res, err := s.svr.IsInMonitor(ctx, &model.ArgMid{
Mid: req.Mid,
RealIP: req.RealIP,
})
if err != nil {
return nil, err
}
isInMonitorReply := &api.IsInMonitorReply{
IsInMonitor: res,
}
return isInMonitorReply, nil
}

View File

@@ -0,0 +1,84 @@
package grpc
import (
"context"
"go-common/app/service/main/member/api"
)
// RealnameStatus get the member realname status
func (s *MemberServer) RealnameStatus(ctx context.Context, req *api.MemberMidReq) (*api.RealnameStatusReply, error) {
res, err := s.svr.RealnameStatus(ctx, req.Mid)
if err != nil {
return nil, err
}
var realnameStatusReply = &api.RealnameStatusReply{
RealnameStatus: int8(res),
}
return realnameStatusReply, nil
}
// RealnameApplyStatus get member realname apply status
func (s *MemberServer) RealnameApplyStatus(ctx context.Context, req *api.MemberMidReq) (*api.RealnameApplyInfoReply, error) {
res, err := s.svr.RealnameApplyStatus(ctx, req.Mid)
if err != nil {
return nil, err
}
var realnameStatusReply = &api.RealnameApplyInfoReply{
Status: int8(res.Status),
Remark: res.Remark,
}
return realnameStatusReply, nil
}
// RealnameTelCapture mobilePhone realname certification
func (s *MemberServer) RealnameTelCapture(ctx context.Context, req *api.MemberMidReq) (*api.EmptyStruct, error) {
_, err := s.svr.RealnameTelCapture(ctx, req.Mid)
if err != nil {
return nil, err
}
return &api.EmptyStruct{}, nil
}
// RealnameApply apply for realname certification
func (s *MemberServer) RealnameApply(ctx context.Context, req *api.ArgRealnameApplyReq) (*api.EmptyStruct, error) {
err := s.svr.RealnameApply(ctx, req.Mid, int(req.CaptureCode), req.Realname, req.CardType, req.CardCode, req.Country, req.HandIMGToken, req.FrontIMGToken, req.BackIMGToken)
if err != nil {
return nil, err
}
return &api.EmptyStruct{}, nil
}
// RealnameDetail detail about realname by mid
func (s *MemberServer) RealnameDetail(ctx context.Context, req *api.MemberMidReq) (*api.RealnameDetailReply, error) {
res, err := s.svr.RealnameDetail(ctx, req.Mid)
if err != nil {
return nil, err
}
var realnameDetail = &api.RealnameDetailReply{
Realname: res.Realname,
Card: res.Card,
CardType: int8(res.CardType),
Status: int8(res.Status),
Gender: res.Gender,
HandImg: res.HandIMG,
}
return realnameDetail, nil
}
// RealnameStrippedInfo is
func (s *MemberServer) RealnameStrippedInfo(ctx context.Context, req *api.MemberMidReq) (*api.RealnameStrippedInfoReply, error) {
return s.svr.RealnameStrippedInfo(ctx, req.Mid)
}
// MidByRealnameCard is
func (s *MemberServer) MidByRealnameCard(ctx context.Context, req *api.MidByRealnameCardsReq) (*api.MidByRealnameCardReply, error) {
return s.svr.MidByRealnameCard(ctx, req)
}

View 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 = [
"base.go",
"exp.go",
"http.go",
"moral.go",
"realname.go",
],
importpath = "go-common/app/service/main/member/server/http",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/member/api:go_default_library",
"//app/service/main/member/conf:go_default_library",
"//app/service/main/member/model:go_default_library",
"//app/service/main/member/server/http/block:go_default_library",
"//app/service/main/member/service:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/http/blademaster/middleware/verify:go_default_library",
"//library/net/metadata: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",
"//app/service/main/member/server/http/block:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,381 @@
package http
import (
"encoding/json"
"strconv"
"strings"
"go-common/app/service/main/member/model"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/metadata"
"go-common/library/time"
)
func base(ctx *bm.Context) {
var (
err error
mid int64
// baseInfo *model.BaseInfo
params = ctx.Request.Form
midStr = params.Get("mid")
// res = c.Result()
)
if mid, err = strconv.ParseInt(midStr, 10, 64); err != nil {
// res["code"] = ecode.RequestErr
ctx.JSON(nil, ecode.RequestErr)
return
}
// if baseInfo, err = memberSvc.BaseInfo(c, mid); err != nil {
// log.Error("relationSvc.BaseInfo(%d) error(%v)", mid, err)
// res["code"] = err
// return
// }
// res["data"] = baseInfo
ctx.JSON(memberSvc.BaseInfo(ctx, mid))
}
func member(ctx *bm.Context) {
params := ctx.Request.Form
// res := c.Result()
midStr := params.Get("mid")
mid, err := strconv.ParseInt(midStr, 10, 64)
if err != nil || mid <= 0 {
// res["code"] = ecode.RequestErr
ctx.JSON(nil, ecode.RequestErr)
return
}
// mb, err := memberSvc.Member(c, mid)
// if err != nil {
// log.Error("Failed to memberSvc.Member(%d): %+v", mid, err)
// res["code"] = err
// return
// }
// res["data"] = mb
ctx.JSON(memberSvc.Member(ctx, mid))
}
func batchBase(ctx *bm.Context) {
var (
err error
mid int64
mids []int64
// binfo map[int64]*model.BaseInfo
params = ctx.Request.Form
midsStr = params.Get("mids")
// res = c.Result()
)
for _, str := range strings.Split(midsStr, ",") {
if mid, err = strconv.ParseInt(str, 10, 64); err != nil {
// res["code"] = ecode.RequestErr
ctx.JSON(nil, ecode.RequestErr)
return
}
mids = append(mids, mid)
}
// if binfo, err = memberSvc.BatchBaseInfo(c, mids); err != nil {
// log.Error("memberSvc.BaseInfo(%d) error(%v)", mid, err)
// res["code"] = err
// return
// }
// res["data"] = binfo
ctx.JSON(memberSvc.BatchBaseInfo(ctx, mids))
}
func setSign(ctx *bm.Context) {
var (
err error
mid int64
params = ctx.Request.Form
midStr = params.Get("mid")
usersign = params.Get("user_sign")
// res = c.Result()
)
if mid, err = strconv.ParseInt(midStr, 10, 64); err != nil {
// res["code"] = ecode.RequestErr
ctx.JSON(nil, ecode.RequestErr)
return
}
// if usersign == "" {
// res["code"] = ecode.RequestErr
// return
// }
// 获取用户状态逻辑 status判断
// if err := memberSvc.SetSign(c, mid, usersign); err != nil {
// log.Error("memberSvc.SetSign(%d) error(%v)", mid, err)
// res["code"] = ecode.ServerErr
// return
// }
ctx.JSON(nil, memberSvc.SetSign(ctx, mid, usersign))
}
func setName(ctx *bm.Context) {
var (
err error
mid int64
params = ctx.Request.Form
midStr = params.Get("mid")
name = params.Get("name")
// res = c.Result()
)
if mid, err = strconv.ParseInt(midStr, 10, 64); err != nil {
// res["code"] = ecode.RequestErr
ctx.JSON(nil, ecode.RequestErr)
return
}
if name == "" {
// res["code"] = ecode.RequestErr
ctx.JSON(nil, ecode.RequestErr)
return
}
// if err := memberSvc.SetName(c, mid, name); err != nil {
// log.Error("memberSvc.SetUname(%d) error(%v)", mid, err)
// res["code"] = ecode.ServerErr
// return
// }
ctx.JSON(nil, memberSvc.SetName(ctx, mid, name))
}
func setRank(ctx *bm.Context) {
var (
err error
mid int64
rank int64
params = ctx.Request.Form
midStr = params.Get("mid")
rankStr = params.Get("rank")
// res = c.Result()
)
if mid, err = strconv.ParseInt(midStr, 10, 64); err != nil {
// res["code"] = ecode.RequestErr
ctx.JSON(nil, ecode.RequestErr)
return
}
if rank, err = strconv.ParseInt(rankStr, 10, 64); err != nil {
// res["code"] = ecode.RequestErr
ctx.JSON(nil, ecode.RequestErr)
return
}
// if err := memberSvc.SetRank(c, mid, rank); err != nil {
// log.Error("relationSvc.SetRank(%d) error(%v)", mid, err)
// res["code"] = ecode.ServerErr
// return
// }
ctx.JSON(nil, memberSvc.SetRank(ctx, mid, rank))
}
// setSex set sex.
func setSex(ctx *bm.Context) {
var (
err error
mid int64
sex int64
params = ctx.Request.Form
midStr = params.Get("mid")
sexStr = params.Get("sex")
// res = c.Result()
)
if mid, err = strconv.ParseInt(midStr, 10, 64); err != nil {
// res["code"] = ecode.RequestErr
ctx.JSON(nil, ecode.RequestErr)
return
}
if sex, err = strconv.ParseInt(sexStr, 10, 8); err != nil {
// res["code"] = ecode.RequestErr
ctx.JSON(nil, ecode.RequestErr)
return
}
// if err = memberSvc.SetSex(c, mid, sex); err != nil {
// log.Error("memberSvc.SetSex(%d, %d) error(%v)", mid, sex, err)
// res["code"] = ecode.ServerErr
// }
ctx.JSON(nil, memberSvc.SetSex(ctx, mid, sex))
}
// setBirthday set Birthday.
func setBirthday(ctx *bm.Context) {
var (
err error
mid int64
birthdayTs int64
birthday time.Time
params = ctx.Request.Form
midStr = params.Get("mid")
birthdayStr = params.Get("birthday")
// res = c.Result()
)
if mid, err = strconv.ParseInt(midStr, 10, 64); err != nil {
// res["code"] = ecode.RequestErr
ctx.JSON(nil, ecode.RequestErr)
return
}
if birthdayTs, err = strconv.ParseInt(birthdayStr, 10, 32); err != nil {
// res["code"] = ecode.RequestErr
ctx.JSON(nil, ecode.RequestErr)
return
}
birthday = time.Time(birthdayTs)
// if err = memberSvc.SetBirthday(c, mid, birthday); err != nil {
// log.Error("memberSvc.SetBirthday(%d, %d) error(%v)", mid, birthday, err)
// res["code"] = ecode.ServerErr
// }
ctx.JSON(nil, memberSvc.SetBirthday(ctx, mid, birthday))
}
// setFace set face.
func setFace(ctx *bm.Context) {
var (
err error
mid int64
params = ctx.Request.Form
midStr = params.Get("mid")
face = params.Get("face")
// res = c.Result()
)
if mid, err = strconv.ParseInt(midStr, 10, 64); err != nil {
// res["code"] = ecode.RequestErr
ctx.JSON(nil, ecode.RequestErr)
return
}
// if err = memberSvc.SetFace(c, mid, face); err != nil {
// log.Error("memberSvc.SetFace(%d, %d) error(%v)", mid, face, err)
// res["code"] = ecode.ServerErr
// }
ctx.JSON(nil, memberSvc.SetFace(ctx, mid, face))
}
func setBase(ctx *bm.Context) {
var (
err error
mid int64
rank int64
sex int64
birthday int64
params = ctx.Request.Form
midStr = params.Get("mid")
rankStr = params.Get("rank")
face = params.Get("face")
birthdayStr = params.Get("birthday")
name = params.Get("name")
sign = params.Get("user_sign")
sexStr = params.Get("sex")
// res = c.Result()
)
if mid, err = strconv.ParseInt(midStr, 10, 64); err != nil {
// res["code"] = ecode.RequestErr
ctx.JSON(nil, ecode.RequestErr)
return
}
if len(rankStr) != 0 {
if rank, err = strconv.ParseInt(rankStr, 10, 64); err != nil {
// res["code"] = ecode.RequestErr
ctx.JSON(nil, ecode.RequestErr)
return
}
}
if len(sexStr) != 0 {
if sex, err = strconv.ParseInt(sexStr, 10, 64); err != nil {
// res["code"] = ecode.RequestErr
ctx.JSON(nil, ecode.RequestErr)
return
}
}
if len(birthdayStr) != 0 {
if birthday, err = strconv.ParseInt(birthdayStr, 10, 64); err != nil {
// res["code"] = ecode.RequestErr
ctx.JSON(nil, ecode.RequestErr)
return
}
}
b := &model.BaseInfo{Mid: mid, Face: face, Sex: sex, Birthday: time.Time(birthday), Name: name, Sign: sign, Rank: rank}
// if err := memberSvc.SetBase(c, b); err != nil {
// log.Error("memberSvc.SetBase(%d) error(%v)", mid, err)
// res["code"] = ecode.ServerErr
// return
// }
ctx.JSON(nil, memberSvc.SetBase(ctx, b))
}
func updateMorals(ctx *bm.Context) {
var (
err error
// morals map[int64]int64
)
// res := c.Result()
arg := &model.ArgUpdateMorals{}
if err = ctx.Bind(arg); err != nil {
return
}
arg.IP = metadata.String(ctx, metadata.RemoteIP)
// morals, err = memberSvc.UpdateMorals(c, arg)
// if err != nil {
// res["code"] = err
// return
// }
// res["data"] = morals
ctx.JSON(memberSvc.UpdateMorals(ctx, arg))
}
func updateMoral(ctx *bm.Context) {
arg := &model.ArgUpdateMoral{}
if err := ctx.Bind(arg); err != nil {
return
}
arg.IP = metadata.String(ctx, metadata.RemoteIP)
ctx.JSON(nil, memberSvc.UpdateMoral(ctx, arg))
}
func undoMoral(ctx *bm.Context) {
arg := &model.ArgUndo{}
if err := ctx.Bind(arg); err != nil {
return
}
ctx.JSON(nil, memberSvc.UndoMoral(ctx, arg.LogID, arg.Remark, arg.Operator))
}
// cacheDel delete user cache.
func cacheDel(ctx *bm.Context) {
var (
mid int64
action string
ak string
sd string
err error
)
// res := c.Result()
query := ctx.Request.Form
midStr := query.Get("mid")
if mid, err = strconv.ParseInt(midStr, 10, 64); err != nil {
// res["code"] = ecode.RequestErr
ctx.JSON(nil, ecode.RequestErr)
return
}
action = query.Get("modifiedAttr")
ak = query.Get("access_token")
sd = query.Get("session")
memberSvc.DelCache(ctx, mid, action, ak, sd)
// res["code"] = ecode.OK
ctx.JSON(nil, nil)
}
// addPropertyReview add user property update review.
func addPropertyReview(ctx *bm.Context) {
arg := &model.ArgAddPropertyReview{}
if err := ctx.Bind(arg); err != nil {
return
}
form := ctx.Request.Form
extra := form.Get("extra")
if extra != "" {
extraData := map[string]interface{}{}
if err := json.Unmarshal([]byte(extra), &extraData); err != nil {
log.Error("Failed to Unmarshal extra: %+v, error: %+v", extra, err)
ctx.JSON(nil, ecode.RequestErr)
return
}
arg.Extra = extraData
}
ctx.JSON(nil, memberSvc.AddPropertyReview(ctx, arg))
}

View File

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

View File

@@ -0,0 +1,97 @@
package block
import (
"time"
model "go-common/app/service/main/member/model/block"
"go-common/library/ecode"
bm "go-common/library/net/http/blademaster"
)
func info(c *bm.Context) {
var (
err error
v = &model.ParamInfo{}
)
if err = bind(c, v); err != nil {
return
}
var infos []*model.BlockInfo
if infos, err = svc.Infos(c, []int64{v.MID}); err != nil {
c.JSON(nil, err)
return
}
if len(infos) != 1 {
c.JSON(nil, ecode.ServerErr)
return
}
c.JSON(infos[0], nil)
}
func batchInfo(c *bm.Context) {
var (
err error
v = &model.ParamBatchInfo{}
)
if err = bind(c, v); err != nil {
return
}
c.JSON(svc.Infos(c, v.MIDs))
}
func batchDetail(c *bm.Context) {
var (
err error
v = &model.ParamBatchDetail{}
)
if err = bind(c, v); err != nil {
return
}
c.JSON(svc.UserDetails(c, v.MIDs))
}
func block(c *bm.Context) {
var (
err error
v = &model.ParamBlock{}
)
if err = bind(c, v); err != nil {
return
}
duration := time.Duration(v.Duration) * time.Second
c.JSON(nil, svc.Block(c, []int64{v.MID}, v.Source, v.Area, v.Action, v.StartTime, duration, v.Operator, v.Reason, v.Comment, v.Notify))
}
func batchBlock(c *bm.Context) {
var (
err error
v = &model.ParamBatchBlock{}
)
if err = bind(c, v); err != nil {
return
}
duration := time.Duration(v.Duration) * time.Second
c.JSON(nil, svc.Block(c, v.MIDs, v.Source, v.Area, v.Action, v.StartTime, duration, v.Operator, v.Reason, v.Comment, v.Notify))
}
func remove(c *bm.Context) {
var (
err error
v = &model.ParamRemove{}
)
if err = bind(c, v); err != nil {
return
}
c.JSON(nil, svc.Remove(c, []int64{v.MID}, v.Source, model.BlockAreaNone, v.Operator, v.Reason, v.Comment, v.Notify))
}
func batchRemove(c *bm.Context) {
var (
err error
v = &model.ParamBatchRemove{}
)
if err = bind(c, v); err != nil {
return
}
c.JSON(nil, svc.Remove(c, v.MIDs, v.Source, model.BlockAreaNone, v.Operator, v.Reason, v.Comment, v.Notify))
}

View File

@@ -0,0 +1,44 @@
package block
import (
model "go-common/app/service/main/member/model/block"
service "go-common/app/service/main/member/service/block"
"go-common/library/ecode"
bm "go-common/library/net/http/blademaster"
v "go-common/library/net/http/blademaster/middleware/verify"
"github.com/pkg/errors"
)
var (
svc *service.Service
)
// Setup is
func Setup(blockSvc *service.Service, engine *bm.Engine, v *v.Verify) {
svc = blockSvc
blkGroup := engine.Group("/x/internal/block", v.Verify)
blkGroup.POST("/block", block)
blkGroup.POST("/remove", remove)
blkGroup.GET("/info", info)
blkGroupBatch := engine.Group("/x/internal/block/batch", v.Verify)
blkGroupBatch.POST("/block", batchBlock)
blkGroupBatch.POST("/remove", batchRemove)
blkGroupBatch.POST("/info", batchInfo)
blkGroupBatch.GET("/detail", batchDetail)
}
func bind(c *bm.Context, v model.ParamValidator) (err error) {
if err = c.Bind(v); err != nil {
err = errors.WithStack(err)
return
}
if !v.Validate() {
err = ecode.RequestErr
c.JSON(nil, ecode.RequestErr)
return
}
return
}

View File

@@ -0,0 +1,66 @@
package http
import (
"go-common/app/service/main/member/model"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/metadata"
)
func exp(ctx *bm.Context) {
arg := new(model.ArgMid2)
if err := ctx.Bind(arg); err != nil {
return
}
ctx.JSON(memberSvc.Exp(ctx, arg.Mid))
}
func level(ctx *bm.Context) {
arg := new(model.ArgMid2)
if err := ctx.Bind(arg); err != nil {
return
}
ctx.JSON(memberSvc.Level(ctx, arg.Mid))
}
func official(ctx *bm.Context) {
arg := new(model.ArgMid2)
if err := ctx.Bind(arg); err != nil {
return
}
ctx.JSON(memberSvc.Official(ctx, arg.Mid))
}
func explog(ctx *bm.Context) {
arg := new(model.ArgMid2)
if err := ctx.Bind(arg); err != nil {
return
}
arg.RealIP = metadata.String(ctx, metadata.RemoteIP)
ctx.JSON(memberSvc.ExpLog(ctx, arg.Mid, arg.RealIP))
}
func updateExp(ctx *bm.Context) {
arg := new(model.ArgAddExp)
if err := ctx.Bind(arg); err != nil {
return
}
arg.IP = metadata.String(ctx, metadata.RemoteIP)
ctx.JSON(nil, memberSvc.UpdateExp(ctx, arg))
}
func setExp(ctx *bm.Context) {
arg := new(model.ArgAddExp)
if err := ctx.Bind(arg); err != nil {
return
}
arg.IP = metadata.String(ctx, metadata.RemoteIP)
ctx.JSON(nil, memberSvc.SetExp(ctx, arg))
}
func stat(ctx *bm.Context) {
arg := new(model.ArgMid2)
if err := ctx.Bind(arg); err != nil {
return
}
ctx.JSON(memberSvc.Stat(ctx, arg.Mid))
}

View File

@@ -0,0 +1,83 @@
package http
import (
"go-common/app/service/main/member/conf"
"go-common/app/service/main/member/server/http/block"
"go-common/app/service/main/member/service"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
v "go-common/library/net/http/blademaster/middleware/verify"
"net/http"
)
var (
memberSvc *service.Service
verify *v.Verify
)
// Init init http sever instance.
func Init(c *conf.Config, s *service.Service) {
verify = v.New(c.Verify)
memberSvc = s
engine := bm.DefaultServer(c.BM)
setup(engine)
block.Setup(memberSvc.BlockImpl(), engine, verify)
if err := engine.Start(); err != nil {
log.Error("http.Serve inner error(%v)", err)
panic(err)
}
}
func setup(e *bm.Engine) {
e.Ping(ping)
e.Register(register)
mb := e.Group("/x/internal/member", verify.Verify)
mb.POST("/sign/update", setSign)
mb.POST("/name/update", setName)
mb.POST("/rank/update", setRank)
mb.POST("/birthday/update", setBirthday)
mb.POST("/sex/update", setSex)
mb.POST("/face/update", setFace)
mb.POST("/base/update", setBase)
mb.POST("/morals/update", updateMorals)
mb.POST("/moral/update", updateMoral)
mb.POST("/moral/undo", undoMoral)
mb.GET("/moral", moral)
mb.GET("/moral/log", moralLog)
mb.GET("", member)
mb.GET("/base", base)
mb.GET("/batchBase", batchBase)
mb.GET("/exp", exp)
mb.GET("/level", level)
mb.GET("/official", official)
mb.POST("/exp/set", setExp)
mb.POST("/exp/update", updateExp)
mb.GET("/exp/log", explog)
mb.GET("/exp/stat", stat)
mb.GET("/cache/del", cacheDel)
mb.POST("/property/review/add", addPropertyReview)
// realname
mb.GET("/realname/status", realnameStatus)
mb.GET("/realname/info", realnameInfo)
mb.POST("/realname/tel/capture", realnameTelCapture)
mb.GET("/realname/tel/capture/check", realnameCheckTelCapture)
mb.GET("/realname/apply/status", realnameApplyStatus)
mb.POST("/realname/apply", realnameApply)
mb.GET("/realname/adult", realnameAdult)
mb.GET("/realname/check", realnameCheck)
mb.GET("/realname/stripped/info", realnameStrippedInfo)
mb.GET("/realname/mid/by/card", realnameMidByCard)
}
// ping check server ok.
func ping(c *bm.Context) {
if err := memberSvc.Ping(c); err != nil {
log.Error("service ping error(%+v)", err)
c.AbortWithStatus(http.StatusServiceUnavailable)
}
}
func register(c *bm.Context) {
c.JSON(nil, nil)
}

Some files were not shown because too many files have changed in this diff Show More