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,23 @@
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/service/live/xanchor/api/grpc/v1:all-srcs",
"//app/service/live/xanchor/cmd:all-srcs",
"//app/service/live/xanchor/conf:all-srcs",
"//app/service/live/xanchor/dao:all-srcs",
"//app/service/live/xanchor/model:all-srcs",
"//app/service/live/xanchor/server/grpc:all-srcs",
"//app/service/live/xanchor/server/http:all-srcs",
"//app/service/live/xanchor/service:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

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

View File

@@ -0,0 +1,14 @@
# Owner
zhaohailin
wangyao
zhangwei01
# Author
zhaohailin
wangyao
zhangwei01
# Reviewer
zhaohailin
wangyao
zhangwei01

View File

@@ -0,0 +1,16 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- wangyao
- zhangwei01
- zhaohailin
labels:
- live
- service
- service/live/xanchor
options:
no_parent_owners: true
reviewers:
- wangyao
- zhangwei01
- zhaohailin

View File

@@ -0,0 +1,12 @@
# xanchor-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/xanchor/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/xanchor/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,277 @@
// Code generated by protoc-gen-bm v0.1, DO NOT EDIT.
// source: api/grpc/v1/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/grpc/v1/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
// =================
// XAnchor Interface
// =================
type XAnchor interface {
// FetchRoomByIDs 查询房间信息
FetchRoomByIDs(ctx context.Context, req *RoomByIDsReq) (resp *RoomByIDsResp, err error)
// RoomOnlineList 在线房间列表
RoomOnlineList(ctx context.Context, req *RoomOnlineListReq) (resp *RoomOnlineListResp, err error)
// RoomCreate 房间创建
RoomCreate(ctx context.Context, req *RoomCreateReq) (resp *RoomCreateResp, err error)
// RoomUpdate 房间信息更新
RoomUpdate(ctx context.Context, req *RoomUpdateReq) (resp *UpdateResp, err error)
// RoomBatchUpdate 房间信息批量更新
RoomBatchUpdate(ctx context.Context, req *RoomBatchUpdateReq) (resp *UpdateResp, err error)
// RoomExtendUpdate 房间扩展信息更新
RoomExtendUpdate(ctx context.Context, req *RoomExtendUpdateReq) (resp *UpdateResp, err error)
// RoomExtendBatchUpdate 房间扩展信息批量更新
RoomExtendBatchUpdate(ctx context.Context, req *RoomExtendBatchUpdateReq) (resp *UpdateResp, err error)
// RoomExtendIncre 房间信息增量更新
RoomExtendIncre(ctx context.Context, req *RoomExtendIncreReq) (resp *UpdateResp, err error)
// RoomExtendBatchIncre 房间信息批量增量更新
RoomExtendBatchIncre(ctx context.Context, req *RoomExtendBatchIncreReq) (resp *UpdateResp, err error)
// RoomTagSet 房间Tag更新
RoomTagSet(ctx context.Context, req *RoomTagSetReq) (resp *UpdateResp, err error)
// AnchorUpdate 主播信息更新
AnchorUpdate(ctx context.Context, req *AnchorUpdateReq) (resp *UpdateResp, err error)
// AnchorBatchUpdate 主播信息批量更新
AnchorBatchUpdate(ctx context.Context, req *AnchorBatchUpdateReq) (resp *UpdateResp, err error)
// AnchorIncre 主播信息增量更新
AnchorIncre(ctx context.Context, req *AnchorIncreReq) (resp *UpdateResp, err error)
// AnchorBatchIncre 主播信息批量增量更新
AnchorBatchIncre(ctx context.Context, req *AnchorBatchIncreReq) (resp *UpdateResp, err error)
// AnchorTagSet 主播Tag更新
AnchorTagSet(ctx context.Context, req *AnchorTagSetReq) (resp *UpdateResp, err error)
}
var v1XAnchorSvc XAnchor
// @params RoomByIDsReq
// @router GET /xlive/xanchor/v1/xAnchor/FetchRoomByIDs
// @response RoomByIDsResp
func xAnchorFetchRoomByIDs(c *bm.Context) {
p := new(RoomByIDsReq)
if err := c.BindWith(p, binding.Default(c.Request.Method, c.Request.Header.Get("Content-Type"))); err != nil {
return
}
resp, err := v1XAnchorSvc.FetchRoomByIDs(c, p)
c.JSON(resp, err)
}
// @params RoomOnlineListReq
// @router GET /xlive/xanchor/v1/xAnchor/RoomOnlineList
// @response RoomOnlineListResp
func xAnchorRoomOnlineList(c *bm.Context) {
p := new(RoomOnlineListReq)
if err := c.BindWith(p, binding.Default(c.Request.Method, c.Request.Header.Get("Content-Type"))); err != nil {
return
}
resp, err := v1XAnchorSvc.RoomOnlineList(c, p)
c.JSON(resp, err)
}
// @params RoomCreateReq
// @router GET /xlive/xanchor/v1/xAnchor/RoomCreate
// @response RoomCreateResp
func xAnchorRoomCreate(c *bm.Context) {
p := new(RoomCreateReq)
if err := c.BindWith(p, binding.Default(c.Request.Method, c.Request.Header.Get("Content-Type"))); err != nil {
return
}
resp, err := v1XAnchorSvc.RoomCreate(c, p)
c.JSON(resp, err)
}
// @params RoomUpdateReq
// @router GET /xlive/xanchor/v1/xAnchor/RoomUpdate
// @response UpdateResp
func xAnchorRoomUpdate(c *bm.Context) {
p := new(RoomUpdateReq)
if err := c.BindWith(p, binding.Default(c.Request.Method, c.Request.Header.Get("Content-Type"))); err != nil {
return
}
resp, err := v1XAnchorSvc.RoomUpdate(c, p)
c.JSON(resp, err)
}
// @params RoomBatchUpdateReq
// @router GET /xlive/xanchor/v1/xAnchor/RoomBatchUpdate
// @response UpdateResp
func xAnchorRoomBatchUpdate(c *bm.Context) {
p := new(RoomBatchUpdateReq)
if err := c.BindWith(p, binding.Default(c.Request.Method, c.Request.Header.Get("Content-Type"))); err != nil {
return
}
resp, err := v1XAnchorSvc.RoomBatchUpdate(c, p)
c.JSON(resp, err)
}
// @params RoomExtendUpdateReq
// @router GET /xlive/xanchor/v1/xAnchor/RoomExtendUpdate
// @response UpdateResp
func xAnchorRoomExtendUpdate(c *bm.Context) {
p := new(RoomExtendUpdateReq)
if err := c.BindWith(p, binding.Default(c.Request.Method, c.Request.Header.Get("Content-Type"))); err != nil {
return
}
resp, err := v1XAnchorSvc.RoomExtendUpdate(c, p)
c.JSON(resp, err)
}
// @params RoomExtendBatchUpdateReq
// @router GET /xlive/xanchor/v1/xAnchor/RoomExtendBatchUpdate
// @response UpdateResp
func xAnchorRoomExtendBatchUpdate(c *bm.Context) {
p := new(RoomExtendBatchUpdateReq)
if err := c.BindWith(p, binding.Default(c.Request.Method, c.Request.Header.Get("Content-Type"))); err != nil {
return
}
resp, err := v1XAnchorSvc.RoomExtendBatchUpdate(c, p)
c.JSON(resp, err)
}
// @params RoomExtendIncreReq
// @router GET /xlive/xanchor/v1/xAnchor/RoomExtendIncre
// @response UpdateResp
func xAnchorRoomExtendIncre(c *bm.Context) {
p := new(RoomExtendIncreReq)
if err := c.BindWith(p, binding.Default(c.Request.Method, c.Request.Header.Get("Content-Type"))); err != nil {
return
}
resp, err := v1XAnchorSvc.RoomExtendIncre(c, p)
c.JSON(resp, err)
}
// @params RoomExtendBatchIncreReq
// @router GET /xlive/xanchor/v1/xAnchor/RoomExtendBatchIncre
// @response UpdateResp
func xAnchorRoomExtendBatchIncre(c *bm.Context) {
p := new(RoomExtendBatchIncreReq)
if err := c.BindWith(p, binding.Default(c.Request.Method, c.Request.Header.Get("Content-Type"))); err != nil {
return
}
resp, err := v1XAnchorSvc.RoomExtendBatchIncre(c, p)
c.JSON(resp, err)
}
// @params RoomTagSetReq
// @router GET /xlive/xanchor/v1/xAnchor/RoomTagSet
// @response UpdateResp
func xAnchorRoomTagSet(c *bm.Context) {
p := new(RoomTagSetReq)
if err := c.BindWith(p, binding.Default(c.Request.Method, c.Request.Header.Get("Content-Type"))); err != nil {
return
}
resp, err := v1XAnchorSvc.RoomTagSet(c, p)
c.JSON(resp, err)
}
// @params AnchorUpdateReq
// @router GET /xlive/xanchor/v1/xAnchor/AnchorUpdate
// @response UpdateResp
func xAnchorAnchorUpdate(c *bm.Context) {
p := new(AnchorUpdateReq)
if err := c.BindWith(p, binding.Default(c.Request.Method, c.Request.Header.Get("Content-Type"))); err != nil {
return
}
resp, err := v1XAnchorSvc.AnchorUpdate(c, p)
c.JSON(resp, err)
}
// @params AnchorBatchUpdateReq
// @router GET /xlive/xanchor/v1/xAnchor/AnchorBatchUpdate
// @response UpdateResp
func xAnchorAnchorBatchUpdate(c *bm.Context) {
p := new(AnchorBatchUpdateReq)
if err := c.BindWith(p, binding.Default(c.Request.Method, c.Request.Header.Get("Content-Type"))); err != nil {
return
}
resp, err := v1XAnchorSvc.AnchorBatchUpdate(c, p)
c.JSON(resp, err)
}
// @params AnchorIncreReq
// @router GET /xlive/xanchor/v1/xAnchor/AnchorIncre
// @response UpdateResp
func xAnchorAnchorIncre(c *bm.Context) {
p := new(AnchorIncreReq)
if err := c.BindWith(p, binding.Default(c.Request.Method, c.Request.Header.Get("Content-Type"))); err != nil {
return
}
resp, err := v1XAnchorSvc.AnchorIncre(c, p)
c.JSON(resp, err)
}
// @params AnchorBatchIncreReq
// @router GET /xlive/xanchor/v1/xAnchor/AnchorBatchIncre
// @response UpdateResp
func xAnchorAnchorBatchIncre(c *bm.Context) {
p := new(AnchorBatchIncreReq)
if err := c.BindWith(p, binding.Default(c.Request.Method, c.Request.Header.Get("Content-Type"))); err != nil {
return
}
resp, err := v1XAnchorSvc.AnchorBatchIncre(c, p)
c.JSON(resp, err)
}
// @params AnchorTagSetReq
// @router GET /xlive/xanchor/v1/xAnchor/AnchorTagSet
// @response UpdateResp
func xAnchorAnchorTagSet(c *bm.Context) {
p := new(AnchorTagSetReq)
if err := c.BindWith(p, binding.Default(c.Request.Method, c.Request.Header.Get("Content-Type"))); err != nil {
return
}
resp, err := v1XAnchorSvc.AnchorTagSet(c, p)
c.JSON(resp, err)
}
// RegisterV1XAnchorService Register the blademaster route with middleware map
// midMap is the middleware map, the key is defined in proto
func RegisterV1XAnchorService(e *bm.Engine, svc XAnchor, midMap map[string]bm.HandlerFunc) {
v1XAnchorSvc = svc
e.GET("/xlive/xanchor/v1/xAnchor/FetchRoomByIDs", xAnchorFetchRoomByIDs)
e.GET("/xlive/xanchor/v1/xAnchor/RoomOnlineList", xAnchorRoomOnlineList)
e.GET("/xlive/xanchor/v1/xAnchor/RoomCreate", xAnchorRoomCreate)
e.GET("/xlive/xanchor/v1/xAnchor/RoomUpdate", xAnchorRoomUpdate)
e.GET("/xlive/xanchor/v1/xAnchor/RoomBatchUpdate", xAnchorRoomBatchUpdate)
e.GET("/xlive/xanchor/v1/xAnchor/RoomExtendUpdate", xAnchorRoomExtendUpdate)
e.GET("/xlive/xanchor/v1/xAnchor/RoomExtendBatchUpdate", xAnchorRoomExtendBatchUpdate)
e.GET("/xlive/xanchor/v1/xAnchor/RoomExtendIncre", xAnchorRoomExtendIncre)
e.GET("/xlive/xanchor/v1/xAnchor/RoomExtendBatchIncre", xAnchorRoomExtendBatchIncre)
e.GET("/xlive/xanchor/v1/xAnchor/RoomTagSet", xAnchorRoomTagSet)
e.GET("/xlive/xanchor/v1/xAnchor/AnchorUpdate", xAnchorAnchorUpdate)
e.GET("/xlive/xanchor/v1/xAnchor/AnchorBatchUpdate", xAnchorAnchorBatchUpdate)
e.GET("/xlive/xanchor/v1/xAnchor/AnchorIncre", xAnchorAnchorIncre)
e.GET("/xlive/xanchor/v1/xAnchor/AnchorBatchIncre", xAnchorAnchorBatchIncre)
e.GET("/xlive/xanchor/v1/xAnchor/AnchorTagSet", xAnchorAnchorTagSet)
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,231 @@
syntax = "proto3";
package live.xanchor.v1;
option go_package = "v1";
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
message ExpData {
int64 level = 1 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
int64 next_level = 2 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
int64 level_color = 3 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
int64 exp = 4 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
int64 current_level_exp = 5 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
int64 next_level_exp = 6 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
}
message TagData {
int64 tag_id = 1 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
int64 tag_type = 2 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
int64 tag_value = 3 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
string tag_attribute = 4 [(gogoproto.moretags) = "validate:\"required\""];
}
message RoomData {
int64 uid = 1 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
int64 room_id = 2 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
int64 short_id = 3 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
string title = 4 [(gogoproto.moretags) = "validate:\"required\""];
string cover = 5;
string tags = 6;
string background = 7;
string description = 8;
int64 live_status = 9 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
int64 live_start_time = 10 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
int64 live_screen_type = 11 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
int64 live_mark = 12;
int64 lock_status = 13;
int64 lock_time = 14;
int64 hidden_status = 15 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
int64 hidden_time = 16;
int64 area_id = 17 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
string area_name = 18 [(gogoproto.moretags) = "validate:\"required\""];
int64 parent_area_id = 19 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
string parent_area_name = 20 [(gogoproto.moretags) = "validate:\"required\""];
string keyframe = 21;
int64 popularity_count = 22;
repeated TagData room_tag_list = 23;
repeated TagData anchor_tag_list = 24;
int64 anchor_profile_type = 25;
repeated ExpData anchor_exp = 26;
int64 anchor_round_switch = 27;
int64 anchor_round_status = 28;
int64 anchor_record_switch = 29;
int64 anchor_record_status = 30;
int64 anchor_san = 31;
int64 live_type = 32;
}
message RoomByIDsReq {
repeated int64 room_ids = 1;
repeated int64 uids = 2;
repeated string fields = 3;
int64 default_fields = 4;
}
message RoomByIDsResp {
map<int64, RoomData> room_data_set = 1;
}
message RoomOnlineListReq {
string filter = 1;
string sort = 2;
int64 page = 3;
int64 page_size = 4;
repeated string fields = 5;
}
message RoomOnlineListResp {
map<int64, RoomData> room_data_list = 1;
}
message RoomCreateReq {
int64 uid = 1 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
int64 room_id = 2;
}
message RoomCreateResp {
int64 room_id = 1;
}
message UpdateResp {
int64 affected_rows = 1;
}
message RoomUpdateReq {
repeated string fields = 1 [(gogoproto.moretags) = "validate:\"required\""];
int64 room_id = 2 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
string title = 3;
string cover = 4;
string tags = 5;
string background = 6;
string description = 7;
int64 live_start_time = 8;
int64 live_screen_type = 9;
int64 lock_status = 10;
int64 lock_time = 11;
int64 hidden_time = 12;
int64 area_id = 13;
int64 anchor_round_switch = 14;
int64 anchor_record_switch = 15;
int64 live_type = 16;
}
message RoomBatchUpdateReq {
repeated RoomUpdateReq reqs = 1 [(gogoproto.moretags) = "validate:\"required\""];
}
message AnchorData {
int64 uid = 1 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
int64 profile_type = 2 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
repeated ExpData exp = 3 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
}
message AnchorUpdateReq {
repeated string fields = 1 [(gogoproto.moretags) = "validate:\"required\""];
int64 uid = 2 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
int64 profile_type = 3;
int64 san_score = 4;
int64 round_status = 5;
int64 record_status = 6;
int64 exp = 7;
}
message AnchorBatchUpdateReq {
repeated AnchorUpdateReq reqs = 1 [(gogoproto.moretags) = "validate:\"required\""];
}
message AnchorIncreReq {
string req_id = 1 [(gogoproto.moretags) = "validate:\"required\""];
repeated string fields = 2 [(gogoproto.moretags) = "validate:\"required\""];
int64 uid = 3 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
int64 san_score = 4;
int64 exp = 5;
}
message AnchorBatchIncreReq {
repeated AnchorIncreReq reqs = 1 [(gogoproto.moretags) = "validate:\"required\""];
}
message RoomExtendUpdateReq {
repeated string fields = 1 [(gogoproto.moretags) = "validate:\"required\""];
int64 room_id = 2 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
string key_frame = 3;
int64 danmu_count = 4;
int64 popularity_count = 5;
int64 audience_count = 6;
int64 gift_count = 7;
int64 gift_gold_amount = 8;
int64 gift_gold_count = 9;
}
message RoomExtendBatchUpdateReq {
repeated RoomExtendUpdateReq reqs = 1 [(gogoproto.moretags) = "validate:\"required\""];
}
message RoomExtendIncreReq {
string req_id = 1 [(gogoproto.moretags) = "validate:\"required\""];
repeated string fields = 2 [(gogoproto.moretags) = "validate:\"required\""];
int64 room_id = 3 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
int64 danmu_count = 4;
int64 popularity_count = 5;
int64 audience_count = 6;
int64 gift_count = 7;
int64 gift_gold_amount = 8;
int64 gift_gold_count = 9;
}
message RoomExtendBatchIncreReq {
repeated RoomExtendIncreReq reqs = 1 [(gogoproto.moretags) = "validate:\"required\""];
}
message RoomTagSetReq {
repeated string fields = 1 [(gogoproto.moretags) = "validate:\"required\""];
int64 room_id = 2 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
int64 tag_type = 3 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
int64 tag_value = 4;
string tag_attribute = 5;
int64 tag_expire_at = 6;
}
message AnchorTagSetReq {
repeated string fields = 1 [(gogoproto.moretags) = "validate:\"required\""];
int64 anchor_id = 2 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
int64 tag_type = 3 [(gogoproto.moretags) = "validate:\"gt=0,required\""];
int64 tag_value = 4;
string tag_attribute = 5;
int64 tag_expire_at = 6;
}
service XAnchor {
// FetchRoomByIDs 查询房间信息
rpc FetchRoomByIDs(RoomByIDsReq) returns (RoomByIDsResp);
// RoomOnlineList 在线房间列表
rpc RoomOnlineList(RoomOnlineListReq) returns (RoomOnlineListResp);
// RoomCreate 房间创建
rpc RoomCreate(RoomCreateReq) returns (RoomCreateResp);
// RoomUpdate 房间信息更新
rpc RoomUpdate(RoomUpdateReq) returns (UpdateResp);
// RoomBatchUpdate 房间信息批量更新
rpc RoomBatchUpdate(RoomBatchUpdateReq) returns (UpdateResp);
// RoomExtendUpdate 房间扩展信息更新
rpc RoomExtendUpdate(RoomExtendUpdateReq) returns (UpdateResp);
// RoomExtendBatchUpdate 房间扩展信息批量更新
rpc RoomExtendBatchUpdate(RoomExtendBatchUpdateReq) returns (UpdateResp);
// RoomExtendIncre 房间信息增量更新
rpc RoomExtendIncre(RoomExtendIncreReq) returns (UpdateResp);
// RoomExtendBatchIncre 房间信息批量增量更新
rpc RoomExtendBatchIncre(RoomExtendBatchIncreReq) returns (UpdateResp);
// RoomTagSet 房间Tag更新
rpc RoomTagSet(RoomTagSetReq) returns (UpdateResp);
// AnchorUpdate 主播信息更新
rpc AnchorUpdate(AnchorUpdateReq) returns (UpdateResp);
// AnchorBatchUpdate 主播信息批量更新
rpc AnchorBatchUpdate(AnchorBatchUpdateReq) returns (UpdateResp);
// AnchorIncre 主播信息增量更新
rpc AnchorIncre(AnchorIncreReq) returns (UpdateResp);
// AnchorBatchIncre 主播信息批量增量更新
rpc AnchorBatchIncre(AnchorBatchIncreReq) returns (UpdateResp);
// AnchorTagSet 主播Tag更新
rpc AnchorTagSet(AnchorTagSetReq) returns (UpdateResp);
}

View File

@@ -0,0 +1,556 @@
## FetchRoomByIDs 查询房间信息
`GET http://api.live.bilibili.com/xlive/xanchor/v1/xAnchor/FetchRoomByIDs`
### 请求参数
|参数名|必选|类型|描述|
|:---|:---|:---|:---|
|room_ids|否|多个integer||
|uids|否|多个integer||
|fields|否|多个string||
|default_fields|否|integer||
```json
{
"code": 0,
"message": "ok",
"data": {
"room_data_set": {
"1": {
"uid": 0,
"room_id": 0,
"short_id": 0,
"title": "",
"cover": "",
"tags": "",
"background": "",
"description": "",
"live_status": 0,
"live_start_time": 0,
"live_screen_type": 0,
"live_mark": 0,
"lock_status": 0,
"lock_time": 0,
"hidden_status": 0,
"hidden_time": 0,
"area_id": 0,
"area_name": "",
"parent_area_id": 0,
"parent_area_name": "",
"keyframe": "",
"popularity_count": 0,
"room_tag_list": [
{
"tag_id": 0,
"tag_type": 0,
"tag_value": 0,
"tag_attribute": ""
}
],
"anchor_tag_list": [
{
"tag_id": 0,
"tag_type": 0,
"tag_value": 0,
"tag_attribute": ""
}
],
"anchor_profile_type": 0,
"anchor_exp": [
{
"level": 0,
"next_level": 0,
"level_color": 0,
"exp": 0,
"current_level_exp": 0,
"next_level_exp": 0
}
],
"anchor_round_switch": 0,
"anchor_round_status": 0,
"anchor_record_switch": 0,
"anchor_record_status": 0,
"anchor_san": 0,
"live_type": 0
}
}
}
}
```
## RoomOnlineList 在线房间列表
`GET http://api.live.bilibili.com/xlive/xanchor/v1/xAnchor/RoomOnlineList`
### 请求参数
|参数名|必选|类型|描述|
|:---|:---|:---|:---|
|filter|否|string||
|sort|否|string||
|page|否|integer||
|page_size|否|integer||
|fields|否|多个string||
```json
{
"code": 0,
"message": "ok",
"data": {
"room_data_list": {
"1": {
"uid": 0,
"room_id": 0,
"short_id": 0,
"title": "",
"cover": "",
"tags": "",
"background": "",
"description": "",
"live_status": 0,
"live_start_time": 0,
"live_screen_type": 0,
"live_mark": 0,
"lock_status": 0,
"lock_time": 0,
"hidden_status": 0,
"hidden_time": 0,
"area_id": 0,
"area_name": "",
"parent_area_id": 0,
"parent_area_name": "",
"keyframe": "",
"popularity_count": 0,
"room_tag_list": [
{
"tag_id": 0,
"tag_type": 0,
"tag_value": 0,
"tag_attribute": ""
}
],
"anchor_tag_list": [
{
"tag_id": 0,
"tag_type": 0,
"tag_value": 0,
"tag_attribute": ""
}
],
"anchor_profile_type": 0,
"anchor_exp": [
{
"level": 0,
"next_level": 0,
"level_color": 0,
"exp": 0,
"current_level_exp": 0,
"next_level_exp": 0
}
],
"anchor_round_switch": 0,
"anchor_round_status": 0,
"anchor_record_switch": 0,
"anchor_record_status": 0,
"anchor_san": 0,
"live_type": 0
}
}
}
}
```
## RoomCreate 房间创建
`GET http://api.live.bilibili.com/xlive/xanchor/v1/xAnchor/RoomCreate`
### 请求参数
|参数名|必选|类型|描述|
|:---|:---|:---|:---|
|uid|是|integer||
|room_id|否|integer||
```json
{
"code": 0,
"message": "ok",
"data": {
"room_id": 0
}
}
```
## RoomUpdate 房间信息更新
`GET http://api.live.bilibili.com/xlive/xanchor/v1/xAnchor/RoomUpdate`
### 请求参数
|参数名|必选|类型|描述|
|:---|:---|:---|:---|
|fields|是|多个string||
|room_id|是|integer||
|title|否|string||
|cover|否|string||
|tags|否|string||
|background|否|string||
|description|否|string||
|live_start_time|否|integer||
|live_screen_type|否|integer||
|lock_status|否|integer||
|lock_time|否|integer||
|hidden_time|否|integer||
|area_id|否|integer||
|anchor_round_switch|否|integer||
|anchor_record_switch|否|integer||
|live_type|否|integer||
```json
{
"code": 0,
"message": "ok",
"data": {
"affected_rows": 0
}
}
```
## RoomBatchUpdate 房间信息批量更新
`GET http://api.live.bilibili.com/xlive/xanchor/v1/xAnchor/RoomBatchUpdate`
### 请求参数
```json
{
"reqs": [
{
"fields": [
""
],
"room_id": 0,
"title": "",
"cover": "",
"tags": "",
"background": "",
"description": "",
"live_start_time": 0,
"live_screen_type": 0,
"lock_status": 0,
"lock_time": 0,
"hidden_time": 0,
"area_id": 0,
"anchor_round_switch": 0,
"anchor_record_switch": 0,
"live_type": 0
}
]
}
```
```json
{
"code": 0,
"message": "ok",
"data": {
"affected_rows": 0
}
}
```
## RoomExtendUpdate 房间扩展信息更新
`GET http://api.live.bilibili.com/xlive/xanchor/v1/xAnchor/RoomExtendUpdate`
### 请求参数
|参数名|必选|类型|描述|
|:---|:---|:---|:---|
|fields|是|多个string||
|room_id|是|integer||
|key_frame|否|string||
|danmu_count|否|integer||
|popularity_count|否|integer||
|audience_count|否|integer||
|gift_count|否|integer||
|gift_gold_amount|否|integer||
|gift_gold_count|否|integer||
```json
{
"code": 0,
"message": "ok",
"data": {
"affected_rows": 0
}
}
```
## RoomExtendBatchUpdate 房间扩展信息批量更新
`GET http://api.live.bilibili.com/xlive/xanchor/v1/xAnchor/RoomExtendBatchUpdate`
### 请求参数
```json
{
"reqs": [
{
"fields": [
""
],
"room_id": 0,
"key_frame": "",
"danmu_count": 0,
"popularity_count": 0,
"audience_count": 0,
"gift_count": 0,
"gift_gold_amount": 0,
"gift_gold_count": 0
}
]
}
```
```json
{
"code": 0,
"message": "ok",
"data": {
"affected_rows": 0
}
}
```
## RoomExtendIncre 房间信息增量更新
`GET http://api.live.bilibili.com/xlive/xanchor/v1/xAnchor/RoomExtendIncre`
### 请求参数
|参数名|必选|类型|描述|
|:---|:---|:---|:---|
|req_id|是|string||
|fields|是|多个string||
|room_id|是|integer||
|danmu_count|否|integer||
|popularity_count|否|integer||
|audience_count|否|integer||
|gift_count|否|integer||
|gift_gold_amount|否|integer||
|gift_gold_count|否|integer||
```json
{
"code": 0,
"message": "ok",
"data": {
"affected_rows": 0
}
}
```
## RoomExtendBatchIncre 房间信息批量增量更新
`GET http://api.live.bilibili.com/xlive/xanchor/v1/xAnchor/RoomExtendBatchIncre`
### 请求参数
```json
{
"reqs": [
{
"req_id": "",
"fields": [
""
],
"room_id": 0,
"danmu_count": 0,
"popularity_count": 0,
"audience_count": 0,
"gift_count": 0,
"gift_gold_amount": 0,
"gift_gold_count": 0
}
]
}
```
```json
{
"code": 0,
"message": "ok",
"data": {
"affected_rows": 0
}
}
```
## RoomTagSet 房间Tag更新
`GET http://api.live.bilibili.com/xlive/xanchor/v1/xAnchor/RoomTagSet`
### 请求参数
|参数名|必选|类型|描述|
|:---|:---|:---|:---|
|fields|是|多个string||
|room_id|是|integer||
|tag_type|是|integer||
|tag_value|否|integer||
|tag_attribute|否|string||
|tag_expire_at|否|integer||
```json
{
"code": 0,
"message": "ok",
"data": {
"affected_rows": 0
}
}
```
## AnchorUpdate 主播信息更新
`GET http://api.live.bilibili.com/xlive/xanchor/v1/xAnchor/AnchorUpdate`
### 请求参数
|参数名|必选|类型|描述|
|:---|:---|:---|:---|
|fields|是|多个string||
|uid|是|integer||
|profile_type|否|integer||
|san_score|否|integer||
|round_status|否|integer||
|record_status|否|integer||
|exp|否|integer||
```json
{
"code": 0,
"message": "ok",
"data": {
"affected_rows": 0
}
}
```
## AnchorBatchUpdate 主播信息批量更新
`GET http://api.live.bilibili.com/xlive/xanchor/v1/xAnchor/AnchorBatchUpdate`
### 请求参数
```json
{
"reqs": [
{
"fields": [
""
],
"uid": 0,
"profile_type": 0,
"san_score": 0,
"round_status": 0,
"record_status": 0,
"exp": 0
}
]
}
```
```json
{
"code": 0,
"message": "ok",
"data": {
"affected_rows": 0
}
}
```
## AnchorIncre 主播信息增量更新
`GET http://api.live.bilibili.com/xlive/xanchor/v1/xAnchor/AnchorIncre`
### 请求参数
|参数名|必选|类型|描述|
|:---|:---|:---|:---|
|req_id|是|string||
|fields|是|多个string||
|uid|是|integer||
|san_score|否|integer||
|exp|否|integer||
```json
{
"code": 0,
"message": "ok",
"data": {
"affected_rows": 0
}
}
```
## AnchorBatchIncre 主播信息批量增量更新
`GET http://api.live.bilibili.com/xlive/xanchor/v1/xAnchor/AnchorBatchIncre`
### 请求参数
```json
{
"reqs": [
{
"req_id": "",
"fields": [
""
],
"uid": 0,
"san_score": 0,
"exp": 0
}
]
}
```
```json
{
"code": 0,
"message": "ok",
"data": {
"affected_rows": 0
}
}
```
## AnchorTagSet 主播Tag更新
`GET http://api.live.bilibili.com/xlive/xanchor/v1/xAnchor/AnchorTagSet`
### 请求参数
|参数名|必选|类型|描述|
|:---|:---|:---|:---|
|fields|是|多个string||
|anchor_id|是|integer||
|tag_type|是|integer||
|tag_value|否|integer||
|tag_attribute|否|string||
|tag_expire_at|否|integer||
```json
{
"code": 0,
"message": "ok",
"data": {
"affected_rows": 0
}
}
```

View File

@@ -0,0 +1,27 @@
package v1
import (
"context"
"google.golang.org/grpc"
"go-common/library/net/rpc/warden"
)
const AppID = "live.xanchor"
type Client struct {
XAnchorClient
}
// NewClient new anchor grpc client
func NewClient(cfg *warden.ClientConfig, opts ...grpc.DialOption) (*Client, error) {
client := warden.NewClient(cfg, opts...)
conn, err := client.Dial(context.Background(), "discovery://default/"+AppID)
if err != nil {
return nil, err
}
cli := &Client{}
cli.XAnchorClient = NewXAnchorClient(conn)
return cli, nil
}

View File

@@ -0,0 +1,45 @@
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/xanchor/cmd",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/live/xanchor/conf:go_default_library",
"//app/service/live/xanchor/server/grpc:go_default_library",
"//app/service/live/xanchor/server/http:go_default_library",
"//app/service/live/xanchor/service: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"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,60 @@
package main
import (
"context"
"flag"
"fmt"
"os"
"os/signal"
"syscall"
"time"
"go-common/app/service/live/xanchor/conf"
"go-common/app/service/live/xanchor/server/grpc"
"go-common/app/service/live/xanchor/server/http"
"go-common/app/service/live/xanchor/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("xanchor-service start")
trace.Init(conf.Conf.Tracer)
defer trace.Close()
ecode.Init(conf.Conf.Ecode)
svc := service.New(conf.Conf)
http.Init(conf.Conf)
// start grpc server
svr, err := grpc.New(svc)
if err != nil {
panic(fmt.Sprintf("start xanchor grpc server fail! %s", err))
}
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()
if svr != nil {
svr.Shutdown(context.Background())
}
log.Info("xanchor-service exit")
time.Sleep(time.Second)
return
case syscall.SIGHUP:
default:
return
}
}
}

