1.优化首页分类接口;

2.新增/编辑游戏,增加首页分类选择;
This commit is contained in:
chenlin 2025-01-03 17:40:47 +08:00
parent 4a3a558daf
commit e4a634da65
6 changed files with 248 additions and 27 deletions

View File

@ -92,7 +92,7 @@ func GameCardAdd(c *gin.Context) {
Labels []string `json:"labels"` // 游戏标签
RealPrice uint32 `json:"real_price"` // 真实价格
VideoLink string `json:"video_link"` // 链接
HomeCategoryId []uint32 `json:"home_category_id"` // 首页分类ID
}{}
if c.ShouldBindJSON(&req) != nil {
logger.Errorf("para err")
@ -150,6 +150,48 @@ func GameCardAdd(c *gin.Context) {
}
}
// 添加到首页分类
if len(req.HomeCategoryId) != 0 {
for _, categoryId := range req.HomeCategoryId {
// 删除已有的 home_category_id 和 game_id 记录
err = orm.Eloquent.Table("home_category_game").
Where("home_category_id = ? AND game_id = ?", categoryId, card.ID).
Delete(&models.HomeCategoryGame{}).Error
if err != nil {
logger.Errorf("Failed to delete existing home_category_game record, home_category_id: %d, game_id: %d, err: %v", categoryId, card.ID, err)
return
}
// 查询新的 HomeCategoryId 的最大排序值
type MaxSortOrderResult struct {
MaxSortOrder int `json:"max_sort_order"` // 数据库字段类型应与此字段匹配
}
var result MaxSortOrderResult
err = orm.Eloquent.Table("home_category_game").
Where("home_category_id = ?", categoryId).
Select("COALESCE(MAX(sort_order), 0) AS max_sort_order").
Scan(&result).Error
if err != nil {
logger.Errorf("Failed to fetch max sort_order for home_category_id: %d, err: %v", categoryId, err)
return
}
// 插入新记录
newHomeCategoryGame := models.HomeCategoryGame{
HomeCategoryID: categoryId,
GameID: card.ID,
GameName: card.Name,
SortOrder: result.MaxSortOrder + 1,
}
err = orm.Eloquent.Table("home_category_game").
Create(&newHomeCategoryGame).Error
if err != nil {
logger.Errorf("Failed to create new home_category_game record, home_category_id: %d, game_id: %d, err: %v", card.HomeCategoryId, card.ID, err)
}
}
}
app.OK(c, nil, "添加成功")
}

View File

