This commit is contained in:
2025-10-20 05:45:19 +08:00
parent d3174a73f3
commit 15af405d02
37 changed files with 3570 additions and 5 deletions

View File

@@ -0,0 +1,183 @@
import { faker } from '@faker-js/faker';
import { nanoid, customAlphabet } from 'nanoid';
export const random = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
// 类型定义
export type MarkDataNode = {
id?: string;
content?: string;
type?: string;
title?: string;
position?: { x: number; y: number };
size?: { width: number; height: number };
metadata?: Record<string, any>;
[key: string]: any;
};
export type MarkFile = {
id: string;
name: string;
url: string;
size: number;
type: 'self' | 'data' | 'generate'; // generate为生成文件
query: string; // 'data.nodes[id].content';
hash: string;
fileKey: string; // 文件的名称, 唯一
};
export type MarkData = {
md?: string; // markdown
mdList?: string[]; // markdown list
type?: string; // 类型 markdown | json | html | image | video | audio | code | link | file
data?: any;
key?: string; // 文件的名称, 唯一
push?: boolean; // 是否推送到elasticsearch
pushTime?: Date; // 推送时间
summary?: string; // 摘要
nodes?: MarkDataNode[]; // 节点
[key: string]: any;
};
export type MarkConfig = {
visibility?: 'public' | 'private' | 'restricted';
allowComments?: boolean;
allowDownload?: boolean;
password?: string;
expiredAt?: Date;
[key: string]: any;
};
export type MarkAuth = {
permissions?: string[];
roles?: string[];
userId?: string;
[key: string]: any;
};
export type Mark = {
id: string;
title: string;
description: string;
cover: string;
thumbnail: string;
key: string;
markType: string;
link: string;
tags: string[];
summary: string;
data: MarkData;
uid: string;
puid: string;
config: MarkConfig;
fileList: MarkFile[];
uname: string;
markedAt: Date;
createdAt: Date;
updatedAt: Date;
version: number;
};
// 生成模拟的 MarkDataNode
const generateMarkDataNode = (): MarkDataNode => ({
id: random(12),
content: faker.lorem.paragraph(),
type: faker.helpers.arrayElement(['text', 'image', 'video', 'code', 'link']),
title: faker.lorem.sentence(),
position: {
x: faker.number.int({ min: 0, max: 1920 }),
y: faker.number.int({ min: 0, max: 1080 })
},
size: {
width: faker.number.int({ min: 100, max: 800 }),
height: faker.number.int({ min: 50, max: 600 })
},
metadata: {
createdBy: faker.person.fullName(),
lastModified: faker.date.recent(),
isLocked: faker.datatype.boolean()
}
});
// 生成模拟的 MarkFile
const generateMarkFile = (): MarkFile => ({
id: faker.string.uuid(),
name: faker.system.fileName(),
url: faker.internet.url(),
size: faker.number.int({ min: 1024, max: 50 * 1024 * 1024 }), // 1KB to 50MB
type: faker.helpers.arrayElement(['self', 'data', 'generate']),
query: `data.nodes[${random(12)}].content`,
hash: faker.git.commitSha(),
fileKey: faker.system.fileName()
});
// 生成模拟的 MarkData
const generateMarkData = (): MarkData => ({
md: faker.lorem.paragraphs(3, '\n\n'),
mdList: Array.from({ length: faker.number.int({ min: 3, max: 8 }) }, () => faker.lorem.sentence()),
type: faker.helpers.arrayElement(['markdown', 'json', 'html', 'image', 'video', 'audio', 'code', 'link', 'file']),
data: {
author: faker.person.fullName(),
category: faker.helpers.arrayElement(['技术', '生活', '工作', '学习', '思考']),
priority: faker.helpers.arrayElement(['low', 'medium', 'high'])
},
key: faker.system.fileName(),
push: faker.datatype.boolean(),
pushTime: faker.date.recent(),
summary: faker.lorem.paragraph(),
nodes: Array.from({ length: faker.number.int({ min: 2, max: 6 }) }, generateMarkDataNode)
});
// 生成模拟的 MarkConfig
const generateMarkConfig = (): MarkConfig => ({
visibility: faker.helpers.arrayElement(['public', 'private', 'restricted']),
allowComments: faker.datatype.boolean(),
allowDownload: faker.datatype.boolean(),
password: faker.datatype.boolean() ? faker.internet.password() : undefined,
expiredAt: faker.datatype.boolean() ? faker.date.future() : undefined,
theme: faker.helpers.arrayElement(['light', 'dark', 'auto']),
language: faker.helpers.arrayElement(['zh-CN', 'en-US', 'ja-JP'])
});
// 生成单个 Mark 记录
const generateMark = (): Mark => {
const markType = faker.helpers.arrayElement(['markdown', 'json', 'html', 'image', 'video', 'audio', 'code', 'link', 'file']);
const title = faker.lorem.sentence({ min: 3, max: 8 });
return {
id: faker.string.uuid(),
title,
description: faker.lorem.paragraph(),
cover: faker.image.url({ width: 800, height: 600 }),
thumbnail: faker.image.url({ width: 200, height: 150 }),
key: faker.system.filePath(),
markType,
link: faker.internet.url(),
tags: Array.from({ length: faker.number.int({ min: 1, max: 5 }) }, () =>
faker.helpers.arrayElement(['技术', '前端', '后端', '设计', 'AI', '工具', '教程', '笔记'])
),
summary: faker.lorem.sentence(),
data: generateMarkData(),
uid: faker.string.uuid(),
puid: faker.string.uuid(),
config: generateMarkConfig(),
fileList: Array.from({ length: faker.number.int({ min: 0, max: 4 }) }, generateMarkFile),
uname: faker.person.fullName(),
markedAt: faker.date.past(),
createdAt: faker.date.past(),
updatedAt: faker.date.recent(),
version: faker.number.int({ min: 1, max: 10 })
};
};
// 生成 20 条模拟数据
export const mockMarks: Mark[] = Array.from({ length: 20 }, generateMark);
// 导出生成器函数
export {
generateMark,
generateMarkData,
generateMarkFile,
generateMarkDataNode,
generateMarkConfig
};