You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

391 lines
8.5 KiB
Go

package service
import (
"joybuywork/internal/app"
"joybuywork/internal/consts"
"joybuywork/internal/consts/ckey"
"joybuywork/internal/repository/dbcheck"
"joybuywork/internal/repository/model"
"joybuywork/internal/repository/mtype"
"joybuywork/internal/repository/withdefault"
containers "joybuywork/internal/service/containers/games"
"joybuywork/internal/utils"
"joybuywork/internal/utils/blink"
pb "joybuywork/proto/go_proto/w_games"
"fmt"
"strings"
"time"
"github.com/golang-module/carbon/v2"
"gorm.io/gen/field"
)
type WGames struct {
Service
}
// LinkList 链接列表
func (s *WGames) LinkList(req *pb.LinkListReq, res *pb.LinkListRes) (err error) {
defer s.checkErr()
project, err := s.ProjectErrNil(req.GetProjectHashId())
if err != nil {
return
}
_, gameMap := consts.GameLinkMap()
m := s.GetDao().GameLink
list, err := m.WithContext(s.ctx).Where(m.ProjectID.Eq(project.ID), m.GameID.Eq(req.GetGameId()), m.IsDel.Eq(mtype.No)).Find()
if err != nil {
return
}
var playLinkMap = make(map[int64]string, len(list))
for _, v := range list {
playLinkMap[v.ID] = blink.NewGameLink(gameMap[v.GameID].Link, project.HashID, blink.SetGameLinkId(v.HashID)).Link()
}
*res = pb.LinkListRes{
List: make([]*pb.LinkListRes_One, 0, len(list)),
}
for _, v := range list {
res.List = append(res.List, &pb.LinkListRes_One{
Id: v.ID,
Title: v.Title,
IsDefault: int32(v.IsDefault),
Link: playLinkMap[v.ID],
})
}
return
}
// Visit 访问小游戏
func (s *WGames) Visit(req *pb.VisitReq, res *pb.VisitRes) (err error) {
defer s.checkErr()
*res = pb.VisitRes{}
container := new(containers.Visit)
{
container.Init(s.ctx)
container.Req = req
container.Res = res
}
return container.Run()
}
// List 游戏列表
func (s *WGames) List(req *pb.ListReq, res *pb.ListRes) (err error) {
defer s.checkErr()
project, err := s.ProjectErrNil(req.GetProjectHashId())
if err != nil {
return
}
games := consts.Games
ids, gameMap := consts.GameLinkMap()
m := s.GetDao().GameLink
list, err := m.WithContext(s.ctx).Where(m.ProjectID.Eq(project.ID), m.GameID.In(ids...), m.IsDel.Eq(mtype.No), m.IsDefault.Eq(mtype.Yes)).Find()
if err != nil {
return
}
var linkMap = make(map[int64]*model.GameLink)
for _, v := range list {
linkMap[v.GameID] = v
}
var playLinkMap = make(map[int64]string, len(games))
for _, id := range ids {
link, ok := linkMap[id]
if !ok {
lc := app.NewFollower(s.ctx, ckey.GameLinkInit(project.ID, id))
if ok1, _ := lc.SoftLock(); ok1 {
link = withdefault.GameLink(&model.GameLink{
ProjectID: project.ID,
GameID: id,
Title: "默认链接",
IsDefault: mtype.Yes,
})
err = m.WithContext(s.ctx).Create(link)
if err != nil {
return
}
lc.Release()
}
}
playLinkMap[id] = blink.NewGameLink(gameMap[id].Link, project.HashID, blink.SetGameLinkId(link.HashID)).Link()
}
*res = pb.ListRes{
List: make([]*pb.ListRes_One, 0, len(games)),
}
for _, v := range games {
res.List = append(res.List, &pb.ListRes_One{
Id: v.ID,
Title: v.Title,
Img: v.Img,
Link: playLinkMap[v.ID],
})
}
return
}
// LinkStore 创建链接
func (s *WGames) LinkStore(req *pb.LinkStoreReq, res *pb.LinkStoreRes) (err error) {
defer s.checkErr()
project, err := s.ProjectErrNil(req.GetProjectHashId())
if err != nil {
return
}
link := withdefault.GameLink(&model.GameLink{
ProjectID: project.ID,
GameID: req.GetGameId(),
Title: req.GetTitle(),
})
err = s.GetDao().GameLink.WithContext(s.ctx).Create(link)
if err != nil {
err = s.BE().MysqlError(err)
return
}
_, gameMap := consts.GameLinkMap()
*res = pb.LinkStoreRes{
Id: link.ID,
Link: blink.NewGameLink(gameMap[link.GameID].Link, project.HashID, blink.SetGameLinkId(link.HashID)).Link(),
}
return
}
// LinkUpdate 更新链接
func (s *WGames) LinkUpdate(req *pb.LinkUpdateReq, res *pb.LinkUpdateRes) (err error) {
defer s.checkErr()
project, err := s.ProjectErrNil(req.GetProjectHashId())
if err != nil {
return
}
m := s.GetDao().GameLink
link, err := m.WithContext(s.ctx).Where(m.ID.Eq(req.GetId()), m.IsDel.Eq(mtype.No)).Take()
if err = dbcheck.DbError(err); err != nil {
err = s.BE().MysqlError(err)
return
}
if link == nil || link.ProjectID != project.ID {
err = s.BE().VerifyError("not found link")
return
}
var up []field.AssignExpr
if link.Title != req.GetTitle() {
up = append(up, m.Title.Value(req.GetTitle()))
}
if len(up) > 0 {
_, err = m.WithContext(s.ctx).Where(m.ID.Eq(link.ID)).UpdateSimple(up...)
if err != nil {
err = s.BE().MysqlError(err)
return
}
}
*res = pb.LinkUpdateRes{
Id: link.ID,
}
return
}
// LinkDestroy 删除链接
func (s *WGames) LinkDestroy(req *pb.LinkDestroyReq, res *pb.LinkDestroyRes) (err error) {
defer s.checkErr()
project, err := s.ProjectErrNil(req.GetProjectHashId())
if err != nil {
return
}
m := s.GetDao().GameLink
link, err := m.WithContext(s.ctx).Where(m.ID.Eq(req.GetId()), m.IsDel.Eq(mtype.No)).Take()
if err = dbcheck.DbError(err); err != nil {
err = s.BE().MysqlError(err)
return
}
if link == nil || link.ProjectID != project.ID || link.IsDefault == mtype.Yes {
return
}
_, err = m.WithContext(s.ctx).Where(m.ID.Eq(link.ID)).UpdateSimple(m.IsDel.Value(mtype.Yes))
if err != nil {
err = s.BE().MysqlError(err)
return
}
*res = pb.LinkDestroyRes{
Id: link.ID,
}
return
}
// Trace 跟踪小游戏
func (s *WGames) Trace(req *pb.TraceReq, res *pb.TraceRes) (err error) {
defer s.checkErr()
*res = pb.TraceRes{}
container := new(containers.Trace)
{
container.Init(s.ctx)
container.Req = req
container.Res = res
}
return container.Run()
}
// Overview 小游戏统计
func (s *WGames) Overview(req *pb.OverviewReq, res *pb.OverviewRes) (err error) {
defer s.checkErr()
project, err := s.ProjectErrNil(req.GetProjectHashId())
if err != nil {
return
}
m := s.GetDao().GameTotal
total, err := m.WithContext(s.ctx).Where(
m.ProjectID.Eq(project.ID),
m.GameID.Eq(req.GetGameId()),
m.LinkID.Eq(req.GetLinkId()),
).Take()
if err = dbcheck.DbError(err); err != nil {
err = s.BE().MysqlError(err)
return
}
dateM := s.GetDao().GameTotalDate
yes := carbon.Now().SubDay().Format(time.DateOnly)
yesterdayTotal, err := dateM.WithContext(s.ctx).Where(
dateM.ProjectID.Eq(project.ID),
dateM.GameID.Eq(req.GetGameId()),
dateM.LinkID.Eq(req.GetLinkId()),
dateM.Ymd.Eq(yes),
).Take()
if err = dbcheck.DbError(err); err != nil {
err = s.BE().MysqlError(err)
return
}
var mark = []string{"visit_num", "visit_user_num", "total_stay"}
*res = pb.OverviewRes{
List: make([]*pb.OverviewRes_One, 0, len(mark)),
}
for _, v := range mark {
one := &pb.OverviewRes_One{
Mark: v,
Total: 0,
Yesterday: 0,
Avg: "",
}
switch v {
case "visit_num":
if total != nil {
one.Total = total.Pv
}
if yesterdayTotal != nil {
one.Yesterday = yesterdayTotal.Pv
}
case "visit_user_num":
if total != nil {
one.Total = total.Uv
}
if yesterdayTotal != nil {
one.Yesterday = yesterdayTotal.Uv
}
case "total_stay":
if total != nil {
one.Total = total.Psec
one.Avg = strings.TrimSuffix(strings.TrimRight(fmt.Sprintf("%.2f", float64(total.Psec)/float64(total.Uv)), "0"), ".")
}
}
res.List = append(res.List, one)
}
return
}
// Trend 小游戏趋势
func (s *WGames) Trend(req *pb.TrendReq, res *pb.TrendRes) (err error) {
defer s.checkErr()
project, err := s.ProjectErrNil(req.GetProjectHashId())
if err != nil {
return
}
start := utils.Ternary(req.GetStartTime() != 0, carbon.CreateFromTimestamp(req.GetStartTime()), carbon.Now().StartOfDay())
end := utils.Ternary(req.GetEndTime() != 0, carbon.CreateFromTimestamp(req.GetEndTime()), carbon.Now())
var xMap = make(map[string]int)
x := utils.BetweenDay(start, end, time.DateOnly)
for k, v := range x {
xMap[v] = k
}
m := s.GetDao().GameTotalDate
list, err := m.WithContext(s.ctx).Where(
m.ProjectID.Eq(project.ID),
m.GameID.Eq(req.GetGameId()),
m.LinkID.Eq(req.GetLinkId()),
m.Ymd.Between(x[0], x[len(x)-1]),
).Find()
if err != nil {
return
}
var y []*pb.TrendRes_Y
for _, v := range list {
visitNum := &pb.TrendRes_Y{
Type: "visit_num",
Data: make([]int64, len(x)),
}
visitNum.Data[xMap[v.Ymd]] = v.Pv
visitUserNum := &pb.TrendRes_Y{
Type: "visit_user_num",
Data: make([]int64, len(x)),
}
visitUserNum.Data[xMap[v.Ymd]] = v.Uv
y = append(y, visitNum, visitUserNum)
}
*res = pb.TrendRes{
X: x,
Y: y,
}
return
}