feat: 优化项目目录结构

This commit is contained in:
2025-12-12 17:25:26 +08:00
parent ae627d0496
commit b89f83291e
235 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
export * as user from './user/index';
export * as web from './web/index';

View File

@@ -0,0 +1,20 @@
import { User } from "@/lib/types/user";
import fetcher from "../../fetcher";
interface createUserParams {
username: string | null;
nickname: string | null;
email: string | null;
phone: string | null;
password: string | null;
}
export async function create(data: createUserParams) {
return fetcher<User>("/api/admin/user", {
method: "POST",
body: JSON.stringify(data),
headers: {
"Content-Type": "application/json",
},
});
}

View File

@@ -0,0 +1,6 @@
import { User } from "@/lib/types/user";
import fetcher from "../../fetcher";
export function get(userId: string) {
return fetcher<User>(`/api/admin/user/${userId}`);
}

View File

@@ -0,0 +1,6 @@
export * from './list';
export * from './get';
export * from './create';
export * from './update';
export * from './set-password';
export * from './remove';

View File

@@ -0,0 +1,22 @@
import { User } from "@/lib/types/user"
import fetcher from "../../fetcher"
export interface UserListParams {
page?: number
pageSize?: number
}
export interface UserListResponse {
items: User[],
total: number
page: number
pageSize: number
}
export function list(params?: UserListParams): Promise<UserListResponse> {
const searchParams = new URLSearchParams()
if (params?.page) searchParams.set('page', params.page.toString())
if (params?.pageSize) searchParams.set('pageSize', params.pageSize.toString())
return fetcher<UserListResponse>('/api/admin/user')
}

View File

@@ -0,0 +1,7 @@
import fetcher from "../../fetcher";
export async function remove(userId: string, soft: boolean) {
return fetcher(`/api/admin/user/${userId}?soft=${soft}`, {
method: 'DELETE',
})
}

View File

@@ -0,0 +1,10 @@
import fetcher from "../../fetcher";
export async function setPassword(userId: string, password: string) {
return fetcher(`/api/admin/user/${userId}/password`, {
method: 'POST',
body: JSON.stringify({
password,
}),
})
}

View File

@@ -0,0 +1,16 @@
import { User } from "@/lib/types/user";
import fetcher from "../../fetcher";
export type updateUser = {
username: string ;
nickname: string ;
email: string | null;
phone: string | null;
}
export async function update(userId: string, user: updateUser) {
return fetcher<User>(`/api/admin/user/${userId}`, {
body: JSON.stringify(user),
method: "PUT",
});
}

View File

@@ -0,0 +1,14 @@
import fetcher from "@/lib/api/fetcher";
type CreateBlogParams = {
title: string;
description: string;
contentUrl: string;
}
export async function create(data: CreateBlogParams) {
return fetcher('/api/admin/web/blog', {
method: 'POST',
body: JSON.stringify(data)
})
}

View File

@@ -0,0 +1,6 @@
import fetcher from "@/lib/api/fetcher";
import { Blog } from "@/lib/types/blog";
export async function get(id: string) {
return fetcher<Blog>(`/api/admin/web/blog/${id}`)
}

View File

@@ -0,0 +1,6 @@
export * from './create';
export * from './remove';
export * from './list';
export * from './update';
export * from './get';
export * from './setPassword';

View File

@@ -0,0 +1,6 @@
import fetcher from "@/lib/api/fetcher";
import { Blog } from "@/lib/types/blog";
export async function list() {
return fetcher<Blog[]>('/api/admin/web/blog')
}

View File

@@ -0,0 +1,7 @@
import fetcher from "@/lib/api/fetcher";
export async function remove(id: string) {
return fetcher(`/api/admin/web/blog/${id}`, {
method: 'DELETE',
})
}

View File

@@ -0,0 +1,10 @@
import fetcher from "@/lib/api/fetcher";
export async function setPassword(id: string, password: string) {
return fetcher<boolean>(`/api/admin/web/blog/${id}/password`, {
method: 'POST',
body: JSON.stringify({
password,
})
})
}

View File

