feat(hero): 新增英雄相关接口和功能

- 新增英雄信息获取接口和相关逻辑
- 实现英雄列表和详情查询功能- 添加英雄相关数据结构和VO对象
- 更新项目结构,移除不必要的文件
This commit is contained in:
hxt
2025-06-21 20:12:02 +08:00
parent 85e3a6540b
commit c5c273f0ab
19 changed files with 374 additions and 66 deletions

View File

@@ -2,12 +2,10 @@ package cmd
import (
"context"
"epic/internal/controller/hero"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/gcmd"
"epic/internal/controller/hello"
)
var (
@@ -20,7 +18,7 @@ var (
s.Group("/", func(group *ghttp.RouterGroup) {
group.Middleware(ghttp.MiddlewareHandlerResponse)
group.Bind(
hello.NewV1(),
hero.NewV1(),
)
})
s.Run()

View File

@@ -1,13 +0,0 @@
package hello
import (
"context"
"github.com/gogf/gf/v2/frame/g"
"epic/api/hello/v1"
)
func (c *ControllerV1) Hello(ctx context.Context, req *v1.HelloReq) (res *v1.HelloRes, err error) {
g.RequestFromCtx(ctx).Response.Writeln("Hello World!")
return
}

View File

@@ -2,4 +2,4 @@
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package hello
package hero

View File

@@ -1,16 +1,15 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package hello
package hero
import (
"epic/api/hello"
"epic/api/hero"
)
type ControllerV1 struct{}
func NewV1() hello.IHelloV1 {
func NewV1() hero.IHeroV1 {
return &ControllerV1{}
}

View File

@@ -0,0 +1,45 @@
// internal/controller/hero/hero_v1.go
package hero
import (
"context"
"epic/api/hero/v1"
"epic/internal/service"
)
func (c *ControllerV1) GetOne(ctx context.Context, req *v1.GetOneReq) (res *v1.GetOneRes, err error) {
hero, err := service.Hero().GetHeroByCode(ctx, req.Code)
if err != nil {
return nil, err
}
res = &v1.GetOneRes{
EpicHeroInfo: hero,
}
return res, nil
}
func (c *ControllerV1) GetList(ctx context.Context, req *v1.GetListReq) (res *v1.GetListRes, err error) {
// 获取 VO 列表
list, err := service.Hero().GetHeroList(ctx)
if err != nil {
return nil, err
}
// 构造响应
res = &v1.GetListRes{
Records: list, // ✅ 正确赋值字段
}
return res, nil
}
func (c *ControllerV1) GetDetail(ctx context.Context, req *v1.GetDetailReq) (res *v1.GetDetailRes, err error) {
detail, err := service.Hero().GetHeroDetailByCode(ctx, req.Code)
if err != nil {
return nil, err
}
res = &v1.GetDetailRes{
Data: detail,
}
return res, nil
}

103
internal/logic/hero/hero.go Normal file
View File

@@ -0,0 +1,103 @@
package hero
import (
"context"
v1 "epic/api/hero/v1"
"epic/internal/dao"
"epic/internal/model/entity"
"epic/internal/service"
"github.com/gogf/gf/v2/frame/g"
)
type Logic struct{}
func New() *Logic {
return &Logic{}
}
func init() {
service.SetHero(New())
}
// GetHeroByCode 根据 code 获取英雄信息
func (l *Logic) GetHeroByCode(ctx context.Context, code string) (*entity.EpicHeroInfo, error) {
// 2. 缓存未命中,查数据库
var hero *entity.EpicHeroInfo
err := dao.EpicHeroInfo.Ctx(ctx).
Where(dao.EpicHeroInfo.Columns().HeroCode, code).
Scan(&hero)
if err != nil {
return nil, err
}
return hero, nil
}
// GetHeroList 查询所有英雄信息,并按创建时间倒序排列
func (l *Logic) GetHeroList(ctx context.Context) ([]*v1.EpicHeroVO, error) {
redis := g.Redis()
cacheKey := "hero:list"
// 1. 先查缓存
value, err := redis.Get(ctx, cacheKey)
if err == nil && !value.IsEmpty() {
var voList []*v1.EpicHeroVO
if err := value.Scan(&voList); err == nil {
return voList, nil
}
}
var (
doList []*entity.EpicHeroInfo // 数据库原始结构
voList []*v1.EpicHeroVO // 要返回的视图结构
)
// 2. 缓存未命中,查数据库
err = dao.EpicHeroInfo.Ctx(ctx).
OrderDesc(dao.EpicHeroInfo.Columns().CreateTime). // 按创建时间倒序
Scan(&doList)
if err != nil {
return nil, err
}
// 3. 手动映射 DO -> VO
for _, hero := range doList {
voList = append(voList, &v1.EpicHeroVO{
Id: hero.Id,
HeroName: hero.HeroName,
HeroCode: hero.HeroCode,
Attribute: hero.Attribute,
HeadImgUrl: hero.HeadImgUrl,
HeroAttrLv60: hero.HeroAttrLv60,
NickName: hero.NickName,
Rarity: hero.Rarity,
Role: hero.Role,
Zodiac: hero.Zodiac,
Remark: hero.Remark,
})
}
return voList, nil
}
func (l *Logic) GetHeroDetailByCode(ctx context.Context, code string) (*v1.HeroDetailVO, error) {
//TODO implement me
panic("implement me")
}
// ClearHeroCache 清理英雄相关缓存
func (l *Logic) ClearHeroCache(ctx context.Context, code string) error {
redis := g.Redis()
// 清理单个英雄缓存
if code != "" {
cacheKey := "hero:" + code
redis.Del(ctx, cacheKey)
}
// 清理英雄列表缓存
redis.Del(ctx, "hero:list")
return nil
}

9
internal/logic/logic.go Normal file
View File

@@ -0,0 +1,9 @@
// ==========================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package logic
import (
_ "epic/internal/logic/hero"
)

34
internal/service/hero.go Normal file
View File

@@ -0,0 +1,34 @@
package service
import (
"context"
v1 "epic/api/hero/v1"
"epic/internal/model/entity"
)
// HeroService 定义了英雄相关的业务接口
type HeroService interface {
// GetHeroByCode 根据 code 查询角色信息
GetHeroByCode(ctx context.Context, code string) (*entity.EpicHeroInfo, error)
GetHeroList(ctx context.Context) ([]*v1.EpicHeroVO, error)
GetHeroDetailByCode(ctx context.Context, code string) (*v1.HeroDetailVO, error)
// ClearHeroCache 清理英雄相关缓存
ClearHeroCache(ctx context.Context, code string) error
}
var heroService HeroService
// Hero 返回 HeroService 的实例
func Hero() HeroService {
if heroService == nil {
panic("implement not found for interface HeroService")
}
return heroService
}
// SetHero 注册 HeroService 实现
func SetHero(s HeroService) {
heroService = s
}