feat: 优化项目目录结构
This commit is contained in:
2
apps/frontend/lib/api/admin/index.ts
Normal file
2
apps/frontend/lib/api/admin/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * as user from './user/index';
|
||||
export * as web from './web/index';
|
||||
20
apps/frontend/lib/api/admin/user/create.ts
Normal file
20
apps/frontend/lib/api/admin/user/create.ts
Normal 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",
|
||||
},
|
||||
});
|
||||
}
|
||||
6
apps/frontend/lib/api/admin/user/get.ts
Normal file
6
apps/frontend/lib/api/admin/user/get.ts
Normal 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}`);
|
||||
}
|
||||
6
apps/frontend/lib/api/admin/user/index.ts
Normal file
6
apps/frontend/lib/api/admin/user/index.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export * from './list';
|
||||
export * from './get';
|
||||
export * from './create';
|
||||
export * from './update';
|
||||
export * from './set-password';
|
||||
export * from './remove';
|
||||
22
apps/frontend/lib/api/admin/user/list.ts
Normal file
22
apps/frontend/lib/api/admin/user/list.ts
Normal 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')
|
||||
}
|
||||
7
apps/frontend/lib/api/admin/user/remove.ts
Normal file
7
apps/frontend/lib/api/admin/user/remove.ts
Normal 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',
|
||||
})
|
||||
}
|
||||
10
apps/frontend/lib/api/admin/user/set-password.ts
Normal file
10
apps/frontend/lib/api/admin/user/set-password.ts
Normal 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,
|
||||
}),
|
||||
})
|
||||
}
|
||||
16
apps/frontend/lib/api/admin/user/update.ts
Normal file
16
apps/frontend/lib/api/admin/user/update.ts
Normal 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",
|
||||
});
|
||||
}
|
||||
14
apps/frontend/lib/api/admin/web/blog/create.ts
Normal file
14
apps/frontend/lib/api/admin/web/blog/create.ts
Normal 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)
|
||||
})
|
||||
}
|
||||
6
apps/frontend/lib/api/admin/web/blog/get.ts
Normal file
6
apps/frontend/lib/api/admin/web/blog/get.ts
Normal 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}`)
|
||||
}
|
||||
6
apps/frontend/lib/api/admin/web/blog/index.ts
Normal file
6
apps/frontend/lib/api/admin/web/blog/index.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export * from './create';
|
||||
export * from './remove';
|
||||
export * from './list';
|
||||
export * from './update';
|
||||
export * from './get';
|
||||
export * from './setPassword';
|
||||
6
apps/frontend/lib/api/admin/web/blog/list.ts
Normal file
6
apps/frontend/lib/api/admin/web/blog/list.ts
Normal 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')
|
||||
}
|
||||
7
apps/frontend/lib/api/admin/web/blog/remove.ts
Normal file
7
apps/frontend/lib/api/admin/web/blog/remove.ts
Normal 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',
|
||||
})
|
||||
}
|
||||
10
apps/frontend/lib/api/admin/web/blog/setPassword.ts
Normal file
10
apps/frontend/lib/api/admin/web/blog/setPassword.ts
Normal 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,
|
||||
})
|
||||
})
|
||||
}
|
||||
16
apps/frontend/lib/api/admin/web/blog/update.ts
Normal file
16
apps/frontend/lib/api/admin/web/blog/update.ts
Normal 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)
|
||||
})
|
||||
}
|
||||
2
apps/frontend/lib/api/admin/web/index.ts
Normal file
2
apps/frontend/lib/api/admin/web/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * as blog from './blog/index';
|
||||
export * as resource from './resource/index';
|
||||
19
apps/frontend/lib/api/admin/web/resource/create.ts
Normal file
19
apps/frontend/lib/api/admin/web/resource/create.ts
Normal 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)
|
||||
})
|
||||
}
|
||||
6
apps/frontend/lib/api/admin/web/resource/get.ts
Normal file
6
apps/frontend/lib/api/admin/web/resource/get.ts
Normal 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}`)
|
||||
}
|
||||
5
apps/frontend/lib/api/admin/web/resource/index.ts
Normal file
5
apps/frontend/lib/api/admin/web/resource/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export * from './create';
|
||||
export * from './remove';
|
||||
export * from './list';
|
||||
export * from './update';
|
||||
export * from './get';
|
||||
6
apps/frontend/lib/api/admin/web/resource/list.ts
Normal file
6
apps/frontend/lib/api/admin/web/resource/list.ts
Normal 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')
|
||||
}
|
||||
7
apps/frontend/lib/api/admin/web/resource/remove.ts
Normal file
7
apps/frontend/lib/api/admin/web/resource/remove.ts
Normal 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',
|
||||
})
|
||||
}
|
||||
19
apps/frontend/lib/api/admin/web/resource/update.ts
Normal file
19
apps/frontend/lib/api/admin/web/resource/update.ts
Normal 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)
|
||||
})
|
||||
}
|
||||
2
apps/frontend/lib/api/auth/index.ts
Normal file
2
apps/frontend/lib/api/auth/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './login';
|
||||
export * from './logout';
|
||||
53
apps/frontend/lib/api/auth/login.ts
Normal file
53
apps/frontend/lib/api/auth/login.ts
Normal 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),
|
||||
})
|
||||
}
|
||||
5
apps/frontend/lib/api/auth/logout.ts
Normal file
5
apps/frontend/lib/api/auth/logout.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import fetcher from "../fetcher";
|
||||
|
||||
export async function logout() {
|
||||
return fetcher('/api/auth/logout', { method: 'POST' });
|
||||
}
|
||||
12
apps/frontend/lib/api/blog/createComment.ts
Normal file
12
apps/frontend/lib/api/blog/createComment.ts
Normal 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,
|
||||
}),
|
||||
});
|
||||
}
|
||||
13
apps/frontend/lib/api/blog/get.ts
Normal file
13
apps/frontend/lib/api/blog/get.ts
Normal 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}` : ''));
|
||||
}
|
||||
6
apps/frontend/lib/api/blog/getComments.ts
Normal file
6
apps/frontend/lib/api/blog/getComments.ts
Normal 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' });
|
||||
}
|
||||
4
apps/frontend/lib/api/blog/index.ts
Normal file
4
apps/frontend/lib/api/blog/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export * from './list';
|
||||
export * from './get';
|
||||
export * from './getComments';
|
||||
export * from './createComment';
|
||||
6
apps/frontend/lib/api/blog/list.ts
Normal file
6
apps/frontend/lib/api/blog/list.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { Blog } from "@/lib/types/blog";
|
||||
import fetcher from "../fetcher";
|
||||
|
||||
export async function list() {
|
||||
return fetcher<Blog[]>('/api/blog');
|
||||
}
|
||||
39
apps/frontend/lib/api/fetcher.ts
Normal file
39
apps/frontend/lib/api/fetcher.ts
Normal 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
|
||||
7
apps/frontend/lib/api/index.ts
Normal file
7
apps/frontend/lib/api/index.ts
Normal 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';
|
||||
13
apps/frontend/lib/api/oss/index.ts
Normal file
13
apps/frontend/lib/api/oss/index.ts
Normal 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' });
|
||||
}
|
||||
1
apps/frontend/lib/api/resource/index.ts
Normal file
1
apps/frontend/lib/api/resource/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './list';
|
||||
6
apps/frontend/lib/api/resource/list.ts
Normal file
6
apps/frontend/lib/api/resource/list.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { Resource } from "@/lib/types/resource";
|
||||
import fetcher from "../fetcher";
|
||||
|
||||
export async function list() {
|
||||
return fetcher<Resource[]>('/api/resource');
|
||||
}
|
||||
2
apps/frontend/lib/api/user/index.ts
Normal file
2
apps/frontend/lib/api/user/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './me';
|
||||
export * from './updatePassword';
|
||||
8
apps/frontend/lib/api/user/me.ts
Normal file
8
apps/frontend/lib/api/user/me.ts
Normal 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';
|
||||
10
apps/frontend/lib/api/user/updatePassword.ts
Normal file
10
apps/frontend/lib/api/user/updatePassword.ts
Normal 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,
|
||||
}),
|
||||
})
|
||||
}
|
||||
1
apps/frontend/lib/api/verification/index.ts
Normal file
1
apps/frontend/lib/api/verification/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './send';
|
||||
15
apps/frontend/lib/api/verification/send.ts
Normal file
15
apps/frontend/lib/api/verification/send.ts
Normal 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),
|
||||
})
|
||||
}
|
||||
130
apps/frontend/lib/oss/OssStore.ts
Normal file
130
apps/frontend/lib/oss/OssStore.ts
Normal file
@@ -0,0 +1,130 @@
|
||||
import { Dispatch, SetStateAction } from "react";
|
||||
import OSS from "ali-oss";
|
||||
|
||||
export interface OssObjectItem {
|
||||
id: string;
|
||||
name: string;
|
||||
size: number;// Byte
|
||||
lastModified: Date;
|
||||
isChecked: boolean;
|
||||
};
|
||||
|
||||
export type OssObjectList = OssObjectItem[] | null;
|
||||
|
||||
export class OssStore {
|
||||
|
||||
private setObjectList?: Dispatch<SetStateAction<OssObjectList>>;
|
||||
public store?: OSS;
|
||||
private workDir: string;
|
||||
|
||||
constructor(options: {
|
||||
workDir?: string;
|
||||
setObjectList?: Dispatch<SetStateAction<OssObjectList>>;
|
||||
} = {}) {
|
||||
this.workDir = options.workDir ?? '';
|
||||
this.setObjectList = options.setObjectList;
|
||||
}
|
||||
|
||||
public setStore(store: OSS | undefined) {
|
||||
this.store = store;
|
||||
}
|
||||
|
||||
public setSetObjectList(setObjectList: Dispatch<SetStateAction<OssObjectList>>) {
|
||||
this.setObjectList = setObjectList;
|
||||
}
|
||||
|
||||
public async loadObjectList() {
|
||||
if (!this.setObjectList) {
|
||||
throw new Error('setObjectList need provided');
|
||||
}
|
||||
|
||||
const store = this.getStore();
|
||||
this.setObjectList(null);
|
||||
|
||||
const workDir = this.getWorkDir();
|
||||
const res = await store.listV2({ ...workDir ? { prefix: workDir } : {} }, {});
|
||||
if (!res || !res.objects) throw new Error('文件列表加载失败');
|
||||
|
||||
this.setObjectList(res.objects.map(v => ({
|
||||
id: v.name,
|
||||
name: v.name.replace(`${workDir}/`, ''),
|
||||
size: v.size,
|
||||
lastModified: new Date(v.lastModified),
|
||||
isChecked: false,
|
||||
})))
|
||||
}
|
||||
|
||||
public handleObjectCheckedStateChanged(id: string, value: boolean) {
|
||||
if (!this.setObjectList) {
|
||||
throw new Error('setObjectList need provided');
|
||||
}
|
||||
|
||||
this.setObjectList(current => current ? current.map(objectItem => {
|
||||
if (objectItem.id === id) {
|
||||
return { ...objectItem, isChecked: value }
|
||||
}
|
||||
return objectItem;
|
||||
}) : null)
|
||||
}
|
||||
|
||||
public async deleteObject(objectItem: OssObjectItem) {
|
||||
const store = this.getStore();
|
||||
|
||||
const objectName = this.getObjectNameByLocalname(objectItem.name);
|
||||
const delRes = await store.delete(objectName).catch(() => null);
|
||||
if (!delRes) throw new Error('删除失败');
|
||||
}
|
||||
|
||||
public async deleteCheckedObjects(objectItems: OssObjectItem[]) {
|
||||
if (!this.getStore()) {
|
||||
throw new Error('初始化失败,请刷新界面重试');
|
||||
}
|
||||
|
||||
if (objectItems.length === 0) throw new Error('请选择需要删除的文件');
|
||||
|
||||
let failedCount = 0;
|
||||
for (const objectItem of objectItems) {
|
||||
await this.deleteObject(objectItem).catch(() => failedCount++);
|
||||
}
|
||||
|
||||
return { all: objectItems.length, failed: failedCount };
|
||||
}
|
||||
|
||||
public async downloadObject(objectItem: OssObjectItem) {
|
||||
const store = this.getStore();
|
||||
if (!store) {
|
||||
throw new Error('初始化失败,请刷新界面重试');
|
||||
}
|
||||
|
||||
const url = store.signatureUrl(this.getObjectNameByLocalname(objectItem.name));
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = objectItem.name;
|
||||
a.target = '_blank';
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Error
|
||||
*/
|
||||
public getStore() {
|
||||
if (!this.store) {
|
||||
throw new Error('初始化失败,请刷新界面重试');
|
||||
}
|
||||
return this.store;
|
||||
}
|
||||
|
||||
private getObjectNameByLocalname(localName: string) {
|
||||
return `${this.getWorkDir()}/${localName}`;
|
||||
}
|
||||
|
||||
public getWorkDir() {
|
||||
return this.workDir;
|
||||
}
|
||||
|
||||
public setWorkDir(dir: string) {
|
||||
this.workDir = dir;
|
||||
}
|
||||
}
|
||||
6
apps/frontend/lib/types/Blog.Permission.enum.ts
Normal file
6
apps/frontend/lib/types/Blog.Permission.enum.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export enum BlogPermission {
|
||||
Public = 'Public',
|
||||
ByPassword = 'ByPassword',
|
||||
List = 'List',
|
||||
AllowComments = 'AllowComments',
|
||||
}
|
||||
11
apps/frontend/lib/types/blog.ts
Normal file
11
apps/frontend/lib/types/blog.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { BlogPermission } from "./Blog.Permission.enum";
|
||||
|
||||
export interface Blog {
|
||||
id: string;
|
||||
title: string;
|
||||
description: string;
|
||||
viewCount: number;
|
||||
contentUrl: string;
|
||||
createdAt: string;
|
||||
permissions: BlogPermission[];
|
||||
}
|
||||
12
apps/frontend/lib/types/blogComment.ts
Normal file
12
apps/frontend/lib/types/blogComment.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { User } from "./user";
|
||||
|
||||
export interface BlogComment {
|
||||
id: string;
|
||||
blogId: string;
|
||||
content: string;
|
||||
createdAt: string;
|
||||
deletedAt: string | null;
|
||||
parentId: string | null;
|
||||
user: User | null;
|
||||
address: string;
|
||||
}
|
||||
13
apps/frontend/lib/types/resource.ts
Normal file
13
apps/frontend/lib/types/resource.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export type TagType = {
|
||||
name: string;
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface Resource {
|
||||
id: string;
|
||||
title: string;
|
||||
description: string;
|
||||
imageUrl: string;
|
||||
link: string;
|
||||
tags: TagType[];
|
||||
}
|
||||
3
apps/frontend/lib/types/role.ts
Normal file
3
apps/frontend/lib/types/role.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export enum Role {
|
||||
Admin = 'admin',
|
||||
}
|
||||
14
apps/frontend/lib/types/user.ts
Normal file
14
apps/frontend/lib/types/user.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { Role } from "./role";
|
||||
|
||||
export interface User {
|
||||
userId: string;
|
||||
username: string;
|
||||
nickname: string;
|
||||
email?: string;
|
||||
phone?: string;
|
||||
avatar?: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
deletedAt: string | null;
|
||||
roles: Role[];
|
||||
}
|
||||
9
apps/frontend/lib/utils.ts
Normal file
9
apps/frontend/lib/utils.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { clsx, type ClassValue } from "clsx"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
import basex from "base-x"
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs))
|
||||
}
|
||||
|
||||
export const base62 = basex('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
|
||||
Reference in New Issue
Block a user