@@ -0,0 +1,16 @@
import fetcher from "@/lib/api/fetcher";
import { BlogPermission } from "@/lib/types/Blog.Permission.enum";
type UpdateBlogParams = {
title: string;
description: string;
contentUrl: string;
permissions: BlogPermission[],
}
export async function update(id: string, data: UpdateBlogParams) {
return fetcher(`/api/admin/web/blog/${id}`, {
method: 'PUT',
body: JSON.stringify(data)
})
}

View File

@@ -0,0 +1,2 @@
export * as blog from './blog/index';
export * as resource from './resource/index';

View File

@@ -0,0 +1,19 @@
import fetcher from "@/lib/api/fetcher";
type CreateResourceParams = {
title: string;
description: string;
imageUrl: string;
link: string;
tags: {
name: string;
type: string;
}[];
}
export async function create(data: CreateResourceParams) {
return fetcher('/api/admin/web/resource', {
method: 'POST',
body: JSON.stringify(data)
})
}

View File

@@ -0,0 +1,6 @@
import fetcher from "@/lib/api/fetcher";
import { Resource } from "@/lib/types/resource";
export async function get(id: string) {
return fetcher<Resource>(`/api/admin/web/resource/${id}`)
}

View File

@@ -0,0 +1,5 @@
export * from './create';
export * from './remove';
export * from './list';
export * from './update';
export * from './get';

View File

@@ -0,0 +1,6 @@
import fetcher from "@/lib/api/fetcher";
import { Resource } from "@/lib/types/resource";
export async function list() {
return fetcher<Resource[]>('/api/admin/web/resource')
}

View File

@@ -0,0 +1,7 @@
import fetcher from "@/lib/api/fetcher";
export async function remove(id: string) {
return fetcher(`/api/admin/web/resource/${id}`, {
method: 'DELETE',
})
}

View File

@@ -0,0 +1,19 @@
import fetcher from "@/lib/api/fetcher";
type UpdateResourceParams = {
title: string;
description: string;
imageUrl: string;
link: string;
tags: {
name: string;
type: string;
}[];
}
export async function update(id: string, data: UpdateResourceParams) {
return fetcher(`/api/admin/web/resource/${id}`, {
method: 'PUT',
body: JSON.stringify(data)
})
}

View File

@@ -0,0 +1,2 @@
export * from './login';
export * from './logout';

View File

@@ -0,0 +1,53 @@
import fetcher, { ApiError } from "../fetcher"
interface LoginParams {
type: 'password' | 'phone' | 'email';
account?: string;
password?: string;
phone?: string;
email?: string;
code?: string;
}
export const login = async (data: LoginParams): Promise<{ token: string }> => {
if (data.type === 'password') {
if (!data.account || !data.password) {
throw new ApiError(400, '请输入账户和密码')
}
if (data.account.length < 1 || data.account.length > 254) {
throw new ApiError(400, '请输入正确的账户')
}
if (data.password.length < 6 || data.password.length > 32) {
throw new ApiError(400, '请输入正确的密码')
}
} else if (data.type === 'phone') {
if (!data.phone || !data.code) {
throw new ApiError(400, '请输入手机号和验证码')
}
if (data.phone.length !== 11) {
throw new ApiError(400, '请输入正确的手机号')
}
if (data.code.length != 6) {
throw new ApiError(400, '请输入正确的验证码')
}
} else if (data.type === 'email') {
if (!data.email || !data.code) {
throw new ApiError(400, '请输入邮箱和验证码')
}
if (data.email.length < 1 || data.email.length > 254) {
throw new ApiError(400, '请输入正确的邮箱')
}
if (data.code.length != 6) {
throw new ApiError(400, '请输入正确的验证码')
}
} else {
throw new ApiError(400, '登录方式异常')
}
return fetcher<{
token: string;
}>('/api/auth/login', {
method: 'POST',
body: JSON.stringify(data),
})
}

View File

@@ -0,0 +1,5 @@
import fetcher from "../fetcher";
export async function logout() {
return fetcher('/api/auth/logout', { method: 'POST' });
}

View File

