openxiangda 1.0.264 → 2.0.0-alpha.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.
- package/README.md +11 -666
- package/bin/run.js +11 -0
- package/dist/browser/AuthoritativeSelector.d.ts +37 -0
- package/dist/browser/AuthoritativeSelector.d.ts.map +1 -0
- package/dist/browser/AuthoritativeSelector.js +357 -0
- package/dist/browser/AuthoritativeSelector.js.map +1 -0
- package/dist/browser/FilePreviewPage.d.ts +2 -0
- package/dist/browser/FilePreviewPage.d.ts.map +1 -0
- package/dist/browser/FilePreviewPage.js +191 -0
- package/dist/browser/FilePreviewPage.js.map +1 -0
- package/dist/browser/Shell.d.ts +6 -0
- package/dist/browser/Shell.d.ts.map +1 -0
- package/dist/browser/Shell.js +198 -0
- package/dist/browser/Shell.js.map +1 -0
- package/dist/browser/appearance.d.ts +12 -0
- package/dist/browser/appearance.d.ts.map +1 -0
- package/dist/browser/appearance.js +100 -0
- package/dist/browser/appearance.js.map +1 -0
- package/dist/browser/application.d.ts +8 -0
- package/dist/browser/application.d.ts.map +1 -0
- package/dist/browser/application.js +42 -0
- package/dist/browser/application.js.map +1 -0
- package/dist/browser/components/platform-fields/AddressField.d.ts +12 -0
- package/dist/browser/components/platform-fields/AddressField.d.ts.map +1 -0
- package/dist/browser/components/platform-fields/AddressField.js +179 -0
- package/dist/browser/components/platform-fields/AddressField.js.map +1 -0
- package/dist/browser/components/platform-fields/AttachmentFileList.d.ts +9 -0
- package/dist/browser/components/platform-fields/AttachmentFileList.d.ts.map +1 -0
- package/dist/browser/components/platform-fields/AttachmentFileList.js +164 -0
- package/dist/browser/components/platform-fields/AttachmentFileList.js.map +1 -0
- package/dist/browser/components/platform-fields/CascadeField.d.ts +13 -0
- package/dist/browser/components/platform-fields/CascadeField.d.ts.map +1 -0
- package/dist/browser/components/platform-fields/CascadeField.js +14 -0
- package/dist/browser/components/platform-fields/CascadeField.js.map +1 -0
- package/dist/browser/components/platform-fields/DateTimeField.d.ts +16 -0
- package/dist/browser/components/platform-fields/DateTimeField.d.ts.map +1 -0
- package/dist/browser/components/platform-fields/DateTimeField.js +51 -0
- package/dist/browser/components/platform-fields/DateTimeField.js.map +1 -0
- package/dist/browser/components/platform-fields/JsonField.d.ts +11 -0
- package/dist/browser/components/platform-fields/JsonField.d.ts.map +1 -0
- package/dist/browser/components/platform-fields/JsonField.js +40 -0
- package/dist/browser/components/platform-fields/JsonField.js.map +1 -0
- package/dist/browser/components/platform-fields/LocationField.d.ts +11 -0
- package/dist/browser/components/platform-fields/LocationField.d.ts.map +1 -0
- package/dist/browser/components/platform-fields/LocationField.js +73 -0
- package/dist/browser/components/platform-fields/LocationField.js.map +1 -0
- package/dist/browser/components/platform-fields/PlatformDirectoryPicker.d.ts +12 -0
- package/dist/browser/components/platform-fields/PlatformDirectoryPicker.d.ts.map +1 -0
- package/dist/browser/components/platform-fields/PlatformDirectoryPicker.js +269 -0
- package/dist/browser/components/platform-fields/PlatformDirectoryPicker.js.map +1 -0
- package/dist/browser/components/platform-fields/ResourceReferenceField.d.ts +12 -0
- package/dist/browser/components/platform-fields/ResourceReferenceField.d.ts.map +1 -0
- package/dist/browser/components/platform-fields/ResourceReferenceField.js +22 -0
- package/dist/browser/components/platform-fields/ResourceReferenceField.js.map +1 -0
- package/dist/browser/components/platform-fields/RichTextField.d.ts +14 -0
- package/dist/browser/components/platform-fields/RichTextField.d.ts.map +1 -0
- package/dist/browser/components/platform-fields/RichTextField.js +214 -0
- package/dist/browser/components/platform-fields/RichTextField.js.map +1 -0
- package/dist/browser/components/platform-fields/SignatureField.d.ts +15 -0
- package/dist/browser/components/platform-fields/SignatureField.d.ts.map +1 -0
- package/dist/browser/components/platform-fields/SignatureField.js +179 -0
- package/dist/browser/components/platform-fields/SignatureField.js.map +1 -0
- package/dist/browser/components/platform-fields/SubtableField.d.ts +18 -0
- package/dist/browser/components/platform-fields/SubtableField.d.ts.map +1 -0
- package/dist/browser/components/platform-fields/SubtableField.js +236 -0
- package/dist/browser/components/platform-fields/SubtableField.js.map +1 -0
- package/dist/browser/components/platform-fields/address-value.d.ts +13 -0
- package/dist/browser/components/platform-fields/address-value.d.ts.map +1 -0
- package/dist/browser/components/platform-fields/address-value.js +70 -0
- package/dist/browser/components/platform-fields/address-value.js.map +1 -0
- package/dist/browser/components/platform-fields/cascade-value.d.ts +6 -0
- package/dist/browser/components/platform-fields/cascade-value.d.ts.map +1 -0
- package/dist/browser/components/platform-fields/cascade-value.js +47 -0
- package/dist/browser/components/platform-fields/cascade-value.js.map +1 -0
- package/dist/browser/components/platform-fields/directory-value.d.ts +7 -0
- package/dist/browser/components/platform-fields/directory-value.d.ts.map +1 -0
- package/dist/browser/components/platform-fields/directory-value.js +35 -0
- package/dist/browser/components/platform-fields/directory-value.js.map +1 -0
- package/dist/browser/components/platform-fields/field-form-codec.d.ts +10 -0
- package/dist/browser/components/platform-fields/field-form-codec.d.ts.map +1 -0
- package/dist/browser/components/platform-fields/field-form-codec.js +82 -0
- package/dist/browser/components/platform-fields/field-form-codec.js.map +1 -0
- package/dist/browser/components/platform-fields/location-value.d.ts +20 -0
- package/dist/browser/components/platform-fields/location-value.d.ts.map +1 -0
- package/dist/browser/components/platform-fields/location-value.js +57 -0
- package/dist/browser/components/platform-fields/location-value.js.map +1 -0
- package/dist/browser/components/platform-fields/resource-query.d.ts +14 -0
- package/dist/browser/components/platform-fields/resource-query.d.ts.map +1 -0
- package/dist/browser/components/platform-fields/resource-query.js +102 -0
- package/dist/browser/components/platform-fields/resource-query.js.map +1 -0
- package/dist/browser/components/platform-fields/rich-text-value.d.ts +12 -0
- package/dist/browser/components/platform-fields/rich-text-value.d.ts.map +1 -0
- package/dist/browser/components/platform-fields/rich-text-value.js +83 -0
- package/dist/browser/components/platform-fields/rich-text-value.js.map +1 -0
- package/dist/browser/components/platform-fields/subtable-value.d.ts +31 -0
- package/dist/browser/components/platform-fields/subtable-value.d.ts.map +1 -0
- package/dist/browser/components/platform-fields/subtable-value.js +120 -0
- package/dist/browser/components/platform-fields/subtable-value.js.map +1 -0
- package/dist/browser/components/resource/GeneratedResourceCrud.d.ts +8 -0
- package/dist/browser/components/resource/GeneratedResourceCrud.d.ts.map +1 -0
- package/dist/browser/components/resource/GeneratedResourceCrud.js +580 -0
- package/dist/browser/components/resource/GeneratedResourceCrud.js.map +1 -0
- package/dist/browser/components/resource/ResourceBatchActions.d.ts +25 -0
- package/dist/browser/components/resource/ResourceBatchActions.d.ts.map +1 -0
- package/dist/browser/components/resource/ResourceBatchActions.js +168 -0
- package/dist/browser/components/resource/ResourceBatchActions.js.map +1 -0
- package/dist/browser/components/resource/StandardResourcePages.d.ts +57 -0
- package/dist/browser/components/resource/StandardResourcePages.d.ts.map +1 -0
- package/dist/browser/components/resource/StandardResourcePages.js +89 -0
- package/dist/browser/components/resource/StandardResourcePages.js.map +1 -0
- package/dist/browser/components/resource/SurfaceFields.d.ts +88 -0
- package/dist/browser/components/resource/SurfaceFields.d.ts.map +1 -0
- package/dist/browser/components/resource/SurfaceFields.js +497 -0
- package/dist/browser/components/resource/SurfaceFields.js.map +1 -0
- package/dist/browser/components/resource/generated-resource-definition.d.ts +19 -0
- package/dist/browser/components/resource/generated-resource-definition.d.ts.map +1 -0
- package/dist/browser/components/resource/generated-resource-definition.js +2 -0
- package/dist/browser/components/resource/generated-resource-definition.js.map +1 -0
- package/dist/browser/components/resource/resource-import.d.ts +15 -0
- package/dist/browser/components/resource/resource-import.d.ts.map +1 -0
- package/dist/browser/components/resource/resource-import.js +197 -0
- package/dist/browser/components/resource/resource-import.js.map +1 -0
- package/dist/browser/data-provider.d.ts +4 -0
- package/dist/browser/data-provider.d.ts.map +1 -0
- package/dist/browser/data-provider.js +45 -0
- package/dist/browser/data-provider.js.map +1 -0
- package/dist/browser/platform-client.d.ts +81 -0
- package/dist/browser/platform-client.d.ts.map +1 -0
- package/dist/browser/platform-client.js +422 -0
- package/dist/browser/platform-client.js.map +1 -0
- package/dist/browser/resource-definitions.d.ts +8 -0
- package/dist/browser/resource-definitions.d.ts.map +1 -0
- package/dist/browser/resource-definitions.js +14 -0
- package/dist/browser/resource-definitions.js.map +1 -0
- package/dist/browser/runtime-meta.d.ts +22 -0
- package/dist/browser/runtime-meta.d.ts.map +1 -0
- package/dist/browser/runtime-meta.js +79 -0
- package/dist/browser/runtime-meta.js.map +1 -0
- package/dist/browser/runtime.d.ts +13 -0
- package/dist/browser/runtime.d.ts.map +1 -0
- package/dist/browser/runtime.js +47 -0
- package/dist/browser/runtime.js.map +1 -0
- package/dist/browser/styles.css +1941 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +2 -0
- package/dist/config.js.map +1 -0
- package/dist/core.d.ts +6 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +4 -0
- package/dist/core.js.map +1 -0
- package/dist/field-kit.d.ts +22 -0
- package/dist/field-kit.d.ts.map +1 -0
- package/dist/field-kit.js +22 -0
- package/dist/field-kit.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/nest.d.ts +10 -0
- package/dist/nest.d.ts.map +1 -0
- package/dist/nest.js +9 -0
- package/dist/nest.js.map +1 -0
- package/dist/react.d.ts +12 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +11 -0
- package/dist/react.js.map +1 -0
- package/dist/testing.d.ts +4 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +4 -0
- package/dist/testing.js.map +1 -0
- package/package.json +95 -200
- package/skills/manifest.json +10 -0
- package/skills/openxiangda-v2/SKILL.md +55 -0
- package/skills/openxiangda-v2/references/architecture.md +7 -0
- package/skills/openxiangda-v2/references/backend.md +116 -0
- package/skills/openxiangda-v2/references/data-authz.md +93 -0
- package/skills/openxiangda-v2/references/delivery.md +11 -0
- package/skills/openxiangda-v2/references/discovery.md +15 -0
- package/skills/openxiangda-v2/references/frontend.md +10 -0
- package/skills/openxiangda-v2/references/testing.md +16 -0
- package/skills/openxiangda-v2/references/workflow-notification.md +69 -0
- package/skills/openxiangda-v2/references/workspace.md +21 -0
- package/bin/openxiangda.js +0 -26
- package/lib/app-function-invoke.js +0 -28
- package/lib/application-environments.js +0 -1134
- package/lib/change-baseline.js +0 -1359
- package/lib/cli.js +0 -31084
- package/lib/config.js +0 -450
- package/lib/content-cache.js +0 -97
- package/lib/delivery-v2-cli.js +0 -329
- package/lib/delivery-v2-executor.js +0 -1703
- package/lib/delivery-v2-package.js +0 -1176
- package/lib/dependency-capsule.js +0 -246
- package/lib/design-gates.js +0 -668
- package/lib/design-review.js +0 -220
- package/lib/developer-center.js +0 -160
- package/lib/form-field-contract.js +0 -79
- package/lib/form-schema-loader.js +0 -181
- package/lib/git-remote-identity.js +0 -89
- package/lib/http.js +0 -196
- package/lib/integration-bundle.js +0 -225
- package/lib/js-code-build.js +0 -175
- package/lib/open-api.js +0 -256
- package/lib/policy.js +0 -137
- package/lib/publish-context.js +0 -98
- package/lib/publish-lease-heartbeat.js +0 -182
- package/lib/publish-lease.js +0 -221
- package/lib/release-error-classification.js +0 -41
- package/lib/release-explain.js +0 -75
- package/lib/release-mainline.js +0 -654
- package/lib/release-plan.js +0 -550
- package/lib/release-telemetry.js +0 -182
- package/lib/resource-binding-contract.js +0 -210
- package/lib/role-resolution.js +0 -57
- package/lib/runtime-lineage.js +0 -326
- package/lib/sdd.js +0 -3306
- package/lib/skills.js +0 -453
- package/lib/source-dependencies.js +0 -921
- package/lib/task-status.js +0 -330
- package/lib/utils.js +0 -178
- package/lib/workspace-bootstrap.js +0 -268
- package/lib/workspace-init.js +0 -202
- package/lib/worktree-cleanup.js +0 -631
- package/lib/worktree-owner.js +0 -354
- package/openxiangda-skills/SKILL.md +0 -226
- package/openxiangda-skills/references/architecture-design.md +0 -409
- package/openxiangda-skills/references/architecture-patterns.md +0 -264
- package/openxiangda-skills/references/automation-v3.md +0 -349
- package/openxiangda-skills/references/best-practices.md +0 -272
- package/openxiangda-skills/references/component-guide.md +0 -287
- package/openxiangda-skills/references/connector-resources.md +0 -80
- package/openxiangda-skills/references/data-views.md +0 -360
- package/openxiangda-skills/references/forms/component-registry.md +0 -90
- package/openxiangda-skills/references/forms/form-schema.md +0 -146
- package/openxiangda-skills/references/forms/layout-and-rules.md +0 -24
- package/openxiangda-skills/references/notifications.md +0 -227
- package/openxiangda-skills/references/openxiangda-api.md +0 -971
- package/openxiangda-skills/references/pages/app-shell.md +0 -66
- package/openxiangda-skills/references/pages/page-sdk.md +0 -401
- package/openxiangda-skills/references/pages/publish-flow.md +0 -84
- package/openxiangda-skills/references/pages/workspace-structure.md +0 -41
- package/openxiangda-skills/references/permission-design-patterns.md +0 -313
- package/openxiangda-skills/references/permissions-settings.md +0 -468
- package/openxiangda-skills/references/platform-data-model.md +0 -340
- package/openxiangda-skills/references/resource-manifest-cheatsheet.md +0 -936
- package/openxiangda-skills/references/school-contact-relations.md +0 -224
- package/openxiangda-skills/references/style-system.md +0 -218
- package/openxiangda-skills/references/troubleshooting.md +0 -271
- package/openxiangda-skills/references/workflow-v3.md +0 -441
- package/openxiangda-skills/references/workspace-state.md +0 -115
- package/openxiangda-skills/skills/openxiangda-app/SKILL.md +0 -118
- package/openxiangda-skills/skills/openxiangda-architecture-design/SKILL.md +0 -137
- package/openxiangda-skills/skills/openxiangda-core/SKILL.md +0 -222
- package/openxiangda-skills/skills/openxiangda-form/SKILL.md +0 -184
- package/openxiangda-skills/skills/openxiangda-inspect/SKILL.md +0 -63
- package/openxiangda-skills/skills/openxiangda-open-api/SKILL.md +0 -57
- package/openxiangda-skills/skills/openxiangda-open-api/agents/openai.yaml +0 -4
- package/openxiangda-skills/skills/openxiangda-open-api/references/backend-authentication.md +0 -63
- package/openxiangda-skills/skills/openxiangda-open-api/references/dingtalk-api.openapi.json +0 -15653
- package/openxiangda-skills/skills/openxiangda-page/SKILL.md +0 -154
- package/openxiangda-skills/skills/openxiangda-permission-settings/SKILL.md +0 -209
- package/openxiangda-skills/skills/openxiangda-workflow-automation/SKILL.md +0 -201
- package/packages/sdk/bin/lowcode-workspace.mjs +0 -4
- package/packages/sdk/dist/ProcessPreview-DSUIJi5V.d.mts +0 -1292
- package/packages/sdk/dist/ProcessPreview-DSUIJi5V.d.ts +0 -1292
- package/packages/sdk/dist/build/index.cjs +0 -1
- package/packages/sdk/dist/build/index.d.mts +0 -60
- package/packages/sdk/dist/build/index.d.ts +0 -60
- package/packages/sdk/dist/build/index.mjs +0 -1
- package/packages/sdk/dist/components/index.cjs +0 -148
- package/packages/sdk/dist/components/index.d.mts +0 -970
- package/packages/sdk/dist/components/index.d.ts +0 -970
- package/packages/sdk/dist/components/index.mjs +0 -148
- package/packages/sdk/dist/dataManagementApi-Ro9itwm8.d.ts +0 -142
- package/packages/sdk/dist/dataManagementApi-p_HOhQnA.d.mts +0 -142
- package/packages/sdk/dist/runtime/index.cjs +0 -148
- package/packages/sdk/dist/runtime/index.d.mts +0 -171
- package/packages/sdk/dist/runtime/index.d.ts +0 -171
- package/packages/sdk/dist/runtime/index.mjs +0 -148
- package/packages/sdk/dist/runtime/react.cjs +0 -148
- package/packages/sdk/dist/runtime/react.d.mts +0 -3202
- package/packages/sdk/dist/runtime/react.d.ts +0 -3202
- package/packages/sdk/dist/runtime/react.mjs +0 -148
- package/packages/sdk/dist/styles/antd-theme.cjs +0 -1
- package/packages/sdk/dist/styles/antd-theme.d.mts +0 -6
- package/packages/sdk/dist/styles/antd-theme.d.ts +0 -6
- package/packages/sdk/dist/styles/antd-theme.mjs +0 -1
- package/packages/sdk/dist/styles/tailwind-preset.cjs +0 -1
- package/packages/sdk/dist/styles/tailwind-preset.d.mts +0 -74
- package/packages/sdk/dist/styles/tailwind-preset.d.ts +0 -74
- package/packages/sdk/dist/styles/tailwind-preset.mjs +0 -1
- package/packages/sdk/dist/styles/tokens.css +0 -74
- package/packages/sdk/dist/workflow/index.cjs +0 -3
- package/packages/sdk/dist/workflow/index.d.mts +0 -291
- package/packages/sdk/dist/workflow/index.d.ts +0 -291
- package/packages/sdk/dist/workflow/index.mjs +0 -3
- package/packages/sdk/source/admin-list/AdminList.tsx +0 -1734
- package/packages/sdk/source/admin-list/README.md +0 -12
- package/packages/sdk/source/admin-list/dataSources.ts +0 -345
- package/packages/sdk/source/admin-list/index.ts +0 -42
- package/packages/sdk/source/admin-list/preferences.ts +0 -174
- package/packages/sdk/source/admin-list/types.ts +0 -273
- package/packages/sdk/src/build-source/README.md +0 -9
- package/packages/sdk/src/build-source/bin/lowcode-workspace.mjs +0 -7
- package/packages/sdk/src/build-source/package.json +0 -34
- package/packages/sdk/src/build-source/scripts/build-forms.mjs +0 -1129
- package/packages/sdk/src/build-source/scripts/build-pages.mjs +0 -897
- package/packages/sdk/src/build-source/scripts/build-workspace.mjs +0 -89
- package/packages/sdk/src/build-source/scripts/publish-all.mjs +0 -190
- package/packages/sdk/src/build-source/scripts/publish-oss.mjs +0 -144
- package/packages/sdk/src/build-source/scripts/register-bundle.mjs +0 -1
- package/packages/sdk/src/build-source/scripts/register.mjs +0 -362
- package/packages/sdk/src/build-source/scripts/sync-schema.mjs +0 -381
- package/packages/sdk/src/build-source/scripts/utils/form-api.mjs +0 -1058
- package/packages/sdk/src/build-source/scripts/utils/form-runtime-assets.mjs +0 -57
- package/packages/sdk/src/build-source/scripts/utils/incremental.mjs +0 -348
- package/packages/sdk/src/build-source/scripts/utils/load-config.mjs +0 -331
- package/packages/sdk/src/build-source/scripts/utils/mime-types.mjs +0 -70
- package/packages/sdk/src/build-source/scripts/utils/namespace-css.mjs +0 -77
- package/packages/sdk/src/build-source/scripts/utils/oss-client.mjs +0 -128
- package/packages/sdk/src/build-source/scripts/utils/pages.mjs +0 -150
- package/packages/sdk/src/build-source/scripts/utils/progress.mjs +0 -57
- package/packages/sdk/src/build-source/scripts/utils/publish-oss-patterns.mjs +0 -20
- package/packages/sdk/src/build-source/scripts/utils/register-payload.mjs +0 -90
- package/packages/sdk/src/build-source/scripts/utils/runtime-css-check.mjs +0 -44
- package/packages/sdk/src/build-source/scripts/utils/schema-transform.mjs +0 -142
- package/packages/sdk/src/build-source/scripts/utils/static-assets.mjs +0 -165
- package/packages/sdk/src/build-source/scripts/utils/tailwind-config.mjs +0 -283
- package/packages/sdk/src/build-source/scripts/utils/tailwind-token-warnings.mjs +0 -146
- package/packages/sdk/src/build-source/scripts/utils/workspace-style-entry.mjs +0 -29
- package/packages/sdk/src/build-source/src/cli.mjs +0 -735
- package/policy/openxiangda-policy.json +0 -72
- package/templates/openxiangda-react-spa/.cursor/rules/openxiangda-form.mdc +0 -24
- package/templates/openxiangda-react-spa/.cursor/rules/openxiangda-page.mdc +0 -25
- package/templates/openxiangda-react-spa/.cursor/rules/openxiangda-resources.mdc +0 -32
- package/templates/openxiangda-react-spa/.cursor/rules/openxiangda-workflow-automation.mdc +0 -26
- package/templates/openxiangda-react-spa/.cursor/rules/openxiangda.mdc +0 -68
- package/templates/openxiangda-react-spa/.env.example +0 -4
- package/templates/openxiangda-react-spa/.qoder/rules/openxiangda-form.md +0 -37
- package/templates/openxiangda-react-spa/.qoder/rules/openxiangda-page.md +0 -29
- package/templates/openxiangda-react-spa/.qoder/rules/openxiangda-resources.md +0 -32
- package/templates/openxiangda-react-spa/.qoder/rules/openxiangda-workflow-automation.md +0 -34
- package/templates/openxiangda-react-spa/.qoder/rules/openxiangda.md +0 -66
- package/templates/openxiangda-react-spa/AGENTS.md +0 -192
- package/templates/openxiangda-react-spa/DELIVERY.md +0 -43
- package/templates/openxiangda-react-spa/app-workspace.config.ts +0 -50
- package/templates/openxiangda-react-spa/index.html +0 -12
- package/templates/openxiangda-react-spa/package.json +0 -53
- package/templates/openxiangda-react-spa/postcss.config.cjs +0 -6
- package/templates/openxiangda-react-spa/scripts/build-js-code.mjs +0 -600
- package/templates/openxiangda-react-spa/scripts/deploy.mjs +0 -18
- package/templates/openxiangda-react-spa/scripts/guard-publish.mjs +0 -21
- package/templates/openxiangda-react-spa/src/app/navigation.ts +0 -73
- package/templates/openxiangda-react-spa/src/app/router.tsx +0 -146
- package/templates/openxiangda-react-spa/src/app/starter-content.ts +0 -144
- package/templates/openxiangda-react-spa/src/forms/.gitkeep +0 -1
- package/templates/openxiangda-react-spa/src/layouts/AdminShell.tsx +0 -570
- package/templates/openxiangda-react-spa/src/main.tsx +0 -21
- package/templates/openxiangda-react-spa/src/pages/admin/AdminDashboardPage.tsx +0 -170
- package/templates/openxiangda-react-spa/src/pages/admin/LoginLogPage.tsx +0 -425
- package/templates/openxiangda-react-spa/src/pages/defaults/DataRoutePage.tsx +0 -36
- package/templates/openxiangda-react-spa/src/pages/defaults/FilePreviewRoutePage.tsx +0 -65
- package/templates/openxiangda-react-spa/src/pages/defaults/FormRoutePage.tsx +0 -235
- package/templates/openxiangda-react-spa/src/pages/public/PublicRegisterPage.tsx +0 -15
- package/templates/openxiangda-react-spa/src/pages/states/NotFoundPage.tsx +0 -31
- package/templates/openxiangda-react-spa/src/resources/menus/menus.json +0 -22
- package/templates/openxiangda-react-spa/src/resources/permissions/page-groups/app-admin.json +0 -8
- package/templates/openxiangda-react-spa/src/resources/permissions/page-groups/public-visitor.json +0 -8
- package/templates/openxiangda-react-spa/src/resources/public-access/public-register.json +0 -14
- package/templates/openxiangda-react-spa/src/resources/roles/roles.json +0 -15
- package/templates/openxiangda-react-spa/src/resources/routes/public-register.json +0 -8
- package/templates/openxiangda-react-spa/src/runtime/default-page-overrides.tsx +0 -35
- package/templates/openxiangda-react-spa/src/runtime/default-routes.ts +0 -16
- package/templates/openxiangda-react-spa/src/shared/form-schema.ts +0 -135
- package/templates/openxiangda-react-spa/src/shared/mac-admin.tsx +0 -651
- package/templates/openxiangda-react-spa/src/shared/ui.tsx +0 -22
- package/templates/openxiangda-react-spa/src/styles/index.css +0 -105
- package/templates/openxiangda-react-spa/tailwind.config.cjs +0 -37
- package/templates/openxiangda-react-spa/tsconfig.app.json +0 -36
- package/templates/openxiangda-react-spa/tsconfig.js-code-nodes.json +0 -19
- package/templates/openxiangda-react-spa/tsconfig.json +0 -7
- package/templates/openxiangda-react-spa/tsconfig.node.json +0 -10
- package/templates/openxiangda-react-spa/vite.config.ts +0 -209
- package/templates/sy-lowcode-app-workspace/.cursor/rules/openxiangda-form.mdc +0 -24
- package/templates/sy-lowcode-app-workspace/.cursor/rules/openxiangda-page.mdc +0 -21
- package/templates/sy-lowcode-app-workspace/.cursor/rules/openxiangda-resources.mdc +0 -40
- package/templates/sy-lowcode-app-workspace/.cursor/rules/openxiangda-workflow-automation.mdc +0 -21
- package/templates/sy-lowcode-app-workspace/.cursor/rules/openxiangda.mdc +0 -81
- package/templates/sy-lowcode-app-workspace/.qoder/rules/openxiangda-form.md +0 -38
- package/templates/sy-lowcode-app-workspace/.qoder/rules/openxiangda-page.md +0 -39
- package/templates/sy-lowcode-app-workspace/.qoder/rules/openxiangda-resources.md +0 -59
- package/templates/sy-lowcode-app-workspace/.qoder/rules/openxiangda-workflow-automation.md +0 -46
- package/templates/sy-lowcode-app-workspace/.qoder/rules/openxiangda.md +0 -82
- package/templates/sy-lowcode-app-workspace/AGENTS.md +0 -158
- package/templates/sy-lowcode-app-workspace/DELIVERY.md +0 -43
- package/templates/sy-lowcode-app-workspace/app-workspace.config.ts +0 -51
- package/templates/sy-lowcode-app-workspace/examples/best-practices/README.md +0 -43
- package/templates/sy-lowcode-app-workspace/examples/best-practices/access-governance.md +0 -239
- package/templates/sy-lowcode-app-workspace/examples/best-practices/catalog.json +0 -99
- package/templates/sy-lowcode-app-workspace/examples/best-practices/decision-guide.md +0 -94
- package/templates/sy-lowcode-app-workspace/examples/best-practices/design-style.md +0 -91
- package/templates/sy-lowcode-app-workspace/examples/best-practices/module-structure.md +0 -48
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/domain/role-governance/index.ts +0 -2
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/domain/role-governance/permissions.test.ts +0 -52
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/domain/role-governance/permissions.ts +0 -37
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/domain/role-governance/types.ts +0 -19
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/domain/service-ticket/index.ts +0 -4
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/domain/service-ticket/permissions.test.ts +0 -42
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/domain/service-ticket/permissions.ts +0 -25
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/domain/service-ticket/state-machine.test.ts +0 -63
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/domain/service-ticket/state-machine.ts +0 -73
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/domain/service-ticket/ticket-query.test.ts +0 -34
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/domain/service-ticket/ticket-query.ts +0 -73
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/domain/service-ticket/types.ts +0 -66
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/forms/app-role/page.tsx +0 -1
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/forms/app-role/schema.ts +0 -109
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/forms/customer-profile/page.tsx +0 -1
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/forms/customer-profile/schema.ts +0 -92
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/forms/service-ticket/page.tsx +0 -1
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/forms/service-ticket/schema.ts +0 -153
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/forms/ticket-action-log/page.tsx +0 -1
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/forms/ticket-action-log/schema.ts +0 -65
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/js-code-nodes/daily_ticket_digest/index.ts +0 -44
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/js-code-nodes/sync_roles_to_platform/index.ts +0 -33
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/glass-home-dashboard/App.tsx +0 -8
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/glass-home-dashboard/GlassHomeDashboard.tsx +0 -232
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/glass-home-dashboard/index.tsx +0 -10
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/glass-home-dashboard/page.config.ts +0 -14
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/glass-home-dashboard/styles.css +0 -196
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/interactive-workbench/App.tsx +0 -7
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/interactive-workbench/WorkbenchPage.tsx +0 -36
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/interactive-workbench/components/ConfigPanel.tsx +0 -34
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/interactive-workbench/components/PreviewPanel.tsx +0 -17
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/interactive-workbench/index.tsx +0 -10
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/interactive-workbench/page.config.ts +0 -9
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/interactive-workbench/reducer.ts +0 -29
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/interactive-workbench/styles.css +0 -24
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/mint-analytics-dashboard/App.tsx +0 -8
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/mint-analytics-dashboard/MintAnalyticsDashboard.tsx +0 -279
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/mint-analytics-dashboard/index.tsx +0 -10
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/mint-analytics-dashboard/page.config.ts +0 -14
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/mint-analytics-dashboard/styles.css +0 -163
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/mobile-portal-shell/App.tsx +0 -7
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/mobile-portal-shell/MobilePortalShell.tsx +0 -31
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/mobile-portal-shell/index.tsx +0 -10
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/mobile-portal-shell/modules/MobileHome.tsx +0 -13
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/mobile-portal-shell/page.config.ts +0 -14
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/mobile-portal-shell/routes.ts +0 -13
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/mobile-portal-shell/styles.css +0 -11
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/ops-monitor-dashboard/App.tsx +0 -8
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/ops-monitor-dashboard/OpsMonitorDashboard.tsx +0 -306
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/ops-monitor-dashboard/index.tsx +0 -10
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/ops-monitor-dashboard/page.config.ts +0 -14
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/ops-monitor-dashboard/styles.css +0 -248
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/pc-portal-shell/App.tsx +0 -7
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/pc-portal-shell/PcPortalShell.tsx +0 -35
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/pc-portal-shell/components/PortalMetric.tsx +0 -11
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/pc-portal-shell/index.tsx +0 -10
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/pc-portal-shell/modules/HomeModule.tsx +0 -25
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/pc-portal-shell/modules/TicketsModule.tsx +0 -14
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/pc-portal-shell/page.config.ts +0 -14
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/pc-portal-shell/routes.ts +0 -19
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/pc-portal-shell/styles.css +0 -35
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/service-ticket-ops/App.tsx +0 -7
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/service-ticket-ops/TicketOpsPage.tsx +0 -105
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/service-ticket-ops/components/TicketActionTimeline.tsx +0 -22
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/service-ticket-ops/components/TicketDetailDrawer.tsx +0 -44
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/service-ticket-ops/components/TicketTableActions.tsx +0 -57
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/service-ticket-ops/index.tsx +0 -10
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/service-ticket-ops/page.config.ts +0 -9
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/service-ticket-ops/styles.css +0 -35
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/work-order-list-drawer/App.tsx +0 -8
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/work-order-list-drawer/WorkOrderListDrawerPage.tsx +0 -371
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/work-order-list-drawer/index.tsx +0 -10
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/work-order-list-drawer/page.config.ts +0 -14
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/work-order-list-drawer/styles.css +0 -182
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/resources/automations/daily-ticket-digest/automation.json +0 -25
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/resources/automations/daily-ticket-digest/trigger.json +0 -9
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/resources/notifications/daily-ticket-digest.json +0 -24
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/resources/permissions/form-groups/service-ticket-college.json +0 -21
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/resources/permissions/roles.json +0 -17
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/resources/workflows/expense-approval-workflow.json +0 -48
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/shared/components/ConfirmAction.tsx +0 -22
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/shared/components/QueryState.tsx +0 -37
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/shared/components/StatusTag.tsx +0 -20
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/shared/components/admin-ui-templates/DashboardPrimitives.tsx +0 -832
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/shared/components/admin-ui-templates/chartOptions.ts +0 -140
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/shared/components/admin-ui-templates/sampleData.ts +0 -466
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/shared/components/admin-ui-templates/styles.css +0 -874
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/shared/components/admin-ui-templates/types.ts +0 -150
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/shared/hooks/useTicketOps.ts +0 -96
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/shared/services/role-governance.ts +0 -48
- package/templates/sy-lowcode-app-workspace/examples/best-practices/src/shared/services/service-ticket.ts +0 -113
- package/templates/sy-lowcode-app-workspace/examples/forms/customer/page.tsx +0 -1
- package/templates/sy-lowcode-app-workspace/examples/forms/customer/schema.ts +0 -36
- package/templates/sy-lowcode-app-workspace/index.html +0 -12
- package/templates/sy-lowcode-app-workspace/package.json +0 -58
- package/templates/sy-lowcode-app-workspace/postcss.config.cjs +0 -9
- package/templates/sy-lowcode-app-workspace/scripts/build-js-code.mjs +0 -600
- package/templates/sy-lowcode-app-workspace/scripts/guard-publish.mjs +0 -29
- package/templates/sy-lowcode-app-workspace/src/dev/App.tsx +0 -820
- package/templates/sy-lowcode-app-workspace/src/forms/.gitkeep +0 -1
- package/templates/sy-lowcode-app-workspace/src/forms/README.md +0 -52
- package/templates/sy-lowcode-app-workspace/src/index.css +0 -26
- package/templates/sy-lowcode-app-workspace/src/js-code-nodes/.gitkeep +0 -1
- package/templates/sy-lowcode-app-workspace/src/js-code-nodes/types.d.ts +0 -3
- package/templates/sy-lowcode-app-workspace/src/main.tsx +0 -29
- package/templates/sy-lowcode-app-workspace/src/pages/.gitkeep +0 -1
- package/templates/sy-lowcode-app-workspace/src/runtime/builtin-overrides.tsx +0 -8
- package/templates/sy-lowcode-app-workspace/src/shared/form-schema.ts +0 -135
- package/templates/sy-lowcode-app-workspace/src/types/app-workspace.types.ts +0 -88
- package/templates/sy-lowcode-app-workspace/tailwind.config.cjs +0 -31
- package/templates/sy-lowcode-app-workspace/tsconfig.app.json +0 -40
- package/templates/sy-lowcode-app-workspace/tsconfig.examples.json +0 -24
- package/templates/sy-lowcode-app-workspace/tsconfig.js-code-nodes.json +0 -19
- package/templates/sy-lowcode-app-workspace/tsconfig.json +0 -7
- package/templates/sy-lowcode-app-workspace/tsconfig.node.json +0 -10
- package/templates/sy-lowcode-app-workspace/vite.config.ts +0 -85
- package/v2/README.md +0 -35
- package/v2/skills/manifest.json +0 -45
- package/v2/skills/openxiangda-v1-maintenance/SKILL.md +0 -21
- package/v2/skills/openxiangda-v1-maintenance/agents/openai.yaml +0 -4
- package/v2/skills/openxiangda-v2/SKILL.md +0 -38
- package/v2/skills/openxiangda-v2-architecture/SKILL.md +0 -29
- package/v2/skills/openxiangda-v2-architecture/agents/openai.yaml +0 -4
- package/v2/skills/openxiangda-v2-backend/SKILL.md +0 -28
- package/v2/skills/openxiangda-v2-backend/agents/openai.yaml +0 -4
- package/v2/skills/openxiangda-v2-data-authz/SKILL.md +0 -28
- package/v2/skills/openxiangda-v2-data-authz/agents/openai.yaml +0 -4
- package/v2/skills/openxiangda-v2-delivery/SKILL.md +0 -30
- package/v2/skills/openxiangda-v2-delivery/agents/openai.yaml +0 -4
- package/v2/skills/openxiangda-v2-frontend/SKILL.md +0 -21
- package/v2/skills/openxiangda-v2-frontend/agents/openai.yaml +0 -4
- package/v2/skills/openxiangda-v2-workflow-events/SKILL.md +0 -28
- package/v2/skills/openxiangda-v2-workflow-events/agents/openai.yaml +0 -4
- /package/{v2/skills → skills}/openxiangda-v2/agents/openai.yaml +0 -0
|
@@ -1,936 +0,0 @@
|
|
|
1
|
-
# Resource Manifest Cheatsheet
|
|
2
|
-
|
|
3
|
-
> 1-2 屏速查:`src/resources/` 下各类型 manifest 的最小可用模板与对应运行时调用方式。
|
|
4
|
-
> 这里只放"复制即用"的骨架;字段语义详见对应的 reference 文档。
|
|
5
|
-
|
|
6
|
-
## 通用约定
|
|
7
|
-
|
|
8
|
-
- **本地用逻辑 code**:所有 manifest 用稳定的 `formCode` / `pageCode` / `workflowCode` / `automationCode` / `connectorCode` / `dataViewCode` / `roleCode` / `notificationType`。
|
|
9
|
-
- **平台 ID 由 CLI 解析**:`openxiangda resource publish --profile <name>` 把 code 解析成当前 profile 的真实 ID 并写回 `.openxiangda/state.json`。
|
|
10
|
-
- **永远不写密钥**:第三方 API key、token、secret、password、authorization、headers 等绝不出现在 `src/resources/`,平台管理员在后台配置。
|
|
11
|
-
- **多 profile 不共享 ID**:`dev` / `prod` 各自维护一份资源 ID 映射,复制 manifest 即可复用,不要复制平台 ID。
|
|
12
|
-
- **Auth provider 只返回身份声明**:登录 provider App Function 不能发 token、写 cookie、直接改用户表或绑定表;平台按策略创建/绑定/拒绝。
|
|
13
|
-
|
|
14
|
-
## 命令
|
|
15
|
-
|
|
16
|
-
正式多资源开发仍推荐先写 `src/resources/**`,再走声明式发布:
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
openxiangda resource validate --profile <name> # 静态校验所有 manifest
|
|
20
|
-
openxiangda resource plan --profile <name> # diff:本地 vs. 平台
|
|
21
|
-
openxiangda resource publish --profile <name> --dry-run # 预览 publish 计划,不写平台和本地生成文件
|
|
22
|
-
openxiangda resource publish --profile <name> # 非破坏性 upsert(不 prune)
|
|
23
|
-
openxiangda resource publish --profile <name> --prune # 删除 manifest 未声明的平台资源(谨慎)
|
|
24
|
-
openxiangda resource pull --profile <name> # 拉取平台资源回写到本地(用于初次同步)
|
|
25
|
-
openxiangda resource explain public-access --json # 查看资源目录、最小 manifest、验证命令
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
小步诊断、修复或 AI 自动发现能力时,可以用一等资源 CLI。写命令默认是 live mutation;需要让仓库继续作为来源时加 `--write-manifest`,复杂 DTO 用 `--json-file`,危险动作用 `--force`,先看请求就加 `--dry-run`。
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
openxiangda doctor --profile <name> --json
|
|
32
|
-
openxiangda design gates --topic public-access --json
|
|
33
|
-
|
|
34
|
-
openxiangda route upsert --json-file src/resources/routes/public_register.json --dry-run
|
|
35
|
-
openxiangda public-access upsert --json-file src/resources/public-access/public_register.json --write-manifest
|
|
36
|
-
openxiangda public-access ticket-create public_register --json-file ticket.json
|
|
37
|
-
openxiangda public-access session-test public_register --path /view/APP_XXX/public/register --json
|
|
38
|
-
openxiangda public-access grant-check public_register --form-code registration_form --json
|
|
39
|
-
|
|
40
|
-
openxiangda auth-config methods --json
|
|
41
|
-
openxiangda auth-config upsert --json-file src/resources/auth/default.json --write-manifest
|
|
42
|
-
|
|
43
|
-
openxiangda function upsert --json-file src/resources/functions/submit_public_registration.json
|
|
44
|
-
openxiangda function invoke submit_public_registration --body-json '{"input":{}}'
|
|
45
|
-
|
|
46
|
-
openxiangda connector upsert --json-file src/resources/connectors/sms.json
|
|
47
|
-
openxiangda connector invoke sms.sendCode --body-json '{"body":{"phone":"13800000000"}}'
|
|
48
|
-
|
|
49
|
-
openxiangda notification template-upsert --json-file src/resources/notifications/register.json
|
|
50
|
-
openxiangda notification type-upsert --json-file src/resources/notifications/register.json
|
|
51
|
-
openxiangda notification preview public_register_notice --body-json '{"payload":{"title":"测试"}}'
|
|
52
|
-
|
|
53
|
-
openxiangda resource plan storage --profile <name>
|
|
54
|
-
openxiangda data-view upsert --json-file src/resources/data-views/public_lookup.json
|
|
55
|
-
openxiangda scope dimension-upsert college --json-file src/resources/permissions/scope-dimensions/college.json --write-manifest
|
|
56
|
-
openxiangda scope grant-source-upsert college_grants --json-file src/resources/permissions/scope-grant-sources/college_grants.json --write-manifest
|
|
57
|
-
openxiangda scope policy-upsert college_data --json-file src/resources/permissions/data-scope-policies/college_data.json --write-manifest
|
|
58
|
-
openxiangda scope sync college_grants --json
|
|
59
|
-
openxiangda scope explain college_data --json
|
|
60
|
-
openxiangda menu update public_register --json-file src/resources/menus/public_register.json --write-manifest
|
|
61
|
-
openxiangda permission audit --json
|
|
62
|
-
openxiangda permission role-update external_visitor --json-file src/resources/roles/external_visitor.json --write-manifest
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
调用和测试类命令会检查 JSON envelope。HTTP 200 但 `code: "PUBLIC_GRANT_DENIED"`、`success: false` 或其他字符串错误码必须当失败,不能只看 HTTP status。
|
|
66
|
-
|
|
67
|
-
## 0. Auth — `src/resources/auth/<code>.json`
|
|
68
|
-
|
|
69
|
-
```json
|
|
70
|
-
{
|
|
71
|
-
"code": "default",
|
|
72
|
-
"name": "Default App Login",
|
|
73
|
-
"status": "active",
|
|
74
|
-
"configJson": {
|
|
75
|
-
"methods": [
|
|
76
|
-
{ "type": "password", "enabled": true, "label": "账号密码" },
|
|
77
|
-
{ "type": "dingtalk", "enabled": true, "label": "钉钉登录", "flow": "auto" },
|
|
78
|
-
{ "type": "sso", "enabled": true, "label": "CAS", "protocol": "cas" },
|
|
79
|
-
{
|
|
80
|
-
"type": "phone_code",
|
|
81
|
-
"enabled": true,
|
|
82
|
-
"label": "手机号验证码",
|
|
83
|
-
"ttlSeconds": 300,
|
|
84
|
-
"sendFrequencySeconds": 60,
|
|
85
|
-
"maxAttempts": 5,
|
|
86
|
-
"provider": { "functionCode": "auth_phone_code" }
|
|
87
|
-
}
|
|
88
|
-
],
|
|
89
|
-
"registration": { "mode": "reject" },
|
|
90
|
-
"binding": { "mode": "auto" },
|
|
91
|
-
"matching": {
|
|
92
|
-
"keys": ["phone", "email", "externalId", "unionId", "jobNumber", "username"]
|
|
93
|
-
},
|
|
94
|
-
"defaultRoleCodes": []
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
Provider function:
|
|
100
|
-
|
|
101
|
-
```ts
|
|
102
|
-
export default async function authPhoneCodeProvider(ctx, input) {
|
|
103
|
-
if (input.event === "phone_code.send") {
|
|
104
|
-
return { ok: true, providerState: { nonce: "vendor-message-id" } };
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
if (input.event === "phone_code.verify") {
|
|
108
|
-
if (input.credential.code !== "123456") {
|
|
109
|
-
return { ok: false, message: "验证码错误" };
|
|
110
|
-
}
|
|
111
|
-
return {
|
|
112
|
-
ok: true,
|
|
113
|
-
identity: {
|
|
114
|
-
phone: input.credential.phone,
|
|
115
|
-
externalId: `phone:${input.credential.phone}`
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return { ok: false, message: "不支持的认证事件" };
|
|
121
|
-
}
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
React 默认页:
|
|
125
|
-
|
|
126
|
-
```tsx
|
|
127
|
-
import { LoginPage } from "openxiangda/runtime/react";
|
|
128
|
-
|
|
129
|
-
export default function AppLogin() {
|
|
130
|
-
return <LoginPage dingtalkFlow="auto" />;
|
|
131
|
-
}
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
自定义登录页:
|
|
135
|
-
|
|
136
|
-
```ts
|
|
137
|
-
import { createAuthClient } from "openxiangda/runtime";
|
|
138
|
-
|
|
139
|
-
const auth = createAuthClient({ appType, servicePrefix: "/service" });
|
|
140
|
-
const methods = await auth.getMethods();
|
|
141
|
-
|
|
142
|
-
async function startDingTalkLogin() {
|
|
143
|
-
const { loginUrl } = await auth.getDingTalkOAuthUrl({
|
|
144
|
-
returnUrl: `/view/${encodeURIComponent(appType)}/admin`,
|
|
145
|
-
});
|
|
146
|
-
window.location.assign(loginUrl);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
const sent = await auth.sendPhoneCode({ phone, purpose: "login" });
|
|
150
|
-
await auth.phoneCodeLogin({ phone, code, challengeId: sent.challengeId });
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
钉钉 `flow: "auto"` 会在确认处于钉钉容器且 JSAPI 可用时走免登,否则走平台托管的浏览器 OAuth。`returnUrl` 只能是当前应用的 `/view/:appType/*` 路径;应用不要自行拼装钉钉授权 URL、保存 OAuth `state` 或实现回调页。
|
|
154
|
-
|
|
155
|
-
设计前必须确认启用方式、注册策略、身份匹配键、provider 边界、默认权限、安全参数、第三方配置归属。
|
|
156
|
-
|
|
157
|
-
## 1. Storage — `src/resources/storage/<code>.json`
|
|
158
|
-
|
|
159
|
-
用于给附件字段声明自定义 OSS 上传目标。manifest 里只能写环境变量引用,不能写真实 AK/SK;发布时 CLI 解析环境变量,后端密文保存。
|
|
160
|
-
|
|
161
|
-
```json
|
|
162
|
-
{
|
|
163
|
-
"code": "evaluate_oss",
|
|
164
|
-
"name": "Evaluate OSS",
|
|
165
|
-
"provider": "oss",
|
|
166
|
-
"status": "active",
|
|
167
|
-
"configJson": {
|
|
168
|
-
"region": "oss-cn-hangzhou",
|
|
169
|
-
"bucket": "evaluate-oss",
|
|
170
|
-
"publicBaseUrl": "https://evaluate-oss.oss-cn-hangzhou.aliyuncs.com",
|
|
171
|
-
"pathPrefix": "openxiangda/{{appType}}/{{yyyy}}/{{MM}}/{{dd}}",
|
|
172
|
-
"maxFileSizeMb": 20,
|
|
173
|
-
"allowedExtensions": ["txt", "pdf", "png"],
|
|
174
|
-
"cors": {
|
|
175
|
-
"managed": true,
|
|
176
|
-
"allowedOrigins": ["https://yida.wisejob.cn"],
|
|
177
|
-
"allowedMethods": ["PUT", "GET", "HEAD"],
|
|
178
|
-
"allowedHeaders": ["content-type", "x-oss-*"],
|
|
179
|
-
"exposeHeaders": ["ETag", "x-oss-request-id"],
|
|
180
|
-
"maxAgeSeconds": 600
|
|
181
|
-
}
|
|
182
|
-
},
|
|
183
|
-
"credentials": {
|
|
184
|
-
"accessKeyId": "${APP_OSS_ACCESS_KEY_ID}",
|
|
185
|
-
"accessKeySecret": "${APP_OSS_ACCESS_KEY_SECRET}"
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
表单字段引用:
|
|
191
|
-
|
|
192
|
-
```tsx
|
|
193
|
-
<AttachmentField
|
|
194
|
-
name="attachments"
|
|
195
|
-
label="附件"
|
|
196
|
-
uploadProvider="oss"
|
|
197
|
-
storageCode="evaluate_oss"
|
|
198
|
-
/>
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
图片字段也可以引用同一个 storage:
|
|
202
|
-
|
|
203
|
-
```tsx
|
|
204
|
-
<ImageField
|
|
205
|
-
name="photos"
|
|
206
|
-
label="照片"
|
|
207
|
-
uploadProvider="oss"
|
|
208
|
-
storageCode="evaluate_oss"
|
|
209
|
-
imageCompression={{ enabled: true }}
|
|
210
|
-
/>
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
默认附件或图片不配置 `uploadProvider`/`storageCode` 时仍走平台上传。OSS 文件保存真实 OSS URL;预览、下载、删除对象都通过 storage 配置对应的运行时接口处理。
|
|
214
|
-
|
|
215
|
-
`imageCompression` 是浏览器端图片压缩配置,只对 jpg/png/webp/bmp 生效,GIF、SVG 和非图片文件会自动跳过。启用后会在原图之外上传 `thumb` / `preview` 变体,字段值会写入 `thumbUrl`、`previewUrl` 和 `variants`。默认输出格式为 `source`,如果显式设置 `format: "webp"`,storage 的 `allowedExtensions` 必须包含 `webp`。
|
|
216
|
-
|
|
217
|
-
`configJson.cors.managed: true` 会在发布 storage 配置时顺便设置 OSS bucket CORS。后端会读取现有规则并合并,不覆盖其他系统规则;该操作需要 OSS 凭据具备 bucket CORS 管理权限。未声明 `cors.managed` 时不会修改 bucket 级配置。
|
|
218
|
-
|
|
219
|
-
## 1. Public Route — `src/resources/routes/<code>.json`
|
|
220
|
-
|
|
221
|
-
新 React SPA 公开页使用 `/view/:appType/public/*`,不要再使用旧 `?publicAccess=guest`。
|
|
222
|
-
|
|
223
|
-
```json
|
|
224
|
-
{
|
|
225
|
-
"code": "public.register",
|
|
226
|
-
"title": "公开报名",
|
|
227
|
-
"kind": "page",
|
|
228
|
-
"pathPattern": "/view/:appType/public/register",
|
|
229
|
-
"publicAccess": "guest",
|
|
230
|
-
"publicPolicyCode": "public_register"
|
|
231
|
-
}
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
React Router 中用 `PublicAccessGate` 创建 scoped public session:
|
|
235
|
-
|
|
236
|
-
```tsx
|
|
237
|
-
import {
|
|
238
|
-
OpenXiangdaPageProvider,
|
|
239
|
-
OpenXiangdaProvider,
|
|
240
|
-
PublicAccessGate,
|
|
241
|
-
} from "openxiangda/runtime/react";
|
|
242
|
-
|
|
243
|
-
const PublicLoading = () => <div role="status">正在进入公开页面</div>;
|
|
244
|
-
const PublicAccessError = ({ error }: { error: { message?: string } }) => (
|
|
245
|
-
<div role="alert">{error.message || "公开链接不可用或已过期"}</div>
|
|
246
|
-
);
|
|
247
|
-
|
|
248
|
-
<OpenXiangdaProvider appType={appType} servicePrefix="/service">
|
|
249
|
-
<OpenXiangdaPageProvider>
|
|
250
|
-
<PublicAccessGate
|
|
251
|
-
errorFallback={error => <PublicAccessError error={error} />}
|
|
252
|
-
fallback={<PublicLoading />}
|
|
253
|
-
policyCode="public_register"
|
|
254
|
-
routeCode="public.register"
|
|
255
|
-
>
|
|
256
|
-
<PublicRegisterPage />
|
|
257
|
-
</PublicAccessGate>
|
|
258
|
-
</OpenXiangdaPageProvider>
|
|
259
|
-
</OpenXiangdaProvider>
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
React SPA 中 `OpenXiangdaProvider` 负责 runtime/bootstrap 和 public token 注入,`OpenXiangdaPageProvider` 负责 `usePageSdk()` / `usePageContext()` 的 Page SDK 上下文。缺少 `OpenXiangdaPageProvider` 会抛出 `usePageSdkStore 必须在 PageProvider 内使用`。公开页面必须给 `PublicAccessGate` 配 `fallback` 和 `errorFallback`,避免慢网、缺 ticket、ticket 过期时出现空白页。
|
|
263
|
-
|
|
264
|
-
公开访问验证必须检查 JSON envelope。HTTP 200 但 `code: "PUBLIC_GRANT_DENIED"` 代表后端已拒绝;只有 `code` 为 `200`、`"200"` 或兼容成功码 `0`,且没有 `success: false` 时才算成功。
|
|
265
|
-
|
|
266
|
-
## 2. Public Access Policy — `src/resources/public-access/<code>.json`
|
|
267
|
-
|
|
268
|
-
公开策略声明外部角色和可访问资源。未显式 grant 的 form/dataView/function/connector 默认拒绝;grant 后仍受对应后端权限组控制。
|
|
269
|
-
|
|
270
|
-
```json
|
|
271
|
-
{
|
|
272
|
-
"code": "public_register",
|
|
273
|
-
"name": "公开报名入口",
|
|
274
|
-
"mode": "guest",
|
|
275
|
-
"routeCode": "public.register",
|
|
276
|
-
"pathPattern": "/view/:appType/public/register",
|
|
277
|
-
"externalRoleCodes": ["external_visitor"],
|
|
278
|
-
"grants": {
|
|
279
|
-
"forms": ["registration_form"],
|
|
280
|
-
"dataViews": ["public_registration_lookup"],
|
|
281
|
-
"functions": ["submit_public_registration"],
|
|
282
|
-
"connectors": ["sms.sendCode"]
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
Ticket 模式:
|
|
288
|
-
|
|
289
|
-
```json
|
|
290
|
-
{
|
|
291
|
-
"code": "public_score_lookup",
|
|
292
|
-
"name": "公开成绩查询",
|
|
293
|
-
"mode": "ticket",
|
|
294
|
-
"routeCode": "public.scoreLookup",
|
|
295
|
-
"pathPattern": "/view/:appType/public/score",
|
|
296
|
-
"externalRoleCodes": ["external_ticket_holder"],
|
|
297
|
-
"ticketConfig": { "ttlSeconds": 1800, "singleUse": true },
|
|
298
|
-
"grants": {
|
|
299
|
-
"dataViews": ["public_score_lookup"]
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
Ticket 默认单次使用,首次换取 public session 后立即失效;只有明确配置 `ticketConfig.singleUse: false` 的业务场景才允许复用。
|
|
305
|
-
|
|
306
|
-
`grants.forms` 可以写本地 `formCode`,CLI 发布时会解析为真实 `formUuid`。
|
|
307
|
-
|
|
308
|
-
## Business Scope Permission — `src/resources/permissions/scope-*`
|
|
309
|
-
|
|
310
|
-
Use this when a form-maintained business authorization relationship controls
|
|
311
|
-
row visibility. The pattern replaces "one role / one permission group per
|
|
312
|
-
college, class, project, customer, region, store, etc."
|
|
313
|
-
|
|
314
|
-
Dimension:
|
|
315
|
-
|
|
316
|
-
```json
|
|
317
|
-
{
|
|
318
|
-
"code": "college",
|
|
319
|
-
"name": "学院",
|
|
320
|
-
"sourceFormCode": "college",
|
|
321
|
-
"sourceValueField": "collegeCode",
|
|
322
|
-
"sourceLabelField": "collegeName",
|
|
323
|
-
"hierarchyMode": "flat"
|
|
324
|
-
}
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
Grant source:
|
|
328
|
-
|
|
329
|
-
```json
|
|
330
|
-
{
|
|
331
|
-
"code": "college_grants",
|
|
332
|
-
"name": "学院授权",
|
|
333
|
-
"sourceFormCode": "college_grant",
|
|
334
|
-
"subjectMappings": [
|
|
335
|
-
{ "subjectType": "user", "field": "userId" },
|
|
336
|
-
{ "subjectType": "role", "field": "roleCode" }
|
|
337
|
-
],
|
|
338
|
-
"dimensionMappings": [
|
|
339
|
-
{ "dimensionCode": "college", "field": "collegeCode" }
|
|
340
|
-
],
|
|
341
|
-
"filterJson": {
|
|
342
|
-
"logic": "AND",
|
|
343
|
-
"rules": [
|
|
344
|
-
{ "field": "status", "op": "eq", "value": "enabled" }
|
|
345
|
-
]
|
|
346
|
-
},
|
|
347
|
-
"syncMode": "on_write",
|
|
348
|
-
"sync": true
|
|
349
|
-
}
|
|
350
|
-
```
|
|
351
|
-
|
|
352
|
-
Policy:
|
|
353
|
-
|
|
354
|
-
```json
|
|
355
|
-
{
|
|
356
|
-
"code": "college_data",
|
|
357
|
-
"name": "学院数据",
|
|
358
|
-
"matchMode": "AND",
|
|
359
|
-
"rules": [
|
|
360
|
-
{ "dimensionCode": "college", "field": "collegeCode", "operation": "view" }
|
|
361
|
-
]
|
|
362
|
-
}
|
|
363
|
-
```
|
|
364
|
-
|
|
365
|
-
Form permission group reference:
|
|
366
|
-
|
|
367
|
-
```json
|
|
368
|
-
{
|
|
369
|
-
"code": "college_view",
|
|
370
|
-
"formCode": "student",
|
|
371
|
-
"name": "学院查看学生",
|
|
372
|
-
"type": "view",
|
|
373
|
-
"roles": ["college_admin"],
|
|
374
|
-
"operations": ["view"],
|
|
375
|
-
"dataPermission": {
|
|
376
|
-
"type": "scope_policy",
|
|
377
|
-
"policyCode": "college_data"
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
```
|
|
381
|
-
|
|
382
|
-
Data View permission groups use the same `dataPermission` object inside
|
|
383
|
-
`permissionGroups`. Empty grant sets deny; multiple policy rules are AND by
|
|
384
|
-
default; large grant sets use DB `EXISTS` instead of huge `IN` SQL. Prefer
|
|
385
|
-
hidden scalar target fields such as `collegeCode`; if the target is a JSONB
|
|
386
|
-
option/person/department field, set `valuePath: "value"` or `componentType`.
|
|
387
|
-
Authorization source form changes are synced by the platform after
|
|
388
|
-
create/update/delete/import when the grant source uses the default
|
|
389
|
-
`syncMode: "on_write"`. Use `syncMode: "manual"` only for externally maintained
|
|
390
|
-
sources or special bulk jobs that explicitly call `openxiangda scope sync`.
|
|
391
|
-
Manifest `sync: true` still performs an immediate full sync during resource
|
|
392
|
-
publish.
|
|
393
|
-
|
|
394
|
-
## 3. Connector — `src/resources/connectors/<code>.json`
|
|
395
|
-
|
|
396
|
-
```json
|
|
397
|
-
{
|
|
398
|
-
"code": "crm",
|
|
399
|
-
"name": "CRM Service",
|
|
400
|
-
"url": "https://crm.internal.example.com/api",
|
|
401
|
-
"authType": "apiKey",
|
|
402
|
-
"authConfig": {
|
|
403
|
-
"apiKey": { "key": "X-API-Key", "value": "internal-secret", "in": "header" }
|
|
404
|
-
},
|
|
405
|
-
"userContext": {
|
|
406
|
-
"enabled": true,
|
|
407
|
-
"inject": [
|
|
408
|
-
{ "target": "header", "key": "X-User-Id", "value": "userId" },
|
|
409
|
-
{ "target": "body", "key": "operator", "value": "user" }
|
|
410
|
-
]
|
|
411
|
-
},
|
|
412
|
-
"apis": [
|
|
413
|
-
{
|
|
414
|
-
"code": "getCustomer",
|
|
415
|
-
"name": "Get Customer",
|
|
416
|
-
"method": "POST",
|
|
417
|
-
"path": "/customers/search",
|
|
418
|
-
"requestBodyType": "json",
|
|
419
|
-
"responseType": "json"
|
|
420
|
-
}
|
|
421
|
-
]
|
|
422
|
-
}
|
|
423
|
-
```
|
|
424
|
-
|
|
425
|
-
页面调用:
|
|
426
|
-
|
|
427
|
-
```ts
|
|
428
|
-
const data = await sdk.connector.call("crm.getCustomer", { body: { keyword } });
|
|
429
|
-
```
|
|
430
|
-
|
|
431
|
-
不要把 `authConfig` 里的真实 secret 写进 manifest;用 placeholder,由平台管理员在后台覆盖。完整字段见 [`connector-resources.md`](connector-resources.md)。
|
|
432
|
-
|
|
433
|
-
## 4. Data View — `src/resources/data-views/<code>.json`
|
|
434
|
-
|
|
435
|
-
选择规则:
|
|
436
|
-
|
|
437
|
-
- 多表只读联表列表 / lookup / 报表明细:用行级 data view,页面调用 `sdk.dataView.query`。
|
|
438
|
-
- 固定口径统计 / 看板指标 / 图表数据源:用 `viewType: "aggregate"`,页面调用 `sdk.dataView.stats`。
|
|
439
|
-
- ECharts 或自定义 dashboard 只负责展示;统计口径稳定时,数据源优先沉淀成 aggregate data view。
|
|
440
|
-
- 默认 `storageMode: "materialized"`,适合读多写少和可接受刷新延迟的列表/报表;发布前为常用筛选、排序、维度和时间桶声明 `indexes`。
|
|
441
|
-
- `storageMode: "live"` 每次查询实时执行,适合强实时但数据量可控的固定复杂查询;live 模式忽略 `indexes` 且不能 refresh。
|
|
442
|
-
- 不用于单表 CRUD、简单 `linkedForm` 下拉、写回、无边界重查询或临时 BI 查询。
|
|
443
|
-
|
|
444
|
-
```json
|
|
445
|
-
{
|
|
446
|
-
"code": "ticket_with_customer",
|
|
447
|
-
"name": "Ticket With Customer",
|
|
448
|
-
"storageMode": "materialized",
|
|
449
|
-
"base": { "formCode": "service_ticket", "alias": "ticket" },
|
|
450
|
-
"joins": [
|
|
451
|
-
{
|
|
452
|
-
"type": "left",
|
|
453
|
-
"formCode": "customer",
|
|
454
|
-
"alias": "customer",
|
|
455
|
-
"on": [
|
|
456
|
-
{ "left": "ticket.customer.value", "op": "=", "right": "customer.form_instance_id" }
|
|
457
|
-
]
|
|
458
|
-
}
|
|
459
|
-
],
|
|
460
|
-
"select": [
|
|
461
|
-
{ "field": "ticket.form_instance_id", "as": "ticketId" },
|
|
462
|
-
{ "field": "ticket.title", "as": "ticketTitle" },
|
|
463
|
-
{ "field": "ticket.status.label", "as": "statusLabel" },
|
|
464
|
-
{ "field": "ticket.status.value", "as": "statusValue" },
|
|
465
|
-
{ "field": "customer.name", "as": "customerName" }
|
|
466
|
-
],
|
|
467
|
-
"indexes": [{ "fields": ["ticketId"], "unique": true }],
|
|
468
|
-
"refresh": { "mode": "scheduled", "cron": "0 */10 * * * *" },
|
|
469
|
-
"permissionGroups": [
|
|
470
|
-
{ "code": "ticket_query", "name": "Ticket Query", "roles": ["manager"], "operations": ["query"] }
|
|
471
|
-
]
|
|
472
|
-
}
|
|
473
|
-
```
|
|
474
|
-
|
|
475
|
-
页面调用:
|
|
476
|
-
|
|
477
|
-
```ts
|
|
478
|
-
const list = await sdk.dataView.query("ticket_with_customer", {
|
|
479
|
-
filters: [{ field: "statusValue", op: "in", values: ["open", "processing"] }],
|
|
480
|
-
order: [{ field: "ticketId", direction: "desc" }],
|
|
481
|
-
page: { current: 1, size: 20 },
|
|
482
|
-
});
|
|
483
|
-
```
|
|
484
|
-
|
|
485
|
-
统计聚合视图:
|
|
486
|
-
|
|
487
|
-
```json
|
|
488
|
-
{
|
|
489
|
-
"code": "ticket_stats_by_customer",
|
|
490
|
-
"name": "Ticket Stats By Customer",
|
|
491
|
-
"viewType": "aggregate",
|
|
492
|
-
"base": { "formCode": "service_ticket", "alias": "ticket" },
|
|
493
|
-
"dimensions": [
|
|
494
|
-
{ "field": "ticket.customer.value", "as": "customerId" },
|
|
495
|
-
{ "field": "ticket.created_at", "as": "createdMonth", "bucket": "month" }
|
|
496
|
-
],
|
|
497
|
-
"measures": [
|
|
498
|
-
{ "type": "count", "as": "ticketCount" },
|
|
499
|
-
{ "type": "sum", "field": "ticket.amount", "as": "totalAmount" }
|
|
500
|
-
],
|
|
501
|
-
"having": { "field": "ticketCount", "op": ">", "value": 0 },
|
|
502
|
-
"indexes": [{ "fields": ["customerId", "createdMonth"] }]
|
|
503
|
-
}
|
|
504
|
-
```
|
|
505
|
-
|
|
506
|
-
```ts
|
|
507
|
-
const stats = await sdk.dataView.stats("ticket_stats_by_customer", {
|
|
508
|
-
fields: ["customerId", "createdMonth", "ticketCount", "totalAmount"],
|
|
509
|
-
having: [{ field: "ticketCount", op: ">", value: 0 }],
|
|
510
|
-
});
|
|
511
|
-
```
|
|
512
|
-
|
|
513
|
-
性能要点:索引只能引用输出 alias;行级视图索引常用 filter/order 字段;聚合视图索引 dimensions/date buckets;`countDistinct` 和高基数维度刷新成本较高;低于 5 分钟的 scheduled refresh 需要用户明确确认时间敏感度。live 视图不刷新、不建索引,必须控制字段、过滤和分页。完整规则见 [`data-views.md`](data-views.md)。
|
|
514
|
-
|
|
515
|
-
## 3. Notification — `src/resources/notifications/<code>.json`
|
|
516
|
-
|
|
517
|
-
```json
|
|
518
|
-
{
|
|
519
|
-
"templates": [
|
|
520
|
-
{
|
|
521
|
-
"code": "reservation_reminder",
|
|
522
|
-
"name": "预约提醒",
|
|
523
|
-
"content": "{{title}}",
|
|
524
|
-
"variables": ["title", "instrumentName", "startTime"],
|
|
525
|
-
"channelsConfig": {
|
|
526
|
-
"inapp": { "enabled": true, "content": "{{instrumentName}} 将于 {{startTime}} 开始" },
|
|
527
|
-
"dingding": {
|
|
528
|
-
"enabled": true,
|
|
529
|
-
"content": "{{title}}",
|
|
530
|
-
"config": {
|
|
531
|
-
"deliveryMode": "card_preferred",
|
|
532
|
-
"fallbackToWorkNotice": true,
|
|
533
|
-
"card": {
|
|
534
|
-
"mode": "standard",
|
|
535
|
-
"title": "{{title}}",
|
|
536
|
-
"summary": "{{instrumentName}} 将于 {{startTime}} 开始",
|
|
537
|
-
"jumpUrl": "{{detailUrl}}"
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
],
|
|
544
|
-
"typeConfigs": [
|
|
545
|
-
{
|
|
546
|
-
"notificationType": "reservation_reminder",
|
|
547
|
-
"templateCode": "reservation_reminder",
|
|
548
|
-
"enabled": true,
|
|
549
|
-
"priority": 0
|
|
550
|
-
}
|
|
551
|
-
]
|
|
552
|
-
}
|
|
553
|
-
```
|
|
554
|
-
|
|
555
|
-
页面调用:
|
|
556
|
-
|
|
557
|
-
```ts
|
|
558
|
-
await sdk.notification.sendByType({
|
|
559
|
-
notificationType: "reservation_reminder",
|
|
560
|
-
recipientId: userId,
|
|
561
|
-
payload: { title: "预约提醒", instrumentName, startTime },
|
|
562
|
-
});
|
|
563
|
-
```
|
|
564
|
-
|
|
565
|
-
JS_CODE 调用:`ctx.notification.sendByType({ ... })`。允许的 channels:`inapp` / `email` / `dingding` / `wechat` / `thirdparty_todo`。完整规则见 [`notifications.md`](notifications.md)。
|
|
566
|
-
|
|
567
|
-
钉钉卡片预览/发送:`sdk.notification.previewDingTalk({ notificationType, payload })`、`sdk.notification.sendDingTalk({ notificationType, recipientId, payload })`;CLI 为 `openxiangda notification dingding-preview` 和 `openxiangda notification dingding-send --force`。
|
|
568
|
-
|
|
569
|
-
## 4. App Function — `src/resources/functions/<functionCode>.json` + `src/functions/<functionCode>/index.ts`
|
|
570
|
-
|
|
571
|
-
```json
|
|
572
|
-
{
|
|
573
|
-
"code": "reservation_reminder_summary",
|
|
574
|
-
"name": "Reservation Reminder Summary",
|
|
575
|
-
"secretRefs": [
|
|
576
|
-
{ "name": "notification_provider_token", "required": false }
|
|
577
|
-
],
|
|
578
|
-
"resources": {
|
|
579
|
-
"forms": ["reservation_order"],
|
|
580
|
-
"dataViews": ["reservation_order_overview"],
|
|
581
|
-
"connectors": ["crm"]
|
|
582
|
-
},
|
|
583
|
-
"definitionJson": {
|
|
584
|
-
"version": "function_v2",
|
|
585
|
-
"runtimeMode": "trusted_node",
|
|
586
|
-
"runtimeContractVersion": "trusted_node_v2",
|
|
587
|
-
"timeout": 30000,
|
|
588
|
-
"runtimeInvoke": {
|
|
589
|
-
"audience": {
|
|
590
|
-
"type": "page_permission_group",
|
|
591
|
-
"resourceCodes": ["member_portal_pages"]
|
|
592
|
-
}
|
|
593
|
-
},
|
|
594
|
-
"sourceFile": {
|
|
595
|
-
"localPath": "src/functions/reservation_reminder_summary/index.ts"
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
```
|
|
600
|
-
|
|
601
|
-
```ts
|
|
602
|
-
// src/functions/reservation_reminder_summary/index.ts
|
|
603
|
-
import type { AppFunctionContextV2 } from "openxiangda/runtime";
|
|
604
|
-
|
|
605
|
-
export default async function reservationReminderSummary(
|
|
606
|
-
ctx: AppFunctionContextV2,
|
|
607
|
-
input: { scope?: string },
|
|
608
|
-
) {
|
|
609
|
-
// Only resolve a name declared in top-level secretRefs. Never log or return it.
|
|
610
|
-
const providerToken = await ctx.secrets.get("notification_provider_token");
|
|
611
|
-
const providerResponse = await ctx.utils.http.post(
|
|
612
|
-
"https://api.dingtalk.com/v1.0/example/operation",
|
|
613
|
-
{ requestId: input.scope || "default" },
|
|
614
|
-
{ headers: { authorization: `Bearer ${providerToken}` } },
|
|
615
|
-
);
|
|
616
|
-
const roleCodes = ctx.operator?.roleCodes || ctx.permissions?.roleCodes || [];
|
|
617
|
-
const platformRoleCodes =
|
|
618
|
-
ctx.operator?.platformRoleCodes || ctx.permissions?.platformRoleCodes || [];
|
|
619
|
-
const canManage =
|
|
620
|
-
ctx.operator?.hasFullAccess === true ||
|
|
621
|
-
ctx.permissions?.hasFullAccess === true ||
|
|
622
|
-
roleCodes.includes("union_admin") ||
|
|
623
|
-
platformRoleCodes.includes("SCHOOL_TEACHER");
|
|
624
|
-
if (!canManage) throw new Error("当前账号无权执行该操作。");
|
|
625
|
-
|
|
626
|
-
const orders = await ctx.form.queryMany({
|
|
627
|
-
formCode: "reservation_order",
|
|
628
|
-
filters: [{ field: "status", operator: "=", value: "pending" }],
|
|
629
|
-
pageSize: 50,
|
|
630
|
-
});
|
|
631
|
-
const firstOrder = orders.data?.[0] || orders[0];
|
|
632
|
-
const detail = firstOrder?.formInstId
|
|
633
|
-
? await ctx.form.getById({
|
|
634
|
-
formCode: "reservation_order",
|
|
635
|
-
formInstId: firstOrder.formInstId,
|
|
636
|
-
})
|
|
637
|
-
: null;
|
|
638
|
-
|
|
639
|
-
const overview = await ctx.dataView.query("reservation_order_overview", {
|
|
640
|
-
pageSize: 20,
|
|
641
|
-
});
|
|
642
|
-
|
|
643
|
-
return {
|
|
644
|
-
providerStatus: providerResponse.status,
|
|
645
|
-
pendingCount: orders.totalCount || orders.data?.length || 0,
|
|
646
|
-
detail,
|
|
647
|
-
overview: overview.data || [],
|
|
648
|
-
input,
|
|
649
|
-
};
|
|
650
|
-
}
|
|
651
|
-
```
|
|
652
|
-
|
|
653
|
-
`ctx.utils.http` is the typed, server-controlled public HTTPS bridge for
|
|
654
|
-
`trusted_node_v2`; it never forwards the platform Runtime bearer token and
|
|
655
|
-
rejects redirects plus private/reserved network targets. For whole-app atomic
|
|
656
|
-
activation, stage the exact backend scope with
|
|
657
|
-
`openxiangda resource publish function --only <code> --stage-only`, combine its
|
|
658
|
-
verified `stagedResource` with the other changed staged children, and pass that
|
|
659
|
-
overlay to `openxiangda release app-finalize --staged-resources-json ...`.
|
|
660
|
-
Already-active Backend Releases return `activeResource`, not a staged descriptor.
|
|
661
|
-
|
|
662
|
-
调用方式:
|
|
663
|
-
|
|
664
|
-
```ts
|
|
665
|
-
const result = await sdk.function.invoke("reservation_reminder_summary", {
|
|
666
|
-
input: { scope: "today" },
|
|
667
|
-
});
|
|
668
|
-
```
|
|
669
|
-
|
|
670
|
-
自动化 / 流程图节点调用:
|
|
671
|
-
|
|
672
|
-
```json
|
|
673
|
-
{
|
|
674
|
-
"id": "call_summary",
|
|
675
|
-
"type": "function_call",
|
|
676
|
-
"data": {
|
|
677
|
-
"functionCode": "reservation_reminder_summary",
|
|
678
|
-
"input": { "scope": "today" },
|
|
679
|
-
"saveResponseTo": "summary"
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
```
|
|
683
|
-
|
|
684
|
-
适用边界:可复用后端业务逻辑、跨页面/自动化/流程共享的查询编排、连接器调用、通知编排、受控平台 API 调用。App Function 支持 `ctx.form.queryOne/queryMany/getById/createOne/updateOne/updateById`、`ctx.dataView`、`ctx.connector`、`ctx.notification`、`ctx.platform.roles`、`ctx.platform.api` 等受控 helper,当前 MVP 不暴露原始 SQL/Redis。应用角色查询和成员维护优先使用 `ctx.platform.roles.list/findByCode/addUsers/removeUser`;底层 `ctx.platform.api` 返回 HTTP 包装与平台 envelope,需要自行解包。已发布可信代码可以访问当前租户、当前应用内的资源;function manifest 的 `resources` 是可选映射、审计和影响分析信息,不再是逐函数权限白名单。页面用户仍不能直接提交内部表单,跨应用和跨租户访问仍被拒绝。运行时接口默认需要应用自动化管理权限;普通用户页面要调用时,用 `definitionJson.runtimeInvoke.audience` 声明 `authenticated`、`page_permission_group`、`app_roles`、`platform_roles` 或 `scope_policy`,使用 `roleCodes` 匹配应用角色、使用 `platformRoleCodes` 匹配同步身份 `SCHOOL_GUARDIAN`、`SCHOOL_STUDENT`、`SCHOOL_TEACHER`,不要把 `"*"`、`"all-app-roles"` 写进角色编码。若表单只能由函数/流程写入,在 `src/resources/settings/forms/<formCode>.json` 设置 `runtimeWrite.mode="function_only"` 关闭原始写入接口。
|
|
685
|
-
|
|
686
|
-
## 5. Workflow — `src/resources/workflows/<code>/workflow.json`(manifest)+ `src/workflows/<code>/workflow.ts`(代码优先)
|
|
687
|
-
|
|
688
|
-
```jsonc
|
|
689
|
-
// src/resources/workflows/customer_approval/workflow.json
|
|
690
|
-
{
|
|
691
|
-
"code": "customer_approval",
|
|
692
|
-
"formCode": "customer",
|
|
693
|
-
"kind": "workflow_v3",
|
|
694
|
-
"definitionFile": "definition.v3.json",
|
|
695
|
-
"previewFile": "preview.json"
|
|
696
|
-
}
|
|
697
|
-
```
|
|
698
|
-
|
|
699
|
-
代码优先(推荐):
|
|
700
|
-
|
|
701
|
-
```ts
|
|
702
|
-
// src/workflows/customer_approval/workflow.ts
|
|
703
|
-
import { defineWorkflow } from "openxiangda/workflow";
|
|
704
|
-
|
|
705
|
-
export default defineWorkflow({
|
|
706
|
-
name: "客户审批",
|
|
707
|
-
trigger: { type: "form_submit", formCode: "customer" },
|
|
708
|
-
nodes: [
|
|
709
|
-
/* approval / copy / branch / js_code 节点 */
|
|
710
|
-
],
|
|
711
|
-
});
|
|
712
|
-
```
|
|
713
|
-
|
|
714
|
-
CLI 编译为 `definition.v3.json` + `preview.json`,平台运行时仍走标准工作流引擎。完整规则见 [`workflow-v3.md`](workflow-v3.md)。
|
|
715
|
-
|
|
716
|
-
## 6. Automation — `src/resources/automations/<code>/{definition.code.json,preview.json}` + `src/automations/<code>/index.ts`
|
|
717
|
-
|
|
718
|
-
```jsonc
|
|
719
|
-
// src/resources/automations/notify_on_submit/definition.code.json
|
|
720
|
-
{
|
|
721
|
-
"code": "notify_on_submit",
|
|
722
|
-
"name": "提交后通知",
|
|
723
|
-
"kind": "automation_code_ts",
|
|
724
|
-
"trigger": {
|
|
725
|
-
"version": 2,
|
|
726
|
-
"mode": "event",
|
|
727
|
-
"event": { "source": "form_data", "action": "submitted" },
|
|
728
|
-
"filters": { "formCode": "customer" }
|
|
729
|
-
},
|
|
730
|
-
"sourceFile": { "localPath": "src/automations/notify_on_submit/index.ts" },
|
|
731
|
-
"previewFile": "preview.json",
|
|
732
|
-
"timeout": 30000
|
|
733
|
-
}
|
|
734
|
-
```
|
|
735
|
-
|
|
736
|
-
```ts
|
|
737
|
-
// src/automations/notify_on_submit/index.ts
|
|
738
|
-
export default async function (ctx) {
|
|
739
|
-
ctx.logger.info("automation start", { formCode: ctx.formData.current.formCode });
|
|
740
|
-
await ctx.notification.sendByType({
|
|
741
|
-
notificationType: "submission_notice",
|
|
742
|
-
recipientId: ctx.operator.userId,
|
|
743
|
-
payload: { /* ... */ },
|
|
744
|
-
});
|
|
745
|
-
}
|
|
746
|
-
```
|
|
747
|
-
|
|
748
|
-
`trigger_v2` 事件源:`form_data` / `form_field` / `workflow_task` / `workflow_process` / `mode: "scheduled"`(fixed_time / form_date_field)。完整规则见 [`automation-v3.md`](automation-v3.md)。
|
|
749
|
-
|
|
750
|
-
## 7. JS_CODE V2 — `src/js-code-nodes/<scriptCode>/index.ts`
|
|
751
|
-
|
|
752
|
-
JS_CODE V2 适合自动化/流程图里的节点级脚本。跨页面、跨自动化、需要一个稳定后端入口的可复用逻辑优先写 App Function,再用 `function_call` 节点或 `sdk.function.invoke` 调用。
|
|
753
|
-
|
|
754
|
-
```ts
|
|
755
|
-
export default async function (ctx) {
|
|
756
|
-
const { formData, operator, form, dataView, connector, notification, platform, utils, console } = ctx;
|
|
757
|
-
const result = await form.queryMany({
|
|
758
|
-
formCode: "customer",
|
|
759
|
-
filters: [/* 查询条件 */],
|
|
760
|
-
});
|
|
761
|
-
return { count: result.totalCount || result.data?.length || 0 };
|
|
762
|
-
}
|
|
763
|
-
```
|
|
764
|
-
|
|
765
|
-
工作流 / 自动化 v3 JSON 节点引用:
|
|
766
|
-
|
|
767
|
-
```json
|
|
768
|
-
{
|
|
769
|
-
"id": "sync_customer",
|
|
770
|
-
"type": "js_code",
|
|
771
|
-
"data": {
|
|
772
|
-
"label": "同步客户",
|
|
773
|
-
"runtimeMode": "trusted_node",
|
|
774
|
-
"sourceType": "file_snapshot",
|
|
775
|
-
"scriptCode": "sync_customer",
|
|
776
|
-
"sourceFile": { "localPath": "src/js-code-nodes/sync_customer/index.ts" },
|
|
777
|
-
"timeout": 30000
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
```
|
|
781
|
-
|
|
782
|
-
构建:`pnpm build-js-code --script sync_customer`(只校验该入口及其传递/shared/ambient 依赖,再打包到 `dist/js-code-nodes/<code>/index.cjs`;仅无 selector 时全量校验)。CLI validate/create/publish 时会上传快照、用 `{ bucketName, objectName, sha256 }` 替换 `sourceFile.localPath`。
|
|
783
|
-
|
|
784
|
-
`ctx.methods.*` 仍可用于兼容旧脚本;新脚本优先使用 `ctx.resources`、`ctx.form.queryOne/queryMany/getById/createOne/updateOne/updateById`、`ctx.dataView`、`ctx.connector`、`ctx.notification`、`ctx.platform.roles` 和 `ctx.platform.api`。
|
|
785
|
-
|
|
786
|
-
## 8. Role — `src/resources/roles/<code>.json`
|
|
787
|
-
|
|
788
|
-
Before creating roles or permission groups for account/role/data-scope work,
|
|
789
|
-
run `openxiangda design gates --topic permissions --json` and choose a
|
|
790
|
-
permission mode: `managed-platform-account`,
|
|
791
|
-
`existing-platform-user-assignment`, `static-role-permission`, or
|
|
792
|
-
`query-param-context`. Query parameters and `PermissionBoundary` are never
|
|
793
|
-
sensitive authorization by themselves.
|
|
794
|
-
|
|
795
|
-
```json
|
|
796
|
-
{
|
|
797
|
-
"code": "sales",
|
|
798
|
-
"name": "销售",
|
|
799
|
-
"description": "销售人员"
|
|
800
|
-
}
|
|
801
|
-
```
|
|
802
|
-
|
|
803
|
-
Delegated admin roles that manage roles, role members, permission groups, or
|
|
804
|
-
organization accounts must also declare API permissions:
|
|
805
|
-
|
|
806
|
-
```json
|
|
807
|
-
{
|
|
808
|
-
"code": "campus_admin",
|
|
809
|
-
"name": "校区管理员",
|
|
810
|
-
"description": "维护本校区账号、角色和权限",
|
|
811
|
-
"apiPermissionMode": "merge",
|
|
812
|
-
"apiPermissionCodes": [
|
|
813
|
-
"app:role:manage",
|
|
814
|
-
"app:page-permission-group:manage",
|
|
815
|
-
"app:form-permission-group:manage",
|
|
816
|
-
"app:organization:manage"
|
|
817
|
-
]
|
|
818
|
-
}
|
|
819
|
-
```
|
|
820
|
-
|
|
821
|
-
`apiPermissionMode` is `merge` by default. Use `replace` only when the manifest
|
|
822
|
-
should become the full API permission list for that role. Platform role setup
|
|
823
|
-
requires platform-admin authority; app roles can only receive app-scoped API
|
|
824
|
-
permission codes.
|
|
825
|
-
|
|
826
|
-
## 9. Page Permission Group — `src/resources/permissions/page-groups/<code>.json`
|
|
827
|
-
|
|
828
|
-
```json
|
|
829
|
-
{
|
|
830
|
-
"code": "sales_pages",
|
|
831
|
-
"name": "销售页面",
|
|
832
|
-
"roles": ["sales"],
|
|
833
|
-
"formCodes": ["customer", "orders"],
|
|
834
|
-
"pageCodes": ["dashboard"]
|
|
835
|
-
}
|
|
836
|
-
```
|
|
837
|
-
|
|
838
|
-
`formCodes` / `pageCodes` / `menuCodes` 留空表示对匹配角色全部可见。
|
|
839
|
-
|
|
840
|
-
## 10. Form Permission Group — `src/resources/permissions/form-groups/<formCode>/<groupCode>.json`
|
|
841
|
-
|
|
842
|
-
每个表单权限组必须有稳定、唯一的 `code`。同一张表单通常会有多个查看/提交/管理员权限组,不能把 `formCode` 当成权限组 code,否则本地 state 和平台 `resourceCode` 会把不同组混在一起。
|
|
843
|
-
|
|
844
|
-
```json
|
|
845
|
-
{
|
|
846
|
-
"code": "sales_view",
|
|
847
|
-
"name": "销售查看",
|
|
848
|
-
"type": "view",
|
|
849
|
-
"roles": ["sales"],
|
|
850
|
-
"operations": ["view"],
|
|
851
|
-
"dataScope": {
|
|
852
|
-
"type": "expression",
|
|
853
|
-
"match": "all",
|
|
854
|
-
"conditions": [
|
|
855
|
-
{ "field": "ownerScopeKey", "op": "=", "valueRef": "currentUser.id" }
|
|
856
|
-
]
|
|
857
|
-
},
|
|
858
|
-
"fieldPermissions": {
|
|
859
|
-
"internalNote": "hidden",
|
|
860
|
-
"amount": "readonly"
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
```
|
|
864
|
-
|
|
865
|
-
## 11. Form Settings — `src/resources/settings/forms/<formCode>.json`
|
|
866
|
-
|
|
867
|
-
```json
|
|
868
|
-
{
|
|
869
|
-
"code": "customer",
|
|
870
|
-
"settings": {
|
|
871
|
-
"submitButtonText": "提交",
|
|
872
|
-
"successMessage": "提交成功",
|
|
873
|
-
"runtimeWrite": {
|
|
874
|
-
"mode": "permission_group"
|
|
875
|
-
}
|
|
876
|
-
},
|
|
877
|
-
"indexes": [
|
|
878
|
-
{ "fields": ["customerCode"], "unique": true },
|
|
879
|
-
{ "fields": ["status", "ownerDept"] }
|
|
880
|
-
],
|
|
881
|
-
"dataManagement": { "enabled": true, "default": "list" }
|
|
882
|
-
}
|
|
883
|
-
```
|
|
884
|
-
|
|
885
|
-
`runtimeWrite.mode` 可选 `permission_group`、`function_only`、`public_form`。内部业务表单需要强制走 App Function / Workflow 时使用 `function_only`;这会关闭页面原始写入接口,但不影响 `ctx.form.createOne/updateOne/updateById` 等受信后端写入。
|
|
886
|
-
|
|
887
|
-
`publicAccess` 表单 setting 只用于旧 `sy-lowcode-view` 兼容。新 React SPA 公开页面必须使用 `src/resources/routes/` + `src/resources/public-access/` + `OpenXiangdaProvider` + `OpenXiangdaPageProvider` + `PublicAccessGate`。
|
|
888
|
-
|
|
889
|
-
## 12. Menu — `src/resources/menus/<code>.json`
|
|
890
|
-
|
|
891
|
-
菜单可以写成单个资源文件,也可以在 `menus.json` 中用 `children` 声明树形结构;`resource validate|plan|publish` 会把 children 展开成独立菜单资源,并自动给子菜单补 `parentCode`。
|
|
892
|
-
|
|
893
|
-
```json
|
|
894
|
-
{
|
|
895
|
-
"code": "main",
|
|
896
|
-
"name": "主菜单",
|
|
897
|
-
"type": "nav",
|
|
898
|
-
"children": [
|
|
899
|
-
{ "code": "customer-entry", "name": "客户信息", "type": "receipt", "formCode": "customer" },
|
|
900
|
-
{ "code": "orders-entry", "name": "订单", "type": "receipt", "formCode": "orders" },
|
|
901
|
-
{ "code": "dashboard-entry","name": "驾驶舱", "type": "page", "pageCode": "dashboard" }
|
|
902
|
-
]
|
|
903
|
-
}
|
|
904
|
-
```
|
|
905
|
-
|
|
906
|
-
## 选型决策树
|
|
907
|
-
|
|
908
|
-
```text
|
|
909
|
-
需要展示数据?
|
|
910
|
-
├─ 单表 CRUD → 表单页 + DataManagementList(不要 data view)
|
|
911
|
-
├─ 多表只读联表 → src/resources/data-views/(materialized 或 live)
|
|
912
|
-
├─ 表单字段下拉 → SelectField + optionSource.type: "linkedForm"(不要 data view)
|
|
913
|
-
└─ 大屏 / 报表 → 原生报表 → ECharts page
|
|
914
|
-
|
|
915
|
-
需要后端逻辑?
|
|
916
|
-
├─ 真有审批 → workflow(src/workflows/<code>/workflow.ts)
|
|
917
|
-
├─ 状态流转 → 表单 status 字段 + 状态机 + automation
|
|
918
|
-
├─ 可复用服务逻辑 → App Function(src/functions/<code>/index.ts + function_call / sdk.function.invoke)
|
|
919
|
-
├─ 提交/字段触发 → automation(trigger_v2 + src/automations/<code>/index.ts)
|
|
920
|
-
├─ 定时任务 → automation(mode: "scheduled")
|
|
921
|
-
└─ 流程/自动化节点内脚本 → JS_CODE V2 trusted_node(src/js-code-nodes/<code>/index.ts)
|
|
922
|
-
|
|
923
|
-
需要外部数据?
|
|
924
|
-
├─ 第三方 HTTP → src/resources/connectors/ + sdk.connector.call
|
|
925
|
-
└─ 钉钉 / 飞书等 → 同上,平台后端配置 OAuth/AK,前端只引用 connector code
|
|
926
|
-
```
|
|
927
|
-
|
|
928
|
-
## 常见错误
|
|
929
|
-
|
|
930
|
-
- ❌ 把 `formUuid` / `pageId` 等平台 ID 写进 manifest。**用 code,CLI 自动解析。**
|
|
931
|
-
- ❌ 把 API key、token、密码写进 manifest。**用占位符,平台后台填真实值。**
|
|
932
|
-
- ❌ 同时在 manifest 与平台后台编辑同一个资源(漂移源)。**统一以 manifest 为单一来源**,需要看平台版本就 `resource pull`。
|
|
933
|
-
- ❌ 用 data view 代替 `linkedForm` 下拉、单表 CRUD 或写回。**data view 是只读;materialized 有刷新延迟,live 要控制查询边界。**
|
|
934
|
-
- ❌ 把跨页面/跨流程复用的后端逻辑都塞进 JS_CODE。**优先 App Function,JS_CODE 只做节点内脚本。**
|
|
935
|
-
- ❌ 在 page 源码里 hardcode `/api/notification-config/*` 或 `/connectors/actions/invoke`。**用 `sdk.notification` / `sdk.connector`。**
|
|
936
|
-
- ❌ 发布 workflow resource 后不检查是否激活。**用 `openxiangda workflow list --profile <name> --json` 确认 `isPublished: true`,需要时再跑 `openxiangda workflow publish <workflowCode>`。**
|