@lovrabet/rabetbase-cli 2.5.2-beta.3 → 2.5.2-beta.4

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 (349) hide show
  1. package/README.md +1 -1
  2. package/lib/api/api-doc.js +1 -1
  3. package/lib/api/fetch-model-list.js +1 -1
  4. package/lib/api/generate-api-file.js +1 -1
  5. package/lib/api/generate-sdk-config-file.js +1 -1
  6. package/lib/auth/auth-server-ui.js +1 -1
  7. package/lib/auth/auth-server.js +1 -1
  8. package/lib/auth/constant.js +1 -1
  9. package/lib/auth/get-cookie.js +1 -1
  10. package/lib/auth/get-session-user.js +1 -1
  11. package/lib/auth/is-session-valid.js +1 -1
  12. package/lib/auth/login-success-html.js +1 -1
  13. package/lib/auth/logout.js +1 -1
  14. package/lib/cli-flags.js +1 -1
  15. package/lib/cli.js +1 -1
  16. package/lib/commands/api/generate.js +1 -1
  17. package/lib/commands/api/index.js +1 -1
  18. package/lib/commands/api/list.js +1 -1
  19. package/lib/commands/api/pull.js +1 -1
  20. package/lib/commands/api/shared.js +1 -1
  21. package/lib/commands/app/index.js +1 -1
  22. package/lib/commands/app/list.js +1 -1
  23. package/lib/commands/app/members-list.js +1 -1
  24. package/lib/commands/app/remote-directory.js +1 -1
  25. package/lib/commands/app/shared.js +1 -1
  26. package/lib/commands/app-config/delete.js +1 -1
  27. package/lib/commands/app-config/get.js +1 -1
  28. package/lib/commands/app-config/index.js +1 -1
  29. package/lib/commands/app-config/list.js +1 -1
  30. package/lib/commands/app-config/set.js +1 -1
  31. package/lib/commands/app-config/shared.js +1 -1
  32. package/lib/commands/auth/index.js +1 -1
  33. package/lib/commands/bff/create.js +1 -1
  34. package/lib/commands/bff/delete.js +1 -1
  35. package/lib/commands/bff/detail.js +1 -1
  36. package/lib/commands/bff/index.js +1 -1
  37. package/lib/commands/bff/list.js +1 -1
  38. package/lib/commands/bff/pull.js +1 -1
  39. package/lib/commands/bff/push.js +1 -1
  40. package/lib/commands/bff/status.js +1 -1
  41. package/lib/commands/cli-skill/index.js +1 -1
  42. package/lib/commands/cli-update.js +1 -1
  43. package/lib/commands/codegen/index.js +1 -1
  44. package/lib/commands/codegen/sdk.js +1 -1
  45. package/lib/commands/codegen/sql.js +1 -1
  46. package/lib/commands/common/app-registry.js +1 -1
  47. package/lib/commands/common/app-selector.js +1 -1
  48. package/lib/commands/common/async-task.js +1 -1
  49. package/lib/commands/common/dry-run.js +1 -1
  50. package/lib/commands/common/flags.js +1 -1
  51. package/lib/commands/common/local-file.js +1 -1
  52. package/lib/commands/common/validate.js +1 -1
  53. package/lib/commands/config/delete.js +1 -1
  54. package/lib/commands/config/get.js +1 -1
  55. package/lib/commands/config/index.js +1 -1
  56. package/lib/commands/config/init.js +1 -1
  57. package/lib/commands/config/list.js +1 -1
  58. package/lib/commands/config/set.js +1 -1
  59. package/lib/commands/config/shared.js +1 -1
  60. package/lib/commands/dataset/business-group-update.js +1 -1
  61. package/lib/commands/dataset/business-groups.js +1 -1
  62. package/lib/commands/dataset/capability.js +1 -1
  63. package/lib/commands/dataset/delete.js +1 -1
  64. package/lib/commands/dataset/detail.js +1 -1
  65. package/lib/commands/dataset/extend-update.js +1 -1
  66. package/lib/commands/dataset/field-restore.js +1 -1
  67. package/lib/commands/dataset/field-update.js +1 -1
  68. package/lib/commands/dataset/generate.js +1 -1
  69. package/lib/commands/dataset/index.js +1 -1
  70. package/lib/commands/dataset/list.js +1 -1
  71. package/lib/commands/dataset/operations.js +1 -1
  72. package/lib/commands/dataset/relation-audit.js +1 -1
  73. package/lib/commands/dataset/relation-create.js +1 -1
  74. package/lib/commands/dataset/relation-delete.js +1 -1
  75. package/lib/commands/dataset/relation-shared.js +1 -1
  76. package/lib/commands/dataset/relation-update.js +1 -1
  77. package/lib/commands/dataset/relations.js +1 -1
  78. package/lib/commands/dataset/rename.js +1 -1
  79. package/lib/commands/dataset/restore.js +1 -1
  80. package/lib/commands/dataset/user-deleted-field-list.js +1 -1
  81. package/lib/commands/db/analysis-batching.js +1 -1
  82. package/lib/commands/db/analyze-batch-plan.js +1 -1
  83. package/lib/commands/db/analyze-cancel.js +1 -1
  84. package/lib/commands/db/analyze-start.js +1 -1
  85. package/lib/commands/db/analyze-status.js +1 -1
  86. package/lib/commands/db/create.js +1 -1
  87. package/lib/commands/db/delete.js +1 -1
  88. package/lib/commands/db/detail.js +1 -1
  89. package/lib/commands/db/diff-refresh-start.js +1 -1
  90. package/lib/commands/db/diff-refresh-status.js +1 -1
  91. package/lib/commands/db/diff.js +1 -1
  92. package/lib/commands/db/index.js +1 -1
  93. package/lib/commands/db/list.js +1 -1
  94. package/lib/commands/db/shared.js +1 -1
  95. package/lib/commands/db/table-diff-shared.js +1 -1
  96. package/lib/commands/db/tables.js +1 -1
  97. package/lib/commands/db/test.js +1 -1
  98. package/lib/commands/db/update.js +1 -1
  99. package/lib/commands/deployment/auto-sync.js +1 -1
  100. package/lib/commands/deployment/index.js +1 -1
  101. package/lib/commands/deployment/sync-all.js +1 -1
  102. package/lib/commands/deployment/sync-jobs.js +1 -1
  103. package/lib/commands/deployment/sync-status.js +1 -1
  104. package/lib/commands/deployment/sync.js +1 -1
  105. package/lib/commands/doctor.js +1 -1
  106. package/lib/commands/file/index.js +1 -1
  107. package/lib/commands/instant-api-policy/current.js +1 -1
  108. package/lib/commands/instant-api-policy/index.js +1 -1
  109. package/lib/commands/instant-api-policy/init.js +1 -1
  110. package/lib/commands/instant-api-policy/publish.js +1 -1
  111. package/lib/commands/instant-api-policy/pull.js +1 -1
  112. package/lib/commands/instant-api-policy/revision.js +1 -1
  113. package/lib/commands/instant-api-policy/revisions.js +1 -1
  114. package/lib/commands/instant-api-policy/rollback.js +1 -1
  115. package/lib/commands/instant-api-policy/shared.js +1 -1
  116. package/lib/commands/instant-api-policy/validate.js +1 -1
  117. package/lib/commands/issue/index.js +1 -1
  118. package/lib/commands/issue/nudge.js +1 -1
  119. package/lib/commands/issue/report.js +1 -1
  120. package/lib/commands/issue/shared.js +1 -1
  121. package/lib/commands/kb/create.js +1 -1
  122. package/lib/commands/kb/delete.js +1 -1
  123. package/lib/commands/kb/detail.js +1 -1
  124. package/lib/commands/kb/index.js +1 -1
  125. package/lib/commands/kb/list.js +1 -1
  126. package/lib/commands/kb/search.js +1 -1
  127. package/lib/commands/kb/shared.js +1 -1
  128. package/lib/commands/kb/update.js +1 -1
  129. package/lib/commands/logs/index.js +1 -1
  130. package/lib/commands/menu/asset-update.js +1 -1
  131. package/lib/commands/menu/delete.js +1 -1
  132. package/lib/commands/menu/external-link-create.js +1 -1
  133. package/lib/commands/menu/external-link-update.js +1 -1
  134. package/lib/commands/menu/group-create.js +1 -1
  135. package/lib/commands/menu/group-update.js +1 -1
  136. package/lib/commands/menu/index.js +1 -1
  137. package/lib/commands/menu/list.js +1 -1
  138. package/lib/commands/menu/move.js +1 -1
  139. package/lib/commands/menu/regroup-start.js +1 -1
  140. package/lib/commands/menu/rename.js +1 -1
  141. package/lib/commands/menu/shared/compare-table.js +1 -1
  142. package/lib/commands/menu/shared/delete-plan.js +1 -1
  143. package/lib/commands/menu/shared/facts.js +1 -1
  144. package/lib/commands/menu/shared/index.js +1 -1
  145. package/lib/commands/menu/shared/inquirer.js +1 -1
  146. package/lib/commands/menu/shared/local-pages.js +1 -1
  147. package/lib/commands/menu/shared/logic.js +1 -1
  148. package/lib/commands/menu/shared/mutations.js +1 -1
  149. package/lib/commands/menu/shared/service.js +1 -1
  150. package/lib/commands/menu/shared/sync-core.js +1 -1
  151. package/lib/commands/menu/shared/update-core.js +1 -1
  152. package/lib/commands/menu/shared/valid-url.js +1 -1
  153. package/lib/commands/menu/sync.js +1 -1
  154. package/lib/commands/menu/visibility-update.js +1 -1
  155. package/lib/commands/notification/config-create.js +1 -1
  156. package/lib/commands/notification/config-delete.js +1 -1
  157. package/lib/commands/notification/config-list.js +1 -1
  158. package/lib/commands/notification/config-update.js +1 -1
  159. package/lib/commands/notification/index.js +1 -1
  160. package/lib/commands/notification/shared.js +1 -1
  161. package/lib/commands/ocr/index.js +1 -1
  162. package/lib/commands/page/create.js +1 -1
  163. package/lib/commands/page/custom/detail.js +1 -1
  164. package/lib/commands/page/custom/list.js +1 -1
  165. package/lib/commands/page/custom/publish.js +1 -1
  166. package/lib/commands/page/custom/shared.d.ts +0 -8
  167. package/lib/commands/page/custom/shared.js +1 -1
  168. package/lib/commands/page/custom/syntax.js +1 -1
  169. package/lib/commands/page/custom/update.js +1 -1
  170. package/lib/commands/page/data-list-status.js +1 -1
  171. package/lib/commands/page/generate-start.js +1 -1
  172. package/lib/commands/page/generate-status.js +1 -1
  173. package/lib/commands/page/index.js +1 -1
  174. package/lib/commands/page/pull.js +1 -1
  175. package/lib/commands/page/push.js +1 -1
  176. package/lib/commands/page/relation-audit.js +1 -1
  177. package/lib/commands/page/restore.js +1 -1
  178. package/lib/commands/page/shared.js +1 -1
  179. package/lib/commands/page/sync.js +1 -1
  180. package/lib/commands/project/create/enhanced-guided-create.js +1 -1
  181. package/lib/commands/project/create/format-elapsed.js +1 -1
  182. package/lib/commands/project/create/main.js +1 -1
  183. package/lib/commands/project/create/materialize-project-template.js +1 -1
  184. package/lib/commands/project/create/project-name.js +1 -1
  185. package/lib/commands/project/create/project-template-archive.js +1 -1
  186. package/lib/commands/project/create/project-template-path.js +1 -1
  187. package/lib/commands/project/create/use-copy-project-template.js +1 -1
  188. package/lib/commands/project/create/use-format-code.js +1 -1
  189. package/lib/commands/project/create/use-install-dependencies.js +1 -1
  190. package/lib/commands/project/domain-routing-sync.js +1 -1
  191. package/lib/commands/project/index.js +1 -1
  192. package/lib/commands/project/upgrade.js +1 -1
  193. package/lib/commands/registry.js +1 -1
  194. package/lib/commands/role/delete.js +1 -1
  195. package/lib/commands/role/detail.js +1 -1
  196. package/lib/commands/role/index.js +1 -1
  197. package/lib/commands/role/list.js +1 -1
  198. package/lib/commands/role/shared.js +1 -1
  199. package/lib/commands/role/update.js +1 -1
  200. package/lib/commands/role/user-add.js +1 -1
  201. package/lib/commands/role/user-remove.js +1 -1
  202. package/lib/commands/role/user-resolve.js +1 -1
  203. package/lib/commands/rule/get.js +1 -1
  204. package/lib/commands/rule/index.js +1 -1
  205. package/lib/commands/rule/list.js +1 -1
  206. package/lib/commands/rule/set.js +1 -1
  207. package/lib/commands/rule/shared.js +1 -1
  208. package/lib/commands/run/index.d.ts +4 -0
  209. package/lib/commands/run/index.js +1 -1
  210. package/lib/commands/schema.js +1 -1
  211. package/lib/commands/sql/create.js +1 -1
  212. package/lib/commands/sql/delete.js +1 -1
  213. package/lib/commands/sql/detail.js +1 -1
  214. package/lib/commands/sql/exec.js +1 -1
  215. package/lib/commands/sql/index.js +1 -1
  216. package/lib/commands/sql/list.js +1 -1
  217. package/lib/commands/sql/pull.js +1 -1
  218. package/lib/commands/sql/push.js +1 -1
  219. package/lib/commands/sql/shared.js +1 -1
  220. package/lib/commands/sql/status.js +1 -1
  221. package/lib/commands/sql/validate.js +1 -1
  222. package/lib/commands/task/index.js +1 -1
  223. package/lib/commands/task/status.js +1 -1
  224. package/lib/commands/tenant/index.js +1 -1
  225. package/lib/commands/tenant/members-list.js +1 -1
  226. package/lib/commands/tenant/shared.js +1 -1
  227. package/lib/commands/user-account/dingding-sandbox-bind.js +1 -1
  228. package/lib/commands/user-account/index.js +1 -1
  229. package/lib/commands/workspace/add.js +1 -1
  230. package/lib/commands/workspace/index.js +1 -1
  231. package/lib/commands/workspace/remove.js +1 -1
  232. package/lib/config/domain-config.js +1 -1
  233. package/lib/config/project-domain-routing.d.ts +5 -1
  234. package/lib/config/project-domain-routing.js +1 -1
  235. package/lib/config/schema.js +1 -1
  236. package/lib/constant/cdn.js +1 -1
  237. package/lib/constant/cli.js +1 -1
  238. package/lib/constant/defaults.js +1 -1
  239. package/lib/constant/domain.js +1 -1
  240. package/lib/constant/env.js +1 -1
  241. package/lib/constant/output.js +1 -1
  242. package/lib/constant/paths.js +1 -1
  243. package/lib/constant/region.js +1 -1
  244. package/lib/constant/risk.js +1 -1
  245. package/lib/constant/routing-profile.js +1 -1
  246. package/lib/context/app-resolver.js +1 -1
  247. package/lib/context/auth-resolver.js +1 -1
  248. package/lib/context/config-loader.js +1 -1
  249. package/lib/context.js +1 -1
  250. package/lib/core/alias-resolver.js +1 -1
  251. package/lib/core/api-client.d.ts +0 -26
  252. package/lib/core/api-client.js +1 -1
  253. package/lib/core/bff/config.js +1 -1
  254. package/lib/core/bff/file-system.js +1 -1
  255. package/lib/core/bff/hash.js +1 -1
  256. package/lib/core/bff/lock.js +1 -1
  257. package/lib/core/bff/utils.js +1 -1
  258. package/lib/core/db-resolver.js +1 -1
  259. package/lib/core/instant-api-policy/config.js +1 -1
  260. package/lib/core/kb-search-client.js +1 -1
  261. package/lib/core/page/file-system.d.ts +43 -0
  262. package/lib/core/page/file-system.js +1 -1
  263. package/lib/core/page/hash.js +1 -1
  264. package/lib/core/page/lock.js +1 -1
  265. package/lib/core/sql-index-auditor.js +1 -1
  266. package/lib/core/sql-sync/config.js +1 -1
  267. package/lib/core/sql-sync/file-system.js +1 -1
  268. package/lib/core/sql-sync/hash.js +1 -1
  269. package/lib/core/sql-sync/lock.js +1 -1
  270. package/lib/core/sql-sync/utils.js +1 -1
  271. package/lib/core/sql-validator.js +1 -1
  272. package/lib/errors.js +1 -1
  273. package/lib/framework/build-all-flags.js +1 -1
  274. package/lib/framework/error-output.js +1 -1
  275. package/lib/framework/explicit-yes.js +1 -1
  276. package/lib/framework/flags.js +1 -1
  277. package/lib/framework/help.js +1 -1
  278. package/lib/framework/index.js +1 -1
  279. package/lib/framework/output.js +1 -1
  280. package/lib/framework/response.js +1 -1
  281. package/lib/framework/runner-alias.js +1 -1
  282. package/lib/framework/runner.js +1 -1
  283. package/lib/framework/schema-export.js +1 -1
  284. package/lib/framework/supported-flags.js +1 -1
  285. package/lib/framework/types.js +1 -1
  286. package/lib/generated/build-info.d.ts +4 -4
  287. package/lib/generated/build-info.js +1 -1
  288. package/lib/generated/official-routing.js +1 -1
  289. package/lib/generated/routing-contract.js +1 -1
  290. package/lib/help.js +1 -1
  291. package/lib/postinstall.js +1 -1
  292. package/lib/runtime/confirmation.js +1 -1
  293. package/lib/runtime/event.js +1 -1
  294. package/lib/runtime/index.js +1 -1
  295. package/lib/runtime/queue.js +1 -1
  296. package/lib/runtime/resolve.js +1 -1
  297. package/lib/skills/builtin-skill.js +1 -1
  298. package/lib/skills/main.js +1 -1
  299. package/lib/skills/npx-skills-add.js +1 -1
  300. package/lib/skills/skill-presence.js +1 -1
  301. package/lib/telemetry/cli-command-trace.js +1 -1
  302. package/lib/telemetry/cli-help-trace.js +1 -1
  303. package/lib/telemetry/ensure-cli-otel-config.js +1 -1
  304. package/lib/telemetry/register-otel-exit-shutdown.js +1 -1
  305. package/lib/telemetry/send-cli-trace-log.js +1 -1
  306. package/lib/telemetry/send-platform-issue-collect-log.js +1 -1
  307. package/lib/utils/ai_config.js +1 -1
  308. package/lib/utils/apply-jq-filter.js +1 -1
  309. package/lib/utils/cdn-config.js +1 -1
  310. package/lib/utils/check-sdk-version.js +1 -1
  311. package/lib/utils/cli-version-check.js +1 -1
  312. package/lib/utils/cli-version-policy.js +1 -1
  313. package/lib/utils/config.js +1 -1
  314. package/lib/utils/entity-with-id.js +1 -1
  315. package/lib/utils/file-utils.js +1 -1
  316. package/lib/utils/guides-cdn.js +1 -1
  317. package/lib/utils/http-client.js +1 -1
  318. package/lib/utils/is-non-interactive.js +1 -1
  319. package/lib/utils/logger.js +1 -1
  320. package/lib/utils/params.js +1 -1
  321. package/lib/utils/platform.js +1 -1
  322. package/lib/utils/sleep.js +1 -1
  323. package/lib/utils/template-replacer.js +1 -1
  324. package/lib/utils/update-notice.js +1 -1
  325. package/lib/utils/version.js +1 -1
  326. package/lib/utils/with-active-cookie.js +1 -1
  327. package/lib/utils/write-cli-side-channel.js +1 -1
  328. package/package.json +2 -1
  329. package/skills/rabetbase/SKILL.md +5 -5
  330. package/skills/rabetbase/guides/custom-page-workflow.md +35 -17
  331. package/skills/rabetbase/guides/page-development-workflow.md +1 -1
  332. package/skills/rabetbase/knowledge/components.md +292 -0
  333. package/skills/rabetbase/knowledge/custom-page/generation-standards.md +74 -4
  334. package/skills/rabetbase/knowledge/custom-page/page-templates.md +68 -0
  335. package/skills/rabetbase/references/rabetbase-page-create.md +21 -9
  336. package/skills/rabetbase/references/rabetbase-page-custom-detail.md +1 -1
  337. package/skills/rabetbase/references/rabetbase-page-custom-update.md +13 -9
  338. package/skills/rabetbase/references/rabetbase-project-create.md +5 -2
  339. package/skills/rabetbase/references/rabetbase-project-domain-routing-sync.md +2 -2
  340. package/skills/rabetbase/references/rabetbase-run.md +1 -0
  341. package/skills/rabetbase.manifest.json +5 -4
  342. package/templates/README.md +10 -4
  343. package/templates/custom-pages/blank.json +5 -0
  344. package/templates/custom-pages/dashboard.json +5 -0
  345. package/templates/custom-pages/onepage.json +5 -0
  346. package/templates/generate-api/api.ts.tpl +1 -1
  347. package/lib/commands/page/custom/template.d.ts +0 -8
  348. package/lib/commands/page/custom/template.js +0 -1
  349. package/skills/rabetbase/knowledge/custom-page/components.md +0 -225