View File

@@ -0,0 +1,66 @@
[mysql]
addr = "127.0.0.1:3306"
dsn = "test:test@tcp(127.0.0.1:3306)/test?timeout=200ms&readTimeout=200ms&writeTimeout=200ms&parseTime=true&loc=Local&charset=utf8,utf8mb4"
readDSN = ["test:test@tcp(127.0.0.2:3306)/test? timeout=200ms&readTimeout=200ms&writeTimeout=200ms&parseTime=true&loc=Local&charset=utf8,utf8mb4","test:test@tcp(127.0.0.3:3306)/test?timeout=200ms&readTimeout=200ms&writeTimeout=200ms&parseTime=true&loc=Local&charset=utf8,utf8mb4"]
active = 20
idle = 10
idleTimeout ="4h"
queryTimeout = "100ms"
execTimeout = "100ms"
tranTimeout = "200ms"
[redis]
name = "xanchor-service"
proto = "tcp"
addr = ""
idle = 10
active = 10
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "10s"
expire = "1m"
[memcache]
name = "xanchor-service"
proto = "tcp"
addr = ""
active = 50
idle = 10
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "10s"
expire = "24h"
[liveDanmuSub]
key = "ec4c0820d525d67b"
secret = "e20f8f664bf10722efeb6aac0cc16011"
group = "LiveXanchor-LiveLive-S"
topic = "LiveDanmuSend-T"
action ="sub"
name = "service/xacnhor"
proto = "tcp"
addr = "172.18.33.50:6205"
idle = 10
active = 100
dialTimeout = "10s"
readTimeout = "40s"
writeTimeout = "10s"
idleTimeout = "60s"
[liveGiftSendSub]
key = "ec4c0820d525d67b"
secret = "e20f8f664bf10722efeb6aac0cc16011"
group = "LiveXanchor-LiveLive-S"
topic = "LiveGiftSend-T"
action ="sub"
name = "service/xacnhor"
proto = "tcp"
addr = "172.18.33.50:6205"
idle = 10
active = 100
dialTimeout = "10s"
readTimeout = "40s"
writeTimeout = "10s"
idleTimeout = "60s"

