Create & Init Project...

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

View File

@@ -0,0 +1,24 @@
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/service/live/gift/api/grpc/v1:all-srcs",
"//app/service/live/gift/api/liverpc:all-srcs",
"//app/service/live/gift/cmd:all-srcs",
"//app/service/live/gift/conf:all-srcs",
"//app/service/live/gift/dao:all-srcs",
"//app/service/live/gift/model:all-srcs",
"//app/service/live/gift/server/grpc:all-srcs",
"//app/service/live/gift/server/http:all-srcs",
"//app/service/live/gift/service:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,2 @@
# v1.0.0
1. 上线功能xxx

View File

@@ -0,0 +1,6 @@
# Owner
shenli01
# Author
# Reviewer

View File

@@ -0,0 +1,10 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- shenli01
labels:
- live
- service
- service/live/gift
options:
no_parent_owners: true

View File

@@ -0,0 +1,12 @@
# gift-service
# 项目简介
1.
# 编译环境
# 依赖包
# 编译执行

View File

@@ -0,0 +1,62 @@
load(
"@io_bazel_rules_go//proto:def.bzl",
"go_proto_library",
)
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
proto_library(
name = "v1_proto",
srcs = ["api.proto"],
tags = ["automanaged"],
deps = ["@gogo_special_proto//github.com/gogo/protobuf/gogoproto"],
)
go_proto_library(
name = "v1_go_proto",
compilers = ["@io_bazel_rules_go//proto:gogofast_grpc"],
importpath = "go-common/app/service/live/gift/api/grpc/v1",
proto = ":v1_proto",
tags = ["automanaged"],
deps = ["@com_github_gogo_protobuf//gogoproto:go_default_library"],
)
go_library(
name = "go_default_library",
srcs = [
"api.bm.go",
"client.go",
],
embed = [":v1_go_proto"],
importpath = "go-common/app/service/live/gift/api/grpc/v1",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//library/net/http/blademaster:go_default_library",
"//library/net/http/blademaster/binding:go_default_library",
"//library/net/rpc/warden:go_default_library",
"@com_github_gogo_protobuf//gogoproto:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@org_golang_google_grpc//:go_default_library",
"@org_golang_x_net//context:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,88 @@
// Code generated by protoc-gen-bm v0.1, DO NOT EDIT.
// source: api.proto
/*
Package v1 is a generated blademaster stub package.
This code was generated with go-common/app/tool/bmgen/protoc-gen-bm v0.1.
It is generated from these files:
api.proto
*/
package v1
import (
"context"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/binding"
)
// to suppressed 'imported but not used warning'
var _ *bm.Context
var _ context.Context
var _ binding.StructValidator
var PathGiftRoomGiftList = "/live.xgift.v1.Gift/room_gift_list"
var PathGiftGiftConfig = "/live.xgift.v1.Gift/gift_config"
var PathGiftDiscountGiftList = "/live.xgift.v1.Gift/discount_gift_list"
var PathGiftDailyBag = "/live.xgift.v1.Gift/daily_bag"
// ==============
// Gift Interface
// ==============
type GiftBMServer interface {
RoomGiftList(ctx context.Context, req *RoomGiftListReq) (resp *RoomGiftListResp, err error)
GiftConfig(ctx context.Context, req *GiftConfigReq) (resp *GiftConfigResp, err error)
DiscountGiftList(ctx context.Context, req *DiscountGiftListReq) (resp *DiscountGiftListResp, err error)
DailyBag(ctx context.Context, req *DailyBagReq) (resp *DailyBagResp, err error)
}
var v1GiftSvc GiftBMServer
func giftRoomGiftList(c *bm.Context) {
p := new(RoomGiftListReq)
if err := c.BindWith(p, binding.Default(c.Request.Method, c.Request.Header.Get("Content-Type"))); err != nil {
return
}
resp, err := v1GiftSvc.RoomGiftList(c, p)
c.JSON(resp, err)
}
func giftGiftConfig(c *bm.Context) {
p := new(GiftConfigReq)
if err := c.BindWith(p, binding.Default(c.Request.Method, c.Request.Header.Get("Content-Type"))); err != nil {
return
}
resp, err := v1GiftSvc.GiftConfig(c, p)
c.JSON(resp, err)
}
func giftDiscountGiftList(c *bm.Context) {
p := new(DiscountGiftListReq)
if err := c.BindWith(p, binding.Default(c.Request.Method, c.Request.Header.Get("Content-Type"))); err != nil {
return
}
resp, err := v1GiftSvc.DiscountGiftList(c, p)
c.JSON(resp, err)
}
func giftDailyBag(c *bm.Context) {
p := new(DailyBagReq)
if err := c.BindWith(p, binding.Default(c.Request.Method, c.Request.Header.Get("Content-Type"))); err != nil {
return
}
resp, err := v1GiftSvc.DailyBag(c, p)
c.JSON(resp, err)
}
// RegisterGiftBMServer Register the blademaster route
func RegisterGiftBMServer(e *bm.Engine, server GiftBMServer) {
e.GET("/live.xgift.v1.Gift/room_gift_list", giftRoomGiftList)
e.GET("/live.xgift.v1.Gift/gift_config", giftGiftConfig)
e.GET("/live.xgift.v1.Gift/discount_gift_list", giftDiscountGiftList)
e.GET("/live.xgift.v1.Gift/daily_bag", giftDailyBag)
}

View File

@@ -0,0 +1,216 @@
<!-- package=live.xgift.v1 -->
- [/live.xgift.v1.Gift/room_gift_list](#live.xgift.v1.Giftroom_gift_list)
- [/live.xgift.v1.Gift/gift_config](#live.xgift.v1.Giftgift_config)
- [/live.xgift.v1.Gift/discount_gift_list](#live.xgift.v1.Giftdiscount_gift_list)
- [/live.xgift.v1.Gift/daily_bag](#live.xgift.v1.Giftdaily_bag)
## /live.xgift.v1.Gift/room_gift_list
### 无标题
#### 方法GET
#### 请求参数
|参数名|必选|类型|描述|
|:---|:---|:---|:---|
|room_id|否|integer||
|area_v2_parent_id|否|integer||
|area_v2_id|否|integer||
|platform|否|string||
|build|否|integer||
|mobi_app|否|string||
#### 响应
```javascript
{
"code": 0,
"message": "ok",
"data": {
"list": [
{
"id": 0,
"position": 0,
"plan_id": 0
}
],
"silver_list": [
{
"id": 0,
"position": 0,
"plan_id": 0
}
],
"show_count_map": 0,
"old_list": [
{
"id": 0,
"name": "",
"price": 0,
"type": 0,
"coin_type": {
"mapKey": ""
},
"img": "",
"gift_url": "",
"count_set": "",
"combo_num": 0,
"super_num": 0,
"count_map": {
"1": ""
}
}
]
}
}
```
## /live.xgift.v1.Gift/gift_config
### 无标题
#### 方法GET
#### 请求参数
|参数名|必选|类型|描述|
|:---|:---|:---|:---|
|platform|否|string||
|build|否|integer||
#### 响应
```javascript
{
"code": 0,
"message": "ok",
"data": {
"data": [
{
"id": 0,
"name": "",
"price": 0,
"type": 0,
"coin_type": "",
"bag_gift": 0,
"effect": 0,
"corner_mark": "",
"broadcast": 0,
"draw": 0,
"stay_time": 0,
"animation_frame_num": 0,
"desc": "",
"rule": "",
"rights": "",
"privilege_required": 0,
"count_map": [
{
"num": 0,
"text": ""
}
],
"img_basic": "",
"img_dynamic": "",
"frame_animation": "",
"gif": "",
"webp": "",
"full_sc_web": "",
"full_sc_horizontal": "",
"full_sc_vertical": "",
"full_sc_horizontal_svga": "",
"full_sc_vertical_svga": "",
"bullet_head": "",
"bullet_tail": "",
"limit_interval": 0
}
]
}
}
```
## /live.xgift.v1.Gift/discount_gift_list
### 无标题
#### 方法GET
#### 请求参数
|参数名|必选|类型|描述|
|:---|:---|:---|:---|
|uid|否|integer||
|roomid|否|integer||
|area_v2_parent_id|否|integer||
|area_v2_id|否|integer||
|platform|否|string||
|ruid|否|integer||
#### 响应
```javascript
{
"code": 0,
"message": "ok",
"data": {
"discount_list": [
{
"gift_id": 0,
"price": 0,
"discount_price": 0,
"corner_mark": "",
"corner_position": 0,
"corner_color": ""
}
]
}
}
```
## /live.xgift.v1.Gift/daily_bag
### 无标题
#### 方法GET
#### 请求参数
|参数名|必选|类型|描述|
|:---|:---|:---|:---|
|uid|否|integer||
#### 响应
```javascript
{
"code": 0,
"message": "ok",
"data": {
"bag_status": 0,
"bag_expire_status": 0,
"bag_toast": {
"toast_status": 0,
"toast_message": ""
},
"bag_list": [
{
"type": 0,
"bag_name": "",
"source": {
"medal_id": 0,
"medal_name": "",
"level": 0,
"user_level": 0
},
"gift_list": [
{
"gift_id": "",
"gift_num": 0,
"expire_at": 0
}
]
}
]
}
}
```

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,149 @@
syntax = "proto3";
package live.xgift.v1;
option go_package = "v1";
option (gogoproto.goproto_getters_all) = false;
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
service Gift{
rpc room_gift_list(RoomGiftListReq) returns (RoomGiftListResp);
rpc gift_config(GiftConfigReq) returns (GiftConfigResp);
rpc discount_gift_list(DiscountGiftListReq) returns (DiscountGiftListResp);
rpc daily_bag(DailyBagReq) returns (DailyBagResp);
}
message RoomGiftListReq{
int64 room_id = 1;
int64 area_v2_parent_id = 2;
int64 area_v2_id = 3;
string platform = 4;
int64 build = 5;
string mobi_app = 6;
}
message RoomGiftListResp{
repeated List list = 1 [(gogoproto.jsontag)="list"];
message List{
int64 id = 1 [(gogoproto.jsontag)="id"];
int64 position = 2 [(gogoproto.jsontag)="position"];
int64 plan_id = 3 [(gogoproto.jsontag)="plan_id"];
}
repeated List silver_list = 2 [(gogoproto.jsontag)="silver_list"];
int64 show_count_map = 3 [(gogoproto.jsontag)="show_count_map"];
repeated OldList old_list = 4 [(gogoproto.jsontag)="old_list"];
message OldList{
int64 id = 1 [(gogoproto.jsontag)="id"];
string name = 2 [(gogoproto.jsontag)="name"];
int64 price = 3 [(gogoproto.jsontag)="price"];
int64 type = 4 [(gogoproto.jsontag)="type"];
map<string, string> coin_type=5 [(gogoproto.jsontag)="coin_type"];
string img = 6 [(gogoproto.jsontag)="img"];
string gift_url = 7 [(gogoproto.jsontag)="gift_url"];
string count_set = 8 [(gogoproto.jsontag)="count_set"];
int64 combo_num = 9 [(gogoproto.jsontag)="combo_num"];
int64 super_num = 10 [(gogoproto.jsontag)="super_num"];
map<int64, string> count_map = 11 [(gogoproto.jsontag)="count_map"];
}
}
message GiftConfigReq{
string platform = 1;
int64 build = 2;
}
message GiftConfigResp{
repeated Config data = 1 [(gogoproto.jsontag)="data"];
message Config{
int64 id = 1 [(gogoproto.jsontag)="id"];
string name = 2 [(gogoproto.jsontag)="name"];
int64 price = 3 [(gogoproto.jsontag)="price"];
int64 type = 4 [(gogoproto.jsontag)="type"];
string coin_type = 5 [(gogoproto.jsontag)="coin_type"];
int64 bag_gift = 6 [(gogoproto.jsontag)="bag_gift"];
int64 effect = 7 [(gogoproto.jsontag)="effect"];
string corner_mark = 8 [(gogoproto.jsontag)="corner_mark"];
int64 broadcast = 9 [(gogoproto.jsontag)="broadcast"];
int64 draw = 10 [(gogoproto.jsontag)="draw"];
int64 stay_time = 11 [(gogoproto.jsontag)="stay_time"];
int64 animation_frame_num = 12 [(gogoproto.jsontag)="animation_frame_num"];
string desc = 13 [(gogoproto.jsontag)="desc"];
string rule = 14 [(gogoproto.jsontag)="rule"];
string rights = 15 [(gogoproto.jsontag)="rights"];
int64 privilege_required = 16 [(gogoproto.jsontag)="privilege_required"];
repeated CountMap count_map = 17 [(gogoproto.jsontag)="count_map"];
string img_basic = 18 [(gogoproto.jsontag)="img_basic"];
string img_dynamic = 19 [(gogoproto.jsontag)="img_dynamic"];
string frame_animation = 20 [(gogoproto.jsontag)="frame_animation"];
string gif = 21 [(gogoproto.jsontag)="gif"];
string webp = 22 [(gogoproto.jsontag)="webp"];
string full_sc_web = 23 [(gogoproto.jsontag)="full_sc_web"];
string full_sc_horizontal = 24 [(gogoproto.jsontag)="full_sc_horizontal"];
string full_sc_vertical = 25 [(gogoproto.jsontag)="full_sc_vertical"];
string full_sc_horizontal_svga = 26 [(gogoproto.jsontag)="full_sc_horizontal_svga"];
string full_sc_vertical_svga = 27 [(gogoproto.jsontag)="full_sc_vertical_svga"];
string bullet_head = 28 [(gogoproto.jsontag)="bullet_head"];
string bullet_tail = 29 [(gogoproto.jsontag)="bullet_tail"];
int64 limit_interval = 30 [(gogoproto.jsontag)="limit_interval"];
}
message CountMap{
int64 num = 1 [(gogoproto.jsontag)="num"];
string text = 2 [(gogoproto.jsontag)="text"];
}
}
message DiscountGiftListReq{
int64 uid=1;
int64 roomid=2;
int64 area_v2_parent_id=3;
int64 area_v2_id=4;
string platform=5;
int64 ruid=6;
}
message DiscountGiftListResp{
repeated GiftInfo discount_list = 1;
message GiftInfo{
int64 gift_id=1 [(gogoproto.jsontag)="gift_id"];
int64 price=2 [(gogoproto.jsontag)="price"];
int64 discount_price=3 [(gogoproto.jsontag)="discount_price"];
string corner_mark=4 [(gogoproto.jsontag)="corner_mark"];
int64 corner_position=5 [(gogoproto.jsontag)="corner_position"];
string corner_color=6 [(gogoproto.jsontag)="corner_color"];
}
}
message DailyBagReq{
int64 uid = 1;
}
message DailyBagResp{
int64 bag_status=1 [(gogoproto.jsontag)="bag_status"];
int64 bag_expire_status=2 [(gogoproto.jsontag)="bag_expire_status"];
BagToast bag_toast = 3 [(gogoproto.jsontag)="bag_toast"];
message BagToast{
int64 toast_status=1 [(gogoproto.jsontag)="toast_status"];
string toast_message=2 [(gogoproto.jsontag)="toast_message"];
}
repeated BagList bag_list = 4 [(gogoproto.jsontag)="bag_list"];
message BagList{
int64 type=1 [(gogoproto.jsontag)="type"];
string bag_name=2 [(gogoproto.jsontag)="bag_name"];
Source source = 3 [(gogoproto.jsontag)="source"];
message Source{
int64 medal_id = 1 [(gogoproto.jsontag)="medal_id"];
string medal_name = 2 [(gogoproto.jsontag)="medal_name"];
int64 level = 3 [(gogoproto.jsontag)="level"];
int64 user_level = 4 [(gogoproto.jsontag)="user_level"];
}
repeated GiftList gift_list = 4 [(gogoproto.jsontag)="gift_list"];
message GiftList{
string gift_id=1 [(gogoproto.jsontag)="gift_id"];
int64 gift_num=2 [(gogoproto.jsontag)="gift_num"];
int64 expire_at=3 [(gogoproto.jsontag)="expire_at"];
}
}
}

View File

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

View File

@@ -0,0 +1 @@
# HTTP API文档

View File

@@ -0,0 +1,187 @@
##
`GET http://api.live.bilibili.com/xlive/gift/v1/gift/room_gift_list`
### 请求参数
|参数名|必选|类型|描述|
|:---|:---|:---|:---|
|room_id|否|integer||
|area_v2_parent_id|否|integer||
|area_v2_id|否|integer||
|platform|否|string||
|build|否|integer||
```json
{
"code": 0,
"message": "ok",
"data": {
"list": [
{
"id": 0,
"position": 0,
"plan_id": 0
}
],
"silver_list": [
{
"id": 0,
"position": 0,
"plan_id": 0
}
],
"show_count_map": 0,
"old_list": [
{
"id": 0,
"name": "",
"price": 0,
"type": 0,
"coin_type": {
"mapKey": ""
},
"img": "",
"gift_url": "",
"count_set": "",
"combo_num": 0,
"super_num": 0,
"count_map": {
"1": ""
}
}
]
}
}
```
##
`GET http://api.live.bilibili.com/xlive/gift/v1/gift/gift_config`
### 请求参数
|参数名|必选|类型|描述|
|:---|:---|:---|:---|
|platform|否|string||
|build|否|integer||
```json
{
"code": 0,
"message": "ok",
"data": {
"data": [
{
"id": 0,
"name": "",
"price": 0,
"type": 0,
"coin_type": "",
"bag_gift": 0,
"effect": 0,
"corner_mark": "",
"broadcast": 0,
"draw": 0,
"stay_time": 0,
"animation_frame_num": 0,
"desc": "",
"rule": "",
"rights": "",
"privilege_required": 0,
"count_map": [
{
"num": 0,
"text": ""
}
],
"img_basic": "",
"img_dynamic": "",
"frame_animation": "",
"gif": "",
"webp": "",
"full_sc_web": "",
"full_sc_horizontal": "",
"full_sc_vertical": "",
"full_sc_horizontal_svga": "",
"full_sc_vertical_svga": "",
"bullet_head": "",
"bullet_tail": ""
}
]
}
}
```
##
`GET http://api.live.bilibili.com/xlive/gift/v1/gift/discount_gift_list`
### 请求参数
|参数名|必选|类型|描述|
|:---|:---|:---|:---|
|uid|否|integer||
|roomid|否|integer||
|area_v2_parent_id|否|integer||
|area_v2_id|否|integer||
|platform|否|string||
|ruid|否|integer||
```json
{
"code": 0,
"message": "ok",
"data": {
"discount_list": [
{
"gift_id": 0,
"price": 0,
"discount_price": 0,
"corner_mark": "",
"corner_position": 0,
"corner_color": ""
}
]
}
}
```
##
`GET http://api.live.bilibili.com/xlive/gift/v1/gift/daily_bag`
### 请求参数
|参数名|必选|类型|描述|
|:---|:---|:---|:---|
|uid|否|integer||
```json
{
"code": 0,
"message": "ok",
"data": {
"bag_status": 0,
"bag_expire_status": 0,
"bag_toast": {
"toast_status": 0,
"toast_message": ""
},
"bag_list": [
{
"type": 0,
"bag_name": "",
"gift_list": [
{
"gift_id": 0,
"gift_num": 0,
"expire_at": 0
}
]
}
]
}
}
```

View File

@@ -0,0 +1,37 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["client.go"],
importpath = "go-common/app/service/live/gift/api/liverpc",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/live/gift/api/liverpc/v0:go_default_library",
"//app/service/live/gift/api/liverpc/v1:go_default_library",
"//library/net/rpc/liverpc:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/service/live/gift/api/liverpc/v0:all-srcs",
"//app/service/live/gift/api/liverpc/v1:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,46 @@
// Code generated by liverpcgen, DO NOT EDIT.
// source: *.proto files under this directory
// If you want to change this file, Please see README in go-common/app/tool/liverpc/protoc-gen-liverpc/
package liverpc
import (
"go-common/app/service/live/gift/api/liverpc/v0"
"go-common/app/service/live/gift/api/liverpc/v1"
"go-common/library/net/rpc/liverpc"
)
// Client that represents a liverpc gift service api
type Client struct {
cli *liverpc.Client
// V0Smalltv presents the controller in liverpc
V0Smalltv v0.Smalltv
// V1Gift presents the controller in liverpc
V1Gift v1.Gift
}
// DiscoveryAppId the discovery id is not the tree name
var DiscoveryAppId = "live.gift"
// New a Client that represents a liverpc live.gift service api
// conf can be empty, and it will use discovery to find service by default
// conf.AppID will be overwrite by a fixed value DiscoveryAppId
// therefore is no need to set
func New(conf *liverpc.ClientConfig) *Client {
if conf == nil {
conf = &liverpc.ClientConfig{}
}
conf.AppID = DiscoveryAppId
var realCli = liverpc.NewClient(conf)
cli := &Client{cli: realCli}
cli.clientInit(realCli)
return cli
}
func (cli *Client) GetRawCli() *liverpc.Client {
return cli.cli
}
func (cli *Client) clientInit(realCli *liverpc.Client) {
cli.V0Smalltv = v0.NewSmalltvRpcClient(realCli)
cli.V1Gift = v1.NewGiftRpcClient(realCli)
}

View File

@@ -0,0 +1,56 @@
load(
"@io_bazel_rules_go//proto:def.bzl",
"go_proto_library",
)
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
proto_library(
name = "v0_proto",
srcs = ["Smalltv.proto"],
tags = ["automanaged"],
deps = ["@gogo_special_proto//github.com/gogo/protobuf/gogoproto"],
)
go_proto_library(
name = "v0_go_proto",
compilers = ["@io_bazel_rules_go//proto:gogofast_grpc"],
importpath = "go-common/app/service/live/gift/api/liverpc/v0",
proto = ":v0_proto",
tags = ["automanaged"],
deps = ["@com_github_gogo_protobuf//gogoproto:go_default_library"],
)
go_library(
name = "go_default_library",
srcs = ["Smalltv.liverpc.go"],
embed = [":v0_go_proto"],
importpath = "go-common/app/service/live/gift/api/liverpc/v0",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//library/net/rpc/liverpc:go_default_library",
"@com_github_gogo_protobuf//gogoproto:go_default_library",
"@com_github_gogo_protobuf//proto: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"],
)

View File

@@ -0,0 +1,63 @@
// Code generated by protoc-gen-liverpc v0.1, DO NOT EDIT.
// source: v0/Smalltv.proto
/*
Package v0 is a generated liverpc stub package.
This code was generated with go-common/app/tool/liverpc/protoc-gen-liverpc v0.1.
It is generated from these files:
v0/Smalltv.proto
*/
package v0
import context "context"
import proto "github.com/golang/protobuf/proto"
import "go-common/library/net/rpc/liverpc"
var _ proto.Message // generate to suppress unused imports
// Imports only used by utility functions:
// =================
// Smalltv Interface
// =================
type Smalltv interface {
// * 开启抽奖的内部接口
// 返回的是广播的内容列表
Start(context.Context, *SmalltvStartReq) (*SmalltvStartResp, error)
}
// =======================
// Smalltv Live Rpc Client
// =======================
type smalltvRpcClient struct {
client *liverpc.Client
}
// NewSmalltvRpcClient creates a Rpc client that implements the Smalltv interface.
// It communicates using Rpc and can be configured with a custom HTTPClient.
func NewSmalltvRpcClient(client *liverpc.Client) Smalltv {
return &smalltvRpcClient{
client: client,
}
}
func (c *smalltvRpcClient) Start(ctx context.Context, in *SmalltvStartReq) (*SmalltvStartResp, error) {
out := new(SmalltvStartResp)
err := doRpcRequest(ctx, c.client, 0, "Smalltv.start", in, out)
if err != nil {
return nil, err
}
return out, nil
}
// =====
// Utils
// =====
func doRpcRequest(ctx context.Context, client *liverpc.Client, version int, method string, in, out proto.Message) (err error) {
err = client.Call(ctx, version, method, in, out)
return
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,68 @@
syntax = "proto3";
package gift.v0;
option go_package = "v0";
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
service Smalltv {
/** 开启抽奖的内部接口
* 返回的是广播的内容列表
*/
rpc start (SmalltvStartReq) returns (SmalltvStartResp);
}
message SmalltvStartReq {
// 用户id
int64 uid = 1 [(gogoproto.jsontag) = "uid"];
// 房间号
int64 roomid = 2 [(gogoproto.jsontag) = "roomid"];
// 道具id
int64 gift_id = 3 [(gogoproto.jsontag) = "gift_id"];
// 道具个数
int64 num = 4 [(gogoproto.jsontag) = "num"];
// 业务id
int64 tid = 5 [(gogoproto.jsontag) = "tid"];
// 公告样式id
int64 style_id = 6 [(gogoproto.jsontag) = "style_id"];
}
message SmalltvStartResp {
//
int64 code = 1 [(gogoproto.jsontag) = "code"];
//
string msg = 2 [(gogoproto.jsontag) = "msg"];
//
repeated MSG data = 3 [(gogoproto.jsontag) = "data"];
message MSG {
//
string cmd = 1 [(gogoproto.jsontag) = "cmd"];
//
string msg = 2 [(gogoproto.jsontag) = "msg"];
//
string msg_text = 3 [(gogoproto.jsontag) = "msg_text"];
//
string msg_common = 4 [(gogoproto.jsontag) = "msg_common"];
//
string msg_self = 5 [(gogoproto.jsontag) = "msg_self"];
//
int64 rep = 6 [(gogoproto.jsontag) = "rep"];
//
int64 styleType = 7 [(gogoproto.jsontag) = "styleType"];
//
string url = 8 [(gogoproto.jsontag) = "url"];
//
int64 roomid = 9 [(gogoproto.jsontag) = "roomid"];
//
int64 real_roomid = 10 [(gogoproto.jsontag) = "real_roomid"];
//
int64 rnd = 11 [(gogoproto.jsontag) = "rnd"];
//
int64 broadcast_type = 12 [(gogoproto.jsontag) = "broadcast_type"];
}
}

View File

@@ -0,0 +1,56 @@
load(
"@io_bazel_rules_go//proto:def.bzl",
"go_proto_library",
)
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
proto_library(
name = "v1_proto",
srcs = ["Gift.proto"],
tags = ["automanaged"],
deps = ["@gogo_special_proto//github.com/gogo/protobuf/gogoproto"],
)
go_proto_library(
name = "v1_go_proto",
compilers = ["@io_bazel_rules_go//proto:gogofast_grpc"],
importpath = "go-common/app/service/live/gift/api/liverpc/v1",
proto = ":v1_proto",
tags = ["automanaged"],
deps = ["@com_github_gogo_protobuf//gogoproto:go_default_library"],
)
go_library(
name = "go_default_library",
srcs = ["Gift.liverpc.go"],
embed = [":v1_go_proto"],
importpath = "go-common/app/service/live/gift/api/liverpc/v1",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//library/net/rpc/liverpc:go_default_library",
"@com_github_gogo_protobuf//gogoproto:go_default_library",
"@com_github_gogo_protobuf//proto: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"],
)

View File

@@ -0,0 +1,63 @@
// Code generated by protoc-gen-liverpc v0.1, DO NOT EDIT.
// source: v1/Gift.proto
/*
Package v1 is a generated liverpc stub package.
This code was generated with go-common/app/tool/liverpc/protoc-gen-liverpc v0.1.
It is generated from these files:
v1/Gift.proto
*/
package v1
import context "context"
import proto "github.com/golang/protobuf/proto"
import "go-common/library/net/rpc/liverpc"
var _ proto.Message // generate to suppress unused imports
// Imports only used by utility functions:
// ==============
// Gift Interface
// ==============
type Gift interface {
// * 增加包裹道具
//
AddFreeGift(context.Context, *GiftAddFreeGiftReq) (*GiftAddFreeGiftResp, error)
}
// ====================
// Gift Live Rpc Client
// ====================
type giftRpcClient struct {
client *liverpc.Client
}
// NewGiftRpcClient creates a Rpc client that implements the Gift interface.
// It communicates using Rpc and can be configured with a custom HTTPClient.
func NewGiftRpcClient(client *liverpc.Client) Gift {
return &giftRpcClient{
client: client,
}
}
func (c *giftRpcClient) AddFreeGift(ctx context.Context, in *GiftAddFreeGiftReq) (*GiftAddFreeGiftResp, error) {
out := new(GiftAddFreeGiftResp)
err := doRpcRequest(ctx, c.client, 1, "Gift.addFreeGift", in, out)
if err != nil {
return nil, err
}
return out, nil
}
// =====
// Utils
// =====
func doRpcRequest(ctx context.Context, client *liverpc.Client, version int, method string, in, out proto.Message) (err error) {
err = client.Call(ctx, version, method, in, out)
return
}

View File

@@ -0,0 +1,938 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: v1/Gift.proto
package v1
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import _ "github.com/gogo/protobuf/gogoproto"
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.GoGoProtoPackageIsVersion2 // please upgrade the proto package
type GiftAddFreeGiftReq struct {
// 用户uid
Uid int64 `protobuf:"varint,1,opt,name=uid,proto3" json:"uid"`
// 礼物id
Giftid int64 `protobuf:"varint,2,opt,name=giftid,proto3" json:"giftid"`
// 数量
Num int64 `protobuf:"varint,3,opt,name=num,proto3" json:"num"`
// 过期时间
Expireat int64 `protobuf:"varint,4,opt,name=expireat,proto3" json:"expireat"`
//
Code string `protobuf:"bytes,5,opt,name=code,proto3" json:"code"`
//
Caller string `protobuf:"bytes,6,opt,name=caller,proto3" json:"caller"`
}
func (m *GiftAddFreeGiftReq) Reset() { *m = GiftAddFreeGiftReq{} }
func (m *GiftAddFreeGiftReq) String() string { return proto.CompactTextString(m) }
func (*GiftAddFreeGiftReq) ProtoMessage() {}
func (*GiftAddFreeGiftReq) Descriptor() ([]byte, []int) {
return fileDescriptor_Gift_7d77e02c48c2917b, []int{0}
}
func (m *GiftAddFreeGiftReq) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *GiftAddFreeGiftReq) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_GiftAddFreeGiftReq.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalTo(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (dst *GiftAddFreeGiftReq) XXX_Merge(src proto.Message) {
xxx_messageInfo_GiftAddFreeGiftReq.Merge(dst, src)
}
func (m *GiftAddFreeGiftReq) XXX_Size() int {
return m.Size()
}
func (m *GiftAddFreeGiftReq) XXX_DiscardUnknown() {
xxx_messageInfo_GiftAddFreeGiftReq.DiscardUnknown(m)
}
var xxx_messageInfo_GiftAddFreeGiftReq proto.InternalMessageInfo
func (m *GiftAddFreeGiftReq) GetUid() int64 {
if m != nil {
return m.Uid
}
return 0
}
func (m *GiftAddFreeGiftReq) GetGiftid() int64 {
if m != nil {
return m.Giftid
}
return 0
}
func (m *GiftAddFreeGiftReq) GetNum() int64 {
if m != nil {
return m.Num
}
return 0
}
func (m *GiftAddFreeGiftReq) GetExpireat() int64 {
if m != nil {
return m.Expireat
}
return 0
}
func (m *GiftAddFreeGiftReq) GetCode() string {
if m != nil {
return m.Code
}
return ""
}
func (m *GiftAddFreeGiftReq) GetCaller() string {
if m != nil {
return m.Caller
}
return ""
}
type GiftAddFreeGiftResp struct {
//
Code int64 `protobuf:"varint,1,opt,name=code,proto3" json:"code"`
//
Msg string `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg"`
//
Data *GiftAddFreeGiftResp_Data `protobuf:"bytes,3,opt,name=data" json:"data"`
}
func (m *GiftAddFreeGiftResp) Reset() { *m = GiftAddFreeGiftResp{} }
func (m *GiftAddFreeGiftResp) String() string { return proto.CompactTextString(m) }
func (*GiftAddFreeGiftResp) ProtoMessage() {}
func (*GiftAddFreeGiftResp) Descriptor() ([]byte, []int) {
return fileDescriptor_Gift_7d77e02c48c2917b, []int{1}
}
func (m *GiftAddFreeGiftResp) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *GiftAddFreeGiftResp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_GiftAddFreeGiftResp.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalTo(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (dst *GiftAddFreeGiftResp) XXX_Merge(src proto.Message) {
xxx_messageInfo_GiftAddFreeGiftResp.Merge(dst, src)
}
func (m *GiftAddFreeGiftResp) XXX_Size() int {
return m.Size()
}
func (m *GiftAddFreeGiftResp) XXX_DiscardUnknown() {
xxx_messageInfo_GiftAddFreeGiftResp.DiscardUnknown(m)
}
var xxx_messageInfo_GiftAddFreeGiftResp proto.InternalMessageInfo
func (m *GiftAddFreeGiftResp) GetCode() int64 {
if m != nil {
return m.Code
}
return 0
}
func (m *GiftAddFreeGiftResp) GetMsg() string {
if m != nil {
return m.Msg
}
return ""
}
func (m *GiftAddFreeGiftResp) GetData() *GiftAddFreeGiftResp_Data {
if m != nil {
return m.Data
}
return nil
}
type GiftAddFreeGiftResp_Data struct {
//
BagId int64 `protobuf:"varint,1,opt,name=bag_id,json=bagId,proto3" json:"bag_id"`
}
func (m *GiftAddFreeGiftResp_Data) Reset() { *m = GiftAddFreeGiftResp_Data{} }
func (m *GiftAddFreeGiftResp_Data) String() string { return proto.CompactTextString(m) }
func (*GiftAddFreeGiftResp_Data) ProtoMessage() {}
func (*GiftAddFreeGiftResp_Data) Descriptor() ([]byte, []int) {
return fileDescriptor_Gift_7d77e02c48c2917b, []int{1, 0}
}
func (m *GiftAddFreeGiftResp_Data) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *GiftAddFreeGiftResp_Data) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_GiftAddFreeGiftResp_Data.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalTo(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (dst *GiftAddFreeGiftResp_Data) XXX_Merge(src proto.Message) {
xxx_messageInfo_GiftAddFreeGiftResp_Data.Merge(dst, src)
}
func (m *GiftAddFreeGiftResp_Data) XXX_Size() int {
return m.Size()
}
func (m *GiftAddFreeGiftResp_Data) XXX_DiscardUnknown() {
xxx_messageInfo_GiftAddFreeGiftResp_Data.DiscardUnknown(m)
}
var xxx_messageInfo_GiftAddFreeGiftResp_Data proto.InternalMessageInfo
func (m *GiftAddFreeGiftResp_Data) GetBagId() int64 {
if m != nil {
return m.BagId
}
return 0
}
func init() {
proto.RegisterType((*GiftAddFreeGiftReq)(nil), "gift.v1.GiftAddFreeGiftReq")
proto.RegisterType((*GiftAddFreeGiftResp)(nil), "gift.v1.GiftAddFreeGiftResp")
proto.RegisterType((*GiftAddFreeGiftResp_Data)(nil), "gift.v1.GiftAddFreeGiftResp.Data")
}
func (m *GiftAddFreeGiftReq) 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 *GiftAddFreeGiftReq) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if m.Uid != 0 {
dAtA[i] = 0x8
i++
i = encodeVarintGift(dAtA, i, uint64(m.Uid))
}
if m.Giftid != 0 {
dAtA[i] = 0x10
i++
i = encodeVarintGift(dAtA, i, uint64(m.Giftid))
}
if m.Num != 0 {
dAtA[i] = 0x18
i++
i = encodeVarintGift(dAtA, i, uint64(m.Num))
}
if m.Expireat != 0 {
dAtA[i] = 0x20
i++
i = encodeVarintGift(dAtA, i, uint64(m.Expireat))
}
if len(m.Code) > 0 {
dAtA[i] = 0x2a
i++
i = encodeVarintGift(dAtA, i, uint64(len(m.Code)))
i += copy(dAtA[i:], m.Code)
}
if len(m.Caller) > 0 {
dAtA[i] = 0x32
i++
i = encodeVarintGift(dAtA, i, uint64(len(m.Caller)))
i += copy(dAtA[i:], m.Caller)
}
return i, nil
}
func (m *GiftAddFreeGiftResp) 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 *GiftAddFreeGiftResp) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if m.Code != 0 {
dAtA[i] = 0x8
i++
i = encodeVarintGift(dAtA, i, uint64(m.Code))
}
if len(m.Msg) > 0 {
dAtA[i] = 0x12
i++
i = encodeVarintGift(dAtA, i, uint64(len(m.Msg)))
i += copy(dAtA[i:], m.Msg)
}
if m.Data != nil {
dAtA[i] = 0x1a
i++
i = encodeVarintGift(dAtA, i, uint64(m.Data.Size()))
n1, err := m.Data.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n1
}
return i, nil
}
func (m *GiftAddFreeGiftResp_Data) 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 *GiftAddFreeGiftResp_Data) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if m.BagId != 0 {
dAtA[i] = 0x8
i++
i = encodeVarintGift(dAtA, i, uint64(m.BagId))
}
return i, nil
}
func encodeVarintGift(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 *GiftAddFreeGiftReq) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.Uid != 0 {
n += 1 + sovGift(uint64(m.Uid))
}
if m.Giftid != 0 {
n += 1 + sovGift(uint64(m.Giftid))
}
if m.Num != 0 {
n += 1 + sovGift(uint64(m.Num))
}
if m.Expireat != 0 {
n += 1 + sovGift(uint64(m.Expireat))
}
l = len(m.Code)
if l > 0 {
n += 1 + l + sovGift(uint64(l))
}
l = len(m.Caller)
if l > 0 {
n += 1 + l + sovGift(uint64(l))
}
return n
}
func (m *GiftAddFreeGiftResp) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.Code != 0 {
n += 1 + sovGift(uint64(m.Code))
}
l = len(m.Msg)
if l > 0 {
n += 1 + l + sovGift(uint64(l))
}
if m.Data != nil {
l = m.Data.Size()
n += 1 + l + sovGift(uint64(l))
}
return n
}
func (m *GiftAddFreeGiftResp_Data) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.BagId != 0 {
n += 1 + sovGift(uint64(m.BagId))
}
return n
}
func sovGift(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
}
func sozGift(x uint64) (n int) {
return sovGift(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *GiftAddFreeGiftReq) 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 ErrIntOverflowGift
}
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: GiftAddFreeGiftReq: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: GiftAddFreeGiftReq: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Uid", wireType)
}
m.Uid = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGift
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Uid |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Giftid", wireType)
}
m.Giftid = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGift
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Giftid |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Num", wireType)
}
m.Num = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGift
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Num |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 4:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Expireat", wireType)
}
m.Expireat = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGift
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Expireat |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGift
}
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 ErrInvalidLengthGift
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Code = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 6:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Caller", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGift
}
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 ErrInvalidLengthGift
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Caller = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGift(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthGift
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *GiftAddFreeGiftResp) 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 ErrIntOverflowGift
}
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: GiftAddFreeGiftResp: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: GiftAddFreeGiftResp: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType)
}
m.Code = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGift
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Code |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Msg", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGift
}
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 ErrInvalidLengthGift
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Msg = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGift
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGift
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Data == nil {
m.Data = &GiftAddFreeGiftResp_Data{}
}
if err := m.Data.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGift(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthGift
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *GiftAddFreeGiftResp_Data) 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 ErrIntOverflowGift
}
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: Data: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Data: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field BagId", wireType)
}
m.BagId = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGift
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.BagId |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipGift(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthGift
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipGift(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, ErrIntOverflowGift
}
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, ErrIntOverflowGift
}
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, ErrIntOverflowGift
}
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, ErrInvalidLengthGift
}
return iNdEx, nil
case 3:
for {
var innerWire uint64
var start int = iNdEx
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowGift
}
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 := skipGift(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 (
ErrInvalidLengthGift = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowGift = fmt.Errorf("proto: integer overflow")
)
func init() { proto.RegisterFile("v1/Gift.proto", fileDescriptor_Gift_7d77e02c48c2917b) }
var fileDescriptor_Gift_7d77e02c48c2917b = []byte{
// 365 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x52, 0xbd, 0x6e, 0xe2, 0x40,
0x10, 0x66, 0xb1, 0x31, 0x30, 0xdc, 0x35, 0x7b, 0x8d, 0xe1, 0x90, 0x0d, 0x54, 0x5c, 0x71, 0x46,
0x90, 0x07, 0x88, 0x82, 0xa2, 0xfc, 0x74, 0xd1, 0x96, 0x69, 0xa2, 0x35, 0x5e, 0x36, 0x96, 0x30,
0x06, 0x63, 0xa3, 0x3c, 0x46, 0x9e, 0x27, 0x4f, 0x90, 0x92, 0x32, 0x4a, 0x61, 0x45, 0xd0, 0xf9,
0x29, 0xa2, 0x1d, 0x5b, 0x46, 0xca, 0x5f, 0xf3, 0xed, 0xcc, 0x37, 0x9a, 0x6f, 0xbe, 0x19, 0x2d,
0xfc, 0xde, 0x8e, 0x47, 0x97, 0xfe, 0x3c, 0x76, 0x56, 0x51, 0x18, 0x87, 0xb4, 0x2e, 0x55, 0xbc,
0x1d, 0x77, 0xfe, 0x4b, 0x3f, 0xbe, 0x4f, 0x5c, 0x67, 0x16, 0x06, 0x23, 0x19, 0xca, 0x70, 0x84,
0x75, 0x37, 0x99, 0x63, 0x86, 0x09, 0x46, 0x79, 0xdf, 0xe0, 0x95, 0x00, 0x55, 0x32, 0x67, 0x9e,
0x77, 0x11, 0x09, 0xa1, 0x42, 0x26, 0xd6, 0xb4, 0x0d, 0x5a, 0xe2, 0x7b, 0x26, 0xe9, 0x91, 0xa1,
0x36, 0xad, 0x67, 0xa9, 0xad, 0x52, 0xa6, 0x80, 0x0e, 0xc0, 0x50, 0xb3, 0x7c, 0xcf, 0xac, 0x62,
0x15, 0xb2, 0xd4, 0x2e, 0x18, 0x56, 0xbc, 0xaa, 0x7d, 0x99, 0x04, 0xa6, 0x76, 0x6c, 0x5f, 0x26,
0x01, 0x53, 0x40, 0x87, 0xd0, 0x10, 0x0f, 0x2b, 0x3f, 0x12, 0x3c, 0x36, 0x75, 0xac, 0xff, 0xca,
0x52, 0xbb, 0xe4, 0x58, 0x19, 0xd1, 0x2e, 0xe8, 0xb3, 0xd0, 0x13, 0x66, 0xad, 0x47, 0x86, 0xcd,
0x69, 0x23, 0x4b, 0x6d, 0xcc, 0x19, 0xa2, 0xb2, 0x31, 0xe3, 0x8b, 0x85, 0x88, 0x4c, 0x03, 0xeb,
0x68, 0x23, 0x67, 0x58, 0xf1, 0x0e, 0x9e, 0x08, 0xfc, 0xf9, 0xb4, 0xdc, 0x66, 0x55, 0x2a, 0xe7,
0xeb, 0x7d, 0x54, 0x6e, 0x83, 0x16, 0x6c, 0x24, 0x6e, 0xd7, 0xcc, 0xcd, 0x07, 0x1b, 0xc9, 0x14,
0xd0, 0x53, 0xd0, 0x3d, 0x1e, 0x73, 0x5c, 0xac, 0x35, 0xe9, 0x3b, 0xc5, 0xd1, 0x9d, 0x2f, 0x86,
0x38, 0xe7, 0x3c, 0xe6, 0xb9, 0xb6, 0x6a, 0x61, 0x88, 0x9d, 0x7f, 0xa0, 0x2b, 0x9e, 0xf6, 0xc1,
0x70, 0xb9, 0xbc, 0x2b, 0x4f, 0x8c, 0xee, 0x73, 0x86, 0xd5, 0x5c, 0x2e, 0xaf, 0xbd, 0xc9, 0x0d,
0xe8, 0x4a, 0x8b, 0x5e, 0x41, 0x8b, 0x1f, 0xa5, 0xe9, 0xdf, 0xef, 0x87, 0xae, 0x3b, 0xdd, 0x9f,
0x1c, 0x4d, 0xbb, 0xcf, 0x7b, 0x8b, 0xec, 0xf6, 0x16, 0x79, 0xdb, 0x5b, 0xe4, 0xf1, 0x60, 0x55,
0x76, 0x07, 0xab, 0xf2, 0x72, 0xb0, 0x2a, 0xb7, 0xd5, 0xed, 0xd8, 0x35, 0xf0, 0x43, 0x9c, 0xbc,
0x07, 0x00, 0x00, 0xff, 0xff, 0x49, 0xd7, 0x75, 0x4e, 0x59, 0x02, 0x00, 0x00,
}

View File

@@ -0,0 +1,46 @@
syntax = "proto3";
package gift.v1;
option go_package = "v1";
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
service Gift {
/** 增加包裹道具
*
*/
rpc addFreeGift (GiftAddFreeGiftReq) returns (GiftAddFreeGiftResp);
}
message GiftAddFreeGiftReq {
// 用户uid
int64 uid = 1 [(gogoproto.jsontag) = "uid"];
// 礼物id
int64 giftid = 2 [(gogoproto.jsontag) = "giftid"];
// 数量
int64 num = 3 [(gogoproto.jsontag) = "num"];
// 过期时间
int64 expireat = 4 [(gogoproto.jsontag) = "expireat"];
//
string code = 5 [(gogoproto.jsontag) = "code"];
//
string caller = 6 [(gogoproto.jsontag) = "caller"];
}
message GiftAddFreeGiftResp {
//
int64 code = 1 [(gogoproto.jsontag) = "code"];
//
string msg = 2 [(gogoproto.jsontag) = "msg"];
//
Data data = 3 [(gogoproto.jsontag) = "data"];
message Data {
//
int64 bag_id = 1 [(gogoproto.jsontag) = "bag_id"];
}
}

View File

@@ -0,0 +1,49 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_binary(
name = "cmd",
embed = [":go_default_library"],
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = ["main.go"],
data = ["test.toml"],
importpath = "go-common/app/service/live/gift/cmd",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/live/gift/conf:go_default_library",
"//app/service/live/gift/server/grpc:go_default_library",
"//app/service/live/gift/server/http:go_default_library",
"//app/service/live/gift/service:go_default_library",
"//app/service/live/resource/sdk:go_default_library",
"//library/ecode/tip:go_default_library",
"//library/log:go_default_library",
"//library/net/trace:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/service/live/gift/cmd/client:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,40 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_binary(
name = "client",
embed = [":go_default_library"],
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = ["main.go"],
importpath = "go-common/app/service/live/gift/cmd/client",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/live/gift/api/grpc/v1:go_default_library",
"//library/net/rpc/warden:go_default_library",
"//library/time:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,58 @@
package main
import (
"context"
"flag"
"fmt"
"log"
"time"
"go-common/app/service/live/gift/api/grpc/v1"
"go-common/library/net/rpc/warden"
xtime "go-common/library/time"
)
var name, addr string
func init() {
flag.StringVar(&name, "name", "lily", "name")
flag.StringVar(&addr, "addr", "127.0.0.1:9000", "server addr")
}
func main() {
flag.Parse()
cfg := &warden.ClientConfig{
Dial: xtime.Duration(time.Second * 3),
Timeout: xtime.Duration(time.Second * 3),
}
cc, err := warden.NewClient(cfg).Dial(context.Background(), addr)
if err != nil {
log.Fatalf("new client failed!err:=%v", err)
return
}
client := v1.NewGiftClient(cc)
//resp, err := client.RoomGiftList(context.Background(), &v1.RoomGiftListReq{
// RoomId: 1,
// AreaV2ParentId:1,
// AreaV2Id:1,
// Platform:"android",
//})
//resp, err:= client.GiftConfig(context.Background(), &v1.GiftConfigReq{
// Platform:"android",
// Build:1,
//})
resp, err := client.DiscountGiftList(context.Background(), &v1.DiscountGiftListReq{
//Uid: 88895029,
Uid: 1,
Roomid: 1,
//Ruid: 1,
AreaV2Id: 89,
})
if err != nil {
log.Fatalf("say hello failed!err:=%v,resp:(%v)", err, resp)
return
}
fmt.Printf("got HelloReply:%+v", resp)
}

View File

@@ -0,0 +1,52 @@
package main
import (
"flag"
"go-common/app/service/live/resource/sdk"
"os"
"os/signal"
"syscall"
"time"
"go-common/app/service/live/gift/conf"
"go-common/app/service/live/gift/server/grpc"
"go-common/app/service/live/gift/server/http"
"go-common/app/service/live/gift/service"
ecode "go-common/library/ecode/tip"
"go-common/library/log"
"go-common/library/net/trace"
)
func main() {
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
log.Init(conf.Conf.Log)
defer log.Close()
log.Info("gift-service start")
trace.Init(conf.Conf.Tracer)
defer trace.Close()
ecode.Init(conf.Conf.Ecode)
svc := service.New(conf.Conf)
http.Init(conf.Conf, svc)
grpc.Init(conf.Conf)
titansSdk.Init(conf.Conf.Titan)
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
for {
s := <-c
log.Info("get a signal %s", s.String())
switch s {
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
svc.Close()
log.Info("gift-service exit")
time.Sleep(time.Second)
return
case syscall.SIGHUP:
default:
return
}
}
}

View File

@@ -0,0 +1,81 @@
[mysql]
addr = "172.22.34.101:3312"
dsn = "livetestuat:livetestuat20180711@tcp(172.22.34.101:3312)/live-ugift?timeout=200ms&readTimeout=200ms&writeTimeout=200ms&parseTime=true&loc=Local&charset=utf8,utf8mb4"
#readDSN = ["livetestuat:livetestuat20180711@tcp(172.22.34.101:3312)/live-ugift?timeout=200ms&readTimeout=200ms&writeTimeout=200ms&parseTime=true&loc=Local&charset=utf8,utf8mb4","livetestuat:livetestuat20180711@tcp(172.22.34.101:3312)/live-ugift?timeout=200ms&readTimeout=200ms&writeTimeout=200ms&parseTime=true&loc=Local&charset=utf8,utf8mb4"]
#dsn = "live:oWni@ElNs0P0C(dphdj*F1y4@tcp(172.16.38.117:3312)/live-ugift?timeout=400ms&readTimeout=400ms&writeTimeout=400ms&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 20
idle = 10
idleTimeout ="4h"
queryTimeout = "800ms"
execTimeout = "800ms"
tranTimeout = "800ms"
[redis]
name = "gift-service"
proto = "tcp"
addr = "127.0.0.1:6379"
idle = 10
active = 10
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "10s"
expire = "1m"
[memcache]
name = "gift-service"
proto = "tcp"
addr = ""
active = 50
idle = 10
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "10s"
expire = "24h"
[log]
stdout = true
[gift]
enableFilterGift = true
bubbleId = 30027
[liverpc]
[liverpc.room]
Addr = "172.18.33.128:20200"
[liverpc.live_user]
Addr = "172.18.33.128:20206"
[liverpc.user]
Addr = "172.18.33.128:20802"
[liverpc.fans_medal]
Addr = "172.18.33.110:20800"
[liverpc.activity]
Addr = "172.18.33.128:20201"
[infoc]
[infoc.bagLog]
taskID = "000736"
proto = "tcp"
addr = "172.18.33.124:15140"
chanSize = 10240
[databus]
[databus.AddGift]
key = "ec4c0820d525d67b"
secret = "e20f8f664bf10722efeb6aac0cc16011"
group = "LiveAddGift-LiveLive-P"
topic = "LiveAddGift-T"
action = "pub"
name = "xgift/addFreeGift"
proto = "tcp"
addr = "172.18.33.50:6205"
idle = 1
active = 1
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "10s"
[titan]
treeID = 1114
expire = 10

View File

@@ -0,0 +1,44 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["conf.go"],
importpath = "go-common/app/service/live/gift/conf",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/live/resource/sdk:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/cache/redis:go_default_library",
"//library/conf:go_default_library",
"//library/database/sql:go_default_library",
"//library/ecode/tip:go_default_library",
"//library/log:go_default_library",
"//library/log/infoc:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/http/blademaster/middleware/verify:go_default_library",
"//library/net/rpc/liverpc:go_default_library",
"//library/net/trace:go_default_library",
"//library/queue/databus:go_default_library",
"//vendor/github.com/BurntSushi/toml:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,108 @@
package conf
import (
"errors"
"flag"
"go-common/app/service/live/resource/sdk"
"go-common/library/log/infoc"
"go-common/library/net/rpc/liverpc"
"go-common/library/queue/databus"
"go-common/library/cache/memcache"
"go-common/library/cache/redis"
"go-common/library/conf"
"go-common/library/database/sql"
ecode "go-common/library/ecode/tip"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/middleware/verify"
"go-common/library/net/trace"
"github.com/BurntSushi/toml"
)
var (
confPath string
client *conf.Client
// Conf config
Conf = &Config{}
)
// Config .
type Config struct {
Log *log.Config
BM *bm.ServerConfig
Verify *verify.Config
Tracer *trace.Config
Redis *redis.Config
Memcache *memcache.Config
MySQL *sql.Config
Ecode *ecode.Config
Gift *Gift
LiveRpc map[string]*liverpc.ClientConfig
Infoc map[string]*infoc.Config
Databus *Databus
Titan *titansSdk.Config
}
//Gift Gift配置信息
type Gift struct {
EnableFilterGift bool
BubbleId int64
}
//Databus Databus
type Databus struct {
AddGift *databus.Config
}
func init() {
flag.StringVar(&confPath, "conf", "", "default config path")
}
// Init init conf
func Init() 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
}

View File

@@ -0,0 +1,79 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"dao_test.go",
"discount_gift_test.go",
"discount_plan_test.go",
"gift_online_test.go",
"gift_plan_test.go",
"redis_test.go",
"ugift_day_test.go",
"ugift_week_test.go",
"user_gift_test.go",
],
embed = [":go_default_library"],
tags = ["automanaged"],
deps = [
"//app/service/live/gift/api/grpc/v1:go_default_library",
"//app/service/live/gift/conf:go_default_library",
"//app/service/live/gift/model:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"dao.go",
"discount_gift.go",
"discount_plan.go",
"gift_online.go",
"gift_plan.go",
"redis.go",
"ugift_day.go",
"ugift_week.go",
"user_gift.go",
],
importpath = "go-common/app/service/live/gift/dao",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/live/activity/api/liverpc:go_default_library",
"//app/service/live/fans_medal/api/liverpc:go_default_library",
"//app/service/live/gift/api/grpc/v1:go_default_library",
"//app/service/live/gift/conf:go_default_library",
"//app/service/live/gift/model:go_default_library",
"//app/service/live/live_user/api/liverpc:go_default_library",
"//app/service/live/room/api/liverpc:go_default_library",
"//app/service/live/user/api/liverpc:go_default_library",
"//app/service/live/xuser/api/grpc/v1:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/cache/redis:go_default_library",
"//library/database/sql:go_default_library",
"//library/log:go_default_library",
"//library/net/rpc/liverpc:go_default_library",
"//library/xstr:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,86 @@
package dao
import (
"context"
"go-common/app/service/live/gift/conf"
"go-common/library/cache/memcache"
"go-common/library/cache/redis"
xsql "go-common/library/database/sql"
"go-common/library/net/rpc/liverpc"
activity "go-common/app/service/live/activity/api/liverpc"
fans_medal "go-common/app/service/live/fans_medal/api/liverpc"
live_user "go-common/app/service/live/live_user/api/liverpc"
room "go-common/app/service/live/room/api/liverpc"
user "go-common/app/service/live/user/api/liverpc"
xuser "go-common/app/service/live/xuser/api/grpc/v1"
)
// Dao dao
type Dao struct {
c *conf.Config
mc *memcache.Pool
redis *redis.Pool
db *xsql.DB
}
// New init mysql db
func New(c *conf.Config) (dao *Dao) {
dao = &Dao{
c: c,
mc: memcache.NewPool(c.Memcache),
redis: redis.NewPool(c.Redis),
db: xsql.NewMySQL(c.MySQL),
}
return
}
// Close close the resource.
func (d *Dao) Close() {
d.mc.Close()
d.redis.Close()
d.db.Close()
}
// Ping dao ping
func (d *Dao) Ping(ctx context.Context) error {
// TODO: add mc,redis... if you use
return d.db.Ping(ctx)
}
var (
// RoomApi RoomApi
RoomApi *room.Client
// LiveUserApi LiveUserApi
LiveUserApi *live_user.Client
// UserApi UserApi
UserApi *user.Client
// FansMedalApi FansMedalApi
FansMedalApi *fans_medal.Client
// ActivityApi ActivityApi
ActivityApi *activity.Client
// XuserClient XuserClient
XuserClient *xuser.Client
)
//InitApi InitApi
func InitApi() {
RoomApi = room.New(getConf("room"))
LiveUserApi = live_user.New(getConf("live_user"))
UserApi = user.New(getConf("user"))
FansMedalApi = fans_medal.New(getConf("fans_medal"))
ActivityApi = activity.New(getConf("activity"))
var err error
XuserClient, err = xuser.NewClient(nil)
if err != nil {
panic(err)
}
}
func getConf(appName string) *liverpc.ClientConfig {
c := conf.Conf.LiveRpc
if c != nil {
return c[appName]
}
return nil
}