@@ -0,0 +1,292 @@
1
+ # 公共组件用法
2
+
3
+ 本文件基于 `@lovrabet/components` 最新版本的 README 和包根入口公开类型,登记可复用的 UI 组件规范。生成或修改页面前,先确认项目使用最新版本;生成或修改自定义页面时还需阅读 [`generation-standards.md`](custom-page/generation-standards.md)。
4
+
5
+ ## 使用边界
6
+
7
+ - 自定义页面可导入的组件包仅限 [`generation-standards.md`](custom-page/generation-standards.md)“依赖白名单”中的包及其子路径
8
+ - `@lovrabet/components` 使用包根入口的公开具名导出,不导入内部实现路径
9
+ - 组件的用户可见文案必须使用 `$i18n.t("key")`
10
+ - 所有组件均支持 Ant Design 主题、多语言和响应式自适应;优先继承页面配置,仅在单个组件确需覆盖时传入 `locale`
11
+ - `env` 已废弃,后续不再透出,也不属于向用户展示或由用户选择的能力;新代码不得传入该参数
12
+ - 组件样式优先复用 Ant Design token 和 CSS 变量,不写死主题色
13
+ - 未登记的业务组件、组件属性或行为不得猜测
14
+
15
+ ## `@lovrabet/components` 组件
16
+
17
+ 组件、属性和行为以 `@lovrabet/components` 最新版本包根入口的公开导出为准。页面代码从包根入口导入:
18
+
19
+ ```js
20
+ import {
21
+ YTAIButton,
22
+ YTAIInput,
23
+ YtAddressPicker,
24
+ YtCodeEditor,
25
+ YTRichEditor,
26
+ YTRichEditorPreview,
27
+ YtUpload,
28
+ YtUserSelect,
29
+ } from "@lovrabet/components";
30
+ ```
31
+
32
+ ### 请求能力
33
+
34
+ 组件只消费已传入的请求实例,不负责创建或配置请求实例。`apiFetch` 用于 `YTAIButton`、`YTAIInput` 等 AI 组件;`runtimeFetch` 用于 `YtUserSelect`、`YtUpload`、`YTRichEditor` 等用户、文件和默认图片上传能力。
35
+
36
+ 面向新代码,请求实例的消费优先级为:组件属性传入的实例优先于 `YtConfigProvider` 注入的实例;两者均未传入时,组件使用内置的线上默认实例。页面中多个相关组件共用同一实例时,在根部通过 `YtConfigProvider` 注入;仅单个组件需要使用另一实例时,直接传入该组件的 `apiFetch` 或 `runtimeFetch` 属性。
37
+
38
+ `apiFetch` 与 `runtimeFetch` 分别独立解析,不会相互替代:未传入 `runtimeFetch` 时不会使用 `apiFetch`,反之亦然。已废弃的 `env` 不属于新代码的请求实例选择规则。
39
+
40
+ 推荐按以下顺序使用:
41
+
42
+ 1. 页面内多个组件共用实例时,优先通过 `YtConfigProvider` 在根部传入。
43
+ 2. 仅个别组件需要不同实例时,再通过该组件属性覆盖根部实例。
44
+ 3. 不需要传入实例时,直接使用组件,组件会回退到内置的线上默认实例。
45
+
46
+ 根部共享实例时,其下未显式传入实例的相关组件都会消费对应实例:
47
+
48
+ ```tsx
49
+ import { YtConfigProvider } from "@lovrabet/components";
50
+
51
+ <YtConfigProvider apiFetch={apiFetch} runtimeFetch={runtimeFetch}>
52
+ <YtUserSelect appCode={appCode} />
53
+ <YtUpload appCode={appCode} />
54
+ <YTAIButton promptId={promptId} userPrompt={userPrompt} />
55
+ </YtConfigProvider>;
56
+ ```
57
+
58
+ 单个组件传入的实例会覆盖根部同类实例,适合该组件有独立请求需求的场景:
59
+
60
+ ```tsx
61
+ <YtUpload appCode={appCode} runtimeFetch={fileRuntimeFetch} />
62
+
63
+ <YTAIButton apiFetch={aiApiFetch} promptId={promptId} userPrompt={userPrompt} />
64
+ ```
65
+
66
+ 未传入 `YtConfigProvider` 或组件级实例时,无需额外配置:
67
+
68
+ ```tsx
69
+ <YtUserSelect appCode={appCode} />
70
+
71
+ <YTRichEditor appCode={appCode} defaultValue={content} />
72
+ ```
73
+
74
+ 请求实例的创建、Domain 配置和注入位置由上层应用处理;组件文档不约定这些配置方式。
75
+
76
+ | 组件 | 适用场景 | 关键使用方式 |
77
+ | --- | --- | --- |
78
+ | `YTAIButton` | 通过已配置的提示词或 Skill 发起 AI 调用 | 配置 `promptId` 或 `skillId` 与必填 `userPrompt`,处理成功和失败回调 |
79
+ | `YTAIInput` | 需要输入内容后发起 AI 调用 | 配置 AI 调用参数,并使用 `inputType`、`userPromptTemplate` 和提交前校验控制输入流程 |
80
+ | `YtUserSelect` | 多选、编辑或只读展示应用用户 | 交互值使用用户 code 字符串数组,使用 `preview` 切换只读展示 |
81
+ | `YtAddressPicker` | 选择或只读展示地址层级 | 受控传入地址 value 路径;需要自定义地址时传入 `options` 或 `optionsUrl` |
82
+ | `YtUpload` | 上传、展示、预览或下载附件 | 使用默认上传时必须显式传入当前有效的 `appCode`,组件不再自动注入;以 `value` 和 `onChange` 管理已完成的业务文件,使用 `maxCount` 限制数量 |
83
+ | `YTRichEditor` | 编辑富文本内容 | 用 `defaultValue` 初始化,通过 `onChange` 接收 HTML;使用默认图片上传时必须显式传入 `appCode`,组件不再自动注入,也可通过 `upload` 使用自定义上传 |
84
+ | `YTRichEditorPreview` | 只读展示富文本 HTML | 传入必填 `content` |
85
+ | `YtCodeEditor` | 编辑或只读展示代码、JSON 等文本 | 以 `value` 和 `onChange` 受控,按需设置 `language`、`readOnly` 和编辑器选项 |
86
+
87
+ ## 使用 Demo
88
+
89
+ 以下示例基于组件库 Storybook 用例调整而来。示例中的 `appCode`、提示词或 Skill 标识、数据和回调均由页面上下文提供;所有用户可见文案使用 `$i18n.t("key")`。示例均假设已通过 `useI18n()` 获取 `$i18n`,并按需从 React 导入 `useState`。
90
+
91
+ ### AI 按钮
92
+
93
+ ```jsx
94
+ <YTAIButton
95
+ promptId={promptId}
96
+ userPrompt={$i18n.t("ai.userPrompt")}
97
+ onSuccess={setGeneratedContent}
98
+ onError={setError}
99
+ >
100
+ {$i18n.t("ai.generate")}
101
+ </YTAIButton>
102
+ ```
103
+
104
+ 使用 `skillId` 替代 `promptId` 时,同时传入 `appCode`。Skill 调用需要展示流式结果时可传入 `showPopover`,默认值为 `false`。需要在调用前校验页面状态时,传入 `onClick` 并在不满足条件时返回 `false`。
105
+
106
+ ### AI 输入框
107
+
108
+ ```jsx
109
+ <YTAIInput
110
+ inputType="textarea"
111
+ promptId={promptId}
112
+ userPromptTemplate={$i18n.t("ai.userPromptTemplate")}
113
+ placeholder={$i18n.t("ai.placeholder")}
114
+ buttonText={$i18n.t("ai.generate")}
115
+ onBeforeSubmit={validateInput}
116
+ onSuccess={setGeneratedContent}
117
+ onError={setError}
118
+ />
119
+ ```
120
+
121
+ `userPromptTemplate` 中使用 `{input}` 引用输入内容。`validateInput` 返回 `false` 时不会调用 AI。
122
+
123
+ ### 用户选择
124
+
125
+ ```jsx
126
+ const [userCodes, setUserCodes] = useState([]);
127
+
128
+ <YtUserSelect
129
+ appCode={appCode}
130
+ value={userCodes}
131
+ onChange={setUserCodes}
132
+ placeholder={$i18n.t("userSelect.placeholder")}
133
+ />
134
+ ```
135
+
136
+ 只读展示时使用 `<YtUserSelect appCode={appCode} value={userCodes} preview />`。
137
+
138
+ ### 地址选择
139
+
140
+ ```jsx
141
+ const [address, setAddress] = useState([]);
142
+
143
+ <YtAddressPicker
144
+ options={addressOptions}
145
+ value={address}
146
+ onChange={setAddress}
147
+ />
148
+ ```
149
+
150
+ `addressOptions` 的用户可见 `label` 必须使用词条或已确认的业务数据。只读展示时传入 `preview`。
151
+
152
+ ### 附件上传
153
+
154
+ ```jsx
155
+ const [files, setFiles] = useState([]);
156
+
157
+ <YtUpload
158
+ appCode={appCode}
159
+ accept="image/*"
160
+ maxCount={maxFiles}
161
+ maxSizeMB={maxFileSizeMB}
162
+ value={files}
163
+ onChange={setFiles}
164
+ />
165
+ ```
166
+
167
+ 展示已有附件时,将已确认的 `YtUploadFile[]` 传给 `value`;只读预览、下载和列表展示时传入 `preview`。`max` 是已废弃的兼容属性,新代码使用 `maxCount`。
168
+
169
+ 自定义 `upload` 的类型为 `(file: File) => Promise<string>`。方法每次只接收一个文件,必须返回非空且可直接用于预览和下载的最终文件 URL;失败时应抛出或返回 rejected Promise,不得吞掉错误后返回空字符串。正式页面不得返回 `URL.createObjectURL(file)` 等仅在当前浏览器会话内有效的临时地址。传入 `upload` 后使用方自行负责上传服务、鉴权和服务端文件校验,组件仍负责 `maxCount`、`maxSizeMB`、`accept` 和上传状态展示;其中 `accept` 只限制文件选择器,不能替代服务端类型校验。文件与业务数据的关联、持久化和删除不属于 `upload` 方法职责。
170
+
171
+ ### 富文本编辑与预览
172
+
173
+ ```jsx
174
+ const [content, setContent] = useState(initialContent);
175
+
176
+ <YTRichEditor
177
+ appCode={appCode}
178
+ defaultValue={initialContent}
179
+ onChange={setContent}
180
+ onImageUploadError={setError}
181
+ />
182
+
183
+ <YTRichEditorPreview content={content} />
184
+ ```
185
+
186
+ 未传 `upload` 时组件使用 Lovrabet 默认图片上传,此时必须由页面显式传入有效的 `appCode`。组件不再从页面配置、运行环境或其他全局信息中自动注入 `appCode`。调用方无需配置或感知内部环境参数。需要使用自定义上传时,传入接收 `File` 并返回可访问图片 URL 的 `upload(file) => Promise<string>`,此时不需要 `appCode`。`upload` 和 `appCode` 均未配置时,文字编辑和内容预览仍可使用,但图片上传功能不可用。图片上传和内容持久化仍需遵循已确认的服务契约。
187
+
188
+ 富文本的自定义 `upload` 每次只处理一张图片,返回值必须是可直接作为图片 `src` 使用的非空最终 URL。失败时应抛出或返回 rejected Promise,由 `onImageUploadError` 统一处理;不得返回临时 Blob URL,也不得返回包含 URL 的对象。`maxImageSize` 和 `imageAccept` 只提供编辑器侧选择与体积限制,上传服务仍需校验文件内容、类型、权限和大小。该方法只负责获得图片地址,富文本内容仍通过 `onChange` 返回并由页面业务逻辑持久化。
189
+
190
+ ### 代码编辑
191
+
192
+ ```jsx
193
+ const [code, setCode] = useState("");
194
+
195
+ <YtCodeEditor
196
+ language="json"
197
+ value={code}
198
+ onChange={setCode}
199
+ placeholder={$i18n.t("codeEditor.placeholder")}
200
+ wordWrap="on"
201
+ />
202
+ ```
203
+
204
+ `YtCodeEditor` 默认使用 JSON 语言和 `240px` 高度。只读展示时使用 `readOnly`,按需使用 `minimap`、`lineNumbers`、`wordWrap`、`fontSize`、`tabSize` 或 `options` 配置编辑器;这些显式属性优先于 `options` 中的同名配置。
205
+
206
+ ## 主题、多语言与自适应
207
+
208
+ - 所有组件继承外层 Ant Design `ConfigProvider` 的主题色以及浅色、深色算法,不需要为组件单独写死颜色
209
+ - 组件默认跟随页面由 `@lovrabet/i18n` 管理的全局语言;确需覆盖单个组件时传入 `locale`
210
+ - `locale` 支持 `zh-CN`、`en-US`、`id-ID`、`ja-JP` 和 `tr-TR`,显式传入时优先于页面全局语言
211
+ - 所有组件均支持响应式自适应;页面仍应提供可收缩的容器,避免固定宽度阻止组件适配小屏
212
+
213
+ ### AI 调用组件
214
+
215
+ #### `YTAIButton`
216
+
217
+ - `userPrompt` 必填
218
+ - `promptId` 与 `skillId` 二选一,组件优先使用 `promptId`
219
+ - 使用 `skillId` 时传入当前 `appCode`;`showPopover` 只在 Skill 场景生效,用于展示流式结果,默认值为 `false`
220
+ - `gradient` 默认开启;需要使用普通 Ant Design 按钮样式时传入 `gradient={false}`
221
+ - `onClick` 返回 `false` 可阻止本次调用;通过 `onSuccess`、`onResponse` 和 `onError` 分别处理结果、完整响应和失败
222
+ - `options` 仅用于传入已确认的 `temperature`、`maxTokens` 等 AI 调用选项
223
+ - 提示词标识、权限和可用环境未确认时,不生成调用代码
224
+
225
+ #### `YTAIInput`
226
+
227
+ - 继承 `YTAIButton` 的 AI 调用配置和回调,且不直接传入 `userPrompt`
228
+ - 使用 `inputType="input"` 或 `inputType="textarea"` 选择输入形态,使用 `display="inline"` 或 `display="block"` 控制按钮布局
229
+ - `userPromptTemplate` 中的 `{input}` 会替换为当前输入内容;需要特殊拼接时使用 `formatUserPrompt`
230
+ - 使用 `onBeforeSubmit` 校验输入,返回 `false` 时阻止调用;使用 `onInputChange` 同步页面状态
231
+ - `placeholder`、`buttonText` 和其他用户可见字符串必须传入 `$i18n.t("key")` 的结果
232
+
233
+ ### 选择与上传组件
234
+
235
+ #### `YtUserSelect`
236
+
237
+ - 当前用户列表由组件加载,页面不自行猜测或复刻用户查询接口
238
+ - 组件固定为多选模式;交互场景使用用户 code 字符串数组,`onChange` 始终返回 `string[]`
239
+ - 读取时兼容字符串或数字类型的用户编号、历史 `{ code }[]` 以及用于旧数据展示的单个字符串或数字,新写入仍使用字符串数组
240
+ - 需要只读展示时传入 `preview`
241
+ - 查询应用用户列表时传入当前 `appCode`
242
+
243
+ #### `YtAddressPicker`
244
+
245
+ - `value` 使用 `string[] | null`,`onChange` 返回仅保留非空字符串的地址层级路径
246
+ - 传入 `options` 时使用调用方提供的级联选项;未传时使用组件内置地址数据,也可通过 `optionsUrl` 配置地址选项来源
247
+ - 只读展示时传入 `preview`
248
+ - 自定义选项的 `label` 为用户可见内容时,必须来自已翻译词条或已确认的业务数据
249
+
250
+ #### `YtUpload`
251
+
252
+ - 使用默认上传时必须由调用方显式传入当前有效的 `appCode`,组件不会自动注入;使用自定义 `upload` 或只读预览时不依赖默认上传配置
253
+ - 自定义 `upload` 的签名为 `(file: File) => Promise<string>`,必须返回非空、稳定且可直接预览和下载的最终文件 URL;传入后替代默认上传逻辑
254
+ - 自定义上传失败时抛出错误或返回 rejected Promise,不返回空字符串、响应对象或仅当前会话有效的 Blob URL
255
+ - `value` 支持 `YtUploadFile[]` 或兼容的 JSON 字符串,`onChange` 返回上传完成的业务文件列表
256
+ - 使用 `maxCount`、`maxSizeMB` 和 `accept` 限制上传数量、体积和文件选择范围;`max` 仅用于兼容旧代码
257
+ - `accept` 只限制文件选择器,需要严格限制文件类型时仍由上传服务校验;需要只读展示、预览和下载时传入 `preview`
258
+ - 文件持久化、提交和删除由页面业务逻辑处理;先确认数据集 SDK 或其他已确认服务契约,再写入文件字段
259
+
260
+ ### 内容编辑组件
261
+
262
+ #### `YTRichEditor` 与 `YTRichEditorPreview`
263
+
264
+ - `YTRichEditor` 的 `defaultValue` 支持 HTML 字符串或 JSON 内容,`onChange` 返回 HTML 字符串,空内容返回 `null`
265
+ - 未传 `upload` 时使用默认图片上传,调用方必须显式传入有效的 `appCode`;组件不会再自动注入 `appCode`
266
+ - 传入 `upload` 时使用自定义图片上传,不需要 `appCode`;方法签名为 `(file: File) => Promise<string>`,必须返回非空、稳定且可直接作为图片 `src` 使用的最终 URL
267
+ - 自定义图片上传失败时抛出错误或返回 rejected Promise,由 `onImageUploadError` 处理;不返回响应对象或临时 Blob URL
268
+ - `upload` 和 `appCode` 均未配置时,文字编辑和内容预览仍可使用,图片上传功能不可用
269
+ - 使用 `maxImageSize` 和 `imageAccept` 限制图片,使用 `onImageUploadError` 处理上传或校验失败
270
+ - 通过 `disabled` 控制编辑状态;通过 `locale` 设置工具栏和错误提示语言
271
+ - 使用 `YTRichEditorPreview` 或 `YTRichEditor.Preview` 展示 HTML,且必须传入 `content`
272
+ - 需要自定义加载占位时使用 `loadingFallback`,不得猜测组件内部资源地址
273
+
274
+ #### `YtCodeEditor`
275
+
276
+ - 使用 `value` 与 `onChange` 管理编辑内容;空值按空字符串处理
277
+ - `language`、`theme`、`minimap`、`lineNumbers`、`wordWrap`、`fontSize`、`tabSize` 和 `options` 用于配置 Monaco 编辑器
278
+ - 需要展示不可编辑内容时使用 `readOnly` 或 `disabled`
279
+ - 未传 `theme` 时组件跟随外层 Ant Design 主题;页面不自行猜测 Monaco 运行资源或加载方式
280
+
281
+ ### 非组件公开能力
282
+
283
+ - 包根入口公开 `useUserList`,用于自定义用户选择交互;默认优先使用 `YtUserSelect`,仅在已确认 Hook 返回结构时直接调用
284
+ - `queryLLM` 未从 `@lovrabet/components` 包根入口公开,不导入内部路径;需要 AI 调用时使用 `YTAIButton` 或 `YTAIInput`
285
+
286
+ ### 使用检查
287
+
288
+ - 组件名称与属性以公开类型声明为准,不使用 README、Storybook 或包内部文件中未公开的实现路径
289
+ - `YTRichEditor` 和 `YtUpload` 使用默认上传时,确认代码显式传入当前有效的 `appCode`,不得依赖历史默认注入行为
290
+ - 所有用户可见字符串,包括按钮文本、占位文本和自定义选项 label,均使用 `$i18n.t("key")` 或来自已确认的业务数据
291
+ - 组件的加载、空态、失败和禁用状态与页面交互一致
292
+ - 自定义数据读取或写入仍遵循 [`generation-standards.md`](custom-page/generation-standards.md) 中的数据客户端文档流程
@@ -6,7 +6,7 @@
6
6
 
