新增多种生成方式

This commit is contained in:
2025-11-28 10:55:29 +08:00
parent 11030750d7
commit dd41072fc9
7 changed files with 2791 additions and 75 deletions

View File

@@ -0,0 +1,201 @@
/**
* 代码生成数据转换工具
* 确保三种模式输出统一的数据格式
*/
export interface FieldType {
name: string;
type: string;
type_length: string;
default: string;
comment: string;
not_null: boolean;
formShow: boolean;
tableShow: boolean;
formType: string;
search: boolean;
searchValue: string;
}
export interface CodeGenData {
class_name: string;
class_comment: string;
icon: string;
sort: number;
pid: number;
field: FieldType[];
}
/**
* 默认字段结构
*/
const createDefaultField = (): FieldType => ({
name: '',
type: 'varchar',
type_length: '',
default: '',
comment: '',
not_null: true,
formShow: true,
tableShow: true,
formType: 'VbenInput',
search: true,
searchValue: '=',
});
/**
* JSON模式数据转换
*/
export function transformJsonToStandard(json: any): CodeGenData {
// 如果JSON包含完整结构,直接使用
if (json.class_name && json.field) {
return {
class_name: json.class_name || '',
class_comment: json.class_comment || '',
icon: json.icon || '',
sort: json.sort ?? 9999,
pid: json.pid ?? 0,
field: Array.isArray(json.field)
? json.field.map((f: any) => ({
name: f.name || '',
type: f.type || 'varchar',
type_length: f.type_length || '',
default: f.default || '',
comment: f.comment || '',
not_null: f.not_null !== undefined ? f.not_null : true,
formShow: f.formShow !== undefined ? f.formShow : true,
tableShow: f.tableShow !== undefined ? f.tableShow : true,
formType: f.formType || 'VbenInput',
search: f.search !== undefined ? f.search : true,
searchValue: f.searchValue || '=',
}))
: [],
};
}
// 如果只有字段数组,需要用户补充基础信息
if (Array.isArray(json)) {
return {
class_name: '',
class_comment: '',
icon: '',
sort: 9999,
pid: 0,
field: json.map((f: any) => ({
name: f.name || '',
type: f.type || 'varchar',
type_length: f.type_length || '',
default: f.default || '',
comment: f.comment || '',
not_null: f.not_null !== undefined ? f.not_null : true,
formShow: f.formShow !== undefined ? f.formShow : true,
tableShow: f.tableShow !== undefined ? f.tableShow : true,
formType: f.formType || 'VbenInput',
search: f.search !== undefined ? f.search : true,
searchValue: f.searchValue || '=',
})),
};
}
// 默认返回空结构
return {
class_name: '',
class_comment: '',
icon: '',
sort: 9999,
pid: 0,
field: [createDefaultField()],
};
}
/**
* 手动模式数据转换
*/
export function transformManualToStandard(
formData: Record<string, any>,
fields: FieldType[],
): CodeGenData {
return {
class_name: formData.class_name || '',
class_comment: formData.class_comment || '',
icon: formData.icon || '',
sort: formData.sort ?? 9999,
pid: formData.pid ?? 0,
field: Array.isArray(fields) ? fields : [],
};
}
/**
* AI模式数据转换
*/
export function transformAiToStandard(aiData: any): CodeGenData {
// AI返回完整表单数据
if (aiData && aiData.class_name) {
return {
class_name: aiData.class_name || '',
class_comment: aiData.class_comment || '',
icon: aiData.icon || '',
sort: aiData.sort ?? 9999,
pid: aiData.pid ?? 0,
field: Array.isArray(aiData.field)
? aiData.field.map((f: any) => ({
name: f.name || '',
type: f.type || 'varchar',
type_length: f.type_length || '',
default: f.default || '',
comment: f.comment || '',
not_null: f.not_null !== undefined ? f.not_null : true,
formShow: f.formShow !== undefined ? f.formShow : true,
tableShow: f.tableShow !== undefined ? f.tableShow : true,
formType: f.formType || 'VbenInput',
search: f.search !== undefined ? f.search : true,
searchValue: f.searchValue || '=',
}))
: [],
};
}
// 默认返回空结构
return {
class_name: '',
class_comment: '',
icon: '',
sort: 9999,
pid: 0,
field: [createDefaultField()],
};
}
/**
* 数据验证
*/
export function validateData(data: CodeGenData): {
valid: boolean;
message?: string;
} {
if (!data.class_name || !data.class_name.trim()) {
return { valid: false, message: '类名不能为空' };
}
if (!data.class_comment || !data.class_comment.trim()) {
return { valid: false, message: '中文名称不能为空' };
}
if (!data.icon || !data.icon.trim()) {
return { valid: false, message: '菜单图标不能为空' };
}
if (!Array.isArray(data.field) || data.field.length === 0) {
return { valid: false, message: '至少需要一个字段' };
}
// 验证字段
for (const field of data.field) {
if (!field.name || !field.name.trim()) {
return { valid: false, message: '字段名不能为空' };
}
}
return { valid: true };
}

View File