View File

@@ -0,0 +1,40 @@
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/xanchor/conf",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//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/net/http/blademaster:go_default_library",
"//library/net/http/blademaster/middleware/verify: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,90 @@
package conf
import (
"errors"
"flag"
"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"
"go-common/library/queue/databus"
"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
MySQL *sql.Config
LiveAppMySQL *sql.Config
Ecode *ecode.Config
LiveDanmuSub *databus.Config //发送弹幕回调配置
LiveGiftSendSub *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,44 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"dao.go",
"mysql.go",
"redisKey.go",
],
importpath = "go-common/app/service/live/xanchor/dao",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/live/xanchor/api/grpc/v1:go_default_library",
"//app/service/live/xanchor/conf:go_default_library",
"//library/cache/redis:go_default_library",
"//library/database/sql:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/service/live/xanchor/dao/consumer:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

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 = [
"dao.go",
"redis.go",
],
importpath = "go-common/app/service/live/xanchor/dao/consumer",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/live/xanchor/conf:go_default_library",
"//library/cache/redis:go_default_library",
"//library/database/sql:go_default_library",
"//library/log:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,46 @@
package consumer
import (
"context"
"go-common/app/service/live/xanchor/conf"
"go-common/library/cache/redis"
xsql "go-common/library/database/sql"
)
type refValue struct {
field string
v interface{}
}
// Dao dao
type Dao struct {
c *conf.Config
redis *redis.Pool
db *xsql.DB
dbLiveApp *xsql.DB
}
// New init mysql db
func New(c *conf.Config) (dao *Dao) {
dao = &Dao{
c: c,
redis: redis.NewPool(c.Redis),
db: xsql.NewMySQL(c.MySQL),
dbLiveApp: xsql.NewMySQL(c.LiveAppMySQL),
}
return
}
// Close close the resource.
func (d *Dao) Close() {
d.redis.Close()
d.db.Close()
return
}
// Ping dao ping
func (d *Dao) Ping(c context.Context) error {
// TODO: if you need use mc,redis, please add
return d.db.Ping(c)
}

