Files
2026-09-11 01:47:20 +08:00

84 lines
2.3 KiB
Go

// Package service 承载管理后台业务逻辑层,编排 dto、mysqldao、redisdao 与 pkg 能力。
//
// 约定:
// - 每个业务域一个 Service 结构体,NewXxxService() 构造,内部持有所需 DAO。
// - 方法统一返回 (*dto.XxxResponse, *errcode.Error),将底层 error 映射为语义化错误。
// - redis 未命中返回 redis.Nil,按缓存未命中处理,不视为错误。
// - 所有管理写操作在 service 层做权限与状态校验(AuthZ)。
package service
import (
"context"
"errors"
"time"
"git.lzcwy.cn/zhengchiliu/zt-closet-manage-backend/internal/middleware"
"git.lzcwy.cn/zhengchiliu/zt-closet-manage-backend/pkg/errcode"
"github.com/google/uuid"
"github.com/redis/go-redis/v9"
"gorm.io/gorm"
)
// isNotFound 判断 gorm 是否为「记录不存在」。
func isNotFound(err error) bool {
return errors.Is(err, gorm.ErrRecordNotFound)
}
// isCacheMiss 判断 redis 是否为「未命中」。
func isCacheMiss(err error) bool {
return errors.Is(err, redis.Nil)
}
// 分页默认值。
const (
defaultPage = 1
defaultPageSize = 10
maxPageSize = 50
)
// normalizePage 规整分页参数,返回可直接用于 DAO 的 page/pageSize。
func normalizePage(page, pageSize int) (int, int) {
if page <= 0 {
page = defaultPage
}
if pageSize <= 0 {
pageSize = defaultPageSize
}
if pageSize > maxPageSize {
pageSize = maxPageSize
}
return page, pageSize
}
// nowUnix 当前秒级时间戳。
func nowUnix() int64 {
return time.Now().Unix()
}
// todayStartUnix 返回本地时区今日 0 点的秒级时间戳。
func todayStartUnix() int64 {
now := time.Now()
start := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
return start.Unix()
}
// todayStatDate 返回本地时区今日的 YYYYMMDD 整数(user_daily_usages 统计日期)。
func todayStatDate() int64 {
now := time.Now()
return int64(now.Year()*10000 + int(now.Month())*100 + now.Day())
}
// genUUID 生成新的 UUID 字符串。
func genUUID() string {
return uuid.NewString()
}
// requireAdminID 从 context 取管理员 ID(由中间件注入),缺失返回未授权错误。
func requireAdminID(ctx context.Context) (int64, *errcode.Error) {
adminID, ok := middleware.GetAdminID(ctx)
if !ok || adminID <= 0 {
return 0, errcode.Unauthorized
}
return adminID, nil
}