@@ -0,0 +1,254 @@
/**
* 草稿管理工具
* 使用 localStorage 存储草稿,每种模式独立存储
*/
export type GenerationMode = 'json' | 'manual' | 'ai';
export interface DraftItem {
id: string;
name: string;
mode: GenerationMode;
data: any;
createdAt: number;
updatedAt: number;
}
const STORAGE_PREFIX = 'code-gen-draft';
const MAX_DRAFTS_PER_MODE = 10; // 每种模式最多保存10个草稿
/**
* 获取存储key
*/
function getStorageKey(mode: GenerationMode, id?: string): string {
if (id) {
return `${STORAGE_PREFIX}-${mode}-${id}`;
}
return `${STORAGE_PREFIX}-${mode}`;
}
/**
* 获取所有草稿的索引key
*/
function getIndexKey(mode: GenerationMode): string {
return `${STORAGE_PREFIX}-index-${mode}`;
}
/**
* 生成草稿ID
*/
function generateDraftId(): string {
return `draft-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
}
/**
* 获取草稿索引列表
*/
function getDraftIndex(mode: GenerationMode): string[] {
try {
const key = getIndexKey(mode);
const indexStr = localStorage.getItem(key);
if (indexStr) {
return JSON.parse(indexStr);
}
} catch (error) {
console.error('获取草稿索引失败:', error);
}
return [];
}
/**
* 保存草稿索引
*/
function saveDraftIndex(mode: GenerationMode, ids: string[]): void {
try {
const key = getIndexKey(mode);
localStorage.setItem(key, JSON.stringify(ids));
} catch (error) {
console.error('保存草稿索引失败:', error);
}
}
/**
* 获取默认草稿名称
*/
function getDefaultDraftName(mode: GenerationMode, index: number): string {
const modeNames = {
json: 'JSON导入',
manual: '手动填写',
ai: 'AI提示词',
};
const numbers = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十'];
const number = numbers[index] || `${index + 1}`;
return `${modeNames[mode]} - 草稿${number}`;
}
/**
* 保存草稿
*/
export function saveDraft(
mode: GenerationMode,
data: any,
name?: string,
draftId?: string,
): string {
try {
const id = draftId || generateDraftId();
const now = Date.now();
const index = getDraftIndex(mode);
// 如果指定了draftId,更新现有草稿
if (draftId && index.includes(draftId)) {
const existingDraft = loadDraft(mode, draftId);
const draftName = name || existingDraft?.name || getDefaultDraftName(mode, 0);
const draft: DraftItem = {
id,
name: draftName,
mode,
data,
createdAt: existingDraft?.createdAt || now,
updatedAt: now,
};
const key = getStorageKey(mode, id);
localStorage.setItem(key, JSON.stringify(draft));
return id;
}
// 创建新草稿
const draftName =
name || getDefaultDraftName(mode, index.length);
const draft: DraftItem = {
id,
name: draftName,
mode,
data,
createdAt: now,
updatedAt: now,
};
// 保存草稿
const key = getStorageKey(mode, id);
localStorage.setItem(key, JSON.stringify(draft));
// 更新索引(限制数量)
const newIndex = [id, ...index].slice(0, MAX_DRAFTS_PER_MODE);
saveDraftIndex(mode, newIndex);
// 如果超出限制,删除最旧的草稿
if (index.length >= MAX_DRAFTS_PER_MODE) {
const oldIds = index.slice(MAX_DRAFTS_PER_MODE - 1);
oldIds.forEach((oldId) => {
try {
localStorage.removeItem(getStorageKey(mode, oldId));
} catch (error) {
console.error('删除旧草稿失败:', error);
}
});
}
return id;
} catch (error) {
console.error('保存草稿失败:', error);
throw error;
}
}
/**
* 加载草稿
*/
export function loadDraft(
mode: GenerationMode,
id: string,
): DraftItem | null {
try {
const key = getStorageKey(mode, id);
const draftStr = localStorage.getItem(key);
if (draftStr) {
const draft = JSON.parse(draftStr) as DraftItem;
// 验证模式是否匹配
if (draft.mode === mode) {
return draft;
}
}
} catch (error) {
console.error('加载草稿失败:', error);
}
return null;
}
/**
* 列出所有草稿
*/
export function listDrafts(mode: GenerationMode): DraftItem[] {
try {
const index = getDraftIndex(mode);
const drafts: DraftItem[] = [];
for (const id of index) {
const draft = loadDraft(mode, id);
if (draft) {
drafts.push(draft);
}
}
// 按更新时间倒序排列
return drafts.sort((a, b) => b.updatedAt - a.updatedAt);
} catch (error) {
console.error('列出草稿失败:', error);
return [];
}
}
/**
* 删除草稿
*/
export function deleteDraft(mode: GenerationMode, id: string): boolean {
try {
const key = getStorageKey(mode, id);
localStorage.removeItem(key);
// 更新索引
const index = getDraftIndex(mode);
const newIndex = index.filter((draftId) => draftId !== id);
saveDraftIndex(mode, newIndex);
return true;
} catch (error) {
console.error('删除草稿失败:', error);
return false;
}
}
/**
* 获取草稿名称
*/
export function getDraftName(mode: GenerationMode, id: string): string {
const draft = loadDraft(mode, id);
return draft?.name || getDefaultDraftName(mode, 0);
}
/**
* 清空所有草稿(用于测试或重置)
*/
export function clearAllDrafts(mode?: GenerationMode): void {
try {
if (mode) {
// 清空指定模式的草稿
const index = getDraftIndex(mode);
index.forEach((id) => {
localStorage.removeItem(getStorageKey(mode, id));
});
localStorage.removeItem(getIndexKey(mode));
} else {
// 清空所有模式的草稿
const modes: GenerationMode[] = ['json', 'manual', 'ai'];
modes.forEach((m) => {
clearAllDrafts(m);
});
}
} catch (error) {
console.error('清空草稿失败:', error);
}
}