View File

@@ -0,0 +1,37 @@
package consumer
import (
"context"
"go-common/library/log"
)
//实时消费缓存设计,异步落地
const VALUE = "value"
const DATE = "date" //是否最新消息是为1(需要刷新到DB) 否为0(不需要刷新到DB)
const DATE_1 = "1"
//Set 设置实时数据
func (d *Dao) Set(ctx context.Context, redisKey string, value string, timeOut int) (err error) {
conn := d.redis.Get(ctx)
defer conn.Close()
if _, err = conn.Do("HMSET", redisKey, VALUE, value, DATE, DATE_1); err != nil {
log.Error("consumer_set_err:key=%s;err=%v", redisKey, err)
return
}
conn.Do("EXPIRE", redisKey, timeOut)
return
}
//Incr 设置增加数据
func (d *Dao) Incr(ctx context.Context, redisKey string, num int64, timeOut int) (err error) {
conn := d.redis.Get(ctx)
defer conn.Close()
if _, err = conn.Do("HINCRBY", redisKey, VALUE, num, DATE, DATE_1); err != nil {
log.Error("consumer_incr_err:key=%s;err=%v", redisKey, err)
return
}
conn.Do("EXPIRE", redisKey, timeOut)
return
}

View File

@@ -0,0 +1,137 @@
package dao
import (
"context"
v1pb "go-common/app/service/live/xanchor/api/grpc/v1"
"go-common/app/service/live/xanchor/conf"
"go-common/library/cache/redis"
xsql "go-common/library/database/sql"
)
type refValue struct {
field string
v interface{}
}
// Dao dao
type Dao struct {
c *conf.Config
redis *redis.Pool
db *xsql.DB
dbLiveApp *xsql.DB
}
// New init mysql db
func New(c *conf.Config) (dao *Dao) {
dao = &Dao{
c: c,
redis: redis.NewPool(c.Redis),
db: xsql.NewMySQL(c.MySQL),
dbLiveApp: xsql.NewMySQL(c.LiveAppMySQL),
}
return
}
// Close close the resource.
func (d *Dao) Close() {
d.redis.Close()
d.db.Close()
return
}
// Ping dao ping
func (d *Dao) Ping(c context.Context) error {
// TODO: if you need use mc,redis, please add
return d.db.Ping(c)
}
// FetchRoomByIDs implementation
// FetchRoomByIDs 查询房间信息
func (d *Dao) FetchRoomByIDs(ctx context.Context, req *v1pb.RoomByIDsReq) (resp *v1pb.RoomByIDsResp, err error) {
return d.fetchRoomByIDs(ctx, req)
}
// RoomOnlineList implementation
// RoomOnlineList 在线房间列表
func (d *Dao) RoomOnlineList(ctx context.Context, req *v1pb.RoomOnlineListReq) (resp *v1pb.RoomOnlineListResp, err error) {
return d.roomOnlineList(ctx, req)
}
// RoomCreate implementation
// RoomCreate 房间创建
func (d *Dao) RoomCreate(ctx context.Context, req *v1pb.RoomCreateReq) (resp *v1pb.RoomCreateResp, err error) {
return d.roomCreate(ctx, req)
}
// RoomUpdate implementation
// RoomUpdate 房间更新
func (d *Dao) RoomUpdate(ctx context.Context, req *v1pb.RoomUpdateReq) (resp *v1pb.UpdateResp, err error) {
return d.roomUpdate(ctx, req)
}
// RoomBatchUpdate implementation
// RoomBatchUpdate 房间更新
func (d *Dao) RoomBatchUpdate(ctx context.Context, req *v1pb.RoomBatchUpdateReq) (resp *v1pb.UpdateResp, err error) {
return d.roomBatchUpdate(ctx, req)
}
// RoomExtendUpdate implementation
// RoomExtendUpdate 房间更新
func (d *Dao) RoomExtendUpdate(ctx context.Context, req *v1pb.RoomExtendUpdateReq) (resp *v1pb.UpdateResp, err error) {
return d.roomExtendUpdate(ctx, req)
}
// RoomExtendBatchUpdate implementation
// RoomExtendBatchUpdate 房间更新
func (d *Dao) RoomExtendBatchUpdate(ctx context.Context, req *v1pb.RoomExtendBatchUpdateReq) (resp *v1pb.UpdateResp, err error) {
return d.roomExtendBatchUpdate(ctx, req)
}
// RoomExtendIncre implementation
// RoomExtendIncre 房间增量更新
func (d *Dao) RoomExtendIncre(ctx context.Context, req *v1pb.RoomExtendIncreReq) (resp *v1pb.UpdateResp, err error) {
return d.roomExtendIncre(ctx, req)
}
// RoomExtendBatchIncre implementation
// RoomExtendBatchIncre 房间增量更新
func (d *Dao) RoomExtendBatchIncre(ctx context.Context, req *v1pb.RoomExtendBatchIncreReq) (resp *v1pb.UpdateResp, err error) {
return d.roomExtendBatchIncre(ctx, req)
}
// RoomTagSet implementation
// RoomTagSet 房间Tag更新
func (d *Dao) RoomTagSet(ctx context.Context, req *v1pb.RoomTagSetReq) (resp *v1pb.UpdateResp, err error) {
return d.roomTagSet(ctx, req)
}
// AnchorUpdate implementation
// AnchorUpdate 主播更新
func (d *Dao) AnchorUpdate(ctx context.Context, req *v1pb.AnchorUpdateReq) (resp *v1pb.UpdateResp, err error) {
return d.anchorUpdate(ctx, req)
}
// AnchorBatchUpdate implementation
// AnchorBatchUpdate 主播更新
func (d *Dao) AnchorBatchUpdate(ctx context.Context, req *v1pb.AnchorBatchUpdateReq) (resp *v1pb.UpdateResp, err error) {
return d.anchorBatchUpdate(ctx, req)
}
// AnchorIncre implementation
// AnchorIncre 主播增量更新
func (d *Dao) AnchorIncre(ctx context.Context, req *v1pb.AnchorIncreReq) (resp *v1pb.UpdateResp, err error) {
return d.anchorIncre(ctx, req)
}
// AnchorBatchIncre implementation
// AnchorBatchIncre 主播增量更新
func (d *Dao) AnchorBatchIncre(ctx context.Context, req *v1pb.AnchorBatchIncreReq) (resp *v1pb.UpdateResp, err error) {
return d.anchorBatchIncre(ctx, req)
}
// AnchorTagSet implementation
// AnchorTagSet 主播Tag更新
func (d *Dao) AnchorTagSet(ctx context.Context, req *v1pb.AnchorTagSetReq) (resp *v1pb.UpdateResp, err error) {
return d.anchorTagSet(ctx, req)
}

