openyida 2026.8.13 → 2026.8.16-beta.0

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.
Files changed (70) hide show
  1. package/README.md +4 -3
  2. package/bin/yida.js +40 -12
  3. package/docs/capabilities.md +21 -5
  4. package/lib/app/check-prd-completeness.js +631 -0
  5. package/lib/app/display-page-readback.js +187 -0
  6. package/lib/app/publish.js +63 -76
  7. package/lib/auth/oauth-loopback.js +25 -4
  8. package/lib/auth/token-auth.js +29 -7
  9. package/lib/auth/token-store.js +600 -61
  10. package/lib/core/agent-capabilities.js +211 -9
  11. package/lib/core/command-manifest.js +8 -1
  12. package/lib/core/copy.js +55 -20
  13. package/lib/core/env.js +33 -2
  14. package/lib/core/locales/en.js +19 -5
  15. package/lib/core/locales/zh.js +19 -5
  16. package/lib/core/utils.js +629 -73
  17. package/lib/core/yida-client.js +4 -0
  18. package/package.json +1 -1
  19. package/scripts/postinstall.js +26 -10
  20. package/yida-skills/SKILL.md +90 -184
  21. package/yida-skills/references/execution-rules.md +8 -0
  22. package/yida-skills/references/resource-context.md +81 -0
  23. package/yida-skills/references/routing-supplement.md +27 -0
  24. package/yida-skills/references/setup-and-env.md +43 -36
  25. package/yida-skills/skills/yida-app/SKILL.md +48 -294
  26. package/yida-skills/skills/yida-app/references/common-issues.md +49 -0
  27. package/yida-skills/skills/yida-app/workflow/step-1-resource-context.md +63 -0
  28. package/yida-skills/skills/yida-app/workflow/step-2-design.md +40 -0
  29. package/yida-skills/skills/yida-app/workflow/step-3-create-or-reuse-app.md +34 -0
  30. package/yida-skills/skills/yida-app/workflow/step-4-forms-processes.md +74 -0
  31. package/yida-skills/skills/yida-app/workflow/step-5-seed-records.md +44 -0
  32. package/yida-skills/skills/yida-app/workflow/step-6-main-page.md +35 -0
  33. package/yida-skills/skills/yida-app/workflow/step-7-page-code.md +50 -0
  34. package/yida-skills/skills/yida-app/workflow/step-8-publish-navigation.md +42 -0
  35. package/yida-skills/skills/yida-app/workflow/step-9-output-finish.md +108 -0
  36. package/yida-skills/skills/yida-create-form-page/SKILL.md +4 -3
  37. package/yida-skills/skills/yida-design/SKILL.md +9 -9
  38. package/yida-skills/skills/yida-design/references/page-quality-gates.md +1 -1
  39. package/yida-skills/skills/yida-design/references/style-design-selection.md +29 -29
  40. package/yida-skills/skills/yida-design/references/style-designs/aqua-service-progress-dashboard.md +3 -3
  41. package/yida-skills/skills/yida-design/references/style-designs/blue-insight-operations-dashboard.md +3 -3
  42. package/yida-skills/skills/yida-design/references/style-designs/blue-productivity-insight-workbench.md +3 -3
  43. package/yida-skills/skills/yida-design/references/style-designs/command-filter-card-console.md +4 -4
  44. package/yida-skills/skills/yida-design/references/style-designs/contrast-command-analytics-workbench.md +4 -4
  45. package/yida-skills/skills/yida-design/references/style-designs/dark-stage-analytic-dashboard.md +8 -8
  46. package/yida-skills/skills/yida-design/references/style-designs/filterable-card-catalog.md +5 -5
  47. package/yida-skills/skills/yida-design/references/style-designs/green-timeline-progress-workbench.md +3 -3
  48. package/yida-skills/skills/yida-design/references/style-designs/registry.md +30 -30
  49. package/yida-skills/skills/yida-design/references/style-designs/soft-analytic-workbench.md +4 -4
  50. package/yida-skills/skills/yida-design/references/style-designs/soft-blue-grid-analytic-dashboard.md +1 -1
  51. package/yida-skills/skills/yida-design/references/style-designs/soft-bordered-analytic-workbench.md +4 -4
  52. package/yida-skills/skills/yida-design/references/style-designs/soft-curated-filter-gallery.md +4 -4
  53. package/yida-skills/skills/yida-design/references/style-designs/soft-modular-analytic-workbench.md +5 -5
  54. package/yida-skills/skills/yida-design/references/style-designs/soft-progress-analytics-workbench.md +4 -4
  55. package/yida-skills/skills/yida-design/references/style-designs/soft-timeline-analytics-workbench.md +8 -8
  56. package/yida-skills/skills/yida-design/references/style-designs/teal-rail-analytics-workbench.md +8 -8
  57. package/yida-skills/skills/yida-design/workflow/output-design.md +25 -19
  58. package/yida-skills/skills/yida-design/workflow/output-prd.md +11 -6
  59. package/yida-skills/skills/yida-design/workflow/step-1-positioning.md +1 -1
  60. package/yida-skills/skills/yida-design/workflow/step-2-theme-system.md +1 -1
  61. package/yida-skills/skills/yida-design/workflow/step-3-information-architecture.md +1 -1
  62. package/yida-skills/skills/yida-design/workflow/step-5-visual-states.md +10 -10
  63. package/yida-skills/skills/yida-design/workflow/step-6-handoff.md +2 -2
  64. package/yida-skills/skills/yida-flash-note-to-prd/SKILL.md +31 -33
  65. package/yida-skills/skills/yida-flash-note-to-prd/references/flash-note-prd-template.md +1 -1
  66. package/yida-skills/skills/yida-form-detail/SKILL.md +7 -7
  67. package/yida-skills/skills/yida-login/SKILL.md +60 -31
  68. package/yida-skills/skills/yida-publish-page/SKILL.md +13 -10
  69. package/yida-skills/references/development-rules.md +0 -85
  70. package/yida-skills/skills/yida-app/references/app-build-contract.md +0 -141
