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,37 @@
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/interface/main/app-wall/cmd:all-srcs",
"//app/interface/main/app-wall/conf:all-srcs",
"//app/interface/main/app-wall/dao/account:all-srcs",
"//app/interface/main/app-wall/dao/callback:all-srcs",
"//app/interface/main/app-wall/dao/live:all-srcs",
"//app/interface/main/app-wall/dao/mobile:all-srcs",
"//app/interface/main/app-wall/dao/offer:all-srcs",
"//app/interface/main/app-wall/dao/padding:all-srcs",
"//app/interface/main/app-wall/dao/seq:all-srcs",
"//app/interface/main/app-wall/dao/shopping:all-srcs",
"//app/interface/main/app-wall/dao/telecom:all-srcs",
"//app/interface/main/app-wall/dao/unicom:all-srcs",
"//app/interface/main/app-wall/dao/wall:all-srcs",
"//app/interface/main/app-wall/http:all-srcs",
"//app/interface/main/app-wall/model:all-srcs",
"//app/interface/main/app-wall/service/mobile:all-srcs",
"//app/interface/main/app-wall/service/offer:all-srcs",
"//app/interface/main/app-wall/service/operator:all-srcs",
"//app/interface/main/app-wall/service/ping:all-srcs",
"//app/interface/main/app-wall/service/telecom:all-srcs",
"//app/interface/main/app-wall/service/unicom:all-srcs",
"//app/interface/main/app-wall/service/wall:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,667 @@
#### App wall 移动端商务对接接口
### Version 2.6.6
> 1.修复联通问题数据
### Version 2.6.5
> 1.修复日志拉取日期判断
### Version 2.6.4
> 1.修复日志拉取日期判断
### Version 2.6.3
> 1.不等ipv4 return
### Version 2.6.2
> 1.多机房
### Version 2.6.1
> 1.多机房
### Version 2.5.19
> 1.福利社日志修改
### Version 2.5.18
1.去掉net/ip调用
### Version 2.5.17
> 1.福利社日志修改
### Version 2.5.16
> 1.福利社用户日志区分
### Version 2.5.15
> 1.福利社绑定状态
### Version 2.5.14
> 1.大会员requestNo int64
### Version 2.5.13
> 1.ip方法更换
### Version 2.5.12
> 1.修复福利社日志问题
### Version 2.5.11
> 1.build
### Version 2.5.10
> 1.福利社用户日志
### Version 2.5.9
> 1.csrf false
### Version 2.5.8
> 1.使用grpc auth
### Version 2.5.7
> 1.去除MC KEY找不到的错误
### Version 2.5.6
> 1.福利社绑定用户
> 2.缓存修改
### Version 2.5.5
> 1.福利社日志查询
### Version 2.5.4
> 1.M站IP查询用户伪码解密
### Version 2.5.3
> 1.M站接口增加IP判断
### Version 2.5.2
> 1.M站接口改用联通加密
### Version 2.5.1
> 1.M站接口开新路由
### Version 2.5.0
> 1. update infoc sdk
##### Version 2.4.3
> 1.广点通
##### Version 2.4.2
> 1.增加流量领取间隔时间
> 2.增加只能流量卡领取限制
> 3.增加积分限制
##### Version 2.4.1
> 1.http active
##### Version 2.4.0
> 1.广点通
##### Version 2.3.9
> 1.seq server
##### Version 2.3.8
>1.修复 url
##### Version 2.3.7
>1.fix bug
##### Version 2.3.6
>2.慢查询
##### Version 2.3.5
>2.gdt重构
##### Version 2.3.4
>2.gdt response返回ret 0
##### Version 2.3.3
>2.gdt 新增 advertiser_id
##### Version 2.3.2
> 1.部分接口bm.CORS
##### Version 2.3.1
> 1.bm cors
##### Version 2.3.0
> 1.http层换成BM
##### Version 2.2.9
> 1.流量卡不能订购流量包
##### Version 2.2.8
> 1.联通流量包强行删除缓存
##### Version 2.2.7
> 1.联通IP异步同步下沉
##### Version 2.2.6
> 1.异步消费逻辑放到job
##### Version 2.2.5
> 1.修复积分异常添加问题
##### Version 2.2.4
> 1.增加礼包领取日志
##### Version 2.2.3
> 1.修复联通礼包BUG
> 2.修复联通订购关系问题
##### Version 2.2.2
> 1.修复联通订购关系BUG
> 2.fix头条重复激活
##### Version 2.2.1
> 1.fix头条重复激活
##### Version 2.2.0
> 1.联通礼包
##### Version 2.1.9
> 1.头条fix
##### Version 2.1.6
> 1.广点通广告投放点击上报
##### Version 2.1.5
> 1.今日头条广告投放点击上报
##### Version 2.1.4
> 1.drop statsd
##### Version 2.1.3
> 1.移动新订单默认流量100%
##### Version 2.1.2
> 1.增加运营商数据回掉结果日志
##### Version 2.1.1
> 1.增加红点
##### Version 2.1.0
> 1.联通订购数据查询修改
##### Version 2.0.9
> 1.移动流量包增加产品类型字段
##### Version 2.0.8
> 1.联通IP同步改为异步更新
##### Version 2.0.7
> 1.联通流量包订购关系接口下沉到服务端
> 2.去除手机号
##### Version 2.0.6
> 1.更新缓存逻辑修改
> 2.删除无用的日志
##### Version 2.0.5
> 1.运营商用户数据缓存修改
##### Version 2.0.4
> 1.缓存增加回去
##### Version 2.0.3
> 1.直播礼包切回原地址
##### Version 2.0.2
> 1.直播接口切换
##### Version 2.0.1
> 1.IOS客户端需要线上测试暂时屏蔽缓存逻辑
##### Version 2.0.0
> 1.修复电信文档与实际请求不符合问题
##### Version 1.9.9
> 1.判断电信流量包是否是有效的
##### Version 1.9.8
> 1.errgroup error return
> 2.验证电信接口状态是否正确
##### Version 1.9.7
> 1.电信接口增加errgroup减少接口超时时间
##### Version 1.9.6
> 1.删除多余的 ecode.NoLogin
> 2.电信端口改成string转int
> 3.增加错误日志
##### Version 1.9.5
> 1.电信增加提示
> 2.电信增加短信模板
> 3.增加流水号和手机号缓存
##### Version 1.9.4
> 1.修复error没有return问题
##### Version 1.9.3
> 1.电信接口返回error修改
##### Version 1.9.2
> 1.电信用户状态接口改成Get请求
> 2.电信用户许可新增状态
> 3.电信支付接口返回订单流水号
##### Version 1.9.1
> 1.电信接口修改
##### Version 1.9.0
> 1.监控图名字修改
##### Version 1.8.9
> 1.监控图名字修改
##### Version 1.8.8
> 1.电信数据同步地址修改
##### Version 1.8.7
> 1.增加缓存监控
##### Version 1.8.6
> 1.联通、电信、移动用户增加缓存
> 2.新增电信流量包服务
##### Version 1.8.5
> 1.联通直播礼包接口日志修改
##### Version 1.8.4
> 1.联通直播礼包接口
##### Version 1.8.3
> 1.联通相关接口infoc数据上报
##### Version 1.8.2
> 1.联通直播礼包实时查询数据库
##### Version 1.8.1
> 1.移动用户IP判断
##### Version 1.8.0
> 1.联通用户IP判断
##### Version 1.7.9
> 1.移动逻辑修改
##### Version 1.7.8
> 1.移动接口数据同步合并成一个接口
##### Version 1.7.7
> 1.中国移动流量包
##### Version 1.7.6
> 1.实时查库去除异步读数据库
> 2.打印联通流量包状态日志
##### Version 1.7.5
> 1.ip限制放入配置文件
##### Version 1.7.4
> 1.修复BUG
##### Version 1.7.3
> 1.修复message="0"的bug
##### Version 1.7.2
> 1.合并大仓库
##### Version 1.7.1
> 1.dotinapp渠道
##### Version 1.7.0
> 1.添加IP白名单
##### Version 1.6.9
> 1.联通用户状态处理
##### Version 1.6.8
> 1.联通用户状态处理
##### Version 1.6.7
> 1.添加IP白名单
##### Version 1.6.6
> 1.unicomtype在其他接口不返回
##### Version 1.6.5
> 1.修改显示订购状态
##### Version 1.6.4
> 1.修改显示订购状态
##### Version 1.6.3
> 1.增加状态接口
##### Version 1.6.2
> 1.增加状态接口
##### Version 1.6.1
> 1.增加预开户数据同步接口
> 2.更新vendor
##### Version 1.6.0
> 1.增加数据同步日志
##### Version 1.5.9
> 1.修复bug
##### Version 1.5.8
> 1.增加错误吗提示
##### Version 1.5.7
> 1.增加H5查看用户状态修改
##### Version 1.5.6
> 1.增加H5查看用户状态修改
##### Version 1.5.5
> 1.更新vendor
##### Version 1.5.4
> 1.增加H5查看用户状态改成GET
##### Version 1.5.3
> 1.增加同步接口IP白名单
##### Version 1.5.2
> 1.增加H5查看用户状态
##### Version 1.5.1
> 1.升级vendor
##### Version 1.5.0
> 1.接入新的配置中心
##### Version 1.4.9
> 1.接入新的配置中心
##### Version 1.4.8
> 1.实时查询订购关系逻辑修改
##### Version 1.4.7
> 1.MonitorPing
##### Version 1.4.6
> 1.本地TW
##### Version 1.4.5
> 1.vendor升级
##### Version 1.4.4
> 1.IP同步SQL逻辑修改
##### Version 1.4.3
> 1.增加数据同步白名单IP
##### Version 1.4.2
> 1.增加message提示
##### Version 1.4.1
> 1.增加message提示
##### Version 1.4.0
> 1.增加错误message
##### Version 1.3.9
> 1.增加ecode
##### Version 1.3.8
> 1.判断是否是联通IP
> 2.增加特权礼包接口
##### Version 1.3.7
> 1.接入平滑发布
##### Version 1.3.6
> 1.增加spid对应卡的类型
##### Version 1.3.5
> 1.vendor升级
##### Version 1.3.4
> 1.增加错误码返回
##### Version 1.3.3
> 1.增加日志信息
##### Version 1.3.2
> 1.ordertype int改成string
##### Version 1.3.1
> 1.增加返回字段spid
##### Version 1.3.0
> 1.升级go-business
##### Version 1.2.9
> 1.修改项目上报
##### Version 1.2.8
> 1.修改联通数据同步缓存
##### Version 1.2.7
> 1.vendor升级
> 2.增加过期判断
> 3.增加返回字段
> 4.增加用户状态接口
##### Version 1.2.6
> 1.ci更新服务镜像
##### Version 1.2.5
> 1.配置文件支持本地读取
##### Version 1.2.4
> 1.删除Inner
> 2.升级vendor
##### Version 1.2.3
> 1.删除无用的接口
##### Version 1.2.2
> 1.vendor升级
##### Version 1.2.1
> 1.vendor升级
##### Version 1.2.0
> 1.vendor升级
##### Version 1.1.9
> 1.Success int改成string
##### Version 1.1.8
> 1.shike接口改成post请求
> 2.vendor升级
##### Version 1.1.7
> 1.增加联通IP
##### Version 1.1.6
> 1.联通IP同步接口Ipbegion改成ipbegin
> 2.增加联通IP
##### Version 1.1.5
> 1.联通IP同步接口开始ip和结束ip字段改成string
##### Version 1.1.4
> 1.联通IP同步接口
##### Version 1.1.3
> 1.联通流量接口请求改成post json
##### Version 1.1.2
> 1.usermob解密
##### Version 1.1.1
> 1.推广渠道编号可以为空
##### Version 1.1.0
> 1.联通流量包接口对接
##### Version 1.0.1
> 1.修复BUG
> 2.联通信息同步接口
##### Version 1.0.0
> 1.初始化项目

View File

@@ -0,0 +1,11 @@
# Owner
peiyifei
liweijia
# Author
sunyu
yujia
# Reviewer
peiyifei
haoguanwei

View File

@@ -0,0 +1,18 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- liweijia
- peiyifei
- sunyu
- yujia
labels:
- interface
- interface/main/app-wall
- main
options:
no_parent_owners: true
reviewers:
- haoguanwei
- peiyifei
- sunyu
- yujia

View File

@@ -0,0 +1,13 @@
#### app-wall
##### 项目简介
> 1.提供移动端与商务对接的各类接口
##### 编译环境
> 请只用golang v1.8.x以上版本编译执行。
##### 依赖包
> 1.公共包go-common
##### 特别说明
> 1.model目录可能会被其他项目引用请谨慎请改并通知各方。

View File