7
7
  在生成 JSX、CSS 或词包前,先阅读本规范,并按需加载以下文档:
8
8
 
9
- - 选择或组合 UI 组件时,阅读 [`components.md`](components.md)
9
+ - 选择或组合 UI 组件时,阅读 [`components.md`](../components.md)
10
10
  - 访问数据集时,先确认数据集事实,并按“数据客户端文档”拉取目标数据集的 SDK 契约
11
11
 
12
12
  未在这些文档中登记的规范、组件或方法,不得假设存在。
@@ -15,7 +15,7 @@
15
15
 
16
16
  | 范畴 | 约束 |
17
17
  | -------- | ------------------------------------------------------------------------------------------------------------------------- |
18
- | 提交内容 | `page custom-update` 提交完整页面文件,未提交的已有文件会被删除 |
18
+ | 提交内容 | `page custom-update --page-dir <dir>` 提交目录中的完整页面文件,未包含的已有文件会被删除 |
19
19
  | 推荐结构 | 页面入口仍为 `src/app/index.jsx`;其余文件和组件目录可按页面需要组织,`src/app/index.css`、`src/locales/index.js`、`src/components/*.jsx` 仅为示例 |
20
20
  | 组件复用 | 优先查阅并复用已有组件库和页面已有组件;仅当现有能力无法满足需求时才创建新组件 |