@@ -0,0 +1,12 @@
import { BlogComment } from "@/lib/types/blogComment";
import fetcher from "../fetcher";
export async function createComment(blogId: string, content: string, parentId?: string) {
return fetcher<BlogComment>(`/api/blog/${blogId}/comment`, {
method: 'POST',
body: JSON.stringify({
content,
parentId: parentId || null,
}),
});
}

View File

@@ -0,0 +1,13 @@
import fetcher from "../fetcher";
export async function get(id: string, option: {
password?: string;
} = {}) {
const { password } = option;
return fetcher<{
id: string;
title: string;
createdAt: string;
content: string;
}>(`/api/blog/${id}` + (password ? `?p=${password}` : ''));
}

View File

@@ -0,0 +1,6 @@
import { BlogComment } from "@/lib/types/blogComment";
import fetcher from "../fetcher";
export async function getComments(blogId: string) {
return fetcher<BlogComment[]>(`/api/blog/${blogId}/comments`, { method: 'GET' });
}

View File

@@ -0,0 +1,4 @@
export * from './list';
export * from './get';
export * from './getComments';
export * from './createComment';

View File

@@ -0,0 +1,6 @@
import { Blog } from "@/lib/types/blog";
import fetcher from "../fetcher";
export async function list() {
return fetcher<Blog[]>('/api/blog');
}

View File

@@ -0,0 +1,39 @@
export interface StanderResponse<T> {
statusCode: number;
message: string;
data?: T;
}
export class ApiError extends Error {
constructor(
public statusCode: number,
public message: string,
public data?: unknown,
) {
super(message);
this.name = 'ApiError';
}
}
const fetcher = async<T>(url: string, options?: RequestInit): Promise<T> => {
const res = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
// 自动带上 token
...(typeof window !== 'undefined' && localStorage.getItem('token')
? { Authorization: `Bearer ${localStorage.getItem('token')}` }
: {}),
},
...options,
});
const result = await res.json();
if (result.statusCode !== 200) {
throw new ApiError(result.statusCode, result.message, result.data);
}
return result.data as T;
}
export default fetcher

View File

@@ -0,0 +1,7 @@
export * as authApi from './auth/index';
export * as verificationApi from './verification/index';
export * as AdminApi from './admin/index';
export * as ResourceApi from './resource/index';
export * as BlogApi from './blog/index';
export * as UserApi from './user/index';
export * as OssApi from './oss/index';

View File

@@ -0,0 +1,13 @@
import fetcher from "../fetcher";
export interface StsToken {
AccessKeyId: string;
AccessKeySecret: string;
Expiration: string;// ISO 8601 格式
SecurityToken: string;
userId: string;
}
export async function getStsToken() {
return fetcher<StsToken>('/api/oss/sts', { method: 'GET' });
}

View File

@@ -0,0 +1 @@
export * from './list';

View File

@@ -0,0 +1,6 @@
import { Resource } from "@/lib/types/resource";
import fetcher from "../fetcher";
export async function list() {
return fetcher<Resource[]>('/api/resource');
}

View File

@@ -0,0 +1,2 @@
export * from './me';
export * from './updatePassword';

View File

@@ -0,0 +1,8 @@
import { User } from "@/lib/types/user";
import fetcher from "../fetcher";
export async function me() {
return fetcher<User>('/api/user/me');
}
export const USER_ME_CACHE_KEY = 'user-me-cache';

View File

@@ -0,0 +1,10 @@
import fetcher from "../fetcher";
export async function updatePassword(password: string) {
return fetcher(`/api/user/password`, {
method: 'PUT',
body: JSON.stringify({
password: password,
}),
})
}

View File

@@ -0,0 +1 @@
export * from './send';

View File

@@ -0,0 +1,15 @@
import fetcher from "../fetcher";
interface SendVerificationCodeParam {
targetType: 'phone' | 'email';
type: 'login';
phone?: string;
email?: string;
}
export const send = async (data: SendVerificationCodeParam) => {
return fetcher<boolean>('/api/verification/send', {
method: 'POST',
body: JSON.stringify(data),
})
}