Create & Init Project...
This commit is contained in:
21
app/job/main/vip/BUILD
Normal file
21
app/job/main/vip/BUILD
Normal file
@ -0,0 +1,21 @@
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//app/job/main/vip/cmd:all-srcs",
|
||||
"//app/job/main/vip/conf:all-srcs",
|
||||
"//app/job/main/vip/dao:all-srcs",
|
||||
"//app/job/main/vip/http:all-srcs",
|
||||
"//app/job/main/vip/model:all-srcs",
|
||||
"//app/job/main/vip/service:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
236
app/job/main/vip/CHANGELOG.md
Normal file
236
app/job/main/vip/CHANGELOG.md
Normal file
@ -0,0 +1,236 @@
|
||||
#### Version 2.15.1
|
||||
>1. fix sync.WaitGroup issue #417
|
||||
|
||||
#### Version 2.15.0
|
||||
>1. 权益发放补偿job
|
||||
|
||||
#### Version 2.14.0
|
||||
>1. 自动续费v2
|
||||
|
||||
#### Version 2.13.1
|
||||
>1. refined log
|
||||
|
||||
#### Version 2.13.0
|
||||
>1. 增加vipinfo缓存清理
|
||||
|
||||
#### Version 2.12.3
|
||||
>1. fix redis conn
|
||||
|
||||
#### Version 2.12.2
|
||||
>1. frozen java refined
|
||||
|
||||
#### Version 2.12.1
|
||||
>1. frozen java
|
||||
|
||||
#### Version 2.12.0
|
||||
>1. add frozen time
|
||||
|
||||
#### Version 2.11.1
|
||||
1. time after coupon
|
||||
|
||||
#### Version 2.11.0
|
||||
1. create order v2
|
||||
|
||||
#### Version 2.10.2
|
||||
>1. refined sync recentTime logic
|
||||
|
||||
#### Version 2.10.0
|
||||
>1. delete unuse code
|
||||
|
||||
#### Version 2.9.11
|
||||
>1. sync all user info
|
||||
|
||||
#### Version 2.9.10
|
||||
>1. vip type fix
|
||||
|
||||
#### Version 2.9.9
|
||||
>1. update cache key
|
||||
|
||||
#### Version 2.9.8
|
||||
>1. supple code data
|
||||
|
||||
#### Version 2.9.7
|
||||
>1. fix code data
|
||||
|
||||
#### Version 2.9.6
|
||||
>1. fix code data
|
||||
|
||||
#### Version 2.9.5
|
||||
>1. fix sync pay order time
|
||||
|
||||
#### Version 2.9.4
|
||||
>1. sync pay order time
|
||||
|
||||
#### Version 2.9.3
|
||||
>1. update cache key
|
||||
|
||||
#### Version 2.9.2
|
||||
>1. add vip cache to account notify
|
||||
|
||||
#### Version 2.9.1
|
||||
>1. limit short vip
|
||||
|
||||
#### Version 2.9.0
|
||||
>1. vip coupon feature
|
||||
|
||||
#### Version 2.8.8
|
||||
>1. fix closter
|
||||
|
||||
#### Version 2.8.7
|
||||
>1. fix code
|
||||
|
||||
#### Version 2.8.6
|
||||
>1. fix code retry
|
||||
|
||||
#### Version 2.8.5
|
||||
>1. fix code send
|
||||
|
||||
#### Version 2.8.4
|
||||
>1. load code config from db
|
||||
|
||||
#### Version 2.8.3
|
||||
>1. make del bacoin salary
|
||||
|
||||
#### Version 2.8.2
|
||||
>1. fix chan full
|
||||
|
||||
#### Version 2.8.1
|
||||
>1. summer active add autorenew order check
|
||||
>2. summer active add tip and send codes
|
||||
|
||||
#### Version 2.8.0
|
||||
>1. push data job
|
||||
|
||||
#### Version 2.7.5
|
||||
>1. sync data user info
|
||||
|
||||
#### Version 2.7.4
|
||||
>1. sync data user info
|
||||
|
||||
#### Version 2.7.3
|
||||
>1. sync data history
|
||||
|
||||
#### Version 2.7.2
|
||||
>1. active add mut activeid
|
||||
|
||||
#### Version 2.7.1
|
||||
>1. check bcoin change history data
|
||||
|
||||
#### Version 2.7.0
|
||||
>1. add auto renew change log
|
||||
|
||||
#### Version 2.6.8
|
||||
>1. clear vip cache
|
||||
#### Version 2.6.7
|
||||
>1. clear vip cache
|
||||
####v2.6.6
|
||||
>1. change mc vip key
|
||||
#### Version 2.6.5
|
||||
>1. clear vip cache by scope
|
||||
#### Version 2.6.4
|
||||
>1. clear vip info cache
|
||||
#### Version 2.6.3
|
||||
>1. update async handler madel
|
||||
#### Version 2.6.2
|
||||
>1. update pay_type
|
||||
#### Version 2.6.1
|
||||
>1. update bili_vip databus
|
||||
#### Version 2.6.0
|
||||
>1. update summery active
|
||||
#### Version 2.5.3
|
||||
>1. sysn vip_user_info data
|
||||
|
||||
#### Version 2.5.2
|
||||
>1. fix check vip_user_info
|
||||
#### Version 2.5.1
|
||||
>1. remove ignore file
|
||||
|
||||
#### Version 2.5.0
|
||||
>1. check vip_user_info table data
|
||||
#### Version 2.4.2
|
||||
>1. check pay channel id update payType
|
||||
|
||||
#### Version 2.4.0
|
||||
>1. 漫画券
|
||||
|
||||
#### Version 2.3.0
|
||||
>1. update sync user info
|
||||
|
||||
|
||||
#### Version 2.2.1
|
||||
>1. update sync user info
|
||||
#### Version 2.2.0
|
||||
>1. update iap auto status
|
||||
#### Version 2.1.1
|
||||
>1. update old recharge order change ttn
|
||||
#### Version 2.1.0
|
||||
>1. add clear cache and sync interface
|
||||
>2. ios_overdue_time data sync
|
||||
#### Version 2.0.9
|
||||
>1. vip user cache clear
|
||||
#### Version 2.0.8
|
||||
>1.update bm
|
||||
#### Version 2.0.7
|
||||
>1. reload all data
|
||||
|
||||
#### Version 2.0.6
|
||||
>1. set defuat
|
||||
|
||||
#### Version 2.0.5
|
||||
>1. config batch size
|
||||
|
||||
#### Version 2.0.4
|
||||
>1.修复vip,order数据同步
|
||||
|
||||
#### Version 2.0.3
|
||||
>1.修复数据同步问题
|
||||
|
||||
#### Version 2.0.2
|
||||
>1.移除clean vip cache
|
||||
|
||||
#### Version 2.0.1
|
||||
>1.注释冻结代码
|
||||
>2.移除databusutil
|
||||
|
||||
#### Version 2.0.0
|
||||
>1.vip-job重构
|
||||
>2.update build
|
||||
|
||||
#### Version 1.1.8
|
||||
> 1.salary mc lock
|
||||
|
||||
#### Version 1.1.7
|
||||
> 1.时间兼容 err = nil
|
||||
|
||||
#### Version 1.1.6
|
||||
> 1.时间兼容"0000-00-00 00:00:00"
|
||||
|
||||
#### Version 1.1.5
|
||||
> 1.观影劵发放
|
||||
|
||||
#### Version 1.1.4
|
||||
> 1.move path
|
||||
#### Version 1.1.3
|
||||
|
||||
> 1.refined log
|
||||
|
||||
#### Version 1.1.2
|
||||
|
||||
> 1.vip purge cache enhance
|
||||
|
||||
#### Version 1.1.1
|
||||
|
||||
> 1.更新读取方式
|
||||
|
||||
#### Version 1.1.0
|
||||
|
||||
> 1.更新 缓存清理策略
|
||||
|
||||
#### Version 1.0.1
|
||||
|
||||
> 1.更改为清除vip缓存类型
|
||||
|
||||
##### Version 1.0.0
|
||||
|
||||
> 1.资源池基础api
|
||||
|
8
app/job/main/vip/CONTRIBUTORS.md
Normal file
8
app/job/main/vip/CONTRIBUTORS.md
Normal file
@ -0,0 +1,8 @@
|
||||
# Owner
|
||||
zhaogangtao
|
||||
|
||||
# Author
|
||||
zhaozhihao
|
||||
|
||||
# Reviewer
|
||||
lintanghui
|
14
app/job/main/vip/OWNERS
Normal file
14
app/job/main/vip/OWNERS
Normal file
@ -0,0 +1,14 @@
|
||||
# See the OWNERS docs at https://go.k8s.io/owners
|
||||
|
||||
approvers:
|
||||
- zhaogangtao
|
||||
- zhaozhihao
|
||||
labels:
|
||||
- job
|
||||
- job/main/vip
|
||||
- main
|
||||
options:
|
||||
no_parent_owners: true
|
||||
reviewers:
|
||||
- lintanghui
|
||||
- zhaozhihao
|
13
app/job/main/vip/README.md
Normal file
13
app/job/main/vip/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
#### vip
|
||||
|
||||
##### 项目简介
|
||||
> 1.大会员job
|
||||
|
||||
##### 编译环境
|
||||
> 请只用golang v1.8.x以上版本编译执行。
|
||||
|
||||
##### 依赖包
|
||||
> 1.公共包go-common
|
||||
|
||||
##### 特别说明
|
||||
> 1.model目录可能会被其他项目引用,请谨慎更改并通知各方。
|
42
app/job/main/vip/cmd/BUILD
Normal file
42
app/job/main/vip/cmd/BUILD
Normal file
@ -0,0 +1,42 @@
|
||||
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 = ["vip-job-test.toml"],
|
||||
importpath = "go-common/app/job/main/vip/cmd",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/job/main/vip/conf:go_default_library",
|
||||
"//app/job/main/vip/http:go_default_library",
|
||||
"//app/job/main/vip/service: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"],
|
||||
)
|
51
app/job/main/vip/cmd/main.go
Normal file
51
app/job/main/vip/cmd/main.go
Normal file
@ -0,0 +1,51 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"go-common/app/job/main/vip/conf"
|
||||
"go-common/app/job/main/vip/http"
|
||||
"go-common/app/job/main/vip/service"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
var (
|
||||
s *service.Service
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
flag.Parse()
|
||||
// init conf,log,trace,stat,perf.
|
||||
if err := conf.Init(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
log.Init(conf.Conf.Xlog)
|
||||
defer log.Close()
|
||||
s = service.New(conf.Conf)
|
||||
http.Init(conf.Conf, s)
|
||||
// rpcSvr := rpc.New(conf.Conf, svr)
|
||||
// signal handler
|
||||
log.Info("vip-job start")
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
|
||||
for {
|
||||
signal := <-c
|
||||
log.Info("vip-job get a signal %s", signal.String())
|
||||
switch signal {
|
||||
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
|
||||
s.Close()
|
||||
time.Sleep(time.Second * 2)
|
||||
log.Info("vip-job exit")
|
||||
return
|
||||
case syscall.SIGHUP:
|
||||
// TODO reload
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
288
app/job/main/vip/cmd/vip-job-test.toml
Normal file
288
app/job/main/vip/cmd/vip-job-test.toml
Normal file
@ -0,0 +1,288 @@
|
||||
# This is a TOML document. Boom.
|
||||
|
||||
version = "1.0.0"
|
||||
|
||||
vipURI = "http://vip.bilibili.co"
|
||||
[app]
|
||||
key = "ad4bb9b8f5d9d4a7"
|
||||
secret = "6912080d78d58be7cb94f57d50d438f6"
|
||||
|
||||
[bm]
|
||||
addr = "0.0.0.0:6822"
|
||||
maxListen = 10
|
||||
timeout = "1s"
|
||||
|
||||
[payConf]
|
||||
CustomerID = "10004"
|
||||
Token ="0ff3d296ee0d7a28b4db1d761d2db907"
|
||||
OrderNotifyURL ="http://vip.bilibili.co/pay/payOrderNotify"
|
||||
SignNotifyURL ="http://vip.bilibili.co/pay/paySignNotify"
|
||||
PlanID = 108217
|
||||
ProductID ="vip_buy"
|
||||
Version ="1.0"
|
||||
|
||||
[URLConf]
|
||||
payCoUrl = "http://pay.bilibili.co"
|
||||
payUrl = "http://pay.bilibili.com"
|
||||
MsgUrl = "http://message.bilibili.co"
|
||||
mallUrl = "http://uat-mall.bilibili.co"
|
||||
accountUrl = "http://account.bilibili.com"
|
||||
apiCoUrl = "http://api.bilibili.co"
|
||||
oldVipCoURL = "http://vip.bilibili.co"
|
||||
|
||||
[property]
|
||||
UpdateUserInfoCron = "0 0 0 * * ?"
|
||||
willExpireMsgCron = "0 0 0 * * ?"
|
||||
hadExpiredMsgCron = "0 0 0 * * ?"
|
||||
AutoRenewCron = "0 0 0 * * ?"
|
||||
SendMessageCron = "0 0 12 * * ?"
|
||||
SalaryVideoCouponCron = "0 0 2 1 * ?"
|
||||
PushDataCron = "0 0 3 * * ?"
|
||||
SalaryVideoCouponnIterval = "5ms"
|
||||
Retry = 3
|
||||
SalaryDay = 10
|
||||
annualVipSalaryCount = 4
|
||||
normalVipSalaryCount = 2
|
||||
frozenExpire = "15m"
|
||||
frozenDate = "30m"
|
||||
frozenLimit= 5
|
||||
frozenCron = "0 1 0 * * ?"
|
||||
sendBcoinCron = "0 0 0/1 10,11 * *"
|
||||
handlerThread = 5
|
||||
ReadThread = 3
|
||||
PayMapping = {3 = "wechart"}
|
||||
ActivityID = 142
|
||||
AnnualVipBcoinCouponMoney = 5
|
||||
AnnualVipBcoinDay = 10
|
||||
batchSize = 200
|
||||
salaryCouponMaps = {1 = {1 = 2, 2 = 4},2 = {1 = 8, 2 = 20}}
|
||||
salaryCouponTypes = [1,2]
|
||||
SalaryCouponBatchNoMaps = {1 = "view_%d_%s",2 = "cartoon_%d_%s"}
|
||||
salaryCouponMsgTitleMaps = {1 = "观影劵到账通知",2 = "漫画阅读劵到账通知"}
|
||||
salaryCouponMsgContentMaps = {1 = '大会员专享观影券已到账,#{点击查看>>}{"https://big.bilibili.com/mobile/userticket"}',2 = '大会员漫画阅读券已到账 #{点击查看>>}{"http://comic.bilibili.com/coupon.html"}'}
|
||||
salaryCouponMsgSupplyContentMaps = {1 = '升级年度大会员赠送观影券%d张已到账,#{点击查看>>}{"https://big.bilibili.com/mobile/userticket"}',2 = '升级年度大会员赠送漫画阅读券%d张已到账,#{点击查看>>}{"http://comic.bilibili.com/coupon.html"}'}
|
||||
salaryCouponURL = "http://api.bilibili.co/x/internal/coupon/grant"
|
||||
msgOpen = true
|
||||
activeStartTime = "2018-06-10 00:00:00"
|
||||
sendMedalEndTime = "2018-07-08 00:00:00"
|
||||
sendVipbuyEndTime = "2018-07-02 00:00:00"
|
||||
summerActiveStartTime = "2018-06-09 00:00:00"
|
||||
summerActiveEndTime = "2018-09-01 00:00:00"
|
||||
sendCodeStartTime = "2018-08-20 00:00:00"
|
||||
SendCodeEndTime = "2018-08-20 16:10:00"
|
||||
couponIDs =["669748557aba188d","ab9b24dfcc107c6b","fe42eca7ed959a36","00244f64f658d1be"]
|
||||
MedalID = 1
|
||||
codeExchangeMap = {1=[2,4],3=[3,8],12=[10,20]}
|
||||
codeExchangeTimeMap = {1=1,3=1,12=4}
|
||||
codeExchangePicMap = {1="http://i0.hdslb.com/bfs/activity-plat/static/20180615/d781502035dedd08821dacc88ea19b81/v573vo4y37.png",3="http://i0.hdslb.com/bfs/activity-plat/static/20180615/d781502035dedd08821dacc88ea19b81/89j8xm0019.png",12="http://i0.hdslb.com/bfs/activity-plat/static/20180615/d781502035dedd08821dacc88ea19b81/89j8xm0019.png"}
|
||||
vipbuyExchangeNameMap={"669748557aba188d"="会员购满349减40优惠券","ab9b24dfcc107c6b"="会员购满269减30优惠券","fe42eca7ed959a36"="会员购满169减20优惠券","00244f64f658d1be"="会员购满69减8优惠券"}
|
||||
grayScope = 500
|
||||
pushToken = "fi6xf5xmldudexsh5tgukerohn3mgrl3"
|
||||
businessId = 1
|
||||
splitPush = 2
|
||||
UpdateDB = true
|
||||
NotGrantLimit = 100
|
||||
EleEompensateCron = "*/5 * * * * ?"
|
||||
|
||||
[RPC]
|
||||
[RPC.VipRPC]
|
||||
pullInterval = "10s"
|
||||
[VipRPC.client]
|
||||
token = "123456789"
|
||||
proto = "tcp"
|
||||
timeout = "1s"
|
||||
timer = 1000
|
||||
[VipRPC.client.breaker]
|
||||
window ="10s"
|
||||
sleep ="10ms"
|
||||
bucket = 10
|
||||
ratio = 0.5
|
||||
request = 100
|
||||
[VipRPC.zookeeper]
|
||||
root = "/microservice/vip/"
|
||||
addrs = ["172.18.33.50:2199","172.18.33.51:2199","172.18.33.52:2199"]
|
||||
timeout = "30s"
|
||||
|
||||
[databusutil]
|
||||
size = 100
|
||||
chan = 1024
|
||||
num = 4
|
||||
|
||||
[httpClient]
|
||||
key = "ad4bb9b8f5d9d4a7"
|
||||
secret = "6912080d78d58be7cb94f57d50d438f6"
|
||||
dial = "2s"
|
||||
timeout = "2s"
|
||||
keepAlive = "60s"
|
||||
timer = 128
|
||||
[httpClient.breaker]
|
||||
window = "3s"
|
||||
sleep = "100ms"
|
||||
bucket = 10
|
||||
ratio = 0.5
|
||||
request = 100
|
||||
|
||||
|
||||
[newMysql]
|
||||
addr = "172.16.33.205"
|
||||
dsn = "test:test@tcp(172.16.33.205:3308)/bilibili_vip?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
|
||||
active = 5
|
||||
idle = 2
|
||||
IdleTimeout ="4h"
|
||||
queryTimeout = "2000ms"
|
||||
execTimeout = "2000ms"
|
||||
tranTimeout = "2000ms"
|
||||
[newMysql.breaker]
|
||||
window = "3s"
|
||||
sleep = "100ms"
|
||||
bucket = 10
|
||||
ratio = 0.5
|
||||
request = 100
|
||||
|
||||
[oldMysql]
|
||||
addr = "172.16.33.205"
|
||||
dsn = "vip:lqfGWO9n3XihPokr@tcp(172.16.33.205:3306)/vip?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
|
||||
active = 5
|
||||
idle = 2
|
||||
IdleTimeout ="4h"
|
||||
queryTimeout = "2000ms"
|
||||
execTimeout = "2000ms"
|
||||
tranTimeout = "2000ms"
|
||||
[oldMysql.breaker]
|
||||
window = "3s"
|
||||
sleep = "100ms"
|
||||
bucket = 10
|
||||
ratio = 0.5
|
||||
request = 100
|
||||
|
||||
[databus]
|
||||
[databus.accLogin]
|
||||
key = "4ba46ba31f9a44ef"
|
||||
secret = "99985eb4451cfb1b899ca0fbe3c4bdc8"
|
||||
group = "Passport-MainAccount-S"
|
||||
topic = "Passport-T"
|
||||
action = "sub"
|
||||
offset = "old"
|
||||
buffer = 1024
|
||||
name = "vip-job"
|
||||
proto = "tcp"
|
||||
addr = "172.16.33.158:6205"
|
||||
idle = 1
|
||||
active = 1
|
||||
dialTimeout = "1s"
|
||||
readTimeout = "60s"
|
||||
writeTimeout = "1s"
|
||||
idleTimeout = "10s"
|
||||
[databus.oldVipBinLog]
|
||||
key = "4ba46ba31f9a44ef"
|
||||
secret = "99985eb4451cfb1b899ca0fbe3c4bdc8"
|
||||
group = "VipBinlog-MainAccount-S"
|
||||
topic = "VipBinlog-T"
|
||||
action = "sub"
|
||||
offset = "old"
|
||||
buffer = 1024
|
||||
name = "vip-job"
|
||||
proto = "tcp"
|
||||
addr = "172.16.33.158:6205"
|
||||
idle = 1
|
||||
active = 1
|
||||
dialTimeout = "1s"
|
||||
readTimeout = "60s"
|
||||
writeTimeout = "1s"
|
||||
idleTimeout = "10s"
|
||||
[databus.newVipBinLog]
|
||||
key = "4ba46ba31f9a44ef"
|
||||
secret = "99985eb4451cfb1b899ca0fbe3c4bdc8"
|
||||
group = "BiliVIPBinlog-MainAccount-S"
|
||||
topic = "BiliVIPBinlog-T"
|
||||
action = "sub"
|
||||
offset = "old"
|
||||
buffer = 1024
|
||||
name = "vip-job"
|
||||
proto = "tcp"
|
||||
addr = "172.16.33.158:6205"
|
||||
idle = 1
|
||||
active = 1
|
||||
dialTimeout = "1s"
|
||||
readTimeout = "60s"
|
||||
writeTimeout = "1s"
|
||||
idleTimeout = "10s"
|
||||
[databus.salaryCoupon]
|
||||
key = "4ba46ba31f9a44ef"
|
||||
secret = "99985eb4451cfb1b899ca0fbe3c4bdc8"
|
||||
group = "VipBinlog-MainAccount-S"
|
||||
topic = "VipBinlog-T"
|
||||
action = "sub"
|
||||
offset = "old"
|
||||
buffer = 1024
|
||||
name = "vip-job"
|
||||
proto = "tcp"
|
||||
addr = "172.16.33.158:6205"
|
||||
idle = 1
|
||||
active = 1
|
||||
dialTimeout = "1s"
|
||||
readTimeout = "60s"
|
||||
writeTimeout = "1s"
|
||||
idleTimeout = "10s"
|
||||
[databus.accountNotify]
|
||||
key = "4ba46ba31f9a44ef"
|
||||
secret = "eab6221e1948b24a7376f6d0535f668a"
|
||||
group = "AccountNotify-MainAccount-P"
|
||||
topic = "AccountNotify-T"
|
||||
action = "pub"
|
||||
offset = "old"
|
||||
buffer = 1024
|
||||
name = "vip-job"
|
||||
proto = "tcp"
|
||||
addr = "172.16.33.158:6205"
|
||||
idle = 1
|
||||
active = 1
|
||||
dialTimeout = "1s"
|
||||
readTimeout = "60s"
|
||||
writeTimeout = "1s"
|
||||
idleTimeout = "10s"
|
||||
[databus.couponNotify]
|
||||
key = "4ba46ba31f9a44ef"
|
||||
secret = "99985eb4451cfb1b899ca0fbe3c4bdc8"
|
||||
group = "BiliVIPBinlog-MainAccount-Coupon-S"
|
||||
topic = "BiliVIPBinlog-T"
|
||||
action = "sub"
|
||||
offset = "old"
|
||||
buffer = 1024
|
||||
name = "vip-job"
|
||||
proto = "tcp"
|
||||
addr = "172.16.33.158:6205"
|
||||
idle = 1
|
||||
active = 1
|
||||
dialTimeout = "1s"
|
||||
readTimeout = "60s"
|
||||
writeTimeout = "1s"
|
||||
idleTimeout = "10s"
|
||||
|
||||
[memcache]
|
||||
name = "vip"
|
||||
proto = "tcp"
|
||||
addr = "172.18.33.60:11234"
|
||||
idle = 5
|
||||
active = 10
|
||||
dialTimeout = "1s"
|
||||
readTimeout = "1s"
|
||||
writeTimeout = "1s"
|
||||
idleTimeout = "10s"
|
||||
expire = "24h"
|
||||
|
||||
[redis]
|
||||
name = "vip"
|
||||
proto = "tcp"
|
||||
addr = "172.18.33.61:6879"
|
||||
idle = 100
|
||||
active = 100
|
||||
dialTimeout = "1s"
|
||||
readTimeout = "1s"
|
||||
writeTimeout = "1s"
|
||||
idleTimeout = "10s"
|
||||
expire = "24h"
|
||||
|
||||
[RPCClient2]
|
||||
[RPCClient2.coupon]
|
||||
timeout = "1s"
|
42
app/job/main/vip/conf/BUILD
Normal file
42
app/job/main/vip/conf/BUILD
Normal file
@ -0,0 +1,42 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["conf.go"],
|
||||
importpath = "go-common/app/job/main/vip/conf",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//library/cache/memcache:go_default_library",
|
||||
"//library/cache/redis:go_default_library",
|
||||
"//library/conf:go_default_library",
|
||||
"//library/database/sql:go_default_library",
|
||||
"//library/log:go_default_library",
|
||||
"//library/net/http/blademaster:go_default_library",
|
||||
"//library/net/rpc:go_default_library",
|
||||
"//library/net/rpc/warden:go_default_library",
|
||||
"//library/queue/databus:go_default_library",
|
||||
"//library/queue/databus/databusutil: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"],
|
||||
)
|
222
app/job/main/vip/conf/conf.go
Normal file
222
app/job/main/vip/conf/conf.go
Normal file
@ -0,0 +1,222 @@
|
||||
package conf
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
|
||||
"go-common/library/cache/memcache"
|
||||
"go-common/library/cache/redis"
|
||||
"go-common/library/conf"
|
||||
"go-common/library/database/sql"
|
||||
"go-common/library/log"
|
||||
bm "go-common/library/net/http/blademaster"
|
||||
"go-common/library/net/rpc"
|
||||
"go-common/library/net/rpc/warden"
|
||||
"go-common/library/queue/databus"
|
||||
"go-common/library/queue/databus/databusutil"
|
||||
xtime "go-common/library/time"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
)
|
||||
|
||||
// Conf global variable.
|
||||
var (
|
||||
Conf = &Config{}
|
||||
client *conf.Client
|
||||
confPath string
|
||||
)
|
||||
|
||||
// Config struct of conf.
|
||||
type Config struct {
|
||||
VipURI string
|
||||
// base
|
||||
App *bm.App
|
||||
// log
|
||||
Xlog *log.Config
|
||||
// http
|
||||
BM *bm.ServerConfig
|
||||
// db
|
||||
NewMysql *sql.Config
|
||||
//old db
|
||||
OldMysql *sql.Config
|
||||
// http client
|
||||
HTTPClient *bm.ClientConfig
|
||||
//Property
|
||||
Property *Property
|
||||
|
||||
URLConf *URLConf
|
||||
//databus group config
|
||||
DatabusUtil *databusutil.Config
|
||||
//point databus
|
||||
Databus *DataSource
|
||||
// mc
|
||||
Memcache *Memcache
|
||||
// redis
|
||||
Redis *Redis
|
||||
PayConf *PayConf
|
||||
// rpc clients
|
||||
RPCClient2 *RPC
|
||||
// grpc
|
||||
VipClient *warden.ClientConfig
|
||||
}
|
||||
|
||||
//RPC rpc clients.
|
||||
type RPC struct {
|
||||
Coupon *rpc.ClientConfig
|
||||
}
|
||||
|
||||
//URLConf url conf
|
||||
type URLConf struct {
|
||||
PayCoURL string
|
||||
PayURL string
|
||||
MsgURL string
|
||||
MallURL string
|
||||
AccountURL string
|
||||
APICoURL string
|
||||
OldVipCoURL string
|
||||
}
|
||||
|
||||
// Property config for biz logic.
|
||||
type Property struct {
|
||||
UpdateUserInfoCron string
|
||||
AutoRenewCron string
|
||||
SendMessageCron string
|
||||
SendBcoinCron string
|
||||
WillExpireMsgCron string
|
||||
HadExpiredMsgCron string
|
||||
PushDataCron string
|
||||
EleEompensateCron string
|
||||
HandlerThread int
|
||||
ReadThread int
|
||||
Retry int
|
||||
FrozenExpire xtime.Duration
|
||||
FrozenDate xtime.Duration
|
||||
FrozenLimit int64
|
||||
FrozenCron string
|
||||
PayMapping map[string]string
|
||||
MsgURL string
|
||||
ActivityID int64
|
||||
AnnualVipBcoinDay int
|
||||
AnnualVipBcoinCouponMoney int
|
||||
PayCoURL string
|
||||
SalaryDay int
|
||||
AnnualVipSalaryCount int
|
||||
NormalVipSalaryCount int
|
||||
SalaryVideoCouponnIterval xtime.Duration
|
||||
SalaryVideoCouponCron string
|
||||
MsgOpen bool
|
||||
BatchSize int
|
||||
SalaryCouponMaps map[string]map[string]int64 // map[coupontype]map[viptype]salarycount
|
||||
SalaryCouponTypes []int8
|
||||
SalaryCouponBatchNoMaps map[string]string // map[coupontype]batchnofmt
|
||||
SalaryCouponMsgTitleMaps map[string]string // map[ coupontype]msgTitle
|
||||
SalaryCouponMsgContentMaps map[string]string // map[coupontype]msgsContent
|
||||
SalaryCouponMsgSupplyContentMaps map[string]string // map[coupontype]msgsContent
|
||||
SalaryCouponURL string
|
||||
ActiveStartTime string
|
||||
SendMedalEndTime string
|
||||
SendVipbuyEndTime string
|
||||
SummerActiveStartTime string
|
||||
SummerActiveEndTime string
|
||||
SendCodeStartTime string
|
||||
SendCodeEndTime string
|
||||
CouponIDs []string
|
||||
MedalID int64
|
||||
CodeExchangeMap map[string][]int64
|
||||
CodeExchangeTimeMap map[string]int
|
||||
CodeExchangePicMap map[string]string
|
||||
VipbuyExchangeNameMap map[string]string
|
||||
GrayScope int64
|
||||
PushToken string
|
||||
BusinessID int64
|
||||
SplitPush int
|
||||
UpdateDB bool
|
||||
NotGrantLimit int
|
||||
}
|
||||
|
||||
//PayConf pay conf info
|
||||
type PayConf struct {
|
||||
BasicURL string
|
||||
CustomerID string
|
||||
Token string
|
||||
NotifyURL string
|
||||
OrderNotifyURL string
|
||||
SignNotifyURL string
|
||||
PlanID int32
|
||||
ProductID string
|
||||
Version string
|
||||
}
|
||||
|
||||
// Memcache memcache
|
||||
type Memcache struct {
|
||||
*memcache.Config
|
||||
Expire xtime.Duration
|
||||
}
|
||||
|
||||
// Redis redis
|
||||
type Redis struct {
|
||||
*redis.Config
|
||||
Expire xtime.Duration
|
||||
}
|
||||
|
||||
// DataSource databus config zone.
|
||||
type DataSource struct {
|
||||
AccLogin *databus.Config
|
||||
OldVipBinLog *databus.Config
|
||||
SalaryCoupon *databus.Config
|
||||
NewVipBinLog *databus.Config
|
||||
AccountNotify *databus.Config
|
||||
CouponNotify *databus.Config
|
||||
AutoRenew *databus.Config
|
||||
}
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&confPath, "conf", "", "default config path")
|
||||
}
|
||||
|
||||
// Init create config instance.
|
||||
func Init() (err error) {
|
||||
if confPath != "" {
|
||||
return local()
|
||||
}
|
||||
return remote()
|
||||
}
|
||||
|
||||
func local() (err error) {
|
||||
_, err = toml.DecodeFile(confPath, &Conf)
|
||||
return
|
||||
}
|
||||
|
||||
func remote() (err error) {
|
||||
if client, err = conf.New(); err != nil {
|
||||
return
|
||||
}
|
||||
if err = load(); err != nil {
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
for range client.Event() {
|
||||
log.Info("config reload")
|
||||
if load() != nil {
|
||||
log.Error("config reload error (%v)", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
return
|
||||
}
|
||||
|
||||
func load() (err error) {
|
||||
var (
|
||||
s string
|
||||
ok bool
|
||||
tmpConf *Config
|
||||
)
|
||||
if s, ok = client.Toml2(); !ok {
|
||||
return errors.New("load config center error")
|
||||
}
|
||||
if _, err = toml.Decode(s, &tmpConf); err != nil {
|
||||
return errors.New("could not decode config")
|
||||
}
|
||||
*Conf = *tmpConf
|
||||
return
|
||||
}
|
92
app/job/main/vip/dao/BUILD
Normal file
92
app/job/main/vip/dao/BUILD
Normal file
@ -0,0 +1,92 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_test",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"associate_test.go",
|
||||
"business_test.go",
|
||||
"coupon_old_test.go",
|
||||
"coupon_test.go",
|
||||
"dao_test.go",
|
||||
"http_test.go",
|
||||
"memcache_test.go",
|
||||
"mysql_test.go",
|
||||
"oldvip_test.go",
|
||||
"order_test.go",
|
||||
"push_test.go",
|
||||
"redis_test.go",
|
||||
"resource_test.go",
|
||||
"sync_test.go",
|
||||
"vip_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
rundir = ".",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//app/job/main/vip/conf:go_default_library",
|
||||
"//app/job/main/vip/model:go_default_library",
|
||||
"//library/database/sql:go_default_library",
|
||||
"//library/time:go_default_library",
|
||||
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
|
||||
"//vendor/gopkg.in/h2non/gock.v1:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"associate.go",
|
||||
"business.go",
|
||||
"coupon.go",
|
||||
"coupon_old.go",
|
||||
"dao.go",
|
||||
"http.go",
|
||||
"memcache.go",
|
||||
"mysql.go",
|
||||
"oldvip.go",
|
||||
"order.go",
|
||||
"push.go",
|
||||
"redis.go",
|
||||
"resource.go",
|
||||
"sync.go",
|
||||
"vip.go",
|
||||
],
|
||||
importpath = "go-common/app/job/main/vip/dao",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/job/main/vip/conf:go_default_library",
|
||||
"//app/job/main/vip/model:go_default_library",
|
||||
"//library/cache/memcache:go_default_library",
|
||||
"//library/cache/redis:go_default_library",
|
||||
"//library/database/sql:go_default_library",
|
||||
"//library/ecode:go_default_library",
|
||||
"//library/log:go_default_library",
|
||||
"//library/net/http/blademaster:go_default_library",
|
||||
"//library/stat/prom:go_default_library",
|
||||
"//library/time:go_default_library",
|
||||
"//library/xstr:go_default_library",
|
||||
"//vendor/github.com/google/uuid: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"],
|
||||
)
|
35
app/job/main/vip/dao/associate.go
Normal file
35
app/job/main/vip/dao/associate.go
Normal file
@ -0,0 +1,35 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
"go-common/library/database/sql"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
_notGrantActOrder = "SELECT id,mid,order_no,product_id,months,panel_type,associate_state,ctime,mtime FROM vip_order_activity_record WHERE associate_state = 0 AND panel_type = ? limit ?;"
|
||||
)
|
||||
|
||||
// NotGrantActOrders not grant activity order.
|
||||
func (d *Dao) NotGrantActOrders(c context.Context, panelType string, limit int) (res []*model.VipOrderActivityRecord, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = d.oldDb.Query(c, _notGrantActOrder, panelType, limit); err != nil {
|
||||
err = errors.Wrapf(err, "dao associate not grants query (%s,%d)", panelType, limit)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
r := new(model.VipOrderActivityRecord)
|
||||
if err = rows.Scan(&r.ID, &r.Mid, &r.OrderNo, &r.ProductID, &r.Months, &r.PanelType, &r.AssociateState, &r.Ctime, &r.Mtime); err != nil {
|
||||
err = errors.Wrapf(err, "dao associate not grants scan (%s,%d)", panelType, limit)
|
||||
res = nil
|
||||
return
|
||||
}
|
||||
res = append(res, r)
|
||||
}
|
||||
err = rows.Err()
|
||||
return
|
||||
}
|
20
app/job/main/vip/dao/associate_test.go
Normal file
20
app/job/main/vip/dao/associate_test.go
Normal file
@ -0,0 +1,20 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
// go test -test.v -test.run TestDaoNotGrantActOrders
|
||||
func TestDaoNotGrantActOrders(t *testing.T) {
|
||||
Convey("TestDaoNotGrantActOrders salary coupon", t, func() {
|
||||
res, err := d.NotGrantActOrders(context.Background(), "ele", 100)
|
||||
for _, v := range res {
|
||||
fmt.Println("res:", v)
|
||||
}
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
470
app/job/main/vip/dao/business.go
Normal file
470
app/job/main/vip/dao/business.go
Normal file
@ -0,0 +1,470 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
xtime "time"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
"go-common/library/ecode"
|
||||
"go-common/library/log"
|
||||
"go-common/library/time"
|
||||
"go-common/library/xstr"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
_cleanCache = "/notify/cleanCache"
|
||||
_payOrder = "/payplatform/pay/pay"
|
||||
_message = "/api/notify/send.user.notify.do"
|
||||
_addBcoin = "/api/coupon/regular/add"
|
||||
_sendVipbuyTicket = "/mall-marketing/coupon_code/create"
|
||||
_sendMedal = "/api/nameplate/get/v2"
|
||||
_pushData = "/x/internal/push-strategy/task/add"
|
||||
|
||||
_retry = 3
|
||||
_minRead = 1024 * 64
|
||||
|
||||
_alreadySend = -804
|
||||
|
||||
_alreadyGet = -663
|
||||
|
||||
_alreadySendVipbuy = 83110005
|
||||
_ok = 1
|
||||
|
||||
//push
|
||||
appID = 1
|
||||
)
|
||||
|
||||
//PushData http push data
|
||||
func (d *Dao) PushData(c context.Context, mids []int64, pushData *model.VipPushData, curtime string) (rel *model.VipPushResq, err error) {
|
||||
var (
|
||||
pushTime xtime.Time
|
||||
expireTime xtime.Time
|
||||
params = url.Values{}
|
||||
)
|
||||
rel = new(model.VipPushResq)
|
||||
|
||||
if pushTime, err = xtime.ParseInLocation("2006-01-02 15:04:05", fmt.Sprintf("%v %v", curtime, pushData.PushStartTime), xtime.Local); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
|
||||
if expireTime, err = xtime.ParseInLocation("2006-01-02 15:04:05", fmt.Sprintf("%v %v", curtime, pushData.PushEndTime), xtime.Local); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
|
||||
page := len(mids) / d.c.Property.SplitPush
|
||||
if len(mids)%d.c.Property.SplitPush != 0 {
|
||||
page++
|
||||
}
|
||||
for i := 0; i < page; i++ {
|
||||
startID := i * d.c.Property.SplitPush
|
||||
endID := (i + 1) * d.c.Property.SplitPush
|
||||
if endID > len(mids) {
|
||||
endID = len(mids)
|
||||
}
|
||||
tempMids := mids[startID:endID]
|
||||
params.Set("app_id", fmt.Sprintf("%v", appID))
|
||||
params.Set("business_id", fmt.Sprintf("%v", d.c.Property.BusinessID))
|
||||
params.Set("alert_title", pushData.Title)
|
||||
params.Set("alert_body", pushData.Content)
|
||||
params.Set("mids", xstr.JoinInts(tempMids))
|
||||
params.Set("link_type", fmt.Sprintf("%v", pushData.LinkType))
|
||||
params.Set("link_value", pushData.LinkURL)
|
||||
params.Set("builds", pushData.Platform)
|
||||
params.Set("group", pushData.GroupName)
|
||||
params.Set("uuid", uuid.New().String())
|
||||
params.Set("push_time", fmt.Sprintf("%v", pushTime.Unix()))
|
||||
params.Set("expire_time", fmt.Sprintf("%v", expireTime.Unix()))
|
||||
|
||||
header := make(map[string]string)
|
||||
header["Authorization"] = fmt.Sprintf("token=%v", d.c.Property.PushToken)
|
||||
header["Content-Type"] = "application/x-www-form-urlencoded"
|
||||
|
||||
for i := 0; i < _retry; i++ {
|
||||
if err = d.doNomalSend(c, d.c.URLConf.APICoURL, _pushData, "127.0.0.1", header, params, rel); err != nil {
|
||||
log.Error("send error(%v) url(%v)", err, d.c.URLConf.APICoURL+_pushData)
|
||||
return
|
||||
}
|
||||
|
||||
if rel.Code == int64(ecode.OK.Code()) {
|
||||
log.Info("send url:%v params:%+v return:%+v error(%+v)", d.c.URLConf.APICoURL+_pushData, params, rel, err)
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
//SendMedal send medal
|
||||
func (d *Dao) SendMedal(c context.Context, mid, medalID int64) (status int64) {
|
||||
var (
|
||||
err error
|
||||
)
|
||||
params := url.Values{}
|
||||
params.Set("mid", fmt.Sprintf("%v", mid))
|
||||
params.Set("nid", fmt.Sprintf("%v", medalID))
|
||||
rel := new(struct {
|
||||
Code int64 `json:"code"`
|
||||
Data string `json:"data"`
|
||||
})
|
||||
defer func() {
|
||||
if err == nil {
|
||||
log.Info("send url:%+v params:%+v return:%+v", d.c.URLConf.AccountURL+_sendMedal, params, rel)
|
||||
}
|
||||
}()
|
||||
for i := 0; i < _retry; i++ {
|
||||
if err = d.client.Get(c, d.c.URLConf.AccountURL+_sendMedal, "127.0.0.1", params, rel); err != nil {
|
||||
log.Error("send error(%v) url(%v)", err, d.c.URLConf.AccountURL+_sendMedal)
|
||||
continue
|
||||
}
|
||||
if rel.Code == int64(ecode.OK.Code()) || rel.Code == _alreadyGet {
|
||||
status = 1
|
||||
if rel.Code == _alreadyGet {
|
||||
status = 2
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SendVipBuyTicket send vipbuy ticket
|
||||
func (d *Dao) SendVipBuyTicket(c context.Context, mid int64, couponID string) (status int64) {
|
||||
var (
|
||||
err error
|
||||
)
|
||||
header := make(map[string]string)
|
||||
header["Content-Type"] = "application/json"
|
||||
|
||||
params := make(map[string]string)
|
||||
params["mid"] = fmt.Sprintf("%v", mid)
|
||||
params["couponId"] = fmt.Sprintf("%v", couponID)
|
||||
|
||||
for i := 0; i < _retry; i++ {
|
||||
repl := new(struct {
|
||||
Code int64 `json:"code"`
|
||||
Message string `json:"message"`
|
||||
})
|
||||
|
||||
if err = d.doSend(c, d.c.URLConf.MallURL, _sendVipbuyTicket, "127.0.0.1", header, params, repl); err != nil {
|
||||
log.Error("send vip buy ticket(%+v) error(%+v)", params, err)
|
||||
continue
|
||||
}
|
||||
if repl.Code == int64(ecode.OK.Code()) || repl.Code == _alreadySendVipbuy {
|
||||
status = 1
|
||||
if repl.Code == _alreadySendVipbuy {
|
||||
status = 2
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SendCleanCache clean cache
|
||||
func (d *Dao) SendCleanCache(c context.Context, hv *model.HandlerVip) (err error) {
|
||||
params := url.Values{}
|
||||
params.Set("mid", strconv.FormatInt(int64(hv.Mid), 10))
|
||||
if err = d.client.Get(c, d.c.VipURI+_cleanCache, "127.0.0.1", params, nil); err != nil {
|
||||
log.Error("SendCleanCache error(%v) url(%v)", err, d.c.VipURI+_cleanCache)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SendBcoin send bcoin http
|
||||
func (d *Dao) SendBcoin(c context.Context, mids []int64, money int32, dueTime time.Time, ip string) (err error) {
|
||||
if len(mids) <= 0 {
|
||||
return
|
||||
}
|
||||
var midStrs []string
|
||||
for _, v := range mids {
|
||||
midStrs = append(midStrs, fmt.Sprintf("%v", v))
|
||||
}
|
||||
params := url.Values{}
|
||||
params.Add("activity_id", fmt.Sprintf("%v", d.c.Property.ActivityID))
|
||||
params.Add("mids", strings.Join(midStrs, ","))
|
||||
params.Add("money", fmt.Sprintf("%v", money*100))
|
||||
params.Add("due_time", dueTime.Time().Format("2006-01-02"))
|
||||
|
||||
res := new(struct {
|
||||
Code int64 `json:"code"`
|
||||
Message string `json:"message"`
|
||||
TS int64 `json:"ts"`
|
||||
Data struct {
|
||||
CouponMoney int64 `json:"coupon_money"`
|
||||
Status int8 `json:"status"`
|
||||
} `json:"data"`
|
||||
})
|
||||
if err = d.client.Post(c, d.c.URLConf.PayCoURL+_addBcoin, ip, params, res); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
if res.Code == int64(_alreadySend) {
|
||||
return
|
||||
}
|
||||
if int(res.Code) != ecode.OK.Code() {
|
||||
err = fmt.Errorf("发放B币失败 message: %s mid: %s resp(%+v)", res.Message, strings.Join(midStrs, ","), res)
|
||||
return
|
||||
}
|
||||
if res.Data.Status != _ok {
|
||||
err = fmt.Errorf("发放B币失败 message: %s mid: %s resp(%+v)", res.Message, strings.Join(midStrs, ","), res)
|
||||
return
|
||||
}
|
||||
log.Info("发放B币成功 mids %v resp(%+v)", mids, res)
|
||||
return
|
||||
}
|
||||
|
||||
//SendAppCleanCache notice app clean cache
|
||||
func (d *Dao) SendAppCleanCache(c context.Context, hv *model.HandlerVip, app *model.VipAppInfo) (err error) {
|
||||
params := url.Values{}
|
||||
params.Set("modifiedAttr", "updateVip")
|
||||
params.Set("mid", fmt.Sprintf("%v", hv.Mid))
|
||||
params.Set("status", fmt.Sprintf("%v", hv.Type))
|
||||
params.Set("buyMonths", fmt.Sprintf("%v", hv.Months))
|
||||
params.Set("days", fmt.Sprintf("%v", hv.Days))
|
||||
if err = d.client.Get(c, app.PurgeURL, "127.0.0.1", params, nil); err != nil {
|
||||
log.Error("SendAppCleanCache error(%v) url(%v) params(%v)", err, app.PurgeURL, params)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SendMultipMsg send multip msg
|
||||
func (d *Dao) SendMultipMsg(c context.Context, mids, content, title, mc string, dataType int) (err error) {
|
||||
params := url.Values{}
|
||||
params.Set("mc", mc)
|
||||
params.Set("title", title)
|
||||
params.Set("context", content)
|
||||
params.Set("data_type", strconv.FormatInt(int64(dataType), 10))
|
||||
params.Set("mid_list", mids)
|
||||
defer func() {
|
||||
log.Info("SendMultipMsg(%v) params(%+v) error(%+v)", d.c.URLConf.MsgURL+_message, params, err)
|
||||
}()
|
||||
if err = d.client.Post(c, d.c.URLConf.MsgURL+_message, "127.0.0.1", params, nil); err != nil {
|
||||
log.Error("SendMultipMsg params(%+v) error(%v)", err, params)
|
||||
return
|
||||
}
|
||||
log.Info("cur send mid(%+v)", mids)
|
||||
return
|
||||
}
|
||||
|
||||
// PayOrder pay order.
|
||||
func (d *Dao) PayOrder(c context.Context, paramsMap map[string]interface{}) (err error) {
|
||||
params := make(map[string]string)
|
||||
for k, v := range paramsMap {
|
||||
params[k] = fmt.Sprintf("%v", v)
|
||||
}
|
||||
|
||||
header := make(map[string]string)
|
||||
header["Content-Type"] = "application/json"
|
||||
success := false
|
||||
for i := 0; i < 3; i++ {
|
||||
repl := new(struct {
|
||||
ErrNo int64 `json:"errno"`
|
||||
Msg string `json:"msg"`
|
||||
Data interface{} `json:"data"`
|
||||
})
|
||||
if err = d.doPaySend(c, d.c.URLConf.PayURL, _payOrder, "127.0.0.1", header, params, repl); err != nil {
|
||||
continue
|
||||
}
|
||||
if repl.ErrNo == 0 {
|
||||
success = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !success {
|
||||
err = fmt.Errorf("下单失败")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *Dao) sortParamsKey(v map[string]string) 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 + "="
|
||||
if buf.Len() > 0 {
|
||||
buf.WriteByte('&')
|
||||
}
|
||||
buf.WriteString(prefix)
|
||||
buf.WriteString(vs)
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
//PaySign pay sign
|
||||
func (d *Dao) PaySign(params map[string]string, token string) (sign string) {
|
||||
|
||||
tmp := d.sortParamsKey(params)
|
||||
|
||||
var b bytes.Buffer
|
||||
b.WriteString(tmp)
|
||||
b.WriteString(fmt.Sprintf("&token=%s", token))
|
||||
log.Info("sign params:%v ", b.String())
|
||||
mh := md5.Sum(b.Bytes())
|
||||
// query
|
||||
var qb bytes.Buffer
|
||||
qb.WriteString(tmp)
|
||||
qb.WriteString("&sign=")
|
||||
qb.WriteString(hex.EncodeToString(mh[:]))
|
||||
sign = hex.EncodeToString(mh[:])
|
||||
log.Info("sign params(%v) and sign(%v)", b.String(), sign)
|
||||
return
|
||||
}
|
||||
|
||||
func (d *Dao) doNomalSend(c context.Context, basePath, path, ip string, header map[string]string, params url.Values, data interface{}) (err error) {
|
||||
var (
|
||||
req *http.Request
|
||||
client = new(http.Client)
|
||||
resp *http.Response
|
||||
bs []byte
|
||||
marshal string
|
||||
)
|
||||
url := basePath + path
|
||||
|
||||
if req, err = d.client.NewRequest(http.MethodPost, url, ip, params); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
|
||||
for k, v := range header {
|
||||
req.Header.Add(k, v)
|
||||
}
|
||||
if resp, err = client.Do(req); err != nil {
|
||||
log.Error("call url:%v params:%v", basePath+path, string(marshal))
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
defer func() {
|
||||
log.Info("call url:%v params:(%v) result:(%+v) header:(%+v)", url, string(marshal), data, header)
|
||||
}()
|
||||
if resp.StatusCode >= http.StatusBadRequest {
|
||||
err = errors.Errorf("incorrect http status:%d host:%s, url:%s", resp.StatusCode, req.URL.Host, req.URL.String())
|
||||
return
|
||||
}
|
||||
if bs, err = readAll(resp.Body, _minRead); err != nil {
|
||||
err = errors.Wrapf(err, "host:%s, url:%s", req.URL.Host, req.URL.String())
|
||||
return
|
||||
}
|
||||
if err = json.Unmarshal(bs, data); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *Dao) doSend(c context.Context, basePath, path, IP string, header map[string]string, params map[string]string, data interface{}) (err error) {
|
||||
var (
|
||||
req *http.Request
|
||||
client = new(http.Client)
|
||||
resp *http.Response
|
||||
bs []byte
|
||||
)
|
||||
url := basePath + path
|
||||
marshal, _ := json.Marshal(params)
|
||||
if req, err = http.NewRequest(http.MethodPost, url, strings.NewReader(string(marshal))); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
for k, v := range header {
|
||||
req.Header.Add(k, v)
|
||||
}
|
||||
if resp, err = client.Do(req); err != nil {
|
||||
log.Error("call url:%v params:%v", basePath+path, string(marshal))
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
defer func() {
|
||||
log.Info("call url:%v params:(%v) result:(%+v) header:(%+v)", url, string(marshal), data, header)
|
||||
}()
|
||||
if resp.StatusCode >= http.StatusBadRequest {
|
||||
err = errors.Errorf("incorrect http status:%d host:%s, url:%s", resp.StatusCode, req.URL.Host, req.URL.String())
|
||||
return
|
||||
}
|
||||
if bs, err = readAll(resp.Body, _minRead); err != nil {
|
||||
err = errors.Wrapf(err, "host:%s, url:%s", req.URL.Host, req.URL.String())
|
||||
return
|
||||
}
|
||||
if err = json.Unmarshal(bs, data); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *Dao) doPaySend(c context.Context, basePath, path, IP string, header map[string]string, params map[string]string, data interface{}) (err error) {
|
||||
sign := d.PaySign(params, d.c.PayConf.Token)
|
||||
params["sign"] = sign
|
||||
return d.doSend(c, basePath, path, IP, header, params, data)
|
||||
}
|
||||
|
||||
func readAll(r io.Reader, capacity int64) (b []byte, err error) {
|
||||
buf := bytes.NewBuffer(make([]byte, 0, capacity))
|
||||
// If the buffer overflows, we will get bytes.ErrTooLarge.
|
||||
// Return that as an error. Any other panic remains.
|
||||
defer func() {
|
||||
e := recover()
|
||||
if e == nil {
|
||||
return
|
||||
}
|
||||
if panicErr, ok := e.(error); ok && panicErr == bytes.ErrTooLarge {
|
||||
err = panicErr
|
||||
} else {
|
||||
panic(e)
|
||||
}
|
||||
}()
|
||||
_, err = buf.ReadFrom(r)
|
||||
return buf.Bytes(), err
|
||||
}
|
||||
|
||||
// SalaryCoupon salary coupon.
|
||||
func (d *Dao) SalaryCoupon(c context.Context, mid int64, couponType int8, count int64, token string) (err error) {
|
||||
params := url.Values{}
|
||||
params.Set("mid", fmt.Sprintf("%d", mid))
|
||||
params.Set("type", fmt.Sprintf("%d", couponType))
|
||||
params.Set("count", fmt.Sprintf("%d", count))
|
||||
params.Set("batch_no", token)
|
||||
var resp struct {
|
||||
Code int64 `json:"code"`
|
||||
}
|
||||
if err = d.client.Post(c, d.c.Property.SalaryCouponURL, "", params, &resp); err != nil {
|
||||
log.Error("message url(%s) error(%v)", d.c.Property.SalaryCouponURL+"?"+params.Encode(), err)
|
||||
return
|
||||
}
|
||||
if resp.Code != 0 {
|
||||
err = fmt.Errorf("POST SalaryCoupon url resp(%v)", resp)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
121
app/job/main/vip/dao/business_test.go
Normal file
121
app/job/main/vip/dao/business_test.go
Normal file
@ -0,0 +1,121 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
xtime "go-common/library/time"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
gock "gopkg.in/h2non/gock.v1"
|
||||
)
|
||||
|
||||
// go test -test.v -test.run TestDaoSalaryCoupon
|
||||
func TestDaoSalaryCoupon(t *testing.T) {
|
||||
convey.Convey("TestDaoSalaryCoupon salary coupon", t, func() {
|
||||
var (
|
||||
c = context.TODO()
|
||||
mid int64 = 123
|
||||
ct int8 = 2
|
||||
count int64 = 2
|
||||
err error
|
||||
)
|
||||
err = d.SalaryCoupon(c, mid, ct, count, "cartoon_1_2018_06")
|
||||
convey.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDao_SendMultipMsg(t *testing.T) {
|
||||
convey.Convey("send multipmsg", t, func() {
|
||||
defer gock.OffAll()
|
||||
httpMock("POST", _message).Reply(200).JSON(`{"code":0,"data":1}`)
|
||||
err := d.SendMultipMsg(context.TODO(), "27515256", "test", "test", "10_1_2", 4)
|
||||
convey.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoPushData(t *testing.T) {
|
||||
pushData := &model.VipPushData{
|
||||
Title: "TEST",
|
||||
PushStartTime: "15:04:05",
|
||||
PushEndTime: "15:04:05",
|
||||
}
|
||||
convey.Convey("PushData", t, func() {
|
||||
defer gock.OffAll()
|
||||
httpMock("POST", _pushData).Reply(200).JSON(`{"code":0,"data":1}`)
|
||||
rel, err := d.PushData(context.TODO(), []int64{7593623}, pushData, "2006-01-02")
|
||||
convey.So(err, convey.ShouldBeNil)
|
||||
convey.So(rel, convey.ShouldNotBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoSendMedal(t *testing.T) {
|
||||
convey.Convey("SendMedal", t, func() {
|
||||
defer gock.OffAll()
|
||||
httpMock("GET", _sendMedal).Reply(200).JSON(`{"code":0,"data":{"status":1}}`)
|
||||
status := d.SendMedal(context.TODO(), 0, 0)
|
||||
convey.So(status, convey.ShouldNotBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoSendCleanCache(t *testing.T) {
|
||||
hv := &model.HandlerVip{Mid: 7593623}
|
||||
convey.Convey("SendCleanCache", t, func() {
|
||||
defer gock.OffAll()
|
||||
httpMock("GET", _cleanCache).Reply(200).JSON(`{"code":0,"data":{"status":1}}`)
|
||||
err := d.SendCleanCache(context.TODO(), hv)
|
||||
convey.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoSendBcoin(t *testing.T) {
|
||||
convey.Convey("SendBcoin", t, func() {
|
||||
defer gock.OffAll()
|
||||
httpMock("POST", _addBcoin).Reply(200).JSON(`{"code":0,"data":{"status":1}}`)
|
||||
err := d.SendBcoin(context.TODO(), []int64{7593623}, 0, xtime.Time(time.Now().Unix()), "")
|
||||
convey.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoSendAppCleanCache(t *testing.T) {
|
||||
var (
|
||||
hv = &model.HandlerVip{Mid: 7593623}
|
||||
app = &model.VipAppInfo{
|
||||
PurgeURL: "http://bilibili.com/test",
|
||||
}
|
||||
)
|
||||
convey.Convey("SendAppCleanCache", t, func() {
|
||||
defer gock.OffAll()
|
||||
httpMock("GET", app.PurgeURL).Reply(200).JSON(`{"code":0}`)
|
||||
err := d.SendAppCleanCache(context.TODO(), hv, app)
|
||||
convey.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaosortParamsKey(t *testing.T) {
|
||||
var v map[string]string
|
||||
convey.Convey("sortParamsKey", t, func() {
|
||||
p1 := d.sortParamsKey(v)
|
||||
convey.So(p1, convey.ShouldNotBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoPaySign(t *testing.T) {
|
||||
var params map[string]string
|
||||
convey.Convey("PaySign", t, func() {
|
||||
sign := d.PaySign(params, "test")
|
||||
convey.So(sign, convey.ShouldNotBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaodoNomalSend(t *testing.T) {
|
||||
var path = "/x/internal/vip/user/info"
|
||||
convey.Convey("doNomalSend", t, func() {
|
||||
defer gock.OffAll()
|
||||
httpMock("POST", path).Reply(200).JSON(`{"code":0}`)
|
||||
err := d.doNomalSend(context.TODO(), "http://api.bilibili.com", path, "", nil, nil, new(model.VipPushResq))
|
||||
convey.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
}
|
46
app/job/main/vip/dao/coupon.go
Normal file
46
app/job/main/vip/dao/coupon.go
Normal file
@ -0,0 +1,46 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
"go-common/library/database/sql"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
_SelSalaryVideoCoupon = "SELECT `id`,`mid`,`coupon_count`,`coupon_type`,`state`,`type`,`ver` FROM `vip_view_coupon_salary_log_%s` WHERE `mid` = ?;"
|
||||
_addSalaryLogSQL = "INSERT INTO `vip_view_coupon_salary_log_%s`(`mid`,`coupon_count`,`coupon_type`,`state`,`type`)VALUES(?,?,?,?,?);"
|
||||
)
|
||||
|
||||
//SalaryVideoCouponList select salary video coupon list.
|
||||
func (d *Dao) SalaryVideoCouponList(c context.Context, mid int64, dv string) (res []*model.VideoCouponSalaryLog, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = d.db.Query(c, fmt.Sprintf(_SelSalaryVideoCoupon, dv), mid); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
r := new(model.VideoCouponSalaryLog)
|
||||
if err = rows.Scan(&r.ID, &r.Mid, &r.CouponCount, &r.CouponType, &r.State, &r.Type, &r.Ver); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
res = nil
|
||||
return
|
||||
}
|
||||
res = append(res, r)
|
||||
}
|
||||
err = rows.Err()
|
||||
return
|
||||
}
|
||||
|
||||
//AddSalaryLog add salary log.
|
||||
func (d *Dao) AddSalaryLog(c context.Context, l *model.VideoCouponSalaryLog, dv string) (err error) {
|
||||
if _, err = d.db.Exec(c, fmt.Sprintf(_addSalaryLogSQL, dv), l.Mid, l.CouponCount, l.CouponType, l.State, l.Type); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
46
app/job/main/vip/dao/coupon_old.go
Normal file
46
app/job/main/vip/dao/coupon_old.go
Normal file
@ -0,0 +1,46 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"go-common/app/job/main/vip/model"
|
||||
"go-common/library/database/sql"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
_selSalaryMaxID = "SELECT IFNULL(MAX(id),0) id FROM vip_view_coupon_salary_log_%s;"
|
||||
_selOldSalaryList = "SELECT `mid`,`coupon_count`,`state`,`type` FROM `vip_view_coupon_salary_log_%s` WHERE id>? AND id <=?;"
|
||||
)
|
||||
|
||||
// SalaryLogMaxID select salary log max id.
|
||||
func (d *Dao) SalaryLogMaxID(c context.Context, dv string) (maxID int, err error) {
|
||||
var row = d.oldDb.QueryRow(c, fmt.Sprintf(_selSalaryMaxID, dv))
|
||||
if err = row.Scan(&maxID); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SelOldSalaryList sel old salary list
|
||||
func (d *Dao) SelOldSalaryList(c context.Context, id, endID int, dv string) (res []*model.OldSalaryLog, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = d.oldDb.Query(c, fmt.Sprintf(_selOldSalaryList, dv), id, endID); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
r := new(model.OldSalaryLog)
|
||||
if err = rows.Scan(&r.Mid, &r.CouponCount, &r.State, &r.Type); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
res = nil
|
||||
return
|
||||
}
|
||||
res = append(res, r)
|
||||
}
|
||||
err = rows.Err()
|
||||
return
|
||||
}
|
41
app/job/main/vip/dao/coupon_old_test.go
Normal file
41
app/job/main/vip/dao/coupon_old_test.go
Normal file
@ -0,0 +1,41 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestDaoSalaryLogMaxID(t *testing.T) {
|
||||
convey.Convey("SalaryLogMaxID", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
dv = "2018_09"
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
maxID, err := d.SalaryLogMaxID(c, dv)
|
||||
ctx.Convey("Then err should be nil.maxID should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(maxID, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoSelOldSalaryList(t *testing.T) {
|
||||
convey.Convey("SelOldSalaryList", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
id = int(0)
|
||||
endID = int(0)
|
||||
dv = "2018_09"
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.SelOldSalaryList(c, id, endID, dv)
|
||||
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
44
app/job/main/vip/dao/coupon_test.go
Normal file
44
app/job/main/vip/dao/coupon_test.go
Normal file
@ -0,0 +1,44 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"go-common/app/job/main/vip/model"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestDaoSalaryVideoCouponList(t *testing.T) {
|
||||
convey.Convey("SalaryVideoCouponList", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(0)
|
||||
dv = "2018_09"
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.SalaryVideoCouponList(c, mid, dv)
|
||||
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoAddSalaryLog(t *testing.T) {
|
||||
convey.Convey("AddSalaryLog", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
l = &model.VideoCouponSalaryLog{
|
||||
Mid: time.Now().Unix(),
|
||||
}
|
||||
dv = "2018_09"
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
err := d.AddSalaryLog(c, l, dv)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
77
app/job/main/vip/dao/dao.go
Normal file
77
app/job/main/vip/dao/dao.go
Normal file
@ -0,0 +1,77 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"go-common/app/job/main/vip/conf"
|
||||
"go-common/library/cache/memcache"
|
||||
"go-common/library/cache/redis"
|
||||
"go-common/library/database/sql"
|
||||
bm "go-common/library/net/http/blademaster"
|
||||
"go-common/library/stat/prom"
|
||||
)
|
||||
|
||||
// Dao struct info of Dao.
|
||||
type Dao struct {
|
||||
// mysql
|
||||
db *sql.DB
|
||||
oldDb *sql.DB
|
||||
// http
|
||||
client *bm.Client
|
||||
// conf
|
||||
c *conf.Config
|
||||
// memcache
|
||||
mc *memcache.Pool
|
||||
mcExpire int32
|
||||
//redis pool
|
||||
redis *redis.Pool
|
||||
redisExpire int32
|
||||
errProm *prom.Prom
|
||||
frozenExpire int32
|
||||
}
|
||||
|
||||
// New new a Dao and return.
|
||||
func New(c *conf.Config) (d *Dao) {
|
||||
d = &Dao{
|
||||
// conf
|
||||
c: c,
|
||||
// mc
|
||||
mc: memcache.NewPool(c.Memcache.Config),
|
||||
mcExpire: int32(time.Duration(c.Memcache.Expire) / time.Second),
|
||||
// redis
|
||||
redis: redis.NewPool(c.Redis.Config),
|
||||
redisExpire: int32(time.Duration(c.Redis.Expire) / time.Second),
|
||||
// db
|
||||
db: sql.NewMySQL(c.NewMysql),
|
||||
oldDb: sql.NewMySQL(c.OldMysql),
|
||||
// http client
|
||||
client: bm.NewClient(c.HTTPClient),
|
||||
errProm: prom.BusinessErrCount,
|
||||
frozenExpire: int32(time.Duration(c.Property.FrozenExpire) / time.Second),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Ping ping health of db.
|
||||
func (d *Dao) Ping(c context.Context) (err error) {
|
||||
return d.db.Ping(c)
|
||||
}
|
||||
|
||||
// Close close connections of mc, redis, db.
|
||||
func (d *Dao) Close() {
|
||||
if d.db != nil {
|
||||
d.db.Close()
|
||||
}
|
||||
if d.redis != nil {
|
||||
d.redis.Close()
|
||||
}
|
||||
}
|
||||
|
||||
//StartTx start tx
|
||||
func (d *Dao) StartTx(c context.Context) (tx *sql.Tx, err error) {
|
||||
if d.db != nil {
|
||||
tx, err = d.db.Begin(c)
|
||||
}
|
||||
return
|
||||
}
|
45
app/job/main/vip/dao/dao_test.go
Normal file
45
app/job/main/vip/dao/dao_test.go
Normal file
@ -0,0 +1,45 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"go-common/app/job/main/vip/conf"
|
||||
|
||||
gock "gopkg.in/h2non/gock.v1"
|
||||
)
|
||||
|
||||
var (
|
||||
d *Dao
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
if os.Getenv("DEPLOY_ENV") != "" {
|
||||
flag.Set("app_id", "main.account.vip-job")
|
||||
flag.Set("conf_token", "9a445028722910ccf99d501d56c6aea0")
|
||||
flag.Set("tree_id", "14826")
|
||||
flag.Set("conf_version", "docker-1")
|
||||
flag.Set("deploy_env", "uat")
|
||||
flag.Set("conf_host", "config.bilibili.co")
|
||||
flag.Set("conf_path", "/tmp")
|
||||
flag.Set("region", "sh")
|
||||
flag.Set("zone", "sh001")
|
||||
} else {
|
||||
flag.Set("conf", "../cmd/vip-job-test.toml")
|
||||
}
|
||||
flag.Parse()
|
||||
if err := conf.Init(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
d = New(conf.Conf)
|
||||
d.client.SetTransport(gock.DefaultTransport)
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
func httpMock(method, url string) *gock.Request {
|
||||
r := gock.New(url)
|
||||
r.Method = strings.ToUpper(method)
|
||||
return r
|
||||
}
|
35
app/job/main/vip/dao/http.go
Normal file
35
app/job/main/vip/dao/http.go
Normal file
@ -0,0 +1,35 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
"go-common/library/log"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
_retryAutoRenew = "/x/internal/autorenew/retry"
|
||||
)
|
||||
|
||||
//AutoRenewPay auto renew pay.
|
||||
func (d *Dao) AutoRenewPay(c context.Context, mid int64) (res *model.CommonResq, err error) {
|
||||
res = new(model.CommonResq)
|
||||
val := url.Values{}
|
||||
val.Add("mid", fmt.Sprintf("%d", mid))
|
||||
url := d.c.VipURI + _retryAutoRenew
|
||||
if err = d.client.Post(c, url, "", val, res); err != nil {
|
||||
log.Error("reques fail url %v params:%+v result:%+v, err:%+v", url, val, res, err)
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
if res.Code != 0 {
|
||||
log.Error("reques fail url %v params:%+v result:%+v, err:%+v", url, val, res, err)
|
||||
return
|
||||
}
|
||||
log.Info("reques success url %v params:%+v result:%+v", url, val, res)
|
||||
return
|
||||
}
|
16
app/job/main/vip/dao/http_test.go
Normal file
16
app/job/main/vip/dao/http_test.go
Normal file
@ -0,0 +1,16 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestDaoAutoRenewPay(t *testing.T) {
|
||||
Convey("TestDaoAutoRenewPay", t, func() {
|
||||
res, err := d.AutoRenewPay(context.Background(), 1234)
|
||||
t.Logf("%+v,%+v", res, err)
|
||||
So(res, ShouldNotBeNil)
|
||||
})
|
||||
}
|
213
app/job/main/vip/dao/memcache.go
Normal file
213
app/job/main/vip/dao/memcache.go
Normal file
@ -0,0 +1,213 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
"go-common/library/cache/memcache"
|
||||
"go-common/library/log"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
_vipInfo = "vo:%d"
|
||||
_vipMadel = "madel:%d"
|
||||
_vipbuy = "vipbuy:%d"
|
||||
_vipfrozen = "vipfrozen:%d"
|
||||
|
||||
madelExpired = 3600 * 24 * 15
|
||||
|
||||
vipbuyExpired = 3600 * 24 * 8
|
||||
|
||||
vipFrozenExpired = 60 * 30
|
||||
|
||||
vipFrozenFlag = 1
|
||||
|
||||
_prefixInfo = "i:"
|
||||
)
|
||||
|
||||
func vipfrozen(mid int64) string {
|
||||
return fmt.Sprintf(_vipfrozen, mid)
|
||||
}
|
||||
|
||||
func vipbuy(mid int64) string {
|
||||
return fmt.Sprintf(_vipbuy, mid)
|
||||
}
|
||||
func vipInfoKey(mid int64) string {
|
||||
return fmt.Sprintf(_vipInfo, mid)
|
||||
}
|
||||
|
||||
func vipMadel(mid int64) string {
|
||||
return fmt.Sprintf(_vipMadel, mid)
|
||||
}
|
||||
|
||||
func keyInfo(mid int64) string {
|
||||
return _prefixInfo + strconv.FormatInt(mid, 10)
|
||||
}
|
||||
|
||||
//SetVipFrozen .
|
||||
func (d *Dao) SetVipFrozen(c context.Context, mid int64) (err error) {
|
||||
var (
|
||||
key = vipfrozen(mid)
|
||||
)
|
||||
conn := d.mc.Get(c)
|
||||
defer conn.Close()
|
||||
item := &memcache.Item{Key: key, Object: vipFrozenFlag, Expiration: vipFrozenExpired, Flags: memcache.FlagJSON}
|
||||
if err = conn.Set(item); err != nil {
|
||||
err = errors.Wrapf(err, "d.setVipFrozen")
|
||||
d.errProm.Incr("vip frozen_mc")
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//DelVipFrozen .
|
||||
func (d *Dao) DelVipFrozen(c context.Context, mid int64) (err error) {
|
||||
return d.delCache(c, vipfrozen(mid))
|
||||
}
|
||||
|
||||
//SetVipMadelCache set vip madel cache
|
||||
func (d *Dao) SetVipMadelCache(c context.Context, mid int64, val int64) (err error) {
|
||||
var (
|
||||
key = vipMadel(mid)
|
||||
)
|
||||
conn := d.mc.Get(c)
|
||||
defer conn.Close()
|
||||
item := &memcache.Item{Key: key, Object: val, Expiration: madelExpired, Flags: memcache.FlagJSON}
|
||||
if err = conn.Set(item); err != nil {
|
||||
err = errors.Wrap(err, "d.SetVipMadelCache")
|
||||
d.errProm.Incr("vipmadel_mc")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//GetVipBuyCache get vipbuy cache by key
|
||||
func (d *Dao) GetVipBuyCache(c context.Context, mid int64) (val int64, err error) {
|
||||
var (
|
||||
key = vipbuy(mid)
|
||||
item *memcache.Item
|
||||
)
|
||||
conn := d.mc.Get(c)
|
||||
defer conn.Close()
|
||||
if item, err = conn.Get(key); err != nil {
|
||||
if err == memcache.ErrNotFound {
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
err = errors.Wrapf(err, "conn.Get(%s)", key)
|
||||
d.errProm.Incr("vipinfo_mc")
|
||||
return
|
||||
}
|
||||
if err = conn.Scan(item, &val); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("vipMadelCache_mc")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SetVipBuyCache set vipbuy cache
|
||||
func (d *Dao) SetVipBuyCache(c context.Context, mid int64, val int64) (err error) {
|
||||
var (
|
||||
key = vipbuy(mid)
|
||||
)
|
||||
conn := d.mc.Get(c)
|
||||
defer conn.Close()
|
||||
item := &memcache.Item{Key: key, Object: val, Expiration: vipbuyExpired, Flags: memcache.FlagJSON}
|
||||
if err = conn.Set(item); err != nil {
|
||||
err = errors.Wrap(err, "d.SetVipBuyCache")
|
||||
d.errProm.Incr("vipbuy_mc")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//GetVipMadelCache get madel info by mid
|
||||
func (d *Dao) GetVipMadelCache(c context.Context, mid int64) (val int64, err error) {
|
||||
var (
|
||||
key = vipMadel(mid)
|
||||
item *memcache.Item
|
||||
)
|
||||
conn := d.mc.Get(c)
|
||||
defer conn.Close()
|
||||
if item, err = conn.Get(key); err != nil {
|
||||
if err == memcache.ErrNotFound {
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
err = errors.Wrapf(err, "conn.Get(%s)", key)
|
||||
d.errProm.Incr("vipinfo_mc")
|
||||
return
|
||||
}
|
||||
if err = conn.Scan(item, &val); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("vipMadelCache_mc")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// SetVipInfoCache set vip info cache.
|
||||
func (d *Dao) SetVipInfoCache(c context.Context, mid int64, v *model.VipInfo) (err error) {
|
||||
var (
|
||||
key = vipInfoKey(mid)
|
||||
)
|
||||
conn := d.mc.Get(c)
|
||||
defer conn.Close()
|
||||
item := &memcache.Item{Key: key, Object: v, Expiration: d.mcExpire, Flags: memcache.FlagProtobuf}
|
||||
if err = conn.Set(item); err != nil {
|
||||
err = errors.Wrap(err, "d.SetVipInfo")
|
||||
d.errProm.Incr("vipinfo_mc")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DelVipInfoCache del vip info cache.
|
||||
func (d *Dao) DelVipInfoCache(c context.Context, mid int64) (err error) {
|
||||
err = d.delCache(c, vipInfoKey(mid))
|
||||
return
|
||||
}
|
||||
|
||||
// DelInfoCache del vip info cache.
|
||||
func (d *Dao) DelInfoCache(c context.Context, mid int64) (err error) {
|
||||
if err = d.delCache(c, keyInfo(mid)); err != nil {
|
||||
log.Error("del vipinfo cache(mid:%d) error(%+v)", mid, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *Dao) delCache(c context.Context, key string) (err error) {
|
||||
conn := d.mc.Get(c)
|
||||
defer conn.Close()
|
||||
if err = conn.Delete(key); err != nil {
|
||||
if err == memcache.ErrNotFound {
|
||||
err = nil
|
||||
} else {
|
||||
err = errors.Wrapf(err, "conn.Delete(%s)", key)
|
||||
d.errProm.Incr("del_mc")
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
// AddTransferLock add lock.
|
||||
func (d *Dao) AddTransferLock(c context.Context, key string) (succeed bool) {
|
||||
var (
|
||||
conn = d.mc.Get(c)
|
||||
)
|
||||
defer conn.Close()
|
||||
item := &memcache.Item{
|
||||
Key: key,
|
||||
Value: []byte("0"),
|
||||
Expiration: 3600,
|
||||
}
|
||||
if err := conn.Add(item); err != nil {
|
||||
if err != memcache.ErrNotStored {
|
||||
log.Error("conn.Add(%s) error(%v)", key, err)
|
||||
}
|
||||
} else {
|
||||
succeed = true
|
||||
}
|
||||
return
|
||||
}
|
74
app/job/main/vip/dao/memcache_test.go
Normal file
74
app/job/main/vip/dao/memcache_test.go
Normal file
@ -0,0 +1,74 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"context"
|
||||
"go-common/app/job/main/vip/model"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestDao_DelVipInfoCache(t *testing.T) {
|
||||
Convey("should return true where err != nil and res not empty", t, func() {
|
||||
err := d.DelVipInfoCache(context.TODO(), 1234)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDao_SetVipInfoCache(t *testing.T) {
|
||||
Convey("set vip info cache", t, func() {
|
||||
err := d.SetVipInfoCache(context.TODO(), 1234, &model.VipInfo{Mid: 1234, VipType: model.Vip, VipStatus: model.VipStatusNotOverTime})
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
func TestDao_AddPayOrderLog(t *testing.T) {
|
||||
Convey("add pay order log", t, func() {
|
||||
_, err := d.AddPayOrderLog(context.TODO(), &model.VipPayOrderLog{Mid: 1234, Status: 1, OrderNo: "12891723894189"})
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDao_GetVipMadelCache(t *testing.T) {
|
||||
Convey("get vip madel cache ", t, func() {
|
||||
val, err := d.GetVipMadelCache(context.TODO(), 2089801)
|
||||
t.Logf("val %v \n", val)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDao_SetVipMadelCache(t *testing.T) {
|
||||
Convey("set vip madel", t, func() {
|
||||
err := d.SetVipMadelCache(context.TODO(), 2089801, 1)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDao_SetVipFrozen(t *testing.T) {
|
||||
Convey("set vip frozen", t, func() {
|
||||
err := d.SetVipFrozen(context.TODO(), 2089809)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDao_GetVipBuyCache(t *testing.T) {
|
||||
var val int64 = 1
|
||||
Convey("SetVipBuyCache", t, func() {
|
||||
err := d.SetVipBuyCache(context.TODO(), 2089809, val)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
Convey("GetVipBuyCache", t, func() {
|
||||
res, err := d.GetVipBuyCache(context.TODO(), 2089809)
|
||||
So(err, ShouldBeNil)
|
||||
So(val, ShouldEqual, res)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDao_AddTransferLock(t *testing.T) {
|
||||
Convey("AddTransferLock", t, func() {
|
||||
err := d.delCache(context.TODO(), "2089809")
|
||||
So(err, ShouldBeNil)
|
||||
bool := d.AddTransferLock(context.TODO(), "2089809")
|
||||
So(bool, ShouldBeTrue)
|
||||
})
|
||||
}
|
310
app/job/main/vip/dao/mysql.go
Normal file
310
app/job/main/vip/dao/mysql.go
Normal file
@ -0,0 +1,310 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
"go-common/library/database/sql"
|
||||
"go-common/library/log"
|
||||
"go-common/library/xstr"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
_selAppInfo = "SELECT id,name,app_key,purge_url from vip_app_info WHERE `type` = 1"
|
||||
|
||||
//bcoin sql
|
||||
_selBcoinSalarySQL = "SELECT id,mid,status,give_now_status,payday,amount,memo FROM vip_user_bcoin_salary WHERE 1=1"
|
||||
_selBcoinSalaryDataSQL = "SELECT id,mid,status,give_now_status,payday,amount,memo FROM vip_user_bcoin_salary WHERE id>? AND id<=?"
|
||||
_selBcoinSalaryByMidSQL = "SELECT id,mid,status,give_now_status,payday,amount,memo FROM vip_user_bcoin_salary WHERE mid IN (%v)"
|
||||
_selOldBcoinSalaryByMidSQL = "SELECT id,mid,IFNULL(status,0),IFNULL(give_now_status,0),month,IFNULL(amount,0),IFNULL(memo,'') FROM vip_bcoin_salary WHERE mid IN (%v)"
|
||||
_selOldBcoinSalarySQL = "SELECT id,mid,IFNULL(status,0),IFNULL(give_now_status,0),month,IFNULL(amount,0),IFNULL(memo,'') FROM vip_bcoin_salary WHERE id>? AND id<=?"
|
||||
_addBcoinSalarySQL = "INSERT INTO vip_user_bcoin_salary(mid,status,give_now_status,payday,amount,memo) VALUES(?,?,?,?,?,?)"
|
||||
_updateBcoinSalarySQL = "UPDATE vip_user_bcoin_salary set status = ? WHERE mid = ? AND payday = ?"
|
||||
_updateBcoinSalaryBatchSQL = "UPDATE vip_user_bcoin_salary set status = ? WHERE id in (?)"
|
||||
_batchAddBcoinSalarySQL = "INSERT INTO vip_user_bcoin_salary(mid,status,give_now_status,payday,amount,memo) VALUES "
|
||||
_selBcoinMaxIDSQL = "SELECT IFNULL(MAX(id),0) FROM vip_user_bcoin_salary"
|
||||
_selOldBcoinMaxIDSQL = "SELECT IFNULL(MAX(id),0) FROM vip_bcoin_salary"
|
||||
_delBcoinSalarySQL = "DELETE FROM vip_user_bcoin_salary WHERE mid = ? AND payday = ?"
|
||||
|
||||
_getAbleCodeSQL = "SELECT code FROM vip_resource_code WHERE batch_code_id = ? AND status = 1 AND relation_id = '' LIMIT 1"
|
||||
_selBatchCodeSQL = "SELECT id,business_id,pool_id,status,type,batch_name,reason,unit,count,surplus_count,price,start_time,end_time FROM vip_resource_batch_code WHERE id = ?"
|
||||
|
||||
_updateCodeRelationIDSQL = "UPDATE vip_resource_code SET relation_id=?,bmid=? WHERE code=?"
|
||||
|
||||
_selEffectiveVipList = "SELECT id,mid,vip_type,vip_status,vip_overdue_time,annual_vip_overdue_time FROM vip_user_info WHERE id>? AND id <=? "
|
||||
|
||||
//push
|
||||
_selPushDataSQL = "SELECT id,disable_type,group_name,title,content,push_total_count,pushed_count,progress_status,`status`,platform,link_type,link_url,error_code,expired_day_start,expired_day_end,effect_start_date,effect_end_date,push_start_time,push_end_time FROM vip_push_data WHERE effect_start_date <= ? AND effect_end_date >= ? "
|
||||
_updatePushDataSQL = "UPDATE vip_push_data SET progress_status=?,status=?, pushed_count=?,error_code=?,task_id=? WHERE id=?"
|
||||
)
|
||||
|
||||
//SelOldBcoinMaxID sel oldbcoin maxID
|
||||
func (d *Dao) SelOldBcoinMaxID(c context.Context) (maxID int64, err error) {
|
||||
row := d.oldDb.QueryRow(c, _selOldBcoinMaxIDSQL)
|
||||
if err = row.Scan(&maxID); err != nil {
|
||||
if err == sql.ErrStmtNil {
|
||||
err = nil
|
||||
maxID = 0
|
||||
return
|
||||
}
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("db_scan")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SelBcoinMaxID sel bcoin maxID
|
||||
func (d *Dao) SelBcoinMaxID(c context.Context) (maxID int64, err error) {
|
||||
row := d.db.QueryRow(c, _selBcoinMaxIDSQL)
|
||||
if err = row.Scan(&maxID); err != nil {
|
||||
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("db_scan")
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SelBcoinSalaryData sel bcoinSalary data
|
||||
func (d *Dao) SelBcoinSalaryData(c context.Context, startID int64, endID int64) (res []*model.VipBcoinSalary, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = d.db.Query(c, _selBcoinSalaryDataSQL, startID, endID); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("db_query")
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
r := new(model.VipBcoinSalary)
|
||||
if err = rows.Scan(&r.ID, &r.Mid, &r.Status, &r.GiveNowStatus, &r.Payday, &r.Amount, &r.Memo); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("db_scan")
|
||||
return
|
||||
}
|
||||
res = append(res, r)
|
||||
}
|
||||
err = rows.Err()
|
||||
return
|
||||
}
|
||||
|
||||
//SelBcoinSalaryDataMaps sel bcoin salary data convert map
|
||||
func (d *Dao) SelBcoinSalaryDataMaps(c context.Context, mids []int64) (res map[int64][]*model.VipBcoinSalary, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = d.db.Query(c, fmt.Sprintf(_selBcoinSalaryByMidSQL, xstr.JoinInts(mids))); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("db_query")
|
||||
return
|
||||
}
|
||||
res = make(map[int64][]*model.VipBcoinSalary)
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
r := new(model.VipBcoinSalary)
|
||||
if err = rows.Scan(&r.ID, &r.Mid, &r.Status, &r.GiveNowStatus, &r.Payday, &r.Amount, &r.Memo); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("db_scan")
|
||||
return
|
||||
}
|
||||
salaries := res[r.Mid]
|
||||
salaries = append(salaries, r)
|
||||
res[r.Mid] = salaries
|
||||
}
|
||||
err = rows.Err()
|
||||
return
|
||||
}
|
||||
|
||||
//SelOldBcoinSalaryDataMaps sel old bcoin salary data convert map
|
||||
func (d *Dao) SelOldBcoinSalaryDataMaps(c context.Context, mids []int64) (res map[int64][]*model.VipBcoinSalary, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = d.oldDb.Query(c, fmt.Sprintf(_selOldBcoinSalaryByMidSQL, xstr.JoinInts(mids))); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("db_query")
|
||||
return
|
||||
}
|
||||
res = make(map[int64][]*model.VipBcoinSalary)
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
r := new(model.VipBcoinSalary)
|
||||
if err = rows.Scan(&r.ID, &r.Mid, &r.Status, &r.GiveNowStatus, &r.Payday, &r.Amount, &r.Memo); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("db_scan")
|
||||
return
|
||||
}
|
||||
salaries := res[r.Mid]
|
||||
salaries = append(salaries, r)
|
||||
res[r.Mid] = salaries
|
||||
}
|
||||
err = rows.Err()
|
||||
return
|
||||
}
|
||||
|
||||
//SelBcoinSalary sel bcoin salary data by query
|
||||
func (d *Dao) SelBcoinSalary(c context.Context, arg *model.QueryBcoinSalary) (res []*model.VipBcoinSalary, err error) {
|
||||
var rows *sql.Rows
|
||||
sqlStr := ""
|
||||
if arg.StartID >= 0 {
|
||||
sqlStr += fmt.Sprintf(" AND id > %v ", arg.StartID)
|
||||
}
|
||||
if arg.EndID >= 0 {
|
||||
sqlStr += fmt.Sprintf(" AND id <= %v ", arg.EndID)
|
||||
}
|
||||
if arg.StartMonth > 0 {
|
||||
sqlStr += fmt.Sprintf(" AND payday>= '%v' ", arg.StartMonth.Time().Format("2006-01-02"))
|
||||
}
|
||||
if arg.EndMonth > 0 {
|
||||
sqlStr += fmt.Sprintf(" AND payday <= '%v' ", arg.EndMonth.Time().Format("2006-01-02"))
|
||||
}
|
||||
if arg.GiveNowStatus > -1 {
|
||||
sqlStr += fmt.Sprintf(" AND give_now_status = %v ", arg.GiveNowStatus)
|
||||
}
|
||||
if arg.Status > -1 {
|
||||
sqlStr += fmt.Sprintf(" AND status = %v ", arg.Status)
|
||||
}
|
||||
if rows, err = d.db.Query(c, _selBcoinSalarySQL+sqlStr); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("db_query")
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
r := new(model.VipBcoinSalary)
|
||||
if err = rows.Scan(&r.ID, &r.Mid, &r.Status, &r.GiveNowStatus, &r.Payday, &r.Amount, &r.Memo); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("db_scan")
|
||||
}
|
||||
res = append(res, r)
|
||||
}
|
||||
err = rows.Err()
|
||||
return
|
||||
}
|
||||
|
||||
//SelOldBcoinSalary sel old bcoin salary
|
||||
func (d *Dao) SelOldBcoinSalary(c context.Context, startID, endID int64) (res []*model.VipBcoinSalary, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = d.oldDb.Query(c, _selOldBcoinSalarySQL, startID, endID); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("db_query")
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
r := new(model.VipBcoinSalary)
|
||||
if err = rows.Scan(&r.ID, &r.Mid, &r.Status, &r.GiveNowStatus, &r.Payday, &r.Amount, &r.Memo); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("db_scan")
|
||||
}
|
||||
res = append(res, r)
|
||||
}
|
||||
err = rows.Err()
|
||||
return
|
||||
}
|
||||
|
||||
//AddBcoinSalary add bcoin salary
|
||||
func (d *Dao) AddBcoinSalary(c context.Context, arg *model.VipBcoinSalaryMsg) (err error) {
|
||||
if _, err = d.db.Exec(c, _addBcoinSalarySQL, &arg.Mid, &arg.Status, &arg.GiveNowStatus, &arg.Payday, &arg.Amount, &arg.Memo); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("db_exec")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//UpdateBcoinSalary update bcoin salary
|
||||
func (d *Dao) UpdateBcoinSalary(c context.Context, payday string, mid int64, status int8) (err error) {
|
||||
if _, err = d.db.Exec(c, _updateBcoinSalarySQL, status, mid, payday); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("db_exec")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//DelBcoinSalary del bcoin salary
|
||||
func (d *Dao) DelBcoinSalary(c context.Context, payday string, mid int64) (err error) {
|
||||
if _, err = d.db.Exec(c, _delBcoinSalarySQL, mid, payday); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//UpdateBcoinSalaryBatch update bcoin salary batch
|
||||
func (d *Dao) UpdateBcoinSalaryBatch(c context.Context, ids []int64, status int8) (err error) {
|
||||
if len(ids) <= 0 {
|
||||
return
|
||||
}
|
||||
sqlStr := ""
|
||||
for _, v := range ids {
|
||||
sqlStr += "," + strconv.FormatInt(v, 10)
|
||||
}
|
||||
if _, err = d.db.Exec(c, _updateBcoinSalaryBatchSQL, status, sqlStr[1:]); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//BatchAddBcoinSalary batch add bcoin salary data
|
||||
func (d *Dao) BatchAddBcoinSalary(bcoins []*model.VipBcoinSalary) (err error) {
|
||||
var values []string
|
||||
if len(bcoins) <= 0 {
|
||||
return
|
||||
}
|
||||
for _, v := range bcoins {
|
||||
str := fmt.Sprintf("('%v','%v','%v','%v','%v','%v')", v.Mid, v.Status, v.GiveNowStatus, v.Payday.Time().Format("2006-01-02"), v.Amount, v.Memo)
|
||||
values = append(values, str)
|
||||
}
|
||||
valueStr := strings.Join(values, ",")
|
||||
|
||||
if _, err = d.db.Exec(context.TODO(), _batchAddBcoinSalarySQL+valueStr); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("db_exec")
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SelAppInfo sel vip_app_info data
|
||||
func (d *Dao) SelAppInfo(c context.Context) (res []*model.VipAppInfo, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = d.oldDb.Query(c, _selAppInfo); err != nil {
|
||||
log.Error("SelAppInfo db.query() error(%v)", err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
r := new(model.VipAppInfo)
|
||||
if err = rows.Scan(&r.ID, &r.Name, &r.AppKey, &r.PurgeURL); err != nil {
|
||||
log.Error("row.scan() error(%v)", err)
|
||||
res = nil
|
||||
return
|
||||
}
|
||||
res = append(res, r)
|
||||
|
||||
}
|
||||
err = rows.Err()
|
||||
return
|
||||
}
|
||||
|
||||
//SelEffectiveVipList sel effective vip data
|
||||
func (d *Dao) SelEffectiveVipList(c context.Context, id, endID int) (res []*model.VipUserInfo, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = d.oldDb.Query(c, _selEffectiveVipList, id, endID); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
r := new(model.VipUserInfo)
|
||||
if err = rows.Scan(&r.ID, &r.Mid, &r.Type, &r.Status, &r.OverdueTime, &r.AnnualVipOverdueTime); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
res = nil
|
||||
return
|
||||
}
|
||||
res = append(res, r)
|
||||
}
|
||||
err = rows.Err()
|
||||
return
|
||||
}
|
162
app/job/main/vip/dao/mysql_test.go
Normal file
162
app/job/main/vip/dao/mysql_test.go
Normal file
@ -0,0 +1,162 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func Test_SelVipList(t *testing.T) {
|
||||
var (
|
||||
res []*model.VipUserInfo
|
||||
err error
|
||||
id = 0
|
||||
mID = 10000
|
||||
ot = time.Now().Format("2006-01-02")
|
||||
)
|
||||
Convey("should return true where err != nil and res not empty", t, func() {
|
||||
res, err = d.SelVipList(context.TODO(), id, mID, ot)
|
||||
So(err, ShouldBeNil)
|
||||
So(res, ShouldNotBeEmpty)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_UpdateVipUserInfo(t *testing.T) {
|
||||
vuf := new(model.VipUserInfo)
|
||||
vuf.ID = 1
|
||||
vuf.Type = 1
|
||||
vuf.Status = 0
|
||||
Convey("should return true where err == nil", t, func() {
|
||||
tx, err := d.StartTx(context.TODO())
|
||||
So(err, ShouldBeNil)
|
||||
_, err = d.UpdateVipUserInfo(tx, vuf)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_SelAppInfo(t *testing.T) {
|
||||
Convey("should return true where err == nil and res not empty", t, func() {
|
||||
res, err := d.SelAppInfo(context.TODO())
|
||||
So(err, ShouldBeNil)
|
||||
So(res, ShouldNotBeEmpty)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func Test_SelMaxID(t *testing.T) {
|
||||
Convey("should return true where err == nil ", t, func() {
|
||||
r, err := d.SelMaxID(context.TODO())
|
||||
So(r, ShouldBeGreaterThan, 100)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDao_SelOrderMaxID(t *testing.T) {
|
||||
Convey("sel order max id", t, func() {
|
||||
_, err := d.SelOrderMaxID(context.TODO())
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
func TestDao_SelOldBcoinMaxID(t *testing.T) {
|
||||
Convey("sel old bcoin Max id", t, func() {
|
||||
_, err := d.SelOldBcoinMaxID(context.TODO())
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDao_SelBcoinMaxID(t *testing.T) {
|
||||
Convey("sel bcoin maxID", t, func() {
|
||||
_, err := d.SelBcoinMaxID(context.TODO())
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
func TestDao_SelChangeHistoryMaxID(t *testing.T) {
|
||||
Convey("sel change hsitory max id", t, func() {
|
||||
_, err := d.SelChangeHistoryMaxID(context.TODO())
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDao_SelOldOrderMaxID(t *testing.T) {
|
||||
Convey("sel old Order maxID", t, func() {
|
||||
_, err := d.SelOldOrderMaxID(context.TODO())
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDao_VipStatus(t *testing.T) {
|
||||
Convey("vip status", t, func() {
|
||||
_, err := d.VipStatus(context.TODO(), 1)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDao_SelOldBcoinSalaryDataMaps(t *testing.T) {
|
||||
Convey("vip SelOldBcoinSalaryDataMaps", t, func() {
|
||||
_, err := d.SelOldBcoinSalaryDataMaps(context.TODO(), []int64{7593623})
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDao_SelBcoinSalary(t *testing.T) {
|
||||
arg := &model.QueryBcoinSalary{
|
||||
StartID: 1,
|
||||
EndID: 1,
|
||||
Status: 1,
|
||||
}
|
||||
Convey("vip SelBcoinSalary", t, func() {
|
||||
_, err := d.SelBcoinSalary(context.TODO(), arg)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
func TestDao_SelOldBcoinSalary(t *testing.T) {
|
||||
arg := &model.VipBcoinSalaryMsg{
|
||||
Mid: 7593623,
|
||||
Status: 1,
|
||||
GiveNowStatus: 1,
|
||||
Payday: "10",
|
||||
Amount: 1,
|
||||
Memo: "memo",
|
||||
}
|
||||
Convey("vip AddBcoinSalary", t, func() {
|
||||
err := d.AddBcoinSalary(context.TODO(), arg)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
Convey("vip UpdateBcoinSalary", t, func() {
|
||||
err := d.UpdateBcoinSalary(context.TODO(), "10", 7593623, 2)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
Convey("del bcoin salary", t, func() {
|
||||
err := d.DelBcoinSalary(context.TODO(), "10", 7593623)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
Convey("vip SelOldBcoinSalary", t, func() {
|
||||
_, err := d.SelOldBcoinSalary(context.TODO(), 1, 1)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDao_SelBcoinSalaryData(t *testing.T) {
|
||||
Convey("SelBcoinSalaryData", t, func() {
|
||||
_, err := d.SelBcoinSalaryData(context.TODO(), 1, 1)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDao_SelBcoinSalaryDataMaps(t *testing.T) {
|
||||
Convey("SelBcoinSalaryDataMaps", t, func() {
|
||||
_, err := d.SelBcoinSalaryDataMaps(context.TODO(), []int64{1})
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDao_SelEffectiveVipList(t *testing.T) {
|
||||
Convey("SelEffectiveVipList", t, func() {
|
||||
_, err := d.SelEffectiveVipList(context.TODO(), 1, 1)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
37
app/job/main/vip/dao/oldvip.go
Normal file
37
app/job/main/vip/dao/oldvip.go
Normal file
@ -0,0 +1,37 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"go-common/library/ecode"
|
||||
"go-common/library/log"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
const (
|
||||
_frozenChange = "/internal/v1/user/frozenChange"
|
||||
)
|
||||
|
||||
// OldFrozenChange .
|
||||
func (d *Dao) OldFrozenChange(mid, status int64) (err error) {
|
||||
var (
|
||||
c = context.Background()
|
||||
)
|
||||
params := url.Values{}
|
||||
params.Set("mid", fmt.Sprintf("%v", mid))
|
||||
params.Set("status", fmt.Sprintf("%v", status))
|
||||
rel := new(struct {
|
||||
Code int64 `json:"code"`
|
||||
Data string `json:"data"`
|
||||
})
|
||||
if err = d.client.Get(c, d.c.URLConf.OldVipCoURL+_frozenChange, "127.0.0.1", params, rel); err != nil {
|
||||
log.Error("send error(%v) url(%v)", err, d.c.URLConf.OldVipCoURL+_frozenChange)
|
||||
return
|
||||
}
|
||||
if rel != nil && rel.Code == int64(ecode.OK.Code()) {
|
||||
return
|
||||
}
|
||||
err = ecode.VipJavaAPIErr
|
||||
return
|
||||
}
|
14
app/job/main/vip/dao/oldvip_test.go
Normal file
14
app/job/main/vip/dao/oldvip_test.go
Normal file
@ -0,0 +1,14 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestDaoOldFrozenChange(t *testing.T) {
|
||||
convey.Convey("OldFrozenChange", t, func() {
|
||||
err := d.OldFrozenChange(7593623, 0)
|
||||
convey.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
}
|
252
app/job/main/vip/dao/order.go
Normal file
252
app/job/main/vip/dao/order.go
Normal file
@ -0,0 +1,252 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
xsql "go-common/library/database/sql"
|
||||
"go-common/library/log"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
_insertPayOrder = "INSERT IGNORE INTO vip_pay_order(order_no,app_id,platform,order_type,mid,to_mid,buy_months,money,status,pay_type,recharge_bp,third_trade_no,payment_time,ver,app_sub_id,coupon_money) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
|
||||
_selPayOrder = "SELECT order_no,app_id,platform,order_type,mid,to_mid,buy_months,money,status,pay_type,third_trade_no,payment_time,ver,app_sub_id FROM vip_pay_order WHERE id>? AND id <=?"
|
||||
_selPayOrderByMidSQL = "SELECT order_no,app_id,platform,order_type,mid,to_mid,buy_months,money,status,pay_type,third_trade_no,payment_time,ver,app_sub_id FROM vip_pay_order WHERE mid=? AND order_type=? AND status=? ORDER BY ID DESC LIMIT 1"
|
||||
_selOrderByMidSQL = "SELECT order_no,app_id,platform,order_type,mid,to_mid,buy_months,money,status,pay_type,third_trade_no,payment_time,ver,app_sub_id FROM vip_pay_order WHERE order_no=?"
|
||||
_selPayOrderLogByMidSQL = "SELECT order_no,status,mid FROM vip_pay_order_log WHERE mid=? AND status=? ORDER BY ID DESC LIMIT 1"
|
||||
_selOldPayOrder = "SELECT order_no,app_id,order_type,mid,IFNULL(buy_months,0),money,IFNULL(pay_type,4),IFNULL(status,1),ver,IFNULL(platform,3),mtime,app_sub_id,bmid,coupon_money from vip_pay_order WHERE id>? AND id<=?"
|
||||
_selOldRechargeOrder = "SELECT pay_order_no,third_trade_no,recharge_bp FROM vip_recharge_order WHERE pay_order_no IN "
|
||||
_updatePayOrderStatusSQL = "UPDATE vip_pay_order SET "
|
||||
_updateRechageOrderSQL = "UPDATE vip_pay_order SET recharge_bp = ?,third_trade_no = ? where order_no = ?"
|
||||
_insertPayOrderLog = "INSERT INTO vip_pay_order_log(order_no,mid,status) VALUES(?,?,?)"
|
||||
_batchAddPayOrder = "INSERT INTO vip_pay_order(order_no,app_id,platform,order_type,mid,to_mid,buy_months,money,status,pay_type,recharge_bp,third_trade_no,payment_time,ver,app_sub_id) VALUES"
|
||||
|
||||
_selOrderMaxIDSQL = "SELECT IFNULL(MAX(id),0) FROM vip_pay_order"
|
||||
_selOldOrderMaxIDSQL = "SELECT IFNULL(MAX(id),0) FROM vip_pay_order"
|
||||
)
|
||||
|
||||
//SelPayOrderByMid sel payorder by mid
|
||||
func (d *Dao) SelPayOrderByMid(c context.Context, mid int64, orderType, status int8) (r *model.VipPayOrder, err error) {
|
||||
row := d.db.QueryRow(c, _selPayOrderByMidSQL, mid, orderType, status)
|
||||
r = new(model.VipPayOrder)
|
||||
if err = row.Scan(&r.OrderNo, &r.AppID, &r.Platform, &r.OrderType, &r.Mid, &r.ToMid, &r.BuyMonths, &r.Money, &r.Status, &r.PayType, &r.ThirdTradeNo, &r.PaymentTime, &r.Ver, &r.AppSubID); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
err = nil
|
||||
r = nil
|
||||
return
|
||||
}
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("db_scan")
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SelOrderByOrderNo sel payorder by orderNo
|
||||
func (d *Dao) SelOrderByOrderNo(c context.Context, orderNo string) (r *model.VipPayOrder, err error) {
|
||||
row := d.db.QueryRow(c, _selOrderByMidSQL, orderNo)
|
||||
r = new(model.VipPayOrder)
|
||||
if err = row.Scan(&r.OrderNo, &r.AppID, &r.Platform, &r.OrderType, &r.Mid, &r.ToMid, &r.BuyMonths, &r.Money, &r.Status, &r.PayType, &r.ThirdTradeNo, &r.PaymentTime, &r.Ver, &r.AppSubID); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
err = nil
|
||||
r = nil
|
||||
return
|
||||
}
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("db_scan")
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SelPayOrderLog sel pay order log.
|
||||
func (d *Dao) SelPayOrderLog(c context.Context, mid int64, status int8) (r *model.VipPayOrderLog, err error) {
|
||||
row := d.db.QueryRow(c, _selPayOrderLogByMidSQL, mid, status)
|
||||
r = new(model.VipPayOrderLog)
|
||||
if err = row.Scan(&r.OrderNo, &r.Status, &r.Mid); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
err = nil
|
||||
r = nil
|
||||
return
|
||||
}
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("db_scan")
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//AddPayOrder add payorder
|
||||
func (d *Dao) AddPayOrder(c context.Context, r *model.VipPayOrder) (a int64, err error) {
|
||||
var result sql.Result
|
||||
if result, err = d.db.Exec(c, _insertPayOrder, &r.OrderNo, &r.AppID, &r.Platform, &r.OrderType, &r.Mid, &r.ToMid, &r.BuyMonths, &r.Money, &r.Status, &r.PayType, &r.RechargeBp, &r.ThirdTradeNo, &r.PaymentTime, &r.Ver, &r.AppSubID, &r.CouponMoney); err != nil {
|
||||
log.Error("AddPayOrder d.db.exec(%v) error(%v)", r, err)
|
||||
return
|
||||
}
|
||||
if a, err = result.RowsAffected(); err != nil {
|
||||
log.Error("AddPayOrder result.RowsAffected() error(%v)", err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SelOrderMaxID sel order maxID
|
||||
func (d *Dao) SelOrderMaxID(c context.Context) (maxID int, err error) {
|
||||
row := d.db.QueryRow(c, _selOrderMaxIDSQL)
|
||||
if err = row.Scan(&maxID); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("db_scan")
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SelOldOrderMaxID sel old order maxID
|
||||
func (d *Dao) SelOldOrderMaxID(c context.Context) (maxID int, err error) {
|
||||
row := d.oldDb.QueryRow(c, _selOldOrderMaxIDSQL)
|
||||
if err = row.Scan(&maxID); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("db_scan")
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//BatchAddPayOrder batch add pay order
|
||||
func (d *Dao) BatchAddPayOrder(c context.Context, res []*model.VipPayOrder) (err error) {
|
||||
var values []string
|
||||
if len(res) == 0 {
|
||||
return
|
||||
}
|
||||
for _, v := range res {
|
||||
value := fmt.Sprintf("('%v','%v','%v','%v','%v','%v','%v','%v','%v','%v','%v','%v','%v','%v','%v','%v')", v.OrderNo, v.AppID, v.Platform, v.OrderType, v.Mid, v.ToMid, v.BuyMonths, v.Money, v.Status, v.PayType, v.RechargeBp, v.ThirdTradeNo, v.PaymentTime.Time().Format("2006-01-02 15:04:05"), v.Ver, v.AppSubID, v.CouponMoney)
|
||||
values = append(values, value)
|
||||
}
|
||||
valuesStr := strings.Join(values, ",")
|
||||
dupStr := " ON DUPLICATE KEY UPDATE app_id = VALUES(app_id),platform=VALUES(platform),order_type=VALUES(order_type)," +
|
||||
"mid=VALUES(mid),to_mid=VALUES(to_mid),buy_months=VALUES(buy_months),money=VALUES(money),status=VALUES(status),pay_type=VALUES(pay_type),recharge_bp=VALUES(recharge_bp)," +
|
||||
"third_trade_no=VALUES(third_trade_no) ,payment_time=VALUES(payment_time) ,ver=VALUES(ver),app_sub_id=VALUES(app_sub_id),coupon_money=VALUES(coupon_money) "
|
||||
if _, err = d.db.Exec(c, _batchAddPayOrder+valuesStr+dupStr); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//UpdatePayOrderStatus update payorder status
|
||||
func (d *Dao) UpdatePayOrderStatus(c context.Context, r *model.VipPayOrder) (a int64, err error) {
|
||||
var result sql.Result
|
||||
sqlStr := _updatePayOrderStatusSQL
|
||||
if r.PayType != 0 {
|
||||
sqlStr += fmt.Sprintf(" pay_type=%v ,payment_time='%v' ,", r.PayType, r.PaymentTime.Time().Format("2006-01-02 15:04:05"))
|
||||
}
|
||||
sqlStr += fmt.Sprintf(" ctime='%v',mtime='%v',ver=%v,status=%v,order_type=%v,coupon_money=%v WHERE order_no='%v' ", r.Ctime.Time().Format("2006-01-02 15:04:05"), r.Mtime.Time().Format("2006-01-02 15:04:05"), r.Ver, r.Status, r.OrderType, r.CouponMoney, r.OrderNo)
|
||||
if result, err = d.db.Exec(c, sqlStr); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
if a, err = result.RowsAffected(); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//UpdateRechargeOrder update recharge order info
|
||||
func (d *Dao) UpdateRechargeOrder(c context.Context, r *model.VipPayOrder) (a int64, err error) {
|
||||
var result sql.Result
|
||||
if result, err = d.db.Exec(c, _updateRechageOrderSQL, &r.RechargeBp, &r.ThirdTradeNo, &r.OrderNo); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
if a, err = result.RowsAffected(); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//AddPayOrderLog add payorderlog
|
||||
func (d *Dao) AddPayOrderLog(c context.Context, r *model.VipPayOrderLog) (a int64, err error) {
|
||||
var result sql.Result
|
||||
if result, err = d.db.Exec(c, _insertPayOrderLog, &r.OrderNo, &r.Mid, &r.Status); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
if a, err = result.RowsAffected(); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SelPayOrder sel payorder
|
||||
func (d *Dao) SelPayOrder(c context.Context, sID, eID int) (res []*model.VipPayOrder, err error) {
|
||||
var rows *xsql.Rows
|
||||
if rows, err = d.db.Query(c, _selPayOrder, sID, eID); err != nil {
|
||||
log.Error("SelPayOrder d.db.query(sID:%v,eID:%v) error(%v)", sID, eID, err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
r := new(model.VipPayOrder)
|
||||
if err = rows.Scan(&r.OrderNo, &r.AppID, &r.Platform, &r.OrderType, &r.Mid, &r.ToMid, &r.BuyMonths, &r.Money, &r.Status, &r.PayType, &r.ThirdTradeNo, &r.PaymentTime, &r.Ver, &r.AppSubID); err != nil {
|
||||
log.Error("SelPayOrder rows.scan() error(%v)", err)
|
||||
res = nil
|
||||
return
|
||||
}
|
||||
res = append(res, r)
|
||||
}
|
||||
err = rows.Err()
|
||||
return
|
||||
}
|
||||
|
||||
//SelOldPayOrder sel old payorder
|
||||
func (d *Dao) SelOldPayOrder(c context.Context, sID, eID int) (res []*model.VipPayOrderOld, err error) {
|
||||
var rows *xsql.Rows
|
||||
if rows, err = d.oldDb.Query(c, _selOldPayOrder, sID, eID); err != nil {
|
||||
log.Error("SelOldPayOrder d.db.query(sID:%v,eID:%v) error(%v)", sID, eID, err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
r := new(model.VipPayOrderOld)
|
||||
if err = rows.Scan(&r.OrderNo, &r.AppID, &r.OrderType, &r.Mid, &r.BuyMonths, &r.Money, &r.PayType, &r.Status, &r.Ver, &r.Platform, &r.PaymentTime, &r.AppSubID, &r.Bmid, &r.CouponMoney); err != nil {
|
||||
log.Error("SelOldPayOrder rows.scan() error(%v)", err)
|
||||
res = nil
|
||||
return
|
||||
}
|
||||
res = append(res, r)
|
||||
}
|
||||
err = rows.Err()
|
||||
return
|
||||
}
|
||||
|
||||
//SelOldRechargeOrder sel old rechargeOrder
|
||||
func (d *Dao) SelOldRechargeOrder(c context.Context, orderNos []string) (res []*model.VipRechargeOrder, err error) {
|
||||
var inStr = strings.Join(orderNos, "','")
|
||||
inStr = "('" + inStr + "')"
|
||||
|
||||
var rows *xsql.Rows
|
||||
if rows, err = d.oldDb.Query(c, _selOldRechargeOrder+inStr); err != nil {
|
||||
log.Error("SelOldRechargeOrder d.db.query(%v) error(%v)", orderNos, err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
r := new(model.VipRechargeOrder)
|
||||
if err = rows.Scan(&r.PayOrderNo, &r.ThirdTradeNo, &r.RechargeBp); err != nil {
|
||||
log.Error("SelOldRechargeOrder rows.scan(%v) error(%v)", orderNos, err)
|
||||
res = nil
|
||||
return
|
||||
}
|
||||
res = append(res, r)
|
||||
}
|
||||
err = rows.Err()
|
||||
return
|
||||
}
|
76
app/job/main/vip/dao/order_test.go
Normal file
76
app/job/main/vip/dao/order_test.go
Normal file
@ -0,0 +1,76 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
xtime "go-common/library/time"
|
||||
|
||||
"time"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestDao_AddPayOrder(t *testing.T) {
|
||||
Convey("add pay order", t, func() {
|
||||
d.AddPayOrder(context.TODO(), &model.VipPayOrder{Mid: 123})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDao_UpdatePayOrderStatus(t *testing.T) {
|
||||
Convey("update order", t, func() {
|
||||
r := new(model.VipPayOrder)
|
||||
r.OrderType = 1
|
||||
r.PayType = 6
|
||||
r.Status = 2
|
||||
r.Ver = 2
|
||||
r.OrderNo = "1807021929153562939"
|
||||
r.Mtime = xtime.Time(time.Now().Unix())
|
||||
_, err := d.UpdatePayOrderStatus(context.TODO(), r)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
func TestDao_SelPayOrderByMid(t *testing.T) {
|
||||
Convey("SelPayOrderByMid", t, func() {
|
||||
_, err := d.SelPayOrderByMid(context.TODO(), 7593623, 1, 1)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDao_SSelOrderByOrderNo(t *testing.T) {
|
||||
Convey("SelOrderByOrderNo", t, func() {
|
||||
_, err := d.SelOrderByOrderNo(context.TODO(), "7593623")
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDao_SelPayOrderLog(t *testing.T) {
|
||||
Convey("SelPayOrderLog", t, func() {
|
||||
_, err := d.SelPayOrderLog(context.TODO(), 7593623, 1)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDao_SelPayOrder(t *testing.T) {
|
||||
Convey("SelPayOrder", t, func() {
|
||||
_, err := d.SelPayOrder(context.TODO(), 1, 1)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDao_SelOldPayOrder(t *testing.T) {
|
||||
Convey("SelOldPayOrder", t, func() {
|
||||
_, err := d.SelOldPayOrder(context.TODO(), 1, 1)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDao_SelOldRechargeOrder(t *testing.T) {
|
||||
Convey("SelOldRechargeOrder", t, func() {
|
||||
_, err := d.SelOldRechargeOrder(context.TODO(), []string{"test"})
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
39
app/job/main/vip/dao/push.go
Normal file
39
app/job/main/vip/dao/push.go
Normal file
@ -0,0 +1,39 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
"go-common/library/database/sql"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
//PushDatas get push datas
|
||||
func (d *Dao) PushDatas(c context.Context, curtime string) (res []*model.VipPushData, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = d.db.Query(c, _selPushDataSQL, curtime, curtime); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
r := new(model.VipPushData)
|
||||
if err = rows.Scan(&r.ID, &r.DisableType, &r.GroupName, &r.Title, &r.Content, &r.PushTotalCount, &r.PushedCount, &r.ProgressStatus, &r.Status, &r.Platform, &r.LinkType, &r.LinkURL, &r.ErrorCode, &r.ExpiredDayStart, &r.ExpiredDayEnd, &r.EffectStartDate, &r.EffectEndDate, &r.PushStartTime, &r.PushEndTime); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
res = append(res, r)
|
||||
}
|
||||
err = rows.Err()
|
||||
return
|
||||
}
|
||||
|
||||
//UpdatePushData update push data
|
||||
func (d *Dao) UpdatePushData(c context.Context, status, progressStatus int8, pushedCount int32, errcode, data, id int64) (err error) {
|
||||
if _, err = d.db.Exec(c, _updatePushDataSQL, progressStatus, status, pushedCount, errcode, data, id); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("exec_err")
|
||||
}
|
||||
return
|
||||
}
|
43
app/job/main/vip/dao/push_test.go
Normal file
43
app/job/main/vip/dao/push_test.go
Normal file
@ -0,0 +1,43 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestDaoPushDatas(t *testing.T) {
|
||||
convey.Convey("PushDatas", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
curtime = ""
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.PushDatas(c, curtime)
|
||||
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoUpdatePushData(t *testing.T) {
|
||||
convey.Convey("UpdatePushData", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
status = int8(0)
|
||||
progressStatus = int8(0)
|
||||
pushedCount = int32(0)
|
||||
errcode = int64(0)
|
||||
data = int64(0)
|
||||
id = int64(0)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
err := d.UpdatePushData(c, status, progressStatus, pushedCount, errcode, data, id)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
123
app/job/main/vip/dao/redis.go
Normal file
123
app/job/main/vip/dao/redis.go
Normal file
@ -0,0 +1,123 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"go-common/library/cache/redis"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
_frozenDelayQueue = "fdq"
|
||||
_accLogin = "al:%d"
|
||||
)
|
||||
|
||||
func accLoginKey(mid int64) string {
|
||||
return fmt.Sprintf(_accLogin, mid)
|
||||
}
|
||||
|
||||
// Enqueue put frozen user to redis sortset queue
|
||||
func (d *Dao) Enqueue(c context.Context, mid, score int64) (err error) {
|
||||
var (
|
||||
conn = d.redis.Get(c)
|
||||
)
|
||||
defer conn.Close()
|
||||
if err = conn.Send("ZADD", _frozenDelayQueue, score, mid); err != nil {
|
||||
err = errors.Wrap(err, "redis send zadd err(%+v)")
|
||||
return
|
||||
}
|
||||
if err = conn.Send("EXPIRE", _frozenDelayQueue, d.redisExpire); err != nil {
|
||||
err = errors.Wrap(err, "redis send expire err(%+v)")
|
||||
return
|
||||
}
|
||||
if err = conn.Flush(); err != nil {
|
||||
return
|
||||
}
|
||||
for i := 0; i < 2; i++ {
|
||||
if _, err = conn.Receive(); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Dequeue get a frozen user from redis sortset queue
|
||||
func (d *Dao) Dequeue(c context.Context) (mid []int64, err error) {
|
||||
var (
|
||||
conn = d.redis.Get(c)
|
||||
from = time.Now().Add(-1 * time.Minute).Unix()
|
||||
to = time.Now().Unix()
|
||||
)
|
||||
defer conn.Close()
|
||||
if mid, err = redis.Int64s(conn.Do("ZRANGEBYSCORE", _frozenDelayQueue, from, to)); err != nil {
|
||||
err = errors.Wrap(err, "redis do zrevrangebyscore err")
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// RemQueue del a frozen user from redis sortset queue
|
||||
func (d *Dao) RemQueue(c context.Context, mid int64) (err error) {
|
||||
var (
|
||||
conn = d.redis.Get(c)
|
||||
)
|
||||
defer conn.Close()
|
||||
if _, err = conn.Do("ZREM", _frozenDelayQueue, mid); err != nil {
|
||||
err = errors.Wrap(err, "redis do zrem err")
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// AddLogginIP save user loggin info to sortset
|
||||
func (d *Dao) AddLogginIP(c context.Context, mid int64, ip uint32) (err error) {
|
||||
var (
|
||||
conn = d.redis.Get(c)
|
||||
key = accLoginKey(mid)
|
||||
)
|
||||
defer conn.Close()
|
||||
if err = conn.Send("SADD", key, ip); err != nil {
|
||||
err = errors.Wrap(err, "redis do zadd err")
|
||||
return
|
||||
}
|
||||
if err = conn.Send("EXPIRE", key, d.frozenExpire); err != nil {
|
||||
err = errors.Wrap(err, "redis send expire err(%+v)")
|
||||
return
|
||||
}
|
||||
if err = conn.Flush(); err != nil {
|
||||
return
|
||||
}
|
||||
for i := 0; i < 2; i++ {
|
||||
if _, err = conn.Receive(); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//DelCache del cache.
|
||||
func (d *Dao) DelCache(c context.Context, mid int64) (err error) {
|
||||
var (
|
||||
conn = d.redis.Get(c)
|
||||
key = accLoginKey(mid)
|
||||
)
|
||||
defer conn.Close()
|
||||
if _, err = conn.Do("DEL", key); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// LoginCount get user recent loggin count
|
||||
func (d *Dao) LoginCount(c context.Context, mid int64) (count int64, err error) {
|
||||
var conn = d.redis.Get(c)
|
||||
defer conn.Close()
|
||||
if count, err = redis.Int64(conn.Do("SCARD", accLoginKey(mid))); err != nil {
|
||||
err = errors.Wrap(err, "redis send zcard err(%+v)")
|
||||
}
|
||||
return
|
||||
}
|
54
app/job/main/vip/dao/redis_test.go
Normal file
54
app/job/main/vip/dao/redis_test.go
Normal file
@ -0,0 +1,54 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
var (
|
||||
ctx = context.TODO()
|
||||
mid int64 = 7593623
|
||||
)
|
||||
|
||||
func Test_FrozenQueue(t *testing.T) {
|
||||
Convey("Test_FrozenQueue", t, func() {
|
||||
var (
|
||||
err error
|
||||
score = time.Now().Add(-50 * time.Second).Unix()
|
||||
)
|
||||
err = d.Enqueue(ctx, mid, score)
|
||||
So(err, ShouldBeNil)
|
||||
res, err2 := d.Dequeue(ctx)
|
||||
So(err2, ShouldBeNil)
|
||||
So(res[0], ShouldEqual, mid)
|
||||
err3 := d.RemQueue(ctx, mid)
|
||||
So(err3, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDao_Enqueue(t *testing.T) {
|
||||
Convey("test enqueue", t, func() {
|
||||
duration := time.Duration(d.c.Property.FrozenDate)
|
||||
t.Logf("duration %+v", duration)
|
||||
err := d.Enqueue(ctx, mid, time.Now().Add(duration).Unix())
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDao_Dequeue(t *testing.T) {
|
||||
Convey("dequeue", t, func() {
|
||||
res, err := d.Dequeue(ctx)
|
||||
t.Logf("%+v", res)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_AddLogginIP(t *testing.T) {
|
||||
Convey("Test_FrozenQueue", t, func() {
|
||||
err := d.AddLogginIP(ctx, mid, 234231)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
43
app/job/main/vip/dao/resource.go
Normal file
43
app/job/main/vip/dao/resource.go
Normal file
@ -0,0 +1,43 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"go-common/app/job/main/vip/model"
|
||||
"go-common/library/database/sql"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
//GetAbleCode get able code
|
||||
func (d *Dao) GetAbleCode(tx *sql.Tx, batchCodeID int64) (code string, err error) {
|
||||
row := tx.QueryRow(_getAbleCodeSQL, batchCodeID)
|
||||
if err = row.Scan(&code); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
err = errors.WithStack(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//UpdateCodeRelationID update code relationID
|
||||
func (d *Dao) UpdateCodeRelationID(tx *sql.Tx, code, relationID string, bmid int64) (err error) {
|
||||
if _, err = tx.Exec(_updateCodeRelationIDSQL, relationID, bmid, code); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SelBatchCodeByID .
|
||||
func (d *Dao) SelBatchCodeByID(tx *sql.Tx, batchCodeID int64) (r *model.VipResourceBatchCode, err error) {
|
||||
row := tx.QueryRow(_selBatchCodeSQL, batchCodeID)
|
||||
r = new(model.VipResourceBatchCode)
|
||||
if err = row.Scan(&r.ID, &r.BusinessID, &r.PoolID, &r.Status, &r.Type, &r.BatchName, &r.Reason, &r.Unit, &r.Count, &r.SurplusCount, &r.Price, &r.StartTime, &r.EndTime); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
err = errors.WithStack(err)
|
||||
}
|
||||
return
|
||||
}
|
63
app/job/main/vip/dao/resource_test.go
Normal file
63
app/job/main/vip/dao/resource_test.go
Normal file
@ -0,0 +1,63 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"go-common/library/database/sql"
|
||||
"testing"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestDaoGetAbleCode(t *testing.T) {
|
||||
convey.Convey("GetAbleCode", t, func(ctx convey.C) {
|
||||
var (
|
||||
tx = &sql.Tx{}
|
||||
batchCodeID = int64(0)
|
||||
)
|
||||
tx, err := d.StartTx(context.Background())
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(tx, convey.ShouldNotBeNil)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.GetAbleCode(tx, batchCodeID)
|
||||
ctx.Convey("Then err should be nil.code should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoUpdateCodeRelationID(t *testing.T) {
|
||||
convey.Convey("UpdateCodeRelationID", t, func(ctx convey.C) {
|
||||
var (
|
||||
code = ""
|
||||
relationID = ""
|
||||
bmid = int64(0)
|
||||
)
|
||||
tx, err := d.StartTx(context.Background())
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(tx, convey.ShouldNotBeNil)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
err := d.UpdateCodeRelationID(tx, code, relationID, bmid)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoSelBatchCodeByID(t *testing.T) {
|
||||
convey.Convey("SelBatchCodeByID", t, func(ctx convey.C) {
|
||||
var (
|
||||
batchCodeID = int64(0)
|
||||
)
|
||||
tx, err := d.StartTx(context.Background())
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(tx, convey.ShouldNotBeNil)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.SelBatchCodeByID(tx, batchCodeID)
|
||||
ctx.Convey("Then err should be nil.r should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
37
app/job/main/vip/dao/sync.go
Normal file
37
app/job/main/vip/dao/sync.go
Normal file
@ -0,0 +1,37 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
xsql "database/sql"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
//sync
|
||||
_syncAddUser = "INSERT INTO vip_user_info(mid,vip_type,vip_pay_type,vip_status,vip_start_time,vip_overdue_time,annual_vip_overdue_time,vip_recent_time,ios_overdue_time,pay_channel_id,ctime,mtime,ver) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)"
|
||||
_syncUpdateUser = "UPDATE vip_user_info SET vip_type=?,vip_pay_type=?,vip_status=?,vip_overdue_time=?,annual_vip_overdue_time=?,vip_recent_time=?,ios_overdue_time=?,pay_channel_id=?,ctime=?,mtime=?,ver=? WHERE mid=? AND ver=?"
|
||||
)
|
||||
|
||||
//SyncAddUser insert vipUserInfo
|
||||
func (d *Dao) SyncAddUser(c context.Context, r *model.VipUserInfo) (err error) {
|
||||
if _, err = d.db.Exec(c, _syncAddUser, r.Mid, r.Type, r.PayType, r.Status, r.StartTime, r.OverdueTime, r.AnnualVipOverdueTime, r.RecentTime, r.OverdueTime, r.PayChannelID, r.Ctime, r.Mtime, r.Ver); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SyncUpdateUser insert vipUserInfo
|
||||
func (d *Dao) SyncUpdateUser(c context.Context, r *model.VipUserInfo, ver int64) (eff int64, err error) {
|
||||
var res xsql.Result
|
||||
if res, err = d.db.Exec(c, _syncUpdateUser, r.Type, r.PayType, r.Status, r.OverdueTime, r.AnnualVipOverdueTime, r.RecentTime, r.IosOverdueTime, r.PayChannelID, r.Ctime, r.Mtime, r.Ver, r.Mid, ver); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
if eff, err = res.RowsAffected(); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
}
|
||||
return
|
||||
}
|
29
app/job/main/vip/dao/sync_test.go
Normal file
29
app/job/main/vip/dao/sync_test.go
Normal file
@ -0,0 +1,29 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"go-common/app/job/main/vip/model"
|
||||
"testing"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestDaoSyncAddUser(t *testing.T) {
|
||||
var r = &model.VipUserInfo{Mid: 7993}
|
||||
convey.Convey("clean data before", t, func() {
|
||||
d.db.Exec(context.Background(), "delete from vip_user_info where mid = ?", r.Mid)
|
||||
})
|
||||
convey.Convey("SyncAddUser", t, func() {
|
||||
err := d.SyncAddUser(context.Background(), r)
|
||||
convey.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
convey.Convey("SyncUpdateUser", t, func() {
|
||||
r.Status = 2
|
||||
eff, err := d.SyncUpdateUser(context.Background(), r, r.Ver)
|
||||
convey.So(err, convey.ShouldBeNil)
|
||||
convey.So(eff, convey.ShouldNotBeNil)
|
||||
})
|
||||
convey.Convey("clean data", t, func() {
|
||||
d.db.Exec(context.Background(), "delete from vip_user_info where mid = ?", r.Mid)
|
||||
})
|
||||
}
|
522
app/job/main/vip/dao/vip.go
Normal file
522
app/job/main/vip/dao/vip.go
Normal file
@ -0,0 +1,522 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
xsql "database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
"go-common/library/database/sql"
|
||||
"go-common/library/log"
|
||||
"go-common/library/time"
|
||||
"go-common/library/xstr"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
_getVipStatus = "SELECT id,mid,vip_status FROM vip_user_info WHERE mid=?"
|
||||
_dupUserDiscountHistory = "INSERT INTO vip_user_discount_history(mid,discount_id,order_no,status) VALUES(?,?,?,?) ON DUPLICATE KEY UPDATE order_no= VALUES(order_no) ,status = VALUES(status)"
|
||||
_insertUserInfo = "INSERT ignore INTO vip_user_info(mid,vip_type,vip_pay_type,vip_status,vip_start_time,vip_recent_time,vip_overdue_time,annual_vip_overdue_time,pay_channel_id,ios_overdue_time,ver) VALUES(?,?,?,?,?,?,?,?,?,?,?) "
|
||||
|
||||
_updateUserInfo = "UPDATE vip_user_info SET vip_type=?,vip_pay_type=?,vip_status=?,vip_start_time=?,vip_recent_time=?,vip_overdue_time=?,annual_vip_overdue_time=?,pay_channel_id=?,ios_overdue_time=?,ver=? WHERE mid=? AND ver=? "
|
||||
_SelUserDiscountHistorys = "SELECT mid,discount_id FROM vip_user_discount_history WHERE id>? AND id<=? AND discount_id=?"
|
||||
_SelVipUserInfos = "SELECT mid,vip_type,vip_pay_type,vip_status,vip_start_time,vip_recent_time,vip_overdue_time,annual_vip_overdue_time FROM vip_user_info WHERE id>? and id<=? "
|
||||
_SelOldVipUserInfos = "SELECT mid,vip_type,is_auto_renew,auto_renewed,IFNULL(vip_status,0),vip_recent_time,TIMESTAMP(IFNULL(vip_start_time,'2016-01-01 00:00:00')),TIMESTAMP(IFNULL(vip_overdue_time,'2016-01-01 00:00:00')),TIMESTAMP(IFNULL(annual_vip_overdue_time,'2016-01-01 00:00:00')),ver,ios_overdue_time,pay_channel_id,ctime,mtime FROM vip_user_info WHERE id>? and id<=?"
|
||||
_SelVipList = "SELECT id,mid,vip_type,vip_status,vip_overdue_time,annual_vip_overdue_time,is_auto_renew,pay_channel_id FROM vip_user_info WHERE id>? AND id <=? AND vip_status != 0 AND annual_vip_overdue_time<=?"
|
||||
_selVipUsersSQL = "SELECT id,mid,vip_type,vip_status,vip_overdue_time,annual_vip_overdue_time FROM vip_user_info WHERE id>? AND id <=? AND vip_pay_type = 1 AND vip_overdue_time>=? AND vip_overdue_time<?"
|
||||
_selVipUserInfoSQL = "SELECT mid FROM vip_user_info WHERE id>? AND id <=? AND vip_status = ? AND vip_overdue_time>=? AND vip_overdue_time<?"
|
||||
_UpdateVipUserInfoByID = "UPDATE vip_user_info SET pay_channel_id=?,vip_pay_type=?,vip_recent_time=?,vip_overdue_time=?,annual_vip_overdue_time=?, vip_type=?, vip_status=? WHERE mid=?"
|
||||
_updateVipStatus = "UPDATE vip_user_info SET vip_status=? WHERE mid=?"
|
||||
_updateVipUserSQL = "UPDATE vip_user_info SET vip_status=?,vip_type=?,is_auto_renew=? WHERE mid=?"
|
||||
_SelMaxID = "SELECT IFNULL(MAX(id),0) id FROM vip_user_info"
|
||||
_SelEffectiveScopeVipList = "SELECT `id`,`mid`,`ver`,`vip_type`,`vip_pay_type`,`pay_channel_id`,`vip_status`,`vip_start_time`,`vip_recent_time`,`vip_overdue_time`,`annual_vip_overdue_time`,`ios_overdue_time`,`ctime` FROM `vip_user_info` WHERE id>? AND id <=?;"
|
||||
|
||||
_selDiscountMaxID = "SELECT IFNULL(MAX(id),0) id FROM vip_user_discount_history"
|
||||
_selUserInfoMaxID = "SELECT IFNULL(MAX(id),0) id FROM vip_user_info"
|
||||
|
||||
//Vip change history
|
||||
_selOldMaxIDSQL = "SELECT IFNULL(MAX(id),0) FROM vip_change_history"
|
||||
_selMaxIDSQL = "SELECT IFNULL(MAX(id),0) FROM vip_user_change_history"
|
||||
_selOldChangeHistorySQL = "SELECT id,mid,change_type,change_time,days,month,operator_id,relation_id,batch_id,IFNULL(remark,''),batch_code_id FROM vip_change_history WHERE id>? AND id<=?"
|
||||
_selOldChangeHistoryByMidsSQL = "SELECT id,mid,change_type,change_time,days,month,operator_id,relation_id,batch_id,IFNULL(remark,''),batch_code_id FROM vip_change_history WHERE mid IN (%v)"
|
||||
_selChangeHistorySQL = "SELECT id,mid,change_type,change_time,days,operator_id,relation_id,batch_id,remark,batch_code_id FROM vip_user_change_history WHERE id>? AND id<=?"
|
||||
_selChangeHistoryByMidsSQL = "SELECT id,mid,change_type,change_time,days,operator_id,relation_id,batch_id,remark,batch_code_id FROM vip_user_change_history WHERE mid IN (%v)"
|
||||
_addChangeHistoryBatchSQL = "INSERT INTO vip_user_change_history(mid,change_type,change_time,days,operator_id,relation_id,batch_id,remark,batch_code_id) VALUES"
|
||||
|
||||
// old vip db
|
||||
_selOldVipUserInfo = "SELECT mid,vip_type,is_auto_renew,auto_renewed,IFNULL(vip_status,0),vip_recent_time,TIMESTAMP(IFNULL(vip_start_time,'2016-01-01 00:00:00')),TIMESTAMP(IFNULL(vip_overdue_time,'2016-01-01 00:00:00')),annual_vip_overdue_time,ios_overdue_time,ver,pay_channel_id FROM vip_user_info WHERE mid=?"
|
||||
|
||||
_selVipByMidsSQL = "SELECT id,mid,vip_type,vip_status,vip_recent_time,vip_start_time,vip_overdue_time,annual_vip_overdue_time,vip_pay_type,pay_channel_id,ios_overdue_time,ctime,mtime,ver FROM vip_user_info WHERE mid IN (%s)"
|
||||
|
||||
_selVipUserInfoByMid = "SELECT id,mid,ver,vip_type,vip_pay_type,vip_status,vip_start_time,vip_overdue_time,annual_vip_overdue_time,vip_recent_time FROM vip_user_info WHERE mid = ?"
|
||||
)
|
||||
|
||||
//AddChangeHistoryBatch batch add change history
|
||||
func (d *Dao) AddChangeHistoryBatch(res []*model.VipChangeHistory) (err error) {
|
||||
var values []string
|
||||
if len(res) <= 0 {
|
||||
return
|
||||
}
|
||||
for _, v := range res {
|
||||
value := fmt.Sprintf("('%v','%v','%v','%v','%v','%v','%v','%v','%v')", v.Mid, v.ChangeType, v.ChangeTime.Time().Format("2006-01-02 15:04:05"), v.Days, v.OperatorID, v.RelationID, v.BatchID, v.Remark, v.BatchCodeID)
|
||||
values = append(values, value)
|
||||
}
|
||||
valuesStr := strings.Join(values, ",")
|
||||
if _, err = d.db.Exec(context.TODO(), _addChangeHistoryBatchSQL+valuesStr); err != nil {
|
||||
log.Error("AddChangeHistoryBatch d.db.exec(%v),error(%v)", valuesStr, err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SelChangeHistory .
|
||||
func (d *Dao) SelChangeHistory(c context.Context, startID, endID int64) (res []*model.VipChangeHistory, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = d.db.Query(c, _selChangeHistorySQL, startID, endID); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
r := new(model.VipChangeHistory)
|
||||
if err = rows.Scan(&r.ID, &r.Mid, &r.ChangeType, &r.ChangeTime, &r.Days, &r.OperatorID, &r.RelationID, &r.BatchID, &r.Remark, &r.BatchCodeID); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
res = nil
|
||||
return
|
||||
}
|
||||
res = append(res, r)
|
||||
}
|
||||
err = rows.Err()
|
||||
return
|
||||
}
|
||||
|
||||
//SelOldChangeHistory .
|
||||
func (d *Dao) SelOldChangeHistory(c context.Context, startID, endID int64) (res []*model.VipChangeHistory, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = d.oldDb.Query(c, _selOldChangeHistorySQL, startID, endID); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
r := new(model.VipChangeHistory)
|
||||
if err = rows.Scan(&r.ID, &r.Mid, &r.ChangeType, &r.ChangeTime, &r.Days, &r.Month, &r.OperatorID, &r.RelationID, &r.BatchID, &r.Remark, &r.BatchCodeID); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
res = nil
|
||||
return
|
||||
}
|
||||
res = append(res, r)
|
||||
}
|
||||
err = rows.Err()
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
//SelChangeHistoryMaps .
|
||||
func (d *Dao) SelChangeHistoryMaps(c context.Context, mids []int64) (res map[int64][]*model.VipChangeHistory, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = d.db.Query(c, fmt.Sprintf(_selChangeHistoryByMidsSQL, xstr.JoinInts(mids))); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
res = make(map[int64][]*model.VipChangeHistory)
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
r := new(model.VipChangeHistory)
|
||||
if err = rows.Scan(&r.ID, &r.Mid, &r.ChangeType, &r.ChangeTime, &r.Days, &r.OperatorID, &r.RelationID, &r.BatchID, &r.Remark, &r.BatchCodeID); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
res = nil
|
||||
return
|
||||
}
|
||||
histories := res[r.Mid]
|
||||
histories = append(histories, r)
|
||||
res[r.Mid] = histories
|
||||
}
|
||||
err = rows.Err()
|
||||
return
|
||||
}
|
||||
|
||||
//SelOldChangeHistoryMaps .
|
||||
func (d *Dao) SelOldChangeHistoryMaps(c context.Context, mids []int64) (res map[int64][]*model.VipChangeHistory, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = d.oldDb.Query(c, fmt.Sprintf(_selOldChangeHistoryByMidsSQL, xstr.JoinInts(mids))); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
res = make(map[int64][]*model.VipChangeHistory)
|
||||
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
r := new(model.VipChangeHistory)
|
||||
if err = rows.Scan(&r.ID, &r.Mid, &r.ChangeType, &r.ChangeTime, &r.Days, &r.Month, &r.OperatorID, &r.RelationID, &r.BatchID, &r.Remark, &r.BatchCodeID); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
res = nil
|
||||
return
|
||||
}
|
||||
histories := res[r.Mid]
|
||||
histories = append(histories, r)
|
||||
res[r.Mid] = histories
|
||||
}
|
||||
err = rows.Err()
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
//SelOldChangeHistoryMaxID .
|
||||
func (d *Dao) SelOldChangeHistoryMaxID(c context.Context) (id int64, err error) {
|
||||
var row = d.oldDb.QueryRow(c, _selOldMaxIDSQL)
|
||||
if err = row.Scan(&id); err != nil {
|
||||
log.Error("SelMaxID row.Scan() error(%v)", err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SelChangeHistoryMaxID .
|
||||
func (d *Dao) SelChangeHistoryMaxID(c context.Context) (id int64, err error) {
|
||||
var row = d.db.QueryRow(c, _selMaxIDSQL)
|
||||
if err = row.Scan(&id); err != nil {
|
||||
log.Error("SelMaxID row.Scan() error(%v)", err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// VipStatus get user vip status.
|
||||
func (d *Dao) VipStatus(c context.Context, mid int64) (res *model.VipUserInfo, err error) {
|
||||
row := d.db.QueryRow(c, _getVipStatus, mid)
|
||||
res = new(model.VipUserInfo)
|
||||
if err = row.Scan(&res.ID, &res.Mid, &res.Status); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
err = nil
|
||||
res = nil
|
||||
} else {
|
||||
err = errors.Wrapf(err, "d.VipStatus(%d)", mid)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SelMaxID get max id
|
||||
func (d *Dao) SelMaxID(c context.Context) (mID int, err error) {
|
||||
var row = d.db.QueryRow(c, _SelMaxID)
|
||||
if err = row.Scan(&mID); err != nil {
|
||||
log.Error("SelMaxID row.Scan() error(%v)", err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//UpdateVipUserInfo update vip user info by id
|
||||
func (d *Dao) UpdateVipUserInfo(tx *sql.Tx, r *model.VipUserInfo) (a int64, err error) {
|
||||
var res xsql.Result
|
||||
if res, err = tx.Exec(_UpdateVipUserInfoByID, r.PayChannelID, r.PayType, r.RecentTime, r.OverdueTime, r.AnnualVipOverdueTime, r.Type, r.Status, r.Mid); err != nil {
|
||||
log.Error("UpdateVipUserInfo: db.Exec(%v) error(%v)", r, err)
|
||||
return
|
||||
}
|
||||
|
||||
if a, err = res.RowsAffected(); err != nil {
|
||||
log.Error("UpdateVipUserInfo: res.RowsAffected error(%v)", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateVipUser update vip user info
|
||||
func (d *Dao) UpdateVipUser(c context.Context, mid int64, status, vipType int8, payType int8) (eff int64, err error) {
|
||||
var res xsql.Result
|
||||
if res, err = d.oldDb.Exec(c, _updateVipUserSQL, status, vipType, payType, mid); err != nil {
|
||||
err = errors.Wrapf(err, "d.UpdateVipStatus(%d)", mid)
|
||||
return
|
||||
}
|
||||
if eff, err = res.RowsAffected(); err != nil {
|
||||
err = errors.Wrapf(err, "d.UpdateVipStatus(%d) res.RowsAffected", mid)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//UpdateVipStatus update vip status info by mid
|
||||
func (d *Dao) UpdateVipStatus(c context.Context, mid int64, status int) (eff int64, err error) {
|
||||
var res xsql.Result
|
||||
if res, err = d.db.Exec(c, _updateVipStatus, status, mid); err != nil {
|
||||
err = errors.Wrapf(err, "d.UpdateVipStatus(%d)", mid)
|
||||
return
|
||||
}
|
||||
if eff, err = res.RowsAffected(); err != nil {
|
||||
err = errors.Wrapf(err, "d.UpdateVipStatus(%d) res.RowsAffected", mid)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DupUserDiscountHistory add user discount history.
|
||||
func (d *Dao) DupUserDiscountHistory(tx *sql.Tx, r *model.VipUserDiscountHistory) (a int64, err error) {
|
||||
var res xsql.Result
|
||||
if res, err = tx.Exec(_dupUserDiscountHistory, r.Mid, r.DiscountID, r.OrderNo, r.Status); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
|
||||
if a, err = res.RowsAffected(); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//AddUserInfo add user info.
|
||||
func (d *Dao) AddUserInfo(tx *sql.Tx, r *model.VipUserInfo) (eff int64, err error) {
|
||||
var res xsql.Result
|
||||
if res, err = tx.Exec(_insertUserInfo, r.Mid, r.Type, r.PayType, r.Status, r.StartTime, r.RecentTime, r.OverdueTime, r.AnnualVipOverdueTime, r.PayChannelID, r.IosOverdueTime, r.Ver); err != nil {
|
||||
log.Error("AddUserDiscountHistory d.db.exec(%v) error(%v)", r, err)
|
||||
return
|
||||
}
|
||||
if eff, err = res.RowsAffected(); err != nil {
|
||||
log.Error("AddUserDiscountHistory RowsAffected(%v)", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SelVipUserInfo sel vipuser info
|
||||
func (d *Dao) SelVipUserInfo(c context.Context, mid int64) (r *model.VipUserInfo, err error) {
|
||||
var row = d.db.QueryRow(c, _selVipUserInfoByMid, mid)
|
||||
r = new(model.VipUserInfo)
|
||||
if err = row.Scan(&r.ID, &r.Mid, &r.Ver, &r.Type, &r.PayType, &r.Status, &r.StartTime, &r.OverdueTime, &r.AnnualVipOverdueTime, &r.RecentTime); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
r = nil
|
||||
err = nil
|
||||
} else {
|
||||
log.Error("row.Scan() error(%v)", err)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//UpdateUserInfo add user info
|
||||
func (d *Dao) UpdateUserInfo(tx *sql.Tx, r *model.VipUserInfo) (eff int64, err error) {
|
||||
var res xsql.Result
|
||||
if res, err = tx.Exec(_updateUserInfo, r.Type, r.PayType, r.Status, r.StartTime, r.RecentTime, r.OverdueTime, r.AnnualVipOverdueTime, r.PayChannelID, r.IosOverdueTime, r.Ver, r.Mid, r.OldVer); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
if eff, err = res.RowsAffected(); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SelUserDiscountMaxID sel discount maxID
|
||||
func (d *Dao) SelUserDiscountMaxID(c context.Context) (maxID int, err error) {
|
||||
var row = d.db.QueryRow(c, _selDiscountMaxID)
|
||||
if err = row.Scan(&maxID); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("db_scan")
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SelUserDiscountHistorys sel user discount hsitorys
|
||||
func (d *Dao) SelUserDiscountHistorys(c context.Context, sID, eID, discountID int) (res []*model.VipUserDiscountHistory, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = d.db.Query(c, _SelUserDiscountHistorys, sID, eID, discountID); err != nil {
|
||||
log.Error("SelUserDiscountHistorys d.db.query(sID:%d,eID:%d,discountID:%d) error(%+v)", sID, eID, discountID, err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
r := new(model.VipUserDiscountHistory)
|
||||
if err = rows.Scan(&r.Mid, &r.DiscountID); err != nil {
|
||||
log.Error("SelUserDiscountHistorys rows.scan() error(%v)", err)
|
||||
res = nil
|
||||
return
|
||||
}
|
||||
res = append(res, r)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SelOldUserInfoMaxID sel old userinfo maxID
|
||||
func (d *Dao) SelOldUserInfoMaxID(c context.Context) (maxID int, err error) {
|
||||
var row = d.oldDb.QueryRow(c, _selUserInfoMaxID)
|
||||
if err = row.Scan(&maxID); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("db_scan")
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// SelUserInfoMaxID select userinfo maxID.
|
||||
func (d *Dao) SelUserInfoMaxID(c context.Context) (maxID int, err error) {
|
||||
var row = d.db.QueryRow(c, _selUserInfoMaxID)
|
||||
if err = row.Scan(&maxID); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("db_scan")
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SelUserInfos sel user infos
|
||||
func (d *Dao) SelUserInfos(c context.Context, sID, eID int) (res []*model.VipUserInfo, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = d.db.Query(c, _SelVipUserInfos, sID, eID); err != nil {
|
||||
log.Error("SelUserDiscountHistorys d.db.query(sID:%v,eID:%v) error(%v)", sID, eID, err)
|
||||
return
|
||||
}
|
||||
for rows.Next() {
|
||||
r := new(model.VipUserInfo)
|
||||
if err = rows.Scan(&r.Mid, &r.Type, &r.PayType, &r.Status, &r.StartTime, &r.RecentTime, &r.OverdueTime, &r.AnnualVipOverdueTime); err != nil {
|
||||
log.Error("SelUserDiscountHistorys rows.scan() error(%v)", err)
|
||||
res = nil
|
||||
return
|
||||
}
|
||||
res = append(res, r)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SelVipList sel vipuserinfo list
|
||||
func (d *Dao) SelVipList(c context.Context, id, endID int, ot string) (res []*model.VipUserInfo, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = d.oldDb.Query(c, _SelVipList, id, endID, ot); err != nil {
|
||||
log.Error("SelVipList db.query(id:%v,ot:%v,endID:%v) error(%v)", id, ot, endID, err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
r := new(model.VipUserInfo)
|
||||
if err = rows.Scan(&r.ID, &r.Mid, &r.Type, &r.Status, &r.OverdueTime, &r.AnnualVipOverdueTime, &r.PayType, &r.PayChannelID); err != nil {
|
||||
log.Error("row.Scan() error(%v)", err)
|
||||
res = nil
|
||||
return
|
||||
}
|
||||
res = append(res, r)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SelVipUsers .
|
||||
func (d *Dao) SelVipUsers(c context.Context, id, endID int, startTime, endTime time.Time) (res []*model.VipUserInfo, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = d.db.Query(c, _selVipUsersSQL, id, endID, startTime, endTime); err != nil {
|
||||
log.Error("SelVipList db.query(id:%v,endID:%v,st:%v,et:%v) error(%v)", id, endID, startTime, endTime, err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
r := new(model.VipUserInfo)
|
||||
if err = rows.Scan(&r.ID, &r.Mid, &r.Type, &r.Status, &r.OverdueTime, &r.AnnualVipOverdueTime); err != nil {
|
||||
log.Error("row.Scan() error(%v)", err)
|
||||
res = nil
|
||||
return
|
||||
}
|
||||
res = append(res, r)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SelVipUserInfos sel vipuser info datas
|
||||
func (d *Dao) SelVipUserInfos(c context.Context, id, endID int, startTime, endTime time.Time, status int) (res []int64, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = d.db.Query(c, _selVipUserInfoSQL, id, endID, status, startTime.Time().Format("2006-01-02"), endTime.Time().Format("2006-01-02")); err != nil {
|
||||
log.Error("SelVipList db.query(id:%v,endID:%v,st:%v,et:%v) error(%v)", id, endID, startTime, endTime, err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var r int64
|
||||
if err = rows.Scan(&r); err != nil {
|
||||
log.Error("row.Scan() error(%v)", err)
|
||||
res = nil
|
||||
return
|
||||
}
|
||||
res = append(res, r)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//OldVipInfo get old user by mid.
|
||||
func (d *Dao) OldVipInfo(c context.Context, mid int64) (r *model.VipUserInfoOld, err error) {
|
||||
var row = d.oldDb.QueryRow(c, _selOldVipUserInfo, mid)
|
||||
r = new(model.VipUserInfoOld)
|
||||
if err = row.Scan(&r.Mid, &r.Type, &r.IsAutoRenew, &r.AutoRenewed, &r.Status, &r.RecentTime, &r.StartTime, &r.OverdueTime,
|
||||
&r.AnnualVipOverdueTime, &r.IosOverdueTime, &r.Ver, &r.PayChannelID); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
r = nil
|
||||
err = nil
|
||||
} else {
|
||||
err = errors.WithStack(err)
|
||||
d.errProm.Incr("row_scan_db")
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// SelEffectiveScopeVipList get vip list by id scope.
|
||||
func (d *Dao) SelEffectiveScopeVipList(c context.Context, id, endID int) (res []*model.VipInfoDB, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = d.db.Query(c, _SelEffectiveScopeVipList, id, endID); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
r := new(model.VipInfoDB)
|
||||
if err = rows.Scan(&r.ID, &r.Mid, &r.Ver, &r.Type, &r.PayType, &r.PayChannelID, &r.Status, &r.StartTime, &r.RecentTime, &r.OverdueTime, &r.AnnualVipOverdueTime,
|
||||
&r.IosOverdueTime, &r.Ctime); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
res = nil
|
||||
return
|
||||
}
|
||||
res = append(res, r)
|
||||
}
|
||||
err = rows.Err()
|
||||
return
|
||||
}
|
||||
|
||||
// SelVipByIds select vip by ids .
|
||||
func (d *Dao) SelVipByIds(c context.Context, ids []int64) (res map[int64]*model.VipUserInfo, err error) {
|
||||
var (
|
||||
rows *sql.Rows
|
||||
idStr = xstr.JoinInts(ids)
|
||||
)
|
||||
res = make(map[int64]*model.VipUserInfo, len(ids))
|
||||
if rows, err = d.db.Query(c, fmt.Sprintf(_selVipByMidsSQL, idStr)); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
r := new(model.VipUserInfo)
|
||||
if err = rows.Scan(&r.ID, &r.Mid, &r.Type, &r.Status, &r.RecentTime, &r.StartTime, &r.OverdueTime, &r.AnnualVipOverdueTime, &r.PayType, &r.PayChannelID, &r.IosOverdueTime, &r.Ctime, &r.Mtime, &r.Ver); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
res = nil
|
||||
return
|
||||
}
|
||||
res[r.Mid] = r
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//SelOldUserInfoMaps sel old user info map.
|
||||
func (d *Dao) SelOldUserInfoMaps(c context.Context, sID, eID int) (res map[int64]*model.VipUserInfoOld, err error) {
|
||||
var (
|
||||
rows *sql.Rows
|
||||
)
|
||||
res = make(map[int64]*model.VipUserInfoOld, eID-sID)
|
||||
if rows, err = d.oldDb.Query(c, _SelOldVipUserInfos, sID, eID); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
for rows.Next() {
|
||||
r := new(model.VipUserInfoOld)
|
||||
if err = rows.Scan(&r.Mid, &r.Type, &r.IsAutoRenew, &r.AutoRenewed, &r.Status, &r.RecentTime, &r.StartTime, &r.OverdueTime, &r.AnnualVipOverdueTime, &r.Ver, &r.IosOverdueTime, &r.PayChannelID, &r.Ctime, &r.Mtime); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
res = nil
|
||||
return
|
||||
}
|
||||
res[r.Mid] = r
|
||||
}
|
||||
return
|
||||
}
|
408
app/job/main/vip/dao/vip_test.go
Normal file
408
app/job/main/vip/dao/vip_test.go
Normal file
@ -0,0 +1,408 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"go-common/app/job/main/vip/model"
|
||||
xtime "go-common/library/time"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestDaoAddChangeHistoryBatch(t *testing.T) {
|
||||
convey.Convey("AddChangeHistoryBatch", t, func(ctx convey.C) {
|
||||
var (
|
||||
res = []*model.VipChangeHistory{}
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
err := d.AddChangeHistoryBatch(res)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoSelChangeHistory(t *testing.T) {
|
||||
convey.Convey("SelChangeHistory", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
startID = int64(0)
|
||||
endID = int64(0)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.SelChangeHistory(c, startID, endID)
|
||||
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoSelOldChangeHistory(t *testing.T) {
|
||||
convey.Convey("SelOldChangeHistory", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
startID = int64(0)
|
||||
endID = int64(0)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.SelOldChangeHistory(c, startID, endID)
|
||||
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoSelOldChangeHistoryMaxID(t *testing.T) {
|
||||
convey.Convey("SelOldChangeHistoryMaxID", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.SelOldChangeHistoryMaxID(c)
|
||||
ctx.Convey("Then err should be nil.id should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoSelChangeHistoryMaxID(t *testing.T) {
|
||||
convey.Convey("SelChangeHistoryMaxID", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.SelChangeHistoryMaxID(c)
|
||||
ctx.Convey("Then err should be nil.id should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoVipStatus(t *testing.T) {
|
||||
convey.Convey("VipStatus", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(0)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.VipStatus(c, mid)
|
||||
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoSelMaxID(t *testing.T) {
|
||||
convey.Convey("SelMaxID", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.SelMaxID(c)
|
||||
ctx.Convey("Then err should be nil.mID should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoUpdateVipUserInfo(t *testing.T) {
|
||||
convey.Convey("UpdateVipUserInfo", t, func(ctx convey.C) {
|
||||
var (
|
||||
r = &model.VipUserInfo{}
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
tx, err := d.StartTx(context.Background())
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(tx, convey.ShouldNotBeNil)
|
||||
_, err = d.UpdateVipUserInfo(tx, r)
|
||||
ctx.Convey("Then err should be nil.a should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoUpdateVipUser(t *testing.T) {
|
||||
convey.Convey("UpdateVipUser", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(0)
|
||||
status = int8(0)
|
||||
vipType = int8(0)
|
||||
payType = int8(0)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.UpdateVipUser(c, mid, status, vipType, payType)
|
||||
ctx.Convey("Then err should be nil.eff should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoDupUserDiscountHistory(t *testing.T) {
|
||||
convey.Convey("DupUserDiscountHistory", t, func(ctx convey.C) {
|
||||
var (
|
||||
r = &model.VipUserDiscountHistory{}
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
tx, err := d.StartTx(context.Background())
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(tx, convey.ShouldNotBeNil)
|
||||
_, err = d.DupUserDiscountHistory(tx, r)
|
||||
ctx.Convey("Then err should be nil.a should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoAddUserInfo(t *testing.T) {
|
||||
convey.Convey("AddUserInfo", t, func(ctx convey.C) {
|
||||
var (
|
||||
r = &model.VipUserInfo{}
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
tx, err := d.StartTx(context.Background())
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(tx, convey.ShouldNotBeNil)
|
||||
_, err = d.AddUserInfo(tx, r)
|
||||
ctx.Convey("Then err should be nil.eff should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoSelVipUserInfo(t *testing.T) {
|
||||
convey.Convey("SelVipUserInfo", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(0)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.SelVipUserInfo(c, mid)
|
||||
ctx.Convey("Then err should be nil.r should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoUpdateUserInfo(t *testing.T) {
|
||||
convey.Convey("UpdateUserInfo", t, func(ctx convey.C) {
|
||||
var (
|
||||
r = &model.VipUserInfo{}
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
tx, err := d.StartTx(context.Background())
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(tx, convey.ShouldNotBeNil)
|
||||
_, err = d.UpdateUserInfo(tx, r)
|
||||
ctx.Convey("Then err should be nil.eff should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoSelUserDiscountMaxID(t *testing.T) {
|
||||
convey.Convey("SelUserDiscountMaxID", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.SelUserDiscountMaxID(c)
|
||||
ctx.Convey("Then err should be nil.maxID should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoSelUserDiscountHistorys(t *testing.T) {
|
||||
convey.Convey("SelUserDiscountHistorys", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
sID = int(0)
|
||||
eID = int(0)
|
||||
discountID = int(0)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.SelUserDiscountHistorys(c, sID, eID, discountID)
|
||||
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoSelOldUserInfoMaxID(t *testing.T) {
|
||||
convey.Convey("SelOldUserInfoMaxID", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.SelOldUserInfoMaxID(c)
|
||||
ctx.Convey("Then err should be nil.maxID should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoSelUserInfoMaxID(t *testing.T) {
|
||||
convey.Convey("SelUserInfoMaxID", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.SelUserInfoMaxID(c)
|
||||
ctx.Convey("Then err should be nil.maxID should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoSelUserInfos(t *testing.T) {
|
||||
convey.Convey("SelUserInfos", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
sID = int(0)
|
||||
eID = int(0)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.SelUserInfos(c, sID, eID)
|
||||
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoSelVipList(t *testing.T) {
|
||||
convey.Convey("SelVipList", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
id = int(0)
|
||||
endID = int(0)
|
||||
ot = ""
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.SelVipList(c, id, endID, ot)
|
||||
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoSelVipUsers(t *testing.T) {
|
||||
convey.Convey("SelVipUsers", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
id = int(0)
|
||||
endID = int(0)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.SelVipUsers(c, id, endID, xtime.Time(time.Now().Unix()), xtime.Time(time.Now().Unix()))
|
||||
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoSelVipUserInfos(t *testing.T) {
|
||||
convey.Convey("SelVipUserInfos", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
id = int(0)
|
||||
endID = int(0)
|
||||
status = int(0)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.SelVipUserInfos(c, id, endID, xtime.Time(time.Now().Unix()), xtime.Time(time.Now().Unix()), status)
|
||||
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoOldVipInfo(t *testing.T) {
|
||||
convey.Convey("OldVipInfo", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
mid = int64(0)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.OldVipInfo(c, mid)
|
||||
ctx.Convey("Then err should be nil.r should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoSelEffectiveScopeVipList(t *testing.T) {
|
||||
convey.Convey("SelEffectiveScopeVipList", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
id = int(0)
|
||||
endID = int(0)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.SelEffectiveScopeVipList(c, id, endID)
|
||||
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDaoSelOldUserInfoMaps(t *testing.T) {
|
||||
convey.Convey("SelOldUserInfoMaps", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
sID = int(0)
|
||||
eID = int(0)
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
_, err := d.SelOldUserInfoMaps(c, sID, eID)
|
||||
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func Test_SelChangeHistoryMaps(t *testing.T) {
|
||||
convey.Convey("SelChangeHistoryMaps", t, func(ctx convey.C) {
|
||||
_, err := d.SelChangeHistoryMaps(context.Background(), []int64{7593623})
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_SelOldChangeHistoryMaps(t *testing.T) {
|
||||
convey.Convey("SelOldChangeHistoryMaps", t, func(ctx convey.C) {
|
||||
_, err := d.SelOldChangeHistoryMaps(context.Background(), []int64{7593623})
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_SelVipByIds(t *testing.T) {
|
||||
convey.Convey("SelVipByIds", t, func(ctx convey.C) {
|
||||
_, err := d.SelVipByIds(context.Background(), []int64{7593623})
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
}
|
35
app/job/main/vip/http/BUILD
Normal file
35
app/job/main/vip/http/BUILD
Normal file
@ -0,0 +1,35 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["http.go"],
|
||||
importpath = "go-common/app/job/main/vip/http",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/job/main/vip/conf:go_default_library",
|
||||
"//app/job/main/vip/model:go_default_library",
|
||||
"//app/job/main/vip/service: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"],
|
||||
)
|
181
app/job/main/vip/http/http.go
Normal file
181
app/job/main/vip/http/http.go
Normal file
@ -0,0 +1,181 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"go-common/app/job/main/vip/conf"
|
||||
"go-common/app/job/main/vip/model"
|
||||
"go-common/app/job/main/vip/service"
|
||||
"go-common/library/log"
|
||||
bm "go-common/library/net/http/blademaster"
|
||||
)
|
||||
|
||||
var (
|
||||
s *service.Service
|
||||
)
|
||||
|
||||
// Init init http sever instance.
|
||||
func Init(c *conf.Config, ss *service.Service) {
|
||||
// init inner router
|
||||
engine := bm.DefaultServer(c.BM)
|
||||
innerRouter(engine)
|
||||
// init inner server
|
||||
if err := engine.Start(); err != nil {
|
||||
log.Error("engine start error(%v)", err)
|
||||
panic(err)
|
||||
}
|
||||
s = ss
|
||||
}
|
||||
|
||||
// innerRouter init inner router.
|
||||
func innerRouter(r *bm.Engine) {
|
||||
r.Ping(ping)
|
||||
r.GET("/scanUserInfo", checkscanUserInfo)
|
||||
r.GET("/handlerOrder", handlerOrder)
|
||||
r.GET("/handlerChangeHistory", handlerVipChangeHistory)
|
||||
r.GET("/handlerVipSendBcoin", handlerVipSendBcoin)
|
||||
r.GET("/sendBcoinJob", sendBcoinJob)
|
||||
r.GET("/hadExpiredJob", hadExpireJob)
|
||||
r.GET("/willExpiredJob", willExpireJob)
|
||||
r.GET("/sendMessageJob", sendMessageJob)
|
||||
r.GET("/autoRenewJob", autoRenewJob)
|
||||
r.GET("/syncvipdata", syncVipInfoData)
|
||||
r.GET("/clearcache", clearUserCache)
|
||||
r.GET("/scansalarylog", scanSalaryLog)
|
||||
r.GET("/checkuserdata", checkUserData)
|
||||
r.GET("/checkBcoinSalary", checkBcoinSalary)
|
||||
r.GET("/checkChangeHistory", checkHistory)
|
||||
|
||||
r.GET("/sync/all/user", syncAllUser)
|
||||
r.GET("/frozen", frozen)
|
||||
}
|
||||
|
||||
func syncAllUser(c *bm.Context) {
|
||||
log.Info("syncAllUser start........................................")
|
||||
s.SyncAllUser(c)
|
||||
log.Info("syncAllUser end........................................")
|
||||
}
|
||||
|
||||
func checkHistory(c *bm.Context) {
|
||||
log.Info("check history info start........................................")
|
||||
mids, err := s.CheckChangeHistory(c)
|
||||
log.Info("check history info end..............error mids(%+v) error(%+v)", mids, err)
|
||||
c.JSON(mids, err)
|
||||
}
|
||||
|
||||
func checkBcoinSalary(c *bm.Context) {
|
||||
log.Info("check bcoin info start........................................")
|
||||
mids, err := s.CheckBcoinData(c)
|
||||
log.Info("check bcoin info end..............error mids(%+v) error(%+v)", mids, err)
|
||||
c.JSON(mids, err)
|
||||
}
|
||||
|
||||
func autoRenewJob(c *bm.Context) {
|
||||
//s.AutoRenewJob()
|
||||
}
|
||||
|
||||
func sendBcoinJob(c *bm.Context) {
|
||||
//s.SendBcoinJob()
|
||||
}
|
||||
|
||||
func hadExpireJob(c *bm.Context) {
|
||||
//s.HadExpiredMsgJob()
|
||||
}
|
||||
|
||||
func willExpireJob(c *bm.Context) {
|
||||
//s.WillExpiredMsgJob()
|
||||
}
|
||||
|
||||
func sendMessageJob(c *bm.Context) {
|
||||
//s.SendMessageJob()
|
||||
}
|
||||
|
||||
// ping check server ok.
|
||||
func ping(c *bm.Context) {}
|
||||
|
||||
func handlerOrder(c *bm.Context) {
|
||||
log.Info("handler order start.........................................")
|
||||
s.HandlerPayOrder()
|
||||
log.Info("handler order end ............................................")
|
||||
}
|
||||
|
||||
func handlerVipChangeHistory(c *bm.Context) {
|
||||
log.Info("handler vip change history start ...................... ")
|
||||
s.HandlerVipChangeHistory()
|
||||
log.Info("handler vip change history end ...................... ")
|
||||
}
|
||||
|
||||
func handlerVipSendBcoin(c *bm.Context) {
|
||||
log.Info(" handler vip send bcoin start ..............")
|
||||
s.HandlerBcoin()
|
||||
log.Info("handler vip send bcoin end ...............")
|
||||
}
|
||||
|
||||
func checkscanUserInfo(c *bm.Context) {
|
||||
log.Info("scan user info start ..........................")
|
||||
s.ScanUserInfo(c)
|
||||
log.Info("scan user info end ...........................")
|
||||
}
|
||||
|
||||
func syncVipInfoData(c *bm.Context) {
|
||||
var err error
|
||||
arg := new(struct {
|
||||
Mid int64 `form:"mid" validate:"required"`
|
||||
})
|
||||
if err = c.Bind(arg); err != nil {
|
||||
log.Error("c.Bind err(%+v)", err)
|
||||
return
|
||||
}
|
||||
if err = s.SyncUserInfoByMid(c, arg.Mid); err != nil {
|
||||
c.JSON(nil, err)
|
||||
return
|
||||
}
|
||||
c.JSON(nil, nil)
|
||||
}
|
||||
|
||||
func clearUserCache(c *bm.Context) {
|
||||
var err error
|
||||
arg := new(struct {
|
||||
Mid int64 `form:"mid" validate:"required"`
|
||||
})
|
||||
if err = c.Bind(arg); err != nil {
|
||||
log.Error("c.Bind err(%+v)", err)
|
||||
return
|
||||
}
|
||||
s.ClearUserCache(arg.Mid)
|
||||
c.JSON(nil, nil)
|
||||
}
|
||||
|
||||
func scanSalaryLog(c *bm.Context) {
|
||||
log.Info("scan salary log start ..........................")
|
||||
var err error
|
||||
if err = s.ScanSalaryLog(c); err != nil {
|
||||
log.Error("scan salary log err(%+v)", err)
|
||||
c.JSON(nil, err)
|
||||
return
|
||||
}
|
||||
log.Info("scan salary log end ...........................")
|
||||
c.JSON(nil, nil)
|
||||
}
|
||||
|
||||
func checkUserData(c *bm.Context) {
|
||||
log.Info("check vip_user_info data start ..........................")
|
||||
var (
|
||||
err error
|
||||
diffs map[int64]string
|
||||
)
|
||||
if diffs, err = s.CheckUserData(c); err != nil {
|
||||
c.JSON(diffs, err)
|
||||
return
|
||||
}
|
||||
log.Info("check vip_user_info data end diffs(%v) size(%d)...........................", diffs, len(diffs))
|
||||
c.JSON(diffs, err)
|
||||
}
|
||||
|
||||
func frozen(c *bm.Context) {
|
||||
var err error
|
||||
arg := new(model.LoginLog)
|
||||
if err = c.Bind(arg); err != nil {
|
||||
log.Error("c.Bind err(%+v)", err)
|
||||
return
|
||||
}
|
||||
c.JSON(nil, s.Frozen(c, arg))
|
||||
}
|
68
app/job/main/vip/model/BUILD
Normal file
68
app/job/main/vip/model/BUILD
Normal file
@ -0,0 +1,68 @@
|
||||
load(
|
||||
"@io_bazel_rules_go//proto:def.bzl",
|
||||
"go_proto_library",
|
||||
)
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"associate.go",
|
||||
"coupon.go",
|
||||
"databus.go",
|
||||
"handler.go",
|
||||
"http.go",
|
||||
"model.go",
|
||||
"oldVip.go",
|
||||
"query.go",
|
||||
"vip.go",
|
||||
],
|
||||
embed = [":model_go_proto"],
|
||||
importpath = "go-common/app/job/main/vip/model",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//library/time:go_default_library",
|
||||
"@com_github_gogo_protobuf//gogoproto:go_default_library",
|
||||
"@com_github_golang_protobuf//proto:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "model_proto",
|
||||
srcs = ["vip.proto"],
|
||||
tags = ["automanaged"],
|
||||
deps = ["@gogo_special_proto//github.com/gogo/protobuf/gogoproto"],
|
||||
)
|
||||
|
||||
go_proto_library(
|
||||
name = "model_go_proto",
|
||||
compilers = ["@io_bazel_rules_go//proto:gogofast_proto"],
|
||||
importpath = "go-common/app/job/main/vip/model",
|
||||
proto = ":model_proto",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//library/time:go_default_library",
|
||||
"@com_github_gogo_protobuf//gogoproto:go_default_library",
|
||||
],
|
||||
)
|
16
app/job/main/vip/model/associate.go
Normal file
16
app/job/main/vip/model/associate.go
Normal file
@ -0,0 +1,16 @@
|
||||
package model
|
||||
|
||||
import "go-common/library/time"
|
||||
|
||||
// VipOrderActivityRecord vip record.
|
||||
type VipOrderActivityRecord struct {
|
||||
ID int64
|
||||
Mid int64
|
||||
OrderNo string
|
||||
ProductID string
|
||||
Months int32
|
||||
PanelType string
|
||||
AssociateState int32
|
||||
Ctime time.Time
|
||||
Mtime time.Time
|
||||
}
|
23
app/job/main/vip/model/coupon.go
Normal file
23
app/job/main/vip/model/coupon.go
Normal file
@ -0,0 +1,23 @@
|
||||
package model
|
||||
|
||||
// VideoCouponSalaryLog videl coupon salary log.
|
||||
type VideoCouponSalaryLog struct {
|
||||
ID int64 `json:"id"`
|
||||
Mid int64 `json:"mid"`
|
||||
CouponCount int64 `json:"coupon_count"`
|
||||
CouponType int8 `json:"coupon_type"`
|
||||
State int8 `json:"state"`
|
||||
Type int8 `json:"type"`
|
||||
ExpireTime int64 `json:"expire_time"`
|
||||
StartTime int64 `json:"start_time"`
|
||||
Ver int64 `json:"ver"`
|
||||
}
|
||||
|
||||
// OldSalaryLog def.
|
||||
type OldSalaryLog struct {
|
||||
ID int64 `json:"id"`
|
||||
Mid int64 `json:"mid"`
|
||||
CouponCount int64 `json:"coupon_count"`
|
||||
State int8 `json:"state"`
|
||||
Type int8 `json:"type"`
|
||||
}
|
155
app/job/main/vip/model/databus.go
Normal file
155
app/job/main/vip/model/databus.go
Normal file
@ -0,0 +1,155 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"go-common/library/time"
|
||||
)
|
||||
|
||||
//VipUserInfoMsg get databus vip_user_info msg
|
||||
type VipUserInfoMsg struct {
|
||||
ID int64 `json:"id"`
|
||||
Mid int64 `json:"mid"`
|
||||
Type int8 `json:"vip_type"`
|
||||
Status int8 `json:"vip_status"`
|
||||
StartTime string `json:"vip_start_time"`
|
||||
OverdueTime string `json:"vip_overdue_time"`
|
||||
AnnualVipOverdueTime string `json:"annual_vip_overdue_time"`
|
||||
RecentTime string `json:"vip_recent_time"`
|
||||
Wander int8 `json:"wander"`
|
||||
AutoRenewed int8 `json:"auto_renewed"`
|
||||
IsAutoRenew int8 `json:"is_auto_renew"`
|
||||
Ver int64 `json:"ver"`
|
||||
PayChannelID int64 `json:"pay_channel_id"`
|
||||
IosOverdueTime string `json:"ios_overdue_time"`
|
||||
}
|
||||
|
||||
//VipUserInfoNewMsg .
|
||||
type VipUserInfoNewMsg struct {
|
||||
ID int64 `json:"id"`
|
||||
Mid int64 `json:"mid"`
|
||||
Ver int64 `json:"ver"`
|
||||
VipType int8 `json:"vip_type"`
|
||||
VipPayType int8 `json:"vip_pay_type"`
|
||||
PayChannelID int64 `json:"pay_channel_id"`
|
||||
VipStatus int8 `json:"vip_status"`
|
||||
VipStartTime string `json:"vip_start_time"`
|
||||
VipRecentTime string `json:"vip_recent_time"`
|
||||
VipOverdueTime string `json:"vip_overdue_time"`
|
||||
AnnualVipOverdueTime string `json:"annual_vip_overdue_time"`
|
||||
IosOverdueTime string `json:"ios_overdue_time"`
|
||||
}
|
||||
|
||||
//VipPointChangeHistoryMsg get databus json data
|
||||
type VipPointChangeHistoryMsg struct {
|
||||
ID int `json:"id"`
|
||||
Mid int `json:"mid"`
|
||||
Point int `json:"point"`
|
||||
OrderID string `json:"order_id"`
|
||||
ChangeType int `json:"change_type"`
|
||||
ChangeTime string `json:"change_time"`
|
||||
RelationID string `json:"relation_id"`
|
||||
PointBalance int `json:"point_balance"`
|
||||
Remark string `json:"remark"`
|
||||
Operator string `json:"operator"`
|
||||
}
|
||||
|
||||
//VipPayOrderOldMsg get databus json data
|
||||
type VipPayOrderOldMsg struct {
|
||||
ID int64 `json:"id"`
|
||||
OrderNo string `json:"order_no"`
|
||||
AppID int64 `json:"app_id"`
|
||||
Platform int8 `json:"platform"`
|
||||
OrderType int8 `json:"order_type"`
|
||||
Mid int64 `json:"mid"`
|
||||
Bmid int64 `json:"bmid"`
|
||||
BuyMonths int16 `json:"buy_months"`
|
||||
Money float64 `json:"money"`
|
||||
RechargeBp float64 `json:"recharge_bp"`
|
||||
Status int8 `json:"status"`
|
||||
PayType int8 `json:"pay_type"`
|
||||
PaymentTime string `json:"payment_time"`
|
||||
Ver int64 `json:"ver"`
|
||||
AppSubID string `json:"app_sub_id"`
|
||||
CouponMoney float64 `json:"coupon_money"`
|
||||
Ctime string `json:"ctime"`
|
||||
Mtime string `json:"mtime"`
|
||||
}
|
||||
|
||||
//VipPayOrderNewMsg .
|
||||
type VipPayOrderNewMsg struct {
|
||||
ID int64 `json:"id"`
|
||||
OrderNo string `json:"order_no"`
|
||||
AppID int64 `json:"app_id"`
|
||||
Platform int8 `json:"platform"`
|
||||
OrderType int8 `json:"order_type"`
|
||||
Mid int64 `json:"mid"`
|
||||
ToMid int64 `json:"to_mid"`
|
||||
BuyMonths int16 `json:"buy_months"`
|
||||
Money float64 `json:"money"`
|
||||
RechargeBp float64 `json:"recharge_bp"`
|
||||
ThirdTradeNo string `json:"third_trade_no"`
|
||||
Status int8 `json:"status"`
|
||||
PayType string `json:"pay_type"`
|
||||
PaymentTime string `json:"payment_time"`
|
||||
Ver int64 `json:"ver"`
|
||||
AppSubID string `json:"app_sub_id"`
|
||||
CouponMoney float64 `json:"coupon_money"`
|
||||
}
|
||||
|
||||
//VipRechargeOrderMsg get databus json data
|
||||
type VipRechargeOrderMsg struct {
|
||||
ID int64 `json:"id"`
|
||||
AppID int64 `json:"app_id"`
|
||||
PayMid int64 `json:"pay_mid"`
|
||||
OrderNo string `json:"order_no"`
|
||||
RechargeBp float64 `json:"recharge_bp"`
|
||||
ThirdTradeNo string `json:"third_trade_no"`
|
||||
PayOrderNo string `json:"pay_order_no"`
|
||||
Status int8 `json:"status"`
|
||||
Ver int64 `json:"ver"`
|
||||
Bmid int64 `json:"bmid"`
|
||||
}
|
||||
|
||||
//VipChangeHistoryMsg vip change history msg
|
||||
type VipChangeHistoryMsg struct {
|
||||
Mid int64 `json:"mid"`
|
||||
ChangeType int8 `json:"change_type"`
|
||||
ChangeTime string `json:"change_time"`
|
||||
Days int32 `json:"days"`
|
||||
Month int16 `json:"month"`
|
||||
OperatorID string `json:"operator_id"`
|
||||
RelationID string `json:"relation_id"`
|
||||
BatchID int64 `json:"batch_id"`
|
||||
Remark string `json:"remark"`
|
||||
BatchCodeID int64 `json:"batch_code_id"`
|
||||
}
|
||||
|
||||
//VipBcoinSalaryMsg .
|
||||
type VipBcoinSalaryMsg struct {
|
||||
ID int64 `json:"id"`
|
||||
Mid int64 `json:"mid"`
|
||||
Status int8 `json:"status"`
|
||||
GiveNowStatus int8 `json:"give_now_status"`
|
||||
Payday string `json:"month"`
|
||||
Amount int32 `json:"amount"`
|
||||
Memo string `json:"memo"`
|
||||
}
|
||||
|
||||
//Message databus message
|
||||
type Message struct {
|
||||
Action string `json:"action"`
|
||||
Table string `json:"table"`
|
||||
New json.RawMessage `json:"new"`
|
||||
Old json.RawMessage `json:"old"`
|
||||
}
|
||||
|
||||
// LoginLog login log.
|
||||
type LoginLog struct {
|
||||
Mid int64 `json:"mid,omitempty" form:"mid"`
|
||||
IP uint32 `json:"loginip" form:"ip"`
|
||||
Location string `json:"location"`
|
||||
LocationID int64 `json:"location_id,omitempty"`
|
||||
Time time.Time `json:"timestamp,omitempty"`
|
||||
Type int8 `json:"type,omitempty"`
|
||||
}
|
37
app/job/main/vip/model/handler.go
Normal file
37
app/job/main/vip/model/handler.go
Normal file
@ -0,0 +1,37 @@
|
||||
package model
|
||||
|
||||
import "go-common/library/time"
|
||||
|
||||
//HandlerVip vip handler
|
||||
type HandlerVip struct {
|
||||
Days int32
|
||||
Months int16
|
||||
Mid int64
|
||||
Type int8
|
||||
}
|
||||
|
||||
//AppCache appCache
|
||||
type AppCache struct {
|
||||
AppID int64 `json:"appID"`
|
||||
Mid int64 `json:"mid"`
|
||||
}
|
||||
|
||||
//BcoinSendInfo .
|
||||
type BcoinSendInfo struct {
|
||||
Amount int32 `json:"amount"`
|
||||
DueDate time.Time `json:"dueDate"`
|
||||
DayOfMonth int `json:"dayOfMonth"`
|
||||
}
|
||||
|
||||
//VipBuyResq .
|
||||
type VipBuyResq struct {
|
||||
Mid int64 `json:"mid"`
|
||||
CouponID string `json:"coupon_id"`
|
||||
OrderNo string `json:"order_no"`
|
||||
}
|
||||
|
||||
//VipPushResq .
|
||||
type VipPushResq struct {
|
||||
Code int64 `json:"code"`
|
||||
Data int64 `json:"data"`
|
||||
}
|
8
app/job/main/vip/model/http.go
Normal file
8
app/job/main/vip/model/http.go
Normal file
@ -0,0 +1,8 @@
|
||||
package model
|
||||
|
||||
// CommonResq response params.
|
||||
type CommonResq struct {
|
||||
Code int64 `json:"code"`
|
||||
TS int64 `json:"ts"`
|
||||
Message string `json:"message"`
|
||||
}
|
102
app/job/main/vip/model/model.go
Normal file
102
app/job/main/vip/model/model.go
Normal file
@ -0,0 +1,102 @@
|
||||
package model
|
||||
|
||||
//Eunm vip enum value
|
||||
const (
|
||||
//ChangeType
|
||||
ChangeTypePointExhchange = 1 // 积分兑换
|
||||
ChangeTypeRechange = 2 //充值开通
|
||||
ChangeTypeSystem = 3 // 系统发放
|
||||
ChangeTypeActiveGive = 4 //活动赠送
|
||||
ChangeTypeRepeatDeduction = 5 //重复领取扣除
|
||||
|
||||
VipDaysMonth = 31
|
||||
VipDaysYear = 366
|
||||
|
||||
NotVip = 0 //非大会员
|
||||
Vip = 1 //月度大会员
|
||||
AnnualVip = 2 //年度会员
|
||||
|
||||
VipStatusOverTime = 0 //过期
|
||||
VipStatusNotOverTime = 1 //未过期
|
||||
VipStatusFrozen = 2 //冻结
|
||||
VipStatusBan = 3 //封禁
|
||||
|
||||
VipAppUser = 1 //大会员对接业务方user缓存
|
||||
VipAppPoint = 2 //大会员对接业务方积分缓存
|
||||
|
||||
VipChangeFrozen = -1 //冻结
|
||||
VipChangeUnFrozen = 0 //解冻
|
||||
VipChangeOpen = 1 //开通
|
||||
VipChangeModify = 2 //变更
|
||||
|
||||
VipBusinessStatusOpen = 0 //有效
|
||||
VipBusinessStatusClose = 1 //无效
|
||||
|
||||
VipUserFirstDiscount = 1
|
||||
|
||||
AnnualVipBcoinDay = "annual_vip_bcoin_day" //年费VIPB券发放每月第几天
|
||||
AnnualVipBcoinCouponMoney = "annual_vip_bcoin_coupon_money" //年费VIP返回B券金额
|
||||
AnnualVipBcoinCouponActivityID = "annual_vip_bcoin_coupon_activity_id" //年费VIP返B券活动ID
|
||||
|
||||
HadSalaryState = 1 // 已发放
|
||||
|
||||
NormalVipSalaryType = 1
|
||||
AnnualVipSalaryType = 2
|
||||
VipSupplyType = 3
|
||||
TimingSalaryType = 4
|
||||
|
||||
SalaryVipOrigin = 1
|
||||
|
||||
TimeFormatSec = "2006-01-02 15:04:05"
|
||||
|
||||
DayOfHour = 24
|
||||
|
||||
IsAutoRenew = 1
|
||||
|
||||
IAPChannelID = 100
|
||||
|
||||
MsgSystemNotify = 4
|
||||
MsgCouponSalaryMc = "10_99_2"
|
||||
|
||||
CouponSalaryTitle = `观影劵到账通知`
|
||||
CouponSalaryMsg = `大会员专享观影券已到账,#{点击查看>>}{"https://big.bilibili.com/mobile/userticket"}`
|
||||
CouponToAnnualSalaryMsg = `升级年度大会员赠送观影券%d张已到账,#{点击查看>>}{"https://big.bilibili.com/mobile/userticket"}`
|
||||
|
||||
CouponCartoonSalaryTitle = `漫画阅读劵到账通知`
|
||||
CouponCartoonSalaryMsg = `大会员漫画阅读券已到账 #{点击查看>>}{"https://big.bilibili.com/mobile/userticket"}`
|
||||
CouponCartoonToAnnualSalaryMsg = `升级年度大会员赠送漫画阅读券%d张已到账,#{点击查看>>}{"https://big.bilibili.com/mobile/userticket"}`
|
||||
)
|
||||
|
||||
// dicount type
|
||||
const (
|
||||
DiscountNotUse = iota
|
||||
DiscountUsed
|
||||
)
|
||||
|
||||
// coupon salary type
|
||||
const (
|
||||
CouponSalaryTiming int8 = iota
|
||||
CouponSalaryAtonce
|
||||
)
|
||||
|
||||
// coupon type
|
||||
const (
|
||||
SalaryCouponType int8 = iota + 1
|
||||
SalaryCartoonCouponType
|
||||
)
|
||||
|
||||
//pay order type
|
||||
const (
|
||||
Normal = iota
|
||||
AutoRenew
|
||||
IAPAutoRenew
|
||||
)
|
||||
|
||||
//pay order status
|
||||
const (
|
||||
PAYING = iota + 1
|
||||
SUCCESS
|
||||
FAILED
|
||||
SIGN
|
||||
UNSIGN
|
||||
)
|
91
app/job/main/vip/model/oldVip.go
Normal file
91
app/job/main/vip/model/oldVip.go
Normal file
@ -0,0 +1,91 @@
|
||||
package model
|
||||
|
||||
import "go-common/library/time"
|
||||
|
||||
//VipUserInfoOld vip_user_info table
|
||||
type VipUserInfoOld struct {
|
||||
ID int64 `json:"id"`
|
||||
Mid int64 `json:"mid"`
|
||||
Type int8 `json:"vipType"`
|
||||
Status int8 `json:"vipStatus"`
|
||||
StartTime time.Time `json:"vipStartTime"`
|
||||
OverdueTime time.Time `json:"vipOverdueTime"`
|
||||
AnnualVipOverdueTime time.Time `json:"annualVipOverdueTime"`
|
||||
RecentTime time.Time `json:"vip_recent_time"`
|
||||
Wander int8 `json:"wander"`
|
||||
AccessStatus int8 `json:"accessStatus"`
|
||||
AutoRenewed int8 `json:"auto_renewed"`
|
||||
IsAutoRenew int8 `json:"is_auto_renew"`
|
||||
IosOverdueTime time.Time `json:"ios_overdue_time"`
|
||||
PayChannelID int64 `json:"pay_channel_id"`
|
||||
Ver int64 `json:"ver"`
|
||||
Ctime time.Time `json:"ctime"`
|
||||
Mtime time.Time `json:"mtime"`
|
||||
}
|
||||
|
||||
// ToNew convert old model to new.
|
||||
func (v *VipUserInfoOld) ToNew() (n *VipUserInfo) {
|
||||
return &VipUserInfo{
|
||||
Mid: v.Mid,
|
||||
Type: v.Type,
|
||||
PayType: v.IsAutoRenew,
|
||||
PayChannelID: v.PayChannelID,
|
||||
Status: v.Status,
|
||||
StartTime: v.StartTime,
|
||||
RecentTime: v.RecentTime,
|
||||
OverdueTime: v.OverdueTime,
|
||||
AnnualVipOverdueTime: v.AnnualVipOverdueTime,
|
||||
Ctime: v.Ctime,
|
||||
Mtime: v.Mtime,
|
||||
IosOverdueTime: v.IosOverdueTime,
|
||||
Ver: v.Ver,
|
||||
}
|
||||
}
|
||||
|
||||
//VipPayOrderOld vip pay order table
|
||||
type VipPayOrderOld struct {
|
||||
ID int64 `json:"id"`
|
||||
OrderNo string `json:"orderNo"`
|
||||
AppID int64 `json:"appId"`
|
||||
Platform int8 `json:"platform"`
|
||||
OrderType int8 `json:"orderType"`
|
||||
Mid int64 `json:"mid"`
|
||||
Bmid int64 `json:"bmid"`
|
||||
BuyMonths int16 `json:"buyMonths"`
|
||||
Money float64 `json:"money"`
|
||||
Status int8 `json:"status"`
|
||||
PayType int8 `json:"payType"`
|
||||
PaymentTime time.Time `json:"paymentTime"`
|
||||
Ver int64 `json:"ver"`
|
||||
AppSubID string `json:"appSubId"`
|
||||
CouponMoney float64 `json:"coupon_money"`
|
||||
}
|
||||
|
||||
//VipRechargeOrder vip recharge order table
|
||||
type VipRechargeOrder struct {
|
||||
ID int `json:"id"`
|
||||
AppID int `json:"appId"`
|
||||
PayMid int `json:"payMid"`
|
||||
OrderNo string `json:"orderNo"`
|
||||
RechargeBp float64 `json:"rechargeBp"`
|
||||
ThirdTradeNo string `json:"thirdTradeNo"`
|
||||
PayOrderNo string `json:"payOrderNo"`
|
||||
Status int `json:"status"`
|
||||
Ver int `json:"ver"`
|
||||
Bmid int `json:"bmid"`
|
||||
}
|
||||
|
||||
//VipChangeHistory .
|
||||
type VipChangeHistory struct {
|
||||
ID int64 `json:"id"`
|
||||
Mid int64 `json:"mid"`
|
||||
ChangeType int8 `json:"change_type"`
|
||||
ChangeTime time.Time `json:"change_time"`
|
||||
Month int16 `json:"month"`
|
||||
Days int32 `json:"days"`
|
||||
OperatorID string `json:"operator_id"`
|
||||
RelationID string `json:"relation_id"`
|
||||
BatchCodeID int64 `json:"batch_code_id"`
|
||||
BatchID int64 `json:"batch_id"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
13
app/job/main/vip/model/query.go
Normal file
13
app/job/main/vip/model/query.go
Normal file
@ -0,0 +1,13 @@
|
||||
package model
|
||||
|
||||
import "go-common/library/time"
|
||||
|
||||
//QueryBcoinSalary .
|
||||
type QueryBcoinSalary struct {
|
||||
StartID int64 `json:"start_id"`
|
||||
EndID int64 `json:"end_id"`
|
||||
StartMonth time.Time `json:"start_month"`
|
||||
EndMonth time.Time `json:"end_month"`
|
||||
GiveNowStatus int8 `json:"give_now_status"`
|
||||
Status int8 `json:"status"`
|
||||
}
|
185
app/job/main/vip/model/vip.go
Normal file
185
app/job/main/vip/model/vip.go
Normal file
@ -0,0 +1,185 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"go-common/library/time"
|
||||
)
|
||||
|
||||
//VipAppInfo app info
|
||||
type VipAppInfo struct {
|
||||
ID int64 `json:"id"`
|
||||
Type int8 `json:"type"`
|
||||
Name string `json:"name"`
|
||||
PurgeURL string `json:"purgeUrl"`
|
||||
AppKey string `json:"appKey"`
|
||||
}
|
||||
|
||||
// VipPoint vip_point table
|
||||
type VipPoint struct {
|
||||
ID int `json:"id"`
|
||||
Mid int `json:"mid"`
|
||||
PointBalance int `json:"point_balance"`
|
||||
Ver int `json:"ver"`
|
||||
}
|
||||
|
||||
//VipPointChangeHistory vip_point_change_history table
|
||||
type VipPointChangeHistory struct {
|
||||
ID int `json:"id"`
|
||||
Mid int `json:"mid"`
|
||||
Point int `json:"point"`
|
||||
OrderID string `json:"orderId"`
|
||||
ChangeType int `json:"changeType"`
|
||||
ChangeTime time.Time `json:"changeTime"`
|
||||
RelationID string `json:"relationId"`
|
||||
PointBalance int `json:"pointBalance"`
|
||||
Remark string `json:"remark"`
|
||||
Operator string `json:"operator"`
|
||||
}
|
||||
|
||||
//VipPayOrderLog vip pay order log table
|
||||
type VipPayOrderLog struct {
|
||||
ID int64 `json:"id"`
|
||||
OrderNo string `json:"orderNo"`
|
||||
Mid int64 `json:"mid"`
|
||||
Status int8 `json:"status"`
|
||||
}
|
||||
|
||||
//VipPayOrder VipPayOrder table
|
||||
type VipPayOrder struct {
|
||||
ID int64 `json:"id"`
|
||||
OrderNo string `json:"orderNo"`
|
||||
AppID int64 `json:"appId"`
|
||||
Platform int8 `json:"platform"`
|
||||
OrderType int8 `json:"orderType"`
|
||||
Mid int64 `json:"mid"`
|
||||
ToMid int64 `json:"toMid"`
|
||||
BuyMonths int16 `json:"buyMonths"`
|
||||
Money float64 `json:"money"`
|
||||
RechargeBp float64 `json:"rechargeBp"`
|
||||
Status int8 `json:"status"`
|
||||
PayType int8 `json:"payType"`
|
||||
ThirdTradeNo string `json:"thirdTradeNo"`
|
||||
PaymentTime time.Time `json:"paymentTime"`
|
||||
Ver int64 `json:"ver"`
|
||||
AppSubID string `json:"appSubId"`
|
||||
CouponMoney float64 `json:"coupon_money"`
|
||||
Ctime time.Time `json:"ctime"`
|
||||
Mtime time.Time `json:"mtime"`
|
||||
}
|
||||
|
||||
//VipUserInfo vip user info table
|
||||
type VipUserInfo struct {
|
||||
ID int64 `json:"id"`
|
||||
Mid int64 `json:"mid"`
|
||||
Type int8 `json:"vipType"`
|
||||
PayType int8 `json:"payType"`
|
||||
PayChannelID int64 `json:"payChannelId"`
|
||||
Status int8 `json:"vipStatus"`
|
||||
Ver int64 `json:"ver"`
|
||||
OldVer int64 `json:"old_ver"`
|
||||
StartTime time.Time `json:"vipStartTime"`
|
||||
RecentTime time.Time `json:"vipRecentTime"`
|
||||
OverdueTime time.Time `json:"vipOverdueTime"`
|
||||
AnnualVipOverdueTime time.Time `json:"annualVipOverdueTime"`
|
||||
AutoRenewed int8 `json:"auto_renewed"`
|
||||
IosOverdueTime time.Time `json:"ios_overdue_time"`
|
||||
Ctime time.Time `json:"ctime"`
|
||||
Mtime time.Time `json:"mtime"`
|
||||
}
|
||||
|
||||
//VipPushData .
|
||||
type VipPushData struct {
|
||||
ID int64 `json:"id"`
|
||||
DisableType int8 `json:"disable_type"`
|
||||
GroupName string `json:"group_name"`
|
||||
Title string `json:"title" `
|
||||
Content string `json:"content"`
|
||||
PushTotalCount int32 `json:"-"`
|
||||
PushedCount int32 `json:"-"`
|
||||
PushProgress string `json:"push_progress"`
|
||||
ProgressStatus int8 `json:"progress_status"`
|
||||
Status int8 `json:"status"`
|
||||
Platform string `json:"platform"`
|
||||
LinkType int32 `json:"link_type"`
|
||||
ErrorCode int32 `json:"error_code"`
|
||||
LinkURL string `json:"link_url"`
|
||||
ExpiredDayStart int32 `json:"expired_day_start" `
|
||||
ExpiredDayEnd int64 `json:"expired_day_end" `
|
||||
EffectStartDate time.Time `json:"effect_start_date" `
|
||||
EffectEndDate time.Time `json:"effect_end_date" `
|
||||
PushStartTime string `json:"push_start_time" `
|
||||
PushEndTime string `json:"push_end_time" `
|
||||
}
|
||||
|
||||
//VipUserDiscountHistory vip user discount history table
|
||||
type VipUserDiscountHistory struct {
|
||||
ID int64 `json:"id"`
|
||||
Mid int64 `json:"mid"`
|
||||
DiscountID int32 `json:"discountId"`
|
||||
OrderNo string `json:"orderNo"`
|
||||
Status int8 `json:"status"`
|
||||
}
|
||||
|
||||
//VipBcoinSalary .
|
||||
type VipBcoinSalary struct {
|
||||
ID int64 `json:"id"`
|
||||
Mid int64 `json:"mid"`
|
||||
Status int8 `json:"status"`
|
||||
GiveNowStatus int8 `json:"giveNowStatus"`
|
||||
Payday time.Time `json:"month"`
|
||||
Amount int32 `json:"amount"`
|
||||
Memo string `json:"memo"`
|
||||
Ctime time.Time `json:"ctime"`
|
||||
Mtime time.Time `json:"mtime"`
|
||||
}
|
||||
|
||||
//VipInfoDB vip user info db
|
||||
type VipInfoDB struct {
|
||||
ID int64 `json:"id"`
|
||||
Mid int64 `json:"mid"`
|
||||
Ver int64 `json:"ver"`
|
||||
Type int8 `json:"vip_type"`
|
||||
PayType int8 `json:"vip_pay_type"`
|
||||
PayChannelID int64 `json:"pay_channel_id"`
|
||||
Status int8 `json:"vip_status"`
|
||||
StartTime time.Time `json:"vip_start_time"`
|
||||
RecentTime time.Time `json:"vip_recent_time"`
|
||||
OverdueTime time.Time `json:"vip_overdue_time"`
|
||||
AnnualVipOverdueTime time.Time `json:"annual_vip_overdue_time"`
|
||||
IosOverdueTime time.Time `json:"ios_overdue_time"`
|
||||
Ctime time.Time `json:"ctime"`
|
||||
Mtime time.Time `json:"mtime"`
|
||||
}
|
||||
|
||||
//VipConfig .
|
||||
type VipConfig struct {
|
||||
ID int64 `json:"id"`
|
||||
ConfigKey string `json:"config_key"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
//VipResourceBatchCode .
|
||||
type VipResourceBatchCode struct {
|
||||
ID int64 `json:"id"`
|
||||
BusinessID int64 `json:"business_id"`
|
||||
PoolID int64 `json:"pool_id"`
|
||||
Status int8 `json:"status"`
|
||||
Type int8 `json:"type"`
|
||||
BatchName string `json:"batch_name"`
|
||||
Reason string `json:"reason"`
|
||||
Unit int32 `json:"unit"`
|
||||
Count int64 `json:"count"`
|
||||
SurplusCount int64 `json:"surplus_count"`
|
||||
Price float64 `json:"price"`
|
||||
StartTime time.Time `json:"start_time"`
|
||||
EndTime time.Time `json:"end_time"`
|
||||
}
|
||||
|
||||
//VipResourceCode vip resource code
|
||||
type VipResourceCode struct {
|
||||
ID int64 `json:"id"`
|
||||
Bmid int64 `json:"bmid"`
|
||||
RelationID string `json:"relation_id"`
|
||||
Code string `json:"code"`
|
||||
Status int8 `json:"status"`
|
||||
BatchCodeID int64 `json:"batch_code_id"`
|
||||
}
|
570
app/job/main/vip/model/vip.pb.go
Normal file
570
app/job/main/vip/model/vip.pb.go
Normal file
@ -0,0 +1,570 @@
|
||||
// Code generated by protoc-gen-gogo. DO NOT EDIT.
|
||||
// source: vip.proto
|
||||
|
||||
/*
|
||||
Package model is a generated protocol buffer package.
|
||||
|
||||
It is generated from these files:
|
||||
vip.proto
|
||||
|
||||
It has these top-level messages:
|
||||
VipInfo
|
||||
*/
|
||||
package model
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
import _ "github.com/gogo/protobuf/gogoproto"
|
||||
|
||||
import go_common_time "go-common/library/time"
|
||||
|
||||
import io "io"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
type VipInfo struct {
|
||||
Mid int64 `protobuf:"varint,1,opt,name=Mid,proto3" json:"mid"`
|
||||
VipType int32 `protobuf:"varint,2,opt,name=VipType,proto3" json:"vip_type"`
|
||||
VipStatus int32 `protobuf:"varint,3,opt,name=VipStatus,proto3" json:"vip_status"`
|
||||
VipStartTime go_common_time.Time `protobuf:"varint,4,opt,name=VipStartTime,proto3,casttype=go-common/library/time.Time" json:"vip_start_time"`
|
||||
VipOverdueTime go_common_time.Time `protobuf:"varint,5,opt,name=VipOverdueTime,proto3,casttype=go-common/library/time.Time" json:"vip_overdue_time"`
|
||||
AnnualVipOverdueTime go_common_time.Time `protobuf:"varint,6,opt,name=AnnualVipOverdueTime,proto3,casttype=go-common/library/time.Time" json:"annual_vip_overdue_time"`
|
||||
AccessStatus int32 `protobuf:"varint,7,opt,name=AccessStatus,proto3" json:"access_status"`
|
||||
FrozenDate go_common_time.Time `protobuf:"varint,8,opt,name=FrozenDate,proto3,casttype=go-common/library/time.Time" json:"frozen_date"`
|
||||
VipStatusWarn string `protobuf:"bytes,9,opt,name=VipStatusWarn,proto3" json:"vip_status_warn"`
|
||||
VipRecentTime go_common_time.Time `protobuf:"varint,10,opt,name=VipRecentTime,proto3,casttype=go-common/library/time.Time" json:"vip_recent_time"`
|
||||
}
|
||||
|
||||
func (m *VipInfo) Reset() { *m = VipInfo{} }
|
||||
func (m *VipInfo) String() string { return proto.CompactTextString(m) }
|
||||
func (*VipInfo) ProtoMessage() {}
|
||||
func (*VipInfo) Descriptor() ([]byte, []int) { return fileDescriptorVip, []int{0} }
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*VipInfo)(nil), "model.VipInfo")
|
||||
}
|
||||
func (m *VipInfo) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalTo(dAtA)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *VipInfo) MarshalTo(dAtA []byte) (int, error) {
|
||||
var i int
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if m.Mid != 0 {
|
||||
dAtA[i] = 0x8
|
||||
i++
|
||||
i = encodeVarintVip(dAtA, i, uint64(m.Mid))
|
||||
}
|
||||
if m.VipType != 0 {
|
||||
dAtA[i] = 0x10
|
||||
i++
|
||||
i = encodeVarintVip(dAtA, i, uint64(m.VipType))
|
||||
}
|
||||
if m.VipStatus != 0 {
|
||||
dAtA[i] = 0x18
|
||||
i++
|
||||
i = encodeVarintVip(dAtA, i, uint64(m.VipStatus))
|
||||
}
|
||||
if m.VipStartTime != 0 {
|
||||
dAtA[i] = 0x20
|
||||
i++
|
||||
i = encodeVarintVip(dAtA, i, uint64(m.VipStartTime))
|
||||
}
|
||||
if m.VipOverdueTime != 0 {
|
||||
dAtA[i] = 0x28
|
||||
i++
|
||||
i = encodeVarintVip(dAtA, i, uint64(m.VipOverdueTime))
|
||||
}
|
||||
if m.AnnualVipOverdueTime != 0 {
|
||||
dAtA[i] = 0x30
|
||||
i++
|
||||
i = encodeVarintVip(dAtA, i, uint64(m.AnnualVipOverdueTime))
|
||||
}
|
||||
if m.AccessStatus != 0 {
|
||||
dAtA[i] = 0x38
|
||||
i++
|
||||
i = encodeVarintVip(dAtA, i, uint64(m.AccessStatus))
|
||||
}
|
||||
if m.FrozenDate != 0 {
|
||||
dAtA[i] = 0x40
|
||||
i++
|
||||
i = encodeVarintVip(dAtA, i, uint64(m.FrozenDate))
|
||||
}
|
||||
if len(m.VipStatusWarn) > 0 {
|
||||
dAtA[i] = 0x4a
|
||||
i++
|
||||
i = encodeVarintVip(dAtA, i, uint64(len(m.VipStatusWarn)))
|
||||
i += copy(dAtA[i:], m.VipStatusWarn)
|
||||
}
|
||||
if m.VipRecentTime != 0 {
|
||||
dAtA[i] = 0x50
|
||||
i++
|
||||
i = encodeVarintVip(dAtA, i, uint64(m.VipRecentTime))
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func encodeVarintVip(dAtA []byte, offset int, v uint64) int {
|
||||
for v >= 1<<7 {
|
||||
dAtA[offset] = uint8(v&0x7f | 0x80)
|
||||
v >>= 7
|
||||
offset++
|
||||
}
|
||||
dAtA[offset] = uint8(v)
|
||||
return offset + 1
|
||||
}
|
||||
func (m *VipInfo) Size() (n int) {
|
||||
var l int
|
||||
_ = l
|
||||
if m.Mid != 0 {
|
||||
n += 1 + sovVip(uint64(m.Mid))
|
||||
}
|
||||
if m.VipType != 0 {
|
||||
n += 1 + sovVip(uint64(m.VipType))
|
||||
}
|
||||
if m.VipStatus != 0 {
|
||||
n += 1 + sovVip(uint64(m.VipStatus))
|
||||
}
|
||||
if m.VipStartTime != 0 {
|
||||
n += 1 + sovVip(uint64(m.VipStartTime))
|
||||
}
|
||||
if m.VipOverdueTime != 0 {
|
||||
n += 1 + sovVip(uint64(m.VipOverdueTime))
|
||||
}
|
||||
if m.AnnualVipOverdueTime != 0 {
|
||||
n += 1 + sovVip(uint64(m.AnnualVipOverdueTime))
|
||||
}
|
||||
if m.AccessStatus != 0 {
|
||||
n += 1 + sovVip(uint64(m.AccessStatus))
|
||||
}
|
||||
if m.FrozenDate != 0 {
|
||||
n += 1 + sovVip(uint64(m.FrozenDate))
|
||||
}
|
||||
l = len(m.VipStatusWarn)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovVip(uint64(l))
|
||||
}
|
||||
if m.VipRecentTime != 0 {
|
||||
n += 1 + sovVip(uint64(m.VipRecentTime))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func sovVip(x uint64) (n int) {
|
||||
for {
|
||||
n++
|
||||
x >>= 7
|
||||
if x == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
func sozVip(x uint64) (n int) {
|
||||
return sovVip(uint64((x << 1) ^ uint64((int64(x) >> 63))))
|
||||
}
|
||||
func (m *VipInfo) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowVip
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: VipInfo: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: VipInfo: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Mid", wireType)
|
||||
}
|
||||
m.Mid = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowVip
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.Mid |= (int64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field VipType", wireType)
|
||||
}
|
||||
m.VipType = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowVip
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.VipType |= (int32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 3:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field VipStatus", wireType)
|
||||
}
|
||||
m.VipStatus = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowVip
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.VipStatus |= (int32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 4:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field VipStartTime", wireType)
|
||||
}
|
||||
m.VipStartTime = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowVip
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.VipStartTime |= (go_common_time.Time(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 5:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field VipOverdueTime", wireType)
|
||||
}
|
||||
m.VipOverdueTime = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowVip
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.VipOverdueTime |= (go_common_time.Time(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 6:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field AnnualVipOverdueTime", wireType)
|
||||
}
|
||||
m.AnnualVipOverdueTime = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowVip
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.AnnualVipOverdueTime |= (go_common_time.Time(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 7:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field AccessStatus", wireType)
|
||||
}
|
||||
m.AccessStatus = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowVip
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.AccessStatus |= (int32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 8:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field FrozenDate", wireType)
|
||||
}
|
||||
m.FrozenDate = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowVip
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.FrozenDate |= (go_common_time.Time(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 9:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field VipStatusWarn", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowVip
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthVip
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.VipStatusWarn = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 10:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field VipRecentTime", wireType)
|
||||
}
|
||||
m.VipRecentTime = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowVip
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.VipRecentTime |= (go_common_time.Time(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipVip(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthVip
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func skipVip(dAtA []byte) (n int, err error) {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowVip
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
wireType := int(wire & 0x7)
|
||||
switch wireType {
|
||||
case 0:
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowVip
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx++
|
||||
if dAtA[iNdEx-1] < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return iNdEx, nil
|
||||
case 1:
|
||||
iNdEx += 8
|
||||
return iNdEx, nil
|
||||
case 2:
|
||||
var length int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowVip
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
length |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
iNdEx += length
|
||||
if length < 0 {
|
||||
return 0, ErrInvalidLengthVip
|
||||
}
|
||||
return iNdEx, nil
|
||||
case 3:
|
||||
for {
|
||||
var innerWire uint64
|
||||
var start int = iNdEx
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowVip
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
innerWire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
innerWireType := int(innerWire & 0x7)
|
||||
if innerWireType == 4 {
|
||||
break
|
||||
}
|
||||
next, err := skipVip(dAtA[start:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
iNdEx = start + next
|
||||
}
|
||||
return iNdEx, nil
|
||||
case 4:
|
||||
return iNdEx, nil
|
||||
case 5:
|
||||
iNdEx += 4
|
||||
return iNdEx, nil
|
||||
default:
|
||||
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
|
||||
}
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
var (
|
||||
ErrInvalidLengthVip = fmt.Errorf("proto: negative length found during unmarshaling")
|
||||
ErrIntOverflowVip = fmt.Errorf("proto: integer overflow")
|
||||
)
|
||||
|
||||
func init() { proto.RegisterFile("vip.proto", fileDescriptorVip) }
|
||||
|
||||
var fileDescriptorVip = []byte{
|
||||
// 429 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xcf, 0x6e, 0xd3, 0x40,
|
||||
0x10, 0xc6, 0x63, 0x42, 0x9a, 0x66, 0x49, 0x03, 0x6c, 0x91, 0x30, 0x1c, 0xbc, 0x11, 0x87, 0x2a,
|
||||
0xfc, 0x69, 0x22, 0x81, 0x38, 0x70, 0xac, 0x85, 0x2a, 0x71, 0xa8, 0x40, 0x6e, 0x15, 0x8e, 0xd6,
|
||||
0xc6, 0x5e, 0x9b, 0x95, 0xea, 0xdd, 0xd5, 0x7a, 0x1d, 0x54, 0x1e, 0x83, 0x13, 0x8f, 0xd4, 0x63,
|
||||
0x9f, 0x60, 0x45, 0xc3, 0x6d, 0x1f, 0x81, 0x13, 0xf2, 0xb8, 0xa1, 0xb8, 0x82, 0x88, 0x9b, 0x67,
|
||||
0xbe, 0xef, 0xfb, 0xed, 0x68, 0xc6, 0x68, 0xb0, 0xe4, 0x6a, 0xaa, 0xb4, 0x34, 0x12, 0xf7, 0x0a,
|
||||
0x99, 0xb2, 0xd3, 0xc7, 0xfb, 0x39, 0x37, 0x9f, 0xaa, 0xc5, 0x34, 0x91, 0xc5, 0x2c, 0x97, 0xb9,
|
||||
0x9c, 0x81, 0xba, 0xa8, 0x32, 0xa8, 0xa0, 0x80, 0xaf, 0x26, 0xf5, 0xe4, 0x6b, 0x0f, 0xf5, 0xe7,
|
||||
0x5c, 0xbd, 0x13, 0x99, 0xc4, 0x8f, 0x50, 0xf7, 0x88, 0xa7, 0xbe, 0x37, 0xf6, 0x26, 0xdd, 0xb0,
|
||||
0xef, 0x2c, 0xe9, 0x16, 0x3c, 0x8d, 0xea, 0x1e, 0xde, 0x03, 0xd7, 0xc9, 0x99, 0x62, 0xfe, 0xad,
|
||||
0xb1, 0x37, 0xe9, 0x85, 0x43, 0x67, 0xc9, 0xf6, 0x92, 0xab, 0xd8, 0x9c, 0x29, 0x16, 0xad, 0x45,
|
||||
0xfc, 0x02, 0x0d, 0xe6, 0x5c, 0x1d, 0x1b, 0x6a, 0xaa, 0xd2, 0xef, 0x82, 0x73, 0xe4, 0x2c, 0x41,
|
||||
0xb5, 0xb3, 0x84, 0x6e, 0x74, 0x6d, 0xc0, 0x47, 0x68, 0xd8, 0x14, 0xda, 0x9c, 0xf0, 0x82, 0xf9,
|
||||
0xb7, 0xe1, 0xe5, 0xa7, 0xce, 0x92, 0xd1, 0x55, 0x40, 0x9b, 0xd8, 0xf0, 0x82, 0xfd, 0xb4, 0x64,
|
||||
0x37, 0x97, 0xfb, 0x89, 0x2c, 0x0a, 0x29, 0x66, 0x75, 0x67, 0x5a, 0x07, 0xa2, 0x56, 0x1c, 0x1f,
|
||||
0xa3, 0xd1, 0x9c, 0xab, 0xf7, 0x4b, 0xa6, 0xd3, 0x8a, 0x01, 0xb0, 0x07, 0xc0, 0xe7, 0xce, 0x92,
|
||||
0x7b, 0x35, 0x50, 0x36, 0xd2, 0x46, 0xe4, 0x0d, 0x04, 0xce, 0xd0, 0x83, 0x03, 0x21, 0x2a, 0x7a,
|
||||
0x7a, 0x03, 0xbd, 0x05, 0xe8, 0x97, 0xce, 0x92, 0x87, 0x14, 0xf4, 0xf8, 0x7f, 0x5f, 0xf8, 0x2b,
|
||||
0x0f, 0xbf, 0x46, 0xc3, 0x83, 0x24, 0x61, 0x65, 0x79, 0xb5, 0xbc, 0x3e, 0x2c, 0xef, 0xbe, 0xb3,
|
||||
0x64, 0x87, 0x42, 0x7f, 0xbd, 0xbf, 0x96, 0x0d, 0x1f, 0x22, 0x74, 0xa8, 0xe5, 0x17, 0x26, 0xde,
|
||||
0x52, 0xc3, 0xfc, 0x6d, 0x18, 0x6a, 0xcf, 0x59, 0x72, 0x27, 0x83, 0x6e, 0x9c, 0x52, 0xf3, 0xcf,
|
||||
0x41, 0xfe, 0x48, 0xe2, 0x37, 0x68, 0xe7, 0xf7, 0x5d, 0x3e, 0x52, 0x2d, 0xfc, 0xc1, 0xd8, 0x9b,
|
||||
0x0c, 0xc2, 0x5d, 0x67, 0xc9, 0xdd, 0xeb, 0xe3, 0xc5, 0x9f, 0xa9, 0x16, 0x51, 0xdb, 0x89, 0x3f,
|
||||
0x40, 0x34, 0x62, 0x09, 0x13, 0xcd, 0x19, 0x11, 0x4c, 0xf1, 0x6c, 0x1d, 0xd5, 0xa0, 0x6c, 0x5c,
|
||||
0x49, 0x1b, 0x10, 0xfa, 0xe7, 0x97, 0x41, 0xe7, 0xe2, 0x32, 0xe8, 0x9c, 0xaf, 0x02, 0xef, 0x62,
|
||||
0x15, 0x78, 0xdf, 0x57, 0x81, 0xf7, 0xed, 0x47, 0xd0, 0x59, 0x6c, 0xc1, 0x5f, 0xfb, 0xea, 0x57,
|
||||
0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x38, 0x57, 0xb5, 0xf8, 0x02, 0x00, 0x00,
|
||||
}
|
23
app/job/main/vip/model/vip.proto
Normal file
23
app/job/main/vip/model/vip.proto
Normal file
@ -0,0 +1,23 @@
|
||||
syntax = "proto3";
|
||||
package model;
|
||||
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
||||
|
||||
option (gogoproto.goproto_enum_prefix_all) = false;
|
||||
option (gogoproto.goproto_getters_all) = false;
|
||||
option (gogoproto.unmarshaler_all) = true;
|
||||
option (gogoproto.marshaler_all) = true;
|
||||
option (gogoproto.sizer_all) = true;
|
||||
|
||||
message VipInfo {
|
||||
int64 Mid = 1 [(gogoproto.jsontag) = "mid"];
|
||||
int32 VipType = 2 [(gogoproto.jsontag) = "vip_type"];
|
||||
int32 VipStatus = 3 [(gogoproto.jsontag) = "vip_status"];
|
||||
int64 VipStartTime = 4 [(gogoproto.jsontag) = "vip_start_time", (gogoproto.casttype) = "go-common/library/time.Time"];
|
||||
int64 VipOverdueTime = 5 [(gogoproto.jsontag) = "vip_overdue_time", (gogoproto.casttype) = "go-common/library/time.Time"];
|
||||
int64 AnnualVipOverdueTime = 6 [(gogoproto.jsontag) = "annual_vip_overdue_time", (gogoproto.casttype) = "go-common/library/time.Time"];
|
||||
int32 AccessStatus = 7 [(gogoproto.jsontag) = "access_status"];
|
||||
int64 FrozenDate = 8 [(gogoproto.jsontag) = "frozen_date", (gogoproto.casttype) = "go-common/library/time.Time"];
|
||||
string VipStatusWarn = 9 [(gogoproto.jsontag) = "vip_status_warn"];
|
||||
int64 VipRecentTime = 10 [(gogoproto.jsontag) = "vip_recent_time", (gogoproto.casttype) = "go-common/library/time.Time"];
|
||||
}
|
||||
|
84
app/job/main/vip/service/BUILD
Normal file
84
app/job/main/vip/service/BUILD
Normal file
@ -0,0 +1,84 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_test",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"associate_test.go",
|
||||
"autorenew_test.go",
|
||||
"coupon_test.go",
|
||||
"frozen_test.go",
|
||||
"order_test.go",
|
||||
"salary_test.go",
|
||||
"service_test.go",
|
||||
"sync_test.go",
|
||||
"vip_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
rundir = ".",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//app/job/main/vip/conf:go_default_library",
|
||||
"//app/job/main/vip/model:go_default_library",
|
||||
"//library/log:go_default_library",
|
||||
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"associate.go",
|
||||
"autorenew.go",
|
||||
"bcoin.go",
|
||||
"check_data.go",
|
||||
"coupon.go",
|
||||
"frozen.go",
|
||||
"message.go",
|
||||
"order.go",
|
||||
"push.go",
|
||||
"salary.go",
|
||||
"salary_data.go",
|
||||
"service.go",
|
||||
"sync.go",
|
||||
"vip.go",
|
||||
],
|
||||
importpath = "go-common/app/job/main/vip/service",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/job/main/vip/conf:go_default_library",
|
||||
"//app/job/main/vip/dao:go_default_library",
|
||||
"//app/job/main/vip/model:go_default_library",
|
||||
"//app/service/main/coupon/model:go_default_library",
|
||||
"//app/service/main/coupon/rpc/client:go_default_library",
|
||||
"//app/service/main/vip/api:go_default_library",
|
||||
"//app/service/main/vip/model:go_default_library",
|
||||
"//library/database/sql:go_default_library",
|
||||
"//library/log:go_default_library",
|
||||
"//library/queue/databus:go_default_library",
|
||||
"//library/sync/errgroup:go_default_library",
|
||||
"//library/time:go_default_library",
|
||||
"//vendor/github.com/pkg/errors:go_default_library",
|
||||
"//vendor/github.com/robfig/cron: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"],
|
||||
)
|
37
app/job/main/vip/service/associate.go
Normal file
37
app/job/main/vip/service/associate.go
Normal file
@ -0,0 +1,37 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
v1 "go-common/app/service/main/vip/api"
|
||||
vipmol "go-common/app/service/main/vip/model"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
func (s *Service) eleEompensateJob() {
|
||||
log.Info("ele grant eompensate job start..................")
|
||||
if succeed := s.dao.AddTransferLock(context.TODO(), "lock:elegrant"); succeed {
|
||||
if err := s.EleGrantCompensate(context.TODO()); err != nil {
|
||||
log.Error("error(%+v)", err)
|
||||
}
|
||||
}
|
||||
log.Info("ele grant eompensate job end..................")
|
||||
}
|
||||
|
||||
// EleGrantCompensate ele frant compensate.
|
||||
func (s *Service) EleGrantCompensate(c context.Context) (err error) {
|
||||
var res []*model.VipOrderActivityRecord
|
||||
if res, err = s.dao.NotGrantActOrders(c, vipmol.PanelTypeEle, s.c.Property.NotGrantLimit); err != nil {
|
||||
return
|
||||
}
|
||||
for _, v := range res {
|
||||
if _, err = s.vipgRPC.EleVipGrant(c, &v1.EleVipGrantReq{OrderNo: v.OrderNo}); err != nil {
|
||||
log.Error("EleVipGrant a(%s) err(%+v)", v.OrderNo, err)
|
||||
continue
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
return
|
||||
}
|
22
app/job/main/vip/service/associate_test.go
Normal file
22
app/job/main/vip/service/associate_test.go
Normal file
@ -0,0 +1,22 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
//go test -test.v -test.run TestEleEompensateJob
|
||||
func TestEleEompensateJob(t *testing.T) {
|
||||
Convey("TestEleEompensateJob ", t, func() {
|
||||
s.eleEompensateJob()
|
||||
})
|
||||
}
|
||||
|
||||
//go test -test.v -test.run TestEleGrantCompensate
|
||||
func TestEleGrantCompensate(t *testing.T) {
|
||||
Convey("TestEleGrantCompensate ", t, func() {
|
||||
err := s.EleGrantCompensate(c)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
}
|
66
app/job/main/vip/service/autorenew.go
Normal file
66
app/job/main/vip/service/autorenew.go
Normal file
@ -0,0 +1,66 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
func (s *Service) autoRenewPay(c context.Context, n *model.VipUserInfoMsg, o *model.VipUserInfoMsg) (err error) {
|
||||
// wechat autorenew 扣款重放条件:
|
||||
// 1.自动续费用户
|
||||
// 2.非IAP支付方式
|
||||
// 3.用户状态发生变化
|
||||
// 4.旧状态为未过期
|
||||
// 5.新状态为过期
|
||||
// 6.新旧类型都是不是NotVip type
|
||||
if n.IsAutoRenew == model.AutoRenew &&
|
||||
o.IsAutoRenew == model.AutoRenew &&
|
||||
n.PayChannelID != model.IAPChannelID &&
|
||||
o.PayChannelID != model.IAPChannelID &&
|
||||
n.Status != o.Status &&
|
||||
o.Status == model.VipStatusNotOverTime &&
|
||||
n.Status == model.VipStatusOverTime &&
|
||||
n.Type != model.NotVip && o.Type != model.NotVip {
|
||||
_, err = s.dao.AutoRenewPay(c, n.Mid)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) retryautorenewpayproc() {
|
||||
defer s.waiter.Done()
|
||||
msgs := s.autoRenewdDatabus.Messages()
|
||||
var err error
|
||||
for {
|
||||
msg, ok := <-msgs
|
||||
if !ok {
|
||||
log.Warn("[service.retryautorenewpayproc|vip] dataConsumer has been closed.")
|
||||
return
|
||||
}
|
||||
if err = msg.Commit(); err != nil {
|
||||
log.Error("retryautorenewpayproc msg.Commit err(%+v)", err)
|
||||
}
|
||||
log.Info("cur consumer retryautorenewpayproc(%v)", string(msg.Value))
|
||||
v := &model.Message{}
|
||||
if err = json.Unmarshal([]byte(msg.Value), v); err != nil {
|
||||
log.Error("retryautorenewpayproc json.Unmarshal(%v) err(%v)", v, err)
|
||||
continue
|
||||
}
|
||||
if v.Table != _tableUserInfo || v.Action != _updateAction {
|
||||
continue
|
||||
}
|
||||
n := new(model.VipUserInfoMsg)
|
||||
if err = json.Unmarshal(v.New, n); err != nil {
|
||||
log.Error("retryautorenewpayproc json.Unmarshal val(%v) error(%v)", string(v.New), err)
|
||||
continue
|
||||
}
|
||||
o := new(model.VipUserInfoMsg)
|
||||
if err = json.Unmarshal(v.Old, o); err != nil {
|
||||
log.Error("retryautorenewpayproc json.Unmarshal val(%v) error(%v)", string(v.Old), err)
|
||||
continue
|
||||
}
|
||||
s.autoRenewPay(context.Background(), n, o)
|
||||
}
|
||||
}
|
39
app/job/main/vip/service/autorenew_test.go
Normal file
39
app/job/main/vip/service/autorenew_test.go
Normal file
@ -0,0 +1,39 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
//go test -test.v -test.run TestAutoRenewPay
|
||||
func TestAutoRenewPay(t *testing.T) {
|
||||
Convey("TestAutoRenewPay ", t, func() {
|
||||
err := s.autoRenewPay(c, &model.VipUserInfoMsg{
|
||||
IsAutoRenew: model.AutoRenew,
|
||||
PayChannelID: 100,
|
||||
Status: 0,
|
||||
Type: 1,
|
||||
}, &model.VipUserInfoMsg{
|
||||
Type: 1,
|
||||
Status: 1,
|
||||
IsAutoRenew: model.AutoRenew,
|
||||
PayChannelID: 1,
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
err = s.autoRenewPay(c, &model.VipUserInfoMsg{
|
||||
IsAutoRenew: model.AutoRenew,
|
||||
PayChannelID: 1,
|
||||
Status: 0,
|
||||
Type: 1,
|
||||
}, &model.VipUserInfoMsg{
|
||||
Type: 1,
|
||||
Status: 1,
|
||||
IsAutoRenew: model.AutoRenew,
|
||||
PayChannelID: 1,
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
256
app/job/main/vip/service/bcoin.go
Normal file
256
app/job/main/vip/service/bcoin.go
Normal file
@ -0,0 +1,256 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
"go-common/library/log"
|
||||
xtime "go-common/library/time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
//HandlerBcoin handler bcoin
|
||||
func (s *Service) HandlerBcoin() (err error) {
|
||||
var (
|
||||
batchSize int64 = 2000
|
||||
oldMaxID int64
|
||||
newMaxID int64
|
||||
exitMap = make(map[string]int)
|
||||
batch []*model.VipBcoinSalary
|
||||
)
|
||||
if oldMaxID, err = s.dao.SelOldBcoinMaxID(context.TODO()); err != nil {
|
||||
log.Error("s.dao.SelOldBcoinMaxID error(%+v)", err)
|
||||
return
|
||||
}
|
||||
if newMaxID, err = s.dao.SelBcoinMaxID(context.TODO()); err != nil {
|
||||
log.Error("s.dao.SelBcoinMaxID error(%v)", err)
|
||||
return
|
||||
}
|
||||
page := newMaxID / batchSize
|
||||
if newMaxID%batchSize != 0 {
|
||||
page++
|
||||
}
|
||||
for i := 0; i < int(page); i++ {
|
||||
arg := new(model.QueryBcoinSalary)
|
||||
arg.StartID = int64(i) * batchSize
|
||||
arg.EndID = int64(i+1) * batchSize
|
||||
if arg.EndID > newMaxID {
|
||||
arg.EndID = newMaxID
|
||||
}
|
||||
arg.GiveNowStatus = -1
|
||||
var res []*model.VipBcoinSalary
|
||||
if res, err = s.dao.SelBcoinSalaryData(context.TODO(), arg.StartID, arg.EndID); err != nil {
|
||||
log.Error("s.dao.SelBcoinSalary(%+v) error(%+v)", arg, err)
|
||||
return
|
||||
}
|
||||
for _, v := range res {
|
||||
exitMap[s.makeBcoinMD5(v)] = 1
|
||||
}
|
||||
}
|
||||
|
||||
page = oldMaxID / batchSize
|
||||
if oldMaxID%batchSize != 0 {
|
||||
page++
|
||||
}
|
||||
for i := 0; i < int(page); i++ {
|
||||
startID := int64(i) * batchSize
|
||||
EndID := int64(i+1) * batchSize
|
||||
if EndID > oldMaxID {
|
||||
EndID = oldMaxID
|
||||
}
|
||||
var res []*model.VipBcoinSalary
|
||||
if res, err = s.dao.SelOldBcoinSalary(context.TODO(), startID, EndID); err != nil {
|
||||
log.Error("sel.OldBcoinSalary(startID:%v endID:%v) error(%+v)", startID, EndID, err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, v := range res {
|
||||
if exitMap[s.makeBcoinMD5(v)] == 0 {
|
||||
batch = append(batch, v)
|
||||
}
|
||||
}
|
||||
|
||||
if err = s.dao.BatchAddBcoinSalary(batch); err != nil {
|
||||
log.Error("s.dao.BatchAddBcoinSalary (%+v)", err)
|
||||
return
|
||||
}
|
||||
batch = nil
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) handleraddbcoinproc() {
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("service.handlerupdaterechargeorderproc panic(%v)", x)
|
||||
go s.handleraddbcoinproc()
|
||||
log.Info("service.handlerupdaterechargeorderproc recover")
|
||||
}
|
||||
}()
|
||||
for {
|
||||
msg := <-s.handlerAddBcoinSalary
|
||||
log.Info("cur bcoin msage:%+v", msg)
|
||||
for i := 0; i < s.c.Property.Retry; i++ {
|
||||
if err := s.dao.AddBcoinSalary(context.TODO(), msg); err != nil {
|
||||
log.Error("s.dao.addbcoinsalary(%+v) error(%+v)", msg, err)
|
||||
} else if err == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) handlerdelbcoinproc() {
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("service.handlerdelbcoinproc panic(%v)", x)
|
||||
go s.handlerdelbcoinproc()
|
||||
log.Info("service.handlerdelbcoinproc recover")
|
||||
}
|
||||
}()
|
||||
var err error
|
||||
for {
|
||||
msg := <-s.handlerDelBcoinSalary
|
||||
for i := 0; i < s.c.Property.Retry; i++ {
|
||||
if err = s.dao.DelBcoinSalary(context.TODO(), msg.Payday, msg.Mid); err == nil {
|
||||
break
|
||||
}
|
||||
log.Error("s.dao.DelBcoinSalary(msg:%+v) error(%+v)", msg, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) handlerupdatebcoinproc() {
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("service.handlerupdaterechargeorderproc panic(%v)", x)
|
||||
go s.handlerupdatebcoinproc()
|
||||
log.Info("service.handlerupdaterechargeorderproc recover")
|
||||
}
|
||||
}()
|
||||
var err error
|
||||
for {
|
||||
msg := <-s.handlerUpdateBcoinSalary
|
||||
for i := 0; i < s.c.Property.Retry; i++ {
|
||||
if err = s.dao.UpdateBcoinSalary(context.TODO(), msg.Payday, msg.Mid, msg.Status); err == nil {
|
||||
break
|
||||
}
|
||||
log.Error("s.dao.UpdateBcoinSalary(msg:%+v) error(%+v)", msg, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) sendBcoinJob() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
r = errors.WithStack(r.(error))
|
||||
log.Error("recover panic error(%+v)", r)
|
||||
}
|
||||
}()
|
||||
log.Info("sen bcoin job start ........................................ ")
|
||||
s.sendBcoin()
|
||||
log.Info("sen bcoin job end ........................................ ")
|
||||
}
|
||||
|
||||
func (s *Service) sendBcoin() {
|
||||
var (
|
||||
maxID int64
|
||||
batchSize int64 = 3000
|
||||
sendSize = 50
|
||||
err error
|
||||
)
|
||||
if maxID, err = s.dao.SelBcoinMaxID(context.TODO()); err != nil {
|
||||
log.Error("s.dao.selBcoinMaxID() error(%+v)", err)
|
||||
return
|
||||
}
|
||||
page := maxID / batchSize
|
||||
if maxID%batchSize != 0 {
|
||||
page++
|
||||
}
|
||||
now := time.Now()
|
||||
startMonth := now.AddDate(0, 0, 1-now.Day())
|
||||
endMonth := startMonth.AddDate(0, 1, 0)
|
||||
sendInfo := s.sendInfo()
|
||||
for i := 0; i < int(page); i++ {
|
||||
arg := new(model.QueryBcoinSalary)
|
||||
arg.StartID = int64(i) * batchSize
|
||||
arg.EndID = int64(i+1) * batchSize
|
||||
arg.GiveNowStatus = 0
|
||||
arg.Status = 0
|
||||
arg.StartMonth = xtime.Time(startMonth.Unix())
|
||||
arg.EndMonth = xtime.Time(endMonth.Unix())
|
||||
var res []*model.VipBcoinSalary
|
||||
if res, err = s.dao.SelBcoinSalary(context.TODO(), arg); err != nil {
|
||||
log.Error("s.dao.selBcoinSalary(%+v) error(%+v)", arg, err)
|
||||
return
|
||||
}
|
||||
pageSend := len(res) / sendSize
|
||||
if len(res)%sendSize != 0 {
|
||||
pageSend++
|
||||
}
|
||||
for j := 0; j < pageSend; j++ {
|
||||
start := j * sendSize
|
||||
end := int(j+1) * sendSize
|
||||
if end > len(res) {
|
||||
end = len(res)
|
||||
}
|
||||
if err = s.sendBocinNow(res[start:end], sendInfo.Amount, sendInfo.DueDate); err != nil {
|
||||
log.Error("%+v", err)
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) sendInfo() (r *model.BcoinSendInfo) {
|
||||
var (
|
||||
c time.Time
|
||||
day = s.c.Property.AnnualVipBcoinDay
|
||||
amount = s.c.Property.AnnualVipBcoinCouponMoney
|
||||
)
|
||||
r = new(model.BcoinSendInfo)
|
||||
r.Amount = int32(amount)
|
||||
r.DayOfMonth = day
|
||||
c = time.Now()
|
||||
c = c.AddDate(0, 1, int(day)-1-c.Day())
|
||||
r.DueDate = xtime.Time(c.Unix())
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) sendBocinNow(res []*model.VipBcoinSalary, amount int32, duTime xtime.Time) (err error) {
|
||||
var (
|
||||
mids []int64
|
||||
ids []int64
|
||||
)
|
||||
for _, v := range res {
|
||||
mids = append(mids, v.Mid)
|
||||
ids = append(ids, v.ID)
|
||||
}
|
||||
if err = s.dao.SendBcoin(context.TODO(), mids, amount, duTime, "127.0.0.1"); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = s.dao.UpdateBcoinSalaryBatch(context.TODO(), ids, 1); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func (s *Service) makeBcoinMD5(r *model.VipBcoinSalary) string {
|
||||
key := fmt.Sprintf("%v,%v,%v,%v,%v,%v", r.Mid, r.Memo, r.Amount, r.Payday.Time().Format("2006-01-02"), r.GiveNowStatus, r.Status)
|
||||
hash := md5.New()
|
||||
hash.Write([]byte(key))
|
||||
sum := hash.Sum(nil)
|
||||
return hex.EncodeToString(sum)
|
||||
}
|
226
app/job/main/vip/service/check_data.go
Normal file
226
app/job/main/vip/service/check_data.go
Normal file
@ -0,0 +1,226 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
"go-common/library/log"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// CheckUserData check vip_user_info data.
|
||||
func (s *Service) CheckUserData(c context.Context) (diffs map[int64]string, err error) {
|
||||
var (
|
||||
maxID int
|
||||
size = s.c.Property.BatchSize
|
||||
ids = []int64{}
|
||||
ousers = make(map[int64]*model.VipUserInfoOld, size)
|
||||
nusers = make(map[int64]*model.VipUserInfo, _ps)
|
||||
ou *model.VipUserInfoOld
|
||||
nu *model.VipUserInfo
|
||||
ok bool
|
||||
)
|
||||
diffs = make(map[int64]string)
|
||||
if maxID, err = s.dao.SelOldUserInfoMaxID(context.TODO()); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
page := maxID / size
|
||||
if maxID%size != 0 {
|
||||
page++
|
||||
}
|
||||
log.Info("check vip_user_info total(%d)", page)
|
||||
for i := 0; i < page; i++ {
|
||||
log.Info("check vip_user_info page index(%d) total(%d)", i, page)
|
||||
startID := i * size
|
||||
endID := (i + 1) * size
|
||||
if endID > maxID {
|
||||
endID = maxID
|
||||
}
|
||||
if ousers, err = s.dao.SelOldUserInfoMaps(context.TODO(), startID, endID); err != nil {
|
||||
return
|
||||
}
|
||||
j := 1
|
||||
for _, v := range ousers {
|
||||
ids = append(ids, v.Mid)
|
||||
if j%_ps == 0 || j == len(ousers) {
|
||||
if nusers, err = s.dao.SelVipByIds(context.TODO(), ids); err != nil {
|
||||
return
|
||||
}
|
||||
for _, mid := range ids {
|
||||
if ou, ok = ousers[mid]; !ok {
|
||||
diffs[mid] = "old not found"
|
||||
continue
|
||||
}
|
||||
if nu, ok = nusers[mid]; !ok {
|
||||
diffs[mid] = "new not found"
|
||||
continue
|
||||
}
|
||||
if nu.Type != ou.Type {
|
||||
diffs[mid] = "vip_type"
|
||||
continue
|
||||
}
|
||||
if nu.Status != ou.Status {
|
||||
diffs[mid] = "vip_status"
|
||||
continue
|
||||
}
|
||||
if !nu.OverdueTime.Time().Equal(ou.OverdueTime.Time()) {
|
||||
diffs[mid] = "vip_overdue_time"
|
||||
continue
|
||||
}
|
||||
if !nu.AnnualVipOverdueTime.Time().Equal(ou.AnnualVipOverdueTime.Time()) {
|
||||
diffs[mid] = "annual_vip_overdue_time"
|
||||
continue
|
||||
}
|
||||
if nu.PayType != ou.IsAutoRenew {
|
||||
diffs[mid] = "vip_pay_type"
|
||||
continue
|
||||
}
|
||||
if nu.PayChannelID != ou.PayChannelID {
|
||||
diffs[mid] = "pay_channel_id"
|
||||
continue
|
||||
}
|
||||
if !nu.IosOverdueTime.Time().Equal(ou.IosOverdueTime.Time()) {
|
||||
diffs[mid] = "ios_overdue_time"
|
||||
continue
|
||||
}
|
||||
}
|
||||
// reset
|
||||
ids = []int64{}
|
||||
}
|
||||
j++
|
||||
}
|
||||
log.Info("check index (%d) vip_user_info diff len (%d)", i, len(diffs))
|
||||
log.Info("check index (%d) vip_user_info diff data mids(%v)", i, diffs)
|
||||
time.Sleep(time.Millisecond * _defsleepmsec)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//CheckBcoinData check bcoin data
|
||||
func (s *Service) CheckBcoinData(c context.Context) (mids []int64, err error) {
|
||||
var (
|
||||
maxID int
|
||||
size = s.c.Property.BatchSize
|
||||
)
|
||||
if maxID, err = s.dao.SelMaxID(context.TODO()); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
page := maxID / size
|
||||
if maxID%size != 0 {
|
||||
page++
|
||||
}
|
||||
|
||||
for i := 0; i < page; i++ {
|
||||
startID := size * i
|
||||
endID := (i + 1) * size
|
||||
var res []*model.VipUserInfo
|
||||
if res, err = s.dao.SelUserInfos(context.TODO(), startID, endID); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
var (
|
||||
tempMids []int64
|
||||
bcoinMap map[int64][]*model.VipBcoinSalary
|
||||
oldBcoinMap map[int64][]*model.VipBcoinSalary
|
||||
)
|
||||
for _, v := range res {
|
||||
tempMids = append(tempMids, v.Mid)
|
||||
}
|
||||
|
||||
if bcoinMap, err = s.dao.SelBcoinSalaryDataMaps(context.TODO(), tempMids); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
|
||||
if oldBcoinMap, err = s.dao.SelOldBcoinSalaryDataMaps(context.TODO(), tempMids); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(bcoinMap) > len(oldBcoinMap) {
|
||||
for key, val := range bcoinMap {
|
||||
salaries := oldBcoinMap[key]
|
||||
if len(salaries) != len(val) {
|
||||
mids = append(mids, key)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for key, val := range oldBcoinMap {
|
||||
salaries := bcoinMap[key]
|
||||
if len(salaries) != len(val) {
|
||||
mids = append(mids, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
log.Info("cur not sync data mid is(%+v)", mids)
|
||||
return
|
||||
}
|
||||
|
||||
//CheckChangeHistory check change history data
|
||||
func (s *Service) CheckChangeHistory(c context.Context) (mids []int64, err error) {
|
||||
var (
|
||||
maxID int
|
||||
size = 2000
|
||||
)
|
||||
if maxID, err = s.dao.SelMaxID(context.TODO()); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
page := maxID / size
|
||||
if maxID%size != 0 {
|
||||
page++
|
||||
}
|
||||
|
||||
for i := 0; i < page; i++ {
|
||||
startID := size * i
|
||||
endID := (i + 1) * size
|
||||
var res []*model.VipUserInfo
|
||||
if res, err = s.dao.SelUserInfos(context.TODO(), startID, endID); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
tempMids []int64
|
||||
historyMap map[int64][]*model.VipChangeHistory
|
||||
oldHistoryMap map[int64][]*model.VipChangeHistory
|
||||
)
|
||||
|
||||
for _, v := range res {
|
||||
tempMids = append(tempMids, v.Mid)
|
||||
}
|
||||
|
||||
if historyMap, err = s.dao.SelChangeHistoryMaps(context.TODO(), tempMids); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
if oldHistoryMap, err = s.dao.SelOldChangeHistoryMaps(context.TODO(), tempMids); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(historyMap) > len(oldHistoryMap) {
|
||||
for key, val := range historyMap {
|
||||
histories := oldHistoryMap[key]
|
||||
if len(histories) != len(val) {
|
||||
mids = append(mids, key)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for key, val := range oldHistoryMap {
|
||||
histories := historyMap[key]
|
||||
if len(histories) != len(val) {
|
||||
mids = append(mids, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
log.Info("cur not sync data mid is(%+v)", mids)
|
||||
return
|
||||
}
|
66
app/job/main/vip/service/coupon.go
Normal file
66
app/job/main/vip/service/coupon.go
Normal file
@ -0,0 +1,66 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
xlog "log"
|
||||
"time"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
comol "go-common/app/service/main/coupon/model"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
func (s *Service) couponnotifyproc() {
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("couponnotifyproc panic(%v)", x)
|
||||
go s.couponnotifyproc()
|
||||
log.Info("couponnotifyproc recover")
|
||||
}
|
||||
}()
|
||||
for {
|
||||
f := <-s.notifycouponchan
|
||||
time.AfterFunc(2*time.Second, f)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) couponnotify(f func()) {
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("couponnotifyproc panic(%v)", x)
|
||||
}
|
||||
}()
|
||||
select {
|
||||
case s.notifycouponchan <- f:
|
||||
default:
|
||||
xlog.Panic("s.couponnotifyproc chan full!")
|
||||
}
|
||||
}
|
||||
|
||||
// CouponNotify coupon notify.
|
||||
func (s *Service) CouponNotify(c context.Context, o *model.VipPayOrderNewMsg) (err error) {
|
||||
var (
|
||||
state int8
|
||||
retrytimes = 3
|
||||
)
|
||||
if o == nil {
|
||||
return
|
||||
}
|
||||
if o.Status == model.SUCCESS {
|
||||
state = comol.AllowanceUseSuccess
|
||||
} else {
|
||||
state = comol.AllowanceUseFaild
|
||||
}
|
||||
for i := 0; i < retrytimes; i++ {
|
||||
if err = s.couponRPC.CouponNotify(c, &comol.ArgNotify{
|
||||
Mid: o.Mid,
|
||||
OrderNo: o.OrderNo,
|
||||
State: state,
|
||||
}); err != nil {
|
||||
log.Error("rpc.CouponNotify(%+v) error(%+v)", o, err)
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
return
|
||||
}
|
22
app/job/main/vip/service/coupon_test.go
Normal file
22
app/job/main/vip/service/coupon_test.go
Normal file
@ -0,0 +1,22 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
//go test -test.v -test.run TestCouponNotify
|
||||
func TestCouponNotify(t *testing.T) {
|
||||
Convey("TestCouponNotify ", t, func() {
|
||||
o := &model.VipPayOrderNewMsg{
|
||||
OrderNo: "1807211806450011799",
|
||||
Status: model.SUCCESS,
|
||||
Mid: 1,
|
||||
}
|
||||
err := s.CouponNotify(c, o)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
131
app/job/main/vip/service/frozen.go
Normal file
131
app/job/main/vip/service/frozen.go
Normal file
@ -0,0 +1,131 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
"go-common/library/log"
|
||||
"go-common/library/queue/databus"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func (s *Service) accloginproc() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
r = errors.WithStack(r.(error))
|
||||
log.Error("Runtime error caught: %+v", r)
|
||||
go s.accloginproc()
|
||||
}
|
||||
}()
|
||||
var (
|
||||
err error
|
||||
msgChan = s.accLogin.Messages()
|
||||
msg *databus.Message
|
||||
ok bool
|
||||
)
|
||||
for {
|
||||
msg, ok = <-msgChan
|
||||
log.Info("login ip msg %+v", string(msg.Value))
|
||||
if !ok {
|
||||
log.Info("accLogin msgChan closed")
|
||||
}
|
||||
if err = msg.Commit(); err != nil {
|
||||
log.Error("msg.Commit err(%+v)", err)
|
||||
}
|
||||
m := &model.LoginLog{}
|
||||
if err = json.Unmarshal([]byte(msg.Value), m); err != nil {
|
||||
log.Error("json.Unmarshal(%v) err(%+v)", m, err)
|
||||
continue
|
||||
}
|
||||
s.Frozen(context.TODO(), m)
|
||||
}
|
||||
}
|
||||
|
||||
// Frozen handle vip frozen logic.
|
||||
func (s *Service) Frozen(c context.Context, ll *model.LoginLog) (err error) {
|
||||
var (
|
||||
lc int64
|
||||
uvs *model.VipUserInfo
|
||||
ctx = context.TODO()
|
||||
)
|
||||
// 判定用户是否为vip
|
||||
if uvs, err = s.dao.VipStatus(ctx, ll.Mid); err != nil {
|
||||
log.Error("s.dao.VipStatus(%d)err(%+v)", ll.Mid, err)
|
||||
return
|
||||
}
|
||||
if uvs == nil || uvs.Status == model.VipStatusOverTime {
|
||||
log.Warn("user(%d) not vip.(%+v)", ll.Mid, uvs)
|
||||
return
|
||||
}
|
||||
// 判定是否为15分钟4次以上不同ip登录
|
||||
if err = s.dao.AddLogginIP(ctx, ll.Mid, ll.IP); err != nil {
|
||||
log.Error("s.dao.AddLogginIP(%d)err(%+v)", ll.Mid, err)
|
||||
return
|
||||
}
|
||||
if lc, err = s.dao.LoginCount(ctx, ll.Mid); err != nil {
|
||||
log.Error("s.dao.LoginCount(%d)err(%+v)", ll.Mid, err)
|
||||
return
|
||||
}
|
||||
if lc >= s.c.Property.FrozenLimit {
|
||||
if err = s.dao.Enqueue(ctx, ll.Mid, time.Now().Add(s.frozenDate).Unix()); err != nil {
|
||||
log.Error("enqueue error(%+v)", err)
|
||||
}
|
||||
if err = s.dao.SetVipFrozen(ctx, ll.Mid); err != nil {
|
||||
log.Error("set vip frozen err(%+v)", err)
|
||||
}
|
||||
//通知业务方清理缓存
|
||||
s.cleanCache(ll.Mid)
|
||||
if err = s.notifyOldVip(ll.Mid, -1); err != nil {
|
||||
log.Error("del vip java frozen err(%+v)", err)
|
||||
}
|
||||
log.Info("mid(%+v) frozen success", ll.Mid)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// unFrozenJob timing to unFrozen vip user
|
||||
func (s *Service) unFrozenJob() {
|
||||
log.Info("unfrozen job start........................................")
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
r = errors.WithStack(r.(error))
|
||||
log.Error("recover panic error(%+v)", r)
|
||||
}
|
||||
log.Info("unfrozen job end.............................")
|
||||
}()
|
||||
|
||||
var (
|
||||
err error
|
||||
mids []int64
|
||||
ctx = context.TODO()
|
||||
)
|
||||
if mids, err = s.dao.Dequeue(ctx); err != nil {
|
||||
log.Error("s.dao.Dequeue err(%+v)", err)
|
||||
return
|
||||
}
|
||||
for _, mid := range mids {
|
||||
if err = s.dao.RemQueue(ctx, mid); err != nil {
|
||||
log.Error("s.dao.RemQueue(%d)err(%+v)", mid, err)
|
||||
continue
|
||||
}
|
||||
if err = s.dao.DelCache(ctx, mid); err != nil {
|
||||
log.Error("del cache mid(%+v) err(%+v)", mid, err)
|
||||
}
|
||||
if err = s.dao.DelVipFrozen(ctx, mid); err != nil {
|
||||
log.Error("del vip frozen err(%+v)", err)
|
||||
}
|
||||
if err = s.notifyOldVip(mid, 0); err != nil {
|
||||
log.Error("del vip java frozen err(%+v)", err)
|
||||
}
|
||||
s.cleanCache(mid)
|
||||
log.Info("mid(%+v) unfrozen success", mid)
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME AFTER REMOVE JAVA.
|
||||
func (s *Service) notifyOldVip(mid, status int64) error {
|
||||
return s.dao.OldFrozenChange(mid, status)
|
||||
}
|
31
app/job/main/vip/service/frozen_test.go
Normal file
31
app/job/main/vip/service/frozen_test.go
Normal file
@ -0,0 +1,31 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
var (
|
||||
ctx = context.TODO()
|
||||
)
|
||||
|
||||
func Test_Frozen(t *testing.T) {
|
||||
Convey("test user frozen", t, func() {
|
||||
la := []uint32{1, 2, 3, 4, 5}
|
||||
for _, i := range la {
|
||||
s.dao.AddLogginIP(ctx, 7593666, i)
|
||||
}
|
||||
s.Frozen(ctx, &model.LoginLog{Mid: 7593666, IP: 234566})
|
||||
})
|
||||
}
|
||||
|
||||
func Test_UnFrozen(t *testing.T) {
|
||||
Test_Frozen(t)
|
||||
Convey("test user unfrozen", t, func() {
|
||||
s.unFrozenJob()
|
||||
})
|
||||
}
|
151
app/job/main/vip/service/message.go
Normal file
151
app/job/main/vip/service/message.go
Normal file
@ -0,0 +1,151 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
xtime "time"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
"go-common/library/log"
|
||||
"go-common/library/time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
maxSendMsgCount = 200
|
||||
willExpiredDay = 7
|
||||
hadExpiredDays = 14
|
||||
willExpiredMsg = "您还有%d天大会员即将到期,请尽快续期,享受更多特权!"
|
||||
willExpiredTitle = "大会员即将到期提醒"
|
||||
|
||||
hadExpiredMsg = "很抱歉的通知您,您的大会员已过期,请尽快续期享受更多特权!"
|
||||
hadExpiredTitle = "大会员过期提醒"
|
||||
|
||||
vipWillExpiredMsgCode = "10_1_2"
|
||||
vipHadExpiredMsgCode = "10_1_3"
|
||||
|
||||
systemNotify = 4
|
||||
)
|
||||
|
||||
func (s *Service) hadExpiredMsgJob() {
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("service.hadExpiredMsgJob panic(%v)", x)
|
||||
go s.hadExpiredMsgJob()
|
||||
log.Info("service.hadExpiredMsgJob recover")
|
||||
}
|
||||
}()
|
||||
log.Info("start send had expire msg job ...................")
|
||||
var (
|
||||
err error
|
||||
mids []int64
|
||||
)
|
||||
now := xtime.Now()
|
||||
startTime := now.AddDate(0, 0, -hadExpiredDays-1)
|
||||
endTime := now.AddDate(0, 0, -hadExpiredDays)
|
||||
|
||||
if mids, err = s.willExpireUser(time.Time(startTime.Unix()), time.Time(endTime.Unix()), model.VipStatusOverTime); err != nil {
|
||||
log.Error("will expire user(startTime:%v endTime:%v status:%v) error(%+v)", startTime, endTime, model.VipStatusOverTime, err)
|
||||
return
|
||||
}
|
||||
log.Info("send startTime(%v) endDate(%v) mids(%v)", startTime.Format("2006-01-02"), endTime.Format("2006-01-02"), mids)
|
||||
if err = s.batchSendMsg(mids, hadExpiredMsg, hadExpiredTitle, vipHadExpiredMsgCode, systemNotify); err != nil {
|
||||
log.Error("batch send msg error(%+v)", err)
|
||||
return
|
||||
}
|
||||
log.Info("end send had expire msg job..........................")
|
||||
}
|
||||
|
||||
func (s *Service) willExpiredMsgJob() {
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("service.hadExpiredMsgJob panic(%v)", x)
|
||||
go s.willExpiredMsgJob()
|
||||
log.Info("service.hadExpiredMsgJob recover")
|
||||
}
|
||||
}()
|
||||
log.Info("start send will expire msg job............................")
|
||||
var (
|
||||
err error
|
||||
mids []int64
|
||||
)
|
||||
now := xtime.Now()
|
||||
startTime := now.AddDate(0, 0, willExpiredDay)
|
||||
endTime := now.AddDate(0, 0, willExpiredDay+1)
|
||||
if mids, err = s.willExpireUser(time.Time(startTime.Unix()), time.Time(endTime.Unix()), model.VipStatusNotOverTime); err != nil {
|
||||
log.Error("will expire user(startTime:%v endTime:%v status:%v) error(%+v)", startTime, endTime, model.VipStatusNotOverTime, err)
|
||||
return
|
||||
}
|
||||
log.Info("send startTime(%v) endDate(%v) mids(%v)", startTime.Format("2006-01-02"), endTime.Format("2006-01-02"), mids)
|
||||
if err = s.batchSendMsg(mids, fmt.Sprintf(willExpiredMsg, willExpiredDay), willExpiredTitle, vipWillExpiredMsgCode, systemNotify); err != nil {
|
||||
log.Error("batch send msg error(%+v)", err)
|
||||
return
|
||||
}
|
||||
log.Info("end send will expire msg job............................")
|
||||
}
|
||||
|
||||
func (s *Service) willExpireUser(startTime time.Time, endTime time.Time, status int) (mids []int64, err error) {
|
||||
var (
|
||||
maxID int
|
||||
size = 10000
|
||||
)
|
||||
|
||||
if maxID, err = s.dao.SelMaxID(context.TODO()); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
page := maxID / size
|
||||
if maxID%size != 0 {
|
||||
page++
|
||||
}
|
||||
|
||||
for i := 0; i < page; i++ {
|
||||
startID := i * size
|
||||
endID := (i + 1) * size
|
||||
var tempMid []int64
|
||||
if tempMid, err = s.dao.SelVipUserInfos(context.TODO(), startID, endID, startTime, endTime, status); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
mids = append(mids, tempMid...)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) batchSendMsg(mids []int64, content string, title string, ms string, dataType int) (err error) {
|
||||
if len(mids) <= maxSendMsgCount && len(mids) >= 1 {
|
||||
var midsStr = ""
|
||||
for _, v := range mids {
|
||||
midsStr += fmt.Sprintf(",%v", v)
|
||||
}
|
||||
if err = s.dao.SendMultipMsg(context.TODO(), midsStr, content, title, ms, dataType); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
} else if len(mids) > maxSendMsgCount {
|
||||
page := len(mids) / maxSendMsgCount
|
||||
if len(mids)%maxSendMsgCount != 0 {
|
||||
page++
|
||||
}
|
||||
for i := 0; i < page; i++ {
|
||||
start := i * maxSendMsgCount
|
||||
end := (i + 1) * maxSendMsgCount
|
||||
if len(mids) < end {
|
||||
end = len(mids)
|
||||
}
|
||||
tempMids := mids[start:end]
|
||||
|
||||
var midsStr []string
|
||||
for _, v := range tempMids {
|
||||
midsStr = append(midsStr, fmt.Sprintf("%v", v))
|
||||
}
|
||||
if err = s.dao.SendMultipMsg(context.TODO(), strings.Join(midsStr, ","), content, title, ms, dataType); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
471
app/job/main/vip/service/order.go
Normal file
471
app/job/main/vip/service/order.go
Normal file
@ -0,0 +1,471 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
"go-common/library/log"
|
||||
xtime "go-common/library/time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
_autoRenewFailTwoMsg = "连续包月大会员今天凌晨续费又失败了,服务已暂停。如果想要再次享受连续包月大会员服务,请先取消连续包月,再去开通哦~"
|
||||
_autoRenewFailOneMsg = "连续包月大会员今天凌晨续费失败了,%s 0点将会再次重试。"
|
||||
_deadlineAutoRenewMsg = "您的连续包月服务将在%s 0点续费。"
|
||||
|
||||
_autoRenewFailTitle = "连续包月服务续费失败"
|
||||
_deadlineAutoRenewTitle = "连续包月服务即将续费"
|
||||
|
||||
_sleep = 20 * time.Millisecond
|
||||
|
||||
_maxtime = 20
|
||||
)
|
||||
|
||||
func (s *Service) handlerinsertorderproc() {
|
||||
var (
|
||||
err error
|
||||
)
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("service.handlerinsertorderproc panic(%v)", x)
|
||||
go s.handlerinsertorderproc()
|
||||
log.Info("service.handlerinsertorderproc recover")
|
||||
}
|
||||
}()
|
||||
for {
|
||||
order := <-s.handlerInsertOrder
|
||||
for i := 0; i < s.c.Property.Retry; i++ {
|
||||
if err = s.insertOrder(order); err == nil {
|
||||
break
|
||||
}
|
||||
log.Error("error(%+v)", err)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) insertOrder(r *model.VipPayOrder) (err error) {
|
||||
var aff int64
|
||||
if aff, err = s.dao.AddPayOrder(context.TODO(), r); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
if aff != 1 {
|
||||
return
|
||||
}
|
||||
log.Info("vip_pay_order sysn data(%+v)", r)
|
||||
rlog := new(model.VipPayOrderLog)
|
||||
rlog.Mid = r.Mid
|
||||
rlog.OrderNo = r.OrderNo
|
||||
rlog.Status = r.Status
|
||||
if _, err = s.dao.AddPayOrderLog(context.TODO(), rlog); err != nil {
|
||||
log.Error("add pay order log(%+v) error(%+v)", rlog, err)
|
||||
err = nil
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) handlerupdateorderproc() {
|
||||
var (
|
||||
err error
|
||||
flag bool
|
||||
)
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("service.handlerupdateorderproc panic(%v)", x)
|
||||
go s.handlerupdateorderproc()
|
||||
log.Info("service.handlerupdateorderproc recover")
|
||||
}
|
||||
}()
|
||||
for {
|
||||
order := <-s.handlerUpdateOrder
|
||||
flag = true
|
||||
for i := 0; i < s.c.Property.Retry; i++ {
|
||||
if err = s.updatePayOrder(context.TODO(), order); err == nil {
|
||||
flag = false
|
||||
break
|
||||
}
|
||||
log.Error("error(%+v)", err)
|
||||
}
|
||||
if flag {
|
||||
s.handlerFailPayOrder <- order
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) handlerfailpayorderproc() {
|
||||
var (
|
||||
err error
|
||||
)
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("service.handlerfailpayorderproc panic(%v)", x)
|
||||
go s.handlerfailpayorderproc()
|
||||
log.Info("service.handlerfailpayorderproc recover")
|
||||
}
|
||||
}()
|
||||
for {
|
||||
order := <-s.handlerFailPayOrder
|
||||
_time := 0
|
||||
for {
|
||||
if err = s.updatePayOrder(context.TODO(), order); err == nil {
|
||||
break
|
||||
}
|
||||
log.Error("pay order error(%+v)", err)
|
||||
_time++
|
||||
if _time > _maxtime {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) handlerfailrechargeorderproc() {
|
||||
var (
|
||||
eff int64
|
||||
err error
|
||||
)
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("service.handlerfailrechargeorderproc panic(%v)", x)
|
||||
go s.handlerfailrechargeorderproc()
|
||||
log.Info("service.handlerfailrechargeorderproc recover")
|
||||
}
|
||||
}()
|
||||
for {
|
||||
order := <-s.handlerFailRechargeOrder
|
||||
_time := 0
|
||||
for {
|
||||
if eff, err = s.dao.UpdateRechargeOrder(context.TODO(), order); err != nil {
|
||||
log.Error("error(%+v)", err)
|
||||
break
|
||||
}
|
||||
if eff > 0 {
|
||||
break
|
||||
}
|
||||
_time++
|
||||
if _time > _maxtime {
|
||||
break
|
||||
}
|
||||
time.Sleep(_sleep)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) handlerupdaterechargeorderproc() {
|
||||
var (
|
||||
eff int64
|
||||
err error
|
||||
flag bool
|
||||
)
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("service.handlerupdaterechargeorderproc panic(%v)", x)
|
||||
go s.handlerupdaterechargeorderproc()
|
||||
log.Info("service.handlerupdaterechargeorderproc recover")
|
||||
}
|
||||
}()
|
||||
for {
|
||||
order := <-s.handlerRechargeOrder
|
||||
flag = true
|
||||
for i := 0; i < s.c.Property.Retry; i++ {
|
||||
if eff, err = s.dao.UpdateRechargeOrder(context.TODO(), order); err != nil {
|
||||
log.Error("error(%+v)", err)
|
||||
continue
|
||||
}
|
||||
if eff > 0 {
|
||||
log.Info("update recharge order(%+v)", order)
|
||||
flag = false
|
||||
break
|
||||
}
|
||||
time.Sleep(_sleep)
|
||||
}
|
||||
if flag {
|
||||
s.handlerFailRechargeOrder <- order
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) updatePayOrder(c context.Context, r *model.VipPayOrder) (err error) {
|
||||
var eff int64
|
||||
if eff, err = s.dao.UpdatePayOrderStatus(c, r); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
if eff <= 0 {
|
||||
err = fmt.Errorf("order更新未执行(%+v)", r)
|
||||
time.Sleep(_sleep)
|
||||
return
|
||||
}
|
||||
log.Info("cur pay order update order(%+v)", r)
|
||||
|
||||
rlogKey := fmt.Sprintf("%v:%v", r.OrderNo, r.Status)
|
||||
if succeed := s.dao.AddTransferLock(c, rlogKey); succeed {
|
||||
rlog := new(model.VipPayOrderLog)
|
||||
rlog.Mid = r.Mid
|
||||
rlog.OrderNo = r.OrderNo
|
||||
rlog.Status = r.Status
|
||||
if _, err = s.dao.AddPayOrderLog(context.TODO(), rlog); err != nil {
|
||||
log.Error("add pay order log(%+v) error(%+v)", rlog, err)
|
||||
err = nil
|
||||
}
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) convertPayOrder(r *model.VipPayOrderOldMsg) (res *model.VipPayOrder) {
|
||||
res = new(model.VipPayOrder)
|
||||
res.Mid = r.Mid
|
||||
res.AppID = r.AppID
|
||||
res.AppSubID = r.AppSubID
|
||||
res.BuyMonths = r.BuyMonths
|
||||
res.Money = r.Money
|
||||
res.RechargeBp = r.RechargeBp
|
||||
res.OrderNo = r.OrderNo
|
||||
res.OrderType = r.OrderType
|
||||
res.PayType = r.PayType
|
||||
res.Platform = r.Platform
|
||||
res.Status = r.Status
|
||||
res.ToMid = r.Bmid
|
||||
res.Ver = r.Ver
|
||||
res.CouponMoney = r.CouponMoney
|
||||
if paymentTime, err := time.ParseInLocation("2006-01-02 15:04:05", r.PaymentTime, time.Local); err == nil {
|
||||
res.PaymentTime = xtime.Time(paymentTime.Unix())
|
||||
}
|
||||
res.Ctime = xtime.Time(parseTime(r.Ctime).Unix())
|
||||
res.Mtime = xtime.Time(parseTime(r.Mtime).Unix())
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) convertPayOrderByMsg(r *model.VipRechargeOrderMsg) (res *model.VipPayOrder) {
|
||||
res = new(model.VipPayOrder)
|
||||
res.Mid = r.PayMid
|
||||
res.OrderNo = r.PayOrderNo
|
||||
res.ThirdTradeNo = r.ThirdTradeNo
|
||||
res.RechargeBp = r.RechargeBp
|
||||
return
|
||||
}
|
||||
|
||||
func convertPayOrderOldToNew(r *model.VipPayOrderOld) (res *model.VipPayOrder) {
|
||||
res = new(model.VipPayOrder)
|
||||
res.Mid = r.Mid
|
||||
res.AppID = r.AppID
|
||||
res.AppSubID = r.AppSubID
|
||||
res.BuyMonths = r.BuyMonths
|
||||
res.Money = r.Money
|
||||
res.OrderNo = r.OrderNo
|
||||
res.OrderType = r.OrderType
|
||||
res.PayType = r.PayType
|
||||
res.Platform = r.Platform
|
||||
res.Status = r.Status
|
||||
res.ToMid = r.Bmid
|
||||
res.Ver = r.Ver
|
||||
res.PaymentTime = r.PaymentTime
|
||||
res.CouponMoney = r.CouponMoney
|
||||
return
|
||||
}
|
||||
|
||||
//HandlerPayOrder handler pay order
|
||||
func (s *Service) HandlerPayOrder() (err error) {
|
||||
var (
|
||||
size = 1000
|
||||
oldMaxID int
|
||||
)
|
||||
if oldMaxID, err = s.dao.SelOldOrderMaxID(context.TODO()); err != nil {
|
||||
log.Error("selOldOrderMaxID error(%+v)", err)
|
||||
return
|
||||
}
|
||||
|
||||
page := oldMaxID / size
|
||||
if oldMaxID%size != 0 {
|
||||
page++
|
||||
}
|
||||
for i := 0; i < page; i++ {
|
||||
startID := i * size
|
||||
endID := (i + 1) * size
|
||||
if endID > oldMaxID {
|
||||
endID = oldMaxID
|
||||
}
|
||||
var (
|
||||
res []*model.VipPayOrderOld
|
||||
batchOrder []*model.VipPayOrder
|
||||
orderNos []string
|
||||
oldRechargeOrder []*model.VipRechargeOrder
|
||||
)
|
||||
|
||||
rechargeMap := make(map[string]*model.VipRechargeOrder)
|
||||
if res, err = s.dao.SelOldPayOrder(context.TODO(), startID, endID); err != nil {
|
||||
log.Error("selOldPayOrder(startID:%v endID:%v) error(%+v)", startID, endID, err)
|
||||
return
|
||||
}
|
||||
for _, v := range res {
|
||||
batchOrder = append(batchOrder, convertPayOrderOldToNew(v))
|
||||
}
|
||||
|
||||
for _, v := range batchOrder {
|
||||
orderNos = append(orderNos, v.OrderNo)
|
||||
}
|
||||
if oldRechargeOrder, err = s.dao.SelOldRechargeOrder(context.TODO(), orderNos); err != nil {
|
||||
return
|
||||
}
|
||||
for _, v := range oldRechargeOrder {
|
||||
rechargeMap[v.PayOrderNo] = v
|
||||
}
|
||||
for _, v := range batchOrder {
|
||||
rechargeOrder := rechargeMap[v.OrderNo]
|
||||
if rechargeOrder != nil {
|
||||
v.ThirdTradeNo = rechargeOrder.ThirdTradeNo
|
||||
v.RechargeBp = rechargeOrder.RechargeBp
|
||||
}
|
||||
}
|
||||
if err = s.dao.BatchAddPayOrder(context.TODO(), batchOrder); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) willDedutionMsg() (err error) {
|
||||
var (
|
||||
size = 5000
|
||||
endID int
|
||||
now time.Time
|
||||
vips []*model.VipUserInfo
|
||||
)
|
||||
if now, err = time.ParseInLocation("2006-01-02", time.Now().Format("2006-01-02"), time.Local); err != nil {
|
||||
log.Error("time.ParseInLocation(%v) error(%+v)", time.Now(), err)
|
||||
return
|
||||
}
|
||||
start := now.AddDate(0, 0, 1)
|
||||
|
||||
end := start.AddDate(0, 0, 3)
|
||||
|
||||
if endID, err = s.dao.SelMaxID(context.TODO()); err != nil {
|
||||
return
|
||||
}
|
||||
page := endID / size
|
||||
if endID%size != 0 {
|
||||
page++
|
||||
}
|
||||
for i := 0; i < page; i++ {
|
||||
startID := i * size
|
||||
eID := (i + 1) * size
|
||||
if vips, err = s.dao.SelVipUsers(context.TODO(), startID, eID, xtime.Time(start.Unix()), xtime.Time(end.Unix())); err != nil {
|
||||
continue
|
||||
}
|
||||
for _, v := range vips {
|
||||
if v.OverdueTime.Time().Equal(start) {
|
||||
s.dao.SendMultipMsg(context.TODO(), fmt.Sprintf("%v", v.Mid),
|
||||
_autoRenewFailTwoMsg,
|
||||
_autoRenewFailTitle,
|
||||
vipWillExpiredMsgCode,
|
||||
systemNotify)
|
||||
} else if start.AddDate(0, 0, 1).Equal(v.OverdueTime.Time()) {
|
||||
s.dao.SendMultipMsg(context.TODO(), fmt.Sprintf("%v", v.Mid),
|
||||
fmt.Sprint(_autoRenewFailOneMsg, v.OverdueTime.Time().AddDate(0, 0, -1).Format("2006-01-02")),
|
||||
_autoRenewFailTitle,
|
||||
vipWillExpiredMsgCode,
|
||||
systemNotify)
|
||||
} else if start.AddDate(0, 0, 2).Equal(v.OverdueTime.Time()) {
|
||||
s.dao.SendMultipMsg(context.TODO(), fmt.Sprintf("%v", v.Mid),
|
||||
fmt.Sprint(_deadlineAutoRenewMsg, start.Format("2006-01-02")),
|
||||
_deadlineAutoRenewTitle,
|
||||
vipWillExpiredMsgCode,
|
||||
systemNotify)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) autoRenews() (err error) {
|
||||
//var (
|
||||
// size = 5000
|
||||
// endID int
|
||||
// now time.Time
|
||||
// vips []*model.VipUserInfo
|
||||
// price float64
|
||||
//)
|
||||
//if now, err = time.ParseInLocation("2006-01-02", time.Now().Format("2006-01-02"), time.Local); err != nil {
|
||||
// log.Error("time.ParseInLocation(%v) error(%+v)", time.Now(), err)
|
||||
// return
|
||||
//}
|
||||
//
|
||||
//start := now.AddDate(0, 0, 1)
|
||||
//
|
||||
//end := start.AddDate(0, 0, 3)
|
||||
//if price, err = s.vipRPC.Price(context.TODO(), 1, xmodel.DevicePC, xmodel.AutoRenew, 1); err != nil {
|
||||
// err = errors.WithStack(err)
|
||||
// return
|
||||
//}
|
||||
//if endID, err = s.dao.SelMaxID(context.TODO()); err != nil {
|
||||
// return
|
||||
//}
|
||||
//
|
||||
//page := endID / size
|
||||
//if endID%size != 0 {
|
||||
// page++
|
||||
//}
|
||||
//for i := 0; i < page; i++ {
|
||||
// startID := i * size
|
||||
// eID := (i + 1) * size
|
||||
// if vips, err = s.dao.SelVipUsers(context.TODO(), startID, eID, xtime.Time(start.Unix()), xtime.Time(end.Unix())); err != nil {
|
||||
// err = errors.WithStack(err)
|
||||
// continue
|
||||
// }
|
||||
// for _, v := range vips {
|
||||
// var params = make(map[string]interface{}, 0)
|
||||
// if params, err = s.vipRPC.CreateOrderPlatfrom(context.TODO(), int64(v.Mid), 0, 0, 1, price, xmodel.DevicePC, 5, xmodel.AutoRenew, ""); err != nil {
|
||||
// log.Error("CreateOrderPlatform error(%+v)", err)
|
||||
// continue
|
||||
// }
|
||||
// params["payChannelId"] = v.PayChannelId
|
||||
// params["payChannel"] = s.c.Property.PayMapping[strconv.Itoa(int(v.PayChannelId))]
|
||||
// if err = s.dao.PayOrder(context.TODO(), params); err != nil {
|
||||
// log.Error("handler fail orderId->%v mid:%v", params["orderId"], v.Mid)
|
||||
// continue
|
||||
// }
|
||||
// log.Info("handler success orderId:%v mid:%v", params["orderId"], v.Mid)
|
||||
// }
|
||||
//}
|
||||
return
|
||||
}
|
||||
|
||||
// AutoRenewJob auto renew job.
|
||||
//func (s *Service) autoRenewJob() {
|
||||
// defer func() {
|
||||
// if x := recover(); x != nil {
|
||||
// log.Error("service.autoRenewJob panic(%v)", x)
|
||||
// go s.autoRenewJob()
|
||||
// log.Info("service.autoRenewJob recover")
|
||||
// }
|
||||
// }()
|
||||
// log.Info("auto renew job start.................................")
|
||||
// var err error
|
||||
// if err = s.autoRenews(); err != nil {
|
||||
// log.Error("autoRenews error(%+v)", err)
|
||||
// }
|
||||
// log.Info("auto renew job end...................................")
|
||||
//}
|
||||
|
||||
// SendMessageJob send message job.
|
||||
func (s *Service) sendMessageJob() {
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("service.sendMessageJob panic(%v)", x)
|
||||
go s.sendMessageJob()
|
||||
log.Info("service.sendMessageJob recover")
|
||||
}
|
||||
}()
|
||||
|
||||
log.Info("sendMessage job start .........................")
|
||||
s.willDedutionMsg()
|
||||
log.Info("sendMessage job end .........................")
|
||||
}
|
20
app/job/main/vip/service/order_test.go
Normal file
20
app/job/main/vip/service/order_test.go
Normal file
@ -0,0 +1,20 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func Test_handlerPayOrder(t *testing.T) {
|
||||
Convey("handler pay order", t, func() {
|
||||
s.HandlerPayOrder()
|
||||
})
|
||||
}
|
||||
|
||||
func Test_autoRenews(t *testing.T) {
|
||||
Convey("autorenews ", t, func() {
|
||||
err := s.autoRenews()
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
115
app/job/main/vip/service/push.go
Normal file
115
app/job/main/vip/service/push.go
Normal file
@ -0,0 +1,115 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
"go-common/library/log"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
_fail = 2
|
||||
|
||||
_handlering = 2
|
||||
_finish = 3
|
||||
|
||||
_nomarl = 0
|
||||
|
||||
_statusnomarl = 1
|
||||
)
|
||||
|
||||
func (s *Service) pushDataJob() {
|
||||
log.Info("push data job start..................")
|
||||
if succeed := s.dao.AddTransferLock(context.TODO(), "lock:pushDatajob"); succeed {
|
||||
if err := s.pushData(context.TODO()); err != nil {
|
||||
log.Error("error(%+v)", err)
|
||||
}
|
||||
}
|
||||
log.Info("push data job end.....................")
|
||||
}
|
||||
|
||||
func (s *Service) pushData(c context.Context) (err error) {
|
||||
var (
|
||||
res []*model.VipPushData
|
||||
pushDataMap = make(map[int64]*model.VipPushData)
|
||||
pushMidsMap = make(map[int64][]int64)
|
||||
maxID int
|
||||
size = s.c.Property.BatchSize
|
||||
vips []*model.VipUserInfo
|
||||
curDate time.Time
|
||||
rel *model.VipPushResq
|
||||
)
|
||||
now := time.Now()
|
||||
format := now.Format("2006-01-02")
|
||||
if curDate, err = time.ParseInLocation("2006-01-02", format, time.Local); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
if res, err = s.dao.PushDatas(c, format); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
if len(res) == 0 {
|
||||
log.Info("not need reduce push data.........")
|
||||
return
|
||||
}
|
||||
for _, v := range res {
|
||||
pushDataMap[v.ID] = v
|
||||
}
|
||||
if maxID, err = s.dao.SelMaxID(c); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
page := maxID / size
|
||||
if maxID%size != 0 {
|
||||
page++
|
||||
}
|
||||
for i := 0; i < page; i++ {
|
||||
startID := i * size
|
||||
endID := (i + 1) * size
|
||||
if vips, err = s.dao.SelUserInfos(context.TODO(), startID, endID); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
for _, v := range vips {
|
||||
for key, val := range pushDataMap {
|
||||
startDate := curDate.AddDate(0, 0, int(val.ExpiredDayStart))
|
||||
endDate := curDate.AddDate(0, 0, int(val.ExpiredDayEnd))
|
||||
if !(v.OverdueTime.Time().Before(startDate) || v.OverdueTime.Time().After(endDate)) && v.PayType == model.Normal && val.DisableType == _nomarl && val.Status != _fail {
|
||||
mids := pushMidsMap[key]
|
||||
mids = append(mids, v.Mid)
|
||||
pushMidsMap[key] = mids
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for key, val := range pushMidsMap {
|
||||
data := pushDataMap[key]
|
||||
var status int8
|
||||
progressStatus := data.ProgressStatus
|
||||
pushedCount := data.PushedCount
|
||||
if rel, err = s.dao.PushData(context.TODO(), val, data, format); err != nil {
|
||||
log.Error("push data error(%+v)", err)
|
||||
continue
|
||||
}
|
||||
if rel.Code != 0 {
|
||||
status = _fail
|
||||
} else {
|
||||
pushedCount++
|
||||
if pushedCount == data.PushTotalCount {
|
||||
progressStatus = _finish
|
||||
} else {
|
||||
progressStatus = _handlering
|
||||
}
|
||||
status = _statusnomarl
|
||||
}
|
||||
if err = s.dao.UpdatePushData(context.TODO(), status, progressStatus, pushedCount, rel.Code, rel.Data, data.ID); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
349
app/job/main/vip/service/salary.go
Normal file
349
app/job/main/vip/service/salary.go
Normal file
@ -0,0 +1,349 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
"go-common/library/log"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
//ScanSalaryVideoCoupon scan all vip user to salary video coupon.
|
||||
func (s *Service) ScanSalaryVideoCoupon(c context.Context) (err error) {
|
||||
var (
|
||||
userInfos []*model.VipInfoDB
|
||||
size = 100
|
||||
endID int
|
||||
now = time.Now()
|
||||
dv = now.Format("2006_01")
|
||||
y = now.Year()
|
||||
m = now.Month()
|
||||
salaryDate = time.Date(y, m, s.c.Property.SalaryDay, 0, 0, 0, 0, time.Local)
|
||||
)
|
||||
for {
|
||||
if endID, err = s.dao.SelUserInfoMaxID(context.TODO()); err != nil {
|
||||
log.Error("s.dao.SelMaxID error(%v)", err)
|
||||
time.Sleep(time.Minute * 2)
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
page := endID / size
|
||||
if endID%size != 0 {
|
||||
page++
|
||||
}
|
||||
for i := 0; i < page; {
|
||||
log.Info("salary page(%d) total(%d) ....................................", i, page)
|
||||
startID := i * size
|
||||
eID := (i + 1) * size
|
||||
if userInfos, err = s.dao.SelEffectiveScopeVipList(context.TODO(), startID, eID); err != nil {
|
||||
log.Error("s.dao.SelEffectiveScopeVipList error(%v)", err)
|
||||
time.Sleep(time.Second * 5)
|
||||
continue
|
||||
}
|
||||
i++
|
||||
for _, v := range userInfos {
|
||||
time.Sleep(time.Duration(s.c.Property.SalaryVideoCouponnIterval))
|
||||
var (
|
||||
vipType = model.NotVip
|
||||
)
|
||||
if v.Status != model.VipStatusNotOverTime && v.Status != model.VipStatusFrozen {
|
||||
continue
|
||||
}
|
||||
if salaryDate.Before(v.OverdueTime.Time()) {
|
||||
vipType = model.Vip
|
||||
if salaryDate.Before(v.AnnualVipOverdueTime.Time()) {
|
||||
vipType = model.AnnualVip
|
||||
}
|
||||
}
|
||||
if vipType == model.NotVip {
|
||||
continue
|
||||
}
|
||||
day := v.OverdueTime.Time().Sub(v.RecentTime.Time()).Hours() / model.DayOfHour
|
||||
if day < model.VipDaysMonth {
|
||||
continue
|
||||
}
|
||||
if err = s.salaryCoupon(c, v.Mid, model.TimingSalaryType, int8(vipType), dv, model.CouponSalaryTiming); err != nil {
|
||||
err = errors.Wrapf(err, "salaryCoupon mid(%d)(%v)", v.Mid, v)
|
||||
log.Error("%+v", err)
|
||||
continue
|
||||
}
|
||||
log.Info("salary suc mid(%d) ....................................", v.Mid)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// salaryCoupon salary coupon.
|
||||
func (s *Service) salaryCoupon(c context.Context, mid int64, salaryType int8, vipType int8, dv string, atonce int8) (err error) {
|
||||
var (
|
||||
logs []*model.VideoCouponSalaryLog
|
||||
hs = map[int8]int64{} // key:coupontype value:salarycount
|
||||
ms map[string]int64 // key:viptype value:salarycount
|
||||
)
|
||||
if logs, err = s.dao.SalaryVideoCouponList(c, mid, dv); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
for _, v := range logs {
|
||||
hs[v.CouponType] = hs[v.CouponType] + v.CouponCount
|
||||
}
|
||||
for _, v := range s.c.Property.SalaryCouponTypes {
|
||||
ms = s.c.Property.SalaryCouponMaps[fmt.Sprintf("%d", v)]
|
||||
if len(ms) != 0 {
|
||||
if salaryType == model.VipSupplyType {
|
||||
if hs[v] == 0 {
|
||||
hs[v] = ms[fmt.Sprintf("%d", model.AnnualVip)] - ms[fmt.Sprintf("%d", model.Vip)]
|
||||
} else {
|
||||
hs[v] = ms[fmt.Sprintf("%d", model.AnnualVip)] - hs[v]
|
||||
}
|
||||
} else {
|
||||
hs[v] = ms[fmt.Sprintf("%d", vipType)] - hs[v]
|
||||
}
|
||||
}
|
||||
}
|
||||
for k, count := range hs {
|
||||
var (
|
||||
token string
|
||||
tokenfmt string
|
||||
)
|
||||
if count <= 0 {
|
||||
continue
|
||||
}
|
||||
tokenfmt = s.c.Property.SalaryCouponBatchNoMaps[fmt.Sprintf("%d", k)]
|
||||
if len(tokenfmt) == 0 {
|
||||
continue
|
||||
}
|
||||
token = fmt.Sprintf(tokenfmt, atonce, dv)
|
||||
if err = s.dao.SalaryCoupon(c, mid, k, count, token); err != nil {
|
||||
err = errors.Wrapf(err, "s.dao.SalaryCoupon(%d)", mid)
|
||||
return
|
||||
}
|
||||
l := &model.VideoCouponSalaryLog{
|
||||
Mid: mid,
|
||||
CouponCount: count,
|
||||
State: model.HadSalaryState,
|
||||
Type: salaryType,
|
||||
CouponType: k,
|
||||
}
|
||||
if err = s.dao.AddSalaryLog(c, l, dv); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
if s.c.Property.MsgOpen {
|
||||
var (
|
||||
title string
|
||||
content string
|
||||
)
|
||||
title = s.c.Property.SalaryCouponMsgTitleMaps[fmt.Sprintf("%d", k)]
|
||||
if len(title) == 0 {
|
||||
continue
|
||||
}
|
||||
if salaryType == model.VipSupplyType {
|
||||
content = s.c.Property.SalaryCouponMsgSupplyContentMaps[fmt.Sprintf("%d", k)]
|
||||
if len(content) == 0 {
|
||||
continue
|
||||
}
|
||||
content = fmt.Sprintf(content, count)
|
||||
} else {
|
||||
content = s.c.Property.SalaryCouponMsgContentMaps[fmt.Sprintf("%d", k)]
|
||||
if len(content) == 0 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
s.sendmessage(func() {
|
||||
s.dao.SendMultipMsg(context.TODO(), fmt.Sprintf("%d", mid), content,
|
||||
title, model.MsgCouponSalaryMc, model.MsgSystemNotify)
|
||||
})
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// SalaryVideoCouponAtOnce salary video coupon at once.
|
||||
func (s *Service) SalaryVideoCouponAtOnce(c context.Context, nvip *model.VipUserInfoMsg, ovip *model.VipUserInfoMsg, act string) (res int, err error) {
|
||||
if act == _insertAction {
|
||||
if err = s.salaryInsertAct(c, nvip); err != nil {
|
||||
err = errors.Wrapf(err, "salaryInsertAct (%v)", nvip)
|
||||
return
|
||||
}
|
||||
} else if act == _updateAction {
|
||||
if err = s.salaryUpdateAct(c, nvip, ovip); err != nil {
|
||||
err = errors.Wrapf(err, "salaryInsertAct (%v)", nvip)
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) salaryInsertAct(c context.Context, nvip *model.VipUserInfoMsg) (err error) {
|
||||
var (
|
||||
now = time.Now()
|
||||
otime time.Time
|
||||
aotime time.Time
|
||||
vipType = model.NotVip
|
||||
zeroTime = now.AddDate(-10, 0, 0)
|
||||
salaryType int8
|
||||
dv = now.Format("2006_01")
|
||||
)
|
||||
otime, err = time.ParseInLocation(model.TimeFormatSec, nvip.OverdueTime, time.Local)
|
||||
if err != nil {
|
||||
log.Error("time.ParseInLocation error(%v)", errors.Wrapf(err, "time(%s)", nvip.OverdueTime))
|
||||
otime = zeroTime
|
||||
err = nil
|
||||
}
|
||||
aotime, err = time.ParseInLocation(model.TimeFormatSec, nvip.AnnualVipOverdueTime, time.Local)
|
||||
if err != nil {
|
||||
aotime = zeroTime
|
||||
err = nil
|
||||
}
|
||||
if nvip.Status != model.VipStatusNotOverTime && nvip.Status != model.VipStatusFrozen {
|
||||
return
|
||||
}
|
||||
days := otime.Sub(now).Hours() / model.DayOfHour
|
||||
if days < model.VipDaysMonth {
|
||||
log.Info("cur user not enough send coupon (%+v)", nvip)
|
||||
return
|
||||
}
|
||||
if now.Before(otime) {
|
||||
vipType = model.Vip
|
||||
if now.Before(aotime) {
|
||||
vipType = model.AnnualVip
|
||||
}
|
||||
}
|
||||
switch vipType {
|
||||
case model.Vip:
|
||||
salaryType = model.NormalVipSalaryType
|
||||
case model.AnnualVip:
|
||||
salaryType = model.AnnualVipSalaryType
|
||||
default:
|
||||
return
|
||||
}
|
||||
if err = s.salaryCoupon(c, int64(nvip.Mid), salaryType, int8(vipType), dv, model.CouponSalaryAtonce); err != nil {
|
||||
err = errors.Wrapf(err, "salaryCoupon mid(%d)(%v)", nvip.Mid, nvip)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) salaryUpdateAct(c context.Context, nvip *model.VipUserInfoMsg, ovip *model.VipUserInfoMsg) (err error) {
|
||||
var (
|
||||
ovType int
|
||||
nvType int
|
||||
expire bool
|
||||
now = time.Now()
|
||||
zeroTime = now.AddDate(-10, 0, 0)
|
||||
ntime time.Time
|
||||
oatime time.Time
|
||||
natime time.Time
|
||||
salaryType int8
|
||||
dv = now.Format("2006_01")
|
||||
)
|
||||
ntime, err = time.ParseInLocation(model.TimeFormatSec, nvip.OverdueTime, time.Local)
|
||||
if err != nil {
|
||||
log.Error("time.ParseInLocation error(%v)", errors.Wrapf(err, "time(%s)", nvip.OverdueTime))
|
||||
ntime = zeroTime
|
||||
err = nil
|
||||
}
|
||||
natime, err = time.ParseInLocation(model.TimeFormatSec, nvip.AnnualVipOverdueTime, time.Local)
|
||||
if err != nil {
|
||||
natime = zeroTime
|
||||
err = nil
|
||||
}
|
||||
// check OverdueTime time.
|
||||
if ntime.Before(now) {
|
||||
return
|
||||
}
|
||||
nvType = model.Vip
|
||||
// check AnnualVipOverdueTime time.
|
||||
if now.Before(natime) {
|
||||
nvType = model.AnnualVip
|
||||
}
|
||||
// check old vip info expire.
|
||||
expire, _ = s.judgeVipExpire(c, ovip)
|
||||
if expire {
|
||||
//check open days is enough 31
|
||||
days := ntime.Sub(now).Hours() / model.DayOfHour
|
||||
if days < model.VipDaysMonth {
|
||||
log.Info("cur user not enough send coupon (%+v)", nvip)
|
||||
return
|
||||
}
|
||||
if nvType == model.Vip {
|
||||
// expire vip -> vip
|
||||
salaryType = model.NormalVipSalaryType
|
||||
} else if nvType == model.AnnualVip {
|
||||
// expire vip -> annual vip
|
||||
salaryType = model.AnnualVipSalaryType
|
||||
}
|
||||
} else {
|
||||
if ovip.Type == model.Vip {
|
||||
ovType = model.Vip
|
||||
}
|
||||
|
||||
oatime, err = time.ParseInLocation(model.TimeFormatSec, ovip.AnnualVipOverdueTime, time.Local)
|
||||
if err != nil {
|
||||
oatime = zeroTime
|
||||
err = nil
|
||||
}
|
||||
if ovip.Type == model.AnnualVip && oatime.After(now) {
|
||||
ovType = model.AnnualVip
|
||||
}
|
||||
if ovType == model.Vip && nvType == model.AnnualVip {
|
||||
// normal vip -> annual vip
|
||||
salaryType = model.VipSupplyType
|
||||
}
|
||||
// short vip -> normal vip
|
||||
recentTime := parseTime(ovip.RecentTime)
|
||||
otime := parseTime(ovip.OverdueTime)
|
||||
days := otime.Sub(recentTime).Hours() / model.DayOfHour
|
||||
if days < model.VipDaysMonth {
|
||||
//check open days is enough 31
|
||||
days := ntime.Sub(now).Hours() / model.DayOfHour
|
||||
if days < model.VipDaysMonth {
|
||||
log.Info("cur user not enough send coupon (%+v)", nvip)
|
||||
return
|
||||
}
|
||||
if nvType == model.Vip {
|
||||
// expire vip -> vip
|
||||
salaryType = model.NormalVipSalaryType
|
||||
} else if nvType == model.AnnualVip {
|
||||
// expire vip -> annual vip
|
||||
salaryType = model.AnnualVipSalaryType
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
switch salaryType {
|
||||
case model.NormalVipSalaryType, model.AnnualVipSalaryType, model.VipSupplyType:
|
||||
if err = s.salaryCoupon(c, int64(nvip.Mid), salaryType, int8(nvType), dv, model.CouponSalaryAtonce); err != nil {
|
||||
err = errors.Wrapf(err, "salaryCoupon mid(%d)(%v)", int64(nvip.Mid), nvip)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// judgeVipExpire judge vip is expire.
|
||||
func (s *Service) judgeVipExpire(c context.Context, v *model.VipUserInfoMsg) (expire bool, err error) {
|
||||
var (
|
||||
now = time.Now()
|
||||
overdueTime time.Time
|
||||
zeroTime = now.AddDate(-10, 0, 0)
|
||||
)
|
||||
if v.Status != model.VipStatusNotOverTime && v.Status != model.VipStatusFrozen {
|
||||
expire = true
|
||||
return
|
||||
}
|
||||
overdueTime, err = time.ParseInLocation(model.TimeFormatSec, v.OverdueTime, time.Local)
|
||||
if err != nil {
|
||||
log.Error("time.ParseInLocation error(%v)", errors.Wrapf(err, "time(%s)", v.OverdueTime))
|
||||
overdueTime = zeroTime
|
||||
err = nil
|
||||
}
|
||||
if overdueTime.Before(now) {
|
||||
expire = true
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
53
app/job/main/vip/service/salary_data.go
Normal file
53
app/job/main/vip/service/salary_data.go
Normal file
@ -0,0 +1,53 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
"go-common/library/log"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
//ScanSalaryLog scan salary log.
|
||||
func (s *Service) ScanSalaryLog(c context.Context) (err error) {
|
||||
var (
|
||||
dv = time.Now().Format("2006_01")
|
||||
olds []*model.OldSalaryLog
|
||||
size = 1000
|
||||
endID = 0
|
||||
)
|
||||
if endID, err = s.dao.SalaryLogMaxID(context.TODO(), dv); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
page := endID / size
|
||||
if endID%size != 0 {
|
||||
page++
|
||||
}
|
||||
for i := 0; i < page; {
|
||||
startID := i * size
|
||||
eID := (i + 1) * size
|
||||
if olds, err = s.dao.SelOldSalaryList(context.TODO(), startID, eID, dv); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
i++
|
||||
for _, v := range olds {
|
||||
l := &model.VideoCouponSalaryLog{
|
||||
Mid: v.Mid,
|
||||
CouponCount: v.CouponCount,
|
||||
State: v.State,
|
||||
Type: v.Type,
|
||||
CouponType: model.SalaryCouponType,
|
||||
}
|
||||
if err = s.dao.AddSalaryLog(context.TODO(), l, dv); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
log.Error("+%v", err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
99
app/job/main/vip/service/salary_test.go
Normal file
99
app/job/main/vip/service/salary_test.go
Normal file
@ -0,0 +1,99 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
// go test -test.v -test.run TestServiceSalaryCoupon
|
||||
func TestServiceSalaryCoupon(t *testing.T) {
|
||||
Convey("TestServiceSalaryCoupon", t, func() {
|
||||
var (
|
||||
err error
|
||||
mid int64 = 999
|
||||
st int8 = model.TimingSalaryType
|
||||
vt int8 = model.AnnualVip
|
||||
dv = time.Now().Format("2006_01")
|
||||
atonce = model.CouponSalaryTiming
|
||||
)
|
||||
err = s.salaryCoupon(c, mid, st, vt, dv, atonce)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
// go test -test.v -test.run TestServiceSalaryInsertAct
|
||||
func TestServiceSalaryInsertAct(t *testing.T) {
|
||||
Convey("TestServiceSalaryCoupon", t, func() {
|
||||
var (
|
||||
err error
|
||||
nvip = &model.VipUserInfoMsg{
|
||||
Mid: 9995,
|
||||
Status: 1,
|
||||
OverdueTime: "2018-06-11 18:27:12",
|
||||
AnnualVipOverdueTime: "2018-06-09 18:27:12",
|
||||
}
|
||||
)
|
||||
err = s.salaryInsertAct(c, nvip)
|
||||
So(err, ShouldBeNil)
|
||||
nvip.Mid = 88881
|
||||
nvip.OverdueTime = "2018-07-31 18:27:12"
|
||||
nvip.AnnualVipOverdueTime = "2018-07-31 18:27:12"
|
||||
err = s.salaryInsertAct(c, nvip)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
// go test -test.v -test.run TestServiceSalaryUpdateAct
|
||||
func TestServiceSalaryUpdateAct(t *testing.T) {
|
||||
Convey("TestServiceSalaryUpdateAct", t, func() {
|
||||
var (
|
||||
err error
|
||||
nvip = &model.VipUserInfoMsg{
|
||||
Mid: 65,
|
||||
Status: 2,
|
||||
OverdueTime: "2019-06-11 18:27:12",
|
||||
AnnualVipOverdueTime: "2019-06-11 18:27:12",
|
||||
}
|
||||
ovip = &model.VipUserInfoMsg{
|
||||
Mid: 65,
|
||||
Status: 2,
|
||||
OverdueTime: "2018-06-16 18:27:12",
|
||||
AnnualVipOverdueTime: "2018-06-09 18:27:12",
|
||||
Type: 1,
|
||||
}
|
||||
)
|
||||
// vip -> a vip
|
||||
err = s.salaryUpdateAct(c, nvip, ovip)
|
||||
So(err, ShouldBeNil)
|
||||
// not vip -> vip
|
||||
ovip.OverdueTime = "2017-06-11 18:27:12"
|
||||
nvip.OverdueTime = "2018-07-31 18:27:12"
|
||||
nvip.AnnualVipOverdueTime = "2018-07-31 18:27:12"
|
||||
ovip.Mid = 66
|
||||
nvip.Mid = 66
|
||||
err = s.salaryUpdateAct(c, nvip, ovip)
|
||||
So(err, ShouldBeNil)
|
||||
// vip - > a vip
|
||||
ovip.OverdueTime = "2018-08-19 18:27:12"
|
||||
nvip.AnnualVipOverdueTime = "2019-06-11 18:27:12"
|
||||
ovip.Mid = 66
|
||||
nvip.Mid = 66
|
||||
err = s.salaryUpdateAct(c, nvip, ovip)
|
||||
So(err, ShouldBeNil)
|
||||
nvip.Mid = 67
|
||||
err = s.salaryInsertAct(c, nvip)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
// go test -test.v -test.run TestServiceScanSalaryLog
|
||||
func TestServiceScanSalaryLog(t *testing.T) {
|
||||
Convey("TestServiceScanSalaryLog", t, func() {
|
||||
err := s.ScanSalaryLog(c)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
728
app/job/main/vip/service/service.go
Normal file
728
app/job/main/vip/service/service.go
Normal file
@ -0,0 +1,728 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
xlog "log"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go-common/app/job/main/vip/conf"
|
||||
"go-common/app/job/main/vip/dao"
|
||||
"go-common/app/job/main/vip/model"
|
||||
couponrpc "go-common/app/service/main/coupon/rpc/client"
|
||||
v1 "go-common/app/service/main/vip/api"
|
||||
"go-common/library/log"
|
||||
"go-common/library/queue/databus"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/robfig/cron"
|
||||
)
|
||||
|
||||
const (
|
||||
_tableUserInfo = "vip_user_info"
|
||||
_tablePayOrder = "vip_pay_order"
|
||||
_insertAction = "insert"
|
||||
_updateAction = "update"
|
||||
_deleteAction = "delete"
|
||||
|
||||
notifyAction = "updateVip"
|
||||
|
||||
_ps = 50
|
||||
_defsleepmsec = 100
|
||||
)
|
||||
|
||||
//Service vip service
|
||||
type Service struct {
|
||||
dao *dao.Dao
|
||||
c *conf.Config
|
||||
//vipRPC *client.Service
|
||||
reducePayOrder map[string]*model.VipPayOrder
|
||||
appMap map[int64]*model.VipAppInfo
|
||||
confMap map[string]*model.VipConfig
|
||||
cleanVipCache chan int64
|
||||
cleanAppCache chan *model.AppCache
|
||||
ds *databus.Databus
|
||||
handlerFailPayOrder chan *model.VipPayOrder
|
||||
handlerFailUserInfo chan *model.VipUserInfo
|
||||
handlerFailRechargeOrder chan *model.VipPayOrder
|
||||
handlerFailVipbuy chan *model.VipBuyResq
|
||||
handlerInsertOrder chan *model.VipPayOrder
|
||||
handlerUpdateOrder chan *model.VipPayOrder
|
||||
handlerRechargeOrder chan *model.VipPayOrder
|
||||
handlerInsertUserInfo chan *model.VipUserInfo
|
||||
handlerUpdateUserInfo chan *model.VipUserInfo
|
||||
handlerStationActive chan *model.VipPayOrder
|
||||
handlerAutoRenewLog chan *model.VipUserInfo
|
||||
handlerAddVipHistory chan *model.VipChangeHistoryMsg
|
||||
handlerAddBcoinSalary chan *model.VipBcoinSalaryMsg
|
||||
handlerUpdateBcoinSalary chan *model.VipBcoinSalaryMsg
|
||||
handlerDelBcoinSalary chan *model.VipBcoinSalaryMsg
|
||||
notifycouponchan chan func()
|
||||
accLogin *databus.Databus
|
||||
frozenDate time.Duration
|
||||
newVipDatabus *databus.Databus
|
||||
salaryCoupnDatabus *databus.Databus
|
||||
accountNoitfyDatabus *databus.Databus
|
||||
couponNotifyDatabus *databus.Databus
|
||||
autoRenewdDatabus *databus.Databus
|
||||
// waiter
|
||||
waiter sync.WaitGroup
|
||||
closed bool
|
||||
sendmsgchan chan func()
|
||||
couponRPC *couponrpc.Service
|
||||
// vip service
|
||||
vipgRPC v1.VipClient
|
||||
}
|
||||
|
||||
//New new service
|
||||
func New(c *conf.Config) (s *Service) {
|
||||
s = &Service{
|
||||
c: c,
|
||||
dao: dao.New(c),
|
||||
//vipRPC: client.New(c.VipRPC),
|
||||
cleanVipCache: make(chan int64, 10240),
|
||||
confMap: make(map[string]*model.VipConfig),
|
||||
cleanAppCache: make(chan *model.AppCache, 10240),
|
||||
handlerFailPayOrder: make(chan *model.VipPayOrder, 10240),
|
||||
handlerFailUserInfo: make(chan *model.VipUserInfo, 10240),
|
||||
handlerFailRechargeOrder: make(chan *model.VipPayOrder, 10240),
|
||||
handlerInsertOrder: make(chan *model.VipPayOrder, 10240),
|
||||
handlerRechargeOrder: make(chan *model.VipPayOrder, 10240),
|
||||
handlerUpdateOrder: make(chan *model.VipPayOrder, 10240),
|
||||
handlerInsertUserInfo: make(chan *model.VipUserInfo, 10240),
|
||||
handlerUpdateUserInfo: make(chan *model.VipUserInfo, 10240),
|
||||
handlerStationActive: make(chan *model.VipPayOrder, 10240),
|
||||
handlerAutoRenewLog: make(chan *model.VipUserInfo, 10240),
|
||||
handlerAddVipHistory: make(chan *model.VipChangeHistoryMsg, 10240),
|
||||
handlerAddBcoinSalary: make(chan *model.VipBcoinSalaryMsg, 10240),
|
||||
handlerUpdateBcoinSalary: make(chan *model.VipBcoinSalaryMsg, 10240),
|
||||
handlerDelBcoinSalary: make(chan *model.VipBcoinSalaryMsg, 10240),
|
||||
handlerFailVipbuy: make(chan *model.VipBuyResq, 10240),
|
||||
notifycouponchan: make(chan func(), 10240),
|
||||
ds: databus.New(c.Databus.OldVipBinLog),
|
||||
newVipDatabus: databus.New(c.Databus.NewVipBinLog),
|
||||
accLogin: databus.New(c.Databus.AccLogin),
|
||||
frozenDate: time.Duration(c.Property.FrozenDate),
|
||||
reducePayOrder: make(map[string]*model.VipPayOrder),
|
||||
sendmsgchan: make(chan func(), 10240),
|
||||
accountNoitfyDatabus: databus.New(c.Databus.AccountNotify),
|
||||
couponRPC: couponrpc.New(c.RPCClient2.Coupon),
|
||||
}
|
||||
vipgRPC, err := v1.NewClient(c.VipClient)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
s.vipgRPC = vipgRPC
|
||||
t := cron.New()
|
||||
go s.loadappinfoproc()
|
||||
go s.cleanappcacheretryproc()
|
||||
go s.cleanvipretryproc()
|
||||
go s.sendmessageproc()
|
||||
go s.handlerfailpayorderproc()
|
||||
go s.handlerfailrechargeorderproc()
|
||||
go s.handlerfailuserinfoproc()
|
||||
go s.handlerautorenewlogproc()
|
||||
go s.handlerdelbcoinproc()
|
||||
if c.Databus.SalaryCoupon != nil {
|
||||
s.salaryCoupnDatabus = databus.New(c.Databus.SalaryCoupon)
|
||||
s.waiter.Add(1)
|
||||
go s.salarycouponproc()
|
||||
}
|
||||
if c.Databus.CouponNotify != nil {
|
||||
s.couponNotifyDatabus = databus.New(c.Databus.CouponNotify)
|
||||
go s.couponnotifyproc()
|
||||
s.waiter.Add(1)
|
||||
go s.couponnotifybinlogproc()
|
||||
}
|
||||
for i := 0; i < s.c.Property.HandlerThread; i++ {
|
||||
go s.handlerinsertorderproc()
|
||||
go s.handlerupdateorderproc()
|
||||
go s.handlerinsertuserinfoproc()
|
||||
go s.handlerupdateuserinfoproc()
|
||||
go s.handleraddchangehistoryproc()
|
||||
go s.handleraddbcoinproc()
|
||||
go s.handlerupdatebcoinproc()
|
||||
go s.handlerupdaterechargeorderproc()
|
||||
}
|
||||
for i := 0; i < s.c.Property.ReadThread; i++ {
|
||||
go s.readdatabusproc()
|
||||
}
|
||||
go s.readnewvipdatabusproc()
|
||||
if c.Property.FrozenCron != "" {
|
||||
go s.accloginproc()
|
||||
t.AddFunc(c.Property.FrozenCron, s.unFrozenJob)
|
||||
}
|
||||
t.AddFunc(c.Property.UpdateUserInfoCron, s.updateUserInfoJob)
|
||||
t.AddFunc(c.Property.SalaryVideoCouponCron, s.salaryVideoCouponJob)
|
||||
t.AddFunc(c.Property.PushDataCron, s.pushDataJob)
|
||||
t.AddFunc(c.Property.EleEompensateCron, s.eleEompensateJob)
|
||||
//t.AddFunc(c.Property.HadExpiredMsgCron, s.hadExpiredMsgJob)
|
||||
//t.AddFunc(c.Property.WillExpireMsgCron, s.willExpiredMsgJob)
|
||||
//t.AddFunc(c.Property.SendMessageCron, s.sendMessageJob)
|
||||
//t.AddFunc(c.Property.AutoRenewCron, s.autoRenewJob)
|
||||
//t.AddFunc(c.Property.SendBcoinCron, s.sendBcoinJob)
|
||||
t.Start()
|
||||
go s.consumercheckproc()
|
||||
if c.Databus.AutoRenew != nil {
|
||||
s.autoRenewdDatabus = databus.New(c.Databus.AutoRenew)
|
||||
s.waiter.Add(1)
|
||||
go s.retryautorenewpayproc()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) readnewvipdatabusproc() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
r = errors.WithStack(r.(error))
|
||||
log.Error("Runtime error caught: %+v", r)
|
||||
go s.readnewvipdatabusproc()
|
||||
}
|
||||
}()
|
||||
var err error
|
||||
|
||||
for msg := range s.newVipDatabus.Messages() {
|
||||
val := msg.Value
|
||||
if err = msg.Commit(); err != nil {
|
||||
log.Error("readdatabusproc msg.commit() error(%v)", err)
|
||||
msg.Commit()
|
||||
}
|
||||
log.Info("cur consumer new vip db message(%v)", string(msg.Value))
|
||||
message := new(model.Message)
|
||||
if err = json.Unmarshal(val, message); err != nil {
|
||||
log.Error("readnewvipdatabusproc json.unmarshal val(%+v) error(%+v)", string(val), err)
|
||||
continue
|
||||
}
|
||||
if message.Table == "vip_user_info" {
|
||||
userInfo := new(model.VipUserInfoNewMsg)
|
||||
if err = json.Unmarshal(message.New, userInfo); err != nil {
|
||||
log.Error("readdatabusproc json.Unmarshal val(%v) error(%v)", string(message.New), err)
|
||||
continue
|
||||
}
|
||||
vipUser := convertUserInfoByNewMsg(userInfo)
|
||||
s.dao.DelInfoCache(context.Background(), vipUser.Mid)
|
||||
if message.Action == _insertAction {
|
||||
if vipUser.PayType == model.AutoRenew {
|
||||
select {
|
||||
case s.handlerAutoRenewLog <- vipUser:
|
||||
default:
|
||||
log.Error("s.handlerAutoRenewLog full!")
|
||||
}
|
||||
}
|
||||
} else if message.Action == _updateAction {
|
||||
oldUserMsg := new(model.VipUserInfoNewMsg)
|
||||
if err = json.Unmarshal(message.Old, oldUserMsg); err != nil {
|
||||
log.Error("readdatabusproc json.Unmarshal val(%v) error(%v)", string(message.Old), err)
|
||||
continue
|
||||
}
|
||||
oldUser := convertUserInfoByNewMsg(oldUserMsg)
|
||||
|
||||
if oldUser.PayType != vipUser.PayType {
|
||||
select {
|
||||
case s.handlerAutoRenewLog <- vipUser:
|
||||
default:
|
||||
log.Error("s.handlerAutoRenewLog full update!")
|
||||
}
|
||||
}
|
||||
}
|
||||
s.pubAccountNotify(vipUser.Mid)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) readdatabusproc() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
r = errors.WithStack(r.(error))
|
||||
log.Error("Runtime error caught: %+v", r)
|
||||
go s.readdatabusproc()
|
||||
}
|
||||
}()
|
||||
var err error
|
||||
for msg := range s.ds.Messages() {
|
||||
val := msg.Value
|
||||
message := new(model.Message)
|
||||
|
||||
if err = json.Unmarshal(val, message); err != nil {
|
||||
log.Error("readdatabusproc json.Unmarshal val(%v) error(%v)", string(val), err)
|
||||
if err = msg.Commit(); err != nil {
|
||||
log.Error("msg.commit() error(%v)", err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if message.Table == "vip_pay_order" {
|
||||
order := new(model.VipPayOrderOldMsg)
|
||||
if err = json.Unmarshal(message.New, order); err != nil {
|
||||
log.Error("readdatabusproc json.Unmarshal val(%v) error(%v)", string(message.New), err)
|
||||
if err = msg.Commit(); err != nil {
|
||||
log.Error("msg.commit() error(%v)", err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
payOrder := s.convertPayOrder(order)
|
||||
if message.Action == "insert" {
|
||||
select {
|
||||
case s.handlerInsertOrder <- payOrder:
|
||||
default:
|
||||
xlog.Panic("s.handlerInsertOrder full!")
|
||||
}
|
||||
} else if message.Action == "update" {
|
||||
select {
|
||||
case s.handlerUpdateOrder <- payOrder:
|
||||
default:
|
||||
xlog.Panic("s.handlerUpdateOrder full!")
|
||||
}
|
||||
}
|
||||
|
||||
} else if message.Table == "vip_recharge_order" {
|
||||
order := new(model.VipRechargeOrderMsg)
|
||||
if err = json.Unmarshal(message.New, order); err != nil {
|
||||
log.Error("readdatabusproc json.Unmarshal val(%v) error(%v)", string(message.New), err)
|
||||
if err = msg.Commit(); err != nil {
|
||||
log.Error("msg.commit() error(%v)", err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
payOrder := s.convertPayOrderByMsg(order)
|
||||
if message.Action == "update" {
|
||||
select {
|
||||
case s.handlerRechargeOrder <- payOrder:
|
||||
default:
|
||||
xlog.Panic("s.handlerRechargeOrder full!")
|
||||
}
|
||||
} else if message.Action == "insert" {
|
||||
if len(payOrder.ThirdTradeNo) > 0 {
|
||||
select {
|
||||
case s.handlerRechargeOrder <- payOrder:
|
||||
default:
|
||||
xlog.Panic("s.handlerRechargeOrder full!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if message.Table == "vip_user_info" {
|
||||
userInfo := new(model.VipUserInfoMsg)
|
||||
if err = json.Unmarshal(message.New, userInfo); err != nil {
|
||||
log.Error("readdatabusproc json.Unmarshal val(%v) error(%v)", string(message.New), err)
|
||||
if err = msg.Commit(); err != nil {
|
||||
log.Error("msg.commit() error(%v)", err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
vipUser := convertMsgToUserInfo(userInfo)
|
||||
if message.Action == "insert" {
|
||||
select {
|
||||
case s.handlerInsertUserInfo <- vipUser:
|
||||
default:
|
||||
xlog.Panic("s.handlerInsertUserInfo full!")
|
||||
}
|
||||
} else if message.Action == "update" {
|
||||
oldUser := new(model.VipUserInfoMsg)
|
||||
if err = json.Unmarshal(message.Old, oldUser); err != nil {
|
||||
log.Error("readdatabusproc json.Unmarshal val(%v) error(%v)", string(message.Old), err)
|
||||
if err = msg.Commit(); err != nil {
|
||||
log.Error("msg.commit() error(%v)", err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
vipUser.OldVer = oldUser.Ver
|
||||
select {
|
||||
case s.handlerUpdateUserInfo <- vipUser:
|
||||
default:
|
||||
xlog.Panic("s.handlerUpdateUserInfo full!")
|
||||
}
|
||||
}
|
||||
if !s.grayScope(userInfo.Mid) {
|
||||
s.cleanCache(userInfo.Mid)
|
||||
}
|
||||
|
||||
} else if message.Table == "vip_change_history" {
|
||||
historyMsg := new(model.VipChangeHistoryMsg)
|
||||
if err = json.Unmarshal(message.New, historyMsg); err != nil {
|
||||
log.Error("readdatabusproc json.Unmarshal val(%v) error(%v)", string(message.New), err)
|
||||
if err = msg.Commit(); err != nil {
|
||||
log.Error("msg.commit() error(%v)", err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if message.Action == "insert" {
|
||||
select {
|
||||
case s.handlerAddVipHistory <- historyMsg:
|
||||
default:
|
||||
xlog.Panic("s.handlerAddVipHistory full!")
|
||||
}
|
||||
}
|
||||
} else if message.Table == "vip_bcoin_salary" {
|
||||
bcoinMsg := new(model.VipBcoinSalaryMsg)
|
||||
|
||||
if err = json.Unmarshal(message.New, bcoinMsg); err != nil {
|
||||
log.Error("readdatabusproc json.Unmarshal val(%v) error(%v)", string(message.New), err)
|
||||
if err = msg.Commit(); err != nil {
|
||||
log.Error("msg.commit() error(%v)", err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if message.Action == _insertAction {
|
||||
select {
|
||||
case s.handlerAddBcoinSalary <- bcoinMsg:
|
||||
default:
|
||||
xlog.Panic("s.handlerAddBcoinSalary full!")
|
||||
}
|
||||
} else if message.Action == _updateAction {
|
||||
select {
|
||||
case s.handlerUpdateBcoinSalary <- bcoinMsg:
|
||||
default:
|
||||
xlog.Panic("s.handlerUpdateBcoinSalary full!")
|
||||
}
|
||||
} else if message.Action == _deleteAction {
|
||||
select {
|
||||
case s.handlerDelBcoinSalary <- bcoinMsg:
|
||||
default:
|
||||
xlog.Panic("s.handlerDelBcoinSalary full!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err = msg.Commit(); err != nil {
|
||||
log.Error("readdatabusproc msg.commit() error(%v)", err)
|
||||
msg.Commit()
|
||||
}
|
||||
log.Info("cur consumer message(%v)", string(msg.Value))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) cleanCache(mid int64) {
|
||||
var (
|
||||
hv = new(model.HandlerVip)
|
||||
err error
|
||||
)
|
||||
hv.Type = 2
|
||||
hv.Days = 0
|
||||
hv.Months = 0
|
||||
hv.Mid = mid
|
||||
if err = s.cleanCacheAndNotify(context.TODO(), hv); err != nil {
|
||||
select {
|
||||
case s.cleanVipCache <- hv.Mid:
|
||||
default:
|
||||
xlog.Panic("s.cleanVipCache full!")
|
||||
}
|
||||
}
|
||||
s.pubAccountNotify(mid)
|
||||
}
|
||||
|
||||
func (s *Service) pubAccountNotify(mid int64) (err error) {
|
||||
|
||||
data := new(struct {
|
||||
Mid int64 `json:"mid"`
|
||||
Action string `json:"action"`
|
||||
})
|
||||
data.Mid = mid
|
||||
data.Action = notifyAction
|
||||
if err = s.accountNoitfyDatabus.Send(context.TODO(), strconv.FormatInt(mid, 10), data); err != nil {
|
||||
log.Error("send (%+v) error(%+v)", data, err)
|
||||
}
|
||||
log.Info("send(mid:%+v) data:%+v", mid, data)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) loadappinfoproc() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
r = errors.WithStack(r.(error))
|
||||
log.Error("Runtime error caught: %+v", r)
|
||||
go s.loadappinfoproc()
|
||||
}
|
||||
}()
|
||||
for {
|
||||
s.loadAppInfo()
|
||||
time.Sleep(time.Minute * 2)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) loadAppInfo() {
|
||||
var (
|
||||
res []*model.VipAppInfo
|
||||
err error
|
||||
)
|
||||
if res, err = s.dao.SelAppInfo(context.TODO()); err != nil {
|
||||
log.Error("loadAppInfo SelAppInfo error(%v)", err)
|
||||
return
|
||||
}
|
||||
aMap := make(map[int64]*model.VipAppInfo, len(res))
|
||||
for _, v := range res {
|
||||
aMap[v.ID] = v
|
||||
}
|
||||
s.appMap = aMap
|
||||
bytes, _ := json.Marshal(res)
|
||||
log.Info("load app success :%v", string(bytes))
|
||||
}
|
||||
|
||||
func (s *Service) cleanvipretryproc() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
r = errors.WithStack(r.(error))
|
||||
log.Error("Runtime error caught: %+v", r)
|
||||
go s.cleanvipretryproc()
|
||||
}
|
||||
}()
|
||||
for {
|
||||
mid := <-s.cleanVipCache
|
||||
s.cleanVipRetry(mid)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (s *Service) cleanVipRetry(mid int64) {
|
||||
|
||||
hv := new(model.HandlerVip)
|
||||
hv.Type = 2
|
||||
hv.Days = 0
|
||||
hv.Months = 0
|
||||
hv.Mid = mid
|
||||
s.dao.DelInfoCache(context.Background(), mid)
|
||||
for i := 0; i < s.c.Property.Retry; i++ {
|
||||
if err := s.cleanCacheAndNotify(context.TODO(), hv); err == nil {
|
||||
break
|
||||
}
|
||||
s.dao.DelVipInfoCache(context.TODO(), int64(hv.Mid))
|
||||
|
||||
}
|
||||
log.Info("handler success cache fail mid(%v)", mid)
|
||||
}
|
||||
|
||||
func (s *Service) cleanappcacheretryproc() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
r = errors.WithStack(r.(error))
|
||||
log.Error("Runtime error caught: %+v", r)
|
||||
go s.cleanappcacheretryproc()
|
||||
}
|
||||
}()
|
||||
for {
|
||||
ac := <-s.cleanAppCache
|
||||
s.cleanAppCacheRetry(ac)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) cleanAppCacheRetry(ac *model.AppCache) {
|
||||
appInfo := s.appMap[ac.AppID]
|
||||
hv := new(model.HandlerVip)
|
||||
hv.Type = 2
|
||||
hv.Days = 0
|
||||
hv.Months = 0
|
||||
hv.Mid = ac.Mid
|
||||
for i := 0; i < s.c.Property.Retry; i++ {
|
||||
if err := s.dao.SendAppCleanCache(context.TODO(), hv, appInfo); err == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
log.Info("handler success cache app fail appInfo(%v)", ac)
|
||||
}
|
||||
|
||||
func (s *Service) salarycouponproc() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
r = errors.WithStack(r.(error))
|
||||
log.Error("Runtime error caught: %+v", r)
|
||||
go s.salarycouponproc()
|
||||
}
|
||||
}()
|
||||
defer s.waiter.Done()
|
||||
var (
|
||||
err error
|
||||
msg *databus.Message
|
||||
msgChan = s.salaryCoupnDatabus.Messages()
|
||||
ok bool
|
||||
c = context.Background()
|
||||
)
|
||||
for {
|
||||
msg, ok = <-msgChan
|
||||
if !ok || s.closed {
|
||||
log.Info("salary coupon msgChan closed")
|
||||
return
|
||||
}
|
||||
msg.Commit()
|
||||
v := &model.Message{}
|
||||
if err = json.Unmarshal([]byte(msg.Value), v); err != nil {
|
||||
log.Error("json.Unmarshal(%v) err(%v)", v, err)
|
||||
continue
|
||||
}
|
||||
if v.Table != _tableUserInfo {
|
||||
continue
|
||||
}
|
||||
nvip := &model.VipUserInfoMsg{}
|
||||
if err = json.Unmarshal(v.New, &nvip); err != nil {
|
||||
log.Error("salary new json.Unmarshal values(%v),error(%v)", string(v.New), err)
|
||||
continue
|
||||
}
|
||||
ovip := &model.VipUserInfoMsg{}
|
||||
if v.Action != _insertAction {
|
||||
if err = json.Unmarshal(v.Old, &ovip); err != nil {
|
||||
log.Error("salary old json.Unmarshal values(%v),error(%v)", string(v.Old), err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
log.Info("salary coupon start mid(%d)", nvip.Mid)
|
||||
if _, err = s.SalaryVideoCouponAtOnce(c, nvip, ovip, v.Action); err != nil {
|
||||
log.Error("SalaryVideoCouponAtOnce fail(%d) nvip(%v) ovip(%v) %s error(%v)", nvip.Mid, nvip, ovip, v.Action, err)
|
||||
continue
|
||||
}
|
||||
log.Info("salary coupon suc mid(%d)", nvip.Mid)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) couponnotifybinlogproc() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
r = errors.WithStack(r.(error))
|
||||
log.Error("Runtime error couponnotifybinlogproc caught: %+v", r)
|
||||
go s.couponnotifybinlogproc()
|
||||
}
|
||||
}()
|
||||
defer s.waiter.Done()
|
||||
var (
|
||||
err error
|
||||
msg *databus.Message
|
||||
msgChan = s.couponNotifyDatabus.Messages()
|
||||
ok bool
|
||||
c = context.Background()
|
||||
)
|
||||
for {
|
||||
msg, ok = <-msgChan
|
||||
if !ok || s.closed {
|
||||
log.Info("coupon notify couponnotifybinlogproc msgChan closed")
|
||||
return
|
||||
}
|
||||
if err = msg.Commit(); err != nil {
|
||||
log.Error("couponnotifybinlogproc msg.Commit err(%v)", err)
|
||||
continue
|
||||
}
|
||||
log.Info("cur consumer couponnotifybinlogproc(%v)", string(msg.Value))
|
||||
v := &model.Message{}
|
||||
if err = json.Unmarshal([]byte(msg.Value), v); err != nil {
|
||||
log.Error("couponnotifybinlogproc json.Unmarshal(%v) err(%v)", v, err)
|
||||
continue
|
||||
}
|
||||
if v.Table != _tablePayOrder || v.Action != _updateAction {
|
||||
continue
|
||||
}
|
||||
newo := new(model.VipPayOrderNewMsg)
|
||||
if err = json.Unmarshal(v.New, newo); err != nil {
|
||||
log.Error("couponnotifybinlogproc json.Unmarshal val(%v) error(%v)", string(v.New), err)
|
||||
continue
|
||||
}
|
||||
oldo := new(model.VipPayOrderNewMsg)
|
||||
if err = json.Unmarshal(v.Old, oldo); err != nil {
|
||||
log.Error("couponnotifybinlogproc json.Unmarshal val(%v) error(%v)", string(v.Old), err)
|
||||
continue
|
||||
}
|
||||
if newo == nil || oldo == nil {
|
||||
continue
|
||||
}
|
||||
if oldo.Status != model.PAYING {
|
||||
continue
|
||||
}
|
||||
if newo.Status != model.SUCCESS && newo.Status != model.FAILED {
|
||||
continue
|
||||
}
|
||||
if newo.CouponMoney <= 0 {
|
||||
continue
|
||||
}
|
||||
s.couponnotify(func() {
|
||||
s.CouponNotify(c, newo)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) updateUserInfoJob() {
|
||||
log.Info("update user info job start ....................................")
|
||||
s.ScanUserInfo(context.TODO())
|
||||
log.Info("update user info job end ........................................")
|
||||
}
|
||||
|
||||
func (s *Service) salaryVideoCouponJob() {
|
||||
log.Info("salary video coupon job start ....................................")
|
||||
var err error
|
||||
if ok := s.dao.AddTransferLock(context.TODO(), "_transferLock"); !ok {
|
||||
log.Info("salary video coupon job had run ....................................")
|
||||
return
|
||||
}
|
||||
if err = s.ScanSalaryVideoCoupon(context.TODO()); err != nil {
|
||||
log.Error("ScanSalaryVideoCoupon error(%v)", err)
|
||||
return
|
||||
}
|
||||
log.Info("salary video coupon job end ........................................")
|
||||
}
|
||||
|
||||
//Ping check db live
|
||||
func (s *Service) Ping(c context.Context) (err error) {
|
||||
return s.dao.Ping(c)
|
||||
}
|
||||
|
||||
// Close all resource.
|
||||
func (s *Service) Close() {
|
||||
defer s.waiter.Wait()
|
||||
s.closed = true
|
||||
s.salaryCoupnDatabus.Close()
|
||||
s.dao.Close()
|
||||
s.ds.Close()
|
||||
s.newVipDatabus.Close()
|
||||
}
|
||||
|
||||
func (s *Service) sendmessageproc() {
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("service.sendmessageproc panic(%v)", x)
|
||||
go s.sendmessageproc()
|
||||
log.Info("service.sendmessageproc recover")
|
||||
}
|
||||
}()
|
||||
for {
|
||||
f := <-s.sendmsgchan
|
||||
f()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) sendmessage(f func()) {
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("service.sendmessage panic(%v)", x)
|
||||
}
|
||||
}()
|
||||
select {
|
||||
case s.sendmsgchan <- f:
|
||||
default:
|
||||
log.Error("service.sendmessage chan full")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) consumercheckproc() {
|
||||
for {
|
||||
time.Sleep(time.Second)
|
||||
log.Info("consumercheckproc chan(cleanVipCache) size: %d", len(s.cleanVipCache))
|
||||
log.Info("consumercheckproc chan(cleanAppCache) size: %d", len(s.cleanAppCache))
|
||||
log.Info("consumercheckproc chan(handlerFailPayOrder) size: %d", len(s.handlerFailPayOrder))
|
||||
log.Info("consumercheckproc chan(handlerFailUserInfo) size: %d", len(s.handlerFailUserInfo))
|
||||
log.Info("consumercheckproc chan(handlerFailRechargeOrder) size: %d", len(s.handlerFailRechargeOrder))
|
||||
log.Info("consumercheckproc chan(handlerFailVipbuy) size: %d", len(s.handlerFailVipbuy))
|
||||
log.Info("consumercheckproc chan(handlerInsertOrder) size: %d", len(s.handlerInsertOrder))
|
||||
log.Info("consumercheckproc chan(handlerUpdateOrder) size: %d", len(s.handlerUpdateOrder))
|
||||
log.Info("consumercheckproc chan(handlerRechargeOrder) size: %d", len(s.handlerRechargeOrder))
|
||||
log.Info("consumercheckproc chan(handlerInsertUserInfo) size: %d", len(s.handlerInsertUserInfo))
|
||||
log.Info("consumercheckproc chan(handlerUpdateUserInfo) size: %d", len(s.handlerUpdateUserInfo))
|
||||
log.Info("consumercheckproc chan(handlerStationActive) size: %d", len(s.handlerStationActive))
|
||||
log.Info("consumercheckproc chan(handlerAutoRenewLog) size: %d", len(s.handlerAutoRenewLog))
|
||||
log.Info("consumercheckproc chan(handlerAddVipHistory) size: %d", len(s.handlerAddVipHistory))
|
||||
log.Info("consumercheckproc chan(handlerAddBcoinSalary) size: %d", len(s.handlerAddBcoinSalary))
|
||||
log.Info("consumercheckproc chan(handlerUpdateBcoinSalary) size: %d", len(s.handlerUpdateBcoinSalary))
|
||||
log.Info("consumercheckproc chan(handlerDelBcoinSalary) size: %d", len(s.handlerDelBcoinSalary))
|
||||
log.Info("consumercheckproc chan(sendmsgchan) size: %d", len(s.sendmsgchan))
|
||||
log.Info("consumercheckproc chan(notifycouponchan) size: %d", len(s.notifycouponchan))
|
||||
}
|
||||
}
|
117
app/job/main/vip/service/service_test.go
Normal file
117
app/job/main/vip/service/service_test.go
Normal file
@ -0,0 +1,117 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"go-common/app/job/main/vip/conf"
|
||||
"go-common/app/job/main/vip/model"
|
||||
"go-common/library/log"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
var (
|
||||
s *Service
|
||||
c context.Context
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.Set("conf", "../cmd/vip-job-test.toml")
|
||||
if err := conf.Init(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
c = context.TODO()
|
||||
log.Init(conf.Conf.Xlog)
|
||||
defer log.Close()
|
||||
s = New(conf.Conf)
|
||||
time.Sleep(time.Second * 2)
|
||||
}
|
||||
|
||||
func Test_ScanUserInfo(t *testing.T) {
|
||||
Convey("should return true err == nil", t, func() {
|
||||
err := s.ScanUserInfo(context.TODO())
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestService_HadExpiredMsgJob(t *testing.T) {
|
||||
Convey("had expireMsg job", t, func() {
|
||||
s.hadExpiredMsgJob()
|
||||
})
|
||||
}
|
||||
|
||||
func TestService_WillExpiredMsgJob(t *testing.T) {
|
||||
Convey("had expire msg job", t, func() {
|
||||
s.willExpiredMsgJob()
|
||||
})
|
||||
}
|
||||
|
||||
func TestService_SendMessageJob(t *testing.T) {
|
||||
Convey("send message job", t, func() {
|
||||
s.sendMessageJob()
|
||||
})
|
||||
}
|
||||
func TestService_SendBcoinJob(t *testing.T) {
|
||||
Convey("send bcoin job", t, func() {
|
||||
s.sendBcoinJob()
|
||||
})
|
||||
}
|
||||
func TestSalaryVideoCouponJob(t *testing.T) {
|
||||
Convey("salaryVideoCouponJob err == nil", t, func() {
|
||||
s.salaryVideoCouponJob()
|
||||
s.salaryVideoCouponJob()
|
||||
})
|
||||
}
|
||||
|
||||
func TestService_HandlerVipChangeHistory(t *testing.T) {
|
||||
Convey("handlervip change history ", t, func() {
|
||||
err := s.HandlerVipChangeHistory()
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestService_HandlerBcoin(t *testing.T) {
|
||||
Convey(" handler bcoin history ", t, func() {
|
||||
err := s.HandlerBcoin()
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestService_HandlerPayOrder(t *testing.T) {
|
||||
Convey("handler pay order", t, func() {
|
||||
err := s.HandlerPayOrder()
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_push(t *testing.T) {
|
||||
Convey("handler push data err should be nil", t, func() {
|
||||
|
||||
err := s.pushData(context.TODO())
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
func TestService_CheckBcoinData(t *testing.T) {
|
||||
Convey("check bcoin data", t, func() {
|
||||
mids, err := s.CheckBcoinData(context.TODO())
|
||||
So(mids, ShouldBeEmpty)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestService_CheckChangeHistory(t *testing.T) {
|
||||
Convey("check change history", t, func() {
|
||||
mids, err := s.CheckChangeHistory(context.TODO())
|
||||
So(mids, ShouldBeEmpty)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
func Test_HandlerAutoRenewLogInfo(t *testing.T) {
|
||||
Convey("err should be nil", t, func() {
|
||||
err := s.handlerAutoRenewLogInfo(context.TODO(), &model.VipUserInfo{Mid: 2089809, PayType: model.AutoRenew, PayChannelID: 100})
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
96
app/job/main/vip/service/sync.go
Normal file
96
app/job/main/vip/service/sync.go
Normal file
@ -0,0 +1,96 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
// SyncAllUser 同步旧user——info到新db.
|
||||
// FIXME 切新db后删除.
|
||||
func (s *Service) SyncAllUser(c context.Context) {
|
||||
var (
|
||||
err error
|
||||
maxID int
|
||||
size = s.c.Property.BatchSize
|
||||
ids = []int64{}
|
||||
ousers = make(map[int64]*model.VipUserInfoOld, size)
|
||||
nusers = make(map[int64]*model.VipUserInfo, _ps)
|
||||
updateDB = s.c.Property.UpdateDB
|
||||
nu *model.VipUserInfo
|
||||
ok bool
|
||||
)
|
||||
if maxID, err = s.dao.SelOldUserInfoMaxID(context.TODO()); err != nil {
|
||||
log.Error("sync job s.dao.SelOldUserInfoMaxID err(%+v)", err)
|
||||
return
|
||||
}
|
||||
page := maxID / size
|
||||
if maxID%size != 0 {
|
||||
page++
|
||||
}
|
||||
log.Info("sync job vip_user_info total(%d)", page)
|
||||
for i := 0; i < page; i++ {
|
||||
log.Info("sync job vip_user_info page index(%d) total(%d)", i, page)
|
||||
startID := i * size
|
||||
endID := (i + 1) * size
|
||||
if endID > maxID {
|
||||
endID = maxID
|
||||
}
|
||||
if ousers, err = s.dao.SelOldUserInfoMaps(context.TODO(), startID, endID); err != nil {
|
||||
log.Error("sync job s.dao.SelOldUserInfoMaps(%d, %d) err(%+v)", startID, endID, err)
|
||||
return
|
||||
}
|
||||
j := 1
|
||||
for _, v := range ousers {
|
||||
ids = append(ids, v.Mid)
|
||||
if j%_ps == 0 || j == len(ousers) {
|
||||
if nusers, err = s.dao.SelVipByIds(context.TODO(), ids); err != nil {
|
||||
return
|
||||
}
|
||||
for _, mid := range ids {
|
||||
var ou *model.VipUserInfoOld
|
||||
if ou, ok = ousers[mid]; !ok {
|
||||
log.Warn("sync job old not found %d", mid)
|
||||
continue
|
||||
}
|
||||
if nu, ok = nusers[mid]; !ok {
|
||||
log.Warn("sync job need insert to new %d, old(%+v), toNew(%+v)", mid, ou, ou.ToNew())
|
||||
if updateDB {
|
||||
s.dao.SyncAddUser(context.Background(), ou.ToNew())
|
||||
}
|
||||
continue
|
||||
}
|
||||
if ou.RecentTime <= 0 {
|
||||
ou.RecentTime = ou.Mtime
|
||||
}
|
||||
if nu.Type != ou.Type ||
|
||||
nu.Status != ou.Status ||
|
||||
!nu.StartTime.Time().Equal(ou.StartTime.Time()) ||
|
||||
!nu.OverdueTime.Time().Equal(ou.OverdueTime.Time()) ||
|
||||
!nu.AnnualVipOverdueTime.Time().Equal(ou.AnnualVipOverdueTime.Time()) ||
|
||||
!nu.Ctime.Time().Equal(ou.Ctime.Time()) ||
|
||||
!nu.Mtime.Time().Equal(ou.Mtime.Time()) ||
|
||||
nu.PayType != ou.IsAutoRenew ||
|
||||
nu.PayChannelID != ou.PayChannelID ||
|
||||
!nu.IosOverdueTime.Time().Equal(ou.IosOverdueTime.Time()) ||
|
||||
nu.Ver != ou.Ver ||
|
||||
!nu.RecentTime.Time().Equal(ou.RecentTime.Time()) {
|
||||
log.Warn("sync job need update to new %d, old(%+v), new(%+v), toNew(%+v)", mid, ou, nu, ou.ToNew())
|
||||
if updateDB {
|
||||
s.dao.SyncUpdateUser(context.Background(), ou.ToNew(), nu.Ver)
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
log.Info("sync job vip_user_info page index(%d) ids(%+v)", j, ids)
|
||||
// reset
|
||||
ids = []int64{}
|
||||
}
|
||||
j++
|
||||
}
|
||||
log.Info("sync job vip_user_info page index(%d) end", i)
|
||||
time.Sleep(time.Millisecond * _defsleepmsec)
|
||||
}
|
||||
}
|
14
app/job/main/vip/service/sync_test.go
Normal file
14
app/job/main/vip/service/sync_test.go
Normal file
@ -0,0 +1,14 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func Test_SyncAllUser(t *testing.T) {
|
||||
Convey("Test_SyncAllUser", t, func() {
|
||||
s.SyncAllUser(context.Background())
|
||||
})
|
||||
}
|
595
app/job/main/vip/service/vip.go
Normal file
595
app/job/main/vip/service/vip.go
Normal file
@ -0,0 +1,595 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"go-common/app/job/main/vip/model"
|
||||
"go-common/library/database/sql"
|
||||
"go-common/library/log"
|
||||
"go-common/library/sync/errgroup"
|
||||
xtime "go-common/library/time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
iapChannelID = 100
|
||||
)
|
||||
|
||||
func (s *Service) cleanCacheAndNotify(c context.Context, hv *model.HandlerVip) (err error) {
|
||||
s.dao.DelInfoCache(c, hv.Mid)
|
||||
if err = s.dao.SendCleanCache(c, hv); err != nil {
|
||||
return
|
||||
}
|
||||
if err = s.dao.DelVipInfoCache(c, int64(hv.Mid)); err != nil {
|
||||
log.Error("del vip info cache (mid:%v) error(%+v)", hv.Mid, err)
|
||||
return
|
||||
}
|
||||
eg, ec := errgroup.WithContext(c)
|
||||
for _, app := range s.appMap {
|
||||
ta := app
|
||||
eg.Go(func() error {
|
||||
if err = s.dao.SendAppCleanCache(ec, hv, ta); err == nil {
|
||||
log.Info("SendAppCleanCache success hv(%v) app(%v)", hv, ta)
|
||||
} else {
|
||||
ac := new(model.AppCache)
|
||||
ac.AppID = ta.ID
|
||||
ac.Mid = hv.Mid
|
||||
s.cleanAppCache <- ac
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
if err = eg.Wait(); err != nil {
|
||||
log.Error(" eg.Wait err(%+v)", err)
|
||||
}
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
|
||||
//ScanUserInfo scan all userinfo update status
|
||||
func (s *Service) ScanUserInfo(c context.Context) (err error) {
|
||||
var (
|
||||
ot = time.Now().Format("2006-01-02 15:04:05")
|
||||
userInfos []*model.VipUserInfo
|
||||
size = 2000
|
||||
endID = 0
|
||||
)
|
||||
for {
|
||||
if endID, err = s.dao.SelOldUserInfoMaxID(context.TODO()); err != nil {
|
||||
time.Sleep(time.Minute * 2)
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
page := endID / size
|
||||
if endID%size != 0 {
|
||||
page++
|
||||
}
|
||||
for i := 0; i < page; {
|
||||
startID := i * size
|
||||
eID := (i + 1) * size
|
||||
if userInfos, err = s.dao.SelVipList(context.TODO(), startID, eID, ot); err != nil {
|
||||
time.Sleep(time.Second * 5)
|
||||
continue
|
||||
}
|
||||
i++
|
||||
for _, v := range userInfos {
|
||||
s.updateUserInfo(context.TODO(), v)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) updateUserInfo(c context.Context, v *model.VipUserInfo) (err error) {
|
||||
var (
|
||||
curTime = time.Now()
|
||||
fType = v.Type
|
||||
fStatus = v.Status
|
||||
)
|
||||
if v.AnnualVipOverdueTime.Time().Before(curTime) {
|
||||
fType = model.Vip
|
||||
}
|
||||
if v.OverdueTime.Time().Before(curTime) {
|
||||
fStatus = model.VipStatusOverTime
|
||||
}
|
||||
if fType != v.Type || fStatus != v.Status {
|
||||
v.Type = fType
|
||||
v.Status = fStatus
|
||||
if v.Status == model.VipStatusOverTime && v.PayChannelID == iapChannelID {
|
||||
v.PayType = model.Normal
|
||||
}
|
||||
if _, err = s.dao.UpdateVipUser(c, int64(v.Mid), v.Status, v.Type, v.PayType); err != nil {
|
||||
return
|
||||
}
|
||||
s.dao.DelInfoCache(c, v.Mid)
|
||||
s.dao.DelVipInfoCache(c, int64(v.Mid))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) handlerautorenewlogproc() {
|
||||
var (
|
||||
err error
|
||||
)
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("service.handlerautorenewlogproc panic(%v)", x)
|
||||
go s.handlerautorenewlogproc()
|
||||
log.Info("service.handlerautorenewlogproc recover")
|
||||
}
|
||||
}()
|
||||
for {
|
||||
user := <-s.handlerAutoRenewLog
|
||||
for i := 0; i <= s.c.Property.Retry; i++ {
|
||||
if err = s.handlerAutoRenewLogInfo(context.TODO(), user); err == nil {
|
||||
break
|
||||
}
|
||||
log.Error("%+v", err)
|
||||
time.Sleep(2 * time.Second)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) handlerAutoRenewLogInfo(c context.Context, user *model.VipUserInfo) (err error) {
|
||||
var (
|
||||
payOrder *model.VipPayOrder
|
||||
paylog *model.VipPayOrderLog
|
||||
rlog *model.VipPayOrderLog
|
||||
)
|
||||
if user.PayType == model.AutoRenew {
|
||||
if user.PayChannelID == iapChannelID {
|
||||
if payOrder, err = s.dao.SelPayOrderByMid(c, user.Mid, model.IAPAutoRenew, model.SUCCESS); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
if payOrder == nil {
|
||||
err = errors.Errorf("订单号不能为空......")
|
||||
return
|
||||
}
|
||||
rlog = new(model.VipPayOrderLog)
|
||||
rlog.Mid = payOrder.Mid
|
||||
rlog.OrderNo = payOrder.OrderNo
|
||||
rlog.Status = model.SIGN
|
||||
} else {
|
||||
if payOrder, err = s.dao.SelPayOrderByMid(c, user.Mid, model.AutoRenew, model.SUCCESS); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
if payOrder == nil {
|
||||
err = errors.Errorf("订单号不能为空......")
|
||||
return
|
||||
}
|
||||
rlog = new(model.VipPayOrderLog)
|
||||
rlog.Mid = payOrder.Mid
|
||||
rlog.OrderNo = payOrder.OrderNo
|
||||
rlog.Status = model.SIGN
|
||||
}
|
||||
} else {
|
||||
if paylog, err = s.dao.SelPayOrderLog(c, user.Mid, model.SIGN); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
rlog = new(model.VipPayOrderLog)
|
||||
rlog.Mid = paylog.Mid
|
||||
rlog.Status = model.UNSIGN
|
||||
rlog.OrderNo = paylog.OrderNo
|
||||
}
|
||||
|
||||
if rlog != nil {
|
||||
if _, err = s.dao.AddPayOrderLog(c, rlog); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) handlerinsertuserinfoproc() {
|
||||
var (
|
||||
err error
|
||||
)
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("service.handlerinsertuserinfoproc panic(%v)", x)
|
||||
go s.handlerinsertuserinfoproc()
|
||||
log.Info("service.handlerinsertuserinfoproc recover")
|
||||
}
|
||||
}()
|
||||
for {
|
||||
userInfo := <-s.handlerInsertUserInfo
|
||||
for i := 0; i < s.c.Property.Retry; i++ {
|
||||
if err = s.addUserInfo(context.TODO(), userInfo); err == nil {
|
||||
s.dao.DelInfoCache(context.Background(), userInfo.Mid)
|
||||
s.dao.DelVipInfoCache(context.TODO(), userInfo.Mid)
|
||||
if s.grayScope(userInfo.Mid) {
|
||||
s.cleanCache(userInfo.Mid)
|
||||
}
|
||||
break
|
||||
}
|
||||
log.Error("add info error(%+v)", err)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) addUserInfo(c context.Context, ui *model.VipUserInfo) (err error) {
|
||||
var (
|
||||
tx *sql.Tx
|
||||
udh *model.VipUserDiscountHistory
|
||||
)
|
||||
if tx, err = s.dao.StartTx(c); err != nil {
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if err == nil {
|
||||
if err = tx.Commit(); err != nil {
|
||||
log.Error("commit(%+v)", err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
tx.Rollback()
|
||||
}
|
||||
}()
|
||||
if _, err = s.dao.AddUserInfo(tx, ui); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
if ui.AutoRenewed == 1 {
|
||||
udh = new(model.VipUserDiscountHistory)
|
||||
udh.DiscountID = model.VipUserFirstDiscount
|
||||
udh.Status = model.DiscountUsed
|
||||
udh.Mid = ui.Mid
|
||||
|
||||
if _, err = s.dao.DupUserDiscountHistory(tx, udh); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func (s *Service) updateVipUserInfo(c context.Context, ui *model.VipUserInfo) (err error) {
|
||||
var (
|
||||
tx *sql.Tx
|
||||
udh *model.VipUserDiscountHistory
|
||||
eff int64
|
||||
)
|
||||
if tx, err = s.dao.StartTx(c); err != nil {
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if err == nil {
|
||||
if err = tx.Commit(); err != nil {
|
||||
log.Error("commit(%+v)", err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
tx.Rollback()
|
||||
}
|
||||
}()
|
||||
if eff, err = s.dao.UpdateUserInfo(tx, ui); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
if eff <= 0 {
|
||||
log.Warn("update vip RowsAffected 0 vip(%+v)", ui)
|
||||
return
|
||||
}
|
||||
if ui.AutoRenewed == 1 {
|
||||
udh = new(model.VipUserDiscountHistory)
|
||||
udh.DiscountID = model.VipUserFirstDiscount
|
||||
udh.Status = model.DiscountUsed
|
||||
udh.Mid = ui.Mid
|
||||
|
||||
if _, err = s.dao.DupUserDiscountHistory(tx, udh); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func (s *Service) handlerfailuserinfoproc() {
|
||||
var (
|
||||
err error
|
||||
)
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("service.handlerfailuserinfoproc panic(%v)", x)
|
||||
go s.handlerfailuserinfoproc()
|
||||
log.Info("service.handlerfailuserinfoproc recover")
|
||||
}
|
||||
}()
|
||||
for {
|
||||
userInfo := <-s.handlerFailUserInfo
|
||||
_time := 0
|
||||
for {
|
||||
if err = s.updateVipUserInfo(context.TODO(), userInfo); err == nil {
|
||||
s.dao.DelInfoCache(context.Background(), userInfo.Mid)
|
||||
s.dao.DelVipInfoCache(context.TODO(), userInfo.Mid)
|
||||
if s.grayScope(userInfo.Mid) {
|
||||
s.cleanCache(userInfo.Mid)
|
||||
}
|
||||
break
|
||||
}
|
||||
log.Error("info error(%+v)", err)
|
||||
_time++
|
||||
if _time > _maxtime {
|
||||
break
|
||||
}
|
||||
time.Sleep(_sleep)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) handlerupdateuserinfoproc() {
|
||||
var (
|
||||
err error
|
||||
flag bool
|
||||
)
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("service.handlerupdateuserinfoproc panic(%v)", x)
|
||||
go s.handlerupdateuserinfoproc()
|
||||
log.Info("service.handlerupdateuserinfoproc recover")
|
||||
}
|
||||
}()
|
||||
for {
|
||||
userInfo := <-s.handlerUpdateUserInfo
|
||||
flag = true
|
||||
for i := 0; i < s.c.Property.Retry; i++ {
|
||||
if err = s.updateVipUserInfo(context.TODO(), userInfo); err == nil {
|
||||
s.dao.DelInfoCache(context.Background(), userInfo.Mid)
|
||||
s.dao.DelVipInfoCache(context.TODO(), userInfo.Mid)
|
||||
if s.grayScope(userInfo.Mid) {
|
||||
s.cleanCache(userInfo.Mid)
|
||||
}
|
||||
flag = false
|
||||
break
|
||||
}
|
||||
log.Error("info error(%+v)", err)
|
||||
}
|
||||
|
||||
if flag {
|
||||
s.handlerFailUserInfo <- userInfo
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) handleraddchangehistoryproc() {
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
log.Error("service.handleraddchangehistoryproc panic(%v)", x)
|
||||
go s.handleraddchangehistoryproc()
|
||||
log.Info("service.handleraddchangehistoryproc recover")
|
||||
}
|
||||
}()
|
||||
for {
|
||||
msg := <-s.handlerAddVipHistory
|
||||
history := convertMsgToHistory(msg)
|
||||
var res []*model.VipChangeHistory
|
||||
res = append(res, history)
|
||||
for i := 0; i < s.c.Property.Retry; i++ {
|
||||
if err := s.dao.AddChangeHistoryBatch(res); err == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
func convertMsgToHistory(msg *model.VipChangeHistoryMsg) (r *model.VipChangeHistory) {
|
||||
r = new(model.VipChangeHistory)
|
||||
r.Mid = msg.Mid
|
||||
r.Days = msg.Days
|
||||
r.Month = msg.Month
|
||||
r.ChangeType = msg.ChangeType
|
||||
r.OperatorID = msg.OperatorID
|
||||
r.RelationID = msg.RelationID
|
||||
r.BatchID = msg.BatchID
|
||||
r.Remark = msg.Remark
|
||||
r.ChangeTime = xtime.Time(parseTime(msg.ChangeTime).Unix())
|
||||
r.BatchCodeID = msg.BatchCodeID
|
||||
return
|
||||
}
|
||||
|
||||
func parseTime(timeStr string) (t time.Time) {
|
||||
var err error
|
||||
if t, err = time.ParseInLocation("2006-01-02 15:04:05", timeStr, time.Local); err != nil {
|
||||
t = time.Now()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func convertMsgToUserInfo(msg *model.VipUserInfoMsg) (r *model.VipUserInfo) {
|
||||
r = new(model.VipUserInfo)
|
||||
r.AnnualVipOverdueTime = xtime.Time(parseTime(msg.AnnualVipOverdueTime).Unix())
|
||||
r.Mid = msg.Mid
|
||||
r.OverdueTime = xtime.Time(parseTime(msg.OverdueTime).Unix())
|
||||
r.PayType = msg.IsAutoRenew
|
||||
r.RecentTime = xtime.Time(parseTime(msg.RecentTime).Unix())
|
||||
r.StartTime = xtime.Time(parseTime(msg.StartTime).Unix())
|
||||
r.Status = msg.Status
|
||||
r.Type = msg.Type
|
||||
r.PayChannelID = msg.PayChannelID
|
||||
r.AutoRenewed = msg.AutoRenewed
|
||||
r.IosOverdueTime = xtime.Time(parseTime(msg.IosOverdueTime).Unix())
|
||||
r.Ver = msg.Ver
|
||||
return
|
||||
}
|
||||
|
||||
func convertUserInfoByNewMsg(msg *model.VipUserInfoNewMsg) (r *model.VipUserInfo) {
|
||||
r = new(model.VipUserInfo)
|
||||
r.AnnualVipOverdueTime = xtime.Time(parseTime(msg.AnnualVipOverdueTime).Unix())
|
||||
r.Mid = msg.Mid
|
||||
r.OverdueTime = xtime.Time(parseTime(msg.VipOverdueTime).Unix())
|
||||
r.PayType = msg.VipPayType
|
||||
r.RecentTime = xtime.Time(parseTime(msg.VipRecentTime).Unix())
|
||||
r.StartTime = xtime.Time(parseTime(msg.VipStartTime).Unix())
|
||||
r.Status = msg.VipStatus
|
||||
r.Type = msg.VipType
|
||||
r.PayChannelID = msg.PayChannelID
|
||||
r.IosOverdueTime = xtime.Time(parseTime(msg.IosOverdueTime).Unix())
|
||||
r.Ver = msg.Ver
|
||||
return
|
||||
}
|
||||
|
||||
func convertOldToNew(old *model.VipUserInfoOld) (r *model.VipUserInfo) {
|
||||
r = new(model.VipUserInfo)
|
||||
r.AnnualVipOverdueTime = old.AnnualVipOverdueTime
|
||||
r.Mid = old.Mid
|
||||
r.OverdueTime = old.OverdueTime
|
||||
r.PayType = old.IsAutoRenew
|
||||
r.RecentTime = old.RecentTime
|
||||
r.PayChannelID = old.PayChannelID
|
||||
if old.RecentTime.Time().Unix() < 0 {
|
||||
r.RecentTime = xtime.Time(1451577600)
|
||||
}
|
||||
r.StartTime = old.StartTime
|
||||
r.Status = old.Status
|
||||
r.Type = old.Type
|
||||
r.IosOverdueTime = old.IosOverdueTime
|
||||
r.Ver = old.Ver
|
||||
return
|
||||
}
|
||||
|
||||
//HandlerVipChangeHistory handler sync change history data
|
||||
func (s *Service) HandlerVipChangeHistory() (err error) {
|
||||
var (
|
||||
newMaxID int64
|
||||
oldMaxID int64
|
||||
size = int64(s.c.Property.BatchSize)
|
||||
startID int64
|
||||
endID = size
|
||||
exitMap = make(map[string]int)
|
||||
)
|
||||
if oldMaxID, err = s.dao.SelOldChangeHistoryMaxID(context.TODO()); err != nil {
|
||||
log.Error("selOldChangeHistory error(%+v)", err)
|
||||
return
|
||||
}
|
||||
if newMaxID, err = s.dao.SelChangeHistoryMaxID(context.TODO()); err != nil {
|
||||
log.Error("selChangeHistoryMaxID error(%+v)", err)
|
||||
return
|
||||
}
|
||||
page := newMaxID / size
|
||||
if newMaxID%size != 0 {
|
||||
page++
|
||||
}
|
||||
for i := 0; i < int(page); i++ {
|
||||
startID = int64(i) * size
|
||||
endID = int64((i + 1)) * size
|
||||
if endID > newMaxID {
|
||||
endID = newMaxID
|
||||
}
|
||||
|
||||
var res []*model.VipChangeHistory
|
||||
if res, err = s.dao.SelChangeHistory(context.TODO(), startID, endID); err != nil {
|
||||
log.Error("selChangeHistory(startID:%v endID:%v) error(%+v)", startID, endID, endID)
|
||||
return
|
||||
}
|
||||
for _, v := range res {
|
||||
exitMap[s.madeChangeHistoryMD5(v)] = 1
|
||||
}
|
||||
}
|
||||
|
||||
page = oldMaxID / size
|
||||
if oldMaxID%size != 0 {
|
||||
page++
|
||||
}
|
||||
var batch []*model.VipChangeHistory
|
||||
for i := 0; i < int(page); i++ {
|
||||
startID = int64(i) * size
|
||||
endID = int64(i+1) * size
|
||||
if endID > oldMaxID {
|
||||
endID = oldMaxID
|
||||
}
|
||||
|
||||
var res []*model.VipChangeHistory
|
||||
if res, err = s.dao.SelOldChangeHistory(context.TODO(), startID, endID); err != nil {
|
||||
log.Error("sel old change history (startID:%v endID:%v) error(%+v)", startID, endID, err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, v := range res {
|
||||
v.Days = s.calcDay(v)
|
||||
madeMD5 := s.madeChangeHistoryMD5(v)
|
||||
if exitMap[madeMD5] == 0 {
|
||||
batch = append(batch, v)
|
||||
}
|
||||
}
|
||||
if err = s.dao.AddChangeHistoryBatch(batch); err != nil {
|
||||
log.Error("add change history batch(%+v) error(%+v)", batch, err)
|
||||
return
|
||||
}
|
||||
batch = nil
|
||||
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) calcDay(r *model.VipChangeHistory) int32 {
|
||||
if r.Month != 0 {
|
||||
year := r.Month / 12
|
||||
month := r.Month % 12
|
||||
|
||||
return int32(year)*model.VipDaysYear + int32(month)*model.VipDaysMonth
|
||||
}
|
||||
return r.Days
|
||||
}
|
||||
|
||||
func (s *Service) madeChangeHistoryMD5(r *model.VipChangeHistory) string {
|
||||
str := fmt.Sprintf("%v,%v,%v,%v,%v,%v,%v,%v,%v", r.Mid, r.Remark, r.BatchID, r.RelationID, r.OperatorID, r.Days, r.ChangeTime.Time().Format("2006-01-02 15:04:05"), r.ChangeType, r.BatchCodeID)
|
||||
b := []byte(str)
|
||||
hash := md5.New()
|
||||
hash.Write(b)
|
||||
sum := hash.Sum(nil)
|
||||
return hex.EncodeToString(sum)
|
||||
}
|
||||
|
||||
//SyncUserInfoByMid sync user by mid.
|
||||
func (s *Service) SyncUserInfoByMid(c context.Context, mid int64) (err error) {
|
||||
var (
|
||||
old *model.VipUserInfoOld
|
||||
user *model.VipUserInfo
|
||||
)
|
||||
|
||||
if old, err = s.dao.OldVipInfo(c, mid); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
if user, err = s.dao.SelVipUserInfo(c, mid); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
|
||||
r := convertOldToNew(old)
|
||||
r.OldVer = user.Ver
|
||||
|
||||
if err = s.updateVipUserInfo(c, r); err != nil {
|
||||
err = errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
// clear cache.
|
||||
s.cleanVipRetry(mid)
|
||||
return
|
||||
}
|
||||
|
||||
// ClearUserCache clear user cache.
|
||||
func (s *Service) ClearUserCache(mid int64) {
|
||||
s.cleanVipRetry(mid)
|
||||
}
|
||||
|
||||
// ClearUserCache clear user cache.
|
||||
func (s *Service) grayScope(mid int64) bool {
|
||||
return mid%10000 < s.c.Property.GrayScope
|
||||
}
|
46
app/job/main/vip/service/vip_test.go
Normal file
46
app/job/main/vip/service/vip_test.go
Normal file
@ -0,0 +1,46 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"go-common/app/job/main/vip/model"
|
||||
"testing"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
// go test -test.v -test.run TestSyncUserInfoByMid
|
||||
func TestSyncUserInfoByMid(t *testing.T) {
|
||||
Convey("SyncUserInfoByMid err == nil", t, func() {
|
||||
err := s.SyncUserInfoByMid(context.TODO(), 1002)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
// go test -test.v -test.run TestUpdateDatabusUserInfo
|
||||
|
||||
func TestUpdateDatabusUserInfo(t *testing.T) {
|
||||
Convey("TestUpdateDatabusUserInfo err == nil", t, func() {
|
||||
var (
|
||||
mid int64 = 2089809
|
||||
old *model.VipUserInfoOld
|
||||
msg = new(model.VipUserInfoMsg)
|
||||
err error
|
||||
)
|
||||
old, err = s.dao.OldVipInfo(context.TODO(), mid)
|
||||
So(err, ShouldBeNil)
|
||||
msg.Mid = old.Mid
|
||||
msg.Type = old.Type
|
||||
msg.Status = old.Status
|
||||
msg.StartTime = old.StartTime.Time().Format("2006-01-02 15:04:05")
|
||||
msg.OverdueTime = old.OverdueTime.Time().Format("2006-01-02 15:04:05")
|
||||
msg.AnnualVipOverdueTime = old.AnnualVipOverdueTime.Time().Format("2006-01-02 15:04:05")
|
||||
msg.RecentTime = old.RecentTime.Time().Format("2006-01-02 15:04:05")
|
||||
msg.Wander = old.Wander
|
||||
msg.AutoRenewed = old.AutoRenewed
|
||||
msg.IsAutoRenew = old.IsAutoRenew
|
||||
msg.IosOverdueTime = old.IosOverdueTime.Time().Format("2006-01-02 15:04:05")
|
||||
userInfo := convertMsgToUserInfo(msg)
|
||||
err = s.addUserInfo(context.TODO(), userInfo)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
Reference in New Issue
Block a user