feat: update template
This commit is contained in:
@@ -3,7 +3,17 @@ package auth
|
||||
import "time"
|
||||
|
||||
type RefreshTokenRecord struct {
|
||||
UserID int32 `json:"user_id"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
ExpiresAt time.Time `json:"expires_at"`
|
||||
UserID int32 `json:"user_id"`
|
||||
TokenVersion int32 `json:"token_version"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
ExpiresAt time.Time `json:"expires_at"`
|
||||
}
|
||||
|
||||
// IsAdmin 判断用户是否是超级管理员
|
||||
func IsAdmin(uid int32) bool {
|
||||
if uid == 1 {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
35
internal/model/request/file.go
Normal file
35
internal/model/request/file.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type UploadFileRequest struct {
|
||||
Folder string `json:"folder" validate:"omitempty,oneof=cover avatar article common"`
|
||||
}
|
||||
|
||||
// AllowedUploadExts 上传文件扩展名白名单(扩展名 → 期望的真实 MIME)。
|
||||
var AllowedUploadExts = map[string]string{
|
||||
// 图片
|
||||
".jpg": "image/jpeg",
|
||||
".jpeg": "image/jpeg",
|
||||
".png": "image/png",
|
||||
".gif": "image/gif",
|
||||
".webp": "image/webp",
|
||||
// 视频
|
||||
".mp4": "video/mp4",
|
||||
".webm": "video/webm",
|
||||
}
|
||||
|
||||
// IsAllowedUploadExt 扩展名是否在白名单内(大小写不敏感)
|
||||
func IsAllowedUploadExt(ext string) bool {
|
||||
_, ok := AllowedUploadExts[strings.ToLower(ext)]
|
||||
return ok
|
||||
}
|
||||
|
||||
// MatchUploadMime 校验实际 MIME 与扩展名匹配
|
||||
func MatchUploadMime(filename, detectedMime string) bool {
|
||||
expected, ok := AllowedUploadExts[strings.ToLower(filepath.Ext(filename))]
|
||||
return ok && detectedMime == expected
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"server/internal/pkg/validator"
|
||||
"time"
|
||||
)
|
||||
|
||||
type CreatePostRequest struct {
|
||||
Title string `json:"title" validate:"required,min=1"`
|
||||
CoverID int32 `json:"cover_id" validate:"required,min=1"`
|
||||
CoverID *int32 `json:"cover_id" validate:"omitempty"`
|
||||
Slug string `json:"slug" validate:"required,min=0"`
|
||||
Content string `json:"content" validate:"required,min=0"`
|
||||
Summary string `json:"summary" validate:"required,min=0"`
|
||||
@@ -18,15 +19,20 @@ type CreatePostRequest struct {
|
||||
}
|
||||
|
||||
type UpdatePostRequest struct {
|
||||
Title *string `json:"title" validate:"omitempty,min=1"`
|
||||
CoverID *int32 `json:"cover_id" validate:"omitempty,min=1"`
|
||||
Slug *string `json:"slug" validate:"omitempty,min=1"`
|
||||
Content *string `json:"content" validate:"required,min=0"`
|
||||
Summary *string `json:"summary" validate:"omitempty,min=1"`
|
||||
Status *int16 `json:"status" validate:"omitempty,oneof=0 1 2"`
|
||||
View *int32 `json:"view" validate:"omitempty,min=1"`
|
||||
Sort *int32 `json:"sort" validate:"omitempty,min=0"`
|
||||
PublishedAt *time.Time `json:"published_at" validate:"omitempty"`
|
||||
CategoryID *int32 `json:"category_id" validate:"required,min=1"`
|
||||
Tags []int32 `json:"tags" validate:"omitempty,dive,min=1"`
|
||||
Title *string `json:"title" validate:"omitempty,min=1"`
|
||||
CoverID validator.NullInt32 `json:"cover_id" validate:"omitempty"`
|
||||
Slug *string `json:"slug" validate:"omitempty,min=1"`
|
||||
Content *string `json:"content" validate:"required,min=0"`
|
||||
Summary *string `json:"summary" validate:"omitempty,min=1"`
|
||||
Status *int16 `json:"status" validate:"omitempty,oneof=0 1 2"`
|
||||
View *int32 `json:"view" validate:"omitempty,min=1"`
|
||||
Sort *int32 `json:"sort" validate:"omitempty,min=0"`
|
||||
PublishedAt *time.Time `json:"published_at" validate:"omitempty"`
|
||||
CategoryID *int32 `json:"category_id" validate:"required,min=1"`
|
||||
Tags []int32 `json:"tags" validate:"omitempty,dive,min=1"`
|
||||
}
|
||||
|
||||
type SearchPublishedPostsParams struct {
|
||||
CategoryCode string `json:"category_code" validate:"omitempty"`
|
||||
TagCode string `json:"tag_code" validate:"omitempty"`
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"server/internal/db/sqlc"
|
||||
"server/internal/pkg/httputil"
|
||||
)
|
||||
|
||||
func ToFiles(files []sqlc.File) []sqlc.File {
|
||||
result := make([]sqlc.File, len(files))
|
||||
for i := range files {
|
||||
result[i] = files[i]
|
||||
result[i].FilePath = httputil.BuildFileUrl(&files[i].FilePath)
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -28,7 +28,7 @@ type LoginResponse struct {
|
||||
RefreshTokenExp time.Time `json:"refresh_token_exp"`
|
||||
}
|
||||
|
||||
func NewUserInfo(user sqlc.GetUserByIDRow, roles []sqlc.SysRole, menus []sqlc.SysMenu, p []*string) *UserInfo {
|
||||
func NewUserInfo(user sqlc.GetUserRow, roles []sqlc.SysRole, menus []sqlc.SysMenu, p []*string) *UserInfo {
|
||||
roleCodes := make([]string, len(roles))
|
||||
for i, role := range roles {
|
||||
roleCodes[i] = role.Code
|
||||
@@ -41,11 +41,16 @@ func NewUserInfo(user sqlc.GetUserByIDRow, roles []sqlc.SysRole, menus []sqlc.Sy
|
||||
}
|
||||
}
|
||||
|
||||
avatarURL := ""
|
||||
if user.AvatarUrl != nil {
|
||||
avatarURL = *user.AvatarUrl
|
||||
}
|
||||
|
||||
return &UserInfo{
|
||||
ID: user.ID,
|
||||
Account: user.Account,
|
||||
Username: user.Username,
|
||||
AvatarUrl: *user.AvatarUrl,
|
||||
AvatarUrl: avatarURL,
|
||||
Roles: roleCodes,
|
||||
Menus: menus,
|
||||
Permissions: permissions,
|
||||
|
||||
Reference in New Issue
Block a user