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,36 @@
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/admin/live/live-admin/service",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/live/live-admin/conf:go_default_library",
"//app/admin/live/live-admin/dao:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/admin/live/live-admin/service/v1:all-srcs",
"//app/admin/live/live-admin/service/v2:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,33 @@
package service
import (
"context"
"go-common/app/admin/live/live-admin/conf"
"go-common/app/admin/live/live-admin/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,72 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = [
"banner.go",
"capsule.go",
"gaea.go",
"payGoods.go",
"payLive.go",
"resource.go",
"roomMng.go",
"splash.go",
"token.go",
"upload.go",
],
importpath = "go-common/app/admin/live/live-admin/service/v1",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/live/live-admin/api/http/v1:go_default_library",
"//app/admin/live/live-admin/conf:go_default_library",
"//app/admin/live/live-admin/dao:go_default_library",
"//app/admin/live/live-admin/model:go_default_library",
"//app/service/live/av/api/liverpc/v0:go_default_library",
"//app/service/live/relation/api/liverpc/v1:go_default_library",
"//app/service/live/resource/api/grpc/v1:go_default_library",
"//app/service/live/room/api/liverpc:go_default_library",
"//app/service/live/room/api/liverpc/v1:go_default_library",
"//app/service/live/xlottery/api/grpc/v1:go_default_library",
"//app/service/video/stream-mng/api/v1:go_default_library",
"//library/database/bfs:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/sync/errgroup:go_default_library",
"@org_golang_google_grpc//status:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
go_test(
name = "go_default_test",
srcs = ["token_test.go"],
embed = [":go_default_library"],
tags = ["automanaged"],
deps = [
"//app/admin/live/live-admin/api/http/v1:go_default_library",
"//app/admin/live/live-admin/conf:go_default_library",
"//app/admin/live/live-admin/dao:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)

View File

@ -0,0 +1,38 @@
package v1
import (
"context"
v1pb "go-common/app/admin/live/live-admin/api/http/v1"
"go-common/app/admin/live/live-admin/conf"
)
// BannerService struct
type BannerService struct {
conf *conf.Config
// optionally add other properties here, such as dao
// dao *dao.Dao
}
//NewBannerService init
func NewBannerService(c *conf.Config) (s *BannerService) {
s = &BannerService{
conf: c,
}
return s
}
// GetBlinkBanner implementation
// 获取有效banner配置
// `method:"GET" internal:"true" `
func (s *BannerService) GetBlinkBanner(ctx context.Context, req *v1pb.GetInfoReq) (resp *v1pb.GetInfoResp, err error) {
resp = &v1pb.GetInfoResp{}
return
}
// GetBanner implementation
// 获取有效banner配置
// `method:"GET" internal:"true" `
func (s *BannerService) GetBanner(ctx context.Context, req *v1pb.GetBannerReq) (resp *v1pb.GetBannerResp, err error) {
resp = &v1pb.GetBannerResp{}
return
}

View File

@ -0,0 +1,547 @@
package v1
import (
"context"
"encoding/json"
"go-common/library/ecode"
"regexp"
"strconv"
"strings"
"time"
"google.golang.org/grpc/status"
v1pb "go-common/app/admin/live/live-admin/api/http/v1"
"go-common/app/admin/live/live-admin/conf"
rspb "go-common/app/service/live/xlottery/api/grpc/v1"
"go-common/library/log"
)
// CapsuleService struct
type CapsuleService struct {
conf *conf.Config
// optionally add other properties here, such as dao
// dao *dao.Dao
capsuleCli *rspb.Client
}
//NewCapsuleService init
func NewCapsuleService(c *conf.Config) (s *CapsuleService) {
s = &CapsuleService{
conf: c,
}
var svc *rspb.Client
var err error
log.Info("CapsuleService Init: %+v", s.conf.CapsuleClient)
if svc, err = rspb.NewClient(s.conf.CapsuleClient); err != nil {
panic(err)
}
s.capsuleCli = svc
return s
}
// GetCoinList implementation
func (s *CapsuleService) GetCoinList(ctx context.Context, req *v1pb.GetCoinListReqAdmin) (resp *v1pb.GetCoinListRespAdmin, err error) {
var RPCResponse *rspb.GetCoinListResp
RPCReq := &rspb.GetCoinListReq{
Page: req.Page,
PageSize: req.PageSize,
}
if RPCReq.Page < 1 {
RPCReq.Page = 1
}
if RPCReq.PageSize < 1 {
RPCReq.PageSize = 16
}
RPCResponse, err = s.capsuleCli.GetCoinList(ctx, RPCReq)
if err != nil {
return
}
coinListResp := make([]*v1pb.GetCoinListRespAdmin_List, 0)
for _, singleCoinList := range RPCResponse.List {
coinList := &v1pb.GetCoinListRespAdmin_List{}
coinList.Id = singleCoinList.Id
coinList.Status = singleCoinList.Status
coinList.Title = singleCoinList.Title
coinList.GiftConfig = singleCoinList.GiftConfig
coinList.GiftType = singleCoinList.GiftType
coinList.ChangeNum = singleCoinList.ChangeNum
startTimeUnix := time.Unix(singleCoinList.StartTime, 0)
coinList.StartTime = startTimeUnix.Format("2006-01-02 15:04:05")
endTimeUnix := time.Unix(singleCoinList.EndTime, 0)
coinList.EndTime = endTimeUnix.Format("2006-01-02 15:04:05")
areaIds := make([]*v1pb.GetCoinListRespAdmin_List_AreaIds, 0)
for _, areaId := range singleCoinList.AreaIds {
singleAreaId := &v1pb.GetCoinListRespAdmin_List_AreaIds{}
singleAreaId.IsAll = areaId.IsAll
singleAreaId.List = areaId.List
singleAreaId.ParentId = areaId.ParentId
areaIds = append(areaIds, singleAreaId)
}
coinList.AreaIds = areaIds
coinListResp = append(coinListResp, coinList)
}
resp = &v1pb.GetCoinListRespAdmin{
Total: RPCResponse.Total,
TotalPage: RPCResponse.TotalPage,
List: coinListResp,
}
return
}
// UpdateCoinConfig implementation
func (s *CapsuleService) UpdateCoinConfig(ctx context.Context, req *v1pb.UpdateCoinConfigReqAdmin) (resp *v1pb.UpdateCoinConfigRespAdmin, err error) {
var RPCResponse *rspb.UpdateCoinConfigResp
loc, _ := time.LoadLocation("Local")
var endTime, startTime time.Time
startTime, err = time.ParseInLocation("2006-01-02 15:04:05", req.StartTime, loc)
if err != nil {
err = ecode.Error(ecode.InvalidParam, "参数错误")
return nil, err
}
endTime, err = time.ParseInLocation("2006-01-02 15:04:05", req.EndTime, loc)
if err != nil {
err = ecode.Error(ecode.InvalidParam, "参数错误")
return nil, err
}
var areaIds []*rspb.UpdateCoinConfigReq_AreaIds
err = json.Unmarshal([]byte(req.AreaIds), &areaIds)
if err != nil {
err = ecode.Error(ecode.InvalidParam, "参数错误")
return nil, err
}
if len(areaIds) == 0 {
err = ecode.Error(ecode.InvalidParam, "参数错误")
return nil, err
}
var isHasArea bool
for _, areaInfo := range areaIds {
if areaInfo.IsAll == 1 {
isHasArea = true
break
}
if len(areaInfo.List) > 0 {
isHasArea = true
break
}
}
if !isHasArea {
err = ecode.Error(ecode.XLotteryCapsuleAreaParamErr, "必须设置生效分区")
return nil, err
}
var giftIds = make([]int64, 0)
if req.GiftType == 3 {
if req.GiftConfig == "" {
err = ecode.Error(ecode.InvalidParam, "参数错误")
return nil, err
}
giftConfig := strings.Split(req.GiftConfig, ",")
for _, giftStr := range giftConfig {
var giftId int64
giftId, err = strconv.ParseInt(giftStr, 10, 64)
if err != nil {
err = ecode.Error(ecode.InvalidParam, "参数错误")
return nil, err
}
giftIds = append(giftIds, giftId)
}
if len(giftIds) == 0 {
err = ecode.Error(ecode.InvalidParam, "参数错误")
return nil, err
}
match, _ := regexp.Compile("^([0-9]+,)*[0-9]+$")
if !match.MatchString(req.GiftConfig) {
err = ecode.Error(ecode.InvalidParam, "参数错误")
return nil, err
}
}
RPCReq := &rspb.UpdateCoinConfigReq{
Id: req.Id,
Title: req.Title,
ChangeNum: req.ChangeNum,
StartTime: startTime.Unix(),
EndTime: endTime.Unix(),
Status: req.Status,
GiftType: req.GiftType,
GiftIds: giftIds,
AreaIds: areaIds,
}
RPCResponse, err = s.capsuleCli.UpdateCoinConfig(ctx, RPCReq)
if err != nil {
return
}
resp = &v1pb.UpdateCoinConfigRespAdmin{
Status: RPCResponse.Status,
}
return
}
// UpdateCoinStatus implementation
func (s *CapsuleService) UpdateCoinStatus(ctx context.Context, req *v1pb.UpdateCoinStatusReqAdmin) (resp *v1pb.UpdateCoinStatusRespAdmin, err error) {
var RPCResponse *rspb.UpdateCoinStatusResp
RPCReq := &rspb.UpdateCoinStatusReq{
Id: req.Id,
Status: req.Status,
}
if RPCReq.Status != 1 {
RPCReq.Status = 0
}
RPCResponse, err = s.capsuleCli.UpdateCoinStatus(ctx, RPCReq)
if err != nil {
return
}
resp = &v1pb.UpdateCoinStatusRespAdmin{
Status: RPCResponse.Status,
}
return
}
// DeleteCoin implementation
func (s *CapsuleService) DeleteCoin(ctx context.Context, req *v1pb.DeleteCoinReqAdmin) (resp *v1pb.DeleteCoinRespAdmin, err error) {
var RPCResponse *rspb.DeleteCoinResp
RPCReq := &rspb.DeleteCoinReq{
Id: req.Id,
}
RPCResponse, err = s.capsuleCli.DeleteCoin(ctx, RPCReq)
if err != nil {
return
}
resp = &v1pb.DeleteCoinRespAdmin{
Status: RPCResponse.Status,
}
return
}
// GetPoolList implementation
// `internal:"true"`
func (s *CapsuleService) GetPoolList(ctx context.Context, req *v1pb.GetPoolListReqAdmin) (resp *v1pb.GetPoolListRespAdmin, err error) {
var RPCResponse *rspb.GetPoolListResp
RPCReq := &rspb.GetPoolListReq{
Page: req.Page,
PageSize: req.PageSize,
}
if RPCReq.Page < 1 {
RPCReq.Page = 1
}
if RPCReq.PageSize < 1 {
RPCReq.PageSize = 16
}
RPCResponse, err = s.capsuleCli.GetPoolList(ctx, RPCReq)
if err != nil {
return
}
poolList := make([]*v1pb.GetPoolListRespAdmin_List, 0)
for _, singleList := range RPCResponse.List {
poolInfo := &v1pb.GetPoolListRespAdmin_List{}
poolInfo.Id = singleList.Id
startTimeUnix := time.Unix(singleList.StartTime, 0)
poolInfo.StartTime = startTimeUnix.Format("2006-01-02 15:04:05")
endTimeUnix := time.Unix(singleList.EndTime, 0)
poolInfo.EndTime = endTimeUnix.Format("2006-01-02 15:04:05")
poolInfo.Title = singleList.Title
poolInfo.CoinTitle = singleList.CoinTitle
poolInfo.Status = singleList.Status
poolInfo.Rule = singleList.Rule
poolInfo.CoinId = singleList.CoinId
poolList = append(poolList, poolInfo)
}
resp = &v1pb.GetPoolListRespAdmin{
Total: RPCResponse.Total,
TotalPage: RPCResponse.TotalPage,
List: poolList,
}
return
}
// UpdatePool implementation
// `method:"POST" internal:"true"`
func (s *CapsuleService) UpdatePool(ctx context.Context, req *v1pb.UpdatePoolReqAdmin) (resp *v1pb.UpdatePoolRespAdmin, err error) {
var RPCResponse *rspb.UpdatePoolResp
loc, _ := time.LoadLocation("Local")
startTime, err := time.ParseInLocation("2006-01-02 15:04:05", req.StartTime, loc)
if err != nil {
err = ecode.Error(ecode.InvalidParam, "参数错误")
return nil, err
}
endTime, err := time.ParseInLocation("2006-01-02 15:04:05", req.EndTime, loc)
if err != nil {
err = ecode.Error(ecode.InvalidParam, "参数错误")
return nil, err
}
RPCReq := &rspb.UpdatePoolReq{
Id: req.Id,
CoinId: req.CoinId,
Title: req.Title,
StartTime: startTime.Unix(),
EndTime: endTime.Unix(),
Rule: req.Rule,
}
RPCResponse, err = s.capsuleCli.UpdatePool(ctx, RPCReq)
if err != nil {
return
}
resp = &v1pb.UpdatePoolRespAdmin{
Status: RPCResponse.Status,
}
return
}
// DeletePool implementation
func (s *CapsuleService) DeletePool(ctx context.Context, req *v1pb.DeletePoolReqAdmin) (resp *v1pb.DeletePoolRespAdmin, err error) {
var RPCResponse *rspb.DeletePoolResp
RPCReq := &rspb.DeletePoolReq{
Id: req.Id,
}
RPCResponse, err = s.capsuleCli.DeletePool(ctx, RPCReq)
if err != nil {
return
}
resp = &v1pb.DeletePoolRespAdmin{
Status: RPCResponse.Status,
}
return
}
// UpdatePoolStatus implementation
func (s *CapsuleService) UpdatePoolStatus(ctx context.Context, req *v1pb.UpdatePoolStatusReqAdmin) (resp *v1pb.UpdatePoolStatusRespAdmin, err error) {
resp = &v1pb.UpdatePoolStatusRespAdmin{}
data, err := s.capsuleCli.UpdatePoolStatus(ctx, &rspb.UpdatePoolStatusReq{Id: req.Id, Status: req.Status})
if err != nil {
return
}
resp.Status = data.Status
return
}
// GetPoolPrize implementation
// `internal:"true"`
func (s *CapsuleService) GetPoolPrize(ctx context.Context, req *v1pb.GetPoolPrizeReqAdmin) (resp *v1pb.GetPoolPrizeRespAdmin, err error) {
var RPCResponse *rspb.GetPoolPrizeResp
RPCReq := &rspb.GetPoolPrizeReq{
PoolId: req.PoolId,
}
RPCResponse, err = s.capsuleCli.GetPoolPrize(ctx, RPCReq)
if err != nil {
return
}
list := make([]*v1pb.GetPoolPrizeRespAdmin_List, 0)
for _, poolDetail := range RPCResponse.List {
singleDetail := &v1pb.GetPoolPrizeRespAdmin_List{}
singleDetail.Id = poolDetail.Id
singleDetail.Limit = poolDetail.Limit
singleDetail.Loop = poolDetail.Loop
singleDetail.Chance = poolDetail.Chance
singleDetail.ProType = poolDetail.ProType
singleDetail.JumpUrl = poolDetail.JumpUrl
singleDetail.Description = poolDetail.Description
singleDetail.MobileUrl = poolDetail.MobileUrl
singleDetail.WebUrl = poolDetail.WebUrl
singleDetail.Num = poolDetail.Num
singleDetail.Type = poolDetail.Type
singleDetail.ObjectId = poolDetail.ObjectId
singleDetail.Expire = poolDetail.Expire
singleDetail.PoolId = poolDetail.PoolId
singleDetail.Name = poolDetail.Name
singleDetail.Weight = poolDetail.Weight
singleDetail.WhiteUids = ""
wlen := len(poolDetail.WhiteUids)
if wlen > 0 {
wUids := make([]string, wlen)
for ix, uid := range poolDetail.WhiteUids {
wUids[ix] = strconv.FormatInt(uid, 10)
}
singleDetail.WhiteUids = strings.Join(wUids, ",")
}
list = append(list, singleDetail)
}
resp = &v1pb.GetPoolPrizeRespAdmin{
List: list,
}
return
}
// UpdatePoolPrize implementation
// `method:"POST" internal:"true"`
func (s *CapsuleService) UpdatePoolPrize(ctx context.Context, req *v1pb.UpdatePoolPrizeReqAdmin) (resp *v1pb.UpdatePoolPrizeRespAdmin, err error) {
chance, err := strconv.ParseFloat(req.Chance, 64)
if err != nil || chance > 1 {
err = ecode.Error(ecode.InvalidParam, "参数错误")
return
}
chance = chance*10000 + 0.5
whiteUids := make([]int64, 0)
if req.ProType == 1 {
if chance < 1 {
err = ecode.Error(ecode.InvalidParam, "参数错误")
return
}
req.Loop = 0
req.Limit = 0
} else if req.ProType == 2 {
chance = 0
if req.Loop < 1 || req.Limit < 1 {
err = ecode.Error(ecode.InvalidParam, "参数错误")
return
}
} else if req.ProType == 3 {
chance = 0
if req.Loop < 1 || req.Limit < 1 {
err = ecode.Error(ecode.InvalidParam, "参数错误")
return
}
} else if req.ProType == 4 {
chance = 0
req.Loop = 0
req.Limit = 0
if req.WhiteUids == "" {
err = ecode.Error(ecode.InvalidParam, "参数错误")
return
}
wUids := strings.Split(req.WhiteUids, ",")
for _, uidStr := range wUids {
var uid int64
uid, err = strconv.ParseInt(uidStr, 10, 64)
if err != nil {
err = ecode.Error(ecode.InvalidParam, "参数错误")
return nil, err
}
whiteUids = append(whiteUids, uid)
}
wlen := len(whiteUids)
if wlen == 0 || wlen > 1000 {
err = ecode.Error(ecode.InvalidParam, "参数错误")
return nil, err
}
} else {
err = ecode.Error(ecode.InvalidParam, "参数错误")
return
}
var RPCResponse *rspb.UpdatePoolPrizeResp
RPCReq := &rspb.UpdatePoolPrizeReq{
Id: req.Id,
PoolId: req.PoolId,
Type: req.Type,
Num: req.Num,
ObjectId: req.ObjectId,
Expire: req.Expire,
WebUrl: req.WebUrl,
MobileUrl: req.MobileUrl,
Description: req.Description,
JumpUrl: req.JumpUrl,
ProType: req.ProType,
Chance: int64(chance),
Loop: req.Loop,
Limit: req.Limit,
Weight: req.Weight,
WhiteUids: whiteUids,
}
RPCResponse, err = s.capsuleCli.UpdatePoolPrize(ctx, RPCReq)
if err != nil {
return
}
resp = &v1pb.UpdatePoolPrizeRespAdmin{
Status: RPCResponse.Status,
PrizeId: RPCResponse.PrizeId,
}
return
}
// DeletePoolPrize implementation
// `method:"POST" internal:"true" `
func (s *CapsuleService) DeletePoolPrize(ctx context.Context, req *v1pb.DeletePoolPrizeReqAdmin) (resp *v1pb.DeletePoolPrizeRespAdmin, err error) {
var RPCResponse *rspb.DeletePoolPrizeResp
RPCReq := &rspb.DeletePoolPrizeReq{
Id: req.Id,
}
RPCResponse, err = s.capsuleCli.DeletePoolPrize(ctx, RPCReq)
if err != nil {
return
}
resp = &v1pb.DeletePoolPrizeRespAdmin{
Status: RPCResponse.Status,
}
return
}
// GetPrizeType implementation
// `internal:"true"`
func (s *CapsuleService) GetPrizeType(ctx context.Context, req *v1pb.GetPrizeTypeReq) (resp *v1pb.GetPrizeTypeResp, err error) {
resp = &v1pb.GetPrizeTypeResp{}
prizeType, err := s.capsuleCli.GetPrizeType(ctx, &rspb.GetPrizeTypeReq{})
if err != nil || prizeType == nil {
return
}
resp.List = make([]*v1pb.GetPrizeTypeResp_List, len(prizeType.List))
for ix, data := range prizeType.List {
resp.List[ix] = &v1pb.GetPrizeTypeResp_List{Type: data.Type, Name: data.Name}
}
return
}
// GetPrizeExpire implementation
// `internal:"true"`
func (s *CapsuleService) GetPrizeExpire(ctx context.Context, req *v1pb.GetPrizeExpireReq) (resp *v1pb.GetPrizeExpireResp, err error) {
resp = &v1pb.GetPrizeExpireResp{}
prizeExpire, err := s.capsuleCli.GetPrizeExpire(ctx, &rspb.GetPrizeExpireReq{})
if err != nil || prizeExpire == nil {
return
}
resp.List = make([]*v1pb.GetPrizeExpireResp_List, len(prizeExpire.List))
for ix, data := range prizeExpire.List {
resp.List[ix] = &v1pb.GetPrizeExpireResp_List{Expire: data.Expire, Name: data.Name}
}
return
}
// FormatErr format error msg
func (s *CapsuleService) FormatErr(statusCode *status.Status) (code int32, msg string) {
gCode := statusCode.Code()
code = 1
if gCode == 2 {
code, _ := strconv.Atoi(statusCode.Message())
switch code {
case -400:
msg = "参数错误"
case -401:
msg = "上线失败概率设置不为1"
case -402:
msg = "保底奖池的上下线时间不可修改"
case -403:
msg = "保底奖池不可下线"
case -404:
msg = "普通扭蛋币不可更改道具类型"
case -500:
msg = "内部错误"
default:
msg = "内部错误"
}
} else {
msg = "内部错误"
}
return
}
// GetCouponList implementation
// `internal:"true"`
func (s *CapsuleService) GetCouponList(ctx context.Context, req *v1pb.CapsuleGetCouponListReq) (resp *v1pb.CapsuleGetCouponListResp, err error) {
resp = &v1pb.CapsuleGetCouponListResp{}
couponList, err := s.capsuleCli.GetCouponList(ctx, &rspb.CapsuleGetCouponListReq{Uid: req.Uid})
if err != nil || couponList == nil {
return
}
resp.List = make([]*v1pb.CapsuleGetCouponListResp_List, len(couponList.List))
for ix, conpon := range couponList.List {
resp.List[ix] = &v1pb.CapsuleGetCouponListResp_List{}
resp.List[ix].Uid = req.Uid
resp.List[ix].Status = conpon.Status
resp.List[ix].AwardTime = conpon.AwardTime
resp.List[ix].RetryTime = conpon.RetryTime
resp.List[ix].AwardName = conpon.AwardName
resp.List[ix].AwardCode = conpon.AwardCode
}
return
}

View File

@ -0,0 +1,158 @@
package v1
import (
"context"
"strconv"
"google.golang.org/grpc/status"
v1pb "go-common/app/admin/live/live-admin/api/http/v1"
"go-common/app/admin/live/live-admin/conf"
client "go-common/app/service/live/resource/api/grpc/v1"
"go-common/library/ecode"
)
// GaeaService struct
type GaeaService struct {
conf *conf.Config
client *client.Client
// optionally add other properties here, such as dao
// dao *dao.Dao
}
//NewGaeaService init
func NewGaeaService(c *conf.Config) (s *GaeaService) {
s = &GaeaService{
conf: c,
}
s.client, _ = client.NewClient(c.ResourceClient)
return s
}
// GetConfigByKeyword implementation
// 获取team下某个keyword的配置 `internal:"true"`
func (s *GaeaService) GetConfigByKeyword(ctx context.Context, req *v1pb.GetConfigReq) (resp *v1pb.GetConfigResp, err error) {
resp = &v1pb.GetConfigResp{}
if "" == req.GetKeyword() || 0 == req.GetTeam() {
err = ecode.Error(1, "参数错误")
return
}
ret, err := s.client.GetConfigByKeyword(ctx, &client.GetConfigReq{
Team: req.GetTeam(),
Keyword: req.GetKeyword(),
})
if err != nil {
return
}
resp.Team = ret.Team
resp.Keyword = ret.Keyword
resp.Name = ret.Name
resp.Value = ret.Value
resp.Ctime = ret.Ctime
resp.Mtime = ret.Mtime
resp.Status = ret.Status
resp.Id = ret.Id
return
}
// SetConfigByKeyword implementation
// 设置team下某个keyword配置 `internal:"true"`
func (s *GaeaService) SetConfigByKeyword(ctx context.Context, req *v1pb.SetConfigReq) (resp *v1pb.SetConfigResp, err error) {
resp = &v1pb.SetConfigResp{}
if "" == req.GetKeyword() || len(req.GetKeyword()) > 16 {
err = ecode.Error(1, "参数错误")
return
}
ret, err := s.client.SetConfigByKeyword(ctx, &client.SetConfigReq{
Team: req.GetTeam(),
Keyword: req.GetKeyword(),
Value: req.GetValue(),
Name: req.GetName(),
Id: req.GetId(),
Status: req.GetStatus(),
})
if err != nil {
return
}
resp.Id = ret.Id
return
}
// GetConfigsByParams implementation
// 管理后台根据条件获取配置 `internal:"true"`
func (s *GaeaService) GetConfigsByParams(ctx context.Context, req *v1pb.ParamsConfigReq) (resp *v1pb.ParamsConfigResp, err error) {
resp = &v1pb.ParamsConfigResp{}
clientResp, err := s.client.GetConfigsByParams(ctx, &client.ParamsConfigReq{
Team: req.GetTeam(),
Keyword: req.GetKeyword(),
Name: req.GetName(),
Status: req.GetStatus(),
Page: req.GetPage(),
PageSize: req.GetPageSize(),
Id: req.GetId(),
})
resp.TotalNum = clientResp.TotalNum
resp.List = []*v1pb.List{}
for _, v := range clientResp.List {
detail := &v1pb.List{
Id: v.Id,
Team: v.Team,
Keyword: v.Keyword,
Name: v.Name,
Value: v.Value,
Ctime: v.Ctime,
Mtime: v.Mtime,
Status: v.Status,
}
resp.List = append(resp.List, detail)
}
if err != nil {
return
}
return
}
// FormatErr format error msg
func (s *GaeaService) FormatErr(statusCode *status.Status) (code int32, msg string) {
gCode := statusCode.Code()
code = 1
if gCode == 2 {
code, _ := strconv.Atoi(statusCode.Message())
switch code {
case 1:
msg = "必要参数不正确"
case 11:
msg = "索引名称在分组内冲突"
case -500:
msg = "内部错误"
default:
msg = "内部错误"
}
} else {
msg = "内部错误"
}
return
}
// GetConfigsByTeam implementation
// 获取单个team的全部配置 `internal:"true"`
func (s *GaeaService) GetConfigsByTeam(ctx context.Context, req *v1pb.TeamConfigReq) (resp *v1pb.TeamConfigResp, err error) {
resp = &v1pb.TeamConfigResp{}
return
}
// GetConfigsByKeyword implementation
// 通过keyword获取配置 `internal:"true"`
func (s *GaeaService) GetConfigsByKeyword(ctx context.Context, req *v1pb.GetConfigsReq) (resp *v1pb.GetConfigsResp, err error) {
resp = &v1pb.GetConfigsResp{}
return
}
// GetConfigsByTeams implementation
// 获取多个team下的全部配置 `internal:"true"`
func (s *GaeaService) GetConfigsByTeams(ctx context.Context, req *v1pb.TeamsConfigReq) (resp *v1pb.TeamsConfigResp, err error) {
resp = &v1pb.TeamsConfigResp{}
return
}

View File

@ -0,0 +1,161 @@
package v1
import (
"context"
v1pb "go-common/app/admin/live/live-admin/api/http/v1"
"go-common/app/admin/live/live-admin/conf"
"go-common/app/admin/live/live-admin/dao"
v0av "go-common/app/service/live/av/api/liverpc/v0"
"go-common/library/ecode"
"go-common/library/log"
)
// PayGoodsService struct
type PayGoodsService struct {
conf *conf.Config
// optionally add other properties here, such as dao
// dao *dao.Dao
}
//NewPayGoodsService init
func NewPayGoodsService(c *conf.Config) (s *PayGoodsService) {
s = &PayGoodsService{
conf: c,
}
return s
}
// Add implementation
// * 生成一张付费直播票
func (s *PayGoodsService) Add(ctx context.Context, req *v1pb.PayGoodsAddReq) (resp *v1pb.PayGoodsAddResp, err error) {
resp = &v1pb.PayGoodsAddResp{}
log.Info("Add params:%v", req)
r, err := dao.AvApi.V0PayGoods.Add(ctx, &v0av.PayGoodsAddReq{
Platform: req.Platform,
Title: req.Title,
Type: req.Type,
Price: req.Price,
StartTime: req.StartTime,
EndTime: req.EndTime,
IpLimit: req.IpLimit,
})
if err != nil {
log.Error("call av error,err:%v", err)
return
}
if r.Code != 0 {
log.Error("call av error,code:%v,msg:%v", r.Code, r.Msg)
err = ecode.Error(ecode.Int(int(r.Code)), r.Msg)
return
}
return
}
// Update implementation
// * 更新一张付费直播票
func (s *PayGoodsService) Update(ctx context.Context, req *v1pb.PayGoodsUpdateReq) (resp *v1pb.PayGoodsUpdateResp, err error) {
resp = &v1pb.PayGoodsUpdateResp{}
log.Info("Update params:%v", req)
r, err := dao.AvApi.V0PayGoods.Update(ctx, &v0av.PayGoodsUpdateReq{
Id: req.Id,
Platform: req.Platform,
Title: req.Title,
Type: req.Type,
Price: req.Price,
StartTime: req.StartTime,
EndTime: req.EndTime,
IpLimit: req.IpLimit,
})
if err != nil {
log.Error("call av error,err:%v", err)
return
}
if r.Code != 0 {
log.Error("call av error,code:%v,msg:%v", r.Code, r.Msg)
err = ecode.Error(ecode.Int(int(r.Code)), r.Msg)
return
}
return
}
// GetList implementation
// * 获取付费直播票列表
func (s *PayGoodsService) GetList(ctx context.Context, req *v1pb.PayGoodsGetListReq) (resp *v1pb.PayGoodsGetListResp, err error) {
resp = &v1pb.PayGoodsGetListResp{}
r, err := dao.AvApi.V0PayGoods.GetList(ctx, &v0av.PayGoodsGetListReq{
Id: req.Id,
Platform: req.Platform,
Title: req.Title,
Type: req.Type,
IpLimit: req.IpLimit,
PageNum: req.PageNum,
PageSize: req.PageSize,
})
if err != nil {
log.Error("call av error,err:%v", err)
return
}
if r.Code != 0 {
log.Error("call av error,code:%v,msg:%v", r.Code, r.Msg)
err = ecode.Error(ecode.Int(int(r.Code)), r.Msg)
return
}
data := r.Data
resp.PageInfo = &v1pb.PayGoodsGetListResp_PageInfo{
TotalCount: data.PageInfo.TotalCount,
PageNum: data.PageInfo.PageNum,
}
for _, v := range r.Data.GoodsInfo {
tmp := &v1pb.PayGoodsGetListResp_GoodsInfo{
Id: v.Id,
Title: v.Title,
Platform: v.Platform,
Type: v.Type,
Price: v.Price,
StartTime: v.StartTime,
EndTime: v.EndTime,
IpLimit: v.IpLimit,
Status: v.Status,
}
resp.GoodsInfo = append(resp.GoodsInfo, tmp)
}
return
}
// Close implementation
// * 关闭购票
func (s *PayGoodsService) Close(ctx context.Context, req *v1pb.PayGoodsCloseReq) (resp *v1pb.PayGoodsCloseResp, err error) {
resp = &v1pb.PayGoodsCloseResp{}
r, err := dao.AvApi.V0PayGoods.Close(ctx, &v0av.PayGoodsCloseReq{
Id: req.Id,
})
if err != nil {
log.Error("call av error,err:%v", err)
return
}
if r.Code != 0 {
log.Error("call av error,code:%v,msg:%v", r.Code, r.Msg)
err = ecode.Error(ecode.Int(int(r.Code)), r.Msg)
return
}
return
}
// Open implementation
// * 开启购票
func (s *PayGoodsService) Open(ctx context.Context, req *v1pb.PayGoodsOpenReq) (resp *v1pb.PayGoodsOpenResp, err error) {
resp = &v1pb.PayGoodsOpenResp{}
r, err := dao.AvApi.V0PayGoods.Open(ctx, &v0av.PayGoodsOpenReq{
Id: req.Id,
})
if err != nil {
log.Error("call av error,err:%v", err)
return
}
if r.Code != 0 {
log.Error("call av error,code:%v,msg:%v", r.Code, r.Msg)
err = ecode.Error(ecode.Int(int(r.Code)), r.Msg)
return
}
return
}

View File

@ -0,0 +1,177 @@
package v1
import (
"context"
v1pb "go-common/app/admin/live/live-admin/api/http/v1"
"go-common/app/admin/live/live-admin/conf"
"go-common/app/admin/live/live-admin/dao"
v0av "go-common/app/service/live/av/api/liverpc/v0"
"go-common/library/ecode"
"go-common/library/log"
)
// PayLiveService struct
type PayLiveService struct {
conf *conf.Config
// optionally add other properties here, such as dao
// dao *dao.Dao
}
//NewPayLiveService init
func NewPayLiveService(c *conf.Config) (s *PayLiveService) {
s = &PayLiveService{
conf: c,
}
return s
}
// Add implementation
// `method:"POST" internal:"true"` 生成付费直播信息
func (s *PayLiveService) Add(ctx context.Context, req *v1pb.PayLiveAddReq) (resp *v1pb.PayLiveAddResp, err error) {
resp = &v1pb.PayLiveAddResp{}
log.Info("Add params:%v", req)
r, err := dao.AvApi.V0PayLive.Add(ctx, &v0av.PayLiveAddReq{
Platform: req.Platform,
RoomId: req.RoomId,
Title: req.Title,
Status: req.Status,
StartTime: req.StartTime,
EndTime: req.EndTime,
LiveEndTime: req.LiveEndTime,
LivePic: req.LivePic,
AdPic: req.AdPic,
GoodsLink: req.GoodsLink,
GoodsId: req.GoodsId,
IpLimit: req.IpLimit,
BuyGoodsId: req.BuyGoodsId,
})
if err != nil {
log.Error("call av error,err:%v", err)
return
}
if r.Code != 0 {
log.Error("call av error,code:%v,msg:%v", r.Code, r.Msg)
err = ecode.Error(ecode.Int(int(r.Code)), r.Msg)
return
}
return
}
// Update implementation
// `method:"POST" internal:"true"` 更新付费直播信息
func (s *PayLiveService) Update(ctx context.Context, req *v1pb.PayLiveUpdateReq) (resp *v1pb.PayLiveUpdateResp, err error) {
resp = &v1pb.PayLiveUpdateResp{}
log.Info("Update params:%v", req)
r, err := dao.AvApi.V0PayLive.Update(ctx, &v0av.PayLiveUpdateReq{
LiveId: req.LiveId,
Platform: req.Platform,
RoomId: req.RoomId,
Title: req.Title,
Status: req.Status,
StartTime: req.StartTime,
EndTime: req.EndTime,
LiveEndTime: req.LiveEndTime,
LivePic: req.LivePic,
AdPic: req.AdPic,
GoodsLink: req.GoodsLink,
GoodsId: req.GoodsId,
IpLimit: req.IpLimit,
BuyGoodsId: req.BuyGoodsId,
})
if err != nil {
log.Error("call av error,err:%v", err)
return
}
if r.Code != 0 {
log.Error("call av error,code:%v,msg:%v", r.Code, r.Msg)
err = ecode.Error(ecode.Int(int(r.Code)), r.Msg)
return
}
return
}
// GetList implementation
// `method:"POST" internal:"true"` 获取付费直播列表
func (s *PayLiveService) GetList(ctx context.Context, req *v1pb.PayLiveGetListReq) (resp *v1pb.PayLiveGetListResp, err error) {
resp = &v1pb.PayLiveGetListResp{}
r, err := dao.AvApi.V0PayLive.GetList(ctx, &v0av.PayLiveGetListReq{
RoomId: req.RoomId,
Title: req.Title,
IpLimit: req.IpLimit,
PageNum: req.PageNum,
PageSize: req.PageSize,
})
if err != nil {
log.Error("call av error,err:%v", err)
return
}
if r.Code != 0 {
log.Error("call av error,code:%v,msg:%v", r.Code, r.Msg)
err = ecode.Error(ecode.Int(int(r.Code)), r.Msg)
return
}
data := r.Data
resp.PageInfo = &v1pb.PayLiveGetListResp_PageInfo{
TotalCount: data.PageInfo.TotalCount,
PageNum: data.PageInfo.PageNum,
}
for _, v := range r.Data.GoodsInfo {
tmp := &v1pb.PayLiveGetListResp_GoodsInfo{
LiveId: v.LiveId,
Platform: v.Platform,
RoomId: v.RoomId,
Title: v.Title,
Status: v.Status,
PayLiveStatus: v.PayLiveStatus,
StartTime: v.StartTime,
EndTime: v.EndTime,
LiveEndTime: v.LiveEndTime,
LivePic: v.LivePic,
AdPic: v.AdPic,
GoodsLink: v.GoodsLink,
GoodsId: v.GoodsId,
IpLimit: v.IpLimit,
BuyGoodsId: v.BuyGoodsId,
}
resp.GoodsInfo = append(resp.GoodsInfo, tmp)
}
return
}
// Close implementation
// `method:"POST" internal:"true"` 关闭鉴权
func (s *PayLiveService) Close(ctx context.Context, req *v1pb.PayLiveCloseReq) (resp *v1pb.PayLiveCloseResp, err error) {
resp = &v1pb.PayLiveCloseResp{}
r, err := dao.AvApi.V0PayLive.Close(ctx, &v0av.PayLiveCloseReq{
LiveId: req.LiveId,
})
if err != nil {
log.Error("call av error,err:%v", err)
return
}
if r.Code != 0 {
log.Error("call av error,code:%v,msg:%v", r.Code, r.Msg)
err = ecode.Error(ecode.Int(int(r.Code)), r.Msg)
return
}
return
}
// Open implementation
// `method:"POST" internal:"true"` 开启鉴权
func (s *PayLiveService) Open(ctx context.Context, req *v1pb.PayLiveOpenReq) (resp *v1pb.PayLiveOpenResp, err error) {
resp = &v1pb.PayLiveOpenResp{}
r, err := dao.AvApi.V0PayLive.Open(ctx, &v0av.PayLiveOpenReq{
LiveId: req.LiveId,
})
if err != nil {
log.Error("call av error,err:%v", err)
return
}
if err != nil || r.Code != 0 {
log.Error("call av error,code:%v,msg:%v", r.Code, r.Msg)
err = ecode.Error(ecode.Int(int(r.Code)), r.Msg)
return
}
return
}

View File

@ -0,0 +1,239 @@
package v1
import (
"context"
"strings"
v1pb "go-common/app/admin/live/live-admin/api/http/v1"
"go-common/app/admin/live/live-admin/conf"
rspb "go-common/app/service/live/resource/api/grpc/v1"
"go-common/library/log"
)
// ResourceService struct
type ResourceService struct {
conf *conf.Config
// optionally add other properties here, such as dao
// dao *dao.Dao
rsCli *rspb.Client
}
//NewResourceService init
func NewResourceService(c *conf.Config) (s *ResourceService) {
s = &ResourceService{
conf: c,
}
var svc *rspb.Client
var err error
log.Info("ResourceService Init: %+v", s.conf.ResourceClient)
if svc, err = rspb.NewClient(s.conf.ResourceClient); err != nil {
panic(err)
}
s.rsCli = svc
return s
}
// Add implementation
// Add 添加资源接口
// `method:"POST" internal:"true"
func (s *ResourceService) Add(ctx context.Context, req *v1pb.AddReq) (resp *v1pb.AddResp, err error) {
respRPC, error := s.rsCli.Add(ctx, &rspb.AddReq{
Platform: req.Platform,
Title: req.Title,
JumpPath: req.JumpPath,
JumpPathType: req.JumpPathType,
JumpTime: req.JumpTime,
Type: req.Type,
Device: req.Device,
StartTime: req.StartTime,
EndTime: req.EndTime,
ImageUrl: req.ImageUrl,
})
err = error
if error == nil {
resp = &v1pb.AddResp{
Id: respRPC.Id,
}
}
return
}
// AddEx implementation
// AddEx 添加资源接口
// `method:"POST" internal:"true"
func (s *ResourceService) AddEx(ctx context.Context, req *v1pb.AddReq) (resp *v1pb.AddResp, err error) {
respRPC, error := s.rsCli.AddEx(ctx, &rspb.AddReq{
Platform: req.Platform,
Title: req.Title,
JumpPath: req.JumpPath,
JumpPathType: req.JumpPathType,
JumpTime: req.JumpTime,
Type: req.Type,
Device: req.Device,
StartTime: req.StartTime,
EndTime: req.EndTime,
ImageUrl: req.ImageUrl,
})
err = error
if error == nil {
resp = &v1pb.AddResp{
Id: respRPC.Id,
}
}
return
}
// Edit implementation
// Edit 编辑资源接口
// `method:"POST" internal:"true" `
func (s *ResourceService) Edit(ctx context.Context, req *v1pb.EditReq) (resp *v1pb.EditResp, err error) {
_, err = s.rsCli.Edit(ctx, &rspb.EditReq{
Platform: req.Platform,
Id: req.Id,
Title: req.Title,
JumpPath: req.JumpPath,
JumpTime: req.JumpTime,
StartTime: req.StartTime,
EndTime: req.EndTime,
ImageUrl: req.ImageUrl,
JumpPathType: req.JumpPathType,
})
return
}
// Offline implementation
// Offline 下线资源接口
// `method:"POST" internal:"true" `
func (s *ResourceService) Offline(ctx context.Context, req *v1pb.OfflineReq) (resp *v1pb.OfflineResp, err error) {
_, err = s.rsCli.Offline(ctx, &rspb.OfflineReq{
Platform: req.Platform,
Id: req.Id,
})
if err == nil {
resp = &v1pb.OfflineResp{}
}
return
}
// GetList implementation
// GetList 获取资源列表
// `method:"GET" internal:"true" `
func (s *ResourceService) GetList(ctx context.Context, req *v1pb.GetListReq) (resp *v1pb.GetListResp, err error) {
RPCReq := &rspb.GetListReq{
Platform: req.Platform,
Type: req.Type,
Page: req.Page,
PageSize: req.PageSize,
}
if RPCReq.Page == 0 {
RPCReq.Page = 1
}
if RPCReq.PageSize == 0 {
RPCReq.PageSize = 50
}
var RPCResp *rspb.GetListResp
RPCResp, err = s.rsCli.GetList(ctx, RPCReq)
if err == nil {
resp = &v1pb.GetListResp{
CurrentPage: RPCResp.CurrentPage,
TotalCount: RPCResp.TotalCount,
List: convertRPCList2HttpList(RPCResp.List),
}
}
return
}
// GetPlatformList implementation
// 获取平台列表
// `method:"GET" internal:"true" `
func (s *ResourceService) GetPlatformList(ctx context.Context, req *v1pb.GetPlatformListReq) (resp *v1pb.GetPlatformListResp, err error) {
var RPCResp *rspb.GetPlatformListResp
RPCResp, err = s.rsCli.GetPlatformList(ctx, &rspb.GetPlatformListReq{
Type: req.Type,
})
if err == nil {
resp = &v1pb.GetPlatformListResp{
Platform: RPCResp.Platform,
}
}
return
}
// GetListEx implementation
// GetListEx 获取资源列表
// `method:"GET" internal:"true" `
func (s *ResourceService) GetListEx(ctx context.Context, req *v1pb.GetListExReq) (resp *v1pb.GetListExResp, err error) {
var RPCResp *rspb.GetListExResp
// 默认分页参数
if req.Page == 0 {
req.Page = 1
}
if req.PageSize == 0 {
req.PageSize = 50
}
if len(req.Type) > 0 {
req.Type = strings.Split(req.Type[0], ",")
}
RPCResp, err = s.rsCli.GetListEx(ctx, &rspb.GetListExReq{
Platform: req.Platform,
Page: req.Page,
PageSize: req.PageSize,
Type: req.Type,
DevicePlatform: req.DevicePlatform,
Status: req.Status,
StartTime: req.StartTime,
EndTime: req.EndTime,
})
if err == nil {
resp = &v1pb.GetListExResp{
CurrentPage: RPCResp.CurrentPage,
TotalCount: RPCResp.TotalCount,
List: convertRPCListEx2HttpListEx(RPCResp.List),
}
}
return
}
func convertRPCList2HttpList(RPCList []*rspb.GetListResp_List) (HTTPList []*v1pb.GetListResp_List) {
HTTPList = make([]*v1pb.GetListResp_List, len(RPCList))
for index, RPCRespItem := range RPCList {
HTTPList[index] = &v1pb.GetListResp_List{
Id: RPCRespItem.Id,
Title: RPCRespItem.Title,
JumpPath: RPCRespItem.JumpPath,
DevicePlatform: RPCRespItem.DevicePlatform,
DeviceBuild: RPCRespItem.DeviceBuild,
StartTime: RPCRespItem.StartTime,
EndTime: RPCRespItem.EndTime,
Status: RPCRespItem.Status,
DeviceLimit: RPCRespItem.DeviceLimit,
ImageUrl: RPCRespItem.ImageUrl,
JumpPathType: RPCRespItem.JumpPathType,
JumpTime: RPCRespItem.JumpTime,
}
}
return
}
func convertRPCListEx2HttpListEx(RPCList []*rspb.GetListExResp_List) (HTTPList []*v1pb.GetListExResp_List) {
HTTPList = make([]*v1pb.GetListExResp_List, len(RPCList))
for index, RPCRespItem := range RPCList {
HTTPList[index] = &v1pb.GetListExResp_List{
Id: RPCRespItem.Id,
Title: RPCRespItem.Title,
JumpPath: RPCRespItem.JumpPath,
DevicePlatform: RPCRespItem.DevicePlatform,
DeviceBuild: RPCRespItem.DeviceBuild,
StartTime: RPCRespItem.StartTime,
EndTime: RPCRespItem.EndTime,
Status: RPCRespItem.Status,
DeviceLimit: RPCRespItem.DeviceLimit,
ImageUrl: RPCRespItem.ImageUrl,
JumpPathType: RPCRespItem.JumpPathType,
JumpTime: RPCRespItem.JumpTime,
Type: RPCRespItem.Type,
}
}
return
}

View File

@ -0,0 +1,175 @@
package v1
import (
"context"
"fmt"
v1pb "go-common/app/admin/live/live-admin/api/http/v1"
"go-common/app/admin/live/live-admin/conf"
"go-common/app/admin/live/live-admin/dao"
relationV1 "go-common/app/service/live/relation/api/liverpc/v1"
liveRPCCli "go-common/app/service/live/room/api/liverpc"
v1liveRPCpb "go-common/app/service/live/room/api/liverpc/v1"
"go-common/library/log"
"go-common/library/sync/errgroup"
"os"
"time"
streamPb "go-common/app/service/video/stream-mng/api/v1"
"go-common/library/ecode"
)
const timeFormat = "2006-01-02 15:04:05"
// RoomMngService struct
type RoomMngService struct {
conf *conf.Config
// optionally add other properties here, such as dao
// dao *dao.Dao
rpcCli *liveRPCCli.Client
streamCli streamPb.StreamClient
dao *dao.Dao
}
//NewRoomMngService init
func NewRoomMngService(c *conf.Config) (s *RoomMngService) {
s = &RoomMngService{
conf: c,
dao: dao.New(c),
}
log.Info("RoomMngLiveRPCClient Init: %+v", s.conf.RoomMngClient)
s.rpcCli = liveRPCCli.New(s.conf.RoomMngClient)
log.Info("Stream Mng Client Init: %+v", s.conf.StreamMngClient)
if svc, err := streamPb.NewClient(s.conf.StreamMngClient); err != nil {
panic(err)
} else {
s.streamCli = svc
}
return s
}
// GetSecondVerifyListWithPics implementation
// 获取带有图片地址的二次审核列表
// `method:"GET" internal:"true" `
func (s *RoomMngService) GetSecondVerifyListWithPics(ctx context.Context, req *v1pb.RoomMngGetSecondVerifyListReq) (resp *v1pb.RoomMngGetSecondVerifyListResp, err error) {
if req.Pagesize == 0 {
req.Pagesize = 30
}
rpcResp, err := s.rpcCli.V1RoomMng.GetSecondVerifyList(ctx, &v1liveRPCpb.RoomMngGetSecondVerifyListReq{
RoomId: req.RoomId,
Area: req.Area,
Page: req.Page,
Pagesize: req.Pagesize,
Biz: req.Biz,
})
if err != nil {
return
}
if rpcResp.Code == 0 {
result, getPicErr := s.getExtraInfo(ctx, rpcResp.Data.Result)
if getPicErr != nil {
err = getPicErr
} else {
resp = &v1pb.RoomMngGetSecondVerifyListResp{
Count: rpcResp.Data.Count,
Page: rpcResp.Data.Page,
Pagesize: rpcResp.Data.Pagesize,
Result: result,
}
}
} else {
err = ecode.Error(ecode.ServerErr, fmt.Sprintf("Room v1 RoomMng LiveRPC 业务错误: { Code: %d ; Msg: %s }", rpcResp.Code, rpcResp.Msg))
}
return
}
func (s *RoomMngService) getExtraInfo(ctx context.Context, list []*v1liveRPCpb.RoomMngGetSecondVerifyListResp_Result) (respList []*v1pb.RoomMngGetSecondVerifyListResp_Result, err error) {
picRes := make([][]string, len(list))
fcRes := make([]int64, len(list))
g, _ := errgroup.WithContext(ctx)
for i := 0; i < len(list); i++ {
x := i
// 获取指定时间内的截图
g.Go(func() error {
picRes[x] = s.getSingleRoomPic(ctx, list[x].RoomId, list[x].BreakTime)
return nil
})
// 获取粉丝计数
g.Go(func() (feedErr error) {
fcRes[x] = s.getUserFC(ctx, list[x].Uid)
return nil
})
}
if err := g.Wait(); err != nil {
log.Error("get ExtraData Error (%+v)", err)
}
respList = make([]*v1pb.RoomMngGetSecondVerifyListResp_Result, len(list))
for index, RPCRespItem := range list {
// 当截图张数大于 0 且有证据图片时,将截图第一张替换为证据图片
if len(picRes[index]) > 0 && RPCRespItem.ProofImg != "" {
picRes[index][0] = RPCRespItem.ProofImg
}
respList[index] = &v1pb.RoomMngGetSecondVerifyListResp_Result{
Id: RPCRespItem.Id,
RecentCutTimes: RPCRespItem.RecentCutTimes,
RecentWarnTimes: RPCRespItem.RecentWarnTimes,
Uname: RPCRespItem.Uname,
RoomId: RPCRespItem.RoomId,
Uid: RPCRespItem.Uid,
Title: RPCRespItem.Title,
AreaV2Name: RPCRespItem.AreaV2Name,
Fc: fcRes[index],
WarnReason: RPCRespItem.WarnReason,
BreakTime: RPCRespItem.BreakTime,
Pics: picRes[index],
WarnTimes: RPCRespItem.WarnTimes,
}
}
return
}
func (s *RoomMngService) getSingleRoomPic(ctx context.Context, roomID int64, breakTime string) (picList []string) {
// uat 环境写死 11891462 房间号
if os.Getenv("DEPLOY_ENV") == "uat" {
roomID = 11891462
}
// 计算结束时间点,规定为 5 分钟后
startTime, _ := time.Parse(timeFormat, breakTime)
endTimeStr := startTime.Add(5 * 60 * 1000 * 1000 * 1000).Format(timeFormat)
RPCResp, err := s.streamCli.GetSingleScreeShot(ctx, &streamPb.GetSingleScreeShotReq{
RoomId: roomID,
StartTime: breakTime,
EndTime: endTimeStr,
})
// log.Info("res: (%+v) err:(%+v) \n", RPCResp, err)
if err != nil {
log.Error("Get Pic Fail: error(%v) roomId(%d) startTime(%s) endTime(%s)", err, roomID, breakTime, endTimeStr)
picList = []string{
"https://static.hdslb.com/error/very_sorry.png",
}
} else {
picList = RPCResp.List
}
return
}
func (s *RoomMngService) getUserFC(ctx context.Context, UID int64) (resp int64) {
feedResp, feedErr := s.dao.Relation.V1Feed.GetUserFc(ctx, &relationV1.FeedGetUserFcReq{Follow: UID})
if feedErr != nil || feedResp.Data == nil {
resp = 0
log.Error("Get FC Error for UID(%d) with Error(%+v)", UID, feedErr)
} else {
resp = feedResp.Data.Fc
}
return
}

View File

@ -0,0 +1,30 @@
package v1
import (
"context"
v1pb "go-common/app/admin/live/live-admin/api/http/v1"
"go-common/app/admin/live/live-admin/conf"
)
// SplashService struct
type SplashService struct {
conf *conf.Config
// optionally add other properties here, such as dao
// dao *dao.Dao
}
//NewSplashService init
func NewSplashService(c *conf.Config) (s *SplashService) {
s = &SplashService{
conf: c,
}
return s
}
// GetInfo implementation
// 获取有效闪屏配置
// `method:"GET" internal:"true" `
func (s *SplashService) GetInfo(ctx context.Context, req *v1pb.GetInfoReq) (resp *v1pb.GetInfoResp, err error) {
resp = &v1pb.GetInfoResp{}
return
}

View File

@ -0,0 +1,53 @@
package v1
import (
"context"
"time"
v1pb "go-common/app/admin/live/live-admin/api/http/v1"
"go-common/app/admin/live/live-admin/conf"
"go-common/app/admin/live/live-admin/dao"
"go-common/library/ecode"
"go-common/library/log"
)
// TokenService struct
type TokenService struct {
conf *conf.Config
// optionally add other properties here, such as dao
dao *dao.Dao
}
//NewTokenService init
func NewTokenService(c *conf.Config, d *dao.Dao) (s *TokenService) {
s = &TokenService{
conf: c,
dao: d,
}
return s
}
// New implementation
// Request for a token for upload.
// `method:"POST" internal:"true"`
func (s *TokenService) New(ctx context.Context, req *v1pb.NewTokenReq) (resp *v1pb.NewTokenResp, err error) {
// Must be live's bucket.
_, ok := s.conf.Bucket[req.Bucket]
if !ok {
err = ecode.UploadBucketErr
return
}
var token string
if token, err = s.dao.RequestUploadToken(ctx, req.Bucket, req.Operator, time.Now().Unix()); err != nil {
log.Error("New a upload token failure: %v", err)
err = ecode.UploadTokenGenErr
return
}
resp = &v1pb.NewTokenResp{
Token: token,
}
return
}

View File

@ -0,0 +1,45 @@
package v1
import (
"context"
"flag"
"go-common/app/admin/live/live-admin/dao"
"testing"
"time"
v1pb "go-common/app/admin/live/live-admin/api/http/v1"
"go-common/app/admin/live/live-admin/conf"
. "github.com/smartystreets/goconvey/convey"
)
var tokenSrv *TokenService
func init() {
flag.Set("conf", "../../cmd/test.toml")
if err := conf.Init(); err != nil {
panic(err)
}
tokenSrv = NewTokenService(conf.Conf, dao.New(conf.Conf))
}
func TestUploadToken(t *testing.T) {
Convey("TestTokenService", t, func() {
req := &v1pb.NewTokenReq{
Bucket: "slive",
Operator: "KC",
}
resp, err := tokenSrv.New(context.TODO(), req)
So(err, ShouldBeNil)
So(resp.Token, ShouldNotBeEmpty)
ok := tokenSrv.dao.VerifyUploadToken(context.TODO(), resp.Token)
So(ok, ShouldBeTrue)
// Test token expiration.
time.Sleep(time.Second * 11)
ok = tokenSrv.dao.VerifyUploadToken(context.TODO(), resp.Token)
So(ok, ShouldBeFalse)
})
}

View File

@ -0,0 +1,130 @@
package v1
import (
"bytes"
"context"
"crypto/hmac"
"crypto/sha1"
"encoding/base64"
"fmt"
"io"
"net/url"
"strings"
"time"
v1pb "go-common/app/admin/live/live-admin/api/http/v1"
"go-common/app/admin/live/live-admin/conf"
"go-common/app/admin/live/live-admin/dao"
"go-common/app/admin/live/live-admin/model"
"go-common/library/database/bfs"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/http/blademaster"
)
// UploadService struct
type UploadService struct {
conf *conf.Config
// optionally add other properties here, such as dao
dao *dao.Dao
}
//NewUploadService init
func NewUploadService(c *conf.Config, d *dao.Dao) (s *UploadService) {
s = &UploadService{
conf: c,
dao: d,
}
return s
}
// File implementation
// `method:"POST" content-type:"multipart/form-data" midware:"guest"`
func (s *UploadService) File(ctx context.Context, req *v1pb.UploadFileReq) (resp *v1pb.UploadFileResp, err error) {
_, ok := s.conf.Bucket[req.Bucket]
if !ok {
err = ecode.UploadBucketErr
return
}
if !s.verify(ctx, req.Token) {
err = ecode.Error(ecode.InvalidParam, "invalid upload token")
return
}
bmc := ctx.(*blademaster.Context)
file, _, err := bmc.Request.FormFile("file_up")
if err != nil {
log.Error("Parse file part failure: %v", err)
err = ecode.Error(ecode.InvalidParam, "file not found")
return
}
defer file.Close()
fileData := new(bytes.Buffer)
if _, err = io.Copy(fileData, file); err != nil {
log.Error("Read file data failure: %v", err)
err = ecode.UploadUploadErr
return
}
resp = &v1pb.UploadFileResp{}
bfsClient := bfs.New(nil)
bfsReq := &bfs.Request{
Bucket: req.Bucket,
Dir: req.Dir,
ContentType: req.ContentType,
Filename: req.Filename,
File: fileData.Bytes(),
WMKey: req.WmKey,
WMText: req.WmText,
WMPaddingX: req.WmPaddingX,
WMPaddingY: req.WmPaddingY,
WMScale: req.WmScale,
}
model.TweakWatermark(bfsReq)
resp.Url, err = bfsClient.Upload(ctx, bfsReq)
if err != nil {
log.Error("Upload to bfs failure: %v", err)
err = ecode.UploadUploadErr
return
}
resp.Url = s.getPrivateURL(req.Bucket, resp.Url)
return
}
func (s *UploadService) verify(ctx context.Context, token string) bool {
return s.dao.VerifyUploadToken(ctx, token)
}
func (s *UploadService) getPrivateURL(bucket, fileURL string) string {
bucketConf, ok := s.conf.Bucket[bucket]
if !ok || !bucketConf.Private {
return fileURL
}
bucketFindStr := fmt.Sprintf("/%s/", bucket)
bucketIndex := strings.Index(fileURL, bucketFindStr)
if bucketIndex < 0 {
return fileURL
}
filename := fileURL[bucketIndex+len(bucketFindStr):]
now := time.Now().Unix()
mac := hmac.New(sha1.New, []byte(bucketConf.Secret))
salt := fmt.Sprintf("GET\n%s\n%s\n%d\n", bucket, filename, now)
mac.Write([]byte(salt))
sign := base64.StdEncoding.EncodeToString(mac.Sum(nil))
token := fmt.Sprintf("%s:%s:%d", bucketConf.Key, sign, now)
v := url.Values{}
v.Set("token", token)
return fmt.Sprintf("%s?%s", fileURL, v.Encode())
}

View File

@ -0,0 +1,34 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["userResource.go"],
importpath = "go-common/app/admin/live/live-admin/service/v2",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/live/live-admin/api/http/v2:go_default_library",
"//app/admin/live/live-admin/conf:go_default_library",
"//app/service/live/resource/api/grpc/v2: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,144 @@
package v2
import (
"context"
v2pb "go-common/app/admin/live/live-admin/api/http/v2"
"go-common/app/admin/live/live-admin/conf"
v2rspb "go-common/app/service/live/resource/api/grpc/v2"
"go-common/library/log"
)
// UserResourceService struct
type UserResourceService struct {
conf *conf.Config
// optionally add other properties here, such as dao
// dao *dao.Dao
v2rsCli *v2rspb.Client
}
//NewUserResourceService init
func NewUserResourceService(c *conf.Config) (s *UserResourceService) {
s = &UserResourceService{
conf: c,
}
var svc *v2rspb.Client
var err error
log.Info("ResourceServiceV2 Init: %+v", s.conf.ResourceClientV2)
if svc, err = v2rspb.NewClient(s.conf.ResourceClientV2); err != nil {
panic(err)
}
s.v2rsCli = svc
return s
}
// Add implementation
// Add 添加资源接口
// `method:"POST" internal:"true" `
func (s *UserResourceService) Add(ctx context.Context, req *v2pb.UserResourceAddReq) (resp *v2pb.UserResourceAddResp, err error) {
respRPC, err := s.v2rsCli.Add(ctx, &v2rspb.AddReq{
ResType: req.ResType,
Title: req.Title,
Url: req.Url,
Weight: req.Weight,
Creator: req.Creator,
})
if err == nil {
resp = &v2pb.UserResourceAddResp{
Id: respRPC.Id,
CustomId: respRPC.CustomId,
}
}
return
}
// Edit implementation
// Edit 编辑现有资源
// `method:"POST" internal:"true" `
func (s *UserResourceService) Edit(ctx context.Context, req *v2pb.UserResourceEditReq) (resp *v2pb.UserResourceEditResp, err error) {
resp = &v2pb.UserResourceEditResp{}
_, err = s.v2rsCli.Edit(ctx, &v2rspb.EditReq{
ResType: req.ResType,
Title: req.Title,
Url: req.Url,
Weight: req.Weight,
CustomId: req.CustomId,
})
return
}
// Get implementation
// Get 获取资源列表
// `method:"GET" internal:"true" `
func (s *UserResourceService) Get(ctx context.Context, req *v2pb.UserResourceListReq) (resp *v2pb.UserResourceListResp, err error) {
respRPC, err := s.v2rsCli.List(ctx, &v2rspb.ListReq{
ResType: req.ResType,
Page: req.Page,
PageSize: req.PageSize,
})
if err == nil {
resp = &v2pb.UserResourceListResp{
CurrentPage: respRPC.CurrentPage,
TotalCount: respRPC.TotalCount,
List: convertRPCListRes(respRPC.List),
}
}
return
}
// SetStatus implementation
// SetStatus 更改资源状态
// `method:"POST" internal:"true" `
func (s *UserResourceService) SetStatus(ctx context.Context, req *v2pb.UserResourceSetStatusReq) (resp *v2pb.UserResourceSetStatusResp, err error) {
resp = &v2pb.UserResourceSetStatusResp{}
_, err = s.v2rsCli.SetStatus(ctx, &v2rspb.SetStatusReq{
ResType: req.ResType,
CustomId: req.CustomId,
Status: req.Status,
})
return
}
// GetSingle implementation
// Query 请求单个资源
func (s *UserResourceService) GetSingle(ctx context.Context, req *v2pb.UserResourceGetSingleReq) (resp *v2pb.UserResourceGetSingleResp, err error) {
respRPC, err := s.v2rsCli.Query(ctx, &v2rspb.QueryReq{
CustomId: req.CustomId,
ResType: req.ResType,
})
if err == nil {
resp = &v2pb.UserResourceGetSingleResp{
Id: respRPC.Id,
ResType: respRPC.ResType,
CustomId: respRPC.CustomId,
Title: respRPC.Title,
Url: respRPC.Url,
Weight: respRPC.Weight,
Creator: respRPC.Creator,
Status: respRPC.Status,
Ctime: respRPC.Ctime,
Mtime: respRPC.Mtime,
}
}
return
}
func convertRPCListRes(RPCList []*v2rspb.ListResp_List) (HTTPList []*v2pb.UserResourceListResp_List) {
HTTPList = make([]*v2pb.UserResourceListResp_List, len(RPCList))
for index, RPCListItem := range RPCList {
HTTPList[index] = &v2pb.UserResourceListResp_List{
Id: RPCListItem.Id,
ResType: RPCListItem.ResType,
CustomId: RPCListItem.CustomId,
Title: RPCListItem.Title,
Url: RPCListItem.Url,
Weight: RPCListItem.Weight,
Creator: RPCListItem.Creator,
Status: RPCListItem.Status,
Ctime: RPCListItem.Ctime,
Mtime: RPCListItem.Mtime,
}
}
return
}