View File

@@ -0,0 +1,34 @@
package dao
import (
"flag"
"go-common/app/service/live/gift/conf"
"os"
"testing"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "")
flag.Set("conf_token", "")
flag.Set("tree_id", "")
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/test.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
os.Exit(m.Run())
}

View File

@@ -0,0 +1,39 @@
package dao
import (
"context"
"errors"
"fmt"
"go-common/app/service/live/gift/model"
"go-common/library/database/sql"
"go-common/library/log"
"go-common/library/xstr"
)
var _getDiscountGift = "SELECT id,discount_id,gift_id,user_type,discount_price,corner_mark,corner_position FROM discount_gift WHERE discount_id in (%s)"
// GetByDiscountIds GetByDiscountIds
func (d *Dao) GetByDiscountIds(ctx context.Context, ids []int64) (res []*model.DiscountGift, err error) {
log.Info("GetByDiscountIds,ids:%v", ids)
if len(ids) == 0 {
log.Error("query GetByDiscountIds params null")
err = errors.New("params error")
return
}
var rows *sql.Rows
if rows, err = d.db.Query(ctx, fmt.Sprintf(_getDiscountGift, xstr.JoinInts(ids))); err != nil {
log.Error("query GetByDiscountIds error,err %v", err)
return
}
defer rows.Close()
for rows.Next() {
d := &model.DiscountGift{}
if err = rows.Scan(&d.Id, &d.DiscountId, &d.GiftId, &d.UserType, &d.DiscountPrice, &d.CornerMark, &d.CornerPosition); err != nil {
log.Error("GetByDiscountIds scan error,err %v", err)
return
}
res = append(res, d)
}
return
}