@@ -0,0 +1,44 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_binary(
name = "cmd",
embed = [":go_default_library"],
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = ["main.go"],
data = ["app-wall-test.toml"],
importpath = "go-common/app/interface/main/app-wall/cmd",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//app/interface/main/app-wall/http:go_default_library",
"//library/ecode/tip: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,233 @@
# This is a TOML document. Boom.
version = "1.0.0"
user = "nobody"
pid = "/tmp/app-wall.pid"
dir = "./"
family = "app-wall"
checkFile = "/data/www/wall.html"
tick = "1m"
[unicomuserInfoc2]
taskID = "000242"
proto = "tcp"
addr = ""
chanSize = 10240
[unicomipInfoc2]
taskID = "000243"
proto = "tcp"
addr = ""
chanSize = 10240
[unicomPackInfoc]
taskID = "000918"
proto = "tcp"
addr = ""
chanSize = 10240
[host]
apiCo = "http://uat-api.bilibili.co"
dotin = "http://svr.dotinapp.com"
live = "http://inner.live.bilibili.co"
apiLive = "http://api.live.bilibili.co"
telecom = "https://open.fg.21cn.com"
unicom = "http://123.125.99.7:9001"
unicomFlow = "http://open.10010.com"
broadband = "http://114.255.201.238:8092"
sms = "http://uat-api.bilibili.co"
mall = "http://uat-mall.bilibili.co"
telecomReturnURL = "http://www.bilibili.com/blackboard/preview/activity-telecom2017.html?biliStatus=1"
telecomCancelPayURL = "http://www.bilibili.com/blackboard/preview/activity-telecom2017.html"
[log]
Dir = "/data/log/app-wall/"
[log.syslog]
project = "app-wall"
proto = "udp"
addr = "172.18.19.22:9999"
chansize = 10240
[statsd]
project = "app-wall"
addr = "172.18.20.15:8200"
chanSize = 1024
[app]
key = "e7482d29be4a95b8"
secret = "9e803791cdef756e75faee68e12b7442"
[httpClient]
key = "e7482d29be4a95b8"
secret = "9e803791cdef756e75faee68e12b7442"
dial = "500ms"
timeout = "2s"
keepAlive = "60s"
timer = 10
[httpClient.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[httpTelecom]
key = "e7482d29be4a95b8"
secret = "9e803791cdef756e75faee68e12b7442"
dial = "500ms"
timeout = "50s"
keepAlive = "60s"
timer = 10
[httpTelecom.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[HTTPBroadband]
key = "e7482d29be4a95b8"
secret = "9e803791cdef756e75faee68e12b7442"
dial = "500ms"
timeout = "4s"
keepAlive = "60s"
timer = 10
[HTTPBroadband.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[HTTPUnicom]
key = "e7482d29be4a95b8"
secret = "9e803791cdef756e75faee68e12b7442"
dial = "500ms"
timeout = "4s"
keepAlive = "60s"
timer = 10
[HTTPUnicom.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[httpActive]
key = "e7482d29be4a95b8"
secret = "9e803791cdef756e75faee68e12b7442"
dial = "500ms"
timeout = "2s"
keepAlive = "60s"
timer = 10
[httpActive.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[bm]
[bm.outer]
addr = "0.0.0.0:6251"
timeout = "5s"
readTimeout = "5s"
writeTimeout = "5s"
[mysql]
[mysql.show]
addr = "172.16.33.205:3308"
dsn = "test:test@tcp(172.16.33.205:3308)/bilibili_show?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 5
idle = 2
idleTimeout ="4h"
queryTimeout = "1s"
execTimeout = "1s"
tranTimeout = "1s"
[mysql.show.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[seq]
businessID =1
token ="Y1zHA2esXfd2T6bc1VRHkFWryD01Aswi"
[seqRPC]
pullInterval = "10s"
timeout = "200ms"
[iplimit]
mobileIPFile = "/data/conf/operate/mobileip.txt"
[iplimit.addrs]
unicom = ["127.0.0.1", "111.206.133.54", "114.255.201.224", "111.206.133.34", "111.8.57.60", "111.197.4.233"]
telecom = ["127.0.0.1"]
[redis]
[redis.recommend]
name = "app-show/recommend"
proto = "tcp"
addr = "172.16.33.54:6380"
active = 20
idle = 10
dialTimeout = "50ms"
readTimeout = "100ms"
writeTimeout = "100ms"
idleTimeout = "80s"
expire = "2h"
[memcache]
[memcache.operator]
name = "app-show/archive"
proto = "tcp"
addr = "172.16.33.54:11213"
active = 50
idle = 10
dialTimeout = "50ms"
readTimeout = "100ms"
writeTimeout = "100ms"
idleTimeout = "80s"
expire = "1s"
[reddot]
starttime="2018-02-26 00:00:00"
endtime="2028-02-26 00:00:00"
[unicom]
keyExpired = "1s"
flowWait = "60s"
[telecom]
keyExpired = "5m"
payKeyExpired = "5m"
smsTemplate = "app-wall-01"
smsMsgTemplate = "app-wall-04"
smsFlowTemplate = "app-wall-03"
smsOrderTemplateOK = "app-wall-02"
flowPercentage = 10
[telecom.area]
area=["CN50","CN44","CN31","CN43","CN14","CN13","CN45","CN35","CN37","CN46","CN64","CN23","CN62","CN63","CN15","CN21","CN41","CN36","CN12","CN42","CN53"]
# 重庆 CN50
# 广东 CN44
# 上海 CN31
# 湖南 CN43
# 山西 CN14
# 河北 CN13
# 广西 CN45
# 福建 CN35
# 山东 CN37
# 海南 CN46
# 宁夏 CN64
# 黑龙江 CN23
# 甘肃 CN62
# 青海 CN63
# 内蒙 CN15
# 辽宁 CN21
# 河南 CN41
# 江西 CN36
# 天津 CN12
# 湖北 CN42
# 云南 CN53

View File

@@ -0,0 +1,53 @@
package main
import (
"flag"
"os"
"os/signal"
"syscall"
"go-common/app/interface/main/app-wall/conf"
"go-common/app/interface/main/app-wall/http"
ecode "go-common/library/ecode/tip"
"go-common/library/log"
"go-common/library/net/trace"
"go-common/library/queue/databus/report"
)
func main() {
flag.Parse()
if err := conf.Init(); err != nil {
log.Error("conf.Init() error(%v)", err)
panic(err)
}
// init log
log.Init(conf.Conf.Log)
defer log.Close()
log.Info("app-wall start")
// init trace
trace.Init(conf.Conf.Tracer)
defer trace.Close()
// ecode init
ecode.Init(conf.Conf.Ecode)
// report init
report.InitUser(conf.Conf.Report)
// service init
http.Init(conf.Conf)
// init pprof conf.Conf.Perf
// init signal
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
for {
s := <-c
log.Info("app-wall get a signal %s", s.String())
switch s {
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
log.Info("app-wall exit")
return
case syscall.SIGHUP:
// TODO reload
default:
return
}
}
}

View File

@@ -0,0 +1,44 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["conf.go"],
importpath = "go-common/app/interface/main/app-wall/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/elastic:go_default_library",
"//library/database/sql:go_default_library",
"//library/ecode/tip:go_default_library",
"//library/log:go_default_library",
"//library/log/infoc:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/rpc: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,206 @@
package conf
import (
"errors"
"flag"
"go-common/library/cache/memcache"
"go-common/library/cache/redis"
"go-common/library/conf"
"go-common/library/database/elastic"
"go-common/library/database/sql"
ecode "go-common/library/ecode/tip"
"go-common/library/log"
"go-common/library/log/infoc"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/rpc"
"go-common/library/net/trace"
"go-common/library/queue/databus"
xtime "go-common/library/time"
"github.com/BurntSushi/toml"
)
var (
confPath string
Conf = &Config{}
client *conf.Client
)
type Config struct {
// Env
Env string
// db
MySQL *MySQL
// show XLog
Log *log.Config
// tracer
Tracer *trace.Config
// tick time
Tick xtime.Duration
// httpClinet
HTTPClient *bm.ClientConfig
// HTTPTelecom
HTTPTelecom *bm.ClientConfig
// HTTPBroadband
HTTPBroadband *bm.ClientConfig
// HTTPUnicom
HTTPUnicom *bm.ClientConfig
// HTTPUnicom
HTTPActive *bm.ClientConfig
// bm http
BM *HTTPServers
// rpc account
AccountRPC *rpc.ClientConfig
// seq
SeqRPC *rpc.ClientConfig
// host
Host *Host
// ecode
Ecode *ecode.Config
// Report
Report *databus.Config
// iplimit
IPLimit *IPLimit
// infoc2
UnicomUserInfoc2 *infoc.Config
UnicomIpInfoc2 *infoc.Config
UnicomPackInfoc *infoc.Config
// Seq
Seq *Seq
// Telecom
Telecom *Telecom
// Redis
Redis *Redis
// mc
Memcache *Memcache
// reddot
Reddot *Reddot
// unicom
Unicom *Unicom
ES *elastic.Config
// databus
UnicomDatabus *databus.Config
}
type Host struct {
APICo string
Dotin string
Live string
APILive string
Telecom string
Unicom string
UnicomFlow string
Broadband string
Sms string
Mall string
TelecomReturnURL string
TelecomCancelPayURL string
}
type HTTPServers struct {
Outer *bm.ServerConfig
}
type Seq struct {
BusinessID int64
Token string
}
// App bilibili intranet authorization.
type App struct {
Key string
Secret string
}
type MySQL struct {
Show *sql.Config
}
type IPLimit struct {
MobileIPFile string
Addrs map[string][]string
}
type Reddot struct {
StartTime string
EndTime string
}
type Unicom struct {
KeyExpired xtime.Duration
FlowWait xtime.Duration
}
type Telecom struct {
KeyExpired xtime.Duration
PayKeyExpired xtime.Duration
SMSTemplate string
SMSMsgTemplate string
SMSFlowTemplate string
SMSOrderTemplateOK string
FlowPercentage int
Area map[string][]string
}
type Redis struct {
Recommend *struct {
*redis.Config
Expire xtime.Duration
}
}
type Memcache struct {
Operator *struct {
*memcache.Config
Expire xtime.Duration
}
}
func init() {
flag.StringVar(&confPath, "conf", "", "default config path")
}
// Init init config.
func Init() (err error) {
if confPath != "" {
_, err = toml.DecodeFile(confPath, &Conf)
return
}
err = remote()
return
}
func remote() (err error) {
if client, err = conf.New(); err != nil {
return
}
if err = load(); err != nil {
return
}
go func() {
for range client.Event() {
log.Info("config reload")
if load() != nil {
log.Error("config reload error (%v)", err)
}
}
}()
return
}
func load() (err error) {
var (
s string
ok bool
tmpConf *Config
)
if s, ok = client.Toml2(); !ok {
return errors.New("load config center error")
}
if _, err = toml.Decode(s, &tmpConf); err != nil {
return errors.New("could not decode config")
}
*Conf = *tmpConf
return
}

View File

@@ -0,0 +1,50 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["account_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//app/service/main/account/model:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["account.go"],
importpath = "go-common/app/interface/main/app-wall/dao/account",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//app/service/main/account/model:go_default_library",
"//app/service/main/account/rpc/client:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,75 @@
package account
import (
"context"
"net/url"
"strconv"
"go-common/app/interface/main/app-wall/conf"
account "go-common/app/service/main/account/model"
accrpc "go-common/app/service/main/account/rpc/client"
"go-common/library/ecode"
"go-common/library/log"
httpx "go-common/library/net/http/blademaster"
)
const (
_addVIPURL = "/x/internal/big/useBatchInfo"
)
// Dao account dao
type Dao struct {
client *httpx.Client
// account rpc
accRPC *accrpc.Service3
// url
addVIPURL string
}
// New account dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
client: httpx.NewClient(c.HTTPClient),
// account rpc
accRPC: accrpc.New3(c.AccountRPC),
// url
addVIPURL: c.Host.APICo + _addVIPURL,
}
return
}
// AddVIP add user vip
func (d *Dao) AddVIP(c context.Context, mid, orderNo int64, batchID int, remark string) (msg string, err error) {
params := url.Values{}
params.Set("orderNo", strconv.FormatInt(orderNo, 10))
params.Set("mid", strconv.FormatInt(mid, 10))
params.Set("remark", remark)
params.Set("batchId", strconv.Itoa(batchID))
var res struct {
Code int `json:"code"`
Msg string `json:"message"`
}
if err = d.client.Post(c, d.addVIPURL, "", params, &res); err != nil {
log.Error("account add vip url(%v) error(%v)", d.addVIPURL+"?"+params.Encode(), err)
return
}
msg = res.Msg
if res.Code != 0 {
err = ecode.Int(res.Code)
log.Error("account add vip url(%v) res code(%d)", d.addVIPURL+"?"+params.Encode(), res.Code)
return
}
return
}
// Info user info
func (d *Dao) Info(ctx context.Context, mid int64) (res *account.Info, err error) {
arg := &account.ArgMid{
Mid: mid,
}
if res, err = d.accRPC.Info3(ctx, arg); err != nil {
log.Error("d.accRPC.Info3(%v) error(%v)", arg, err)
return
}
return
}

View File

@@ -0,0 +1,60 @@
package account
import (
"context"
"flag"
"os"
"testing"
"time"
"go-common/app/interface/main/app-wall/conf"
account "go-common/app/service/main/account/model"
. "github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func ctx() context.Context {
return context.Background()
}
func init() {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.app-svr.app-wall")
flag.Set("conf_token", "yvxLjLpTFMlbBbc9yWqysKLMigRHaaiJ")
flag.Set("tree_id", "2283")
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)
}
d = New(conf.Conf)
time.Sleep(time.Second)
}
func TestAddVIP(t *testing.T) {
Convey("unicom AddVIP", t, func() {
_, err := d.AddVIP(ctx(), 1, 1, 1, "")
err = nil
So(err, ShouldBeNil)
})
}
func TestInfo(t *testing.T) {
Convey("unicom Info", t, func() {
res, err := d.Info(ctx(), 1)
err = nil
res = &account.Info{}
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1,49 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["callback_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["callback.go"],
importpath = "go-common/app/interface/main/app-wall/dao/callback",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//app/interface/main/app-wall/model:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster: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,131 @@
package callback
import (
"context"
"crypto/md5"
"encoding/base64"
"encoding/hex"
"fmt"
"net/url"
"strings"
"time"
"go-common/app/interface/main/app-wall/conf"
"go-common/app/interface/main/app-wall/model"
"go-common/library/ecode"
"go-common/library/log"
httpx "go-common/library/net/http/blademaster"
"github.com/pkg/errors"
)
const (
_iis = "/iis?clkid=%s"
)
type Dao struct {
client *httpx.Client
iisURL string
}
func New(c *conf.Config) (d *Dao) {
d = &Dao{
client: httpx.NewClient(conf.Conf.HTTPActive),
iisURL: c.Host.Dotin + _iis,
}
return
}
func (d *Dao) GdtCallback(c context.Context, appID, appType, aderID string, idfa, cb string, now time.Time) (err error) {
key, ok := model.ChannelGdt[aderID]
if !ok {
return
}
encrypt := []byte(key.Encrypt)
signKey := key.Sign
uri := fmt.Sprintf("http://t.gdt.qq.com/conv/app/%s/conv?", appID)
// sign v
queryS := fmt.Sprintf("muid=%s&conv_time=%d&click_id=%s", idfa, now.Unix(), cb)
page := signKey + "&GET&" + url.QueryEscape(uri+queryS)
bs := md5.Sum([]byte(page))
sign := hex.EncodeToString(bs[:])
queryS = queryS + "&sign=" + sign
queryBs := []byte(queryS)
i := 0
bss := []byte{}
for _, b := range queryBs {
bss = append(bss, b^encrypt[i])
i = i + 1
i = i % len(encrypt)
}
baseS := base64.StdEncoding.EncodeToString(bss)
baseS = strings.Replace(baseS, "\n", "", -1)
// finish uri
furi := uri + "v=" + url.QueryEscape(baseS) + fmt.Sprintf("&conv_type=MOBILEAPP_ACTIVITE&app_type=%s&advertiser_id=%s", appType, aderID)
var res struct {
Ret int `json:"ret"`
Msg string `json:"msg"`
}
for i := 0; i < 5; i++ {
if err = d.client.Get(c, furi, "", nil, &res); err == nil {
break
}
}
if err != nil {
return
}
if !ecode.Int(res.Ret).Equal(ecode.OK) {
err = errors.Wrapf(ecode.Int(res.Ret), furi)
if res.Ret == -1 {
log.Error("%+v", err)
err = nil
}
return
}
log.Info("callback gdt furi(%s) idfa(%s) cb(%s) success ret(%d) msg(%s)", furi, idfa, cb, res.Ret, res.Msg)
return
}
func (d *Dao) ShikeCallback(c context.Context, idfa, cb string, now time.Time) (err error) {
var res struct {
Success string `json:"success"`
Message string `json:"message"`
}
if err = d.client.Get(c, cb, "", nil, &res); err != nil {
return
}
log.Info("callback shike idfa(%s) cb(%s) success ret(%s) msg(%s)", idfa, cb, res.Success, res.Message)
return
}
func (d *Dao) DontinCallback(c context.Context, idfa, clickid string) (err error) {
urlStr := fmt.Sprintf(d.iisURL, clickid)
if err = d.client.Get(c, urlStr, "", nil, nil); err != nil {
return
}
log.Info("callback dontin idfa(%s) clickid(%s) success", idfa, clickid)
return
}
func (d *Dao) ToutiaoCallback(c context.Context, cb string, eventType string) (err error) {
if cb == "" {
return
}
cbURL := strings.TrimSpace(cb + "&event_type=" + eventType)
var res struct {
Ret int `json:"ret"`
}
if err = d.client.Get(c, cbURL, "", nil, &res); err != nil {
return
}
if !ecode.Int(res.Ret).Equal(ecode.OK) {
err = errors.Wrap(ecode.Int(res.Ret), cbURL)
if res.Ret == -1 {
log.Error("%+v", err)
err = nil
}
return
}
log.Info("callback toutiao cb(%s) eventType(%s) success", cb, eventType)
return
}

View File

@@ -0,0 +1,133 @@
package callback
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-wall/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func init() {
dir, _ := filepath.Abs("../../cmd/app-wall-test.toml")
flag.Set("conf", dir)
conf.Init()
d = New(conf.Conf)
time.Sleep(time.Second)
}
func TestNew(t *testing.T) {
type args struct {
c *conf.Config
}
tests := []struct {
name string
args args
wantD *Dao
}{
// TODO: Add test cases.
}
for _, tt := range tests {
Convey(tt.name, t, func() {
gotD := New(tt.args.c)
So(gotD, ShouldResemble, tt.wantD)
})
}
}
func TestDao_GdtCallback(t *testing.T) {
type args struct {
c context.Context
appID string
appType string
aderID string
idfa string
cb string
now time.Time
}
tests := []struct {
name string
args args
wantErr error
}{
// TODO: Add test cases.
}
for _, tt := range tests {
Convey(tt.name, t, func() {
err := d.GdtCallback(tt.args.c, tt.args.appID, tt.args.appType, tt.args.aderID, tt.args.idfa, tt.args.cb, tt.args.now)
So(err, ShouldEqual, tt.wantErr)
})
}
}
func TestDao_ShikeCallback(t *testing.T) {
type args struct {
c context.Context
idfa string
cb string
now time.Time
}
tests := []struct {
name string
args args
wantErr error
}{
// TODO: Add test cases.
}
for _, tt := range tests {
Convey(tt.name, t, func() {
err := d.ShikeCallback(tt.args.c, tt.args.idfa, tt.args.cb, tt.args.now)
So(err, ShouldEqual, tt.wantErr)
})
}
}
func TestDao_DontinCallback(t *testing.T) {
type args struct {
c context.Context
idfa string
clickid string
}
tests := []struct {
name string
args args
wantErr error
}{
// TODO: Add test cases.
}
for _, tt := range tests {
Convey(tt.name, t, func() {
err := d.DontinCallback(tt.args.c, tt.args.idfa, tt.args.clickid)
So(err, ShouldEqual, tt.wantErr)
})
}
}
func TestDao_ToutiaoCallback(t *testing.T) {
type args struct {
c context.Context
cb string
eventType string
}
tests := []struct {
name string
args args
wantErr error
}{
// TODO: Add test cases.
}
for _, tt := range tests {
Convey(tt.name, t, func() {
err := d.ToutiaoCallback(tt.args.c, tt.args.cb, tt.args.eventType)
So(err, ShouldEqual, tt.wantErr)
})
}
}

View File

@@ -0,0 +1,47 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["live_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["live.go"],
importpath = "go-common/app/interface/main/app-wall/dao/live",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,94 @@
package live
import (
"bytes"
"context"
"encoding/json"
"net/http"
"net/url"
"strconv"
"go-common/app/interface/main/app-wall/conf"
"go-common/library/ecode"
"go-common/library/log"
httpx "go-common/library/net/http/blademaster"
)
const (
_liveURL = "/gift/simGift"
_addVipURL = "/user/v0/Vip/addVip"
)
// Dao is live dao
type Dao struct {
client *httpx.Client
liveURL string
addVipURL string
}
// New live dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
client: httpx.NewClient(c.HTTPClient),
liveURL: c.Host.Live + _liveURL,
addVipURL: c.Host.APILive + _addVipURL,
}
return
}
// Pack
func (d *Dao) Pack(c context.Context, mid int64, cardType int) (err error) {
var res struct {
Code int `json:"code"`
}
upack := map[string]map[string]interface{}{
"header": map[string]interface{}{},
"body": map[string]interface{}{
"uid": mid,
"card_type": cardType,
},
}
bytesData, err := json.Marshal(upack)
if err != nil {
log.Error("json.Marshal error(%v)", err)
return
}
req, err := http.NewRequest("POST", d.liveURL, bytes.NewReader(bytesData))
if err != nil {
log.Error("http.NewRequest error(%v)", err)
return
}
req.Header.Set("Content-Type", "application/json;charset=UTF-8")
req.Header.Set("X-BACKEND-BILI-REAL-IP", "")
log.Info("unicom pack mid(%d) card_type(%d)", mid, cardType)
if err = d.client.Do(c, req, &res); err != nil || res.Code != 0 {
err = ecode.Int(res.Code)
log.Error("unicom pack d.client.Do(%s) mid(%d) card_type(%d) error(%v)", d.liveURL, mid, cardType, err)
return
}
return
}
// AddVip add live vip
func (d *Dao) AddVip(c context.Context, mid int64, day int) (msg string, err error) {
params := url.Values{}
params.Set("vip_type", "1")
params.Set("day", strconv.Itoa(day))
params.Set("uid", strconv.FormatInt(mid, 10))
params.Set("platform", "main")
var res struct {
Code int `json:"code"`
Msg string `json:"message"`
}
if err = d.client.Post(c, d.addVipURL, "", params, &res); err != nil {
log.Error("live add vip url(%v) error(%v)", d.addVipURL+"?"+params.Encode(), err)
return
}
msg = res.Msg
if res.Code != 0 {
err = ecode.Int(res.Code)
log.Error("live add vip url(%v) res code(%d)", d.addVipURL+"?"+params.Encode(), res.Code)
return
}
return
}

View File

@@ -0,0 +1,43 @@
package live
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-wall/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func ctx() context.Context {
return context.Background()
}
func init() {
dir, _ := filepath.Abs("../../cmd/app-wall-test.toml")
flag.Set("conf", dir)
conf.Init()
d = New(conf.Conf)
time.Sleep(time.Second)
}
func TestPack(t *testing.T) {
Convey("Pack", t, func() {
err := d.Pack(ctx(), 1, 1)
So(err, ShouldBeNil)
})
}
func TestAddVip(t *testing.T) {
Convey("AddVip", t, func() {
_, err := d.AddVip(ctx(), 1, 1)
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1,52 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["mobile_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//app/interface/main/app-wall/model/mobile:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"cache.go",
"mobile.go",
],
importpath = "go-common/app/interface/main/app-wall/dao/mobile",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//app/interface/main/app-wall/model/mobile:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/database/sql:go_default_library",
"//library/log:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,133 @@
package mobile
import (
"context"
"fmt"
"go-common/app/interface/main/app-wall/model/mobile"
"go-common/library/cache/memcache"
"go-common/library/log"
)
const (
_prefix = "mobiles_user_%v"
)
func keyMobile(usermob string) string {
return fmt.Sprintf(_prefix, usermob)
}
// AddMobileCache
func (d *Dao) AddMobileCache(c context.Context, usermob string, m []*mobile.Mobile) (err error) {
var (
key = keyMobile(usermob)
conn = d.mc.Get(c)
)
if err = conn.Set(&memcache.Item{Key: key, Object: m, Flags: memcache.FlagJSON, Expiration: d.expire}); err != nil {
log.Error("addMobileCache d.mc.Set(%s,%v) error(%v)", key, m, err)
}
conn.Close()
return
}
// MobileCache
func (d *Dao) MobileCache(c context.Context, usermob string) (m []*mobile.Mobile, err error) {
var (
key = keyMobile(usermob)
conn = d.mc.Get(c)
r *memcache.Item
)
defer conn.Close()
if r, err = conn.Get(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
log.Error("mobileCache MemchDB.Get(%s) error(%v)", key, err)
return
}
if err = conn.Scan(r, &m); err != nil {
log.Error("r.Scan(%s) error(%v)", r.Value, err)
}
return
}
// DeleteMobileCache
func (d *Dao) DeleteMobileCache(c context.Context, usermob string) (err error) {
var (
key = keyMobile(usermob)
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Delete(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
log.Error("mobileCache MemchDB.Delete(%s) error(%v)", key, err)
return
}
return
}
// UpdateMobileCache
func (d *Dao) UpdateMobileCache(c context.Context, usermob string, m *mobile.Mobile) (err error) {
var (
ms []*mobile.Mobile
mobiles []*mobile.Mobile
uproductid = map[string]struct{}{}
)
if ms, err = d.MobileCache(c, usermob); err != nil && len(ms) > 0 {
log.Error("d.MobileCache error(%v)", err)
return
}
if len(ms) > 0 {
for _, ml := range ms {
tmp := &mobile.Mobile{}
*tmp = *ml
if tmp.Productid == m.Productid {
tmp = m
if m.Threshold == 0 {
tmp.Threshold = ml.Threshold
}
uproductid[m.Productid] = struct{}{}
}
mobiles = append(mobiles, tmp)
}
if _, ok := uproductid[m.Productid]; !ok {
mobiles = append(mobiles, m)
}
if err = d.AddMobileCache(c, usermob, mobiles); err != nil {
log.Error("d.AddMobileCache error(%v)", err)
return
}
}
return
}
// UpdateMobileFlowCache
func (d *Dao) UpdateMobileFlowCache(c context.Context, usermob string, m *mobile.Mobile) (err error) {
var (
ms []*mobile.Mobile
mobiles []*mobile.Mobile
)
if ms, err = d.MobileCache(c, usermob); err != nil && len(ms) > 0 {
log.Error("d.MobileCache error(%v)", err)
return
}
if len(ms) > 0 {
for _, ml := range ms {
tmp := &mobile.Mobile{}
*tmp = *ml
if tmp.Productid == m.Productid {
tmp.Threshold = m.Threshold
}
mobiles = append(mobiles, tmp)
}
if err = d.AddMobileCache(c, usermob, mobiles); err != nil {
log.Error("d.AddMobileCache error(%v)", err)
return
}
}
return
}

View File

@@ -0,0 +1,102 @@
package mobile
import (
"context"
"strconv"
"time"
"go-common/app/interface/main/app-wall/conf"
"go-common/app/interface/main/app-wall/model/mobile"
"go-common/library/cache/memcache"
xsql "go-common/library/database/sql"
"go-common/library/log"
)
const (
_inOrderSyncSQL = `INSERT IGNORE INTO mobile_order (orderid,userpseudocode,channelseqid,price,actiontime,actionid,effectivetime,expiretime,channelid,productid,ordertype,threshold)
VALUES(?,?,?,?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE orderid=?,channelseqid=?,price=?,actiontime=?,actionid=?,effectivetime=?,expiretime=?,channelid=?,productid=?,ordertype=?,threshold=?`
_upOrderFlowSQL = `UPDATE mobile_order SET threshold=?,resulttime=? WHERE userpseudocode=? AND productid=?`
_orderSyncByUserSQL = `SELECT orderid,userpseudocode,channelseqid,price,actionid,effectivetime,expiretime,channelid,productid,ordertype,threshold FROM mobile_order WHERE effectivetime<? AND userpseudocode=?`
)
type Dao struct {
db *xsql.DB
inOrderSyncSQL *xsql.Stmt
upOrderFlowSQL *xsql.Stmt
orderUserSyncSQL *xsql.Stmt
// memcache
mc *memcache.Pool
expire int32
}
func New(c *conf.Config) (d *Dao) {
d = &Dao{
db: xsql.NewMySQL(c.MySQL.Show),
// memcache
mc: memcache.NewPool(c.Memcache.Operator.Config),
expire: int32(time.Duration(c.Memcache.Operator.Expire) / time.Second),
}
d.inOrderSyncSQL = d.db.Prepared(_inOrderSyncSQL)
d.upOrderFlowSQL = d.db.Prepared(_upOrderFlowSQL)
d.orderUserSyncSQL = d.db.Prepared(_orderSyncByUserSQL)
return
}
func (d *Dao) InOrdersSync(ctx context.Context, u *mobile.MobileXML) (row int64, err error) {
res, err := d.inOrderSyncSQL.Exec(ctx, u.Orderid, u.Userpseudocode, u.Channelseqid, u.Price, u.Actiontime, u.Actionid, u.Effectivetime, u.Expiretime,
u.Channelid, u.Productid, u.Ordertype, u.Threshold,
u.Orderid, u.Channelseqid, u.Price, u.Actiontime, u.Actionid, u.Effectivetime, u.Expiretime,
u.Channelid, u.Productid, u.Ordertype, u.Threshold)
if err != nil {
log.Error("d.inOrderSyncSQL.Exec error(%v)", err)
return
}
tmp := &mobile.Mobile{}
tmp.MobileXMLMobile(u)
if err = d.UpdateMobileCache(ctx, u.Userpseudocode, tmp); err != nil {
log.Error("mobile d.UpdateMobileCache usermob(%v) error(%v)", u.Userpseudocode, err)
return
}
return res.RowsAffected()
}
// FlowSync update OrdersSync
func (d *Dao) FlowSync(ctx context.Context, u *mobile.MobileXML) (row int64, err error) {
res, err := d.upOrderFlowSQL.Exec(ctx, u.Threshold, u.Resulttime, u.Userpseudocode, u.Productid)
if err != nil {
log.Error("d.upOrderFlowSQL.Exec error(%v)", err)
return
}
thresholdInt, _ := strconv.Atoi(u.Threshold)
tmp := &mobile.Mobile{
Threshold: thresholdInt,
Productid: u.Productid,
}
if err = d.UpdateMobileFlowCache(ctx, u.Userpseudocode, tmp); err != nil {
log.Error("mobile d.UpdateMobileFlowCache usermob(%v) error(%v)", u.Userpseudocode, err)
return
}
return res.RowsAffected()
}
// OrdersUserFlow select user OrdersSync
func (d *Dao) OrdersUserFlow(ctx context.Context, usermob string, now time.Time) (res map[string][]*mobile.Mobile, err error) {
rows, err := d.orderUserSyncSQL.Query(ctx, now, usermob)
if err != nil {
log.Error("query error (%v)", err)
return
}
defer rows.Close()
res = map[string][]*mobile.Mobile{}
for rows.Next() {
u := &mobile.Mobile{}
if err = rows.Scan(&u.Orderid, &u.Userpseudocode, &u.Channelseqid, &u.Price, &u.Actionid, &u.Effectivetime, &u.Expiretime,
&u.Channelid, &u.Productid, &u.Ordertype, &u.Threshold); err != nil {
log.Error("Mobile OrdersUserFlow rows.Scan err (%v)", err)
return
}
u.MobileChange()
res[u.Userpseudocode] = append(res[u.Userpseudocode], u)
}
return
}

View File

@@ -0,0 +1,62 @@
package mobile
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-wall/conf"
"go-common/app/interface/main/app-wall/model/mobile"
. "github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func ctx() context.Context {
return context.Background()
}
func init() {
dir, _ := filepath.Abs("../../cmd/app-wall-test.toml")
flag.Set("conf", dir)
conf.Init()
d = New(conf.Conf)
time.Sleep(time.Second)
}
func TestInOrdersSync(t *testing.T) {
Convey("unicom InOrdersSync", t, func() {
res, err := d.InOrdersSync(ctx(), &mobile.MobileXML{})
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
})
}
func TestFlowSync(t *testing.T) {
Convey("unicom FlowSync", t, func() {
res, err := d.FlowSync(ctx(), &mobile.MobileXML{})
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
})
}
func TestOrdersUserFlow(t *testing.T) {
Convey("unicom OrdersUserFlow", t, func() {
res, err := d.OrdersUserFlow(ctx(), "", time.Now())
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
})
}
func TestMobileCache(t *testing.T) {
Convey("unicom MobileCache", t, func() {
res, err := d.MobileCache(ctx(), "")
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
})
}

View File

@@ -0,0 +1,46 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["offer_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["offer.go"],
importpath = "go-common/app/interface/main/app-wall/dao/offer",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//library/database/sql:go_default_library",
"//library/log:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,204 @@
package offer
import (
"context"
"database/sql"
"time"
"go-common/app/interface/main/app-wall/conf"
xsql "go-common/library/database/sql"
"go-common/library/log"
)
const (
//offer
_inClkSQL = "INSERT IGNORE INTO wall_click (ip,cid,mac,idfa,cb,ctime,mtime) VALUES(?,?,?,?,?,?,?)"
_inActSQL = "INSERT IGNORE INTO wall_active (ip,mid,rmac,mac,idfa,device,ctime,mtime) VALUES(?,?,?,?,?,?,?,?)"
_upActIdfaSQL = "UPDATE wall_click SET idfa_active=?,mtime=? WHERE idfa=?"
_cbSQL = "SELECT cid,cb FROM wall_click WHERE (idfa=? OR idfa=?) and ctime>? and ctime<? ORDER BY id DESC LIMIT 1"
_rMacCntSQL = "SELECT COUNT(*) FROM wall_active WHERE rmac=?"
_idfaSQL = "SELECT id FROM wall_active WHERE idfa=?"
_inANClkSQL = "INSERT IGNORE INTO `wall_click_an` (`channel`,`imei`,`androidid`,`mac`,`ip`,`cb`,`ctime`,`mtime`) VALUES (?,?,?,?,?,?,?,?)"
_anActiveSQL = "SELECT COUNT(*) FROM `wall_click_an` WHERE `type`=1 AND ((`androidid`=? AND `androidid`<>'') OR ((`imei`=? OR `imei`=?) AND `imei`<>''))"
_anCbSQL = "SELECT `id`,`channel`,`cb`,`type` FROM `wall_click_an` WHERE (`androidid`=? AND `androidid`<>'') OR (`imei`=? AND `imei`<>'') ORDER BY `id` DESC LIMIT 1"
_anGdtCbSQL = "SELECT `id`,`channel`,`cb`,`type` FROM `wall_click_an` WHERE `imei`=? ORDER BY `id` DESC LIMIT 1"
_upClkActSQL = "UPDATE `wall_click_an` SET `type`=? WHERE `id`=?"
)
// Dao is wall dao.
type Dao struct {
db *xsql.DB
inClkSQL *xsql.Stmt
inActSQL *xsql.Stmt
upActIdfaSQL *xsql.Stmt
cbSQL *xsql.Stmt
rMacCntSQL *xsql.Stmt
idfaSQL *xsql.Stmt
// android
inANClkSQL *xsql.Stmt
anActiveSQL *xsql.Stmt
anCbSQL *xsql.Stmt
anGdtCbSQL *xsql.Stmt
upClkActSQL *xsql.Stmt
}
func New(c *conf.Config) (d *Dao) {
d = &Dao{
db: xsql.NewMySQL(c.MySQL.Show),
}
d.inClkSQL = d.db.Prepared(_inClkSQL)
d.inActSQL = d.db.Prepared(_inActSQL)
d.upActIdfaSQL = d.db.Prepared(_upActIdfaSQL)
d.cbSQL = d.db.Prepared(_cbSQL)
d.rMacCntSQL = d.db.Prepared(_rMacCntSQL)
d.idfaSQL = d.db.Prepared(_idfaSQL)
// android
d.inANClkSQL = d.db.Prepared(_inANClkSQL)
d.anActiveSQL = d.db.Prepared(_anActiveSQL)
d.anCbSQL = d.db.Prepared(_anCbSQL)
d.anGdtCbSQL = d.db.Prepared(_anGdtCbSQL)
d.upClkActSQL = d.db.Prepared(_upClkActSQL)
return
}
func (d *Dao) InClick(ctx context.Context, ip uint32, cid, mac, idfa, cb string, now time.Time) (row int64, err error) {
res, err := d.inClkSQL.Exec(ctx, ip, cid, mac, idfa, cb, now, now)
if err != nil {
log.Error("tx.Exec error(%v)", err)
return
}
return res.RowsAffected()
}
func (d *Dao) InActive(ctx context.Context, ip uint32, mid, rmac, mac, idfa, device string, now time.Time) (row int64, err error) {
res, err := d.inActSQL.Exec(ctx, ip, mid, rmac, mac, idfa, device, now, now)
if err != nil {
log.Error("tx.Exec error(%v)", err)
return
}
return res.RowsAffected()
}
func (d *Dao) UpIdfaActive(ctx context.Context, idfaAct, idfa string, now time.Time) (row int64, err error) {
res, err := d.upActIdfaSQL.Exec(ctx, idfaAct, now, idfa)
if err != nil {
log.Error("tx.Exec error(%v)", err)
return
}
return res.RowsAffected()
}
func (d *Dao) Callback(ctx context.Context, idfa, gdtIdfa string, now time.Time) (cid, cb string, err error) {
lo := now.AddDate(0, 0, -1)
row := d.cbSQL.QueryRow(ctx, idfa, gdtIdfa, lo, now)
if row == nil {
log.Error("d.cbSQL.QueryRow is null")
return
}
if err = row.Scan(&cid, &cb); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("Callback row.Scan error(%v)", err)
}
return
}
return
}
func (d *Dao) RMacCount(ctx context.Context, rmac string) (count int, err error) {
row := d.rMacCntSQL.QueryRow(ctx, rmac)
if row == nil {
log.Error("d.rMacCntSQL.QueryRow is null")
return
}
if err = row.Scan(&count); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("RMacCount row.Scan error(%v)", err)
}
return
}
return
}
func (d *Dao) Exists(ctx context.Context, idfa string) (exist bool, err error) {
row := d.idfaSQL.QueryRow(ctx, idfa)
var id int
if row == nil {
log.Error("d.idfaSQL.QueryRow is null")
return
}
if err = row.Scan(&id); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("RMacCount row.Scan error(%v)", err)
}
return
}
exist = id > 0
return
}
func (d *Dao) InANClick(c context.Context, channel, imei, androidid, mac, cb string, ip uint32, now time.Time) (row int64, err error) {
res, err := d.inANClkSQL.Exec(c, channel, imei, androidid, mac, ip, cb, now, now)
if err != nil {
return
}
return res.RowsAffected()
}
func (d *Dao) ANActive(c context.Context, androidid, imei, gdtImei string) (count int, err error) {
row := d.anActiveSQL.QueryRow(c, androidid, imei, gdtImei)
if row == nil {
return
}
if err = row.Scan(&count); err != nil {
if err == sql.ErrNoRows {
err = nil
}
}
return
}
func (d *Dao) ANCallback(c context.Context, androidid, imei, gdtImei string) (id int64, channel, cb string, typ int, err error) {
row := d.anCbSQL.QueryRow(c, androidid, imei)
if err = row.Scan(&id, &channel, &cb, &typ); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
return
}
}
if gdtImei != "" {
var (
gdtID int64
gdtChannel, gdtCb string
gdtTyp int
)
row := d.anGdtCbSQL.QueryRow(c, gdtImei)
if err = row.Scan(&gdtID, &gdtChannel, &gdtCb, &gdtTyp); err != nil {
if err == sql.ErrNoRows {
err = nil
}
return
}
if gdtID > id {
id = gdtID
channel = gdtChannel
cb = gdtCb
typ = gdtTyp
}
}
return
}
func (d *Dao) ANClickAct(c context.Context, id int64, typ int) (row int64, err error) {
res, err := d.upClkActSQL.Exec(c, typ, id)
if err != nil {
return
}
return res.RowsAffected()
}

View File

@@ -0,0 +1,78 @@
package offer
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-wall/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func ctx() context.Context {
return context.Background()
}
func init() {
dir, _ := filepath.Abs("../../cmd/app-wall-test.toml")
flag.Set("conf", dir)
conf.Init()
d = New(conf.Conf)
time.Sleep(time.Second)
}
func TestUpIdfaActive(t *testing.T) {
Convey("UpIdfaActive", t, func() {
_, err := d.UpIdfaActive(ctx(), "", "", time.Now())
So(err, ShouldBeNil)
})
}
func TestCallback(t *testing.T) {
Convey("Callback", t, func() {
_, _, err := d.Callback(ctx(), "", "", time.Now())
So(err, ShouldBeNil)
})
}
func TestRMacCount(t *testing.T) {
Convey("RMacCount", t, func() {
_, err := d.RMacCount(ctx(), "")
So(err, ShouldBeNil)
})
}
func TestExists(t *testing.T) {
Convey("RMacCount", t, func() {
_, err := d.RMacCount(ctx(), "")
So(err, ShouldBeNil)
})
}
func TestInANClick(t *testing.T) {
Convey("InANClick", t, func() {
_, err := d.InANClick(ctx(), "", "", "", "", "", 11, time.Now())
So(err, ShouldBeNil)
})
}
func TestANActive(t *testing.T) {
Convey("ANActive", t, func() {
_, err := d.ANActive(ctx(), "", "", "")
So(err, ShouldBeNil)
})
}
func TestANCallback(t *testing.T) {
Convey("ANCallback", t, func() {
_, _, _, _, err := d.ANCallback(ctx(), "", "", "")
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1,38 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["padding_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = ["//vendor/github.com/smartystreets/goconvey/convey:go_default_library"],
)
go_library(
name = "go_default_library",
srcs = ["padding.go"],
importpath = "go-common/app/interface/main/app-wall/dao/padding",
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,39 @@
package padding
import "errors"
var (
ErrPaddingSize = errors.New("pkcs5 padding size error")
PKCS5 = &pkcs5{}
)
// pkcs5Padding is a pkcs5 padding struct.
type pkcs5 struct{}
// Padding is interface used for crypto.
type Padding interface {
Padding(src []byte, blockSize int) []byte
Unpadding(src []byte, blockSize int) ([]byte, error)
}
// Padding implements the Padding interface Padding method.
func (p *pkcs5) Padding(src []byte, blockSize int) []byte {
srcLen := len(src)
padLen := byte(blockSize - (srcLen % blockSize))
pd := make([]byte, srcLen+int(padLen))
copy(pd, src)
for i := srcLen; i < len(pd); i++ {
pd[i] = padLen
}
return pd
}
// Unpadding implements the Padding interface Unpadding method.
func (p *pkcs5) Unpadding(src []byte, blockSize int) ([]byte, error) {
srcLen := len(src)
paddingLen := int(src[srcLen-1])
if paddingLen >= srcLen || paddingLen > blockSize {
return nil, ErrPaddingSize
}
return src[:srcLen-paddingLen], nil
}

View File

@@ -0,0 +1,24 @@
package padding
import (
"testing"
"time"
. "github.com/smartystreets/goconvey/convey"
)
var (
p *pkcs5
)
func init() {
p = &pkcs5{}
time.Sleep(time.Second)
}
func TestPadding(t *testing.T) {
Convey("Padding", t, func() {
res := p.Padding([]byte{}, 1)
So(res, ShouldNotBeEmpty)
})
}

View File

@@ -0,0 +1,47 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["seq_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["seq.go"],
importpath = "go-common/app/interface/main/app-wall/dao/seq",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//app/service/main/seq-server/model:go_default_library",
"//app/service/main/seq-server/rpc/client:go_default_library",
"//library/log:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,40 @@
package seq
import (
"context"
"go-common/app/interface/main/app-wall/conf"
seq "go-common/app/service/main/seq-server/model"
seqrpc "go-common/app/service/main/seq-server/rpc/client"
"go-common/library/log"
)
type Dao struct {
c *conf.Config
seqRPC *seqrpc.Service2
businessID int64
token string
}
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
seqRPC: seqrpc.New2(c.SeqRPC),
businessID: c.Seq.BusinessID,
token: c.Seq.Token,
}
return
}
// SeqID
func (d *Dao) SeqID(ctx context.Context) (requestNo int64, err error) {
arg := &seq.ArgBusiness{
BusinessID: d.businessID,
Token: d.token,
}
if requestNo, err = d.seqRPC.ID(ctx, arg); err != nil {
log.Error("d.seqRPC.ID error (%v)", err)
return
}
return
}

View File

@@ -0,0 +1,37 @@
package seq
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-wall/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func ctx() context.Context {
return context.Background()
}
func init() {
dir, _ := filepath.Abs("../../cmd/app-wall-test.toml")
flag.Set("conf", dir)
conf.Init()
d = New(conf.Conf)
time.Sleep(time.Second)
}
func TestSeqID(t *testing.T) {
Convey("SeqID", t, func() {
res, err := d.SeqID(ctx())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1,47 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["shopping_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["shopping.go"],
importpath = "go-common/app/interface/main/app-wall/dao/shopping",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,72 @@
package shopping
import (
"bytes"
"context"
"encoding/json"
"net/http"
"go-common/app/interface/main/app-wall/conf"
"go-common/library/ecode"
"go-common/library/log"
httpx "go-common/library/net/http/blademaster"
)
const (
_couponURL = "/mall-marketing/coupon_code/create"
)
// Dao is shopping dao
type Dao struct {
client *httpx.Client
couponURL string
}
// New shopping dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
client: httpx.NewClient(c.HTTPClient),
// url
couponURL: c.Host.Mall + _couponURL,
}
return
}
// Coupon user vip
func (d *Dao) Coupon(c context.Context, couponID string, mid int64, uname string) (msg string, err error) {
var res struct {
Code int `json:"code"`
Msg string `json:"message"`
}
data := map[string]interface{}{
"couponId": couponID,
"mid": mid,
"uname": uname,
}
var (
bytesData []byte
req *http.Request
)
if bytesData, err = json.Marshal(data); err != nil {
log.Error("json.Marshal error(%v)", err)
return
}
if req, err = http.NewRequest("POST", d.couponURL, bytes.NewReader(bytesData)); err != nil {
log.Error("http.NewRequest error(%v)", err)
return
}
req.Header.Set("Content-Type", "application/json;charset=UTF-8")
req.Header.Set("X-BACKEND-BILI-REAL-IP", "")
log.Info("coupon vip mid(%d) couponID(%s)", mid, couponID)
if err = d.client.Do(c, req, &res); err != nil {
log.Error("coupon vip url(%v) error(%v)", d.couponURL, err)
return
}
msg = res.Msg
if res.Code != 0 {
err = ecode.Int(res.Code)
log.Error("coupon vip url(%v) res code(%d)", d.couponURL, res.Code)
return
}
return
}

View File

@@ -0,0 +1,36 @@
package shopping
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-wall/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func ctx() context.Context {
return context.Background()
}
func init() {
dir, _ := filepath.Abs("../../cmd/app-wall-test.toml")
flag.Set("conf", dir)
conf.Init()
d = New(conf.Conf)
time.Sleep(time.Second)
}
func TestCoupon(t *testing.T) {
Convey("Coupon", t, func() {
_, err := d.Coupon(ctx(), "", 1, "")
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1,58 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["telecom_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"api.go",
"cache.go",
"memcache.go",
"sms.go",
"telecom.go",
],
importpath = "go-common/app/interface/main/app-wall/dao/telecom",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//app/interface/main/app-wall/model/telecom: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",
"//vendor/github.com/xxtea/xxtea-go/xxtea: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,255 @@
package telecom
import (
"context"
"crypto/md5"
"encoding/hex"
"net/http"
"net/url"
"strconv"
"strings"
"time"
"go-common/app/interface/main/app-wall/model/telecom"
"go-common/library/ecode"
"go-common/library/log"
"github.com/xxtea/xxtea-go/xxtea"
)
const (
_telecomAppsecret = "FD9B667503E74DDDBcF28E2327F88EEA"
_telecomAppID = "1000000053"
_telecomFormat = "json"
_telecomClientType = "3"
_flowPackageID = 279
_payInfo = "/api/v1/0/getPayInfo.do"
_cancelRepeatOrder = "/api/v1/0/cancelRepeatOrder.do"
_sucOrderList = "/api/v1/0/getSucOrderList.do"
_phoneArea = "/api/v1/0/queryOperatorAndProvince.do"
_orderState = "/api/v1/0/queryOrderStatus.do"
)
// PayInfo
func (d *Dao) PayInfo(c context.Context, requestNo int64, phone, isRepeatOrder, payChannel, payAction int, orderID int64, ipStr string,
beginTime, firstOrderEndtime time.Time) (data *telecom.Pay, err error, msg string) {
var payChannelStr string
switch payChannel {
case 1:
payChannelStr = "31"
ipStr = ""
case 2:
payChannelStr = "29"
}
params := url.Values{}
params.Set("requestNo", strconv.FormatInt(requestNo, 10))
params.Set("flowPackageId", strconv.Itoa(_flowPackageID))
params.Set("contractId", "100174")
params.Set("activityId", "101043")
params.Set("phoneId", strconv.Itoa(phone))
params.Set("bindApps", "tv.danmaku.bilianime|tv.danmaku.bili")
params.Set("bindAppNames", "哔哩哔哩|哔哩哔哩")
params.Set("isRepeatOrder", strconv.Itoa(isRepeatOrder))
params.Set("payChannel", payChannelStr)
if ipStr != "" {
params.Set("userIp", ipStr)
}
params.Set("payPageType", "1")
if d.telecomReturnURL != "" {
params.Set("returnUrl", d.telecomReturnURL)
}
if d.telecomCancelPayURL != "" {
params.Set("cancelPayUrl", d.telecomCancelPayURL)
}
params.Set("payAction", strconv.Itoa(payAction))
// if startTime := beginTime.Format("20060102"); startTime != "19700101" && !beginTime.IsZero() {
// params.Set("beginTime", startTime)
// }
// if endTime := firstOrderEndtime.Format("20060102"); endTime != "19700101" && !firstOrderEndtime.IsZero() {
// params.Set("firstOrderEndtime", endTime)
// }
if orderID > 0 {
params.Set("orderId", strconv.FormatInt(orderID, 10))
}
var res struct {
Code int `json:"resCode"`
Detail struct {
OrderID int64 `json:"orderId"`
PayInfo struct {
PayURL string `json:"payUrl"`
} `json:"payInfo"`
} `json:"detail"`
Msg string `json:"resMsg"`
}
if err = d.wallHTTPPost(c, d.payInfoURL, params, &res); err != nil {
log.Error("telecom_payInfoURL url(%s) error(%v)", d.payInfoURL+"?"+params.Encode(), err)
return
}
if res.Code != 10000 {
err = ecode.Int(res.Code)
log.Error("telecom_url(%s) res code(%d) or res.data(%v)", d.payInfoURL+"?"+params.Encode(), res.Code, res.Detail)
msg = res.Msg
return
}
data = &telecom.Pay{
RequestNo: requestNo,
OrderID: res.Detail.OrderID,
PayURL: res.Detail.PayInfo.PayURL,
}
return
}
// wallHTTPPost
func (d *Dao) wallHTTPPost(c context.Context, urlStr string, params url.Values, res interface{}) (err error) {
newParams := url.Values{}
encryptData := xxtea.Encrypt([]byte(params.Encode()), []byte(_telecomAppsecret))
hexStr := hex.EncodeToString(encryptData)
newParams.Set("paras", hexStr)
mh := md5.Sum([]byte(_telecomAppID + _telecomClientType + _telecomFormat + hexStr + _telecomAppsecret))
newParams.Set("sign", hex.EncodeToString(mh[:]))
newParams.Set("appId", _telecomAppID)
newParams.Set("clientType", _telecomClientType)
newParams.Set("format", _telecomFormat)
req, err := http.NewRequest("POST", urlStr, strings.NewReader(newParams.Encode()))
if err != nil {
log.Error("telecom_http.NewRequest url(%s) error(%v)", urlStr+"?"+newParams.Encode(), err)
return
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("X-BACKEND-BILI-REAL-IP", "")
return d.client.Do(c, req, &res)
}
// CancelRepeatOrder
func (d *Dao) CancelRepeatOrder(c context.Context, phone int, signNo string) (msg string, err error) {
params := url.Values{}
params.Set("phoneId", strconv.Itoa(phone))
params.Set("signNo", signNo)
var res struct {
Code int `json:"resCode"`
Msg string `json:"resMsg"`
}
if err = d.wallHTTPPost(c, d.cancelRepeatOrderURL, params, &res); err != nil {
log.Error("telecom_payInfoURL url(%s) error(%v)", d.cancelRepeatOrderURL+"?"+params.Encode(), err)
return
}
if res.Code != 10000 {
err = ecode.Int(res.Code)
log.Error("telecom_url(%s) res code(%d)", d.cancelRepeatOrderURL+"?"+params.Encode(), res.Code)
msg = res.Msg
return
}
msg = res.Msg
return
}
// SucOrderList user order list
func (d *Dao) SucOrderList(c context.Context, phone int) (res *telecom.SucOrder, err error, msg string) {
params := url.Values{}
params.Set("phoneId", strconv.Itoa(phone))
var resData struct {
Code int `json:"resCode"`
Detail struct {
AccessToken string `json:"accessToken"`
Orders []*telecom.SucOrder `json:"orders"`
} `json:"detail"`
Msg string `json:"resMsg"`
}
if err = d.wallHTTPPost(c, d.sucOrderListURL, params, &resData); err != nil {
log.Error("telecom_sucOrderListURL url(%s) error(%v)", d.sucOrderListURL+"?"+params.Encode(), err)
return
}
if resData.Code != 10000 {
err = ecode.Int(resData.Code)
log.Error("telecom_url(%s) res code(%d)", d.sucOrderListURL+"?"+params.Encode(), resData.Code)
msg = resData.Msg
return
}
if len(resData.Detail.Orders) == 0 {
err = ecode.NothingFound
msg = "订单不存在"
log.Error("telecom_order list phone(%v) len 0", phone)
return
}
for _, r := range resData.Detail.Orders {
if r.FlowPackageID == strconv.Itoa(_flowPackageID) {
r.OrderID, _ = strconv.ParseInt(r.OrderIDStr, 10, 64)
r.OrderIDStr = ""
r.PortInt, _ = strconv.Atoi(r.Port)
r.Port = ""
res = r
res.AccessToken = resData.Detail.AccessToken
break
}
}
if res == nil {
log.Error("telecom_order bili phone(%v) is null", phone)
msg = "订单不存在"
err = ecode.NothingFound
return
}
msg = resData.Msg
return
}
// PhoneArea phone by area
func (d *Dao) PhoneArea(c context.Context, phone int) (area string, err error, msg string) {
params := url.Values{}
params.Set("phoneId", strconv.Itoa(phone))
var resData struct {
Code int `json:"resCode"`
Detail struct {
RegionCode string `json:"regionCode"`
AreaName string `json:"areaName"`
} `json:"detail"`
Msg string `json:"resMsg"`
}
if err = d.wallHTTPPost(c, d.phoneAreaURL, params, &resData); err != nil {
log.Error("telecom_phoneAreaURL url(%s) error(%v)", d.phoneAreaURL+"?"+params.Encode(), err)
return
}
if resData.Code != 10000 {
err = ecode.Int(resData.Code)
log.Error("telecom_url(%s) res code(%d)", d.phoneAreaURL+"?"+params.Encode(), resData.Code)
msg = resData.Msg
return
}
area = resData.Detail.RegionCode
return
}
// OrderState
func (d *Dao) OrderState(c context.Context, orderid int64) (res *telecom.OrderPhoneState, err error) {
params := url.Values{}
params.Set("orderId", strconv.FormatInt(orderid, 10))
var resData struct {
Code int `json:"resCode"`
Detail *telecom.OrderPhoneState `json:"detail"`
Msg string `json:"resMsg"`
}
if err = d.wallHTTPPost(c, d.orderStateURL, params, &resData); err != nil {
log.Error("telecom_orderStateURL url(%s) error(%v)", d.orderStateURL+"?"+params.Encode(), err)
return
}
if resData.Code != 10000 && resData.Code != 10013 {
err = ecode.Int(resData.Code)
log.Error("telecom_url(%s) res code(%d)", d.orderStateURL+"?"+params.Encode(), resData.Code)
return
}
if resData.Code == 10013 {
res = &telecom.OrderPhoneState{
OrderState: 6,
}
return
}
res = resData.Detail
if res.FlowPackageID != _flowPackageID {
res.OrderState = 5
return
}
switch resData.Detail.OrderState {
case 5:
res.OrderState = 6
}
return
}

View File

@@ -0,0 +1,73 @@
package telecom
import (
"context"
"fmt"
"go-common/library/cache/redis"
"go-common/library/ecode"
"go-common/library/log"
)
const (
_phoneKey = "phone_%d"
_payKey = "pay_%d"
)
// AddPhoneCode
func (d *Dao) AddPhoneCode(c context.Context, phone int, captcha string) (res int, err error) {
conn := d.phoneRds.Get(c)
defer conn.Close()
key := fmt.Sprintf(_phoneKey, phone)
if _, err = redis.String(conn.Do("SET", key, captcha)); err != nil {
log.Error("telecom_AddPhoneCode add conn.Do SET error(%v)", err)
return
}
if res, err = redis.Int(conn.Do("EXPIRE", key, d.phoneKeyExpired)); err != nil {
log.Error("telecom_AddPhoneCode add conn.Do EXPIRE error(%v)", err)
return
}
return
}
// PhoneCode
func (d *Dao) PhoneCode(c context.Context, phone int) (captcha string, err error) {
conn := d.phoneRds.Get(c)
defer conn.Close()
key := fmt.Sprintf(_phoneKey, phone)
if captcha, err = redis.String(conn.Do("GET", key)); err != nil {
log.Error("telecom_get conn.Do GET error(%v)", err)
err = ecode.NotModified
return
}
return
}
// AddPayPhone add phone and requestNo
func (d *Dao) AddPayPhone(c context.Context, requestNo int64, phone string) (res int, err error) {
conn := d.phoneRds.Get(c)
defer conn.Close()
key := fmt.Sprintf(_payKey, requestNo)
if _, err = redis.String(conn.Do("SET", key, phone)); err != nil {
log.Error("telecom_AddPhoneCode add conn.Do SET error(%v)", err)
return
}
if res, err = redis.Int(conn.Do("EXPIRE", key, d.payKeyExpired)); err != nil {
log.Error("telecom_AddPhoneCode add conn.Do EXPIRE error(%v)", err)
return
}
return
}
// PayPhone requestNo by phone
func (d *Dao) PayPhone(c context.Context, requestNo int64) (phone string, err error) {
conn := d.phoneRds.Get(c)
defer conn.Close()
key := fmt.Sprintf(_payKey, requestNo)
if phone, err = redis.String(conn.Do("GET", key)); err != nil {
log.Error("telecom_get conn.Do GET requestNo(%v) error(%v)", requestNo, err)
err = ecode.NothingFound
return
}
return
}

View File

@@ -0,0 +1,93 @@
package telecom
import (
"context"
"fmt"
"go-common/app/interface/main/app-wall/model/telecom"
"go-common/library/cache/memcache"
"go-common/library/log"
)
const (
_prefix = "telecom_%d"
_preorderid = "telecom_orderid_%d"
)
func keyTelecom(userphone int) string {
return fmt.Sprintf(_prefix, userphone)
}
func keyTelecomOrderID(orderID int64) string {
return fmt.Sprintf(_preorderid, orderID)
}
// AddTelecomCache
func (d *Dao) AddTelecomCache(c context.Context, userphone int, u *telecom.OrderInfo) (err error) {
var (
key = keyTelecom(userphone)
conn = d.mc.Get(c)
)
if err = conn.Set(&memcache.Item{Key: key, Object: u, Flags: memcache.FlagJSON, Expiration: d.expire}); err != nil {
log.Error("addTelecomCache d.mc.Set(%s,%v) error(%v)", key, u, err)
}
conn.Close()
return
}
// TelecomCache
func (d *Dao) TelecomCache(c context.Context, userphone int) (u *telecom.OrderInfo, err error) {
var (
key = keyTelecom(userphone)
conn = d.mc.Get(c)
r *memcache.Item
)
defer conn.Close()
if r, err = conn.Get(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
log.Error("telecomCache MemchDB.Get(%s) error(%v)", key, err)
return
}
if err = conn.Scan(r, &u); err != nil {
log.Error("r.Scan(%s) error(%v)", r.Value, err)
}
return
}
// AddTelecomOrderIDCache
func (d *Dao) AddTelecomOrderIDCache(c context.Context, orderID int64, u *telecom.OrderInfo) (err error) {
var (
key = keyTelecomOrderID(orderID)
conn = d.mc.Get(c)
)
if err = conn.Set(&memcache.Item{Key: key, Object: u, Flags: memcache.FlagJSON, Expiration: d.expire}); err != nil {
log.Error("addTelecomCache d.mc.Set(%s,%v) error(%v)", key, u, err)
}
conn.Close()
return
}
// TelecomOrderIDCache
func (d *Dao) TelecomOrderIDCache(c context.Context, orderID int64) (u *telecom.OrderInfo, err error) {
var (
key = keyTelecomOrderID(orderID)
conn = d.mc.Get(c)
r *memcache.Item
)
defer conn.Close()
if r, err = conn.Get(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
log.Error("telecomCache MemchDB.Get(%s) error(%v)", key, err)
return
}
if err = conn.Scan(r, &u); err != nil {
log.Error("r.Scan(%s) error(%v)", r.Value, err)
}
return
}

View File

@@ -0,0 +1,57 @@
package telecom
import (
"context"
"fmt"
"net/url"
"strconv"
"go-common/library/log"
)
const (
_smsSendURL = "/x/internal/sms/send"
)
// SendSMS
func (d *Dao) SendSMS(c context.Context, phone int, smsTemplate, dataJSON string) (err error) {
params := url.Values{}
params.Set("mobile", strconv.Itoa(phone))
params.Set("country", "086")
params.Set("tcode", smsTemplate)
params.Set("tparam", dataJSON)
var res struct {
Code int `json:"code"`
}
if err = d.client.Post(c, d.smsSendURL, "", params, &res); err != nil {
log.Error("SendSMS hots url(%s) error(%v)", d.smsSendURL+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Error("SendSMS hots url(%s) error(%v)", d.smsSendURL+"?"+params.Encode(), res.Code)
err = fmt.Errorf("SendSMS api response code(%v)", res)
return
}
return
}
// SendTelecomSMS
func (d *Dao) SendTelecomSMS(c context.Context, phone int, smsTemplate string) (err error) {
params := url.Values{}
params.Set("mobile", strconv.Itoa(phone))
params.Set("country", "086")
params.Set("tcode", smsTemplate)
var res struct {
Code int `json:"code"`
}
if err = d.client.Post(c, d.smsSendURL, "", params, &res); err != nil {
log.Error("SendSMS hots url(%s) model(%v) error(%v)", d.smsSendURL+"?"+params.Encode(), smsTemplate, err)
return
}
if res.Code != 0 {
log.Error("SendSMS hots url(%s) error(%v)", d.smsSendURL+"?"+params.Encode(), res.Code)
err = fmt.Errorf("SendSMS api response code(%v)", res)
return
}
return
}

View File

@@ -0,0 +1,165 @@
package telecom
import (
"context"
"database/sql"
"strconv"
"time"
"go-common/app/interface/main/app-wall/conf"
"go-common/app/interface/main/app-wall/model/telecom"
"go-common/library/cache/memcache"
"go-common/library/cache/redis"
xsql "go-common/library/database/sql"
"go-common/library/log"
httpx "go-common/library/net/http/blademaster"
)
const (
_inOrderSyncSQL = `INSERT IGNORE INTO telecom_order (request_no,result_type,flowpackageid,flowpackagesize,flowpackagetype,trafficattribution,begintime,endtime,
ismultiplyorder,settlementtype,operator,order_status,remainedrebindnum,maxbindnum,orderid,sign_no,accesstoken,phoneid,isrepeatorder,paystatus,
paytime,paychannel,sign_status,refund_status) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE
request_no=?,result_type=?,flowpackagesize=?,flowpackagetype=?,trafficattribution=?,begintime=?,endtime=?,
ismultiplyorder=?,settlementtype=?,operator=?,order_status=?,remainedrebindnum=?,maxbindnum=?,orderid=?,sign_no=?,accesstoken=?,
isrepeatorder=?,paystatus=?,paytime=?,paychannel=?,sign_status=?,refund_status=?`
_inRechargeSyncSQL = `INSERT INTO telecom_recharge (request_no,fcrecharge_no,recharge_status,ordertotalsize,flowbalance) VALUES(?,?,?,?,?)`
_orderByPhoneSQL = `SELECT phoneid,orderid,order_status,sign_no,isrepeatorder,begintime,endtime FROM telecom_order WHERE phoneid=?`
_orderByOrderIDSQL = `SELECT phoneid,orderid,order_status,sign_no,isrepeatorder,begintime,endtime FROM telecom_order WHERE orderid=?`
)
type Dao struct {
c *conf.Config
client *httpx.Client
payInfoURL string
cancelRepeatOrderURL string
sucOrderListURL string
telecomReturnURL string
telecomCancelPayURL string
phoneAreaURL string
orderStateURL string
smsSendURL string
phoneKeyExpired int32
payKeyExpired int32
db *xsql.DB
inOrderSyncSQL *xsql.Stmt
inRechargeSyncSQL *xsql.Stmt
orderByPhoneSQL *xsql.Stmt
orderByOrderIDSQL *xsql.Stmt
phoneRds *redis.Pool
// memcache
mc *memcache.Pool
expire int32
}
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
client: httpx.NewClient(conf.Conf.HTTPTelecom),
payInfoURL: c.Host.Telecom + _payInfo,
cancelRepeatOrderURL: c.Host.Telecom + _cancelRepeatOrder,
sucOrderListURL: c.Host.Telecom + _sucOrderList,
phoneAreaURL: c.Host.Telecom + _phoneArea,
orderStateURL: c.Host.Telecom + _orderState,
telecomReturnURL: c.Host.TelecomReturnURL,
telecomCancelPayURL: c.Host.TelecomCancelPayURL,
smsSendURL: c.Host.Sms + _smsSendURL,
db: xsql.NewMySQL(c.MySQL.Show),
phoneRds: redis.NewPool(c.Redis.Recommend.Config),
//reids
phoneKeyExpired: int32(time.Duration(c.Telecom.KeyExpired) / time.Second),
payKeyExpired: int32(time.Duration(c.Telecom.PayKeyExpired) / time.Second),
// memcache
mc: memcache.NewPool(c.Memcache.Operator.Config),
expire: int32(time.Duration(c.Memcache.Operator.Expire) / time.Second),
}
d.inOrderSyncSQL = d.db.Prepared(_inOrderSyncSQL)
d.inRechargeSyncSQL = d.db.Prepared(_inRechargeSyncSQL)
d.orderByPhoneSQL = d.db.Prepared(_orderByPhoneSQL)
d.orderByOrderIDSQL = d.db.Prepared(_orderByOrderIDSQL)
return
}
// InOrderSync
func (d *Dao) InOrderSync(ctx context.Context, requestNo, resultType int, phone string, t *telecom.TelecomJSON) (row int64, err error) {
res, err := d.inOrderSyncSQL.Exec(ctx, requestNo, resultType, t.FlowpackageID, t.FlowPackageSize, t.FlowPackageType, t.TrafficAttribution, t.BeginTime, t.EndTime,
t.IsMultiplyOrder, t.SettlementType, t.Operator, t.OrderStatus, t.RemainedRebindNum, t.MaxbindNum, t.OrderID, t.SignNo, t.AccessToken,
phone, t.IsRepeatOrder, t.PayStatus, t.PayTime, t.PayChannel, t.SignStatus, t.RefundStatus,
requestNo, resultType, t.FlowPackageSize, t.FlowPackageType, t.TrafficAttribution, t.BeginTime, t.EndTime,
t.IsMultiplyOrder, t.SettlementType, t.Operator, t.OrderStatus, t.RemainedRebindNum, t.MaxbindNum, t.OrderID,
t.SignNo, t.AccessToken, t.IsRepeatOrder, t.PayStatus, t.PayTime, t.PayChannel, t.SignStatus, t.RefundStatus)
if err != nil {
log.Error("d.inOrderSyncSQL.Exec error(%v)", err)
return
}
tmp := &telecom.OrderInfo{}
tmp.OrderInfoJSONChange(t)
phoneInt, _ := strconv.Atoi(t.PhoneID)
if err = d.AddTelecomCache(ctx, phoneInt, tmp); err != nil {
log.Error("s.AddTelecomCache error(%v)", err)
}
orderID, _ := strconv.ParseInt(t.OrderID, 10, 64)
if err = d.AddTelecomOrderIDCache(ctx, orderID, tmp); err != nil {
log.Error("s.AddTelecomOrderIDCache error(%v)", err)
}
return res.RowsAffected()
}
// InRechargeSync
func (d *Dao) InRechargeSync(ctx context.Context, r *telecom.RechargeJSON) (row int64, err error) {
res, err := d.inRechargeSyncSQL.Exec(ctx, r.RequestNo, r.FcRechargeNo, r.RechargeStatus, r.OrderTotalSize, r.FlowBalance)
if err != nil {
log.Error("d.inRechargeSyncSQL.Exec error(%v)", err)
return
}
return res.RowsAffected()
}
func (d *Dao) OrdersUserFlow(ctx context.Context, phoneID int) (res map[int]*telecom.OrderInfo, err error) {
res = map[int]*telecom.OrderInfo{}
var (
PhoneIDStr string
OrderIDStr string
)
t := &telecom.OrderInfo{}
row := d.orderByPhoneSQL.QueryRow(ctx, phoneID)
if err = row.Scan(&PhoneIDStr, &OrderIDStr, &t.OrderState, &t.SignNo, &t.IsRepeatorder, &t.Begintime, &t.Endtime); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("OrdersUserFlow row.Scan err (%v)", err)
}
return
}
t.TelecomChange()
t.PhoneID, _ = strconv.Atoi(PhoneIDStr)
t.OrderID, _ = strconv.ParseInt(OrderIDStr, 10, 64)
if t.PhoneID > 0 {
res[t.PhoneID] = t
}
return
}
func (d *Dao) OrdersUserByOrderID(ctx context.Context, orderID int64) (res map[int64]*telecom.OrderInfo, err error) {
res = map[int64]*telecom.OrderInfo{}
var (
PhoneIDStr string
OrderIDStr string
)
t := &telecom.OrderInfo{}
row := d.orderByOrderIDSQL.QueryRow(ctx, orderID)
if err = row.Scan(&PhoneIDStr, &OrderIDStr, &t.OrderState, &t.SignNo, &t.IsRepeatorder, &t.Begintime, &t.Endtime); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("OrdersUserFlow row.Scan err (%v)", err)
}
return
}
t.TelecomChange()
t.PhoneID, _ = strconv.Atoi(PhoneIDStr)
t.OrderID, _ = strconv.ParseInt(OrderIDStr, 10, 64)
if t.OrderID > 0 {
res[t.OrderID] = t
}
return
}

View File

@@ -0,0 +1,45 @@
package telecom
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-wall/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func ctx() context.Context {
return context.Background()
}
func init() {
dir, _ := filepath.Abs("../../cmd/app-wall-test.toml")
flag.Set("conf", dir)
conf.Init()
d = New(conf.Conf)
time.Sleep(time.Second)
}
func TestOrdersUserFlow(t *testing.T) {
Convey("OrdersUserFlow", t, func() {
res, err := d.OrdersUserFlow(ctx(), 1)
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestOrdersUserByOrderID(t *testing.T) {
Convey("OrdersUserByOrderID", t, func() {
res, err := d.OrdersUserByOrderID(ctx(), 1)
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1,58 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["unicom_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//app/interface/main/app-wall/model/unicom:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"api.go",
"cache.go",
"log.go",
"unicom.go",
],
importpath = "go-common/app/interface/main/app-wall/dao/unicom",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//app/interface/main/app-wall/model:go_default_library",
"//app/interface/main/app-wall/model/unicom:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/database/elastic: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",
],
)
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,464 @@
package unicom
import (
"bytes"
"context"
"crypto/des"
"crypto/md5"
"encoding/base64"
"encoding/hex"
"encoding/json"
"errors"
"net/http"
"net/url"
"sort"
"strconv"
"strings"
"time"
"go-common/app/interface/main/app-wall/model"
"go-common/app/interface/main/app-wall/model/unicom"
"go-common/library/ecode"
"go-common/library/log"
httpx "go-common/library/net/http/blademaster"
)
const (
_cpid = "bilibl"
_spid = "979"
_apptype = "2"
_broadbandPass = "9ed226d9"
// url
_orderURL = "/videoif/order.do"
_ordercancelURL = "/videoif/cancelOrder.do"
_sendsmscodeURL = "/videoif/sendSmsCode.do"
_smsNumberURL = "/videoif/smsNumber.do"
// unicom
_unicomIPURL = "/web/statistics/subsystem_2/query_ip.php"
_unicomUser = "000012"
_unicomPass = "1pibH5e1BN4V"
_unicomFlowExchangeURL = "/openservlet"
_unicomAppKey = "com.aop.app.bilibili"
_unicomSecurity = "DVniSMVU6Z3cCIG3vbOn4Fqbof+QJ/6etD+lpa4M4clgj/Dv6XT0syTR8Xgu5nVzKuzro8eiTUzHy/QAzGjp+A=="
_unicomAppMethodFlow = "com.ssp.method.outflowchange"
_unicomMethodNumber = "com.aop.method.checkusernumber"
_unicomMethodFlowPre = "com.ssp.method.outflowpre"
_unicomMethodQryFlowChange = "com.ssp.method.outqryflowchange"
)
// Order unicom order
func (d *Dao) Order(c context.Context, usermob, channel string, ordertype int) (data *unicom.BroadbandOrder, msg string, err error) {
params := url.Values{}
params.Set("cpid", _cpid)
params.Set("spid", _spid)
params.Set("ordertype", strconv.Itoa(ordertype))
params.Set("userid", usermob)
params.Set("apptype", _apptype)
if channel != "" {
params.Set("channel", channel)
}
var res struct {
Code string `json:"resultcode"`
Msg string `json:"errorinfo"`
*unicom.BroadbandOrder
}
if err = d.broadbandHTTPGet(c, d.orderURL, params, &res); err != nil {
log.Error("unicom order url(%v) error(%v)", d.orderURL+"?"+params.Encode(), err)
return
}
b, _ := json.Marshal(&res)
log.Info("unicom order url(%v) response(%s)", d.orderURL+"?"+params.Encode(), b)
if res.Code != "0" {
err = ecode.String(res.Code)
msg = res.Msg
log.Error("unicom order url(%v) code(%s) Msg(%s)", d.orderURL+"?"+params.Encode(), res.Code, res.Msg)
return
}
data = res.BroadbandOrder
return
}
// CancelOrder unicom cancel order
func (d *Dao) CancelOrder(c context.Context, usermob string) (data *unicom.BroadbandOrder, msg string, err error) {
params := url.Values{}
params.Set("cpid", _cpid)
params.Set("spid", _spid)
params.Set("userid", usermob)
params.Set("apptype", _apptype)
var res struct {
Code string `json:"resultcode"`
Msg string `json:"errorinfo"`
*unicom.BroadbandOrder
}
if err = d.broadbandHTTPGet(c, d.ordercancelURL, params, &res); err != nil {
log.Error("unicom cancel order url(%s) error(%v)", d.ordercancelURL+"?"+params.Encode(), err)
return
}
b, _ := json.Marshal(&res)
log.Info("unicom cancel order url(%s) response(%s)", d.ordercancelURL+"?"+params.Encode(), b)
if res.Code != "0" {
err = ecode.String(res.Code)
msg = res.Msg
log.Error("unicom cancel order url(%v) code(%s) Msg(%s)", d.orderURL+"?"+params.Encode(), res.Code, res.Msg)
return
}
data = res.BroadbandOrder
return
}
// UnicomIP unicom ip orders
func (d *Dao) UnicomIP(c context.Context, now time.Time) (unicomIPs []*unicom.UnicomIP, err error) {
params := url.Values{}
params.Set("user", _unicomUser)
tick := strconv.FormatInt(now.Unix(), 10)
params.Set("tick", tick)
mh := md5.Sum([]byte(_unicomUser + tick + _unicomPass))
var (
key string
)
if key = hex.EncodeToString(mh[:]); len(key) > 16 {
key = key[:16]
}
params.Set("key", key)
var res struct {
Code int `json:"code"`
LastUpdateTime int64 `json:"last_update_time"`
Desc []struct {
StartIP string `json:"start_ip"`
Length string `json:"length"`
} `json:"desc"`
}
if err = d.broadbandHTTPPost(c, d.unicomIPURL, params, &res); err != nil {
log.Error("unicom ip order url(%s) error(%v)", d.unicomIPURL+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
err = ecode.Int(res.Code)
log.Error("unicom ip order url(%s) res code (%d)", d.unicomIPURL+"?"+params.Encode(), res.Code)
return
}
b, _ := json.Marshal(&res)
log.Info("unicom ip url(%s) response(%s)", d.unicomIPURL+"?"+params.Encode(), b)
for _, uip := range res.Desc {
uiplen, _ := strconv.Atoi(uip.Length)
if uiplen < 1 {
log.Error("unicom ip length 0")
continue
}
ipEndInt := model.InetAtoN(uip.StartIP) + uint32((uiplen - 1))
ipEnd := model.InetNtoA(ipEndInt)
unicomIP := &unicom.UnicomIP{}
unicomIP.UnicomIPStrToint(uip.StartIP, ipEnd)
unicomIPs = append(unicomIPs, unicomIP)
}
return
}
// SendSmsCode unicom sms code
func (d *Dao) SendSmsCode(c context.Context, phone string) (msg string, err error) {
var (
key = []byte(_broadbandPass)
phoneByte = []byte(phone)
userid string
)
userid, err = d.desEncrypt(phoneByte, key)
if err != nil {
log.Error("d.desEncrypt error(%v)", err)
return
}
params := url.Values{}
params.Set("cpid", _cpid)
params.Set("userid", string(userid))
params.Set("apptype", _apptype)
var res struct {
Code string `json:"resultcode"`
Msg string `json:"errorinfo"`
}
if err = d.unicomHTTPGet(c, d.sendsmscodeURL, params, &res); err != nil {
log.Error("unicom sendsmscode url(%v) error(%v)", d.sendsmscodeURL+"?"+params.Encode(), err)
return
}
b, _ := json.Marshal(&res)
log.Info("unicom sendsmscode url(%v) response(%s)", d.sendsmscodeURL+"?"+params.Encode(), b)
if res.Code != "0" {
err = ecode.String(res.Code)
msg = res.Msg
log.Error("unicom sendsmscode url(%v) code(%s) Msg(%s)", d.sendsmscodeURL+"?"+params.Encode(), res.Code, res.Msg)
return
}
return
}
// SmsNumber unicom sms usermob
func (d *Dao) SmsNumber(c context.Context, phone string, code int) (usermob string, msg string, err error) {
var (
key = []byte(_broadbandPass)
phoneByte = []byte(phone)
userid string
)
userid, err = d.desEncrypt(phoneByte, key)
if err != nil {
log.Error("d.desEncrypt error(%v)", err)
return
}
params := url.Values{}
params.Set("cpid", _cpid)
params.Set("userid", userid)
params.Set("vcode", strconv.Itoa(code))
params.Set("apptype", _apptype)
var res struct {
Code string `json:"resultcode"`
Usermob string `json:"userid"`
Msg string `json:"errorinfo"`
}
if err = d.unicomHTTPGet(c, d.smsNumberURL, params, &res); err != nil {
log.Error("unicom smsNumberURL url(%v) error(%v)", d.smsNumberURL+"?"+params.Encode(), err)
return
}
b, _ := json.Marshal(&res)
log.Info("unicom sendsmsnumber url(%v) response(%s)", d.smsNumberURL+"?"+params.Encode(), b)
if res.Code != "0" {
err = ecode.String(res.Code)
msg = res.Msg
log.Error("unicom sendsmsnumber url(%v) code(%s) Msg(%s)", d.smsNumberURL+"?"+params.Encode(), res.Code, res.Msg)
return
}
usermob = res.Usermob
return
}
// FlowExchange flow exchange
func (d *Dao) FlowExchange(c context.Context, phone int, flowcode string, requestNo int64, ts time.Time) (orderID, outorderID, msg string, err error) {
outorderIDStr := "bili" + ts.Format("20060102") + strconv.FormatInt(requestNo%10000000, 10)
if len(outorderIDStr) > 22 {
outorderIDStr = outorderIDStr[:22]
}
param := url.Values{}
param.Set("appkey", _unicomAppKey)
param.Set("apptx", strconv.FormatInt(requestNo, 10))
param.Set("flowexchangecode", flowcode)
param.Set("method", _unicomAppMethodFlow)
param.Set("outorderid", outorderIDStr)
param.Set("timestamp", ts.Format("2006-01-02 15:04:05"))
param.Set("usernumber", strconv.Itoa(phone))
urlVal := d.urlParams(param)
urlVal = urlVal + "&" + d.sign(urlVal)
var res struct {
Code string `json:"respcode"`
Msg string `json:"respdesc"`
OrderID string `json:"orderid"`
OutorderID string `json:"outorderid"`
}
if err = d.unicomHTTPGet(c, d.unicomFlowExchangeURL+"?"+urlVal, nil, &res); err != nil {
log.Error("unicom flow change url(%v) error(%v)", d.unicomFlowExchangeURL+"?"+urlVal, err)
return
}
b, _ := json.Marshal(&res)
log.Info("unicom flow url(%v) response(%s)", d.unicomFlowExchangeURL+"?"+urlVal, b)
msg = res.Msg
if res.Code != "0000" {
err = ecode.String(res.Code)
log.Error("unicom flow change url(%v) code(%v) msg(%v)", d.unicomFlowExchangeURL+"?"+urlVal, res.Code, res.Msg)
return
}
orderID = res.OrderID
outorderID = res.OutorderID
return
}
// PhoneVerification unicom phone verification
func (d *Dao) PhoneVerification(c context.Context, phone string, requestNo int64, ts time.Time) (msg string, err error) {
param := url.Values{}
param.Set("appkey", _unicomAppKey)
param.Set("apptx", strconv.FormatInt(requestNo, 10))
param.Set("method", _unicomMethodNumber)
param.Set("timestamp", ts.Format("2006-01-02 15:04:05"))
param.Set("usernumber", phone)
urlVal := d.urlParams(param)
urlVal = urlVal + "&" + d.sign(urlVal)
var res struct {
Code string `json:"respcode"`
Msg string `json:"respdesc"`
}
if err = d.unicomHTTPGet(c, d.unicomFlowExchangeURL+"?"+urlVal, nil, &res); err != nil {
log.Error("unicom phone url(%v) error(%v)", d.unicomFlowExchangeURL+"?"+urlVal, err)
return
}
b, _ := json.Marshal(&res)
log.Info("unicom phone url(%v) response(%s)", d.unicomFlowExchangeURL+"?"+urlVal, b)
msg = res.Msg
if res.Code != "0000" {
err = ecode.String(res.Code)
log.Error("unicom phone url(%v) code(%v) msg(%v)", d.unicomFlowExchangeURL+"?"+urlVal, res.Code, res.Msg)
return
}
return
}
// FlowPre unicom phone flow pre
func (d *Dao) FlowPre(c context.Context, phone int, requestNo int64, ts time.Time) (msg string, err error) {
param := url.Values{}
param.Set("appkey", _unicomAppKey)
param.Set("apptx", strconv.FormatInt(requestNo, 10))
param.Set("method", _unicomMethodFlowPre)
param.Set("timestamp", ts.Format("2006-01-02 15:04:05"))
param.Set("usernumber", strconv.Itoa(phone))
urlVal := d.urlParams(param)
urlVal = urlVal + "&" + d.sign(urlVal)
var res struct {
Code string `json:"respcode"`
Notice string `json:"noticecontent"`
Msg string `json:"respdesc"`
}
if err = d.unicomHTTPGet(c, d.unicomFlowExchangeURL+"?"+urlVal, nil, &res); err != nil {
log.Error("unicom flowpre url(%v) error(%v)", d.unicomFlowExchangeURL+"?"+urlVal, err)
return
}
b, _ := json.Marshal(&res)
log.Info("unicom flowpre url(%v) response(%s)", d.unicomFlowExchangeURL+"?"+urlVal, b)
msg = res.Msg
if res.Code != "0000" {
if res.Code == "0001" {
err = ecode.String(res.Code)
msg = res.Notice
} else {
err = ecode.String(res.Code)
log.Error("unicom flowpre url(%v) code(%v) msg(%v)", d.unicomFlowExchangeURL+"?"+urlVal, res.Code, res.Msg)
}
return
}
return
}
// FlowQry unicom phone qryflowchange
func (d *Dao) FlowQry(c context.Context, phone int, requestNo int64, outorderid, orderid string, ts time.Time) (orderstatus, msg string, err error) {
param := url.Values{}
param.Set("appkey", _unicomAppKey)
param.Set("apptx", strconv.FormatInt(requestNo, 10))
param.Set("method", _unicomMethodQryFlowChange)
param.Set("orderid", orderid)
param.Set("outorderid", outorderid)
param.Set("timestamp", ts.Format("2006-01-02 15:04:05"))
param.Set("usernumber", strconv.Itoa(phone))
urlVal := d.urlParams(param)
urlVal = urlVal + "&" + d.sign(urlVal)
var res struct {
Code string `json:"respcode"`
Orderstatus string `json:"orderstatus"`
Failurtype string `json:"failurtype"`
Msg string `json:"respdesc"`
}
if err = d.unicomHTTPGet(c, d.unicomFlowExchangeURL+"?"+urlVal, nil, &res); err != nil {
log.Error("unicom flowQry url(%v) error(%v)", d.unicomFlowExchangeURL+"?"+urlVal, err)
return
}
b, _ := json.Marshal(&res)
log.Info("unicom flowQry url(%v) response(%s)", d.unicomFlowExchangeURL+"?"+urlVal, b)
msg = res.Msg
if res.Code != "0000" {
err = ecode.String(res.Code)
log.Error("unicom flowQry url(%v) code(%v) msg(%v)", d.unicomFlowExchangeURL+"?"+urlVal, res.Code, res.Msg)
return
}
orderstatus = res.Orderstatus
return
}
// broadbandHTTPGet http get
func (d *Dao) broadbandHTTPGet(c context.Context, urlStr string, params url.Values, res interface{}) (err error) {
return d.wallHTTP(c, d.client, http.MethodGet, urlStr, params, res)
}
// broadbandHTTPPost http post
func (d *Dao) broadbandHTTPPost(c context.Context, urlStr string, params url.Values, res interface{}) (err error) {
return d.wallHTTP(c, d.client, http.MethodPost, urlStr, params, res)
}
// unicomHTTPGet http get
func (d *Dao) unicomHTTPGet(c context.Context, urlStr string, params url.Values, res interface{}) (err error) {
return d.wallHTTP(c, d.uclient, http.MethodGet, urlStr, params, res)
}
// wallHTTP http
func (d *Dao) wallHTTP(c context.Context, client *httpx.Client, method, urlStr string, params url.Values, res interface{}) (err error) {
var (
req *http.Request
)
ru := urlStr
if params != nil {
ru = urlStr + "?" + params.Encode()
}
switch method {
case http.MethodGet:
req, err = http.NewRequest(http.MethodGet, ru, nil)
default:
req, err = http.NewRequest(http.MethodPost, urlStr, strings.NewReader(params.Encode()))
}
if err != nil {
log.Error("unicom_http.NewRequest url(%s) error(%v)", urlStr+"?"+params.Encode(), err)
return
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("X-BACKEND-BILI-REAL-IP", "")
return d.client.Do(c, req, &res)
}
func (d *Dao) desEncrypt(src, key []byte) (string, error) {
block, err := des.NewCipher(key)
if err != nil {
return "", err
}
bs := block.BlockSize()
src = d.pkcs5Padding(src, bs)
if len(src)%bs != 0 {
return "", errors.New("Need a multiple of the blocksize")
}
out := make([]byte, len(src))
dst := out
for len(src) > 0 {
block.Encrypt(dst, src[:bs])
src = src[bs:]
dst = dst[bs:]
}
encodeString := base64.StdEncoding.EncodeToString(out)
return encodeString, nil
}
func (d *Dao) pkcs5Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
func (d *Dao) urlParams(v url.Values) string {
if v == nil {
return ""
}
var buf bytes.Buffer
keys := make([]string, 0, len(v))
for k := range v {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
vs := v[k]
prefix := k + "="
for _, v := range vs {
if buf.Len() > 0 {
buf.WriteByte('&')
}
buf.WriteString(prefix)
buf.WriteString(v)
}
}
return buf.String()
}
func (d *Dao) sign(params string) string {
str := strings.Replace(params, "&", "$", -1)
str2 := strings.Replace(str, "=", "$", -1)
mh := md5.Sum([]byte(_unicomSecurity + "$" + str2 + "$" + _unicomSecurity))
signparam := url.Values{}
signparam.Set("sign", base64.StdEncoding.EncodeToString(mh[:]))
return signparam.Encode()
}

View File

@@ -0,0 +1,345 @@
package unicom
import (
"context"
"fmt"
"go-common/app/interface/main/app-wall/model/unicom"
"go-common/library/cache/memcache"
"go-common/library/log"
)
const (
_prefix = "unicoms_user_%v"
_userbindkey = "unicoms_user_bind_%d"
_userpackkey = "unicom_user_pack_%d"
_userflowkey = "unicom_user_flow_%v"
_userflowlistkey = "unicom_user_flow_list"
_userflowWait = "u_flowwait_%d"
)
func keyUnicom(usermob string) string {
return fmt.Sprintf(_prefix, usermob)
}
func keyUserBind(mid int64) string {
return fmt.Sprintf(_userbindkey, mid)
}
func keyUserPack(id int64) string {
return fmt.Sprintf(_userpackkey, id)
}
func keyUserFlow(key string) string {
return fmt.Sprintf(_userflowkey, key)
}
func keyUserflowWait(phone int) string {
return fmt.Sprintf(_userflowWait, phone)
}
// AddUnicomCache
func (d *Dao) AddUnicomCache(c context.Context, usermob string, u []*unicom.Unicom) (err error) {
var (
key = keyUnicom(usermob)
conn = d.mc.Get(c)
)
if err = conn.Set(&memcache.Item{Key: key, Object: u, Flags: memcache.FlagJSON, Expiration: d.expire}); err != nil {
log.Error("addUnicomCache d.mc.Set(%s,%v) error(%v)", key, u, err)
}
conn.Close()
return
}
// UnicomCache
func (d *Dao) UnicomCache(c context.Context, usermob string) (u []*unicom.Unicom, err error) {
var (
key = keyUnicom(usermob)
conn = d.mc.Get(c)
r *memcache.Item
)
defer conn.Close()
if r, err = conn.Get(key); err != nil {
log.Error("unicomCache MemchDB.Get(%s) error(%v)", key, err)
return
}
if err = conn.Scan(r, &u); err != nil {
log.Error("r.Scan(%s) error(%v)", r.Value, err)
}
return
}
// UpdateUnicomCache
func (d *Dao) UpdateUnicomCache(c context.Context, usermob string, u *unicom.Unicom) (err error) {
var (
us []*unicom.Unicom
unicoms []*unicom.Unicom
uspid = map[int]struct{}{}
)
if u.Spid == 979 && u.TypeInt == 1 {
return d.DeleteUnicomCache(c, usermob)
}
if us, err = d.UnicomCache(c, usermob); err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
log.Error("d.UnicomCache error(%v)", err)
return
}
if len(us) > 0 {
for _, um := range us {
if um.Spid == 979 && um.TypeInt == 1 {
return d.DeleteUnicomCache(c, usermob)
}
tmp := &unicom.Unicom{}
*tmp = *um
if tmp.Spid == u.Spid {
tmp = u
uspid[u.Spid] = struct{}{}
}
unicoms = append(unicoms, tmp)
}
if _, ok := uspid[u.Spid]; !ok {
unicoms = append(unicoms, u)
}
if err = d.AddUnicomCache(c, usermob, unicoms); err != nil {
log.Error("d.AddUnicomCache error(%v)", err)
return
}
}
return
}
// DeleteUnicomCache
func (d *Dao) DeleteUnicomCache(c context.Context, usermob string) (err error) {
var (
key = keyUnicom(usermob)
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Delete(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
log.Error("unicomCache MemchDB.Delete(%s) error(%v)", key, err)
return
}
return
}
// UserBindCache user bind cache
func (d *Dao) UserBindCache(c context.Context, mid int64) (ub *unicom.UserBind, err error) {
var (
key = keyUserBind(mid)
conn = d.mc.Get(c)
r *memcache.Item
)
defer conn.Close()
if r, err = conn.Get(key); err != nil {
log.Error("UserBindCache MemchDB.Get(%s) error(%v)", key, err)
return
}
if err = conn.Scan(r, &ub); err != nil {
log.Error("r.Scan(%s) error(%v)", r.Value, err)
}
return
}
// AddUserBindCache add user user bind cache
func (d *Dao) AddUserBindCache(c context.Context, mid int64, ub *unicom.UserBind) (err error) {
var (
key = keyUserBind(mid)
conn = d.mc.Get(c)
)
if err = conn.Set(&memcache.Item{Key: key, Object: ub, Flags: memcache.FlagJSON, Expiration: 0}); err != nil {
log.Error("AddUserBindCache d.mc.Set(%s,%v) error(%v)", key, ub, err)
}
conn.Close()
return
}
// DeleteUserBindCache delete user bind cache
func (d *Dao) DeleteUserBindCache(c context.Context, mid int64) (err error) {
var (
key = keyUserBind(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("DeleteUserBindCache MemchDB.Delete(%s) error(%v)", key, err)
return
}
return
}
// UserPackCache user packs
func (d *Dao) UserPackCache(c context.Context, id int64) (res *unicom.UserPack, err error) {
var (
key = keyUserPack(id)
conn = d.mc.Get(c)
r *memcache.Item
)
defer conn.Close()
if r, err = conn.Get(key); err != nil {
log.Error("UserBindCache MemchDB.Get(%s) error(%v)", key, err)
return
}
if err = conn.Scan(r, &res); err != nil {
log.Error("r.Scan(%s) error(%v)", r.Value, err)
}
return
}
// AddUserPackCache add user pack cache
func (d *Dao) AddUserPackCache(c context.Context, id int64, u *unicom.UserPack) (err error) {
var (
key = keyUserPack(id)
conn = d.mc.Get(c)
)
if err = conn.Set(&memcache.Item{Key: key, Object: u, Flags: memcache.FlagJSON, Expiration: d.flowKeyExpired}); err != nil {
log.Error("AddUserPackCache d.mc.Set(%s,%v) error(%v)", key, u, err)
}
conn.Close()
return
}
// DeleteUserPackCache delete user pack cache
func (d *Dao) DeleteUserPackCache(c context.Context, id int64) (err error) {
var (
key = keyUserPack(id)
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Delete(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
log.Error("DeleteUserPackCache MemchDB.Delete(%s) error(%v)", key, err)
return
}
return
}
//UserFlowCache unicom flow cache
func (d *Dao) UserFlowCache(c context.Context, keyStr string) (err error) {
var (
key = keyUserFlow(keyStr)
conn = d.mc.Get(c)
r *memcache.Item
res struct{}
)
defer conn.Close()
if r, err = conn.Get(key); err != nil {
log.Error("UserFlowCache MemchDB.Get(%s) error(%v)", key, err)
return
}
if err = conn.Scan(r, &res); err != nil {
log.Error("r.Scan(%s) error(%v)", r.Value, err)
}
return
}
// AddUserFlowCache add user pack cache
func (d *Dao) AddUserFlowCache(c context.Context, keyStr string) (err error) {
var (
key = keyUserFlow(keyStr)
conn = d.mc.Get(c)
)
if err = conn.Set(&memcache.Item{Key: key, Object: struct{}{}, Flags: memcache.FlagJSON, Expiration: d.flowKeyExpired}); err != nil {
log.Error("AddUserPackCache d.mc.Set(%s) error(%v)", key, err)
}
conn.Close()
return
}
// DeleteUserPackCache delete user pack cache
func (d *Dao) DeleteUserFlowCache(c context.Context, keyStr string) (err error) {
var (
key = keyUserFlow(keyStr)
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Delete(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
log.Error("DeleteUserFlowCache MemchDB.Delete(%s) error(%v)", key, err)
return
}
return
}
//UserFlowListCache unicom flow cache
func (d *Dao) UserFlowListCache(c context.Context) (res map[string]*unicom.UnicomUserFlow, err error) {
var (
key = _userflowlistkey
conn = d.mc.Get(c)
r *memcache.Item
)
defer conn.Close()
if r, err = conn.Get(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
log.Error("UserFlowListCache MemchDB.Get(%s) error(%v)", key, err)
return
}
if err = conn.Scan(r, &res); err != nil {
log.Error("r.Scan(%s) error(%v)", r.Value, err)
}
return
}
// AddUserFlowListCache add user pack cache
func (d *Dao) AddUserFlowListCache(c context.Context, list map[string]*unicom.UnicomUserFlow) (err error) {
var (
key = _userflowlistkey
conn = d.mc.Get(c)
)
if err = conn.Set(&memcache.Item{Key: key, Object: list, Flags: memcache.FlagJSON, Expiration: d.flowKeyExpired}); err != nil {
log.Error("AddUserFlowListCache d.mc.Set(%s,%v) error(%v)", key, list, err)
}
conn.Close()
return
}
//UserFlowWaitCache unicom flow wait
func (d *Dao) UserFlowWaitCache(c context.Context, phone int) (err error) {
var (
key = keyUserflowWait(phone)
conn = d.mc.Get(c)
r *memcache.Item
res struct{}
)
defer conn.Close()
if r, err = conn.Get(key); err != nil {
log.Error("UserFlowWaitCache MemchDB.Get(%s) error(%v)", key, err)
return
}
if err = conn.Scan(r, &res); err != nil {
log.Error("r.Scan(%s) error(%v)", r.Value, err)
}
return
}
// AddUserFlowWaitCache add user flow wait
func (d *Dao) AddUserFlowWaitCache(c context.Context, phone int) (err error) {
var (
key = keyUserflowWait(phone)
conn = d.mc.Get(c)
)
if err = conn.Set(&memcache.Item{Key: key, Object: struct{}{}, Flags: memcache.FlagJSON, Expiration: d.flowWait}); err != nil {
log.Error("AddUserFlowWaitCache d.mc.Set(%s) error(%v)", key, err)
}
conn.Close()
return
}

View File

@@ -0,0 +1,55 @@
package unicom
import (
"context"
"fmt"
"time"
"go-common/app/interface/main/app-wall/model/unicom"
"go-common/library/database/elastic"
"go-common/library/log"
)
const (
_logUserKey = "log_user_action_91_%s"
)
func keyLogUser(now time.Time) string {
return fmt.Sprintf(_logUserKey, now.Format("2006_01"))
}
func timeToString(now time.Time) string {
return now.Format("2006-01-02 15:04:05")
}
// SearchUserBindLog unicom user bind log
func (d *Dao) SearchUserBindLog(ctx context.Context, mid int64, now time.Time) (ulogs []*unicom.UserLog, err error) {
var data struct {
Result []struct {
Ctime string `json:"ctime"`
ExtraData string `json:"extra_data"`
} `json:"result"`
}
var (
endtime = now.AddDate(0, -1, 0)
endWeekTime = now.AddDate(0, 0, -7)
)
req := d.es.NewRequest("log_user_action")
req.Index(keyLogUser(now), keyLogUser(endtime)).WhereEq("mid", mid).WhereIn("action", []string{"unicom_userpack_add", "unicom_userpack_deduct"}).
WhereRange("ctime", timeToString(endWeekTime), timeToString(now), elastic.RangeScopeLcRc).Order("ctime", "desc").
Pn(1).Ps(2000)
if err = req.Scan(ctx, &data); err != nil {
log.Error("search user bind params(%s) error(%v)", req.Params(), err)
return
}
for _, d := range data.Result {
ulog := &unicom.UserLog{}
if err = ulog.UserLogJSONChange(d.ExtraData); err != nil {
log.Error("ulog json change error(%v)", err)
continue
}
ulog.Ctime = d.Ctime
ulogs = append(ulogs, ulog)
}
return
}

View File

@@ -0,0 +1,442 @@
package unicom
import (
"context"
"database/sql"
"time"
"go-common/app/interface/main/app-wall/conf"
"go-common/app/interface/main/app-wall/model/unicom"
"go-common/library/cache/memcache"
"go-common/library/database/elastic"
xsql "go-common/library/database/sql"
"go-common/library/log"
httpx "go-common/library/net/http/blademaster"
)
const (
//unicom
_inOrderSyncSQL = `INSERT IGNORE INTO unicom_order (usermob,cpid,spid,type,ordertime,canceltime,endtime,channelcode,province,area,ordertype,videoid,ctime,mtime)
VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE cpid=?,spid=?,type=?,ordertime=?,canceltime=?,endtime=?,channelcode=?,province=?,area=?,ordertype=?,videoid=?,mtime=?`
_inAdvanceSyncSQL = `INSERT IGNORE INTO unicom_order_advance (usermob,userphone,cpid,spid,ordertime,channelcode,province,area,ctime,mtime)
VALUES(?,?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE cpid=?,spid=?,ordertime=?,channelcode=?,province=?,area=?,mtime=?`
_upOrderFlowSQL = `UPDATE unicom_order SET time=?,flowbyte=?,mtime=? WHERE usermob=?`
_orderUserSyncSQL = `SELECT usermob,cpid,spid,type,ordertime,canceltime,endtime,channelcode,province,area,ordertype,videoid,time,flowbyte FROM unicom_order WHERE usermob=?
ORDER BY type DESC`
_inIPSyncSQL = `INSERT IGNORE INTO unicom_ip (ipbegion,ipend,provinces,isopen,opertime,sign,ctime,mtime) VALUES(?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE
ipbegion=?,ipend=?,provinces=?,isopen=?,opertime=?,sign=?,mtime=?`
_ipSyncSQL = `SELECT ipbegion,ipend FROM unicom_ip WHERE isopen=1`
//pack
_inPackSQL = `INSERT IGNORE INTO unicom_pack (usermob,mid) VALUES(?,?)`
_packSQL = `SELECT usermob,mid FROM unicom_pack WHERE usermob=?`
// update unicom ip
_inUnicomIPSyncSQL = `INSERT IGNORE INTO unicom_ip (ipbegion,ipend,isopen,ctime,mtime) VALUES(?,?,?,?,?) ON DUPLICATE KEY UPDATE
ipbegion=?,ipend=?,isopen=?,mtime=?`
_upUnicomIPSQL = `UPDATE unicom_ip SET isopen=?,mtime=? WHERE ipbegion=? AND ipend=?`
// unicom integral change
_inUserBindSQL = `INSERT IGNORE INTO unicom_user_bind (usermob,phone,mid,state,integral,flow) VALUES(?,?,?,?,?,?) ON DUPLICATE KEY UPDATE
phone=?,state=?`
_userBindSQL = `SELECT usermob,phone,mid,state,integral,flow,monthlytime FROM unicom_user_bind WHERE state=1 AND mid=?`
_userBindPhoneMidSQL = `SELECT mid FROM unicom_user_bind WHERE phone=? AND state=1`
_upUserIntegralSQL = `UPDATE unicom_user_bind SET integral=?,flow=? WHERE phone=? AND mid=?`
_userPacksSQL = `SELECT id,ptype,pdesc,amount,capped,integral,param FROM unicom_user_packs WHERE state=1`
_userPacksByIDSQL = `SELECT id,ptype,pdesc,amount,capped,integral,param,state FROM unicom_user_packs WHERE id=?`
_upUserPacksSQL = `UPDATE unicom_user_packs SET amount=?,state=? WHERE id=?`
_inUserPackLogSQL = `INSERT INTO unicom_user_packs_log (phone,usermob,mid,request_no,ptype,integral,pdesc) VALUES (?,?,?,?,?,?,?)`
_userBindOldSQL = `SELECT usermob,phone,mid,state,integral,flow FROM unicom_user_bind WHERE phone=? ORDER BY mtime DESC limit 1`
_userPacksLogSQL = `SELECT phone,integral,ptype,pdesc FROM unicom_user_packs_log WHERE mtime>=? AND mtime<?`
)
type Dao struct {
db *xsql.DB
client *httpx.Client
uclient *httpx.Client
//unicom
inOrderSyncSQL *xsql.Stmt
inAdvanceSyncSQL *xsql.Stmt
upOrderFlowSQL *xsql.Stmt
orderUserSyncSQL *xsql.Stmt
inIPSyncSQL *xsql.Stmt
ipSyncSQL *xsql.Stmt
// unicom integral change
inUserBindSQL *xsql.Stmt
userBindSQL *xsql.Stmt
userBindPhoneMidSQL *xsql.Stmt
upUserIntegralSQL *xsql.Stmt
userPacksSQL *xsql.Stmt
userPacksByIDSQL *xsql.Stmt
upUserPacksSQL *xsql.Stmt
inUserPackLogSQL *xsql.Stmt
userBindOldSQL *xsql.Stmt
//pack
inPackSQL *xsql.Stmt
packSQL *xsql.Stmt
// memcache
mc *memcache.Pool
expire int32
flowKeyExpired int32
flowWait int32
// unicom url
unicomIPURL string
unicomFlowExchangeURL string
// order url
orderURL string
ordercancelURL string
sendsmscodeURL string
smsNumberURL string
// elastic
es *elastic.Elastic
}
func New(c *conf.Config) (d *Dao) {
d = &Dao{
db: xsql.NewMySQL(c.MySQL.Show),
client: httpx.NewClient(conf.Conf.HTTPBroadband),
uclient: httpx.NewClient(conf.Conf.HTTPUnicom),
// unicom url
unicomIPURL: c.Host.Unicom + _unicomIPURL,
unicomFlowExchangeURL: c.Host.UnicomFlow + _unicomFlowExchangeURL,
// memcache
mc: memcache.NewPool(c.Memcache.Operator.Config),
expire: int32(time.Duration(c.Memcache.Operator.Expire) / time.Second),
flowKeyExpired: int32(time.Duration(c.Unicom.KeyExpired) / time.Second),
flowWait: int32(time.Duration(c.Unicom.FlowWait) / time.Second),
// order url
orderURL: c.Host.Broadband + _orderURL,
ordercancelURL: c.Host.Broadband + _ordercancelURL,
sendsmscodeURL: c.Host.Broadband + _sendsmscodeURL,
smsNumberURL: c.Host.Broadband + _smsNumberURL,
// elastic
es: elastic.NewElastic(nil),
}
d.inOrderSyncSQL = d.db.Prepared(_inOrderSyncSQL)
d.inAdvanceSyncSQL = d.db.Prepared(_inAdvanceSyncSQL)
d.upOrderFlowSQL = d.db.Prepared(_upOrderFlowSQL)
d.orderUserSyncSQL = d.db.Prepared(_orderUserSyncSQL)
d.inIPSyncSQL = d.db.Prepared(_inIPSyncSQL)
d.ipSyncSQL = d.db.Prepared(_ipSyncSQL)
// unicom integral change
d.inUserBindSQL = d.db.Prepared(_inUserBindSQL)
d.userBindSQL = d.db.Prepared(_userBindSQL)
d.userBindPhoneMidSQL = d.db.Prepared(_userBindPhoneMidSQL)
d.upUserIntegralSQL = d.db.Prepared(_upUserIntegralSQL)
d.userPacksSQL = d.db.Prepared(_userPacksSQL)
d.upUserPacksSQL = d.db.Prepared(_upUserPacksSQL)
d.userPacksByIDSQL = d.db.Prepared(_userPacksByIDSQL)
d.inUserPackLogSQL = d.db.Prepared(_inUserPackLogSQL)
d.userBindOldSQL = d.db.Prepared(_userBindOldSQL)
//pack
d.inPackSQL = d.db.Prepared(_inPackSQL)
d.packSQL = d.db.Prepared(_packSQL)
return
}
// InOrdersSync insert OrdersSync
func (d *Dao) InOrdersSync(ctx context.Context, usermob string, u *unicom.UnicomJson, now time.Time) (row int64, err error) {
res, err := d.inOrderSyncSQL.Exec(ctx, usermob,
u.Cpid, u.Spid, u.TypeInt, u.Ordertime, u.Canceltime, u.Endtime,
u.Channelcode, u.Province, u.Area, u.Ordertypes, u.Videoid, now, now,
u.Cpid, u.Spid, u.TypeInt, u.Ordertime, u.Canceltime, u.Endtime,
u.Channelcode, u.Province, u.Area, u.Ordertypes, u.Videoid, now)
if err != nil {
log.Error("d.inOrderSyncSQL.Exec error(%v)", err)
return
}
utmp := &unicom.Unicom{}
utmp.UnicomJSONTOUincom(usermob, u)
if err = d.UpdateUnicomCache(ctx, usermob, utmp); err != nil {
log.Error("d.UpdateUnicomCache usermob(%v) error(%v)", usermob, err)
return 0, err
}
return res.RowsAffected()
}
// InAdvanceSync insert AdvanceSync
func (d *Dao) InAdvanceSync(ctx context.Context, usermob string, u *unicom.UnicomJson, now time.Time) (row int64, err error) {
res, err := d.inAdvanceSyncSQL.Exec(ctx, usermob, u.Userphone,
u.Cpid, u.Spid, u.Ordertime, u.Channelcode, u.Province, u.Area, now, now,
u.Cpid, u.Spid, u.Ordertime, u.Channelcode, u.Province, u.Area, now)
if err != nil {
log.Error("d.inAdvanceSyncSQL.Exec error(%v)", err)
return 0, err
}
return res.RowsAffected()
}
// FlowSync update OrdersSync
func (d *Dao) FlowSync(ctx context.Context, flowbyte int, usermob, time string, now time.Time) (row int64, err error) {
res, err := d.upOrderFlowSQL.Exec(ctx, time, flowbyte, now, usermob)
if err != nil {
log.Error("d.upOrderFlowSQL.Exec error(%v)", err)
return 0, err
}
return res.RowsAffected()
}
// OrdersUserFlow select user OrdersSync
func (d *Dao) OrdersUserFlow(ctx context.Context, usermob string) (res []*unicom.Unicom, err error) {
rows, err := d.orderUserSyncSQL.Query(ctx, usermob)
if err != nil {
log.Error("query error (%v)", err)
return
}
defer rows.Close()
for rows.Next() {
u := &unicom.Unicom{}
if err = rows.Scan(&u.Usermob, &u.Cpid, &u.Spid, &u.TypeInt, &u.Ordertime, &u.Canceltime, &u.Endtime, &u.Channelcode, &u.Province,
&u.Area, &u.Ordertypes, &u.Videoid, &u.Time, &u.Flowbyte); err != nil {
log.Error("OrdersUserFlow row.Scan err (%v)", err)
return
}
u.UnicomChange()
res = append(res, u)
}
return
}
// InIPSync insert IpSync
func (d *Dao) InIPSync(ctx context.Context, u *unicom.UnicomIpJson, now time.Time) (row int64, err error) {
res, err := d.inIPSyncSQL.Exec(ctx, u.Ipbegin, u.Ipend, u.Provinces, u.Isopen, u.Opertime, u.Sign, now, now,
u.Ipbegin, u.Ipend, u.Provinces, u.Isopen, u.Opertime, u.Sign, now)
if err != nil {
log.Error("d.inIPSyncSQL.Exec error(%v)", err)
return 0, err
}
return res.RowsAffected()
}
// InPack insert Privilege pack
func (d *Dao) InPack(ctx context.Context, usermob string, mid int64) (row int64, err error) {
res, err := d.inPackSQL.Exec(ctx, usermob, mid)
if err != nil {
log.Error("d.inPackSQL.Exec error(%v)", err)
return 0, err
}
return res.RowsAffected()
}
// Pack select Privilege pack
func (d *Dao) Pack(ctx context.Context, usermobStr string) (res map[string]map[int64]struct{}, err error) {
row := d.packSQL.QueryRow(ctx, usermobStr)
var (
usermob string
mid int64
)
res = map[string]map[int64]struct{}{}
if err = row.Scan(&usermob, &mid); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("OrdersUserFlow rows.Scan err (%v)", err)
}
}
if user, ok := res[usermob]; !ok {
res[usermob] = map[int64]struct{}{
mid: struct{}{},
}
} else {
user[mid] = struct{}{}
}
return
}
// IPSync select all ipSync
func (d *Dao) IPSync(ctx context.Context) (res []*unicom.UnicomIP, err error) {
rows, err := d.ipSyncSQL.Query(ctx)
if err != nil {
log.Error("query error (%v)", err)
return
}
defer rows.Close()
res = []*unicom.UnicomIP{}
for rows.Next() {
u := &unicom.UnicomIP{}
if err = rows.Scan(&u.Ipbegin, &u.Ipend); err != nil {
log.Error("rows.Scan error(%v)", err)
return
}
u.UnicomIPChange()
res = append(res, u)
}
return
}
// InUnicomIPSync insert or update unicom_ip
func (d *Dao) InUnicomIPSync(tx *xsql.Tx, u *unicom.UnicomIP, now time.Time) (row int64, err error) {
res, err := tx.Exec(_inUnicomIPSyncSQL, u.Ipbegin, u.Ipend, 1, now, now,
u.Ipbegin, u.Ipend, 1, now)
if err != nil {
log.Error("tx.inUnicomIPSyncSQL.Exec error(%v)", err)
return 0, err
}
return res.RowsAffected()
}
// UpUnicomIP update unicom_ip state
func (d *Dao) UpUnicomIP(tx *xsql.Tx, ipstart, ipend, state int, now time.Time) (row int64, err error) {
res, err := tx.Exec(_upUnicomIPSQL, state, now, ipstart, ipend)
if err != nil {
log.Error("tx.upUnicomIPSQL.Exec error(%v)", err)
return 0, err
}
return res.RowsAffected()
}
// InUserBind unicom insert user bind
func (d *Dao) InUserBind(ctx context.Context, ub *unicom.UserBind) (row int64, err error) {
res, err := d.inUserBindSQL.Exec(ctx, ub.Usermob, ub.Phone, ub.Mid, ub.State, ub.Integral, ub.Flow, ub.Phone, ub.State)
if err != nil {
log.Error("insert user bind error(%v)", err)
return
}
return res.RowsAffected()
}
// UserBind unicom select user bind
func (d *Dao) UserBind(ctx context.Context, mid int64) (res *unicom.UserBind, err error) {
row := d.userBindSQL.QueryRow(ctx, mid)
if row == nil {
log.Error("userBindSQL is null")
return
}
res = &unicom.UserBind{}
if err = row.Scan(&res.Usermob, &res.Phone, &res.Mid, &res.State, &res.Integral, &res.Flow, &res.Monthly); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("userBindSQL row.Scan error(%v)", err)
}
res = nil
return
}
return
}
// UserPacks user pack list
func (d *Dao) UserPacks(ctx context.Context) (res []*unicom.UserPack, err error) {
rows, err := d.userPacksSQL.Query(ctx)
if err != nil {
log.Error("user pack sql error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
u := &unicom.UserPack{}
if err = rows.Scan(&u.ID, &u.Type, &u.Desc, &u.Amount, &u.Capped, &u.Integral, &u.Param); err != nil {
log.Error("user pack sql error(%v)", err)
return
}
res = append(res, u)
}
return
}
// UserPackByID user pack by id
func (d *Dao) UserPackByID(ctx context.Context, id int64) (res map[int64]*unicom.UserPack, err error) {
res = map[int64]*unicom.UserPack{}
row := d.userPacksByIDSQL.QueryRow(ctx, id)
if row == nil {
log.Error("user pack sql is null")
return
}
u := &unicom.UserPack{}
if err = row.Scan(&u.ID, &u.Type, &u.Desc, &u.Amount, &u.Capped, &u.Integral, &u.Param, &u.State); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("userPacksByIDSQL row.Scan error(%v)", err)
}
return
}
res[id] = u
return
}
// UpUserPacks update user packs
func (d *Dao) UpUserPacks(ctx context.Context, u *unicom.UserPack, id int64) (row int64, err error) {
res, err := d.upUserPacksSQL.Exec(ctx, u.Amount, u.State, id)
if err != nil {
log.Error("update user pack sql error(%v)", err)
return 0, err
}
return res.RowsAffected()
}
// UpUserIntegral update unicom user integral
func (d *Dao) UpUserIntegral(ctx context.Context, ub *unicom.UserBind) (row int64, err error) {
res, err := d.upUserIntegralSQL.Exec(ctx, ub.Integral, ub.Flow, ub.Phone, ub.Mid)
if err != nil {
log.Error("update user integral sql error(%v)", err)
return 0, err
}
return res.RowsAffected()
}
// UserBindPhoneMid mid by phone
func (d *Dao) UserBindPhoneMid(ctx context.Context, phone string) (mid int64, err error) {
row := d.userBindPhoneMidSQL.QueryRow(ctx, phone)
if row == nil {
log.Error("user pack sql is null")
return
}
if err = row.Scan(&mid); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("userPacksByIDSQL row.Scan error(%v)", err)
}
return
}
return
}
// InUserPackLog insert unicom user pack log
func (d *Dao) InUserPackLog(ctx context.Context, u *unicom.UserPackLog) (row int64, err error) {
res, err := d.inUserPackLogSQL.Exec(ctx, u.Phone, u.Usermob, u.Mid, u.RequestNo, u.Type, u.Integral, u.Desc)
if err != nil {
log.Error("insert user pack log integral sql error(%v)", err)
return 0, err
}
return res.RowsAffected()
}
// UserBindOld user by phone
func (d *Dao) UserBindOld(ctx context.Context, phone string) (res *unicom.UserBind, err error) {
row := d.userBindOldSQL.QueryRow(ctx, phone)
if row == nil {
log.Error("user bind old sql is null")
return
}
res = &unicom.UserBind{}
if err = row.Scan(&res.Usermob, &res.Phone, &res.Mid, &res.State, &res.Integral, &res.Flow); err != nil {
log.Error("userBindSQL row.Scan error(%v)", err)
res = nil
return
}
return
}
// UserPacksLog user pack logs
func (d *Dao) UserPacksLog(ctx context.Context, start, end time.Time) (res []*unicom.UserPackLog, err error) {
rows, err := d.db.Query(ctx, _userPacksLogSQL, start, end)
if err != nil {
log.Error("query error (%v)", err)
return
}
defer rows.Close()
for rows.Next() {
u := &unicom.UserPackLog{}
if err = rows.Scan(&u.Phone, &u.Integral, &u.Type, &u.UserDesc); err != nil {
log.Error("user packs log sql error(%v)", err)
return
}
res = append(res, u)
}
err = rows.Err()
return
}
// BeginTran begin a transacition
func (d *Dao) BeginTran(ctx context.Context) (tx *xsql.Tx, err error) {
return d.db.Begin(ctx)
}

View File

@@ -0,0 +1,547 @@
package unicom
import (
"context"
"flag"
"os"
"testing"
"time"
"go-common/app/interface/main/app-wall/conf"
"go-common/app/interface/main/app-wall/model/unicom"
. "github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func ctx() context.Context {
return context.Background()
}
func init() {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.app-svr.app-wall")
flag.Set("conf_token", "yvxLjLpTFMlbBbc9yWqysKLMigRHaaiJ")
flag.Set("tree_id", "2283")
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)
}
d = New(conf.Conf)
time.Sleep(time.Second)
}
func TestOrder(t *testing.T) {
Convey("unicom Order", t, func() {
_, _, err := d.Order(ctx(), "", "", 0)
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestCancelOrder(t *testing.T) {
Convey("unicom CancelOrder", t, func() {
_, _, err := d.CancelOrder(ctx(), "")
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestOrdersUserFlow(t *testing.T) {
Convey("unicom OrdersUserFlow", t, func() {
_, err := d.OrdersUserFlow(ctx(), "")
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestPack(t *testing.T) {
Convey("unicom Pack", t, func() {
_, err := d.Pack(ctx(), "")
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestIPSync(t *testing.T) {
Convey("unicom IPSync", t, func() {
_, err := d.IPSync(ctx())
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestUnicomIP(t *testing.T) {
Convey("unicom UnicomIP", t, func() {
_, err := d.UnicomIP(ctx(), time.Now())
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestSendSmsCode(t *testing.T) {
Convey("unicom SendSmsCode", t, func() {
_, err := d.SendSmsCode(ctx(), "1")
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestSmsNumber(t *testing.T) {
Convey("unicom SmsNumber", t, func() {
_, _, err := d.SmsNumber(ctx(), "1", 1)
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestFlowExchange(t *testing.T) {
Convey("unicom FlowExchange", t, func() {
_, _, _, err := d.FlowExchange(ctx(), 1, "1", 1, time.Now())
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestPhoneVerification(t *testing.T) {
Convey("unicom PhoneVerification", t, func() {
_, err := d.PhoneVerification(ctx(), "1", 1, time.Now())
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestFlowPre(t *testing.T) {
Convey("unicom FlowPre", t, func() {
_, err := d.FlowPre(ctx(), 1, 1, time.Now())
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestFlowQry(t *testing.T) {
Convey("unicom FlowQry", t, func() {
_, _, err := d.FlowQry(ctx(), 1, 1, "1", "1", time.Now())
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestAddUnicomCache(t *testing.T) {
Convey("unicom AddUnicomCache", t, func() {
err := d.AddUnicomCache(ctx(), "1", nil)
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestUnicomCache(t *testing.T) {
Convey("unicom UnicomCache", t, func() {
_, err := d.UnicomCache(ctx(), "1")
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestUpdateUnicomCache(t *testing.T) {
Convey("unicom UpdateUnicomCache", t, func() {
err := d.UpdateUnicomCache(ctx(), "1", &unicom.Unicom{})
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestDeleteUnicomCache(t *testing.T) {
Convey("unicom DeleteUnicomCache", t, func() {
err := d.DeleteUnicomCache(ctx(), "1")
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestUserBindCache(t *testing.T) {
Convey("unicom UserBindCache", t, func() {
_, err := d.UserBindCache(ctx(), 1)
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestAddUserBindCache(t *testing.T) {
Convey("unicom AddUserBindCache", t, func() {
err := d.AddUserBindCache(ctx(), 1, nil)
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestDeleteUserBindCache(t *testing.T) {
Convey("unicom DeleteUserBindCache", t, func() {
err := d.DeleteUserBindCache(ctx(), 1)
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestUserPackCache(t *testing.T) {
Convey("unicom UserPackCache", t, func() {
_, err := d.UserPackCache(ctx(), 1)
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestAddUserPackCache(t *testing.T) {
Convey("unicom AddUserPackCache", t, func() {
err := d.AddUserPackCache(ctx(), 1, nil)
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestDeleteUserPackCache(t *testing.T) {
Convey("unicom DeleteUserPackCache", t, func() {
err := d.DeleteUserPackCache(ctx(), 1)
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestUserFlowCache(t *testing.T) {
Convey("unicom UserFlowCache", t, func() {
err := d.UserFlowCache(ctx(), "1")
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestAddUserFlowCache(t *testing.T) {
Convey("unicom AddUserFlowCache", t, func() {
err := d.AddUserFlowCache(ctx(), "1")
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestDeleteUserFlowCache(t *testing.T) {
Convey("unicom DeleteUserFlowCache", t, func() {
err := d.DeleteUserFlowCache(ctx(), "1")
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestUserFlowListCache(t *testing.T) {
Convey("unicom UserFlowListCache", t, func() {
_, err := d.UserFlowListCache(ctx())
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestAddUserFlowListCache(t *testing.T) {
Convey("unicom AddUserFlowListCache", t, func() {
err := d.AddUserFlowListCache(ctx(), nil)
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestUserFlowWaitCache(t *testing.T) {
Convey("unicom UserFlowWaitCache", t, func() {
err := d.UserFlowWaitCache(ctx(), 1)
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestAddUserFlowWaitCache(t *testing.T) {
Convey("unicom AddUserFlowWaitCache", t, func() {
err := d.AddUserFlowWaitCache(ctx(), 1)
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestSearchUserBindLog(t *testing.T) {
Convey("unicom SearchUserBindLog", t, func() {
_, err := d.SearchUserBindLog(ctx(), 1, time.Now())
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestInOrdersSync(t *testing.T) {
Convey("unicom InOrdersSync", t, func() {
_, err := d.InOrdersSync(ctx(), "", &unicom.UnicomJson{}, time.Now())
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestInAdvanceSync(t *testing.T) {
Convey("unicom InAdvanceSync", t, func() {
_, err := d.InAdvanceSync(ctx(), "", &unicom.UnicomJson{}, time.Now())
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestFlowSync(t *testing.T) {
Convey("unicom FlowSync", t, func() {
_, err := d.FlowSync(ctx(), 1, "", "", time.Now())
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestInIPSync(t *testing.T) {
Convey("unicom InIPSync", t, func() {
_, err := d.InIPSync(ctx(), &unicom.UnicomIpJson{}, time.Now())
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestInPack(t *testing.T) {
Convey("unicom InPack", t, func() {
_, err := d.InPack(ctx(), "", 1)
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestInUnicomIPSync(t *testing.T) {
Convey("unicom InUnicomIPSync", t, func() {
tx, _ := d.BeginTran(ctx())
_, err := d.InUnicomIPSync(tx, &unicom.UnicomIP{}, time.Now())
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestUpUnicomIP(t *testing.T) {
Convey("unicom UpUnicomIP", t, func() {
tx, _ := d.BeginTran(ctx())
_, err := d.UpUnicomIP(tx, 1, 1, 1, time.Now())
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestInUserBind(t *testing.T) {
Convey("unicom InUserBind", t, func() {
_, err := d.InUserBind(ctx(), &unicom.UserBind{})
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestUserBind(t *testing.T) {
Convey("unicom UserBind", t, func() {
_, err := d.UserBind(ctx(), 1)
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestUserPacks(t *testing.T) {
Convey("unicom UserPacks", t, func() {
_, err := d.UserPacks(ctx())
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestUserPackByID(t *testing.T) {
Convey("unicom UserPackByID", t, func() {
_, err := d.UserPackByID(ctx(), 1)
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestUpUserPacks(t *testing.T) {
Convey("unicom UpUserPacks", t, func() {
_, err := d.UpUserPacks(ctx(), &unicom.UserPack{}, 1)
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestUpUserIntegral(t *testing.T) {
Convey("unicom UpUserIntegral", t, func() {
_, err := d.UpUserIntegral(ctx(), &unicom.UserBind{})
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestUserBindPhoneMid(t *testing.T) {
Convey("unicom UserBindPhoneMid", t, func() {
_, err := d.UserBindPhoneMid(ctx(), "")
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestInUserPackLog(t *testing.T) {
Convey("unicom InUserPackLog", t, func() {
_, err := d.InUserPackLog(ctx(), &unicom.UserPackLog{})
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestUserBindOld(t *testing.T) {
Convey("unicom UserBindOld", t, func() {
_, err := d.UserBindOld(ctx(), "")
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestUserPacksLog(t *testing.T) {
Convey("unicom UserPacksLog", t, func() {
_, err := d.UserPacksLog(ctx(), time.Now(), time.Now())
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestBeginTran(t *testing.T) {
Convey("unicom BeginTran", t, func() {
_, err := d.BeginTran(ctx())
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestBroadbandHTTPGet(t *testing.T) {
Convey("unicom broadbandHTTPGet", t, func() {
err := d.broadbandHTTPGet(ctx(), "", nil, nil)
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestBroadbandHTTPPost(t *testing.T) {
Convey("unicom broadbandHTTPPost", t, func() {
err := d.broadbandHTTPPost(ctx(), "", nil, nil)
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestUnicomHTTPGet(t *testing.T) {
Convey("unicom unicomHTTPGet", t, func() {
err := d.unicomHTTPGet(ctx(), "", nil, nil)
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestWallHTTP(t *testing.T) {
Convey("unicom wallHTTP", t, func() {
err := d.wallHTTP(ctx(), nil, "", "", nil, nil)
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestDesEncrypt(t *testing.T) {
Convey("unicom desEncrypt", t, func() {
_, err := d.desEncrypt([]byte{1}, []byte{1})
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestPkcs5Padding(t *testing.T) {
Convey("unicom pkcs5Padding", t, func() {
d.pkcs5Padding([]byte{1}, 1)
// err = nil
So(nil, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestUrlParams(t *testing.T) {
Convey("unicom urlParams", t, func() {
d.urlParams(nil)
// err = nil
So(nil, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestSign(t *testing.T) {
Convey("unicom sign", t, func() {
d.sign("")
// err = nil
So(nil, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}

View File

@@ -0,0 +1,47 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["wall_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["wall.go"],
importpath = "go-common/app/interface/main/app-wall/dao/wall",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//app/interface/main/app-wall/model/wall:go_default_library",
"//library/database/sql:go_default_library",
"//library/log:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,51 @@
package wall
import (
"context"
"go-common/app/interface/main/app-wall/conf"
"go-common/app/interface/main/app-wall/model/wall"
"go-common/library/database/sql"
"go-common/library/log"
)
const (
//wall
_wallSQL = "SELECT logo,download,name,package,size,remark FROM wall WHERE state=1 ORDER BY rank DESC"
)
type Dao struct {
db *sql.DB
wallSQL *sql.Stmt
}
func New(c *conf.Config) (d *Dao) {
d = &Dao{
db: sql.NewMySQL(c.MySQL.Show),
}
d.wallSQL = d.db.Prepared(_wallSQL)
return
}
func (d *Dao) WallAll(ctx context.Context) (res []*wall.Wall, err error) {
rows, err := d.wallSQL.Query(ctx)
if err != nil {
log.Error("query error (%v)", err)
return
}
defer rows.Close()
res = []*wall.Wall{}
for rows.Next() {
a := &wall.Wall{}
if err = rows.Scan(&a.Logo, &a.Download, &a.Name, &a.Package, &a.Size, &a.Remark); err != nil {
log.Error("rows.Scan err (%v)", err)
return
}
res = append(res, a)
}
return
}
func (d *Dao) Ping(c context.Context) (err error) {
return d.db.Ping(c)
}

View File

@@ -0,0 +1,37 @@
package wall
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-wall/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func ctx() context.Context {
return context.Background()
}
func init() {
dir, _ := filepath.Abs("../../cmd/app-wall-test.toml")
flag.Set("conf", dir)
conf.Init()
d = New(conf.Conf)
time.Sleep(time.Second)
}
func TestWallAll(t *testing.T) {
Convey("WallAll", t, func() {
res, err := d.WallAll(ctx())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1,61 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"http.go",
"ip.go",
"local.go",
"mobile.go",
"offer.go",
"operator.go",
"telecom.go",
"unicom.go",
"wall.go",
],
importpath = "go-common/app/interface/main/app-wall/http",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//app/interface/main/app-wall/dao/padding:go_default_library",
"//app/interface/main/app-wall/model:go_default_library",
"//app/interface/main/app-wall/model/mobile:go_default_library",
"//app/interface/main/app-wall/model/telecom:go_default_library",
"//app/interface/main/app-wall/model/unicom:go_default_library",
"//app/interface/main/app-wall/service/mobile:go_default_library",
"//app/interface/main/app-wall/service/offer:go_default_library",
"//app/interface/main/app-wall/service/operator:go_default_library",
"//app/interface/main/app-wall/service/ping:go_default_library",
"//app/interface/main/app-wall/service/telecom:go_default_library",
"//app/interface/main/app-wall/service/unicom:go_default_library",
"//app/interface/main/app-wall/service/wall: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/auth:go_default_library",
"//library/net/http/blademaster/middleware/proxy:go_default_library",
"//library/net/http/blademaster/middleware/verify:go_default_library",
"//library/net/http/blademaster/render:go_default_library",
"//library/net/metadata:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,160 @@
package http
import (
"net/http"
"go-common/app/interface/main/app-wall/conf"
"go-common/app/interface/main/app-wall/service/mobile"
"go-common/app/interface/main/app-wall/service/offer"
"go-common/app/interface/main/app-wall/service/operator"
pingSvr "go-common/app/interface/main/app-wall/service/ping"
"go-common/app/interface/main/app-wall/service/telecom"
"go-common/app/interface/main/app-wall/service/unicom"
"go-common/app/interface/main/app-wall/service/wall"
"go-common/library/ecode"
log "go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/middleware/auth"
"go-common/library/net/http/blademaster/middleware/proxy"
"go-common/library/net/http/blademaster/middleware/verify"
"go-common/library/net/http/blademaster/render"
)
var (
// depend service
verifySvc *verify.Verify
authSvc *auth.Auth
// self service
wallSvc *wall.Service
offerSvc *offer.Service
unicomSvc *unicom.Service
mobileSvc *mobile.Service
pingSvc *pingSvr.Service
telecomSvc *telecom.Service
operatorSvc *operator.Service
)
func Init(c *conf.Config) {
initService(c)
// init external router
engineOut := bm.DefaultServer(c.BM.Outer)
outerRouter(engineOut)
// init Outer server
if err := engineOut.Start(); err != nil {
log.Error("engineOut.Start() error(%v)", err)
panic(err)
}
}
// initService init services.
func initService(c *conf.Config) {
verifySvc = verify.New(nil)
authSvc = auth.New(&auth.Config{DisableCSRF: true})
// init self service
wallSvc = wall.New(c)
offerSvc = offer.New(c)
unicomSvc = unicom.New(c)
mobileSvc = mobile.New(c)
pingSvc = pingSvr.New(c)
telecomSvc = telecom.New(c)
operatorSvc = operator.New(c)
}
func outerRouter(e *bm.Engine) {
e.Ping(ping)
// formal api
proxyHandler := proxy.NewZoneProxy("sh004", "http://sh001-app.bilibili.com")
w := e.Group("/x/wall")
{
w.GET("/get", walls)
op := w.Group("/operator", authSvc.Guest)
{
op.GET("/ip", userOperatorIP)
op.GET("/m/ip", mOperatorIP)
op.GET("/reddot", reddot)
}
of := w.Group("/offer")
{
of.GET("/exist", wallExist)
of.POST("/click/shike", proxyHandler, wallShikeClick)
of.GET("/click/dotinapp", wallDotinappClick)
of.GET("/click/gdt", wallGdtClick)
of.GET("/click/toutiao", wallToutiaoClick)
of.POST("/active", proxyHandler, verifySvc.Verify, wallActive)
of.GET("/active/test", wallTestActive)
of.POST("/active2", proxyHandler, verifySvc.Verify, wallActive2)
}
uc := w.Group("/unicom", proxyHandler)
{
// unicomSync
uc.POST("/orders", ordersSync)
uc.POST("/advance", advanceSync)
uc.POST("/flow", flowSync)
uc.POST("/ip", inIPSync)
// unicom
uc.GET("/userflow", verifySvc.Verify, userFlow)
uc.GET("/user/userflow", bm.CORS(), userFlowState)
uc.GET("/userstate", verifySvc.Verify, userState)
uc.GET("/state", verifySvc.Verify, unicomState)
uc.GET("/m/state", unicomStateM)
uc.POST("/pack", authSvc.User, bm.CORS(), pack)
uc.GET("/userip", bm.CORS(), isUnciomIP)
uc.GET("/user/ip", bm.CORS(), userUnciomIP)
uc.POST("/order/pay", bm.CORS(), orderPay)
uc.POST("/order/cancel", bm.CORS(), orderCancel)
uc.POST("/order/smscode", authSvc.Guest, bm.CORS(), smsCode)
uc.POST("/order/bind", authSvc.Guest, bm.CORS(), addUnicomBind)
uc.POST("/order/untie", authSvc.Guest, bm.CORS(), releaseUnicomBind)
uc.GET("/bind/info", authSvc.Guest, bm.CORS(), userBind)
uc.GET("/pack/list", authSvc.Guest, bm.CORS(), packList)
uc.POST("/order/pack/receive", authSvc.Guest, bm.CORS(), packReceive)
uc.POST("/order/pack/flow", authSvc.Guest, bm.CORS(), flowPack)
uc.GET("/order/userlog", authSvc.User, bm.CORS(), userBindLog)
uc.GET("/pack/log", userPacksLog)
uc.GET("/bind/state", verifySvc.Verify, welfareBindState)
}
mb := w.Group("/mobile", proxyHandler)
{
mb.POST("/orders.so", ordersMobileSync)
mb.GET("/activation", verifySvc.Verify, mobileActivation)
mb.GET("/status", verifySvc.Verify, mobileState)
mb.GET("/user/status", bm.CORS(), userMobileState)
}
tl := w.Group("/telecom", proxyHandler)
{
tl.POST("/orders.so", bm.CORS(), telecomOrdersSync)
tl.POST("/flow.so", bm.CORS(), telecomMsgSync)
tl.POST("/order/pay", bm.CORS(), telecomPay)
tl.POST("/order/pay/cancel", bm.CORS(), cancelRepeatOrder)
tl.GET("/order/consent", verifySvc.Verify, orderConsent)
tl.GET("/order/list", verifySvc.Verify, orderList)
tl.GET("/order/user/flow", bm.CORS(), phoneFlow)
tl.POST("/send/sms", verifySvc.Verify, phoneSendSMS)
tl.GET("/verification", verifySvc.Verify, phoneVerification)
tl.GET("/order/state", bm.CORS(), orderState)
}
}
}
//returnDataJSON return json no message
func returnDataJSON(c *bm.Context, data map[string]interface{}, err error) {
code := http.StatusOK
if data == nil {
c.JSON(data, err)
return
}
if _, ok := data["message"]; !ok {
data["message"] = ""
}
if err != nil {
c.Error = err
bcode := ecode.Cause(err)
data["code"] = bcode.Code()
} else {
if _, ok := data["code"]; !ok {
data["code"] = ecode.OK
}
data["ttl"] = 1
}
c.Render(code, render.MapJSON(data))
}

View File

@@ -0,0 +1,81 @@
package http
import (
"encoding/base64"
"strconv"
"time"
"go-common/app/interface/main/app-wall/model"
"go-common/library/ecode"
log "go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/metadata"
)
func userOperatorIP(c *bm.Context) {
res := map[string]interface{}{}
params := c.Request.Form
usermob := params.Get("usermob")
operator := params.Get("operator")
mobiApp := params.Get("mobi_app")
buildStr := params.Get("build")
build, _ := strconv.Atoi(buildStr)
if operator == "" {
c.JSON(nil, ecode.RequestErr)
return
}
ipStr := metadata.String(c, metadata.RemoteIP)
ip := model.InetAtoN(ipStr)
switch operator {
case "unicom":
res["data"] = unicomSvc.UserUnciomIP(ip, ipStr, usermob, mobiApp, build, time.Now())
case "mobile":
res["data"] = mobileSvc.IsMobileIP(ip, ipStr, usermob)
default:
c.JSON(nil, ecode.RequestErr)
return
}
returnDataJSON(c, res, nil)
}
func mOperatorIP(c *bm.Context) {
res := map[string]interface{}{}
params := c.Request.Form
usermob := params.Get("usermob")
operator := params.Get("operator")
ipStr := params.Get("ip")
ip := model.InetAtoN(ipStr)
switch operator {
case "unicom":
var usermobStr string
if usermob != "" {
var (
_aesKey = []byte("9ed226d9")
)
bs, err := base64.StdEncoding.DecodeString(usermob)
if err != nil {
log.Error("base64.StdEncoding.DecodeString(%s) error(%v)", usermob, err)
c.JSON(nil, ecode.RequestErr)
return
}
bs, err = unicomSvc.DesDecrypt(bs, _aesKey)
if err != nil {
log.Error("unicomSvc.DesDecrypt error(%v)", err)
c.JSON(nil, ecode.RequestErr)
return
}
if len(bs) > 32 {
usermobStr = string(bs[:32])
} else {
usermobStr = string(bs)
}
}
res["data"] = unicomSvc.UserUnciomIP(ip, ipStr, usermobStr, "missevan", 0, time.Now())
case "mobile":
res["data"] = mobileSvc.IsMobileIP(ip, ipStr, usermob)
default:
c.JSON(nil, ecode.RequestErr)
return
}
returnDataJSON(c, res, nil)
}

View File

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

View File

@@ -0,0 +1,170 @@
package http
import (
"encoding/xml"
"io/ioutil"
"net/http"
"time"
"go-common/app/interface/main/app-wall/model/mobile"
"go-common/library/ecode"
log "go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/metadata"
)
const (
mobileOrders = 0
mobileFlow = 1
)
var (
emptyByte = []byte{}
)
// ordersSync
func ordersMobileSync(c *bm.Context) {
mobile, mtype, err := requestXMLToMap(c.Request)
if err != nil {
log.Error("requestXMLToMap error (%v)", err)
mobileMessage(c, err, mtype)
return
}
b, _ := xml.Marshal(&mobile)
ip := metadata.String(c, metadata.RemoteIP)
switch mtype {
case mobileOrders:
log.Info("mobile user orders xml response(%s)", b)
if mobile.Threshold == "" {
mobile.Threshold = "100"
}
if err := mobileSvc.InOrdersSync(c, ip, mobile, time.Now()); err != nil {
log.Error("mobileSvc.InOrdersSync error (%v)", err)
mobileMessage(c, err, mtype)
return
}
case mobileFlow:
log.Info("mobile user flow xml response(%s)", b)
if err := mobileSvc.FlowSync(c, mobile, ip); err != nil {
log.Error("mobileSvc.FlowSync error (%v)", err)
mobileMessage(c, err, mtype)
return
}
}
mobileMessage(c, ecode.OK, mtype)
}
// mobileActivation
func mobileActivation(c *bm.Context) {
res := map[string]interface{}{}
params := c.Request.Form
usermob := params.Get("usermob")
msg, err := mobileSvc.Activation(c, usermob, time.Now())
if err != nil {
if msg != "" {
returnDataJSON(c, res, err)
res["message"] = msg
}
returnDataJSON(c, res, err)
return
}
res["message"] = ""
returnDataJSON(c, res, nil)
}
// mobileState
func mobileState(c *bm.Context) {
params := c.Request.Form
usermob := params.Get("usermob")
data := mobileSvc.MobileState(c, usermob, time.Now())
res := map[string]interface{}{
"data": data,
}
returnDataJSON(c, res, nil)
}
// userFlowState
func userMobileState(c *bm.Context) {
params := c.Request.Form
usermob := params.Get("usermob")
data := mobileSvc.UserMobileState(c, usermob, time.Now())
res := map[string]interface{}{
"data": data,
}
returnDataJSON(c, res, nil)
}
// RequestXmlToMap
func requestXMLToMap(request *http.Request) (data *mobile.MobileXML, mobileType int, err error) {
body, err := ioutil.ReadAll(request.Body)
if err != nil {
log.Error("mobile_ioutil.ReadAll error (%v)", err)
return
}
defer request.Body.Close()
if len(body) == 0 {
err = ecode.RequestErr
return
}
var res interface{} = &mobile.OrderXML{}
mobileType = mobileOrders
log.Info("mobile orders xml body(%s)", body)
if err = xml.Unmarshal(body, &res); err != nil {
res = &mobile.FlowXML{}
mobileType = mobileFlow
if err = xml.Unmarshal(body, &res); err != nil {
log.Error("xml.Unmarshal OrderXML(%v) error (%v)", res, err)
err = ecode.RequestErr
return
}
}
if res == nil {
err = ecode.NothingFound
log.Error("xml.Unmarshal OrderXML is null")
return
}
switch v := res.(type) {
case *mobile.OrderXML:
data = v.MobileXML
case *mobile.FlowXML:
data = v.MobileXML
}
return
}
func mobileMessage(c *bm.Context, err error, mobileType int) {
// response header
c.Writer.Header().Set("Content-Type", "text/xml; charset=UTF-8")
c.Writer.Header().Set("Cache-Control", "no-cache")
c.Writer.Header().Set("Connection", "keep-alive")
var msg interface{}
switch mobileType {
case mobileOrders:
msg = &mobile.OrderMsgXML{
Msg: &mobile.Msg{
Xmlns: "http://www.monternet.com/dsmp/schemas/",
MsgType: "SyncFlowPkgOrderResp",
Version: "1.0.0",
HRet: err.Error(),
},
}
case mobileFlow:
msg = &mobile.FlowMsgXML{
Msg: &mobile.Msg{
Xmlns: "http://www.monternet.com/dsmp/schemas/",
MsgType: "SyncFlowPkgLeftQuotaResp",
Version: "1.0.0",
HRet: err.Error(),
},
}
}
output, err := xml.MarshalIndent(msg, " ", " ")
if err != nil {
log.Error("xml.MarshalIndent (%v)", err)
err = ecode.RequestErr
output = emptyByte
}
c.Writer.Write([]byte(xml.Header))
c.Writer.Write(output)
}

View File

@@ -0,0 +1,316 @@
package http
import (
"encoding/base64"
"fmt"
"net/http"
"net/url"
"strconv"
"strings"
"time"
"go-common/app/interface/main/app-wall/dao/padding"
"go-common/app/interface/main/app-wall/model"
"go-common/library/ecode"
log "go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/metadata"
)
// wallShikeClick
func wallShikeClick(c *bm.Context) {
params := c.Request.Form
// ip uint32, cid, mac, idfa, cb
appid := params.Get("appid")
mac := params.Get("mac")
idfa := params.Get("idfa")
cb := params.Get("cb")
cid := model.ChannelShike
if appid != model.GdtIOSAppID {
log.Error("gdt click wrong appid(%s)", appid)
c.JSON(nil, ecode.RequestErr)
return
}
if cid == "" || idfa == "" || cb == "" {
log.Error("arg cid(%s) mac(%s) idfa(%s) callback(%s) is empty", cid, idfa, cb)
c.JSON(nil, ecode.RequestErr)
return
}
ip := model.InetAtoN(metadata.String(c, metadata.RemoteIP))
if err := offerSvc.Click(c, ip, cid, mac, idfa, cb, time.Now()); err != nil {
log.Error("offerSvc.Click error(%v)", err)
c.JSON(nil, ecode.NotModified)
return
}
res := map[string]interface{}{}
res["code"] = ecode.OK
returnDataJSON(c, res, nil)
}
// wallGdtClick
func wallGdtClick(c *bm.Context) {
params := c.Request.Form
appID := params.Get("appid")
muid := params.Get("muid")
var now time.Time
ts, _ := strconv.ParseInt(params.Get("click_time"), 10, 64)
if ts != 0 {
now = time.Unix(ts, 0)
} else {
now = time.Now()
}
clickid := params.Get("click_id")
adid := params.Get("advertiser_id")
appType := params.Get("app_type")
if id, ok := model.AppIDGdt[appType]; !ok || appID != id {
log.Error("wallGdtClick app_type(%s) and appid(%s) is illegal", appType, appID)
res := map[string]interface{}{"ret": ecode.RequestErr}
returnDataJSON(c, res, nil)
return
}
if _, ok := model.ChannelGdt[adid]; !ok {
log.Error("wallGdtClick advertiser_id(%s) is illegal", adid)
res := map[string]interface{}{"ret": ecode.RequestErr}
returnDataJSON(c, res, nil)
return
}
ip := model.InetAtoN(metadata.String(c, metadata.RemoteIP))
if appType == model.TypeIOS {
if err := offerSvc.Click(c, ip, adid, "", muid, clickid, now); err != nil {
log.Error("wallGdtClick %+v", err)
res := map[string]interface{}{"ret": ecode.ServerErr}
returnDataJSON(c, res, nil)
return
}
} else if appType == model.TypeAndriod {
if err := offerSvc.ANClick(c, adid, muid, "", "", clickid, ip, now); err != nil {
log.Error("wallGdtClick %+v", err)
res := map[string]interface{}{"ret": ecode.ServerErr}
returnDataJSON(c, res, nil)
return
}
}
res := map[string]interface{}{"ret": ecode.OK}
returnDataJSON(c, res, nil)
}
// wallTestActive
func wallTestActive(c *bm.Context) {
params := c.Request.Form
idfa := params.Get("idfa")
if idfa == "" {
c.JSON(nil, ecode.RequestErr)
return
}
ip := model.InetAtoN(metadata.String(c, metadata.RemoteIP))
if err := offerSvc.Active(c, ip, "0", "", "", idfa, "test by haogw", time.Now()); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
res := map[string]interface{}{
"code": ecode.OK,
}
returnDataJSON(c, res, nil)
}
// wallActive
func wallActive(c *bm.Context) {
var (
_aesKey = []byte("iHiRzNVIy8mvc4HnKPKeiJEP90zycllH")
_aesIv = []byte("w4gQHf5M7RQdBq2U")
)
body := c.Request.Form.Get("body")
if body == "" {
log.Error("body is empty")
c.JSON(nil, ecode.RequestErr)
return
}
log.Info("body before base64 (%v)", body)
paramBody := c.Request.Form
appkey := paramBody.Get("appkey")
appver := paramBody.Get("appver")
build := paramBody.Get("build")
device := paramBody.Get("device")
filtered := paramBody.Get("filtered")
mobiApp := paramBody.Get("mobi_app")
sign := paramBody.Get("sign")
log.Info("appkey: (%v)\n appver: (%v)\n build: (%v)\n device: (%v)\n filtered: (%v)\n mobi_app: (%v)\n sign: (%v)", appkey, appver, build, device, filtered, mobiApp, sign)
bs, err := base64.StdEncoding.DecodeString(body)
if err != nil {
log.Error("base64.StdEncoding.DecodeString(%s) error(%v)", body, err)
c.JSON(nil, ecode.SignCheckErr)
return
}
bs, err = offerSvc.CBCDecrypt(bs, _aesKey, _aesIv, padding.PKCS5)
if err != nil {
log.Error("aes.CBCDecrypt(%s) error(%v)", base64.StdEncoding.EncodeToString(bs), err)
c.JSON(nil, ecode.SignCheckErr)
return
}
params, err := url.ParseQuery(string(bs))
if err != nil {
log.Error("url.ParseQuery(%s) error(%v)", bs, err)
c.JSON(nil, ecode.RequestErr)
return
}
rmac := params.Get("rmac")
mac := params.Get("mac")
idfa := params.Get("idfa")
name := params.Get("name")
log.Info("rmac: (%v)\n mac: (%v)\n idfa: (%v)\n name: (%v)\n", rmac, mac, idfa, name)
if idfa == "" || name == "" || strings.Contains(idfa, "-") || strings.Contains(rmac, ":") || strings.Contains(mac, ":") {
log.Error("mac(%s) rmac(%s) idfa(%s) format error, or idfa(%s) name(%s) is empty", mac, rmac, idfa, idfa, name)
c.JSON(nil, ecode.RequestErr)
return
}
ip := model.InetAtoN(metadata.String(c, metadata.RemoteIP))
var (
mid int64
)
if midInter, ok := c.Get("mid"); ok {
mid = midInter.(int64)
}
log.Info("mid: (%d)", mid)
err = offerSvc.Active(c, ip, strconv.FormatInt(mid, 10), rmac, mac, idfa, name, time.Now())
if err != nil {
log.Error("offerSvc.Active(%d, %d, %s, %s, %s, %s) error(%v)", ip, mid, rmac, mac, idfa, name, err)
c.JSON(nil, ecode.NotModified)
return
}
log.Info("wall offer active idfa(%s)", idfa)
res := map[string]interface{}{
"code": ecode.OK,
}
returnDataJSON(c, res, nil)
}
func wallExist(c *bm.Context) {
params := c.Request.Form
// ip uint32, cid, mac, idfa, cb
appID := params.Get("appid")
idfa := params.Get("idfa")
if (appID != model.GdtIOSAppID && appID != model.GdtAndroidAppID) || idfa == "" {
log.Error("arg cid(%s) idfa(%s) is empty", appID, idfa)
c.JSON(nil, ecode.RequestErr)
return
}
exist, _ := offerSvc.Exists(c, strings.Replace(idfa, "-", "", -1))
const (
ret = `{"%s":"%d"}`
)
e := 1
if !exist {
e = 0
}
bs := []byte(fmt.Sprintf(ret, idfa, e))
if _, err := c.Writer.Write(bs); err != nil {
log.Error("w.Write error(%v)", err)
}
res := map[string]interface{}{
"code": ecode.OK,
}
returnDataJSON(c, res, nil)
}
func wallDotinappClick(c *bm.Context) {
params := c.Request.Form
appid := params.Get("appid")
// pid := params.Get("pid")
// subid := params.Get("subid")
// ua := params.Get("ua")
idfa := params.Get("idfa")
clickid := params.Get("clickid")
pid := model.ChannelDontin
if appid != model.GdtIOSAppID {
log.Error("dotinapp click wrong appid(%s)", appid)
c.JSON(nil, ecode.RequestErr)
return
}
if pid == "" || idfa == "" || clickid == "" {
log.Error("pid(%s) idfa(%s) clickid(%s) is empty", pid, idfa, clickid)
c.JSON(nil, ecode.RequestErr)
return
}
ip := model.InetAtoN(metadata.String(c, metadata.RemoteIP))
if err := offerSvc.Click(c, ip, pid, "", idfa, clickid, time.Now()); err != nil {
log.Error("offerSvc.Click error(%v)", err)
c.JSON(nil, ecode.NotModified)
return
}
res := map[string]interface{}{
"code": ecode.OK,
}
returnDataJSON(c, res, nil)
}
func wallToutiaoClick(c *bm.Context) {
const (
OSAndroid = "0"
// OSIOS = "1"
)
params := c.Request.Form
os := params.Get("os")
if os != OSAndroid {
log.Error("wallToutiaoClick os(%s) is illegal", os)
c.AbortWithStatus(http.StatusBadRequest)
return
}
imei := params.Get("imei")
androidid := params.Get("androidid")
if imei == "" && androidid == "" {
log.Error("wallToutiaoClick imei(%s) and androidid(%s) is illegal", imei, androidid)
c.AbortWithStatus(http.StatusBadRequest)
return
}
cb := params.Get("callback_url")
if cb == "" {
log.Error("wallToutiaoClick callback_url(%s) is illegal", cb)
c.AbortWithStatus(http.StatusBadRequest)
return
}
mac := params.Get("mac")
ip := model.InetAtoN(params.Get("ip"))
var now time.Time
ts, _ := strconv.ParseInt(params.Get("timestamp"), 10, 64)
if ts != 0 {
now = time.Unix(0, ts*1e6)
} else {
now = time.Now()
}
if os == OSAndroid {
if err := offerSvc.ANClick(c, model.ChannelToutiao, imei, androidid, mac, cb, ip, now); err != nil {
log.Error("%+v", err)
c.AbortWithStatus(http.StatusInternalServerError)
return
}
}
}
func wallActive2(c *bm.Context) {
params := c.Request.Form
os := params.Get("os")
if _, ok := model.AppIDGdt[os]; !ok {
log.Error("wallActive2 os(%s) is illegal", os)
c.JSON(nil, ecode.RequestErr)
return
}
if os != model.TypeAndriod {
log.Error("wallActive2 os(%s) is illegal", os)
c.JSON(nil, ecode.RequestErr)
return
}
imei := params.Get("imei")
androidid := params.Get("androidid")
if imei == "" && androidid == "" {
log.Error("wallActive2 imei(%s) and androidid(%s) is illegal", imei, androidid)
c.JSON(nil, ecode.RequestErr)
return
}
mac := params.Get("mac")
err := offerSvc.ANActive(c, imei, androidid, mac, time.Now())
if err != nil {
log.Error("wallActive2 %+v", err)
}
c.JSON(nil, err)
}

View File

@@ -0,0 +1,14 @@
package http
import (
"time"
bm "go-common/library/net/http/blademaster"
)
func reddot(c *bm.Context) {
res := map[string]interface{}{
"data": operatorSvc.Reddot(time.Now()),
}
returnDataJSON(c, res, nil)
}

View File

@@ -0,0 +1,362 @@
package http
import (
"encoding/base64"
"encoding/json"
"io/ioutil"
"net/http"
"strconv"
"time"
"go-common/app/interface/main/app-wall/model/telecom"
"go-common/library/ecode"
log "go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/metadata"
)
// ordersSync
func telecomOrdersSync(c *bm.Context) {
data, err := requestJSONTelecom(c.Request)
if err != nil {
telecomMessage(c, err.Error())
return
}
switch v := data.(type) {
case *telecom.TelecomOrderJson:
if err = telecomSvc.InOrdersSync(c, metadata.String(c, metadata.RemoteIP), v); err != nil {
log.Error("telecomSvc.InOrdersSync error (%v)", err)
telecomMessage(c, err.Error())
return
}
telecomMessage(c, "1")
case *telecom.TelecomRechargeJson:
if v == nil {
telecomMessage(c, ecode.NothingFound.Error())
return
}
if err = telecomSvc.InRechargeSync(c, metadata.String(c, metadata.RemoteIP), v.Detail); err != nil {
log.Error("telecomSvc.InOrdersSync error (%v)", err)
telecomMessage(c, err.Error())
return
}
telecomMessage(c, "1")
}
}
// telecomMsgSync
func telecomMsgSync(c *bm.Context) {
data, err := requestJSONTelecomMsg(c.Request)
if err != nil {
telecomMessage(c, err.Error())
return
}
if err = telecomSvc.TelecomMessageSync(c, metadata.String(c, metadata.RemoteIP), data); err != nil {
log.Error("telecomSvc.TelecomMessageSync error (%v)", err)
telecomMessage(c, err.Error())
return
}
telecomMessage(c, "1")
}
func telecomPay(c *bm.Context) {
res := map[string]interface{}{}
params := c.Request.Form
phoneDES := params.Get("phone")
phone, err := phoneDesToInt(phoneDES)
if err != nil {
log.Error("phoneDesToInt error(%v)", err)
res["message"] = ""
returnDataJSON(c, res, ecode.RequestErr)
return
}
isRepeatOrderStr := params.Get("is_repeat_order")
isRepeatOrder, err := strconv.Atoi(isRepeatOrderStr)
if err != nil {
log.Error("isRepeatOrder strconv.Atoi error(%v)", err)
res["message"] = ""
returnDataJSON(c, res, ecode.RequestErr)
return
}
payChannelStr := params.Get("pay_channel")
payChannel, err := strconv.Atoi(payChannelStr)
if err != nil {
log.Error("payChannel strconv.Atoi error(%v)", err)
res["message"] = ""
returnDataJSON(c, res, ecode.RequestErr)
return
}
payActionStr := params.Get("pay_action")
payAction, err := strconv.Atoi(payActionStr)
if err != nil {
log.Error("payAction strconv.Atoi error(%v)", err)
res["message"] = ""
returnDataJSON(c, res, ecode.RequestErr)
return
}
orderIDStr := params.Get("orderid")
orderID, _ := strconv.ParseInt(orderIDStr, 10, 64)
data, msg, err := telecomSvc.TelecomPay(c, phone, isRepeatOrder, payChannel, payAction, orderID, metadata.String(c, metadata.RemoteIP))
if err != nil {
log.Error("telecomSvc.TelecomPay error(%v)", err)
res["message"] = msg
returnDataJSON(c, res, err)
return
}
res["data"] = data
returnDataJSON(c, res, nil)
}
func cancelRepeatOrder(c *bm.Context) {
res := map[string]interface{}{}
params := c.Request.Form
phoneDES := params.Get("phone")
phone, err := phoneDesToInt(phoneDES)
if err != nil {
log.Error("phoneDesToInt error(%v)", err)
res["message"] = ""
returnDataJSON(c, res, ecode.RequestErr)
return
}
msg, err := telecomSvc.CancelRepeatOrder(c, phone)
if err != nil {
res["message"] = msg
returnDataJSON(c, res, err)
return
}
res["message"] = msg
returnDataJSON(c, res, nil)
}
func orderList(c *bm.Context) {
res := map[string]interface{}{}
params := c.Request.Form
phoneDES := params.Get("phone")
phone, err := phoneDesToInt(phoneDES)
if err != nil {
log.Error("phoneDesToInt error(%v)", err)
res["message"] = ""
returnDataJSON(c, res, ecode.RequestErr)
return
}
orderIDStr := params.Get("orderid")
orderID, _ := strconv.ParseInt(orderIDStr, 10, 64)
data, msg, err := telecomSvc.OrderList(c, orderID, phone)
if err != nil {
log.Error("telecomSvc.OrderList error(%v)", err)
res["message"] = msg
returnDataJSON(c, res, err)
return
}
res["data"] = data
returnDataJSON(c, res, nil)
}
func phoneFlow(c *bm.Context) {
res := map[string]interface{}{}
params := c.Request.Form
phoneDES := params.Get("phone")
phone, err := phoneDesToInt(phoneDES)
if err != nil {
log.Error("phoneDesToInt error(%v)", err)
res["message"] = ""
returnDataJSON(c, res, ecode.RequestErr)
return
}
orderIDStr := params.Get("orderid")
orderID, _ := strconv.ParseInt(orderIDStr, 10, 64)
data, msg, err := telecomSvc.PhoneFlow(c, orderID, phone)
if err != nil {
log.Error("telecomSvc.PhoneFlow error(%v)", err)
res["message"] = msg
returnDataJSON(c, res, err)
return
}
res["data"] = data
returnDataJSON(c, res, nil)
}
func orderConsent(c *bm.Context) {
res := map[string]interface{}{}
params := c.Request.Form
phoneDES := params.Get("phone")
phone, err := phoneDesToInt(phoneDES)
if err != nil {
log.Error("phoneDesToInt error(%v)", err)
res["message"] = ""
returnDataJSON(c, res, ecode.RequestErr)
return
}
captcha := params.Get("captcha")
orderIDStr := params.Get("orderid")
orderID, _ := strconv.ParseInt(orderIDStr, 10, 64)
data, msg, err := telecomSvc.OrderConsent(c, phone, orderID, captcha)
if err != nil {
log.Error("telecomSvc.OrderConsent error(%v)", err)
res["message"] = msg
returnDataJSON(c, res, err)
return
}
res["data"] = data
returnDataJSON(c, res, nil)
}
func phoneSendSMS(c *bm.Context) {
res := map[string]interface{}{}
params := c.Request.Form
phoneDES := params.Get("phone")
phone, err := phoneDesToInt(phoneDES)
if err != nil {
log.Error("phoneDesToInt error(%v)", err)
res["message"] = ""
returnDataJSON(c, res, ecode.RequestErr)
return
}
err = telecomSvc.PhoneSendSMS(c, phone)
if err != nil {
log.Error("telecomSvc.PhoneSendSMS error(%v)", err)
res["code"] = err
res["message"] = ""
returnDataJSON(c, res, err)
return
}
res["message"] = ""
returnDataJSON(c, res, nil)
}
func phoneVerification(c *bm.Context) {
res := map[string]interface{}{}
params := c.Request.Form
phoneDES := params.Get("phone")
phone, err := phoneDesToInt(phoneDES)
if err != nil {
log.Error("phoneDesToInt error(%v)", err)
res["message"] = ""
returnDataJSON(c, res, ecode.RequestErr)
return
}
captcha := params.Get("captcha")
data, err, msg := telecomSvc.PhoneCode(c, phone, captcha, time.Now())
if err != nil {
log.Error("telecomSvc.PhoneCode error(%v)", err)
res["message"] = msg
returnDataJSON(c, res, err)
return
}
res["data"] = data
res["message"] = msg
returnDataJSON(c, res, nil)
}
func orderState(c *bm.Context) {
res := map[string]interface{}{}
params := c.Request.Form
orderIDStr := params.Get("orderid")
orderID, err := strconv.ParseInt(orderIDStr, 10, 64)
if err != nil {
log.Error("orderID strconv.ParseInt error(%v)", err)
res["message"] = ""
returnDataJSON(c, res, ecode.RequestErr)
return
}
data, msg, err := telecomSvc.OrderState(c, orderID)
if err != nil {
log.Error("telecomSvc.OrderState error(%v)", err)
res["message"] = msg
returnDataJSON(c, res, err)
return
}
res["data"] = data
res["message"] = msg
returnDataJSON(c, res, nil)
}
// requestJSONTelecom
func requestJSONTelecom(request *http.Request) (res interface{}, err error) {
var (
telecomOrder *telecom.TelecomOrderJson
telecomRecharge *telecom.TelecomRechargeJson
)
body, err := ioutil.ReadAll(request.Body)
if err != nil {
log.Error("unicom_ioutil.ReadAll error (%v)", err)
return
}
defer request.Body.Close()
if len(body) == 0 {
err = ecode.RequestErr
return
}
log.Info("telecom orders json body(%s)", body)
if err = json.Unmarshal(body, &telecomOrder); err == nil && telecomOrder != nil {
if telecomOrder.ResultType != 2 {
res = telecomOrder
return
}
}
if err = json.Unmarshal(body, &telecomRecharge); err == nil {
res = telecomRecharge
return
}
log.Error("telecom json.Unmarshal error (%v)", err)
return
}
// requestJSONTelecomMsg
func requestJSONTelecomMsg(request *http.Request) (res *telecom.TelecomMessageJSON, err error) {
body, err := ioutil.ReadAll(request.Body)
if err != nil {
log.Error("unicom_ioutil.ReadAll error (%v)", err)
return
}
defer request.Body.Close()
if len(body) == 0 {
err = ecode.RequestErr
return
}
log.Info("telecom json msg body(%s)", body)
if err = json.Unmarshal(body, &res); err != nil {
log.Error("telecom Message json.Unmarshal error (%v)", err)
return
}
return
}
// telecomMessage
func telecomMessage(c *bm.Context, code string) {
// response header
c.Writer.Header().Set("Content-Type", "text; charset=UTF-8")
c.Writer.Header().Set("Cache-Control", "no-cache")
c.Writer.Header().Set("Connection", "keep-alive")
c.Writer.Write([]byte(code))
}
// phoneDesToInt des to int
func phoneDesToInt(phoneDes string) (phoneInt int, err error) {
var (
_aesKey = []byte("6b7e8b8a")
)
bs, err := base64.StdEncoding.DecodeString(phoneDes)
if err != nil {
log.Error("base64.StdEncoding.DecodeString(%s) error(%v)", phoneDes, err)
err = ecode.RequestErr
return
}
if bs, err = telecomSvc.DesDecrypt(bs, _aesKey); err != nil {
log.Error("phone s.DesDecrypt error(%v)", err)
return
}
var phoneStr string
if len(bs) > 11 {
phoneStr = string(bs[:11])
} else {
phoneStr = string(bs)
}
phoneInt, err = strconv.Atoi(phoneStr)
if err != nil {
log.Error("phoneDesToInt phoneStr:%v error(%v)", phoneStr, err)
err = ecode.RequestErr
return
}
return
}

View File

@@ -0,0 +1,656 @@
package http
import (
"encoding/base64"
"encoding/json"
"io/ioutil"
"net/http"
"net/url"
"strconv"
"time"
"go-common/app/interface/main/app-wall/model"
"go-common/app/interface/main/app-wall/model/unicom"
"go-common/library/ecode"
log "go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/metadata"
)
// ordersSync
func ordersSync(c *bm.Context) {
res := map[string]interface{}{}
unicom, err := requestJSONToMap(c.Request)
if err != nil {
res["result"] = "1"
res["errorcode"] = "100"
log.Error("unicom_ioutil.ReadAll error (%v)", err)
returnDataJSON(c, res, ecode.RequestErr)
return
}
usermob, err := url.QueryUnescape(unicom.Usermob)
if err != nil {
log.Error("unicom_url.QueryUnescape (%v) error (%v)", unicom.Usermob, err)
res["result"] = "1"
res["errorcode"] = "100"
returnDataJSON(c, res, ecode.RequestErr)
return
}
var (
_aesKey = []byte("9ed226d9")
)
bs, err := base64.StdEncoding.DecodeString(usermob)
if err != nil {
log.Error("base64.StdEncoding.DecodeString(%s) error(%v)", usermob, err)
c.JSON(nil, ecode.RequestErr)
return
}
bs, err = unicomSvc.DesDecrypt(bs, _aesKey)
if err != nil {
log.Error("unicomSvc.DesDecrypt error(%v)", err)
c.JSON(nil, ecode.RequestErr)
return
}
var usermobStr string
if len(bs) > 32 {
usermobStr = string(bs[:32])
} else {
usermobStr = string(bs)
}
log.Info("unicomSvc.OrdersSync_usermob (%v) unicom (%v)", usermobStr, unicom)
if err := unicomSvc.InOrdersSync(c, usermobStr, metadata.String(c, metadata.RemoteIP), unicom, time.Now()); err != nil {
log.Error("unicomSvc.OrdersSync usermob (%v) unicom (%v) error (%v)", usermobStr, unicom, err)
res["result"] = "1"
res["errorcode"] = "100"
returnDataJSON(c, res, err)
return
}
res["result"] = "0"
res["message"] = ""
res["errorcode"] = ""
returnDataJSON(c, res, nil)
}
// advanceSync
func advanceSync(c *bm.Context) {
res := map[string]interface{}{}
unicom, err := requestJSONToMap(c.Request)
if err != nil {
res["result"] = "1"
res["errorcode"] = "100"
log.Error("unicom_ioutil.ReadAll error (%v)", err)
returnDataJSON(c, res, ecode.RequestErr)
return
}
usermob, err := url.QueryUnescape(unicom.Usermob)
if err != nil {
log.Error("unicom_url.QueryUnescape (%v) error (%v)", unicom.Usermob, err)
res["result"] = "1"
res["errorcode"] = "100"
returnDataJSON(c, res, ecode.RequestErr)
return
}
var (
_aesKey = []byte("9ed226d9")
)
bs, err := base64.StdEncoding.DecodeString(usermob)
if err != nil {
log.Error("base64.StdEncoding.DecodeString(%s) error(%v)", usermob, err)
c.JSON(nil, ecode.RequestErr)
return
}
bs, err = unicomSvc.DesDecrypt(bs, _aesKey)
if err != nil {
log.Error("unicomSvc.DesDecrypt error(%v)", err)
c.JSON(nil, ecode.RequestErr)
return
}
var usermobStr string
if len(bs) > 32 {
usermobStr = string(bs[:32])
} else {
usermobStr = string(bs)
}
log.Info("unicomSvc.AdvanceSync_usermob (%v) unicom (%v)", usermobStr, unicom)
if err := unicomSvc.InAdvanceSync(c, usermobStr, metadata.String(c, metadata.RemoteIP), unicom, time.Now()); err != nil {
log.Error("unicomSvc.InAdvanceSync usermob (%v) unicom (%v) error (%v)", usermobStr, unicom, err)
res["result"] = "1"
res["errorcode"] = "100"
returnDataJSON(c, res, err)
return
}
res["result"] = "0"
res["message"] = ""
res["errorcode"] = ""
returnDataJSON(c, res, nil)
}
// flowSync
func flowSync(c *bm.Context) {
res := map[string]interface{}{}
unicom, err := requestJSONToMap(c.Request)
if err != nil {
res["result"] = "1"
res["errorcode"] = "100"
log.Error("unicom_ioutil.ReadAll error (%v)", err)
returnDataJSON(c, res, ecode.RequestErr)
return
}
var flowbyte float64
if flowbyte, err = strconv.ParseFloat(unicom.FlowbyteStr, 64); err != nil {
log.Error("unicom_flowbyte strconv.ParseFloat(%s) error(%v)", unicom.FlowbyteStr, err)
res["result"] = "1"
res["errorcode"] = "100"
returnDataJSON(c, res, ecode.RequestErr)
return
}
usermob, err := url.QueryUnescape(unicom.Usermob)
if err != nil {
log.Error("unicom_url.QueryUnescape (%v) error (%v)", unicom.Usermob, err)
res["result"] = "1"
res["errorcode"] = "100"
returnDataJSON(c, res, ecode.RequestErr)
return
}
var (
_aesKey = []byte("9ed226d9")
)
bs, err := base64.StdEncoding.DecodeString(usermob)
if err != nil {
log.Error("unicom_base64.StdEncoding.DecodeString(%s) error(%v)", usermob, err)
c.JSON(nil, ecode.RequestErr)
return
}
bs, err = unicomSvc.DesDecrypt(bs, _aesKey)
if err != nil {
log.Error("unicomSvc.DesDecrypt error(%v)", err)
c.JSON(nil, ecode.RequestErr)
return
}
var usermobStr string
if len(bs) > 32 {
usermobStr = string(bs[:32])
} else {
usermobStr = string(bs)
}
if err := unicomSvc.FlowSync(c, int(flowbyte*1024), usermobStr, unicom.Time, metadata.String(c, metadata.RemoteIP), time.Now()); err != nil {
log.Error("unicomSvc.FlowSync error (%v)", err)
res["result"] = "1"
res["errorcode"] = "100"
returnDataJSON(c, res, err)
return
}
res["result"] = "0"
res["message"] = ""
res["errorcode"] = ""
returnDataJSON(c, res, nil)
}
// inIPSync
func inIPSync(c *bm.Context) {
res := map[string]interface{}{}
unicom, err := requestIPJSONToMap(c.Request)
if err != nil {
res["result"] = "1"
res["errorcode"] = "100"
log.Error("unicom_ioutil.ReadAll error (%v)", err)
returnDataJSON(c, res, ecode.RequestErr)
return
}
log.Info("unicomSvc.InIpSync_unicom (%v)", unicom)
if err := unicomSvc.InIPSync(c, metadata.String(c, metadata.RemoteIP), unicom, time.Now()); err != nil {
log.Error("unicomSvc.InIpSync unicom (%v) error (%v)", unicom, err)
res["result"] = "1"
res["errorcode"] = "100"
returnDataJSON(c, res, err)
return
}
res["result"] = "0"
res["message"] = ""
res["errorcode"] = ""
returnDataJSON(c, res, nil)
}
// userFlow
func userFlow(c *bm.Context) {
res := map[string]interface{}{}
params := c.Request.Form
usermob := params.Get("usermob")
mobiApp := params.Get("mobi_app")
buildStr := params.Get("build")
build, _ := strconv.Atoi(buildStr)
ipStr := metadata.String(c, metadata.RemoteIP)
data, msg, err := unicomSvc.UserFlow(c, usermob, mobiApp, ipStr, build, time.Now())
if err != nil {
res["message"] = msg
returnDataJSON(c, res, err)
return
}
res["data"] = data
returnDataJSON(c, res, nil)
}
// userFlowState
func userFlowState(c *bm.Context) {
params := c.Request.Form
usermob := params.Get("usermob")
data, err := unicomSvc.UserFlowState(c, usermob, time.Now())
if err != nil {
c.JSON(nil, err)
return
}
res := map[string]interface{}{
"data": data,
}
returnDataJSON(c, res, nil)
}
// userState
func userState(c *bm.Context) {
res := map[string]interface{}{}
params := c.Request.Form
usermob := params.Get("usermob")
mobiApp := params.Get("mobi_app")
buildStr := params.Get("build")
build, _ := strconv.Atoi(buildStr)
ipStr := metadata.String(c, metadata.RemoteIP)
data, msg, err := unicomSvc.UserState(c, usermob, mobiApp, ipStr, build, time.Now())
if err != nil {
res["message"] = msg
returnDataJSON(c, res, err)
return
}
res["data"] = data
returnDataJSON(c, res, nil)
}
// unicomState
func unicomState(c *bm.Context) {
params := c.Request.Form
usermob := params.Get("usermob")
mobiApp := params.Get("mobi_app")
buildStr := params.Get("build")
build, _ := strconv.Atoi(buildStr)
ipStr := metadata.String(c, metadata.RemoteIP)
data, err := unicomSvc.UnicomState(c, usermob, mobiApp, ipStr, build, time.Now())
if err != nil {
c.JSON(nil, err)
return
}
res := map[string]interface{}{
"data": data,
}
returnDataJSON(c, res, nil)
}
// unicomStateM
func unicomStateM(c *bm.Context) {
params := c.Request.Form
usermob := params.Get("usermob")
mobiApp := params.Get("mobi_app")
buildStr := params.Get("build")
build, _ := strconv.Atoi(buildStr)
ipStr := metadata.String(c, metadata.RemoteIP)
var (
_aesKey = []byte("9ed226d9")
)
bs, err := base64.StdEncoding.DecodeString(usermob)
if err != nil {
log.Error("base64.StdEncoding.DecodeString(%s) error(%v)", usermob, err)
c.JSON(nil, ecode.RequestErr)
return
}
bs, err = unicomSvc.DesDecrypt(bs, _aesKey)
if err != nil {
log.Error("unicomSvc.DesDecrypt error(%v)", err)
c.JSON(nil, ecode.RequestErr)
return
}
var usermobStr string
if len(bs) > 32 {
usermobStr = string(bs[:32])
} else {
usermobStr = string(bs)
}
data, err := unicomSvc.UnicomState(c, usermobStr, mobiApp, ipStr, build, time.Now())
if err != nil {
c.JSON(nil, err)
return
}
res := map[string]interface{}{
"data": data,
}
returnDataJSON(c, res, nil)
}
// RequestJsonToMap
func requestJSONToMap(request *http.Request) (unicom *unicom.UnicomJson, err error) {
body, err := ioutil.ReadAll(request.Body)
if err != nil {
log.Error("unicom_ioutil.ReadAll error (%v)", err)
return
}
defer request.Body.Close()
if len(body) == 0 {
err = ecode.RequestErr
return
}
log.Info("unicom orders json body(%s)", body)
if err = json.Unmarshal(body, &unicom); err != nil {
log.Error("json.Unmarshal UnicomJson(%v) error (%v)", unicom, err)
return
}
if err = unicom.UnicomJSONChange(); err != nil {
log.Error("unicom.UnicomJSONChange unicom (%v) error (%v)", unicom, err)
}
return
}
// RequestIpJsonToMap
func requestIPJSONToMap(request *http.Request) (unicom *unicom.UnicomIpJson, err error) {
body, err := ioutil.ReadAll(request.Body)
if err != nil {
log.Error("unicom_ioutil.ReadAll error (%v)", err)
return
}
defer request.Body.Close()
if len(body) == 0 {
err = ecode.RequestErr
return
}
log.Info("unicom ip json body(%s)", body)
json.Unmarshal(body, &unicom)
return
}
func pack(c *bm.Context) {
var mid int64
res := map[string]interface{}{}
params := c.Request.Form
usermob := params.Get("usermob")
midInter, _ := c.Get("mid")
mid = midInter.(int64)
msg, err := unicomSvc.Pack(c, usermob, mid, time.Now())
if err != nil {
res["message"] = msg
returnDataJSON(c, res, err)
return
}
res["message"] = msg
returnDataJSON(c, res, nil)
}
func isUnciomIP(c *bm.Context) {
params := c.Request.Form
mobiApp := params.Get("mobi_app")
buildStr := params.Get("build")
build, _ := strconv.Atoi(buildStr)
ipStr := metadata.String(c, metadata.RemoteIP)
ip := model.InetAtoN(ipStr)
if err := unicomSvc.IsUnciomIP(ip, ipStr, mobiApp, build, time.Now()); err != nil {
log.Error("unicom_user_ip:%v", ipStr)
c.JSON(nil, err)
}
res := map[string]interface{}{
"code": ecode.OK,
}
returnDataJSON(c, res, nil)
}
func userUnciomIP(c *bm.Context) {
params := c.Request.Form
usermob := params.Get("usermob")
mobiApp := params.Get("mobi_app")
buildStr := params.Get("build")
build, _ := strconv.Atoi(buildStr)
ipStr := metadata.String(c, metadata.RemoteIP)
ip := model.InetAtoN(ipStr)
res := map[string]interface{}{}
res["data"] = unicomSvc.UserUnciomIP(ip, ipStr, usermob, mobiApp, build, time.Now())
returnDataJSON(c, res, nil)
}
func orderPay(c *bm.Context) {
res := map[string]interface{}{}
params := c.Request.Form
usermob := params.Get("usermob")
channel := params.Get("channel")
ordertypeStr := params.Get("ordertype")
ordertype, _ := strconv.Atoi(ordertypeStr)
data, msg, err := unicomSvc.Order(c, usermob, channel, ordertype, time.Now())
if err != nil {
res["message"] = msg
returnDataJSON(c, res, err)
return
}
res["data"] = data
returnDataJSON(c, res, nil)
}
func orderCancel(c *bm.Context) {
res := map[string]interface{}{}
params := c.Request.Form
usermob := params.Get("usermob")
data, msg, err := unicomSvc.CancelOrder(c, usermob)
if err != nil {
res["message"] = msg
returnDataJSON(c, res, err)
return
}
res["data"] = data
returnDataJSON(c, res, nil)
}
func smsCode(c *bm.Context) {
res := map[string]interface{}{}
params := c.Request.Form
phone := params.Get("phone")
msg, err := unicomSvc.UnicomSMSCode(c, phone, time.Now())
if err != nil {
res["message"] = msg
returnDataJSON(c, res, err)
return
}
res["message"] = msg
returnDataJSON(c, res, nil)
}
func addUnicomBind(c *bm.Context) {
res := map[string]interface{}{}
params := c.Request.Form
phone := params.Get("phone")
codeStr := params.Get("code")
code, err := strconv.Atoi(codeStr)
if err != nil {
log.Error("code(%v) strconv.Atoi error(%v)", codeStr, err)
res["message"] = "参数错误"
returnDataJSON(c, res, ecode.RequestErr)
return
}
var mid int64
midInter, ok := c.Get("mid")
if ok {
mid = midInter.(int64)
} else {
res["message"] = "账号未登录"
returnDataJSON(c, res, ecode.RequestErr)
return
}
msg, err := unicomSvc.AddUnicomBind(c, phone, code, mid, time.Now())
if err != nil {
res["code"] = err
res["message"] = msg
returnDataJSON(c, res, err)
return
}
res["message"] = msg
returnDataJSON(c, res, nil)
}
func releaseUnicomBind(c *bm.Context) {
res := map[string]interface{}{}
params := c.Request.Form
phoneStr := params.Get("phone")
phone, err := strconv.Atoi(phoneStr)
if err != nil {
log.Error("phone(%v) strconv.Atoi error(%v)", phoneStr, err)
res["message"] = "参数错误"
returnDataJSON(c, res, ecode.RequestErr)
return
}
var mid int64
midInter, ok := c.Get("mid")
if ok {
mid = midInter.(int64)
} else {
res["message"] = "账号未登录"
returnDataJSON(c, res, ecode.RequestErr)
return
}
msg, err := unicomSvc.ReleaseUnicomBind(c, mid, phone)
if err != nil {
res["message"] = msg
returnDataJSON(c, res, err)
return
}
res["message"] = msg
returnDataJSON(c, res, nil)
}
func userBind(c *bm.Context) {
res := map[string]interface{}{}
var mid int64
midInter, ok := c.Get("mid")
if ok {
mid = midInter.(int64)
} else {
res["message"] = "账号未登录"
returnDataJSON(c, res, ecode.RequestErr)
return
}
data, msg, err := unicomSvc.UserBind(c, mid)
if err != nil {
res["message"] = msg
returnDataJSON(c, res, err)
return
}
res["data"] = data
res["message"] = ""
returnDataJSON(c, res, nil)
}
func packList(c *bm.Context) {
res := map[string]interface{}{
"data": unicomSvc.UnicomPackList(),
}
returnDataJSON(c, res, nil)
}
func packReceive(c *bm.Context) {
res := map[string]interface{}{}
params := c.Request.Form
idStr := params.Get("id")
id, err := strconv.ParseInt(idStr, 10, 64)
if err != nil {
log.Error("id(%v) strconv.ParseInt error(%v)", idStr, err)
c.JSON(nil, err)
return
}
var mid int64
midInter, ok := c.Get("mid")
if ok {
mid = midInter.(int64)
} else {
res["message"] = "账号未登录"
returnDataJSON(c, res, ecode.RequestErr)
return
}
msg, err := unicomSvc.UnicomPackReceive(c, mid, id, time.Now())
if err != nil {
res["message"] = msg
returnDataJSON(c, res, err)
return
}
res["message"] = msg
returnDataJSON(c, res, nil)
}
func flowPack(c *bm.Context) {
res := map[string]interface{}{}
params := c.Request.Form
var mid int64
midInter, ok := c.Get("mid")
if ok {
mid = midInter.(int64)
} else {
res["message"] = "账号未登录"
returnDataJSON(c, res, ecode.RequestErr)
return
}
flowID := params.Get("flow_id")
msg, err := unicomSvc.UnicomFlowPack(c, mid, flowID, time.Now())
if err != nil {
res["message"] = msg
returnDataJSON(c, res, err)
return
}
res["message"] = msg
returnDataJSON(c, res, nil)
}
func userPacksLog(c *bm.Context) {
params := c.Request.Form
starttimeStr := params.Get("starttime")
pnStr := params.Get("pn")
pn, err := strconv.Atoi(pnStr)
if err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
if pn < 1 {
pn = 1
}
timeLayout := "2006-01"
loc, _ := time.LoadLocation("Local")
startTime, err := time.ParseInLocation(timeLayout, starttimeStr, loc)
if err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
c.JSON(unicomSvc.UserPacksLog(c, startTime, time.Now(), pn, metadata.String(c, metadata.RemoteIP)))
}
func userBindLog(c *bm.Context) {
res := map[string]interface{}{}
var mid int64
midInter, ok := c.Get("mid")
if ok {
mid = midInter.(int64)
} else {
res["message"] = "账号未登录"
returnDataJSON(c, res, ecode.RequestErr)
return
}
data, err := unicomSvc.UserBindLog(c, mid, time.Now())
if err != nil {
c.JSON(nil, err)
return
}
res["data"] = data
returnDataJSON(c, res, nil)
}
func welfareBindState(c *bm.Context) {
params := c.Request.Form
midStr := params.Get("mid")
mid, err := strconv.ParseInt(midStr, 10, 64)
if err != nil || mid < 1 {
c.JSON(nil, ecode.RequestErr)
return
}
data := unicomSvc.WelfareBindState(c, mid)
res := map[string]interface{}{
"state": data,
}
c.JSON(res, nil)
}

View File

@@ -0,0 +1,11 @@
package http
import bm "go-common/library/net/http/blademaster"
// walls get GetWall
func walls(c *bm.Context) {
res := map[string]interface{}{
"data": wallSvc.Wall(),
}
returnDataJSON(c, res, nil)
}

View File

@@ -0,0 +1,35 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["const.go"],
importpath = "go-common/app/interface/main/app-wall/model",
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/interface/main/app-wall/model/mobile:all-srcs",
"//app/interface/main/app-wall/model/operator:all-srcs",
"//app/interface/main/app-wall/model/telecom:all-srcs",
"//app/interface/main/app-wall/model/unicom:all-srcs",
"//app/interface/main/app-wall/model/wall:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,82 @@
package model
import (
"crypto/md5"
"encoding/hex"
"net"
)
const (
TypeIOS = "ios"
TypeAndriod = "android"
GdtIOSAppID = "736536022"
GdtAndroidAppID = "100951776"
ChannelToutiao = "toutiao"
ChannelShike = "2883"
ChannelDontin = "415209141"
)
type GdtKey struct {
Encrypt string
Sign string
}
var (
ChannelGdt = map[string]*GdtKey{
"1439767": &GdtKey{Encrypt: "BAAAAAAAAAAAFfgX", Sign: "ee358e8dccbbc4ba"},
"406965": &GdtKey{Encrypt: "BAAAAAAAAAAABjW1", Sign: "a45cbd2d4c5344b3"},
"7799673": &GdtKey{Encrypt: "BAAAAAAAAAAAdwN5", Sign: "54b6deffcd64b6b0"},
}
AppIDGdt = map[string]string{
TypeIOS: GdtIOSAppID,
TypeAndriod: GdtAndroidAppID,
}
)
func GdtIMEI(imei string) (gdtImei string) {
if imei == "" {
return
}
bs := md5.Sum([]byte(imei))
gdtImei = hex.EncodeToString(bs[:])
return
}
// InetAtoN conver ip addr to uint32.
func InetAtoN(s string) (sum uint32) {
ip := net.ParseIP(s)
if ip == nil {
return
}
ip = ip.To4()
if ip == nil {
return
}
sum += uint32(ip[0]) << 24
sum += uint32(ip[1]) << 16
sum += uint32(ip[2]) << 8
sum += uint32(ip[3])
return sum
}
// InetNtoA conver uint32 to ip addr.
func InetNtoA(sum uint32) string {
ip := make(net.IP, net.IPv4len)
ip[0] = byte((sum >> 24) & 0xFF)
ip[1] = byte((sum >> 16) & 0xFF)
ip[2] = byte((sum >> 8) & 0xFF)
ip[3] = byte(sum & 0xFF)
return ip.String()
}
// IsIPv4 is ipv4
func IsIPv4(addr string) bool {
ipv := net.ParseIP(addr)
if ip := ipv.To4(); ip != nil {
return true
} else {
return false
}
}

View File

@@ -0,0 +1,32 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["mobile.go"],
importpath = "go-common/app/interface/main/app-wall/model/mobile",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//library/log:go_default_library",
"//library/time:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,118 @@
package mobile
import (
"encoding/xml"
"strconv"
"time"
"go-common/library/log"
xtime "go-common/library/time"
)
type OrderXML struct {
XMLName xml.Name `xml:"SyncFlowPkgOrderReq"`
*MobileXML
}
type FlowXML struct {
XMLName xml.Name `xml:"SyncFlowPkgLeftQuotaReq"`
*MobileXML
}
type MobileXML struct {
Orderid string `xml:"OrderID"`
Userpseudocode string `xml:"UserPseudoCode"`
Channelseqid string `xml:"ChannelSeqId"`
Price string `xml:"Price"`
Actiontime string `xml:"ActionTime"`
Actionid string `xml:"ActionID"`
Effectivetime string `xml:"EffectiveTime"`
Expiretime string `xml:"ExpireTime"`
Channelid string `xml:"ChannelId"`
Productid string `xml:"ProductId"`
Ordertype string `xml:"OrderType"`
Threshold string `xml:"Threshold"`
Resulttime string `xml:"ResultTime"`
}
type Mobile struct {
Orderid string `json:"-"`
Userpseudocode string `json:"-"`
Channelseqid string `json:"-"`
Price int `json:"-"`
Actionid int `json:"actionid"`
Effectivetime xtime.Time `json:"starttime,omitempty"`
Expiretime xtime.Time `json:"endtime,omitempty"`
Channelid string `json:"-"`
Productid string `json:"productid,omitempty"`
Ordertype int `json:"-"`
Threshold int `json:"flow"`
Resulttime xtime.Time `json:"-"`
MobileType int `json:"orderstatus,omitempty"`
ProductType int `json:"product_type,omitempty"`
}
type MobileIP struct {
IPStartUint uint32 `json:"-"`
IPEndUint uint32 `json:"-"`
}
type MobileUserIP struct {
IPStr string `json:"ip"`
IsValide bool `json:"is_valide"`
}
// MobileChange
func (u *Mobile) MobileChange() {
if u.Effectivetime.Time().IsZero() {
u.Effectivetime = 0
}
if u.Expiretime.Time().IsZero() {
u.Expiretime = 0
}
switch u.Productid {
case "100000000028":
u.ProductType = 1
case "100000000030":
u.ProductType = 2
}
}
type Msg struct {
Xmlns string `xml:"xmlns,attr"`
MsgType string `xml:"MsgType"`
Version string `xml:"Version"`
HRet string `xml:"hRet"`
}
type OrderMsgXML struct {
XMLName xml.Name `xml:"SyncFlowPkgOrderResp"`
*Msg
}
type FlowMsgXML struct {
XMLName xml.Name `xml:"SyncFlowPkgLeftQuotaResp"`
*Msg
}
// MobileXMLMobile
func (u *Mobile) MobileXMLMobile(uxml *MobileXML) {
u.Actionid, _ = strconv.Atoi(uxml.Actionid)
u.Effectivetime = timeStrToInt(uxml.Effectivetime)
u.Expiretime = timeStrToInt(uxml.Expiretime)
u.Threshold, _ = strconv.Atoi(uxml.Threshold)
u.Productid = uxml.Productid
u.MobileChange()
}
// timeStrToInt
func timeStrToInt(timeStr string) (timeInt xtime.Time) {
var err error
timeLayout := "20060102"
loc, _ := time.LoadLocation("Local")
theTime, _ := time.ParseInLocation(timeLayout, timeStr, loc)
if err = timeInt.Scan(theTime); err != nil {
log.Error("timeInt.Scan error(%v)", err)
}
return
}

View File

@@ -0,0 +1,32 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["operator.go"],
importpath = "go-common/app/interface/main/app-wall/model/operator",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//library/log:go_default_library",
"//library/time:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,33 @@
package operator
import (
"time"
"go-common/library/log"
xtime "go-common/library/time"
)
type Reddot struct {
StartTime xtime.Time `json:"start_time,omitempty"`
EndTime xtime.Time `json:"end_time,omitempty"`
}
// ReddotChange Reddot change
func (r *Reddot) ReddotChange(startStr, endStr string) {
if startStr != "" && endStr != "" {
r.StartTime = timeStrToInt(startStr)
r.EndTime = timeStrToInt(endStr)
}
}
// timeStrToInt string to int
func timeStrToInt(timeStr string) (timeInt xtime.Time) {
var err error
timeLayout := "2006-01-02 15:04:05"
loc, _ := time.LoadLocation("Local")
theTime, _ := time.ParseInLocation(timeLayout, timeStr, loc)
if err = timeInt.Scan(theTime); err != nil {
log.Error("timeInt.Scan error(%v)", err)
}
return
}

View File

@@ -0,0 +1,32 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["telecom.go"],
importpath = "go-common/app/interface/main/app-wall/model/telecom",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//library/log:go_default_library",
"//library/time:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,163 @@
package telecom
import (
"strconv"
"time"
"go-common/library/log"
xtime "go-common/library/time"
)
type TelecomJSON struct {
FlowpackageID int `json:"flowPackageId"`
FlowPackageSize int `json:"flowPackageSize"`
FlowPackageType int `json:"flowPackageType"`
TrafficAttribution int `json:"trafficAttribution"`
BeginTime string `json:"beginTime"`
EndTime string `json:"endTime"`
IsMultiplyOrder int `json:"isMultiplyOrder"`
SettlementType int `json:"settlementType"`
Operator int `json:"operator"`
OrderStatus int `json:"orderStatus"`
RemainedRebindNum int `json:"remainedRebindNum"`
MaxbindNum int `json:"maxBindNum"`
OrderID string `json:"orderId"`
SignNo string `json:"signNo"`
AccessToken string `json:"accessToken"`
PhoneID string `json:"phoneId"`
IsRepeatOrder int `json:"isRepeatOrder"`
PayStatus int `json:"payStatus"`
PayTime string `json:"payTime"`
PayChannel int `json:"payChannel"`
SignStatus string `json:"signStatus "`
RefundStatus int `json:"refundStatus"`
PayResult *PayResultJSON `json:"payResult,omitempty"`
}
type PayResultJSON struct {
IsRepeatOrder int `json:"isRepeatOrder"`
RefundStatus int `json:"refundStatus"`
PayStatus int `json:"payStatus"`
PayChannel int `json:"payChannel"`
}
type TelecomOrderJson struct {
RequestNo string `json:"requestNo"`
ResultType int `json:"resultType"`
Detail *TelecomJSON `json:"detail"`
}
type TelecomRechargeJson struct {
RequestNo string `json:"requestNo"`
ResultType int `json:"resultType"`
Detail *RechargeJSON `json:"detail"`
}
type RechargeJSON struct {
RequestNo string `json:"requestNo"`
FcRechargeNo string `json:"fcRechargeNo"`
RechargeStatus int `json:"rechargeStatus"`
OrderTotalSize int `json:"orderTotalSize"`
FlowBalance int `json:"flowBalance"`
}
type OrderInfo struct {
PhoneID int `json:"phone"`
OrderID int64 `json:"orderid"`
OrderState int `json:"order_status"`
IsRepeatorder int `json:"isrepeatorder"`
SignNo string `json:"sign_no"`
Begintime xtime.Time `json:"begintime"`
Endtime xtime.Time `json:"endtime"`
}
type Pay struct {
OrderID int64 `json:"orderid"`
RequestNo int64 `json:"requestno,omitempty"`
PayURL string `json:"pay_url,omitempty"`
}
type SucOrder struct {
FlowPackageID string `json:"flowPackageId,omitempty"`
Domain string `json:"domain"`
Port string `json:"port,omitempty"`
PortInt int `json:"portInt"`
KeyEffectiveDuration int `json:"keyEffectiveDuration"`
OrderKey string `json:"orderKey"`
FlowBalance int `json:"flowBalance"`
FlowPackageSize int `json:"flowPackageSize"`
AccessToken string `json:"accessToken"`
OrderIDStr string `json:"orderId,omitempty"`
OrderID int64 `json:"orderid"`
}
type OrderFlow struct {
FlowBalance int `json:"flowBalance"`
}
type PhoneConsent struct {
Consent int `json:"consent"`
}
type TelecomMessageJSON struct {
PhoneID string `json:"phoneId"`
ResultType int `json:"resultType"`
ResultMessage string `json:"resultMsg"`
}
type OrderState struct {
FlowBalance int `json:"flowBalance,omitempty"`
FlowSize int `json:"flow_size"`
OrderState int `json:"order_state"`
Endtime xtime.Time `json:"endtime,omitempty"`
IsRepeatorder int `json:"is_repeatorder"`
}
type OrderPhoneState struct {
FlowPackageID int `json:"flowPackageId"`
FlowSize int `json:"flowPackageSize"`
OrderState int `json:"orderStatus"`
PhoneStr string `json:"phoneId"`
}
func (s *TelecomJSON) TelecomJSONChange() {
if s.PayResult != nil {
s.IsRepeatOrder = s.PayResult.IsRepeatOrder
s.RefundStatus = s.PayResult.RefundStatus
s.PayStatus = s.PayResult.PayStatus
s.PayChannel = s.PayResult.PayChannel
}
}
func (t *OrderInfo) OrderInfoJSONChange(tjson *TelecomJSON) {
t.PhoneID, _ = strconv.Atoi(tjson.PhoneID)
t.OrderID, _ = strconv.ParseInt(tjson.OrderID, 10, 64)
t.OrderState = tjson.OrderStatus
t.IsRepeatorder = tjson.IsRepeatOrder
t.SignNo = tjson.SignNo
t.Begintime = timeStrToInt(tjson.BeginTime)
t.Endtime = timeStrToInt(tjson.EndTime)
t.TelecomChange()
}
// timeStrToInt
func timeStrToInt(timeStr string) (timeInt xtime.Time) {
var err error
timeLayout := "2006-01-02 15:04:05"
loc, _ := time.LoadLocation("Local")
theTime, _ := time.ParseInLocation(timeLayout, timeStr, loc)
if err = timeInt.Scan(theTime); err != nil {
log.Error("timeInt.Scan error(%v)", err)
}
return
}
// TelecomChange
func (t *OrderInfo) TelecomChange() {
if t.Begintime.Time().IsZero() {
t.Begintime = 0
}
if t.Endtime.Time().IsZero() {
t.Endtime = 0
}
}

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 = ["unicom.go"],
importpath = "go-common/app/interface/main/app-wall/model/unicom",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-wall/model:go_default_library",
"//library/log:go_default_library",
"//library/time:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,259 @@
package unicom
import (
"encoding/json"
"fmt"
"strconv"
"strings"
"time"
"go-common/app/interface/main/app-wall/model"
"go-common/library/log"
xtime "go-common/library/time"
)
type Unicom struct {
Id int `json:"-"`
Spid int `json:"spid"`
CardType int `json:"cardtype"`
TypeInt int `json:"type"`
Unicomtype int `json:"unicomtype,omitempty"`
Ordertypes int `json:"-"`
Channelcode int `json:"-"`
Usermob string `json:"-"`
Cpid string `json:"-"`
Ordertime xtime.Time `json:"ordertime"`
Canceltime xtime.Time `json:"canceltime,omitempty"`
Endtime xtime.Time `json:"endtime,omitempty"`
Province string `json:"-"`
Area string `json:"-"`
Videoid string `json:"-"`
Time xtime.Time `json:"-"`
Flowbyte int `json:"flowbyte"`
}
type UnicomJson struct {
Usermob string `json:"usermob"`
Userphone string `json:"userphone"`
Cpid string `json:"cpid"`
Spid string `json:"spid"`
TypeInt string `json:"type"`
Ordertime string `json:"ordertime"`
Canceltime string `json:"canceltime"`
Endtime string `json:"endtime"`
Channelcode string `json:"channelcode"`
Province string `json:"province"`
Area string `json:"area"`
Ordertypes string `json:"ordertype"`
Videoid string `json:"videoid"`
Time string `json:"time"`
FlowbyteStr string `json:"flowbyte"`
}
type UnicomIpJson struct {
Ipbegin string `json:"ipbegin"`
Ipend string `json:"ipend"`
Provinces string `json:"province"`
Isopen string `json:"isopen"`
Opertime string `json:"opertime"`
Sign string `json:"sign"`
}
type UnicomIP struct {
Ipbegin int `json:"-"`
Ipend int `json:"-"`
IPStartUint uint32 `json:"-"`
IPEndUint uint32 `json:"-"`
}
type UnicomUserIP struct {
IPStr string `json:"ip"`
IsValide bool `json:"is_valide"`
}
type BroadbandOrder struct {
Usermob string `json:"userid,omitempty"`
Endtime string `json:"endtime,omitempty"`
Channel string `json:"channel,omitempty"`
}
type UserBind struct {
Usermob string `json:"usermob,omitempty"`
Phone int `json:"phone"`
Mid int64 `json:"mid"`
Name string `json:"name,omitempty"`
State int `json:"state,omitempty"`
Integral int `json:"integral"`
Flow int `json:"flow"`
Monthly time.Time `json:"monthly,omitempty"`
}
type UserPack struct {
ID int64 `json:"id"`
Type int `json:"type"`
Desc string `json:"desc"`
Amount int `json:"amount"`
Capped int8 `json:"capped"`
Integral int `json:"integral"`
Param string `json:"param"`
State int `json:"state,omitempty"`
}
type UserPackLimit struct {
IsLimit int `json:"is_limit"`
Count int `json:"count"`
}
type UnicomUserFlow struct {
Phone int `json:"phone"`
Mid int64 `json:"mid"`
Integral int `json:"integral"`
Flow int `json:"flow"`
Outorderid string `json:"outorderid"`
Orderid string `json:"orderid"`
Desc string `json:"desc"`
}
type UserPackLog struct {
Phone int `json:"phone,omitempty"`
Usermob string `json:"usermob,omitempty"`
Mid int64 `json:"mid,omitempty"`
RequestNo string `json:"request_no,omitempty"`
Type int `json:"pack_type"`
Desc string `json:"-"`
UserDesc string `json:"pack_desc,omitempty"`
Integral int `json:"integral,omitempty"`
}
type UserLog struct {
Phone int `json:"phone,omitempty"`
Integral int `json:"integral,omitempty"`
Desc string `json:"pack_desc,omitempty"`
Ctime string `json:"ctime,omitempty"`
}
type UserBindInfo struct {
MID int64 `json:"mid"`
Phone int `json:"phone"`
Action string `json:"action"`
}
// UnicomChange
func (u *Unicom) UnicomChange() {
if u.Canceltime.Time().IsZero() {
u.Canceltime = 0
}
if u.Endtime.Time().IsZero() {
u.Endtime = 0
}
switch u.Spid {
case 10019:
u.CardType = 1
case 10020:
u.CardType = 2
case 10021:
u.CardType = 3
case 979:
u.CardType = 4
}
}
func (u *UnicomJson) UnicomJSONChange() (err error) {
if u.Ordertypes != "" {
if _, err = strconv.Atoi(u.Ordertypes); err != nil {
log.Error("UnicomJsonChange error(%v)", u)
}
}
return
}
func (u *UnicomIP) UnicomIPChange() {
u.IPStartUint = u.unicomIPTOUint(u.Ipbegin)
u.IPEndUint = u.unicomIPTOUint(u.Ipend)
}
func (u *UnicomIP) unicomIPTOUint(ip int) (ipUnit uint32) {
var (
ip1, ip2, ip3, ip4 int
ipStr string
)
var _initIP = "%d.%d.%d.%d"
ip1 = ip / 1000000000
ip2 = (ip / 1000000) % 1000
ip3 = (ip / 1000) % 1000
ip4 = ip % 1000
ipStr = fmt.Sprintf(_initIP, ip1, ip2, ip3, ip4)
ipUnit = model.InetAtoN(ipStr)
return
}
// UnicomJSONTOUincom
func (u *Unicom) UnicomJSONTOUincom(usermob string, ujson *UnicomJson) {
u.Spid, _ = strconv.Atoi(ujson.Spid)
u.Ordertime = timeStrToInt(ujson.Ordertime)
u.Canceltime = timeStrToInt(ujson.Canceltime)
u.Endtime = timeStrToInt(ujson.Endtime)
u.TypeInt, _ = strconv.Atoi(ujson.TypeInt)
u.Ordertypes, _ = strconv.Atoi(ujson.Ordertypes)
u.Channelcode, _ = strconv.Atoi(ujson.Channelcode)
u.Usermob = usermob
u.Cpid = ujson.Cpid
u.Province = ujson.Province
u.UnicomChange()
}
// timeStrToInt
func timeStrToInt(timeStr string) (timeInt xtime.Time) {
var err error
timeLayout := "20060102150405"
loc, _ := time.LoadLocation("Local")
theTime, _ := time.ParseInLocation(timeLayout, timeStr, loc)
if err = timeInt.Scan(theTime); err != nil {
log.Error("timeInt.Scan error(%v)", err)
}
return
}
func (u *UnicomIP) UnicomIPStrToint(ipstart, ipend string) {
u.Ipbegin = ipToInt(ipstart)
u.Ipend = ipToInt(ipend)
}
// ipToint
func ipToInt(ipString string) (ipInt int) {
tmp := strings.Split(ipString, ".")
if len(tmp) < 4 {
return
}
var ipStr string
for _, tip := range tmp {
var (
ipLen = len(tip)
last int
ip1 string
)
if ipLen < 3 {
last = 3 - ipLen
switch last {
case 1:
ip1 = "0" + tip
case 2:
ip1 = "00" + tip
case 3:
ip1 = "000"
}
} else {
ip1 = tip
}
ipStr = ipStr + ip1
}
ipInt, _ = strconv.Atoi(ipStr)
return
}
func (t *UserLog) UserLogJSONChange(jsonData string) (err error) {
if err = json.Unmarshal([]byte(jsonData), &t); err != nil {
return
}
return
}

View File

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

View File

@@ -0,0 +1,11 @@
package wall
type Wall struct {
Id int `json:"-"`
Name string `json:"name"`
Package string `json:"package"`
Size string `json:"size"`
Logo string `json:"logo"`
Download string `json:"download"`
Remark string `json:"remark"`
}

View File

@@ -0,0 +1,53 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["mobile_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"mobile.go",
"service.go",
],
importpath = "go-common/app/interface/main/app-wall/service/mobile",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//app/interface/main/app-wall/dao/mobile:go_default_library",
"//app/interface/main/app-wall/model:go_default_library",
"//app/interface/main/app-wall/model/mobile:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/stat/prom: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,167 @@
package mobile
import (
"context"
"time"
"go-common/app/interface/main/app-wall/model"
"go-common/app/interface/main/app-wall/model/mobile"
"go-common/library/ecode"
"go-common/library/log"
)
const (
_mobileKey = "mobile"
)
// InOrdersSync insert OrdersSync
func (s *Service) InOrdersSync(c context.Context, ip string, u *mobile.MobileXML, now time.Time) (err error) {
if !s.iplimit(_mobileKey, ip) {
err = ecode.AccessDenied
return
}
var result int64
if result, err = s.dao.InOrdersSync(c, u); err != nil || result == 0 {
log.Error("mobile_s.dao.OrdersSync (%v) error(%v) or result==0", u, err)
}
return
}
// FlowSync update OrdersSync
func (s *Service) FlowSync(c context.Context, u *mobile.MobileXML, ip string) (err error) {
if !s.iplimit(_mobileKey, ip) {
err = ecode.AccessDenied
return
}
var result int64
if result, err = s.dao.FlowSync(c, u); err != nil || result == 0 {
log.Error("mobile_s.dao.OrdersSync(%v) error(%v) or result==0", u, err)
}
return
}
// Activation
func (s *Service) Activation(c context.Context, usermob string, now time.Time) (msg string, err error) {
rows := s.mobileInfo(c, usermob, now)
res, ok := rows[usermob]
if !ok {
err = ecode.NothingFound
msg = "该卡号尚未开通哔哩哔哩专属免流服务"
return
}
for _, u := range res {
if u.Actionid == 1 || (u.Actionid == 2 && now.Unix() <= int64(u.Expiretime)) {
return
}
}
err = ecode.NotModified
msg = "该卡号哔哩哔哩专属免流服务已退订且已过期"
return
}
// Activation
func (s *Service) MobileState(c context.Context, usermob string, now time.Time) (res *mobile.Mobile) {
data := s.mobileInfo(c, usermob, now)
res = s.userState(data, usermob, now)
return
}
// UserFlowState
func (s *Service) UserMobileState(c context.Context, usermob string, now time.Time) (res *mobile.Mobile) {
data := s.mobileInfo(c, usermob, now)
if rows, ok := data[usermob]; ok {
for _, res = range rows {
if res.Actionid == 1 || (res.Actionid == 2 && now.Unix() <= int64(res.Expiretime)) {
res.MobileType = 2
return
}
}
res = &mobile.Mobile{MobileType: 1}
}
res = &mobile.Mobile{MobileType: 1}
return
}
// userState
func (s *Service) userState(user map[string][]*mobile.Mobile, usermob string, now time.Time) (res *mobile.Mobile) {
if rows, ok := user[usermob]; !ok {
res = &mobile.Mobile{MobileType: 1}
} else {
for _, res = range rows {
if res.Actionid == 2 && now.Unix() <= int64(res.Expiretime) {
res.MobileType = 4
break
} else if res.Actionid == 1 {
res.MobileType = 2
break
}
}
if res.MobileType == 0 {
res.MobileType = 3
}
}
log.Info("mobile_state_type:%v mobile_state_usermob:%v", res.MobileType, usermob)
return
}
// mobileInfo
func (s *Service) mobileInfo(c context.Context, usermob string, now time.Time) (res map[string][]*mobile.Mobile) {
var (
err error
m []*mobile.Mobile
tmps []*mobile.Mobile
row = map[string][]*mobile.Mobile{}
)
res = map[string][]*mobile.Mobile{}
if m, err = s.dao.MobileCache(c, usermob); err == nil && len(m) > 0 {
row[usermob] = m
s.pHit.Incr("mobile_cache")
} else {
row, err = s.dao.OrdersUserFlow(c, usermob, now)
if err != nil {
log.Error("mobile_s.dao.OrdersUserFlow error(%v)", err)
return
}
s.pMiss.Incr("mobile_cache")
if user, ok := row[usermob]; ok && len(user) > 0 {
if err = s.dao.AddMobileCache(c, usermob, user); err != nil {
log.Error("s.dao.AddMobileCache error(%v)", err)
return
}
}
}
if ms, ok := row[usermob]; ok && len(ms) > 0 {
for _, m := range ms {
tmp := &mobile.Mobile{}
*tmp = *m
tmp.Productid = ""
tmps = append(tmps, tmp)
}
res[usermob] = tmps
}
return
}
// IsMobileIP is mobile ip
func (s *Service) IsMobileIP(ipUint uint32, ipStr, usermob string) (res *mobile.MobileUserIP) {
res = &mobile.MobileUserIP{
IPStr: ipStr,
IsValide: false,
}
if !model.IsIPv4(ipStr) {
return
}
for _, u := range s.mobileIpCache {
if u.IPStartUint <= ipUint && u.IPEndUint >= ipUint {
res.IsValide = true
return
}
}
log.Error("mobile_user_ip:%v mobile_ip_usermob:%v", ipStr, usermob)
return
}
// mobileIp ip limit
func (s *Service) iplimit(k, ip string) bool {
return true
}

View File

@@ -0,0 +1,60 @@
package mobile
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-wall/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
s *Service
)
func WithService(f func(s *Service)) func() {
return func() {
f(s)
}
}
func init() {
dir, _ := filepath.Abs("../../cmd/app-wall-test.toml")
flag.Set("conf", dir)
conf.Init()
s = New(conf.Conf)
time.Sleep(time.Second)
}
func TestActivation(t *testing.T) {
Convey("Unicom Activation", t, WithService(func(s *Service) {
res, err := s.Activation(context.TODO(), "", time.Now())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
}))
}
func TestMobileState(t *testing.T) {
Convey("Unicom MobileState", t, WithService(func(s *Service) {
res := s.MobileState(context.TODO(), "", time.Now())
So(res, ShouldNotBeEmpty)
}))
}
func TestUserMobileState(t *testing.T) {
Convey("Unicom UserMobileState", t, WithService(func(s *Service) {
res := s.UserMobileState(context.TODO(), "", time.Now())
So(res, ShouldNotBeEmpty)
}))
}
func TestIsMobileIP(t *testing.T) {
Convey("Unicom IsMobileIP", t, WithService(func(s *Service) {
res := s.IsMobileIP(1, "", "")
So(res, ShouldNotBeEmpty)
}))
}

View File

@@ -0,0 +1,78 @@
package mobile
import (
"bufio"
"io"
"os"
"strings"
"time"
"go-common/app/interface/main/app-wall/conf"
mobileDao "go-common/app/interface/main/app-wall/dao/mobile"
"go-common/app/interface/main/app-wall/model"
"go-common/app/interface/main/app-wall/model/mobile"
"go-common/library/log"
"go-common/library/stat/prom"
)
type Service struct {
c *conf.Config
dao *mobileDao.Dao
tick time.Duration
mobileIpCache []*mobile.MobileIP
ipPath string
// prom
pHit *prom.Prom
pMiss *prom.Prom
}
func New(c *conf.Config) (s *Service) {
s = &Service{
c: c,
dao: mobileDao.New(c),
tick: time.Duration(c.Tick),
mobileIpCache: []*mobile.MobileIP{},
ipPath: c.IPLimit.MobileIPFile,
// prom
pHit: prom.CacheHit,
pMiss: prom.CacheMiss,
}
s.loadIP()
return
}
func (s *Service) loadIP() {
var (
ip *mobile.MobileIP
file *os.File
line string
err error
ips []*mobile.MobileIP
)
if file, err = os.Open(s.ipPath); err != nil {
log.Error("mobileIPFile is null")
return
}
defer file.Close()
reader := bufio.NewReader(file)
for {
if line, err = reader.ReadString('\n'); err != nil {
if err == io.EOF {
err = nil
break
}
continue
}
lines := strings.Fields(line)
if len(lines) < 3 {
continue
}
ip = &mobile.MobileIP{
IPStartUint: model.InetAtoN(lines[1]),
IPEndUint: model.InetAtoN(lines[2]),
}
ips = append(ips, ip)
}
s.mobileIpCache = ips
log.Info("loadMobileIPCache success")
}

View File

@@ -0,0 +1,50 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["offer_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["offer.go"],
importpath = "go-common/app/interface/main/app-wall/service/offer",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//app/interface/main/app-wall/dao/callback:go_default_library",
"//app/interface/main/app-wall/dao/offer:go_default_library",
"//app/interface/main/app-wall/dao/padding:go_default_library",
"//app/interface/main/app-wall/model:go_default_library",
"//library/log: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,224 @@
package offer
import (
"context"
iaes "crypto/aes"
icipher "crypto/cipher"
"crypto/md5"
"encoding/hex"
"time"
"go-common/app/interface/main/app-wall/conf"
callbackdao "go-common/app/interface/main/app-wall/dao/callback"
offerdao "go-common/app/interface/main/app-wall/dao/offer"
"go-common/app/interface/main/app-wall/dao/padding"
"go-common/app/interface/main/app-wall/model"
"go-common/library/log"
"github.com/pkg/errors"
)
type Service struct {
c *conf.Config
dao *offerdao.Dao
cbdao *callbackdao.Dao
}
func New(c *conf.Config) (s *Service) {
s = &Service{
c: c,
dao: offerdao.New(c),
cbdao: callbackdao.New(c),
}
return
}
// Click
func (s *Service) Click(c context.Context, ip uint32, cid, mac, idfa, cb string, now time.Time) (err error) {
res, err := s.dao.InClick(c, ip, cid, mac, idfa, cb, now)
if err != nil || res == 0 {
log.Error("s.dao.InClick(%d, %s, %s, %s, %s) error(%v) or row==0", ip, cid, mac, idfa, cb, now, err)
}
return
}
// ANClick
func (s *Service) ANClick(c context.Context, channel, imei, androidid, mac, cb string, ip uint32, now time.Time) (err error) {
res, err := s.dao.InANClick(c, channel, imei, androidid, mac, cb, ip, now)
if err != nil {
return
}
if res == 0 {
log.Error("s.dao.InANClick(%s, %s, %s, %s, %s, %d, %s) row==0", channel, imei, androidid, mac, cb, ip, now, err)
}
return
}
func (s *Service) ANActive(c context.Context, imei, androidid, mac string, now time.Time) (err error) {
const (
_typeUnactive = 0
_typeActive = 1
)
//gdt
gdtImei := model.GdtIMEI(imei)
count, err := s.dao.ANActive(c, androidid, imei, gdtImei)
if err != nil {
return
}
if count > 0 {
log.Warn("ANActive androidid(%s) imei(%s) gdtImei(%s) already count(%d) activated", androidid, imei, gdtImei, count)
return
}
id, channel, cb, typ, err := s.dao.ANCallback(c, androidid, imei, gdtImei)
if err != nil {
return
}
if id == 0 {
log.Warn("ANActive androidid(%s) imei(%s) gdtImei(%s) not exist", androidid, imei, gdtImei)
return
}
if typ != _typeUnactive {
log.Warn("ANActive androidid(%s) imei(%s) gdtImei(%s) already activated", androidid, imei, gdtImei)
return
}
if err = s.newCallback(c, model.TypeAndriod, channel, imei, gdtImei, cb, now); err != nil {
err = errors.Wrapf(err, "%d", id)
return
}
if _, err = s.dao.ANClickAct(c, id, _typeActive); err != nil {
return
}
return
}
func (s *Service) newCallback(c context.Context, appType, channel string, imei, gdtImei, cb string, now time.Time) (err error) {
const (
_eventActive = "0"
)
switch channel {
case model.ChannelToutiao:
err = s.cbdao.ToutiaoCallback(c, cb, _eventActive)
// gdt
case model.ChannelShike:
err = s.cbdao.ShikeCallback(c, imei, cb, now)
case model.ChannelDontin:
err = s.cbdao.DontinCallback(c, imei, cb)
default:
if _, ok := model.ChannelGdt[channel]; ok {
if appID, ok := model.AppIDGdt[appType]; ok {
err = s.cbdao.GdtCallback(c, appID, appType, channel, gdtImei, cb, now)
}
} else {
log.Warn("channel(%s) undefined", channel)
}
}
return
}
func (s *Service) Active(c context.Context, ip uint32, mid, rmac, mac, idfa, device string, now time.Time) (err error) {
var (
count int
)
res, err := s.dao.InActive(c, ip, mid, rmac, mac, idfa, device, now)
if err != nil {
log.Error("s.dao.InActive(%d, %s, %s, %s, %s, %s) error(%v) or row==0", ip, mid, rmac, mac, idfa, device, err)
return
}
if res == 0 {
log.Warn("wall active(%s) exist", idfa)
return
}
if rmac != "" {
count, err = s.dao.RMacCount(c, rmac)
if err != nil {
log.Error("s.dao.RMacCount(%s) error(%d)", rmac, err)
return
}
if count > 10 {
log.Warn("wallService.RMacCount(%s) count(%d) more than 10", rmac, count)
return
}
}
return s.callback(c, model.TypeIOS, idfa, now)
}
func (s *Service) Exists(c context.Context, idfa string) (exist bool, err error) {
exist, err = s.dao.Exists(c, idfa)
if err != nil {
log.Error("s.dao.Exists(%s) error(%v)", idfa, err)
}
return
}
// callback
func (s *Service) callback(c context.Context, appType, idfa string, now time.Time) (err error) {
if len(idfa) <= 20 {
return
}
// only gdt
allIdfa := idfa[0:8] + "-" + idfa[8:12] + "-" + idfa[12:16] + "-" + idfa[16:20] + "-" + idfa[20:]
bs := md5.Sum([]byte(allIdfa))
gdtIdfa := hex.EncodeToString(bs[:])
// get callback
channel, cb, err := s.dao.Callback(c, idfa, gdtIdfa, now)
if err != nil {
log.Error("s.dao.Callback(%s) error(%v)", idfa, err)
return
}
if cb == "" {
log.Info("callback idfa(%s) callback url is not exists", idfa)
return
}
switch channel {
case model.ChannelShike:
s.cbdao.ShikeCallback(c, idfa, cb, now)
s.dao.UpIdfaActive(c, allIdfa, idfa, now)
case model.ChannelDontin:
s.cbdao.DontinCallback(c, idfa, cb)
s.dao.UpIdfaActive(c, allIdfa, idfa, now)
default:
if _, ok := model.ChannelGdt[channel]; ok {
if appID, ok := model.AppIDGdt[appType]; ok {
if err = s.cbdao.GdtCallback(c, appID, appType, channel, gdtIdfa, cb, now); err != nil {
s.dao.UpIdfaActive(c, allIdfa, gdtIdfa, now)
}
}
} else {
log.Warn("channel(%s) undefined", channel)
}
}
return
}
// CBCDecrypt aes cbc decrypt.
func (s *Service) CBCDecrypt(src, key, iv []byte, p padding.Padding) ([]byte, error) {
var (
ErrAesSrcSize = errors.New("ciphertext too short")
ErrAesIVSize = errors.New("iv size is not a block size")
)
// check src
if len(src) < iaes.BlockSize || len(src)%iaes.BlockSize != 0 {
log.Info("check src src(%v) blockSize (%v)", src, iaes.BlockSize)
log.Info("len(src) < iaes.BlockSize (%v)", len(src) < iaes.BlockSize)
log.Info("len(src)%iaes.BlockSize != 0 (%v)", len(src)%iaes.BlockSize != 0)
return nil, ErrAesSrcSize
}
// check iv
if len(iv) != iaes.BlockSize {
log.Info("check iv iv(%v) blockSize (%v)", iv, iaes.BlockSize)
return nil, ErrAesIVSize
}
block, err := iaes.NewCipher(key)
if err != nil {
log.Error("iaes.NewCipher err(%v)", err)
return nil, err
}
mode := icipher.NewCBCDecrypter(block, iv)
decryptText := make([]byte, len(src))
mode.CryptBlocks(decryptText, src)
if p == nil {
return decryptText, nil
} else {
return p.Unpadding(decryptText, iaes.BlockSize)
}
}

View File

@@ -0,0 +1,58 @@
package offer
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-wall/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
s *Service
)
func init() {
dir, _ := filepath.Abs("../../cmd/app-wall-test.toml")
flag.Set("conf", dir)
conf.Init()
s = New(conf.Conf)
}
func WithService(f func(s *Service)) func() {
return func() {
f(s)
}
}
func TestTelecomPay(t *testing.T) {
Convey("TelecomPay", t, WithService(func(s *Service) {
err := s.Click(context.TODO(), 1, "", "", "", "", time.Now())
So(err, ShouldBeNil)
}))
}
func TestANClick(t *testing.T) {
Convey("ANClick", t, WithService(func(s *Service) {
err := s.ANClick(context.TODO(), "", "", "", "", "", 1, time.Now())
So(err, ShouldBeNil)
}))
}
func TestANActive(t *testing.T) {
Convey("ANActive", t, WithService(func(s *Service) {
err := s.ANActive(context.TODO(), "", "", "", time.Now())
So(err, ShouldBeNil)
}))
}
func TestActive(t *testing.T) {
Convey("Active", t, WithService(func(s *Service) {
err := s.Active(context.TODO(), 1, "", "", "", "", "", time.Now())
So(err, ShouldBeNil)
}))
}

View File

@@ -0,0 +1,45 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["operator_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["operator.go"],
importpath = "go-common/app/interface/main/app-wall/service/operator",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//app/interface/main/app-wall/model/operator: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,42 @@
package operator
import (
"time"
"go-common/app/interface/main/app-wall/conf"
"go-common/app/interface/main/app-wall/model/operator"
)
// Service reddot service
type Service struct {
c *conf.Config
cache *operator.Reddot
}
// New reddot new
func New(c *conf.Config) (s *Service) {
s = &Service{
c: c,
cache: &operator.Reddot{},
}
s.loadCache(c)
return
}
// Reddot get reddot
func (s *Service) Reddot(now time.Time) (res *operator.Reddot) {
res = s.cache
if res != nil {
current := now.Unix()
if current > int64(res.EndTime) || current < int64(res.StartTime) {
res = &operator.Reddot{}
}
}
return
}
func (s *Service) loadCache(c *conf.Config) {
tmp := &operator.Reddot{}
tmp.ReddotChange(c.Reddot.StartTime, c.Reddot.EndTime)
s.cache = tmp
}

View File

@@ -0,0 +1,37 @@
package operator
import (
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-wall/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
s *Service
)
func WithService(f func(s *Service)) func() {
return func() {
f(s)
}
}
func init() {
dir, _ := filepath.Abs("../../cmd/app-wall-test.toml")
flag.Set("conf", dir)
conf.Init()
s = New(conf.Conf)
time.Sleep(time.Second)
}
func TestReddot(t *testing.T) {
Convey("operator Reddot", t, WithService(func(s *Service) {
res := s.Reddot(time.Now())
So(res, ShouldNotBeEmpty)
}))
}

View File

@@ -0,0 +1,45 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["ping_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["ping.go"],
importpath = "go-common/app/interface/main/app-wall/service/ping",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//app/interface/main/app-wall/dao/wall: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,24 @@
package ping
import (
"context"
"go-common/app/interface/main/app-wall/conf"
walldao "go-common/app/interface/main/app-wall/dao/wall"
)
type Service struct {
wallDao *walldao.Dao
}
func New(c *conf.Config) (s *Service) {
s = &Service{
wallDao: walldao.New(c),
}
return
}
// Ping is check server ping.
func (s *Service) Ping(c context.Context) (err error) {
return s.wallDao.Ping(c)
}

View File

@@ -0,0 +1,38 @@
package ping
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-wall/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
s *Service
)
func WithService(f func(s *Service)) func() {
return func() {
f(s)
}
}
func init() {
dir, _ := filepath.Abs("../../cmd/app-wall-test.toml")
flag.Set("conf", dir)
conf.Init()
s = New(conf.Conf)
time.Sleep(time.Second)
}
func TestPing(t *testing.T) {
Convey("Unicom Ping", t, WithService(func(s *Service) {
err := s.Ping(context.TODO())
So(err, ShouldBeNil)
}))
}

View File

@@ -0,0 +1,54 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["telecom_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"service.go",
"telecom.go",
],
importpath = "go-common/app/interface/main/app-wall/service/telecom",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//app/interface/main/app-wall/dao/seq:go_default_library",
"//app/interface/main/app-wall/dao/telecom:go_default_library",
"//app/interface/main/app-wall/model/telecom:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/stat/prom:go_default_library",
"//library/sync/errgroup: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,80 @@
package telecom
import (
"fmt"
"go-common/app/interface/main/app-wall/conf"
seqDao "go-common/app/interface/main/app-wall/dao/seq"
telecomDao "go-common/app/interface/main/app-wall/dao/telecom"
"go-common/library/log"
"go-common/library/stat/prom"
)
const (
_initIPlimitKey = "iplimit_%v_%v"
_telecomKey = "telecom"
)
type Service struct {
c *conf.Config
dao *telecomDao.Dao
seqdao *seqDao.Dao
flowPercentage int
smsTemplate string
smsMsgTemplate string
smsFlowTemplate string
smsOrderTemplateOK string
operationIPlimit map[string]struct{}
telecomArea map[string]struct{}
// prom
pHit *prom.Prom
pMiss *prom.Prom
}
func New(c *conf.Config) (s *Service) {
s = &Service{
c: c,
dao: telecomDao.New(c),
seqdao: seqDao.New(c),
flowPercentage: c.Telecom.FlowPercentage,
smsTemplate: c.Telecom.SMSTemplate,
smsMsgTemplate: c.Telecom.SMSMsgTemplate,
smsFlowTemplate: c.Telecom.SMSFlowTemplate,
smsOrderTemplateOK: c.Telecom.SMSOrderTemplateOK,
operationIPlimit: map[string]struct{}{},
telecomArea: map[string]struct{}{},
// prom
pHit: prom.CacheHit,
pMiss: prom.CacheMiss,
}
go s.loadIPlimit(c)
go s.loadTelecomArea(c)
return
}
func (s *Service) loadIPlimit(c *conf.Config) {
hosts := make(map[string]struct{}, len(c.IPLimit.Addrs))
for k, v := range c.IPLimit.Addrs {
for _, ipStr := range v {
key := fmt.Sprintf(_initIPlimitKey, k, ipStr)
if _, ok := hosts[key]; !ok {
hosts[key] = struct{}{}
}
}
}
s.operationIPlimit = hosts
log.Info("loadTelecomIPCache success")
}
func (s *Service) loadTelecomArea(c *conf.Config) {
areas := make(map[string]struct{}, len(c.Telecom.Area))
for _, v := range c.Telecom.Area {
for _, area := range v {
if _, ok := areas[area]; !ok {
areas[area] = struct{}{}
}
}
}
s.telecomArea = areas
log.Info("loadTelecomArea success")
}

View File

@@ -0,0 +1,488 @@
package telecom
import (
"bytes"
"context"
"crypto/des"
"errors"
"fmt"
"math/rand"
"strconv"
"time"
"go-common/app/interface/main/app-wall/model/telecom"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/sync/errgroup"
)
const (
_sendSMSCaptcha = `{"captcha":"%v"}`
_sendSMSFlow = `{"flow":"%v"}`
_flowPackageID = 279
)
// InOrdersSync insert OrdersSync
func (s *Service) InOrdersSync(c context.Context, ip string, u *telecom.TelecomOrderJson) (err error) {
if !s.iplimit(_telecomKey, ip) {
err = ecode.AccessDenied
return
}
if u == nil || u.Detail == nil {
err = ecode.NothingFound
return
}
var (
result int64
requestNo int
phoneStr string
detail = u.Detail
)
detail.TelecomJSONChange()
requestNo, _ = strconv.Atoi(u.RequestNo)
if detail.PhoneID == "" {
if phoneStr, err = s.dao.PayPhone(c, int64(requestNo)); err != nil {
log.Error("telecom_s.dao.PayPhone error(%v)", err)
return
}
} else {
phoneStr = detail.PhoneID
}
if result, err = s.dao.InOrderSync(c, requestNo, u.ResultType, phoneStr, detail); err != nil || result == 0 {
log.Error("telecom_s.dao.OrdersSync (%v) error(%v) or result==0", u, err)
return
}
if detail.OrderStatus == 3 {
phoneInt, _ := strconv.Atoi(phoneStr)
if err = s.dao.SendTelecomSMS(c, phoneInt, s.smsOrderTemplateOK); err != nil {
log.Error("telecom_s.dao.SendTelecomSMS error(%v)", err)
return
}
}
return
}
// InRechargeSync insert RechargeSync
func (s *Service) InRechargeSync(c context.Context, ip string, u *telecom.RechargeJSON) (err error) {
if !s.iplimit(_telecomKey, ip) {
err = ecode.AccessDenied
return
}
var result int64
if result, err = s.dao.InRechargeSync(c, u); err != nil || result == 0 {
log.Error("telecom_s.dao.InRechargeSync (%v) error(%v) or result==0", u, err)
return
}
return
}
// telecomMessageOrder
func (s *Service) TelecomMessageSync(c context.Context, ip string, u *telecom.TelecomMessageJSON) (err error) {
if !s.iplimit(_telecomKey, ip) {
err = ecode.AccessDenied
return
}
if u == nil {
err = ecode.ServerErr
return
}
phoneInt, _ := strconv.Atoi(u.PhoneID)
if err = s.dao.SendTelecomSMS(c, phoneInt, s.smsMsgTemplate); err != nil {
log.Error("telecom_s.dao.SendTelecomSMS error(%v)", err)
return
}
return
}
// telecomInfo
func (s *Service) telecomInfo(c context.Context, phone int) (res map[int]*telecom.OrderInfo, err error) {
var (
row *telecom.OrderInfo
)
res = map[int]*telecom.OrderInfo{}
if row, err = s.dao.TelecomCache(c, phone); err == nil && row != nil {
res[phone] = row
s.pHit.Incr("telecom_cache")
return
}
if res, err = s.dao.OrdersUserFlow(c, phone); err != nil {
log.Error("telecom_s.dao.OrdersUserFlow phone (%v) error(%v)", phone, err)
return
}
s.pMiss.Incr("telecom_cache")
if user, ok := res[phone]; ok {
if err = s.dao.AddTelecomCache(c, phone, user); err != nil {
log.Error("telecom_s.dao.AddTelecomCache error(%v)", err)
return
}
}
return
}
// telecomInfoByOrderID
func (s *Service) telecomInfoByOrderID(c context.Context, orderID int64) (res map[int64]*telecom.OrderInfo, err error) {
var (
row *telecom.OrderInfo
)
res = map[int64]*telecom.OrderInfo{}
if row, err = s.dao.TelecomOrderIDCache(c, orderID); err == nil && row != nil {
res[orderID] = row
s.pHit.Incr("telecom_orderid_cache")
return
}
if res, err = s.dao.OrdersUserByOrderID(c, orderID); err != nil {
log.Error("telecom_s.dao.OrdersUserByOrderID phone (%v) error(%v)", orderID, err)
return
}
s.pMiss.Incr("telecom_orderid_cache")
if user, ok := res[orderID]; ok {
if err = s.dao.AddTelecomOrderIDCache(c, orderID, user); err != nil {
log.Error("telecom_s.dao.AddTelecomOrderIDCache error(%v)", err)
return
}
}
return
}
// TelecomPay
func (s *Service) TelecomPay(c context.Context, phone, isRepeatOrder, payChannel, payAction int, orderID int64, ipStr string) (res *telecom.Pay, msg string, err error) {
var (
requestNo int64
t map[int]*telecom.OrderInfo
rcode int
beginTime time.Time
firstOrderEndtime time.Time
)
if requestNo, err = s.seqdao.SeqID(c); err != nil {
log.Error("telecom_s.seqdao.SeqID error (%v)", err)
return
}
if t, err = s.telecomInfo(c, phone); err != nil {
log.Error("telecom_s.telecomInfo phone(%v) error (%v)", phone, err)
return
}
if user, ok := t[phone]; ok {
beginTime = user.Begintime.Time()
firstOrderEndtime = user.Endtime.Time()
}
if res, err, msg = s.dao.PayInfo(c, requestNo, phone, isRepeatOrder, payChannel, payAction, orderID, ipStr, beginTime, firstOrderEndtime); err != nil || res == nil {
log.Error("telecom_s.dao.PayInfo requestNo (%v) phone (%v) isRepeatOrder (%v) payChannel (%v) payAction (%v) t.OrderID (%v) ipStr (%v) error (%v)",
requestNo, phone, isRepeatOrder, payChannel, payAction, orderID, ipStr, err)
return
}
phoneStr := strconv.Itoa(phone)
if rcode, err = s.dao.AddPayPhone(c, requestNo, phoneStr); err != nil || rcode != 1 {
log.Error("telecom_s.dao.AddPayPhone error (%v)", err)
return
}
return
}
// CancelRepeatOrder
func (s *Service) CancelRepeatOrder(c context.Context, phone int) (msg string, err error) {
var (
res map[int]*telecom.OrderInfo
)
res, err = s.telecomInfo(c, phone)
if err != nil {
log.Error("telecom_s.telecomInfo phone(%v) error (%v)", phone, err)
return
}
user, ok := res[phone]
if !ok {
err = ecode.NothingFound
msg = "订单不存在"
return
}
if msg, err = s.dao.CancelRepeatOrder(c, phone, user.SignNo); err != nil {
log.Error("telecom_s.dao.CancelRepeatOrder phone(%v) signNo(%v) error (%v)", phone, user.SignNo, err)
return
}
return
}
// OrderList user order list
func (s *Service) OrderList(c context.Context, orderID int64, phone int) (res *telecom.SucOrder, msg string, err error) {
if res, err, msg = s.dao.SucOrderList(c, phone); err != nil || res == nil {
log.Error("telecom_s.dao.SucOrderList orderID (%v) phone (%v) error (%v)", orderID, phone, err)
return
}
return
}
// PhoneFlow user flow
func (s *Service) PhoneFlow(c context.Context, orderID int64, phone int) (res *telecom.OrderFlow, msg string, err error) {
var t *telecom.SucOrder
if t, err, msg = s.dao.SucOrderList(c, phone); err != nil || t == nil {
log.Error("telecom_s.dao.SucOrderList orderID (%v) phone (%v) error (%v)", orderID, phone, err)
return
}
res = &telecom.OrderFlow{
FlowBalance: t.FlowBalance,
}
if (t.FlowBalance/t.FlowPackageSize)*100 < s.flowPercentage {
flow := strconv.Itoa(t.FlowBalance)
dataJSON := fmt.Sprintf(_sendSMSFlow, flow)
if err = s.dao.SendSMS(c, phone, s.smsFlowTemplate, dataJSON); err != nil {
log.Error("telecom_s.dao.SendSMS phone(%v) error (%v)", phone, err)
return
}
msg = "免流量量剩余不不⾜足10%,超出部分会按正常流量量资费计费"
return
}
return
}
// OrderConsent user orderConsent
func (s *Service) OrderConsent(c context.Context, phone int, orderID int64, captcha string) (res *telecom.PhoneConsent, msg string, err error) {
var (
area string
t *telecom.SucOrder
captchaStr string
order *telecom.OrderPhoneState
)
captchaStr, err = s.dao.PhoneCode(c, phone)
if err != nil {
log.Error("telecom_s.dao.PhoneCode error (%v)", err)
msg = "验证码已过期"
return
}
if captchaStr == "" || captchaStr != captcha {
err = ecode.NotModified
msg = "验证码错误"
return
}
res = &telecom.PhoneConsent{
Consent: 0,
}
g, ctx := errgroup.WithContext(c)
g.Go(func() error {
if area, err, msg = s.dao.PhoneArea(ctx, phone); err != nil {
log.Error("telecom_s.dao.PhoneArea phone(%v) error (%v)", phone, err)
return err
}
return nil
})
g.Go(func() error {
if t, err, _ = s.dao.SucOrderList(ctx, phone); err != nil {
if err == ecode.NothingFound {
err = nil
} else {
log.Error("telecom_s.dao.SucOrderList sphone (%v) error (%v)", phone, err)
}
return err
}
return nil
})
if orderID > 0 {
g.Go(func() error {
if order, err = s.dao.OrderState(ctx, orderID); err != nil {
log.Error("telecom_s.dao.OrderState phone(%v) orderID(%v) error(%v)", phone, orderID, err)
return err
}
return nil
})
}
if err = g.Wait(); err != nil {
log.Error("telecom_errgroup.WithContext error(%v)", err)
return
}
if len(area) >= 4 {
a := area[:4]
if _, ok := s.telecomArea[a]; !ok {
return
}
}
if order != nil && order.OrderState == 2 && order.FlowPackageID == _flowPackageID {
res.Consent = 3
return
}
if t != nil && t.OrderID > 0 {
res.Consent = 2
return
}
res.Consent = 1
return
}
// PhoneCode
func (s *Service) PhoneCode(c context.Context, phone int, captcha string, now time.Time) (res *telecom.Pay, err error, msg string) {
var (
captchaStr string
order map[int]*telecom.OrderInfo
)
captchaStr, err = s.dao.PhoneCode(c, phone)
if err != nil {
log.Error("telecom_s.dao.PhoneCode error (%v)", err)
msg = "验证码已过期"
return
}
if captchaStr == "" || captchaStr != captcha {
err = ecode.NotModified
msg = "验证码错误"
return
}
if order, err = s.telecomInfo(c, phone); err != nil {
log.Error("telecom_s.telecomInfo phone(%v) error (%v)", phone, err)
return
}
user, ok := order[phone]
if !ok {
err = ecode.NothingFound
msg = "订单不存在"
return
}
switch user.OrderState {
case 2:
err = ecode.NotModified
msg = "订购中"
case 3:
if now.Unix() > int64(user.Endtime) {
err = ecode.NotModified
msg = "订单已过期"
} else {
res = &telecom.Pay{
OrderID: user.OrderID,
}
msg = "激活成功,麻麻再也不不⽤用担⼼心我的流量量了了(/≧▽≦)/"
}
case 4:
err = ecode.NotModified
msg = "订单失败"
case 5:
err = ecode.NotModified
msg = "订单已过期"
}
return
}
// PhoneSendSMS
func (s *Service) PhoneSendSMS(c context.Context, phone int) (err error) {
var (
captcha string
rcode int
)
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := 0; i < 6; i++ {
captcha = captcha + strconv.Itoa(r.Intn(10))
}
dataJSON := fmt.Sprintf(_sendSMSCaptcha, captcha)
if err = s.dao.SendSMS(c, phone, s.smsTemplate, dataJSON); err != nil {
log.Error("telecom_s.dao.SendSMS error (%v)", err)
return
}
if rcode, err = s.dao.AddPhoneCode(c, phone, captcha); err != nil || rcode != 1 {
log.Error("telecom_s.dao.AddPhoneCode error (%v)", err)
return
}
return
}
// OrderState
func (s *Service) OrderState(c context.Context, orderid int64) (t *telecom.OrderState, msg string, err error) {
var (
orderState *telecom.OrderPhoneState
torder map[int64]*telecom.OrderInfo
userOrder *telecom.OrderInfo
tSucOrder *telecom.SucOrder
ok bool
)
g, ctx := errgroup.WithContext(c)
log.Error("userOrder.PhoneID_test")
g.Go(func() error {
if orderState, err = s.dao.OrderState(ctx, orderid); err != nil {
log.Error("telecom_s.dao.OrderState orderID error(%v)", orderid, err)
return err
}
return nil
})
g.Go(func() error {
if torder, err = s.telecomInfoByOrderID(c, orderid); err != nil {
log.Error("telecom_s.telecomInfoByOrderID error(%v)", orderid, err)
return err
}
if userOrder, ok = torder[orderid]; ok {
if tSucOrder, err, _ = s.dao.SucOrderList(ctx, userOrder.PhoneID); err != nil {
if err == ecode.NothingFound {
err = nil
} else {
log.Error("telecom_s.dao.SucOrderList sphone (%v) error (%v)", userOrder.PhoneID, err)
}
return err
}
}
return nil
})
if err = g.Wait(); err != nil {
log.Error("telecom_errgroup.WithContext error(%v)", err)
return
}
if orderState == nil {
t = &telecom.OrderState{
OrderState: 1,
}
return
}
t = &telecom.OrderState{
OrderState: orderState.OrderState,
FlowSize: orderState.FlowSize,
}
if tSucOrder != nil && tSucOrder.OrderID > 0 {
t.FlowBalance = tSucOrder.FlowBalance
t.FlowSize = tSucOrder.FlowPackageSize
}
if ok {
t.IsRepeatorder = userOrder.IsRepeatorder
if userOrder.IsRepeatorder == 0 {
t.Endtime = userOrder.Endtime
}
}
switch t.OrderState {
case 6:
if !ok {
err = ecode.NothingFound
msg = "订单不存在"
return
}
t.Endtime = userOrder.Endtime
}
return
}
// telecomIp ip limit
func (s *Service) iplimit(k, ip string) bool {
key := fmt.Sprintf(_initIPlimitKey, k, ip)
if _, ok := s.operationIPlimit[key]; ok {
return true
}
return false
}
// DesDecrypt
func (s *Service) DesDecrypt(src, key []byte) ([]byte, error) {
block, err := des.NewCipher(key)
if err != nil {
return nil, err
}
out := make([]byte, len(src))
dst := out
bs := block.BlockSize()
if len(src)%bs != 0 {
return nil, errors.New("crypto/cipher: input not full blocks")
}
for len(src) > 0 {
block.Decrypt(dst, src[:bs])
src = src[bs:]
dst = dst[bs:]
}
out = s.zeroUnPadding(out)
return out, nil
}
// zeroUnPadding
func (s *Service) zeroUnPadding(origData []byte) []byte {
return bytes.TrimFunc(origData,
func(r rune) bool {
return r == rune(0)
})
}

View File

@@ -0,0 +1,94 @@
package telecom
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-wall/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
s *Service
)
func WithService(f func(s *Service)) func() {
return func() {
f(s)
}
}
func init() {
dir, _ := filepath.Abs("../../cmd/app-wall-test.toml")
flag.Set("conf", dir)
conf.Init()
s = New(conf.Conf)
time.Sleep(time.Second)
}
func TestTelecomPay(t *testing.T) {
Convey("TelecomPay", t, WithService(func(s *Service) {
res, _, err := s.TelecomPay(context.TODO(), 1, 1, 1, 1, 1, "")
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
}))
}
func TestCancelRepeatOrder(t *testing.T) {
Convey("CancelRepeatOrder", t, WithService(func(s *Service) {
res, err := s.CancelRepeatOrder(context.TODO(), 1)
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
}))
}
func TestOrderList(t *testing.T) {
Convey("OrderList", t, WithService(func(s *Service) {
res, _, err := s.OrderList(context.TODO(), 1, 1)
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
}))
}
func TestPhoneFlow(t *testing.T) {
Convey("PhoneFlow", t, WithService(func(s *Service) {
res, _, err := s.PhoneFlow(context.TODO(), 1, 1)
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
}))
}
func TestOrderConsent(t *testing.T) {
Convey("OrderConsent", t, WithService(func(s *Service) {
res, _, err := s.OrderConsent(context.TODO(), 1, 1, "")
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
}))
}
func TestPhoneCode(t *testing.T) {
Convey("PhoneCode", t, WithService(func(s *Service) {
res, _, err := s.PhoneCode(context.TODO(), 1, "", time.Now())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
}))
}
func TestPhoneSendSMS(t *testing.T) {
Convey("PhoneSendSMS", t, WithService(func(s *Service) {
err := s.PhoneSendSMS(context.TODO(), 1)
So(err, ShouldBeNil)
}))
}
func TestOrderState(t *testing.T) {
Convey("OrderState", t, WithService(func(s *Service) {
res, _, err := s.OrderState(context.TODO(), 1)
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
}))
}

View File

@@ -0,0 +1,66 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["unicom_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"cache.go",
"databus.go",
"infoc.go",
"pack.go",
"service.go",
"unicom.go",
],
importpath = "go-common/app/interface/main/app-wall/service/unicom",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//app/interface/main/app-wall/dao/account:go_default_library",
"//app/interface/main/app-wall/dao/live:go_default_library",
"//app/interface/main/app-wall/dao/seq:go_default_library",
"//app/interface/main/app-wall/dao/shopping:go_default_library",
"//app/interface/main/app-wall/dao/unicom:go_default_library",
"//app/interface/main/app-wall/model:go_default_library",
"//app/interface/main/app-wall/model/unicom:go_default_library",
"//app/service/main/account/model:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/log/infoc:go_default_library",
"//library/queue/databus:go_default_library",
"//library/queue/databus/report:go_default_library",
"//library/stat/prom: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,203 @@
package unicom
import (
"context"
"fmt"
"time"
"go-common/app/interface/main/app-wall/conf"
"go-common/app/interface/main/app-wall/model/unicom"
"go-common/library/cache/memcache"
"go-common/library/ecode"
log "go-common/library/log"
)
const (
_initIPUnicomKey = "ipunicom_%v_%v"
)
// loadUnicomIP load unicom ip
func (s *Service) loadUnicomIP() {
unicomIP, err := s.dao.IPSync(context.TODO())
if err != nil {
log.Error("s.dao.IPSync error(%v)", err)
return
}
s.unicomIpCache = unicomIP
tmp := map[string]*unicom.UnicomIP{}
for _, u := range s.unicomIpCache {
key := fmt.Sprintf(_initIPUnicomKey, u.Ipbegin, u.Ipend)
tmp[key] = u
}
s.unicomIpSQLCache = tmp
log.Info("loadUnicomIPCache success")
}
// loadIPlimit ip limit
func (s *Service) loadIPlimit(c *conf.Config) {
hosts := make(map[string]struct{}, len(c.IPLimit.Addrs))
for k, v := range c.IPLimit.Addrs {
for _, ipStr := range v {
key := fmt.Sprintf(_initIPlimitKey, k, ipStr)
if _, ok := hosts[key]; !ok {
hosts[key] = struct{}{}
}
}
}
s.operationIPlimit = hosts
log.Info("load operationIPlimit success")
}
// loadUnicomIPOrder load unciom ip order update
func (s *Service) loadUnicomIPOrder(now time.Time) {
unicomIP, err := s.dao.UnicomIP(context.TODO(), now)
if err != nil {
log.Error("s.dao.UnicomIP(%v)", err)
return
}
if len(unicomIP) == 0 {
log.Info("unicom ip orders is null")
return
}
tx, err := s.dao.BeginTran(context.TODO())
if err != nil {
log.Error("s.dao.BeginTran error(%v)", err)
return
}
for _, uip := range unicomIP {
key := fmt.Sprintf(_initIPUnicomKey, uip.Ipbegin, uip.Ipend)
if _, ok := s.unicomIpSQLCache[key]; ok {
delete(s.unicomIpSQLCache, key)
continue
}
var (
result int64
)
if result, err = s.dao.InUnicomIPSync(tx, uip, time.Now()); err != nil || result == 0 {
tx.Rollback()
log.Error("s.dao.InUnicomIPSync error(%v)", err)
return
}
}
for _, uold := range s.unicomIpSQLCache {
var (
result int64
)
if result, err = s.dao.UpUnicomIP(tx, uold.Ipbegin, uold.Ipend, 0, time.Now()); err != nil || result == 0 {
tx.Rollback()
log.Error("s.dao.UpUnicomIP error(%v)", err)
return
}
}
if err = tx.Commit(); err != nil {
log.Error("tx.Commit error(%v)", err)
return
}
log.Info("update unicom ip success")
}
func (s *Service) loadUnicomPacks() {
pack, err := s.dao.UserPacks(context.TODO())
if err != nil {
log.Error("s.dao.UserPacks error(%v)", err)
return
}
s.unicomPackCache = pack
}
func (s *Service) loadUnicomFlow() {
var (
list map[string]*unicom.UnicomUserFlow
err error
)
if list, err = s.dao.UserFlowListCache(context.TODO()); err != nil {
log.Error("load unicom s.dao.UserFlowListCache error(%v)", err)
return
}
for key, u := range list {
var (
c = context.TODO()
requestNo int64
orderstatus string
msg string
)
if err = s.dao.UserFlowCache(c, key); err != nil {
if err == memcache.ErrNotFound {
if err = s.returnPoints(c, u); err != nil {
if err != ecode.NothingFound {
log.Error("load unicom s.returnPoints error(%v)", err)
continue
}
err = nil
}
log.Info("load unicom userbind timeout flow(%v)", u)
} else {
log.Error("load unicom s.dao.UserFlowCache error(%v)", err)
continue
}
} else {
if requestNo, err = s.seqdao.SeqID(c); err != nil {
log.Error("load unicom s.seqdao.SeqID error(%v)", err)
continue
}
if orderstatus, msg, err = s.dao.FlowQry(c, u.Phone, requestNo, u.Outorderid, u.Orderid, time.Now()); err != nil {
log.Error("load unicom s.dao.FlowQry error(%v) msg(%s)", err, msg)
continue
}
log.Info("load unicom userbind flow(%v) orderstatus(%s)", u, orderstatus)
if orderstatus == "00" {
continue
} else if orderstatus != "01" {
if err = s.returnPoints(c, u); err != nil {
if err != ecode.NothingFound {
log.Error("load unicom s.returnPoints error(%v)", err)
continue
}
err = nil
}
}
}
delete(list, key)
if err = s.dao.DeleteUserFlowCache(c, key); err != nil {
log.Error("load unicom s.dao.DeleteUserFlowCache error(%v)", err)
continue
}
}
if err = s.dao.AddUserFlowListCache(context.TODO(), list); err != nil {
log.Error("load unicom s.dao.AddUserFlowListCache error(%v)", err)
return
}
log.Info("load unicom flow success")
}
// returnPoints retutn user integral and flow
func (s *Service) returnPoints(c context.Context, u *unicom.UnicomUserFlow) (err error) {
var (
userbind *unicom.UserBind
result int64
)
if userbind, err = s.unicomBindInfo(c, u.Mid); err != nil {
return
}
ub := &unicom.UserBind{}
*ub = *userbind
ub.Flow = ub.Flow + u.Flow
ub.Integral = ub.Integral + u.Integral
if err = s.dao.AddUserBindCache(c, ub.Mid, ub); err != nil {
log.Error("unicom s.dao.AddUserBindCache error(%v)", err)
return
}
if result, err = s.dao.UpUserIntegral(c, ub); err != nil || result == 0 {
log.Error("unicom s.dao.UpUserIntegral error(%v) or result==0", err)
return
}
var packInt int
if u.Integral > 0 {
packInt = u.Integral
} else {
packInt = u.Flow
}
log.Info("unicom_pack(%v) mid(%v)", u.Desc+",领取失败并返还", userbind.Mid)
s.unicomPackInfoc(userbind.Usermob, u.Desc+",领取失败并返还", u.Orderid, userbind.Phone, packInt, 0, userbind.Mid, time.Now())
return
}

View File

@@ -0,0 +1,38 @@
package unicom
import (
"context"
"strconv"
"go-common/app/interface/main/app-wall/model/unicom"
log "go-common/library/log"
)
func (s *Service) addUserBindState(u *unicom.UserBindInfo) {
select {
case s.userBindCh <- u:
default:
log.Warn("add user bind state buffer is full")
}
}
func (s *Service) userbindConsumer() {
defer s.waiter.Done()
for {
i, ok := <-s.userBindCh
if !ok {
return
}
var (
err error
)
switch v := i.(type) {
case *unicom.UserBindInfo:
if err = s.userbindPub.Send(context.TODO(), strconv.FormatInt(v.MID, 10), v); err != nil {
log.Error("s.userbindSub.Send error(%v)", err)
continue
}
log.Info("s.userbindSub.Send(%+v) success", v)
}
}
}

View File

@@ -0,0 +1,104 @@
package unicom
import (
"strconv"
"time"
"go-common/app/interface/main/app-wall/conf"
log "go-common/library/log"
binfoc "go-common/library/log/infoc"
)
type orderInfoc struct {
usermob string
orderType string
ip string
mobiApp string
build string
now string
}
type ipInfoc struct {
usermob string
isValide string
ip string
mobiApp string
build string
now string
}
type packInfoc struct {
usermob string
phone string
mid string
requestNo string
packName string
packIntegral string
packType string
now string
}
// Infoc write data for Hadoop do analytics
func (s *Service) unicomInfoc(mobiApp, usermob, ip string, build, orderType int, now time.Time) {
select {
case s.logCh <- orderInfoc{usermob, strconv.Itoa(orderType), ip, mobiApp, strconv.Itoa(build), strconv.FormatInt(now.Unix(), 10)}:
default:
log.Warn("unicomInfoc log buffer is full")
}
}
// Infoc write data for Hadoop do analytics
func (s *Service) ipInfoc(mobiApp, usermob, ip string, build int, isValide bool, now time.Time) {
select {
case s.logCh <- ipInfoc{usermob, strconv.FormatBool(isValide), ip, mobiApp, strconv.Itoa(build), strconv.FormatInt(now.Unix(), 10)}:
default:
log.Warn("ipInfoc log buffer is full")
}
}
func (s *Service) unicomInfocproc() {
var (
unicominf2 = binfoc.New(conf.Conf.UnicomUserInfoc2)
ipinf2 = binfoc.New(conf.Conf.UnicomIpInfoc2)
)
for {
i, ok := <-s.logCh
if !ok {
log.Warn("infoc proc exit")
return
}
switch v := i.(type) {
case orderInfoc:
unicominf2.Info(v.now, "0", v.usermob, v.orderType, v.ip, v.mobiApp, v.build)
case ipInfoc:
ipinf2.Info(v.now, "0", v.isValide, v.ip, v.usermob, v.mobiApp, v.build)
}
}
}
// unicomPackInfoc unicom pack infoc
func (s *Service) unicomPackInfoc(usermob, packName, orderNumber string, phone, packIntegral, packType int, mid int64, now time.Time) {
select {
case s.packCh <- packInfoc{usermob, strconv.Itoa(phone), strconv.FormatInt(mid, 10),
orderNumber, packName, strconv.Itoa(packIntegral), strconv.Itoa(packType), strconv.FormatInt(now.Unix(), 10)}:
default:
log.Warn("unicomPackInfoc log buffer is full")
}
}
func (s *Service) unicomPackInfocproc() {
var (
packinf = binfoc.New(conf.Conf.UnicomPackInfoc)
)
for {
i, ok := <-s.packCh
if !ok {
log.Warn("infoc proc exit")
return
}
switch v := i.(type) {
case packInfoc:
packinf.Info(v.now, "0", v.usermob, v.phone, v.mid, v.requestNo, v.packName, v.packIntegral, v.packType)
}
}
}

View File

@@ -0,0 +1,69 @@
package unicom
import (
"context"
"time"
"go-common/library/ecode"
"go-common/library/log"
)
// PrivilegePack
func (s *Service) Pack(c context.Context, usermob string, mid int64, now time.Time) (msg string, err error) {
row := s.unicomInfo(c, usermob, now)
u, ok := row[usermob]
if !ok || u == nil {
err = ecode.NothingFound
msg = "该卡号尚未开通哔哩哔哩专属免流服务"
return
}
var (
result int64
)
userpacke, err := s.userPack(c, usermob)
if err != nil {
log.Error("s.userPack error(%v)", err)
msg = "特权礼包领取失败"
return
}
var (
unicomPackOk bool
userPackOk bool
user map[int64]struct{}
)
if user, unicomPackOk = userpacke[usermob]; unicomPackOk {
_, userPackOk = user[mid]
}
if !unicomPackOk && !userPackOk {
result, err = s.dao.InPack(c, usermob, mid)
if err != nil {
log.Error("s.pack.InPack(%s, %s) error(%v)", usermob, mid, err)
} else if result == 0 {
err = ecode.RequestErr
msg = "每张卡只能领取一次特权礼包哦"
log.Error("s.pack.InPackc(%s,%s) error(%v) result==0", usermob, mid, err)
} else {
if err = s.live.Pack(c, mid, u.CardType); err != nil {
msg = "礼包领取失败"
log.Error("s.live.Pack mid error(%v)", mid, err)
}
}
} else if unicomPackOk {
err = ecode.NotModified
msg = "每张卡只能领取一次特权礼包哦"
} else if userPackOk {
err = ecode.NotModified
msg = "每个账号只能领取一次哦"
} else {
msg = "领取成功特权礼包将在1~3个⼯工作⽇日内发放到您的账号"
}
return
}
func (s *Service) userPack(c context.Context, usermob string) (pack map[string]map[int64]struct{}, err error) {
if pack, err = s.dao.Pack(c, usermob); err != nil {
log.Error("s.pack.Pack usermob:%v error(%v)", usermob, err)
return
}
return
}

View File

@@ -0,0 +1,97 @@
package unicom
import (
"sync"
"time"
"go-common/app/interface/main/app-wall/conf"
accdao "go-common/app/interface/main/app-wall/dao/account"
liveDao "go-common/app/interface/main/app-wall/dao/live"
seqDao "go-common/app/interface/main/app-wall/dao/seq"
shopDao "go-common/app/interface/main/app-wall/dao/shopping"
unicomDao "go-common/app/interface/main/app-wall/dao/unicom"
"go-common/app/interface/main/app-wall/model/unicom"
"go-common/library/queue/databus"
"go-common/library/stat/prom"
)
const (
_initIPlimitKey = "iplimit_%v_%v"
)
type Service struct {
c *conf.Config
dao *unicomDao.Dao
live *liveDao.Dao
seqdao *seqDao.Dao
accd *accdao.Dao
shop *shopDao.Dao
tick time.Duration
unicomIpCache []*unicom.UnicomIP
unicomIpSQLCache map[string]*unicom.UnicomIP
operationIPlimit map[string]struct{}
unicomPackCache []*unicom.UserPack
// infoc
logCh chan interface{}
packCh chan interface{}
packLogCh chan interface{}
userBindCh chan interface{}
// waiter
waiter sync.WaitGroup
// databus
userbindPub *databus.Databus
// prom
pHit *prom.Prom
pMiss *prom.Prom
}
func New(c *conf.Config) (s *Service) {
s = &Service{
c: c,
dao: unicomDao.New(c),
live: liveDao.New(c),
seqdao: seqDao.New(c),
accd: accdao.New(c),
shop: shopDao.New(c),
tick: time.Duration(c.Tick),
unicomIpCache: []*unicom.UnicomIP{},
unicomIpSQLCache: map[string]*unicom.UnicomIP{},
operationIPlimit: map[string]struct{}{},
unicomPackCache: []*unicom.UserPack{},
// databus
userbindPub: databus.New(c.UnicomDatabus),
// infoc
logCh: make(chan interface{}, 1024),
packCh: make(chan interface{}, 1024),
packLogCh: make(chan interface{}, 1024),
userBindCh: make(chan interface{}, 1024),
// prom
pHit: prom.CacheHit,
pMiss: prom.CacheMiss,
}
// now := time.Now()
s.loadIPlimit(c)
s.loadUnicomIP()
// s.loadUnicomIPOrder(now)
s.loadUnicomPacks()
// s.loadUnicomFlow()
go s.loadproc()
go s.unicomInfocproc()
go s.unicomPackInfocproc()
go s.addUserPackLogproc()
s.waiter.Add(1)
go s.userbindConsumer()
return
}
// cacheproc load cache
func (s *Service) loadproc() {
for {
time.Sleep(s.tick)
// now := time.Now()
s.loadUnicomIP()
// s.loadUnicomIPOrder(now)
s.loadUnicomPacks()
// s.loadUnicomFlow()
}
}

View File

@@ -0,0 +1,961 @@
package unicom
import (
"bytes"
"context"
"crypto/des"
"encoding/base64"
"errors"
"fmt"
"strconv"
"time"
"go-common/app/interface/main/app-wall/model"
"go-common/app/interface/main/app-wall/model/unicom"
account "go-common/app/service/main/account/model"
"go-common/library/ecode"
log "go-common/library/log"
"go-common/library/queue/databus/report"
)
const (
_unicomKey = "unicom"
_unicomPackKey = "unicom_pack"
)
// InOrdersSync insert OrdersSync
func (s *Service) InOrdersSync(c context.Context, usermob, ip string, u *unicom.UnicomJson, now time.Time) (err error) {
if !s.iplimit(_unicomKey, ip) {
err = ecode.AccessDenied
return
}
var result int64
if result, err = s.dao.InOrdersSync(c, usermob, u, now); err != nil || result == 0 {
log.Error("unicom_s.dao.OrdersSync (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%v) error(%v) or result==0",
usermob, u.Cpid, u.Spid, u.TypeInt, u.Ordertypes, u.Channelcode, u.Ordertime, u.Canceltime, u.Endtime, u.Province, u.Area, u.Videoid, err)
}
return
}
// InAdvanceSync insert AdvanceSync
func (s *Service) InAdvanceSync(c context.Context, usermob, ip string, u *unicom.UnicomJson, now time.Time) (err error) {
if !s.iplimit(_unicomKey, ip) {
err = ecode.AccessDenied
return
}
var result int64
if result, err = s.dao.InAdvanceSync(c, usermob, u, now); err != nil || result == 0 {
log.Error("unicom_s.dao.InAdvanceSync (%s,%s,%s,%s,%s,%s,%s,%s,%v) error(%v) or result==0",
usermob, u.Userphone, u.Cpid, u.Spid, u.Ordertypes, u.Channelcode, u.Province, u.Area, err)
}
return
}
// FlowSync update OrdersSync
func (s *Service) FlowSync(c context.Context, flowbyte int, usermob, time, ip string, now time.Time) (err error) {
if !s.iplimit(_unicomKey, ip) {
err = ecode.AccessDenied
return
}
var result int64
if result, err = s.dao.FlowSync(c, flowbyte, usermob, time, now); err != nil || result == 0 {
log.Error("unicom_s.dao.OrdersSync(%s, %s, %s) error(%v) or result==0", usermob, time, flowbyte, err)
}
return
}
// InIPSync
func (s *Service) InIPSync(c context.Context, ip string, u *unicom.UnicomIpJson, now time.Time) (err error) {
if !s.iplimit(_unicomKey, ip) {
err = ecode.AccessDenied
return
}
var result int64
if result, err = s.dao.InIPSync(c, u, now); err != nil {
log.Error("s.dao.InIpSync(%s,%s) error(%v)", u.Ipbegin, u.Ipend, err)
} else if result == 0 {
err = ecode.RequestErr
log.Error("unicom_s.dao.InIpSync(%s,%s) error(%v) result==0", u.Ipbegin, u.Ipend, err)
}
return
}
// UserFlow
func (s *Service) UserFlow(c context.Context, usermob, mobiApp, ip string, build int, now time.Time) (res *unicom.Unicom, msg string, err error) {
var (
row map[string]*unicom.Unicom
orderType int
)
row = s.unicomInfo(c, usermob, now)
res, msg, err = s.uState(row, usermob, now)
switch err {
case ecode.NothingFound:
orderType = 1
case ecode.NotModified:
orderType = 3
default:
orderType = 2
}
s.unicomInfoc(mobiApp, usermob, ip, build, orderType, now)
return
}
// unicomInfo
func (s *Service) unicomInfo(c context.Context, usermob string, now time.Time) (res map[string]*unicom.Unicom) {
var (
err error
us []*unicom.Unicom
)
res = map[string]*unicom.Unicom{}
if us, err = s.dao.UnicomCache(c, usermob); err == nil && len(us) > 0 {
s.pHit.Incr("unicoms_cache")
} else {
if us, err = s.dao.OrdersUserFlow(context.TODO(), usermob); err != nil {
log.Error("unicom_s.dao.OrdersUserFlow error(%v)", err)
return
}
s.pMiss.Incr("unicoms_cache")
if len(us) > 0 {
if err = s.dao.AddUnicomCache(c, usermob, us); err != nil {
log.Error("s.dao.AddUnicomCache usermob(%v) error(%v)", usermob, err)
return
}
}
}
if len(us) > 0 {
row := &unicom.Unicom{}
channel := &unicom.Unicom{}
for _, u := range us {
if u.TypeInt == 1 && now.Unix() <= int64(u.Endtime) {
*row = *u
continue
} else if u.TypeInt == 0 {
if int64(row.Ordertime) == 0 {
*row = *u
} else if int64(row.Ordertime) < int64(u.Ordertime) {
continue
}
*row = *u
continue
} else if u.TypeInt == 1 {
if int64(row.Ordertime) > int64(u.Ordertime) {
continue
}
*channel = *u
}
}
if row.Spid == 0 && channel.Spid == 0 {
return
} else if row.Spid == 0 && channel.Spid > 0 {
row = channel
}
res[usermob] = row
}
return
}
// UserState
func (s *Service) UserState(c context.Context, usermob, mobiApp, ip string, build int, now time.Time) (res *unicom.Unicom, msg string, err error) {
var (
orderType int
)
row := s.unicomInfo(c, usermob, now)
res, msg, err = s.uState(row, usermob, now)
switch err {
case ecode.NothingFound:
orderType = 1
case ecode.NotModified:
orderType = 3
default:
orderType = 2
}
s.unicomInfoc(mobiApp, usermob, ip, build, orderType, now)
return
}
// UnicomState
func (s *Service) UnicomState(c context.Context, usermob, mobiApp, ip string, build int, now time.Time) (res *unicom.Unicom, err error) {
var (
ok bool
)
row := s.unicomInfo(c, usermob, now)
if res, ok = row[usermob]; !ok {
res = &unicom.Unicom{Unicomtype: 1}
} else if res.TypeInt == 1 && now.Unix() > int64(res.Endtime) {
res.Unicomtype = 3
} else if res.TypeInt == 1 {
res.Unicomtype = 4
} else if res.TypeInt == 0 {
res.Unicomtype = 2
}
log.Info("unicomstate_type:%v unicomstate_type_usermob:%v", res.Unicomtype, usermob)
s.unicomInfoc(mobiApp, usermob, ip, build, res.Unicomtype, now)
return
}
// UserFlowState
func (s *Service) UserFlowState(c context.Context, usermob string, now time.Time) (res *unicom.Unicom, err error) {
row := s.unicomInfo(c, usermob, now)
var ok bool
if res, ok = row[usermob]; !ok {
res = &unicom.Unicom{Unicomtype: 1}
} else if res.TypeInt == 1 {
res.Unicomtype = 3
} else if res.TypeInt == 0 {
res.Unicomtype = 2
}
return
}
// uState
func (s *Service) uState(unicom map[string]*unicom.Unicom, usermob string, now time.Time) (res *unicom.Unicom, msg string, err error) {
var ok bool
if res, ok = unicom[usermob]; !ok {
err = ecode.NothingFound
msg = "该卡号尚未开通哔哩哔哩专属免流服务"
} else if res.TypeInt == 1 && now.Unix() > int64(res.Endtime) {
err = ecode.NotModified
msg = "该卡号哔哩哔哩专属免流服务已退订且已过期"
}
return
}
// IsUnciomIP is unicom ip
func (s *Service) IsUnciomIP(ipUint uint32, ipStr, mobiApp string, build int, now time.Time) (err error) {
if !model.IsIPv4(ipStr) {
err = ecode.NothingFound
return
}
isValide := s.unciomIPState(ipUint)
s.ipInfoc(mobiApp, "", ipStr, build, isValide, now)
if isValide {
return
}
err = ecode.NothingFound
return
}
// UserUnciomIP
func (s *Service) UserUnciomIP(ipUint uint32, ipStr, usermob, mobiApp string, build int, now time.Time) (res *unicom.UnicomUserIP) {
res = &unicom.UnicomUserIP{
IPStr: ipStr,
IsValide: false,
}
if !model.IsIPv4(ipStr) {
return
}
if res.IsValide = s.unciomIPState(ipUint); !res.IsValide {
log.Error("unicom_user_ip:%v unicom_ip_usermob:%v", ipStr, usermob)
}
s.ipInfoc(mobiApp, usermob, ipStr, build, res.IsValide, now)
return
}
// Order unicom user order
func (s *Service) Order(c context.Context, usermobDes, channel string, ordertype int, now time.Time) (res *unicom.BroadbandOrder, msg string, err error) {
var (
usermob string
)
var (
_aesKey = []byte("9ed226d9")
)
bs, err := base64.StdEncoding.DecodeString(usermobDes)
if err != nil {
log.Error("base64.StdEncoding.DecodeString(%s) error(%v)", usermobDes, err)
return
}
bs, err = s.DesDecrypt(bs, _aesKey)
if err != nil {
log.Error("unicomSvc.DesDecrypt error(%v)", err)
return
}
if len(bs) > 32 {
usermob = string(bs[:32])
} else {
usermob = string(bs)
}
row := s.unicomInfo(c, usermob, now)
if u, ok := row[usermob]; ok {
if u.Spid != 979 && u.Spid != 0 && u.TypeInt == 0 {
err = ecode.NotModified
msg = "您当前是流量卡并且已生效无法再订购流量包"
return
}
}
if res, msg, err = s.dao.Order(c, usermobDes, channel, ordertype); err != nil {
log.Error("s.dao.Order usermobDes(%v) error(%v)", usermobDes, err)
return
}
return
}
// CancelOrder unicom user cancel order
func (s *Service) CancelOrder(c context.Context, usermob string) (res *unicom.BroadbandOrder, msg string, err error) {
if res, msg, err = s.dao.CancelOrder(c, usermob); err != nil {
log.Error("s.dao.CancelOrder usermob(%v) error(%v)", usermob, err)
return
}
return
}
// UnicomSMSCode unicom sms code
func (s *Service) UnicomSMSCode(c context.Context, phone string, now time.Time) (msg string, err error) {
if msg, err = s.dao.SendSmsCode(c, phone); err != nil {
log.Error("s.dao.SendSmsCode phone(%v) error(%v)", phone, err)
return
}
return
}
// AddUnicomBind unicom user bind
func (s *Service) AddUnicomBind(c context.Context, phone string, code int, mid int64, now time.Time) (msg string, err error) {
var (
usermobDes string
usermob string
ub *unicom.UserBind
result int64
res *unicom.Unicom
)
if usermobDes, msg, err = s.dao.SmsNumber(c, phone, code); err != nil {
log.Error("s.dao.SmsNumber error(%v)", err)
return
}
if usermobDes == "" {
err = ecode.NotModified
msg = "激活失败,请重新输入验证码激活"
return
}
var (
_aesKey = []byte("9ed226d9")
)
bs, err := base64.StdEncoding.DecodeString(usermobDes)
if err != nil {
log.Error("base64.StdEncoding.DecodeString(%s) error(%v)", usermobDes, err)
return
}
bs, err = s.DesDecrypt(bs, _aesKey)
if err != nil {
log.Error("unicomSvc.DesDecrypt error(%v)", err)
return
}
if len(bs) > 32 {
usermob = string(bs[:32])
} else {
usermob = string(bs)
}
row := s.unicomInfo(c, usermob, now)
if res, msg, err = s.uState(row, usermob, now); err != nil {
return
}
if res.Spid == 979 {
err = ecode.NotModified
msg = "该业务只支持哔哩哔哩免流卡"
return
}
if _, err = s.unicomBindInfo(c, mid); err == nil {
err = ecode.NotModified
msg = "该账户已绑定过手机号"
return
}
if midtmp := s.unicomBindMIdByPhone(c, phone); midtmp > 0 {
err = ecode.NotModified
msg = "该手机号已被注册"
return
}
if ub, err = s.dao.UserBindOld(c, phone); err != nil || ub == nil {
phoneInt, _ := strconv.Atoi(phone)
ub = &unicom.UserBind{
Usermob: usermob,
Phone: phoneInt,
Mid: mid,
State: 1,
}
} else {
ub.Mid = mid
ub.State = 1
}
if result, err = s.dao.InUserBind(c, ub); err != nil || result == 0 {
log.Error("s.dao.InUserBind ub(%v) error(%v) or result==0", ub, err)
return
}
if err = s.dao.AddUserBindCache(c, mid, ub); err != nil {
log.Error("s.dao.AddUserBindCache error(%v)", err)
return
}
// databus
s.addUserBindState(&unicom.UserBindInfo{MID: ub.Mid, Phone: ub.Phone, Action: "unicom_welfare_bind"})
return
}
// ReleaseUnicomBind release unicom bind
func (s *Service) ReleaseUnicomBind(c context.Context, mid int64, phone int) (msg string, err error) {
var (
result int64
ub *unicom.UserBind
)
if ub, err = s.unicomBindInfo(c, mid); err != nil {
msg = "用户未绑定手机号"
return
}
ub.State = 0
if err = s.dao.DeleteUserBindCache(c, mid); err != nil {
log.Error("s.dao.DeleteUserBindCache error(%v)", err)
return
}
if result, err = s.dao.InUserBind(c, ub); err != nil || result == 0 {
log.Error("s.dao.InUserBind ub(%v) error(%v) or result==0", ub, err)
return
}
// databus
s.addUserBindState(&unicom.UserBindInfo{MID: ub.Mid, Phone: ub.Phone, Action: "unicom_welfare_untied"})
return
}
// unicomBindInfo unicom bind info
func (s *Service) unicomBindInfo(c context.Context, mid int64) (res *unicom.UserBind, err error) {
if res, err = s.dao.UserBindCache(c, mid); err == nil {
s.pHit.Incr("unicoms_userbind_cache")
} else {
if res, err = s.dao.UserBind(c, mid); err != nil {
log.Error("s.dao.UserBind error(%v)", err)
return
}
s.pMiss.Incr("unicoms_userbind_cache")
if res == nil {
err = ecode.NothingFound
return
}
if err = s.dao.AddUserBindCache(c, mid, res); err != nil {
log.Error("s.dao.AddUserBindCache mid(%d) error(%v)", mid, err)
return
}
}
return
}
func (s *Service) unicomBindMIdByPhone(c context.Context, phone string) (mid int64) {
var err error
if mid, err = s.dao.UserBindPhoneMid(c, phone); err != nil {
log.Error("s.dao.UserBindPhoneMid error(%v)", phone)
return
}
return
}
// UserBind user bind
func (s *Service) UserBind(c context.Context, mid int64) (res *unicom.UserBind, msg string, err error) {
var (
acc *account.Info
ub *unicom.UserBind
)
if acc, err = s.accd.Info(c, mid); err != nil {
log.Error("s.accd.info error(%v)", err)
return
}
res = &unicom.UserBind{
Name: acc.Name,
Mid: acc.Mid,
}
if ub, err = s.unicomBindInfo(c, mid); err != nil {
log.Error("s.userBindInfo error(%v)", err)
err = nil
}
if ub != nil {
res.Phone = ub.Phone
res.Integral = ub.Integral
res.Flow = ub.Flow
}
return
}
// UnicomPackList unicom pack list
func (s *Service) UnicomPackList() (res []*unicom.UserPack) {
res = s.unicomPackCache
return
}
// UnicomPackReceive unicom pack receive
func (s *Service) UnicomPackReceive(c context.Context, mid int64, packID int64, now time.Time) (msg string, err error) {
var (
pack *unicom.UserPack
userbind *unicom.UserBind
requestNo int64
unicomOrderID string
unicomOutorderID string
u *unicom.Unicom
)
if userbind, err = s.unicomBindInfo(c, mid); err != nil {
err = ecode.NotModified
msg = "用户未绑定手机号"
return
}
row := s.unicomInfo(c, userbind.Usermob, now)
if u, msg, err = s.uState(row, userbind.Usermob, now); err != nil {
return
}
if u.Spid == 979 {
err = ecode.NotModified
msg = "该业务只支持哔哩哔哩免流卡"
return
}
if pack, err = s.unicomPackInfos(c, packID); err != nil {
err = ecode.NotModified
msg = "该礼包不存在"
return
}
if pack.Capped != 0 && pack.Amount == 0 {
err = ecode.NotModified
msg = "该礼包不存在"
return
}
if userbind.Integral < pack.Integral {
err = ecode.NotModified
msg = "福利点不足"
return
}
if requestNo, err = s.seqdao.SeqID(c); err != nil {
log.Error("unicom_s.seqdao.SeqID error (%v)", err)
return
}
switch pack.Type {
case 0:
if err = s.dao.UserFlowWaitCache(c, userbind.Phone); err == nil {
err = ecode.NotModified
msg = "请间隔一分钟之后再领取流量包"
return
}
if msg, err = s.dao.FlowPre(c, userbind.Phone, requestNo, now); err != nil {
log.Error("s.dao.FlowPre error(%v)", err)
return
}
if unicomOrderID, unicomOutorderID, msg, err = s.dao.FlowExchange(c, userbind.Phone, pack.Param, requestNo, now); err != nil {
log.Error("s.dao.FlowExchange error(%v)", err)
return
}
uf := &unicom.UnicomUserFlow{
Phone: userbind.Phone,
Mid: mid,
Integral: pack.Integral,
Flow: 0,
Orderid: unicomOrderID,
Outorderid: unicomOutorderID,
Desc: pack.Desc,
}
key := strconv.Itoa(userbind.Phone) + unicomOutorderID
if err = s.addUserFlowCache(c, key, uf); err != nil {
log.Error("s.addUserFlowCache error(%v)", err)
return
}
if err = s.dao.AddUserFlowWaitCache(c, userbind.Phone); err != nil {
log.Error("s.dao.AddUserFlowWaitCache error(%v)", err)
return
}
case 1:
var batchID int
if batchID, err = strconv.Atoi(pack.Param); err != nil {
log.Error("batchID(%v) strconv.Atoi error(%v)", pack.Param, err)
msg = "礼包参数错误"
err = ecode.RequestErr
return msg, err
}
if msg, err = s.accd.AddVIP(c, mid, requestNo, batchID, pack.Desc); err != nil {
log.Error("s.accd.AddVIP error(%v)", err)
return msg, err
}
case 2:
var day int
if day, err = strconv.Atoi(pack.Param); err != nil {
log.Error("day(%v) strconv.Atoi error(%v)", pack.Param, err)
msg = "礼包参数错误"
err = ecode.RequestErr
return msg, err
}
if msg, err = s.live.AddVip(c, mid, day); err != nil {
log.Error("s.live.AddVip error(%v)", err)
return "", err
}
case 3:
var acc *account.Info
if acc, err = s.accd.Info(c, mid); err != nil {
log.Error("s.accd.info error(%v)", err)
return
}
if msg, err = s.shop.Coupon(c, pack.Param, mid, acc.Name); err != nil {
log.Error("s.shop.Coupon error(%v)", err)
return
}
}
var (
p = &unicom.UserPack{}
ub = &unicom.UserBind{}
requestNoStr string
result int64
)
if pack.Capped != 0 {
*p = *pack
p.Amount = p.Amount - 1
if p.Amount == 0 {
if err = s.dao.DeleteUserPackCache(c, p.ID); err != nil {
log.Error("s.dao.DeleteUserPackCache error(%v)", err)
return
}
p.State = 0
} else {
if err = s.dao.AddUserPackCache(c, p.ID, p); err != nil {
log.Error("s.dao.AddUserPackCache error(%v)", err)
return
}
}
if result, err = s.dao.UpUserPacks(c, p, p.ID); err != nil || result == 0 {
log.Error("s.dao.UpUserPacks error(%v) or result==0", err)
return
}
}
*ub = *userbind
ub.Integral = ub.Integral - pack.Integral
if err = s.updateUserIntegral(c, mid, ub); err != nil {
log.Error("s.updateUserIntegral error(%v)", err)
return
}
msg = pack.Desc + ",领取成功"
if unicomOrderID != "" {
requestNoStr = unicomOrderID
} else {
requestNoStr = strconv.FormatInt(requestNo, 10)
}
log.Info("unicom_pack(%v) mid(%v)", pack.Desc+",领取成功", userbind.Mid)
s.unicomPackInfoc(userbind.Usermob, pack.Desc, requestNoStr, userbind.Phone, pack.Integral, int(pack.Capped), userbind.Mid, now)
ul := &unicom.UserPackLog{
Phone: userbind.Phone,
Usermob: userbind.Usermob,
Mid: userbind.Mid,
RequestNo: requestNoStr,
Type: pack.Type,
Desc: pack.Desc,
UserDesc: ("您当前已领取" + pack.Desc + ",扣除" + strconv.Itoa(pack.Integral) + "福利点"),
Integral: pack.Integral,
}
s.addUserPackLog(ul)
return
}
// UnicomFlowPack unicom flow pack
func (s *Service) UnicomFlowPack(c context.Context, mid int64, flowID string, now time.Time) (msg string, err error) {
var (
userbind *unicom.UserBind
ub = &unicom.UserBind{}
requestNo int64
flowDesc string
flow int
unicomOrderID string
unicomOutorderID string
u *unicom.Unicom
)
if userbind, err = s.unicomBindInfo(c, mid); err != nil {
err = ecode.NotModified
msg = "用户未绑定手机号"
return
}
row := s.unicomInfo(c, userbind.Usermob, now)
if u, msg, err = s.uState(row, userbind.Usermob, now); err != nil {
return
}
if u.Spid == 979 {
err = ecode.NotModified
msg = "该业务只支持哔哩哔哩免流卡"
return
}
switch flowID {
case "01":
flow = 100
flowDesc = "100MB流量包"
case "02":
flow = 200
flowDesc = "200MB流量包"
case "03":
flow = 300
flowDesc = "300MB流量包"
case "04":
flow = 500
flowDesc = "500MB流量包"
case "05":
flow = 1024
flowDesc = "1024MB流量包"
case "06":
flow = 2048
flowDesc = "2048MB流量包"
default:
err = ecode.RequestErr
msg = "流量包参数错误"
return
}
if userbind.Flow < flow {
err = ecode.NotModified
msg = "可用流量不足"
return
}
if err = s.dao.UserFlowWaitCache(c, userbind.Phone); err == nil {
err = ecode.NotModified
msg = "请间隔一分钟之后再领取流量包"
return
}
if requestNo, err = s.seqdao.SeqID(c); err != nil {
log.Error("unicom_s.seqdao.SeqID error (%v)", err)
return
}
if unicomOrderID, unicomOutorderID, msg, err = s.dao.FlowExchange(c, userbind.Phone, flowID, requestNo, now); err != nil {
log.Error("s.dao.FlowExchange error(%v)", err)
return
}
uf := &unicom.UnicomUserFlow{
Phone: userbind.Phone,
Mid: mid,
Integral: 0,
Flow: flow,
Orderid: unicomOrderID,
Outorderid: unicomOutorderID,
Desc: flowDesc,
}
key := strconv.Itoa(userbind.Phone) + unicomOutorderID
if err = s.addUserFlowCache(c, key, uf); err != nil {
log.Error("s.addUserFlowCache error(%v)", err)
return
}
*ub = *userbind
ub.Flow = ub.Flow - flow
if err = s.updateUserIntegral(c, mid, ub); err != nil {
log.Error("s.updateUserIntegral error(%v)", err)
return
}
msg = flowDesc + ",领取成功"
log.Info("unicom_pack(%v) mid(%v)", flowDesc+",领取成功", userbind.Mid)
s.unicomPackInfoc(userbind.Usermob, flowDesc, unicomOrderID, userbind.Phone, flow, 0, userbind.Mid, now)
ul := &unicom.UserPackLog{
Phone: userbind.Phone,
Usermob: userbind.Usermob,
Mid: userbind.Mid,
RequestNo: unicomOrderID,
Type: 0,
Desc: flowDesc,
UserDesc: ("您当前已领取" + flowDesc + ",扣除" + strconv.Itoa(flow) + "MB流量"),
Integral: flow,
}
s.addUserPackLog(ul)
if err = s.dao.AddUserFlowWaitCache(c, userbind.Phone); err != nil {
log.Error("s.dao.AddUserFlowWaitCache error(%v)", err)
return
}
return
}
// UserBindLog user bind week log
func (s *Service) UserBindLog(c context.Context, mid int64, now time.Time) (res []*unicom.UserLog, err error) {
if res, err = s.dao.SearchUserBindLog(c, mid, now); err != nil {
log.Error("unicom s.dao.SearchUserBindLog error(%v)", err)
return
}
return
}
// WelfareBindState welfare user bind state
func (s *Service) WelfareBindState(c context.Context, mid int64) (res int) {
if ub, err := s.dao.UserBindCache(c, mid); err == nil && ub != nil {
res = 1
}
return
}
func (s *Service) updateUserIntegral(c context.Context, mid int64, ub *unicom.UserBind) (err error) {
var result int64
if err = s.dao.AddUserBindCache(c, mid, ub); err != nil {
log.Error("s.dao.AddUserBindCache error(%v)", err)
return
}
if result, err = s.dao.UpUserIntegral(c, ub); err != nil {
log.Error("s.dao.UpUserIntegral error(%v) ", err)
return
}
if result == 0 {
log.Error("s.dao.UpUserIntegral result==0")
err = ecode.NotModified
return
}
return
}
// unicomPackInfos unicom pack infos
func (s *Service) unicomPackInfos(c context.Context, id int64) (res *unicom.UserPack, err error) {
var (
ub *unicom.UserPack
row = map[int64]*unicom.UserPack{}
ok bool
)
if ub, err = s.dao.UserPackCache(c, id); err == nil {
res = ub
s.pHit.Incr("unicoms_pack_cache")
} else {
if row, err = s.dao.UserPackByID(c, id); err != nil {
log.Error("s.dao.UserBind error(%v)", err)
return
}
s.pMiss.Incr("unicoms_pack_cache")
ub, ok = row[id]
if !ok {
err = ecode.NothingFound
return
}
if err = s.dao.AddUserPackCache(c, id, ub); err != nil {
log.Error("s.dao.AddUserPackCache id(%d) error(%v)", id, err)
return
}
res = ub
}
return
}
// unciomIPState
func (s *Service) unciomIPState(ipUint uint32) (isValide bool) {
for _, u := range s.unicomIpCache {
if u.IPStartUint <= ipUint && u.IPEndUint >= ipUint {
isValide = true
return
}
}
isValide = false
return
}
// unicomIp ip limit
func (s *Service) iplimit(k, ip string) bool {
key := fmt.Sprintf(_initIPlimitKey, k, ip)
if _, ok := s.operationIPlimit[key]; ok {
return true
}
return false
}
// DesDecrypt
func (s *Service) DesDecrypt(src, key []byte) ([]byte, error) {
block, err := des.NewCipher(key)
if err != nil {
return nil, err
}
out := make([]byte, len(src))
dst := out
bs := block.BlockSize()
if len(src)%bs != 0 {
return nil, errors.New("crypto/cipher: input not full blocks")
}
for len(src) > 0 {
block.Decrypt(dst, src[:bs])
src = src[bs:]
dst = dst[bs:]
}
out = s.zeroUnPadding(out)
return out, nil
}
// zeroUnPadding
func (s *Service) zeroUnPadding(origData []byte) []byte {
return bytes.TrimFunc(origData,
func(r rune) bool {
return r == rune(0)
})
}
func (s *Service) addUserFlowCache(c context.Context, key string, uf *unicom.UnicomUserFlow) (err error) {
if err = s.dao.AddUserFlowCache(c, key); err != nil {
log.Error("s.dao.AddUserFlowCache error(%v)", err)
return
}
var flowList map[string]*unicom.UnicomUserFlow
if flowList, err = s.dao.UserFlowListCache(c); err != nil {
log.Error("s.dao.UserFlowListCache error(%v)", err)
return
}
if flowList == nil {
flowList = map[string]*unicom.UnicomUserFlow{
key: uf,
}
} else {
flowList[key] = uf
}
if err = s.dao.AddUserFlowListCache(c, flowList); err != nil {
log.Error("s.dao.AddUserFlowListCache error(%v)", err)
return
}
return
}
// UserPacksLog user pack logs
func (s *Service) UserPacksLog(c context.Context, starttime, now time.Time, start int, ip string) (res []*unicom.UserPackLog, err error) {
if !s.iplimit(_unicomPackKey, ip) {
err = ecode.AccessDenied
return
}
var (
endday time.Time
)
if starttime.Month() >= now.Month() && starttime.Year() >= now.Year() {
res = []*unicom.UserPackLog{}
return
}
if endInt := starttime.AddDate(0, 1, -1).Day(); start > endInt {
res = []*unicom.UserPackLog{}
return
} else if start == endInt {
endday = starttime.AddDate(0, 1, 0)
} else {
endday = starttime.AddDate(0, 0, start)
}
if res, err = s.dao.UserPacksLog(c, endday.AddDate(0, 0, -1), endday); err != nil {
log.Error("user pack logs s.dao.UserPacksLog error(%v)", err)
return
}
if len(res) == 0 {
res = []*unicom.UserPackLog{}
}
return
}
func (s *Service) addUserPackLog(u *unicom.UserPackLog) {
select {
case s.packLogCh <- u:
default:
log.Warn("user pack log buffer is full")
}
}
func (s *Service) addUserPackLogproc() {
for {
i, ok := <-s.packLogCh
if !ok {
log.Warn("user pack log proc exit")
return
}
var (
c = context.TODO()
result int64
err error
logID = 91
)
switch v := i.(type) {
case *unicom.UserPackLog:
if result, err = s.dao.InUserPackLog(c, v); err != nil || result == 0 {
log.Error("s.dao.UpUserIntegral error(%v) or result==0", err)
continue
}
report.User(&report.UserInfo{
Mid: v.Mid,
Business: logID,
Action: "unicom_userpack_deduct",
Ctime: time.Now(),
Content: map[string]interface{}{
"phone": v.Phone,
"pack_desc": v.UserDesc,
"integral": (0 - v.Integral),
},
})
}
}
}

View File

@@ -0,0 +1,158 @@
package unicom
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-wall/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
s *Service
)
func WithService(f func(s *Service)) func() {
return func() {
f(s)
}
}
func init() {
dir, _ := filepath.Abs("../../cmd/app-wall-test.toml")
flag.Set("conf", dir)
conf.Init()
s = New(conf.Conf)
time.Sleep(time.Second)
}
func TestUserFlow(t *testing.T) {
Convey("Unicom UserFlow", t, WithService(func(s *Service) {
res, _, err := s.UserFlow(context.TODO(), "", "iphone", "127.0.0.1", 111, time.Now())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
}))
}
func TestUserState(t *testing.T) {
Convey("Unicom UserState", t, WithService(func(s *Service) {
res, _, err := s.UserState(context.TODO(), "", "iphone", "127.0.0.1", 111, time.Now())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
}))
}
func TestUnicomState(t *testing.T) {
Convey("Unicom UnicomState", t, WithService(func(s *Service) {
res, err := s.UnicomState(context.TODO(), "", "iphone", "127.0.0.1", 111, time.Now())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
}))
}
func TestUserFlowState(t *testing.T) {
Convey("Unicom UserFlowState", t, WithService(func(s *Service) {
res, err := s.UserFlowState(context.TODO(), "", time.Now())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
}))
}
func TestIsUnciomIP(t *testing.T) {
Convey("Unicom IsUnciomIP", t, WithService(func(s *Service) {
err := s.IsUnciomIP(0, "127.0.0.1", "iphone", 0, time.Now())
So(err, ShouldBeNil)
}))
}
func TestUserUnciomIP(t *testing.T) {
Convey("Unicom UserUnciomIP", t, WithService(func(s *Service) {
err := s.UserUnciomIP(0, "127.0.0.1", "", "iphone", 0, time.Now())
So(err, ShouldBeNil)
}))
}
func TestOrder(t *testing.T) {
Convey("Unicom Order", t, WithService(func(s *Service) {
res, _, err := s.Order(context.TODO(), "", "", 0, time.Now())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
}))
}
func TestCancelOrder(t *testing.T) {
Convey("Unicom CancelOrder", t, WithService(func(s *Service) {
res, _, err := s.CancelOrder(context.TODO(), "")
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
}))
}
func TestUnicomSMSCode(t *testing.T) {
Convey("Unicom UnicomSMSCode", t, WithService(func(s *Service) {
res, err := s.UnicomSMSCode(context.TODO(), "", time.Now())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
}))
}
func TestAddUnicomBind(t *testing.T) {
Convey("Unicom AddUnicomBind", t, WithService(func(s *Service) {
res, err := s.AddUnicomBind(context.TODO(), "", 1, 1, time.Now())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
}))
}
func TestReleaseUnicomBind(t *testing.T) {
Convey("Unicom ReleaseUnicomBind", t, WithService(func(s *Service) {
res, err := s.ReleaseUnicomBind(context.TODO(), 1, 1)
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
}))
}
func TestUserBind(t *testing.T) {
Convey("Unicom UserBind", t, WithService(func(s *Service) {
res, _, err := s.UserBind(context.TODO(), 1)
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
}))
}
func TestUnicomPackList(t *testing.T) {
Convey("Unicom UnicomPackList", t, WithService(func(s *Service) {
res := s.UnicomPackList()
So(res, ShouldNotBeEmpty)
}))
}
func TestUnicomPackReceive(t *testing.T) {
Convey("Unicom UnicomPackReceive", t, WithService(func(s *Service) {
res, _ := s.UnicomPackReceive(context.TODO(), 1, 1, time.Now())
So(res, ShouldNotBeEmpty)
}))
}
func TestUnicomUnicomFlowPack(t *testing.T) {
Convey("Unicom UnicomFlowPack", t, WithService(func(s *Service) {
res, _ := s.UnicomFlowPack(context.TODO(), 1, "", time.Now())
So(res, ShouldNotBeEmpty)
}))
}
func TestUnicomloadUnicomFlow(t *testing.T) {
Convey("Unicom loadUnicomFlow", t, WithService(func(s *Service) {
s.loadUnicomFlow()
}))
}
func TestUnicomloadUnicomIPOrder(t *testing.T) {
Convey("Unicom loadUnicomIPOrder", t, WithService(func(s *Service) {
s.loadUnicomIPOrder(time.Now())
}))
}

View File

@@ -0,0 +1,48 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["wall_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["wall.go"],
importpath = "go-common/app/interface/main/app-wall/service/wall",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-wall/conf:go_default_library",
"//app/interface/main/app-wall/dao/wall:go_default_library",
"//app/interface/main/app-wall/model/wall:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,59 @@
package wall
import (
"context"
"time"
"go-common/app/interface/main/app-wall/conf"
walldao "go-common/app/interface/main/app-wall/dao/wall"
"go-common/app/interface/main/app-wall/model/wall"
log "go-common/library/log"
httpx "go-common/library/net/http/blademaster"
)
type Service struct {
c *conf.Config
client *httpx.Client
dao *walldao.Dao
tick time.Duration
cache []*wall.Wall
testCache []*wall.Wall
}
func New(c *conf.Config) (s *Service) {
s = &Service{
c: c,
client: httpx.NewClient(c.HTTPClient),
dao: walldao.New(c),
tick: time.Duration(c.Tick),
}
s.load()
go s.loadproc()
return
}
// GetWall All
func (s *Service) Wall() (res []*wall.Wall) {
res = s.cache
return
}
// load WallAll
func (s *Service) load() {
res, err := s.dao.WallAll(context.TODO())
if err != nil {
log.Error("s.dao.wallAll error(%v)", err)
return
}
s.cache = res
s.testCache = res
log.Info("loadWallsCache success")
}
// cacheproc load cache
func (s *Service) loadproc() {
for {
time.Sleep(s.tick)
s.load()
}
}

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