View File

@@ -0,0 +1,578 @@
package dao
import (
"context"
"fmt"
v1pb "go-common/app/service/live/xanchor/api/grpc/v1"
"go-common/library/ecode"
"go-common/library/log"
"github.com/pkg/errors"
)
const (
_roomTable = "room"
_roomExtTablePrefix = "room_extend"
_anchorTable = "anchor"
_tagTable = "tag"
_areaTable = "ap_room_area_v2"
// add room info
_addRoomInfo1 = "insert into `%s` (`uid`) values (?)"
// add room info
_addRoomInfo2 = "insert into `%s` (`uid`,`room_id`) values (?,?)"
// add room extend info
_addRoomExtInfo = "insert into `%s_%d` (`room_id`) values (?)"
// add anchor info
_addAnchorInfo = "insert into `%s` (`uid`,`room_id`,`san_score`) values (?,?,12)"
// update room info
_updateRoomInfo = "update `%s` set %s where `room_id`=?"
// update room extend info
_updateRoomExtInfo = "update `%s_%d` set %s where `room_id`=?"
// update anchor info
_updateAnchorInfo = "update `%s` set %s where `uid`=?"
// tag set info
_tagSetInfo = "insert into `%s` set `target_type`=%d,%s on duplicate key update %s"
// query room info
_queryRoomInfo = "select `room`.`room_id`,`room`.`uid`,`room`.`title`,`room`.`description`,`room`.`tags`,`room`.`background`,`room`.`cover`,`room`.`lock_status`,`room`.`lock_time`,`room`.`hidden_time`,`room`.`record_switch`,`room`.`round_switch`,`room`.`live_start_time`,`room`.`live_screen_type`,`room`.`live_area_id`,`room`.`live_area_parent_id`,`room`.`live_type`,`anchor`.`san_score`,`anchor`.`profile_type`,`anchor`.`round_status`,`anchor`.`record_status`,`anchor`.`exp` from `room`,`anchor` where `room`.`uid`=`anchor`.`uid` and `%s` in (%s)"
// query online room info
_queryOnlineRoomInfo = "select `room`.`room_id`,`room`.`uid`,`room`.`title`,`room`.`description`,`room`.`tags`,`room`.`background`,`room`.`cover`,`room`.`lock_status`,`room`.`lock_time`,`room`.`hidden_time`,`room`.`record_switch`,`room`.`round_switch`,`room`.`live_start_time`,`room`.`live_screen_type`,`room`.`live_area_id`,`room`.`live_area_parent_id`,`room`.`live_type`,`anchor`.`san_score`,`anchor`.`profile_type`,`anchor`.`round_status`,`anchor`.`record_status`,`anchor`.`exp` from `room`,`anchor` where `room`.`uid`=`anchor`.`uid` and `live_start_time`!=0 order by id limit ?,?"
// get parent area id
_queryParentAreaID = "select `parent_id` from `%s` where `id`=?"
)
// fetchParentAreaID implementation
// fetchParentAreaID 查询房间信息
func (d *Dao) fetchParentAreaID(ctx context.Context, areaID int64) (parentAreaID int64, err error) {
sql := fmt.Sprintf(_queryParentAreaID, _areaTable)
err = d.dbLiveApp.QueryRow(ctx, sql, areaID).Scan(&parentAreaID)
return
}
// fetchRoomByIDs implementation
// fetchRoomByIDs 查询房间信息
func (d *Dao) fetchRoomByIDs(ctx context.Context, req *v1pb.RoomByIDsReq) (resp *v1pb.RoomByIDsResp, err error) {
condField := ""
valueList := ""
if len(req.RoomIds) > 0 {
condField = "room`.`room_id"
for i, id := range req.RoomIds {
if i > 0 {
valueList += ","
}
valueList += fmt.Sprintf("%d", id)
}
} else if len(req.Uids) > 0 {
condField = "room`.`uid"
for i, id := range req.Uids {
if i > 0 {
valueList += ","
}
valueList += fmt.Sprintf("%d", id)
}
}
sql := fmt.Sprintf(_queryRoomInfo, condField, valueList)
rows, err := d.db.Query(ctx, sql)
if err != nil {
log.Error("[dao.xanchor.mysql|fetchRoomByIDs] get room record error(%v), req(%v)", err, req)
return nil, err
}
defer rows.Close()
resp = &v1pb.RoomByIDsResp{}
for rows.Next() {
var data v1pb.RoomData
err = rows.Scan(&data.RoomId, &data.Uid, &data.Title, &data.Description, &data.Tags, &data.Background, &data.Cover, &data.LockStatus, &data.LockTime, &data.HiddenTime, &data.AnchorRecordSwitch, &data.AnchorRoundSwitch, &data.LiveStartTime, &data.LiveScreenType, &data.AreaId, &data.ParentAreaId, &data.AnchorSan, &data.AnchorProfileType, &data.AnchorRoundStatus, &data.AnchorRecordStatus, &data.AnchorExp)
// TODO area name
if err != nil {
log.Error("[dao.xanchor.mysql|fetchRoomByIDs] scan room record error(%v), req(%v)", err, req)
return nil, err
}
resp.RoomDataSet[data.RoomId] = &data
// TODO short-id
}
// TODO Tag List
return
}
// roomOnlineList implementation
// roomOnlineList 在线房间列表
func (d *Dao) roomOnlineList(ctx context.Context, req *v1pb.RoomOnlineListReq) (resp *v1pb.RoomOnlineListResp, err error) {
rows, err := d.db.Query(ctx, _queryOnlineRoomInfo, req.Page*req.PageSize, req.PageSize)
if err != nil {
log.Error("[dao.xanchor.mysql|roomOnlineList] get online room list error(%v), req(%v)", err, req)
return nil, err
}
defer rows.Close()
resp = &v1pb.RoomOnlineListResp{}
for rows.Next() {
var data v1pb.RoomData
err = rows.Scan(&data.RoomId, &data.Uid, &data.Title, &data.Description, &data.Tags, &data.Background, &data.Cover, &data.LockStatus, &data.LockTime, &data.HiddenTime, &data.AnchorRecordSwitch, &data.AnchorRoundSwitch, &data.LiveStartTime, &data.LiveScreenType, &data.AreaId, &data.ParentAreaId, &data.AnchorSan, &data.AnchorProfileType, &data.AnchorRoundStatus, &data.AnchorRecordStatus, &data.AnchorExp)
// TODO area name
if err != nil {
log.Error("[dao.xanchor.mysql|roomOnlineList] scan online room list error(%v), req(%v)", err, req)
return nil, err
}
resp.RoomDataList[data.RoomId] = &data
// TODO short-id
}
// TODO Tag List
return
}
// roomCreate implementation
// roomCreate 房间创建
func (d *Dao) roomCreate(ctx context.Context, req *v1pb.RoomCreateReq) (resp *v1pb.RoomCreateResp, err error) {
resp = &v1pb.RoomCreateResp{}
tx, err := d.db.Begin(ctx)
if err != nil {
err = errors.WithStack(err)
return resp, err
}
if req.RoomId != 0 {
resp.RoomId = req.RoomId
sql := fmt.Sprintf(_addRoomInfo2, _roomTable)
_, err = tx.Exec(sql, req.Uid, req.RoomId)
if err != nil {
if e := tx.Rollback(); e != nil {
log.Error("[dao.xanchor.mysql|roomCreate] create room record rollback error(%v), req(%v)", e, req)
}
// unique key exists error
log.Error("[dao.xanchor.mysql|roomCreate] create room record error(%v), req(%v)", err, req)
return resp, err
}
} else {
sql := fmt.Sprintf(_addRoomInfo1, _roomTable)
res, err := tx.Exec(sql, req.Uid)
if err != nil {
if e := tx.Rollback(); e != nil {
log.Error("[dao.xanchor.mysql|roomCreate] create room record rollback error(%v), req(%v)", e, req)
}
// unique key exists error
log.Error("[dao.xanchor.mysql|roomCreate] create room record error(%v), req(%v)", err, req)
return resp, err
}
if resp.RoomId, err = res.LastInsertId(); err != nil {
err = errors.WithStack(err)
log.Error("[dao.xanchor.mysql|AddGuard] get last insert id error(%v), req(%v)", err, req)
}
}
sql := fmt.Sprintf(_addRoomExtInfo, _roomExtTablePrefix, resp.RoomId%10)
if _, err = tx.Exec(sql, resp.RoomId); err != nil {
if e := tx.Rollback(); e != nil {
log.Error("[dao.xanchor.mysql|roomCreate] create room extend record rollback error(%v), req(%v)", e, req)
}
log.Error("[dao.xanchor.mysql|roomCreate] create room extend record error(%v), req(%v)", err, req)
return resp, err
}
sql = fmt.Sprintf(_addAnchorInfo, _anchorTable)
if _, err = tx.Exec(sql, req.Uid, resp.RoomId); err != nil {
if e := tx.Rollback(); e != nil {
log.Error("[dao.xanchor.mysql|roomCreate] create anchor record rollback error(%v), req(%v)", e, req)
}
log.Error("[dao.xanchor.mysql|roomCreate] create anchor record error(%v), req(%v)", err, req)
return resp, err
}
if err = tx.Commit(); err != nil {
log.Error("[dao.xanchor.mysql|roomCreate] commit error(%v), req(%v)", err, req)
return resp, err
}
return
}
// roomUpdate implementation
// roomUpdate 房间信息更新
func (d *Dao) roomUpdate(ctx context.Context, req *v1pb.RoomUpdateReq) (resp *v1pb.UpdateResp, err error) {
updateSub := ""
args := make([]interface{}, len(req.Fields)+1)
args[len(req.Fields)] = req.RoomId
for i, f := range req.Fields {
switch f {
case "title":
args[i] = req.Title
case "cover":
args[i] = req.Cover
case "tags":
args[i] = req.Tags
case "background":
args[i] = req.Background
case "description":
args[i] = req.Description
case "live_start_time":
args[i] = req.LiveStartTime
if req.LiveStartTime > 0 {
if i > 0 {
updateSub += ","
}
updateSub += "`live_mark`=1"
if i == 0 {
updateSub += ","
}
}
case "live_screen_type":
args[i] = req.LiveScreenType
case "lock_status":
args[i] = req.LockStatus
case "lock_time":
args[i] = req.LockTime
case "hidden_time":
args[i] = req.HiddenTime
case "area_id":
f = "live_area_id"
args[i] = req.AreaId
var parentAreaID int64
parentAreaID, err = d.fetchParentAreaID(ctx, req.AreaId)
if err != nil {
log.Error("[dao.xanchor.mysql|roomUpdate] fetch parent area ID error(%v), req(%v)", err, req)
err = ecode.InvalidParam
return
}
if i > 0 {
updateSub += ","
}
updateSub += fmt.Sprintf("`live_area_parent_id`=%d", parentAreaID)
if i == 0 {
updateSub += ","
}
case "anchor_round_switch":
f = "round_switch"
args[i] = req.AnchorRoundSwitch
case "anchor_record_switch":
f = "record_switch"
args[i] = req.AnchorRecordSwitch
default:
log.Error("[dao.xanchor.mysql|roomUpdate] unsupported field(%v), req(%s)", f, req)
err = ecode.InvalidParam
return
}
if i > 0 {
updateSub += ","
}
updateSub += fmt.Sprintf("`%s`=?", f)
}
resp = &v1pb.UpdateResp{}
sql := fmt.Sprintf(_updateRoomInfo, _roomTable, updateSub)
res, err := d.db.Exec(ctx, sql, args...)
if err != nil {
log.Error("[dao.xanchor.mysql|roomUpdate] update room record error(%v), req(%v)", err, req)
return
}
resp.AffectedRows, err = res.RowsAffected()
return
}
// roomBatchUpdate implementation
// roomBatchUpdate 房间信息批量更新
func (d *Dao) roomBatchUpdate(ctx context.Context, req *v1pb.RoomBatchUpdateReq) (resp *v1pb.UpdateResp, err error) {
resp = &v1pb.UpdateResp{}
for _, r := range req.Reqs {
res, err := d.roomUpdate(ctx, r)
if err != nil {
log.Error("[dao.xanchor.mysql|roomBatchUpdate] update room record error(%v), req(%v)", err, r)
return nil, err
}
resp.AffectedRows += res.AffectedRows
}
return
}
// roomExtendUpdate implementation
// roomExtendUpdate 房间扩展信息更新
func (d *Dao) roomExtendUpdate(ctx context.Context, req *v1pb.RoomExtendUpdateReq) (resp *v1pb.UpdateResp, err error) {
updateSub := ""
args := make([]interface{}, len(req.Fields)+1)
args[len(req.Fields)] = req.RoomId
for i, f := range req.Fields {
switch f {
case "key_frame":
args[i] = req.KeyFrame
case "danmu_count":
args[i] = req.DanmuCount
case "popularity_count":
args[i] = req.PopularityCount
case "audience_count":
args[i] = req.AudienceCount
case "gift_count":
args[i] = req.GiftCount
case "gift_gold_amount":
args[i] = req.GiftGoldAmount
case "gift_gold_count":
args[i] = req.GiftGoldCount
default:
log.Error("[dao.xanchor.mysql|roomExtendUpdate] unsupported field(%v), req(%s)", f, req)
err = ecode.InvalidParam
return
}
if i > 0 {
updateSub += ","
}
updateSub += fmt.Sprintf("`%s`=?", f)
}
resp = &v1pb.UpdateResp{}
sql := fmt.Sprintf(_updateRoomExtInfo, _roomExtTablePrefix, req.RoomId%10, updateSub)
res, err := d.db.Exec(ctx, sql, args...)
if err != nil {
log.Error("[dao.xanchor.mysql|roomExtendUpdate] update room extend record error(%v), req(%v)", err, req)
return
}
resp.AffectedRows, err = res.RowsAffected()
return
}
// roomExtendBatchUpdate implementation
// roomExtendBatchUpdate 房间扩展信息批量更新
func (d *Dao) roomExtendBatchUpdate(ctx context.Context, req *v1pb.RoomExtendBatchUpdateReq) (resp *v1pb.UpdateResp, err error) {
resp = &v1pb.UpdateResp{}
for _, r := range req.Reqs {
res, err := d.roomExtendUpdate(ctx, r)
if err != nil {
log.Error("[dao.xanchor.mysql|roomExtendBatchUpdate] update room extend record error(%v), req(%v)", err, r)
return nil, err
}
resp.AffectedRows += res.AffectedRows
}
return
}
// roomExtendIncre implementation
// roomExtendIncre 房间扩展信息增量更新
func (d *Dao) roomExtendIncre(ctx context.Context, req *v1pb.RoomExtendIncreReq) (resp *v1pb.UpdateResp, err error) {
// TODO: req_id
updateSub := ""
args := make([]interface{}, len(req.Fields)+1)
args[len(req.Fields)] = req.RoomId
for i, f := range req.Fields {
switch f {
case "danmu_count":
args[i] = req.DanmuCount
case "popularity_count":
args[i] = req.PopularityCount
case "audience_count":
args[i] = req.AudienceCount
case "gift_count":
args[i] = req.GiftCount
case "gift_gold_amount":
args[i] = req.GiftGoldAmount
case "gift_gold_count":
args[i] = req.GiftGoldCount
default:
log.Error("[dao.xanchor.mysql|roomExtendIncre] unsupported field(%v), req(%s)", f, req)
err = ecode.InvalidParam
return
}
if i > 0 {
updateSub += ","
}
updateSub += fmt.Sprintf("`%s`=`%s`+(?)", f, f)
}
resp = &v1pb.UpdateResp{}
sql := fmt.Sprintf(_updateRoomExtInfo, _roomExtTablePrefix, req.RoomId%10, updateSub)
res, err := d.db.Exec(ctx, sql, args...)
if err != nil {
log.Error("[dao.xanchor.mysql|roomExtendIncre] update room extend increment record error(%v), req(%v)", err, req)
return
}
resp.AffectedRows, err = res.RowsAffected()
return
}
// roomExtendBatchIncre implementation
// roomExtendBatchIncre 房间扩展信息批量更新
func (d *Dao) roomExtendBatchIncre(ctx context.Context, req *v1pb.RoomExtendBatchIncreReq) (resp *v1pb.UpdateResp, err error) {
resp = &v1pb.UpdateResp{}
for _, r := range req.Reqs {
res, err := d.roomExtendIncre(ctx, r)
if err != nil {
log.Error("[dao.xanchor.mysql|roomExtendBatchIncre] update room extend increment record error(%v), req(%v)", err, r)
return nil, err
}
resp.AffectedRows += res.AffectedRows
}
return
}
// roomTagSet implementation
// roomTagSet 房间Tag更新
func (d *Dao) roomTagSet(ctx context.Context, req *v1pb.RoomTagSetReq) (resp *v1pb.UpdateResp, err error) {
updateSub := ""
args := make([]interface{}, len(req.Fields)*2+1)
args[len(req.Fields)] = req.RoomId
for i, f := range req.Fields {
switch f {
case "tag_value":
args[i] = req.TagValue
args[len(req.Fields)+i] = req.TagValue
case "tag_attribute":
args[i] = req.TagAttribute
args[len(req.Fields)+i] = req.TagAttribute
case "tag_expire_at":
args[i] = req.TagExpireAt
args[len(req.Fields)+i] = req.TagExpireAt
default:
log.Error("[dao.xanchor.mysql|roomTagSet] unsupported field(%v), req(%s)", f, req)
err = ecode.InvalidParam
return
}
if i > 0 {
updateSub += ","
}
updateSub += fmt.Sprintf("`%s`=?", f)
}
resp = &v1pb.UpdateResp{}
sql := fmt.Sprintf(_tagSetInfo, _tagTable, 2, updateSub, updateSub)
res, err := d.db.Exec(ctx, sql, args...)
if err != nil {
log.Error("[dao.xanchor.mysql|roomTagSet] set room tag error(%v), req(%v)", err, req)
return
}
resp.AffectedRows, err = res.RowsAffected()
return
}
// anchorUpdate implementation
// anchorUpdate 主播信息更新
func (d *Dao) anchorUpdate(ctx context.Context, req *v1pb.AnchorUpdateReq) (resp *v1pb.UpdateResp, err error) {
updateSub := ""
args := make([]interface{}, len(req.Fields)+1)
args[len(req.Fields)] = req.Uid
for i, f := range req.Fields {
switch f {
case "profile_type":
args[i] = req.ProfileType
case "san_score":
args[i] = req.SanScore
case "round_status":
args[i] = req.RoundStatus
case "record_status":
args[i] = req.RecordStatus
case "exp":
args[i] = req.Exp
default:
log.Error("[dao.xanchor.mysql|anchorUpdate] unsupported field(%v), req(%s)", f, req)
err = ecode.InvalidParam
return
}
if i > 0 {
updateSub += ","
}
updateSub += fmt.Sprintf("`%s`=?", f)
}
resp = &v1pb.UpdateResp{}
sql := fmt.Sprintf(_updateAnchorInfo, _anchorTable, updateSub)
res, err := d.db.Exec(ctx, sql, args...)
if err != nil {
log.Error("[dao.xanchor.mysql|anchorUpdate] update anchor record error(%v), req(%v)", err, req)
return
}
resp.AffectedRows, err = res.RowsAffected()
return
}
// anchorBatchUpdate implementation
// anchorBatchUpdate 主播信息批量更新
func (d *Dao) anchorBatchUpdate(ctx context.Context, req *v1pb.AnchorBatchUpdateReq) (resp *v1pb.UpdateResp, err error) {
resp = &v1pb.UpdateResp{}
for _, r := range req.Reqs {
res, err := d.anchorUpdate(ctx, r)
if err != nil {
log.Error("[dao.xanchor.mysql|anchorBatchUpdate] update anchor record error(%v), req(%v)", err, r)
return nil, err
}
resp.AffectedRows += res.AffectedRows
}
return
}
// anchorIncre implementation
// anchorIncre 主播信息增量更新
func (d *Dao) anchorIncre(ctx context.Context, req *v1pb.AnchorIncreReq) (resp *v1pb.UpdateResp, err error) {
// TODO: req_id
updateSub := ""
args := make([]interface{}, len(req.Fields)+1)
args[len(req.Fields)] = req.Uid
for i, f := range req.Fields {
switch f {
case "san_score":
args[i] = req.SanScore
case "exp":
args[i] = req.Exp
default:
log.Error("[dao.xanchor.mysql|anchorIncre] unsupported field(%v), req(%s)", f, req)
err = ecode.InvalidParam
return
}
if i > 0 {
updateSub += ","
}
updateSub += fmt.Sprintf("`%s`=`%s`+(?)", f, f)
}
resp = &v1pb.UpdateResp{}
sql := fmt.Sprintf(_updateAnchorInfo, _anchorTable, updateSub)
res, err := d.db.Exec(ctx, sql, args...)
if err != nil {
log.Error("[dao.xanchor.mysql|anchorUpdate] update anchor increment record error(%v), req(%v)", err, req)
return
}
resp.AffectedRows, err = res.RowsAffected()
return
}
// anchorBatchIncre implementation
// anchorBatchIncre 主播信息批量增量更新
func (d *Dao) anchorBatchIncre(ctx context.Context, req *v1pb.AnchorBatchIncreReq) (resp *v1pb.UpdateResp, err error) {
resp = &v1pb.UpdateResp{}
for _, r := range req.Reqs {
res, err := d.anchorIncre(ctx, r)
if err != nil {
log.Error("[dao.xanchor.mysql|anchorBatchIncre] update anchor increment record error(%v), req(%v)", err, r)
return nil, err
}
resp.AffectedRows += res.AffectedRows
}
return
}
// anchorTagSet implementation
// anchorTagSet 主播Tag更新
func (d *Dao) anchorTagSet(ctx context.Context, req *v1pb.AnchorTagSetReq) (resp *v1pb.UpdateResp, err error) {
updateSub := ""
args := make([]interface{}, len(req.Fields)*2+1)
args[len(req.Fields)] = req.AnchorId
for i, f := range req.Fields {
switch f {
case "tag_value":
args[i] = req.TagValue
args[len(req.Fields)+i] = req.TagValue
case "tag_attribute":
args[i] = req.TagAttribute
args[len(req.Fields)+i] = req.TagAttribute
case "tag_expire_at":
args[i] = req.TagExpireAt
args[len(req.Fields)+i] = req.TagExpireAt
default:
log.Error("[dao.xanchor.mysql|roomTagSet] unsupported field(%v), req(%s)", f, req)
err = ecode.InvalidParam
return
}
if i > 0 {
updateSub += ","
}
updateSub += fmt.Sprintf("`%s`=?", f)
}
resp = &v1pb.UpdateResp{}
sql := fmt.Sprintf(_tagSetInfo, _tagTable, 1, updateSub, updateSub)
res, err := d.db.Exec(ctx, sql, args...)
if err != nil {
log.Error("[dao.xanchor.mysql|roomTagSet] set anchor tag error(%v), req(%v)", err, req)
return
}
resp.AffectedRows, err = res.RowsAffected()
return
}