View File

@@ -0,0 +1,24 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoGetByDiscountIds(t *testing.T) {
convey.Convey("GetByDiscountIds", t, func(c convey.C) {
var (
ctx = context.Background()
ids = []int64{1}
)
c.Convey("When everything gose positive", func(c convey.C) {
res, err := d.GetByDiscountIds(ctx, ids)
c.Convey("Then err should be nil.res should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(res, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,34 @@
package dao
import (
"context"
"go-common/app/service/live/gift/model"
"go-common/library/database/sql"
"go-common/library/log"
"time"
)
var _getDiscountPlan = "SELECT id,scene_key,scene_value,platform FROM discount_plan WHERE online_time < ? AND offline_time > ? ORDER BY ctime"
// GetDiscountPlan GetDiscountPlan
func (d *Dao) GetDiscountPlan(ctx context.Context, now time.Time) (plans []*model.DiscountPlan, err error) {
log.Info("GetDiscountPlan")
var rows *sql.Rows
var curTime = now.Format("2006-01-02 15:04:05")
curTime = "2018-07-20 00:00:00"
if rows, err = d.db.Query(ctx, _getDiscountPlan, curTime, curTime); err != nil {
log.Error("query GetDiscountPlan error,err %v", err)
return
}
defer rows.Close()
for rows.Next() {
d := &model.DiscountPlan{}
if err = rows.Scan(&d.Id, &d.SceneKey, &d.SceneValue, &d.Platform); err != nil {
log.Error("GetDiscountPlan scan error,err %v", err)
return
}
plans = append(plans, d)
}
return
}

View File

@@ -0,0 +1,25 @@
package dao
import (
"context"
"testing"
"time"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoGetDiscountPlan(t *testing.T) {
convey.Convey("GetDiscountPlan", t, func(c convey.C) {
var (
ctx = context.Background()
now = time.Now()
)
c.Convey("When everything gose positive", func(c convey.C) {
plans, err := d.GetDiscountPlan(ctx, now)
c.Convey("Then err should be nil.plans should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(plans, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,36 @@
package dao
import (
"context"
"go-common/app/service/live/gift/model"
"go-common/library/database/sql"
"go-common/library/log"
)
var (
_getAllGift = "SELECT id,gift_id,name,price,coin_type,type,effect,corner_mark,broadcast,draw,asset_img_basic,asset_img_dynamic,asset_frame_animation,animation_frame_num,asset_gif,asset_webp,asset_full_sc_web,asset_full_sc_horizontal,asset_full_sc_vertical,asset_full_sc_horizontal_svga,asset_full_sc_vertical_svga,asset_bullet_head,asset_bullet_tail,`desc`,rights,rule,limit_interval FROM gift_online"
)
// GetAllGift GetAllGift
func (d *Dao) GetAllGift(ctx context.Context) (gifts []*model.GiftOnline, err error) {
log.Info("GetAllGift")
var rows *sql.Rows
if rows, err = d.db.Query(ctx, _getAllGift); err != nil {
log.Error("query getAllGift error,err %v", err)
return
}
defer rows.Close()
for rows.Next() {
g := &model.GiftOnline{}
if err = rows.Scan(&g.Id, &g.GiftId, &g.Name, &g.Price, &g.CoinType, &g.Type, &g.Effect, &g.CornerMark, &g.Broadcast,
&g.Draw, &g.AssetImgBasic, &g.AssetImgDynamic, &g.AssetFrameAnimation, &g.AnimationFrameNum, &g.AssetGif, &g.AssetWebp,
&g.AssetFullScWeb, &g.AssetFullScHorizontal, &g.AssetFullScVertical, &g.AssetFullScHorizontalSvga, &g.AssetFullScVerticalSvga,
&g.AssetBulletHead, &g.AssetBulletTail, &g.Desc, &g.Rights, &g.Rule, &g.LimitInterval); err != nil {
log.Error("getAllGift scan error,err %v", err)
return
}
gifts = append(gifts, g)
}
return
}

View File

@@ -0,0 +1,23 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoGetAllGift(t *testing.T) {
convey.Convey("GetAllGift", t, func(c convey.C) {
var (
ctx = context.Background()
)
c.Convey("When everything gose positive", func(c convey.C) {
gifts, err := d.GetAllGift(ctx)
c.Convey("Then err should be nil.gifts should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(gifts, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,33 @@
package dao
import (
"context"
"go-common/app/service/live/gift/model"
"go-common/library/database/sql"
"go-common/library/log"
"time"
)
var _getOnlinePlan = "SELECT id,list,silver_list,scene_key,scene_value,mtime,platform FROM gift_plan WHERE online_time <= ? AND offline_time >= ? ORDER BY scene_key DESC,mtime DESC"
// GetOnlinePlan GetOnlinePlan
func (d *Dao) GetOnlinePlan(ctx context.Context) (plans []*model.GiftPlan, err error) {
log.Info("GetOnlinePlan")
var rows *sql.Rows
var curTime = time.Now().Format("2006-01-02 15:04:05")
if rows, err = d.db.Query(ctx, _getOnlinePlan, curTime, curTime); err != nil {
log.Error("query getOnlinePlan error,err %v", err)
return
}
defer rows.Close()
for rows.Next() {
p := &model.GiftPlan{}
if err = rows.Scan(&p.Id, &p.List, &p.SilverList, &p.SceneKey, &p.SceneValue, &p.Mtime, &p.Platform); err != nil {
log.Error("getOnlinePlan scan error,err %v", err)
return
}
plans = append(plans, p)
}
return
}

View File

@@ -0,0 +1,23 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoGetOnlinePlan(t *testing.T) {
convey.Convey("GetOnlinePlan", t, func(c convey.C) {
var (
ctx = context.Background()
)
c.Convey("When everything gose positive", func(c convey.C) {
plans, err := d.GetOnlinePlan(ctx)
c.Convey("Then err should be nil.plans should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(plans, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,392 @@
package dao
import (
"context"
"encoding/json"
"errors"
"fmt"
v1pb "go-common/app/service/live/gift/api/grpc/v1"
"go-common/app/service/live/gift/model"
"go-common/library/cache/redis"
"go-common/library/log"
"math/rand"
"time"
)
func dailyBagKey(uid int64) string {
return fmt.Sprintf("gift:daily_bag:%s:%d", time.Now().Format("20060102"), uid)
}
// GetDailyBagCache GetDailyBagCache
func (d *Dao) GetDailyBagCache(ctx context.Context, uid int64) (res []*v1pb.DailyBagResp_BagList, err error) {
key := dailyBagKey(uid)
conn := d.redis.Get(ctx)
defer conn.Close()
item, err := redis.Bytes(conn.Do("GET", key))
if err != nil {
if err == redis.ErrNil {
err = nil
res = nil
} else {
log.Error("conn.Do(GET, %s) error(%v)", key, err)
}
return
}
if err = json.Unmarshal(item, &res); err != nil {
log.Error("json.Unmarshal(%s) error(%v)", string(item), err)
}
return
}
// SetDailyBagCache SetDailyBagCache
func (d *Dao) SetDailyBagCache(ctx context.Context, uid int64, data []*v1pb.DailyBagResp_BagList, expire int64) (err error) {
key := dailyBagKey(uid)
conn := d.redis.Get(ctx)
defer conn.Close()
bs, err := json.Marshal(data)
if err != nil {
log.Error("json.Marshal(%v) err(%v)", data, err)
return
}
_, err = conn.Do("SETEX", key, expire, bs)
if err != nil {
log.Error("conn.Do(SETEX, %s) error(%v)", key, err)
}
return
}
func dailyMedalBagKey(uid int64) string {
return fmt.Sprintf("gift:medal:daily_gift_bag:%s:%d", time.Now().Format("20060102"), uid)
}
// GetMedalDailyBagCache GetMedalDailyBagCache
func (d *Dao) GetMedalDailyBagCache(ctx context.Context, uid int64) (res *model.BagGiftStatus, err error) {
key := dailyMedalBagKey(uid)
fmt.Println(key)
res = &model.BagGiftStatus{}
conn := d.redis.Get(ctx)
defer conn.Close()
item, err := redis.Bytes(conn.Do("GET", key))
if err != nil {
if err == redis.ErrNil {
err = nil
res = nil
} else {
log.Error("conn.Do(GET, %s) error(%v)", key, err)
}
return
}
if err = json.Unmarshal(item, &res); err != nil {
log.Error("json.Unmarshal(%s) error(%v)", string(item), err)
}
return
}
// SetMedalDailyBagCache SetMedalDailyBagCache
func (d *Dao) SetMedalDailyBagCache(ctx context.Context, uid int64, data *model.BagGiftStatus, expire int64) (err error) {
key := dailyMedalBagKey(uid)
conn := d.redis.Get(ctx)
defer conn.Close()
bs, err := json.Marshal(data)
if err != nil {
log.Error("json.Marshal(%v) err(%v)", data, err)
return
}
_, err = conn.Do("SETEX", key, expire, bs)
if err != nil {
log.Error("conn.Do(SETEX, %s) error(%v)", key, err)
}
return
}
func weekLevelBagKey(uid, level int64) string {
_, week := time.Now().ISOWeek()
return fmt.Sprintf("gift:level:week_gift_bag:%d:%d:%d", week, uid, level)
}
// GetWeekLevelBagCache GetWeekLevelBagCache
func (d *Dao) GetWeekLevelBagCache(ctx context.Context, uid, level int64) (res *model.BagGiftStatus, err error) {
key := weekLevelBagKey(uid, level)
res = &model.BagGiftStatus{}
conn := d.redis.Get(ctx)
defer conn.Close()
item, err := redis.Bytes(conn.Do("GET", key))
if err != nil {
if err == redis.ErrNil {
err = nil
res = nil
} else {
log.Error("conn.Do(GET, %s) error(%v)", key, err)
}
return
}
if err = json.Unmarshal(item, &res); err != nil {
log.Error("json.Unmarshal(%s) error(%v)", string(item), err)
}
return
}
// SetWeekLevelBagCache SetWeekLevelBagCache
func (d *Dao) SetWeekLevelBagCache(ctx context.Context, uid, level int64, data *model.BagGiftStatus, expire int64) (err error) {
key := weekLevelBagKey(uid, level)
conn := d.redis.Get(ctx)
defer conn.Close()
bs, err := json.Marshal(data)
if err != nil {
log.Error("json.Marshal(%v) err(%v)", data, err)
return
}
_, err = conn.Do("SETEX", key, expire, bs)
if err != nil {
log.Error("conn.Do(SETEX, %s) error(%v)", key, err)
}
return
}
//Lock Lock
func (d *Dao) Lock(ctx context.Context, key string, ttl int, retry int, retryDelay int) (gotLock bool, lockValue string, err error) {
if retry <= 0 {
retry = 1
}
lockValue = "locked:" + randomString(5)
retryTimes := 0
conn := d.redis.Get(ctx)
defer conn.Close()
realKey := lockKey(key)
for ; retryTimes < retry; retryTimes++ {
var res interface{}
res, err = conn.Do("SET", realKey, lockValue, "PX", ttl, "NX")
if err != nil {
log.Error("redis_lock failed:%s:%v", realKey, err)
break
}
if res != nil {
gotLock = true
break
}
time.Sleep(time.Duration(retryDelay) * time.Millisecond)
}
return
}
// UnLock UnLock
func (d *Dao) UnLock(ctx context.Context, key string, lockValue string) (err error) {
conn := d.redis.Get(ctx)
defer conn.Close()
realKey := lockKey(key)
res, err := redis.String(conn.Do("GET", realKey))
if err != nil {
if err == redis.ErrNil {
err = nil
} else {
log.Error("conn.Do(GET, %s) error(%v)", key, err)
}
return
}
if res != lockValue {
err = errors.New("unlock value error")
return
}
_, err = conn.Do("DEL", realKey)
return
}
//ForceUnLock UnLock without lockValue
func (d *Dao) ForceUnLock(ctx context.Context, key string) (err error) {
realKey := lockKey(key)
conn := d.redis.Get(ctx)
defer conn.Close()
_, err = conn.Do("DEL", realKey)
return
}
func lockKey(key string) string {
return fmt.Sprintf("gift_lock:%s", key)
}
func randomString(l int) string {
str := "0123456789abcdefghijklmnopqrstuvwxyz"
bytes := []byte(str)
result := []byte{}
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := 0; i < l; i++ {
result = append(result, bytes[r.Intn(len(bytes))])
}
return string(result)
}
func bagIDCache(uid, giftID, expireAt int64) string {
return fmt.Sprintf("bag_id:%d:%d:%d", uid, giftID, expireAt)
}
// GetBagIDCache GetBagIDCache
func (d *Dao) GetBagIDCache(ctx context.Context, uid, giftID, expireAt int64) (bagID int64, err error) {
key := bagIDCache(uid, giftID, expireAt)
conn := d.redis.Get(ctx)
defer conn.Close()
bagID, err = redis.Int64(conn.Do("GET", key))
if err != nil {
if err == redis.ErrNil {
err = nil
} else {
log.Error("conn.Do(GET, %s) error(%v)", key, err)
}
return
}
return
}
// SetBagIDCache SetBagIDCache
func (d *Dao) SetBagIDCache(ctx context.Context, uid, giftID, expireAt, bagID, expire int64) (err error) {
key := bagIDCache(uid, giftID, expireAt)
conn := d.redis.Get(ctx)
defer conn.Close()
_, err = conn.Do("SETEX", key, expire, bagID)
if err != nil {
log.Error("conn.Do(SETEX, %s) error(%v)", key, err)
}
return
}
func bagListKey(uid int64) string {
return fmt.Sprintf("bag_list:%d", uid)
}
// GetBagListCache GetBagListCache
func (d *Dao) GetBagListCache(ctx context.Context, uid int64) (res []*model.BagGiftList, err error) {
key := bagListKey(uid)
conn := d.redis.Get(ctx)
defer conn.Close()
item, err := redis.Bytes(conn.Do("GET", key))
if err != nil {
if err == redis.ErrNil {
err = nil
res = nil
} else {
log.Error("conn.Do(GET, %s) error(%v)", key, err)
}
return
}
if err = json.Unmarshal(item, &res); err != nil {
log.Error("json.Unmarshal(%s) error(%v)", string(item), err)
}
return
}
// SetBagListCache SetBagListCache
func (d *Dao) SetBagListCache(ctx context.Context, uid int64, data []*model.BagGiftList, expire int64) (err error) {
key := bagListKey(uid)
conn := d.redis.Get(ctx)
defer conn.Close()
bs, err := json.Marshal(data)
if err != nil {
log.Error("json.Marshal(%v) err(%v)", data, err)
return
}
_, err = conn.Do("SETEX", key, expire, bs)
if err != nil {
log.Error("conn.Do(SETEX, %s) error(%v)", key, err)
}
return
}
// ClearBagListCache ClearBagListCache
func (d *Dao) ClearBagListCache(ctx context.Context, uid int64) (err error) {
key := bagListKey(uid)
conn := d.redis.Get(ctx)
defer conn.Close()
_, err = conn.Do("DEL", key)
if err != nil {
log.Error("conn.Do(DEL, %s) error(%v)", key, err)
}
return
}
func bagNumKey(uid, giftID, expireAt int64) string {
return fmt.Sprintf("bag_num:%d:%d:%d", uid, giftID, expireAt)
}
// SetBagNumCache SetBagNumCache
func (d *Dao) SetBagNumCache(ctx context.Context, uid, giftID, expireAt, giftNum, expire int64) (err error) {
key := bagNumKey(uid, giftID, expireAt)
conn := d.redis.Get(ctx)
defer conn.Close()
_, err = conn.Do("SETEX", key, expire, giftNum)
if err != nil {
log.Error("conn.Do(SETEX, %s) error(%v)", key, err)
}
return
}
func vipMonthBag(uid int64) string {
return fmt.Sprintf("gift:vip_month:%s:%d", time.Now().Format("200601"), uid)
}
// GetVipStatusCache GetVipStatusCache
func (d *Dao) GetVipStatusCache(ctx context.Context, uid int64) (status int64, err error) {
key := vipMonthBag(uid)
conn := d.redis.Get(ctx)
defer conn.Close()
status, err = redis.Int64(conn.Do("GET", key))
if err != nil {
if err == redis.ErrNil {
err = nil
} else {
log.Error("conn.Do(GET, %s) error(%v)", key, err)
}
return
}
return
}
// ClearVipStatusCache ClearVipStatusCache
func (d *Dao) ClearVipStatusCache(ctx context.Context, uid int64) (err error) {
key := vipMonthBag(uid)
conn := d.redis.Get(ctx)
defer conn.Close()
_, err = conn.Do("DEL", key)
if err != nil {
log.Error("conn.Do(DEL, %s) error(%v)", key, err)
}
return
}
func giftBagStatus(uid int64) string {
return fmt.Sprintf("gift:bag:status:%d", uid)
}
// GetBagStatusCache GetBagStatusCache
func (d *Dao) GetBagStatusCache(ctx context.Context, uid int64) (status int64, err error) {
key := giftBagStatus(uid)
conn := d.redis.Get(ctx)
defer conn.Close()
status, err = redis.Int64(conn.Do("GET", key))
if err != nil {
if err == redis.ErrNil {
err = nil
status = -100 // means cache miss
} else {
log.Error("conn.Do(GET, %s) error(%v)", key, err)
}
return
}
return
}
// SetBagStatusCache SetBagStatusCache
func (d *Dao) SetBagStatusCache(ctx context.Context, uid, status int64, expire int64) (err error) {
key := giftBagStatus(uid)
conn := d.redis.Get(ctx)
defer conn.Close()
_, err = conn.Do("SETEX", key, expire, status)
if err != nil {
log.Error("conn.Do(SETEX, %s) error(%v)", key, err)
}
return
}

View File

@@ -0,0 +1,475 @@
package dao
import (
"context"
v1pb "go-common/app/service/live/gift/api/grpc/v1"
"go-common/app/service/live/gift/model"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaodailyBagKey(t *testing.T) {
convey.Convey("dailyBagKey", t, func(c convey.C) {
var (
uid = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
p1 := dailyBagKey(uid)
c.Convey("Then p1 should not be nil.", func(c convey.C) {
c.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetDailyBagCache(t *testing.T) {
convey.Convey("GetDailyBagCache", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
res, err := d.GetDailyBagCache(ctx, uid)
c.Convey("Then err should be nil.res should be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(res, convey.ShouldBeNil)
})
})
})
}
func TestDaoSetDailyBagCache(t *testing.T) {
convey.Convey("SetDailyBagCache", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(9527)
data = []*v1pb.DailyBagResp_BagList{}
expire = int64(1)
)
c.Convey("When everything gose positive", func(c convey.C) {
err := d.SetDailyBagCache(ctx, uid, data, expire)
c.Convey("Then err should be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaodailyMedalBagKey(t *testing.T) {
convey.Convey("dailyMedalBagKey", t, func(c convey.C) {
var (
uid = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
p1 := dailyMedalBagKey(uid)
c.Convey("Then p1 should not be nil.", func(c convey.C) {
c.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetMedalDailyBagCache(t *testing.T) {
convey.Convey("GetMedalDailyBagCache", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(-1)
)
c.Convey("When everything gose positive", func(c convey.C) {
res, err := d.GetMedalDailyBagCache(ctx, uid)
c.Convey("Then err should be nil.res should be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(res, convey.ShouldBeNil)
})
})
})
}
func TestDaoSetMedalDailyBagCache(t *testing.T) {
convey.Convey("SetMedalDailyBagCache", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(9527)
data = &model.BagGiftStatus{}
expire = int64(1)
)
c.Convey("When everything gose positive", func(c convey.C) {
err := d.SetMedalDailyBagCache(ctx, uid, data, expire)
c.Convey("Then err should be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoweekLevelBagKey(t *testing.T) {
convey.Convey("weekLevelBagKey", t, func(c convey.C) {
var (
uid = int64(0)
level = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
p1 := weekLevelBagKey(uid, level)
c.Convey("Then p1 should not be nil.", func(c convey.C) {
c.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetWeekLevelBagCache(t *testing.T) {
convey.Convey("GetWeekLevelBagCache", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(-1)
level = int64(1)
)
c.Convey("When everything gose positive", func(c convey.C) {
res, err := d.GetWeekLevelBagCache(ctx, uid, level)
c.Convey("Then err should be nil.res should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(res, convey.ShouldBeNil)
})
})
})
}
func TestDaoSetWeekLevelBagCache(t *testing.T) {
convey.Convey("SetWeekLevelBagCache", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(9527)
level = int64(0)
data = &model.BagGiftStatus{}
expire = int64(1)
)
c.Convey("When everything gose positive", func(c convey.C) {
err := d.SetWeekLevelBagCache(ctx, uid, level, data, expire)
c.Convey("Then err should be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoLock(t *testing.T) {
convey.Convey("Lock", t, func(c convey.C) {
var (
ctx = context.Background()
key = "test lock"
ttl = int(1)
retry = int(0)
retryDelay = int(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
gotLock, lockValue, err := d.Lock(ctx, key, ttl, retry, retryDelay)
c.Convey("Then err should be nil.gotLock,lockValue should not be nil.", func(c convey.C) {
c.So(lockValue, convey.ShouldNotBeNil)
c.So(err, convey.ShouldBeNil)
c.So(gotLock, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoUnLock(t *testing.T) {
convey.Convey("UnLock", t, func(c convey.C) {
var (
ctx = context.Background()
key = "test unlock"
lockValue = "1"
)
c.Convey("When everything gose positive", func(c convey.C) {
err := d.UnLock(ctx, key, lockValue)
c.Convey("Then err should be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoForceUnLock(t *testing.T) {
convey.Convey("ForceUnLock", t, func(c convey.C) {
var (
ctx = context.Background()
key = ""
)
c.Convey("When everything gose positive", func(c convey.C) {
err := d.ForceUnLock(ctx, key)
c.Convey("Then err should be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaolockKey(t *testing.T) {
convey.Convey("lockKey", t, func(c convey.C) {
var (
key = ""
)
c.Convey("When everything gose positive", func(c convey.C) {
p1 := lockKey(key)
c.Convey("Then p1 should not be nil.", func(c convey.C) {
c.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaorandomString(t *testing.T) {
convey.Convey("randomString", t, func(c convey.C) {
var (
l = int(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
p1 := randomString(l)
c.Convey("Then p1 should not be nil.", func(c convey.C) {
c.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaobagIDCache(t *testing.T) {
convey.Convey("bagIDCache", t, func(c convey.C) {
var (
uid = int64(0)
giftID = int64(0)
expireAt = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
p1 := bagIDCache(uid, giftID, expireAt)
c.Convey("Then p1 should not be nil.", func(c convey.C) {
c.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetBagIDCache(t *testing.T) {
convey.Convey("GetBagIDCache", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(0)
giftID = int64(0)
expireAt = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
bagID, err := d.GetBagIDCache(ctx, uid, giftID, expireAt)
c.Convey("Then err should be nil.bagID should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(bagID, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoSetBagIDCache(t *testing.T) {
convey.Convey("SetBagIDCache", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(9527)
giftID = int64(1)
expireAt = int64(1)
bagID = int64(1)
expire = int64(1)
)
c.Convey("When everything gose positive", func(c convey.C) {
err := d.SetBagIDCache(ctx, uid, giftID, expireAt, bagID, expire)
c.Convey("Then err should be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaobagListKey(t *testing.T) {
convey.Convey("bagListKey", t, func(c convey.C) {
var (
uid = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
p1 := bagListKey(uid)
c.Convey("Then p1 should not be nil.", func(c convey.C) {
c.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetBagListCache(t *testing.T) {
convey.Convey("GetBagListCache", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
res, err := d.GetBagListCache(ctx, uid)
c.Convey("Then err should be nil.res should be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(res, convey.ShouldBeNil)
})
})
})
}
func TestDaoSetBagListCache(t *testing.T) {
convey.Convey("SetBagListCache", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(0)
data = []*model.BagGiftList{}
expire = int64(1)
)
c.Convey("When everything gose positive", func(c convey.C) {
err := d.SetBagListCache(ctx, uid, data, expire)
c.Convey("Then err should be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoClearBagListCache(t *testing.T) {
convey.Convey("ClearBagListCache", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
err := d.ClearBagListCache(ctx, uid)
c.Convey("Then err should be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaobagNumKey(t *testing.T) {
convey.Convey("bagNumKey", t, func(c convey.C) {
var (
uid = int64(0)
giftID = int64(0)
expireAt = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
p1 := bagNumKey(uid, giftID, expireAt)
c.Convey("Then p1 should not be nil.", func(c convey.C) {
c.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoSetBagNumCache(t *testing.T) {
convey.Convey("SetBagNumCache", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(9527)
giftID = int64(1)
expireAt = int64(1)
giftNum = int64(1)
expire = int64(1)
)
c.Convey("When everything gose positive", func(c convey.C) {
err := d.SetBagNumCache(ctx, uid, giftID, expireAt, giftNum, expire)
c.Convey("Then err should be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaovipMonthBag(t *testing.T) {
convey.Convey("vipMonthBag", t, func(c convey.C) {
var (
uid = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
p1 := vipMonthBag(uid)
c.Convey("Then p1 should not be nil.", func(c convey.C) {
c.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetVipStatusCache(t *testing.T) {
convey.Convey("GetVipStatusCache", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
status, err := d.GetVipStatusCache(ctx, uid)
c.Convey("Then err should be nil.status should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(status, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoClearVipStatusCache(t *testing.T) {
convey.Convey("ClearVipStatusCache", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
err := d.ClearVipStatusCache(ctx, uid)
c.Convey("Then err should be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaogiftBagStatus(t *testing.T) {
convey.Convey("giftBagStatus", t, func(c convey.C) {
var (
uid = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
p1 := giftBagStatus(uid)
c.Convey("Then p1 should not be nil.", func(c convey.C) {
c.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetBagStatusCache(t *testing.T) {
convey.Convey("GetBagStatusCache", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
status, err := d.GetBagStatusCache(ctx, uid)
c.Convey("Then err should be nil.status should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(status, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoSetBagStatusCache(t *testing.T) {
convey.Convey("SetBagStatusCache", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(9527)
status = int64(1)
expire = int64(1)
)
c.Convey("When everything gose positive", func(c convey.C) {
err := d.SetBagStatusCache(ctx, uid, status, expire)
c.Convey("Then err should be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
})
})
})
}

View File

@@ -0,0 +1,46 @@
package dao
import (
"context"
"encoding/json"
"go-common/app/service/live/gift/model"
"go-common/library/database/sql"
"go-common/library/log"
)
var (
_getBagStatus = "SELECT id,uid,day,day_info FROM ugift_day_status WHERE uid = ? AND day = ? LIMIT 1"
_addDayBag = "INSERT INTO ugift_day_status (uid,day,day_info) VALUES (?,?,?)"
)
// GetDayBagStatus GetDayBagStatus
func (d *Dao) GetDayBagStatus(ctx context.Context, uid int64, date string) (res *model.DayGiftInfo, err error) {
log.Info("GetDayBagStatus,%d,%s", uid, date)
row := d.db.QueryRow(ctx, _getBagStatus, uid, date)
res = &model.DayGiftInfo{}
if err = row.Scan(&res.ID, &res.UID, &res.Day, &res.DayInfo); err != nil {
if err == sql.ErrNoRows {
err = nil
return
}
log.Error("GetUserGiftBagStatus row.Scan error(%v)", err)
}
return
}
// AddDayBag AddDayBag
func (d *Dao) AddDayBag(ctx context.Context, uid int64, date string, dayInfo *model.BagGiftStatus) (affected int64, err error) {
log.Info("AddDayBag,%d,%s,%v", uid, date, dayInfo)
di, err := json.Marshal(dayInfo)
if err != nil {
return
}
res, err := d.db.Exec(ctx, _addDayBag, uid, date, di)
if err != nil {
log.Error("AddUserGiftBag error(%v)", err)
return
}
return res.LastInsertId()
}

View File

@@ -0,0 +1,49 @@
package dao
import (
"context"
"go-common/app/service/live/gift/model"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoGetDayBagStatus(t *testing.T) {
convey.Convey("GetDayBagStatus", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(0)
date = ""
)
c.Convey("When everything gose positive", func(c convey.C) {
res, err := d.GetDayBagStatus(ctx, uid, date)
c.Convey("Then err should be nil.res should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoAddDayBag(t *testing.T) {
convey.Convey("AddDayBag", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(9527)
date = "2018-07-04 00:00:00"
dayInfo = &model.BagGiftStatus{
Status: 1,
Gift: []*model.GiftInfo{
{GiftID: 1, GiftNum: 2, ExpireAt: "今天"}, {GiftID: 2, GiftNum: 3, ExpireAt: "今天"},
},
}
)
c.Convey("When everything gose positive", func(c convey.C) {
affected, err := d.AddDayBag(ctx, uid, date, dayInfo)
c.Convey("Then err should be nil.affected should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(affected, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,46 @@
package dao
import (
"context"
"encoding/json"
"go-common/app/service/live/gift/model"
"go-common/library/database/sql"
"go-common/library/log"
)
var (
_getWeekBagStatus = "SELECT id,uid,week,level,week_info FROM ugift_week_status WHERE uid = ? AND week = ? AND level =? ORDER BY ctime DESC LIMIT 1"
_addWeekBag = "INSERT INTO ugift_week_status (uid,week,level,week_info) VALUES (?,?,?,?)"
)
// GetWeekBagStatus GetWeekBagStatus
func (d *Dao) GetWeekBagStatus(ctx context.Context, uid int64, week int, level int64) (res *model.WeekGiftInfo, err error) {
log.Info("GetWeekBagStatus,uid:%d,week:%d,level:%d", uid, week, level)
row := d.db.QueryRow(ctx, _getWeekBagStatus, uid, week, level)
res = &model.WeekGiftInfo{}
if err = row.Scan(&res.ID, &res.UID, &res.Week, &res.Level, &res.WeekInfo); err != nil {
if err == sql.ErrNoRows {
err = nil
return
}
log.Error("GetWeekBagStatus row.Scan error(%v)", err)
}
return
}
// AddWeekBag AddWeekBag
func (d *Dao) AddWeekBag(ctx context.Context, uid int64, week int, level int64, weekInfo *model.BagGiftStatus) (affected int64, err error) {
log.Info("AddWeekBag,uid:%d,week:%d,level:%d,weekInfo:%v", uid, week, level, weekInfo)
wi, err := json.Marshal(weekInfo)
if err != nil {
return
}
res, err := d.db.Exec(ctx, _addWeekBag, uid, week, level, wi)
if err != nil {
log.Error("AddUserGiftBag error(%v)", err)
return
}
return res.LastInsertId()
}

View File

@@ -0,0 +1,51 @@
package dao
import (
"context"
"go-common/app/service/live/gift/model"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoGetWeekBagStatus(t *testing.T) {
convey.Convey("GetWeekBagStatus", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(0)
week = int(0)
level = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
res, err := d.GetWeekBagStatus(ctx, uid, week, level)
c.Convey("Then err should be nil.res should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoAddWeekBag(t *testing.T) {
convey.Convey("AddWeekBag", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(9527)
week = int(1)
level = int64(1)
weekInfo = &model.BagGiftStatus{
Status: 1,
Gift: []*model.GiftInfo{
{GiftID: 1, GiftNum: 2, ExpireAt: "7天"}, {GiftID: 2, GiftNum: 3, ExpireAt: "7天"},
},
}
)
c.Convey("When everything gose positive", func(c convey.C) {
affected, err := d.AddWeekBag(ctx, uid, week, level, weekInfo)
c.Convey("Then err should be nil.affected should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(affected, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,102 @@
package dao
import (
"context"
"crypto/md5"
"encoding/hex"
"fmt"
"go-common/app/service/live/gift/model"
"go-common/library/database/sql"
"go-common/library/log"
"strconv"
"time"
)
var (
_getBag = "SELECT id,gift_num FROM user_gift_%s WHERE uid = ? AND gift_id = ? AND expireat = ? LIMIT 1"
_getBagByID = "SELECT id,gift_num FROM user_gift_%s WHERE id = ?"
_updateBagNum = "UPDATE user_gift_%s SET gift_num = gift_num + ? WHERE id = ?"
_insertBag = "INSERT INTO user_gift_%s (uid,gift_id,gift_num,expireat) VALUES (?,?,?,?)"
_getBagList = "SELECT id,uid,gift_id,gift_num,expireat FROM user_gift_%s WHERE uid = ? AND gift_num > 0 AND (expireat = 0 OR expireat > ?)"
)
// GetBag GetBag
func (d *Dao) GetBag(ctx context.Context, uid, giftID, expireAt int64) (res *model.BagInfo, err error) {
log.Info("GetBag,uid:%d,giftID:%d,expireAt:%d", uid, giftID, expireAt)
row := d.db.QueryRow(ctx, fmt.Sprintf(_getBag, getPostFix(uid)), uid, giftID, expireAt)
res = &model.BagInfo{}
if err = row.Scan(&res.ID, &res.GiftNum); err != nil {
if err == sql.ErrNoRows {
err = nil
return
}
log.Error("GetBag row.Scan error(%v)", err)
}
return
}
// UpdateBagNum UpdateBagNum
func (d *Dao) UpdateBagNum(ctx context.Context, uid, id, num int64) (affected int64, err error) {
log.Info("UpdateBagNum,uid:%d,id:%d,num:%d", uid, id, num)
res, err := d.db.Exec(ctx, fmt.Sprintf(_updateBagNum, getPostFix(uid)), num, id)
if err != nil {
log.Error("UpdateBagNum error(%v)", err)
return
}
return res.RowsAffected()
}
// AddBag AddBag
func (d *Dao) AddBag(ctx context.Context, uid, giftID, giftNum, expireAt int64) (affected int64, err error) {
log.Info("AddBag,uid:%d,giftID:%d,giftNum:%d,expireAt:%d", uid, giftID, giftNum, expireAt)
res, err := d.db.Exec(ctx, fmt.Sprintf(_insertBag, getPostFix(uid)), uid, giftID, giftNum, expireAt)
if err != nil {
log.Error("AddBag error(%v)", err)
return
}
return res.LastInsertId()
}
// GetBagByID GetBagByID
func (d *Dao) GetBagByID(ctx context.Context, uid, id int64) (res *model.BagInfo, err error) {
log.Info("GetBagByID,uid:%d,id:%d", uid, id)
row := d.db.QueryRow(ctx, fmt.Sprintf(_getBagByID, getPostFix(uid)), id)
res = &model.BagInfo{}
if err = row.Scan(&res.ID, &res.GiftNum); err != nil {
if err == sql.ErrNoRows {
err = nil
return
}
log.Error("GetBagByID row.Scan error(%v)", err)
}
return
}
func getPostFix(uid int64) string {
uidStr := strconv.Itoa(int(uid))
h := md5.New()
h.Write([]byte(uidStr))
md5Str := hex.EncodeToString(h.Sum(nil))
return md5Str[0:1]
}
// GetBagList GetBagList
func (d *Dao) GetBagList(ctx context.Context, uid int64) (list []*model.BagGiftList, err error) {
log.Info("GetBagList,uid:%d", uid)
curTime := time.Now().Unix()
rows, err := d.db.Query(ctx, fmt.Sprintf(_getBagList, getPostFix(uid)), uid, curTime)
if err != nil {
log.Error("GetBagGiftList error,err %v", err)
return
}
defer rows.Close()
for rows.Next() {
b := &model.BagGiftList{}
if err = rows.Scan(&b.ID, &b.UID, &b.GiftID, &b.GiftNum, &b.ExpireAt); err != nil {
log.Error("GetBagGiftList scan error,err %v", err)
return
}
list = append(list, b)
}
return
}

View File

@@ -0,0 +1,111 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoGetBag(t *testing.T) {
convey.Convey("GetBag", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(0)
giftID = int64(0)
expireAt = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
res, err := d.GetBag(ctx, uid, giftID, expireAt)
c.Convey("Then err should be nil.res should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoUpdateBagNum(t *testing.T) {
convey.Convey("UpdateBagNum", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(0)
id = int64(0)
num = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
affected, err := d.UpdateBagNum(ctx, uid, id, num)
c.Convey("Then err should be nil.affected should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(affected, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoAddBag(t *testing.T) {
convey.Convey("AddBag", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(0)
giftID = int64(0)
giftNum = int64(0)
expireAt = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
affected, err := d.AddBag(ctx, uid, giftID, giftNum, expireAt)
c.Convey("Then err should be nil.affected should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(affected, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetBagByID(t *testing.T) {
convey.Convey("GetBagByID", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(0)
id = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
res, err := d.GetBagByID(ctx, uid, id)
c.Convey("Then err should be nil.res should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestDaogetPostFix(t *testing.T) {
convey.Convey("getPostFix", t, func(c convey.C) {
var (
uid = int64(1)
)
c.Convey("When everything gose positive", func(c convey.C) {
p1 := getPostFix(uid)
c.Convey("Then p1 should not be nil.", func(c convey.C) {
c.So(p1, convey.ShouldNotBeNil)
c.So(p1, convey.ShouldEqual, "c")
})
})
})
}
func TestDaoGetBagList(t *testing.T) {
convey.Convey("GetBagList", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
list, err := d.GetBagList(ctx, uid)
c.Convey("Then err should be nil.list should be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(list, convey.ShouldBeNil)
})
})
})
}

View File

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

View File

@@ -0,0 +1,11 @@
package model
//AddFreeGift AddFreeGift
type AddFreeGift struct {
UID int64 `json:"uid"`
GiftID int64 `json:"gift_id"`
GiftNum int64 `json:"gift_num"`
ExpireAt int64 `json:"expire_at"`
Source string `json:"source"`
MsgID string `json:"msg_id"`
}

View File

@@ -0,0 +1,117 @@
package model
// DiscountInfo DiscountInfo
type DiscountInfo struct {
Id int64 `json:"id"`
SceneKey int64 `json:"scene_key"`
SceneValue []int64 `json:"scene_value"`
Platform int64 `json:"platform"`
List map[int64]map[string]interface{} `json:"list"`
}
// BagGiftStatus BagGiftStatus
type BagGiftStatus struct {
Status int64 `json:"status"`
Gift []*GiftInfo `json:"gift"`
}
// GiftInfo GiftInfo
type GiftInfo struct {
GiftID int64 `json:"gift_id"`
GiftNum int64 `json:"gift_num"`
ExpireAt string `json:"expireat"`
}
//DayGiftInfo DayGiftInfo
type DayGiftInfo struct {
ID int64 `json:"id"`
UID int64 `json:"uid"`
Day string `json:"day"`
DayInfo string `json:"day_info"`
}
//BagInfo BagInfo
type BagInfo struct {
ID int64 `json:"id"`
GiftNum int64 `json:"gift_num"`
}
//WeekGiftInfo WeekGiftInfo
type WeekGiftInfo struct {
ID int64 `json:"id"`
UID int64 `json:"uid"`
Week int `json:"week"`
Level int64 `json:"level"`
WeekInfo string `json:"week_info"`
}
//BagGiftList BagGiftList
type BagGiftList struct {
ID int64 `json:"id"`
UID int64 `json:"uid"`
GiftID int64 `json:"gift_id"`
GiftNum int64 `json:"gift_num"`
ExpireAt int64 `json:"expireat"`
}
// GiftOnline .
type GiftOnline struct {
Id int64 `json:"id"`
GiftId int64 `json:"gift_id"`
Name string `json:"name"`
Price int64 `json:"price"`
CoinType int64 `json:"coin_type"`
Type int64 `json:"type"`
Effect int64 `json:"effect"`
CornerMark string `json:"corner_mark"`
Broadcast int64 `json:"broadcast"`
Draw int64 `json:"draw"`
AssetImgBasic string `json:"asset_img_basic"`
AssetImgDynamic string `json:"asset_img_dynamic"`
AssetFrameAnimation string `json:"asset_frame_animation"`
AnimationFrameNum int64 `json:"animation_frame_num"`
AssetGif string `json:"asset_gif"`
AssetWebp string `json:"asset_webp"`
AssetFullScWeb string `json:"asset_full_sc_web"`
AssetFullScHorizontal string `json:"asset_full_sc_horizontal"`
AssetFullScVertical string `json:"asset_full_sc_vertical"`
AssetFullScHorizontalSvga string `json:"asset_full_sc_horizontal_svga"`
AssetFullScVerticalSvga string `json:"asset_full_sc_vertical_svga"`
AssetBulletHead string `json:"asset_bullet_head"`
AssetBulletTail string `json:"asset_bullet_tail"`
Desc string `json:"desc"`
Rights string `json:"rights"`
Rule string `json:"rule"`
PrivilegeRequired int64 `json:"privilege_required"`
LimitInterval int64 `json:"limit_interval"`
}
//GiftPlan .
type GiftPlan struct {
Id int64 `json:"id"`
List string `json:"list"`
SilverList string `json:"silver_list"`
SceneKey int64 `json:"scene_key"`
SceneValue int64 `json:"scene_value"`
Mtime string `json:"mtime"`
Platform int64 `json:"platform"`
}
//DiscountPlan .
type DiscountPlan struct {
Id int64 `json:"id"`
SceneKey int64 `json:"scene_key"`
SceneValue string `json:"scene_value"`
Platform int64 `json:"platform"`
}
//DiscountGift .
type DiscountGift struct {
Id int64 `json:"id"`
DiscountId int64 `json:"discount_id"`
GiftId int64 `json:"gift_id"`
UserType int64 `json:"user_type"`
DiscountPrice int64 `json:"discount_price"`
CornerMark string `json:"corner_mark"`
CornerPosition int64 `json:"corner_position"`
}

View File

@@ -0,0 +1,36 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["server.go"],
importpath = "go-common/app/service/live/gift/server/grpc",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/live/gift/api/grpc/v1:go_default_library",
"//app/service/live/gift/conf:go_default_library",
"//app/service/live/gift/dao:go_default_library",
"//app/service/live/gift/service/v1:go_default_library",
"//library/log:go_default_library",
"//library/net/rpc/warden:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,26 @@
package grpc
import (
"fmt"
pb "go-common/app/service/live/gift/api/grpc/v1"
"go-common/app/service/live/gift/conf"
"go-common/app/service/live/gift/dao"
svc "go-common/app/service/live/gift/service/v1"
"go-common/library/log"
"go-common/library/net/rpc/warden"
)
//Init Init
func Init(c *conf.Config) {
s := warden.NewServer(nil) // 酌情传入config
dao.InitApi()
gs := svc.NewGiftService(c)
pb.RegisterGiftServer(s.Server(), gs)
_, err := s.Start()
if err != nil {
log.Error("grpc Start error(%v)", err)
panic(err)
}
fmt.Println("start")
gs.TickerReloadGift()
}

View File

@@ -0,0 +1,35 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["http.go"],
importpath = "go-common/app/service/live/gift/server/http",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/live/gift/conf:go_default_library",
"//app/service/live/gift/service:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/http/blademaster/middleware/verify:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,53 @@
package http
import (
"net/http"
"go-common/app/service/live/gift/conf"
"go-common/app/service/live/gift/service"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/middleware/verify"
)
var (
vfy *verify.Verify
svc *service.Service
)
// Init init
func Init(c *conf.Config, s *service.Service) {
svc = s
vfy = verify.New(c.Verify)
engine := bm.DefaultServer(c.BM)
route(engine)
if err := engine.Start(); err != nil {
log.Error("bm Start error(%v)", err)
panic(err)
}
}
func route(e *bm.Engine) {
e.Ping(ping)
e.Register(register)
g := e.Group("/x/gift")
{
g.GET("/start", vfy.Verify, howToStart)
}
}
func ping(ctx *bm.Context) {
if err := svc.Ping(ctx); err != nil {
log.Error("ping error(%v)", err)
ctx.AbortWithStatus(http.StatusServiceUnavailable)
}
}
func register(c *bm.Context) {
c.JSON(map[string]interface{}{}, nil)
}
// example for http request handler
func howToStart(c *bm.Context) {
c.String(0, "Golang 大法好 !!!")
}

View File

@@ -0,0 +1,35 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["service.go"],
importpath = "go-common/app/service/live/gift/service",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/live/gift/conf:go_default_library",
"//app/service/live/gift/dao:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/service/live/gift/service/v1:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,33 @@
package service
import (
"context"
"go-common/app/service/live/gift/conf"
"go-common/app/service/live/gift/dao"
)
// Service struct
type Service struct {
c *conf.Config
dao *dao.Dao
}
// New init
func New(c *conf.Config) (s *Service) {
s = &Service{
c: c,
dao: dao.New(c),
}
return s
}
// Ping Service
func (s *Service) Ping(ctx context.Context) (err error) {
return s.dao.Ping(ctx)
}
// Close Service
func (s *Service) Close() {
s.dao.Close()
}

View File

@@ -0,0 +1,81 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"bag_test.go",
"databus_test.go",
"discount_test.go",
"gift_test.go",
"infoc_test.go",
"list_test.go",
"package_test.go",
],
embed = [":go_default_library"],
tags = ["automanaged"],
deps = [
"//app/service/live/gift/api/grpc/v1:go_default_library",
"//app/service/live/gift/conf:go_default_library",
"//app/service/live/gift/dao:go_default_library",
"//app/service/live/gift/model:go_default_library",
"//app/service/live/resource/sdk:go_default_library",
"//vendor/github.com/satori/go.uuid:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"bag.go",
"databus.go",
"discount.go",
"gift.go",
"infoc.go",
"list.go",
"package.go",
],
importpath = "go-common/app/service/live/gift/service/v1",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/live/activity/api/liverpc/v1:go_default_library",
"//app/service/live/fans_medal/api/liverpc/v2:go_default_library",
"//app/service/live/gift/api/grpc/v1:go_default_library",
"//app/service/live/gift/conf:go_default_library",
"//app/service/live/gift/dao:go_default_library",
"//app/service/live/gift/model:go_default_library",
"//app/service/live/live_user/api/liverpc/v1:go_default_library",
"//app/service/live/resource/sdk:go_default_library",
"//app/service/live/room/api/liverpc/v1:go_default_library",
"//app/service/live/user/api/liverpc/v3:go_default_library",
"//app/service/live/xuser/api/grpc/v1:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/log/infoc:go_default_library",
"//library/net/rpc/liverpc/context:go_default_library",
"//library/queue/databus:go_default_library",
"//library/sync/errgroup:go_default_library",
"//vendor/github.com/satori/go.uuid:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,440 @@
package v1
import (
"context"
"encoding/json"
"errors"
"fmt"
v1activity "go-common/app/service/live/activity/api/liverpc/v1"
v2fansMedal "go-common/app/service/live/fans_medal/api/liverpc/v2"
v1pb "go-common/app/service/live/gift/api/grpc/v1"
"go-common/app/service/live/gift/dao"
"go-common/app/service/live/gift/model"
v3user "go-common/app/service/live/user/api/liverpc/v3"
xuser "go-common/app/service/live/xuser/api/grpc/v1"
"go-common/library/log"
liveCtx "go-common/library/net/rpc/liverpc/context"
"math"
"strconv"
"sync"
"time"
"github.com/satori/go.uuid"
)
var medalGiftConfig = map[int64]map[int64]int64{
1: {1: 1}, 2: {1: 2}, 3: {1: 3}, 4: {1: 4}, 5: {1: 5}, 6: {1: 6}, 7: {1: 7},
8: {1: 8}, 9: {1: 9}, 10: {1: 10}, 11: {1: 15}, 12: {1: 20}, 13: {1: 30}, 14: {1: 40},
15: {1: 50}, 16: {1: 60}, 17: {1: 70}, 18: {1: 80}, 19: {1: 90}, 20: {1: 100},
}
var levelGiftConfig = map[int64]map[int64]int64{
10: {1: 10}, 15: {1: 20}, 20: {1: 30}, 25: {1: 50}, 30: {1: 75}, 35: {1: 100}, 40: {1: 150}, 45: {1: 200}, 50: {1: 300},
}
// 包裹发送状态
const (
needSend int64 = 1
hasSent int64 = 2
)
const (
medalDailyBag int64 = 1
levelWeekBag int64 = 2
vipMonthBag int64 = 3
)
//GetUserInfo GetUserInfo
func (s *GiftService) GetUserInfo(c context.Context, uid int64) (res map[int64]*v3user.UserGetMultipleResp_UserInfo, err error) {
res = make(map[int64]*v3user.UserGetMultipleResp_UserInfo)
if uid == 0 {
err = errors.New("nil uid")
return
}
reply, err := dao.UserApi.V3User.GetMultiple(c, &v3user.UserGetMultipleReq{
Uids: []int64{uid},
Attributes: []string{"exp"},
})
if err != nil {
log.Error("getUserInfo,uid:%d, err:%v", uid, err)
return
}
if reply.Code != 0 {
log.Error("user_getUserInfo_error:%d,%d,%s,%v,uid", uid, reply.Code, reply.Msg, reply.Data)
return
}
res = reply.Data
return
}
func getBagLockKey(uid int64) string {
return fmt.Sprintf("gift:daily_bag.%d", uid)
}
// GetMedalGift 获取勋章礼包
func (s *GiftService) GetMedalGift(ctx context.Context, uid int64) (bag *v1pb.DailyBagResp_BagList, err error) {
medal, giftConfig, err := s.GetMedalGiftConfig(ctx, uid)
if err != nil || giftConfig == nil {
return
}
bgs := s.GetDailyGiftBag(ctx, uid, giftConfig)
if bgs.Status == needSend {
bag = &v1pb.DailyBagResp_BagList{
Type: medalDailyBag,
BagName: "粉丝勋章礼包",
Source: &v1pb.DailyBagResp_BagList_Source{
MedalId: medal.MedalId,
MedalName: medal.MedalName,
Level: medal.Level,
},
}
expireAt := getDeltaDayTime(1)
for _, v := range bgs.Gift {
bag.GiftList = append(bag.GiftList, &v1pb.DailyBagResp_BagList_GiftList{
GiftId: strconv.FormatInt(v.GiftID, 10),
GiftNum: v.GiftNum,
ExpireAt: expireAt,
})
}
}
return
}
// GetMedalGiftConfig 获取勋章礼物配置
func (s *GiftService) GetMedalGiftConfig(ctx context.Context, uid int64) (medal *v2fansMedal.HighQpsLiveReceivedResp_Data, giftConfig map[int64]int64, err error) {
medal = &v2fansMedal.HighQpsLiveReceivedResp_Data{}
timeout := time.Duration(200) * time.Millisecond
ctx = liveCtx.WithTimeout(ctx, timeout)
resp, err := dao.FansMedalApi.V2HighQps.LiveReceived(ctx, &v2fansMedal.HighQpsLiveReceivedReq{Uid: uid})
if err != nil {
log.Error("get medal list error:%v", err)
return
}
medalList := resp.Data
if len(medalList) == 0 {
return
}
var medalLevel int64
for _, v := range medalList {
if v.Level >= medalLevel {
medalLevel = v.Level
medal = v
}
}
log.Info("daily_bag_info,uid:%d,medalLevel:%d", uid, medalLevel)
var ok bool
giftConfig, ok = medalGiftConfig[medalLevel]
if !ok {
return medal, nil, nil
}
return
}
// GetDailyGiftBag 获取勋章礼包
func (s *GiftService) GetDailyGiftBag(ctx context.Context, uid int64, giftConfig map[int64]int64) (data *model.BagGiftStatus) {
data, err := s.dao.GetMedalDailyBagCache(ctx, uid)
if err != nil {
return
}
if data != nil {
return
}
wg := sync.WaitGroup{}
date := time.Now().Format("2006-01-02 00:00:00")
res, err := s.dao.GetDayBagStatus(ctx, uid, date)
if err != nil {
return
}
curTime := time.Now().Unix()
expireAt := getDeltaDayTime(1)
if res.ID != 0 {
dayInfo := res.DayInfo
data = &model.BagGiftStatus{}
err = json.Unmarshal([]byte(dayInfo), data)
if err != nil {
log.Error("unmarshal err :%v", err)
return
}
data.Status = hasSent
} else {
//发送礼物
giftCfg := s.FormatGift(giftConfig, expireAt)
data = &model.BagGiftStatus{
Status: needSend, Gift: giftCfg,
}
s.dao.AddDayBag(ctx, uid, date, data)
for _, v := range giftCfg {
wg.Add(1)
go func(v *model.GiftInfo) {
defer wg.Done()
s.SendAddGiftMsg(ctx, uid, v.GiftID, v.GiftNum, expireAt, "daily_bag_"+date, uuid.NewV4().String())
}(v)
}
}
wg.Add(1)
go func() {
defer wg.Done()
s.dao.SetMedalDailyBagCache(ctx, uid, data, expireAt-curTime)
}()
wg.Wait()
return
}
func getDeltaDayTime(day int) int64 {
timeStr := time.Now().Format("2006-01-02")
t, _ := time.ParseInLocation("2006-01-02", timeStr, time.Local)
return t.AddDate(0, 0, day).Unix()
}
func getThisWeekTime() int64 {
weekDay := int64(time.Now().Weekday())
if weekDay == 0 {
weekDay = 7
}
return getDeltaDayTime(1) - weekDay*86400
}
func getNextWeekTime() int64 {
return getThisWeekTime() + 7*86400
}
// FormatGift FormatGift
func (s *GiftService) FormatGift(giftConfig map[int64]int64, expireAt int64) (gift []*model.GiftInfo) {
gift = make([]*model.GiftInfo, 0)
for k, v := range giftConfig {
g := &model.GiftInfo{}
g.GiftID = k
g.GiftNum = v
var liveTime = float64(expireAt - time.Now().Unix())
var day float64 = 86400
if liveTime < day {
g.ExpireAt = "今天"
} else {
g.ExpireAt = fmt.Sprintf("%.0f天", math.Ceil(liveTime/day))
}
gift = append(gift, g)
}
return
}
// GetUserLevelInfo grpc获取用户经验信息
func (s *GiftService) GetUserLevelInfo(ctx context.Context, uid int64) (levelInfo *xuser.UserLevelInfo) {
levelInfo = &xuser.UserLevelInfo{}
uids := []int64{uid}
resp, err := dao.XuserClient.UserExpClient.GetUserExp(ctx, &xuser.GetUserExpReq{Uids: uids})
if err != nil {
log.Error("call xuser get exp err,%v", err)
return
}
return resp.Data[uid].UserLevel
}
// GetLevelGift 获取用户等级礼包
func (s *GiftService) GetLevelGift(ctx context.Context, uid int64) (bag *v1pb.DailyBagResp_BagList) {
bag = &v1pb.DailyBagResp_BagList{}
userInfo := s.GetUserLevelInfo(ctx, uid)
level := userInfo.Level
log.Info("daily_bag_info,uid:%d,userLevel:%d", uid, level)
cfg := s.GetLevelGiftConfig(level)
if len(cfg) == 0 {
return
}
bgs := s.GetWeekLevelGiftBag(ctx, uid, level, cfg)
if bgs.Status == needSend {
bag = &v1pb.DailyBagResp_BagList{
Type: levelWeekBag,
BagName: "用户等级礼包",
Source: &v1pb.DailyBagResp_BagList_Source{
UserLevel: level,
},
}
expireAt := getNextWeekTime() + time.Now().Unix() - getDeltaDayTime(0)
for _, v := range bgs.Gift {
bag.GiftList = append(bag.GiftList, &v1pb.DailyBagResp_BagList_GiftList{
GiftId: strconv.FormatInt(v.GiftID, 10),
GiftNum: v.GiftNum,
ExpireAt: expireAt,
})
}
}
return
}
// GetLevelGiftConfig 获取周等级礼包礼物配置
func (s *GiftService) GetLevelGiftConfig(level int64) (r map[int64]int64) {
var flag int64 = 100
for l, v := range levelGiftConfig {
gap := level - l
if gap < 0 {
continue
}
if gap < flag {
flag = gap
r = v
}
}
return
}
// GetWeekLevelGiftBag 获取周等级礼包
func (s *GiftService) GetWeekLevelGiftBag(ctx context.Context, uid, level int64, giftConfig map[int64]int64) (data *model.BagGiftStatus) {
data, err := s.dao.GetWeekLevelBagCache(ctx, uid, level)
if err != nil {
return
}
if data != nil {
return
}
wg := sync.WaitGroup{}
_, week := time.Now().ISOWeek()
res, err := s.dao.GetWeekBagStatus(ctx, uid, week, level)
if err != nil {
return
}
curTime := time.Now().Unix()
expireAt := getNextWeekTime()
if res.ID != 0 {
weekInfo := res.WeekInfo
data = &model.BagGiftStatus{}
err = json.Unmarshal([]byte(weekInfo), data)
if err != nil {
log.Error("unmarshal err :%v", err)
return
}
data.Status = hasSent
} else {
//发送礼物
giftCfg := s.FormatGift(giftConfig, expireAt)
data = &model.BagGiftStatus{
Status: needSend, Gift: giftCfg,
}
s.dao.AddWeekBag(ctx, uid, week, level, data)
source := "week_bag_" + strconv.Itoa(week)
for _, v := range giftCfg {
wg.Add(1)
go func(v *model.GiftInfo) {
defer wg.Done()
s.SendAddGiftMsg(ctx, uid, v.GiftID, v.GiftNum, expireAt, source, uuid.NewV4().String())
}(v)
}
}
wg.Add(1)
go func() {
defer wg.Done()
s.dao.SetWeekLevelBagCache(ctx, uid, level, data, expireAt-curTime)
}()
wg.Wait()
return
}
// GetVipMonthGift 获取月费老爷礼包
func (s *GiftService) GetVipMonthGift(ctx context.Context, uid int64) (bag *v1pb.DailyBagResp_BagList) {
bag = &v1pb.DailyBagResp_BagList{}
status, err := s.dao.GetVipStatusCache(ctx, uid)
log.Info("daily_bag_info,uid:%d,vip_status:%d", uid, status)
if err != nil {
return
}
if status == 1 {
bag = &v1pb.DailyBagResp_BagList{
Type: vipMonthBag,
BagName: "年费老爷每月礼包",
GiftList: []*v1pb.DailyBagResp_BagList_GiftList{
{GiftId: "1", GiftNum: 99}, {GiftId: "3", GiftNum: 1}, {GiftId: "egg", GiftNum: 5},
},
}
s.dao.ClearVipStatusCache(ctx, uid)
}
return
}
// GetUnionFansGift 获取友爱社礼包
func (s *GiftService) GetUnionFansGift(ctx context.Context, uid int64) (bag []*v1pb.DailyBagResp_BagList) {
bag = make([]*v1pb.DailyBagResp_BagList, 0)
unionResp := s.GetUnionConfig(ctx, uid)
if len(unionResp) != 0 {
for _, v := range unionResp {
tmp := &v1pb.DailyBagResp_BagList{
Type: v.Type,
BagName: v.GiftTypeName,
}
for _, u := range v.GiftList {
tmp.GiftList = append(tmp.GiftList, &v1pb.DailyBagResp_BagList_GiftList{
GiftId: u.GiftId,
GiftNum: u.GiftNum,
})
}
bag = append(bag, tmp)
}
}
return
}
// GetUnionConfig 获取友爱社礼物配置
func (s *GiftService) GetUnionConfig(ctx context.Context, uid int64) (res []*v1activity.UnionFansGetSendGiftResp_Data) {
res = make([]*v1activity.UnionFansGetSendGiftResp_Data, 0)
timeout := time.Duration(200) * time.Millisecond
ctx = liveCtx.WithTimeout(ctx, timeout)
reply, err := dao.ActivityApi.V1UnionFans.GetSendGift(ctx, &v1activity.UnionFansGetSendGiftReq{
Uid: uid,
})
if err != nil {
log.Error("GetSendGift err:%v", err)
return
}
if reply.Code != 0 {
log.Error("GetSendGifterror:%d,%s,%v", reply.Code, reply.Msg, reply.Data)
return
}
res = reply.Data
log.Info("daily_bag_info,uid:%d,unionConfig:%v", uid, res)
return
}
// GetBagExpireStatus 包裹过期状态0没有7日内过期的1有7日内过期的-1包裹为空,-100表示cache miss
func (s *GiftService) GetBagExpireStatus(ctx context.Context, uid int64) (status int64) {
status, err := s.dao.GetBagStatusCache(ctx, uid)
if err != nil {
return
}
if status != -100 {
return
}
status = -1
bagList := s.GetBagList(ctx, uid)
now := time.Now().Unix()
for _, v := range bagList {
giftInfo := s.GetGiftInfoByID(ctx, v.GiftID)
if giftInfo.Id == 0 {
continue
}
if (v.ExpireAt > 0 && v.ExpireAt < now) || v.GiftNum < 1 {
continue
}
if v.ExpireAt > 0 && (v.ExpireAt <= now+7*86400) {
status = 1
break
}
}
s.dao.SetBagStatusCache(ctx, uid, status, 30)
return
}
// GetBagList GetBagList from cache and DB
func (s *GiftService) GetBagList(ctx context.Context, uid int64) (bagList []*model.BagGiftList) {
bagList, err := s.dao.GetBagListCache(ctx, uid)
if err != nil {
return
}
if bagList != nil {
return
}
// cache nil then get from db
bagList, err = s.dao.GetBagList(ctx, uid)
if err != nil {
return
}
s.dao.SetBagListCache(ctx, uid, bagList, 3600)
return
}

View File

@@ -0,0 +1,278 @@
package v1
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestV1GetUserInfo(t *testing.T) {
convey.Convey("GetUserInfo", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(88895029)
)
c.Convey("When everything gose positive", func(c convey.C) {
res, err := s.GetUserInfo(ctx, uid)
c.Convey("Then err should be nil.res should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestV1getBagLockKey(t *testing.T) {
convey.Convey("getBagLockKey", t, func(c convey.C) {
var (
uid = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
p1 := getBagLockKey(uid)
c.Convey("Then p1 should not be nil.", func(c convey.C) {
c.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestV1GetMedalGift(t *testing.T) {
convey.Convey("GetMedalGift", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(88895029)
)
c.Convey("When everything gose positive", func(c convey.C) {
bag, err := s.GetMedalGift(ctx, uid)
c.Convey("Then err should be nil.bag should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(bag, convey.ShouldNotBeNil)
})
})
})
}
func TestV1GetMedalGiftConfig(t *testing.T) {
convey.Convey("GetMedalGiftConfig", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(88895029)
)
c.Convey("When everything gose positive", func(c convey.C) {
medal, giftConfig, err := s.GetMedalGiftConfig(ctx, uid)
c.Convey("Then err should be nil.medal,giftConfig should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(giftConfig, convey.ShouldNotBeNil)
c.So(medal, convey.ShouldNotBeNil)
})
})
})
}
func TestV1GetDailyGiftBag(t *testing.T) {
convey.Convey("GetDailyGiftBag", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(0)
giftConfig map[int64]int64
)
c.Convey("When everything gose positive", func(c convey.C) {
data := s.GetDailyGiftBag(ctx, uid, giftConfig)
c.Convey("Then data should not be nil.", func(c convey.C) {
c.So(data, convey.ShouldNotBeNil)
})
})
})
}
func TestV1getDeltaDayTime(t *testing.T) {
convey.Convey("getDeltaDayTime", t, func(c convey.C) {
var (
day = int(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
p1 := getDeltaDayTime(day)
c.Convey("Then p1 should not be nil.", func(c convey.C) {
c.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestV1getThisWeekTime(t *testing.T) {
convey.Convey("getThisWeekTime", t, func(c convey.C) {
c.Convey("When everything gose positive", func(c convey.C) {
p1 := getThisWeekTime()
c.Convey("Then p1 should not be nil.", func(c convey.C) {
c.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestV1getNextWeekTime(t *testing.T) {
convey.Convey("getNextWeekTime", t, func(c convey.C) {
c.Convey("When everything gose positive", func(c convey.C) {
p1 := getNextWeekTime()
c.Convey("Then p1 should not be nil.", func(c convey.C) {
c.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestV1FormatGift(t *testing.T) {
convey.Convey("FormatGift", t, func(c convey.C) {
var (
giftConfig map[int64]int64
expireAt = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
gift := s.FormatGift(giftConfig, expireAt)
c.Convey("Then gift should not be nil.", func(c convey.C) {
c.So(gift, convey.ShouldNotBeNil)
})
})
})
}
func TestV1GetLevelGift(t *testing.T) {
convey.Convey("GetLevelGift", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
bag := s.GetLevelGift(ctx, uid)
c.Convey("Then bag should not be nil.", func(c convey.C) {
c.So(bag, convey.ShouldNotBeNil)
})
})
})
}
func TestV1GetLevelGiftConfig(t *testing.T) {
convey.Convey("GetLevelGiftConfig", t, func(c convey.C) {
c.Convey("When everything gose positive", func(c convey.C) {
r := s.GetLevelGiftConfig(9)
c.So(r, convey.ShouldBeNil)
r = s.GetLevelGiftConfig(20)
c.So(r, convey.ShouldResemble, map[int64]int64{1: 30})
r = s.GetLevelGiftConfig(26)
c.So(r, convey.ShouldResemble, map[int64]int64{1: 50})
r = s.GetLevelGiftConfig(60)
c.So(r, convey.ShouldResemble, map[int64]int64{1: 300})
})
})
}
func TestV1GetWeekLevelGiftBag(t *testing.T) {
convey.Convey("GetWeekLevelGiftBag", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(0)
level = int64(0)
giftConfig map[int64]int64
)
c.Convey("When everything gose positive", func(c convey.C) {
data := s.GetWeekLevelGiftBag(ctx, uid, level, giftConfig)
c.Convey("Then data should not be nil.", func(c convey.C) {
c.So(data, convey.ShouldNotBeNil)
})
})
})
}
func TestV1GetVipMonthGift(t *testing.T) {
convey.Convey("GetVipMonthGift", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
bag := s.GetVipMonthGift(ctx, uid)
c.Convey("Then bag should not be nil.", func(c convey.C) {
c.So(bag, convey.ShouldNotBeNil)
})
})
})
}
func TestV1GetUnionFansGift(t *testing.T) {
convey.Convey("GetUnionFansGift", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
bag := s.GetUnionFansGift(ctx, uid)
c.Convey("Then bag should not be nil.", func(c convey.C) {
c.So(bag, convey.ShouldNotBeNil)
})
})
})
}
func TestV1GetUnionConfig(t *testing.T) {
convey.Convey("GetUnionConfig", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(1)
)
c.Convey("When everything gose positive", func(c convey.C) {
res := s.GetUnionConfig(ctx, uid)
c.Convey("Then res should not be nil.", func(c convey.C) {
c.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestV1GetBagExpireStatus(t *testing.T) {
convey.Convey("GetBagExpireStatus", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(-1)
)
c.Convey("When everything gose positive", func(c convey.C) {
status := s.GetBagExpireStatus(ctx, uid)
c.Convey("Then status should not be nil.", func(c convey.C) {
c.So(status, convey.ShouldEqual, -1)
})
})
})
}
func TestV1GetBagList(t *testing.T) {
convey.Convey("GetBagList", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(123214)
)
c.Convey("When everything gose positive", func(c convey.C) {
bagList := s.GetBagList(ctx, uid)
c.Convey("Then bagList should not be nil.", func(c convey.C) {
c.So(bagList, convey.ShouldBeNil)
})
})
})
}
func TestV1GetUserLevelInfo(t *testing.T) {
convey.Convey("GetUserLevelInfo", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(88895029)
)
c.Convey("When everything gose positive", func(c convey.C) {
levelInfo := s.GetUserLevelInfo(ctx, uid)
c.Convey("Then levelInfo should not be nil.", func(c convey.C) {
c.So(levelInfo, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,22 @@
package v1
import (
"context"
"go-common/app/service/live/gift/model"
"go-common/library/log"
"strconv"
)
//SendAddGiftMsg 投递databus
func (s *GiftService) SendAddGiftMsg(ctx context.Context, uid, giftID, giftNum, expireAt int64, source, msgID string) {
freeGift := &model.AddFreeGift{
UID: uid,
GiftID: giftID,
GiftNum: giftNum,
ExpireAt: expireAt,
Source: source,
MsgID: msgID,
}
sendRet := s.addGift.Send(ctx, strconv.FormatInt(uid, 10), freeGift)
log.Info("addFreeGift,ret:%v,params:%v", sendRet, freeGift)
}

View File

@@ -0,0 +1,28 @@
package v1
import (
"context"
"testing"
"github.com/satori/go.uuid"
"github.com/smartystreets/goconvey/convey"
)
func TestV1SendAddGiftMsg(t *testing.T) {
convey.Convey("SendAddGiftMsg", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(88895029)
giftID = int64(1)
giftNum = int64(3)
expireAt = int64(0)
source = "test"
msgID = uuid.NewV4().String()
)
c.Convey("When everything gose positive", func(c convey.C) {
s.SendAddGiftMsg(ctx, uid, giftID, giftNum, expireAt, source, msgID)
c.Convey("No return values", func(c convey.C) {
})
})
})
}

View File

@@ -0,0 +1,266 @@
package v1
import (
"context"
"encoding/json"
"errors"
"fmt"
"go-common/app/service/live/gift/dao"
"go-common/app/service/live/gift/model"
v1liveuser "go-common/app/service/live/live_user/api/liverpc/v1"
"go-common/library/log"
"strconv"
"strings"
"sync/atomic"
"time"
v1pb "go-common/app/service/live/gift/api/grpc/v1"
)
// DiscountCache DiscountCache
type DiscountCache struct {
discountMap map[int64]map[int64]map[int64]int64
discountPlan map[int64]*model.DiscountInfo
cacheTime int64
}
var (
dCache = new(DiscountCache)
discountAtomic = new(atomic.Value)
)
// GetHighestGuardLevel 获取最高等级大航海
func (s *GiftService) GetHighestGuardLevel(ctx context.Context, uid int64) (lv int64, err error) {
if uid == 0 {
return
}
res, err := dao.LiveUserApi.V1Guard.GetByUid(ctx, &v1liveuser.GuardGetByUidReq{
Uid: uid,
IncExpire: 0,
IsLimitOne: 0,
})
if err != nil || res.Code != 0 {
log.Error("call V1Guard.GetByUid error,err:(%v)", err)
return
}
if res.Code != 0 {
err = errors.New("resp code err")
log.Error("call V1Guard.GetByUid error,code:(%v)", res.Code)
return
}
data := res.Data
if len(data) == 0 {
return
}
lv = data[0].PrivilegeType
return
}
// GetDiscountList 获取折扣道具列表
func (s *GiftService) GetDiscountList(ctx context.Context, platform string, userType, roomID, areaParentID, areaID int64) (config []*v1pb.DiscountGiftListResp_GiftInfo, err error) {
config = make([]*v1pb.DiscountGiftListResp_GiftInfo, 0)
err = s.LoadDiscountCache(ctx, false)
if err != nil {
return
}
platform = strings.ToLower(platform)
platformCheck := make([]int64, 0)
pf, ok := platformMap[platform]
if !ok {
platformCheck = []int64{platformMap["default"]}
}
if pf != platformMap["default"] {
platformCheck = append(platformCheck, pf)
}
// map顺序是随机的
sceneCheck := []int64{sceneRoom, sceneArea, sceneAreaParent, sceneAll, sceneDefault}
sceneMap := map[int64]int64{
sceneRoom: roomID,
sceneArea: areaID,
sceneAreaParent: areaParentID,
sceneAll: 0,
sceneDefault: 0,
}
utStr := strconv.FormatInt(userType, 10)
dCache = discountAtomic.Load().(*DiscountCache)
for _, pf := range platformCheck {
for _, sk := range sceneCheck {
sv := sceneMap[sk]
planID, ok := dCache.discountMap[pf][sk][sv]
if !ok {
continue
}
discountInfo, ok := dCache.discountPlan[planID]
if ok {
for giftID, info := range discountInfo.List {
var (
dp int64
cp int64
cm string
)
price, suc := info["discount_price_"+utStr]
if suc {
dp = int64(price.(int))
} else {
dp = int64(0)
}
pos, suc := info["corner_position_"+utStr]
if suc {
cp = int64(pos.(int))
} else {
cp = int64(0)
}
mark, suc := info["corner_mark_"+utStr]
if suc {
cm = mark.(string)
} else {
cm = ""
}
tmp := &v1pb.DiscountGiftListResp_GiftInfo{
GiftId: giftID,
Price: s.GetGiftPrice(ctx, giftID),
DiscountPrice: dp,
CornerMark: cm,
CornerPosition: cp,
CornerColor: "#699553",
}
config = append(config, tmp)
}
}
}
}
return
}
// GetGiftPrice 获取礼物价格
func (s *GiftService) GetGiftPrice(ctx context.Context, giftID int64) (price int64) {
giftConfig, err := s.GetAllConfig(ctx)
if err != nil {
return
}
for _, v := range giftConfig {
if v.Id == giftID {
return v.Price
}
}
return
}
// LoadDiscountCache LoadDiscountCache
func (s *GiftService) LoadDiscountCache(ctx context.Context, force bool) (err error) {
curTime := time.Now().Unix()
var ok bool
dCache, ok = discountAtomic.Load().(*DiscountCache)
if !ok {
dCache = new(DiscountCache)
}
if force || (curTime-dCache.cacheTime) > 30 {
err = s.SyncDiscountCache(ctx)
}
return
}
// SyncDiscountCache SyncDiscountCache
func (s *GiftService) SyncDiscountCache(ctx context.Context) (err error) {
dPlan, err := s.GetDiscountPlans(ctx)
if err != nil {
return
}
//platform:scene_key:scene_value:plan_id
dMap := make(map[int64]map[int64]map[int64]int64)
for _, v := range dPlan {
platformList := s.parsePlatform2Slice(v.Platform)
for _, sv := range v.SceneValue {
for _, platform := range platformList {
if _, ok := dMap[platform]; !ok {
dMap[platform] = make(map[int64]map[int64]int64)
}
if _, ok := dMap[platform][v.SceneKey]; !ok {
dMap[platform][v.SceneKey] = make(map[int64]int64)
}
dMap[platform][v.SceneKey][sv] = v.Id
}
}
}
dCache.discountPlan = dPlan
dCache.discountMap = dMap
dCache.cacheTime = time.Now().Unix()
discountAtomic.Store(dCache)
log.Info("SyncDiscountCache ,%+v", dCache)
return
}
func (s *GiftService) parsePlatform2Slice(platform int64) (pf []int64) {
if platform == 0 {
pf = []int64{0}
return pf
}
for _, v := range platformMap {
if v > 0 && (v&platform) == v {
pf = append(pf, v)
}
}
return
}
// GetDiscountPlans 获取折扣计划
func (s *GiftService) GetDiscountPlans(ctx context.Context) (dp map[int64]*model.DiscountInfo, err error) {
plans, err := s.dao.GetDiscountPlan(ctx, time.Now())
if err != nil {
return
}
disIds := make([]int64, 0)
for _, v := range plans {
disIds = append(disIds, v.Id)
}
if len(disIds) == 0 {
return
}
details, err := s.dao.GetByDiscountIds(ctx, disIds)
if err != nil {
return
}
list := make(map[int64]map[int64]map[string]interface{})
for _, v := range details {
utStr := strconv.FormatInt(v.UserType, 10)
list[v.DiscountId] = map[int64]map[string]interface{}{
v.GiftId: {
"discount_price_" + utStr: v.DiscountPrice,
"corner_mark_" + utStr: v.CornerMark,
"corner_position_" + utStr: v.CornerPosition,
"discount_id": v.DiscountId,
},
}
}
dp = make(map[int64]*model.DiscountInfo)
for _, v := range plans {
tmp := strings.Split(v.SceneValue, ",")
sv := make([]int64, 0)
for _, svStr := range tmp {
svInt, _ := strconv.ParseInt(svStr, 10, 64)
sv = append(sv, svInt)
}
dp[v.Id] = &model.DiscountInfo{
Id: v.Id,
SceneKey: v.SceneKey,
SceneValue: sv,
Platform: v.Platform,
List: list[v.Id],
}
}
return
}
// MyPrintf 我的打印
func (s *GiftService) MyPrintf(v interface{}, msg string) {
dump, _ := json.MarshalIndent(v, "", " ")
fmt.Printf("**********%s**********\n%s\n", msg, dump)
}
// FormatPrint 我的打印
func (s *GiftService) FormatPrint(v interface{}, msg string) {
fmt.Printf("**********%s**********\n%v\n", msg, v)
}

View File

@@ -0,0 +1,118 @@
package v1
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestV1GetHighestGuardLevel(t *testing.T) {
convey.Convey("GetHighestGuardLevel", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
lv, err := s.GetHighestGuardLevel(ctx, uid)
c.Convey("Then err should be nil.lv should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(lv, convey.ShouldNotBeNil)
})
})
})
}
func TestV1GetDiscountList(t *testing.T) {
convey.Convey("GetDiscountList", t, func(c convey.C) {
var (
ctx = context.Background()
platform = ""
userType = int64(0)
roomID = int64(1)
areaID = int64(1)
areaParentID = int64(1)
)
c.Convey("When everything gose positive", func(c convey.C) {
config, err := s.GetDiscountList(ctx, platform, userType, roomID, areaID, areaParentID)
c.Convey("Then err should be nil.config should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(config, convey.ShouldNotBeNil)
})
})
})
}
func TestV1GetGiftPrice(t *testing.T) {
convey.Convey("GetGiftPrice", t, func(c convey.C) {
var (
ctx = context.Background()
giftID = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
price := s.GetGiftPrice(ctx, giftID)
c.Convey("Then price should not be nil.", func(c convey.C) {
c.So(price, convey.ShouldNotBeNil)
})
})
})
}
func TestV1LoadDiscountCache(t *testing.T) {
convey.Convey("LoadDiscountCache", t, func(c convey.C) {
var (
ctx = context.Background()
force bool
)
c.Convey("When everything gose positive", func(c convey.C) {
err := s.LoadDiscountCache(ctx, force)
c.Convey("Then err should be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
})
})
})
}
func TestV1SyncDiscountCache(t *testing.T) {
convey.Convey("SyncDiscountCache", t, func(c convey.C) {
var (
ctx = context.Background()
)
c.Convey("When everything gose positive", func(c convey.C) {
err := s.SyncDiscountCache(ctx)
c.Convey("Then err should be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
})
})
})
}
func TestV1parsePlatform2Slice(t *testing.T) {
convey.Convey("parsePlatform2Slice", t, func(c convey.C) {
pf := s.parsePlatform2Slice(0)
c.So(pf, convey.ShouldNotBeNil)
c.So(pf, convey.ShouldContain, int64(0))
pf = s.parsePlatform2Slice(6)
c.So(pf, convey.ShouldNotBeNil)
c.So(pf, convey.ShouldHaveLength, 2)
c.So(pf, convey.ShouldContain, int64(2))
c.So(pf, convey.ShouldContain, int64(4))
})
}
func TestV1GetDiscountPlans(t *testing.T) {
convey.Convey("GetDiscountPlans", t, func(c convey.C) {
var (
ctx = context.Background()
)
c.Convey("When everything gose positive", func(c convey.C) {
dp, err := s.GetDiscountPlans(ctx)
c.Convey("Then err should be nil.dp should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(dp, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,252 @@
package v1
import (
"context"
v1pb "go-common/app/service/live/gift/api/grpc/v1"
"go-common/app/service/live/gift/conf"
"go-common/app/service/live/gift/dao"
v1room "go-common/app/service/live/room/api/liverpc/v1"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/queue/databus"
"go-common/library/sync/errgroup"
"sync"
"time"
)
// GiftService struct
type GiftService struct {
conf *conf.Config
// optionally add other properties here, such as dao
// dao *dao.Dao
dao *dao.Dao
addGift *databus.Databus
}
//NewGiftService init
func NewGiftService(c *conf.Config) (s *GiftService) {
s = &GiftService{
conf: c,
dao: dao.New(c),
addGift: databus.New(c.Databus.AddGift),
}
go s.infocproc()
return s
}
// RoomGiftList implementation
func (s *GiftService) RoomGiftList(ctx context.Context, req *v1pb.RoomGiftListReq) (resp *v1pb.RoomGiftListResp, err error) {
resp, err = s.GetOnlinePlanGiftList(ctx, req.RoomId, req.AreaV2ParentId, req.AreaV2Id, req.Platform, req.Build, req.MobiApp)
if err != nil {
return
}
resp.ShowCountMap = 0
resp.OldList = s.getOldList()
return
}
// GiftConfig implementation
func (s *GiftService) GiftConfig(ctx context.Context, req *v1pb.GiftConfigReq) (resp *v1pb.GiftConfigResp, err error) {
resp = &v1pb.GiftConfigResp{
Data: make([]*v1pb.GiftConfigResp_Config, 0),
}
all, err := s.GetAllConfig(ctx)
if err != nil || len(all) == 0 {
log.Error("all gift num:%d", len(all))
return
}
resp.Data = all
enable := s.conf.Gift.EnableFilterGift
bubbleID := s.conf.Gift.BubbleId
if enable {
for _, giftInfo := range all {
giftID := giftInfo.Id
//泡泡糖特殊逻辑
if giftID == bubbleID {
giftInfo.Type = 1
}
//kfc道具特殊逻辑
if giftID == 30082 {
giftInfo.Type = 2
}
if giftInfo.BagGift == 0 && !s.IsValidGift(giftID) && !s.IsSpecialGift(giftID) && !s.isPrivilegeGift(giftID) {
continue
}
if req.Platform == "android" && req.Build != 0 && req.Build < 5270000 {
if giftID >= 30013 && giftID <= 30038 {
giftInfo.FullScHorizontalSvga = ""
giftInfo.FullScVerticalSvga = ""
}
if giftID == 25 {
giftInfo.FullScHorizontalSvga = "http://i0.hdslb.com/bfs/live/9f88c8260ee23b86685a8cae3efa6d9be46717a5.svga"
giftInfo.FullScVerticalSvga = "http://i0.hdslb.com/bfs/live/ec028520a8a951553cc42dc7d841edb38daba427.svga"
}
}
resp.Data = append(resp.Data, giftInfo)
}
}
return
}
// TickerReloadGift 定时加载数据库数据到全局配置
func (s *GiftService) TickerReloadGift() {
ctx := context.Background()
s.LoadGiftCache(ctx, true)
s.LoadDiscountCache(ctx, true)
ticker := time.NewTicker(time.Second * 15)
go func() {
for range ticker.C {
s.LoadGiftCache(ctx, true)
s.LoadDiscountCache(ctx, true)
}
}()
}
// DiscountGiftList implementation
func (s *GiftService) DiscountGiftList(ctx context.Context, req *v1pb.DiscountGiftListReq) (resp *v1pb.DiscountGiftListResp, err error) {
resp = &v1pb.DiscountGiftListResp{}
if req.Uid == 0 {
err = ecode.Error(-1, "请先登录哦")
return
}
roomID := req.Roomid
areaParentID := req.AreaV2ParentId
areaID := req.AreaV2Id
if req.Roomid == 0 {
var r *v1room.RoomGetStatusInfoByUidsResp
r, err = dao.RoomApi.V1Room.GetStatusInfoByUids(ctx, &v1room.RoomGetStatusInfoByUidsReq{
Uids: []int64{req.Ruid},
ShowHidden: 1,
})
if err != nil {
log.Error("call V1Room.GetStatusInfoByUids error,params:uid:%v", req.Ruid)
err = ecode.Error(-1, "内部错误")
return
}
if r.Code != 0 {
log.Error("call V1Room.GetStatusInfoByUids error,params:code:(%v),msg:(%v)", r.Code, r.Msg)
err = ecode.Error(-1, "内部错误")
return
}
if len(r.Data) == 0 {
err = ecode.Error(-1, "折扣道具获取失败")
return
}
roomID = r.Data[req.Ruid].RoomId
areaParentID = r.Data[req.Ruid].AreaV2ParentId
areaID = r.Data[req.Ruid].AreaV2Id
}
userType, err := s.GetHighestGuardLevel(ctx, req.Uid)
if err != nil {
err = ecode.Error(-1, "折扣道具获取失败")
return
}
list, err := s.GetDiscountList(ctx, req.Platform, userType, roomID, areaParentID, areaID)
if err != nil {
return
}
resp.DiscountList = list
return
}
// DailyBag implementation
func (s *GiftService) DailyBag(ctx context.Context, req *v1pb.DailyBagReq) (resp *v1pb.DailyBagResp, err error) {
resp = &v1pb.DailyBagResp{}
if req.Uid == 0 {
err = ecode.Error(400, "请先登录哦")
return
}
uid := req.Uid
res, err := s.dao.GetDailyBagCache(ctx, uid)
if err != nil {
err = ecode.Error(-1, "系统错误")
return
}
if res != nil {
resp = &v1pb.DailyBagResp{
BagStatus: 2,
BagExpireStatus: s.GetBagExpireStatus(ctx, uid),
BagToast: &v1pb.DailyBagResp_BagToast{
ToastStatus: 0,
ToastMessage: "",
},
BagList: res,
}
return
}
gotLock, _, err := s.dao.Lock(ctx, getBagLockKey(uid), 5000, 0, 0)
if !gotLock || err != nil {
err = ecode.Error(400, "包裹领取失败,请重试")
return
}
eg, _ := errgroup.WithContext(ctx)
//同时获取各种礼包返回
resp.BagList = make([]*v1pb.DailyBagResp_BagList, 0)
var mu sync.Mutex
eg.Go(func() error {
bag, _ := s.GetMedalGift(ctx, uid)
if bag.Type > 0 {
mu.Lock()
resp.BagList = append(resp.BagList, bag)
mu.Unlock()
}
return nil
})
eg.Go(func() error {
bag := s.GetLevelGift(ctx, uid)
if bag.Type > 0 {
mu.Lock()
resp.BagList = append(resp.BagList, bag)
mu.Unlock()
}
return nil
})
eg.Go(func() error {
bag := s.GetVipMonthGift(ctx, uid)
if bag.Type > 0 {
mu.Lock()
resp.BagList = append(resp.BagList, bag)
mu.Unlock()
}
return nil
})
eg.Go(func() error {
unionGift := s.GetUnionFansGift(ctx, uid)
mu.Lock()
resp.BagList = append(resp.BagList, unionGift...)
mu.Unlock()
return nil
})
eg.Wait()
// 同时进行后续清理
eg.Go(func() error {
return s.dao.ForceUnLock(ctx, getBagLockKey(uid))
})
var expireStatus int64 = -1
eg.Go(func() error {
expireStatus = s.GetBagExpireStatus(ctx, uid)
return nil
})
eg.Go(func() error {
return s.dao.SetDailyBagCache(ctx, uid, resp.BagList, 3600)
})
eg.Wait()
resp.BagStatus = 2
if len(resp.BagList) > 0 {
resp.BagStatus = 1
}
resp.BagExpireStatus = expireStatus
resp.BagToast = &v1pb.DailyBagResp_BagToast{
ToastStatus: 0,
ToastMessage: "",
}
return
}

View File

@@ -0,0 +1,193 @@
package v1
import (
"context"
"flag"
"fmt"
v1pb "go-common/app/service/live/gift/api/grpc/v1"
"go-common/app/service/live/gift/conf"
"go-common/app/service/live/gift/dao"
"go-common/app/service/live/resource/sdk"
"go-common/app/service/live/gift/model"
"os"
"testing"
"time"
"github.com/smartystreets/goconvey/convey"
)
var (
s *GiftService
//ctx = context.TODO()
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "")
flag.Set("conf_token", "")
flag.Set("tree_id", "")
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/test.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
s = NewGiftService(conf.Conf)
dao.InitApi()
s.TickerReloadGift()
titansSdk.Init(conf.Conf.Titan)
os.Exit(m.Run())
}
func TestV1RoomGiftList(t *testing.T) {
convey.Convey("RoomGiftList", t, func(c convey.C) {
var (
ctx = context.Background()
req = &v1pb.RoomGiftListReq{RoomId: 1}
)
c.Convey("When everything gose positive", func(c convey.C) {
resp, err := s.RoomGiftList(ctx, req)
c.Convey("Then err should be nil.resp should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(resp, convey.ShouldNotBeNil)
c.So(resp.List, convey.ShouldNotBeNil)
c.So(resp.ShowCountMap, convey.ShouldEqual, 0)
c.So(resp.OldList, convey.ShouldHaveLength, 1)
c.So(resp.OldList[0].Id, convey.ShouldEqual, 1)
})
})
})
}
func TestV1GiftConfig(t *testing.T) {
convey.Convey("GiftConfig", t, func(c convey.C) {
var (
ctx = context.Background()
req = &v1pb.GiftConfigReq{
Platform: "pc",
Build: 0,
}
)
c.Convey("When everything gose positive", func(c convey.C) {
resp, err := s.GiftConfig(ctx, req)
c.Convey("Then err should be nil.resp should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(resp, convey.ShouldNotBeNil)
})
})
})
}
func TestV1TickerReloadGift(t *testing.T) {
convey.Convey("TickerReloadGift", t, func(c convey.C) {
c.Convey("When everything gose positive", func(c convey.C) {
s.TickerReloadGift()
c.Convey("No return values", func(c convey.C) {
})
})
})
}
func TestV1DiscountGiftList(t *testing.T) {
convey.Convey("DiscountGiftList", t, func(c convey.C) {
var (
ctx = context.Background()
)
OK, ok := discountAtomic.Load().(*DiscountCache)
fmt.Printf("$$$%v%v", OK, ok)
dCache.discountPlan = map[int64]*model.DiscountInfo{
1: {
Id: 1, SceneKey: 99, SceneValue: []int64{0}, Platform: 0,
List: map[int64]map[string]interface{}{
20003: {
"corner_mark_0": "-20%",
"corner_position_0": 2,
"discount_id": 1,
"discount_price_0": 360000,
},
},
},
63: {
Id: 63, SceneKey: 0, SceneValue: []int64{0}, Platform: 4,
List: map[int64]map[string]interface{}{
20012: {
"corner_mark_1": "-20%",
"corner_position_1": 2,
"discount_id": 1,
"discount_price_1": 360000,
},
},
},
65: {
Id: 65, SceneKey: 0, SceneValue: []int64{0}, Platform: 4,
List: map[int64]map[string]interface{}{
20013: {
"corner_mark_1": "-20%",
"corner_position_1": 2,
"discount_id": 1,
"discount_price_1": 360000,
},
},
},
}
dCache.discountMap = map[int64]map[int64]map[int64]int64{
0: {2: {89: 63}, 99: {0: 1}},
1: {3: {459879: 63, 460460: 63}, 99: {0: 1}},
2: {3: {459879: 63, 460460: 63}, 99: {0: 1}},
4: {3: {123456: 65, 460460: 63}, 99: {0: 1}},
}
dCache.cacheTime = time.Now().Unix()
//discountAtomic.Store(dCache)
resp, err := s.DiscountGiftList(ctx, &v1pb.DiscountGiftListReq{
Uid: 1,
Roomid: 1,
AreaV2Id: 89,
})
c.So(err, convey.ShouldBeNil)
c.So(resp.DiscountList[0].GiftId, convey.ShouldEqual, 20012)
c.So(resp.DiscountList[0].DiscountPrice, convey.ShouldEqual, 360000)
c.So(resp.DiscountList[0].CornerMark, convey.ShouldEqual, "-20%")
c.So(resp.DiscountList[0].CornerColor, convey.ShouldEqual, "#699553")
//resp, err = s.DiscountGiftList(ctx, &v1pb.DiscountGiftListReq{
// Uid: 1,
// Roomid: 123456,
// AreaV2Id: 89,
// Platform: "android",
//})
//c.So(err, convey.ShouldBeNil)
//c.So(resp.DiscountList[0].GiftId, convey.ShouldEqual, 20013)
//c.So(resp.DiscountList[0].DiscountPrice, convey.ShouldEqual, 360000)
//c.So(resp.DiscountList[0].CornerMark, convey.ShouldEqual, "-20%")
//c.So(resp.DiscountList[0].CornerColor, convey.ShouldEqual, "#699553")
})
}
func TestV1DailyBag(t *testing.T) {
convey.Convey("DailyBag", t, func(c convey.C) {
var (
ctx = context.Background()
req = &v1pb.DailyBagReq{Uid: 88895029}
)
c.Convey("When everything gose positive", func(c convey.C) {
resp, err := s.DailyBag(ctx, req)
c.Convey("Then err should be nil.resp should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(resp, convey.ShouldNotBeNil)
c.So(resp.BagStatus, convey.ShouldNotBeNil)
c.So(resp.BagExpireStatus, convey.ShouldNotBeNil)
c.So(resp.BagToast, convey.ShouldNotBeNil)
c.So(resp.BagList, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,82 @@
package v1
import (
"go-common/library/log"
"go-common/library/log/infoc"
"strconv"
"time"
)
var inCh = make(chan interface{}, 10240)
const maxInt = int(^uint(0) >> 1)
type bagLogInfoc struct {
id string
uid string
bagID string
giftID string
num string
afterNum string
source string
infoType string
ctime string
}
// RelationInfoc relation related info to BigData for anti-spam
func (s *GiftService) bagLogInfoc(uid, bagID, giftID, num, afterNum int64, source string) {
s.infoc(bagLogInfoc{
id: MakeID(uid),
uid: strconv.FormatInt(uid, 10),
bagID: strconv.FormatInt(bagID, 10),
giftID: strconv.FormatInt(giftID, 10),
num: strconv.FormatInt(num, 10),
afterNum: strconv.FormatInt(afterNum, 10),
source: source,
infoType: "1",
ctime: time.Now().Format("2006-01-02 15:04:05"),
})
}
// MakeID 生成上报id
func MakeID(uid int64) string {
prefix := strconv.FormatInt(uid%10, 10)
postfix := strconv.Itoa(maxInt - int(time.Now().Unix()*10000))
uidStr := strconv.FormatInt(uid, 10)
l := len(uidStr)
var middle string
if l >= 10 {
middle = uidStr
} else {
var s string
for i := 0; i < (10 - l); i++ {
s += "0"
}
middle = s + uidStr
}
return prefix + middle + postfix
}
//infoc
func (s *GiftService) infoc(i interface{}) {
select {
case inCh <- i:
default:
log.Warn("infocproc chan full")
}
}
// infocproc
func (s *GiftService) infocproc() {
var infoc2 = infoc.New(s.conf.Infoc["bagLog"])
for {
i := <-inCh
switch v := i.(type) {
case bagLogInfoc:
err := infoc2.Info(v.id, v.uid, v.bagID, v.giftID, v.num, v.afterNum, v.source, v.infoType, v.ctime)
log.Info("infocproc info %v,ret:%v", v, err)
default:
log.Warn("infocproc can't process the type")
}
}
}

View File

@@ -0,0 +1,63 @@
package v1
import (
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestV1bagLogInfoc(t *testing.T) {
convey.Convey("bagLogInfoc", t, func(ctx convey.C) {
var (
uid = int64(5)
bagID = int64(10)
giftID = int64(1)
num = int64(1)
afterNum = int64(2)
source = "xx"
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
s.bagLogInfoc(uid, bagID, giftID, num, afterNum, source)
ctx.Convey("No return values", func(ctx convey.C) {
})
})
})
}
func TestV1MakeID(t *testing.T) {
convey.Convey("MakeID", t, func(ctx convey.C) {
var (
uid = int64(5)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
p1 := MakeID(uid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
ctx.So(p1, convey.ShouldContainSubstring, "50000000005")
})
})
})
}
func TestV1infoc(t *testing.T) {
convey.Convey("infoc", t, func(ctx convey.C) {
var (
i = interface{}(0)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
s.infoc(i)
ctx.Convey("No return values", func(ctx convey.C) {
})
})
})
}
func TestV1infocproc(t *testing.T) {
convey.Convey("infocproc", t, func(ctx convey.C) {
ctx.Convey("When everything gose positive", func(ctx convey.C) {
s.infocproc()
ctx.Convey("No return values", func(ctx convey.C) {
})
})
})
}

View File

@@ -0,0 +1,436 @@
package v1
import (
"context"
"encoding/json"
v1pb "go-common/app/service/live/gift/api/grpc/v1"
"go-common/app/service/live/gift/model"
"go-common/app/service/live/resource/sdk"
"go-common/library/log"
"strconv"
"strings"
"sync/atomic"
"time"
//"go-common/library/log"
"go-common/library/sync/errgroup"
)
var privilegeGift = []int64{30047}
var defaultPlan = "20005,20008,20013,3,20009,20012,20003,25,7,8,20011,20014,20007,20002,20010,20004"
var giftCache = new(GiftCache)
var giftAtomic = new(atomic.Value)
// GiftCache GiftCache
type GiftCache struct {
cacheTime int64
giftList map[int64]*model.GiftOnline
plan map[string]map[int64]map[int64]*model.GiftPlan
validGift string
}
var platformMap = map[string]int64{
"default": 0,
"pc": 1,
"ios": 2,
"android": 4,
"ipad": 8,
}
const (
sceneAll int64 = 0
sceneAreaParent int64 = 1
sceneArea int64 = 2
sceneRoom int64 = 3
sceneDefault int64 = 99
//coinTypeSilver = 0
coinTypeGold = 1
coinTypeBag = 2
)
// GetOnlinePlanGiftList 获取在线礼物计划
func (s *GiftService) GetOnlinePlanGiftList(ctx context.Context, roomID, areaParentID, areaID int64, platform string, build int64, mobiApp string) (resp *v1pb.RoomGiftListResp, err error) {
resp = &v1pb.RoomGiftListResp{}
if err = s.LoadGiftCache(ctx, false); err != nil {
return
}
platform = strings.ToLower(platform)
if _, ok := platformMap[platform]; !ok {
platform = "pc"
}
platformCheck := []string{platform, "default"}
// map顺序是随机的
sceneCheck := []int64{sceneRoom, sceneArea, sceneAreaParent, sceneAll, sceneDefault}
sceneMap := map[int64]int64{
sceneRoom: roomID,
sceneArea: areaID,
sceneAreaParent: areaParentID,
sceneAll: 0,
sceneDefault: 0,
}
giftCache = giftAtomic.Load().(*GiftCache)
var plan *model.GiftPlan
for _, pf := range platformCheck {
for _, sceneKey := range sceneCheck {
sceneVal := sceneMap[sceneKey]
if plan == nil {
plan = giftCache.plan[pf][sceneKey][sceneVal]
}
}
}
list := s.ConvertGiftList(plan.List, plan.Id, platform, build, mobiApp)
list = s.AddPrivilegeGift(list, platform, build, mobiApp)
silverList := s.ConvertGiftList(plan.SilverList, plan.Id, platform, build, mobiApp)
resp = &v1pb.RoomGiftListResp{
List: list,
SilverList: silverList,
}
return
}
// LoadGiftCache LoadGiftCache
func (s *GiftService) LoadGiftCache(ctx context.Context, needReload bool) (err error) {
curTime := time.Now().Unix()
var ok bool
giftCache, ok = giftAtomic.Load().(*GiftCache)
if !ok {
giftCache = new(GiftCache)
}
if needReload || (curTime-giftCache.cacheTime) > 30 {
err = s.SyncLocalCache(ctx)
}
return
}
// SyncLocalCache SyncLocalCache
func (s *GiftService) SyncLocalCache(ctx context.Context) (err error) {
var (
allGifts []*model.GiftOnline
allPlans []*model.GiftPlan
)
eg := errgroup.Group{}
eg.Go(func() error {
allGifts, err = s.dao.GetAllGift(ctx)
return err
})
eg.Go(func() error {
allPlans, err = s.dao.GetOnlinePlan(ctx)
return err
})
if err = eg.Wait(); err != nil {
return
}
gifts := make(map[int64]*model.GiftOnline)
for _, gift := range allGifts {
giftID := gift.GiftId
if s.isPrivilegeGift(giftID) {
gift.PrivilegeRequired = 1
}
gifts[giftID] = gift
}
validGiftStr := defaultPlan
plan := make(map[string]map[int64]map[int64]*model.GiftPlan)
s.addDefaultPlan(plan)
for _, v := range allPlans {
sceneKey := v.SceneKey
sceneVal := v.SceneValue
platformList := s.parsePlatform(v.Platform)
for _, platform := range platformList {
if _, ok := plan[platform][sceneKey][sceneVal]; ok {
continue
}
validGiftStr += "," + v.List + "," + v.SilverList
if _, ok := plan[platform]; !ok {
plan[platform] = make(map[int64]map[int64]*model.GiftPlan)
}
if _, ok := plan[platform][sceneKey]; !ok {
plan[platform][sceneKey] = make(map[int64]*model.GiftPlan)
}
plan[platform][sceneKey][sceneVal] = v
}
}
giftCache.giftList = gifts
giftCache.plan = plan
giftCache.validGift = validGiftStr
giftCache.cacheTime = time.Now().Unix()
giftAtomic.Store(giftCache)
log.Info("SyncLocalCache Gift info,%+v", giftCache)
return
}
func (s *GiftService) isPrivilegeGift(giftID int64) bool {
for _, ID := range privilegeGift {
if ID == giftID {
return true
}
}
return false
}
func (s *GiftService) parsePlatform(platform int64) (pf []string) {
if platform == 0 {
pf = []string{"default"}
return pf
}
for k, v := range platformMap {
if v > 0 && (v&platform) == v {
pf = append(pf, k)
}
}
return
}
func (s *GiftService) addDefaultPlan(plan map[string]map[int64]map[int64]*model.GiftPlan) {
plan["default"] = map[int64]map[int64]*model.GiftPlan{
sceneDefault: {
0: &model.GiftPlan{
Id: 0,
List: defaultPlan,
SilverList: "",
},
},
}
}
// ConvertGiftList ConvertGiftList
func (s *GiftService) ConvertGiftList(list string, planID int64, platform string, build int64, mobiApp string) (data []*v1pb.RoomGiftListResp_List) {
l := strings.Split(list, ",")
var p int64 = 1
for _, v := range l {
giftID, _ := strconv.ParseInt(strings.TrimSpace(v), 10, 64)
ret := s.CheckGiftVersion(giftID, platform, build, mobiApp)
if giftID == 0 || !ret {
continue
}
l := s.NewGiftList(giftID, p, planID)
p++
data = append(data, l)
}
return
}
// CheckGiftVersion CheckGiftVersion
func (s *GiftService) CheckGiftVersion(giftID int64, platform string, build int64, mobiApp string) bool {
giftCache = giftAtomic.Load().(*GiftCache)
giftConfig := giftCache.giftList[giftID]
if giftConfig == nil {
return false
}
var err error
verLimit, err := titansSdk.Get("gift_ver_limit")
if err != nil {
log.Error("titans get error,%v", err)
return true
}
var limit map[int64]map[string]int64
if err = json.Unmarshal([]byte(verLimit), &limit); err != nil {
log.Error("json.Unmarshal error,%v", verLimit)
return true
}
minBuild := limit[giftID][mobiApp]
if build > 0 && minBuild > 0 && minBuild > build {
return false
}
return true
}
// AddPrivilegeGift 添加大航海道具
func (s *GiftService) AddPrivilegeGift(list []*v1pb.RoomGiftListResp_List, platform string, build int64, mobiApp string) []*v1pb.RoomGiftListResp_List {
//特殊逻辑: web端展示不支持大航海专属道具
if platform == "pc" {
return list
}
if len(list) >= 32 {
return list
}
var lastPosition int64
if len(list) == 0 {
lastPosition = 0
} else {
last := list[len(list)-1]
lastPosition = last.Position
}
for _, v := range privilegeGift {
if ok := s.CheckGiftVersion(v, platform, build, mobiApp); !ok {
continue
}
lastPosition++
list = append(list, s.NewGiftList(v, lastPosition, 0))
if len(list) >= 32 {
return list
}
}
return list
}
// NewGiftList NewGiftList
func (s *GiftService) NewGiftList(id, position, planID int64) (list *v1pb.RoomGiftListResp_List) {
list = &v1pb.RoomGiftListResp_List{
Id: id,
Position: position,
PlanId: planID,
}
return
}
func (s *GiftService) getOldList() (old []*v1pb.RoomGiftListResp_OldList) {
old = make([]*v1pb.RoomGiftListResp_OldList, 0)
l := &v1pb.RoomGiftListResp_OldList{
Id: 1,
Name: "辣条",
Price: 100,
Type: 0,
CoinType: map[string]string{
"silver": "silver",
},
Img: "https://s1.hdslb.com/bfs/live/da6656add2b14a93ed9eb55de55d0fd19f0fc7f6.png",
GiftUrl: "https://s1.hdslb.com/bfs/static/blive/live-assets/mobile/gift/mobilegift/2/1.gif",
CountSet: "1,10,99,520",
ComboNum: 0,
SuperNum: 0,
CountMap: map[int64]string{
1: "",
10: "",
99: "",
520: "",
},
}
old = append(old, l)
return
}
// GetAllConfig 获取所有礼物配置
func (s *GiftService) GetAllConfig(ctx context.Context) (all []*v1pb.GiftConfigResp_Config, err error) {
if err = s.LoadGiftCache(ctx, false); err != nil {
return
}
giftCache = giftAtomic.Load().(*GiftCache)
gift := giftCache.giftList
for _, v := range gift {
all = append(all, s.ConvertDB2Config(v))
}
return
}
// ConvertDB2Config ConvertDB2Config
func (s *GiftService) ConvertDB2Config(ol *model.GiftOnline) (res *v1pb.GiftConfigResp_Config) {
coinType := "silver"
bagGift := int64(0)
countMap := []*v1pb.GiftConfigResp_CountMap{
{Num: 1, Text: ""}, {Num: 10, Text: ""}, {Num: 99, Text: ""}, {Num: 520, Text: ""},
}
switch ol.CoinType {
case coinTypeGold:
coinType = "gold"
countMap = []*v1pb.GiftConfigResp_CountMap{
{Num: 1, Text: ""},
}
case coinTypeBag:
bagGift = 1
}
cm := map[string]string{
"BROADCAST": "广播",
"ACTIVITY": "活动",
}
cornerMark, ok := cm[ol.CornerMark]
if !ok {
cornerMark = ol.CornerMark
}
stayTime := s.GetStayTime(ol)
res = &v1pb.GiftConfigResp_Config{
Id: ol.GiftId,
Name: ol.Name,
Price: ol.Price,
Type: ol.Type,
CoinType: coinType,
BagGift: bagGift,
Effect: ol.Effect,
CornerMark: cornerMark,
Broadcast: ol.Broadcast,
Draw: ol.Draw,
StayTime: stayTime,
AnimationFrameNum: ol.AnimationFrameNum,
Desc: ol.Desc,
Rule: ol.Rule,
Rights: ol.Rights,
PrivilegeRequired: ol.PrivilegeRequired,
CountMap: countMap,
ImgBasic: strings.Replace(ol.AssetImgBasic, "i0.hdslb.com", "s1.hdslb.com", 1),
ImgDynamic: ol.AssetImgDynamic,
FrameAnimation: ol.AssetFrameAnimation,
Gif: ol.AssetGif,
Webp: ol.AssetWebp,
FullScWeb: ol.AssetFullScWeb,
FullScHorizontal: ol.AssetFullScHorizontal,
FullScVertical: ol.AssetFullScVertical,
FullScHorizontalSvga: ol.AssetFullScHorizontalSvga,
FullScVerticalSvga: ol.AssetFullScVerticalSvga,
BulletHead: ol.AssetBulletHead,
BulletTail: ol.AssetBulletTail,
}
return
}
// GetStayTime 获取礼物stayTime
func (s *GiftService) GetStayTime(ol *model.GiftOnline) (time int64) {
giftIDMap := map[int64]int64{
25: 30,
}
typeMap := map[int64]int64{
0: 3,
1: 2,
2: 20,
3: 6,
}
var ok bool
if time, ok = giftIDMap[ol.GiftId]; !ok {
if time, ok = typeMap[ol.Type]; !ok {
time = 3
}
}
return
}
// IsValidGift 判断道具合法性
func (s *GiftService) IsValidGift(giftID int64) bool {
giftCache = giftAtomic.Load().(*GiftCache)
giftIDStrArr := strings.Split(giftCache.validGift, ",")
for _, giftIDStr := range giftIDStrArr {
validGiftID, _ := strconv.ParseInt(strings.TrimSpace(giftIDStr), 10, 64)
if giftID == validGiftID {
return true
}
}
return false
}
// IsSpecialGift 是否特殊道具
func (s *GiftService) IsSpecialGift(giftID int64) bool {
sp := []int64{1, 3, 4, 6, 10, 25}
for _, v := range sp {
if giftID == v {
return true
}
}
return false
}
// GetGiftInfoByID 通过道具id获取道具信息
func (s *GiftService) GetGiftInfoByID(ctx context.Context, giftID int64) (gift *v1pb.GiftConfigResp_Config) {
gift = &v1pb.GiftConfigResp_Config{}
all, err := s.GetAllConfig(ctx)
if err != nil {
return
}
for _, v := range all {
if v.Id == giftID {
gift = v
return
}
}
return
}

View File

@@ -0,0 +1,268 @@
package v1
import (
"context"
v1pb "go-common/app/service/live/gift/api/grpc/v1"
"go-common/app/service/live/gift/model"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestV1getOnlinePlanGiftList(t *testing.T) {
convey.Convey("getOnlinePlanGiftList", t, func(c convey.C) {
var (
ctx = context.Background()
roomID = int64(0)
areaParentID = int64(0)
areaID = int64(0)
platform = ""
build = int64(0)
mobiApp = "android"
)
c.Convey("When everything gose positive", func(c convey.C) {
resp, err := s.GetOnlinePlanGiftList(ctx, roomID, areaParentID, areaID, platform, build, mobiApp)
c.Convey("Then err should be nil.resp should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(resp, convey.ShouldNotBeNil)
})
})
})
}
func TestV1LoadGiftCache(t *testing.T) {
convey.Convey("LoadGiftCache", t, func(c convey.C) {
var (
ctx = context.Background()
needReload bool
)
c.Convey("When everything gose positive", func(c convey.C) {
err := s.LoadGiftCache(ctx, needReload)
c.Convey("Then err should be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
})
})
})
}
func TestV1SyncLocalCache(t *testing.T) {
convey.Convey("SyncLocalCache", t, func(c convey.C) {
var (
ctx = context.Background()
)
c.Convey("When everything gose positive", func(c convey.C) {
err := s.SyncLocalCache(ctx)
c.Convey("Then err should be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
})
})
})
}
func TestV1isPrivilegeGift(t *testing.T) {
convey.Convey("isPrivilegeGift", t, func(c convey.C) {
var (
giftID = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
p1 := s.isPrivilegeGift(giftID)
c.Convey("Then p1 should not be nil.", func(c convey.C) {
c.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestV1parsePlatform(t *testing.T) {
convey.Convey("parsePlatform", t, func(c convey.C) {
pf := s.parsePlatform(0)
c.So(pf, convey.ShouldNotBeNil)
c.So(pf, convey.ShouldHaveLength, 1)
c.So(pf, convey.ShouldContain, "default")
pf = s.parsePlatform(6)
c.So(pf, convey.ShouldNotBeNil)
c.So(pf, convey.ShouldHaveLength, 2)
c.So(pf, convey.ShouldContain, "ios")
c.So(pf, convey.ShouldContain, "android")
})
}
func TestV1addDefaultPlan(t *testing.T) {
convey.Convey("addDefaultPlan", t, func(c convey.C) {
var (
plan = make(map[string]map[int64]map[int64]*model.GiftPlan)
)
c.Convey("When everything gose positive", func(c convey.C) {
s.addDefaultPlan(plan)
c.Convey("No return values", func(c convey.C) {
})
})
})
}
func TestV1ConvertGiftList(t *testing.T) {
convey.Convey("ConvertGiftList", t, func(c convey.C) {
var (
list = "1,25"
planID = int64(0)
platform = "pc"
build = int64(0)
mobiApp = "android"
)
c.Convey("When everything gose positive", func(c convey.C) {
data := s.ConvertGiftList(list, planID, platform, build, mobiApp)
c.Convey("Then data should not be nil.", func(c convey.C) {
c.So(data, convey.ShouldNotBeNil)
})
})
})
}
func TestV1CheckGiftVersion(t *testing.T) {
convey.Convey("CheckGiftVersion", t, func(c convey.C) {
var (
giftID = int64(30047)
platform = ""
build = int64(0)
mobiApp = "android"
)
c.Convey("When everything gose positive", func(c convey.C) {
p1 := s.CheckGiftVersion(giftID, platform, build, mobiApp)
c.Convey("Then p1 should not be nil.", func(c convey.C) {
c.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestV1AddPrivilegeGift(t *testing.T) {
convey.Convey("AddPrivilegeGift", t, func(c convey.C) {
var (
list = []*v1pb.RoomGiftListResp_List{}
platform = ""
build = int64(0)
mobiApp = "android"
)
c.Convey("When everything gose positive", func(c convey.C) {
p1 := s.AddPrivilegeGift(list, platform, build, mobiApp)
c.Convey("Then p1 should not be nil.", func(c convey.C) {
c.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestV1NewGiftList(t *testing.T) {
convey.Convey("NewGiftList", t, func(c convey.C) {
var (
id = int64(0)
position = int64(0)
planID = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
list := s.NewGiftList(id, position, planID)
c.Convey("Then list should not be nil.", func(c convey.C) {
c.So(list, convey.ShouldNotBeNil)
})
})
})
}
func TestV1getOldList(t *testing.T) {
convey.Convey("getOldList", t, func(c convey.C) {
c.Convey("When everything gose positive", func(c convey.C) {
old := s.getOldList()
c.Convey("Then old should not be nil.", func(c convey.C) {
c.So(old, convey.ShouldNotBeNil)
})
})
})
}
func TestV1GetAllConfig(t *testing.T) {
convey.Convey("GetAllConfig", t, func(c convey.C) {
var (
ctx = context.Background()
)
c.Convey("When everything gose positive", func(c convey.C) {
all, err := s.GetAllConfig(ctx)
c.Convey("Then err should be nil.all should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(all, convey.ShouldNotBeNil)
})
})
})
}
func TestV1ConvertDB2Config(t *testing.T) {
convey.Convey("ConvertDB2Config", t, func(c convey.C) {
var (
ol = &model.GiftOnline{}
)
c.Convey("When everything gose positive", func(c convey.C) {
res := s.ConvertDB2Config(ol)
c.Convey("Then res should not be nil.", func(c convey.C) {
c.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestV1GetStayTime(t *testing.T) {
convey.Convey("GetStayTime", t, func(c convey.C) {
var (
ol = &model.GiftOnline{}
)
c.Convey("When everything gose positive", func(c convey.C) {
time := s.GetStayTime(ol)
c.Convey("Then time should not be nil.", func(c convey.C) {
c.So(time, convey.ShouldNotBeNil)
})
})
})
}
func TestV1IsValidGift(t *testing.T) {
convey.Convey("IsValidGift", t, func(c convey.C) {
var (
giftID = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
p1 := s.IsValidGift(giftID)
c.Convey("Then p1 should not be nil.", func(c convey.C) {
c.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestV1IsSpecialGift(t *testing.T) {
convey.Convey("IsSpecialGift", t, func(c convey.C) {
var (
giftID = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
p1 := s.IsSpecialGift(giftID)
c.Convey("Then p1 should not be nil.", func(c convey.C) {
c.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestV1GetGiftInfoByID(t *testing.T) {
convey.Convey("GetGiftInfoByID", t, func(c convey.C) {
var (
ctx = context.Background()
giftID = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
gift := s.GetGiftInfoByID(ctx, giftID)
c.Convey("Then gift should not be nil.", func(c convey.C) {
c.So(gift, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,93 @@
package v1
import (
"context"
"errors"
"go-common/app/service/live/gift/model"
"go-common/library/log"
"go-common/library/sync/errgroup"
)
// AddGift 发送免费道具
func (s *GiftService) AddGift(ctx context.Context, uid int64, giftID, giftNum, expireAt int64, source string) (bagId int64, err error) {
if uid == 0 || giftID == 0 || giftNum == 0 {
log.Error("add gift params error,uid:%d,giftID:%d,giftNum:%d", uid, giftID, giftNum)
err = errors.New("params error")
return
}
bagID, err := s.GetBagID(ctx, uid, giftID, expireAt)
if err != nil {
return
}
var (
affectNum int64
isUpdate = false
eg, _ = errgroup.WithContext(ctx)
)
if bagID != 0 {
isUpdate = true
affectNum, _ = s.dao.UpdateBagNum(ctx, uid, bagID, giftNum)
} else {
affectNum, _ = s.dao.AddBag(ctx, uid, giftID, giftNum, expireAt)
bagID = affectNum
eg.Go(
func() error {
s.dao.SetBagIDCache(ctx, uid, giftID, expireAt, bagID, 14400)
return nil
})
}
newNum := giftNum
if affectNum > 0 {
eg.Go(
func() error {
s.dao.ClearBagListCache(ctx, uid)
return nil
})
if isUpdate {
res, _ := s.dao.GetBagByID(ctx, uid, bagID)
newNum = res.GiftNum
//上报lancer TODO
s.bagLogInfoc(uid, bagID, giftID, giftNum, newNum, source)
}
}
// 更新免费礼物数量缓存
eg.Go(
func() error {
s.UpdateFreeGiftCache(ctx, uid, giftID, expireAt, newNum)
return nil
})
eg.Wait()
return
}
// GetBagID 获取包裹id
func (s *GiftService) GetBagID(ctx context.Context, uid, giftID, expireAt int64) (id int64, err error) {
id, err = s.dao.GetBagIDCache(ctx, uid, giftID, expireAt)
if err != nil {
return
}
if id == 0 {
//queryDB
var r *model.BagInfo
r, err = s.dao.GetBag(ctx, uid, giftID, expireAt)
if err != nil {
return
}
id = r.ID
}
// 缓存或数据库本身有,再更新缓存
if id != 0 {
s.dao.SetBagIDCache(ctx, uid, giftID, expireAt, id, 14400)
}
return
}
// UpdateFreeGiftCache UpdateFreeGiftCache
func (s *GiftService) UpdateFreeGiftCache(ctx context.Context, uid, giftID, expireAt, num int64) {
giftInfo := s.GetGiftInfoByID(ctx, giftID)
if giftInfo.Id == 0 || giftInfo.Type != 3 {
return
}
s.dao.SetBagNumCache(ctx, uid, giftID, expireAt, num, 14400)
}

View File

@@ -0,0 +1,63 @@
package v1
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestV1AddGift(t *testing.T) {
convey.Convey("AddGift", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(9527)
giftID = int64(1)
giftNum = int64(1)
expireAt = int64(0)
source = "go unit test"
)
c.Convey("When everything gose positive", func(c convey.C) {
bagId, err := s.AddGift(ctx, uid, giftID, giftNum, expireAt, source)
c.Convey("Then err should be nil.bagId should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(bagId, convey.ShouldNotBeNil)
})
})
})
}
func TestV1GetBagID(t *testing.T) {
convey.Convey("GetBagID", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(0)
giftID = int64(0)
expireAt = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
id, err := s.GetBagID(ctx, uid, giftID, expireAt)
c.Convey("Then err should be nil.id should not be nil.", func(c convey.C) {
c.So(err, convey.ShouldBeNil)
c.So(id, convey.ShouldNotBeNil)
})
})
})
}
func TestV1UpdateFreeGiftCache(t *testing.T) {
convey.Convey("UpdateFreeGiftCache", t, func(c convey.C) {
var (
ctx = context.Background()
uid = int64(0)
giftID = int64(0)
expireAt = int64(0)
num = int64(0)
)
c.Convey("When everything gose positive", func(c convey.C) {
s.UpdateFreeGiftCache(ctx, uid, giftID, expireAt, num)
c.Convey("No return values", func(c convey.C) {
})
})
})
}