-
-
-
+
+
+
+
+
+
+
+
+ 请选择一种适合您的代码生成方式
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/apps/web-antd/src/views/code-generation/utils/data-transformer.ts b/apps/web-antd/src/views/code-generation/utils/data-transformer.ts
new file mode 100644
index 00000000..18fd16fa
--- /dev/null
+++ b/apps/web-antd/src/views/code-generation/utils/data-transformer.ts
@@ -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
,
+ 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 };
+}
+
diff --git a/apps/web-antd/src/views/code-generation/utils/draft-manager.ts b/apps/web-antd/src/views/code-generation/utils/draft-manager.ts
new file mode 100644
index 00000000..e2a47780
--- /dev/null
+++ b/apps/web-antd/src/views/code-generation/utils/draft-manager.ts
@@ -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);
+ }
+}
+