21
21
  | 依赖 | 仅使用“依赖白名单”中的包及其子路径 |
@@ -46,7 +46,7 @@
46
46
  | -------- | ---------------------------------- | ------ |
47
47
  | 页面目标 | 页面解决的问题、目标用户、完成标准 | |
48
48
  | 页面身份 | 新建页面或已有 `pageId` | |
49
- | 布局 | 区域划分、响应式要求、视觉约束 | |
49
+ | 布局 | 区域划分、响应式要求(PC Web 与 mobile)以及视觉约束 | |
50
50
  | 交互 | 查询、编辑、跳转、提交、确认等行为 | |
51
51
  | 数据 | 数据集、字段、操作、权限和错误语义 | |
52
52
  | 文案 | 语言范围、词条命名和默认文案 | |
@@ -58,16 +58,22 @@
58
58
  - `src/app/index.jsx` 负责页面入口、页面级状态和主布局
59
59
  - 复杂或可复用区域可按页面需要拆分到合适的相对路径,`src/components/` 仅为示例
60
60
  - 每个组件只接收其实际需要的数据和回调,避免把页面全部状态逐层透传
61
+ - 建议根据具体需求优先考虑自适应设计,尽量避免不必要的固定像素宽高和固定列数;页面需要同时用于 PC Web 与 mobile 时,建议兼顾两端的展示与交互。对于明确限定终端、尺寸或布局的场景,可采用与需求匹配的固定方案
62
+
63
+ ### 内置页面模板
64
+
65
+ `BLANK`、`ONEPAGE` 和 `DASHBOARD` 的选型、内容边界、mock 数据替换、创建与更新方式及交互设计统一见 [`page-templates.md`](page-templates.md)。本文件只维护页面实现所需的数据访问、主题、路由、国际化、ECharts 和源码约束。
61
66
 
