From bef1955fde1277c36d2cfd71ac13e88566017055 Mon Sep 17 00:00:00 2001 From: jingrow Date: Tue, 28 Oct 2025 00:32:39 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=88=9B=E5=BB=BA=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E7=B1=BB=E5=9E=8B=E6=A8=A1=E6=9D=BF=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jingrow/frontend/src/locales/zh-CN.json | 1 + .../src/views/dev/CreatePagetypeTemplate.vue | 78 +++++++++++++++++-- apps/jingrow/jingrow/api/dev.py | 42 +++++++++- 3 files changed, 114 insertions(+), 7 deletions(-) diff --git a/apps/jingrow/frontend/src/locales/zh-CN.json b/apps/jingrow/frontend/src/locales/zh-CN.json index e879e63..a79eeb3 100644 --- a/apps/jingrow/frontend/src/locales/zh-CN.json +++ b/apps/jingrow/frontend/src/locales/zh-CN.json @@ -703,6 +703,7 @@ "Toolbar": "工具栏", "Sidebar": "侧边栏", "Page": "页面", + "Select Field Types": "选择字段类型", "Media Resources": "媒体资源", "Attachments": "附件", diff --git a/apps/jingrow/frontend/src/views/dev/CreatePagetypeTemplate.vue b/apps/jingrow/frontend/src/views/dev/CreatePagetypeTemplate.vue index 15745e4..e0be963 100644 --- a/apps/jingrow/frontend/src/views/dev/CreatePagetypeTemplate.vue +++ b/apps/jingrow/frontend/src/views/dev/CreatePagetypeTemplate.vue @@ -9,11 +9,23 @@ - + - +
+ + +
@@ -61,11 +73,43 @@ const loading = ref(false) const submitting = ref(false) const result = ref(null) const formRef = ref(null) -const form = ref({ pagetype: '', createFrontend: false, createBackend: true, frontendOptions: ['toolbar'] }) +const form = ref({ pagetype: '', createFrontend: false, createBackend: true, frontendOptions: ['toolbar'], fieldTypeNames: [] }) const pagetypeOptions = ref<{ label: string; value: string }[]>([]) + +// 可用的字段类型列表(从 /core/components/form/controls 目录自动生成) +const fieldTypeOptions = ref<{ label: string; value: string }[]>([]) const appName = ref('') const moduleName = ref('') +// 动态加载字段类型选项(从 /core/components/form/controls 目录) +const loadFieldTypeOptions = () => { + try { + const modules = import.meta.glob('@/core/components/form/controls/*.vue', { eager: true }) + const fileNames = Object.keys(modules) + .map(path => path.split('/').pop()?.replace('.vue', '') || '') + .filter(name => name && !name.startsWith('_')) // 过滤私有文件 + + fieldTypeOptions.value = fileNames + .map(name => ({ label: name, value: name })) + .sort((a, b) => a.label.localeCompare(b.label)) + } catch (e) { + console.warn('Failed to load field type options from filesystem:', e) + // 如果加载失败,使用基础选项列表 + fieldTypeOptions.value = [ + 'Attach', 'AttachImage', 'Autocomplete', 'Barcode', 'Button', + 'Check', 'Code', 'Color', 'Comment', 'CronEditor', 'Currency', + 'Data', 'Date', 'DateRange', 'Datetime', 'Duration', 'DynamicLink', + 'Float', 'Geolocation', 'Heading', 'HTML', 'HTMLEditor', 'Icon', + 'Image', 'Int', 'Jeditor', 'JSON', 'Link', 'LongText', 'MarkdownEditor', + 'MultiCheck', 'MultiSelect', 'MultiSelectList', 'MultiSelectPills', + 'Password', 'Percent', 'Phone', 'Rating', 'Select', 'Signature', + 'SmallText', 'Table', 'TableMultiSelect', 'Text', 'TextEditor', 'Time' + ].map(name => ({ label: name, value: name })) + } +} + +loadFieldTypeOptions() + const slug = computed(() => toSnake(form.value.pagetype || '')) function dotToSlash(s: string): string { return s ? s.split('.').join('/').toLowerCase() : '' } const frontendPath = computed(() => { @@ -81,7 +125,13 @@ const frontendPath = computed(() => { files.push(`apps/${appName.value}/frontend/src/views/pagetype/${slug.value}/${slug.value}.vue`) } if (form.value.frontendOptions?.includes('field_types')) { - files.push(`apps/${appName.value}/frontend/src/views/pagetype/${slug.value}/form/controls/`) + if (form.value.fieldTypeNames && form.value.fieldTypeNames.length > 0) { + form.value.fieldTypeNames.forEach((name: string) => { + files.push(`apps/${appName.value}/frontend/src/views/pagetype/${slug.value}/form/controls/${name}.vue`) + }) + } else { + files.push(`apps/${appName.value}/frontend/src/views/pagetype/${slug.value}/form/controls/`) + } } return files.join('\n') }) @@ -120,6 +170,18 @@ function onFrontendToggle(value: boolean) { form.value.frontendOptions = ['toolbar'] } else if (!value) { form.value.frontendOptions = [] + form.value.fieldTypeNames = [] + } +} + +function updateFieldTypesPreview() { + // 触发预览更新 +} + +function onFrontendOptionsChange(value: (string | number)[]) { + // 当取消选择字段类型时,清空字段类型名称 + if (!value.includes('field_types')) { + form.value.fieldTypeNames = [] } } @@ -156,7 +218,8 @@ async function handleSubmit() { module: moduleName.value, create_frontend: form.value.createFrontend, create_backend: form.value.createBackend, - frontend_options: form.value.frontendOptions || [] + frontend_options: form.value.frontendOptions || [], + field_type_names: form.value.fieldTypeNames || [] }, { headers: get_session_api_headers(), withCredentials: true }) result.value = res.data if (res.data?.success) { @@ -192,6 +255,11 @@ async function handleSubmit() { white-space: pre-wrap; word-break: break-all; } +.field-types-row { + display: flex; + align-items: center; + gap: 8px; +} diff --git a/apps/jingrow/jingrow/api/dev.py b/apps/jingrow/jingrow/api/dev.py index 66a8b5c..6ea97c9 100644 --- a/apps/jingrow/jingrow/api/dev.py +++ b/apps/jingrow/jingrow/api/dev.py @@ -17,6 +17,7 @@ async def create_pagetypes(payload: Dict[str, Any]): create_frontend = bool(payload.get("create_frontend", True)) create_backend = bool(payload.get("create_backend", True)) frontend_options = payload.get("frontend_options", ["toolbar"]) + field_type_names = payload.get("field_type_names", []) if not name: raise ValueError("pagetype is required") slug = to_snake(name) @@ -63,11 +64,48 @@ async def create_pagetypes(payload: Dict[str, Any]): fp.write_text(page_content, encoding="utf-8") frontend_paths.append(str(fp)) - # 字段类型控件目录 + # 字段类型控件 if "field_types" in frontend_options: fp = root / "apps" / app / "frontend" / "src" / "views" / "pagetype" / slug / "form" / "controls" fp.mkdir(parents=True, exist_ok=True) - frontend_paths.append(f"{str(fp)} (创建自定义字段控件)") + + if field_type_names: + # 为每个选中的字段类型创建文件 + for field_type_name in field_type_names: + field_file = fp / f"{field_type_name}.vue" + if field_file.exists(): + frontend_exists = True + else: + # 创建字段类型组件的模板 + field_content = f''' + + + + +''' + field_file.write_text(field_content, encoding="utf-8") + frontend_paths.append(str(field_file)) + else: + frontend_paths.append(f"{str(fp)}/ (创建自定义字段控件)") frontend_path = "\n".join(frontend_paths) if frontend_paths else None else: