feat: 统一sql命名、函数命名

This commit is contained in:
2026-08-02 12:02:04 +08:00
parent d39342ce5f
commit 0e674e9d56
68 changed files with 1985 additions and 1720 deletions

View File

@@ -8,11 +8,12 @@ import (
"server/internal/config"
"server/internal/db"
"server/internal/handler"
"server/internal/service"
"server/internal/middleware"
"server/internal/pkg/cache"
"server/internal/pkg/logger"
"server/internal/router"
"server/internal/service"
"github.com/go-chi/chi/v5"
"go.uber.org/fx"

View File

@@ -0,0 +1 @@
ALTER TABLE files DROP COLUMN IF EXISTS file_url;

View File

@@ -0,0 +1,10 @@
ALTER TABLE files
ADD COLUMN IF NOT EXISTS file_url TEXT;
UPDATE files
SET file_url = '';
ALTER TABLE files
ALTER COLUMN file_url SET NOT NULL;
COMMENT ON COLUMN files.file_url IS '完整路径';

View File

@@ -1,12 +1,13 @@
-- name: CreateFile :one
INSERT INTO files(file_name, file_path, original_name, folder_name, mime_type, file_size)
VALUES ($1, $2, $3, $4, $5, $6) RETURNING id,file_path,file_name;
INSERT INTO files(file_name, file_path, original_name, folder_name, mime_type, file_size, file_url)
VALUES ($1, $2, $3, $4, $5, $6, $7)
RETURNING id,file_url,file_name;
-- name: GetFiles :many
-- name: ListFiles :many
SELECT *
FROM files
ORDER BY id LIMIT $1
OFFSET $2;
ORDER BY id
LIMIT $1 OFFSET $2;
-- name: CountFiles :one
SELECT COUNT(*)

View File

@@ -22,7 +22,7 @@ WITH paginated_posts AS (
)
-- 第二步:用这极少量的记录去进行 JOIN
SELECT p.*,
f.file_path AS cover,
f.file_url AS cover,
c.name AS category_name,
c.id AS category_id,
COALESCE(ps.view, 0) AS view,
@@ -54,7 +54,7 @@ GROUP BY p.id,
p.published_at,
p.created_at,
p.updated_at,
f.file_path,
f.file_url,
c.name,
c.id,
ps.view
@@ -64,9 +64,9 @@ ORDER BY p.sort DESC, p.published_at DESC, p.id DESC;
SELECT COUNT(*)
FROM posts;
-- name: GetPostById :one
-- name: GetPostByID :one
SELECT p.*,
f.file_path AS cover,
f.file_url AS cover,
c.name AS category_name,
c.id AS category_id,
COALESCE(
@@ -80,7 +80,7 @@ FROM posts p
LEFT JOIN post_tag pt ON pt.post_id = p.id
WHERE p.id = $1
GROUP BY p.id,
f.file_path,
f.file_url,
c.name,
c.id
LIMIT 1;
@@ -106,7 +106,7 @@ WHERE id = $1;
-- name: GetPublicPostBySlug :one
SELECT p.*,
f.file_path AS cover,
f.file_url AS cover,
COALESCE(ps.view, 0) AS view
FROM posts p
LEFT JOIN files f ON f.id = p.cover_id
@@ -132,7 +132,7 @@ WITH paginated_posts AS (
ORDER BY sort DESC, published_at DESC, id DESC
LIMIT $1 OFFSET $2)
SELECT p.*,
f.file_path AS cover,
f.file_url AS cover,
c.name AS category_name,
c.id AS category_id,
COALESCE(ps.view, 0) AS view,
@@ -161,7 +161,7 @@ GROUP BY p.id,
p.summary,
p.sort,
p.published_at,
f.file_path,
f.file_url,
c.name,
c.id,
ps.view

View File

@@ -1,28 +1,35 @@
-- name: CreateSysApi :one
-- name: CreateApi :one
INSERT INTO sys_apis (name, group_name, method, path, sort)
VALUES ($1, $2, $3, $4, $5)
RETURNING id;
-- name: GetSysApis :many
-- name: ListAllApis :many
SELECT *
FROM sys_apis
WHERE (sqlc.arg('group_name')::text = '' OR group_name ILIKE '%' || sqlc.arg('group_name') || '%')
ORDER BY sort ASC;
-- name: ListApis :many
SELECT *
FROM sys_apis
WHERE (sqlc.arg('name')::text = '' OR name ILIKE '%' || sqlc.arg('name') || '%')
AND (sqlc.arg('group_name')::text = '' OR group_name ILIKE '%' || sqlc.arg('group_name') || '%')
AND (sqlc.arg('method')::text = '' OR method = sqlc.arg('method'))
ORDER BY id
LIMIT $1 OFFSET $2;
-- name: CountSysApis :one
-- name: CountApis :one
SELECT COUNT(*)
FROM sys_apis
WHERE (sqlc.arg('group_name')::text = '' OR group_name ILIKE '%' || sqlc.arg('group_name') || '%')
WHERE (sqlc.arg('name')::text = '' OR name ILIKE '%' || sqlc.arg('name') || '%')
AND (sqlc.arg('group_name')::text = '' OR group_name ILIKE '%' || sqlc.arg('group_name') || '%')
AND (sqlc.arg('method')::text = '' OR method = sqlc.arg('method'));
-- name: GetSysApiByID :one
-- name: GetApiByID :one
SELECT *
FROM sys_apis
WHERE id = $1;
-- name: UpdateSysApi :execrows
-- name: UpdateApi :execrows
UPDATE sys_apis
SET name = $2,
method = $3,
@@ -31,25 +38,21 @@ SET name = $2,
group_name = $6
WHERE id = $1;
-- name: DeleteSysApi :execrows
-- name: DeleteApi :execrows
DELETE
FROM sys_apis
WHERE id = $1;
-- name: CreateSysApiPermission :exec
-- name: CreateApiPermission :exec
INSERT INTO sys_api_permission (api_id, permission_id)
VALUES ($1, $2);
-- name: DeleteSysApiPermission :exec
-- name: DeleteApiPermission :exec
DELETE
FROM sys_api_permission
WHERE api_id = $1;
-- name: GetSysApiGroupNames :many
-- name: ListApiGroups :many
SELECT DISTINCT group_name
FROM sys_apis;
-- name: GetAllSysApis :many
SELECT *
FROM sys_apis
ORDER BY sort ASC;

View File

@@ -1,9 +1,9 @@
-- name: CreateSysMenu :one
-- name: CreateMenu :one
INSERT INTO sys_menus (name, path, component, type, hidden, sort, status, parent_id, icon)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
RETURNING id;
-- name: ListSysMenus :many
-- name: ListMenus :many
SELECT m.*, p.code AS permission_code
FROM sys_menus m
LEFT JOIN sys_menu_permission mp ON m.id = mp.menu_id
@@ -11,11 +11,11 @@ FROM sys_menus m
ORDER BY m.id
LIMIT $1 OFFSET $2;
-- name: CountSysMenus :one
-- name: CountMenus :one
SELECT COUNT(*)
FROM sys_menus;
-- name: GetAllSysMenus :many
-- name: ListAllMenus :many
SELECT m.*,
p.code AS permission_code
FROM sys_menus m
@@ -24,12 +24,12 @@ FROM sys_menus m
ORDER BY m.sort ASC,
m.id ASC;
-- name: GetSysMenuByID :one
-- name: GetMenuByID :one
SELECT *
FROM sys_menus
WHERE id = $1;
-- name: UpdateSysMenu :execrows
-- name: UpdateMenu :execrows
UPDATE sys_menus
SET name = coalesce(sqlc.narg('name'), name),
path = coalesce(sqlc.narg('path'), path),
@@ -42,28 +42,28 @@ SET name = coalesce(sqlc.narg('name'), name),
parent_id = CASE WHEN @update_parent_id::boolean THEN @parent_id ELSE parent_id END
WHERE id = sqlc.arg('id');
-- name: DeleteSysMenu :execrows
-- name: DeleteMenu :execrows
DELETE
FROM sys_menus
WHERE id = $1;
-- name: CreateSysMenuPermission :exec
-- name: CreateMenuPermission :exec
INSERT INTO sys_menu_permission (menu_id, permission_id)
VALUES ($1, $2);
-- name: DeleteSysMenuPermission :exec
-- name: DeleteMenuPermission :exec
DELETE
FROM sys_menu_permission
WHERE menu_id = $1;
-- name: DeleteSysPermissionByMenuID :exec
-- name: DeletePermissionsByMenuID :exec
DELETE
FROM sys_permissions
WHERE id IN (SELECT permission_id
FROM sys_menu_permission
WHERE menu_id = $1);
-- name: UpdateSysMenuPermissionCode :exec
-- name: UpdateMenuPermissionCode :exec
UPDATE sys_permissions p
SET code = coalesce(sqlc.narg('code'), code)
FROM sys_menu_permission mp

View File

@@ -1,23 +1,23 @@
-- name: CreateSysPermission :one
-- name: CreatePermission :one
INSERT INTO sys_permissions(type,code)
VALUES ($1,$2) RETURNING id;
-- name: UpdateSysPermission :exec
-- name: UpdatePermission :exec
UPDATE sys_permissions
SET code = $2
WHERE id = $1;
-- name: DeleteSysPermission :exec
-- name: DeletePermission :exec
DELETE
FROM sys_permissions
WHERE id = $1;
-- name: GetSysPermissionIDBySysApiID :one
-- name: GetPermissionIDBySysApiID :one
SELECT permission_id
FROM sys_api_permission
WHERE api_id = $1;
-- name: GetSysPermissionIDBySysMenuID :one
-- name: GetPermissionIDBySysMenuID :one
SELECT permission_id
FROM sys_menu_permission
WHERE menu_id = $1;

View File

@@ -1,23 +1,27 @@
-- name: CreateSysRole :exec
-- name: CreateRole :exec
INSERT INTO sys_roles (name, code, status)
VALUES ($1, $2, $3);
-- name: ListSysRoles :many
-- name: ListAllRoles :many
SELECT *
from sys_roles;
-- name: ListRoles :many
SELECT *
FROM sys_roles
ORDER BY id
LIMIT $1 OFFSET $2;
-- name: CountSysRoles :one
-- name: CountRoles :one
SELECT COUNT(*)
FROM sys_roles;
-- name: GetSysRoleByID :one
-- name: GetRoleByID :one
SELECT *
FROM sys_roles
WHERE id = $1;
-- name: ExistsSysRoleCode :one
-- name: ExistsRoleCode :one
SELECT EXISTS(SELECT 1
FROM sys_roles
WHERE code = sqlc.arg(code)
@@ -26,67 +30,65 @@ SELECT EXISTS(SELECT 1
OR id <> sqlc.narg(id)::integer
));
-- name: UpdateSysRole :execrows
-- name: UpdateRole :execrows
UPDATE sys_roles
SET name = coalesce(sqlc.narg('name'), name),
status = coalesce(sqlc.narg('status'), status)
WHERE id = sqlc.arg('id');
-- name: DeleteSysRole :execrows
-- name: DeleteRole :execrows
DELETE
FROM sys_roles
WHERE id = $1;
-- name: CreateSysRolePermission :copyfrom
-- name: CreateRolePermission :copyfrom
INSERT INTO sys_role_permission (role_id, permission_id)
VALUES ($1, $2);
-- name: GetSysPermissionIdsByMenuIDs :many
-- name: ListPermissionIDsByMenuIDs :many
SELECT permission_id
FROM sys_menu_permission
WHERE menu_id = ANY ($1::int[]);
-- name: GetSysPermissionIdsByApiIDs :many
-- name: ListPermissionIDsByApiIDs :many
SELECT permission_id
FROM sys_api_permission
WHERE api_id = ANY ($1::int[]);
-- name: GetAllSysRoles :many
SELECT *
from sys_roles;
-- name: GetSysRoleMenus :many
-- name: ListRoleMenus :many
SELECT m.id, m.name
FROM sys_role_permission rp
JOIN sys_menu_permission mp ON mp.permission_id = rp.permission_id
JOIN sys_menus m ON m.id = mp.menu_id
WHERE rp.role_id = $1;
-- name: GetSysRoleApis :many
-- name: ListRoleApis :many
SELECT a.id, a."name"
FROM sys_role_permission rp
JOIN sys_api_permission ap ON ap.permission_id = rp.permission_id
JOIN sys_apis a ON a.id = ap.api_id
WHERE rp.role_id = $1;
-- name: DeleteSysRolePermissionByType :exec
-- name: DeleteRolePermissionsByType :exec
DELETE
FROM sys_role_permission rp USING sys_permissions p
WHERE rp.permission_id = p.id
AND rp.role_id = $1
AND p."type" = $2;
-- name: DeleteSysRolePermissionByRoleID :exec
-- name: DeleteRolePermissionsByRoleID :exec
DELETE
FROM sys_role_permission
WHERE role_id = $1;
-- name: DeleteSysRolePermissionByPermissionID :exec
-- name: DeleteRolePermissionByPermissionID :exec
DELETE
FROM sys_role_permission
WHERE permission_id = $1;
-- name: DeleteSysUserRoleByRoleID :exec
-- name: DeleteUserRoleByRoleID :exec
DELETE
FROM sys_user_role
WHERE role_id = $1;

View File

@@ -1,48 +1,48 @@
-- name: CreateSysUser :exec
-- name: CreateUser :exec
INSERT INTO sys_users (account, username, password_hash, status, avatar_id)
VALUES ($1, $2, $3, $4, $5);
-- name: GetActiveSysUserByID :one
-- name: GetActiveUserByID :one
-- 场景:用户登录、获取个人信息、刷新 Token严格校验 status = 1
SELECT id, account, username, status
FROM sys_users
WHERE id = $1
AND status = 1;
-- name: GetSysUserByID :one
-- name: GetUserByID :one
SELECT u.id,
u.account,
u.username,
u.avatar_id,
u.status,
f.file_path AS avatar_url,
f.file_url AS avatar_url,
u.created_at,
u.updated_at
FROM sys_users u
LEFT JOIN files f ON u.avatar_id = f.id
WHERE u.id = $1;
-- name: GetSysUserByAccount :one
-- name: GetUserByAccount :one
SELECT u.id,
u.account,
u.username,
u.password_hash,
u.status,
u.avatar_id,
f.file_path AS avatar_url,
f.file_url AS avatar_url,
u.created_at,
u.updated_at
FROM sys_users u
LEFT JOIN files f ON u.avatar_id = f.id
WHERE u.account = $1;
-- name: ListSysUsers :many
-- name: ListUsers :many
SELECT u.id,
u.account,
u.username,
u.status,
u.avatar_id,
f.file_path AS avatar_url,
f.file_url AS avatar_url,
u.created_at,
u.updated_at
FROM sys_users u
@@ -51,57 +51,57 @@ WHERE (sqlc.arg('username')::text = '' OR u.username ILIKE '%' || sqlc.arg('user
ORDER BY u.id
LIMIT $1 OFFSET $2;
-- name: CountSysUsers :one
-- name: CountUsers :one
SELECT COUNT(*)
FROM sys_users
WHERE (sqlc.arg('username')::text = '' OR username ILIKE '%' || sqlc.arg('username') || '%');
-- name: UpdateSysUser :execrows
-- name: UpdateUser :execrows
UPDATE sys_users
SET username = coalesce(sqlc.narg('username'), username),
status = coalesce(sqlc.narg('status'), status),
avatar_id = CASE WHEN @update_avatar_id::boolean THEN @avatar_id ELSE avatar_id END
WHERE id = sqlc.arg('id');
-- name: UpdateSysUserPassword :execrows
-- name: UpdateUserPassword :execrows
UPDATE sys_users
SET password_hash = $2
WHERE id = $1;
-- name: DeleteSysUser :execrows
-- name: DeleteUser :execrows
DELETE
FROM sys_users
WHERE id = $1
AND id <> 1;
-- name: ClearSysUserRoles :exec
-- name: ClearUserRoles :exec
DELETE
FROM sys_user_role
WHERE user_id = $1;
-- name: CreateSysUserRole :copyfrom
-- name: CreateUserRole :copyfrom
INSERT INTO sys_user_role (user_id, role_id)
VALUES ($1, $2);
-- name: GetSysUserRoles :many
-- name: ListUserRoles :many
SELECT r.*
FROM sys_roles r
JOIN sys_user_role ur ON r.id = ur.role_id
WHERE ur.user_id = $1;
-- name: GetSysAdminMenus :many
-- name: ListAdminMenus :many
SELECT *
FROM sys_menus
WHERE status = 1
AND type <> 2
ORDER BY sort, id;
-- name: GetSysAdminPermissions :many
-- name: ListAdminPermissionCodes :many
SELECT code
FROM sys_permissions
WHERE type = 0;
-- name: GetSysUserMenus :many
-- name: ListUserMenus :many
SELECT DISTINCT m.*
FROM sys_users u
JOIN sys_user_role ur ON ur.user_id = u.id
@@ -116,7 +116,7 @@ WHERE u.id = $1
AND m.type <> 2
ORDER BY m.sort, m.id;
-- name: GetSysUserPermissions :many
-- name: ListUserPermissionCodes :many
SELECT DISTINCT p.code
FROM sys_users u
JOIN sys_user_role ur ON u.id = ur.user_id
@@ -131,7 +131,7 @@ WHERE u.id = $1
AND m.status = 1
AND p."type" = 0;
-- name: GetSysUserApis :many
-- name: ListUserApis :many
SELECT DISTINCT a.id,
a.PATH,
a.METHOD

View File

@@ -1,12 +1,13 @@
CREATE TABLE files
(
id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
file_name TEXT NOT NULL,
file_path TEXT NOT NULL,
original_name TEXT NOT NULL,
folder_name TEXT NOT NULL,
mime_type TEXT NOT NULL,
file_size BIGINT NOT NULL,
file_name TEXT NOT NULL,
file_path TEXT NOT NULL,
file_url TEXT NOT NULL,
original_name TEXT NOT NULL,
folder_name TEXT NOT NULL,
mime_type TEXT NOT NULL,
file_size BIGINT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ
);
@@ -20,6 +21,7 @@ EXECUTE FUNCTION update_updated_at_column();
COMMENT ON COLUMN files.id IS '主键ID';
COMMENT ON COLUMN files.file_name IS '文件名 xxx.jpg';
COMMENT ON COLUMN files.file_path IS '文件路径 带path /xxx/xxx.jpg';
COMMENT ON COLUMN files.file_url IS '完整路径';
COMMENT ON COLUMN files.original_name IS '原始文件名';
COMMENT ON COLUMN files.folder_name IS '文件夹名称';
COMMENT ON COLUMN files.mime_type IS 'mime_type';

View File

@@ -42,13 +42,13 @@ func (q *Queries) CreatePostTag(ctx context.Context, arg []CreatePostTagParams)
return q.db.CopyFrom(ctx, []string{"post_tag"}, []string{"post_id", "tag_id"}, &iteratorForCreatePostTag{rows: arg})
}
// iteratorForCreateSysRolePermission implements pgx.CopyFromSource.
type iteratorForCreateSysRolePermission struct {
rows []CreateSysRolePermissionParams
// iteratorForCreateRolePermission implements pgx.CopyFromSource.
type iteratorForCreateRolePermission struct {
rows []CreateRolePermissionParams
skippedFirstNextCall bool
}
func (r *iteratorForCreateSysRolePermission) Next() bool {
func (r *iteratorForCreateRolePermission) Next() bool {
if len(r.rows) == 0 {
return false
}
@@ -60,28 +60,28 @@ func (r *iteratorForCreateSysRolePermission) Next() bool {
return len(r.rows) > 0
}
func (r iteratorForCreateSysRolePermission) Values() ([]interface{}, error) {
func (r iteratorForCreateRolePermission) Values() ([]interface{}, error) {
return []interface{}{
r.rows[0].RoleID,
r.rows[0].PermissionID,
}, nil
}
func (r iteratorForCreateSysRolePermission) Err() error {
func (r iteratorForCreateRolePermission) Err() error {
return nil
}
func (q *Queries) CreateSysRolePermission(ctx context.Context, arg []CreateSysRolePermissionParams) (int64, error) {
return q.db.CopyFrom(ctx, []string{"sys_role_permission"}, []string{"role_id", "permission_id"}, &iteratorForCreateSysRolePermission{rows: arg})
func (q *Queries) CreateRolePermission(ctx context.Context, arg []CreateRolePermissionParams) (int64, error) {
return q.db.CopyFrom(ctx, []string{"sys_role_permission"}, []string{"role_id", "permission_id"}, &iteratorForCreateRolePermission{rows: arg})
}
// iteratorForCreateSysUserRole implements pgx.CopyFromSource.
type iteratorForCreateSysUserRole struct {
rows []CreateSysUserRoleParams
// iteratorForCreateUserRole implements pgx.CopyFromSource.
type iteratorForCreateUserRole struct {
rows []CreateUserRoleParams
skippedFirstNextCall bool
}
func (r *iteratorForCreateSysUserRole) Next() bool {
func (r *iteratorForCreateUserRole) Next() bool {
if len(r.rows) == 0 {
return false
}
@@ -93,17 +93,17 @@ func (r *iteratorForCreateSysUserRole) Next() bool {
return len(r.rows) > 0
}
func (r iteratorForCreateSysUserRole) Values() ([]interface{}, error) {
func (r iteratorForCreateUserRole) Values() ([]interface{}, error) {
return []interface{}{
r.rows[0].UserID,
r.rows[0].RoleID,
}, nil
}
func (r iteratorForCreateSysUserRole) Err() error {
func (r iteratorForCreateUserRole) Err() error {
return nil
}
func (q *Queries) CreateSysUserRole(ctx context.Context, arg []CreateSysUserRoleParams) (int64, error) {
return q.db.CopyFrom(ctx, []string{"sys_user_role"}, []string{"user_id", "role_id"}, &iteratorForCreateSysUserRole{rows: arg})
func (q *Queries) CreateUserRole(ctx context.Context, arg []CreateUserRoleParams) (int64, error) {
return q.db.CopyFrom(ctx, []string{"sys_user_role"}, []string{"user_id", "role_id"}, &iteratorForCreateUserRole{rows: arg})
}

View File

@@ -22,8 +22,9 @@ func (q *Queries) CountFiles(ctx context.Context) (int64, error) {
}
const createFile = `-- name: CreateFile :one
INSERT INTO files(file_name, file_path, original_name, folder_name, mime_type, file_size)
VALUES ($1, $2, $3, $4, $5, $6) RETURNING id,file_path,file_name
INSERT INTO files(file_name, file_path, original_name, folder_name, mime_type, file_size, file_url)
VALUES ($1, $2, $3, $4, $5, $6, $7)
RETURNING id,file_url,file_name
`
type CreateFileParams struct {
@@ -33,11 +34,12 @@ type CreateFileParams struct {
FolderName string `json:"folder_name"`
MimeType string `json:"mime_type"`
FileSize int64 `json:"file_size"`
FileUrl string `json:"file_url"`
}
type CreateFileRow struct {
ID int32 `json:"id"`
FilePath string `json:"file_path"`
FileUrl string `json:"file_url"`
FileName string `json:"file_name"`
}
@@ -49,26 +51,27 @@ func (q *Queries) CreateFile(ctx context.Context, arg CreateFileParams) (CreateF
arg.FolderName,
arg.MimeType,
arg.FileSize,
arg.FileUrl,
)
var i CreateFileRow
err := row.Scan(&i.ID, &i.FilePath, &i.FileName)
err := row.Scan(&i.ID, &i.FileUrl, &i.FileName)
return i, err
}
const getFiles = `-- name: GetFiles :many
SELECT id, file_name, file_path, original_name, folder_name, mime_type, file_size, created_at, updated_at
const listFiles = `-- name: ListFiles :many
SELECT id, file_name, file_path, file_url, original_name, folder_name, mime_type, file_size, created_at, updated_at
FROM files
ORDER BY id LIMIT $1
OFFSET $2
ORDER BY id
LIMIT $1 OFFSET $2
`
type GetFilesParams struct {
type ListFilesParams struct {
Limit int32 `json:"limit"`
Offset int32 `json:"offset"`
}
func (q *Queries) GetFiles(ctx context.Context, arg GetFilesParams) ([]File, error) {
rows, err := q.db.Query(ctx, getFiles, arg.Limit, arg.Offset)
func (q *Queries) ListFiles(ctx context.Context, arg ListFilesParams) ([]File, error) {
rows, err := q.db.Query(ctx, listFiles, arg.Limit, arg.Offset)
if err != nil {
return nil, err
}
@@ -80,6 +83,7 @@ func (q *Queries) GetFiles(ctx context.Context, arg GetFilesParams) ([]File, err
&i.ID,
&i.FileName,
&i.FilePath,
&i.FileUrl,
&i.OriginalName,
&i.FolderName,
&i.MimeType,

View File

@@ -29,6 +29,8 @@ type File struct {
FileName string `json:"file_name"`
// 文件路径 带path /xxx/xxx.jpg
FilePath string `json:"file_path"`
// 完整路径
FileUrl string `json:"file_url"`
// 原始文件名
OriginalName string `json:"original_name"`
// 文件夹名称

View File

@@ -83,9 +83,9 @@ func (q *Queries) DeletePost(ctx context.Context, id int32) (int64, error) {
return result.RowsAffected(), nil
}
const getPostById = `-- name: GetPostById :one
const getPostByID = `-- name: GetPostByID :one
SELECT p.id, p.title, p.cover_id, p.slug, p.content, p.summary, p.status, p.sort, p.published_at, p.created_at, p.updated_at,
f.file_path AS cover,
f.file_url AS cover,
c.name AS category_name,
c.id AS category_id,
COALESCE(
@@ -99,13 +99,13 @@ FROM posts p
LEFT JOIN post_tag pt ON pt.post_id = p.id
WHERE p.id = $1
GROUP BY p.id,
f.file_path,
f.file_url,
c.name,
c.id
LIMIT 1
`
type GetPostByIdRow struct {
type GetPostByIDRow struct {
ID int32 `json:"id"`
Title string `json:"title"`
CoverID *int32 `json:"cover_id"`
@@ -123,9 +123,9 @@ type GetPostByIdRow struct {
Tags interface{} `json:"tags"`
}
func (q *Queries) GetPostById(ctx context.Context, id int32) (GetPostByIdRow, error) {
row := q.db.QueryRow(ctx, getPostById, id)
var i GetPostByIdRow
func (q *Queries) GetPostByID(ctx context.Context, id int32) (GetPostByIDRow, error) {
row := q.db.QueryRow(ctx, getPostByID, id)
var i GetPostByIDRow
err := row.Scan(
&i.ID,
&i.Title,
@@ -149,7 +149,7 @@ func (q *Queries) GetPostById(ctx context.Context, id int32) (GetPostByIdRow, er
const getPublicPostBySlug = `-- name: GetPublicPostBySlug :one
SELECT p.id, p.title, p.cover_id, p.slug, p.content, p.summary, p.status, p.sort, p.published_at, p.created_at, p.updated_at,
f.file_path AS cover,
f.file_url AS cover,
COALESCE(ps.view, 0) AS view
FROM posts p
LEFT JOIN files f ON f.id = p.cover_id
@@ -312,7 +312,7 @@ WITH paginated_posts AS (
LIMIT $1 OFFSET $2
)
SELECT p.id, p.title, p.cover_id, p.slug, p.summary, p.status, p.sort, p.published_at, p.created_at, p.updated_at,
f.file_path AS cover,
f.file_url AS cover,
c.name AS category_name,
c.id AS category_id,
COALESCE(ps.view, 0) AS view,
@@ -344,7 +344,7 @@ GROUP BY p.id,
p.published_at,
p.created_at,
p.updated_at,
f.file_path,
f.file_url,
c.name,
c.id,
ps.view
@@ -427,7 +427,7 @@ WITH paginated_posts AS (
ORDER BY sort DESC, published_at DESC, id DESC
LIMIT $1 OFFSET $2)
SELECT p.id, p.title, p.cover_id, p.slug, p.summary, p.sort, p.published_at,
f.file_path AS cover,
f.file_url AS cover,
c.name AS category_name,
c.id AS category_id,
COALESCE(ps.view, 0) AS view,
@@ -456,7 +456,7 @@ GROUP BY p.id,
p.summary,
p.sort,
p.published_at,
f.file_path,
f.file_url,
c.name,
c.id,
ps.view

View File

@@ -9,32 +9,34 @@ import (
"context"
)
const countSysApis = `-- name: CountSysApis :one
const countApis = `-- name: CountApis :one
SELECT COUNT(*)
FROM sys_apis
WHERE ($1::text = '' OR group_name ILIKE '%' || $1 || '%')
AND ($2::text = '' OR method = $2)
WHERE ($1::text = '' OR name ILIKE '%' || $1 || '%')
AND ($2::text = '' OR group_name ILIKE '%' || $2 || '%')
AND ($3::text = '' OR method = $3)
`
type CountSysApisParams struct {
type CountApisParams struct {
Name string `json:"name"`
GroupName string `json:"group_name"`
Method string `json:"method"`
}
func (q *Queries) CountSysApis(ctx context.Context, arg CountSysApisParams) (int64, error) {
row := q.db.QueryRow(ctx, countSysApis, arg.GroupName, arg.Method)
func (q *Queries) CountApis(ctx context.Context, arg CountApisParams) (int64, error) {
row := q.db.QueryRow(ctx, countApis, arg.Name, arg.GroupName, arg.Method)
var count int64
err := row.Scan(&count)
return count, err
}
const createSysApi = `-- name: CreateSysApi :one
const createApi = `-- name: CreateApi :one
INSERT INTO sys_apis (name, group_name, method, path, sort)
VALUES ($1, $2, $3, $4, $5)
RETURNING id
`
type CreateSysApiParams struct {
type CreateApiParams struct {
Name string `json:"name"`
GroupName string `json:"group_name"`
Method string `json:"method"`
@@ -42,8 +44,8 @@ type CreateSysApiParams struct {
Sort *int32 `json:"sort"`
}
func (q *Queries) CreateSysApi(ctx context.Context, arg CreateSysApiParams) (int32, error) {
row := q.db.QueryRow(ctx, createSysApi,
func (q *Queries) CreateApi(ctx context.Context, arg CreateApiParams) (int32, error) {
row := q.db.QueryRow(ctx, createApi,
arg.Name,
arg.GroupName,
arg.Method,
@@ -55,54 +57,76 @@ func (q *Queries) CreateSysApi(ctx context.Context, arg CreateSysApiParams) (int
return id, err
}
const createSysApiPermission = `-- name: CreateSysApiPermission :exec
const createApiPermission = `-- name: CreateApiPermission :exec
INSERT INTO sys_api_permission (api_id, permission_id)
VALUES ($1, $2)
`
type CreateSysApiPermissionParams struct {
type CreateApiPermissionParams struct {
ApiID int32 `json:"api_id"`
PermissionID int32 `json:"permission_id"`
}
func (q *Queries) CreateSysApiPermission(ctx context.Context, arg CreateSysApiPermissionParams) error {
_, err := q.db.Exec(ctx, createSysApiPermission, arg.ApiID, arg.PermissionID)
func (q *Queries) CreateApiPermission(ctx context.Context, arg CreateApiPermissionParams) error {
_, err := q.db.Exec(ctx, createApiPermission, arg.ApiID, arg.PermissionID)
return err
}
const deleteSysApi = `-- name: DeleteSysApi :execrows
const deleteApi = `-- name: DeleteApi :execrows
DELETE
FROM sys_apis
WHERE id = $1
`
func (q *Queries) DeleteSysApi(ctx context.Context, id int32) (int64, error) {
result, err := q.db.Exec(ctx, deleteSysApi, id)
func (q *Queries) DeleteApi(ctx context.Context, id int32) (int64, error) {
result, err := q.db.Exec(ctx, deleteApi, id)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}
const deleteSysApiPermission = `-- name: DeleteSysApiPermission :exec
const deleteApiPermission = `-- name: DeleteApiPermission :exec
DELETE
FROM sys_api_permission
WHERE api_id = $1
`
func (q *Queries) DeleteSysApiPermission(ctx context.Context, apiID int32) error {
_, err := q.db.Exec(ctx, deleteSysApiPermission, apiID)
func (q *Queries) DeleteApiPermission(ctx context.Context, apiID int32) error {
_, err := q.db.Exec(ctx, deleteApiPermission, apiID)
return err
}
const getAllSysApis = `-- name: GetAllSysApis :many
const getApiByID = `-- name: GetApiByID :one
SELECT id, group_name, name, method, path, sort, created_at, updated_at
FROM sys_apis
WHERE id = $1
`
func (q *Queries) GetApiByID(ctx context.Context, id int32) (SysApi, error) {
row := q.db.QueryRow(ctx, getApiByID, id)
var i SysApi
err := row.Scan(
&i.ID,
&i.GroupName,
&i.Name,
&i.Method,
&i.Path,
&i.Sort,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const listAllApis = `-- name: ListAllApis :many
SELECT id, group_name, name, method, path, sort, created_at, updated_at
FROM sys_apis
ORDER BY sort ASC
`
func (q *Queries) GetAllSysApis(ctx context.Context) ([]SysApi, error) {
rows, err := q.db.Query(ctx, getAllSysApis)
func (q *Queries) ListAllApis(ctx context.Context) ([]SysApi, error) {
rows, err := q.db.Query(ctx, listAllApis)
if err != nil {
return nil, err
}
@@ -130,35 +154,13 @@ func (q *Queries) GetAllSysApis(ctx context.Context) ([]SysApi, error) {
return items, nil
}
const getSysApiByID = `-- name: GetSysApiByID :one
SELECT id, group_name, name, method, path, sort, created_at, updated_at
FROM sys_apis
WHERE id = $1
`
func (q *Queries) GetSysApiByID(ctx context.Context, id int32) (SysApi, error) {
row := q.db.QueryRow(ctx, getSysApiByID, id)
var i SysApi
err := row.Scan(
&i.ID,
&i.GroupName,
&i.Name,
&i.Method,
&i.Path,
&i.Sort,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const getSysApiGroupNames = `-- name: GetSysApiGroupNames :many
const listApiGroups = `-- name: ListApiGroups :many
SELECT DISTINCT group_name
FROM sys_apis
`
func (q *Queries) GetSysApiGroupNames(ctx context.Context) ([]string, error) {
rows, err := q.db.Query(ctx, getSysApiGroupNames)
func (q *Queries) ListApiGroups(ctx context.Context) ([]string, error) {
rows, err := q.db.Query(ctx, listApiGroups)
if err != nil {
return nil, err
}
@@ -177,26 +179,29 @@ func (q *Queries) GetSysApiGroupNames(ctx context.Context) ([]string, error) {
return items, nil
}
const getSysApis = `-- name: GetSysApis :many
const listApis = `-- name: ListApis :many
SELECT id, group_name, name, method, path, sort, created_at, updated_at
FROM sys_apis
WHERE ($3::text = '' OR group_name ILIKE '%' || $3 || '%')
AND ($4::text = '' OR method = $4)
WHERE ($3::text = '' OR name ILIKE '%' || $3 || '%')
AND ($4::text = '' OR group_name ILIKE '%' || $4 || '%')
AND ($5::text = '' OR method = $5)
ORDER BY id
LIMIT $1 OFFSET $2
`
type GetSysApisParams struct {
type ListApisParams struct {
Limit int32 `json:"limit"`
Offset int32 `json:"offset"`
Name string `json:"name"`
GroupName string `json:"group_name"`
Method string `json:"method"`
}
func (q *Queries) GetSysApis(ctx context.Context, arg GetSysApisParams) ([]SysApi, error) {
rows, err := q.db.Query(ctx, getSysApis,
func (q *Queries) ListApis(ctx context.Context, arg ListApisParams) ([]SysApi, error) {
rows, err := q.db.Query(ctx, listApis,
arg.Limit,
arg.Offset,
arg.Name,
arg.GroupName,
arg.Method,
)
@@ -227,7 +232,7 @@ func (q *Queries) GetSysApis(ctx context.Context, arg GetSysApisParams) ([]SysAp
return items, nil
}
const updateSysApi = `-- name: UpdateSysApi :execrows
const updateApi = `-- name: UpdateApi :execrows
UPDATE sys_apis
SET name = $2,
method = $3,
@@ -237,7 +242,7 @@ SET name = $2,
WHERE id = $1
`
type UpdateSysApiParams struct {
type UpdateApiParams struct {
ID int32 `json:"id"`
Name string `json:"name"`
Method string `json:"method"`
@@ -246,8 +251,8 @@ type UpdateSysApiParams struct {
GroupName string `json:"group_name"`
}
func (q *Queries) UpdateSysApi(ctx context.Context, arg UpdateSysApiParams) (int64, error) {
result, err := q.db.Exec(ctx, updateSysApi,
func (q *Queries) UpdateApi(ctx context.Context, arg UpdateApiParams) (int64, error) {
result, err := q.db.Exec(ctx, updateApi,
arg.ID,
arg.Name,
arg.Method,

View File

@@ -10,25 +10,25 @@ import (
"time"
)
const countSysMenus = `-- name: CountSysMenus :one
const countMenus = `-- name: CountMenus :one
SELECT COUNT(*)
FROM sys_menus
`
func (q *Queries) CountSysMenus(ctx context.Context) (int64, error) {
row := q.db.QueryRow(ctx, countSysMenus)
func (q *Queries) CountMenus(ctx context.Context) (int64, error) {
row := q.db.QueryRow(ctx, countMenus)
var count int64
err := row.Scan(&count)
return count, err
}
const createSysMenu = `-- name: CreateSysMenu :one
const createMenu = `-- name: CreateMenu :one
INSERT INTO sys_menus (name, path, component, type, hidden, sort, status, parent_id, icon)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
RETURNING id
`
type CreateSysMenuParams struct {
type CreateMenuParams struct {
Name string `json:"name"`
Path *string `json:"path"`
Component *string `json:"component"`
@@ -40,8 +40,8 @@ type CreateSysMenuParams struct {
Icon *int32 `json:"icon"`
}
func (q *Queries) CreateSysMenu(ctx context.Context, arg CreateSysMenuParams) (int32, error) {
row := q.db.QueryRow(ctx, createSysMenu,
func (q *Queries) CreateMenu(ctx context.Context, arg CreateMenuParams) (int32, error) {
row := q.db.QueryRow(ctx, createMenu,
arg.Name,
arg.Path,
arg.Component,
@@ -57,47 +57,47 @@ func (q *Queries) CreateSysMenu(ctx context.Context, arg CreateSysMenuParams) (i
return id, err
}
const createSysMenuPermission = `-- name: CreateSysMenuPermission :exec
const createMenuPermission = `-- name: CreateMenuPermission :exec
INSERT INTO sys_menu_permission (menu_id, permission_id)
VALUES ($1, $2)
`
type CreateSysMenuPermissionParams struct {
type CreateMenuPermissionParams struct {
MenuID int32 `json:"menu_id"`
PermissionID int32 `json:"permission_id"`
}
func (q *Queries) CreateSysMenuPermission(ctx context.Context, arg CreateSysMenuPermissionParams) error {
_, err := q.db.Exec(ctx, createSysMenuPermission, arg.MenuID, arg.PermissionID)
func (q *Queries) CreateMenuPermission(ctx context.Context, arg CreateMenuPermissionParams) error {
_, err := q.db.Exec(ctx, createMenuPermission, arg.MenuID, arg.PermissionID)
return err
}
const deleteSysMenu = `-- name: DeleteSysMenu :execrows
const deleteMenu = `-- name: DeleteMenu :execrows
DELETE
FROM sys_menus
WHERE id = $1
`
func (q *Queries) DeleteSysMenu(ctx context.Context, id int32) (int64, error) {
result, err := q.db.Exec(ctx, deleteSysMenu, id)
func (q *Queries) DeleteMenu(ctx context.Context, id int32) (int64, error) {
result, err := q.db.Exec(ctx, deleteMenu, id)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}
const deleteSysMenuPermission = `-- name: DeleteSysMenuPermission :exec
const deleteMenuPermission = `-- name: DeleteMenuPermission :exec
DELETE
FROM sys_menu_permission
WHERE menu_id = $1
`
func (q *Queries) DeleteSysMenuPermission(ctx context.Context, menuID int32) error {
_, err := q.db.Exec(ctx, deleteSysMenuPermission, menuID)
func (q *Queries) DeleteMenuPermission(ctx context.Context, menuID int32) error {
_, err := q.db.Exec(ctx, deleteMenuPermission, menuID)
return err
}
const deleteSysPermissionByMenuID = `-- name: DeleteSysPermissionByMenuID :exec
const deletePermissionsByMenuID = `-- name: DeletePermissionsByMenuID :exec
DELETE
FROM sys_permissions
WHERE id IN (SELECT permission_id
@@ -105,79 +105,19 @@ WHERE id IN (SELECT permission_id
WHERE menu_id = $1)
`
func (q *Queries) DeleteSysPermissionByMenuID(ctx context.Context, menuID int32) error {
_, err := q.db.Exec(ctx, deleteSysPermissionByMenuID, menuID)
func (q *Queries) DeletePermissionsByMenuID(ctx context.Context, menuID int32) error {
_, err := q.db.Exec(ctx, deletePermissionsByMenuID, menuID)
return err
}
const getAllSysMenus = `-- name: GetAllSysMenus :many
SELECT m.id, m.name, m.path, m.component, m.type, m.hidden, m.sort, m.status, m.parent_id, m.icon, m.created_at, m.updated_at,
p.code AS permission_code
FROM sys_menus m
LEFT JOIN sys_menu_permission mp ON m.id = mp.menu_id
LEFT JOIN sys_permissions p ON p.id = mp.permission_id
ORDER BY m.sort ASC,
m.id ASC
`
type GetAllSysMenusRow struct {
ID int32 `json:"id"`
Name string `json:"name"`
Path *string `json:"path"`
Component *string `json:"component"`
Type int16 `json:"type"`
Hidden *bool `json:"hidden"`
Sort *int32 `json:"sort"`
Status int16 `json:"status"`
ParentID *int32 `json:"parent_id"`
Icon *int32 `json:"icon"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt *time.Time `json:"updated_at"`
PermissionCode *string `json:"permission_code"`
}
func (q *Queries) GetAllSysMenus(ctx context.Context) ([]GetAllSysMenusRow, error) {
rows, err := q.db.Query(ctx, getAllSysMenus)
if err != nil {
return nil, err
}
defer rows.Close()
items := []GetAllSysMenusRow{}
for rows.Next() {
var i GetAllSysMenusRow
if err := rows.Scan(
&i.ID,
&i.Name,
&i.Path,
&i.Component,
&i.Type,
&i.Hidden,
&i.Sort,
&i.Status,
&i.ParentID,
&i.Icon,
&i.CreatedAt,
&i.UpdatedAt,
&i.PermissionCode,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getSysMenuByID = `-- name: GetSysMenuByID :one
const getMenuByID = `-- name: GetMenuByID :one
SELECT id, name, path, component, type, hidden, sort, status, parent_id, icon, created_at, updated_at
FROM sys_menus
WHERE id = $1
`
func (q *Queries) GetSysMenuByID(ctx context.Context, id int32) (SysMenu, error) {
row := q.db.QueryRow(ctx, getSysMenuByID, id)
func (q *Queries) GetMenuByID(ctx context.Context, id int32) (SysMenu, error) {
row := q.db.QueryRow(ctx, getMenuByID, id)
var i SysMenu
err := row.Scan(
&i.ID,
@@ -196,21 +136,17 @@ func (q *Queries) GetSysMenuByID(ctx context.Context, id int32) (SysMenu, error)
return i, err
}
const listSysMenus = `-- name: ListSysMenus :many
SELECT m.id, m.name, m.path, m.component, m.type, m.hidden, m.sort, m.status, m.parent_id, m.icon, m.created_at, m.updated_at, p.code AS permission_code
const listAllMenus = `-- name: ListAllMenus :many
SELECT m.id, m.name, m.path, m.component, m.type, m.hidden, m.sort, m.status, m.parent_id, m.icon, m.created_at, m.updated_at,
p.code AS permission_code
FROM sys_menus m
LEFT JOIN sys_menu_permission mp ON m.id = mp.menu_id
LEFT JOIN sys_permissions p ON mp.permission_id = p.id
ORDER BY m.id
LIMIT $1 OFFSET $2
LEFT JOIN sys_permissions p ON p.id = mp.permission_id
ORDER BY m.sort ASC,
m.id ASC
`
type ListSysMenusParams struct {
Limit int32 `json:"limit"`
Offset int32 `json:"offset"`
}
type ListSysMenusRow struct {
type ListAllMenusRow struct {
ID int32 `json:"id"`
Name string `json:"name"`
Path *string `json:"path"`
@@ -226,15 +162,15 @@ type ListSysMenusRow struct {
PermissionCode *string `json:"permission_code"`
}
func (q *Queries) ListSysMenus(ctx context.Context, arg ListSysMenusParams) ([]ListSysMenusRow, error) {
rows, err := q.db.Query(ctx, listSysMenus, arg.Limit, arg.Offset)
func (q *Queries) ListAllMenus(ctx context.Context) ([]ListAllMenusRow, error) {
rows, err := q.db.Query(ctx, listAllMenus)
if err != nil {
return nil, err
}
defer rows.Close()
items := []ListSysMenusRow{}
items := []ListAllMenusRow{}
for rows.Next() {
var i ListSysMenusRow
var i ListAllMenusRow
if err := rows.Scan(
&i.ID,
&i.Name,
@@ -260,7 +196,71 @@ func (q *Queries) ListSysMenus(ctx context.Context, arg ListSysMenusParams) ([]L
return items, nil
}
const updateSysMenu = `-- name: UpdateSysMenu :execrows
const listMenus = `-- name: ListMenus :many
SELECT m.id, m.name, m.path, m.component, m.type, m.hidden, m.sort, m.status, m.parent_id, m.icon, m.created_at, m.updated_at, p.code AS permission_code
FROM sys_menus m
LEFT JOIN sys_menu_permission mp ON m.id = mp.menu_id
LEFT JOIN sys_permissions p ON mp.permission_id = p.id
ORDER BY m.id
LIMIT $1 OFFSET $2
`
type ListMenusParams struct {
Limit int32 `json:"limit"`
Offset int32 `json:"offset"`
}
type ListMenusRow struct {
ID int32 `json:"id"`
Name string `json:"name"`
Path *string `json:"path"`
Component *string `json:"component"`
Type int16 `json:"type"`
Hidden *bool `json:"hidden"`
Sort *int32 `json:"sort"`
Status int16 `json:"status"`
ParentID *int32 `json:"parent_id"`
Icon *int32 `json:"icon"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt *time.Time `json:"updated_at"`
PermissionCode *string `json:"permission_code"`
}
func (q *Queries) ListMenus(ctx context.Context, arg ListMenusParams) ([]ListMenusRow, error) {
rows, err := q.db.Query(ctx, listMenus, arg.Limit, arg.Offset)
if err != nil {
return nil, err
}
defer rows.Close()
items := []ListMenusRow{}
for rows.Next() {
var i ListMenusRow
if err := rows.Scan(
&i.ID,
&i.Name,
&i.Path,
&i.Component,
&i.Type,
&i.Hidden,
&i.Sort,
&i.Status,
&i.ParentID,
&i.Icon,
&i.CreatedAt,
&i.UpdatedAt,
&i.PermissionCode,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const updateMenu = `-- name: UpdateMenu :execrows
UPDATE sys_menus
SET name = coalesce($1, name),
path = coalesce($2, path),
@@ -274,7 +274,7 @@ SET name = coalesce($1, name),
WHERE id = $12
`
type UpdateSysMenuParams struct {
type UpdateMenuParams struct {
Name *string `json:"name"`
Path *string `json:"path"`
Component *string `json:"component"`
@@ -289,8 +289,8 @@ type UpdateSysMenuParams struct {
ID int32 `json:"id"`
}
func (q *Queries) UpdateSysMenu(ctx context.Context, arg UpdateSysMenuParams) (int64, error) {
result, err := q.db.Exec(ctx, updateSysMenu,
func (q *Queries) UpdateMenu(ctx context.Context, arg UpdateMenuParams) (int64, error) {
result, err := q.db.Exec(ctx, updateMenu,
arg.Name,
arg.Path,
arg.Component,
@@ -310,7 +310,7 @@ func (q *Queries) UpdateSysMenu(ctx context.Context, arg UpdateSysMenuParams) (i
return result.RowsAffected(), nil
}
const updateSysMenuPermissionCode = `-- name: UpdateSysMenuPermissionCode :exec
const updateMenuPermissionCode = `-- name: UpdateMenuPermissionCode :exec
UPDATE sys_permissions p
SET code = coalesce($2, code)
FROM sys_menu_permission mp
@@ -318,12 +318,12 @@ WHERE p.id = mp.permission_id
AND mp.menu_id = $1
`
type UpdateSysMenuPermissionCodeParams struct {
type UpdateMenuPermissionCodeParams struct {
MenuID int32 `json:"menu_id"`
Code *string `json:"code"`
}
func (q *Queries) UpdateSysMenuPermissionCode(ctx context.Context, arg UpdateSysMenuPermissionCodeParams) error {
_, err := q.db.Exec(ctx, updateSysMenuPermissionCode, arg.MenuID, arg.Code)
func (q *Queries) UpdateMenuPermissionCode(ctx context.Context, arg UpdateMenuPermissionCodeParams) error {
_, err := q.db.Exec(ctx, updateMenuPermissionCode, arg.MenuID, arg.Code)
return err
}

View File

@@ -9,72 +9,72 @@ import (
"context"
)
const createSysPermission = `-- name: CreateSysPermission :one
const createPermission = `-- name: CreatePermission :one
INSERT INTO sys_permissions(type,code)
VALUES ($1,$2) RETURNING id
`
type CreateSysPermissionParams struct {
type CreatePermissionParams struct {
Type int16 `json:"type"`
Code *string `json:"code"`
}
func (q *Queries) CreateSysPermission(ctx context.Context, arg CreateSysPermissionParams) (int32, error) {
row := q.db.QueryRow(ctx, createSysPermission, arg.Type, arg.Code)
func (q *Queries) CreatePermission(ctx context.Context, arg CreatePermissionParams) (int32, error) {
row := q.db.QueryRow(ctx, createPermission, arg.Type, arg.Code)
var id int32
err := row.Scan(&id)
return id, err
}
const deleteSysPermission = `-- name: DeleteSysPermission :exec
const deletePermission = `-- name: DeletePermission :exec
DELETE
FROM sys_permissions
WHERE id = $1
`
func (q *Queries) DeleteSysPermission(ctx context.Context, id int32) error {
_, err := q.db.Exec(ctx, deleteSysPermission, id)
func (q *Queries) DeletePermission(ctx context.Context, id int32) error {
_, err := q.db.Exec(ctx, deletePermission, id)
return err
}
const getSysPermissionIDBySysApiID = `-- name: GetSysPermissionIDBySysApiID :one
const getPermissionIDBySysApiID = `-- name: GetPermissionIDBySysApiID :one
SELECT permission_id
FROM sys_api_permission
WHERE api_id = $1
`
func (q *Queries) GetSysPermissionIDBySysApiID(ctx context.Context, apiID int32) (int32, error) {
row := q.db.QueryRow(ctx, getSysPermissionIDBySysApiID, apiID)
func (q *Queries) GetPermissionIDBySysApiID(ctx context.Context, apiID int32) (int32, error) {
row := q.db.QueryRow(ctx, getPermissionIDBySysApiID, apiID)
var permission_id int32
err := row.Scan(&permission_id)
return permission_id, err
}
const getSysPermissionIDBySysMenuID = `-- name: GetSysPermissionIDBySysMenuID :one
const getPermissionIDBySysMenuID = `-- name: GetPermissionIDBySysMenuID :one
SELECT permission_id
FROM sys_menu_permission
WHERE menu_id = $1
`
func (q *Queries) GetSysPermissionIDBySysMenuID(ctx context.Context, menuID int32) (int32, error) {
row := q.db.QueryRow(ctx, getSysPermissionIDBySysMenuID, menuID)
func (q *Queries) GetPermissionIDBySysMenuID(ctx context.Context, menuID int32) (int32, error) {
row := q.db.QueryRow(ctx, getPermissionIDBySysMenuID, menuID)
var permission_id int32
err := row.Scan(&permission_id)
return permission_id, err
}
const updateSysPermission = `-- name: UpdateSysPermission :exec
const updatePermission = `-- name: UpdatePermission :exec
UPDATE sys_permissions
SET code = $2
WHERE id = $1
`
type UpdateSysPermissionParams struct {
type UpdatePermissionParams struct {
ID int32 `json:"id"`
Code *string `json:"code"`
}
func (q *Queries) UpdateSysPermission(ctx context.Context, arg UpdateSysPermissionParams) error {
_, err := q.db.Exec(ctx, updateSysPermission, arg.ID, arg.Code)
func (q *Queries) UpdatePermission(ctx context.Context, arg UpdatePermissionParams) error {
_, err := q.db.Exec(ctx, updatePermission, arg.ID, arg.Code)
return err
}

View File

@@ -9,76 +9,76 @@ import (
"context"
)
const countSysRoles = `-- name: CountSysRoles :one
const countRoles = `-- name: CountRoles :one
SELECT COUNT(*)
FROM sys_roles
`
func (q *Queries) CountSysRoles(ctx context.Context) (int64, error) {
row := q.db.QueryRow(ctx, countSysRoles)
func (q *Queries) CountRoles(ctx context.Context) (int64, error) {
row := q.db.QueryRow(ctx, countRoles)
var count int64
err := row.Scan(&count)
return count, err
}
const createSysRole = `-- name: CreateSysRole :exec
const createRole = `-- name: CreateRole :exec
INSERT INTO sys_roles (name, code, status)
VALUES ($1, $2, $3)
`
type CreateSysRoleParams struct {
type CreateRoleParams struct {
Name string `json:"name"`
Code string `json:"code"`
Status int16 `json:"status"`
}
func (q *Queries) CreateSysRole(ctx context.Context, arg CreateSysRoleParams) error {
_, err := q.db.Exec(ctx, createSysRole, arg.Name, arg.Code, arg.Status)
func (q *Queries) CreateRole(ctx context.Context, arg CreateRoleParams) error {
_, err := q.db.Exec(ctx, createRole, arg.Name, arg.Code, arg.Status)
return err
}
type CreateSysRolePermissionParams struct {
type CreateRolePermissionParams struct {
RoleID int32 `json:"role_id"`
PermissionID int32 `json:"permission_id"`
}
const deleteSysRole = `-- name: DeleteSysRole :execrows
const deleteRole = `-- name: DeleteRole :execrows
DELETE
FROM sys_roles
WHERE id = $1
`
func (q *Queries) DeleteSysRole(ctx context.Context, id int32) (int64, error) {
result, err := q.db.Exec(ctx, deleteSysRole, id)
func (q *Queries) DeleteRole(ctx context.Context, id int32) (int64, error) {
result, err := q.db.Exec(ctx, deleteRole, id)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}
const deleteSysRolePermissionByPermissionID = `-- name: DeleteSysRolePermissionByPermissionID :exec
const deleteRolePermissionByPermissionID = `-- name: DeleteRolePermissionByPermissionID :exec
DELETE
FROM sys_role_permission
WHERE permission_id = $1
`
func (q *Queries) DeleteSysRolePermissionByPermissionID(ctx context.Context, permissionID int32) error {
_, err := q.db.Exec(ctx, deleteSysRolePermissionByPermissionID, permissionID)
func (q *Queries) DeleteRolePermissionByPermissionID(ctx context.Context, permissionID int32) error {
_, err := q.db.Exec(ctx, deleteRolePermissionByPermissionID, permissionID)
return err
}
const deleteSysRolePermissionByRoleID = `-- name: DeleteSysRolePermissionByRoleID :exec
const deleteRolePermissionsByRoleID = `-- name: DeleteRolePermissionsByRoleID :exec
DELETE
FROM sys_role_permission
WHERE role_id = $1
`
func (q *Queries) DeleteSysRolePermissionByRoleID(ctx context.Context, roleID int32) error {
_, err := q.db.Exec(ctx, deleteSysRolePermissionByRoleID, roleID)
func (q *Queries) DeleteRolePermissionsByRoleID(ctx context.Context, roleID int32) error {
_, err := q.db.Exec(ctx, deleteRolePermissionsByRoleID, roleID)
return err
}
const deleteSysRolePermissionByType = `-- name: DeleteSysRolePermissionByType :exec
const deleteRolePermissionsByType = `-- name: DeleteRolePermissionsByType :exec
DELETE
FROM sys_role_permission rp USING sys_permissions p
WHERE rp.permission_id = p.id
@@ -86,28 +86,28 @@ WHERE rp.permission_id = p.id
AND p."type" = $2
`
type DeleteSysRolePermissionByTypeParams struct {
type DeleteRolePermissionsByTypeParams struct {
RoleID int32 `json:"role_id"`
Type int16 `json:"type"`
}
func (q *Queries) DeleteSysRolePermissionByType(ctx context.Context, arg DeleteSysRolePermissionByTypeParams) error {
_, err := q.db.Exec(ctx, deleteSysRolePermissionByType, arg.RoleID, arg.Type)
func (q *Queries) DeleteRolePermissionsByType(ctx context.Context, arg DeleteRolePermissionsByTypeParams) error {
_, err := q.db.Exec(ctx, deleteRolePermissionsByType, arg.RoleID, arg.Type)
return err
}
const deleteSysUserRoleByRoleID = `-- name: DeleteSysUserRoleByRoleID :exec
const deleteUserRoleByRoleID = `-- name: DeleteUserRoleByRoleID :exec
DELETE
FROM sys_user_role
WHERE role_id = $1
`
func (q *Queries) DeleteSysUserRoleByRoleID(ctx context.Context, roleID int32) error {
_, err := q.db.Exec(ctx, deleteSysUserRoleByRoleID, roleID)
func (q *Queries) DeleteUserRoleByRoleID(ctx context.Context, roleID int32) error {
_, err := q.db.Exec(ctx, deleteUserRoleByRoleID, roleID)
return err
}
const existsSysRoleCode = `-- name: ExistsSysRoleCode :one
const existsRoleCode = `-- name: ExistsRoleCode :one
SELECT EXISTS(SELECT 1
FROM sys_roles
WHERE code = $1
@@ -117,143 +117,26 @@ SELECT EXISTS(SELECT 1
))
`
type ExistsSysRoleCodeParams struct {
type ExistsRoleCodeParams struct {
Code string `json:"code"`
ID *int32 `json:"id"`
}
func (q *Queries) ExistsSysRoleCode(ctx context.Context, arg ExistsSysRoleCodeParams) (bool, error) {
row := q.db.QueryRow(ctx, existsSysRoleCode, arg.Code, arg.ID)
func (q *Queries) ExistsRoleCode(ctx context.Context, arg ExistsRoleCodeParams) (bool, error) {
row := q.db.QueryRow(ctx, existsRoleCode, arg.Code, arg.ID)
var exists bool
err := row.Scan(&exists)
return exists, err
}
const getAllSysRoles = `-- name: GetAllSysRoles :many
SELECT id, name, code, status, created_at, updated_at
from sys_roles
`
func (q *Queries) GetAllSysRoles(ctx context.Context) ([]SysRole, error) {
rows, err := q.db.Query(ctx, getAllSysRoles)
if err != nil {
return nil, err
}
defer rows.Close()
items := []SysRole{}
for rows.Next() {
var i SysRole
if err := rows.Scan(
&i.ID,
&i.Name,
&i.Code,
&i.Status,
&i.CreatedAt,
&i.UpdatedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getSysPermissionIdsByApiIDs = `-- name: GetSysPermissionIdsByApiIDs :many
SELECT permission_id
FROM sys_api_permission
WHERE api_id = ANY ($1::int[])
`
func (q *Queries) GetSysPermissionIdsByApiIDs(ctx context.Context, dollar_1 []int32) ([]int32, error) {
rows, err := q.db.Query(ctx, getSysPermissionIdsByApiIDs, dollar_1)
if err != nil {
return nil, err
}
defer rows.Close()
items := []int32{}
for rows.Next() {
var permission_id int32
if err := rows.Scan(&permission_id); err != nil {
return nil, err
}
items = append(items, permission_id)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getSysPermissionIdsByMenuIDs = `-- name: GetSysPermissionIdsByMenuIDs :many
SELECT permission_id
FROM sys_menu_permission
WHERE menu_id = ANY ($1::int[])
`
func (q *Queries) GetSysPermissionIdsByMenuIDs(ctx context.Context, dollar_1 []int32) ([]int32, error) {
rows, err := q.db.Query(ctx, getSysPermissionIdsByMenuIDs, dollar_1)
if err != nil {
return nil, err
}
defer rows.Close()
items := []int32{}
for rows.Next() {
var permission_id int32
if err := rows.Scan(&permission_id); err != nil {
return nil, err
}
items = append(items, permission_id)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getSysRoleApis = `-- name: GetSysRoleApis :many
SELECT a.id, a."name"
FROM sys_role_permission rp
JOIN sys_api_permission ap ON ap.permission_id = rp.permission_id
JOIN sys_apis a ON a.id = ap.api_id
WHERE rp.role_id = $1
`
type GetSysRoleApisRow struct {
ID int32 `json:"id"`
Name string `json:"name"`
}
func (q *Queries) GetSysRoleApis(ctx context.Context, roleID int32) ([]GetSysRoleApisRow, error) {
rows, err := q.db.Query(ctx, getSysRoleApis, roleID)
if err != nil {
return nil, err
}
defer rows.Close()
items := []GetSysRoleApisRow{}
for rows.Next() {
var i GetSysRoleApisRow
if err := rows.Scan(&i.ID, &i.Name); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getSysRoleByID = `-- name: GetSysRoleByID :one
const getRoleByID = `-- name: GetRoleByID :one
SELECT id, name, code, status, created_at, updated_at
FROM sys_roles
WHERE id = $1
`
func (q *Queries) GetSysRoleByID(ctx context.Context, id int32) (SysRole, error) {
row := q.db.QueryRow(ctx, getSysRoleByID, id)
func (q *Queries) GetRoleByID(ctx context.Context, id int32) (SysRole, error) {
row := q.db.QueryRow(ctx, getRoleByID, id)
var i SysRole
err := row.Scan(
&i.ID,
@@ -266,53 +149,13 @@ func (q *Queries) GetSysRoleByID(ctx context.Context, id int32) (SysRole, error)
return i, err
}
const getSysRoleMenus = `-- name: GetSysRoleMenus :many
SELECT m.id, m.name
FROM sys_role_permission rp
JOIN sys_menu_permission mp ON mp.permission_id = rp.permission_id
JOIN sys_menus m ON m.id = mp.menu_id
WHERE rp.role_id = $1
`
type GetSysRoleMenusRow struct {
ID int32 `json:"id"`
Name string `json:"name"`
}
func (q *Queries) GetSysRoleMenus(ctx context.Context, roleID int32) ([]GetSysRoleMenusRow, error) {
rows, err := q.db.Query(ctx, getSysRoleMenus, roleID)
if err != nil {
return nil, err
}
defer rows.Close()
items := []GetSysRoleMenusRow{}
for rows.Next() {
var i GetSysRoleMenusRow
if err := rows.Scan(&i.ID, &i.Name); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listSysRoles = `-- name: ListSysRoles :many
const listAllRoles = `-- name: ListAllRoles :many
SELECT id, name, code, status, created_at, updated_at
FROM sys_roles
ORDER BY id
LIMIT $1 OFFSET $2
from sys_roles
`
type ListSysRolesParams struct {
Limit int32 `json:"limit"`
Offset int32 `json:"offset"`
}
func (q *Queries) ListSysRoles(ctx context.Context, arg ListSysRolesParams) ([]SysRole, error) {
rows, err := q.db.Query(ctx, listSysRoles, arg.Limit, arg.Offset)
func (q *Queries) ListAllRoles(ctx context.Context) ([]SysRole, error) {
rows, err := q.db.Query(ctx, listAllRoles)
if err != nil {
return nil, err
}
@@ -338,21 +181,178 @@ func (q *Queries) ListSysRoles(ctx context.Context, arg ListSysRolesParams) ([]S
return items, nil
}
const updateSysRole = `-- name: UpdateSysRole :execrows
const listPermissionIDsByApiIDs = `-- name: ListPermissionIDsByApiIDs :many
SELECT permission_id
FROM sys_api_permission
WHERE api_id = ANY ($1::int[])
`
func (q *Queries) ListPermissionIDsByApiIDs(ctx context.Context, dollar_1 []int32) ([]int32, error) {
rows, err := q.db.Query(ctx, listPermissionIDsByApiIDs, dollar_1)
if err != nil {
return nil, err
}
defer rows.Close()
items := []int32{}
for rows.Next() {
var permission_id int32
if err := rows.Scan(&permission_id); err != nil {
return nil, err
}
items = append(items, permission_id)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listPermissionIDsByMenuIDs = `-- name: ListPermissionIDsByMenuIDs :many
SELECT permission_id
FROM sys_menu_permission
WHERE menu_id = ANY ($1::int[])
`
func (q *Queries) ListPermissionIDsByMenuIDs(ctx context.Context, dollar_1 []int32) ([]int32, error) {
rows, err := q.db.Query(ctx, listPermissionIDsByMenuIDs, dollar_1)
if err != nil {
return nil, err
}
defer rows.Close()
items := []int32{}
for rows.Next() {
var permission_id int32
if err := rows.Scan(&permission_id); err != nil {
return nil, err
}
items = append(items, permission_id)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listRoleApis = `-- name: ListRoleApis :many
SELECT a.id, a."name"
FROM sys_role_permission rp
JOIN sys_api_permission ap ON ap.permission_id = rp.permission_id
JOIN sys_apis a ON a.id = ap.api_id
WHERE rp.role_id = $1
`
type ListRoleApisRow struct {
ID int32 `json:"id"`
Name string `json:"name"`
}
func (q *Queries) ListRoleApis(ctx context.Context, roleID int32) ([]ListRoleApisRow, error) {
rows, err := q.db.Query(ctx, listRoleApis, roleID)
if err != nil {
return nil, err
}
defer rows.Close()
items := []ListRoleApisRow{}
for rows.Next() {
var i ListRoleApisRow
if err := rows.Scan(&i.ID, &i.Name); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listRoleMenus = `-- name: ListRoleMenus :many
SELECT m.id, m.name
FROM sys_role_permission rp
JOIN sys_menu_permission mp ON mp.permission_id = rp.permission_id
JOIN sys_menus m ON m.id = mp.menu_id
WHERE rp.role_id = $1
`
type ListRoleMenusRow struct {
ID int32 `json:"id"`
Name string `json:"name"`
}
func (q *Queries) ListRoleMenus(ctx context.Context, roleID int32) ([]ListRoleMenusRow, error) {
rows, err := q.db.Query(ctx, listRoleMenus, roleID)
if err != nil {
return nil, err
}
defer rows.Close()
items := []ListRoleMenusRow{}
for rows.Next() {
var i ListRoleMenusRow
if err := rows.Scan(&i.ID, &i.Name); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listRoles = `-- name: ListRoles :many
SELECT id, name, code, status, created_at, updated_at
FROM sys_roles
ORDER BY id
LIMIT $1 OFFSET $2
`
type ListRolesParams struct {
Limit int32 `json:"limit"`
Offset int32 `json:"offset"`
}
func (q *Queries) ListRoles(ctx context.Context, arg ListRolesParams) ([]SysRole, error) {
rows, err := q.db.Query(ctx, listRoles, arg.Limit, arg.Offset)
if err != nil {
return nil, err
}
defer rows.Close()
items := []SysRole{}
for rows.Next() {
var i SysRole
if err := rows.Scan(
&i.ID,
&i.Name,
&i.Code,
&i.Status,
&i.CreatedAt,
&i.UpdatedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const updateRole = `-- name: UpdateRole :execrows
UPDATE sys_roles
SET name = coalesce($1, name),
status = coalesce($2, status)
WHERE id = $3
`
type UpdateSysRoleParams struct {
type UpdateRoleParams struct {
Name *string `json:"name"`
Status *int16 `json:"status"`
ID int32 `json:"id"`
}
func (q *Queries) UpdateSysRole(ctx context.Context, arg UpdateSysRoleParams) (int64, error) {
result, err := q.db.Exec(ctx, updateSysRole, arg.Name, arg.Status, arg.ID)
func (q *Queries) UpdateRole(ctx context.Context, arg UpdateRoleParams) (int64, error) {
result, err := q.db.Exec(ctx, updateRole, arg.Name, arg.Status, arg.ID)
if err != nil {
return 0, err
}

View File

@@ -10,36 +10,36 @@ import (
"time"
)
const clearSysUserRoles = `-- name: ClearSysUserRoles :exec
const clearUserRoles = `-- name: ClearUserRoles :exec
DELETE
FROM sys_user_role
WHERE user_id = $1
`
func (q *Queries) ClearSysUserRoles(ctx context.Context, userID int32) error {
_, err := q.db.Exec(ctx, clearSysUserRoles, userID)
func (q *Queries) ClearUserRoles(ctx context.Context, userID int32) error {
_, err := q.db.Exec(ctx, clearUserRoles, userID)
return err
}
const countSysUsers = `-- name: CountSysUsers :one
const countUsers = `-- name: CountUsers :one
SELECT COUNT(*)
FROM sys_users
WHERE ($1::text = '' OR username ILIKE '%' || $1 || '%')
`
func (q *Queries) CountSysUsers(ctx context.Context, username string) (int64, error) {
row := q.db.QueryRow(ctx, countSysUsers, username)
func (q *Queries) CountUsers(ctx context.Context, username string) (int64, error) {
row := q.db.QueryRow(ctx, countUsers, username)
var count int64
err := row.Scan(&count)
return count, err
}
const createSysUser = `-- name: CreateSysUser :exec
const createUser = `-- name: CreateUser :exec
INSERT INTO sys_users (account, username, password_hash, status, avatar_id)
VALUES ($1, $2, $3, $4, $5)
`
type CreateSysUserParams struct {
type CreateUserParams struct {
Account string `json:"account"`
Username string `json:"username"`
PasswordHash string `json:"password_hash"`
@@ -47,8 +47,8 @@ type CreateSysUserParams struct {
AvatarID *int32 `json:"avatar_id"`
}
func (q *Queries) CreateSysUser(ctx context.Context, arg CreateSysUserParams) error {
_, err := q.db.Exec(ctx, createSysUser,
func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) error {
_, err := q.db.Exec(ctx, createUser,
arg.Account,
arg.Username,
arg.PasswordHash,
@@ -58,34 +58,34 @@ func (q *Queries) CreateSysUser(ctx context.Context, arg CreateSysUserParams) er
return err
}
type CreateSysUserRoleParams struct {
type CreateUserRoleParams struct {
UserID int32 `json:"user_id"`
RoleID int32 `json:"role_id"`
}
const deleteSysUser = `-- name: DeleteSysUser :execrows
const deleteUser = `-- name: DeleteUser :execrows
DELETE
FROM sys_users
WHERE id = $1
AND id <> 1
`
func (q *Queries) DeleteSysUser(ctx context.Context, id int32) (int64, error) {
result, err := q.db.Exec(ctx, deleteSysUser, id)
func (q *Queries) DeleteUser(ctx context.Context, id int32) (int64, error) {
result, err := q.db.Exec(ctx, deleteUser, id)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}
const getActiveSysUserByID = `-- name: GetActiveSysUserByID :one
const getActiveUserByID = `-- name: GetActiveUserByID :one
SELECT id, account, username, status
FROM sys_users
WHERE id = $1
AND status = 1
`
type GetActiveSysUserByIDRow struct {
type GetActiveUserByIDRow struct {
ID int32 `json:"id"`
Account string `json:"account"`
Username string `json:"username"`
@@ -93,9 +93,9 @@ type GetActiveSysUserByIDRow struct {
}
// 场景:用户登录、获取个人信息、刷新 Token严格校验 status = 1
func (q *Queries) GetActiveSysUserByID(ctx context.Context, id int32) (GetActiveSysUserByIDRow, error) {
row := q.db.QueryRow(ctx, getActiveSysUserByID, id)
var i GetActiveSysUserByIDRow
func (q *Queries) GetActiveUserByID(ctx context.Context, id int32) (GetActiveUserByIDRow, error) {
row := q.db.QueryRow(ctx, getActiveUserByID, id)
var i GetActiveUserByIDRow
err := row.Scan(
&i.ID,
&i.Account,
@@ -105,7 +105,92 @@ func (q *Queries) GetActiveSysUserByID(ctx context.Context, id int32) (GetActive
return i, err
}
const getSysAdminMenus = `-- name: GetSysAdminMenus :many
const getUserByAccount = `-- name: GetUserByAccount :one
SELECT u.id,
u.account,
u.username,
u.password_hash,
u.status,
u.avatar_id,
f.file_url AS avatar_url,
u.created_at,
u.updated_at
FROM sys_users u
LEFT JOIN files f ON u.avatar_id = f.id
WHERE u.account = $1
`
type GetUserByAccountRow struct {
ID int32 `json:"id"`
Account string `json:"account"`
Username string `json:"username"`
PasswordHash string `json:"password_hash"`
Status int16 `json:"status"`
AvatarID *int32 `json:"avatar_id"`
AvatarUrl *string `json:"avatar_url"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt *time.Time `json:"updated_at"`
}
func (q *Queries) GetUserByAccount(ctx context.Context, account string) (GetUserByAccountRow, error) {
row := q.db.QueryRow(ctx, getUserByAccount, account)
var i GetUserByAccountRow
err := row.Scan(
&i.ID,
&i.Account,
&i.Username,
&i.PasswordHash,
&i.Status,
&i.AvatarID,
&i.AvatarUrl,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const getUserByID = `-- name: GetUserByID :one
SELECT u.id,
u.account,
u.username,
u.avatar_id,
u.status,
f.file_url AS avatar_url,
u.created_at,
u.updated_at
FROM sys_users u
LEFT JOIN files f ON u.avatar_id = f.id
WHERE u.id = $1
`
type GetUserByIDRow struct {
ID int32 `json:"id"`
Account string `json:"account"`
Username string `json:"username"`
AvatarID *int32 `json:"avatar_id"`
Status int16 `json:"status"`
AvatarUrl *string `json:"avatar_url"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt *time.Time `json:"updated_at"`
}
func (q *Queries) GetUserByID(ctx context.Context, id int32) (GetUserByIDRow, error) {
row := q.db.QueryRow(ctx, getUserByID, id)
var i GetUserByIDRow
err := row.Scan(
&i.ID,
&i.Account,
&i.Username,
&i.AvatarID,
&i.Status,
&i.AvatarUrl,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const listAdminMenus = `-- name: ListAdminMenus :many
SELECT id, name, path, component, type, hidden, sort, status, parent_id, icon, created_at, updated_at
FROM sys_menus
WHERE status = 1
@@ -113,8 +198,8 @@ WHERE status = 1
ORDER BY sort, id
`
func (q *Queries) GetSysAdminMenus(ctx context.Context) ([]SysMenu, error) {
rows, err := q.db.Query(ctx, getSysAdminMenus)
func (q *Queries) ListAdminMenus(ctx context.Context) ([]SysMenu, error) {
rows, err := q.db.Query(ctx, listAdminMenus)
if err != nil {
return nil, err
}
@@ -146,14 +231,14 @@ func (q *Queries) GetSysAdminMenus(ctx context.Context) ([]SysMenu, error) {
return items, nil
}
const getSysAdminPermissions = `-- name: GetSysAdminPermissions :many
const listAdminPermissionCodes = `-- name: ListAdminPermissionCodes :many
SELECT code
FROM sys_permissions
WHERE type = 0
`
func (q *Queries) GetSysAdminPermissions(ctx context.Context) ([]*string, error) {
rows, err := q.db.Query(ctx, getSysAdminPermissions)
func (q *Queries) ListAdminPermissionCodes(ctx context.Context) ([]*string, error) {
rows, err := q.db.Query(ctx, listAdminPermissionCodes)
if err != nil {
return nil, err
}
@@ -172,7 +257,7 @@ func (q *Queries) GetSysAdminPermissions(ctx context.Context) ([]*string, error)
return items, nil
}
const getSysUserApis = `-- name: GetSysUserApis :many
const listUserApis = `-- name: ListUserApis :many
SELECT DISTINCT a.id,
a.PATH,
a.METHOD
@@ -187,21 +272,21 @@ WHERE u.id = $1
AND r.status = 1
`
type GetSysUserApisRow struct {
type ListUserApisRow struct {
ID int32 `json:"id"`
Path string `json:"path"`
Method string `json:"method"`
}
func (q *Queries) GetSysUserApis(ctx context.Context, id int32) ([]GetSysUserApisRow, error) {
rows, err := q.db.Query(ctx, getSysUserApis, id)
func (q *Queries) ListUserApis(ctx context.Context, id int32) ([]ListUserApisRow, error) {
rows, err := q.db.Query(ctx, listUserApis, id)
if err != nil {
return nil, err
}
defer rows.Close()
items := []GetSysUserApisRow{}
items := []ListUserApisRow{}
for rows.Next() {
var i GetSysUserApisRow
var i ListUserApisRow
if err := rows.Scan(&i.ID, &i.Path, &i.Method); err != nil {
return nil, err
}
@@ -213,92 +298,7 @@ func (q *Queries) GetSysUserApis(ctx context.Context, id int32) ([]GetSysUserApi
return items, nil
}
const getSysUserByAccount = `-- name: GetSysUserByAccount :one
SELECT u.id,
u.account,
u.username,
u.password_hash,
u.status,
u.avatar_id,
f.file_path AS avatar_url,
u.created_at,
u.updated_at
FROM sys_users u
LEFT JOIN files f ON u.avatar_id = f.id
WHERE u.account = $1
`
type GetSysUserByAccountRow struct {
ID int32 `json:"id"`
Account string `json:"account"`
Username string `json:"username"`
PasswordHash string `json:"password_hash"`
Status int16 `json:"status"`
AvatarID *int32 `json:"avatar_id"`
AvatarUrl *string `json:"avatar_url"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt *time.Time `json:"updated_at"`
}
func (q *Queries) GetSysUserByAccount(ctx context.Context, account string) (GetSysUserByAccountRow, error) {
row := q.db.QueryRow(ctx, getSysUserByAccount, account)
var i GetSysUserByAccountRow
err := row.Scan(
&i.ID,
&i.Account,
&i.Username,
&i.PasswordHash,
&i.Status,
&i.AvatarID,
&i.AvatarUrl,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const getSysUserByID = `-- name: GetSysUserByID :one
SELECT u.id,
u.account,
u.username,
u.avatar_id,
u.status,
f.file_path AS avatar_url,
u.created_at,
u.updated_at
FROM sys_users u
LEFT JOIN files f ON u.avatar_id = f.id
WHERE u.id = $1
`
type GetSysUserByIDRow struct {
ID int32 `json:"id"`
Account string `json:"account"`
Username string `json:"username"`
AvatarID *int32 `json:"avatar_id"`
Status int16 `json:"status"`
AvatarUrl *string `json:"avatar_url"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt *time.Time `json:"updated_at"`
}
func (q *Queries) GetSysUserByID(ctx context.Context, id int32) (GetSysUserByIDRow, error) {
row := q.db.QueryRow(ctx, getSysUserByID, id)
var i GetSysUserByIDRow
err := row.Scan(
&i.ID,
&i.Account,
&i.Username,
&i.AvatarID,
&i.Status,
&i.AvatarUrl,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const getSysUserMenus = `-- name: GetSysUserMenus :many
const listUserMenus = `-- name: ListUserMenus :many
SELECT DISTINCT m.id, m.name, m.path, m.component, m.type, m.hidden, m.sort, m.status, m.parent_id, m.icon, m.created_at, m.updated_at
FROM sys_users u
JOIN sys_user_role ur ON ur.user_id = u.id
@@ -314,8 +314,8 @@ WHERE u.id = $1
ORDER BY m.sort, m.id
`
func (q *Queries) GetSysUserMenus(ctx context.Context, id int32) ([]SysMenu, error) {
rows, err := q.db.Query(ctx, getSysUserMenus, id)
func (q *Queries) ListUserMenus(ctx context.Context, id int32) ([]SysMenu, error) {
rows, err := q.db.Query(ctx, listUserMenus, id)
if err != nil {
return nil, err
}
@@ -347,7 +347,7 @@ func (q *Queries) GetSysUserMenus(ctx context.Context, id int32) ([]SysMenu, err
return items, nil
}
const getSysUserPermissions = `-- name: GetSysUserPermissions :many
const listUserPermissionCodes = `-- name: ListUserPermissionCodes :many
SELECT DISTINCT p.code
FROM sys_users u
JOIN sys_user_role ur ON u.id = ur.user_id
@@ -363,8 +363,8 @@ WHERE u.id = $1
AND p."type" = 0
`
func (q *Queries) GetSysUserPermissions(ctx context.Context, id int32) ([]*string, error) {
rows, err := q.db.Query(ctx, getSysUserPermissions, id)
func (q *Queries) ListUserPermissionCodes(ctx context.Context, id int32) ([]*string, error) {
rows, err := q.db.Query(ctx, listUserPermissionCodes, id)
if err != nil {
return nil, err
}
@@ -383,15 +383,15 @@ func (q *Queries) GetSysUserPermissions(ctx context.Context, id int32) ([]*strin
return items, nil
}
const getSysUserRoles = `-- name: GetSysUserRoles :many
const listUserRoles = `-- name: ListUserRoles :many
SELECT r.id, r.name, r.code, r.status, r.created_at, r.updated_at
FROM sys_roles r
JOIN sys_user_role ur ON r.id = ur.role_id
WHERE ur.user_id = $1
`
func (q *Queries) GetSysUserRoles(ctx context.Context, userID int32) ([]SysRole, error) {
rows, err := q.db.Query(ctx, getSysUserRoles, userID)
func (q *Queries) ListUserRoles(ctx context.Context, userID int32) ([]SysRole, error) {
rows, err := q.db.Query(ctx, listUserRoles, userID)
if err != nil {
return nil, err
}
@@ -417,13 +417,13 @@ func (q *Queries) GetSysUserRoles(ctx context.Context, userID int32) ([]SysRole,
return items, nil
}
const listSysUsers = `-- name: ListSysUsers :many
const listUsers = `-- name: ListUsers :many
SELECT u.id,
u.account,
u.username,
u.status,
u.avatar_id,
f.file_path AS avatar_url,
f.file_url AS avatar_url,
u.created_at,
u.updated_at
FROM sys_users u
@@ -433,13 +433,13 @@ ORDER BY u.id
LIMIT $1 OFFSET $2
`
type ListSysUsersParams struct {
type ListUsersParams struct {
Limit int32 `json:"limit"`
Offset int32 `json:"offset"`
Username string `json:"username"`
}
type ListSysUsersRow struct {
type ListUsersRow struct {
ID int32 `json:"id"`
Account string `json:"account"`
Username string `json:"username"`
@@ -450,15 +450,15 @@ type ListSysUsersRow struct {
UpdatedAt *time.Time `json:"updated_at"`
}
func (q *Queries) ListSysUsers(ctx context.Context, arg ListSysUsersParams) ([]ListSysUsersRow, error) {
rows, err := q.db.Query(ctx, listSysUsers, arg.Limit, arg.Offset, arg.Username)
func (q *Queries) ListUsers(ctx context.Context, arg ListUsersParams) ([]ListUsersRow, error) {
rows, err := q.db.Query(ctx, listUsers, arg.Limit, arg.Offset, arg.Username)
if err != nil {
return nil, err
}
defer rows.Close()
items := []ListSysUsersRow{}
items := []ListUsersRow{}
for rows.Next() {
var i ListSysUsersRow
var i ListUsersRow
if err := rows.Scan(
&i.ID,
&i.Account,
@@ -479,7 +479,7 @@ func (q *Queries) ListSysUsers(ctx context.Context, arg ListSysUsersParams) ([]L
return items, nil
}
const updateSysUser = `-- name: UpdateSysUser :execrows
const updateUser = `-- name: UpdateUser :execrows
UPDATE sys_users
SET username = coalesce($1, username),
status = coalesce($2, status),
@@ -487,7 +487,7 @@ SET username = coalesce($1, username),
WHERE id = $5
`
type UpdateSysUserParams struct {
type UpdateUserParams struct {
Username *string `json:"username"`
Status *int16 `json:"status"`
UpdateAvatarID bool `json:"update_avatar_id"`
@@ -495,8 +495,8 @@ type UpdateSysUserParams struct {
ID int32 `json:"id"`
}
func (q *Queries) UpdateSysUser(ctx context.Context, arg UpdateSysUserParams) (int64, error) {
result, err := q.db.Exec(ctx, updateSysUser,
func (q *Queries) UpdateUser(ctx context.Context, arg UpdateUserParams) (int64, error) {
result, err := q.db.Exec(ctx, updateUser,
arg.Username,
arg.Status,
arg.UpdateAvatarID,
@@ -509,19 +509,19 @@ func (q *Queries) UpdateSysUser(ctx context.Context, arg UpdateSysUserParams) (i
return result.RowsAffected(), nil
}
const updateSysUserPassword = `-- name: UpdateSysUserPassword :execrows
const updateUserPassword = `-- name: UpdateUserPassword :execrows
UPDATE sys_users
SET password_hash = $2
WHERE id = $1
`
type UpdateSysUserPasswordParams struct {
type UpdateUserPasswordParams struct {
ID int32 `json:"id"`
PasswordHash string `json:"password_hash"`
}
func (q *Queries) UpdateSysUserPassword(ctx context.Context, arg UpdateSysUserPasswordParams) (int64, error) {
result, err := q.db.Exec(ctx, updateSysUserPassword, arg.ID, arg.PasswordHash)
func (q *Queries) UpdateUserPassword(ctx context.Context, arg UpdateUserPasswordParams) (int64, error) {
result, err := q.db.Exec(ctx, updateUserPassword, arg.ID, arg.PasswordHash)
if err != nil {
return 0, err
}

View File

@@ -1,31 +1,48 @@
package handler
package admin
import (
"net/http"
"server/internal/model/common"
"server/internal/model/request"
"server/internal/pkg/httputil"
"server/internal/service"
"server/internal/router"
"server/internal/service/admin"
"github.com/go-chi/chi/v5"
)
type SysApiHandler struct {
apiService *service.SysApiService
type ApiHandler struct {
apiService *admin.ApiService
}
func NewSysApiHandler(apiService *service.SysApiService) *SysApiHandler {
return &SysApiHandler{apiService: apiService}
var _ router.Registrar = (*ApiHandler)(nil)
func NewApiHandler(apiService *admin.ApiService) *ApiHandler {
return &ApiHandler{apiService: apiService}
}
func (h *SysApiHandler) ListPage(w http.ResponseWriter, r *http.Request) {
func (h *ApiHandler) Register(r chi.Router) {
r.Route("/apis", func(r chi.Router) {
r.Get("/", h.List)
r.Get("/all", h.ListAll)
r.Get("/groups", h.ListApiGroups)
r.Post("/", h.Create)
r.Patch("/{id}", h.Update)
r.Delete("/{id}", h.Delete)
})
}
func (h *ApiHandler) List(w http.ResponseWriter, r *http.Request) {
pagination := httputil.Pagination(r)
params := request.SearchSysApiParams{
params := request.SearchApiParams{
Pagination: *pagination,
Name: r.URL.Query().Get("name"),
GroupName: r.URL.Query().Get("group_name"),
Method: r.URL.Query().Get("method"),
}
list, total, err := h.apiService.ListPage(r.Context(), params)
result, err := h.apiService.List(r.Context(), params)
if err != nil {
httputil.Fail(w, err)
@@ -35,15 +52,15 @@ func (h *SysApiHandler) ListPage(w http.ResponseWriter, r *http.Request) {
resp := common.PageResponse{
Page: pagination.Page,
PageSize: pagination.PageSize,
List: list,
Total: total,
List: result.List,
Total: result.Total,
}
httputil.OkWithPage(w, &resp)
}
func (h *SysApiHandler) GetAllSysApis(w http.ResponseWriter, r *http.Request) {
list, err := h.apiService.GetAllSysApis(r.Context())
func (h *ApiHandler) ListAll(w http.ResponseWriter, r *http.Request) {
list, err := h.apiService.ListAll(r.Context())
if err != nil {
httputil.Fail(w, err)
@@ -53,8 +70,8 @@ func (h *SysApiHandler) GetAllSysApis(w http.ResponseWriter, r *http.Request) {
httputil.Ok(w, list)
}
func (h *SysApiHandler) GetApiGroupNames(w http.ResponseWriter, r *http.Request) {
list, err := h.apiService.GetApiGroupNames(r.Context())
func (h *ApiHandler) ListApiGroups(w http.ResponseWriter, r *http.Request) {
list, err := h.apiService.ListApiGroups(r.Context())
if err != nil {
httputil.Fail(w, err)
@@ -64,8 +81,8 @@ func (h *SysApiHandler) GetApiGroupNames(w http.ResponseWriter, r *http.Request)
httputil.Ok(w, list)
}
func (h *SysApiHandler) Create(w http.ResponseWriter, r *http.Request) {
var req request.CreateSysApiRequest
func (h *ApiHandler) Create(w http.ResponseWriter, r *http.Request) {
var req request.CreateApiRequest
if err := httputil.BindJson(r, &req); err != nil {
httputil.Fail(w, err)
@@ -80,8 +97,8 @@ func (h *SysApiHandler) Create(w http.ResponseWriter, r *http.Request) {
httputil.Ok(w)
}
func (h *SysApiHandler) Update(w http.ResponseWriter, r *http.Request) {
var req request.UpdateSysApiRequest
func (h *ApiHandler) Update(w http.ResponseWriter, r *http.Request) {
var req request.UpdateApiRequest
id, err := httputil.URLParamInt32(r, "id")
if err != nil {
@@ -102,7 +119,7 @@ func (h *SysApiHandler) Update(w http.ResponseWriter, r *http.Request) {
httputil.Ok(w)
}
func (h *SysApiHandler) Delete(w http.ResponseWriter, r *http.Request) {
func (h *ApiHandler) Delete(w http.ResponseWriter, r *http.Request) {
id, err := httputil.URLParamInt32(r, "id")
if err != nil {
httputil.Fail(w, err)

View File

@@ -1,4 +1,4 @@
package handler
package admin
import (
"net/http"
@@ -6,19 +6,32 @@ import (
"server/internal/model/request"
"server/internal/pkg/errs"
"server/internal/pkg/httputil"
"server/internal/service"
"server/internal/router"
"server/internal/service/admin"
"time"
"github.com/go-chi/chi/v5"
)
type AuthHandler struct {
authService *service.AuthService
authService *admin.AuthService
cfg *config.Config
}
func NewAuthHandler(authService *service.AuthService, cfg *config.Config) *AuthHandler {
var _ router.Registrar = (*AuthHandler)(nil)
func NewAuthHandler(authService *admin.AuthService, cfg *config.Config) *AuthHandler {
return &AuthHandler{authService: authService, cfg: cfg}
}
func (h *AuthHandler) Register(r chi.Router) {
r.Route("/auth", func(r chi.Router) {
r.Post("/login", h.Login)
r.Post("/refresh-token", h.RefreshToken)
r.Post("/logout", h.Logout)
})
}
func (h *AuthHandler) clearRefreshTokenCookie(w http.ResponseWriter) {
http.SetCookie(w, &http.Cookie{
Name: h.cfg.JWTConfig.CookieName,

View File

@@ -1,24 +1,39 @@
package handler
package admin
import (
"net/http"
"server/internal/model/common"
"server/internal/model/request"
"server/internal/pkg/httputil"
"server/internal/service"
"server/internal/router"
"server/internal/service/admin"
"github.com/go-chi/chi/v5"
)
type CategoryHandler struct {
categoryService *service.CategoryService
categoryService *admin.CategoryService
}
func NewCategoryHandler(categoryService *service.CategoryService) *CategoryHandler {
var _ router.Registrar = (*CategoryHandler)(nil)
func NewCategoryHandler(categoryService *admin.CategoryService) *CategoryHandler {
return &CategoryHandler{categoryService: categoryService}
}
func (h *CategoryHandler) ListPage(w http.ResponseWriter, r *http.Request) {
func (h *CategoryHandler) Register(r chi.Router) {
r.Route("/categories", func(r chi.Router) {
r.Get("/", h.List)
r.Get("/all", h.ListAll)
r.Post("/", h.Create)
r.Patch("/{id}", h.Update)
r.Delete("/{id}", h.Delete)
})
}
func (h *CategoryHandler) List(w http.ResponseWriter, r *http.Request) {
pagination := httputil.Pagination(r)
list, total, err := h.categoryService.ListPage(r.Context(), pagination)
result, err := h.categoryService.List(r.Context(), pagination)
if err != nil {
httputil.Fail(w, err)
return
@@ -27,8 +42,8 @@ func (h *CategoryHandler) ListPage(w http.ResponseWriter, r *http.Request) {
resp := common.PageResponse{
Page: pagination.Page,
PageSize: pagination.PageSize,
List: list,
Total: total,
List: result.List,
Total: result.Total,
}
httputil.OkWithPage(w, &resp)
}

View File

@@ -0,0 +1,70 @@
package admin
import (
"net/http"
"server/internal/model/common"
"server/internal/pkg/httputil"
"server/internal/router"
"server/internal/service/admin"
"github.com/go-chi/chi/v5"
)
type FileHandler struct {
service *admin.FileService
}
var _ router.Registrar = (*FileHandler)(nil)
func NewFileHandler(service *admin.FileService) *FileHandler {
return &FileHandler{
service: service,
}
}
func (h *FileHandler) Register(r chi.Router) {
r.Route("/files", func(r chi.Router) {
r.Get("/", h.List)
r.Post("/", h.Upload)
})
}
func (h *FileHandler) List(w http.ResponseWriter, r *http.Request) {
pagination := httputil.Pagination(r)
result, err := h.service.List(r.Context(), pagination)
if err != nil {
httputil.Fail(w, err)
return
}
resp := common.PageResponse{
Page: pagination.Page,
PageSize: pagination.PageSize,
List: result.List,
Total: result.Total,
}
httputil.OkWithPage(w, &resp)
}
func (h *FileHandler) Upload(w http.ResponseWriter, r *http.Request) {
folder := r.FormValue("folder")
if folder == "" {
folder = "/"
}
_, header, err := r.FormFile("file")
if err != nil {
httputil.Fail(w, err)
return
}
file, err := h.service.Upload(r.Context(), folder, header)
if err != nil {
httputil.Fail(w, err)
return
}
httputil.Ok(w, file)
}

View File

@@ -1,25 +1,40 @@
package handler
package admin
import (
"net/http"
"server/internal/model/common"
"server/internal/model/request"
"server/internal/pkg/httputil"
"server/internal/service"
"server/internal/router"
"server/internal/service/admin"
"github.com/go-chi/chi/v5"
)
type SysMenuHandler struct {
menuService *service.SysMenuService
type MenuHandler struct {
menuService *admin.MenuService
}
func NewSysMenuHandler(menuService *service.SysMenuService) *SysMenuHandler {
return &SysMenuHandler{menuService: menuService}
var _ router.Registrar = (*MenuHandler)(nil)
func NewMenuHandler(menuService *admin.MenuService) *MenuHandler {
return &MenuHandler{menuService: menuService}
}
func (h *SysMenuHandler) ListPage(w http.ResponseWriter, r *http.Request) {
func (h *MenuHandler) Register(r chi.Router) {
r.Route("/menus", func(r chi.Router) {
r.Get("/", h.List)
r.Get("/all", h.ListAll)
r.Post("/", h.Create)
r.Patch("/{id}", h.Update)
r.Delete("/{id}", h.Delete)
})
}
func (h *MenuHandler) List(w http.ResponseWriter, r *http.Request) {
pagination := httputil.Pagination(r)
list, total, err := h.menuService.ListPage(r.Context(), pagination)
result, err := h.menuService.List(r.Context(), pagination)
if err != nil {
httputil.Fail(w, err)
return
@@ -28,15 +43,15 @@ func (h *SysMenuHandler) ListPage(w http.ResponseWriter, r *http.Request) {
resp := common.PageResponse{
Page: pagination.Page,
PageSize: pagination.PageSize,
List: list,
Total: total,
List: result.List,
Total: result.Total,
}
httputil.OkWithPage(w, &resp)
}
func (h *SysMenuHandler) GetMenus(w http.ResponseWriter, r *http.Request) {
list, err := h.menuService.GetMenus(r.Context())
func (h *MenuHandler) ListAll(w http.ResponseWriter, r *http.Request) {
list, err := h.menuService.ListAll(r.Context())
if err != nil {
httputil.Fail(w, err)
return
@@ -45,8 +60,8 @@ func (h *SysMenuHandler) GetMenus(w http.ResponseWriter, r *http.Request) {
httputil.Ok(w, list)
}
func (h *SysMenuHandler) Create(w http.ResponseWriter, r *http.Request) {
var req request.CreateSysMenuRequest
func (h *MenuHandler) Create(w http.ResponseWriter, r *http.Request) {
var req request.CreateMenuRequest
if err := httputil.BindJson(r, &req); err != nil {
httputil.Fail(w, err)
@@ -61,8 +76,8 @@ func (h *SysMenuHandler) Create(w http.ResponseWriter, r *http.Request) {
httputil.Ok(w)
}
func (h *SysMenuHandler) Update(w http.ResponseWriter, r *http.Request) {
var req request.UpdateSysMenuRequest
func (h *MenuHandler) Update(w http.ResponseWriter, r *http.Request) {
var req request.UpdateMenuRequest
id, err := httputil.URLParamInt32(r, "id")
if err != nil {
@@ -83,7 +98,7 @@ func (h *SysMenuHandler) Update(w http.ResponseWriter, r *http.Request) {
httputil.Ok(w)
}
func (h *SysMenuHandler) Delete(w http.ResponseWriter, r *http.Request) {
func (h *MenuHandler) Delete(w http.ResponseWriter, r *http.Request) {
id, err := httputil.URLParamInt32(r, "id")
if err != nil {
httputil.Fail(w, err)

View File

@@ -0,0 +1,24 @@
package admin
import (
"server/internal/router"
"go.uber.org/fx"
)
var Module = fx.Module("admin-handlers",
fx.Provide(
// 特殊路由 不用鉴权
router.AsRegistrar(router.AdminPublicRoutes, NewAuthHandler),
router.AsRegistrar(router.AdminRoutes, NewApiHandler),
router.AsRegistrar(router.AdminRoutes, NewCategoryHandler),
router.AsRegistrar(router.AdminRoutes, NewFileHandler),
router.AsRegistrar(router.AdminRoutes, NewMenuHandler),
router.AsRegistrar(router.AdminRoutes, NewPostHandler),
router.AsRegistrar(router.AdminRoutes, NewRoleHandler),
router.AsRegistrar(router.AdminRoutes, NewTagHandler),
router.AsRegistrar(router.AdminRoutes, NewUserHandler),
router.AsRegistrar(router.AdminRoutes, NewSystemHandler),
),
)

View File

@@ -0,0 +1,123 @@
package admin
import (
"net/http"
"server/internal/model/common"
"server/internal/model/request"
"server/internal/pkg/httputil"
"server/internal/router"
"server/internal/service/admin"
"github.com/go-chi/chi/v5"
)
type PostHandler struct {
postService *admin.PostService
}
var _ router.Registrar = (*PostHandler)(nil)
func NewPostHandler(postService *admin.PostService) *PostHandler {
return &PostHandler{postService: postService}
}
func (h *PostHandler) Register(r chi.Router) {
r.Route("/posts", func(r chi.Router) {
r.Get("/", h.List)
r.Get("/{id}", h.GetPostByID)
r.Post("/", h.Create)
r.Patch("/{id}", h.Update)
r.Delete("/{id}", h.Delete)
})
}
func (h *PostHandler) List(w http.ResponseWriter, r *http.Request) {
pagination := httputil.Pagination(r)
result, err := h.postService.List(r.Context(), pagination)
if err != nil {
httputil.Fail(w, err)
}
resp := common.PageResponse{
Page: pagination.Page,
PageSize: pagination.PageSize,
List: result.List,
Total: result.Total,
}
httputil.OkWithPage(w, &resp)
}
func (h *PostHandler) GetPostByID(w http.ResponseWriter, r *http.Request) {
id, err := httputil.URLParamInt32(r, "id")
if err != nil {
httputil.Fail(w, err)
return
}
post, err := h.postService.FindByID(r.Context(), id)
if err != nil {
httputil.Fail(w, err)
return
}
httputil.Ok(w, post)
}
func (h *PostHandler) Create(w http.ResponseWriter, r *http.Request) {
var req request.CreatePostRequest
if err := httputil.BindJson(r, &req); err != nil {
httputil.Fail(w, err)
return
}
postID, err := h.postService.Create(r.Context(), req)
if err != nil {
httputil.Fail(w, err)
return
}
httputil.Ok(w, map[string]int32{
"post_id": postID,
})
}
func (h *PostHandler) Update(w http.ResponseWriter, r *http.Request) {
id, err := httputil.URLParamInt32(r, "id")
if err != nil {
httputil.Fail(w, err)
return
}
var req request.UpdatePostRequest
if err = httputil.BindJson(r, &req); err != nil {
httputil.Fail(w, err)
return
}
if err = h.postService.Update(r.Context(), id, req); err != nil {
httputil.Fail(w, err)
return
}
httputil.Ok(w)
}
func (h *PostHandler) Delete(w http.ResponseWriter, r *http.Request) {
id, err := httputil.URLParamInt32(r, "id")
if err != nil {
httputil.Fail(w, err)
return
}
if err = h.postService.Delete(r.Context(), id); err != nil {
httputil.Fail(w, err)
return
}
httputil.Ok(w)
}

View File

@@ -1,25 +1,44 @@
package handler
package admin
import (
"net/http"
"server/internal/model/common"
"server/internal/model/request"
"server/internal/pkg/httputil"
"server/internal/service"
"server/internal/router"
"server/internal/service/admin"
"github.com/go-chi/chi/v5"
)
type SysRoleHandler struct {
roleService *service.SysRoleService
type RoleHandler struct {
roleService *admin.RoleService
}
func NewSysRoleHandler(roleService *service.SysRoleService) *SysRoleHandler {
return &SysRoleHandler{roleService: roleService}
var _ router.Registrar = (*RoleHandler)(nil)
func NewRoleHandler(roleService *admin.RoleService) *RoleHandler {
return &RoleHandler{roleService: roleService}
}
func (h *SysRoleHandler) ListPage(w http.ResponseWriter, r *http.Request) {
func (h *RoleHandler) Register(r chi.Router) {
r.Route("/roles", func(r chi.Router) {
r.Get("/", h.List)
r.Get("/{id}/menus", h.ListRoleMenus)
r.Get("/{id}/apis", h.ListRoleApis)
r.Get("/all", h.ListAll)
r.Post("/", h.Create)
r.Patch("/{id}", h.Update)
r.Put("/{id}/menus", h.SetRoleMenus)
r.Put("/{id}/apis", h.SetRoleApis)
r.Delete("/{id}", h.Delete)
})
}
func (h *RoleHandler) List(w http.ResponseWriter, r *http.Request) {
pagination := httputil.Pagination(r)
list, total, err := h.roleService.ListPage(r.Context(), pagination)
result, err := h.roleService.List(r.Context(), pagination)
if err != nil {
httputil.Fail(w, err)
@@ -29,21 +48,21 @@ func (h *SysRoleHandler) ListPage(w http.ResponseWriter, r *http.Request) {
resp := common.PageResponse{
Page: pagination.Page,
PageSize: pagination.PageSize,
List: list,
Total: total,
List: result.List,
Total: result.Total,
}
httputil.OkWithPage(w, &resp)
}
func (h *SysRoleHandler) GetRoleMenus(w http.ResponseWriter, r *http.Request) {
func (h *RoleHandler) ListRoleMenus(w http.ResponseWriter, r *http.Request) {
id, err := httputil.URLParamInt32(r, "id")
if err != nil {
httputil.Fail(w, err)
return
}
list, err := h.roleService.GetRoleMenus(r.Context(), id)
list, err := h.roleService.ListRoleMenus(r.Context(), id)
if err != nil {
httputil.Fail(w, err)
return
@@ -52,14 +71,14 @@ func (h *SysRoleHandler) GetRoleMenus(w http.ResponseWriter, r *http.Request) {
httputil.Ok(w, list)
}
func (h *SysRoleHandler) GetRoleApis(w http.ResponseWriter, r *http.Request) {
func (h *RoleHandler) ListRoleApis(w http.ResponseWriter, r *http.Request) {
id, err := httputil.URLParamInt32(r, "id")
if err != nil {
httputil.Fail(w, err)
return
}
list, err := h.roleService.GetRoleApis(r.Context(), id)
list, err := h.roleService.ListRoleApis(r.Context(), id)
if err != nil {
httputil.Fail(w, err)
return
@@ -68,8 +87,8 @@ func (h *SysRoleHandler) GetRoleApis(w http.ResponseWriter, r *http.Request) {
httputil.Ok(w, list)
}
func (h *SysRoleHandler) GetRoles(w http.ResponseWriter, r *http.Request) {
roles, err := h.roleService.GetRoles(r.Context())
func (h *RoleHandler) ListAll(w http.ResponseWriter, r *http.Request) {
roles, err := h.roleService.ListAll(r.Context())
if err != nil {
httputil.Fail(w, err)
return
@@ -78,8 +97,8 @@ func (h *SysRoleHandler) GetRoles(w http.ResponseWriter, r *http.Request) {
httputil.Ok(w, roles)
}
func (h *SysRoleHandler) Create(w http.ResponseWriter, r *http.Request) {
var req request.CreateSysRoleRequest
func (h *RoleHandler) Create(w http.ResponseWriter, r *http.Request) {
var req request.CreateRoleRequest
if err := httputil.BindJson(r, &req); err != nil {
httputil.Fail(w, err)
@@ -94,8 +113,8 @@ func (h *SysRoleHandler) Create(w http.ResponseWriter, r *http.Request) {
httputil.Ok(w)
}
func (h *SysRoleHandler) Update(w http.ResponseWriter, r *http.Request) {
var req request.UpdateSysRoleRequest
func (h *RoleHandler) Update(w http.ResponseWriter, r *http.Request) {
var req request.UpdateRoleRequest
id, err := httputil.URLParamInt32(r, "id")
if err != nil {
@@ -116,8 +135,8 @@ func (h *SysRoleHandler) Update(w http.ResponseWriter, r *http.Request) {
httputil.Ok(w)
}
func (h *SysRoleHandler) SetRoleMenus(w http.ResponseWriter, r *http.Request) {
var req request.SetSysRoleMenusRequest
func (h *RoleHandler) SetRoleMenus(w http.ResponseWriter, r *http.Request) {
var req request.SetRoleMenusRequest
id, err := httputil.URLParamInt32(r, "id")
if err != nil {
@@ -138,8 +157,8 @@ func (h *SysRoleHandler) SetRoleMenus(w http.ResponseWriter, r *http.Request) {
httputil.Ok(w)
}
func (h *SysRoleHandler) SetRoleApis(w http.ResponseWriter, r *http.Request) {
var req request.SetSysRoleApisRequest
func (h *RoleHandler) SetRoleApis(w http.ResponseWriter, r *http.Request) {
var req request.SetRoleApisRequest
id, err := httputil.URLParamInt32(r, "id")
if err != nil {
@@ -161,7 +180,7 @@ func (h *SysRoleHandler) SetRoleApis(w http.ResponseWriter, r *http.Request) {
}
func (h *SysRoleHandler) Delete(w http.ResponseWriter, r *http.Request) {
func (h *RoleHandler) Delete(w http.ResponseWriter, r *http.Request) {
id, err := httputil.URLParamInt32(r, "id")
if err != nil {
httputil.Fail(w, err)

View File

@@ -0,0 +1,24 @@
package admin
import (
"server/internal/router"
"github.com/go-chi/chi/v5"
)
type SystemHandler struct {
}
func NewSystemHandler() *SystemHandler {
return &SystemHandler{}
}
var _ router.Registrar = (*SystemHandler)(nil)
func (h *SystemHandler) Register(r chi.Router) {
}
func (h *SystemHandler) ListRoutes() {
}

View File

@@ -1,26 +1,41 @@
package handler
package admin
import (
"net/http"
"server/internal/model/common"
"server/internal/model/request"
"server/internal/pkg/httputil"
"server/internal/service"
"server/internal/router"
"server/internal/service/admin"
"github.com/go-chi/chi/v5"
)
type TagHandler struct {
tagService *service.TagService
tagService *admin.TagService
}
func NewTagHandler(tagService *service.TagService) *TagHandler {
var _ router.Registrar = (*TagHandler)(nil)
func NewTagHandler(tagService *admin.TagService) *TagHandler {
return &TagHandler{
tagService: tagService,
}
}
func (h *TagHandler) ListPage(w http.ResponseWriter, r *http.Request) {
func (h *TagHandler) Register(r chi.Router) {
r.Route("/tags", func(r chi.Router) {
r.Get("/", h.List)
r.Get("/all", h.ListAll)
r.Post("/", h.Create)
r.Patch("/{id}", h.Update)
r.Delete("/{id}", h.Delete)
})
}
func (h *TagHandler) List(w http.ResponseWriter, r *http.Request) {
pagination := httputil.Pagination(r)
list, total, err := h.tagService.ListPage(r.Context(), pagination)
result, err := h.tagService.List(r.Context(), pagination)
if err != nil {
httputil.Fail(w, err)
return
@@ -29,9 +44,10 @@ func (h *TagHandler) ListPage(w http.ResponseWriter, r *http.Request) {
resp := common.PageResponse{
Page: pagination.Page,
PageSize: pagination.PageSize,
List: list,
Total: total,
List: result.List,
Total: result.Total,
}
httputil.OkWithPage(w, &resp)
}

View File

@@ -1,4 +1,4 @@
package handler
package admin
import (
"net/http"
@@ -7,44 +7,39 @@ import (
"server/internal/model/request"
"server/internal/pkg/errs"
"server/internal/pkg/httputil"
"server/internal/service"
"server/internal/router"
"server/internal/service/admin"
"github.com/go-chi/chi/v5"
)
type SysUserHandler struct {
userService *service.SysUserService
type UserHandler struct {
userService *admin.UserService
}
func NewSysUserHandler(userService *service.SysUserService) *SysUserHandler {
return &SysUserHandler{
// 编译期接口断言
var _ router.Registrar = (*UserHandler)(nil)
func NewUserHandler(userService *admin.UserService) *UserHandler {
return &UserHandler{
userService: userService,
}
}
func (h *SysUserHandler) ListPage(w http.ResponseWriter, r *http.Request) {
pagination := httputil.Pagination(r)
params := request.SearchSysUserParams{
Pagination: *pagination,
Username: r.URL.Query().Get("username"),
}
list, total, err := h.userService.ListPage(r.Context(), params)
if err != nil {
httputil.Fail(w, err)
return
}
resp := common.PageResponse{
Page: pagination.Page,
PageSize: pagination.PageSize,
List: list,
Total: total,
}
httputil.OkWithPage(w, &resp)
func (h *UserHandler) Register(r chi.Router) {
r.Route("/users", func(r chi.Router) {
r.Get("/", h.List)
r.Get("/me", h.GetCurrentUser)
r.Get("/{id}/roles", h.ListRoles)
r.Post("/", h.Create)
r.Patch("/{id}", h.Update)
r.Put("/{id}/roles", h.SetRoles)
r.Patch("/{id}/password", h.UpdatePassword)
r.Delete("/{id}", h.Delete)
})
}
func (h *SysUserHandler) GetUserInfo(w http.ResponseWriter, r *http.Request) {
func (h *UserHandler) GetCurrentUser(w http.ResponseWriter, r *http.Request) {
claims, ok := middleware.GetClaims(r.Context())
if !ok || claims.UserID == 0 {
@@ -52,10 +47,10 @@ func (h *SysUserHandler) GetUserInfo(w http.ResponseWriter, r *http.Request) {
return
}
isAdmin, _ := r.Context().Value(middleware.IsAdminKey).(bool)
isAdmin := middleware.IsAdmin(r.Context())
uid := claims.UserID
user, err := h.userService.GetUserInfo(r.Context(), uid, isAdmin)
user, err := h.userService.GetCurrentUser(r.Context(), uid, isAdmin)
if err != nil {
httputil.Fail(w, err)
return
@@ -64,14 +59,38 @@ func (h *SysUserHandler) GetUserInfo(w http.ResponseWriter, r *http.Request) {
httputil.Ok(w, user)
}
func (h *SysUserHandler) GetRoles(w http.ResponseWriter, r *http.Request) {
func (h *UserHandler) List(w http.ResponseWriter, r *http.Request) {
pagination := httputil.Pagination(r)
params := request.SearchUserParams{
Pagination: *pagination,
Username: r.URL.Query().Get("username"),
}
result, err := h.userService.List(r.Context(), params)
if err != nil {
httputil.Fail(w, err)
return
}
resp := common.PageResponse{
Page: pagination.Page,
PageSize: pagination.PageSize,
List: result.List,
Total: result.Total,
}
httputil.OkWithPage(w, &resp)
}
func (h *UserHandler) ListRoles(w http.ResponseWriter, r *http.Request) {
id, err := httputil.URLParamInt32(r, "id")
if err != nil {
httputil.Fail(w, err)
return
}
list, err := h.userService.GetRoles(r.Context(), id)
list, err := h.userService.ListRoles(r.Context(), id)
if err != nil {
httputil.Fail(w, err)
return
@@ -80,8 +99,8 @@ func (h *SysUserHandler) GetRoles(w http.ResponseWriter, r *http.Request) {
httputil.Ok(w, list)
}
func (h *SysUserHandler) Create(w http.ResponseWriter, r *http.Request) {
var req request.CreateSysUserRequest
func (h *UserHandler) Create(w http.ResponseWriter, r *http.Request) {
var req request.CreateUserRequest
if err := httputil.BindJson(r, &req); err != nil {
httputil.Fail(w, err)
@@ -96,8 +115,8 @@ func (h *SysUserHandler) Create(w http.ResponseWriter, r *http.Request) {
httputil.Ok(w)
}
func (h *SysUserHandler) Update(w http.ResponseWriter, r *http.Request) {
var req request.UpdateSysUserRequest
func (h *UserHandler) Update(w http.ResponseWriter, r *http.Request) {
var req request.UpdateUserRequest
id, err := httputil.URLParamInt32(r, "id")
if err != nil {
@@ -118,8 +137,8 @@ func (h *SysUserHandler) Update(w http.ResponseWriter, r *http.Request) {
httputil.Ok(w)
}
func (h *SysUserHandler) SetRoles(w http.ResponseWriter, r *http.Request) {
var req request.SetSysUserRolesRequest
func (h *UserHandler) SetRoles(w http.ResponseWriter, r *http.Request) {
var req request.SetUserRolesRequest
id, err := httputil.URLParamInt32(r, "id")
if err != nil {
@@ -141,8 +160,8 @@ func (h *SysUserHandler) SetRoles(w http.ResponseWriter, r *http.Request) {
}
func (h *SysUserHandler) UpdatePassword(w http.ResponseWriter, r *http.Request) {
var req request.UpdateSysUserPassword
func (h *UserHandler) UpdatePassword(w http.ResponseWriter, r *http.Request) {
var req request.UpdateUserPassword
id, err := httputil.URLParamInt32(r, "id")
if err != nil {
@@ -163,7 +182,7 @@ func (h *SysUserHandler) UpdatePassword(w http.ResponseWriter, r *http.Request)
httputil.Ok(w)
}
func (h *SysUserHandler) Delete(w http.ResponseWriter, r *http.Request) {
func (h *UserHandler) Delete(w http.ResponseWriter, r *http.Request) {
id, err := httputil.URLParamInt32(r, "id")
if err != nil {
httputil.Fail(w, err)

View File

@@ -1,22 +1,15 @@
package handler
import (
"server/internal/handler/admin"
"server/internal/handler/site"
"go.uber.org/fx"
)
var Module = fx.Module("handlers",
fx.Provide(
NewSysUserHandler,
NewSysRoleHandler,
NewSysMenuHandler,
NewSysApiHandler,
NewSysFileHandler,
NewSysPostHandler,
NewCategoryHandler,
NewAuthHandler,
NewTagHandler,
NewPostHandler,
NewWebHandler,
fx.Options(
admin.Module,
site.Module,
),
)

View File

@@ -0,0 +1,13 @@
package site
import (
"server/internal/router"
"go.uber.org/fx"
)
var Module = fx.Module("site-handlers",
fx.Provide(
router.AsRegistrar(router.SiteRoutes, NewPostHandler),
),
)

View File

@@ -1,4 +1,4 @@
package handler
package site
import (
"net/http"
@@ -6,24 +6,34 @@ import (
"server/internal/model/common"
"server/internal/pkg/errs"
"server/internal/pkg/httputil"
"server/internal/service"
"server/internal/utils"
"server/internal/router"
"server/internal/service/web"
"github.com/go-chi/chi/v5"
)
var _ router.Registrar = (*PostHandler)(nil)
type PostHandler struct {
postService *service.PostService
postService *web.PostService
}
func NewPostHandler(postService *service.PostService) *PostHandler {
func (h *PostHandler) Register(r chi.Router) {
r.Get("/posts", h.ListPage)
r.Get("/posts/{slug}", h.GetPost)
r.Get("/categories/stats", h.ListCategoryStats)
r.Get("/posts/archives", h.ListArchives)
r.Get("/posts/tags", h.ListPostTags)
}
func NewPostHandler(postService *web.PostService) *PostHandler {
return &PostHandler{postService: postService}
}
func (h *PostHandler) ListPage(w http.ResponseWriter, r *http.Request) {
pagination := httputil.Pagination(r)
list, total, err := h.postService.ListPage(r.Context(), pagination)
result, err := h.postService.ListPage(r.Context(), pagination)
if err != nil {
httputil.Fail(w, err)
return
@@ -32,8 +42,8 @@ func (h *PostHandler) ListPage(w http.ResponseWriter, r *http.Request) {
resp := common.PageResponse{
Page: pagination.Page,
PageSize: pagination.PageSize,
List: list,
Total: total,
List: result.List,
Total: result.Total,
}
httputil.OkWithPage(w, &resp)
@@ -47,7 +57,7 @@ func (h *PostHandler) GetPost(w http.ResponseWriter, r *http.Request) {
return
}
ip, err := netip.ParseAddr(utils.ClientIP(r))
ip, err := netip.ParseAddr(httputil.ClientIP(r))
if err != nil {
httputil.Fail(w, err)
return

View File

@@ -1,58 +0,0 @@
package handler
import (
"net/http"
"server/internal/model/common"
"server/internal/pkg/httputil"
"server/internal/service"
)
type SysFileHandler struct {
service *service.SysFileService
}
func NewSysFileHandler(service *service.SysFileService) *SysFileHandler {
return &SysFileHandler{
service: service,
}
}
func (h *SysFileHandler) ListPage(w http.ResponseWriter, r *http.Request) {
pagination := httputil.Pagination(r)
list, total, err := h.service.ListPage(r.Context(), pagination)
if err != nil {
httputil.Fail(w, err)
return
}
resp := common.PageResponse{
Page: pagination.Page,
PageSize: pagination.PageSize,
List: list,
Total: total,
}
httputil.OkWithPage(w, &resp)
}
func (h *SysFileHandler) Upload(w http.ResponseWriter, r *http.Request) {
folder := r.FormValue("folder")
if folder == "" {
folder = "/"
}
_, header, err := r.FormFile("file")
if err != nil {
httputil.Fail(w, err)
return
}
file, err := h.service.Upload(r.Context(), folder, header)
if err != nil {
httputil.Fail(w, err)
return
}
httputil.Ok(w, file)
}

View File

@@ -1,108 +0,0 @@
package handler
import (
"net/http"
"server/internal/model/common"
"server/internal/model/request"
"server/internal/pkg/httputil"
"server/internal/service"
)
type SysPostHandler struct {
sysPostService *service.SysPostService
}
func NewSysPostHandler(postService *service.SysPostService) *SysPostHandler {
return &SysPostHandler{sysPostService: postService}
}
func (h *SysPostHandler) ListPage(w http.ResponseWriter, r *http.Request) {
pagination := httputil.Pagination(r)
list, total, err := h.sysPostService.ListPage(r.Context(), pagination)
if err != nil {
httputil.Fail(w, err)
}
resp := common.PageResponse{
Page: pagination.Page,
PageSize: pagination.PageSize,
List: list,
Total: total,
}
httputil.OkWithPage(w, &resp)
}
func (h *SysPostHandler) GetPostById(w http.ResponseWriter, r *http.Request) {
id, err := httputil.URLParamInt32(r, "id")
if err != nil {
httputil.Fail(w, err)
return
}
post, err := h.sysPostService.FindByID(r.Context(), id)
if err != nil {
httputil.Fail(w, err)
return
}
httputil.Ok(w, post)
}
func (h *SysPostHandler) Create(w http.ResponseWriter, r *http.Request) {
var req request.CreatePostRequest
if err := httputil.BindJson(r, &req); err != nil {
httputil.Fail(w, err)
return
}
postID, err := h.sysPostService.Create(r.Context(), req)
if err != nil {
httputil.Fail(w, err)
return
}
httputil.Ok(w, map[string]int32{
"post_id": postID,
})
}
func (h *SysPostHandler) Update(w http.ResponseWriter, r *http.Request) {
id, err := httputil.URLParamInt32(r, "id")
if err != nil {
httputil.Fail(w, err)
return
}
var req request.UpdatePostRequest
if err = httputil.BindJson(r, &req); err != nil {
httputil.Fail(w, err)
return
}
if err = h.sysPostService.Update(r.Context(), id, req); err != nil {
httputil.Fail(w, err)
return
}
httputil.Ok(w)
}
func (h *SysPostHandler) Delete(w http.ResponseWriter, r *http.Request) {
id, err := httputil.URLParamInt32(r, "id")
if err != nil {
httputil.Fail(w, err)
return
}
if err = h.sysPostService.Delete(r.Context(), id); err != nil {
httputil.Fail(w, err)
return
}
httputil.Ok(w)
}

View File

@@ -1,30 +0,0 @@
package handler
import (
"net/http"
"server/internal/pkg/httputil"
"server/internal/utils"
)
type WebHandler struct {
}
func NewWebHandler() *WebHandler {
return &WebHandler{}
}
func (h *WebHandler) GetClientInfo(w http.ResponseWriter, r *http.Request) {
ip := utils.ClientIP(r)
userAgent := r.UserAgent()
httputil.Ok(w, map[string]any{
"ip": ip,
"userAgent": userAgent,
"method": r.Method,
"host": r.Host,
"path": r.URL.Path,
"origin": r.Header.Get("Origin"),
"accept": r.Header.Get("Accept"),
"acceptLanguage": r.Header.Get("Accept-Language"),
})
}

View File

@@ -30,43 +30,7 @@ func NewAuthMiddleware(store *db.Store, cache *cache.Caches) *AuthMiddleware {
}
}
func (m *AuthMiddleware) Middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var err error
claims, ok := GetClaims(ctx)
if !ok || claims.UserID == 0 {
httputil.Fail(w, errs.ErrUnauthorized)
return
}
// 判断是否有管理员权限 目前只判断uid是否为1
isAdmin := userIsAdmin(claims.UserID)
if isAdmin {
ctx = context.WithValue(ctx, IsAdminKey, isAdmin)
next.ServeHTTP(w, r.WithContext(ctx))
return
}
// 不是管理员 判断api权限
hasPermission, err := userHasApiPermission(ctx, r, m.store, claims.UserID, m.cache)
if err != nil {
httputil.Fail(w, err)
return
}
if !hasPermission {
httputil.Fail(w, errs.ErrPermissionDenied)
return
}
next.ServeHTTP(w, r)
})
}
func userIsAdmin(uid int32) bool {
func UserIsAdmin(uid int32) bool {
if uid == 1 {
return true
}
@@ -74,31 +38,79 @@ func userIsAdmin(uid int32) bool {
return false
}
func userHasApiPermission(ctx context.Context, r *http.Request, store *db.Store, uid int32, c *cache.Caches) (bool, error) {
func IsAdmin(ctx context.Context) bool {
isAdmin, ok := ctx.Value(IsAdminKey).(bool)
return ok && isAdmin
}
func (m *AuthMiddleware) hasApiPermission(ctx context.Context, uid int32, requestMethod string, requestPath string) (bool, error) {
var (
apis []sqlc.GetSysUserApisRow
apis []sqlc.ListUserApisRow
err error
)
// 先从缓存中获取api数据
k := cachekey.UserApiPermissions(uid)
apis, err = cache.GetOrSetJSON[[]sqlc.GetSysUserApisRow](ctx, c, k, 0, func() ([]sqlc.GetSysUserApisRow, error) {
return store.GetSysUserApis(ctx, uid)
apis, err = cache.GetOrSetJSON[[]sqlc.ListUserApisRow](ctx, m.cache, k, 0, func() ([]sqlc.ListUserApisRow, error) {
return m.store.ListUserApis(ctx, uid)
})
if err != nil {
return false, err
}
requestPath := chi.RouteContext(r.Context()).RoutePattern()
requestPath = strings.TrimPrefix(requestPath, "/api")
requestMethod := r.Method
for _, api := range apis {
if api.Path == requestPath && api.Method == requestMethod {
if api.Method != requestMethod {
continue
}
if api.Path == requestPath {
return true, nil
}
}
return false, nil
}
func (m *AuthMiddleware) Middleware(router chi.Router) func(handler http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
claims, ok := GetClaims(ctx)
if !ok || claims.UserID == 0 {
httputil.Fail(w, errs.ErrUnauthorized)
return
}
// 判断是否有管理员权限
isAdmin := UserIsAdmin(claims.UserID)
if isAdmin {
ctx = context.WithValue(ctx, IsAdminKey, isAdmin)
next.ServeHTTP(w, r.WithContext(ctx))
return
}
// 如果不是管理员 需要判断api权限
rctx := chi.NewRouteContext()
requestMethod := r.Method
// https://github.com/go-chi/chi/pull/872
api := router.Find(rctx, requestMethod, r.URL.Path)
requestPath := strings.TrimPrefix(api, "/api")
hasPermission, err := m.hasApiPermission(ctx, claims.UserID, requestMethod, requestPath)
if err != nil {
httputil.Fail(w, err)
return
}
if !hasPermission {
httputil.Fail(w, errs.ErrPermissionDenied)
return
}
next.ServeHTTP(w, r)
})
}
}

View File

@@ -5,7 +5,7 @@ import (
"log/slog"
"net/http"
"server/internal/model/common"
"server/internal/utils"
"server/internal/pkg/httputil"
"time"
gonanoid "github.com/matoous/go-nanoid/v2"
@@ -71,7 +71,7 @@ func (m *LoggerMiddleware) Middleware(next http.Handler) http.Handler {
duration := time.Since(start)
ip := utils.ClientIP(r)
ip := httputil.ClientIP(r)
fullPath := r.URL.Path
if r.URL.RawQuery != "" {

View File

@@ -14,3 +14,8 @@ type PageResponse struct {
List interface{} `json:"list,omitempty"` // 业务数据
Total int64 `json:"total"` // 总记录数
}
type PageResult[T any] struct {
List []T
Total int64
}

View File

@@ -2,7 +2,7 @@ package request
import "server/internal/model/common"
type CreateSysApiRequest struct {
type CreateApiRequest struct {
Name string `json:"name" validate:"required,min=1,max=100"`
GroupName string `json:"group_name" validate:"required,min=1,max=100"`
Path string `json:"path" validate:"required,min=1,max=100"`
@@ -10,7 +10,7 @@ type CreateSysApiRequest struct {
Sort *int32 `json:"sort" validate:"required,min=0"`
}
type UpdateSysApiRequest struct {
type UpdateApiRequest struct {
Name string `json:"name" validate:"required,min=1,max=100"`
GroupName string `json:"group_name" validate:"required,min=1,max=100"`
Path string `json:"path" validate:"required,min=1,max=100"`
@@ -18,8 +18,9 @@ type UpdateSysApiRequest struct {
Sort *int32 `json:"sort" validate:"required,min=0"`
}
type SearchSysApiParams struct {
type SearchApiParams struct {
common.Pagination
Name string `json:"name" form:"name" validate:"omitempty,max=100"`
Method string `json:"method" form:"method" validate:"omitempty,oneof=GET POST PUT PATCH DELETE"`
GroupName string `json:"group_name" form:"group_name" validate:"omitempty,max=100"`
}

View File

@@ -4,7 +4,7 @@ import (
"server/internal/pkg/validator"
)
type CreateSysMenuRequest struct {
type CreateMenuRequest struct {
Name string `json:"name" validate:"required,min=1,max=100"`
Path *string `json:"path" validate:"omitempty,max=100"`
Type *int16 `json:"type" validate:"required,oneof=0 1 2"`
@@ -17,7 +17,7 @@ type CreateSysMenuRequest struct {
PermissionCode string `json:"permission_code" validate:"required,min=1,max=100"`
}
type UpdateSysMenuRequest struct {
type UpdateMenuRequest struct {
Name *string `json:"name" validate:"omitempty,min=1,max=100"`
Path *string `json:"path" validate:"omitempty,max=100"`
Type *int16 `json:"type" validate:"omitempty,oneof=0 1 2"`

View File

@@ -1,20 +1,20 @@
package request
type CreateSysRoleRequest struct {
type CreateRoleRequest struct {
Name string `json:"name" validate:"required,min=1,max=100"`
Code string `json:"code" validate:"required,max=100"`
Status *int16 `json:"status" validate:"required,oneof=0 1"`
}
type UpdateSysRoleRequest struct {
type UpdateRoleRequest struct {
Name *string `json:"name" validate:"min=1,max=100"`
Status *int16 `json:"status" validate:"omitempty,oneof=0 1"`
}
type SetSysRoleMenusRequest struct {
type SetRoleMenusRequest struct {
MenuIDs []int32 `json:"menu_ids" validate:"required,dive,gt=0"`
}
type SetSysRoleApisRequest struct {
type SetRoleApisRequest struct {
ApiIDs []int32 `json:"api_ids" validate:"required,dive,gt=0"`
}

View File

@@ -5,7 +5,7 @@ import (
"server/internal/pkg/validator"
)
type CreateSysUserRequest struct {
type CreateUserRequest struct {
Username string `json:"username" validate:"required,min=1,max=50"`
Account string `json:"account" validate:"required,min=5,max=100"`
Password string `json:"password" validate:"required,min=6,max=255"`
@@ -13,17 +13,17 @@ type CreateSysUserRequest struct {
Status *int16 `json:"status" validate:"oneof=0 1"`
}
type UpdateSysUserRequest struct {
type UpdateUserRequest struct {
Username *string `json:"username" validate:"omitempty,min=1,max=50"`
AvatarID validator.NullInt32 `json:"avatar_id" validate:"omitempty"`
Status *int16 `json:"status" validate:"omitempty,oneof=0 1"`
}
type UpdateSysUserPassword struct {
type UpdateUserPassword struct {
Password string `json:"password" validate:"required,min=6,max=255"`
}
type SetSysUserRolesRequest struct {
type SetUserRolesRequest struct {
RoleIDs []int32 `json:"role_ids" validate:"required,dive,gt=0"`
}
@@ -32,7 +32,7 @@ type LoginRequest struct {
Password string `json:"password" validate:"required,min=6,max=255"`
}
type SearchSysUserParams struct {
type SearchUserParams struct {
common.Pagination
Username string `json:"username" validate:"omitempty,max=50"`
}

View File

@@ -2,17 +2,16 @@ package response
import (
"server/internal/db/sqlc"
"server/internal/pkg/httputil"
"time"
)
type SysUserRolesResponse struct {
type UserRolesResponse struct {
ID uint `json:"id"`
Code string `json:"code"`
Description string `json:"description"`
}
type SysUserInfo struct {
type UserInfo struct {
ID int32 `json:"id"`
Account string `json:"account"`
Username string `json:"username"`
@@ -29,7 +28,7 @@ type LoginResponse struct {
RefreshTokenExp time.Time `json:"refresh_token_exp"`
}
func NewSysUserInfo(user sqlc.GetSysUserByIDRow, roles []sqlc.SysRole, menus []sqlc.SysMenu, p []*string) *SysUserInfo {
func NewUserInfo(user sqlc.GetUserByIDRow, roles []sqlc.SysRole, menus []sqlc.SysMenu, p []*string) *UserInfo {
roleCodes := make([]string, len(roles))
for i, role := range roles {
roleCodes[i] = role.Code
@@ -42,11 +41,11 @@ func NewSysUserInfo(user sqlc.GetSysUserByIDRow, roles []sqlc.SysRole, menus []s
}
}
return &SysUserInfo{
return &UserInfo{
ID: user.ID,
Account: user.Account,
Username: user.Username,
AvatarUrl: httputil.BuildFileUrl(user.AvatarUrl),
AvatarUrl: *user.AvatarUrl,
Roles: roleCodes,
Menus: menus,
Permissions: permissions,

View File

@@ -19,34 +19,35 @@ func New(httpCode int, msg string) *AppError {
}
var (
ErrInvalidCredentials = New(http.StatusUnauthorized, "用户名或密码错误")
ErrUserDisabled = New(http.StatusForbidden, "用户已被禁用")
ErrUnauthenticated = New(http.StatusUnauthorized, "用户未登录或登录已失效")
ErrUnauthorized = New(http.StatusUnauthorized, "认证失败:无法获取当前用户信息")
ErrInvalidToken = New(http.StatusUnauthorized, "登录凭证无效")
ErrInvalidTokenClaims = New(http.StatusUnauthorized, "登录凭证解析失败")
ErrInvalidRefreshToken = New(http.StatusBadRequest, "invalid_grant")
ErrExpiredRefreshToken = New(http.StatusBadRequest, "invalid_grant")
ErrUserNotFound = New(http.StatusNotFound, "用户数据不存在")
ErrCategoryNotFound = New(http.StatusNotFound, "分类数据不存在")
ErrTagNotFound = New(http.StatusNotFound, "标签数据不存在")
ErrSysApiNotFound = New(http.StatusNotFound, "接口数据不存在")
ErrPostNotFound = New(http.StatusNotFound, "文章数据不存在")
ErrSysMenuNotFound = New(http.StatusNotFound, "菜单数据不存在")
ErrSysRoleNotFound = New(http.StatusNotFound, "角色数据不存在")
ErrCannotDeleteSuperAdmin = New(http.StatusForbidden, "超级管理员账号无法被删除")
ErrSlugRequired = New(http.StatusBadRequest, "slug不能为空")
ErrIDRequired = New(http.StatusBadRequest, "id不能为空")
ErrPermissionDenied = New(http.StatusForbidden, "没有权限访问该资源")
ErrInvalidID = New(http.StatusBadRequest, "id非法请检查传入的id")
ErrEmptyBody = New(http.StatusBadRequest, "请求内容(body)不能为空")
ErrInvalidJSON = New(http.StatusBadRequest, "请求数据格式错误")
ErrAccountAlreadyExists = New(http.StatusBadRequest, "账号已存在")
ErrCodeAlreadyExists = New(http.StatusBadRequest, "角色编码不允许重复")
ErrSlugAlreadyExists = New(http.StatusBadRequest, "slug不允许重复")
ErrPermissionCodeAlreadyExists = New(http.StatusBadRequest, "权限编码不允许重复")
ErrCategoryCodeAlreadyExists = New(http.StatusBadRequest, "分类编码不允许重复")
ErrTagCodeAlreadyExists = New(http.StatusBadRequest, "标签编码不允许重复")
ErrSysMenusPathUniqueIdx = New(http.StatusBadRequest, "菜单路径不允许重复")
ErrSysApiMethodPathAlreadyExists = New(http.StatusBadRequest, "接口方法(method)路径(path)不允许重复")
ErrInvalidCredentials = New(http.StatusUnauthorized, "用户名或密码错误")
ErrUserDisabled = New(http.StatusForbidden, "用户已被禁用")
ErrUnauthenticated = New(http.StatusUnauthorized, "用户未登录或登录已失效")
ErrUnauthorized = New(http.StatusUnauthorized, "认证失败:无法获取当前用户信息")
ErrInvalidToken = New(http.StatusUnauthorized, "登录凭证无效")
ErrInvalidTokenClaims = New(http.StatusUnauthorized, "登录凭证解析失败")
ErrInvalidRefreshToken = New(http.StatusBadRequest, "invalid_grant")
ErrExpiredRefreshToken = New(http.StatusBadRequest, "invalid_grant")
ErrUserNotFound = New(http.StatusNotFound, "用户数据不存在")
ErrCategoryNotFound = New(http.StatusNotFound, "分类数据不存在")
ErrTagNotFound = New(http.StatusNotFound, "标签数据不存在")
ErrApiNotFound = New(http.StatusNotFound, "接口数据不存在")
ErrPostNotFound = New(http.StatusNotFound, "文章数据不存在")
ErrMenuNotFound = New(http.StatusNotFound, "菜单数据不存在")
ErrRoleNotFound = New(http.StatusNotFound, "角色数据不存在")
ErrCannotDeleteSuperAdmin = New(http.StatusForbidden, "超级管理员账号无法被删除")
ErrSlugRequired = New(http.StatusBadRequest, "slug不能为空")
ErrIDRequired = New(http.StatusBadRequest, "id不能为空")
ErrPermissionDenied = New(http.StatusForbidden, "没有权限访问该资源")
ErrInvalidID = New(http.StatusBadRequest, "id非法请检查传入的id")
ErrEmptyBody = New(http.StatusBadRequest, "请求内容(body)不能为空")
ErrInvalidJSON = New(http.StatusBadRequest, "请求数据格式错误")
ErrAccountAlreadyExists = New(http.StatusBadRequest, "账号已存在")
ErrCodeAlreadyExists = New(http.StatusBadRequest, "角色编码不允许重复")
ErrSlugAlreadyExists = New(http.StatusBadRequest, "slug不允许重复")
ErrPermissionCodeAlreadyExists = New(http.StatusBadRequest, "权限编码不允许重复")
ErrCategoryCodeAlreadyExists = New(http.StatusBadRequest, "分类编码不允许重复")
ErrTagCodeAlreadyExists = New(http.StatusBadRequest, "标签编码不允许重复")
ErrMenusPathUniqueIdx = New(http.StatusBadRequest, "菜单路径不允许重复")
ErrApiMethodPathAlreadyExists = New(http.StatusBadRequest, "接口方法(method)路径(path)不允许重复")
ErrInvalidApiPath = New(http.StatusBadRequest, "接口路径格式不正确,必须以/开头,参数段需为{name}格式")
)

View File

@@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"io"
"net"
"net/http"
"net/url"
"server/internal/config"
@@ -11,6 +12,7 @@ import (
"server/internal/pkg/errs"
"server/internal/pkg/validator"
"strconv"
"strings"
"github.com/go-chi/chi/v5"
)
@@ -71,6 +73,28 @@ func BindJson(r *http.Request, dest any) error {
return nil
}
// ClientIP 获取客户端 IP依次从 X-Forwarded-For、X-Real-IP、RemoteAddr 取值
func ClientIP(r *http.Request) string {
if xff := r.Header.Get("X-Forwarded-For"); xff != "" {
parts := strings.Split(xff, ",")
if len(parts) > 0 {
return strings.TrimSpace(parts[0])
}
}
if ip := r.Header.Get("X-Real-IP"); ip != "" {
return ip
}
// RemoteAddr: IP:port
host, _, err := net.SplitHostPort(r.RemoteAddr)
if err == nil {
return host
}
return r.RemoteAddr
}
func BuildFileUrl(path *string) string {
if path == nil || *path == "" {
return ""

View File

@@ -1,19 +0,0 @@
package router
import (
"server/internal/handler"
"github.com/go-chi/chi/v5"
)
func SetupPostRoutes(r chi.Router, h *handler.PostHandler) {
r.Get("/post", h.ListPage)
r.Get("/post/{slug}", h.GetPost)
r.Get("/category/stats", h.ListCategoryStats)
r.Get("/post/archive", h.ListArchives)
r.Get("/post/tags", h.ListPostTags)
}
func SetupWebRoutes(r chi.Router, h *handler.WebHandler) {
}

View File

@@ -5,35 +5,78 @@ import (
"os"
"path/filepath"
"server/internal/config"
"server/internal/handler"
"server/internal/middleware"
"server/internal/pkg/httputil"
"github.com/go-chi/chi/v5"
"go.uber.org/fx"
)
type Handlers struct {
fx.In
// auth
JwtMiddleware *middleware.JWTMiddleware
AuthMiddleware *middleware.AuthMiddleware
LoggerMiddleware *middleware.LoggerMiddleware
// system
AuthHandler *handler.AuthHandler
SysUserHandler *handler.SysUserHandler
SysRoleHandler *handler.SysRoleHandler
SysMenuHandler *handler.SysMenuHandler
SysApiHandler *handler.SysApiHandler
SysFileHandler *handler.SysFileHandler
SysPostHandler *handler.SysPostHandler
CategoryHandler *handler.CategoryHandler
TagHandler *handler.TagHandler
// web
PostHandler *handler.PostHandler
WebHandler *handler.WebHandler
type Group string
const (
AdminPublicRoutes Group = "admin_public_routes"
AdminRoutes Group = "admin_routes"
SiteRoutes Group = "site_routes"
)
type Registrar interface {
Register(r chi.Router)
}
func setupStaticFiles(r chi.Router) {
type Params struct {
fx.In
Jwt *middleware.JWTMiddleware
Auth *middleware.AuthMiddleware
Logger *middleware.LoggerMiddleware
AdminPublicRoutes []Registrar `group:"admin_public_routes"`
AdminRoutes []Registrar `group:"admin_routes"`
SiteRoutes []Registrar `group:"site_routes"`
}
func NewRouter(p Params) *chi.Mux {
mux := chi.NewRouter()
mux.Use(p.Logger.Middleware)
if config.IsDev() {
// 开放静态目录
registerStaticFiles(mux)
// 开发阶段:遍历所有已注册路由的清单接口(无鉴权)
mux.Get("/api/admin/routes", ListRoutes(mux))
}
mux.Route("/api/admin", func(r chi.Router) {
// 免鉴权接口
for _, route := range p.AdminPublicRoutes {
route.Register(r)
}
r.Group(func(r chi.Router) {
// jwt 和 auth中间件
r.Use(p.Jwt.Middleware)
r.Use(p.Auth.Middleware(mux))
// 循环挂载所有后台业务模块
for _, route := range p.AdminRoutes {
route.Register(r)
}
})
})
mux.Route("/api", func(r chi.Router) {
for _, route := range p.SiteRoutes {
route.Register(r)
}
})
return mux
}
func registerStaticFiles(r chi.Router) {
rootDir, _ := os.Getwd()
uploadsDir := filepath.Join(rootDir, "uploads")
@@ -41,43 +84,34 @@ func setupStaticFiles(r chi.Router) {
r.Handle("/static/*", http.StripPrefix("/static/", http.FileServer(http.Dir(uploadsDir))))
}
func NewRouter(m Handlers) *chi.Mux {
r := chi.NewRouter()
r.Use(m.LoggerMiddleware.Middleware)
if config.IsDev() {
// 开放静态目录
setupStaticFiles(r)
}
r.Route("/api/admin", func(r chi.Router) {
r.Post("/auth/login", m.AuthHandler.Login)
r.Post("/auth/refresh-token", m.AuthHandler.RefreshToken)
r.Post("/auth/logout", m.AuthHandler.Logout)
r.Group(func(r chi.Router) {
r.Use(m.JwtMiddleware.Middleware)
r.Use(m.AuthMiddleware.Middleware)
SetupSysUserRoutes(r, m.SysUserHandler)
SetupSysRoleRoutes(r, m.SysRoleHandler)
SetupSysMenuRoutes(r, m.SysMenuHandler)
SetupSysApiRoutes(r, m.SysApiHandler)
SetupSysFileRoutes(r, m.SysFileHandler)
SetupCategoryRoutes(r, m.CategoryHandler)
SetupSysPostRoutes(r, m.SysPostHandler)
SetupTagRoutes(r, m.TagHandler)
})
})
// web api
r.Route("/api", func(r chi.Router) {
r.Group(func(r chi.Router) {
SetupPostRoutes(r, m.PostHandler)
SetupWebRoutes(r, m.WebHandler)
})
})
return r
// RouteInfo 路由信息
type RouteInfo struct {
Method string `json:"method"`
Path string `json:"path"`
}
// ListRoutes 遍历所有已注册的路由
func ListRoutes(mux *chi.Mux) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var routes []RouteInfo
err := chi.Walk(mux, func(method string, route string, _ http.Handler, _ ...func(http.Handler) http.Handler) error {
routes = append(routes, RouteInfo{Method: method, Path: route})
return nil
})
if err != nil {
httputil.Fail(w, err)
return
}
httputil.Ok(w, routes)
}
}
func AsRegistrar(group Group, f any) any {
return fx.Annotate(
f,
fx.As(new(Registrar)),
fx.ResultTags(`group:"`+string(group)+`"`),
)
}

View File

@@ -1,84 +0,0 @@
package router
import (
"server/internal/handler"
"github.com/go-chi/chi/v5"
)
// SetupSysUserRoutes 8
func SetupSysUserRoutes(r chi.Router, h *handler.SysUserHandler) {
r.Get("/user", h.ListPage)
r.Get("/user/info", h.GetUserInfo)
r.Get("/user/{id}/roles", h.GetRoles)
r.Post("/user", h.Create)
r.Patch("/user/{id}", h.Update)
r.Put("/user/{id}/roles", h.SetRoles)
r.Patch("/user/{id}/password", h.UpdatePassword)
r.Delete("/user/{id}", h.Delete)
}
// SetupSysRoleRoutes 9
func SetupSysRoleRoutes(r chi.Router, h *handler.SysRoleHandler) {
r.Get("/role", h.ListPage)
r.Get("/role/{id}/menus", h.GetRoleMenus)
r.Get("/role/{id}/apis", h.GetRoleApis)
r.Get("/role/all", h.GetRoles)
r.Post("/role", h.Create)
r.Patch("/role/{id}", h.Update)
r.Put("/role/{id}/menus", h.SetRoleMenus)
r.Put("/role/{id}/apis", h.SetRoleApis)
r.Delete("/role/{id}", h.Delete)
}
// SetupSysMenuRoutes 5
func SetupSysMenuRoutes(r chi.Router, h *handler.SysMenuHandler) {
r.Get("/menu", h.ListPage)
r.Get("/menu/all", h.GetMenus)
r.Post("/menu", h.Create)
r.Patch("/menu/{id}", h.Update)
r.Delete("/menu/{id}", h.Delete)
}
// SetupSysApiRoutes 6
func SetupSysApiRoutes(r chi.Router, h *handler.SysApiHandler) {
r.Get("/api", h.ListPage)
r.Get("/api/all", h.GetAllSysApis)
r.Get("/api/group-names", h.GetApiGroupNames)
r.Post("/api", h.Create)
r.Patch("/api/{id}", h.Update)
r.Delete("/api/{id}", h.Delete)
}
// SetupSysFileRoutes 2
func SetupSysFileRoutes(r chi.Router, h *handler.SysFileHandler) {
r.Get("/file", h.ListPage)
r.Post("/file", h.Upload)
}
// SetupSysPostRoutes 5
func SetupSysPostRoutes(r chi.Router, h *handler.SysPostHandler) {
r.Get("/post", h.ListPage)
r.Get("/post/{id}", h.GetPostById)
r.Post("/post", h.Create)
r.Patch("/post/{id}", h.Update)
r.Delete("/post/{id}", h.Delete)
}
// SetupCategoryRoutes 5
func SetupCategoryRoutes(r chi.Router, h *handler.CategoryHandler) {
r.Get("/category", h.ListPage)
r.Get("/category/all", h.ListAll)
r.Post("/category", h.Create)
r.Patch("/category/{id}", h.Update)
r.Delete("/category/{id}", h.Delete)
}
// SetupTagRoutes 5
func SetupTagRoutes(r chi.Router, h *handler.TagHandler) {
r.Get("/tag", h.ListPage)
r.Get("/tag/all", h.ListAll)
r.Post("/tag", h.Create)
r.Patch("/tag/{id}", h.Update)
r.Delete("/tag/{id}", h.Delete)
}

View File

@@ -1,9 +1,10 @@
package service
package admin
import (
"context"
"server/internal/db"
"server/internal/db/sqlc"
"server/internal/model/common"
"server/internal/model/enum"
"server/internal/model/request"
"server/internal/pkg/cache"
@@ -12,55 +13,61 @@ import (
"server/internal/pkg/errs"
)
type SysApiService struct {
type ApiService struct {
store *db.Store
cache *cache.Caches
}
func NewSysApiService(store *db.Store, cache *cache.Caches) *SysApiService {
return &SysApiService{
func NewApiService(store *db.Store, cache *cache.Caches) *ApiService {
return &ApiService{
store: store,
cache: cache,
}
}
func (s *SysApiService) ListPage(ctx context.Context, p request.SearchSysApiParams) ([]sqlc.SysApi, int64, error) {
params := sqlc.GetSysApisParams{
func (s *ApiService) List(ctx context.Context, p request.SearchApiParams) (*common.PageResult[sqlc.SysApi], error) {
params := sqlc.ListApisParams{
Limit: p.PageSize,
Offset: (p.Page - 1) * p.PageSize,
Name: p.Name,
GroupName: p.GroupName,
Method: p.Method,
}
total, err := s.store.CountSysApis(ctx, sqlc.CountSysApisParams{
total, err := s.store.CountApis(ctx, sqlc.CountApisParams{
Name: p.Name,
GroupName: p.GroupName,
Method: p.Method,
})
if err != nil {
return nil, 0, err
return nil, err
}
list, err := s.store.GetSysApis(ctx, params)
list, err := s.store.ListApis(ctx, params)
if err != nil {
return nil, 0, err
return nil, err
}
return list, total, nil
return &common.PageResult[sqlc.SysApi]{
List: list,
Total: total,
}, nil
}
func (s *SysApiService) GetAllSysApis(ctx context.Context) ([]sqlc.SysApi, error) {
return s.store.GetAllSysApis(ctx)
func (s *ApiService) ListAll(ctx context.Context) ([]sqlc.SysApi, error) {
return s.store.ListAllApis(ctx)
}
func (s *SysApiService) GetApiGroupNames(ctx context.Context) ([]string, error) {
return s.store.GetSysApiGroupNames(ctx)
func (s *ApiService) ListApiGroups(ctx context.Context) ([]string, error) {
return s.store.ListApiGroups(ctx)
}
func (s *SysApiService) Create(ctx context.Context, req request.CreateSysApiRequest) error {
func (s *ApiService) Create(ctx context.Context, req request.CreateApiRequest) error {
return s.store.WithTx(ctx, func(q *sqlc.Queries) error {
api := sqlc.CreateSysApiParams{
api := sqlc.CreateApiParams{
Name: req.Name,
GroupName: req.GroupName,
Method: req.Method,
@@ -69,7 +76,7 @@ func (s *SysApiService) Create(ctx context.Context, req request.CreateSysApiRequ
}
// 创建权限
permissionId, err := q.CreateSysPermission(ctx, sqlc.CreateSysPermissionParams{
permissionId, err := q.CreatePermission(ctx, sqlc.CreatePermissionParams{
Type: int16(enum.PermissionTypeApi),
})
@@ -78,13 +85,13 @@ func (s *SysApiService) Create(ctx context.Context, req request.CreateSysApiRequ
}
// 创建api
apiId, err := q.CreateSysApi(ctx, api)
apiId, err := q.CreateApi(ctx, api)
if err != nil {
return dberr.MapUniqueViolation(err, dberr.SysApisMethodPathKey, errs.ErrSysApiMethodPathAlreadyExists)
return dberr.MapUniqueViolation(err, dberr.SysApisMethodPathKey, errs.ErrApiMethodPathAlreadyExists)
}
// 关联权限
if err = q.CreateSysApiPermission(ctx, sqlc.CreateSysApiPermissionParams{
if err = q.CreateApiPermission(ctx, sqlc.CreateApiPermissionParams{
ApiID: apiId,
PermissionID: permissionId,
}); err != nil {
@@ -96,8 +103,8 @@ func (s *SysApiService) Create(ctx context.Context, req request.CreateSysApiRequ
})
}
func (s *SysApiService) Update(ctx context.Context, id int32, req request.UpdateSysApiRequest) error {
api := sqlc.UpdateSysApiParams{
func (s *ApiService) Update(ctx context.Context, id int32, req request.UpdateApiRequest) error {
api := sqlc.UpdateApiParams{
ID: id,
Name: req.Name,
GroupName: req.GroupName,
@@ -106,9 +113,9 @@ func (s *SysApiService) Update(ctx context.Context, id int32, req request.Update
Sort: req.Sort,
}
rows, err := s.store.UpdateSysApi(ctx, api)
if err = dberr.MapRowsAffected(rows, err, errs.ErrSysApiNotFound); err != nil {
return dberr.MapUniqueViolation(err, dberr.SysApisMethodPathKey, errs.ErrSysApiMethodPathAlreadyExists)
rows, err := s.store.UpdateApi(ctx, api)
if err = dberr.MapRowsAffected(rows, err, errs.ErrApiNotFound); err != nil {
return dberr.MapUniqueViolation(err, dberr.SysApisMethodPathKey, errs.ErrApiMethodPathAlreadyExists)
}
// 如果更新成功 则清理缓存
@@ -117,28 +124,28 @@ func (s *SysApiService) Update(ctx context.Context, id int32, req request.Update
return nil
}
func (s *SysApiService) Delete(ctx context.Context, id int32) error {
func (s *ApiService) Delete(ctx context.Context, id int32) error {
err := s.store.WithTx(ctx, func(q *sqlc.Queries) error {
// 1. 找出权限id
permissionID, err := q.GetSysPermissionIDBySysApiID(ctx, id)
permissionID, err := q.GetPermissionIDBySysApiID(ctx, id)
if err != nil {
return dberr.MapNoRows(err, errs.ErrSysApiNotFound)
return dberr.MapNoRows(err, errs.ErrApiNotFound)
}
// 2. 根据权限id,删除角色权限关联数据
if err = q.DeleteSysRolePermissionByPermissionID(ctx, permissionID); err != nil {
if err = q.DeleteRolePermissionByPermissionID(ctx, permissionID); err != nil {
return err
}
// 3. 根据api id 删除sys_api_permission关联表数据
if err = q.DeleteSysApiPermission(ctx, id); err != nil {
if err = q.DeleteApiPermission(ctx, id); err != nil {
return err
}
// 4. 根据权限id,删除权限表权限数据
if err = q.DeleteSysPermission(ctx, permissionID); err != nil {
if err = q.DeletePermission(ctx, permissionID); err != nil {
return err
}
// 5. 删除api
rows, err := q.DeleteSysApi(ctx, id)
if err = dberr.MapRowsAffected(rows, err, errs.ErrSysApiNotFound); err != nil {
rows, err := q.DeleteApi(ctx, id)
if err = dberr.MapRowsAffected(rows, err, errs.ErrApiNotFound); err != nil {
return err
}

View File

@@ -1,4 +1,4 @@
package service
package admin
import (
"context"
@@ -47,7 +47,7 @@ func comparePasswordHash(passwordHash, inputPassword string) error {
}
func (s *AuthService) Login(ctx context.Context, req request.LoginRequest) (*response.LoginResponse, error) {
user, err := s.store.GetSysUserByAccount(ctx, req.Account)
user, err := s.store.GetUserByAccount(ctx, req.Account)
if err != nil {
return nil, errs.ErrInvalidCredentials
@@ -138,7 +138,7 @@ func (s *AuthService) Logout(ctx context.Context, refreshToken string) error {
func (s *AuthService) GetActiveSysUser(ctx context.Context, id int32) error {
var err error
_, err = s.store.GetActiveSysUserByID(ctx, id)
_, err = s.store.GetActiveUserByID(ctx, id)
if err != nil {
return err
}

View File

@@ -1,4 +1,4 @@
package service
package admin
import (
"context"
@@ -20,7 +20,7 @@ func NewCategoryService(store *db.Store) *CategoryService {
}
}
func (s *CategoryService) ListPage(ctx context.Context, p *common.Pagination) ([]sqlc.Category, int64, error) {
func (s *CategoryService) List(ctx context.Context, p *common.Pagination) (*common.PageResult[sqlc.Category], error) {
params := sqlc.ListCategoriesParams{
Limit: p.PageSize,
Offset: (p.Page - 1) * p.PageSize,
@@ -28,15 +28,18 @@ func (s *CategoryService) ListPage(ctx context.Context, p *common.Pagination) ([
total, err := s.store.CountCategories(ctx)
if err != nil {
return nil, 0, err
return nil, err
}
list, err := s.store.ListCategories(ctx, params)
if err != nil {
return nil, 0, err
return nil, err
}
return list, total, nil
return &common.PageResult[sqlc.Category]{
List: list,
Total: total,
}, nil
}
func (s *CategoryService) ListAll(ctx context.Context) ([]sqlc.Category, error) {

View File

@@ -1,4 +1,4 @@
package service
package admin
import (
"context"
@@ -8,18 +8,17 @@ import (
"server/internal/db"
"server/internal/db/sqlc"
"server/internal/model/common"
"server/internal/model/response"
"server/internal/pkg/httputil"
gonanoid "github.com/matoous/go-nanoid/v2"
)
type SysFileService struct {
type FileService struct {
store *db.Store
}
func NewSysFileService(store *db.Store) *SysFileService {
return &SysFileService{
func NewFileService(store *db.Store) *FileService {
return &FileService{
store: store,
}
}
@@ -41,8 +40,8 @@ func MakeSavedDir(folder string) (string, error) {
return uploadDir, nil
}
func (s *SysFileService) ListPage(ctx context.Context, p *common.Pagination) ([]sqlc.File, int64, error) {
params := sqlc.GetFilesParams{
func (s *FileService) List(ctx context.Context, p *common.Pagination) (*common.PageResult[sqlc.File], error) {
params := sqlc.ListFilesParams{
Limit: p.PageSize,
Offset: (p.Page - 1) * p.PageSize,
}
@@ -50,19 +49,22 @@ func (s *SysFileService) ListPage(ctx context.Context, p *common.Pagination) ([]
total, err := s.store.CountFiles(ctx)
if err != nil {
return nil, 0, err
return nil, err
}
list, err := s.store.GetFiles(ctx, params)
list, err := s.store.ListFiles(ctx, params)
if err != nil {
return nil, 0, err
return nil, err
}
return response.ToFiles(list), total, nil
return &common.PageResult[sqlc.File]{
List: list,
Total: total,
}, nil
}
func (s *SysFileService) Upload(ctx context.Context, folder string, file *multipart.FileHeader) (*sqlc.CreateFileRow, error) {
func (s *FileService) Upload(ctx context.Context, folder string, file *multipart.FileHeader) (*sqlc.CreateFileRow, error) {
// 生成文件名
fileID, err := gonanoid.New()
if err != nil {
@@ -102,6 +104,7 @@ func (s *SysFileService) Upload(ctx context.Context, folder string, file *multip
params := sqlc.CreateFileParams{
FileName: filename,
FilePath: filePath,
FileUrl: httputil.BuildFileUrl(&filePath),
OriginalName: file.Filename,
FolderName: folder,
MimeType: file.Header.Get("Content-Type"),
@@ -113,7 +116,5 @@ func (s *SysFileService) Upload(ctx context.Context, folder string, file *multip
return nil, err
}
result.FilePath = httputil.BuildFileUrl(&result.FilePath)
return &result, nil
}

View File

@@ -1,4 +1,4 @@
package service
package admin
import (
"context"
@@ -13,21 +13,21 @@ import (
"server/internal/pkg/errs"
)
type SysMenuService struct {
type MenuService struct {
store *db.Store
cache *cache.Caches
}
func NewSysMenuService(store *db.Store, cache *cache.Caches) *SysMenuService {
return &SysMenuService{
func NewMenuService(store *db.Store, cache *cache.Caches) *MenuService {
return &MenuService{
store: store,
cache: cache,
}
}
func (s *SysMenuService) Create(ctx context.Context, req request.CreateSysMenuRequest) error {
func (s *MenuService) Create(ctx context.Context, req request.CreateMenuRequest) error {
err := s.store.WithTx(ctx, func(q *sqlc.Queries) error {
menu := sqlc.CreateSysMenuParams{
menu := sqlc.CreateMenuParams{
Name: req.Name,
Path: req.Path,
Component: req.Component,
@@ -40,7 +40,7 @@ func (s *SysMenuService) Create(ctx context.Context, req request.CreateSysMenuRe
}
// 先创建权限
permissionId, err := q.CreateSysPermission(ctx, sqlc.CreateSysPermissionParams{
permissionId, err := q.CreatePermission(ctx, sqlc.CreatePermissionParams{
Type: int16(enum.PermissionTypeMenu),
Code: &req.PermissionCode,
})
@@ -51,13 +51,13 @@ func (s *SysMenuService) Create(ctx context.Context, req request.CreateSysMenuRe
}
// 创建菜单
menuId, err := q.CreateSysMenu(ctx, menu)
menuId, err := q.CreateMenu(ctx, menu)
if err != nil {
return dberr.MapUniqueViolation(err, dberr.SysMenusPathUniqueIdx, errs.ErrSysMenusPathUniqueIdx)
return dberr.MapUniqueViolation(err, dberr.SysMenusPathUniqueIdx, errs.ErrMenusPathUniqueIdx)
}
// 绑定权限
if err = q.CreateSysMenuPermission(ctx, sqlc.CreateSysMenuPermissionParams{
if err = q.CreateMenuPermission(ctx, sqlc.CreateMenuPermissionParams{
MenuID: menuId,
PermissionID: permissionId,
}); err != nil {
@@ -74,10 +74,10 @@ func (s *SysMenuService) Create(ctx context.Context, req request.CreateSysMenuRe
return nil
}
func (s *SysMenuService) Update(ctx context.Context, id int32, req request.UpdateSysMenuRequest) error {
func (s *MenuService) Update(ctx context.Context, id int32, req request.UpdateMenuRequest) error {
err := s.store.WithTx(ctx, func(q *sqlc.Queries) error {
// 构造 menu 参数
menu := sqlc.UpdateSysMenuParams{
menu := sqlc.UpdateMenuParams{
ID: id,
Name: req.Name,
Path: req.Path,
@@ -103,19 +103,19 @@ func (s *SysMenuService) Update(ctx context.Context, id int32, req request.Updat
}
// 执行更新
rows, err := q.UpdateSysMenu(ctx, menu)
rows, err := q.UpdateMenu(ctx, menu)
// 先判断数据是否存在 在判断path是否重复
if err = dberr.MapRowsAffected(rows, err, errs.ErrSysMenuNotFound); err != nil {
return dberr.MapUniqueViolation(err, dberr.SysMenusPathUniqueIdx, errs.ErrSysMenusPathUniqueIdx)
if err = dberr.MapRowsAffected(rows, err, errs.ErrMenuNotFound); err != nil {
return dberr.MapUniqueViolation(err, dberr.SysMenusPathUniqueIdx, errs.ErrMenusPathUniqueIdx)
}
permission := sqlc.UpdateSysMenuPermissionCodeParams{
permission := sqlc.UpdateMenuPermissionCodeParams{
MenuID: id,
Code: req.PermissionCode,
}
if err = q.UpdateSysMenuPermissionCode(ctx, permission); err != nil {
if err = q.UpdateMenuPermissionCode(ctx, permission); err != nil {
return dberr.MapUniqueViolation(err, dberr.SysPermissionsCodeKey, errs.ErrPermissionCodeAlreadyExists)
}
@@ -132,52 +132,55 @@ func (s *SysMenuService) Update(ctx context.Context, id int32, req request.Updat
return nil
}
func (s *SysMenuService) ListPage(ctx context.Context, p *common.Pagination) ([]sqlc.ListSysMenusRow, int64, error) {
params := sqlc.ListSysMenusParams{
func (s *MenuService) List(ctx context.Context, p *common.Pagination) (*common.PageResult[sqlc.ListMenusRow], error) {
params := sqlc.ListMenusParams{
Limit: p.PageSize,
Offset: (p.Page - 1) * p.PageSize,
}
total, err := s.store.CountSysMenus(ctx)
total, err := s.store.CountMenus(ctx)
if err != nil {
return nil, 0, err
return nil, err
}
list, err := s.store.ListSysMenus(ctx, params)
list, err := s.store.ListMenus(ctx, params)
if err != nil {
return nil, 0, err
return nil, err
}
return list, total, nil
return &common.PageResult[sqlc.ListMenusRow]{
List: list,
Total: total,
}, nil
}
func (s *SysMenuService) GetMenus(ctx context.Context) ([]sqlc.GetAllSysMenusRow, error) {
return s.store.GetAllSysMenus(ctx)
func (s *MenuService) ListAll(ctx context.Context) ([]sqlc.ListAllMenusRow, error) {
return s.store.ListAllMenus(ctx)
}
func (s *SysMenuService) Delete(ctx context.Context, id int32) error {
func (s *MenuService) Delete(ctx context.Context, id int32) error {
err := s.store.WithTx(ctx, func(q *sqlc.Queries) error {
// 1. 根据菜单id, 找出对应的权限id
permissionID, err := q.GetSysPermissionIDBySysMenuID(ctx, id)
permissionID, err := q.GetPermissionIDBySysMenuID(ctx, id)
if err != nil {
return dberr.MapNoRows(err, errs.ErrSysMenuNotFound)
return dberr.MapNoRows(err, errs.ErrMenuNotFound)
}
// 2. 根据权限id 删除角色权限关联
if err = q.DeleteSysRolePermissionByPermissionID(ctx, permissionID); err != nil {
if err = q.DeleteRolePermissionByPermissionID(ctx, permissionID); err != nil {
return err
}
// 3. 根据菜单id 删除sys_menu_permission关联表数据
if err = q.DeleteSysMenuPermission(ctx, id); err != nil {
if err = q.DeleteMenuPermission(ctx, id); err != nil {
return err
}
// 4. 根据权限id删除权限表数据
if err = q.DeleteSysPermission(ctx, permissionID); err != nil {
if err = q.DeletePermission(ctx, permissionID); err != nil {
return err
}
// 5. 删除菜单
rows, err := q.DeleteSysMenu(ctx, id)
if err = dberr.MapRowsAffected(rows, err, errs.ErrSysMenuNotFound); err != nil {
rows, err := q.DeleteMenu(ctx, id)
if err = dberr.MapRowsAffected(rows, err, errs.ErrMenuNotFound); err != nil {
return err
}

View File

@@ -0,0 +1,19 @@
package admin
import (
"go.uber.org/fx"
)
var Module = fx.Module("sys-services",
fx.Provide(
NewUserService,
NewRoleService,
NewMenuService,
NewApiService,
NewFileService,
NewPostService,
NewAuthService,
NewTagService,
NewCategoryService,
),
)

View File

@@ -1,4 +1,4 @@
package service
package admin
import (
"context"
@@ -8,20 +8,19 @@ import (
"server/internal/model/request"
"server/internal/pkg/dberr"
"server/internal/pkg/errs"
"server/internal/pkg/httputil"
)
type SysPostService struct {
type PostService struct {
store *db.Store
}
func NewSysPostService(store *db.Store) *SysPostService {
return &SysPostService{
func NewPostService(store *db.Store) *PostService {
return &PostService{
store: store,
}
}
func (s *SysPostService) ListPage(ctx context.Context, p *common.Pagination) ([]sqlc.ListPostsRow, int64, error) {
func (s *PostService) List(ctx context.Context, p *common.Pagination) (*common.PageResult[sqlc.ListPostsRow], error) {
params := sqlc.ListPostsParams{
Limit: p.PageSize,
Offset: (p.Page - 1) * p.PageSize,
@@ -29,34 +28,30 @@ func (s *SysPostService) ListPage(ctx context.Context, p *common.Pagination) ([]
total, err := s.store.CountPosts(ctx)
if err != nil {
return nil, 0, err
return nil, err
}
list, err := s.store.ListPosts(ctx, params)
if err != nil {
return nil, 0, err
return nil, err
}
for i := range list {
url := httputil.BuildFileUrl(list[i].Cover)
list[i].Cover = &url
}
return list, total, nil
return &common.PageResult[sqlc.ListPostsRow]{
List: list,
Total: total,
}, nil
}
func (s *SysPostService) FindByID(ctx context.Context, id int32) (*sqlc.GetPostByIdRow, error) {
post, err := s.store.GetPostById(ctx, id)
func (s *PostService) FindByID(ctx context.Context, id int32) (*sqlc.GetPostByIDRow, error) {
post, err := s.store.GetPostByID(ctx, id)
if err != nil {
return nil, dberr.MapNoRows(err, errs.ErrPostNotFound)
}
url := httputil.BuildFileUrl(post.Cover)
post.Cover = &url
return &post, nil
}
func (s *SysPostService) Create(ctx context.Context, req request.CreatePostRequest) (int32, error) {
func (s *PostService) Create(ctx context.Context, req request.CreatePostRequest) (int32, error) {
postID, err := db.WithTxResult(ctx, s.store, func(q *sqlc.Queries) (int32, error) {
params := sqlc.CreatePostParams{
Title: req.Title,
@@ -104,7 +99,7 @@ func (s *SysPostService) Create(ctx context.Context, req request.CreatePostReque
return postID, nil
}
func (s *SysPostService) Update(ctx context.Context, id int32, req request.UpdatePostRequest) error {
func (s *PostService) Update(ctx context.Context, id int32, req request.UpdatePostRequest) error {
return s.store.WithTx(ctx, func(q *sqlc.Queries) error {
params := sqlc.UpdatePostParams{
Title: req.Title,
@@ -160,7 +155,7 @@ func (s *SysPostService) Update(ctx context.Context, id int32, req request.Updat
})
}
func (s *SysPostService) Delete(ctx context.Context, id int32) error {
func (s *PostService) Delete(ctx context.Context, id int32) error {
return s.store.WithTx(ctx, func(q *sqlc.Queries) error {
err := q.DeletePostCategoryByPostID(ctx, id)
if err != nil {

View File

@@ -0,0 +1,254 @@
package admin
import (
"context"
"errors"
"server/internal/db"
"server/internal/db/sqlc"
"server/internal/model/common"
"server/internal/model/enum"
"server/internal/model/request"
"server/internal/pkg/cache"
"server/internal/pkg/cache/cachekey"
"server/internal/pkg/dberr"
"server/internal/pkg/errs"
)
type RoleService struct {
store *db.Store
cache *cache.Caches
}
func NewRoleService(store *db.Store, cache *cache.Caches) *RoleService {
return &RoleService{
store: store,
cache: cache,
}
}
// clearCache 清理所有api权限和用户信息 禁用角色/删除角色需要清理
func (s *RoleService) clearCache(ctx context.Context) error {
if err := s.cache.DelByPrefix(ctx, cachekey.UserApiPermissionsPattern); err != nil {
return err
}
if err := s.cache.DelByPrefix(ctx, cachekey.UserInfoPattern); err != nil {
return err
}
return nil
}
func (s *RoleService) List(ctx context.Context, p *common.Pagination) (*common.PageResult[sqlc.SysRole], error) {
params := sqlc.ListRolesParams{
Limit: p.PageSize,
Offset: (p.Page - 1) * p.PageSize,
}
total, err := s.store.CountRoles(ctx)
if err != nil {
return nil, err
}
list, err := s.store.ListRoles(ctx, params)
if err != nil {
return nil, err
}
return &common.PageResult[sqlc.SysRole]{
List: list,
Total: total,
}, nil
}
func (s *RoleService) ListAll(ctx context.Context) ([]sqlc.SysRole, error) {
return s.store.ListAllRoles(ctx)
}
func (s *RoleService) ListRoleMenus(ctx context.Context, id int32) ([]sqlc.ListRoleMenusRow, error) {
_, err := s.store.GetRoleByID(ctx, id)
if err != nil {
return nil, dberr.MapNoRows(err, errs.ErrRoleNotFound)
}
return s.store.ListRoleMenus(ctx, id)
}
func (s *RoleService) ListRoleApis(ctx context.Context, id int32) ([]sqlc.ListRoleApisRow, error) {
_, err := s.store.GetRoleByID(ctx, id)
if err != nil {
return nil, dberr.MapNoRows(err, errs.ErrRoleNotFound)
}
return s.store.ListRoleApis(ctx, id)
}
func (s *RoleService) Create(ctx context.Context, req request.CreateRoleRequest) error {
params := sqlc.CreateRoleParams{
Name: req.Name,
Code: req.Code,
Status: *req.Status,
}
err := s.store.CreateRole(ctx, params)
if err != nil {
return dberr.MapUniqueViolation(err, dberr.SysRoleCodeKey, errs.ErrCodeAlreadyExists)
}
return nil
}
func (s *RoleService) Update(ctx context.Context, id int32, req request.UpdateRoleRequest) error {
params := sqlc.UpdateRoleParams{
ID: id,
Name: req.Name,
Status: req.Status,
}
rows, err := s.store.UpdateRole(ctx, params)
err = dberr.MapRowsAffected(rows, err, errs.ErrRoleNotFound)
if err != nil {
if errors.Is(err, errs.ErrRoleNotFound) {
}
return err
}
// 清理缓存 无论启用禁用 启用时也需要清理缓存以刷新权限
_ = s.clearCache(ctx)
return nil
}
func (s *RoleService) SetRoleMenus(ctx context.Context, roleID int32, req request.SetRoleMenusRequest) error {
// 先检查角色是否存在
_, err := s.store.GetRoleByID(ctx, roleID)
if err != nil {
return dberr.MapNoRows(err, errs.ErrRoleNotFound)
}
err = s.store.WithTx(ctx, func(q *sqlc.Queries) error {
// 1. 先删除所有关联表数据
if err = q.DeleteRolePermissionsByType(ctx, sqlc.DeleteRolePermissionsByTypeParams{
RoleID: roleID,
Type: int16(enum.PermissionTypeMenu),
}); err != nil {
return err
}
// 2. 查出所有权限id并组装数据
permissionIds, err := q.ListPermissionIDsByMenuIDs(ctx, req.MenuIDs)
if err != nil {
return err
}
params := make([]sqlc.CreateRolePermissionParams, 0, len(permissionIds))
for _, id := range permissionIds {
params = append(params, sqlc.CreateRolePermissionParams{
RoleID: roleID,
PermissionID: id,
})
}
// 批量插入
_, err = q.CreateRolePermission(ctx, params)
if err != nil {
return err
}
return nil
})
if err != nil {
return err
}
// 清理缓存 这里只用清理用户信息
_ = s.cache.DelByPrefix(ctx, cachekey.UserInfoPattern)
return nil
}
func (s *RoleService) SetRoleApis(ctx context.Context, roleID int32, req request.SetRoleApisRequest) error {
_, err := s.store.GetRoleByID(ctx, roleID)
if err != nil {
return dberr.MapNoRows(err, errs.ErrRoleNotFound)
}
err = s.store.WithTx(ctx, func(q *sqlc.Queries) error {
// 先删除所有旧权限数据
if err = q.DeleteRolePermissionsByType(ctx, sqlc.DeleteRolePermissionsByTypeParams{
RoleID: roleID,
Type: int16(enum.PermissionTypeApi),
}); err != nil {
return err
}
// 查出数据并组装
permissionIds, err := q.ListPermissionIDsByApiIDs(ctx, req.ApiIDs)
if err != nil {
return err
}
params := make([]sqlc.CreateRolePermissionParams, 0, len(permissionIds))
for _, id := range permissionIds {
params = append(params, sqlc.CreateRolePermissionParams{
RoleID: roleID,
PermissionID: id,
})
}
// 批量插入
_, err = q.CreateRolePermission(ctx, params)
if err != nil {
return err
}
return nil
})
if err != nil {
return err
}
// 清理缓存 这里只用清理接口权限
_ = s.cache.DelByPrefix(ctx, cachekey.UserApiPermissionsPattern)
return nil
}
func (s *RoleService) Delete(ctx context.Context, id int32) error {
err := s.store.WithTx(ctx, func(q *sqlc.Queries) error {
// 1.删除角色关联权限
err := q.DeleteRolePermissionsByRoleID(ctx, id)
if err != nil {
return err
}
// 2. 根据角色id删除用户关联的角色
err = q.DeleteUserRoleByRoleID(ctx, id)
if err != nil {
return err
}
// 3. 删除角色信息
rows, err := q.DeleteRole(ctx, id)
err = dberr.MapRowsAffected(rows, err, errs.ErrRoleNotFound)
if err != nil {
// 如果是数据库不存在这条数据 此时也执行清理
if errors.Is(err, errs.ErrRoleNotFound) {
}
return err
}
return nil
})
if err != nil {
return err
}
// 清理缓存
_ = s.clearCache(ctx)
return nil
}

View File

@@ -1,4 +1,4 @@
package service
package admin
import (
"context"
@@ -20,7 +20,7 @@ func NewTagService(store *db.Store) *TagService {
}
}
func (s *TagService) ListPage(ctx context.Context, p *common.Pagination) ([]sqlc.Tag, int64, error) {
func (s *TagService) List(ctx context.Context, p *common.Pagination) (*common.PageResult[sqlc.Tag], error) {
params := sqlc.ListTagsParams{
Limit: p.PageSize,
Offset: (p.Page - 1) * p.PageSize,
@@ -28,15 +28,18 @@ func (s *TagService) ListPage(ctx context.Context, p *common.Pagination) ([]sqlc
total, err := s.store.CountTags(ctx)
if err != nil {
return nil, 0, err
return nil, err
}
list, err := s.store.ListTags(ctx, params)
if err != nil {
return nil, 0, err
return nil, err
}
return list, total, nil
return &common.PageResult[sqlc.Tag]{
List: list,
Total: total,
}, nil
}
func (s *TagService) ListAll(ctx context.Context) ([]sqlc.Tag, error) {

View File

@@ -1,4 +1,4 @@
package service
package admin
import (
"context"
@@ -6,25 +6,25 @@ import (
"server/internal/db"
"server/internal/db/sqlc"
"server/internal/middleware"
"server/internal/model/common"
"server/internal/model/request"
"server/internal/model/response"
"server/internal/pkg/cache"
"server/internal/pkg/cache/cachekey"
"server/internal/pkg/dberr"
"server/internal/pkg/errs"
"server/internal/pkg/httputil"
"golang.org/x/sync/errgroup"
)
type SysUserService struct {
type UserService struct {
store *db.Store
jwt *middleware.JWTMiddleware
cache *cache.Caches
}
func NewSysUserService(store *db.Store, jwt *middleware.JWTMiddleware, cache *cache.Caches) *SysUserService {
return &SysUserService{
func NewUserService(store *db.Store, jwt *middleware.JWTMiddleware, cache *cache.Caches) *UserService {
return &UserService{
store: store,
jwt: jwt,
cache: cache,
@@ -32,7 +32,7 @@ func NewSysUserService(store *db.Store, jwt *middleware.JWTMiddleware, cache *ca
}
// clearUserCache
func (s *SysUserService) clearUserCache(ctx context.Context, id int32) error {
func (s *UserService) clearUserCache(ctx context.Context, id int32) error {
if err := s.cache.Del(ctx, cachekey.UserApiPermissions(id)); err != nil {
return err
}
@@ -45,7 +45,7 @@ func (s *SysUserService) clearUserCache(ctx context.Context, id int32) error {
}
// clearRefreshToken
func (s *SysUserService) clearRefreshToken(ctx context.Context, id int32) error {
func (s *UserService) clearRefreshToken(ctx context.Context, id int32) error {
keys, err := s.cache.SMembers(ctx, cachekey.AuthRefreshUser(id))
if err != nil {
@@ -64,19 +64,19 @@ func (s *SysUserService) clearRefreshToken(ctx context.Context, id int32) error
return err
}
func (s *SysUserService) GetUserInfo(ctx context.Context, id int32, isAdmin bool) (*response.SysUserInfo, error) {
return cache.GetOrSetJSON[*response.SysUserInfo](ctx, s.cache, cachekey.UserInfo(id), 0, func() (*response.SysUserInfo, error) {
func (s *UserService) GetCurrentUser(ctx context.Context, id int32, isAdmin bool) (*response.UserInfo, error) {
return cache.GetOrSetJSON[*response.UserInfo](ctx, s.cache, cachekey.UserInfo(id), 0, func() (*response.UserInfo, error) {
g, ctx := errgroup.WithContext(ctx)
var (
user sqlc.GetSysUserByIDRow
user sqlc.GetUserByIDRow
roles []sqlc.SysRole
menus []sqlc.SysMenu
permissions []*string
)
g.Go(func() error {
u, err := s.store.GetSysUserByID(ctx, id)
u, err := s.store.GetUserByID(ctx, id)
if err != nil {
return dberr.MapNoRows(err, errs.ErrUserNotFound)
}
@@ -86,7 +86,7 @@ func (s *SysUserService) GetUserInfo(ctx context.Context, id int32, isAdmin bool
})
g.Go(func() error {
r, err := s.store.GetSysUserRoles(ctx, id)
r, err := s.store.ListUserRoles(ctx, id)
if err != nil {
return err
}
@@ -101,9 +101,9 @@ func (s *SysUserService) GetUserInfo(ctx context.Context, id int32, isAdmin bool
)
if isAdmin {
p, err = s.store.GetSysAdminPermissions(ctx)
p, err = s.store.ListAdminPermissionCodes(ctx)
} else {
p, err = s.store.GetSysUserPermissions(ctx, id)
p, err = s.store.ListUserPermissionCodes(ctx, id)
}
if err != nil {
@@ -121,9 +121,9 @@ func (s *SysUserService) GetUserInfo(ctx context.Context, id int32, isAdmin bool
err error
)
if isAdmin {
m, err = s.store.GetSysAdminMenus(ctx)
m, err = s.store.ListAdminMenus(ctx)
} else {
m, err = s.store.GetSysUserMenus(ctx, id)
m, err = s.store.ListUserMenus(ctx, id)
}
if err != nil {
return err
@@ -142,56 +142,53 @@ func (s *SysUserService) GetUserInfo(ctx context.Context, id int32, isAdmin bool
}
// 处理角色
userInfo := response.NewSysUserInfo(user, roles, menus, permissions)
userInfo := response.NewUserInfo(user, roles, menus, permissions)
return userInfo, nil
})
}
func (s *SysUserService) ListPage(ctx context.Context, p request.SearchSysUserParams) ([]sqlc.ListSysUsersRow, int64, error) {
params := sqlc.ListSysUsersParams{
func (s *UserService) List(ctx context.Context, p request.SearchUserParams) (*common.PageResult[sqlc.ListUsersRow], error) {
params := sqlc.ListUsersParams{
Limit: p.PageSize,
Offset: (p.Page - 1) * p.PageSize,
Username: p.Username,
}
total, err := s.store.CountSysUsers(ctx, p.Username)
total, err := s.store.CountUsers(ctx, p.Username)
if err != nil {
return nil, 0, err
return nil, err
}
users, err := s.store.ListSysUsers(ctx, params)
list, err := s.store.ListUsers(ctx, params)
if err != nil {
return nil, 0, err
return nil, err
}
// 处理每个用户的头像URL
for i := range users {
url := httputil.BuildFileUrl(users[i].AvatarUrl)
users[i].AvatarUrl = &url
}
return users, total, nil
return &common.PageResult[sqlc.ListUsersRow]{
List: list,
Total: total,
}, nil
}
func (s *SysUserService) GetRoles(ctx context.Context, id int32) ([]sqlc.SysRole, error) {
func (s *UserService) ListRoles(ctx context.Context, id int32) ([]sqlc.SysRole, error) {
// 先查询用户是否存在
_, err := s.store.GetSysUserByID(ctx, id)
_, err := s.store.GetUserByID(ctx, id)
if err != nil {
return nil, dberr.MapNoRows(err, errs.ErrUserNotFound)
}
return s.store.GetSysUserRoles(ctx, id)
return s.store.ListUserRoles(ctx, id)
}
func (s *SysUserService) Create(ctx context.Context, req request.CreateSysUserRequest) error {
func (s *UserService) Create(ctx context.Context, req request.CreateUserRequest) error {
passwordHash, err := generatePasswordHash(req.Password)
if err != nil {
return err
}
user := sqlc.CreateSysUserParams{
user := sqlc.CreateUserParams{
Account: req.Account,
Username: req.Username,
PasswordHash: passwordHash,
@@ -199,15 +196,15 @@ func (s *SysUserService) Create(ctx context.Context, req request.CreateSysUserRe
Status: *req.Status,
}
if err = s.store.CreateSysUser(ctx, user); err != nil {
if err = s.store.CreateUser(ctx, user); err != nil {
return dberr.MapUniqueViolation(err, dberr.SysUserAccountKey, errs.ErrAccountAlreadyExists)
}
return nil
}
func (s *SysUserService) Update(ctx context.Context, id int32, req request.UpdateSysUserRequest) error {
user := sqlc.UpdateSysUserParams{
func (s *UserService) Update(ctx context.Context, id int32, req request.UpdateUserRequest) error {
user := sqlc.UpdateUserParams{
Username: req.Username,
ID: id,
Status: req.Status,
@@ -220,7 +217,7 @@ func (s *SysUserService) Update(ctx context.Context, id int32, req request.Updat
}
}
rows, err := s.store.UpdateSysUser(ctx, user)
rows, err := s.store.UpdateUser(ctx, user)
if err = dberr.MapRowsAffected(rows, err, errs.ErrUserNotFound); err != nil {
return err
}
@@ -236,30 +233,30 @@ func (s *SysUserService) Update(ctx context.Context, id int32, req request.Updat
return nil
}
func (s *SysUserService) SetRoles(ctx context.Context, userID int32, req request.SetSysUserRolesRequest) error {
func (s *UserService) SetRoles(ctx context.Context, userID int32, req request.SetUserRolesRequest) error {
// 先查询用户是否存在
_, err := s.store.GetSysUserByID(ctx, userID)
_, err := s.store.GetUserByID(ctx, userID)
if err != nil {
return dberr.MapNoRows(err, errs.ErrUserNotFound)
}
err = s.store.WithTx(ctx, func(q *sqlc.Queries) error {
// 1. 先删除关联数据
if err = q.ClearSysUserRoles(ctx, userID); err != nil {
if err = q.ClearUserRoles(ctx, userID); err != nil {
return err
}
var params []sqlc.CreateSysUserRoleParams
var params []sqlc.CreateUserRoleParams
for _, roleID := range req.RoleIDs {
params = append(params, sqlc.CreateSysUserRoleParams{
params = append(params, sqlc.CreateUserRoleParams{
UserID: userID,
RoleID: roleID,
})
}
// 2. 关联用户角色数据
_, err = q.CreateSysUserRole(ctx, params)
_, err = q.CreateUserRole(ctx, params)
if err != nil {
return err
}
@@ -277,18 +274,18 @@ func (s *SysUserService) SetRoles(ctx context.Context, userID int32, req request
return nil
}
func (s *SysUserService) UpdatePassword(ctx context.Context, id int32, req request.UpdateSysUserPassword) error {
func (s *UserService) UpdatePassword(ctx context.Context, id int32, req request.UpdateUserPassword) error {
passwordHash, err := generatePasswordHash(req.Password)
if err != nil {
return err
}
params := sqlc.UpdateSysUserPasswordParams{
params := sqlc.UpdateUserPasswordParams{
ID: id,
PasswordHash: passwordHash,
}
rows, err := s.store.UpdateSysUserPassword(ctx, params)
rows, err := s.store.UpdateUserPassword(ctx, params)
err = dberr.MapRowsAffected(rows, err, errs.ErrUserNotFound)
if err != nil {
return err
@@ -300,20 +297,22 @@ func (s *SysUserService) UpdatePassword(ctx context.Context, id int32, req reque
return nil
}
func (s *SysUserService) Delete(ctx context.Context, id int32) error {
if id == 1 {
func (s *UserService) Delete(ctx context.Context, id int32) error {
isAdmin := middleware.UserIsAdmin(id)
if isAdmin {
return errs.ErrCannotDeleteSuperAdmin
}
err := s.store.WithTx(ctx, func(q *sqlc.Queries) error {
// 清理用户角色关联数据
err := q.ClearSysUserRoles(ctx, id)
err := q.ClearUserRoles(ctx, id)
if err != nil {
return err
}
// 删除用户
rows, err := q.DeleteSysUser(ctx, id)
rows, err := q.DeleteUser(ctx, id)
return dberr.MapRowsAffected(rows, err, errs.ErrUserNotFound)
})

View File

@@ -1,21 +1,15 @@
package service
import (
"server/internal/service/admin"
"server/internal/service/web"
"go.uber.org/fx"
)
var Module = fx.Module("services",
fx.Provide(
NewSysUserService,
NewSysRoleService,
NewSysMenuService,
NewSysApiService,
NewSysFileService,
NewSysPostService,
NewAuthService,
NewTagService,
NewPostService,
NewCategoryService,
fx.Options(
admin.Module,
web.Module,
),
)

View File

@@ -1,251 +0,0 @@
package service
import (
"context"
"errors"
"server/internal/db"
"server/internal/db/sqlc"
"server/internal/model/common"
"server/internal/model/enum"
"server/internal/model/request"
"server/internal/pkg/cache"
"server/internal/pkg/cache/cachekey"
"server/internal/pkg/dberr"
"server/internal/pkg/errs"
)
type SysRoleService struct {
store *db.Store
cache *cache.Caches
}
func NewSysRoleService(store *db.Store, cache *cache.Caches) *SysRoleService {
return &SysRoleService{
store: store,
cache: cache,
}
}
// clearCache 清理所有api权限和用户信息 禁用角色/删除角色需要清理
func (s *SysRoleService) clearCache(ctx context.Context) error {
if err := s.cache.DelByPrefix(ctx, cachekey.UserApiPermissionsPattern); err != nil {
return err
}
if err := s.cache.DelByPrefix(ctx, cachekey.UserInfoPattern); err != nil {
return err
}
return nil
}
func (s *SysRoleService) ListPage(ctx context.Context, p *common.Pagination) ([]sqlc.SysRole, int64, error) {
params := sqlc.ListSysRolesParams{
Limit: p.PageSize,
Offset: (p.Page - 1) * p.PageSize,
}
total, err := s.store.CountSysRoles(ctx)
if err != nil {
return nil, 0, err
}
list, err := s.store.ListSysRoles(ctx, params)
if err != nil {
return nil, 0, err
}
return list, total, nil
}
func (s *SysRoleService) GetRoles(ctx context.Context) ([]sqlc.SysRole, error) {
return s.store.GetAllSysRoles(ctx)
}
func (s *SysRoleService) GetRoleMenus(ctx context.Context, id int32) ([]sqlc.GetSysRoleMenusRow, error) {
_, err := s.store.GetSysRoleByID(ctx, id)
if err != nil {
return nil, dberr.MapNoRows(err, errs.ErrSysRoleNotFound)
}
return s.store.GetSysRoleMenus(ctx, id)
}
func (s *SysRoleService) GetRoleApis(ctx context.Context, id int32) ([]sqlc.GetSysRoleApisRow, error) {
_, err := s.store.GetSysRoleByID(ctx, id)
if err != nil {
return nil, dberr.MapNoRows(err, errs.ErrSysRoleNotFound)
}
return s.store.GetSysRoleApis(ctx, id)
}
func (s *SysRoleService) Create(ctx context.Context, req request.CreateSysRoleRequest) error {
params := sqlc.CreateSysRoleParams{
Name: req.Name,
Code: req.Code,
Status: *req.Status,
}
err := s.store.CreateSysRole(ctx, params)
if err != nil {
return dberr.MapUniqueViolation(err, dberr.SysRoleCodeKey, errs.ErrCodeAlreadyExists)
}
return nil
}
func (s *SysRoleService) Update(ctx context.Context, id int32, req request.UpdateSysRoleRequest) error {
params := sqlc.UpdateSysRoleParams{
ID: id,
Name: req.Name,
Status: req.Status,
}
rows, err := s.store.UpdateSysRole(ctx, params)
err = dberr.MapRowsAffected(rows, err, errs.ErrSysRoleNotFound)
if err != nil {
if errors.Is(err, errs.ErrSysRoleNotFound) {
}
return err
}
// 清理缓存 无论启用禁用 启用时也需要清理缓存以刷新权限
_ = s.clearCache(ctx)
return nil
}
func (s *SysRoleService) SetRoleMenus(ctx context.Context, roleID int32, req request.SetSysRoleMenusRequest) error {
// 先检查角色是否存在
_, err := s.store.GetSysRoleByID(ctx, roleID)
if err != nil {
return dberr.MapNoRows(err, errs.ErrSysRoleNotFound)
}
err = s.store.WithTx(ctx, func(q *sqlc.Queries) error {
// 1. 先删除所有关联表数据
if err = q.DeleteSysRolePermissionByType(ctx, sqlc.DeleteSysRolePermissionByTypeParams{
RoleID: roleID,
Type: int16(enum.PermissionTypeMenu),
}); err != nil {
return err
}
// 2. 查出所有权限id并组装数据
permissionIds, err := q.GetSysPermissionIdsByMenuIDs(ctx, req.MenuIDs)
if err != nil {
return err
}
params := make([]sqlc.CreateSysRolePermissionParams, 0, len(permissionIds))
for _, id := range permissionIds {
params = append(params, sqlc.CreateSysRolePermissionParams{
RoleID: roleID,
PermissionID: id,
})
}
// 批量插入
_, err = q.CreateSysRolePermission(ctx, params)
if err != nil {
return err
}
return nil
})
if err != nil {
return err
}
// 清理缓存 这里只用清理用户信息
_ = s.cache.DelByPrefix(ctx, cachekey.UserInfoPattern)
return nil
}
func (s *SysRoleService) SetRoleApis(ctx context.Context, roleID int32, req request.SetSysRoleApisRequest) error {
_, err := s.store.GetSysRoleByID(ctx, roleID)
if err != nil {
return dberr.MapNoRows(err, errs.ErrSysRoleNotFound)
}
err = s.store.WithTx(ctx, func(q *sqlc.Queries) error {
// 先删除所有旧权限数据
if err = q.DeleteSysRolePermissionByType(ctx, sqlc.DeleteSysRolePermissionByTypeParams{
RoleID: roleID,
Type: int16(enum.PermissionTypeApi),
}); err != nil {
return err
}
// 查出数据并组装
permissionIds, err := q.GetSysPermissionIdsByApiIDs(ctx, req.ApiIDs)
if err != nil {
return err
}
params := make([]sqlc.CreateSysRolePermissionParams, 0, len(permissionIds))
for _, id := range permissionIds {
params = append(params, sqlc.CreateSysRolePermissionParams{
RoleID: roleID,
PermissionID: id,
})
}
// 批量插入
_, err = q.CreateSysRolePermission(ctx, params)
if err != nil {
return err
}
return nil
})
if err != nil {
return err
}
// 清理缓存 这里只用清理接口权限
_ = s.cache.DelByPrefix(ctx, cachekey.UserApiPermissionsPattern)
return nil
}
func (s *SysRoleService) Delete(ctx context.Context, id int32) error {
err := s.store.WithTx(ctx, func(q *sqlc.Queries) error {
// 1.删除角色关联权限
err := q.DeleteSysRolePermissionByRoleID(ctx, id)
if err != nil {
return err
}
// 2. 根据角色id删除用户关联的角色
err = q.DeleteSysUserRoleByRoleID(ctx, id)
if err != nil {
return err
}
// 3. 删除角色信息
rows, err := q.DeleteSysRole(ctx, id)
err = dberr.MapRowsAffected(rows, err, errs.ErrSysRoleNotFound)
if err != nil {
// 如果是数据库不存在这条数据 此时也执行清理
if errors.Is(err, errs.ErrSysRoleNotFound) {
}
return err
}
return nil
})
if err != nil {
return err
}
// 清理缓存
_ = s.clearCache(ctx)
return nil
}

View File

@@ -0,0 +1,11 @@
package web
import (
"go.uber.org/fx"
)
var Module = fx.Module("web-services",
fx.Provide(
NewPostService,
),
)

View File

@@ -1,4 +1,4 @@
package service
package web
import (
"context"
@@ -9,7 +9,6 @@ import (
"server/internal/model/response"
"server/internal/pkg/dberr"
"server/internal/pkg/errs"
"server/internal/pkg/httputil"
)
type PostService struct {
@@ -22,7 +21,7 @@ func NewPostService(store *db.Store) *PostService {
}
}
func (s *PostService) ListPage(ctx context.Context, p *common.Pagination) ([]sqlc.ListPublishedPostsRow, int64, error) {
func (s *PostService) ListPage(ctx context.Context, p *common.Pagination) (*common.PageResult[sqlc.ListPublishedPostsRow], error) {
params := sqlc.ListPublishedPostsParams{
Limit: p.PageSize,
Offset: (p.Page - 1) * p.PageSize,
@@ -30,20 +29,18 @@ func (s *PostService) ListPage(ctx context.Context, p *common.Pagination) ([]sql
total, err := s.store.CountPublishedPosts(ctx)
if err != nil {
return nil, 0, err
return nil, err
}
list, err := s.store.ListPublishedPosts(ctx, params)
if err != nil {
return nil, 0, err
return nil, err
}
for i := range list {
url := httputil.BuildFileUrl(list[i].Cover)
list[i].Cover = &url
}
return list, total, nil
return &common.PageResult[sqlc.ListPublishedPostsRow]{
List: list,
Total: total,
}, nil
}
func (s *PostService) GetPost(ctx context.Context, slug string, ip netip.Addr) (*sqlc.GetPublicPostBySlugRow, error) {

View File

@@ -1,28 +0,0 @@
package utils
import (
"net"
"net/http"
"strings"
)
func ClientIP(r *http.Request) string {
if xff := r.Header.Get("X-Forwarded-For"); xff != "" {
parts := strings.Split(xff, ",")
if len(parts) > 0 {
return strings.TrimSpace(parts[0])
}
}
if ip := r.Header.Get("X-Real-IP"); ip != "" {
return ip
}
// RemoteAddr: IP:port
host, _, err := net.SplitHostPort(r.RemoteAddr)
if err == nil {
return host
}
return r.RemoteAddr
}

33
scripts/Dockerfile Normal file
View File

@@ -0,0 +1,33 @@
FROM golang:1.24-alpine AS builder
# 安装 UPX
RUN apk add --no-cache upx
WORKDIR /app
# 复制依赖文件
COPY go.mod go.sum ./
RUN go mod download
# 复制代码
COPY . .
# 构建静态链接的二进制文件
RUN go build -ldflags="-s -w" -o server ./cmd \
&& upx -9 server
# alpine:3.19 scratch 最小体积
FROM scratch
WORKDIR /app
# 复制二进制文件
COPY --from=builder /app/server .
# 环境变量
ENV APP_ENV=production
EXPOSE 8080
# 运行服务
CMD ["./server"]

46
scripts/deploy.sh Executable file
View File

@@ -0,0 +1,46 @@
#!/bin/bash
set -euo pipefail
PROJECT_ROOT=$(cd -- "$(dirname "${BASH_SOURCE[0]}")/.." &> /dev/null && pwd)
REMOTE_SERVER="01"
REMOTE_DIR="/srv/docker/go-server"
IMAGE_NAME="go-server"
CONTAINER_NAME="go-server"
IMAGE_TAG="latest"
IMAGE_FILE="${IMAGE_NAME}-${IMAGE_TAG}.tar"
DOCKER_NETWORK="docker_app-bridge"
cd "$PROJECT_ROOT"
docker build -f ./scripts/Dockerfile --platform linux/amd64 -t "${IMAGE_NAME}":"${IMAGE_TAG}" .
docker save -o "${IMAGE_FILE}" "${IMAGE_NAME}":"${IMAGE_TAG}"
scp ${IMAGE_FILE} ${REMOTE_SERVER}:${REMOTE_DIR}
ssh "${REMOTE_SERVER}" << EOF
set -euo pipefail
cd "${REMOTE_DIR}"
docker stop "${CONTAINER_NAME}" || true
docker rm "${CONTAINER_NAME}" || true
docker rmi "${IMAGE_NAME}":"${IMAGE_TAG}" || true
docker load -i "${IMAGE_FILE}"
docker run -dit \
--name "${CONTAINER_NAME}" \
--restart unless-stopped \
-v "${REMOTE_DIR}"/production.yaml:/app/production.yaml:ro \
-v "${REMOTE_DIR}"/static:/app/uploads \
-v "${REMOTE_DIR}"/logs:/app/logs \
--network "${DOCKER_NETWORK}" \
${IMAGE_NAME}:${IMAGE_TAG}
rm -f "${IMAGE_FILE}"
EOF
rm -f "${IMAGE_FILE}"
docker rmi "${IMAGE_NAME}":"${IMAGE_TAG}" || true
echo "部署完成"