View File

@@ -0,0 +1,38 @@
package dao
import (
"fmt"
)
type resp struct {
RedisKey string `json:"redis_key"`
TimeOut int `json:"time_out"`
}
//DanmuTotalNum 开播弹幕数统计
func (d *Dao) DanmuNumKey(roomId int64) (resp *resp) {
resp.RedisKey = fmt.Sprintf("danmu_num_key_%d", roomId)
resp.TimeOut = 24 * 60 * 60
return
}
//GiftTotalNum 开播礼物数统计
func (d *Dao) GiftNumKey(roomId int64) (resp *resp) {
resp.RedisKey = fmt.Sprintf("gift_num_key_%d", roomId)
resp.TimeOut = 24 * 60 * 60
return
}
//GiftGoldTotalNum 开播金瓜子数量统计
func (d *Dao) GiftGoldNumKey(roomId int64) (resp *resp) {
resp.RedisKey = fmt.Sprintf("gift_gold_num_key_%d", roomId)
resp.TimeOut = 24 * 60 * 60
return
}
//GiftGoldTotalAmount 开播金瓜子金额统计
func (d *Dao) GiftGoldAmountKey(roomId int64) (resp *resp) {
resp.RedisKey = fmt.Sprintf("gift_gold_num_key_%d", roomId)
resp.TimeOut = 24 * 60 * 60
return
}

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 = [
"databusMsg.go",
"model.go",
],
importpath = "go-common/app/service/live/xanchor/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,42 @@
package model
import "time"
//DanmuSendMessage
type DanmuSendMessage struct {
Topic string `json:"topic"`
MsgID string `json:"msg_id"`
MsgKey string `json:"msg_key"`
MsgContent DanmuSendMessageContent `json:"msg_content"`
}
//DanmuSendMessageContent
type DanmuSendMessageContent struct {
RoomId int64 `json:"room_id"`
Uid int64 `json:"uid"`
Uname string `json:"uname"`
UserLevel int64 `json:"user_level"`
Color string `json:"color"`
Msg string `json:"msg"`
Time time.Time `json:"time"`
}
//GiftSendMessage
type GiftSendMessage struct {
Topic string `json:"topic"`
MsgID string `json:"msg_id"`
MsgKey string `json:"msg_key"`
MsgContent GiftSendMessageContent `json:"msg_content"`
}
//GiftSendMessageContent
type GiftSendMessageContent struct {
Uid int64 `json:"uid"`
Ruid int64 `json:"ruid"`
RoomId int64 `json:"roomid"`
GiftId int64 `json:"giftid"`
GiftName string `json:"giftName"`
PayCoin int64 `json:"pay_coin"`
Num int64 `json:"num"`
CoinType string `json:"coinType"`
}