package/README.md CHANGED
@@ -68,9 +68,9 @@ OpenYida returns a compact machine-readable summary with the version, login stat
68
68
  openyida login
69
69
  ```
70
70
 
71
- OpenYida login defaults to OAuth token mode. It opens the DingTalk OAuth authorization page, receives the local loopback callback, exchanges `code` / `authCode` with the Yida server, and stores `access_token` / `refresh_token` in the current project cache.
71
+ OpenYida login defaults to OAuth token mode. It opens the DingTalk OAuth authorization page, receives the local loopback callback, exchanges `code` / `authCode` with the Yida server, and stores `access_token` / `refresh_token` in the user auth store when available. If the user auth store is not writable, OpenYida explicitly falls back to the current project cache and reports that narrower persistence scope.
72
72
 
73
- When the user names a target Yida entry URL, pass it to the login command so OpenYida can select the matching environment and token session file. For example, Alibaba intranet Yida uses `auth-token-alibaba.json`:
73
+ When the user names a target Yida entry URL, pass it to the login command so OpenYida can select the matching environment and auth profile. For example:
74
74
 
75
75
  ```bash
76
76
  openyida login https://yida-group.alibaba-inc.com/
@@ -357,7 +357,7 @@ Run `openyida --help` or `openyida <command> --help` for detailed usage.
357
357
 
358
358
  | Command | Description |
359
359
  |---------|-------------|
360
- | `openyida login [target-url] [--env <name>\|--intl\|--overseas\|--global\|--yidaapps\|--alibaba] [--client-id <clientId>] [--endpoint <url>]` | Login with OAuth token mode |
360
+ | `openyida login [target-url] [--env <name>\|--intl\|--overseas\|--global\|--yidaapps\|--alibaba] [--client-id <clientId>] [--endpoint <url>] [--no-browser]` | Login with OAuth token mode |
361
361
  | `openyida logout` | Logout / clear token |
362
362
  | `openyida auth <status\|login\|refresh\|logout>` | Token login state management |
363
363
  | `openyida org <list\|switch> [--json] [--corp-id <corpId>]` | Organization management (list / switch by OAuth re-login) |
@@ -395,6 +395,7 @@ Run `openyida --help` or `openyida <command> --help` for detailed usage.
395
395
  | `openyida list-forms <appType> [--keyword <text>]` | List forms/pages in an app |
396
396
  | `openyida aggregate-table <list\|create-empty\|inspect\|preview\|save\|publish\|status> <appType> ...` | Manage aggregate tables (virtualView) |