62
67
  ### `src/app/index.jsx` 模板
63
68
 
64
- 初始化创建自定义页面时,必须以此模板生成 `src/app/index.jsx`。将 `{{pageName}}` 替换为页面名称;保留词包注册、上下文 Hook 和样式导入,再按需求扩展布局、状态与数据调用。通过 `page create --page-content` 初始化创建时,传入的 `src/app/index.jsx` 也必须从此模板派生。
69
+ 初始化创建自定义页面时,必须以此模板生成 `src/app/index.jsx`。将 `{{pageName}}` 替换为页面名称;保留词包注册、上下文 Hook 和样式导入,再按需求扩展布局、状态与数据调用。通过 `page create --page-dir <dir>` 初始化创建时,目录中的 `src/app/index.jsx` 也必须从此模板派生。
65
70
 
66
71
  更新已有页面时,以 `page custom-detail` 返回的最新 `codeContent` 为基线;不强制套用或补齐本模板,应仅按更新需求修改页面内容。
67
72
 
68
73
  ```jsx
69
74
  import React from "react";
70
75
  import {
76
+ useAppTheme,
71
77
  useSdkClient,
72
78
  useNavigate,
73
79
  useLocation,
@@ -79,6 +85,9 @@ const App = () => {
79
85
  const $i18n = useI18n(); // 国际化多语言实例
80
86
  const navigate = useNavigate(); // 路由跳转实例
81
87
  const location = useLocation(); // 浏览器 location 实例
88
+ const theme = useAppTheme(); // 当前主题(可能未提供)
89
+ const mode = theme?.mode; // "light" | "dark"
90
+ const skinColor = theme?.skinColor; // 十六进制色值,如 "#ababab"
82
91
 
83
92
  return <div className="page-container">{/* 自定义页面内容 */}</div>;
84
93
  };
@@ -133,6 +142,7 @@ export default App;
133
142
 
134
143
  ```js