View File

@@ -0,0 +1 @@
package model

View File

@@ -0,0 +1,33 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["server.go"],
importpath = "go-common/app/service/live/xanchor/server/grpc",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/live/xanchor/api/grpc/v1:go_default_library",
"//app/service/live/xanchor/service: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,17 @@
package grpc
import (
v1pb "go-common/app/service/live/xanchor/api/grpc/v1"
"go-common/app/service/live/xanchor/service"
"go-common/library/net/rpc/warden"
)
// New new grpc server
func New(svc *service.Service) (wsvr *warden.Server, err error) {
wsvr = warden.NewServer(nil)
v1pb.RegisterXAnchorServer(wsvr.Server(), svc.V1Svc())
if wsvr, err = wsvr.Start(); err != nil {
return
}
return
}

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/xanchor/server/http",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/live/xanchor/conf:go_default_library",
"//app/service/live/xanchor/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,57 @@
package http
import (
"net/http"
"go-common/app/service/live/xanchor/conf"
"go-common/app/service/live/xanchor/service"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/middleware/verify"
)
var (
srv *service.Service
vfy *verify.Verify
)
// Init init
func Init(c *conf.Config) {
vfy = verify.New(c.Verify)
initService(c)
engine := bm.DefaultServer(c.BM)
route(engine)
if err := engine.Start(); err != nil {
log.Error("bm Start error(%v)", err)
panic(err)
}
}
func initService(c *conf.Config) {
srv = service.New(c)
}
func route(e *bm.Engine) {
e.Ping(ping)
e.Register(register)
g := e.Group("/xlive/xanchor")
{
g.GET("/start", vfy.Verify, howToStart)
}
}
func ping(c *bm.Context) {
if err := srv.Ping(c); err != nil {
log.Error("ping error(%v)", err)
c.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,38 @@
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/xanchor/service",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/live/xanchor/conf:go_default_library",
"//app/service/live/xanchor/dao:go_default_library",
"//app/service/live/xanchor/service/v1:go_default_library",
"//library/queue/databus:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/service/live/xanchor/service/consumer/v1:all-srcs",
"//app/service/live/xanchor/service/v1:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,41 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"ConsumerDanmu.go",
"ConsumerGift.go",
"dataBusNotify.go",
],
importpath = "go-common/app/service/live/xanchor/service/consumer/v1",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/live/xanchor/conf:go_default_library",
"//app/service/live/xanchor/dao:go_default_library",
"//app/service/live/xanchor/dao/consumer:go_default_library",
"//app/service/live/xanchor/model:go_default_library",
"//library/log:go_default_library",
"//library/queue/databus:go_default_library",
"//vendor/github.com/prometheus/common/log:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,27 @@
package v1
import (
"context"
"encoding/json"
"go-common/app/service/live/xanchor/model"
"go-common/library/log"
"go-common/library/queue/databus"
)
//消费弹幕消息的业务逻辑
//DanmuCountStatistics 弹幕数统计
func (s *ConsumerService) DanmuCountStatistics(ctx context.Context, msg *databus.Message) (err error) {
defer msg.Commit()
msgInfo := new(model.DanmuSendMessage)
if err = json.Unmarshal(msg.Value, &msgInfo); err != nil {
log.Error("DanmuCountStatistics_error:msg=%v;err=%v;msgInfo=%v", msg, err, msgInfo)
return
}
msgContent := msgInfo.MsgContent
roomId := msgContent.RoomId
redisKeyInfo := s.Pdao.DanmuNumKey(roomId)
s.dao.Incr(ctx, redisKeyInfo.RedisKey, 1, redisKeyInfo.TimeOut)
return
}

View File

@@ -0,0 +1,39 @@
package v1
import (
"context"
"encoding/json"
"go-common/app/service/live/xanchor/model"
"go-common/library/log"
"go-common/library/queue/databus"
)
//消费礼物消息的业务逻辑
//GiftCountStatistics 礼物相关统计
func (s *ConsumerService) GiftCountStatistics(ctx context.Context, msg *databus.Message) (err error) {
defer msg.Commit()
msgInfo := new(model.GiftSendMessage)
if err = json.Unmarshal(msg.Value, &msgInfo); err != nil {
log.Error("GiftCountStatistics_error:msg=%v;err=%v;msgInfo=%v", msg, err, msgInfo)
return
}
msgContent := msgInfo.MsgContent
roomId := msgContent.RoomId
num := msgContent.Num
payCoin := msgContent.PayCoin
//增加礼物数
GiftNumKeyInfo := s.Pdao.GiftNumKey(roomId)
s.dao.Incr(ctx, GiftNumKeyInfo.RedisKey, num, GiftNumKeyInfo.TimeOut)
//增加金瓜子数量
if msgContent.CoinType == "gold" {
GiftGoldNumKeyInfo := s.Pdao.GiftGoldNumKey(roomId)
s.dao.Incr(ctx, GiftGoldNumKeyInfo.RedisKey, num, GiftGoldNumKeyInfo.TimeOut)
}
//增加礼物金额
if msgContent.CoinType == "gold" {
GiftGoldAmountKeyInfo := s.Pdao.GiftGoldAmountKey(roomId)
s.dao.Incr(ctx, GiftGoldAmountKeyInfo.RedisKey, payCoin, GiftGoldAmountKeyInfo.TimeOut)
}
return
}

View File

@@ -0,0 +1,60 @@
package v1
import (
"context"
"github.com/prometheus/common/log"
"go-common/app/service/live/xanchor/conf"
"go-common/app/service/live/xanchor/dao"
"go-common/app/service/live/xanchor/dao/consumer"
"go-common/library/queue/databus"
)
// XAnchorService struct
type ConsumerService struct {
conf *conf.Config
// optionally add other properties here, such as dao
dao *consumer.Dao
Pdao *dao.Dao
liveDanmuSub *databus.Databus
liveGiftSendSub *databus.Databus
}
//NewXAnchorService init
func NewXAnchorService(c *conf.Config) (s *ConsumerService) {
s = &ConsumerService{
conf: c,
dao: consumer.New(c),
Pdao: dao.New(c),
liveDanmuSub: databus.New(c.LiveDanmuSub),
liveGiftSendSub: databus.New(c.LiveDanmuSub),
}
return s
}
//DanmuSend 消费发送弹幕消息
func (s *ConsumerService) DanmuSend(ctx context.Context) {
log.Info("danmu_send_notify_start")
//接收消息
liveDanmuMsgs := s.liveDanmuSub.Messages()
msg, ok := <-liveDanmuMsgs
if msg == nil || !ok {
log.Error("xanchor_danmu_send_notify_error:msg=%v", liveDanmuMsgs)
return
}
s.DanmuCountStatistics(ctx, msg)
log.Info("danmu_send_notify_end")
}
func (s *ConsumerService) GiftSend(ctx context.Context) {
log.Info("gift_send_notify_start")
//接收消息
liveGiftSendMsgs := s.liveGiftSendSub.Messages()
msg, ok := <-liveGiftSendMsgs
if msg == nil || !ok {
log.Error("xanchor_figt_send_notify_error:msg=%v", liveGiftSendMsgs)
return
}
s.GiftCountStatistics(ctx, msg)
log.Info("gift_send_notify_end")
}

View File

@@ -0,0 +1,45 @@
package service
import (
"context"
"go-common/library/queue/databus"
"go-common/app/service/live/xanchor/conf"
"go-common/app/service/live/xanchor/dao"
v1 "go-common/app/service/live/xanchor/service/v1"
)
// Service struct
type Service struct {
c *conf.Config
dao *dao.Dao
v1svc *v1.XAnchorService
liveDanmuSub *databus.Databus
}
// New init
func New(c *conf.Config) (s *Service) {
s = &Service{
c: c,
dao: dao.New(c),
v1svc: v1.NewXAnchorService(c),
liveDanmuSub: databus.New(c.LiveDanmuSub),
}
return s
}
// Ping Service
func (s *Service) Ping(c context.Context) (err error) {
return s.dao.Ping(c)
}
// Close Service
func (s *Service) Close() {
s.dao.Close()
}
// V1Svc return v1 service
func (s *Service) V1Svc() *v1.XAnchorService {
return s.v1svc
}

View File

@@ -0,0 +1,33 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["xAnchor.go"],
importpath = "go-common/app/service/live/xanchor/service/v1",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/live/xanchor/api/grpc/v1:go_default_library",
"//app/service/live/xanchor/conf:go_default_library",
"//app/service/live/xanchor/dao: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,115 @@
package v1
import (
"context"
v1pb "go-common/app/service/live/xanchor/api/grpc/v1"
"go-common/app/service/live/xanchor/conf"
"go-common/app/service/live/xanchor/dao"
)
// XAnchorService struct
type XAnchorService struct {
conf *conf.Config
// optionally add other properties here, such as dao
dao *dao.Dao
}
//NewXAnchorService init
func NewXAnchorService(c *conf.Config) (s *XAnchorService) {
s = &XAnchorService{
conf: c,
dao: dao.New(c),
}
return s
}
// FetchRoomByIDs implementation
// FetchRoomByIDs 查询房间信息
func (s *XAnchorService) FetchRoomByIDs(ctx context.Context, req *v1pb.RoomByIDsReq) (resp *v1pb.RoomByIDsResp, err error) {
return s.dao.FetchRoomByIDs(ctx, req)
}
// RoomOnlineList implementation
// RoomOnlineList 在线房间列表
func (s *XAnchorService) RoomOnlineList(ctx context.Context, req *v1pb.RoomOnlineListReq) (resp *v1pb.RoomOnlineListResp, err error) {
return s.dao.RoomOnlineList(ctx, req)
}
// RoomCreate implementation
// RoomCreate 房间创建
func (s *XAnchorService) RoomCreate(ctx context.Context, req *v1pb.RoomCreateReq) (resp *v1pb.RoomCreateResp, err error) {
return s.dao.RoomCreate(ctx, req)
}
// RoomUpdate implementation
// RoomUpdate 房间信息更新
func (s *XAnchorService) RoomUpdate(ctx context.Context, req *v1pb.RoomUpdateReq) (resp *v1pb.UpdateResp, err error) {
return s.dao.RoomUpdate(ctx, req)
}
// RoomBatchUpdate implementation
// RoomBatchUpdate 房间信息批量更新
func (s *XAnchorService) RoomBatchUpdate(ctx context.Context, req *v1pb.RoomBatchUpdateReq) (resp *v1pb.UpdateResp, err error) {
return s.dao.RoomBatchUpdate(ctx, req)
}
// RoomExtendUpdate implementation
// RoomExtendUpdate 房间扩展信息更新
func (s *XAnchorService) RoomExtendUpdate(ctx context.Context, req *v1pb.RoomExtendUpdateReq) (resp *v1pb.UpdateResp, err error) {
return s.dao.RoomExtendUpdate(ctx, req)
}
// RoomExtendBatchUpdate implementation
// RoomExtendBatchUpdate 房间扩展信息批量更新
func (s *XAnchorService) RoomExtendBatchUpdate(ctx context.Context, req *v1pb.RoomExtendBatchUpdateReq) (resp *v1pb.UpdateResp, err error) {
return s.dao.RoomExtendBatchUpdate(ctx, req)
}
// RoomExtendIncre implementation
// RoomExtendIncre 房间扩展信息增量更新
func (s *XAnchorService) RoomExtendIncre(ctx context.Context, req *v1pb.RoomExtendIncreReq) (resp *v1pb.UpdateResp, err error) {
return s.dao.RoomExtendIncre(ctx, req)
}
// RoomExtendBatchIncre implementation
// RoomExtendBatchIncre 房间扩展信息批量增量更新
func (s *XAnchorService) RoomExtendBatchIncre(ctx context.Context, req *v1pb.RoomExtendBatchIncreReq) (resp *v1pb.UpdateResp, err error) {
return s.dao.RoomExtendBatchIncre(ctx, req)
}
// RoomTagSet implementation
// RoomTagSet 房间Tag更新
func (s *XAnchorService) RoomTagSet(ctx context.Context, req *v1pb.RoomTagSetReq) (resp *v1pb.UpdateResp, err error) {
return s.dao.RoomTagSet(ctx, req)
}
// AnchorUpdate implementation
// AnchorUpdate 主播信息更新
func (s *XAnchorService) AnchorUpdate(ctx context.Context, req *v1pb.AnchorUpdateReq) (resp *v1pb.UpdateResp, err error) {
return s.dao.AnchorUpdate(ctx, req)
}
// AnchorBatchUpdate implementation
// AnchorBatchUpdate 主播信息批量更新
func (s *XAnchorService) AnchorBatchUpdate(ctx context.Context, req *v1pb.AnchorBatchUpdateReq) (resp *v1pb.UpdateResp, err error) {
return s.dao.AnchorBatchUpdate(ctx, req)
}
// AnchorIncre implementation
// AnchorIncre 主播信息增量更新
func (s *XAnchorService) AnchorIncre(ctx context.Context, req *v1pb.AnchorIncreReq) (resp *v1pb.UpdateResp, err error) {
return s.dao.AnchorIncre(ctx, req)
}
// AnchorBatchIncre implementation
// AnchorBatchIncre 主播信息批量增量更新
func (s *XAnchorService) AnchorBatchIncre(ctx context.Context, req *v1pb.AnchorBatchIncreReq) (resp *v1pb.UpdateResp, err error) {
return s.dao.AnchorBatchIncre(ctx, req)
}
// AnchorTagSet implementation
// AnchorTagSet 主播Tag更新
func (s *XAnchorService) AnchorTagSet(ctx context.Context, req *v1pb.AnchorTagSetReq) (resp *v1pb.UpdateResp, err error) {
return s.dao.AnchorTagSet(ctx, req)
}