duidui_fiber/internal/camp/dao/category_dao.go
2026-03-27 10:34:03 +08:00

207 lines
4.5 KiB
Go

package dao
import (
"database/sql"
"fmt"
"dd_fiber_api/internal/camp"
"dd_fiber_api/pkg/database"
"github.com/didi/gendry/builder"
)
// CategoryDAO 分类数据访问对象
type CategoryDAO struct {
client *database.MySQLClient
}
// NewCategoryDAO 创建分类DAO实例
func NewCategoryDAO(client *database.MySQLClient) *CategoryDAO {
return &CategoryDAO{
client: client,
}
}
// Create 创建分类
func (d *CategoryDAO) Create(category *camp.Category) error {
table := "camp_categories"
data := []map[string]any{
{
"id": category.ID,
"name": category.Name,
"sort_order": category.SortOrder,
},
}
cond, vals, err := builder.BuildInsert(table, data)
if err != nil {
return fmt.Errorf("构建插入语句失败: %v", err)
}
_, err = d.client.DB.Exec(cond, vals...)
if err != nil {
return fmt.Errorf("创建分类失败: %v", err)
}
return nil
}
// GetByID 根据ID获取分类
func (d *CategoryDAO) GetByID(id string) (*camp.Category, error) {
table := "camp_categories"
where := map[string]any{
"id": id,
}
selectFields := []string{"id", "name", "sort_order"}
cond, vals, err := builder.BuildSelect(table, where, selectFields)
if err != nil {
return nil, fmt.Errorf("构建查询失败: %v", err)
}
var category camp.Category
err = d.client.DB.QueryRow(cond, vals...).Scan(
&category.ID,
&category.Name,
&category.SortOrder,
)
if err == sql.ErrNoRows {
return nil, fmt.Errorf("分类不存在: %s", id)
}
if err != nil {
return nil, fmt.Errorf("查询分类失败: %v", err)
}
return &category, nil
}
// Update 更新分类
func (d *CategoryDAO) Update(category *camp.Category) error {
table := "camp_categories"
where := map[string]any{
"id": category.ID,
}
data := map[string]any{
"name": category.Name,
"sort_order": category.SortOrder,
}
cond, vals, err := builder.BuildUpdate(table, where, data)
if err != nil {
return fmt.Errorf("构建更新语句失败: %v", err)
}
result, err := d.client.DB.Exec(cond, vals...)
if err != nil {
return fmt.Errorf("更新分类失败: %v", err)
}
rows, err := result.RowsAffected()
if err != nil {
return fmt.Errorf("获取影响行数失败: %v", err)
}
if rows == 0 {
return fmt.Errorf("分类不存在: %s", category.ID)
}
return nil
}
// Delete 删除分类
func (d *CategoryDAO) Delete(id string) error {
table := "camp_categories"
where := map[string]any{
"id": id,
}
cond, vals, err := builder.BuildDelete(table, where)
if err != nil {
return fmt.Errorf("构建删除语句失败: %v", err)
}
result, err := d.client.DB.Exec(cond, vals...)
if err != nil {
return fmt.Errorf("删除分类失败: %v", err)
}
rows, err := result.RowsAffected()
if err != nil {
return fmt.Errorf("获取影响行数失败: %v", err)
}
if rows == 0 {
return fmt.Errorf("分类不存在: %s", id)
}
return nil
}
// List 列出分类(支持关键词搜索和分页)
func (d *CategoryDAO) List(keyword string, page, pageSize int) ([]*camp.Category, int, error) {
table := "camp_categories"
// 构建查询条件
where := map[string]any{}
if keyword != "" {
// gendry 支持 LIKE 查询
where["_or"] = []map[string]any{
{"name like": "%" + keyword + "%"},
{"id like": "%" + keyword + "%"},
}
}
// 查询总数
countFields := []string{"COUNT(*) as total"}
countCond, countVals, err := builder.BuildSelect(table, where, countFields)
if err != nil {
return nil, 0, fmt.Errorf("构建统计查询失败: %v", err)
}
var total int
err = d.client.DB.QueryRow(countCond, countVals...).Scan(&total)
if err != nil {
return nil, 0, fmt.Errorf("查询分类总数失败: %v", err)
}
// 查询数据
selectFields := []string{"id", "name", "sort_order"}
cond, vals, err := builder.BuildSelect(table, where, selectFields)
if err != nil {
return nil, 0, fmt.Errorf("构建查询失败: %v", err)
}
// 添加排序和分页
offset := (page - 1) * pageSize
cond += " ORDER BY sort_order DESC LIMIT ? OFFSET ?"
vals = append(vals, pageSize, offset)
rows, err := d.client.DB.Query(cond, vals...)
if err != nil {
return nil, 0, fmt.Errorf("查询分类列表失败: %v", err)
}
defer rows.Close()
categories := make([]*camp.Category, 0)
for rows.Next() {
var category camp.Category
err := rows.Scan(
&category.ID,
&category.Name,
&category.SortOrder,
)
if err != nil {
continue
}
categories = append(categories, &category)
}
if err = rows.Err(); err != nil {
return nil, 0, fmt.Errorf("遍历分类数据失败: %v", err)
}
return categories, total, nil
}