openyida 2026.7.29-beta.1 → 2026.7.29-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -60,6 +60,10 @@ const MODULE_ALIAS_MAP = {
60
60
  'framer-motion': 'FramerMotion',
61
61
  };
62
62
 
63
+ const LUCIDE_REACT_PACKAGE = 'lucide-react';
64
+ const LUCIDE_DYNAMIC_ICON_ALIAS = 'DynamicIcon';
65
+ const LUCIDE_MODULE_ALIAS = 'LucideReact';
66
+
63
67
  const IMPORT_PATTERN = /import\s+(?:[\w*\s{},]+\s+from\s+)?['"]([^'"]+)['"]/g;
64
68
  const IMPORT_SIDE_EFFECT_PATTERN = /import\s+['"]([^'"]+)['"]/g;
65
69
  const REQUIRE_PATTERN = /require\(\s*['"]([^'"]+)['"]\s*\)/g;
@@ -78,6 +82,11 @@ function packageTempName(pkg) {
78
82
  return String(pkg || 'module').replace(/[^A-Za-z0-9_$]+/g, '_') || 'module';
79
83
  }
80
84
 
85
+ function packageBaseName(pkg) {
86
+ const segments = String(pkg || '').split('/');
87
+ return pkg.startsWith('@') ? segments.slice(0, 2).join('/') : segments[0];
88
+ }
89
+
81
90
  function stripJsComments(code) {
82
91
  return String(code || '')
83
92
  .replace(/\/\*[\s\S]*?\*\//g, '')
@@ -117,11 +126,14 @@ function resolveWindowAlias(pkg) {
117
126
  if (MODULE_ALIAS_MAP[pkg]) {
118
127
  return MODULE_ALIAS_MAP[pkg];
119
128
  }
120
- const segments = pkg.split('/');
121
- const base = pkg.startsWith('@') ? segments.slice(0, 2).join('/') : segments[0];
129
+ const base = packageBaseName(pkg);
122
130
  return MODULE_ALIAS_MAP[base] || null;
123
131
  }
124
132
 
133
+ function isLucideReactPackage(pkg) {
134
+ return packageBaseName(pkg) === LUCIDE_REACT_PACKAGE;
135
+ }
136
+
125
137
  /**
126
138
  * Babel 插件:把 ESM import/export 改写成画布运行时约定。
127
139
  * import X from 'react' → var _r = window.React; var X = _r && _r.__esModule ? _r.default : _r;
@@ -142,6 +154,76 @@ function esmToWindowPlugin({ types: t }, options = {}) {
142
154
  return t.memberExpression(t.identifier('window'), t.stringLiteral(pkg), true);
143
155
  }
144
156
 
157
+ function buildLucideImportDeclarations(path, specifiers) {
158
+ const decls = [];
159
+ let dynamicIconTmp = null;
160
+ let lucideReactTmp = null;
161
+
162
+ function ensureDynamicIconTmp() {
163
+ if (!dynamicIconTmp) {
164
+ dynamicIconTmp = path.scope.generateUidIdentifier(LUCIDE_DYNAMIC_ICON_ALIAS);
165
+ decls.push(t.variableDeclarator(
166
+ t.cloneNode(dynamicIconTmp),
167
+ moduleExpr(LUCIDE_REACT_PACKAGE, LUCIDE_DYNAMIC_ICON_ALIAS)
168
+ ));
169
+ }
170
+ return dynamicIconTmp;
171
+ }
172
+
173
+ function ensureLucideReactTmp() {
174
+ if (!lucideReactTmp) {
175
+ lucideReactTmp = path.scope.generateUidIdentifier(LUCIDE_MODULE_ALIAS);
176
+ decls.push(t.variableDeclarator(
177
+ t.cloneNode(lucideReactTmp),
178
+ moduleExpr(LUCIDE_REACT_PACKAGE, LUCIDE_MODULE_ALIAS)
179
+ ));
180
+ }
181
+ return lucideReactTmp;
182
+ }
183
+
184
+ const namedIconProps = [];
185
+ for (const spec of specifiers) {
186
+ if (t.isImportDefaultSpecifier(spec)) {
187
+ decls.push(t.variableDeclarator(
188
+ t.identifier(spec.local.name),
189
+ t.cloneNode(ensureDynamicIconTmp())
190
+ ));
191
+ } else if (t.isImportNamespaceSpecifier(spec)) {
192
+ decls.push(t.variableDeclarator(
193
+ t.identifier(spec.local.name),
194
+ t.cloneNode(ensureLucideReactTmp())
195
+ ));
196
+ } else if (t.isImportSpecifier(spec)) {
197
+ const importedName = t.isIdentifier(spec.imported) ? spec.imported.name : spec.imported.value;
198
+ const localName = spec.local.name;
199
+ if (importedName === LUCIDE_DYNAMIC_ICON_ALIAS) {
200
+ decls.push(t.variableDeclarator(
201
+ t.identifier(localName),
202
+ t.cloneNode(ensureDynamicIconTmp())
203
+ ));
204
+ } else {
205
+ namedIconProps.push(
206
+ t.objectProperty(
207
+ t.identifier(importedName),
208
+ t.identifier(localName),
209
+ false,
210
+ importedName === localName
211
+ )
212
+ );
213
+ }
214
+ }
215
+ }
216
+
217
+ if (namedIconProps.length) {
218
+ decls.push(t.variableDeclarator(
219
+ t.objectPattern(namedIconProps),
220
+ t.cloneNode(ensureLucideReactTmp())
221
+ ));
222
+ }
223
+
224
+ return t.variableDeclaration('var', decls);
225
+ }
226
+
145
227
  function buildUnsupportedBareImportError(path, pkg) {
146
228
  return path.buildCodeFrameError(
147
229
  `Code Canvas 不支持从裸包 "${pkg}" 导入绑定。`
@@ -184,6 +266,11 @@ function esmToWindowPlugin({ types: t }, options = {}) {
184
266
  throw buildUnsupportedBareImportError(path, pkg);
185
267
  }
186
268
 
269
+ if (isLucideReactPackage(pkg)) {
270
+ path.replaceWith(buildLucideImportDeclarations(path, specifiers));
271
+ return;
272
+ }
273
+
187
274
  const decls = [];
188
275
  const tmp = path.scope.generateUidIdentifier(alias || packageTempName(pkg));
189
276
  decls.push(t.variableDeclarator(t.cloneNode(tmp), moduleExpr(pkg, alias)));
@@ -402,7 +402,7 @@ function buildAgentCapabilities() {
402
402
  ],
403
403
  retry_policy: 'Do not repeat the same failed command without changing login state, organization, parameters, files, or field IDs.',
404
404
  completion_contracts: {
405
- full_app: 'Default fast_build is complete after creating the app, core forms, primary page, publishing it, and returning an access URL.',
405
+ full_app: 'Default fast_build is complete after creating the app, core forms, primary page, publishing it, and returning access URLs. If three or more resources/links are returned, present them in a Markdown table with type, purpose/name, URL, and status.',
406
406
  },
407
407
  fast_build_data_contract: 'Default fast_build page code must not call this.dataSourceMap.* unless the same run created and bound a designer data source; use this.utils.yida.* or an entry-only page by default.',
408
408
  },
@@ -1302,8 +1302,10 @@ function summarizeLocalizedCommands(commands) {
1302
1302
  mode: 'fast_build',
1303
1303
  trigger_phrases: ['默认方案', '不要追问', '直接创建', '尽快搭建'],
1304
1304
  default_page_skill_id: 'yida-canvas-custom-page',
1305
+ default_ui_guidance_skill_id: 'yida-page-uiux',
1305
1306
  ordinary_jsx_skill_id: 'yida-custom-page',
1306
1307
  page_skill_policy: 'Use Code Canvas by default for the primary custom page. Choose yida-custom-page when the user explicitly asks for the ordinary custom page JSX/Jsx component chain, or when the page strongly depends on this.$(fieldId), this.utils.yida.*, this.dataSourceMap, form submission, or deep field two-way binding.',
1308
+ ui_guidance_policy: 'Default full-app primary page creation includes yida-page-uiux lightweight UI guidance to decide page type, template route, visualProfile, and sample-avoidance checks. This is not deep_design and must not pull yida-app-uiux, theme, navigation, demo data, screenshots, or long PRD work by default.',
1307
1309
  required_command_ids: [
1308
1310
  'agent-capabilities',
1309
1311
  'create-app',
@@ -1326,13 +1328,13 @@ function summarizeLocalizedCommands(commands) {
1326
1328
  'append-chart',
1327
1329
  ],
1328
1330
  do_not_default_skill_ids: [
1329
- 'yida-page-uiux',
1331
+ 'yida-app-uiux',
1330
1332
  'yida-data-source-connectors',
1331
1333
  'yida-data-management',
1332
1334
  'yida-nav-group',
1333
1335
  'yida-dashboard',
1334
1336
  ],
1335
- completion_contract: 'Create app, core forms, primary page, publish it, and return an access URL.',
1337
+ completion_contract: 'Create app, core forms, primary page, publish it, and return access URLs. If three or more resources/links are returned, present them in a Markdown table with type, purpose/name, URL, and status.',
1336
1338
  },
1337
1339
  },
1338
1340
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openyida",
3
- "version": "2026.7.29-beta.1",
3
+ "version": "2026.7.29-beta.2",
4
4
  "description": "OpenYida CLI - 宜搭低代码 AI 开发工具(安装即用,零配置)",
5
5
  "bin": {
6
6
  "openyida": "bin/yida.js",
@@ -259,11 +259,15 @@ openyida copy
259
259
 
260
260
  fast_build 页面源码默认不得使用 \`this.dataSourceMap.*\`,除非本轮已经明确创建并绑定设计器数据源;默认使用入口型页面或 \`this.utils.yida.*\` 查询已创建表单。
261
261
 
262
+ 最终结果如果包含 3 个及以上资源或链接,必须用 Markdown 表格集中展示(资源类型、名称/用途、链接、状态),不要连续堆 URL;1-2 个链接才用简短列表。
263
+
262
264
  fast_build 创建/解析多个表单后,页面阶段需要字段映射时,对每个目标表单默认只执行一次 \`openyida get-schema <appType> <formUuid> --field-map-json\`,读取完整 JSON 并写入/复用 \`.cache/<项目名>-schema.json\`;不要用 \`head\` / \`tail\` / \`grep\` 截断 schema stdout 后重复拉取。
263
265
 
264
266
  Canvas 页面实现二选一:走模板路径时先写业务化 \`page-spec.json\` 再 \`openyida generate-page ... --spec ... --compile\`,之后只做必要小范围 Edit/patch;如果已经明确最终页面结构,跳过 \`generate-page\`,直接 Write 最终 \`.canvas.jsx\`。不要 generate-page 后马上 Read 大段源码并全量 Write 覆盖同一路径。
265
267
 
266
- 不要默认加载 \`yida-page-uiux\`、\`yida-data-source-connectors\`、\`yida-data-management\`、\`yida-nav-group\`、\`yida-dashboard\`,也不要默认做示例数据、导航整理、截图验收、公开访问、长 PRD 或深读 references;这些只在用户明确要求或 \`full_demo\` / \`deep_design\` 时执行。
268
+ 完整应用主页面生成默认包含 \`yida-page-uiux\` 轻量 ui_skill 引导,产出页面类型、模板路由、\`visualProfile\` 和去 sample 化检查,再交给 \`yida-canvas-custom-page\` 或 \`yida-custom-page\` 落地。这不等于 \`deep_design\`。
269
+
270
+ 不要默认加载 \`yida-app-uiux\`、\`yida-data-source-connectors\`、\`yida-data-management\`、\`yida-nav-group\`、\`yida-dashboard\`,也不要默认做示例数据、导航整理、截图验收、公开访问、长 PRD、深度 UI 设计或深读 references;这些只在用户明确要求或 \`full_demo\` / \`deep_design\` 时执行。
267
271
 
268
272
  ## 子技能目录
269
273
 
@@ -136,12 +136,12 @@ OpenYida builder 默认使用 `create-app / create-form / create-page / generate
136
136
 
137
137
  > 📌 仅当第二步判定为「完整搭建 / 补齐」时进入;单一/增量任务请跳「技能路由」。
138
138
  > 加载子技能 `yida-app`,由它负责完整应用 workflow、阶段子技能加载、关键 ID 流转、PRD 与 schema cache 约束。
139
- > 用户说“按默认方案 / 不要追问 / 直接创建 / 尽快搭建”时,`yida-app` 选择 `fast_build`:先解析并复用已有资源,只创建缺失且允许创建的应用/表单/页面,最后发布并输出链接。
139
+ > 用户说“按默认方案 / 不要追问 / 直接创建 / 尽快搭建”时,`yida-app` 选择 `fast_build`:先解析并复用已有资源,只创建缺失且允许创建的应用/表单/页面,最后发布并输出链接;链接较多时用表格集中展示。
140
140
  > `yida-app fast_build` 使用常规 OpenYida 命令编排。
141
141
 
142
- **默认链路**:`fast_build` 必须只做 `resolve app → reserve main page → resolve forms → 编写/更新主页面源码 → 发布 → 返回访问链接`。若需要首页/工作台/智能助手/门户门面且主页面缺失,先创建空 display page 占位,再建表单,最后回填发布;不要因此默认执行导航重排。不要因为应用名里有“看板 / 系统 / 管理”就升级到 `deep_design` 或 `full_demo`。
142
+ **默认链路**:`fast_build` 必须只做 `resolve app → reserve main page → resolve forms → 编写/更新主页面源码 → 发布 → 返回访问链接/资源表格`。若需要首页/工作台/智能助手/门户门面且主页面缺失,先创建空 display page 占位,再建表单,最后回填发布;不要因此默认执行导航重排。不要因为应用名里有“看板 / 系统 / 管理”就升级到 `deep_design` 或 `full_demo`。
143
143
 
144
- **fast_build 默认加载边界**:只加载 `yida-app` 和当前阶段必需的子技能。`yida-create-app`、`yida-create-page`、`yida-create-form-page` 只有在目标资源缺失且本次意图允许创建时才加载;已有资源时进入对应 update / publish 分支。页面默认走 Code Canvas;当用户明确要求普通自定义页面 JSX/Jsx 组件链路,或页面强依赖普通自定义页实例桥(`this.$(fieldId)` / `this.utils.yida.*` / `this.dataSourceMap` / 表单提交或字段双向绑定深度耦合)时,选择 `yida-custom-page`。不要默认加载 `yida-page-uiux`、`yida-data-source-connectors`、`yida-data-management`、`yida-nav-group`、`yida-dashboard`,也不要默认深读 `references/`。
144
+ **fast_build 默认加载边界**:只加载 `yida-app` 和当前阶段必需的子技能。`yida-create-app`、`yida-create-page`、`yida-create-form-page` 只有在目标资源缺失且本次意图允许创建时才加载;已有资源时进入对应 update / publish 分支。主页面生成阶段包含一次 `yida-page-uiux` 轻量 UI 引导(页面类型、模板路由、`visualProfile`、去 sample 化检查),再交给页面实现技能;这不等于升级 `deep_design`,不得顺带做长 PRD、应用蓝图、导航整理或截图验收。页面默认走 Code Canvas;当用户明确要求普通自定义页面 JSX/Jsx 组件链路,或页面强依赖普通自定义页实例桥(`this.$(fieldId)` / `this.utils.yida.*` / `this.dataSourceMap` / 表单提交或字段双向绑定深度耦合)时,选择 `yida-custom-page`。不要默认加载 `yida-app-uiux`、`yida-data-source-connectors`、`yida-data-management`、`yida-nav-group`、`yida-dashboard`,也不要默认深读 `references/`。
145
145
 
146
146
  **Canvas 数据边界**:完整应用/真实交付页如果展示列表、看板或详情记录,必须优先把本轮真实 `appType/formUuid/fieldId` 写入 `page-spec.json` 的 `dataBinding.mode=form`;需要演示记录时先写入真实表单再读取。未接真实表单且未写入 demo records 时,页面展示空态/入口,不用前端 seedRows 冒充业务数据。
147
147
 
@@ -151,7 +151,7 @@ OpenYida builder 默认使用 `create-app / create-form / create-page / generate
151
151
 
152
152
  **doneWhen**:`yida-app` 发布主页面成功并输出可访问 URL。到这里默认完成;不要发布后继续 TaskCreate、重复读技能或继续规划。
153
153
 
154
- **optionalAfterDone**:导航整理、示例数据、公开访问、截图验证、深度视觉方向、数据源/连接器深度接入、报表/大屏,只在用户明确要求或 `yida-app` 模式为 `full_demo` / `deep_design` 时执行。
154
+ **optionalAfterDone**:导航整理、示例数据、公开访问、截图验证、应用级体验蓝图、深度视觉扩展、数据源/连接器深度接入、报表/大屏,只在用户明确要求或 `yida-app` 模式为 `full_demo` / `deep_design` 时执行。
155
155
 
156
156
  ---
157
157
 
@@ -239,7 +239,7 @@ OpenYida builder 默认使用 `create-app / create-form / create-page / generate
239
239
  1. **按阶段加载必要技能**:按意图选 1 个主技能;完整应用按阶段加载当下唯一需要的子技能,禁止并发批量读取多个 `SKILL.md` 或预读未来阶段技能。
240
240
  2. **Resource-First**:任何写操作前先解析本轮显式资源、agent bound context、workspace cache/config、历史上下文;已有目标资源时默认修改/补齐/发布,只有目标缺失且意图允许创建时才加载 create 类技能。
241
241
  3. **优先复用本地 ID 映射**:已有 `.cache/<项目名>-schema.json` 中可确认新鲜的 `appType`/`formUuid`/`fieldId` 可复用;该文件不是远端真相。字段级表单操作优先交给 `create-form update/add-option/bind-datasource/validation/rule` 的 schema-aware 解析,不要求先外部 `get-schema`;若 CLI 返回字段不存在/重名/歧义 diagnostics,再按 candidates、`tableLabel`、已知 `fieldId` 或 `get-schema --compact --resolve-fields` 收敛。页面代码、数据、流程、公式等确实需要多字段/多表单映射时,每表单一次性执行 `get-schema --field-map-json` 并缓存完整字段摘要。不得猜测字段 ID,也不要用 `head`/`tail`/`grep` 截断 schema stdout 当证据。
242
- 4. **模板优先**:复杂产物先用 `openyida sample` 或现有示例生成骨架,再做最小改动。
242
+ 4. **模板骨架优先,业务化先行**:复杂产物可用 `openyida sample` 或 `generate-page` 生成可编译骨架,但真实业务页必须先有业务化 `page-spec.json` 和 `yida-page-uiux` 视觉方向决策;sample 的品牌、文案、指标、图片和 section 顺序不得直接作为最终页。
243
243
  5. **配置承载优先于代码**:字段/公式/联动/报表/审批/集成交给对应技能,自定义页面只做展示与胶水。
244
244
  6. **数据性能优先**:统计聚合用 `yida-report` 服务端聚合,不在前端拉全量后自行聚合。
245
245
  7. **避免无效重试**:失败先查登录态/组织/参数/字段 ID,无修改不连续重试超 1 次。
@@ -248,9 +248,10 @@ OpenYida builder 默认使用 `create-app / create-form / create-page / generate
248
248
  10. **报表美化先分流**:标准统计与原生报表用 `yida-report`;定制图表页面默认用 `yida-rechart`;只有明确 ECharts、维护旧 ECharts 页面或复杂 option 超出 Recharts 能力时用 `yida-chart`。
249
249
  11. **按 schema 证据选技能**:先看 `formType`、组件树、`dataSource.online`;`receipt/process/report` 分别落到表单/流程/报表技能。
250
250
  12. **官方示例范式优先**:蒸馏官方示例时先理解脱敏 schema 承载方式,不凭截图/标题/视觉判断。
251
- 13. **默认完成即停止**:完整应用默认以发布成功并输出 URL 为 doneWhen;UIUX、数据源深读、示例数据、导航、截图、TaskCreate 和深度设计都是 optionalAfterDone。
251
+ 13. **默认完成即停止**:完整应用默认以发布成功并输出 URL 为 doneWhen;默认轻量页面 UI 引导只服务于本轮主页面生成。应用级 UIUX、数据源深读、示例数据、导航、截图、TaskCreate 和深度设计都是 optionalAfterDone。
252
252
  14. **主题技能优先**:涉及应用主题色、品牌色、全局换肤或 `--color-brand1-*` 时先读 `yida-theme`;表单和页面只消费主题,不要在局部 Schema/JSX 中随意写死蓝色/紫色等品牌色。
253
- 15. **任务复盘沉淀**:任务完成前判断是否有可复用经验需要落盘到 CLI、测试、sample 或 skill。用户多次纠正、平台接口假成功、sample 共性质量问题、线上回读验收方法、一次性脚本可产品化等情况必须沉淀;详见 `references/task-retrospective.md`。
253
+ 15. **链接多时表格输出**:最终结果里 3 个及以上资源或链接时,用 Markdown 表格集中展示(资源类型、名称/用途、链接、状态),不要连续堆 URL。
254
+ 16. **任务复盘沉淀**:任务完成前判断是否有可复用经验需要落盘到 CLI、测试、sample 或 skill。用户多次纠正、平台接口假成功、sample 共性质量问题、线上回读验收方法、一次性脚本可产品化等情况必须沉淀;详见 `references/task-retrospective.md`。
254
255
 
255
256
  > 📖 每条规则的完整说明、PRD 质量门槛、临时文件路径规范、报表美化话术 → [references/development-rules.md](references/development-rules.md)
256
257
 
@@ -23,7 +23,7 @@
23
23
  |---|------|---------|
24
24
  | 1 | 按阶段加载必要技能 | 按意图选定 1 个主技能;完整应用按阶段加载当下唯一需要的子技能,仅在已加载技能明确要求时才读对应 `references/`。 |
25
25
  | 2 | 优先复用缓存 | `appType`/`formUuid`/`fieldId`/`reportId` 先从 `.cache/<项目名>-schema.json` 读,缺失或不确定再 `openyida get-schema`。 |
26
- | 3 | 模板优先 | 自定义页面、表单字段、报表配置等复杂产物先用 `openyida sample` 或现有示例生成骨架,再做最小改动。 |
26
+ | 3 | 模板骨架优先,业务化先行 | 自定义页面、表单字段、报表配置等复杂产物可用 `openyida sample` 或现有示例生成可编译骨架;真实业务页必须先有业务化 `page-spec.json` 和 `yida-page-uiux` 视觉方向决策,sample 的品牌、文案、指标、图片和 section 顺序不得直接作为最终页。 |
27
27
  | 4 | 配置承载优先于代码 | 字段结构/公式/联动/报表聚合/审批/集成/连接器动作交给对应技能承载;自定义页面代码只做展示、事件分发和必要胶水。 |
28
28
  | 5 | 数据性能优先 | 统计聚合用 `yida-report` 服务端聚合;不在自定义页面前端分页拉全量后自行聚合。 |
29
29
  | 6 | 避免无效重试 | 失败先按错误信息查登录态/组织/参数/字段 ID;无修改不连续重试超 1 次。 |
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: yida-app
3
- description: 宜搭完整应用开发编排技能。对普通 OpenYida 应用做完整搭建或补齐时使用;默认走 fast_build,先解析资源上下文,再创建缺失资源、更新主页面并发布输出链接。
3
+ description: 宜搭完整应用开发编排技能。对普通 OpenYida 应用做完整搭建或补齐时使用;默认走 fast_build,先解析资源上下文,再创建缺失资源、更新主页面并发布;结果链接较多时用表格输出。
4
4
  ---
5
5
 
6
6
  # yida-app — 完整应用编排契约
@@ -13,7 +13,7 @@ description: 宜搭完整应用开发编排技能。对普通 OpenYida 应用做
13
13
 
14
14
  用户说“按默认方案”“不要追问”“直接创建”“尽快搭建”等,必须选择 `fast_build`,用合理 MVP 假设直接执行,不展开深度 PRD 讨论。
15
15
 
16
- **默认判定**:完整应用搭建或补齐时,用户表达“默认方案 / 不要追问 / 直接创建 / 尽快搭建”等快速交付信号,就命中 `fast_build`。默认链路:`resolve app → reserve main page → resolve forms → 编写/更新主页面源码 → 发布 → 返回访问链接`。
16
+ **默认判定**:完整应用搭建或补齐时,用户表达“默认方案 / 不要追问 / 直接创建 / 尽快搭建”等快速交付信号,就命中 `fast_build`。默认链路:`resolve app → reserve main page → resolve forms → 编写/更新主页面源码 → 发布 → 返回访问链接/资源表格`。
17
17
 
18
18
  > 资源边界:本技能是默认完整应用编排。目标不明时先只读确认或询问用户。
19
19
 
@@ -53,7 +53,7 @@ description: 宜搭完整应用开发编排技能。对普通 OpenYida 应用做
53
53
  | `full_demo` | 用户明确要演示完整、示例数据、导航整理、可点验收 | 在 `fast_build` 后补导航、示例数据、公开访问或截图 |
54
54
  | `deep_design` | 用户明确要深度产品设计、视觉方向、多角色、多页面、复杂流程 | 先做详细 PRD/应用体验蓝图/视觉决策,再执行多阶段搭建 |
55
55
 
56
- 默认不要把 `full_demo` / `deep_design` 的动作塞进 `fast_build`。不要因为用户说“看板”“系统”“管理”就自动加载视觉决策、数据源、示例数据、导航整理或截图验收。
56
+ 默认不要把 `full_demo` / `deep_design` 的动作塞进 `fast_build`。主页面生成链路固定包含 `yida-page-uiux` 轻量 UI 引导,只用于页面类型、模板路由、`visualProfile` 和去 sample 化检查;不要因为用户说“看板”“系统”“管理”就自动加载应用蓝图、数据源、示例数据、导航整理或截图验收。
57
57
 
58
58
  ## 预检
59
59
 
@@ -81,15 +81,17 @@ description: 宜搭完整应用开发编排技能。对普通 OpenYida 应用做
81
81
  [Step 5](按需)配置流程 → use_skill("yida-create-process", "创建带审批流程表单")
82
82
  ↓ 需求含“审批 / 流程 / 申请 / 审核 / 工单”等关键词时执行
83
83
  ↓
84
- [Step 6] 编写自定义页面代码 → 默认 use_skill("yida-canvas-custom-page", "生成 Code Canvas 主页面")
85
- ↓ 先写业务化 page-spec.json,再 openyida generate-page <模板> --theme-profile yida-app-theme --theme-scope page --spec <page-spec.json> --compile
84
+ [Step 6] 编写自定义页面代码 → 默认 use_skill("yida-page-uiux", "主页面 UI 引导")
85
+ ↓ 产出简短视觉方向决策块:页面类型、模板路由、visualProfile、去 sample 化检查
86
+ ↓ 再 use_skill("yida-canvas-custom-page", "生成 Code Canvas 主页面")
87
+ ↓ 先把视觉方向和业务对象写入 page-spec.json,再 openyida generate-page <模板> --theme-profile yida-app-theme --theme-scope page --spec <page-spec.json> --compile
86
88
  ↓ 字段映射优先来自 create/update 命令输出和 `.cache/<项目名>-schema.json`;同一表单不要重复 get-schema,除非页面/数据链路确实需要 fieldId 且缓存不完整
87
89
  ↓ 本轮已创建/解析业务表单且页面需要列表/看板/详情数据时,必须在 spec.dataBinding 写 mode=form + 真实 appType/formUuid/fieldId;深度接入再加载 yida-canvas-data-binding
88
90
  ↓ 明确要求普通自定义页面 JSX/Jsx 组件链路,或强依赖 this.$ / this.utils.yida.* / this.dataSourceMap 等实例桥时选择 yida-custom-page
89
91
  ↓
90
92
  [Step 7] 发布页面 → use_skill("yida-publish-page", "发布主页面") → openyida publish <源文件路径> <appType> <formUuid> [--health-check]
91
93
  ↓
92
- [Step 8] 输出访问链接和资源摘要 → 默认完成
94
+ [Step 8] 输出访问链接/资源表格和资源摘要 → 默认完成
93
95
  ```
94
96
 
95
97
  `full_demo` / `deep_design` 才在 Step 7 后追加导航整理、示例数据、公开访问、截图验收、报表/大屏、数据桥深度接入等动作。
@@ -100,11 +102,11 @@ UI 不是独立替代主流程的步骤,而是按模式插入到页面生成
100
102
 
101
103
  | 模式 | UI/体验怎么集成 | 加载策略 |
102
104
  |------|----------------|----------|
103
- | `fast_build` | 在 Step 6 通过 Code Canvas 场景模板、`yida-app-theme`、基础工作台/看板/列表布局完成;不做长视觉推演 | 默认不加载 `yida-page-uiux` / `yida-app-uiux` / `yida-theme`;页面主色跟随应用主题 token |
105
+ | `fast_build` | Step 6 包含 `yida-page-uiux` 轻量视觉方向决策块,再通过 Code Canvas 场景模板、`yida-app-theme`、业务化 page spec 和基础工作台/看板/列表布局完成;不做长视觉推演 | 默认加载 `yida-page-uiux` 作为 ui_skill 引导;不默认加载 `yida-app-uiux` / `yida-theme`;页面主色跟随应用主题 token |
104
106
  | `full_demo` | 在发布后按用户要求补导航、示例数据、截图、公开访问,让页面可演示 | 只加载命中的后置技能,如 `yida-nav-group`、`yida-data-management`、`yida-page-config` |
105
107
  | `deep_design` | 先做应用体验蓝图和页面视觉方向,再生成页面 | 加载 `yida-app-uiux` 规划角色路径/页面组合/导航分组/门面/壳形态;加载 `yida-page-uiux` 产出页面视觉方向决策块;涉及全局主题时加载 `yida-theme` |
106
108
 
107
- 首次生成面向用户的复杂页面,如果用户明确要求“好看 / 去 AI 味 / 高级视觉 / 品牌化 / 多页面体验”,先用 `use_skill("yida-page-uiux", "确定页面视觉方向")` 产出视觉方向决策块,再交给 `yida-canvas-custom-page` 落地。普通 `fast_build` 不因“系统 / 管理 / 看板”这些词自动升级到视觉深设计。
109
+ 首次生成面向用户的主页面时,默认执行 `use_skill("yida-page-uiux", "主页面 UI 引导")` 产出紧凑决策块,再交给 `yida-canvas-custom-page` 或 `yida-custom-page` 落地。用户明确要求“好看 / 去 AI 味 / 高级视觉 / 品牌化 / 多页面体验”时,可以把该决策块做得更完整;只有用户要求多角色、多页面体验蓝图或深度产品设计时,才升级 `deep_design` 并加载 `yida-app-uiux`。
108
110
 
109
111
  ## 页面链路原则
110
112
 
@@ -134,6 +136,8 @@ UI 不是独立替代主流程的步骤,而是按模式插入到页面生成
134
136
  - `visualProfile`:写一个区别于 sample 的视觉方向,例如信息密度、构图节奏、强调色来源、图表/列表/队列母题。
135
137
  - 官网/品牌页还必须写 `assets` 或明确素材缺口;看板/列表/详情页优先写 `dataBinding`、字段映射或表单链接。
136
138
 
139
+ `visualProfile` 应来自 `yida-page-uiux` 的视觉方向决策块或本轮业务语义推导;不能沿用模板默认 tone、默认 section 节奏或 sample 品牌风格来假装已经业务化。
140
+
137
141
  生成后检查命令输出和 `.openyida-page.json` 里的 `domainFidelity.status`:只有 `domain-ready` 才能把 sample 视为“只是骨架”。`sample-reference` 或 `draft-needs-domain-spec` 表示仍有 sample fallback,必须继续补 page spec 或改源码,不能对用户声称已完成业务化页面。
138
142
 
139
143
  ## 模板优先
@@ -172,11 +176,17 @@ UI 不是独立替代主流程的步骤,而是按模式插入到页面生成
172
176
  | 2. 记录最小需求 | 无 | 写 `prd/<项目名>.md`:只记录 MVP 假设、核心表单/页面、完成标准;写/更新 `.cache/<项目名>-schema.json` 本地 ID 映射;不要写长 PRD | 业务语义和 ID 存储位置明确 |
173
177
  | 3. reserve main page | `yida-create-page` 仅在主页面缺失且允许创建时加载 | 已有页面 URL / `formUuid` / bound page 时直接作为主页面;若需要首页/工作台/智能助手/门户门面且缺少主页面,先创建空 display page 占位,暂不写最终源码 | 拿到真实主页面 `formUuid`,且不会重复创建页面 |
174
178
  | 4. resolve forms | `yida-create-form-page` | 已有目标表单时 update/patch/rule/bind-datasource;简单字段属性更新直接用 compact changes 让 CLI 内部按 label 读 schema/定位字段并输出 resolved evidence;缺少支撑 MVP 的核心表单且允许创建时才 create;字段配置文件写入 `.cache/openyida/<项目名>/`;页面/数据/流程/公式确需多字段映射时,对每个目标表单最多一次性获取完整 `--field-map-json` 并合并写回 `.cache/<项目名>-schema.json` | 拿到或确认表单 `formUuid`,并在需要时拿到真实 `fieldId` |
175
- | 5. 编写/更新页面 | 默认 `yida-canvas-custom-page`;明确要求 JSX/Jsx 组件链路或实例桥强依赖时选择 `yida-custom-page` | 生成或修改主页面源码;只实现 MVP 首屏和核心操作。可用已解析表单链接、真实空态、表单入口和轻量指标口径完成主页面;若展示业务列表/看板/详情记录,必须接本轮真实表单 `dataBinding.mode=form`,或先写入 demo records 后再读取;不要加载视觉/密度/报表/数据源等额外技能 | 本地源码通过对应页面技能的基础校验;未执行 publish 时仍是“源码已修改,尚未发布” |
179
+ | 5. 编写/更新页面 | 主页面生成阶段包含 `yida-page-uiux` 轻量 UI 引导,再 `yida-canvas-custom-page`;明确要求 JSX/Jsx 组件链路或实例桥强依赖时选择 `yida-custom-page` | 先产出页面类型、模板路由、`visualProfile` 和去 sample 化检查,再生成或修改主页面源码;只实现 MVP 首屏和核心操作。可用已解析表单链接、真实空态、表单入口和轻量指标口径完成主页面;若展示业务列表/看板/详情记录,必须接本轮真实表单 `dataBinding.mode=form`,或先写入 demo records 后再读取;不要加载密度/报表/数据源等额外技能 | 本地源码通过对应页面技能的基础校验;未执行 publish 时仍是“源码已修改,尚未发布” |
176
180
  | 6. 发布页面 | `yida-publish-page` | 按页面链路校验后发布到已解析主页面:Canvas `.canvas.jsx` 使用 `openyida publish` 的 Canvas 编译阶段或 `compileCanvasLocal` 快检;普通自定义页面 `.oyd.jsx` / `.jsx` 跑 `check-page` / `compile`;再执行 `openyida publish <source> <appType> <displayPageFormUuid>` 发布主页面 | 发布成功并获得可访问 URL |
177
- | 7. 输出结果 | 无 | 返回应用链接、主页面链接、复用/创建/更新的资源摘要、后续可选项 | 用户拿到 URL |
181
+ | 7. 输出结果 | 无 | 返回应用链接、主页面链接、复用/创建/更新的资源摘要、后续可选项;若本轮输出 3 个及以上资源或链接,必须用 Markdown 表格集中展示 | 用户能一眼区分每个链接用途 |
182
+
183
+ 主页面生成默认包含一次轻量 `yida-page-uiux` 页面引导;除此之外不默认执行:`yida-app-uiux`、`yida-canvas-data-binding`、`yida-data-source-connectors`、`yida-data-management`、`yida-nav-group`、`yida-dashboard`、导航重排、示例数据、截图验收、公开访问配置、深度 UI 设计、长 PRD、TaskCreate / 继续规划任务,也不默认读取 `references/app-build-contract.md`。
184
+
185
+ ## 结果输出格式
178
186
 
179
- `fast_build` 不默认执行:`yida-page-uiux`、`yida-app-uiux`、`yida-canvas-data-binding`、`yida-data-source-connectors`、`yida-data-management`、`yida-nav-group`、`yida-dashboard`、导航重排、示例数据、截图验收、公开访问配置、深度 UI 设计、长 PRD、TaskCreate / 继续规划任务,也不默认读取 `references/app-build-contract.md`。
187
+ - 1-2 个链接:可用简短列表输出,但要标清资源类型和用途。
188
+ - 3 个及以上资源或链接:必须用 Markdown 表格,建议列为 `资源类型 | 名称/用途 | 链接 | 状态`,不要把 URL 连续堆成多行纯文本。
189
+ - 表格里只放真实命令返回或已验证推导的链接;不确定、未发布或仅本地修改的资源,在 `状态` 列标注“未发布 / 待验证 / 本地已修改”。
180
190
 
181
191
  ## 关键决策树
182
192
 
@@ -249,11 +259,11 @@ UI 不是独立替代主流程的步骤,而是按模式插入到页面生成
249
259
  进入 `deep_design` 时,可以读取 [详细编排参考](references/app-build-contract.md),并按需加载:
250
260
 
251
261
  - `yida-app-uiux`:多页面应用体验蓝图、角色路径、页面组合、导航分组、应用门面、壳形态、主题策略。
252
- - `yida-page-uiux`:单点页面视觉方向、去 AI 味、页面类型和模板路由决策。
262
+ - `yida-page-uiux`:单点页面视觉方向、去 AI 味、页面类型和模板路由决策;`fast_build` 默认以轻量方式加载,`deep_design` 时可扩展完整决策。
253
263
  - `yida-theme`:应用主题色、品牌色、全局换肤和运行态主题 token。
254
264
  - `yida-density`、`yida-dashboard`、`yida-canvas-data-binding`、`yida-data-source-connectors`:仅在具体需求命中时加载。
255
265
 
256
- 不要在 `fast_build` 中默认读取这些参考或技能。
266
+ 除 `yida-page-uiux` 的轻量引导外,不要在 `fast_build` 中默认读取这些参考或技能。
257
267
 
258
268
  ## 完成条件
259
269
 
@@ -80,7 +80,7 @@ PRD 只记录业务语义,不记录 `formUuid`、`fieldId` 等 Schema ID;真
80
80
 
81
81
  - 默认使用 `yida-canvas-custom-page`:现代 React 交互、hooks、可视化、开放 API 读数据、AI 生成页面。
82
82
  - 仅当强依赖原生实例数据桥时使用 `yida-custom-page`:`this.$(fieldId)`、`this.utils.yida.*`、`dataSourceMap`、提交流程或设计器数据源深度耦合。
83
- - 视觉方向、密度、看板技能只在用户要求深度设计、看板产品化或 `deep_design` 时加载。
83
+ - `fast_build` 页面阶段默认先加载 `yida-page-uiux` 做轻量视觉方向决策;密度、看板产品化、应用蓝图、主题深设等技能只在用户要求深度设计、看板产品化或 `deep_design` 时加载。
84
84
 
85
85
  ## 常用 URL
86
86
 
@@ -7,7 +7,7 @@ description: 宜搭 Code Canvas / 代码画布自定义页面开发规范,是
7
7
 
8
8
  ## 核心定位
9
9
 
10
- Code Canvas 是宜搭的代码画布自定义页面链路:以 `YidaCodeCanvas` 物料为承载,用户写标准 React18 函数组件源码,OpenYida 本地编译为 `runtimeCode` + `importedModules`,运行时按依赖白名单加载资源并执行 `YidaComp`。
10
+ Code Canvas 是宜搭的代码画布自定义页面链路:用户写标准 React18 函数组件源码,OpenYida 本地编译为 `runtimeCode` + `importedModules`,运行时由 `YidaCodeCanvas` 加载前端资源并执行 `YidaComp`。
11
11
 
12
12
  相较普通 `.oyd.jsx` 自定义页,Code Canvas 更适合:
13
13
 
@@ -25,11 +25,11 @@ Code Canvas 是宜搭的代码画布自定义页面链路:以 `YidaCodeCanvas`
25
25
  - 页面源码路径按 Bash cwd 选择:从仓库根执行命令时用 `project/pages/src/...`;cwd 已是 `<workspace>/project` 时用 `pages/src/...`。
26
26
  - `runtimeCode` 在宿主页真实 `window` 中执行,入口必须返回 `YidaComp` / `YidaComp.default` / 组件函数。
27
27
  - 推荐入口写法是 `function YidaComp(props) { ... }`,或 `const App = ...; export default App;`。CLI 已兼容 `const/let/class YidaComp; export default YidaComp`,但生成新代码时优先避开同名默认导出,减少不同 Canvas 运行态装配器下的重复声明风险。
28
- - Canvas 组件没有普通页面实例上下文;数据读写通过 fetch、开放 API、连接器代理或显式 props 数据桥完成。
29
- - 第三方依赖走白名单;React、antd、ahooks、d3、recharts、Radix、framer-motion 等可按规则 import。
30
- - 宜搭运行态组件通过“先探测、可用再增强、不可用就 fallback、值统一归一化”接入;以 `window.Deep` / `window.DeepYida` 探测为主,`window.YidaNativeComponents` 作为兼容入口。嵌入门户数据管理视图时使用 `DataManageViews`,并显式传入目标表单 `form.value/formUuid`。
28
+ - Canvas 组件使用 React 函数组件上下文;数据读写通过 fetch、开放 API、连接器代理或显式 props 数据桥完成。
29
+ - 第三方前端资源只从可用资源清单中选择;React、antd、ahooks、d3、recharts、Radix、framer-motion、lucide-react 等可按规则 import。
30
+ - 宜搭运行态组件按“先探测、可用增强、fallback 保底、值统一归一化”接入;以 `window.Deep` / `window.DeepYida` 探测为主,`window.YidaNativeComponents` 作为兼容入口。嵌入门户数据管理视图时使用 `DataManageViews`,并显式传入目标表单 `form.value/formUuid`。
31
31
 
32
- > 依赖白名单和运行时细节见 [dependencies-and-cdn.md](references/dependencies-and-cdn.md) 与 [employeefield-verification.md](references/employeefield-verification.md)。
32
+ > 可用资源清单和运行时细节见 [dependencies-and-cdn.md](references/dependencies-and-cdn.md) 与 [employeefield-verification.md](references/employeefield-verification.md)。
33
33
 
34
34
  ## 使用决策
35
35
 
@@ -39,7 +39,7 @@ Code Canvas 是宜搭的代码画布自定义页面链路:以 `YidaCodeCanvas`
39
39
  | 需要开放 API / 连接器读写数据 | 使用本技能,在 `YidaComp` 内自建 HTTP 数据桥 |
40
40
  | 需要门户 topBanner / quickEntry / 数据卡片 | 使用本技能,按“门户组件桥”接入,必要时 fallback 自绘 |
41
41
  | 需要成员、部门、附件上传、图片上传 | 使用本技能,按“宜搭组件桥”接入并归一化值 |
42
- | 需要字段结构、公式、联动、权限、报表、流程 | 使用对应配置型技能承载,Canvas 只做展示和事件分发 |
42
+ | 需要字段结构、公式、联动、权限、报表、流程 | 使用对应配置型技能完成配置,Canvas 展示结果并分发页面事件 |
43
43
  | 深度依赖普通页 `this` 实例桥 | 使用 `yida-custom-page` |
44
44
  | 表单内字段双向绑定 `this.$(fieldId)`、`this.utils.yida.*`、`dataSourceMap`、提交流程深度耦合 | 使用 `yida-custom-page`(该实例桥由普通自定义页面提供) |
45
45
 
@@ -78,7 +78,7 @@ openyida sample yida-canvas-custom-page portal-native-components --output projec
78
78
  - `DepartmentSelectField`:验证部门搜索、弹层、权限提示、单选/多选后启用。
79
79
  - `AttachmentField` / `ImageField`:验证 OSS 签名、上传权限、预览、删除、失败提示后启用。
80
80
 
81
- 做法:原生组件负责交互输入;页面业务状态保存归一化后的成员、部门、文件结构;提交通过 fetch / 连接器 / 开放 API 完成。组件验证通过时使用原生组件;验证未通过时使用 Canvas 自绘输入、搜索或链接录入。
81
+ 做法:原生组件处理交互输入;页面业务状态保存归一化后的成员、部门、文件结构;提交通过 fetch / 连接器 / 开放 API 完成。组件验证通过时使用原生组件;组件条件不足时使用 Canvas 自绘输入、搜索或链接录入。
82
82
 
83
83
  > 详细桥接规则、值结构和验收清单见 [native-components-bridge.md](references/native-components-bridge.md)。
84
84
 
@@ -89,7 +89,7 @@ openyida sample yida-canvas-custom-page portal-native-components --output projec
89
89
  1. **Canvas 入口明确**:源码必须导出或返回 `YidaComp`,并把主组件作为默认导出或 `YidaComp` 暴露。
90
90
  2. **发布链路正确**:Canvas 源码使用 `.canvas.jsx` / `.canvas.tsx`,或发布时显式加 `--canvas`。
91
91
  3. **源码修改发布闭环**:本轮 Write/Edit/Create 了 `project/pages/src/*.canvas.jsx` 或 `project/pages/src/*.canvas.tsx` 后,final 前需要成功执行 `openyida publish <source> <appType> <displayPageFormUuid>`。有 publish 成功证据时表述为“页面已发布”;只有本地校验证据时表述为“Canvas 源码已修改,尚未发布”。
92
- 4. **依赖可加载**:普通 import 只使用 Code Canvas 白名单依赖;宜搭运行态组件走原生组件桥。
92
+ 4. **依赖可加载**:普通 import 只使用 Code Canvas 可用资源清单内的前端资源;宜搭运行态组件走原生组件桥。
93
93
  5. **使用 Canvas 函数组件契约**:Canvas 代码写 `YidaComp` React 函数组件;数据、生命周期和渲染都通过 hooks、props、fetch/连接器完成。需要 `renderJsx()`、`didMount()`、`this.forceUpdate()`、`this.utils.yida.*`、`this.dataSourceMap` 时切到 `yida-custom-page`。
94
94
  6. **副作用清理**:`useEffect` 注册事件、定时器、图表实例时必须返回 cleanup。
95
95
  7. **交互控件必须受控且真正驱动数据**:筛选 `Select`、搜索 `Input`/`Input.Search`、周期切换、`Tabs`/`Segmented`、批量/重置 `Button` 等控件都用 `useState` 建立受控状态,绑定 `onChange`/`onClick`,并让 `Table`/列表/卡片的数据源通过 `useMemo` 按状态派生后渲染。切换筛选后若当前选中项失效,回退选中态(如 `selected < filteredRows.length ? selected : 0`)。
@@ -98,23 +98,24 @@ openyida sample yida-canvas-custom-page portal-native-components --output projec
98
98
 
99
99
  1. **数据桥显式化**:通过 fetch、连接器或开放 API 读写数据;Cookie、CSRF、密钥和签名留在平台、连接器或后端服务侧。
100
100
  2. **组件增强可降级**:门户、成员、部门、上传组件都做 feature detect 和 fallback;组件缺失时页面仍展示 Canvas 自绘基线。
101
- 3. **值先归一化**:成员、部门、文件的原始返回值只作为 `raw` 检查信息,业务 payload 使用统一结构。
101
+ 3. **值先归一化**:成员、部门、文件的原始返回值保留到 `raw` 用于检查,业务 payload 使用统一结构。
102
102
  4. **业务页主色跟随应用主题,sample 例外**:真实业务页默认读取 `--color-brand1-*` 与 `--color-group`;`lib/samples/**` 和官方 sample 展示应用自带页面级固定主题(`followRuntimeTheme: false` 或等价 CSS 变量),每个 sample 使用不同色相。
103
- 5. **先验证再扩展业务**:原生组件、上传、组织搜索、弹层类能力先做 smoke 页面,确认 PC/移动端都可用后再承载复杂业务。
103
+ 5. **先验证再扩展业务**:原生组件、上传、组织搜索、弹层类能力先做 smoke 页面,确认 PC/移动端都可用后再进入复杂业务页面。
104
104
  6. **模板占位符必须可直发**:Canvas sample / generate-page 模板同时支持“生成器替换变量”和“sample 原样发布”。JSON 占位符用 `parseTemplateJson(raw, fallback)`,展示文案占位符用 `withFallback` / `applyPageFallbacks` 兜底,未替换时页面继续可运行,并显示业务化 fallback 文案。
105
105
  7. **light 页面使用清爽业务色**:业务列表、协同表、数据管理页、工作台和门户默认使用 light 模式;主操作、选中态、筛选焦点和批量操作使用品牌色或 sample 自带主题色,边框用浅色品牌混合。用户明确要求暗色大屏/夜间模式/高对比风格时使用深色主视觉。
106
106
  8. **门户运行态组件要补必需 props 和局部降级**:`QuickAccessCard` / `RecentlyUsedCard` 传 `theme="row-white"` 等必需 props;所有门户/字段/上传增强组件外层加局部 ErrorBoundary,单个组件不兼容时只降级该块,整页保持可用。
107
107
  9. **自定义主题必须页面内注入**:`--theme` 只接受平台预置 key;页面设计使用非预置主题(例如活力橙、深玫红、自定义暗黑金)时,在 Canvas 源码中注入 `style#yida-global-theme` 或等价 scoped CSS vars,并在根节点设置 `data-theme-scope="page"`。官方 sample 每个页面都做页面级主题注入。
108
- 10. **真实交付使用真实数据源**:`openyida sample` 原样发布可以保留 sample/seed 数据,并在页面上标注为 sample/seed。完整应用或真实交付页只要需要列表、看板、详情记录,并且本轮已经创建/解析业务表单,就在 `page-spec.json` 写入 `dataBinding.mode=form`、真实 `appType/formUuid` 和字段映射,让页面从表单读取。需要演示数据时,先通过表单数据写入链路创建 demo/mock records,再由 Canvas 读取这些真实表单记录;没有真实数据时展示空态、表单入口、刷新/登记按钮。
109
- 11. **页面生成二选一**:模板路径先写 `page-spec.json`,执行 `openyida generate-page ... --spec ... --compile`,之后读取 CLI 摘要或 `.openyida-page.json` 判断 `domainFidelity` / dataBinding,并对生成源码做小范围 Edit/patch。手写路径直接 Write 最终 `.canvas.jsx` 并快检/发布。
110
- 12. **Canvas 产物使用纯文本业务文案**:`.canvas.jsx` 源码、模板 spec 会渲染到页面的文案、JS 注释、数据常量和产物文件路径都使用无 emoji 文本。`generate-page --compile`、`compileCanvasLocal` 或 `publish` 报 emoji 错误时,先改 spec/源码/路径,再重新校验发布。
108
+ 10. **真实交付使用真实数据源**:`openyida sample` 原样发布可以保留 sample/seed 数据,并在页面上标注为 sample/seed。完整应用或真实交付页只要需要列表、看板、详情记录,并且本轮已经创建/解析业务表单,就在 `page-spec.json` 写入 `dataBinding.mode=form`、真实 `appType/formUuid` 和字段映射,让页面从表单读取。需要演示数据时,先通过表单数据写入链路创建 demo/mock records,再由 Canvas 读取这些真实表单记录;真实数据暂未接入时展示空态、表单入口、刷新/登记按钮。
109
+ 11. **UI 决策块必须进入 page spec**:完整应用 `fast_build` 和真实交付页在生成页面前,先消费 `yida-page-uiux` 的视觉方向决策块,把页面类型、推荐模板、`visualProfile`、素材/图标策略、去 sample 化检查写进 `page-spec.json` 或手写实现备注。缺少决策块时,先用当前业务语义补一个紧凑决策;模板默认 tone、section 顺序、sample 品牌名和 sample 指标必须被当前业务语义替换。
110
+ 12. **页面生成二选一**:模板路径先写 `page-spec.json`,执行 `openyida generate-page ... --spec ... --compile`,之后读取 CLI 摘要或 `.openyida-page.json` 判断 `domainFidelity` / dataBinding,并对生成源码做小范围 Edit/patch。手写路径直接 Write 最终 `.canvas.jsx` 并快检/发布。
111
+ 13. **Canvas 产物使用纯文本业务文案**:`.canvas.jsx` 源码、模板 spec 会渲染到页面的文案、JS 注释、数据常量和产物文件路径都使用无 emoji 文本。`generate-page --compile`、`compileCanvasLocal` 或 `publish` 报 emoji 错误时,先改 spec/源码/路径,再重新校验发布。
111
112
 
112
113
  ## 数据真实性边界
113
114
 
114
115
  Canvas 模板有两种允许状态:
115
116
 
116
117
  - **Sample / 离线预览**:`openyida sample` 或模板原样发布可以显示内置 seedRows,页面必须标注 `sample/seed`,final 也要说明“当前为演示数据/未接真实表单数据”。
117
- - **完整应用 / 真实交付**:先解析真实 `appType/formUuid/fieldId`,写入 `page-spec.json` 的 `dataBinding.mode=form` 后再 `openyida generate-page ... --spec <page-spec.json>`。需要 demo/mock 记录时,先用数据写入链路把记录写入表单并抽查,再让页面读取;前端 seedRows、静态 DEFAULT_FEATURES 或固定指标只作为 sample 数据标注。
118
+ - **完整应用 / 真实交付**:先解析真实 `appType/formUuid/fieldId`,写入 `page-spec.json` 的 `dataBinding.mode=form` 后再 `openyida generate-page ... --spec <page-spec.json>`。需要 demo/mock 记录时,先用数据写入链路把记录写入表单并抽查,再让页面读取;前端 seedRows、静态 DEFAULT_FEATURES 或固定指标必须标注 sample 数据状态。
118
119
 
119
120
  生成后如果 `.openyida-page.json` 的 `dataBinding.enabled !== true`,且页面仍展示列表/看板/详情业务记录,交付状态标为 sample/draft;完整应用 final 只有在真实数据绑定已启用并验证后表述为“已接真实数据”。未接数据的交付页保留真实空态、登记入口、刷新按钮和数据接入提示。
120
121
 
@@ -210,10 +211,10 @@ openyida get-schema <appType> <formUuid> --field-map-json
210
211
  | --- | --- | --- |
211
212
  | [page-generation-guide.md](references/page-generation-guide.md) | 模板路由、官网素材、themeScope、Page Spec、primitives | 生成页面前必读 |
212
213
  | [native-components-bridge.md](references/native-components-bridge.md) | 门户、成员、部门、上传组件桥接和值归一化 | 需要宜搭运行态组件时必读 |
213
- | [dependencies-and-cdn.md](references/dependencies-and-cdn.md) | 依赖白名单、windowAlias、CDN 加载契约 | 新增依赖或验证依赖加载时必读 |
214
+ | [dependencies-and-cdn.md](references/dependencies-and-cdn.md) | 可用前端资源、import 写法、运行时加载契约 | 选择或验证前端资源时必读 |
214
215
  | [employeefield-verification.md](references/employeefield-verification.md) | 运行时事实、原生组件验证、EmployeeField 验收 | 验证成员/字段组件时阅读 |
215
216
  | [data-bridge-guide.md](references/data-bridge-guide.md) | Canvas 内自建 HTTP 数据桥 | 接入真实数据时阅读 |
216
217
  | [canvas-design-system.md](references/canvas-design-system.md) | App 主题色、antd token、控件焦点/下拉 reset、图表配色 | 写样式和主题时阅读 |
217
- | [component-library-guide.md](references/component-library-guide.md) | 开源组件库推荐组合和禁用清单 | 选择 UI/图表依赖时阅读 |
218
+ | [component-library-guide.md](references/component-library-guide.md) | 组件库推荐组合和页面选型建议 | 选择 UI/图表依赖时阅读 |
218
219
  | [canvas-authoring-examples.md](references/canvas-authoring-examples.md) | 最小组件、hooks、副作用、图表示例 | 手写 Canvas 代码时阅读 |
219
220
  | [真实品牌官网 Playbook](../yida-page-uiux/references/landing/realistic-brand-homepage.md) | 实景素材组、材质配色、品牌旅程、Sample 无 CDN 兜底和视觉验收 | 生成或改造强视觉官网时必读 |
@@ -1,12 +1,12 @@
1
1
  # Code Canvas 编写示例 / 脚手架
2
2
 
3
- 本文件是从零写 Code Canvas 页面的 vetted 模板集。所有示例都遵守运行时事实:`YidaComp` 是普通 React18 函数组件,必须**导出或返回** `YidaComp` / `YidaComp.default`;只 `import` 依赖白名单内的包;副作用在 `useEffect` 里注册并返回 cleanup。
3
+ 从零写 Code Canvas 页面时,入口使用普通 React18 函数组件 `YidaComp`,源码导出或返回 `YidaComp` / `YidaComp.default`;`import` 使用可用资源清单内的包;副作用在 `useEffect` 里注册并返回 cleanup。
4
4
 
5
- > 白名单、windowAlias 与 CDN 加载契约见 [dependencies-and-cdn.md](dependencies-and-cdn.md);读写宜搭数据见 [data-bridge-guide.md](data-bridge-guide.md)。
5
+ > 可用资源、import 写法与运行时加载契约见 [dependencies-and-cdn.md](dependencies-and-cdn.md);读写宜搭数据见 [data-bridge-guide.md](data-bridge-guide.md)。
6
6
 
7
7
  ## 1. 最小可运行组件(入口 + 本地状态)
8
8
 
9
- 最小骨架:明确入口导出、用 `useState` 管本地状态,不写任何普通页面契约(无 `renderJsx` / `didMount` / `this.*`)。
9
+ 最小骨架:明确入口导出,用 `useState` 管本地状态,生命周期和事件都写在 React hooks 内。
10
10
 
11
11
  ```jsx
12
12
  import React, { useState } from 'react';
@@ -60,7 +60,7 @@ export default YidaComp;
60
60
 
61
61
  ## 3. 可视化:recharts 图表
62
62
 
63
- `recharts` 在白名单内(windowAlias `Recharts`)。标准 `import` 即可,CLI 本地编译会把它计入 `importedModules`。图表容器给定高度,保证首屏可渲染。图表颜色是 JS 传给库的字符串,用 `readBrandColor` 读平台品牌色,让线条跟随 App 主题(见 [canvas-design-system.md](canvas-design-system.md))。
63
+ `recharts` 在可用资源清单内。标准 `import` 即可,CLI 本地编译会把它计入 `importedModules`。图表容器给定高度,保证首屏可渲染。图表颜色是 JS 传给库的字符串,用 `readBrandColor` 读平台品牌色,让线条跟随 App 主题(见 [canvas-design-system.md](canvas-design-system.md))。
64
64
 
65
65
  ```jsx
66
66
  import React from 'react';
@@ -155,8 +155,8 @@ export default YidaComp;
155
155
 
156
156
  ## 通用自查清单
157
157
 
158
- - 入口:源码有 `export default YidaComp`(或返回组件函数),不是只定义局部组件。
159
- - 依赖:所有 `import` 都在白名单内,能出现在编译结果 `dependencies` 里。
158
+ - 入口:源码有 `export default YidaComp`(或返回组件函数),主组件已完成默认导出。
159
+ - 依赖:所有 `import` 都在可用资源清单内,能出现在编译结果 `dependencies` 里。
160
160
  - 副作用:每个 `useEffect` 的定时器 / 监听 / 图表实例都有 cleanup。
161
161
  - 数据:读写走同源 `fetch` + `credentials: 'include'`,无硬编码 Cookie / CSRF / appSecret。
162
162
  - 主色:antd 走 `ConfigProvider.colorPrimary`、Tailwind 走 `var(--color-brand1-*)`、图表走 `readBrandColor`,无散落的 `#1677ff` / `bg-blue-500`(见 [canvas-design-system.md](canvas-design-system.md))。
@@ -1,9 +1,9 @@
1
1
  # Code Canvas 主色对齐与视觉落地
2
2
 
3
- 本文件是 Code Canvas 页面的**实现层**引导:真实业务页跟随宿主 App 的品牌主题色;官方 sample / 示例展示应用自带页面级固定主题和差异化色盘。视觉方向(页面类型、差异化、去 AI 味)走共用的决策层技能 `yida-page-uiux`,本文件只讲 Canvas(React18 + antd + Tailwind)这套栈怎么把主色落地。
3
+ 真实业务页跟随宿主 App 品牌主题色;官方 sample / 示例展示应用使用页面级固定主题和差异化色盘。`yida-page-uiux` 负责确定页面类型、差异化和去 AI 味方向;Code Canvas 实现层负责把这些决策落到 antd token、Tailwind、图表和控件状态。
4
4
 
5
- > 决策层:需要视觉方向时先遵循 `yida-page-uiux` 技能(先做 Step 0 导航形态判定,再定工作台/仪表盘/列表/详情、5 维差异化、去 AI 味、禁 emoji)。
6
- > 实现层:本文件负责把「真实业务页主色跟随 App 品牌」和「sample 页面级独立主题」落到 antd token / Tailwind / 图表。
5
+ > 决策层:`yida-page-uiux` 负责页面类型、导航形态、5 维差异化、去 AI 味和禁 emoji。
6
+ > 实现层:Code Canvas 负责把真实业务页跟随 App 品牌、sample 页面独立主题落到 antd token / Tailwind / 图表 / 控件状态。
7
7
 
8
8
  > **前提是导航可见且是真实业务页**:跟随品牌主色是为了跟应用框架融合。页面隐藏应用导航(`isRenderNav=false`,沉浸/独立/门户/大屏,由 `yida-page-uiux` Step 0 判定)时,主色相可自立。`lib/samples/**` 或官方 sample 展示应用也使用自立主色相:`followRuntimeTheme: false`,antd `colorPrimary` / 图表色 / CSS 变量都喂页面自己的固定色盘,语义色保持固定。
9
9
 
@@ -74,9 +74,9 @@ React.useEffect(function () {
74
74
  | 整个应用统一、全局换肤、系统整体主题、应用主题也改 | `{ "themeScope": "app" }` |
75
75
  | 左侧导航/菜单/顶部壳层也一起变色,导航和内容区同色 | `{ "themeScope": "app" }` |
76
76
  | 只说某个页面/首页/看板/自定义页变好看或换色 | `{ "themeScope": "page" }` |
77
- | 明确说不要影响导航、不要改其他页面、只改当前页 | `{ "themeScope": "page" }` |
77
+ | 明确说保持导航不变、其他页面不变、只改当前页 | `{ "themeScope": "page" }` |
78
78
 
79
- 同一句话同时出现“整体应用”和“不要影响导航”这类冲突时,以限制更强的 `page` 为准,或者简短确认一次。
79
+ 同一句话同时出现“整体应用”和“保持导航不变”这类冲突时,以限制更强的 `page` 为准,或者简短确认一次。
80
80
 
81
81
  ## 核心事实:CSS 变量直接级联,antd token 使用解析色值
82
82
 
@@ -153,7 +153,7 @@ function YidaComp(props) {
153
153
  export default YidaComp;
154
154
  ```
155
155
 
156
- **要点**:`ConfigProvider` 包在组件最外层,页面内所有 antd 组件才统一吃到品牌色。只设 `colorPrimary` 一个入口,不要逐组件手写颜色。
156
+ **要点**:`ConfigProvider` 包在组件最外层,页面内所有 antd 组件统一吃到品牌色。主色统一从 `colorPrimary` 注入,组件级颜色只保留必要的业务语义色。
157
157
 
158
158
  ## 默认 light 模式避免灰黑主题
159
159
 
@@ -262,7 +262,7 @@ function YidaComp(props) {
262
262
  export default YidaComp;
263
263
  ```
264
264
 
265
- 多色系列需要区分时,用 `--color-group` + 语义色,不要整排饱和撞色(见 `yida-page-uiux` 去 AI 味清单)。
265
+ 多色系列需要区分时,用 `--color-group` + 语义色,保持低饱和、分层明确的图表色组(见 `yida-page-uiux` 去 AI 味清单)。
266
266
 
267
267
  ## 自查清单(主色相关)
268
268
 
@@ -271,4 +271,4 @@ export default YidaComp;
271
271
  - Tailwind 主色类用 `var(--color-brand1-*)`,没有散落的 `#1677ff` / `bg-blue-500`。
272
272
  - 图表 / canvas 绘制颜色走 `readBrandColor` 或 `--color-group`,无硬编码蓝。
273
273
  - 语义色(成功/警告/错误)保持 antd 默认或平台语义变量,未被主色覆盖。
274
- - 视觉方向已按 `yida-page-uiux` 决策:不是默认蓝 + 大圆角 + emoji 的 AI 味套版。
274
+ - 视觉方向已按 `yida-page-uiux` 决策:配色、圆角、图标和文案都完成业务化处理。
@@ -1,17 +1,15 @@
1
- # Code Canvas 开源组件库选型
1
+ # Code Canvas 组件库选型
2
2
 
3
- 本文件回答「Code Canvas 还能用哪些开源组件库」以及生成页面时该怎么选。结论先行:页面默认使用已经在 Code Canvas 依赖白名单内、且 OpenYida 本地编译能映射到 windowAlias 的库;白名单外能力先走 Canvas 自绘、连接器、运行态组件桥或新增依赖评审。
4
-
5
- 依赖白名单、版本和 windowAlias 以 [dependencies-and-cdn.md](dependencies-and-cdn.md) 为准;本文件只做产品化选型建议。
3
+ Code Canvas 页面从 [dependencies-and-cdn.md](dependencies-and-cdn.md) 的可用前端资源中选择组件库。资源版本、import 写法和运行时加载契约以资源清单为准;页面选型按下列组合落地。
6
4
 
7
5
  ## 推荐组合
8
6
 
9
- | 场景 | 推荐库 | 何时使用 | 注意事项 |
7
+ | 场景 | 推荐库 | 何时使用 | 使用要点 |
10
8
  | --- | --- | --- | --- |
11
- | B 端业务界面 | `antd` | 表格、表单控件、按钮、弹窗、Tabs、Tag、Dropdown、分页 | 最外层包 `ConfigProvider`,主色用 `readBrandColor` 注入;按白名单 import,不自行注入依赖脚本 |
9
+ | B 端业务界面 | `antd` | 表格、表单控件、按钮、弹窗、Tabs、Tag、Dropdown、分页 | 最外层包 `ConfigProvider`,主色用 `readBrandColor` 注入;资源加载交给 Code Canvas runtime |
12
10
  | 图表看板 | `recharts` | 折线、柱状、面积、饼图、简单仪表盘 | 容器必须有稳定高度;颜色用品牌色和语义色,不硬编码默认蓝 |
13
11
  | 复杂可视化 | `d3` | 自定义关系图、力导向、桑基、特殊坐标系 | 只在 Recharts 覆盖不了时使用;自己管理 DOM/cleanup |
14
- | 图标 | 内联 SVG 语义集 | 按钮、操作、状态、导航等功能性图标 | 默认选择,零依赖且不会出现运行时组件 undefined |
12
+ | 图标 | 内联 SVG 语义集 | 按钮、操作、状态、导航等功能性图标 | 默认选择,零依赖、运行稳定 |
15
13
  | 交互动效 | `framer-motion` | 抽屉、轻量过渡、局部状态切换 | B 端页面使用克制、局部、服务状态理解的动效 |
16
14
  | Hooks 工具 | `ahooks` | 防抖、请求状态、定时器、列表状态等 | 用来简化状态逻辑;数据读写仍走明确数据桥 |
17
15
  | 轻量主题组件 | `@radix-ui/themes` | 需要更原子化、更少 antd 味的按钮、卡片、布局控件 | 与 antd 混用时要统一圆角、字体、色彩和弹层层级 |
@@ -22,28 +20,48 @@
22
20
  1. **普通业务页默认 `antd + ahooks + 内联 SVG 图标`**:这是最稳的 B 端组合,适合列表、工作台、详情、审批辅助页。
23
21
  2. **看板默认 `antd + recharts + ahooks + 内联 SVG 图标`**:KPI、筛选、图表和明细表都能覆盖;只有 Recharts 做不了的图才引入 `d3`。
24
22
  3. **需要去 antd 味时,少量使用 `@radix-ui/themes`**:适合展示页、门户页、较轻的工具页;同一页面选一个主视觉语言,另一套组件只做局部补充。
25
- 4. **动效只作为状态反馈**:`framer-motion` 用在抽屉、折叠、局部切换,不用于整页炫酷入场。
26
- 5. **图标只作功能用途**:默认内联 SVG;`lucide-react` 只有在当前租户环境最小验证通过后才可使用,不进入默认模板。
27
-
28
- ## lucide-react 特别说明
29
-
30
- `lucide-react` 在依赖白名单内,但不同运行时打包形态可能只暴露 `window.DynamicIcon`,不一定稳定提供 `RefreshCw`、`TrendingUp` 等 named exports。若页面直接写 `<RefreshCw />` 而运行时该导出为 `undefined`,React 会报 `Minified React error #130`。
23
+ 4. **动效服务状态反馈**:`framer-motion` 用在抽屉、折叠、局部切换,服务用户理解状态变化。
24
+ 5. **图标只作功能用途**:默认内联 SVG;需要统一开源图标库时按下方 `lucide-react` 用法引入。
25
+
26
+ ## lucide-react 用法
27
+
28
+ Code Canvas 支持在页面源码中使用 `lucide-react`。从常用图标列表里选择具体组件,用 named import 引入:
29
+
30
+ ```jsx
31
+ import { Search, RefreshCw, ChevronDown, Settings, Plus } from 'lucide-react';
32
+
33
+ function Toolbar() {
34
+ return (
35
+ <div>
36
+ <Search size={16} />
37
+ <RefreshCw size={16} />
38
+ <ChevronDown size={16} />
39
+ <Settings size={16} />
40
+ <Plus size={16} />
41
+ </div>
42
+ );
43
+ }
44
+ ```
31
45
 
32
- 因此默认模板使用内联 SVG 图标。需要使用 `lucide-react` 时先创建最小验证页,确认目标图标组件确实存在;验证前沿用内联 SVG。
46
+ 图标名称来自数据或配置时,在页面内写映射表,映射值仍然是 named import 得到的组件:
33
47
 
34
- ## 需要扩展白名单后使用
48
+ ```jsx
49
+ import { AlertCircle, Check, Clock, Search } from 'lucide-react';
35
50
 
36
- 以下库属于常见开源选择,但当前 Code Canvas 白名单未承诺加载。页面先使用上文推荐组合;确需使用这些库时,先完成依赖扩展和运行时验证:
51
+ const ICONS = {
52
+ alert: AlertCircle,
53
+ check: Check,
54
+ clock: Clock,
55
+ search: Search,
56
+ };
37
57
 
38
- - `@mui/material` / MUI
39
- - `@mantine/core`
40
- - `chakra-ui`
41
- - `semantic-ui`
42
- - `element-plus` / `naive-ui` / `arco-design`
43
- - `echarts`(普通自定义页面可通过 `loadScript` 用 ECharts;Canvas 当前白名单优先用 `recharts` / `d3`)
44
- - 任意未在 [dependencies-and-cdn.md](dependencies-and-cdn.md) 出现的 npm 包
58
+ function StatusIcon(props) {
59
+ const Icon = ICONS[props.type] || Search;
60
+ return <Icon size={16} />;
61
+ }
62
+ ```
45
63
 
46
- 新增库需要补齐三件事:OpenYida `canvas-compile.js` 的 alias 映射、Code Canvas 物料运行时依赖白名单和 CDN 资源、样式资源加载验证。三项都完成后,再进入生成默认推荐。
64
+ 常用图标可以选:`Search`、`RefreshCw`、`ChevronDown`、`ChevronUp`、`Settings`、`Plus`、`Download`、`Upload`、`Edit3`、`Trash2`、`Eye`、`Calendar`、`Clock`、`User`、`Users`、`Building2`、`FileText`、`Check`、`X`、`AlertCircle`、`Info`、`BarChart3`、`TrendingUp`。
47
65
 
48
66
  ## 生成页面时的组合示例
49
67
 
@@ -63,8 +81,8 @@ node -e "const fs=require('fs'); const {compileCanvasLocal}=require('./lib/app/c
63
81
 
64
82
  ## 自查清单
65
83
 
66
- - 所有 `import` 都在白名单内,并能出现在 `importedModules`。
84
+ - 所有 `import` 都在可用前端资源清单内,并能出现在 `importedModules`。
67
85
  - 页面视觉方向已经先走 `yida-page-uiux`,组件库服务于既定视觉方向。
68
86
  - antd 主色通过 `ConfigProvider` 跟随 App 品牌色。
69
- - 图表和图标服务于信息层级;图标默认内联 SVG,`lucide-react` 通过最小验证后再启用。
70
- - 默认模板、示例和推荐话术只包含当前已验证白名单能力。
87
+ - 图表和图标服务于信息层级;图标默认内联 SVG,明确需要图标库时再引入 `lucide-react`。
88
+ - 默认模板、示例和推荐话术只包含当前已验证可用资源能力。
@@ -1,14 +1,14 @@
1
- # Code Canvas 数据桥指南(自写 HTTP 读写宜搭数据)
1
+ # Code Canvas 数据桥
2
2
 
3
- Code Canvas 运行时**没有** `this.utils.yida.*` / `dataSourceMap` / `this.$(fieldId)` 实例数据桥;`YidaComp` 是普通 React 函数组件。因此 `YidaComp` 要读写宜搭数据,只能在组件内使用 HTTP 数据桥、连接器代理或显式 props 注入。本文件给出干净、可复用、合规的写法。
3
+ Code Canvas 运行时提供 React 函数组件上下文;`YidaComp` 读写宜搭数据时,在组件内使用 HTTP 数据桥、连接器代理或显式 props 注入。`this.utils.yida.*` / `dataSourceMap` / `this.$(fieldId)` 属于普通自定义页面实例桥能力。
4
4
 
5
5
  ## 三条数据路径,先选对
6
6
 
7
7
  | 路径 | 是否可在浏览器(Canvas)直接调 | 说明 |
8
8
  | --- | --- | --- |
9
- | 宜搭开放 API(OpenAPI,`appKey`/`appSecret` 签名) | **不可** | 需服务端签名;在浏览器里必然泄露 secret。只能由后端 / 连接器代理调,Canvas 不直连。 |
9
+ | 宜搭开放 API(OpenAPI,`appKey`/`appSecret` 签名) | 服务端 / 连接器代理 | 需服务端签名;浏览器直连会泄露 secret。由后端 / 连接器代理调用。 |
10
10
  | 平台已配置**连接器**(HTTP 连接器暴露的同源代理端点) | **推荐** | 同源 `fetch(url, { credentials: 'include' })` 带 cookie 即可,鉴权与密钥留在平台侧,符合数据源治理。 |
11
- | 内部表单数据端点(同源、依赖登录 cookie + CSRF) | 可,但要谨慎 | 与普通自定义页面 `this.utils.yida.searchFormDatas` 命中的是同类端点;使用同源相对路径、`credentials: 'include'` 和运行态 CSRF token。 |
11
+ | 内部表单数据端点(同源、依赖登录 cookie + CSRF) | 受控可用 | 与普通自定义页面 `this.utils.yida.searchFormDatas` 命中的是同类端点;使用同源相对路径、`credentials: 'include'` 和运行态 CSRF token。 |
12
12
 
13
13
  选路原则:优先走连接器代理,让鉴权、密钥和数据源治理留在平台侧。真需要直连内部端点时,使用**同源相对路径** + `credentials: 'include'`,Cookie / CSRF / appSecret 由平台上下文或后端服务提供。
14
14
 
@@ -127,7 +127,7 @@ function useYidaFetch(buildRequest, deps) {
127
127
 
128
128
  - `credentials: 'include'` 让浏览器带上同源登录态;Cookie 由浏览器和平台管理。
129
129
  - 如需 CSRF,优先从 `window.g_config._csrf_token` / `window.g_config.csrfToken` 动态读取,按接口要求放入 `_csrf_token` 请求参数和 / 或 `global_csrf_token` 头。
130
- - 用 `AbortController` 在卸载 / 依赖变化时取消,避免 setState-after-unmount(对应编码规则 #5 副作用清理)。
130
+ - 用 `AbortController` 在卸载 / 依赖变化时取消请求,保证副作用清理完整(对应编码规则 #5)。
131
131
  - 解析响应按**真实返回结构**处理;不同端点和运行态会出现 `data`、`result.data`、`content.data`、`content.result.data`、`list`、`values`、`records` 等包装。
132
132
 
133
133
  ## 表单查询返回体必须递归解析
@@ -235,7 +235,7 @@ function YidaComp(props) {
235
235
  export default YidaComp;
236
236
  ```
237
237
 
238
- `url`、`body` 字段按你实际接的连接器 / 端点契约填;上面是结构示意,不是可直接跑的真实端点。
238
+ `url`、`body` 字段按实际连接器 / 端点契约填写;示例结构用于说明数据桥写法。
239
239
 
240
240
  ## 轮询只刷新数据,不刷新整页
241
241
 
@@ -264,7 +264,7 @@ function YidaComp() {
264
264
  }
265
265
 
266
266
  // 直连 searchFormDatas.json 必须 GET + query(见下文请求契约):
267
- // formUuid/appType 放 URL query,分页参数名是 currentPage(不是 pageNumber)。
267
+ // formUuid/appType 放 URL query,分页参数名是 currentPage。
268
268
  var qs = new URLSearchParams({
269
269
  formUuid: '<FORM_UUID>',
270
270
  appType: '<APP_TYPE>',
@@ -311,11 +311,11 @@ function YidaComp() {
311
311
 
312
312
  ## 直连内部端点 `searchFormDatas.json` 请求契约
313
313
 
314
- 不方便配连接器、只需读本应用表单数据时,可同源直连内部端点 `searchFormDatas.json`。必须遵守三点请求契约,写错任意一个都会导致列表为空或接口报「参数校验失败formUuid」:
314
+ 不方便配连接器、只需读本应用表单数据时,可同源直连内部端点 `searchFormDatas.json`。请求契约如下:
315
315
 
316
- 1. **必须 `GET` + query 参数**,`formUuid`/`appType` 放 **URL query**。若用 `POST` 把 `formUuid` 塞进 body,后端从 query 读不到 → 直接报 **`参数校验失败formUuid`**。
317
- 2. **分页参数名是 `currentPage`**(不是 `pageNumber`);`searchFieldJson` 传 `'{}'` 表示不过滤。
318
- 3. **返回列表在 `content.data`**,不是顶层 `data`。响应形如 `{ content: { data: [...], totalCount, currentPage }, success: true }`。上文的 `unwrapRows` 已递归兜底解包,直接用即可。(注意:openyida CLI `data query` 会**归一化**把 `data` 提到顶层,你用 CLI 抽查看到的是顶层 `data`,别被误导——浏览器直连拿到的是 `content.data`。)每行字段值在 `row.formData[fieldId]`,`SelectField`/`RadioField` 已是纯字符串,`DateField` 是 13 位毫秒数。
316
+ 1. **`GET` + query 参数**:`formUuid`/`appType` 放 URL query。
317
+ 2. **分页参数名是 `currentPage`**;`searchFieldJson` 传 `'{}'` 表示不过滤。
318
+ 3. **返回列表在 `content.data`**:响应形如 `{ content: { data: [...], totalCount, currentPage }, success: true }`。上文的 `unwrapRows` 已递归兜底解包,直接用即可。每行字段值在 `row.formData[fieldId]`,`SelectField`/`RadioField` 已是纯字符串,`DateField` 是 13 位毫秒数。
319
319
 
320
320
  ```jsx
321
321
  // GET + query,读一个表单的数据
@@ -347,7 +347,7 @@ function fieldOf(row, fieldId) { return (row.formData || row)[fieldId]; }
347
347
 
348
348
  ## 写数据(新增 / 更新 / 删除)额外红线
349
349
 
350
- - **确认再写**:删除、批量更新等不可逆操作,先让用户在 UI 里显式确认,不在 `useEffect` 里静默触发。
351
- - **幂等**:提交按钮加 loading 锁与去重键,避免重复写入。
350
+ - **确认再写**:删除、批量更新等不可逆操作,先让用户在 UI 里显式确认,严禁在 `useEffect` 里静默触发。
351
+ - **幂等**:提交按钮加 loading 锁与去重键,拦截重复写入。
352
352
  - **权限**:写操作是否允许由平台权限决定;失败按后端返回的 `errorMsg` 提示。
353
353
  - **密钥位置**:任何 `appSecret` / 签名逻辑都留在服务端 / 连接器,Canvas 源码里只出现同源相对路径与业务参数。
@@ -1,29 +1,32 @@
1
- # Code Canvas 依赖白名单与 CDN 加载
1
+ # Code Canvas 可用资源与加载契约
2
2
 
3
- 本文件承载 Code Canvas 的依赖白名单、windowAlias 映射与编译改写规则。依赖加载细节以当前宜搭物料运行时为准;本文只保留页面作者需要遵循的 import / CDN 契约。核实自 `vc-deep-yida/src/components/yida-code-canvas` 源码(`dependencies.ts` / `factory.tsx`)。
3
+ Code Canvas 页面按下表 import 前端资源,运行时由 `YidaCodeCanvas` 按 `importedModules` 加载。依赖加载契约核实自 `vc-deep-yida/src/components/yida-code-canvas` 源码(`dependencies.ts` / `factory.tsx`)。
4
4
 
5
- ## 依赖白名单(核实自 `yida-code-canvas/dependencies.ts`)
5
+ ## 可用前端资源
6
6
 
7
- 编译阶段把 `import` 改写为下列白名单的 `windowAlias` 引用,运行时按 `windowAlias` 加载到 `window` 上。带 `${cdn}` 的资源前缀由平台运行时按当前环境决定。
7
+ 编译阶段会把下列资源的 `import` 计入 `importedModules`,运行时按资源表加载。带 `${cdn}` 的资源前缀由平台运行时按当前环境决定。
8
8
 
9
- | 包名 | windowAlias | 资源 |
10
- | --- | --- | --- |
11
- | react | `React` | g.alicdn.com react 18.3.1 |
12
- | react-dom | `ReactDOM` | g.alicdn.com react-dom 18.3.1 |
13
- | antd | `antd` | g.alicdn.com antd **5.23.3** `antd-with-locales.js` |
14
- | @ant-design/icons | `icons` | g.alicdn.com ant-design-icons 5.5.1 |
15
- | ahooks | `ahooks` | `${cdn}/platform/yida-assets/ahooks.js`(默认追加) |
16
- | d3 | `d3` | g.alicdn.com d3 7.9.0 |
17
- | recharts | `Recharts` | g.alicdn.com recharts 2.15.0 |
18
- | @radix-ui/themes | `Radix` | `${cdn}/.../radix.js` + `radix.css` |
19
- | lucide-react | `DynamicIcon` | `${cdn}/.../lucideReact.js` |
20
- | framer-motion | `FramerMotion` | `${cdn}/.../framerMotion.js` |
21
- | yida-plugin-markdown | `YidaMarkdown` | moduleFederation 0.0.4 |
9
+ | 包名 / 资源 | 推荐用途 | 页面源码写法 | 运行时资源 |
10
+ | --- | --- | --- | --- |
11
+ | `react` | React18 运行时 | `import React from 'react'` | g.alicdn.com react 18.3.1 |
12
+ | `react-dom` | React DOM 运行时 | `import ReactDOM from 'react-dom'` | g.alicdn.com react-dom 18.3.1 |
13
+ | `antd` | 表格、表单控件、按钮、弹窗、Tabs、Tag、Dropdown、分页 | `import { Button, Table } from 'antd'` | g.alicdn.com antd **5.23.3** `antd-with-locales.js` |
14
+ | `@ant-design/icons` | Ant Design 图标 | `import { SearchOutlined } from '@ant-design/icons'` | g.alicdn.com ant-design-icons 5.5.1 |
15
+ | `ahooks` | 防抖、请求状态、定时器、列表状态等 hooks | `import { useMemoizedFn } from 'ahooks'` | `${cdn}/platform/yida-assets/ahooks.js`(运行时默认追加) |
16
+ | `recharts` | 折线、柱状、面积、饼图等 React 图表 | `import { LineChart, Line } from 'recharts'` | g.alicdn.com recharts 2.15.0 |
17
+ | `d3` | 自定义关系图、力导向、桑基、特殊坐标系 | `import * as d3 from 'd3'` | g.alicdn.com d3 7.9.0 |
18
+ | `@radix-ui/themes` | 少量轻量主题组件 | `import { Button } from '@radix-ui/themes'` | `${cdn}/.../radix.js` + `radix.css` |
19
+ | `lucide-react` | 线性功能图标 | `import { Search, RefreshCw } from 'lucide-react'`;动态配置用页面内图标映射表 | `${cdn}/.../lucideReact.js` |
20
+ | `framer-motion` | 抽屉、折叠、局部状态切换动效 | `import { motion } from 'framer-motion'` | `${cdn}/.../framerMotion.js` |
21
+ | `yida-plugin-markdown` | PRD、公告、帮助文档、AI 输出内容展示 | `import Markdown from 'yida-plugin-markdown'` | moduleFederation 0.0.4 |
22
22
 
23
- 新增依赖必须同时满足:① 编译能把 import 抽进 `importedModules` 并映射到 windowAlias(见 `canvas-compile.js` 的 `MODULE_ALIAS_MAP`);② 上表或平台运行时能把依赖加载到 window;③ `runtimeCode` 引用的变量名与 windowAlias 一致;④ CSS 资源可加载。页面源码只 import 白名单包;`yida-utils`、`@ali/deep`、原生字段组件等宜搭运行态能力通过 `window.Deep`、`window.DeepYida`、`window.YidaNativeComponents` 等 `window.*` 访问。
23
+ ## 资源使用约定
24
24
 
25
- 当宜搭物料依赖表已经先于 OpenYida CLI 升级,且已确认运行时确实会注入某个新裸包时,可以临时设置 `OPENYIDA_CANVAS_ALLOW_UNSUPPORTED_IMPORTS=1` 退回旧式 `window["pkg"]` 映射发布。该开关只用于白名单漂移期间的发布验证;常规页面仍使用上表白名单和明确的 `windowAlias`。
25
+ - 页面源码只从上表资源 import;第三方资源加载交给 Code Canvas runtime。
26
+ - 宜搭运行态组件和平台能力通过 `window.Deep`、`window.DeepYida`、`window.YidaNativeComponents` 等宿主对象探测。
27
+ - 真实表单数据绑定使用页面内本地 `useYidaData(binding)`、`DataBridge` 与同源 `fetch` 实现。
28
+ - 组件库选型见 [component-library-guide.md](component-library-guide.md)。
26
29
 
27
- 真实表单数据绑定使用页面内本地 `useYidaData(binding)`、`DataBridge` 与同源 `fetch` 实现。
30
+ ## 编译运行契约
28
31
 
29
- 编译位置:OpenYida CLI **本地用 Babel** 把源码转译为 `runtimeCode` + `importedModules`(`import`→`window.<别名>`、`export default`→`YidaComp`、依赖名正则抽取),不调用任何在线编译服务,因此不依赖登录态、不经过风控。别名映射逐条镜像自 `dependencies.ts` 的 `getModuleAliasMap()`;运行时消费契约见 `factory.tsx`(`new Function` 执行 `runtimeCode` 取 `YidaComp`)。
32
+ OpenYida CLI **本地用 Babel** 把源码转译为 `runtimeCode` + `importedModules`,不调用在线编译服务。运行时由 `YidaCodeCanvas` 物料按 `importedModules` 加载上表资源,再用 `new Function` 执行 `runtimeCode` 并取回 `YidaComp`。
@@ -1,6 +1,6 @@
1
1
  # Code Canvas 运行时事实与 EmployeeField 验证
2
2
 
3
- 本文件承载 `yida-canvas-custom-page` 的运行时边界与 EmployeeField 验证示例,SKILL.md 只保留摘要与链接。
3
+ Code Canvas 接入 `EmployeeField` 前,先确认运行时边界、组件探测结果和值结构。
4
4
 
5
5
  ## 运行时事实
6
6
 
@@ -9,7 +9,7 @@
9
9
  - 代码执行后必须返回 `YidaComp`、`YidaComp.default` 或组件函数。
10
10
  - Canvas 要读写宜搭数据,只能在组件内使用 HTTP 数据桥、连接器代理或显式 props 注入。如果用户明确要求普通自定义页面 JSX/Jsx 组件链路,或页面强依赖普通自定义页实例桥,选择 `yida-custom-page`。
11
11
 
12
- > 依赖白名单表、windowAlias 映射与编译端点已拆到 [dependencies-and-cdn.md](dependencies-and-cdn.md)。
12
+ > 可用资源清单、import 写法与运行时加载契约已拆到 [dependencies-and-cdn.md](dependencies-and-cdn.md)。
13
13
 
14
14
  ## 宜搭原生组件判断
15
15
 
@@ -19,7 +19,7 @@
19
19
  - 组件所需 CSS、页面上下文、组织权限、弹层容器、移动端版本均可用。
20
20
  - `onChange` 返回值结构能被后续数据保存或查询逻辑消费。
21
21
 
22
- 这些原生组件从宿主 `window` 探测,不从 `@ali/deep` 等裸包 import。确认条件齐全时渲染原生组件;确认条件不足时使用普通 UI:用 antd 或自定义控件选择候选用户,值只存已知 userId / unionId / 文本快照。
22
+ 这些原生组件从宿主 `window` 探测。确认条件齐全时渲染原生组件;确认条件不足时使用普通 UI:用 antd 或自定义控件选择候选用户,值只存已知 userId / unionId / 文本快照。
23
23
 
24
24
  ## EmployeeField 验证示例
25
25
 
@@ -59,7 +59,7 @@ function YidaComp(props) {
59
59
  <div style={{ padding: 16 }}>
60
60
  <label style={{ display: 'block', marginBottom: 8 }}>负责人</label>
61
61
  <input
62
- placeholder="EmployeeField 不可用,使用文本 fallback"
62
+ placeholder="未探测到 EmployeeField,使用文本 fallback"
63
63
  onChange={function (event) {
64
64
  setValue([{ name: event.target.value, raw: { fallback: true } }]);
65
65
  }}
@@ -91,7 +91,7 @@ export default YidaComp;
91
91
  验收点:
92
92
 
93
93
  - 组件探测结果能明确显示可用或缺失,不因缺失组件白屏。
94
- - 页面控制台没有 `EmployeeField is not defined`、样式缺失、弹层挂载错误。
94
+ - 页面控制台保持干净,无 `EmployeeField is not defined`、样式缺失、弹层挂载错误。
95
95
  - 成员弹层能打开、搜索、选择、清空。
96
96
  - PC 和移动端都能完成选择。
97
97
  - `onChange` 输出的值结构被记录下来,后续代码按真实结构处理。
@@ -1,12 +1,12 @@
1
- # Code Canvas 原生组件桥接指南
1
+ # Code Canvas 原生组件桥
2
2
 
3
- 本文说明在 Code Canvas 自定义页面中接入宜搭运行态组件的推荐做法,覆盖门户组件、数据管理视图、成员、部门、附件上传和图片上传。
3
+ Code Canvas 接入宜搭运行态组件时,统一使用运行时桥接。覆盖门户组件、数据管理视图、成员、部门、附件上传和图片上传。
4
4
 
5
5
  ## 核心策略
6
6
 
7
- Code Canvas 里的宜搭运行态组件按“先探测、可用再增强、不可用就 fallback”的方式接入。字段、门户、数据管理视图等运行态组件统一从宿主 `window.Deep` / `window.DeepYida` / `window.YidaNativeComponents` 查找;页面源码只 `import` Code Canvas 白名单内的通用前端包。
7
+ Code Canvas 里的宜搭运行态组件按“先探测、可用增强、fallback 保底”的方式接入。字段、门户、数据管理视图等运行态组件统一从宿主 `window.Deep` / `window.DeepYida` / `window.YidaNativeComponents` 查找;页面源码只 `import` Code Canvas 可用资源清单内的通用前端包。
8
8
 
9
- 推荐方式是运行时桥接:
9
+ 运行时桥接步骤:
10
10
 
11
11
  1. 从 `window.Deep`、`window.DeepYida` 探测组件;若环境已有 `window.YidaNativeComponents`,作为兼容入口读取。
12
12
  2. 找到组件后渲染原生组件。
@@ -32,7 +32,7 @@ openyida sample yida-canvas-custom-page portal-native-components --output projec
32
32
 
33
33
  业务代码统一走桥接函数读取宿主组件,便于隔离不同运行态差异。
34
34
 
35
- ## 门户组件怎么用
35
+ ## 门户组件接入规则
36
36
 
37
37
  ### TopBanner / QuickEntry
38
38
 
@@ -49,7 +49,7 @@ openyida sample yida-canvas-custom-page portal-native-components --output projec
49
49
  - QuickEntry 只传静态 `content`、`titleConfig`、`themeConfig`。
50
50
  - 点击跳转由 Canvas 自己控制,目标 URL 和打开方式写在页面代码里。
51
51
 
52
- ### QuickAccessCard / RecentlyUsedCard(可用,但 `theme` 必传)
52
+ ### QuickAccessCard / RecentlyUsedCard(`theme` 必传)
53
53
 
54
54
  这两个是**容器型组件**,会在运行态自行拉取应用列表并渲染卡片。`theme` 是必传运行时契约;页面始终传入 `theme="row-white"` 或 `theme="column"`。
55
55
 
@@ -67,7 +67,7 @@ openyida sample yida-canvas-custom-page portal-native-components --output projec
67
67
  使用要求:
68
68
 
69
69
  - **始终传 `theme`**(如 `'row-white'`)。
70
- - 列表数据由组件自取(依赖当前登录用户 + 门户接口),Canvas 只负责容器 props、布局和 fallback。
70
+ - 列表数据由组件自取(依赖当前登录用户 + 门户接口),Canvas 提供容器 props、布局和 fallback。
71
71
  - 组件缺失或无门户接口权限时,渲染 Canvas 自绘应用入口卡片。
72
72
 
73
73
  > 页面侧遵守必传 props 约束并做好局部降级:`theme` 有值,组件缺失或运行态不兼容时展示 Canvas fallback。
@@ -78,7 +78,7 @@ openyida sample yida-canvas-custom-page portal-native-components --output projec
78
78
 
79
79
  页面只需要「门户风格」时,使用 Canvas 自绘卡片并通过 fetch/连接器取数据;需要复用宜搭门户内置的快捷/最近应用卡片时,按上面方式启用 `QuickAccessCard` / `RecentlyUsedCard`。
80
80
 
81
- ## 数据管理视图怎么用
81
+ ## 数据管理视图接入规则
82
82
 
83
83
  需要在自定义页面中嵌入门户里那块「数据管理视图」时,优先探测 `DataManageViews`,并把它当作黑盒组件使用。页面侧只传稳定的 `form` 配置,不自行构造底层数据管理 props。
84
84
 
@@ -129,10 +129,10 @@ openyida sample yida-canvas-custom-page native-components-smoke --output project
129
129
 
130
130
  - 先拿到 `form.value/formUuid`,再渲染 `DataManageViews`。
131
131
  - 组件依赖宿主运行态、登录态、权限、CSRF、`vc-deep-yida` 与 `yc-data-manage` 样式;组件缺失或权限不足时保留 Canvas fallback。
132
- - `DataManageViews` 会自动过滤 `viewType === 'form'` 的视图,并关闭导入、导出、批量操作等门户不需要的能力;页面侧统一使用它承载门户数据管理视图。
132
+ - `DataManageViews` 会自动过滤 `viewType === 'form'` 的视图,并关闭导入、导出、批量操作等门户不需要的能力;页面侧统一使用它渲染门户数据管理视图。
133
133
  - 只需要展示少量业务数据时,用 Canvas 自绘表格 + HTTP 数据桥 / 连接器 / `openyida data`;需要复用门户数据管理视图时使用 `DataManageViews`。
134
134
 
135
- ## 成员组件怎么用
135
+ ## 成员组件接入规则
136
136
 
137
137
  需要成员选择时,优先探测 `EmployeeField`。它属于宿主运行态组件,先验证可用性,再接入业务页面。
138
138
 
@@ -156,9 +156,9 @@ openyida sample yida-canvas-custom-page native-components-smoke --output project
156
156
  }
157
157
  ```
158
158
 
159
- ## 部门组件怎么用
159
+ ## 部门组件接入规则
160
160
 
161
- 需要部门选择时,优先探测 `DepartmentSelectField`。该组件依赖宿主通讯录能力、搜索接口和权限上下文,因此要比成员组件更谨慎。
161
+ 需要部门选择时,优先探测 `DepartmentSelectField`。该组件依赖宿主通讯录能力、搜索接口和权限上下文,先完成 smoke 验证再接入业务页面。
162
162
 
163
163
  使用要求:
164
164
 
@@ -179,7 +179,7 @@ openyida sample yida-canvas-custom-page native-components-smoke --output project
179
179
  }
180
180
  ```
181
181
 
182
- ## 上传组件怎么用
182
+ ## 上传组件接入规则
183
183
 
184
184
  需要上传时,优先探测:
185
185
 
@@ -190,7 +190,7 @@ openyida sample yida-canvas-custom-page native-components-smoke --output project
190
190
 
191
191
  使用要求:
192
192
 
193
- - 原生上传作为增强能力;组件不可用或上传失败时,fallback 到链接录入或业务连接器上传。
193
+ - 原生上传作为增强能力;组件缺失或上传失败时,fallback 到链接录入或业务连接器上传。
194
194
  - Cookie、CSRF、OSS key 或内部上传密钥由平台、连接器或后端服务管理,Canvas 只消费安全返回结果。
195
195
  - 提交数据只使用归一化后的文件数组,`raw` 仅用于检查。
196
196
 
@@ -223,9 +223,9 @@ openyida sample yida-canvas-custom-page native-components-smoke --output project
223
223
  | 值归一化 | 提交 payload 不依赖 raw 原始对象 |
224
224
  | fallback | 任何原生组件缺失时页面仍可完成核心流程 |
225
225
 
226
- ## 什么时候使用普通 Canvas fallback
226
+ ## Fallback 稳定基线
227
227
 
228
- 以下情况应主动使用 fallback:
228
+ 满足任一条件时直接渲染 Canvas fallback,保证页面主流程可用:
229
229
 
230
230
  - 运行态找不到目标组件。
231
231
  - 未指定数据管理视图的 `form.value/formUuid`。
@@ -1,6 +1,6 @@
1
- # Code Canvas 页面生成与视觉路由指南
1
+ # Code Canvas 页面生成与视觉路由
2
2
 
3
- 本文承载 `yida-canvas-custom-page` 的页面类型路由、主题作用域、官网素材流程和 Page Spec 字段说明。SKILL.md 只保留摘要和命令入口。
3
+ Code Canvas 页面生成先确定页面类型、主题作用域、数据绑定和素材来源,再写 `page-spec.json` 或直接手写 `.canvas.jsx`。
4
4
 
5
5
  ## 首次生成模板路由
6
6
 
@@ -22,7 +22,7 @@
22
22
 
23
23
  - `openyida sample` 或模板原样发布可以展示 sample/seed 数据,但页面必须标注 sample/seed。
24
24
  - 完整应用或真实交付页使用真实业务记录;需要演示数据时,先把 demo/mock records 写入真实宜搭表单,再由 Canvas 读取。
25
- - 未写入 demo records 且没有真实数据时,页面应展示空态、表单入口、刷新/登记按钮和 dataBinding 接入提示。
25
+ - 真实数据暂未接入时,页面应展示空态、表单入口、刷新/登记按钮和 dataBinding 接入提示。
26
26
 
27
27
  | 用户需求 | CLI 模板 | scene | 视觉要点 |
28
28
  | --- | --- | --- | --- |
@@ -37,7 +37,7 @@
37
37
 
38
38
  如果用户要求“门户组件 / 成员 / 部门 / 上传组件”,继续使用 Code Canvas,但按 [native-components-bridge.md](native-components-bridge.md) 选择 `portal-native-components` 示例或桥接规则。
39
39
 
40
- 当模板本身包含页面内应用导航(如 `workbench-home` 的侧边导航、`portal-shell-home` 的门户导航)时,生成的 `.openyida-page.json` 会默认写入 `appBlueprint.renderNav: false` / `navConfig.isRenderNav: false`。发布后必须用 `openyida update-form-config <appType> <formUuid> false "<页面标题>"` 隐藏宜搭原应用导航,避免双导航。
40
+ 当模板本身包含页面内应用导航(如 `workbench-home` 的侧边导航、`portal-shell-home` 的门户导航)时,生成的 `.openyida-page.json` 会默认写入 `appBlueprint.renderNav: false` / `navConfig.isRenderNav: false`。发布后必须用 `openyida update-form-config <appType> <formUuid> false "<页面标题>"` 隐藏宜搭原应用导航,保持页面单导航。
41
41
 
42
42
  ## 官网与品牌页素材流程
43
43
 
@@ -87,7 +87,7 @@
87
87
  | “整个应用统一风格 / 全局换肤 / 应用主题也改一下” | `themeScope: app` |
88
88
  | “左侧导航也一起变色 / 菜单也跟着主题走” | `themeScope: app` |
89
89
  | “页面好看一点 / 这个自定义页换主题 / 首页美化” | `themeScope: page` |
90
- | “只改当前页 / 不影响导航 / 不要改其他页面” | `themeScope: page` |
90
+ | “只改当前页 / 保持导航不变 / 其他页面不变” | `themeScope: page` |
91
91
 
92
92
  显式覆盖色只在用户给定品牌色、色值或明确要求覆盖当前应用主题时使用。
93
93
 
@@ -43,7 +43,7 @@ description: 宜搭普通自定义页面 JSX / Jsx 组件开发规范(React 16
43
43
 
44
44
  影响代码质量和用户体验:
45
45
 
46
- 0. **视觉方向按需加载**:单点页面美化、用户明确要求好看/去 AI 味,或 `yida-app` 进入 `deep_design` 时,调用 `use_skill("yida-page-uiux", "确定自定义页面视觉方向")` 完成「视觉方向决策」。`yida-app fast_build` 默认不加载该技能,直接使用克制的 MVP 工作台/列表/入口布局,禁 emoji、少装饰、真实业务页主色跟随 App 品牌即可;`lib/samples/**` 和官方 sample 展示应用例外,必须使用页面级独立主题。
46
+ 0. **视觉方向先于编码**:单点页面美化、用户明确要求好看/去 AI 味,或完整应用进入页面实现阶段时,调用 `use_skill("yida-page-uiux", "确定自定义页面视觉方向")` 完成「视觉方向决策」。默认轻量 UI 引导只产出页面类型、模板路由、`visualProfile` 和去 sample 化检查,不升级为应用蓝图或深度设计;`lib/samples/**` 和官方 sample 展示应用例外,必须使用页面级独立主题。
47
47
  1. **代码生成前确认功能摘要**:详见 [编码指南 编注 0](references/coding-guide.md)
48
48
  2. **pageSize 推荐 50,最大 100**:列表/看板默认 `pageSize: 50`;分页接口 `searchFormDatas` 等的 `pageSize` 最大 100
49
49
  3. **didUnmount 清理定时器**:在 `didUnmount` 中清理所有 `setInterval`/`setTimeout`,防止内存泄漏
@@ -61,7 +61,7 @@ description: 宜搭普通自定义页面 JSX / Jsx 组件开发规范(React 16
61
61
  15. **发布前必须跑检查链路**:先执行 `openyida check-page <file>` 和 `openyida compile <file>`;若出现 warning/error,按规则修复后再发布
62
62
  16. **源码修改发布闭环**:只要本轮 Write/Edit/Create 了 `project/pages/src/*.{oyd.jsx,jsx,tsx}` 普通自定义页面源码,`check-page` / `compile` 只证明源码可发布,不等于远端页面已更新;final 前必须看到成功的 `openyida publish <source> <appType> <displayPageFormUuid>`。没有 publish 成功证据时,只能说“源码已修改,尚未发布”,不能说“页面已更新 / 已重新发布”。
63
63
 
64
- > 每条规则的代码示例、反模式和常见错误见 [编码指南](references/coding-guide.md);`fast_build` 默认先遵守本技能正文,不预读长 reference,只有 check-page 报错、复杂交互、`deep_design` 或正文覆盖不了的问题时才读取。
64
+ > 每条规则的代码示例、反模式和常见错误见 [编码指南](references/coding-guide.md);`fast_build` 默认先遵守 `yida-page-uiux` 决策块和本技能正文,不预读长 reference,只有 check-page 报错、复杂交互、`deep_design` 或正文覆盖不了的问题时才读取。
65
65
  > 运行时易错点、`check-page` 规则和兼容层自动修复边界见 [运行时护栏](references/runtime-guardrails.md),按需读取。
66
66
  > 表单类 JSX 控件、筛选栏、表格、成员/附件等组件写法见 [组件指南](references/component-jsx-guide.md),涉及这些复杂组件时读取;未验证的平台组件能力不得编造。
67
67
 
@@ -164,7 +164,7 @@ export function loadVisitorList() {
164
164
 
165
165
  ## 开发规范
166
166
 
167
- > `fast_build` 默认不读取长 reference,直接遵守本技能正文的核心规则和模板。只有 check-page 报错、复杂交互/复杂组件、`deep_design`、或正文覆盖不了的运行时问题,才读取下方 Available Files。
167
+ > `fast_build` 默认不读取长 reference,直接遵守 `yida-page-uiux` 决策块、本技能正文的核心规则和模板。只有 check-page 报错、复杂交互/复杂组件、`deep_design`、或正文覆盖不了的运行时问题,才读取下方 Available Files。
168
168
  > 涉及输入控件、日期、选择、成员/部门、附件、表格或筛选栏时,读取 [组件指南](references/component-jsx-guide.md)。
169
169
 
170
170
  ## 官方示例模板与编码注意事项
@@ -243,7 +243,7 @@ openyida check-page pages/src/home.oyd.jsx --json # 输出机器可读的
243
243
  | 文档 | 覆盖范围 | 何时阅读 |
244
244
  |------|---------|---------|
245
245
  | **本技能文档** | | |
246
- | `yida-page-uiux` 子技能 | 页面类型 playbook、5 维差异化引擎、去 AI 味黑名单/8 问自检、图标策略 | 用户明确要求好看/去 AI 味或 `deep_design` 时加载;`fast_build` 不默认加载 |
246
+ | `yida-page-uiux` 子技能 | 页面类型 playbook、5 维差异化引擎、去 AI 味黑名单/8 问自检、图标策略 | 页面实现前加载;`fast_build` 用轻量决策块,用户明确要求好看/去 AI 味或 `deep_design` 时可读更多 workflow/reference |
247
247
  | [编码指南](references/coding-guide.md) | 文件结构模板、状态管理、生命周期、19 条编码规范 | check-page 报错、复杂交互、状态管理问题或 `deep_design` 时阅读 |
248
248
  | [运行时护栏](references/runtime-guardrails.md) | pageSize、loading 恢复、ECharts DOM 时序、setState 约束、check-page 规则映射 | 页面运行时报错、check-page 规则不清或编译兼容边界不清时阅读 |
249
249
  | [设计规范](references/design-system.md) | 色彩/圆角/字体/间距系统、7 类组件样式模板、8 条反模式 | 用户明确要求视觉细化,或已进入 `deep_design` / `yida-page-uiux` 后阅读 |
@@ -2,7 +2,7 @@
2
2
  name: yida-page-uiux
3
3
  description: >
4
4
  宜搭自定义页面 UI/UX 视觉方向决策技能。用于在页面实现前,按页面类型(工作台/看板/数据大屏/列表/详情/官网落地页)确定布局骨架、信息密度、视觉风格、素材/图标策略和模板路由,产出「视觉方向决策块」,默认交 Code Canvas 落地。
5
- 当用户要新建或改造自定义页面,并明确关注好看、高级、品牌化、去 AI 味、UI 视觉、美化、页面太丑、不够惊艳,或进入深度视觉设计阶段时触发。
5
+ 当用户要新建或改造自定义页面,并明确关注好看、高级、品牌化、去 AI 味、UI 视觉、美化、页面太丑、不够惊艳,或进入完整应用主页面实现 / 深度视觉设计阶段时触发。
6
6
  完成范围:单页自定义页面的页面类型判断、视觉方向选择、差异化设计原则、素材与图标策略、去 AI 味自检和可交给实现阶段使用的决策块。
7
7
  ---
8
8
 
@@ -22,9 +22,21 @@ description: >
22
22
  - **图表/看板默认**:常规业务图表交 `yida-rechart`。
23
23
  - **ECharts 例外**:只有用户明确要求 ECharts、复杂 ECharts option/扩展系列,或维护旧普通自定义页面图表时,才交 `yida-chart`。
24
24
  - **legacy/native fallback**:用户明确要求普通 JSX/Jsx 页面,或页面深度依赖 `this.$()`、`this.utils.yida.*`、`this.dataSourceMap` 等实例桥时,交 `yida-custom-page`。
25
+ - 判定页面类型和推荐模板,避免所有系统都回落到通用工作台或官网 sample。
25
26
 
26
27
  本技能只做视觉决策,不得因为 references 中存在普通页示例就把新页面从 Canvas 降级到 native。
27
28
 
29
+ ## 默认主页面 UI 引导
30
+
31
+ 完整应用进入主页面实现阶段时,默认把本技能作为 `ui_skill` 轻量加载。目标不是做长 PRD 或深度应用蓝图,而是在不追问的前提下给页面实现阶段一个可执行的「不要照搬 sample」护栏:
32
+
33
+ - 判定页面类型和推荐模板,避免所有系统都回落到通用工作台或官网 sample。
34
+ - 输出 `visualProfile`:信息密度、构图节奏、强调色来源、图表/列表/队列母题。
35
+ - 列出 3-5 条当前业务专属的区块、指标、动作和空/载/错状态要求。
36
+ - 标记 sample 风格禁用项:模板默认品牌名、默认卖点、默认指标、默认图片/section 顺序不得直接成为最终页。
37
+
38
+ 轻量模式只读当前页面类型所需的 workflow/scene;没有用户明确要求“高级视觉 / 品牌化 / 多页面体验 / 深度产品设计”时,不加载 `yida-app-uiux`、`yida-theme` 或长视觉 reference。
39
+
28
40
  ## 重要限制:自定义页面不做表单/录入 UI
29
41
 
30
42
  - 自定义页面**只做展示、工具、看板、详情**,**不手写表单控件**(输入框群、字段校验、提交表单)。
@@ -23,8 +23,8 @@
23
23
  "name": "yida-app",
24
24
  "path": "skills/yida-app/SKILL.md",
25
25
  "display_name": "宜搭完整应用开发",
26
- "description": "完整搭建或补齐普通 OpenYida 应用的流程编排技能。默认 fast_build 先解析并复用 app/page/form/process 上下文,只创建缺失且允许创建的应用、表单或页面;绑定或预创建应用只复用不改名;不默认使用未绑定 dataSourceMap,导航、示例数据和深度设计按需后置。",
27
- "done_when": "若本轮 Write/Edit 页面源码,必须真实执行成功 openyida publish <source> <appType> <displayPageFormUuid> 并返回访问 URL;没有 publish 证据只能声明源码已修改,尚未发布。",
26
+ "description": "完整搭建或补齐普通 OpenYida 应用的流程编排技能。默认 fast_build 先解析并复用 app/page/form/process 上下文,只创建缺失且允许创建的应用、表单或页面;主页面生成默认包含 yida-page-uiux 轻量 UI 引导,绑定或预创建应用只复用不改名;结果链接较多时表格输出,不默认使用未绑定 dataSourceMap,导航、示例数据和深度设计按需后置。",
27
+ "done_when": "若本轮 Write/Edit 页面源码,必须真实执行成功 openyida publish <source> <appType> <displayPageFormUuid> 并返回访问 URL;3 个及以上资源或链接必须用 Markdown 表格输出;没有 publish 证据只能声明源码已修改,尚未发布。",
28
28
  "category": "yida-skills/app",
29
29
  "tags": [
30
30
  "宜搭",
@@ -886,10 +886,12 @@
886
886
  "name": "yida-page-uiux",
887
887
  "path": "skills/yida-page-uiux/SKILL.md",
888
888
  "display_name": "页面视觉方向决策",
889
- "description": "单页自定义页面 UI/UX 视觉方向决策:页面实现前按工作台/看板/大屏/列表/详情/官网等类型产出视觉方向决策块,覆盖布局骨架、信息密度、视觉风格、素材图标、模板路由和去 AI 味自检。用户明确要美化、好看、高级、品牌化、UI 视觉、页面太丑/不够惊艳或进入深度视觉设计阶段时触发。",
889
+ "description": "单页自定义页面 UI/UX 视觉方向决策:页面实现前按工作台/看板/大屏/列表/详情/官网等类型产出视觉方向决策块,覆盖布局骨架、信息密度、视觉风格、素材图标、模板路由和去 AI 味自检。用户明确要美化、好看、高级、品牌化、UI 视觉、页面太丑/不够惊艳,或完整应用进入主页面实现阶段时触发。",
890
890
  "category": "yida-skills/page",
891
891
  "tags": [
892
892
  "UIUX",
893
+ "ui_skill",
894
+ "fast_build",
893
895
  "视觉方向",
894
896
  "去 AI 味",
895
897
  "页面类型"
@@ -899,6 +901,8 @@
899
901
  ],
900
902
  "positive_signals": [
901
903
  "页面美化",
904
+ "主页面 UI 引导",
905
+ "ui_skill",
902
906
  "视觉方向",
903
907
  "去 AI 味",
904
908
  "高级感",