Document-to-Form Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: 把 Word/Excel/图片/PDF 首页变成可确认的表单草案,并可选用现有 AI 助理补校验和选项。
Architecture: 解析仍在客户端。Word/Excel 复用 wordParser / excelParser。图片和 PDF 抽文本或缩略图后走 config.ai。所有来源先产出 IngestDraft(字段数组),确认页再 setRule。不在解析失败时直接覆盖画布。
Tech Stack: 现有 ImportDialog、mammoth/xlsx、config.ai、可选 pdfjs(按需 CDN,与 echarts 同一模式)。
Depends on: 现有 AI 面板;不强制 shared foundation,但确认后应 getSnapshot() 正常。
File map
- Create:
designer3.0/src/modules/ingest/types.js - Create:
designer3.0/src/modules/ingest/draftFromRules.js - Create:
designer3.0/src/modules/ingest/imagePrompt.js - Create:
designer3.0/src/modules/ingest/polishPrompt.js - Create:
designer3.0/tests/modules/ingest/draft.spec.js - Create:
designer3.0/src/designer/ingest/IngestConfirm.vue - Modify:
designer3.0/src/designer/ImportDialog.vue - Modify:
designer3.0/src/locale/zh-cn.js/en.js/jp.js - Modify:
fc-design-pro/src/help/interface/toolbar.md(导入一节)
Task 1: IngestDraft 模型
Files:
Create:
designer3.0/src/modules/ingest/types.jsCreate:
designer3.0/src/modules/ingest/draftFromRules.jsCreate:
designer3.0/tests/modules/ingest/draft.spec.js[ ] Step 1: 写失败测试
import { describe, it, expect } from 'vitest';
import { rulesToDraft, draftToRules } from '../../../src/modules/ingest/draftFromRules.js';
describe('draft roundtrip', () => {
it('keeps field title type required', () => {
const rules = [
{ type: 'input', field: 'mobile', title: '手机号', $required: true, _fc_drag_tag: 'input' },
];
const draft = rulesToDraft(rules);
expect(draft.fields[0]).toMatchObject({ field: 'mobile', title: '手机号', type: 'input', required: true });
const back = draftToRules(draft);
expect(back[0].field).toBe('mobile');
expect(back[0].title).toBe('手机号');
});
});$required 以设计器真实必填存储为准(可能是 validate: [{required:true}])。实现必须读真实结构,测试跟着改。
- [ ] Step 2: 实现
IngestDraft 固定为:
export function createEmptyDraft(source) {
return { source, fields: [] };
}
// field: { field, title, type, required, options }draftToRules 只生成白名单类型:input textarea number select radio checkbox date switch。未知 type 降级为 input。
- [ ] Step 3: 跑测试并提交
pnpm test tests/modules/ingest/draft.spec.jsExpected: PASS
git add src/modules/ingest tests/modules/ingest
git commit -m "feat: add ingest draft model"Task 2: AI 提示词(图片 / 润色)
Files:
Create:
designer3.0/src/modules/ingest/imagePrompt.jsCreate:
designer3.0/src/modules/ingest/polishPrompt.jsModify:
designer3.0/tests/modules/ingest/draft.spec.js[ ] Step 1: 写失败测试
import { buildImageToFormMessages } from '../../../src/modules/ingest/imagePrompt.js';
import { buildPolishMessages } from '../../../src/modules/ingest/polishPrompt.js';
it('asks AI to return JSON draft only', () => {
const msgs = buildImageToFormMessages({ imageDataUrl: 'data:image/png;base64,xx' });
expect(msgs[0].role).toBe('system');
expect(msgs[0].content).toContain('IngestDraft');
expect(JSON.stringify(msgs)).toContain('data:image/png;base64,xx');
});
it('sends current draft for polish', () => {
const msgs = buildPolishMessages({ fields: [{ field: 'mobile', title: '手机', type: 'input', required: false }] });
expect(msgs[1].content).toContain('mobile');
expect(msgs[0].content).toContain('validate');
});- [ ] Step 2: 实现提示词
系统提示必须要求:
- 只返回 JSON:
{"source":"image","fields":[...]} - fields 的 type 只能是白名单
- 手机/邮箱要标
required并在validateHint里写mobile/email - 不要解释性文字
图片消息用 OpenAI vision 兼容格式(image_url)。若客户模型不支持视觉,imagePrompt.js 同时导出 buildOcrTextToFormMessages(text) 作为降级。
- [ ] Step 3: 解析 AI 输出
在 draftFromRules.js 增加:
export function parseDraftResponse(text) {
const json = String(text).replace(/^```json\s*|\s*```$/g, '').trim();
const data = JSON.parse(json);
if (!Array.isArray(data.fields)) {
throw new Error('invalid ingest draft');
}
return data;
}补测试:输入带 markdown 围栏的字符串,解析出 fields。
- [ ] Step 4: 跑测试并提交
pnpm test tests/modules/ingest/draft.spec.jsExpected: PASS
git add src/modules/ingest tests/modules/ingest
git commit -m "feat: add ingest AI prompts and draft parser"Task 3: 改造 ImportDialog
Files:
Create:
designer3.0/src/designer/ingest/IngestConfirm.vueModify:
designer3.0/src/designer/ImportDialog.vue[ ] Step 1: 扩大 acceptTypes
acceptTypes: '.docx,.csv,.tsv,.xls,.xlsx,.xlsm,.xlsb,.json,.png,.jpg,.jpeg,.pdf',processSelectedFile 增加:
图片:
FileReader.readAsDataURL→ 调config.ai(与 AiPanel 同一api/token)→parseDraftResponse→ 打开确认页。PDF:第一页用 pdf.js 渲染到 canvas 再当图片。pdf.js 按
开发环境与依赖说明.md的 CDN 按需加载;失败则提示「请上传图片或 Word」。Word/Excel:解析出 rule 后先
rulesToDraft,确认页可勾选「AI 润色」。[ ] Step 2: IngestConfirm
表格列:标题、字段、类型(可改)、必填。底部:取消、导入、AI 润色。导入调用 draftToRules 再 setRule。取消不改画布。
- [ ] Step 3: 无 AI 时的行为
图片/PDF:提示 t('ingest.aiRequired'),不崩溃。Word/Excel:仍可直接确认导入(现有能力不能回退)。
- [ ] Step 4: 文案
zh-cn.js 增加 ingest.aiRequired、ingest.confirm、ingest.polish、ingest.invalidFileType(扩展原 invalidFileType 或新 key)。en/jp 同步。
- [ ] Step 5: 手动验收
pnpm run dev- 导入现有请假 Excel,确认页出现字段,导入后画布有字段。
- 上传一张打印申请表照片(有 AI token 时),确认页至少 3 个字段。
- 关掉网络再导 Word,仍能导入。
- [ ] Step 6: Commit
git add src/designer/ImportDialog.vue src/designer/ingest src/locale
git commit -m "feat: confirm-page ingest for docs images and spreadsheets"