397
397
  | `openyida get-schema <appType> <formUuid\|--all> [--summary-json\|--field-map-json]` | Get one form Schema or all form Schemas |
398
+ | `openyida check-prd-completeness <prd.md> --app-type <appType> [--build-manifest <file>] [--json]` | Check PRD page/resource count risk |
398
399
  | `openyida er <appType> [--format mermaid\|json] [--output file] [--include-system] [--include-pages]` | Export app entity relationship diagram |
399
400
  | `openyida create-page <appType> "<name>" [--mode dashboard] [--hide-nav] [--locale zh_CN\|en_US\|ja_JP] [--open\|--no-open]` | Create a custom display page |
400
401
  | `openyida build-page <sourceFile> [--output file\|--write]` | Build Yida-compatible page source |
package/bin/yida.js CHANGED
@@ -30,13 +30,22 @@ function isAgentEnvironment(env) {
30
30
  env.CLAUDE_CODE_ENTRYPOINT ||
31
31
  env.MULERUN_CHAT_ID ||
32
32
  env.MULE_DATA_DIR ||
33
+ env.MULE_WORKSPACE_DIR ||
33
34
  env.OPENCODE ||
34
35
  env.OPENCODE_CLIENT ||
35
36
  env.QODER_IDE ||
36
37
  env.QODER_AGENT ||
37
38
  env.QODERCLI_INTEGRATION_MODE ||
39
+ env.QODER_WORK_INTEGRATION_PRODUCT ||
38
40
  env.QWENWORK_INTEGRATION_MODE ||
39
41
  env.QWENWORKCN_INTEGRATION_MODE ||
42
+ env.QWENWORK ||
43
+ env.QWENWORK_CLIENT ||
44
+ env.QWENWORK_WORKSPACE_DIR ||
45
+ env.QWENWORK_SANDBOX_ID ||
46
+ env.QWENWORK_PREVIEW_URL ||
47
+ env.QWENWORK_VNC_URL ||
48
+ (env.AGENT_PLATFORM || '').toLowerCase().includes('qwenwork') ||
40
49
  env.CURSOR_TRACE_ID ||
41
50
  env.AGENT_WORK_ROOT ||
42
51
  env.OPENYIDA_AGENT_MODE ||
@@ -266,6 +275,12 @@ function printLoginResult(result) {
266
275
  status: result.status || (tokenUsable ? 'ok' : 'token_not_issued'),
267
276
  auth_mode: 'token',
268
277
  auth_source: result.auth_source || result.authSource,
278
+ auth_store: result.auth_store || result.authStore,
279
+ auth_profile: result.auth_profile || result.authProfile,
280
+ persistence_scope: result.persistence_scope || result.persistenceScope,
281
+ user_auth_store_writable: result.user_auth_store_writable !== undefined
282
+ ? result.user_auth_store_writable
283
+ : result.userAuthStoreWritable,
269
284
  can_auto_use: result.can_auto_use !== undefined ? !!result.can_auto_use : tokenUsable,
270
285
  token_type: result.token_type || 'Bearer',
271
286
  access_token: maskSensitiveAuthOutput({ access_token: result.access_token }).access_token,
@@ -276,6 +291,7 @@ function printLoginResult(result) {
276
291
  user_name: result.user_name,
277
292
  failure_reason: result.failure_reason,
278
293
  message: result.message,
294
+ warning: result.warning,
279
295
  raw: tokenUsable ? undefined : result.raw,
280
296
  };
281
297
  console.log(JSON.stringify(summary));
@@ -412,6 +428,7 @@ function applyLoginEnvironmentFlags(cliArgs, options = {}) {
412
428
  const valuePassthroughFlags = new Set([
413
429
  '--corp-id',
414
430
  '--client-id',
431
+ '--profile',
415
432
  '--user-id',
416
433
  ]);
417
434
  const targetUrlFlags = new Set([
@@ -520,6 +537,17 @@ function printLoginHelp() {
520
537
  printCommandUsage(t('cli.login_usage'), t('cli.login_example'));
521
538
  }
522
539
 
540
+ function buildTokenLoginOptions(loginArgs) {
541
+ return {
542
+ clientId: getArgValue(loginArgs, '--client-id'),
543
+ corpId: getArgValue(loginArgs, '--corp-id'),
544
+ userId: getArgValue(loginArgs, '--user-id'),
545
+ authProfile: getArgValue(loginArgs, '--profile'),
546
+ quiet: process.env.YIDA_QUIET === '1' || loginArgs.includes('--quiet'),
547
+ noBrowser: loginArgs.includes('--no-browser'),
548
+ };
549
+ }
550
+
523
551
  function printAuthHelp() {
524
552
  printCommandUsage(t('cli.auth_usage'), t('cli.auth_example'));
525
553
  }
@@ -618,15 +646,12 @@ async function main() {
618
646
  } else {
619
647
  assertNoUnsupportedLegacyLoginFlags(rawArgs, loginArgs);
620
648
  if (loginArgs.includes('--check-only')) {
621
- console.log(JSON.stringify(getAuthStatus(), null, 2));
649
+ console.log(JSON.stringify(getAuthStatus(buildTokenLoginOptions(loginArgs)), null, 2));
622
650
  } else if (isEnvAuthMode()) {
623
- printLoginResult(getAuthStatus());
651
+ printLoginResult(getAuthStatus(buildTokenLoginOptions(loginArgs)));
624
652
  } else {
625
653
  const { tokenLogin } = require('../lib/auth/token-auth');
626
- const result = await tokenLogin({
627
- clientId: getArgValue(loginArgs, '--client-id'),
628
- quiet: loginArgs.includes('--quiet'),
629
- });
654
+ const result = await tokenLogin(buildTokenLoginOptions(loginArgs));
630
655
  printLoginResult(result);
631
656
  }
632
657
  }
@@ -647,18 +672,15 @@ async function main() {
647
672
  if (!subCommand || subCommand === '--help' || subCommand === '-h') {
648
673
  printAuthHelp();
649
674
  } else if (subCommand === 'status') {
650
- console.log(JSON.stringify(getAuthStatus(), null, 2));
675
+ console.log(JSON.stringify(getAuthStatus(buildTokenLoginOptions(authArgs)), null, 2));
651
676
  } else if (subCommand === 'login') {
652
677
  if (hasHelpFlag(authArgs)) {
653
678
  printLoginHelp();
654
679
  } else {
655
680
  assertNoUnsupportedLegacyLoginFlags(rawArgs.slice(1), authArgs);
656
681
  const result = isEnvAuthMode()
657
- ? getAuthStatus()
658
- : await tokenLogin({
659
- clientId: getArgValue(authArgs, '--client-id'),
660
- quiet: authArgs.includes('--quiet'),
661
- });
682
+ ? getAuthStatus(buildTokenLoginOptions(authArgs))
683
+ : await tokenLogin(buildTokenLoginOptions(authArgs));
662
684
  printLoginResult(result);
663
685
  }
664
686
  } else if (subCommand === 'refresh') {
@@ -732,6 +754,12 @@ async function main() {
732
754
  break;
733
755
  }
734
756
 
757
+ case 'check-prd-completeness': {
758
+ const { run } = require('../lib/app/check-prd-completeness');
759
+ await run(args);
760
+ break;
761
+ }
762
+
735
763
  case 'er': {
736
764
  const { run } = require('../lib/app/er');
737
765
  await run(args);
@@ -1,6 +1,10 @@
1
1
  # OpenYida 功能完整列表
2
2
 
3
- 这份清单面向宜搭使用者,说明 OpenYida 支持的功能,以及对应可以执行的 `openyida` 命令。参数细节可以继续查看 `openyida --help`、`openyida <command> --help` 或 `openyida commands --json`。
3
+ 这份清单面向宜搭使用者和 AI Agent,按本地 OpenYida `2026.8.12-1` 101 条命令和技能路由整理。参数细节可以继续查看 `openyida --help`、`openyida <command> --help` 或 `openyida commands --json`。
4
+
5
+ <Note>
6
+ 日常使用建议先运行 `openyida agent-capabilities --summary-json`,它会轻量返回版本、登录态、组织、工作目录和命令清单摘要。只有排查命令契约、权限元数据或登录异常时,再使用完整的 `openyida agent-capabilities --json`。
7
+ </Note>
4
8
 
5
9
  ## 基础操作
6
10
 
@@ -27,6 +31,8 @@
27
31
  | 查询我的应用 | `openyida app-list [--size N]` |
28
32
  | 创建应用 | `openyida create-app "<应用名称>"` |
29
33
  | 更新应用名称、布局、主题 | `openyida update-app <appType> [--name "..."] [--layout slide\|ver] [--theme deepBlue]` |
34
+ | 启用应用 / 上线应用 | `openyida app-online <appType> [--to-ding-app-center] [--show-app-center]` |
35
+ | 停用应用 / 下线应用 | `openyida app-offline <appType> [--to-ding-app-center] [--show-app-center]` |
30
36
  | 导出应用迁移包 | `openyida export <appType> [output]` |
31
37
  | 导入应用迁移包 | `openyida import <file> [name]` |
32
38
  | 管理左侧导航分组 | `openyida nav-group <list\|create\|rename\|delete\|move\|order\|hide\|show> <appType> ...` |
@@ -43,6 +49,7 @@
43
49
  | 功能 | 执行操作 |
44
50
  |---|---|
45
51
  | 创建表单 | `openyida create-form create <appType> ...` |
52
+ | 校验表单字段配置 | `openyida create-form validate-fields <fieldsJsonOrFile>` |
46
53
  | 更新表单字段 | `openyida create-form update <appType> ...` |
47
54
  | 用 patch 更新表单 | `openyida create-form patch <appType> <formUuid> <patchJsonOrFile>` |
48
55
  | 配置表单联动规则 | `openyida create-form rule <appType> <formUuid> <rulesJsonOrFile>` |
@@ -54,6 +61,7 @@
54
61
  | 获取表单 Schema | `openyida get-schema <appType> <formUuid>` |
55
62
  | 获取应用全部 Schema | `openyida get-schema <appType> --all` |
56
63
  | 导出 ER 关系图 | `openyida er <appType> [--format mermaid\|json] [--output file]` |
64
+ | 注入、移除或检查表单详情页样式 | `openyida form-detail-style <apply\|remove\|check> <appType> <formUuid> ...` |
57
65
  | 管理聚合表 virtualView | `openyida aggregate-table <list\|create-empty\|inspect\|preview\|save\|publish\|status> <appType> ...` |
58
66
 
59
67
  ## 自定义页面与发布
@@ -62,6 +70,7 @@
62
70
  |---|---|
63
71
  | 创建自定义页面 | `openyida create-page <appType> "<页面名称>"` |
64
72
  | 创建看板页 | `openyida create-page <appType> "<页面名称>" --mode dashboard` |
73
+ | 查看或输出自定义页面示例 | `openyida sample yida-canvas-custom-page <sample> --output project/pages/src/<name>.canvas.jsx` / `openyida sample yida-custom-page <sample> --output project/pages/src/<name>.oyd.jsx` |
65
74
  | 构建宜搭兼容页面源码 | `openyida build-page <sourceFile> [--output file\|--write]` |
66
75
  | 检查普通自定义页面 JSX 规范 | `openyida check-page <src> [--compat]` |
67
76
  | 本地编译普通自定义页面 JSX | `openyida compile <src>` |
@@ -72,8 +81,8 @@
72
81
  | 更新页面/表单配置 | `openyida update-form-config <appType> ...` |
73
82
  | 查询页面/表单配置 | `openyida get-form-config <appType> <formUuid> [--json]` |
74
83
  | 开发高级自定义页面、看板、图表或幻灯片 | 默认优先使用 Code Canvas 链路;明确要求普通自定义页面 JSX/Jsx,或强依赖普通自定义页实例桥时使用 `.oyd.jsx` + `check-page` / `compile` / `publish` |
75
- | Code Canvas 页面使用成员/部门/上传等宜搭运行态组件 | 使用 `yida-canvas-custom-page`,参考 `yida-canvas-custom-page/references/native-components-bridge.md` 做运行态组件探测、fallback 和值归一化 |
76
- | Code Canvas 门户 + 成员/部门/上传组件 | 使用 `yida-canvas-custom-page`,按业务页面结构接入运行态组件桥 |
84
+ | Code Canvas 页面使用成员/部门/上传等宜搭运行态组件 | `openyida sample yida-canvas-custom-page native-components-smoke --output pages/src/native-components-smoke.canvas.jsx`;再参考 `yida-canvas-custom-page/references/native-components-bridge.md` |
85
+ | Code Canvas 门户 + 成员/部门/上传组件示例 | `openyida sample yida-canvas-custom-page portal-native-components --output pages/src/portal-native-components.canvas.jsx` |
77
86
  | 普通自定义页面 JSX/Jsx 使用成员/部门组件 | 使用 `.oyd.jsx`,参考 `yida-custom-page/references/component-jsx-guide.md` |
78
87
  | 普通自定义页面 JSX/Jsx 使用附件/图片上传 | 使用 `.oyd.jsx`,参考 `yida-custom-page/references/attachment-upload-guide.md` |
79
88
 
@@ -81,12 +90,16 @@
81
90
 
82
91
  | 需求 | 推荐链路 |
83
92
  |---|---|
84
- | 现代 React、hooks、官网、工作台、看板、列表、详情、可视化、AI 首次生成页面 | Code Canvas:`.canvas.jsx` / `YidaCodeCanvas` |
93
+ | 现代 React、Hooks、官网、工作台、看板、列表、详情、可视化、AI 首次生成页面 | Code Canvas:`.canvas.jsx` / `.canvas.tsx` / `YidaCodeCanvas` |
85
94
  | 需要成员、部门、附件上传、图片上传等宜搭运行态组件,且希望页面保持现代 React 体验 | Code Canvas + 原生组件桥;先跑 smoke 示例验证运行态组件,再做 fallback 和值归一化 |
86
95
  | 用户明确要求普通自定义页面 JSX/Jsx 组件链路 | 普通自定义页面:`.oyd.jsx` / `Jsx` |
87
96
  | 强依赖 `this.$(fieldId)`、`this.utils.yida.*`、`this.dataSourceMap`、表单提交或字段双向绑定 | 普通自定义页面:`.oyd.jsx` / `Jsx` |
88
97
  | 已有普通 `.oyd.jsx` 页面要迁移到 Code Canvas | 参考 `yida-canvas-upgrade` 技能 |
89
98
 
99
+ <Tip>
100
+ 新版自定义页面默认走 Code Canvas。`check-page` 和 `compile` 主要用于普通自定义页面 JSX;`.canvas.jsx` / `.canvas.tsx` 由 `openyida publish` 的 Canvas 编译阶段校验。
101
+ </Tip>
102
+
90
103
  ## 流程、审批与任务
91
104
 
92
105
  | 功能 | 执行操作 |
@@ -123,7 +136,8 @@
123
136
  |---|---|
124
137
  | 创建宜搭原生报表 | `openyida create-report <appType> "<报表名称>" ...` |
125
138
  | 向已有报表追加图表 | `openyida append-chart <appType> <reportId> ...` |
126
- | 创建 ECharts 高级报表 | 使用自定义页面开发链路,并执行 `openyida publish ...` |
139
+ | 创建 Recharts 高级看板 | 使用 Code Canvas + Recharts 示例,并执行 `openyida publish ...` |
140
+ | 维护 ECharts 复杂图表页面 | 使用普通自定义页面或 ECharts 兼容链路,并执行 `openyida publish ...` |
127
141
  | 创建经营看板/管理驾驶舱/数据大屏 | 使用 `create-page`、数据源配置、报表命令和 `publish` 组合完成 |
128
142
 
129
143
  ## 连接器、集成与钉钉
@@ -164,6 +178,8 @@
164
178
  | 解析并回填页面素材 | `openyida asset resolve [options]` |
165
179
  | 生成 AI 图片素材 | `openyida asset generate [options]` |
166
180
  | 检查宜搭公式 | `openyida formula evaluate <formula\|file> [--schema file]` |
181
+ | 读取钉钉文档并转为 Markdown | `openyida read-dingtalk-doc <docUrl> [--output <file>] [--json]` |
182
+ | 按 taskUuid 读取钉钉听记 | `openyida read-dingtalk-tingji <taskUuid> [--json]` |
167
183
  | 闪记/会议纪要转 PRD | `openyida flash-to-prd --file <path> --name "<project>"` |
168
184
  | 导出 AI 对话记录 | `openyida export-conversation [options]` |
169
185
  | 整理 VOC 反馈材料 | 按故障、需求或性能问题整理成可提交材料 |