@ -18,24 +18,25 @@ import (
type GameCard struct {
Model
Name string `json:"name" gorm:"column:name;index"` // 名称
Price uint32 `json:"price" gorm:"column:price;index"` // 价格
CoverImg string `json:"coverImg" gorm:"column:cover_img"` // 封面
OrderCount uint32 `json:"orderCount" gorm:"column:order_count;index"` // 订单数
NewProducts uint8 `json:"newProducts"` // 新品: 1-新品 2-非新品
Status uint8 `json:"status"` // 状态: 1-上架 2-下架
GameTypeId uint32 `json:"gameTypeId"` // 游戏类型id
GoodsGalleryUrl string `json:"goodsGalleryUrl" gorm:"type:text;comment:'轮播图'"` // 轮播图
ViewCount uint32 `json:"viewCount"` // 查看人数
Playability uint32 `json:"playability"` // 耐玩度
Playfulness uint32 `json:"playfulness"` // 好玩度
GameTime uint32 `json:"gameTime"` // 游戏时间
Likes uint32 `json:"likes"` // 点赞
DetailInfo string `json:"detailInfo" gorm:"type:text;comment:'详情描述'"` // 详情描述
DetailImg string `json:"detailImg"` // 详情图片
EstimateVm uint32 `json:"estimate_vm" gorm:"-"` // 预计积分
RealPrice uint32 `json:"real_price"` // 真实价格
VideoLink string `json:"video_link"` // 链接
Name string `json:"name" gorm:"column:name;index"` // 名称
Price uint32 `json:"price" gorm:"column:price;index"` // 价格
CoverImg string `json:"coverImg" gorm:"column:cover_img"` // 封面
OrderCount uint32 `json:"orderCount" gorm:"column:order_count;index"` // 订单数
NewProducts uint8 `json:"newProducts"` // 新品: 1-新品 2-非新品
Status uint8 `json:"status"` // 状态: 1-上架 2-下架
GameTypeId uint32 `json:"gameTypeId"` // 游戏类型id
GoodsGalleryUrl string `json:"goodsGalleryUrl" gorm:"type:text;comment:'轮播图'"` // 轮播图
ViewCount uint32 `json:"viewCount"` // 查看人数
Playability uint32 `json:"playability"` // 耐玩度
Playfulness uint32 `json:"playfulness"` // 好玩度
GameTime uint32 `json:"gameTime"` // 游戏时间
Likes uint32 `json:"likes"` // 点赞
DetailInfo string `json:"detailInfo" gorm:"type:text;comment:'详情描述'"` // 详情描述
DetailImg string `json:"detailImg"` // 详情图片
EstimateVm uint32 `json:"estimate_vm" gorm:"-"` // 预计积分
RealPrice uint32 `json:"real_price"` // 真实价格
VideoLink string `json:"video_link"` // 链接
HomeCategoryId []uint32 `json:"home_category_id" gorm:"-"` // 首页分类ID
}
func (*GameCard) TableName() string {
@ -102,6 +103,36 @@ func GetGameCardList(gameType, status, page, pageSize int, key string) ([]GameCa
return cards, 0, 0, err
}
// 查询每个 GameCard 的 home_category_id 数据
gameIds := make([]uint32, len(cards))
for i, card := range cards {
gameIds[i] = card.ID
}
// 从 home_category_game 表中查询关联的 home_category_id
var categoryMappings []struct {
GameID uint32 `json:"game_id"`
HomeCategoryID uint32 `json:"home_category_id"`
}
err = orm.Eloquent.Table("home_category_game").
Where("game_id IN (?)", gameIds).
Select("game_id, home_category_id").
Find(&categoryMappings).Error
if err != nil {
logger.Errorf("Failed to fetch home_category_game mappings: %v", err)
return cards, 0, 0, err
}
// 将查询结果映射到 GameCard 的 HomeCategoryId 字段
categoryMap := make(map[uint32][]uint32)
for _, mapping := range categoryMappings {
categoryMap[mapping.GameID] = append(categoryMap[mapping.GameID], mapping.HomeCategoryID)
}
for i := range cards {
cards[i].HomeCategoryId = categoryMap[cards[i].ID]
}
totalPage = uint32(int(count)/pageSize + 1)
return cards, totalPage, uint32(count), nil
@ -394,15 +425,75 @@ func (m *GameCard) Add() error {
return nil
}
//func (m *GameCard) Modify() error {
// para := m.getModifyPara()
// if len(para) > 0 {
// err := orm.Eloquent.Table("game_card").Unscoped().Where("id", m.ID).Updates(para).Error
// if err != nil {
// logger.Errorf(err.Error())
// return err
// }
// }
// return nil
//}
func (m *GameCard) Modify() error {
// 获取需要更新的字段
para := m.getModifyPara()
if len(para) > 0 {
err := orm.Eloquent.Table("game_card").Unscoped().Where("id", m.ID).Updates(para).Error
// 更新 game_card 表
err := orm.Eloquent.Table("game_card").Unscoped().Where("id = ?", m.ID).Updates(para).Error
if err != nil {
logger.Errorf(err.Error())
logger.Errorf("Failed to update game_card, id: %d, err: %v", m.ID, err)
return err
}
}
// 删除与 game_id 相关的所有 home_category_game 记录
err := orm.Eloquent.Table("home_category_game").
Where("game_id = ?", m.ID).
Delete(&HomeCategoryGame{}).Error
if err != nil {
logger.Errorf("Failed to delete home_category_game records for game_id: %d, err: %v", m.ID, err)
return err
}
// 新增当前 HomeCategoryId 的所有记录
if len(m.HomeCategoryId) > 0 {
var newRecords []HomeCategoryGame
for _, categoryID := range m.HomeCategoryId {
// 查询新的 HomeCategoryId 的最大排序值
type MaxSortOrderResult struct {
MaxSortOrder int `json:"max_sort_order"` // 数据库字段类型应与此字段匹配
}
var result MaxSortOrderResult
err = orm.Eloquent.Table("home_category_game").
Where("home_category_id = ?", categoryID).
Select("COALESCE(MAX(sort_order), 0) AS max_sort_order").
Scan(&result).Error
if err != nil {
logger.Errorf("Failed to fetch max sort_order for home_category_id: %d, err: %v", categoryID, err)
return err
}
// 构建新的记录
newRecords = append(newRecords, HomeCategoryGame{
HomeCategoryID: categoryID,
GameID: m.ID,
GameName: m.Name,
SortOrder: result.MaxSortOrder + 1,
})
}
// 批量插入记录
err = orm.Eloquent.Table("home_category_game").Create(&newRecords).Error
if err != nil {
logger.Errorf("Failed to create new home_category_game records for game_id: %d, err: %v", m.ID, err)
return err
}
}
return nil
}

View File

@ -10,10 +10,12 @@ import (
type HomeCategory struct {
Model
Name string `json:"name" gorm:"index"` // 分类名称
SortOrder uint32 `json:"sort_order" gorm:"index"` // 排序序号
State uint32 `json:"state" gorm:"index"` // 状态1-启用2-隐藏
Games []HomeGameList `json:"games" gorm:"-"` // 关联的游戏
Name string `json:"name" gorm:"index"` // 分类名称
SortOrder uint32 `json:"sort_order" gorm:"index"` // 排序序号
State uint32 `json:"state" gorm:"index"` // 状态1-启用2-隐藏
AllFlag uint32 `json:"all_flag"` // 是否包含所有游戏0-不包含1-包含
OrderFlag uint32 `json:"order_flag"` // 是否根据销量排序0-不选择1-根据租赁数量排序
Games []HomeGameList `json:"games" gorm:"-"` // 关联的游戏
}
// HomeGameList 首页分类归属游戏
@ -80,7 +82,7 @@ func (m *HomeCategoryListReq) List() (*HomeCategoryListResp, error) {
resp.Total = int(count)
var orders []HomeCategory
err = qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&orders).Error
err = qs.Order("sort_order ASC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&orders).Error
if err != nil && err != RecordNotFound {
logger.Error("home_category list err:", logger.Field("err", err))
return resp, err
@ -89,7 +91,8 @@ func (m *HomeCategoryListReq) List() (*HomeCategoryListResp, error) {
// 组合关联的游戏数据
for i := range orders {
var games []HomeCategoryGame
err = orm.Eloquent.Table("home_category_game").Where("home_category_id = ?", orders[i].ID).Find(&games).Error
err = orm.Eloquent.Table("home_category_game").Where("home_category_id = ?", orders[i].ID).
Order("sort_order ASC").Find(&games).Error
if err != nil {
logger.Error("home_category_game list err:", logger.Field("err", err))
return resp, err
@ -113,6 +116,8 @@ func (m *HomeCategoryListReq) List() (*HomeCategoryListResp, error) {
type HomeCategoryAddReq struct {
Name string `json:"name" validate:"required"` // 分类名称
SortOrder uint32 `json:"sort_order" validate:"required"` // 排序序号
AllFlag uint32 `json:"all_flag"` // 是否包含所有游戏0-不包含1-包含
OrderFlag uint32 `json:"order_flag"` // 是否根据销量排序0-不选择1-根据租赁数量排序
State uint32 `json:"state" validate:"required"` // 状态1-启用2-隐藏
Games []HomeGameList `json:"games"` // 关联的游戏
}
@ -124,6 +129,8 @@ func CreateHomeCategory(req *HomeCategoryAddReq) error {
Name: req.Name,
SortOrder: req.SortOrder,
State: req.State,
AllFlag: req.AllFlag,
OrderFlag: req.OrderFlag,
}
// 开启事务
@ -232,6 +239,8 @@ type HomeCategoryEditReq struct {
Name string `json:"name" validate:"required"` // 分类名称
SortOrder uint32 `json:"sort_order" validate:"required"` // 排序序号
State uint32 `json:"state" validate:"required"` // 状态1-启用2-隐藏
AllFlag uint32 `json:"all_flag"` // 是否包含所有游戏0-不包含1-包含
OrderFlag uint32 `json:"order_flag"` // 是否根据销量排序0-不选择1-根据租赁数量排序
Games []HomeGameList `json:"games"` // 关联的游戏
}
@ -249,6 +258,8 @@ func EditHomeCategory(req *HomeCategoryEditReq) (*HomeCategory, error) {
homeCategory.Name = req.Name
homeCategory.SortOrder = req.SortOrder
homeCategory.State = req.State
homeCategory.AllFlag = req.AllFlag
homeCategory.OrderFlag = req.OrderFlag
err = orm.Eloquent.Table("home_category").Save(&homeCategory).Error
if err != nil {
logger.Error("update home_category err:", logger.Field("err", err))

View File

@ -13619,6 +13619,10 @@ const docTemplate = `{
"description": "轮播图",
"type": "string"
},
"home_category_id": {
"description": "首页分类ID",
"type": "integer"
},
"id": {
"description": "数据库记录编号",
"type": "integer"
@ -14181,6 +14185,10 @@ const docTemplate = `{
"models.HomeCategory": {
"type": "object",
"properties": {
"all_flag": {
"description": "是否包含所有游戏0-不包含1-包含",
"type": "integer"
},
"createdAt": {
"description": "创建时间",
"type": "string"
@ -14200,6 +14208,10 @@ const docTemplate = `{
"description": "分类名称",
"type": "string"
},
"order_flag": {
"description": "是否根据销量排序0-不选择1-根据租赁数量排序",
"type": "integer"
},
"sort_order": {
"description": "排序序号",
"type": "integer"
@ -14222,6 +14234,10 @@ const docTemplate = `{
"state"
],
"properties": {
"all_flag": {
"description": "是否包含所有游戏0-不包含1-包含",
"type": "integer"
},
"games": {
"description": "关联的游戏",
"type": "array",
@ -14233,6 +14249,10 @@ const docTemplate = `{
"description": "分类名称",
"type": "string"
},
"order_flag": {
"description": "是否根据销量排序0-不选择1-根据租赁数量排序",
"type": "integer"
},
"sort_order": {
"description": "排序序号",
"type": "integer"
@ -14264,6 +14284,10 @@ const docTemplate = `{
"state"
],
"properties": {
"all_flag": {
"description": "是否包含所有游戏0-不包含1-包含",
"type": "integer"
},
"games": {
"description": "关联的游戏",
"type": "array",
@ -14279,6 +14303,10 @@ const docTemplate = `{
"description": "分类名称",
"type": "string"
},
"order_flag": {
"description": "是否根据销量排序0-不选择1-根据租赁数量排序",
"type": "integer"
},
"sort_order": {
"description": "排序序号",
"type": "integer"

View File

@ -13608,6 +13608,10 @@
"description": "轮播图",
"type": "string"
},
"home_category_id": {
"description": "首页分类ID",
"type": "integer"
},
"id": {
"description": "数据库记录编号",
"type": "integer"
@ -14170,6 +14174,10 @@
"models.HomeCategory": {
"type": "object",
"properties": {
"all_flag": {
"description": "是否包含所有游戏0-不包含1-包含",
"type": "integer"
},
"createdAt": {
"description": "创建时间",
"type": "string"
@ -14189,6 +14197,10 @@
"description": "分类名称",
"type": "string"
},
"order_flag": {
"description": "是否根据销量排序0-不选择1-根据租赁数量排序",
"type": "integer"
},
"sort_order": {
"description": "排序序号",
"type": "integer"
@ -14211,6 +14223,10 @@
"state"
],
"properties": {
"all_flag": {
"description": "是否包含所有游戏0-不包含1-包含",
"type": "integer"
},
"games": {
"description": "关联的游戏",
"type": "array",
@ -14222,6 +14238,10 @@
"description": "分类名称",
"type": "string"
},
"order_flag": {
"description": "是否根据销量排序0-不选择1-根据租赁数量排序",
"type": "integer"
},
"sort_order": {
"description": "排序序号",
"type": "integer"
@ -14253,6 +14273,10 @@
"state"
],
"properties": {
"all_flag": {
"description": "是否包含所有游戏0-不包含1-包含",
"type": "integer"
},
"games": {
"description": "关联的游戏",
"type": "array",
@ -14268,6 +14292,10 @@
"description": "分类名称",
"type": "string"
},
"order_flag": {
"description": "是否根据销量排序0-不选择1-根据租赁数量排序",
"type": "integer"
},
"sort_order": {
"description": "排序序号",
"type": "integer"

View File

@ -4802,6 +4802,9 @@ definitions:
goodsGalleryUrl:
description: 轮播图
type: string
home_category_id:
description: 首页分类ID
type: integer
id:
description: 数据库记录编号
type: integer
@ -5195,6 +5198,9 @@ definitions:
type: object
models.HomeCategory:
properties:
all_flag:
description: 是否包含所有游戏0-不包含1-包含
type: integer
createdAt:
description: 创建时间
type: string
@ -5209,6 +5215,9 @@ definitions:
name:
description: 分类名称
type: string
order_flag:
description: 是否根据销量排序0-不选择1-根据租赁数量排序
type: integer
sort_order:
description: 排序序号
type: integer
@ -5221,6 +5230,9 @@ definitions:
type: object
models.HomeCategoryAddReq:
properties:
all_flag:
description: 是否包含所有游戏0-不包含1-包含
type: integer
games:
description: 关联的游戏
items:
@ -5229,6 +5241,9 @@ definitions:
name:
description: 分类名称
type: string
order_flag:
description: 是否根据销量排序0-不选择1-根据租赁数量排序
type: integer
sort_order:
description: 排序序号
type: integer
@ -5250,6 +5265,9 @@ definitions:
type: object
models.HomeCategoryEditReq:
properties:
all_flag:
description: 是否包含所有游戏0-不包含1-包含
type: integer
games:
description: 关联的游戏
items:
@ -5261,6 +5279,9 @@ definitions:
name:
description: 分类名称
type: string
order_flag:
description: 是否根据销量排序0-不选择1-根据租赁数量排序
type: integer
sort_order:
description: 排序序号
type: integer