135
144
  import {
145
+ useAppTheme,
136
146
  useSdkClient,
137
147
  useI18n,
138
148
  useNavigate,
@@ -146,6 +156,66 @@ import {
146
156
  | `useI18n` | 获取页面国际化实例 | 词条 key 和词包翻译 | 见“国际化” |
147
157
  | `useNavigate` | 获取页面路由跳转方法 | 目标页面 code 和跳转方式 | 见“导航” |
148
158
  | `useLocation` | 获取当前地址信息 | 需要读取的地址信息 | 见“导航” |
159
+ | `useAppTheme` | 获取当前主题 | 主题是否可用与组件兼容性 | 见“主题配置” |
160
+
161
+ ### 主题配置
162
+
163
+ 在页面中调用 `useAppTheme()` 即可读取当前主题;没有主题时返回 `undefined`。
164
+
165
+ ```js
166
+ const theme = useAppTheme();
167
+ const mode = theme?.mode; // "light" | "dark"
168
+ const skinColor = theme?.skinColor; // 十六进制色值,如 "#ababab"
169
+ ```
170
+
171
+ - 不要依赖 `theme` 一定存在;所有访问必须使用可选链或默认值
172
+ - `mode` 与 `skinColor` 为运行期提示,不替代完整的 Ant Design 主题系统
173
+ - 推荐使用 `antd` 主题系统设置主题色,优先复用 `ConfigProvider` 的 `token`、`algorithm` 与组件 token
174
+ - 新增页面逻辑涉及颜色时,推荐优先使用当前 `ConfigProvider` 提供的 token 或 CSS 变量,让按钮、链接、选中态和自定义区域尽量跟随应用主题色变化
175
+
176
+ ### antd 主题色使用 Demo
177
+
178
+ ```jsx
179
+ import { Card, ConfigProvider, theme as antdTheme } from "antd";
180
+ import { useAppTheme, useI18n } from "@/context/app-context";
181
+
182
+ const isThemeColor = (value) =>
183
+ /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(value || "");
184
+
185
+ const getThemeConfig = (appTheme) => ({
186
+ cssVar: { key: "custom-page-theme" },
187
+ algorithm:
188
+ appTheme?.mode === "dark"
189
+ ? antdTheme.darkAlgorithm
190
+ : antdTheme.defaultAlgorithm,
191
+ ...(isThemeColor(appTheme?.skinColor)
192
+ ? {
193
+ token: {
194
+ colorPrimary: appTheme.skinColor,
195
+ },
196
+ }
197
+ : {}),
198
+ });
199
+
200
+ const App = () => {
201
+ const $i18n = useI18n();
202
+ const appTheme = useAppTheme();
203
+
204
+ return (
205
+ <ConfigProvider theme={getThemeConfig(appTheme)}>
206
+ <Card title={$i18n.t("title")}>{$i18n.t("content")}</Card>
207
+ </ConfigProvider>
208
+ );
209
+ };
210
+
211
+ export default App;
212
+ ```
213
+
214
+ - 推荐做法(最佳实践,可按页面实际情况调整,不作为强制要求):
215
+ - `mode === "dark"` 时可使用 `antdTheme.darkAlgorithm`,其他情况可使用 `antdTheme.defaultAlgorithm`
216
+ - `skinColor` 合法时可作为 `colorPrimary`;未传入或不合法时建议不设置该 token,交由 Ant Design 使用默认主题色
217
+ - 需要在 CSS 中使用 token 时,建议启用 `cssVar`,随后使用 `var(--ant-color-primary)`、`var(--ant-color-bg-layout)` 等变量,减少直接写死 hex
218
+ - 仅使用组件 token 时,可以不启用 `cssVar`
149
219
 
150
220
  ### 国际化
151
221
 
@@ -0,0 +1,68 @@
1
+ # 自定义页面模板
2
+
3
+ 本文档集中说明自定义页面内置模板的选择、内容边界和使用方式。页面开发约束、数据访问、主题、路由、国际化和 ECharts 规范见 [`generation-standards.md`](generation-standards.md)。
4
+
5
+ ## 模板选择
6
+
7
+ | 模板 | 适合场景 | 模板内容 |
8
+ | --- | --- | --- |
9
+ | `BLANK` | 从空白页面和基础布局开始实现 | 页面入口、基础样式、词包和主题示例,不包含具体业务内容或业务数据 |
10
+ | `ONEPAGE` | 综合页面、一页式业务工作台,或需要在一个页面内集中完成业务数据的查看、编辑、操作和管理 | 一页式工作台布局,包含业务概览、关联记录、详情和后续处理区域 |
11
+ | `DASHBOARD` | 通过指标卡、趋势、分布和对比等图表多维展示业务数据 | 基于 ECharts 的响应式仪表盘布局,包含指标、筛选、图表和明细入口 |
12
+
13
+ 模板随 CLI npm 包发布并从本地读取,不依赖 CDN:
14
+
15
+ | 模板 | 本地文件 |
16
+ | --- | --- |
17
+ | `BLANK` | `templates/custom-pages/blank.json` |
18
+ | `ONEPAGE` | `templates/custom-pages/onepage.json` |
19
+ | `DASHBOARD` | `templates/custom-pages/dashboard.json` |
20
+
21
+ ## 内容与数据边界
22
+
23
+ - `BLANK` 是空白基础页面,不包含具体业务内容或示例业务数据,使用时从实际页面需求开始补充内容和数据接入。
24
+ - `ONEPAGE` 和 `DASHBOARD` 只提供布局、主题和交互示例,其中的数据均为 mock,不直接读取或写入业务数据。
25
+ - 使用 `ONEPAGE` 或 `DASHBOARD` 时,必须使用真实的业务数据集替换全部 mock 数据,不把模板内容作为最终页面发布。
26
+ - 替换数据前先确认实际数据集、字段、关联关系、统计口径、可用操作和权限范围。
27
+ - 按 [`generation-standards.md`](generation-standards.md) 中的数据访问方式,通过 `useSdkClient()` 获取页面提供的 `client`,使用 `client` 完成数据查询和写入,不在页面中另建客户端或自行拼接接口。
28
+ - 数据接入同时处理加载状态、空态、失败提示和重试;需要额外权限或业务规则控制时,按页面开发规范使用受控 BFF。
29
+
30
+ ## 创建和更新
31
+
32
+ 内置模板既用于初始化页面,也用于已有页面的实现参考。页面已经生成或已有完整内容时,仍可根据实际需求参考对应模板的布局、主题、组件组织和交互方式;此时只选择性合并需要的实现,不要求重新创建页面,也不能直接使用模板覆盖已有内容。
33
+
34
+ 创建页面时,通过 `--page-pattern` 使用内置模板初始化:
35
+
36
+ ```bash
37
+ rabetbase page create --page-pattern <BLANK|ONEPAGE|DASHBOARD> --name <name> --appcode <appCode> --dry-run
38
+ ```
39
+
40
+ 创建页面时必须显式选择一种来源:使用内置模板时传入 `--page-pattern <BLANK|ONEPAGE|DASHBOARD>`;使用完整本地页面内容时传入 `--page-dir <dir>`。两个参数不能同时使用,也不能同时省略。
41
+
42
+ 使用 `--page-dir` 创建已经准备好内容的页面时,也可先参考模板实现,再提交完整页面文件。更新已有页面时,`page custom-update` 不接受 `--page-pattern`;先通过 `page custom-detail` 获取最新完整页面内容,再按需要参考 `BLANK`、`ONEPAGE` 或 `DASHBOARD`,选择性合并后提交。
43
+
44
+ ## `ONEPAGE` 交互设计
45
+
46
+ `ONEPAGE` 以当前页面作为业务上下文中心,在一个页面中高效完成业务数据的查看、编辑、操作和管理;存在上下游或关联业务时,通过打开子页面连接完整业务链路。
47
+
48
+ - 主页面集中展示当前业务对象、关联数据、处理进度和可执行操作,减少在多个菜单之间切换。
49
+ - 查看、新增或编辑关联数据时,优先使用 `navigate("/pagecode", { onePage: true })` 打开子页面,保留主页面的筛选条件、选中记录和操作上下文。
50
+ - 子页面关闭或操作完成后,回到主页面并刷新受影响的关联列表、详情和统计信息,同时保持当前操作位置。
51
+ - 使用前确认真实页面 code、数据集关联关系、可用操作和权限范围,并替换模板中的 mock 数据和示例入口。
52
+
53
+ ## `DASHBOARD` 交互设计
54
+
55
+ `DASHBOARD` 在一个页面中组合指标数据和图表,从总览、趋势、分布、构成和对比等维度集中展示业务数据情况。
56
+
57
+ - 先展示关键指标和整体状态,再通过图表呈现变化、差异和构成,避免堆叠与页面目标无关的图表。
58
+ - 时间范围、分类条件和统计维度统一管理,并联动更新相关指标和图表。
59
+ - 图表通过提示信息、图例切换和数据项点击查看具体维度;需要查看明细时,可在当前页面展开明细,或通过 `navigate("/pagecode", { onePage: true })` 打开子页面。
60
+ - 进入明细和返回看板时保留筛选条件和查看位置。
61
+ - 指标和图表分别处理加载、空态、失败和重试,避免单个区域异常阻断整个页面。
62
+ - 使用前确认真实数据来源、统计口径、权限和可用操作;ECharts 只负责呈现,不承担数据访问、业务计算或权限判断。
63
+
64
+ ## 主题适配
65
+
66
+ - 页面通过 `useAppTheme()` 获取应用主题配置,并通过 Ant Design 主题系统应用 `mode` 和 `skinColor`。
67
+ - 推荐复用 Ant Design token 和 CSS 变量,不在业务代码中直接写死主色值。
68
+ - `ONEPAGE` 和 `DASHBOARD` 的布局、组件和图表颜色都需要同时适配亮色与暗色模式。
@@ -7,7 +7,9 @@
7
7
  ```bash
8
8
  rabetbase page create --page-pattern BLANK --name "客户看板" --appcode <appCode> --dry-run --format compress
9
9
  rabetbase page create --page-pattern BLANK --name "客户看板" --parent-menu-id 100 --appcode <appCode>
10
- rabetbase page create --name "客户看板" --page-content '<json>' --appcode <appCode>
10
+ rabetbase page create --page-pattern ONEPAGE --name "客户看板" --appcode <appCode> --dry-run --format compress
11
+ rabetbase page create --page-pattern DASHBOARD --name "业务数据看板" --appcode <appCode> --dry-run --format compress
12
+ rabetbase page create --name "客户看板" --page-dir ./customer-dashboard --appcode <appCode>
11
13
  ```
12
14
 
13
15
  ## 参数
@@ -16,16 +18,26 @@ rabetbase page create --name "客户看板" --page-content '<json>' --appcode <a
16
18
  |---|---|---|
17
19
  | `--name <name>` | 否 | 可选页面名称,1–100 个字符;省略时默认 `Custom_page_<timestamp>` |
18
20
  | `--parent-menu-id <id>` | 否 | 父菜单 ID |
19
- | `--page-pattern <pattern>` | 条件必填 | 页面模式;当前只支持 `BLANK`,与 `--page-content` 必须且只能提供一个 |
20
- | `--page-content <json>` | 条件必填 | 完整页面文件 JSON;对象的键为相对路径,值为文件内容,与 `--page-pattern` 必须且只能提供一个 |
21
+ | `--page-pattern <pattern>` | 条件必填 | 页面模式;支持 `BLANK`、`ONEPAGE`、`DASHBOARD`,不能与 `--page-dir` 同时使用;模板详情见 [`page-templates.md`](../knowledge/custom-page/page-templates.md) |
22
+ | `--page-dir <dir>` | 条件必填 | 完整页面文件目录;不能与 `--page-pattern` 同时使用,目录必须包含文件;CLI 递归读取目录内的常规文件,将相对路径和 UTF-8 文件内容作为完整页面文件提交 |
21
23
  | `--appcode <code>` | 是 | 目标应用 code |
22
24
 
25
+ ## 页面内容来源
26
+
27
+ 1. 使用内置模板时显式传入 `--page-pattern`
28
+ 2. 使用完整页面文件时显式传入 `--page-dir`
29
+ 3. 两者同时提供、均未提供或目录为空时,本地校验失败
30
+
23
31
  ## 执行步骤
24
32
 
25
- 1. 使用基础模板时传 `--page-pattern BLANK`;已有完整源码时只传 `--page-content`。
26
- 2. 使用 `--dry-run` 确认页面名称、父菜单与最终页面文件。
27
- 3. 确认后使用相同参数执行创建。
28
- 4. 从结构化输出的 `data.after.pageId` 确认新页面 ID,并核对 `data.pageType=CUSTOM`;模式创建返回 `data.pagePattern=BLANK`,完整源码创建返回 `null`。
29
- 5. 输出的 `pageUrl` 用于查看最新保存内容,包含尚未发布的修改;`editPageUrl` 用于打开页面编辑器,继续修改页面。
33
+ 1. 不使用页面模板时,若本地已有完整页面目录,直接将该目录传给 `--page-dir`;若本地没有已有内容,则先在当前工作目录创建临时专用页面目录并生成完整页面文件,再传 `--page-dir`。CLI 读取目录后负责转换为请求内容,调用方不需要也不得自行拼接 `page-content` JSON。
34
+ 2. 使用内置模板时,按 [`page-templates.md`](../knowledge/custom-page/page-templates.md) 选择 `BLANK`、`ONEPAGE` 或 `DASHBOARD`,并显式传入对应的 `--page-pattern`。
35
+ 3. 使用 `--dry-run` 确认页面名称、父菜单与最终页面文件。
36
+ 4. 确认后使用相同参数执行创建。
37
+ 5. 仅当步骤 1 创建了临时页面目录时,正式创建流程成功、失败、中断或取消后删除该目录,删除范围仅限本流程创建的临时目录;通过 `--page-dir` 传入的本地已有页面目录不得删除。
38
+ 6. 创建成功时,从结构化输出的 `data.after.pageId` 确认新页面 ID,并核对 `data.pageType=CUSTOM`;模板创建返回对应的 `data.pagePattern`,目录创建返回 `data.pagePattern=null`。
39
+ 7. 输出的 `pageUrl` 用于查看最新保存内容,包含尚未发布的修改;`editPageUrl` 用于打开页面编辑器,继续修改页面。
40
+
41
+ 页面创建始终同时创建菜单。`BLANK`、`ONEPAGE` 与 `DASHBOARD` 分别读取内置的 `templates/custom-pages/blank.json`、`templates/custom-pages/onepage.json` 与 `templates/custom-pages/dashboard.json` 作为完整页面文件。未发布模式会在本地失败,不请求服务端。
30
42
 
31
- 页面创建始终同时创建菜单。`BLANK` 模式会按应用语言设置生成词包;读取设置失败时使用默认中英文词包。未发布模式会在本地失败,不请求服务端。
43
+ 三个模板的适用场景、内容边界、mock 数据替换、真实数据接入和交互设计统一见 [`page-templates.md`](../knowledge/custom-page/page-templates.md)。页面开发和 `client` 使用方式见 [`generation-standards.md`](../knowledge/custom-page/generation-standards.md)。
@@ -23,4 +23,4 @@ rabetbase page custom-detail --id <pageId> --format compress
23
23
  - `runtimePageUrl`:查看已发布内容的页面地址,仅在有已发布内容时返回;host 为 `<appCode>.<appDomain host>`
24
24
  - `editPageUrl`:打开当前节点或独立部署工作台中的页面编辑器
25
25
 
26
- `data.codeContent` 是当前完整页面文件,可在本地完成新增、修改或删除后,作为 `page custom-update --page-content <json>` 的完整页面内容提交。
26
+ `data.codeContent` 是当前完整页面文件。将其写入本地目录后完成新增、修改或删除,再以 `page custom-update --page-dir <dir>` 提交该目录中的完整页面内容。
@@ -1,10 +1,10 @@
1
1
  # page custom-update
2
2
 
3
- 以完整页面文件 JSON 更新 自定义页面,并创建新的保存版本。未包含的文件会被删除。
3
+ 从本地目录读取完整页面文件更新 自定义页面,并创建新的保存版本。目录中未包含的文件会被删除。
4
4
 
5
5
  ```bash
6
- rabetbase page custom-update --id <pageId> --page-content '<json>' --dry-run --format compress
7
- rabetbase page custom-update --id <pageId> --page-content '<json>' --appcode <appCode>
6
+ rabetbase page custom-update --id <pageId> --page-dir <dir> --dry-run --format compress
7
+ rabetbase page custom-update --id <pageId> --page-dir <dir> --appcode <appCode>
8
8
  ```
9
9
 
10
10
  ## 参数
@@ -12,13 +12,17 @@ rabetbase page custom-update --id <pageId> --page-content '<json>' --appcode <ap
12
12
  | 参数 | 必填 | 说明 |
13
13
  |---|---|---|
14
14
  | `--id <pageId>` | 是 | 自定义页面 ID |
15
- | `--page-content <json>` | 是 | 完整页面文件 JSON;对象的键为相对路径,值为文件内容 |
15
+ | `--page-dir <dir>` | 是 | 包含完整页面文件的本地目录,CLI 递归读取其中的常规文件 |
16
16
  | `--appcode <code>` | 否 | 目标应用 code,省略时根据 `pageId` 查询 |
17
17
 
18
18
  ## 执行步骤
19
19
 
20
- 1. 先使用 `page custom-detail` 读取 `data.codeContent` 中的完整页面文件。
21
- 2. 在本地完成所有文件新增、修改或删除后,使用 `--dry-run` 确认完整页面文件。
22
- 3. 确认后使用相同参数执行更新。
23
- 4. 从结构化输出的 `data.after.version` 确认已保存新版本。
24
- 5. 输出的 `pageUrl` 用于查看最新保存内容,包含尚未发布的修改;`editPageUrl` 用于打开页面编辑器,继续修改页面。
20
+ 1. 先使用 `page custom-detail` 读取 `data.codeContent` 中的完整页面文件,并写入专用本地目录。
21
+ 2. 需要调整页面布局或交互时,以具体需求和最新页面文件为准。[`page-templates.md`](../knowledge/custom-page/page-templates.md) 中的 `BLANK`、`ONEPAGE` 和 `DASHBOARD` 仅作为可选参考;模板实现适合当前需求时,可将相关结构、样式和交互选择性合并到最新页面文件中,不要求使用模板。
22
+ 3. 在该目录完成所有文件新增、修改或删除后,使用 `--page-dir` 与 `--dry-run` 确认完整页面文件。
23
+ 4. 确认后使用相同参数执行更新。
24
+ 5. 正式更新命令结束后,无论成功、失败或中断,删除步骤 1 创建的临时页面目录,删除范围仅限该目录。
25
+ 6. 从结构化输出的 `data.after.version` 确认已保存新版本。
26
+ 7. 输出的 `pageUrl` 用于查看最新保存内容,包含尚未发布的修改;`editPageUrl` 用于打开页面编辑器,继续修改页面。
27
+
28
+ `page custom-update` 不接受 `--page-pattern`。内置模板在更新场景中仅作为实现参考,详细规则见 [`page-templates.md`](../knowledge/custom-page/page-templates.md);更新始终以 `page custom-detail` 返回的最新完整页面内容为基线,避免覆盖已有功能和尚未发布的修改。
@@ -57,6 +57,9 @@ rabetbase project create my-project --appcode <code>
57
57
 
58
58
  `api pull` 的单应用/项目应用清单输出结构见 [`rabetbase-api-pull.md`](rabetbase-api-pull.md),TypeScript 合并规则见 [`sdk-client-generation.md`](../guides/sdk-client-generation.md)。Agent 可根据实际输出选择检查、修复和验证方式。
59
59
 
60
+
61
+ 项目创建完成后,如需在子应用页面中使用公共组件,先阅读 [`components.md`](../knowledge/components.md) 确认最新组件用法,并可参考项目内 `src/pages/components-demo` 的交互和实现。`components-demo` 必须在项目配置了有效 AppCode 后使用,优先在创建工程时传入 `--appcode <code>`;如创建后补充 AppCode,需执行 `rabetbase config set appcode <code>` 和 `rabetbase api pull` 完成初始化,否则用户选择、附件上传等依赖应用信息的组件无法使用。示例中的 mock 数据和富文本图片 mock 上传仅用于展示效果,正式页面需按实际业务替换。
62
+
60
63
  ## 提示
61
64
 
62
65
  - `--name` 和位置参数二选一,`--name` 优先
@@ -67,7 +70,7 @@ rabetbase project create my-project --appcode <code>
67
70
  - 交互与非交互模式使用同一创建流程,都会安装依赖、格式化代码并写入项目配置
68
71
  - 项目模板从 CDN 下载并校验 SHA-256;CDN 不可用、模板不兼容或校验失败时命令停止,修复后重试
69
72
  - 新项目中的 `.rabetbase.json` **只继承**全局中的少量偏好及 `region` / Domain 路由配置,**不会**把全局的 `apps` / `defaultApp` 复制进新项目
70
- - `src/api/sdk-config.ts` 与 `rabetbase.domain-routing.json` 只生成浏览器可公开的最终路由,不会写入 `cookie`、`accessKey` 等认证配置;Domain 配置变化后用 [`project domain-routing-sync`](rabetbase-project-domain-routing-sync.md) 刷新项目快照。`api.ts` / `client.ts` 仅在缺失时由 CLI 写脚手架,已有文件按 [`sdk-client-generation.md`](../guides/sdk-client-generation.md) 更新;若项目创建时首次拉取失败,按 CLI 提示执行 `rabetbase api pull --force --yes` 完成占位脚手架初始化
73
+ - `src/api/sdk-config.ts` 与 `rabetbase.domain-routing.json` 只生成浏览器可公开的最终路由,不会写入 `cookie`、`accessKey` 等认证配置;`rabetbase run start|dev|build|preview` 会在执行脚本前刷新公开 Domain 快照,也可用 [`project domain-routing-sync`](rabetbase-project-domain-routing-sync.md) 立即显式刷新。`api.ts` / `client.ts` 仅在缺失时由 CLI 写脚手架,已有文件按 [`sdk-client-generation.md`](../guides/sdk-client-generation.md) 更新;若项目创建时首次拉取失败,按 CLI 提示执行 `rabetbase api pull --force --yes` 完成占位脚手架初始化
71
74
 
72
75
  | 当前有效路由 | `src/api/sdk-config.ts` |
73
76
  |--------------|-------------------------|
@@ -76,7 +79,7 @@ rabetbase project create my-project --appcode <code>
76
79
  | Global | `{ runtimeDomain: "https://runtime.lovrabet.ai" }`,兼容 SDK 1.5.3 |
77
80
  | 独立部署 | `{ runtimeDomain: "https://…" }` |
78
81
 
79
- 模板依赖 SDK 1.5.3+。CLI 从统一 Routing Profile 生成 `rabetbase.domain-routing.json`,其中只包含最终 User/App/Runtime Domain、`cdn.libraries`、`cdn.lovrabet`、本地地址和证书 URL,不复制节点注册表。每个官方节点直接配置两个 CDN 地址;中国大陆当前使用 AliCDN,印尼当前使用 Cloudflare cdnjs,任一新节点都可以使用独立 CDN。企业独立部署使用清单中的显式值。
82
+ 模板依赖 SDK 1.5.3+。CLI 从统一 Routing Profile 生成 `rabetbase.domain-routing.json`,其中只包含最终 API/User/App/Runtime/Skill/KB Domain、`cdn.libraries`、`cdn.lovrabet`、本地地址和证书 URL,不复制节点注册表。每个官方节点直接配置两个 CDN 地址;中国大陆当前使用 AliCDN,印尼当前使用 Cloudflare cdnjs,任一新节点都可以使用独立 CDN。企业独立部署使用清单中的显式值。
80
83
 
81
84
  ## 参考
82
85
 
@@ -16,12 +16,12 @@ rabetbase project domain-routing-sync --format compress
16
16
  - 不要求登录或 AppCode,不访问平台,不生成全局副本。
17
17
  - 该文件供项目模板与 Vite 消费,不是 React Router、页面 path 或菜单路由配置。
18
18
 
19
- 生成内容只包含公开信息:User/App/Runtime Domain、资源策略、本地开发 Domain 与可选证书 URL;不会写入 Cookie、AccessKey 等认证配置。
19
+ 生成内容只包含公开信息:API/User/App/Runtime/Skill/KB Domain、资源策略、本地开发 Domain 与可选证书 URL;不会写入 Cookie、AccessKey 等认证配置。
20
20
 
21
21
  ## 使用时机
22
22
 
23
23
  - `project create` 会自动完成首次生成,无需紧接着重复执行。
24
- - 修改项目级 Domain 配置后执行。
24
+ - 修改项目级 Domain 配置后需要立即刷新时执行;后续执行 `rabetbase run start|dev|build|preview` 也会在脚本启动前自动刷新。
25
25
  - 全局 Domain 配置变化且当前项目需要采用新结果时执行。
26
26
  - 文件缺失或模板提示重新生成时执行。
27
27