From 5a3aa9eaeab6f44349d75263a5f3a42341e73925 Mon Sep 17 00:00:00 2001 From: Newoahil <88387859+Newoahil@users.noreply.github.com> Date: Thu, 23 Jul 2026 18:27:43 +0800 Subject: [PATCH] =?UTF-8?q?retrofit=E6=A8=A1=E5=BC=8F=E5=BC=80=E5=8F=91?= =?UTF-8?q?=E5=AE=8C=E6=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- AGENT.md | 55 +- README.md | 9 +- SKILL.md | 78 + docs/archive/README.md | 32 + .../acceptance-audit-2026-07-02.md | 0 docs/{ => archive}/adapter-first-fix-plan.md | 0 ...pdater-mode-b-long-connection-task-book.md | 2 +- .../current-roadmap-task-book.md | 0 .../current-roadmap-verification-record.md | 0 .../development-direction-v2-adapter-first.md | 0 docs/{ => archive}/development-direction.md | 0 .../second-target-validation-plan.md | 0 docs/capability-validation-matrix.md | 2 +- docs/code2lark-localized-core-architecture.md | 111 ++ docs/code2lark-skill-requirements.md | 134 ++ docs/feishu-docs-audit-2026-07-03.md | 2 +- docs/next-stage-adapter-migration-plan.md | 2 +- docs/product-shape-decision.md | 37 +- docs/project-status.md | 10 +- docs/research/oss-code-analysis-candidates.md | 436 ++++++ .../source-level-cherry-pick-analysis.md | 103 ++ embedded-skills/lark-card-designer/SKILL.md | 180 +++ .../adapters/claude-code.md | 5 + .../lark-card-designer/adapters/opencode.md | 5 + .../lark-card-designer/agents/openai.yaml | 4 + .../lark-card-designer/docs/INDEX.md | 248 ++++ .../docs/github-research.md | 383 +++++ .../lark-card-designer/docs/manifest.json | 828 +++++++++++ .../raw/cardkit-v1__card-element__content.md | 102 ++ .../raw/cardkit-v1__card-element__create.md | 92 ++ .../raw/cardkit-v1__card-element__delete.md | 87 ++ .../raw/cardkit-v1__card-element__patch.md | 89 ++ .../raw/cardkit-v1__card-element__update.md | 87 ++ .../raw/cardkit-v1__card__batch_update.md | 93 ++ .../docs/raw/cardkit-v1__card__create.md | 82 ++ .../docs/raw/cardkit-v1__card__settings.md | 84 ++ .../docs/raw/cardkit-v1__card__update.md | 91 ++ ...rdkit-v1__feishu-card-resource-overview.md | 56 + .../client-docs__bot-v3__add-custom-bot.md | 801 +++++++++++ ...age-card__introduction-of-message-cards.md | 22 + ...rd-interactive-bot__card-building-steps.md | 64 + ...active-bot__explanation-of-example-code.md | 1087 ++++++++++++++ .../develop-a-card-interactive-bot__faqs.md | 15 + ...op-a-card-interactive-bot__introduction.md | 165 +++ ...preview__link-preview-development-guide.md | 171 +++ ...ll-link-preview-data-callback-structure.md | 118 ++ .../development-link-preview__quick-start.md | 194 +++ .../development-link-preview__typical-case.md | 22 + ...ishu-cards__card-callback-communication.md | 256 ++++ ...ds__card-components__component-overview.md | 57 + ...mponents__containers__collapsible-panel.md | 219 +++ ...card-components__containers__column-set.md | 402 ++++++ ...-components__containers__form-container.md | 260 ++++ ...ents__containers__interactive-container.md | 477 +++++++ ...onents__containers__recycling-container.md | 210 +++ ...d-components__content-components__chart.md | 221 +++ ...components__content-components__divider.md | 89 ++ ...d-components__content-components__image.md | 99 ++ ...content-components__multi-image-laylout.md | 176 +++ ...rd-components__content-components__note.md | 100 ++ ...ponents__content-components__plain-text.md | 140 ++ ...mponents__content-components__rich-text.md | 290 ++++ ...d-components__content-components__table.md | 358 +++++ ...d-components__content-components__title.md | 255 ++++ ...mponents__content-components__user-list.md | 189 +++ ...nents__content-components__user-profile.md | 106 ++ ...ponents__interactive-components__button.md | 345 +++++ ...onents__interactive-components__checker.md | 339 +++++ ...ts__interactive-components__date-picker.md | 123 ++ ...nteractive-components__date-time-picker.md | 126 ++ ...s__interactive-components__image-picker.md | 344 +++++ ...mponents__interactive-components__input.md | 301 ++++ ...-components__multi-select-dropdown-menu.md | 264 ++++ ...ve-components__multi-select-user-picker.md | 233 +++ ...nents__interactive-components__overflow.md | 224 +++ ...components__single-select-dropdown-menu.md | 171 +++ ...e-components__single-select-user-picker.md | 121 ++ ...__interactive-components__time-selector.md | 126 ++ .../raw/feishu-cards__card-json-structure.md | 320 +++++ ...-json-v2-breaking-changes-release-notes.md | 238 ++++ ...-components__component-json-v2-overview.md | 64 + ...mponents__containers__collapsible-panel.md | 246 ++++ ...n-v2-components__containers__column-set.md | 612 ++++++++ ...-components__containers__form-container.md | 147 ++ ...ents__containers__interactive-container.md | 512 +++++++ ...2-components__content-components__audio.md | 332 +++++ ...2-components__content-components__chart.md | 227 +++ ...components__content-components__divider.md | 78 + ...2-components__content-components__image.md | 129 ++ ...content-components__multi-image-laylout.md | 236 +++ ...ponents__content-components__plain-text.md | 155 ++ ...mponents__content-components__rich-text.md | 482 +++++++ ...2-components__content-components__table.md | 372 +++++ ...2-components__content-components__title.md | 213 +++ ...mponents__content-components__user-list.md | 203 +++ ...nents__content-components__user-profile.md | 120 ++ ...ponents__interactive-components__button.md | 373 +++++ ...onents__interactive-components__checker.md | 375 +++++ ...ts__interactive-components__date-picker.md | 165 +++ ...nteractive-components__date-time-picker.md | 167 +++ ...s__interactive-components__image-picker.md | 409 ++++++ ...mponents__interactive-components__input.md | 285 ++++ ...-components__multi-select-dropdown-menu.md | 339 +++++ ...ve-components__multi-select-user-picker.md | 308 ++++ ...nents__interactive-components__overflow.md | 226 +++ ...components__single-select-dropdown-menu.md | 238 ++++ ...e-components__single-select-user-picker.md | 187 +++ ...__interactive-components__time-selector.md | 170 +++ .../feishu-cards__card-json-v2-structure.md | 281 ++++ ...cards__configure-multi-language-content.md | 370 +++++ ...hu-cards__configuring-card-interactions.md | 136 ++ ...numerations-for-fields-related-to-color.md | 293 ++++ .../feishu-cards__enumerations-for-icons.md | 1263 +++++++++++++++++ ...hu-card-cardkit__add-interactive-events.md | 138 ++ ...feishu-card-cardkit__build-card-content.md | 81 ++ ...kit-upgraded-version-card-release-notes.md | 132 ++ ...feishu-card-cardkit__components__button.md | 121 ++ ..._feishu-card-cardkit__components__chart.md | 61 + ..._feishu-card-cardkit__components__image.md | 60 + ...ishu-card-cardkit__components__markdown.md | 103 ++ ..._feishu-card-cardkit__components__table.md | 117 ++ ...-card-cardkit__configure-card-languages.md | 87 ++ ...-card-cardkit__configure-card-variables.md | 1066 ++++++++++++++ ...u-card-cardkit__feishu-cardkit-overview.md | 72 + ...cards__feishu-card-cardkit__group-cards.md | 61 + ...u-card-cardkit__import-and-export-cards.md | 43 + ...ishu-card-cardkit__manage-card-template.md | 49 + ...card-cardkit__preview-and-publish-cards.md | 32 + .../raw/feishu-cards__feishu-card-overview.md | 115 ++ ...feishu-cards__feishu-card-release-notes.md | 63 + .../feishu-cards__handle-card-callbacks.md | 169 +++ ...-start__send-feishu-cards-with-app-bots.md | 212 +++ ...art__send-message-cards-with-custom-bot.md | 304 ++++ .../raw/feishu-cards__send-feishu-card.md | 51 + ...rds__streaming-updates-openapi-overview.md | 277 ++++ .../raw/feishu-cards__update-feishu-card.md | 63 + .../docs/raw/im-v1__message__create_json.md | 666 +++++++++ .../raw/reference__im-v1__file__create.md | 160 +++ .../raw/reference__im-v1__image__create.md | 154 ++ ...-v1__message-reaction__emojis-introduce.md | 69 + .../raw/reference__im-v1__message__create.md | 242 ++++ .../raw/reference__im-v1__message__delete.md | 76 + .../raw/reference__im-v1__message__patch.md | 130 ++ .../raw/reference__im-v1__message__reply.md | 187 +++ .../raw/reference__im-v1__message__update.md | 155 ++ .../server-docs__im-v1__message__create.md | 242 ++++ .../docs/requirements-analysis.md | 937 ++++++++++++ .../references/atomic-design-constraints.md | 132 ++ .../references/audience-portfolios.md | 56 + .../references/card-patterns.md | 85 ++ .../references/component-rules.md | 69 + .../references/decision-matrix.md | 69 + .../references/evaluation-cases.md | 56 + .../lark-card-designer/references/examples.md | 155 ++ .../references/github-project-lessons.md | 35 + .../references/interaction-parameters.md | 262 ++++ .../references/key-data-readability-rules.md | 132 ++ .../references/operational-analytics-rules.md | 163 +++ .../references/pattern-structure-sketches.md | 182 +++ .../references/rendering-constraints.md | 97 ++ .../references/streaming-card-rules.md | 123 ++ .../references/visual-preview-review-rules.md | 165 +++ .../references/visual-status-rules.md | 108 ++ .../scripts/fetch_feishu_card_docs.ps1 | 220 +++ references/analyzer-boundary.md | 34 + references/cobuild-workflow.md | 45 + references/confirmation-policy.md | 43 + references/evidence-handoff.md | 50 + references/retrofit-workflow.md | 50 + references/safety-and-secrets.md | 50 + src/commands/analyze.ts | 146 +- src/structural-analysis.ts | 91 +- src/types.ts | 29 +- tests/cli-smoke.test.mjs | 56 +- tools/README.md | 26 + tools/local-module-plan.md | 14 + 176 files changed, 32242 insertions(+), 76 deletions(-) create mode 100644 SKILL.md create mode 100644 docs/archive/README.md rename docs/{ => archive}/acceptance-audit-2026-07-02.md (100%) rename docs/{ => archive}/adapter-first-fix-plan.md (100%) rename docs/{ => archive}/calendar-stock-updater-mode-b-long-connection-task-book.md (99%) rename docs/{ => archive}/current-roadmap-task-book.md (100%) rename docs/{ => archive}/current-roadmap-verification-record.md (100%) rename docs/{ => archive}/development-direction-v2-adapter-first.md (100%) rename docs/{ => archive}/development-direction.md (100%) rename docs/{ => archive}/second-target-validation-plan.md (100%) create mode 100644 docs/code2lark-localized-core-architecture.md create mode 100644 docs/code2lark-skill-requirements.md create mode 100644 docs/research/oss-code-analysis-candidates.md create mode 100644 docs/research/source-level-cherry-pick-analysis.md create mode 100644 embedded-skills/lark-card-designer/SKILL.md create mode 100644 embedded-skills/lark-card-designer/adapters/claude-code.md create mode 100644 embedded-skills/lark-card-designer/adapters/opencode.md create mode 100644 embedded-skills/lark-card-designer/agents/openai.yaml create mode 100644 embedded-skills/lark-card-designer/docs/INDEX.md create mode 100644 embedded-skills/lark-card-designer/docs/github-research.md create mode 100644 embedded-skills/lark-card-designer/docs/manifest.json create mode 100644 embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card-element__content.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card-element__create.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card-element__delete.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card-element__patch.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card-element__update.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card__batch_update.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card__create.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card__settings.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card__update.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/cardkit-v1__feishu-card-resource-overview.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/client-docs__bot-v3__add-custom-bot.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/common-capabilities__message-card__introduction-of-message-cards.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/develop-a-card-interactive-bot__card-building-steps.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/develop-a-card-interactive-bot__explanation-of-example-code.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/develop-a-card-interactive-bot__faqs.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/develop-a-card-interactive-bot__introduction.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/development-link-preview__link-preview-development-guide.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/development-link-preview__pull-link-preview-data-callback-structure.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/development-link-preview__quick-start.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/development-link-preview__typical-case.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-callback-communication.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__component-overview.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__containers__collapsible-panel.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__containers__column-set.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__containers__form-container.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__containers__interactive-container.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__containers__recycling-container.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__chart.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__divider.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__image.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__multi-image-laylout.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__note.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__plain-text.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__rich-text.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__table.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__title.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__user-list.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__user-profile.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__button.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__checker.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__date-picker.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__date-time-picker.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__image-picker.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__input.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__multi-select-dropdown-menu.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__multi-select-user-picker.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__overflow.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__single-select-dropdown-menu.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__single-select-user-picker.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__time-selector.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-structure.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-breaking-changes-release-notes.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__component-json-v2-overview.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__containers__collapsible-panel.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__containers__column-set.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__containers__form-container.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__containers__interactive-container.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__audio.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__chart.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__divider.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__image.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__multi-image-laylout.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__plain-text.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__rich-text.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__table.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__title.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__user-list.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__user-profile.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__interactive-components__button.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__interactive-components__checker.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__interactive-components__date-picker.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__interactive-components__date-time-picker.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__interactive-components__image-picker.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__interactive-components__input.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__interactive-components__multi-select-dropdown-menu.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__interactive-components__multi-select-user-picker.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__interactive-components__overflow.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__interactive-components__single-select-dropdown-menu.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__interactive-components__single-select-user-picker.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__interactive-components__time-selector.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-structure.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__configure-multi-language-content.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__configuring-card-interactions.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__enumerations-for-fields-related-to-color.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__enumerations-for-icons.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__feishu-card-cardkit__add-interactive-events.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__feishu-card-cardkit__build-card-content.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__feishu-card-cardkit__cardkit-upgraded-version-card-release-notes.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__feishu-card-cardkit__components__button.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__feishu-card-cardkit__components__chart.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__feishu-card-cardkit__components__image.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__feishu-card-cardkit__components__markdown.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__feishu-card-cardkit__components__table.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__feishu-card-cardkit__configure-card-languages.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__feishu-card-cardkit__configure-card-variables.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__feishu-card-cardkit__feishu-cardkit-overview.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__feishu-card-cardkit__group-cards.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__feishu-card-cardkit__import-and-export-cards.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__feishu-card-cardkit__manage-card-template.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__feishu-card-cardkit__preview-and-publish-cards.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__feishu-card-overview.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__feishu-card-release-notes.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__handle-card-callbacks.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__quick-start__send-feishu-cards-with-app-bots.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__quick-start__send-message-cards-with-custom-bot.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__send-feishu-card.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__streaming-updates-openapi-overview.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/feishu-cards__update-feishu-card.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/im-v1__message__create_json.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/reference__im-v1__file__create.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/reference__im-v1__image__create.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/reference__im-v1__message-reaction__emojis-introduce.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/reference__im-v1__message__create.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/reference__im-v1__message__delete.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/reference__im-v1__message__patch.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/reference__im-v1__message__reply.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/reference__im-v1__message__update.md create mode 100644 embedded-skills/lark-card-designer/docs/raw/server-docs__im-v1__message__create.md create mode 100644 embedded-skills/lark-card-designer/docs/requirements-analysis.md create mode 100644 embedded-skills/lark-card-designer/references/atomic-design-constraints.md create mode 100644 embedded-skills/lark-card-designer/references/audience-portfolios.md create mode 100644 embedded-skills/lark-card-designer/references/card-patterns.md create mode 100644 embedded-skills/lark-card-designer/references/component-rules.md create mode 100644 embedded-skills/lark-card-designer/references/decision-matrix.md create mode 100644 embedded-skills/lark-card-designer/references/evaluation-cases.md create mode 100644 embedded-skills/lark-card-designer/references/examples.md create mode 100644 embedded-skills/lark-card-designer/references/github-project-lessons.md create mode 100644 embedded-skills/lark-card-designer/references/interaction-parameters.md create mode 100644 embedded-skills/lark-card-designer/references/key-data-readability-rules.md create mode 100644 embedded-skills/lark-card-designer/references/operational-analytics-rules.md create mode 100644 embedded-skills/lark-card-designer/references/pattern-structure-sketches.md create mode 100644 embedded-skills/lark-card-designer/references/rendering-constraints.md create mode 100644 embedded-skills/lark-card-designer/references/streaming-card-rules.md create mode 100644 embedded-skills/lark-card-designer/references/visual-preview-review-rules.md create mode 100644 embedded-skills/lark-card-designer/references/visual-status-rules.md create mode 100644 embedded-skills/lark-card-designer/scripts/fetch_feishu_card_docs.ps1 create mode 100644 references/analyzer-boundary.md create mode 100644 references/cobuild-workflow.md create mode 100644 references/confirmation-policy.md create mode 100644 references/evidence-handoff.md create mode 100644 references/retrofit-workflow.md create mode 100644 references/safety-and-secrets.md create mode 100644 tools/README.md create mode 100644 tools/local-module-plan.md diff --git a/AGENT.md b/AGENT.md index c6bf1df..fb28654 100644 --- a/AGENT.md +++ b/AGENT.md @@ -1,6 +1,43 @@ -# Code2Lark (Lark-deployer) +# Code2Lark -Code2Lark is a build-time generator. It analyzes an existing service and produces reviewable Feishu/Lark adapter packages. It builds and verifies integration artifacts; it does not own the target service lifecycle. +Code2Lark is the official project name. Older package, CLI, folder, and document references may still say `lark-deployer` or `Lark-deployer`; treat those as legacy implementation names, not product positioning. + +Code2Lark is a build-time generator and future skill-first delivery tool. It analyzes an existing service and produces reviewable Feishu/Lark adapter packages. It builds and verifies integration artifacts; it does not own the target service lifecycle. + +## Product Direction + +The intended product shape is **skill-first experience, reusable core underneath**. + +- The skill is the future user-facing product entry. It should orchestrate project understanding, business clarification, Mode A/B selection, Lark workflow design, dry-run review, real Feishu demo guidance, and sanitized evidence packaging. +- The existing CLI is not sacred as the product surface. Keep it only as a repeatable execution layer, CI harness, or temporary developer interface while it remains useful. +- If the execution layer becomes easier to maintain as a library, MCP/tool, or direct skill capability, it may replace or subsume CLI commands. +- Do not describe Code2Lark externally as CLI-first anymore. The current direction is skill-first with a verifiable core. + +External code-understanding skills should be reused and adapted instead of rebuilding generic project analysis from scratch. Code2Lark should focus on converting project capabilities into safe, operable, auditable Lark workflows. + +Recommended ownership split: + +```text +codegraph / understand-anything / project-analysis skills + -> project facts: files, entrypoints, routes, commands, dependencies, env, side effects + +Code2Lark + -> business mapping, Lark card/workflow design, safety policy, Mode A/B delivery, install/verify/handoff evidence +``` + +When adapting an external analysis skill, require structured output suitable for generation: entrypoints, routes, commands, side-effect labels, required env, candidate operations, risk level, and clarification questions. + +## Naming And Workspace Migration + +The repository folder may still be `C:\works\Lark-deployer` during active sessions. A future local rename to `C:\works\code2lark` is acceptable, but do it deliberately: + +1. Preserve or commit important current changes first. +2. Create a session handoff or record the session id before renaming, because project-path based session discovery may not automatically find old sessions from the new path. +3. Rename the folder outside active commands. +4. Update legacy references in `package.json`, README, docs, scripts, and generated examples as a separate verified change. +5. Run `npm run build` and `npm test` after internal name changes. + +Do not mix directory/package renaming with feature work or artifact cleanup. ## Architecture @@ -45,6 +82,8 @@ codegraph query route --kind route --path --json Code2Lark must never install codegraph or run codegraph `init`, `sync`, reindex, or index-rebuild operations. External results are normalized at the boundary; profile and downstream code must not depend on the external schema. +Longer term, `analyze` should be treated as the most replaceable part of the old CLI. Prefer cherry-picking, forking, or wrapping proven open-source project-analysis skills when they can produce the structured facts Code2Lark needs. Keep Code2Lark-specific analysis only where it maps facts into Lark workflows, safety controls, and delivery contracts. + ## Interaction Profiles Target-specific mapping lives in `src/profiles/`: @@ -77,6 +116,16 @@ The current calendar correction contract is strict: The generated package remains the source of truth. Do not replace generated directories manually; use the `install` command. +Current useful external replay for calendar demonstration and regression: + +```text +C:\works\calendar-stock-updater-code2lark-replay-20260716-211227 +``` + +This replay contains the current `integrations/lark` module, local private `.env`, and debug evidence. Do not delete or rewrite it without explicit approval. + +Older calendar replay copies such as `calendar-stock-updater-c2l-replay`, `calendar-stock-updater-mode-b-corrected-replay`, and `calendar-stock-updater-mode-b-replay` are cleanup candidates only after confirming they contain no unique `.env`, evidence, or comparison value. + ```powershell node dist/index.js generate --out --mode embedded-adapter --host-mode embedded-long-connection node dist/index.js verify --mode embedded-adapter --host-mode embedded-long-connection --strict @@ -107,7 +156,7 @@ Card payloads use JSON 2.0 (`schema: "2.0"`, `body.elements`, callback behaviors - `docs/calendar-stock-updater-mode-b-correction-task-book.md`: current calendar Mode B correction contract. - `docs/capability-validation-matrix.md`: validation fact matrix. - `docs/project-status.md`: current project status and evidence summary. -- `docs/calendar-stock-updater-mode-b-long-connection-task-book.md`: superseded historical plan; do not use it as the active contract. +- `docs/archive/calendar-stock-updater-mode-b-long-connection-task-book.md`: superseded historical plan; do not use it as the active contract. When documents conflict, follow the two current correction taskbooks above. diff --git a/README.md b/README.md index b0dabef..ea3cf70 100644 --- a/README.md +++ b/README.md @@ -117,15 +117,16 @@ node dist/index.js install generated\calendar-stock-updater-lark --target C:\pat #### calendar-stock-updater 当前状态 -当前 calendar Mode B 路线已经完成本地工程闭环: +当前 calendar Mode B 路线已经完成本地工程闭环和真实飞书演示链路验证: - 原始 `calendar-stock-updater` 项目保持只读,没有修改根 `package.json`、启动脚本、Docker、业务代码或 Web UI; - 安装验证使用独立 replay,只通过 `install --apply` 写入 `integrations/lark/**`; - 目标调用仍严格限制为 `GET /api/state`、`POST /api/run` 和 `POST /api/stop`; - strict verify 为 32 PASS / 0 WARN / 0 FAIL;Code2Lark 完整测试 41/41、replay 根测试 49/49、安装模块测试 8/8; -- 真实飞书长连接已成功建立并发送起始卡,真实 `card.action.trigger` 也已到达宿主; -- 当前真实联调阻塞在 `ALLOWED_OPERATOR_OPEN_IDS`:配置值与回调中的当前应用维度 `operator.open_id` 不一致,因此安全门禁按预期拒绝了操作; -- 真实 Level 2 尚未完成,仍需修正白名单后重新验证刷新、普通预演、停止流程,并补齐截图、message ID、脱敏日志和签字证据。 +- 真实飞书长连接已成功建立并发送起始卡,真实 `card.action.trigger` 已到达宿主; +- `ALLOWED_OPERATOR_OPEN_IDS` 已在本地私密配置中按当前应用维度 open_id 修正; +- 真实飞书点击已验证刷新、普通预演、停止准备和停止确认链路,宿主审计日志记录 `calendar.status.refresh`、`calendar.task.dry-run`、`calendar.task.stop.prepare`、`calendar.task.stop.confirm` received/succeeded,目标最终状态为 `stopped`; +- 当前剩余项是整理可分享的脱敏截图、message ID 和签字证据;真实 `.env`、open_id、chat id 和日志原文不得提交。 安装模块的本地配置位于目标 replay 的 `integrations/lark/.env`。不要把真实值提交到 Git: diff --git a/SKILL.md b/SKILL.md new file mode 100644 index 0000000..e497e84 --- /dev/null +++ b/SKILL.md @@ -0,0 +1,78 @@ +# Code2Lark Skill + +Code2Lark is a skill-first workflow for adding reviewed Feishu/Lark entrypoints to software projects. It supports two modes: + +- **Retrofit**: add Lark entrypoints to an existing project. +- **Co-Build**: design a new business capability and its Lark entrypoint together while another agent or developer owns the business code. + +Use this skill when the user asks to connect a project, feature, API, job, workflow, internal tool, or business operation to Feishu/Lark. Do not activate when the user only asks for generic coding help without Lark/Feishu intent. + +## Core Principle + +Code2Lark is the orchestrator and safety boundary. The existing Code2Lark CLI remains the execution layer; external analysis tools are optional enrichment; `lark-card-designer` owns card information architecture and interaction design. + +## Mandatory Routing + +1. If the target project already exists and the user wants Lark access added, read `references/retrofit-workflow.md`. +2. If the user is building a new capability and wants Lark access as part of the work, read `references/cobuild-workflow.md`. +3. Before relying on code analysis or external tools, read `references/analyzer-boundary.md`. +4. Before asking, generating, installing, or enabling actions, read `references/confirmation-policy.md` and `references/safety-and-secrets.md`. +5. Before card layout or interaction-state decisions, delegate or reference `embedded-skills/lark-card-designer/SKILL.md`; do not duplicate its design rules here. +6. Before reporting completion, read `references/evidence-handoff.md`. + +## CLI Reuse Model + +The skill should hide command complexity from the user while reusing the existing CLI as the stable execution layer. + +| Layer | Responsibility | Examples | +|---|---|---| +| Code2Lark Skill | Decide mode, ask questions, control risk, orchestrate commands, summarize evidence. | Retrofit/Co-Build routing, confirmation gates, handoff. | +| Code2Lark CLI | Execute repeatable operations. | `analyze`, `plan`, `generate`, `install`, `verify`, `doctor`, `evidence`, `handoff`. | +| External analyzers | Produce optional structural facts. | CodeGraph, dependency-cruiser, ast-grep, ts-morph. | +| lark-card-designer | Design card structure and interaction states. | Candidate, dry-run, running, success, failure, dangerous-action cards. | + +## Package Layout + +```text +code2lark/ + SKILL.md + references/ + embedded-skills/ + lark-card-designer/ + tools/ + src/ +``` + +`SKILL.md` is the only public skill entrypoint. `references/` holds process rules. `embedded-skills/lark-card-designer/` is the bundled card-design capability. `tools/` documents executable reuse and local integration plans. The repository's existing `src/` is the real Code2Lark CLI/core implementation that the skill package will progressively wrap and factor into reusable APIs. + +## Red Lines + +- Do not commit, publish, send cards, delete files, or apply target-project writes without explicit user instruction. +- Do not print or commit secrets, app secrets, open IDs, chat IDs, message IDs, raw tenant logs, or real `.env` values. +- Do not expose destructive or privileged actions without dry-run or prepare/confirm separation. +- Do not assume static analysis knows business intent; turn uncertainty into questions or disabled candidates. +- Do not let Code2Lark take over business code in Co-Build mode. + +## Default Output + +When planning or reporting, summarize in this shape: + +```text +mode: +- retrofit | cobuild + +what_was_discovered: +- source evidence and confidence + +recommended_lark_entrypoints: +- action, risk, required confirmation + +cli_execution_plan: +- commands to run or commands already run + +card_design_dependency: +- when/how lark-card-designer is used + +verification_and_handoff: +- checks, evidence, remaining manual steps +``` diff --git a/docs/archive/README.md b/docs/archive/README.md new file mode 100644 index 0000000..e1f0888 --- /dev/null +++ b/docs/archive/README.md @@ -0,0 +1,32 @@ +# Documentation Archive + +This directory holds historical plans, audits, and superseded design notes that remain useful for project history but are not current operating contracts. + +Use these active sources first: + +- `AGENT.md` +- `README.md` +- `docs/project-status.md` +- `docs/product-shape-decision.md` +- `docs/capability-validation-matrix.md` +- `docs/development-charter.md` +- `docs/codegraph-structural-backend-correction-task-book.md` +- `docs/calendar-stock-updater-mode-b-correction-task-book.md` +- `docs/mode-b-embedding-guide.md` +- `docs/host-delivery-mode-selection.md` +- `docs/feishu-official/` + +## Archived Files + +| File | Reason | +| --- | --- | +| `acceptance-audit-2026-07-02.md` | Point-in-time baseline audit. Its findings are historical, not a current contract. | +| `adapter-first-fix-plan.md` | Completed corrective plan superseded by the current charter and validation records. | +| `calendar-stock-updater-mode-b-long-connection-task-book.md` | Explicitly superseded by the current calendar Mode B correction taskbook. | +| `current-roadmap-task-book.md` | Completed roadmap retained for implementation history. Current status belongs in `docs/project-status.md`. | +| `current-roadmap-verification-record.md` | Completed verification record for the archived roadmap. | +| `development-direction.md` | Early direction note superseded by the charter and current product-shape decision. | +| `development-direction-v2-adapter-first.md` | Early adapter-first design note superseded by the charter and current delivery guides. | +| `second-target-validation-plan.md` | Explicitly marked as a historical Mode A baseline. The current calendar correction taskbook is authoritative. | + +No generated, handoff, replay, secret-bearing, official Feishu, or regression-evidence directories are archived here. diff --git a/docs/acceptance-audit-2026-07-02.md b/docs/archive/acceptance-audit-2026-07-02.md similarity index 100% rename from docs/acceptance-audit-2026-07-02.md rename to docs/archive/acceptance-audit-2026-07-02.md diff --git a/docs/adapter-first-fix-plan.md b/docs/archive/adapter-first-fix-plan.md similarity index 100% rename from docs/adapter-first-fix-plan.md rename to docs/archive/adapter-first-fix-plan.md diff --git a/docs/calendar-stock-updater-mode-b-long-connection-task-book.md b/docs/archive/calendar-stock-updater-mode-b-long-connection-task-book.md similarity index 99% rename from docs/calendar-stock-updater-mode-b-long-connection-task-book.md rename to docs/archive/calendar-stock-updater-mode-b-long-connection-task-book.md index 0875603..88bdb4f 100644 --- a/docs/calendar-stock-updater-mode-b-long-connection-task-book.md +++ b/docs/archive/calendar-stock-updater-mode-b-long-connection-task-book.md @@ -711,4 +711,4 @@ level2_verification_record.md ``` 这份任务书的核心区别是:**cal 的新 Mode B 成功标准不再是“生成 adapter”,而是“用户填一次 `.env`,启动一次,就获得可运行的飞书长连接服务”。** -```numerusformRGCTXDataന്റjson \ No newline at end of file +```numerusformRGCTXDataന്റjson diff --git a/docs/current-roadmap-task-book.md b/docs/archive/current-roadmap-task-book.md similarity index 100% rename from docs/current-roadmap-task-book.md rename to docs/archive/current-roadmap-task-book.md diff --git a/docs/current-roadmap-verification-record.md b/docs/archive/current-roadmap-verification-record.md similarity index 100% rename from docs/current-roadmap-verification-record.md rename to docs/archive/current-roadmap-verification-record.md diff --git a/docs/development-direction-v2-adapter-first.md b/docs/archive/development-direction-v2-adapter-first.md similarity index 100% rename from docs/development-direction-v2-adapter-first.md rename to docs/archive/development-direction-v2-adapter-first.md diff --git a/docs/development-direction.md b/docs/archive/development-direction.md similarity index 100% rename from docs/development-direction.md rename to docs/archive/development-direction.md diff --git a/docs/second-target-validation-plan.md b/docs/archive/second-target-validation-plan.md similarity index 100% rename from docs/second-target-validation-plan.md rename to docs/archive/second-target-validation-plan.md diff --git a/docs/capability-validation-matrix.md b/docs/capability-validation-matrix.md index 64370b3..480786a 100644 --- a/docs/capability-validation-matrix.md +++ b/docs/capability-validation-matrix.md @@ -7,4 +7,4 @@ This matrix is the current human-readable fact source for target profile, delive | image-agent-web | Mode A | self-hosted / long connection | yes | yes | verified sample baseline | | image-agent-web | Mode B | embedded host module | yes | yes | verified sample baseline | | calendar-stock-updater | Mode A | embedded-adapter / embedded-long-connection | yes | package and host contract verified; real Feishu pending | dedicated calendar Profile and `handleCardAction()` facade; formal Feishu ingress is `card.action.trigger`; exact target calls remain `GET /api/state`, `POST /api/run`, and `POST /api/stop` | -| calendar-stock-updater | Mode B | isolated Node module / long connection | yes | replay install verified; real WebSocket, start card, and callback receipt observed; authorized Level 2 pending | `auto` safely fell back to internal without a maintained index; strict generated TypeScript without suppressions; target-controlled status/log/failure text is bounded and redacted; dry-run-first install writes only `integrations/lark`; strict verify `32/0/0`; module `8/8`, replay `49/49`, zero-vulnerability audits, offline/conflict gates, and root/hash integrity passed; current app-scoped operator open_id must be aligned with `ALLOWED_OPERATOR_OPEN_IDS` before authorized refresh/dry-run evidence | +| calendar-stock-updater | Mode B | isolated Node module / long connection | yes | replay install verified; real WebSocket, start card, authorized dry-run, stop, and refresh verified | `auto` safely fell back to internal without a maintained index; strict generated TypeScript without suppressions; target-controlled status/log/failure text is bounded and redacted; dry-run-first install writes only `integrations/lark`; strict verify `32/0/0`; module `8/8`, replay `49/49`, zero-vulnerability audits, offline/conflict gates, and root/hash integrity passed; app-scoped operator open_id allowlist was corrected locally; target ended in `stopped`; shareable screenshot/message-id/sign-off evidence still needs packaging without secrets | diff --git a/docs/code2lark-localized-core-architecture.md b/docs/code2lark-localized-core-architecture.md new file mode 100644 index 0000000..dcd18e1 --- /dev/null +++ b/docs/code2lark-localized-core-architecture.md @@ -0,0 +1,111 @@ +# Code2Lark Localized Core Architecture + +**Date**: 2026-07-22 +**Status**: Implementation guide for the first localized-core branch +**Branch target**: stop before merge; do not merge from this branch without review + +## 1. Product Shape + +Code2Lark is a repository-root composite skill package with a TypeScript CLI/core implementation underneath it. + +```text +SKILL.md # Code2Lark skill entrypoint +references/ # Retrofit, Co-Build, analyzer, safety, evidence rules +embedded-skills/lark-card-designer/ # bundled card-design capability +tools/ # executable reuse and localization plans +src/ # existing TypeScript CLI/core implementation +docs/ # product and engineering records +tests/ # regression gates +``` + +The user-facing product is the Code2Lark skill. The CLI remains because it is the stable local execution harness for tests, CI, and repeatable operations. + +## 2. Layer Boundaries + +| Layer | Owns | Does not own | +|---|---|---| +| Skill | Mode selection, questions, safety gates, orchestration, handoff language. | Business implementation details or raw static-analysis algorithms. | +| Core API | Reusable analyze/generate/verify/evidence functions. | User-facing conversation policy. | +| CLI | Scriptable access to core APIs for CI and local QA. | Primary product UX. | +| Analyzer adapters | Low-level facts from internal scanner and integrated OSS tools. | Final business intent or Lark workflow decisions. | +| Capability mapper | Candidate Lark entrypoints, risk labels, confirmation questions. | Parsing every language itself. | +| Generator/verifier/evidence | Lark integration package, validation, audit, handoff. | Generic code intelligence beyond C2L needs. | +| Embedded lark-card-designer | Card information architecture and interaction-state design. | Sending cards, credentials, callbacks, or runtime implementation. | + +## 3. OSS Localization Policy + +Code2Lark should not ask users to manually operate a pile of external CLIs. OSS capabilities should be localized behind adapters where they materially improve C2L's product loop. + +| Source | Localization style | First use | +|---|---|---| +| dependency-cruiser | Add a local optional analyzer adapter or dependency. | JS/TS module graph, circular deps, orphan modules. | +| ast-grep | Add bundled structural rule packs and an adapter. | Route/config/framework/secret fingerprints. | +| ts-morph | Add a TS analyzer module. | Exported signatures, JSDoc, parameter hints. | +| CodeGraph | Borrow graph vocabulary and route/edge model first; keep external backend optional. | Normalize structural facts and future route/symbol expansion. | +| lark-card-designer | Fully embedded skill. | Card design decisions and review rules. | + +## 4. Normalized Structural Facts + +The first code step is to introduce a backend-neutral graph fact shape while preserving current manifest fields. + +```text +StructuralFacts + backend + routes # existing route_provenance source + graph # new normalized facts + nodes[] # route/file/symbol/config/etc. + edges[] # references/calls/imports/contains/etc. + confidence + notes[] +``` + +MVP rules: + +- Existing `routes` and manifest `route_provenance` remain stable. +- Internal analyzer maps discovered endpoints into `route` nodes. +- CodeGraph route backend maps queried routes into `route` nodes. +- Missing optional analyzers must not block safe fallback. +- Graph facts are evidence, not product decisions. + +## 5. CLI Retention + +Keep the CLI as TypeScript compiled to Node.js: + +```powershell +npm run build +node dist/index.js analyze --out +node dist/index.js plan +node dist/index.js generate --out +node dist/index.js verify --strict +``` + +The desired evolution is not to remove the CLI, but to extract reusable core APIs so both the CLI and skill orchestration use the same implementation. + +## 6. First Implementation Slice + +This branch should implement only the smallest useful code step: + +1. Add normalized structural graph types. +2. Populate route nodes from existing internal and CodeGraph route facts. +3. Emit graph facts into `service_manifest.source_scan.structural_graph` while keeping existing fields. +4. Add tests that prove old fields still work and new graph facts exist. + +Out of scope for this slice: + +- Adding dependency-cruiser as a package dependency. +- Adding ast-grep rule execution. +- Adding ts-morph analysis. +- Replacing the analyzer strategy system. +- Sending real Lark cards. + +## 7. QA Gate Before Merge + +Stop before merge when all are true: + +- New tests show RED before implementation and GREEN after implementation. +- `npm run build` passes. +- Relevant CLI smoke tests pass. +- Full `npm test` passes or any pre-existing blocker is clearly documented. +- `git diff --check` passes. +- Changed TypeScript files have clean diagnostics. +- Branch contains reviewable changes and no secrets. diff --git a/docs/code2lark-skill-requirements.md b/docs/code2lark-skill-requirements.md new file mode 100644 index 0000000..674dcee --- /dev/null +++ b/docs/code2lark-skill-requirements.md @@ -0,0 +1,134 @@ +# Code2Lark Skill MVP Requirements + +**Date**: 2026-07-22 +**Status**: Draft for MVP implementation +**Product direction**: Skill-first experience, reusable CLI/core underneath + +## 1. MVP Positioning + +Code2Lark MVP is a skill-first workflow that helps an AI coding agent turn selected software capabilities into Feishu/Lark entrypoints. It must support both existing-project retrofit and new-feature co-build, but it is not expected to automatically understand every codebase or make irreversible product decisions without confirmation. + +The MVP promise is: + +> For common Web/API/task-style projects, Code2Lark can discover candidate capabilities, ask the right confirmation questions, generate an isolated Lark integration, verify the result, and produce handoff evidence. + +## 2. Modes + +| Mode | Primary user intent | Role of project analysis | Code2Lark behavior | +|---|---|---|---| +| Retrofit | Add Lark entrypoints to an existing project. | Core engine. It discovers existing APIs, jobs, commands, handlers, config, and risk signals. | Analyze first, propose candidates, ask before modifying, then generate/install isolated integration. | +| Co-Build | Build a new business capability and Lark entrypoint together. | Safety guardrail. It detects existing structure and avoids fighting the host project. | Participate only when the user expresses Lark/business-entry intent; coordinate contracts with the main development agent. | + +Retrofit needs stronger static analysis because the product must infer from existing code. Co-Build needs stronger interaction discipline because the product must avoid taking over business design. + +## 3. MVP Scope + +| Area | In scope for MVP | Out of scope for MVP | +|---|---|---| +| Project types | Common JS/TS/Python Web/API/task projects, small internal tools, admin workflows, scheduled jobs with safe dry-run semantics. | Arbitrary desktop/mobile/game/embedded systems, heavily dynamic private frameworks, opaque binary-only systems. | +| Analysis | Routes, handlers, exported functions, module dependencies, config/env hints, side-effect clues, candidate operations. | Guaranteed business intent, complete data-flow proof, full runtime behavior reconstruction. | +| Generation | Isolated Lark adapter/host module, card actions, validation, audit events, `.env.example`, README/runbook. | Deep rewrite of target business logic, production deployment automation, automatic permission ownership changes. | +| Safety | Dry-run-first, allowlist, confirmation cards, audit logs, explicit install/apply steps, no secret commits. | Silent dangerous action exposure, automatic deletion/payment/send actions without confirmation. | +| Evidence | Local verification report, Level 2 evidence template, handoff notes, cleanup rules. | Fully automated real-tenant certification across all Lark app configurations. | + +## 4. Analyzer Sufficiency Boundary + +The current cherry-pick set is sufficient for MVP, not sufficient for a general-purpose product claim. + +| Source | MVP role | Boundary | +|---|---|---| +| CodeGraph | Primary optional graph model and route/symbol backend. | Use when the user maintains an index; do not auto-init or vendor the engine. | +| dependency-cruiser | JS/TS module dependency enrichment. | Not universal; use only as optional JS/TS facts. | +| ast-grep | Structural pattern rules for routes/config/framework/secret fingerprints. | Rule engine only, not a full project understanding engine. | +| ts-morph | TypeScript signatures, exports, JSDoc, and parameter hints. | TS-only enrichment gated by usable project config. | +| Code2Lark-owned logic | Business mapping, Lark workflow design, safety policy, generation, verification. | Must remain the product differentiator; do not outsource product judgment to analyzers. | + +The analyzer layer should produce facts and uncertainty, not final product decisions. Any low-confidence or high-risk finding must become a question, a disabled candidate, or a dry-run-only action. + +## 5. Required Workflow + +### 5.1 Retrofit Workflow + +1. Discover project type, language, package/runtime signals, and likely entrypoints. +2. Extract candidate capabilities from routes, commands, jobs, exported handlers, and documented operations. +3. Classify each candidate by risk: read-only, dry-run, state-changing, destructive, external-send, privileged. +4. Ask confirmation questions before writing any integration files. +5. Generate into an isolated location, defaulting to `integrations/lark` for target-project install mode. +6. Produce `.env.example`, local runbook, verification commands, cleanup instructions, and handoff evidence templates. +7. Verify locally before reporting completion. + +### 5.2 Co-Build Workflow + +1. Activate only when the user asks for a Lark/Feishu-facing business entrypoint. +2. Let the main development agent own business implementation. +3. Code2Lark owns Lark cards, action contracts, adapter glue, validation, audit, and evidence. +4. If required business API/state endpoints do not exist, propose a minimal contract and ask before modifying business code. +5. Keep integration files isolated unless the user explicitly approves touching host project surfaces. + +## 6. Confirmation and Card Principles + +Lark cards in the MVP should be action-oriented and risk-aware. The first screen must show what action will happen, which target it affects, and whether it is dry-run or real execution. + +| State | Card behavior | +|---|---| +| Candidate proposal | Show capability name, source evidence, inferred inputs, risk level, and required confirmation. | +| Dry-run result | Show planned action, target response, warnings, and a separate confirm button if state change is allowed. | +| Running | Show status, operation id if available, refresh action, and safe cancellation if supported. | +| Success | Show result summary, affected target, timestamp, operator, and next safe action. | +| Failure | Show human-readable error, retry/refresh path, and where to inspect logs without exposing secrets. | +| Dangerous action | Require explicit prepare/confirm split; default button must not execute destructively. | + +Design red lines: + +- Do not put raw logs or secrets on the card. +- Do not hide the action behind long explanation. +- Do not use color decoratively; header/status color must express risk or state. +- Do not expose destructive operations without dry-run or two-step confirmation. +- Do not assume the operator is authorized because they can see the card. + +## 7. Security Requirements + +| Requirement | MVP rule | +|---|---| +| Secrets | Real `.env`, app secret, open id, chat id, message id evidence, and raw logs must not be committed. | +| Authorization | Generated integrations must support operator allowlists for action execution. | +| Isolation | Target-project install must default to an isolated integration directory. | +| Side effects | State-changing actions require explicit user confirmation; destructive actions require prepare/confirm split. | +| Debug surfaces | Debug endpoints/tokens must be local or explicitly protected. | +| Audit | Every card action should record action, operator, target, timestamp, result, and correlation id where possible. | + +## 8. Evidence and Handoff Deliverables + +Every MVP run should produce or update: + +| Deliverable | Purpose | +|---|---| +| `README.md` or integration README | How to configure, run, verify, and stop the integration. | +| `.env.example` | Required variables without real values. | +| Verification report | Machine-readable local pass/fail status. | +| Handoff note | What was generated, what was verified, and what remains manual. | +| Cleanup rules | How to remove generated files and which evidence/private files must be preserved or ignored. | +| Level 2 evidence template | Space for real Lark tenant proof without committing secrets. | + +## 9. Acceptance Criteria + +The MVP skill is acceptable when all of the following are true: + +1. Retrofit can analyze at least the existing `image-agent-web` and `calendar-stock-updater` samples and produce candidate Lark operations with source evidence. +2. Co-Build can guide a new small project to expose one safe Lark entrypoint without taking over unrelated business code. +3. Analyzer uncertainty is visible to the user as questions, warnings, or disabled candidates. +4. Generated integration remains isolated and can be reviewed before apply. +5. Dry-run-first and allowlist behavior are present in generated action paths. +6. Local verification passes before handoff. +7. Evidence output is useful without containing real secrets. +8. Failure modes are explicit: missing credentials, unreachable target, unauthorized operator, stale analysis, unsupported framework, and unsafe action. + +## 10. Product Claim Boundary + +Allowed MVP claim: + +> Code2Lark helps agents add reviewed, isolated Lark entrypoints to common software projects by combining project analysis, confirmation workflows, code generation, and verification evidence. + +Disallowed MVP claim: + +> Code2Lark automatically understands any project and safely exposes any capability to Lark without human review. diff --git a/docs/feishu-docs-audit-2026-07-03.md b/docs/feishu-docs-audit-2026-07-03.md index 164475e..d25f4dc 100644 --- a/docs/feishu-docs-audit-2026-07-03.md +++ b/docs/feishu-docs-audit-2026-07-03.md @@ -148,7 +148,7 @@ Long-connection receiving is documented as a future option. 放: - `docs/development-charter.md` -- `docs/development-direction-v2-adapter-first.md` +- `docs/archive/development-direction-v2-adapter-first.md` - `docs/next-stage-adapter-migration-plan.md` 特点: diff --git a/docs/next-stage-adapter-migration-plan.md b/docs/next-stage-adapter-migration-plan.md index 7eade2b..f4595a1 100644 --- a/docs/next-stage-adapter-migration-plan.md +++ b/docs/next-stage-adapter-migration-plan.md @@ -234,7 +234,7 @@ lark-deployer verify \ - `README.md`; - `docs/project-status.md`; -- `docs/development-direction.md`; +- `docs/archive/development-direction.md`; - `docs/mvp-1a-image-agent-web.md` 中与生成 runtime 相关的表述; - 交接文档中增加 embedded adapter 路径。 diff --git a/docs/product-shape-decision.md b/docs/product-shape-decision.md index 54c8c46..2e6fc87 100644 --- a/docs/product-shape-decision.md +++ b/docs/product-shape-decision.md @@ -1,18 +1,19 @@ # Code2Lark 产品形态决策 记录时间:2026-07-08 +更新:2026-07-21 ## 结论 当前阶段,Code2Lark 采用: -> **方案 A:CLI-first,skill 暂缓。** +> **长期产品入口要做成 skill;CLI 保留为可验证、可脚本化的能力内核。** 也就是说: -- **当前主交付形态**:CLI 工具 -- **当前主工作重心**:模式 A / 模式 B 产品化 + manifest-driven 泛用化 -- **暂不优先做的形态**:skill 入口 / agent 入口 +- **当前主交付形态**:CLI 工具 + 可生成的 Lark 接入包 +- **当前主工作重心**:模式 A / 模式 B 产品化 + manifest-driven 泛用化 + skill 化前的能力内核稳定 +- **后续产品入口**:skill / agent 入口,面向“把外部项目变成飞书工作流”的交互式交付体验 ## 为什么是 CLI-first @@ -47,21 +48,23 @@ > 现在做 skill 的收益主要是体验收益,不是能力收益。 -## 这不代表以后不做 skill +calendar-stock-updater 的真实演示链路跑通后,这个判断需要调整:CLI-first 仍适合作为工程内核,但对外展示、需求澄清、项目扫描、交付引导和证据收集更适合由 skill 承载。后续 skill 不应替代 CLI,而应编排 CLI:让用户通过对话完成目标项目选择、能力识别、卡片方案确认、安装 dry-run、真实飞书联调和脱敏证据归档。 -不做 skill 只是**当前阶段的优先级选择**,不是长期否定。 +## Skill 方向 -未来当这些条件成立后,再做 skill 入口: +不做 skill 曾经只是**阶段性优先级选择**,不是长期否定。现在方向已经明确:Code2Lark 后续要形成 skill 入口。 + +做 skill 入口前仍需保留以下前置条件: 1. 模式 A / 模式 B 已稳定 2. `manifest-driven` 泛用化基本成立 -3. 第二目标项目验证通过 +3. 第二目标项目验证通过,且可解释哪些 replay/证据应保留 4. analyze / generate / verify 主路径稳定 5. 文档、术语、产物语义不再持续漂移 -届时,skill 应被定义成: +skill 应被定义成: -> **Code2Lark CLI 内核之上的入口层** +> **Code2Lark CLI 内核之上的交付编排层** 而不是本体。 @@ -69,7 +72,7 @@ 当前 Code2Lark 的产品形态应理解为: -> **一个以 CLI 为内核的、用于生成飞书接入产物的构建时工具。** +> **一个以 CLI 为内核、未来以 skill 为主入口的飞书接入交付工具。** 它未来可以演化成: @@ -79,22 +82,24 @@ skill / agent 入口 → generated adapter / feishu-host / docs / manifests ``` -但这不是这一阶段的主任务。 +下一阶段的设计应把 skill 作为产品入口来规划,但实现上仍先加固 CLI 内核,避免 skill 只包装不可靠能力。 ## 推荐路线 ### 现在 - 继续以 CLI 为主 -- 推进 `docs/current-roadmap-task-book.md` +- 参考归档的 `docs/archive/current-roadmap-task-book.md`,当前状态以 `docs/project-status.md` 为准 - 完成模式 A / B 封装 - 推进泛用化 +- 同步整理 skill 入口的职责边界:项目扫描、问题澄清、生成方案解释、安装 dry-run 审查、飞书联调 runbook、证据归档 ### 之后 -- 当第二目标验证通过后 -- 再评估 skill 入口 +- 把 skill 入口落成第一层产品体验 +- 让 skill 调用 CLI,而不是复制 CLI 逻辑 +- 用 calendar 和 image-agent 两个样板作为 skill 回归演示 ## 一句话总结 -> **当前阶段,Code2Lark 先做成成熟的 CLI 内核工具;skill 作为未来入口层,等泛用化与模式封装稳定后再做。** +> **Code2Lark 后续产品形态是 skill-first 体验、CLI-core 内核:用户通过 skill 完成交付决策和演示闭环,CLI 负责可重复、可验证、可脚本化的生成与检查。** diff --git a/docs/project-status.md b/docs/project-status.md index 51bde3d..3a201aa 100644 --- a/docs/project-status.md +++ b/docs/project-status.md @@ -1,7 +1,7 @@ # 项目进展文档 初始记录:2026-07-02 -最后更新:2026-07-17 +最后更新:2026-07-21 记录人:审计对话(Claude Code) 本文档是对当前代码库和 `docs/` 现有资料的一次快照式审计总结,用于给后续开发和交接提供一个"此刻项目处于什么状态"的基准点。请在重大里程碑后更新此文档,而不是频繁小改。 @@ -10,6 +10,8 @@ Lark-deployer 是一个构建时(build-time)生成器:分析一个已有服务或服务交互流程,生成可审查的服务契约(manifest / capability_map / interaction_contract / required_permissions)、飞书/Lark 交互设计、可嵌入适配器代码、权限说明、验证与交接材料。 +2026-07-21 方向同步:Code2Lark 后续产品形态应走 **skill-first 体验、CLI-core 内核**。CLI 继续承担可重复的 analyze / generate / install / verify / handoff;skill 负责交互式澄清目标项目、解释能力边界、选择 Mode A/B、引导演示联调、整理脱敏证据和判断外部 replay 是否保留。 + 2026-07-02 的设计纠偏后,项目总方向以 `docs/development-charter.md` 为准:核心产物应是 `adapter/` 或目标语言宿主,而不是必须独立部署的 `bot-runtime`。当前已有 `bot-runtime` 应被保留为 standalone/reference host,用于没有现成飞书服务的用户或本地验证;对已有飞书 SDK 服务的场景,应优先生成可嵌入 adapter。2026-07-04 新增的 `self-hosted-runtime` 是第一种目标语言宿主,当前为 Python `feishu-host/`,使用 `lark-oapi` 长连接接收 `card.action.trigger`,通过 HTTP 调用 `image-agent-web`。 当前已验证样板服务:`C:\works\image-agent-web`(`docs/mvp-1a-image-agent-web.md`);当前泛用化第二目标验证服务:`C:\works\calendar-stock-updater`。 @@ -45,7 +47,7 @@ analyze → plan → context(生成给所有者的凭据请求) → generate(生 - **image-agent-web self-hosted-runtime 已有真实飞书长连接 MVP 验证**:2026-07-07 后以 `docs/image-agent-web-mvp-verified-summary.md` 为回归锚点,确认长连接、`card.action.trigger`、Card JSON 2.0、异步 running + patch、generate / iterate / batch / refresh、失败路径已经跑通。webhook/standalone Level 2 仍按各自生成包证据记录独立管理。 - **image-agent-web 样板分类**:The verified image-agent-web sample has completed deployment-test validation in Mode A with a Python self-hosted host module run externally, and it has also completed deployment-test validation in Mode B as a target-project embedded host module. This roadmap treats those validations as the current sample baseline and consolidates them into a reusable MVP integration package. - **self-hosted-runtime 本地 MVP 已作为目标形态落地**:生成物为 `generated/-lark/feishu-host/`,包含 `.env.example`、`requirements.txt`、manifest-derived `spec/*.json`、Python card/client/validation/handler/app 文件、`local_contract_test.py` 和 `app.py --selfcheck`。最终本地完成证据必须在安装 Python 依赖后运行 strict verify,不能把缺依赖 WARN 当成绿灯。 -- **calendar-stock-updater 已完成结构后端纠偏后的 Mode B 本地验证与复审修正**:2026-07-16 至 2026-07-17 在全新 `C:\works\calendar-stock-updater-code2lark-replay-20260716-211227` 上保留原项目当前工作树,完成 `analyze --backend auto` 安全回退 internal、fresh plan → generate → strict verify、dry-run 零写入、`--apply` 仅写 `integrations/lark`、23 个根文件与原始项目 SHA-256 全匹配、模块 `8/8`、replay 根 `49/49`、离线门禁、托管文件冲突门禁和零漏洞审计。最终候选包为 `generated/calendar-stock-updater-codegraph-replay-20260717-0218-v6-lark`,最终脱敏交接包为 `handoff/calendar-stock-updater-codegraph-replay-20260717-0218-v7-lark`;strict verify 为 `32/0/0`,handoff warnings=`0`。生成的 calendar TypeScript 不再使用检查抑制,状态、日志和失败文本已限长与敏感模式脱敏,授权错误使用中文业务文案,generic HTTP 非 2xx 失败卡不再暴露原始响应正文,context/handoff 不再携带图片代理或 generic runtime 残留。专用 calendar Profile 只声明 `GET /api/state`、`POST /api/run`、`POST /api/stop`;正式执行和停止的确认状态留在隔离 Node 宿主。真实飞书预联调已成功建立长连接、发送起始卡并收到 `card.action.trigger`,但当前应用维度的 operator open_id 与本地白名单不匹配,操作被安全门禁拒绝;未发生正式执行,Level 2 仍未完成。 +- **calendar-stock-updater 已完成结构后端纠偏后的 Mode B 本地验证与真实飞书演示链路验证**:2026-07-16 至 2026-07-17 在全新 `C:\works\calendar-stock-updater-code2lark-replay-20260716-211227` 上保留原项目当前工作树,完成 `analyze --backend auto` 安全回退 internal、fresh plan → generate → strict verify、dry-run 零写入、`--apply` 仅写 `integrations/lark`、23 个根文件与原始项目 SHA-256 全匹配、模块 `8/8`、replay 根 `49/49`、离线门禁、托管文件冲突门禁和零漏洞审计。最终候选包为 `generated/calendar-stock-updater-codegraph-replay-20260717-0218-v6-lark`,最终脱敏交接包为 `handoff/calendar-stock-updater-codegraph-replay-20260717-0218-v7-lark`;strict verify 为 `32/0/0`,handoff warnings=`0`。生成的 calendar TypeScript 不再使用检查抑制,状态、日志和失败文本已限长与敏感模式脱敏,授权错误使用中文业务文案,generic HTTP 非 2xx 失败卡不再暴露原始响应正文,context/handoff 不再携带图片代理或 generic runtime 残留。专用 calendar Profile 只声明 `GET /api/state`、`POST /api/run`、`POST /api/stop`;正式执行和停止的确认状态留在隔离 Node 宿主。后续真实飞书联调已修正当前应用维度的 operator open_id 白名单,真实点击验证了 `calendar.status.refresh`、`calendar.task.dry-run`、`calendar.task.stop.prepare`、`calendar.task.stop.confirm`,目标最终状态为 `stopped`。可分享材料仍需整理脱敏截图、message ID 和签字证据;真实 `.env`、open_id、chat id 和日志原文不得提交。 - 唯一一次真实目标服务联调记录:2026-07-01,临时启动 `C:\works\image-agent-web`,验证了 `GET /api/meta`、生成运行时 `/health`、本地卡片 URL 挑战等;`POST /api/generate` 之外的真实调用未覆盖(依赖外部图像/模型服务)。 ## 5. 审计结论:优点 @@ -75,8 +77,8 @@ analyze → plan → context(生成给所有者的凭据请求) → generate(生 ## 7. 处理记录 -- 2026-07-02:完成首次代码审计(本文档);创建 `docs/development-direction.md` 记录后续开发方向;执行 `git init` 首次提交,锁定当前基线。 +- 2026-07-02:完成首次代码审计(本文档);创建早期开发方向记录(现归档至 `docs/archive/`);执行 `git init` 首次提交,锁定当前基线。 - 2026-07-04:按 `docs/mvp-self-hosting-task-book.md` 推进 `self-hosted-runtime`,新增 Python `feishu-host/` 长连接宿主生成、local contract/selfcheck/strict verify 路径,并明确真实飞书 Level 2 仍是人工证据步骤。 - 2026-07-07:冻结 `image-agent-web` self-hosted-runtime 真实飞书 MVP 为回归锚点;将 manifest 契约提升到 `0.2`;把 `analyze` 拆成 strategy-based 结构;新增 `generic_http_api` 粗粒度分析路径;新增 `generic-http-api` embedded-adapter 生成、strict verify、doctor package validation 测试路径。暂未扩展 Slack/企业微信、群 @、私聊命令、全自动部署或 skill 形态。 - 2026-07-08:按当前路线补齐模式 A/B 产品化说明与 Mode B 迁入指南;补充 Node `server.js` 字面量路由发现,使 `calendar-stock-updater` 作为第二目标进入泛用工作流并通过 package validation。 -- 2026-07-08:补充 `docs/current-roadmap-verification-record.md` 记录最终验证证据和不重写 `master` 的提交顺序 waiver;路线任务书与相关阶段任务书已入库,`.claude/` 作为本地工具状态忽略。 +- 2026-07-08:补充路线验证记录(现归档至 `docs/archive/`)和不重写 `master` 的提交顺序 waiver;路线任务书与相关阶段任务书已入库,`.claude/` 作为本地工具状态忽略。 diff --git a/docs/research/oss-code-analysis-candidates.md b/docs/research/oss-code-analysis-candidates.md new file mode 100644 index 0000000..74e6e1b --- /dev/null +++ b/docs/research/oss-code-analysis-candidates.md @@ -0,0 +1,436 @@ +# Code2Lark Project Understanding Layer: OSS Candidate Research Report + +**Date**: 2026-07-22 +**Status**: Research Complete +**Author**: THE LIBRARIAN (automated research agent) + +--- + +## Executive Summary + +Code2Lark is evolving from a CLI-first build-time generator into a **skill-first** tool that converts software capabilities into Feishu/Lark workflows. The current `analyze` command uses a built-in internal scanner with optional codegraph backend, but the AGENT.md explicitly states: *"External code-understanding skills should be reused and adapted instead of rebuilding generic project analysis from scratch."* + +This report evaluates 10 mature open-source projects across 5 capability categories, ranks them for Code2Lark suitability, and provides concrete cherry-pick targets. + +### Top Recommendation + +**CodeGraph (colbymchenry/codegraph)** is the strongest single candidate. It already integrates with Code2Lark via the `--backend codegraph` path, provides framework-aware route detection across 17+ frameworks, and exposes a rich MCP tool surface. Its Rust kernel, SQLite storage, and auto-sync file watcher make it the most complete drop-in replacement for the internal scanner. + +--- + +## 1. Code2Lark's Current Analysis Capabilities + +Before evaluating candidates, here is what Code2Lark's `analyze` command currently does: + +| Capability | Current Implementation | File | +|---|---|---| +| File inventory | `collectSourceFiles()` with skip-dir filtering | `src/commands/analyze.ts:960-980` | +| Route/endpoint detection | Regex-based: FastAPI decorators, Node HTTP patterns, documented endpoints | `src/commands/analyze.ts:856-864, 1002-1011` | +| Framework detection | String matching in requirements.txt, main.py, package.json | `src/commands/analyze.ts:789-799` | +| Secret scanning | Regex patterns for API keys and secret assignments | `src/commands/analyze.ts:49-55` | +| Structural backend | Internal regex + optional codegraph CLI integration | `src/structural-analysis.ts` | +| Dependency graph | **Not implemented** | N/A | +| Symbol extraction | **Not implemented** (only endpoint extraction) | N/A | +| Architecture summarization | **Not implemented** | N/A | +| Code knowledge graph | **Not implemented** | N/A | + +**Gap Analysis**: Code2Lark needs structured output containing: entrypoints, routes, commands, side-effect labels, required env, candidate operations, risk level, and clarification questions. The current internal scanner only covers routes and frameworks at a surface level. + +--- + +## 2. Candidate Evaluation Matrix + +### Category A: Code Knowledge Graph / Symbol Extraction + +| Candidate | Public signal observed during research | License | Language | Maturity | Key Strength | +|---|---|---|---|---|---| +| **CodeGraph** (colbymchenry/codegraph) | High GitHub visibility | MIT | Rust+TS | Active | Framework-aware routes, 20+ languages, MCP native | +| **codelens** (frostorygon/codelens) | Low visibility during research | ? | JS | Early | Call chains, dead code, cycle detection | +| **Arbok** (takuto-san/Arbok) | ? | ? | TS | Active | SQLite index, MCP, memory bank | +| **Ariadne** (CRJFisher/ariadne) | 19 | MIT | TS | Early | Scope graph, call graphs, multi-lang | +| **mcp-codebase-intelligence** (g-tiwari) | Low visibility during research | MIT | TS | Early | 18 tools, 8 languages, LSP hybrid | +| **Specter-Tree** (DinoQuinten/specter-tree) | Low visibility during research | MIT | TS | Early | ts-morph based, TypeScript-only | + +### Category B: Dependency Graph / Module Analysis + +| Candidate | Public signal observed during research | License | Language | Maturity | Key Strength | +|---|---|---|---|---|---| +| **dependency-cruiser** (sverweij) | Mature and widely used | MIT | JS/TS | Active since 2016+ | Programmatic API, JSON output, dependency rules | +| **madge** (pahen/madge) | Mature public repository | MIT | JS | Active since 2012+ | Simple API, circular detection, Graphviz output | + +### Category C: Structural Search / Pattern Matching + +| Candidate | Public signal observed during research | License | Language | Maturity | Key Strength | +|---|---|---|---|---|---| +| **ast-grep** (ast-grep/ast-grep) | Active public repository with strong visibility | MIT | Rust | Active since 2022+ | 20+ languages, Node.js binding, jQuery-like API | + +### Category D: Codebase Packing / Context Preparation + +| Candidate | Public signal observed during research | License | Language | Maturity | Key Strength | +|---|---|---|---|---|---| +| **Repomix** (yamadashy/repomix) | Active public repository with strong visibility | MIT | TS | Active since 2024+ | Tree-sitter compression, MCP server, remote repos | + +### Category E: TypeScript Deep Analysis + +| Candidate | Public signal observed during research | License | Language | Maturity | Key Strength | +|---|---|---|---|---|---| +| **ts-morph** (dsherret/ts-morph) | Mature and widely used | MIT | TS | Active since 2017+ | Full TypeScript Compiler API wrapper | + +--- + +## 3. Detailed Candidate Profiles + +### 3.1 CodeGraph (colbymchenry/codegraph) — **TIER 1: STRONGEST MATCH** + +**GitHub**: https://github.com/colbymchenry/codegraph +**License**: MIT +**Observed status during research**: active public repository with strong visibility + +**What it provides**: +- Native Rust kernel with tree-sitter parsing for 20+ languages +- SQLite-backed knowledge graph with FTS5 full-text search +- **Framework-aware route detection** across 17 frameworks (Django, Flask, FastAPI, Express, NestJS, Laravel, Rails, Spring, Gin, Axum, ASP.NET, React Router, SvelteKit, etc.) +- Symbol extraction: 22 NodeKinds (function, class, method, route, component, etc.) and 12 EdgeKinds (calls, imports, extends, implements, references, etc.) +- MCP server with `codegraph_explore` (single powerful tool) + 7 auxiliary tools +- Auto-sync file watcher using native OS events +- 100% local, no API keys needed +- CLI: `codegraph query`, `codegraph callers`, `codegraph callees`, `codegraph impact`, `codegraph files`, `codegraph context` + +**How it maps to Code2Lark**: +- **Already integrated**: Code2Lark's `structural-analysis.ts` already calls `codegraph status` and `codegraph query route` as an external backend +- **Route detection**: Directly replaces the regex-based `extractFastApiEndpoints()`, `extractNodeHttpEndpoints()`, and `extractDocumentedEndpoints()` with framework-aware, language-agnostic route extraction +- **Symbol extraction**: Provides function/class/method inventory that Code2Lark currently lacks entirely +- **Dependency graph**: `codegraph callers`/`callees`/`impact` provide dependency analysis Code2Lark doesn't have +- **Structured output**: JSON output from `--json` flag is already normalized in `structural-analysis.ts` + +**Cherry-pick targets**: +1. **Route detection logic**: Replace `src/commands/analyze.ts` regex-based endpoint extraction with `codegraph query route --kind route --json` results +2. **Symbol inventory**: Add `codegraph query` results to `StructuralFacts` for function/class/method listing +3. **Dependency analysis**: Use `codegraph callers`/`callees` for impact analysis in generated manifests +4. **Framework detection**: Leverage CodeGraph's 17-framework route recognition instead of string-matching `requirements.txt` + +**Risks**: +- Requires user-maintained codegraph installation and index (Code2Lark policy: never auto-install) +- Native Rust kernel requires Node 20-24 (Code2Lark already requires Node >=24.16) +- WASM fallback is 5-10x slower + +--- + +### 3.2 dependency-cruiser (sverweij/dependency-cruiser) — **TIER 1: DEPENDENCY GRAPH** + +**GitHub**: https://github.com/sverweij/dependency-cruiser +**License**: MIT +**Observed status during research**: mature public repository with broad npm usage + +**What it provides**: +- Full dependency graph extraction for JS/TS/CoffeeScript/Vue/Svelte +- Circular dependency detection +- Orphan detection (unused modules) +- Multiple output formats: JSON, DOT, Mermaid, D2, HTML, CSV +- **Programmatic API** (`cruise()` function) for embedding in Node.js tools +- Validation rules engine (configurable via `.dependency-cruiser.js`) +- TypeScript path alias resolution (`tsConfig` option) +- Webpack alias resolution + +**How it maps to Code2Lark**: +- **Dependency graph**: Fills the biggest gap in Code2Lark's current analysis — no module dependency tracking exists today +- **Programmatic API**: The `cruise()` function can be called directly from `analyze.ts` without shelling out +- **JSON output**: Structured dependency data can feed into `service_manifest.json` and `capability_map.json` +- **Orphan detection**: Identifies unused files/modules that shouldn't be exposed as capabilities +- **Circular dependency detection**: Safety check before generating adapter code + +**Cherry-pick targets**: +1. **Add `cruise()` call** in `collectStructuralFacts()` to produce a dependency graph alongside route facts +2. **Extend `StructuralFacts`** with a `dependencies` field containing module graph data +3. **Use orphan detection** to filter out non-entrypoint files from capability mapping +4. **Generate dependency visualizations** (Mermaid) in analysis reports + +**Integration example**: +```typescript +import { cruise } from "dependency-cruiser"; + +const result = await cruise(["src"], { + outputType: "json", + includeOnly: "^src", + tsConfig: "./tsconfig.json", +}); +// result.output contains the full dependency graph +``` + +--- + +### 3.3 ast-grep (ast-grep/ast-grep) — **TIER 2: STRUCTURAL SEARCH** + +**GitHub**: https://github.com/ast-grep/ast-grep +**License**: MIT +**Observed status during research**: active public repository with broad language support + +**What it provides**: +- Structural code search using code-as-pattern syntax +- 20+ language support via tree-sitter +- **Node.js binding** with jQuery-like API for AST traversal +- YAML-based rule system for linting +- CLI with `--json` output +- Pattern-based code rewriting + +**How it maps to Code2Lark**: +- **Route pattern matching**: Can find route registrations structurally (e.g., `@app.$METHOD("$PATH")`) instead of regex +- **Framework detection**: Structural patterns for detecting Express (`app.$METHOD()`), Flask (`@app.route()`), etc. +- **Secret scanning enhancement**: Structural patterns for `$API_KEY = "$VALUE"` assignments +- **Node.js API**: Can be embedded as a library, not just CLI + +**Cherry-pick targets**: +1. **Replace regex endpoint extraction** with ast-grep structural patterns for more accurate route detection +2. **Enhance secret scanning** with structural patterns that catch more variants +3. **Framework fingerprinting**: Use structural patterns to identify framework usage beyond string matching + +**Limitations**: +- Requires Rust binary installation (or npx) +- Pattern syntax has learning curve +- Not a full knowledge graph — search-focused, not relationship-focused + +--- + +### 3.4 Repomix (yamadashy/repomix) — **TIER 2: CONTEXT PREPARATION** + +**GitHub**: https://github.com/yamadashy/repomix +**License**: MIT +**Observed status during research**: active public repository with strong visibility + +**What it provides**: +- Packs entire repositories into AI-friendly XML/Markdown/JSON/plain text +- Tree-sitter code compression (~70% token reduction while preserving structure) +- Token counting per file and total +- MCP server with `pack_codebase` and `pack_remote_repository` tools +- Git-aware filtering (.gitignore, .repomixignore) +- Secretlint integration for security +- Remote repository packing (no manual clone needed) + +**How it maps to Code2Lark**: +- **Skill-first workflow**: Repomix's MCP server and explorer skill are exactly the pattern Code2Lark wants to follow +- **Context preparation**: Before analysis, pack the target repo for AI consumption +- **Compression**: Tree-sitter compression extracts code signatures — useful for generating capability summaries +- **Remote analysis**: `pack_remote_repository` could enable analyzing targets without local clones + +**Cherry-pick targets**: +1. **Adopt the MCP skill pattern**: Repomix's `repomix-explorer` skill architecture is a reference for Code2Lark's future skill +2. **Use compression for summaries**: Tree-sitter compressed output as input to capability mapping +3. **Token counting**: Add token estimates to analysis reports for LLM context planning + +--- + +### 3.5 ts-morph (dsherret/ts-morph) — **TIER 2: DEEP TYPESCRIPT ANALYSIS** + +**GitHub**: https://github.com/dsherret/ts-morph +**License**: MIT +**Observed status during research**: mature public repository with broad TypeScript ecosystem usage + +**What it provides**: +- Full TypeScript Compiler API wrapper with ergonomic helper methods +- Symbol extraction: classes, interfaces, functions, methods, properties, enums, type aliases +- Import/export analysis +- Type information and call signature resolution +- JSDoc extraction +- In-memory file manipulation (no disk writes until `.save()`) +- Programmatic code generation from structures + +**How it maps to Code2Lark**: +- **TypeScript target analysis**: For TypeScript targets, ts-morph provides the deepest possible analysis +- **Symbol extraction**: Get all exported functions, classes, interfaces with full type signatures +- **JSDoc extraction**: Extract documentation from code for capability descriptions +- **Import graph**: Track which modules import what for dependency analysis + +**Cherry-pick targets**: +1. **TypeScript-specific analyzer strategy**: Add a `ts_api` analyzer that uses ts-morph for deep TS project understanding +2. **Symbol-to-capability mapping**: Use exported function signatures to auto-generate capability input/output schemas +3. **JSDoc → capability descriptions**: Extract documentation as capability descriptions + +**Limitations**: +- TypeScript/JavaScript only (not polyglot like tree-sitter-based tools) +- Heavier dependency (~1.4MB unpacked) +- Requires tsconfig.json for proper resolution + +--- + +### 3.6 madge (pahen/madge) — **TIER 3: LIGHTWEIGHT DEPENDENCY GRAPH** + +**GitHub**: https://github.com/pahen/madge +**License**: MIT +**Observed status during research**: mature public repository +**Observed status during research**: mature public repository with broad npm usage + +**What it provides**: +- Simple module dependency graph generation +- Circular dependency detection +- Orphan and leaf detection +- DOT/SVG/Image output +- Programmatic API: `.obj()`, `.depends()`, `.circular()`, `.orphans()`, `.leaves()` + +**How it maps to Code2Lark**: +- Lighter alternative to dependency-cruiser for simple dependency graphs +- `.depends(id)` for impact analysis +- `.circular()` for safety checks + +**Limitations**: +- Less actively maintained (last release Aug 2024) +- Fewer features than dependency-cruiser (no validation rules, fewer output formats) +- 124 open issues + +--- + +### 3.7 Other Candidates (TIER 3: Niche/Experimental) + +| Candidate | Notes | +|---|---| +| **codelens** (frostorygon) | 13 MCP tools, call chains, dead code, cycle detection. Very new during research with low public visibility. Interesting call chain tracing but too immature. | +| **Arbok** (takuto-san) | SQLite index, MCP server, memory bank generation. Interesting concept but smaller community. | +| **Ariadne** (CRJFisher) | Scope graph approach, multi-language. Early-stage and low-signal during research. | +| **mcp-codebase-intelligence** (g-tiwari) | 18 tools, 8 languages, LSP hybrid. Ambitious but still low-signal during research. | +| **Specter-Tree** (DinoQuinten) | ts-morph based, TypeScript-only. Too narrow and immature for Code2Lark's current needs. | +| **hermes-code-intel-plugin** (rewasa) | tree-sitter + ast-grep + LSP hybrid. Interesting architecture but low-signal during research and tied to Hermes Agent. | + +--- + +## 4. Ranked Recommendations + +### Tier 1: Strongly Recommended (adopt now) + +| Rank | Project | Rationale | Effort | +|---|---|---|---| +| **1** | **CodeGraph** | Already integrated; framework-aware routes; 20+ languages; MCP native; replaces most of internal scanner | Low (enhance existing integration) | +| **2** | **dependency-cruiser** | Fills the dependency graph gap; mature ecosystem usage; programmatic API; JSON output | Medium (new integration) | + +### Tier 2: Recommended (adopt selectively) + +| Rank | Project | Rationale | Effort | +|---|---|---|---| +| **3** | **ast-grep** | Structural search for route/framework detection; Node.js binding; replaces fragile regex | Medium | +| **4** | **ts-morph** | Deep TypeScript analysis for TS targets; JSDoc extraction; type-aware capability mapping | Medium-High | +| **5** | **Repomix** | Reference architecture for skill-first pattern; compression for summaries; MCP skill template | Low (pattern reference) | + +### Tier 3: Watch / Niche Use + +| Rank | Project | Rationale | +|---|---|---| +| **6** | **madge** | Lighter dependency-cruiser alternative; less maintained | +| **7** | **codelens** | Interesting call chain tracing; too immature | +| **8** | **Arbok** | Memory bank concept; small community | + +--- + +## 5. Recommended Architecture: Skill-First Project Understanding Layer + +Based on this research, the recommended architecture for Code2Lark's future project understanding layer: + +``` +┌─────────────────────────────────────────────────────────┐ +│ Code2Lark Skill (Future) │ +│ Orchestrates: understand → clarify → design → deliver │ +└─────────────────────┬───────────────────────────────────┘ + │ +┌─────────────────────▼───────────────────────────────────┐ +│ Project Understanding Layer (NEW) │ +│ │ +│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ +│ │ CodeGraph │ │ dep-cruiser │ │ ast-grep │ │ +│ │ (routes, │ │ (dependency │ │ (structural │ │ +│ │ symbols, │ │ graph, │ │ patterns, │ │ +│ │ call graph) │ │ orphans) │ │ framework │ │ +│ └──────┬───────┘ └──────┬───────┘ │ detection) │ │ +│ │ │ └──────┬───────┘ │ +│ └─────────┬───────┘ │ │ +│ │ │ │ +│ ┌─────────▼──────────────────────────▼───────┐ │ +│ │ Structured Facts (JSON) │ │ +│ │ - entrypoints, routes, commands │ │ +│ │ - dependencies, call graph │ │ +│ │ - side-effect labels, risk levels │ │ +│ │ - required env, candidate operations │ │ +│ │ - clarification questions │ │ +│ └────────────────────┬────────────────────────┘ │ +└──────────────────────────────┼────────────────────────────┘ + │ +┌──────────────────────────────▼────────────────────────────┐ +│ Code2Lark Core (existing) │ +│ Business mapping → Lark card/workflow design → │ +│ Safety policy → Mode A/B delivery → Install/verify/handoff │ +└───────────────────────────────────────────────────────────┘ +``` + +### Key Design Principles + +1. **External tools produce structured facts** — CodeGraph, dependency-cruiser, and ast-grep each produce JSON output that gets normalized into a unified `StructuralFacts` schema +2. **Code2Lark owns business mapping** — The core differentiator remains converting project capabilities into safe, operable, auditable Lark workflows +3. **Graceful degradation** — Each external tool is optional; the system works with any subset (like the current `--backend auto|internal|codegraph` pattern) +4. **MCP-native** — All three Tier 1/2 tools support or are compatible with MCP, aligning with Code2Lark's skill-first direction + +--- + +## 6. Next-Step Plan + +### Phase 1: Enhance CodeGraph Integration (Week 1-2) + +1. **Extend `StructuralFacts`** to include symbol inventory and dependency data from CodeGraph +2. **Add `codegraph query`** call for symbol extraction (functions, classes, methods) +3. **Add `codegraph callers`/`callees`** for impact analysis in generated manifests +4. **Leverage framework-aware routes**: Map CodeGraph's 17-framework route detection into `StructuralRouteFact[]` +5. **Update `structural-analysis.ts`** to normalize the richer CodeGraph output + +### Phase 2: Add Dependency Graph (Week 2-3) + +1. **Add `dependency-cruiser`** as an optional dependency (or `npx` invocation) +2. **Extend `StructuralFacts`** with `dependencies: DependencyGraph` field +3. **Add dependency visualization** (Mermaid) to analysis reports +4. **Use orphan detection** to filter non-entrypoint files from capability mapping +5. **Add circular dependency check** as a safety gate + +### Phase 3: Structural Pattern Enhancement (Week 3-4) + +1. **Add ast-grep patterns** for framework detection (Express, Flask, FastAPI, etc.) +2. **Replace regex-based endpoint extraction** with ast-grep structural patterns +3. **Enhance secret scanning** with structural patterns + +### Phase 4: TypeScript Deep Analysis (Week 4+) + +1. **Add ts-morph-based analyzer** for TypeScript projects +2. **Extract JSDoc** for capability descriptions +3. **Use type information** for auto-generating input/output schemas + +### Phase 5: Skill-First Architecture (Ongoing) + +1. **Study Repomix's skill pattern** as reference architecture +2. **Design Code2Lark skill** that orchestrates: CodeGraph → dependency-cruiser → ast-grep → business mapping → Lark workflow +3. **Implement MCP server** for Code2Lark's project understanding layer + +--- + +## 7. License Summary + +All Tier 1 and Tier 2 candidates are **MIT licensed**, making them safe for cherry-picking, forking, and adaptation: + +| Project | License | Commercial Use | Modification | Distribution | +|---|---|---|---|---| +| CodeGraph | MIT | ✅ | ✅ | ✅ | +| dependency-cruiser | MIT | ✅ | ✅ | ✅ | +| ast-grep | MIT | ✅ | ✅ | ✅ | +| ts-morph | MIT | ✅ | ✅ | ✅ | +| Repomix | MIT | ✅ | ✅ | ✅ | +| madge | MIT | ✅ | ✅ | ✅ | + +--- + +## 8. Key Insights + +1. **CodeGraph is the clear winner** for route/symbol extraction — it's already integrated, has the broadest language support, and provides framework-aware route detection that directly replaces Code2Lark's fragile regex-based approach. + +2. **dependency-cruiser fills the biggest gap** — Code2Lark has zero dependency graph capability today. Adding it would enable impact analysis, orphan detection, and circular dependency checks. + +3. **The MCP ecosystem is converging** — CodeGraph, Repomix, codelens, Arbok, and mcp-codebase-intelligence all expose MCP servers. This aligns perfectly with Code2Lark's skill-first direction. + +4. **Don't rebuild generic analysis** — The AGENT.md guidance is correct. CodeGraph + dependency-cruiser + ast-grep cover 90%+ of what Code2Lark's internal scanner does, with better accuracy and broader language support. + +5. **Keep Code2Lark's core differentiator** — Business mapping, Lark card/workflow design, safety policy, and Mode A/B delivery remain Code2Lark's unique value. External tools should feed structured facts into this pipeline, not replace it. + +--- + +*Report generated by THE LIBRARIAN research agent. All findings based on public GitHub repositories, documentation, and web research as of July 2026.* diff --git a/docs/research/source-level-cherry-pick-analysis.md b/docs/research/source-level-cherry-pick-analysis.md new file mode 100644 index 0000000..175feda --- /dev/null +++ b/docs/research/source-level-cherry-pick-analysis.md @@ -0,0 +1,103 @@ +# Code2Lark Source-Level Cherry-Pick Analysis + +**Date**: 2026-07-22 +**Scope**: Source-level inspection from temporary local shallow clones; clone snapshots are intentionally not retained in this branch +**Goal**: Decide which OSS implementation ideas are worth adapting into Code2Lark's project-understanding layer. + +## Cloned Repositories + +| Repository | Retention | Checked commit | Why inspected | +|---|---|---:|---| +| `colbymchenry/codegraph` | Not retained; avoid vendoring full engine | `ea72e1b` | Strongest match for symbol graph, framework route extraction, MCP/agent workflow, and local indexing model. | +| `sverweij/dependency-cruiser` | Not retained; integrate as dependency/adapter later | `26dffc0` | Mature JS/TS dependency graph and rule-validation engine with a documented programmatic API. | +| `ast-grep/ast-grep` | Not retained; integrate rules/adapter later | `6dc0f31` | Structural AST pattern matching for route/framework/secret fingerprints without fragile text regex. | +| `dsherret/ts-morph` | Not retained; integrate as dependency/adapter later | `699815f` | Deep TypeScript Compiler API wrapper for exported symbols, signatures, JSDoc, and type-aware analysis. | + +## Executive Decision Table + +| Priority | Candidate | Source-level finding | Cherry-pick target for Code2Lark | Integration style | Decision | +|---:|---|---|---|---|---| +| 1 | CodeGraph | `src/index.ts` exposes a `CodeGraph` facade over extraction, SQLite queries, reference resolution, graph traversal, context building, and MCP serving. `src/types.ts` defines normalized `NodeKind`/`EdgeKind`, including `route`, `component`, `calls`, `imports`, and `references`. `src/resolution/frameworks/*` contains many framework-specific route resolvers. | Adopt its normalized graph vocabulary and route-node model; expand the current `--backend codegraph` path from route-only to symbol/impact facts where available. | Optional external backend first; do not vendor the engine. Use CLI/JSON or library API only when user-maintained index exists. | **Use first.** This is the best source for graph shape and framework route behavior. | +| 2 | dependency-cruiser | `src/main/index.mjs` exports `cruise()` and `format()`. `types/dependency-cruiser.d.mts` documents `cruise(files, options, resolveOptions, transpileOptions): Promise`. Output includes module dependencies and can be formatted as JSON/Mermaid/DOT. | Add JS/TS dependency graph enrichment: modules, dependency edges, circular deps, orphan modules, affected test hints. | Add as optional npm dependency or invoke via installed package; start with JSON API for JS/TS targets. | **Use second.** Fills Code2Lark's dependency-graph gap with low implementation risk. | +| 3 | ast-grep | NAPI layer exposes `parse`, `parseAsync`, `SgNode.find`, `findAll`, node traversal, and typed rule objects. Core is tree-sitter-based structural matching, not full graph construction. | Replace fragile regex fingerprints with structural rules for common route declarations, config/env assignments, and framework markers. | Prefer CLI/JSON or `@ast-grep/napi` for narrowly-scoped rules; do not build a general graph on top of it. | **Use selectively.** Best as a rule engine, not as the main analyzer. | +| 4 | ts-morph | Monorepo package wraps TypeScript Compiler API. Tests show APIs for `Project`, `SourceFile`, references, imports, exports, declarations, `SyntaxKind`, and AST traversal. | Build a TypeScript-only deep analyzer for exported handlers/functions, JSDoc-derived capability descriptions, parameter schemas, and import references. | Optional TS-specific plugin strategy, gated behind detected `tsconfig.json`. | **Use selectively.** Strong for TS targets, but not polyglot enough to lead. | + +## Detailed Cherry-Pick Plan + +### 1. CodeGraph: Normalize Code2Lark's structural facts around graph primitives + +| Source area inspected | Useful idea | Code2Lark adaptation | +|---|---|---| +| `src/types.ts` | Stable node and edge vocabulary: `file`, `module`, `function`, `method`, `route`, `component`; `calls`, `imports`, `references`, etc. | Extend Code2Lark's `StructuralFacts` to carry a generic `nodes[]` and `edges[]` shape instead of endpoint-only facts. | +| `src/index.ts` | Public facade wires extraction, resolution, graph traversal, and context building behind a small API. | Keep Code2Lark's analyzer backend interface small: `status`, `routes`, `symbols`, `impact`, `dependencies`. Avoid leaking backend internals into product logic. | +| `src/resolution/frameworks/*` | Framework route extraction is handled as route nodes plus references to handlers. | Model Lark-exposable capabilities as `route/command -> handler -> side effect` chains instead of isolated endpoints. | +| MCP/agent guidance | One high-signal tool is preferred over many narrow tools. | For the future Code2Lark skill, expose a small guided workflow instead of many low-level commands. | + +**Do not cherry-pick by copying CodeGraph internals.** CodeGraph is a complete indexed engine with SQLite, Rust/native parsing, MCP lifecycle, and auto-sync. Code2Lark should consume it when present and borrow its data model, not vendor its engine. + +### 2. dependency-cruiser: Add a JS/TS module dependency layer + +| Source area inspected | Useful idea | Code2Lark adaptation | +|---|---|---| +| `src/main/index.mjs` | Public API is intentionally tiny: `cruise()` and `format()`. | Add an optional `dependencyCruiserAnalyzer` that returns JSON facts for JS/TS projects. | +| `types/dependency-cruiser.d.mts` | API accepts file/dir array plus cruise, resolve, and transpile options. | Call `cruise([rootOrSrc], { outputType: "json", includeOnly }, resolveOptions, transpileOptions)` and normalize the result. | +| `src/analyze/derive/*` | Existing derivations cover circular, reachable, dependents, folders, orphans, and metrics. | Use circular/orphan/dependent facts for risk labeling and capability pruning. | +| Report plugins | Mermaid/DOT outputs are available. | Optionally generate a dependency diagram in `analyze` reports, not in the runtime package. | + +Recommended first implementation: dependency graph only, no custom rule enforcement. Rules can come later after Code2Lark knows how graph facts affect generated Lark entrypoints. + +### 3. ast-grep: Replace brittle regexes with structural patterns + +| Source area inspected | Useful idea | Code2Lark adaptation | +|---|---|---| +| `crates/napi/types/sgnode.d.ts` | `SgNode.find()` and `findAll()` support pattern and rule matching. | Define small rule packs for Express/FastAPI/Nest/Flask/Next-style route declarations. | +| `crates/napi/types/rule.d.ts` | Rules support `pattern`, `kind`, `inside`, `has`, `precedes`, `follows`, `all`, `any`, `not`. | Express capability detection as declarative rules that are easier to test than hand-written regex. | +| `crates/core/src/tree_sitter/*` | Parser caching and injected-language handling are solved by ast-grep. | Use ast-grep only as an external/optional parser; avoid reimplementing parser cache logic. | +| CLI package | `@ast-grep/cli` distributes platform binaries through optional dependencies. | For MVP, prefer CLI invocation to avoid native binding friction in Code2Lark's package. | + +Recommended first implementation: create an `analysis-rules/` directory with 5-10 route/config patterns and golden fixtures. Do not attempt a full AST analyzer. + +### 4. ts-morph: TypeScript-only deep capability extraction + +| Source area inspected | Useful idea | Code2Lark adaptation | +|---|---|---| +| `packages/ts-morph` package surface | `Project` and `SourceFile` are the main API concepts. | Load target `tsconfig.json`, enumerate source files, and extract exported functions/classes. | +| SourceFile reference tests | APIs cover referenced/referencing source files and import/export declarations. | Map exported handlers to imports and likely call sites for impact/risk labels. | +| AST helper tests | `SyntaxKind`, descendant traversal, declaration helpers, and structure extraction are mature. | Extract parameter names/types/JSDoc to seed Lark form fields and capability descriptions. | + +Recommended first implementation: only enable for TypeScript targets with a usable `tsconfig.json`; otherwise fall back to CodeGraph/internal/ast-grep facts. + +## Proposed Code2Lark Analyzer Pipeline + +| Stage | Backend | Required? | Output | +|---|---|---:|---| +| File inventory | Existing internal scanner | Yes | Source files, skipped dirs, target metadata. | +| Route/symbol graph | CodeGraph, if initialized | Optional | Route nodes, handler references, symbol list, call/impact hints. | +| JS/TS dependency graph | dependency-cruiser | Optional | Module dependency edges, circular deps, orphans, affected tests. | +| Structural fingerprints | ast-grep CLI or NAPI | Optional | Route/config/framework/secret pattern hits with source locations. | +| TypeScript signatures | ts-morph | Optional | Exported function/class signatures, JSDoc, input/output hints. | +| Product mapping | Code2Lark-owned logic | Yes | Candidate Lark operations, risk labels, clarification questions, generation plan. | + +## Implementation Order + +| Step | Change | Why first/next | Acceptance signal | +|---:|---|---|---| +| 1 | Define a backend-neutral `StructuralGraphFacts` shape inspired by CodeGraph node/edge vocabulary. | Prevents every backend from leaking custom output into product logic. | Existing `analyze` tests still pass; route-only internal facts map into the new shape. | +| 2 | Expand current CodeGraph backend to include symbols and optional impact/call facts when CLI supports JSON for them. | Highest-value backend already partially integrated. | Calendar/image-agent analysis records richer facts without requiring CodeGraph installation. | +| 3 | Add dependency-cruiser as optional JS/TS dependency enrichment. | Dependency graph is a clear current gap and API is straightforward. | A TS/JS fixture reports module edges and circular/orphan summaries. | +| 4 | Add ast-grep rule pack for route/config fingerprints. | Improves precision of current regex scanner without replacing the analyzer. | Golden fixtures prove regex false positives are reduced. | +| 5 | Add ts-morph TS analyzer. | Useful for schema/JSDoc extraction, but only after the shared facts shape exists. | TS fixture produces parameter/type/JSDoc-derived capability hints. | + +## Risk Notes + +| Risk | Impact | Mitigation | +|---|---|---| +| Vendoring whole analyzers would bloat Code2Lark and duplicate mature tools. | High maintenance cost and packaging risk. | Prefer optional external adapters and normalized output. | +| CodeGraph requires a user-maintained index. | Backend may be unavailable in fresh targets. | Keep `auto` fallback; never run `init`/`sync` without explicit user permission. | +| dependency-cruiser is JS/TS-focused. | No help for Python/Go/etc. | Treat as enrichment, not universal analyzer. | +| ast-grep rule packs can become framework-specific maintenance burden. | Medium. | Keep rules small, fixture-driven, and capability-oriented. | +| ts-morph may need valid project config. | Type-aware extraction can fail on broken targets. | Gate behind tsconfig detection and return non-blocking warnings. | + +## Bottom Line + +The source-level inspection confirms the earlier ranking. CodeGraph should define the graph vocabulary and primary optional backend. dependency-cruiser should fill JS/TS dependency facts. ast-grep should replace brittle regexes for narrowly-scoped structural fingerprints. ts-morph should be a TypeScript-only enrichment layer for signatures and documentation. diff --git a/embedded-skills/lark-card-designer/SKILL.md b/embedded-skills/lark-card-designer/SKILL.md new file mode 100644 index 0000000..be128db --- /dev/null +++ b/embedded-skills/lark-card-designer/SKILL.md @@ -0,0 +1,180 @@ +--- +name: lark-card-designer +description: "Feishu/Lark card style and information-architecture designer for coding workflows. Use when an agent needs to design or review card structure, data presentation, key data, readability, components, atomic constraints, restrained visual/status rules, inline color, tags, typography, spacing, buttons, inputs, selects, forms, accepted/processing/final action states, clarification or duplicate-action feedback, non-production structure sketches, approvals, reports, product or sales cards, daily or weekly reports, operational analytics, governance or anomaly cards, retrospectives, digests, AI streaming, long-running task progress, real-client screenshots, preview comparisons, or CardKit-aware behavior. Guides design decisions, handoff, render review, and acceptance; does not send cards, call Feishu APIs, generate production JSON or field-level schemas, or modify implementation files." +--- + +# Lark Card Designer + +Act as a Feishu/Lark card designer. Decide the card style, key data, readability strategy, information hierarchy, component mix, atomic design constraints, visual/status language, interaction states, and validation checklist for a given data type, data intent, and output audience. + +Do not act as a sender, SDK, webhook wrapper, template marketplace, generic Markdown beautifier, implementation agent, or production JSON generator. Structure sketches are design handoff artifacts only; they may reference Feishu card JSON 2.0 concepts but must not become sendable schemas, callback contracts, or implementation patches. + +## Workflow + +1. Identify the input dimensions: + - data type: KPI, time series, table rows, Top-N, document/article, process object, alert/status, media/person/link, agent/permission + - intent: report, diagnose, decide, execute, warn, preserve knowledge, track progress + - audience: management, business operations, frontline execution, retrospective analysis, knowledge/news, technical reviewer + - constraints: interaction, approval, chart, table, mobile reading, multilingual, long content, source/audit/update time +2. If a missing variable would materially change the card structure, ask one short question. Otherwise infer the most likely audience and state the assumption. +3. Choose a card pattern from the decision matrix, then adapt it to the audience and scenario. +4. Select key data and readability controls before choosing decorative or secondary details. +5. Select components for clarity, not decoration. Prefer structured Feishu components for structured data. +6. Attach restrained visual/status rules. Default to Feishu/Lark native neutral styling. Use color only when it carries status, risk, priority, hierarchy, or action focus. +7. Add design constraints when the output will guide handoff or review. Keep them scoped to the components actually used. +8. Add interaction parameters only when the reader needs to decide, approve, select, input, refresh, filter, or give feedback. For long-running actions, separate accepted, processing, and terminal semantics; define visible duplicate-action feedback and side-effect boundaries. +9. Add streaming design only when progressive text, repeated component updates, or long-running task state has reader value. +10. When screenshots, recordings, or real-client preview acceptance are requested, review the rendered evidence and keep observed issues separate from inferred risks. The implementation owner performs rendering and delivery. +11. Output a Markdown explanation followed by a stable structured decision block. +12. Finish with design red lines and a validation checklist. + +## Reference Routing + +- For pattern selection, read [decision-matrix.md](references/decision-matrix.md). +- For audience differences, read [audience-portfolios.md](references/audience-portfolios.md). +- For key data selection, first-screen priority, field folding, and readability controls by data type, read [key-data-readability-rules.md](references/key-data-readability-rules.md). +- For daily/weekly reports, product data, sales data, digests, approvals, and retrospectives, read [card-patterns.md](references/card-patterns.md). +- For operational analytics, daily operations, governance reminders, anomaly diagnosis, product group analysis, or sameSkuGroup analysis, read [operational-analytics-rules.md](references/operational-analytics-rules.md). +- For AI text streaming, long-running tasks, repeated component updates, progress states, or process-to-result transitions, read [streaming-card-rules.md](references/streaming-card-rules.md). +- For table, chart, button, form, image, collapsible, note, and footer choices, read [component-rules.md](references/component-rules.md). +- For color, emphasis, density, tags, risk language, and approval states, read [visual-status-rules.md](references/visual-status-rules.md). +- For design handoff constraints such as inline text color, tags, typography, spacing, table columns, button states, and fallback behavior, read [atomic-design-constraints.md](references/atomic-design-constraints.md). +- For button layout, input fields, select controls, form layout, validation states, accepted/processing/final states, clarification behavior, duplicate-action feedback, and post-action card states, read [interaction-parameters.md](references/interaction-parameters.md). +- For non-production structure sketch boundaries, Markdown rendering, table limits, interaction constraints, and CardKit concepts, read [rendering-constraints.md](references/rendering-constraints.md). +- For real Feishu/Lark client screenshots, desktop/mobile rendering, visual preview comparison, preview safety, or design acceptance, read [visual-preview-review-rules.md](references/visual-preview-review-rules.md). +- When a concrete sample is requested or the output shape is unclear, read [examples.md](references/examples.md). +- When design handoff needs a more concrete per-pattern structure sketch, read [pattern-structure-sketches.md](references/pattern-structure-sketches.md). +- When validating this skill's behavior or checking whether an output matches expected design decisions, read [evaluation-cases.md](references/evaluation-cases.md). +- When design evidence from GitHub projects is useful, read [github-project-lessons.md](references/github-project-lessons.md). + +Use the raw official documents in `docs/` only when exact Feishu/Lark field behavior is needed. Do not load `docs/` by default. + +## Default Output Shape + +Start with 2 to 5 sentences explaining the key design judgment and any assumptions. Then output this block: + +````markdown +**structured_decision** + +card_intent: +- data_type: +- intent: +- audience: +- assumptions: + +card_pattern: +- name: +- why: +- alternatives: + +information_architecture: +- first_screen: +- body: +- details: +- footer_or_note: + +key_data_rules: +- must_show: +- first_screen_priority: +- folded_or_linked: +- readability_controls: +- missing_data_questions: + +component_plan: +- header: +- content: +- data_display: +- interactions: +- metadata: + +visual_rules: +- color_policy: +- status_color: +- inline_text_color: +- emphasis: +- density: +- labels: + +design_constraints: +- typography: +- spacing: +- color_tokens: +- table_columns: +- tag_variants: +- button_states: +- responsive_behavior: + +interaction_rules: +- primary_action: +- secondary_actions: +- button_layout: +- input_parameters: +- select_parameters: +- form_layout: +- acceptance_state: +- processing_state: +- terminal_states: +- duplicate_action_feedback: +- side_effect_boundary: +- safe_to_leave: +- audit_or_feedback: + +structure_sketch: +```json +{ + "note": "Design handoff sketch only, not production-sendable Feishu JSON.", + "schema": "json_2_0_like", + "config": {}, + "header": {}, + "elements": [] +} +``` + +design_red_lines: +- scenario_specific_failure_modes: + +validation_checklist: +- [ ] first screen states the point +- [ ] required key data for this data type is visible +- [ ] operational analytics cards define the primary subject, reader first question, confidence, priority order, and supported next step when relevant +- [ ] relative-position or contribution claims show the denominator/scope and use a valid comparison grain +- [ ] key numbers include period, unit, and baseline when needed +- [ ] component choice matches the data shape +- [ ] tables are bounded or folded +- [ ] any used status colors carry semantic meaning +- [ ] inline text color is omitted unless local semantic emphasis is needed +- [ ] actions, button layout, and disabled/accepted/processing/final states are clear +- [ ] long-running actions separate accepted from completed, define truthful processing only when needed, and include complete terminal or needs-input states +- [ ] repeated actions receive a visible stable state, and clarification selections are not described as already executed +- [ ] side-effect boundaries and whether the reader may leave are clear when relevant +- [ ] streaming cards use one primary streaming region, explicit exception states, and a stable final-result pattern when relevant +- [ ] input/select/form controls have labels, defaults, validation, and empty/error states when used +- [ ] source, period, owner, or audit fields are present when needed +- [ ] mobile reading density is acceptable +- [ ] real-client preview evidence is requested when rendering-dependent risk cannot be resolved from a structure sketch +```` + +For real-client preview planning or review, append the conditional `preview_review` block from [visual-preview-review-rules.md](references/visual-preview-review-rules.md). Do not include it for every low-risk card. If no real render is available, label the result as pre-render design review rather than visual acceptance. + +For review of an existing card, lead with design red lines, risks, and improvement directions, then include the structured decision block only if a revised design direction is needed. + +## Design Red Lines + +- Do not put full raw details on the first screen. +- Do not use a table as the default home for every number. +- Do not sacrifice "Information Order" or "Context Integrity" for "Simplicity". If data is too wide for mobile, pivot to vertical stacking instead of deleting columns. +- Do not use emojis in Agent, technical, or professional approval contexts. +- Do not use color as decoration without semantic status. +- Do not use color just because a color field exists in the output shape. +- Do not use more than one dominant color family unless the data contains multiple independent statuses that must be compared. +- Do not color full paragraphs when a tag, key number, or short status phrase would carry the emphasis better. +- Do not hide the required action behind long explanation. +- Do not describe an accepted click, selection, or submission as business success. +- Do not leave repeated clicks silent or create duplicate progress transitions. +- Do not leave an accepted or processing action without a terminal or needs-input state. +- Do not label aggregate-window comparisons as a continuous time trend. +- Do not expose raw tool logs or hidden reasoning as streaming progress. +- Do not claim visual acceptance from JSON, source code, or a structure sketch without real-client render evidence. +- Do not include real Feishu/Lark IDs, credentials, webhook URLs, recipient identifiers, or production callback actions in preview-review artifacts. +- Do not omit period, unit, source, owner, or audit fields when the data depends on them. +- Do not output complete production JSON, field-level schemas, API calls, callback handlers, auth logic, or implementation patches as this skill's main product. diff --git a/embedded-skills/lark-card-designer/adapters/claude-code.md b/embedded-skills/lark-card-designer/adapters/claude-code.md new file mode 100644 index 0000000..76b3602 --- /dev/null +++ b/embedded-skills/lark-card-designer/adapters/claude-code.md @@ -0,0 +1,5 @@ +# Claude Code Adapter + +This is a thin entry point. Use the core skill in `../SKILL.md` and load references from `../references/` as directed there. + +Invoke this skill when a task involves Feishu/Lark card design, information architecture, component choice, visual/status rules, interaction states, or review of an existing card. Do not duplicate or fork the core rules in this adapter. diff --git a/embedded-skills/lark-card-designer/adapters/opencode.md b/embedded-skills/lark-card-designer/adapters/opencode.md new file mode 100644 index 0000000..cabd6e2 --- /dev/null +++ b/embedded-skills/lark-card-designer/adapters/opencode.md @@ -0,0 +1,5 @@ +# OpenCode Adapter + +This is a thin entry point. Use the core skill in `../SKILL.md` and load references from `../references/` as directed there. + +Invoke this skill when a task involves Feishu/Lark card design, information architecture, component choice, visual/status rules, interaction states, or review of an existing card. Do not duplicate or fork the core rules in this adapter. diff --git a/embedded-skills/lark-card-designer/agents/openai.yaml b/embedded-skills/lark-card-designer/agents/openai.yaml new file mode 100644 index 0000000..5f81192 --- /dev/null +++ b/embedded-skills/lark-card-designer/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Lark Card Designer" + short_description: "Feishu/Lark card design and review" + default_prompt: "Use $lark-card-designer to design or review a Feishu/Lark card for this data or rendered preview, including key data selection, readability, card pattern, operational analytics, streaming and real-client preview rules when relevant, components, design constraints, accepted/processing/final action states, duplicate-action feedback, visual status, and a non-production structure sketch." diff --git a/embedded-skills/lark-card-designer/docs/INDEX.md b/embedded-skills/lark-card-designer/docs/INDEX.md new file mode 100644 index 0000000..276d56b --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/INDEX.md @@ -0,0 +1,248 @@ +# Feishu/Lark Card Documentation + +Generated at: 2026-06-30 14:14:06 +08:00 + +Downloaded documents: 118 + +These files are raw Markdown copies from Feishu Open Platform documentation. Use manifest.json for source URLs and fetch status. + +## Documents + +- [局部更新卡片实体](raw/cardkit-v1__card__batch_update.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card/batch_update.md +- [创建卡片实体](raw/cardkit-v1__card__create.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card/create.md +- [更新卡片配置](raw/cardkit-v1__card__settings.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card/settings.md +- [全量更新卡片实体](raw/cardkit-v1__card__update.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card/update.md +- [流式更新文本](raw/cardkit-v1__card-element__content.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/content.md +- [新增组件](raw/cardkit-v1__card-element__create.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/create.md +- [删除组件](raw/cardkit-v1__card-element__delete.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/delete.md +- [更新组件属性](raw/cardkit-v1__card-element__patch.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/patch.md +- [更新组件](raw/cardkit-v1__card-element__update.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/update.md +- [飞书卡片资源概述](raw/cardkit-v1__feishu-card-resource-overview.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/feishu-card-resource-overview.md +- [自定义机器人使用指南](raw/client-docs__bot-v3__add-custom-bot.md) + Source: https://open.feishu.cn/document/client-docs/bot-v3/add-custom-bot.md +- [消息卡片概述](raw/common-capabilities__message-card__introduction-of-message-cards.md) + Source: https://open.feishu.cn/document/common-capabilities/message-card/introduction-of-message-cards.md +- [卡片搭建说明](raw/develop-a-card-interactive-bot__card-building-steps.md) + Source: https://open.feishu.cn/document/uAjLw4CM/uMzNwEjLzcDMx4yM3ATM/develop-a-card-interactive-bot/card-building-steps.md +- [示例代码解释](raw/develop-a-card-interactive-bot__explanation-of-example-code.md) + Source: https://open.feishu.cn/document/uAjLw4CM/uMzNwEjLzcDMx4yM3ATM/develop-a-card-interactive-bot/explanation-of-example-code.md +- [应用配置说明](raw/develop-a-card-interactive-bot__faqs.md) + Source: https://open.feishu.cn/document/uAjLw4CM/uMzNwEjLzcDMx4yM3ATM/develop-a-card-interactive-bot/faqs.md +- [三分钟快速开发](raw/develop-a-card-interactive-bot__introduction.md) + Source: https://open.feishu.cn/document/uAjLw4CM/uMzNwEjLzcDMx4yM3ATM/develop-a-card-interactive-bot/introduction.md +- [链接预览开发指南](raw/development-link-preview__link-preview-development-guide.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/development-link-preview/link-preview-development-guide.md +- [拉取链接预览数据](raw/development-link-preview__pull-link-preview-data-callback-structure.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/development-link-preview/pull-link-preview-data-callback-structure.md +- [快速入门](raw/development-link-preview__quick-start.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/development-link-preview/quick-start.md +- [典型案例](raw/development-link-preview__typical-case.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/development-link-preview/typical-case.md +- [卡片回传交互回调](raw/feishu-cards__card-callback-communication.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication.md +- [卡片 JSON 1.0 版本组件概述](raw/feishu-cards__card-components__component-overview.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/component-overview.md +- [折叠面板](raw/feishu-cards__card-components__containers__collapsible-panel.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/collapsible-panel.md +- [分栏组件](raw/feishu-cards__card-components__containers__column-set.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/column-set.md +- [表单容器](raw/feishu-cards__card-components__containers__form-container.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/form-container.md +- [交互容器](raw/feishu-cards__card-components__containers__interactive-container.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/interactive-container.md +- [循环容器](raw/feishu-cards__card-components__containers__recycling-container.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/recycling-container.md +- [图表组件](raw/feishu-cards__card-components__content-components__chart.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/chart.md +- [分割线组件](raw/feishu-cards__card-components__content-components__divider.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/divider.md +- [图片组件](raw/feishu-cards__card-components__content-components__image.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/image.md +- [多图混排组件](raw/feishu-cards__card-components__content-components__multi-image-laylout.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/multi-image-laylout.md +- [备注组件](raw/feishu-cards__card-components__content-components__note.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/note.md +- [普通文本组件](raw/feishu-cards__card-components__content-components__plain-text.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/plain-text.md +- [富文本组件](raw/feishu-cards__card-components__content-components__rich-text.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/rich-text.md +- [表格组件](raw/feishu-cards__card-components__content-components__table.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/table.md +- [标题组件](raw/feishu-cards__card-components__content-components__title.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/title.md +- [人员列表组件](raw/feishu-cards__card-components__content-components__user-list.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/user-list.md +- [人员组件](raw/feishu-cards__card-components__content-components__user-profile.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/user-profile.md +- [按钮组件](raw/feishu-cards__card-components__interactive-components__button.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/button.md +- [勾选器组件](raw/feishu-cards__card-components__interactive-components__checker.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/checker.md +- [日期选择器组件](raw/feishu-cards__card-components__interactive-components__date-picker.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/date-picker.md +- [日期时间选择器组件](raw/feishu-cards__card-components__interactive-components__date-time-picker.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/date-time-picker.md +- [多图选择组件](raw/feishu-cards__card-components__interactive-components__image-picker.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/image-picker.md +- [输入框组件](raw/feishu-cards__card-components__interactive-components__input.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/input.md +- [下拉选择-多选组件](raw/feishu-cards__card-components__interactive-components__multi-select-dropdown-menu.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/multi-select-dropdown-menu.md +- [人员选择-多选组件](raw/feishu-cards__card-components__interactive-components__multi-select-user-picker.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/multi-select-user-picker.md +- [折叠按钮组组件](raw/feishu-cards__card-components__interactive-components__overflow.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/overflow.md +- [下拉选择-单选组件](raw/feishu-cards__card-components__interactive-components__single-select-dropdown-menu.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/single-select-dropdown-menu.md +- [人员选择-单选组件](raw/feishu-cards__card-components__interactive-components__single-select-user-picker.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/single-select-user-picker.md +- [时间选择器组件](raw/feishu-cards__card-components__interactive-components__time-selector.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/time-selector.md +- [卡片 JSON 1.0 结构](raw/feishu-cards__card-json-structure.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-structure.md +- [卡片 JSON 2.0 版本更新说明](raw/feishu-cards__card-json-v2-breaking-changes-release-notes.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-breaking-changes-release-notes.md +- [卡片 JSON 2.0 版本组件概述](raw/feishu-cards__card-json-v2-components__component-json-v2-overview.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/component-json-v2-overview.md +- [折叠面板](raw/feishu-cards__card-json-v2-components__containers__collapsible-panel.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/containers/collapsible-panel.md +- [分栏组件](raw/feishu-cards__card-json-v2-components__containers__column-set.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/containers/column-set.md +- [表单容器](raw/feishu-cards__card-json-v2-components__containers__form-container.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/containers/form-container.md +- [交互容器](raw/feishu-cards__card-json-v2-components__containers__interactive-container.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/containers/interactive-container.md +- [音频](raw/feishu-cards__card-json-v2-components__content-components__audio.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/audio.md +- [图表组件](raw/feishu-cards__card-json-v2-components__content-components__chart.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/chart.md +- [分割线组件](raw/feishu-cards__card-json-v2-components__content-components__divider.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/divider.md +- [图片组件](raw/feishu-cards__card-json-v2-components__content-components__image.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/image.md +- [多图混排组件](raw/feishu-cards__card-json-v2-components__content-components__multi-image-laylout.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/multi-image-laylout.md +- [普通文本组件](raw/feishu-cards__card-json-v2-components__content-components__plain-text.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/plain-text.md +- [富文本组件](raw/feishu-cards__card-json-v2-components__content-components__rich-text.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/rich-text.md +- [表格组件](raw/feishu-cards__card-json-v2-components__content-components__table.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/table.md +- [标题组件](raw/feishu-cards__card-json-v2-components__content-components__title.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/title.md +- [人员列表组件](raw/feishu-cards__card-json-v2-components__content-components__user-list.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/user-list.md +- [人员组件](raw/feishu-cards__card-json-v2-components__content-components__user-profile.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/user-profile.md +- [按钮组件](raw/feishu-cards__card-json-v2-components__interactive-components__button.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/button.md +- [勾选器组件](raw/feishu-cards__card-json-v2-components__interactive-components__checker.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/checker.md +- [日期选择器组件](raw/feishu-cards__card-json-v2-components__interactive-components__date-picker.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/date-picker.md +- [日期时间选择器组件](raw/feishu-cards__card-json-v2-components__interactive-components__date-time-picker.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/date-time-picker.md +- [多图选择组件](raw/feishu-cards__card-json-v2-components__interactive-components__image-picker.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/image-picker.md +- [输入框组件](raw/feishu-cards__card-json-v2-components__interactive-components__input.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/input.md +- [下拉选择-多选组件](raw/feishu-cards__card-json-v2-components__interactive-components__multi-select-dropdown-menu.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/multi-select-dropdown-menu.md +- [人员选择-多选组件](raw/feishu-cards__card-json-v2-components__interactive-components__multi-select-user-picker.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/multi-select-user-picker.md +- [折叠按钮组组件](raw/feishu-cards__card-json-v2-components__interactive-components__overflow.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/overflow.md +- [下拉选择-单选组件](raw/feishu-cards__card-json-v2-components__interactive-components__single-select-dropdown-menu.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/single-select-dropdown-menu.md +- [人员选择-单选组件](raw/feishu-cards__card-json-v2-components__interactive-components__single-select-user-picker.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/single-select-user-picker.md +- [时间选择器组件](raw/feishu-cards__card-json-v2-components__interactive-components__time-selector.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/time-selector.md +- [卡片 JSON 2.0 结构](raw/feishu-cards__card-json-v2-structure.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure.md +- [配置卡片多语言](raw/feishu-cards__configure-multi-language-content.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/configure-multi-language-content.md +- [卡片 JSON 中配置卡片交互](raw/feishu-cards__configuring-card-interactions.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/configuring-card-interactions.md +- [颜色枚举值](raw/feishu-cards__enumerations-for-fields-related-to-color.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color.md +- [图标库](raw/feishu-cards__enumerations-for-icons.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-icons.md +- [添加自定义交互事件](raw/feishu-cards__feishu-card-cardkit__add-interactive-events.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/add-interactive-events.md +- [构建卡片内容](raw/feishu-cards__feishu-card-cardkit__build-card-content.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/build-card-content.md +- [搭建工具新版卡片说明](raw/feishu-cards__feishu-card-cardkit__cardkit-upgraded-version-card-release-notes.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/cardkit-upgraded-version-card-release-notes.md +- [按钮](raw/feishu-cards__feishu-card-cardkit__components__button.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/components/button.md +- [图表](raw/feishu-cards__feishu-card-cardkit__components__chart.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/components/chart.md +- [图片](raw/feishu-cards__feishu-card-cardkit__components__image.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/components/image.md +- [富文本](raw/feishu-cards__feishu-card-cardkit__components__markdown.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/components/markdown.md +- [表格](raw/feishu-cards__feishu-card-cardkit__components__table.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/components/table.md +- [配置卡片多语言](raw/feishu-cards__feishu-card-cardkit__configure-card-languages.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/configure-card-languages.md +- [配置卡片变量](raw/feishu-cards__feishu-card-cardkit__configure-card-variables.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/configure-card-variables.md +- [飞书卡片搭建工具概述](raw/feishu-cards__feishu-card-cardkit__feishu-cardkit-overview.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/feishu-cardkit-overview.md +- [为卡片分组](raw/feishu-cards__feishu-card-cardkit__group-cards.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/group-cards.md +- [导入导出卡片](raw/feishu-cards__feishu-card-cardkit__import-and-export-cards.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/import-and-export-cards.md +- [管理卡片权限](raw/feishu-cards__feishu-card-cardkit__manage-card-template.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/manage-card-template.md +- [预览与发布卡片](raw/feishu-cards__feishu-card-cardkit__preview-and-publish-cards.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/preview-and-publish-cards.md +- [飞书卡片概述](raw/feishu-cards__feishu-card-overview.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-overview.md +- [飞书卡片更新说明](raw/feishu-cards__feishu-card-release-notes.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-release-notes.md +- [处理卡片回调](raw/feishu-cards__handle-card-callbacks.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/handle-card-callbacks.md +- [使用指定应用发送飞书卡片](raw/feishu-cards__quick-start__send-feishu-cards-with-app-bots.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/quick-start/send-feishu-cards-with-app-bots.md +- [使用自定义机器人发送飞书卡片](raw/feishu-cards__quick-start__send-message-cards-with-custom-bot.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/quick-start/send-message-cards-with-custom-bot.md +- [发送卡片方式](raw/feishu-cards__send-feishu-card.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/send-feishu-card.md +- [流式更新卡片](raw/feishu-cards__streaming-updates-openapi-overview.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/streaming-updates-openapi-overview.md +- [更新卡片](raw/feishu-cards__update-feishu-card.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/update-feishu-card.md +- [发送消息内容结构](raw/im-v1__message__create_json.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/im-v1/message/create_json.md +- [上传文件](raw/reference__im-v1__file__create.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/file/create.md +- [上传图片](raw/reference__im-v1__image__create.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create.md +- [发送消息](raw/reference__im-v1__message__create.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/create.md +- [撤回消息](raw/reference__im-v1__message__delete.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/delete.md +- [更新已发送的消息卡片](raw/reference__im-v1__message__patch.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/patch.md +- [回复消息](raw/reference__im-v1__message__reply.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/reply.md +- [编辑消息](raw/reference__im-v1__message__update.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/update.md +- [表情文案说明](raw/reference__im-v1__message-reaction__emojis-introduce.md) + Source: https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message-reaction/emojis-introduce.md +- [发送消息](raw/server-docs__im-v1__message__create.md) + Source: https://open.feishu.cn/document/server-docs/im-v1/message/create.md + +## Failed Or Missing diff --git a/embedded-skills/lark-card-designer/docs/github-research.md b/embedded-skills/lark-card-designer/docs/github-research.md new file mode 100644 index 0000000..6ca38a3 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/github-research.md @@ -0,0 +1,383 @@ +# GitHub 飞书卡片项目调研 + +更新日期:2026-06-30 + +本文汇总前期提到的飞书/Lark 卡片相关 GitHub 仓库,用来支撑 `lark-card-designer` 的 skill 设计。 + +`lark-card-designer` 的定位不是直接生成最终卡片,也不是再做一个 SDK。它应该根据数据类型、数据意图和输出口径,给出稳定的卡片样式决策、信息架构、组件建议、视觉规则和 JSON 骨架示意,让下游实现者或卡片生成器少漂移。 + +## 调研方法 + +- 优先读取公开 GitHub 仓库元信息、README、子目录 `SKILL.md`。 +- 对无法读取 README 或 README 信息很少的仓库,标记为低信号,不把仓库名推断成事实。 +- 将项目价值转译为设计证据:它解决了什么场景、使用了什么卡片结构、如何处理状态/表格/长内容/交互,以及哪些规则可迁移到本 skill。 + +## 全局结论 + +现有 GitHub 项目大多不是“卡片设计规范”,而是围绕某个固定场景做卡片实现,主要落在八类: + +1. 格式化规范:约束 Markdown、标题、表格、折叠面板,保证飞书渲染稳定。 +2. 组件构建器:把 button、table、column、div、image 等组件封装成代码 API。 +3. 原生表格渲染:把 Markdown 表格或结构化 rows 转换成飞书 native table。 +4. 流式进度卡片:把 AI 输出、工具调用、任务状态持续 patch 到同一张卡片。 +5. 操作台/审批卡片:用选择器、按钮、锁定态、历史记录承载流程操作。 +6. 资讯/日报聚合:按优先级、分类、摘要、来源和反馈按钮组织信息集合。 +7. 通知/告警适配器:把外部事件映射到短标题、状态色、少量字段和动作链接。 +8. 轻量发送工具:只解决 webhook、签名、发送 envelope,不解决信息设计。 + +对本项目最关键的启发是:不要把“请生成一个清晰的飞书卡片”当作主要产物。要把决策拆成矩阵和检查表:数据类型 -> 意图 -> 口径 -> 卡片模式 -> 信息层级 -> 组件选择 -> 视觉状态 -> 约束校验。 + +## 仓库全量索引 + +| 仓库 | 信号 | 项目类型 | 可迁移设计支撑 | 主要限制 | +| --- | --- | --- | --- | --- | +| [alva-intelligence/agent-skills/lark-card-formatting](https://github.com/alva-intelligence/agent-skills/tree/main/lark/skills/lark-card-formatting) | 高 | 卡片格式化 skill | 明确 Markdown 渲染规则、表格限制、折叠面板伪语法、渐进加载 references。适合转化为 `rendering-rules` 参考。 | 重点是“如何写可渲染内容”,不是“根据意图选择卡片样式”。 | +| [baileyh8/hermes-feishu-streaming-card](https://github.com/baileyh8/hermes-feishu-streaming-card) | 高 | AI 流式交互卡片 | 单卡持续更新、thinking/tool/final 分区、状态 header、footer 统计、长内容与表格保护。适合支撑“过程态卡片”和“AI 结果卡片”。 | 深度绑定 Hermes 流式事件,不适合直接作为业务报表规范。 | +| [ppaibb/FeishuCardOps](https://github.com/ppaibb/FeishuCardOps) | 高 | 发版操作台/审批流程 | 项目/分支/环境选择、按钮锁定、主卡/副卡、进度追踪、审计群同步、审批人提示。适合审批、流程、执行口径。 | CI/CD 场景很强,报表和资讯类不应照搬它的操作密度。 | +| [ritaswc/lark-card-message-builder](https://github.com/ritaswc/lark-card-message-builder) | 中高 | PHP 卡片组件构建器 | 展示单列表单、按钮、列权重表格、小字号布局等组件封装方式。适合支撑组件词表和表格布局规则。 | 只提供构建 API,不做意图判断。 | +| [CatchZeng/feishu](https://github.com/CatchZeng/feishu) | 中 | Go webhook/机器人消息库 | 覆盖 text、post、image、share_chat、interactive,包含签名和链式写法。适合支撑发送 envelope 与基础消息类型边界。 | 不关注卡片视觉质量。 | +| [AllanChain/grafana-feishu](https://github.com/AllanChain/grafana-feishu) | 中 | Grafana 告警转卡片 | 外部事件 -> 卡片标题/描述/状态色的最小映射。适合告警、异常、红绿状态模型。 | 结构极简,无法覆盖复杂分析卡。 | +| [henryjing96/feishu-codex-bridge](https://github.com/henryjing96/feishu-codex-bridge) | 高 | Codex 远程桥接/流式卡片 | 占位卡、patch 更新、工具进度、权限模式、图片输入、多用户审批。适合支撑“等待中/执行中/需要确认/完成”的状态语义。 | 卡片风格服务于远程操作,不是通用商业数据展示。 | +| [ai-eifying/hermes-feishu-card](https://github.com/ai-eifying/hermes-feishu-card) | 中高 | Hermes 回复卡片化 | 把所有回复包进交互卡片,自动将 Markdown 表格转换为 native table,失败回退文本。适合表格转换和兜底策略。 | 主要是 final answer 包装。 | +| [ISQIShI/feishu_messaging_card_builder](https://github.com/ISQIShI/feishu_messaging_card_builder) | 高 | Hermes 最终回复卡片补丁 | 最终回复卡片化、正文预处理、上下文/进度 footer、长回复拆分、失败回退、标题栏取舍。适合长内容和汇报类卡片。 | 面向特定运行时,不是完整设计系统。 | +| [shareAI-lab/lark-channel](https://github.com/shareAI-lab/lark-channel) | 高 | Lark 群聊到 Claude Code agent | 群 = 独立 workspace,流式文本卡、工具卡、持久会话。适合“多轮任务上下文”和“会话态卡片”设计。 | 偏 agent runtime,不提供业务数据卡片规则。 | +| [arkseek/hermes-feishu](https://github.com/arkseek/hermes-feishu) | 高 | Hermes 飞书表格增强 | 明确指出飞书 post markdown 不支持 pipe table,提供 card table 工具和结构化 table 工具。适合强规则:结构化数据优先 native table。 | 重点是表格渲染,不含视觉分层规范。 | +| [maidou0215/hermes-feishu-card-progress-plugin](https://github.com/maidou0215/hermes-feishu-card-progress-plugin) | 高 | 工具执行进度卡片 | Running/Completed/Failed header、工具调用步骤、响应卡区别、运行统计 footer、表格溢出保护。适合进度卡和状态色规则。 | 针对 Hermes 工具调用。 | +| [Micar2024/hermes-feishu-interactive-cards](https://github.com/Micar2024/hermes-feishu-interactive-cards) | 中高 | Hermes 交互卡片插件 | initial card、tool progress、response text、按钮回调、撤回按钮等生命周期。适合可交互 AI 卡片状态机。 | README 偏安装和 runtime 架构。 | +| [theo-lee1/feishu-progress-card](https://github.com/theo-lee1/feishu-progress-card) | 中 | OpenClaw 多步进度卡 | 工具调用开始/结束/失败/心跳更新同一张卡。适合“任务进度”单卡 patch 模式。 | 场景单一,信息架构较少。 | +| [Matys1009/feishu_daily_news_card](https://github.com/Matys1009/feishu_daily_news_card) | 高 | 每日资讯互动卡片 | Excel 管理资讯,卡片含标题、摘要、图片、链接、点赞按钮和统计。适合文章/blog/资讯集合口径。 | 偏单条资讯/群发,不是复杂知识库整理。 | +| [leecyang/feishu-interactive-cards](https://github.com/leecyang/feishu-interactive-cards) | 低 | JS 交互卡片仓库 | 仓库可访问,但 README 未读取到,元信息也少。只能作为“存在同名交互卡片实现”的低信号样本。 | 不用于关键设计结论。 | +| [iwgyyyy/feishu-interactive-card](https://github.com/iwgyyyy/feishu-interactive-card) | 中 | OpenClaw 交互卡片 skill | buttons、forms、polls、confirmation card,强调不确定时用按钮让用户选择。适合一线执行和审批确认。 | 更像工具/模板集合,业务口径较少。 | +| [tenlywu/lark-push](https://github.com/tenlywu/lark-push) | 中高 | 交互卡片任务调度/管理服务 | 任务模型、收件人映射、callback、manual refresh、admin service。适合“周期推送卡片”和“刷新动作”规则。 | README 未展开具体卡片样式。 | +| [bellehe01/lark-daily-digest](https://github.com/bellehe01/lark-daily-digest) | 高 | 群消息每日摘要 | 聚合过去 24/72 小时群消息,按 Needs Attention/FYI 分类,结构化 DM 卡片。适合日报、周报、资讯 triage。 | 更偏个人效率,业务指标维度较少。 | +| [tagthai-actions/lark-notification-frontend](https://github.com/tagthai-actions/lark-notification-frontend) | 中 | GitHub Action 部署通知 | default/matrix 两种卡片模式,从 CSV 读取发布内容,发送部署摘要。适合“矩阵型部署/模块状态”卡片。 | 只覆盖部署通知。 | +| [DengMingXi777GZ/openclaw-feishu-InteractMeetingCard](https://github.com/DengMingXi777GZ/openclaw-feishu-InteractMeetingCard) | 中 | 会议邀请交互卡片 | 语音输入 -> 会议详情 -> 一键创建日程按钮 -> 群发送。适合“表单型信息 + 单一主动作”模式。 | 和数据展示关系弱。 | +| [Handsome-KK/Hermes-personal-stack](https://github.com/Handsome-KK/Hermes-personal-stack) | 高 | Hermes 个人 AI stack 与卡片渲染补丁 | 把 briefing 中的 Markdown 表格路由到 schema 2.0 native table,保留表格周围正文。适合报告/brief 卡片的正文与表格混排规则。 | 不是独立卡片库,证据来自其中一个补丁章节。 | +| [chareasy/LarkAPI](https://github.com/chareasy/LarkAPI) | 低 | Lark API 仓库 | README 只有极少信息,无法提炼卡片设计规则。 | 不用于关键设计结论。 | +| [kidari/feishu](https://github.com/kidari/feishu) | 低 | 飞书相关仓库 | 仓库可通过 git 访问,但未读取到 README。 | 不用于关键设计结论。 | +| [wr-rebirth/FeiShuMessageCard](https://github.com/wr-rebirth/FeiShuMessageCard) | 中 | Python 消息卡片模板封装 | 快速构建消息模板,表格仅支持 pandas DataFrame。适合“结构化数据输入应保留结构”的规则。 | README 信息较少,组件覆盖不详。 | +| [capediemmmm/feishu_2048_robot](https://github.com/capediemmmm/feishu_2048_robot) | 低 | 飞书消息 2048 小游戏 | 说明飞书消息也能承载游戏状态,但与当前业务卡片规范弱相关。 | 不纳入主要设计依据。 | +| [panda-xing/daily-push](https://github.com/panda-xing/daily-push) | 中高 | 自动化信息聚合推送 | GitHub Trending、NBA、澎湃新闻等多源信息聚合,支持飞书卡片推送。适合“信息源 -> 摘要 -> 推送”的知识口径。 | README 对卡片内部结构描述有限。 | +| [jackcheng321321/feishuproject-elt](https://github.com/jackcheng321321/feishuproject-elt) | 中 | 飞书项目 ETL/卡片通知 | 字段抽取、图片转 image_key、人员信息查询,并以消息卡片自定义通知。适合“项目字段/商品字段/图片字段预处理”规则。 | 更偏 ETL 和 API,卡片设计信息较少。 | +| [Guan-Yep/lark-industry-daily-report-skill](https://github.com/Guan-Yep/lark-industry-daily-report-skill) | 高 | 行业日报与推荐闭环 skill | 行业动态抓取、白板三列阅读、交互卡片、点赞/点踩反馈、偏好沉淀。适合知识/资讯口径和反馈闭环。 | 侧重资讯推荐,不覆盖销售/审批。 | +| [guanchunsheng/feishu-send-card](https://github.com/guanchunsheng/feishu-send-card) | 低中 | Go webhook 发卡脚本 | 使用群机器人 webhook、cardID/version 发送卡片。适合确认“模板卡片发送”边界。 | 不是设计规范。 | +| [benx-guo/github-trending](https://github.com/benx-guo/github-trending) | 中高 | GitHub Trending 到飞书/Bitable | 抓取榜单、写入 Bitable、通过 webhook 推交互卡片。适合榜单类、Top-N、外部链接和存档联动。 | README 未详细展示卡片层级。 | +| [clarklooking/feishu-push](https://github.com/clarklooking/feishu-push) | 中 | 机器人推送工具 | 支持文本、富文本、消息卡片,示例包含标题色。适合通知卡片的极简色彩规则。 | 只提供基础发送。 | +| [Coffee-Tang/feisms](https://github.com/Coffee-Tang/feisms) | 中 | Android 短信转飞书 | 短信用蓝色卡片,低电量告警用红色卡片。适合“普通通知 vs 风险告警”的状态色区分。 | 非业务数据展示。 | + +## 类型洞察 + +### 1. 格式化规范与组件构建器 + +代表项目: + +- `alva-intelligence/agent-skills/lark-card-formatting` +- `ritaswc/lark-card-message-builder` +- `wr-rebirth/FeiShuMessageCard` +- `CatchZeng/feishu` +- `clarklooking/feishu-push` +- `guanchunsheng/feishu-send-card` + +设计支撑: + +- skill 不应只给“审美建议”,要输出可执行的渲染规则,例如标题层级、空行、分隔、表格上限、图片/链接/按钮位置。 +- 组件词表要稳定:header、markdown/div、table、chart、column_set、note、button、select、input、collapsible panel。 +- 对小型通知卡,可以只使用标题、状态色、正文和一条动作链接;不要把它提升成复杂报告卡。 +- 对结构化 rows/columns,输入阶段就应保留字段结构,不要先压成自然语言再让后续重新解析。 + +### 2. 原生表格与长内容渲染 + +代表项目: + +- `arkseek/hermes-feishu` +- `ai-eifying/hermes-feishu-card` +- `ISQIShI/feishu_messaging_card_builder` +- `Handsome-KK/Hermes-personal-stack` +- `baileyh8/hermes-feishu-streaming-card` +- `maidou0215/hermes-feishu-card-progress-plugin` + +设计支撑: + +- Markdown pipe table 在飞书消息里不稳定,结构化表格应优先映射为 native table。 +- 表格不是所有数字的默认归宿。趋势、占比、漏斗、达成率更适合 chart 或 KPI + sparkline/简图。 +- 报告卡片应采用“结论先行 + 证据表格 + 次要明细折叠”的结构。 +- 长回复要拆分或折叠,但拆分不能重复标题、footer 和上下文说明。 +- footer/note 适合放来源、时间范围、数据更新时间、模型/工具统计、免责声明,不应抢正文层级。 + +### 3. 流式进度与任务状态 + +代表项目: + +- `baileyh8/hermes-feishu-streaming-card` +- `shareAI-lab/lark-channel` +- `henryjing96/feishu-codex-bridge` +- `maidou0215/hermes-feishu-card-progress-plugin` +- `Micar2024/hermes-feishu-interactive-cards` +- `theo-lee1/feishu-progress-card` + +设计支撑: + +- 过程卡片和结果卡片应该分型:过程卡强调状态、当前步骤、下一步;结果卡强调结论、证据、动作。 +- 同一任务用同一张卡片 patch 更新,比连续发多条消息更适合保留上下文。 +- 状态机应明确:queued、running、waiting_for_input、needs_approval、completed、failed、cancelled。 +- 卡片头部颜色要绑定状态,不要随意装饰。 +- 工具调用、审批等待、用户选择都适合放在可折叠或二级区域,避免干扰最终结论。 + +### 4. 操作台、审批与执行 + +代表项目: + +- `ppaibb/FeishuCardOps` +- `iwgyyyy/feishu-interactive-card` +- `DengMingXi777GZ/openclaw-feishu-InteractMeetingCard` +- `tagthai-actions/lark-notification-frontend` +- `tenlywu/lark-push` + +设计支撑: + +- 操作卡片不是报告卡片。它的第一目标是降低误操作:对象、范围、风险、确认动作必须清楚。 +- 涉及环境、项目、模块、负责人等变量时,优先用 select/input/form 容器,不要让用户在聊天里手打。 +- 破坏性动作要确认,运行中要锁定按钮,完成后要显示不可再次点击或已完成状态。 +- 审批卡片必须保留审计字段:申请人、审批人、时间、原因、影响范围、当前状态。 +- 矩阵型部署/模块状态适合 table 或 matrix layout;不要用一长串段落。 + +### 5. 日报、周报、资讯与知识集合 + +代表项目: + +- `bellehe01/lark-daily-digest` +- `Matys1009/feishu_daily_news_card` +- `Guan-Yep/lark-industry-daily-report-skill` +- `panda-xing/daily-push` +- `benx-guo/github-trending` + +设计支撑: + +- 信息集合类卡片的核心不是“把文章列表塞进去”,而是 triage:需要关注、可稍后看、仅存档。 +- 资讯卡应包含标题、摘要、来源、时间、链接,可选图片和反馈按钮。 +- Top-N 榜单适合用排名、标签、短摘要和跳转链接,不适合大段全文。 +- 个性化/推荐类卡片需要反馈入口,例如点赞、点踩、不感兴趣、稍后读。 +- 日报/周报应该先给整体判断,再给重点变化、风险、行动项和可折叠明细。 + +### 6. 告警、通知与轻量推送 + +代表项目: + +- `AllanChain/grafana-feishu` +- `Coffee-Tang/feisms` +- `clarklooking/feishu-push` +- `CatchZeng/feishu` +- `tagthai-actions/lark-notification-frontend` + +设计支撑: + +- 告警/通知卡片应短:状态、对象、原因、影响、动作链接。 +- 红色用于失败、紧急、风险;绿色用于成功、恢复、健康;蓝色用于一般信息;橙/黄色用于待处理或警告;灰色用于历史/次要。 +- 通知类不要追求完整分析,完整分析应通过链接、折叠面板或后续详情卡承载。 + +### 7. 字段预处理与数据接入 + +代表项目: + +- `jackcheng321321/feishuproject-elt` +- `wr-rebirth/FeiShuMessageCard` +- `benx-guo/github-trending` +- `Matys1009/feishu_daily_news_card` + +设计支撑: + +- 卡片样式决策前要识别数据形态:标量 KPI、时间序列、明细表、Top-N、富媒体、人员、审批流、外部链接。 +- 图片类字段要先转成飞书可用 image_key;人员字段要尽量转成可读名称或 mention。 +- Excel/CSV/Bitable/项目字段这类来源通常天然结构化,应保留字段名、类型、单位和排序规则。 + +## 对输出口径的映射 + +用户已确认优先支持 1、2、3、4、6 五类输出口径。结合调研,建议这样落地: + +| 输出口径 | 目标读者 | 首屏重点 | 适合借鉴的项目 | 推荐卡片模式 | +| --- | --- | --- | --- | --- | +| 1. 管理层口径 | 决策者、负责人 | 结论、风险、异常、关键 KPI、是否需要决策 | `bellehe01/lark-daily-digest`, `AllanChain/grafana-feishu`, `ISQIShI/feishu_messaging_card_builder` | Executive summary card:一屏结论 + KPI + 风险 + 行动建议,细节折叠 | +| 2. 业务运营口径 | 运营、项目 owner | 达成率、趋势、异常归因、待办 | `ppaibb/FeishuCardOps`, `tagthai-actions/lark-notification-frontend`, `benx-guo/github-trending` | Ops dashboard card:KPI + Top-N + 表格/矩阵 + 刷新/查看详情 | +| 3. 一线执行口径 | 执行人、审批人、值班人 | 当前要做什么、对象是谁、截止时间、按钮 | `ppaibb/FeishuCardOps`, `iwgyyyy/feishu-interactive-card`, `DengMingXi777GZ/openclaw-feishu-InteractMeetingCard` | Action card:对象 + 说明 + 风险 + 主按钮/次按钮 + 状态锁定 | +| 4. 复盘分析口径 | 分析师、项目复盘者 | 结论、证据、对比、原因、改进动作 | `Handsome-KK/Hermes-personal-stack`, `arkseek/hermes-feishu`, `maidou0215/hermes-feishu-card-progress-plugin` | Analysis card:结论先行 + 对比/趋势 + 证据表 + 原因与 action | +| 6. 知识/资讯口径 | 阅读者、研究者、团队成员 | 重要性、主题分类、摘要、来源、是否需跟进 | `Guan-Yep/lark-industry-daily-report-skill`, `Matys1009/feishu_daily_news_card`, `panda-xing/daily-push` | Digest card:分类列表 + 摘要 + 来源 + 标签 + 反馈按钮 | + +## 对用户场景的设计支撑 + +### 日报/周报 + +推荐结构: + +1. Header:日期范围 + 状态色,状态由整体健康度/风险决定。 +2. 首屏:3 到 5 个关键结论,不超过一屏。 +3. KPI 区:完成率、环比/同比、异常数量、待处理数量。 +4. 重点变化:Top gains、Top drops、风险事项。 +5. 行动项:owner、截止时间、下一步。 +6. 明细:放入折叠面板或 native table。 + +调研支撑: + +- `bellehe01/lark-daily-digest` 的 Needs Attention/FYI 分类适合日报 triage。 +- `ISQIShI/feishu_messaging_card_builder` 的长回复拆分和 footer 适合周报。 +- `arkseek/hermes-feishu` 与 `Handsome-KK/Hermes-personal-stack` 支撑 native table 规则。 + +### 商品数据 + +推荐结构: + +1. Header:商品/类目/店铺 + 数据周期。 +2. KPI:销售额、销量、库存、转化率、毛利、退款率。 +3. 异常标签:缺货、滞销、高退货、价格异常。 +4. Top-N:贡献最高/下降最快商品。 +5. 商品明细:native table,字段含 SKU、价格、库存、销量、转化、状态。 +6. 图片:只在需要识别商品时使用缩略图,不要让图片挤占核心指标。 + +调研支撑: + +- `jackcheng321321/feishuproject-elt` 提醒图片、人员、字段预处理很重要。 +- `wr-rebirth/FeiShuMessageCard` 的 DataFrame 输入说明结构化数据不应丢失。 +- `ritaswc/lark-card-message-builder` 的列权重表格适合 SKU 明细。 + +### 销售数据 + +推荐结构: + +1. Header:周期 + 区域/团队 + 状态。 +2. 管理层:目标达成率、预测缺口、关键风险。 +3. 运营层:渠道/区域/销售阶段拆解。 +4. 一线层:客户/商机/跟进行动。 +5. 分析层:同比、环比、漏斗、Top/bottom、原因假设。 +6. 明细:只展示影响最大的记录,其余折叠或链接到表格。 + +调研支撑: + +- `tagthai-actions/lark-notification-frontend` 的 matrix 思路适合多模块/多区域状态。 +- `AllanChain/grafana-feishu` 支撑状态色和异常优先。 +- `arkseek/hermes-feishu` 支撑结构化表格渲染。 + +### 前沿 blog / 文章收集汇总 + +推荐结构: + +1. Header:主题 + 日期 + 推荐级别。 +2. 分类:必读、可选、仅存档。 +3. 每条内容:标题、1 句摘要、来源、发布时间、标签、链接。 +4. 重点内容:可加 2 到 3 条“为什么重要”。 +5. 反馈:喜欢/不感兴趣/稍后读,用于长期偏好。 + +调研支撑: + +- `Guan-Yep/lark-industry-daily-report-skill` 支撑资讯抓取、反馈闭环和个性化沉淀。 +- `Matys1009/feishu_daily_news_card` 支撑图片、链接、点赞互动。 +- `panda-xing/daily-push` 与 `benx-guo/github-trending` 支撑榜单/热点类 Top-N 卡片。 + +### 审批卡片 + +推荐结构: + +1. Header:审批对象 + 当前状态。 +2. 申请信息:申请人、部门、时间、审批类型。 +3. 核心内容:要审批什么、金额/范围/影响。 +4. 风险与依据:为什么需要批、如果拒绝有什么影响。 +5. 动作区:同意、拒绝、退回修改、查看更多。 +6. 状态锁定:审批完成后按钮禁用或卡片更新为已处理。 +7. 审计:审批人、审批时间、操作记录。 + +调研支撑: + +- `ppaibb/FeishuCardOps` 的锁定态、审计同步和流程选择最有价值。 +- `iwgyyyy/feishu-interactive-card` 的确认卡适合审批确认。 +- `henryjing96/feishu-codex-bridge` 的多用户审批/RBAC 给权限边界提供参考。 + +### 复盘分析 + +推荐结构: + +1. Header:主题 + 结果状态。 +2. 结论:一句话判断。 +3. 事实:核心指标、时间线、对比基准。 +4. 分析:原因、影响范围、证据。 +5. 行动:改进项、owner、截止时间。 +6. 附录:原始数据、日志、详细表格折叠。 + +调研支撑: + +- `Handsome-KK/Hermes-personal-stack` 的正文 + native table 混排适合 evidence-first。 +- `maidou0215/hermes-feishu-card-progress-plugin` 的 footer 统计适合附加运行信息。 +- `ISQIShI/feishu_messaging_card_builder` 的去噪、回退和拆分适合长复盘。 + +## 组件选择规则草案 + +| 输入/意图 | 首选组件 | 何时使用 | 避免 | +| --- | --- | --- | --- | +| 单一结论 | header + markdown/div | 管理层摘要、告警、日报首屏 | 用表格承载一句话结论 | +| 多 KPI | columns / KPI blocks | 3 到 5 个关键指标 | 超过 6 个指标平铺 | +| 明细 rows/columns | native table | 商品、销售、项目、榜单、审批记录 | 大表直接放首屏 | +| 趋势 | chart | 时间序列、环比、同比 | 用多列表格堆时间点 | +| 占比/构成 | chart | 渠道、品类、状态分布 | 只给百分比文字 | +| Top-N | table 或 list | 榜单、异常、贡献排行 | 混入完整明细 | +| 次要证据 | collapsible panel | 日志、原始数据、工具过程、参考链接 | 首屏展开所有细节 | +| 用户决策 | button/action | 审批、确认、跳转、反馈 | 让用户复制文字回复 | +| 多参数选择 | select/input/form | 环境、项目、人员、日期范围 | 多个按钮拼成表单 | +| 来源与元数据 | note/footer | 数据更新时间、来源、模型、工具、限制 | 放在标题或正文开头 | + +## 状态色规则草案 + +| 状态 | 建议颜色 | 适用场景 | +| --- | --- | --- | +| 成功、恢复、健康、已完成、已批准 | 绿色 | 发布成功、告警恢复、审批通过、目标达成 | +| 失败、拒绝、严重风险、紧急告警 | 红色 | 部署失败、审批拒绝、销售目标严重缺口、库存断货 | +| 警告、待处理、需关注、临近风险 | 橙色/黄色 | 待审批、指标波动、低电量、库存预警 | +| 信息、分析中、执行中、普通通知 | 蓝色/青色 | 进度卡、普通短信转发、日报信息、AI 回复 | +| 历史、归档、禁用、次要说明 | 灰色 | 已关闭事项、附录、历史记录、无动作通知 | + +## Skill 结构建议 + +结合官方文档与 GitHub 调研,后续 `lark-card-designer` 可以采用以下 references: + +| 文件 | 作用 | +| --- | --- | +| `references/decision-matrix.md` | 数据类型 + 意图 + 输出口径 -> 卡片模式 | +| `references/audience-portfolios.md` | 管理层、业务运营、一线执行、复盘分析、知识资讯的不同信息密度和动作需求 | +| `references/card-patterns.md` | 日报周报、商品数据、销售数据、资讯汇总、审批卡片、复盘分析的固定结构 | +| `references/component-rules.md` | table、chart、button、select、collapsible、note、image 的选择规则 | +| `references/visual-status-rules.md` | 状态色、标题层级、标签、风险提示、强调规则 | +| `references/rendering-constraints.md` | 飞书 JSON 2.0、Markdown、表格、图片、交互回调等硬约束 | +| `references/github-project-lessons.md` | 本文压缩后的项目经验,可作为设计依据索引 | + +`SKILL.md` 本体应保持短,只放工作流: + +1. 识别数据类型:报告、明细、榜单、资讯、审批、任务、告警。 +2. 识别数据意图:汇报、诊断、通知、决策、执行、沉淀。 +3. 识别输出口径:管理层、业务运营、一线执行、复盘分析、知识资讯。 +4. 选择卡片模式。 +5. 输出信息架构和组件建议。 +6. 输出视觉/状态规则。 +7. 输出轻量 JSON 骨架示意。 +8. 用检查表校验可读性和飞书约束。 + +## 不建议复制的做法 + +- 不要把 prompt template 当主产物。用户已经指出提示词容易漂移,调研也说明稳定性来自矩阵、状态机、组件规则。 +- 不要做另一个卡片 SDK。已有大量 builder 和 sender,本项目应补“决策层”。 +- 不要把所有场景统一成一种布局。审批、日报、商品数据、资讯集合的首屏目标完全不同。 +- 不要把所有数字都做成表格。趋势、构成、目标差距和异常更适合图表/KPI/标签。 +- 不要在首屏放完整明细。首屏服务扫描,明细服务追溯。 +- 不要把状态色作为装饰色。颜色必须表达状态或优先级。 + +## 对 `lark-card-designer` 的核心设计命题 + +本 skill 应解决的是“选择什么卡片样式更合适”,不是“如何调用飞书 API 发出去”。 + +建议最终输出固定为: + +1. `card_intent`:数据意图和输出口径判断。 +2. `card_pattern`:推荐卡片模式。 +3. `information_architecture`:首屏、正文、明细、footer 的层级。 +4. `component_plan`:组件选择和原因。 +5. `visual_rules`:状态色、强调、标签、折叠规则。 +6. `interaction_rules`:按钮、审批、反馈、刷新、锁定态。 +7. `json_skeleton`:非完整实现,只展示结构骨架。 +8. `validation_checklist`:防止表格过大、首屏过载、状态不明、动作不清。 + +这样能把 GitHub 项目里的实践经验收敛成稳定、可复用、低漂移的设计规范。 diff --git a/embedded-skills/lark-card-designer/docs/manifest.json b/embedded-skills/lark-card-designer/docs/manifest.json new file mode 100644 index 0000000..d964c97 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/manifest.json @@ -0,0 +1,828 @@ +[ + { + "title": "消息卡片概述", + "url": "https://open.feishu.cn/document/common-capabilities/message-card/introduction-of-message-cards.md", + "file": "raw/common-capabilities__message-card__introduction-of-message-cards.md", + "depth": 0, + "status": "ok" + }, + { + "title": "自定义机器人使用指南", + "url": "https://open.feishu.cn/document/client-docs/bot-v3/add-custom-bot.md", + "file": "raw/client-docs__bot-v3__add-custom-bot.md", + "depth": 0, + "status": "ok" + }, + { + "title": "发送消息", + "url": "https://open.feishu.cn/document/server-docs/im-v1/message/create.md", + "file": "raw/server-docs__im-v1__message__create.md", + "depth": 0, + "status": "ok" + }, + { + "title": "发送消息内容结构", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/im-v1/message/create_json.md", + "file": "raw/im-v1__message__create_json.md", + "depth": 0, + "status": "ok" + }, + { + "title": "飞书卡片概述", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-overview.md", + "file": "raw/feishu-cards__feishu-card-overview.md", + "depth": 0, + "status": "ok" + }, + { + "title": "飞书卡片搭建工具概述", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/feishu-cardkit-overview.md", + "file": "raw/feishu-cards__feishu-card-cardkit__feishu-cardkit-overview.md", + "depth": 0, + "status": "ok" + }, + { + "title": "卡片 JSON 2.0 结构", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure.md", + "file": "raw/feishu-cards__card-json-v2-structure.md", + "depth": 0, + "status": "ok" + }, + { + "title": "卡片 JSON 1.0 结构", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-structure.md", + "file": "raw/feishu-cards__card-json-structure.md", + "depth": 0, + "status": "ok" + }, + { + "title": "卡片 JSON 2.0 版本组件概述", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/component-json-v2-overview.md", + "file": "raw/feishu-cards__card-json-v2-components__component-json-v2-overview.md", + "depth": 0, + "status": "ok" + }, + { + "title": "表格组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/table.md", + "file": "raw/feishu-cards__card-components__content-components__table.md", + "depth": 0, + "status": "ok" + }, + { + "title": "表格组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/table.md", + "file": "raw/feishu-cards__card-json-v2-components__content-components__table.md", + "depth": 0, + "status": "ok" + }, + { + "title": "图表组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/chart.md", + "file": "raw/feishu-cards__card-json-v2-components__content-components__chart.md", + "depth": 0, + "status": "ok" + }, + { + "title": "富文本组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/rich-text.md", + "file": "raw/feishu-cards__card-json-v2-components__content-components__rich-text.md", + "depth": 0, + "status": "ok" + }, + { + "title": "折叠面板", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/containers/collapsible-panel.md", + "file": "raw/feishu-cards__card-json-v2-components__containers__collapsible-panel.md", + "depth": 0, + "status": "ok" + }, + { + "title": "流式更新卡片", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/streaming-updates-openapi-overview.md", + "file": "raw/feishu-cards__streaming-updates-openapi-overview.md", + "depth": 0, + "status": "ok" + }, + { + "title": "发送卡片方式", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/send-feishu-card.md", + "file": "raw/feishu-cards__send-feishu-card.md", + "depth": 0, + "status": "ok" + }, + { + "title": "更新卡片", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/update-feishu-card.md", + "file": "raw/feishu-cards__update-feishu-card.md", + "depth": 0, + "status": "ok" + }, + { + "title": "卡片回传交互回调", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication.md", + "file": "raw/feishu-cards__card-callback-communication.md", + "depth": 0, + "status": "ok" + }, + { + "title": "处理卡片回调", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/handle-card-callbacks.md", + "file": "raw/feishu-cards__handle-card-callbacks.md", + "depth": 0, + "status": "ok" + }, + { + "title": "卡片 JSON 中配置卡片交互", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/configuring-card-interactions.md", + "file": "raw/feishu-cards__configuring-card-interactions.md", + "depth": 0, + "status": "ok" + }, + { + "title": "三分钟快速开发", + "url": "https://open.feishu.cn/document/uAjLw4CM/uMzNwEjLzcDMx4yM3ATM/develop-a-card-interactive-bot/introduction.md", + "file": "raw/develop-a-card-interactive-bot__introduction.md", + "depth": 0, + "status": "ok" + }, + { + "title": "飞书卡片资源概述", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/feishu-card-resource-overview.md", + "file": "raw/cardkit-v1__feishu-card-resource-overview.md", + "depth": 0, + "status": "ok" + }, + { + "title": "创建卡片实体", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card/create.md", + "file": "raw/cardkit-v1__card__create.md", + "depth": 0, + "status": "ok" + }, + { + "title": "更新卡片配置", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card/settings.md", + "file": "raw/cardkit-v1__card__settings.md", + "depth": 0, + "status": "ok" + }, + { + "title": "流式更新文本", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/content.md", + "file": "raw/cardkit-v1__card-element__content.md", + "depth": 0, + "status": "ok" + }, + { + "title": "颜色枚举值", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color.md", + "file": "raw/feishu-cards__enumerations-for-fields-related-to-color.md", + "depth": 0, + "status": "ok" + }, + { + "title": "图标库", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-icons.md", + "file": "raw/feishu-cards__enumerations-for-icons.md", + "depth": 0, + "status": "ok" + }, + { + "title": "上传图片", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create.md", + "file": "raw/reference__im-v1__image__create.md", + "depth": 0, + "status": "ok" + }, + { + "title": "上传文件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/file/create.md", + "file": "raw/reference__im-v1__file__create.md", + "depth": 0, + "status": "ok" + }, + { + "title": "表情文案说明", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message-reaction/emojis-introduce.md", + "file": "raw/reference__im-v1__message-reaction__emojis-introduce.md", + "depth": 0, + "status": "ok" + }, + { + "title": "飞书卡片更新说明", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-release-notes.md", + "file": "raw/feishu-cards__feishu-card-release-notes.md", + "depth": 1, + "status": "ok" + }, + { + "title": "使用自定义机器人发送飞书卡片", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/quick-start/send-message-cards-with-custom-bot.md", + "file": "raw/feishu-cards__quick-start__send-message-cards-with-custom-bot.md", + "depth": 1, + "status": "ok" + }, + { + "title": "撤回消息", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/delete.md", + "file": "raw/reference__im-v1__message__delete.md", + "depth": 1, + "status": "ok" + }, + { + "title": "发送消息", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/create.md", + "file": "raw/reference__im-v1__message__create.md", + "depth": 1, + "status": "ok" + }, + { + "title": "预览与发布卡片", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/preview-and-publish-cards.md", + "file": "raw/feishu-cards__feishu-card-cardkit__preview-and-publish-cards.md", + "depth": 1, + "status": "ok" + }, + { + "title": "管理卡片权限", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/manage-card-template.md", + "file": "raw/feishu-cards__feishu-card-cardkit__manage-card-template.md", + "depth": 1, + "status": "ok" + }, + { + "title": "图表组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/chart.md", + "file": "raw/feishu-cards__card-components__content-components__chart.md", + "depth": 1, + "status": "ok" + }, + { + "title": "卡片 JSON 2.0 版本更新说明", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-breaking-changes-release-notes.md", + "file": "raw/feishu-cards__card-json-v2-breaking-changes-release-notes.md", + "depth": 1, + "status": "ok" + }, + { + "title": "回复消息", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/reply.md", + "file": "raw/reference__im-v1__message__reply.md", + "depth": 1, + "status": "ok" + }, + { + "title": "编辑消息", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/update.md", + "file": "raw/reference__im-v1__message__update.md", + "depth": 1, + "status": "ok" + }, + { + "title": "富文本组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/rich-text.md", + "file": "raw/feishu-cards__card-components__content-components__rich-text.md", + "depth": 1, + "status": "ok" + }, + { + "title": "配置卡片变量", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/configure-card-variables.md", + "file": "raw/feishu-cards__feishu-card-cardkit__configure-card-variables.md", + "depth": 1, + "status": "ok" + }, + { + "title": "使用指定应用发送飞书卡片", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/quick-start/send-feishu-cards-with-app-bots.md", + "file": "raw/feishu-cards__quick-start__send-feishu-cards-with-app-bots.md", + "depth": 1, + "status": "ok" + }, + { + "title": "链接预览开发指南", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/development-link-preview/link-preview-development-guide.md", + "file": "raw/development-link-preview__link-preview-development-guide.md", + "depth": 1, + "status": "ok" + }, + { + "title": "按钮", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/components/button.md", + "file": "raw/feishu-cards__feishu-card-cardkit__components__button.md", + "depth": 1, + "status": "ok" + }, + { + "title": "搭建工具新版卡片说明", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/cardkit-upgraded-version-card-release-notes.md", + "file": "raw/feishu-cards__feishu-card-cardkit__cardkit-upgraded-version-card-release-notes.md", + "depth": 1, + "status": "ok" + }, + { + "title": "构建卡片内容", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/build-card-content.md", + "file": "raw/feishu-cards__feishu-card-cardkit__build-card-content.md", + "depth": 1, + "status": "ok" + }, + { + "title": "配置卡片多语言", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/configure-card-languages.md", + "file": "raw/feishu-cards__feishu-card-cardkit__configure-card-languages.md", + "depth": 1, + "status": "ok" + }, + { + "title": "富文本", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/components/markdown.md", + "file": "raw/feishu-cards__feishu-card-cardkit__components__markdown.md", + "depth": 1, + "status": "ok" + }, + { + "title": "添加自定义交互事件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/add-interactive-events.md", + "file": "raw/feishu-cards__feishu-card-cardkit__add-interactive-events.md", + "depth": 1, + "status": "ok" + }, + { + "title": "导入导出卡片", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/import-and-export-cards.md", + "file": "raw/feishu-cards__feishu-card-cardkit__import-and-export-cards.md", + "depth": 1, + "status": "ok" + }, + { + "title": "为卡片分组", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/group-cards.md", + "file": "raw/feishu-cards__feishu-card-cardkit__group-cards.md", + "depth": 1, + "status": "ok" + }, + { + "title": "配置卡片多语言", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/configure-multi-language-content.md", + "file": "raw/feishu-cards__configure-multi-language-content.md", + "depth": 1, + "status": "ok" + }, + { + "title": "标题组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/title.md", + "file": "raw/feishu-cards__card-json-v2-components__content-components__title.md", + "depth": 1, + "status": "ok" + }, + { + "title": "普通文本组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/plain-text.md", + "file": "raw/feishu-cards__card-json-v2-components__content-components__plain-text.md", + "depth": 1, + "status": "ok" + }, + { + "title": "标题组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/title.md", + "file": "raw/feishu-cards__card-components__content-components__title.md", + "depth": 1, + "status": "ok" + }, + { + "title": "卡片 JSON 1.0 版本组件概述", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/component-overview.md", + "file": "raw/feishu-cards__card-components__component-overview.md", + "depth": 1, + "status": "ok" + }, + { + "title": "普通文本组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/plain-text.md", + "file": "raw/feishu-cards__card-components__content-components__plain-text.md", + "depth": 1, + "status": "ok" + }, + { + "title": "分栏组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/containers/column-set.md", + "file": "raw/feishu-cards__card-json-v2-components__containers__column-set.md", + "depth": 1, + "status": "ok" + }, + { + "title": "循环容器", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/recycling-container.md", + "file": "raw/feishu-cards__card-components__containers__recycling-container.md", + "depth": 1, + "status": "ok" + }, + { + "title": "表单容器", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/containers/form-container.md", + "file": "raw/feishu-cards__card-json-v2-components__containers__form-container.md", + "depth": 1, + "status": "ok" + }, + { + "title": "交互容器", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/containers/interactive-container.md", + "file": "raw/feishu-cards__card-json-v2-components__containers__interactive-container.md", + "depth": 1, + "status": "ok" + }, + { + "title": "图片组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/image.md", + "file": "raw/feishu-cards__card-json-v2-components__content-components__image.md", + "depth": 1, + "status": "ok" + }, + { + "title": "多图混排组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/multi-image-laylout.md", + "file": "raw/feishu-cards__card-json-v2-components__content-components__multi-image-laylout.md", + "depth": 1, + "status": "ok" + }, + { + "title": "人员组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/user-profile.md", + "file": "raw/feishu-cards__card-json-v2-components__content-components__user-profile.md", + "depth": 1, + "status": "ok" + }, + { + "title": "人员列表组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/user-list.md", + "file": "raw/feishu-cards__card-json-v2-components__content-components__user-list.md", + "depth": 1, + "status": "ok" + }, + { + "title": "分割线组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/divider.md", + "file": "raw/feishu-cards__card-json-v2-components__content-components__divider.md", + "depth": 1, + "status": "ok" + }, + { + "title": "输入框组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/input.md", + "file": "raw/feishu-cards__card-json-v2-components__interactive-components__input.md", + "depth": 1, + "status": "ok" + }, + { + "title": "按钮组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/button.md", + "file": "raw/feishu-cards__card-json-v2-components__interactive-components__button.md", + "depth": 1, + "status": "ok" + }, + { + "title": "折叠按钮组组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/overflow.md", + "file": "raw/feishu-cards__card-json-v2-components__interactive-components__overflow.md", + "depth": 1, + "status": "ok" + }, + { + "title": "下拉选择-单选组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/single-select-dropdown-menu.md", + "file": "raw/feishu-cards__card-json-v2-components__interactive-components__single-select-dropdown-menu.md", + "depth": 1, + "status": "ok" + }, + { + "title": "下拉选择-多选组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/multi-select-dropdown-menu.md", + "file": "raw/feishu-cards__card-json-v2-components__interactive-components__multi-select-dropdown-menu.md", + "depth": 1, + "status": "ok" + }, + { + "title": "人员选择-单选组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/single-select-user-picker.md", + "file": "raw/feishu-cards__card-json-v2-components__interactive-components__single-select-user-picker.md", + "depth": 1, + "status": "ok" + }, + { + "title": "人员选择-多选组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/multi-select-user-picker.md", + "file": "raw/feishu-cards__card-json-v2-components__interactive-components__multi-select-user-picker.md", + "depth": 1, + "status": "ok" + }, + { + "title": "日期选择器组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/date-picker.md", + "file": "raw/feishu-cards__card-json-v2-components__interactive-components__date-picker.md", + "depth": 1, + "status": "ok" + }, + { + "title": "时间选择器组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/time-selector.md", + "file": "raw/feishu-cards__card-json-v2-components__interactive-components__time-selector.md", + "depth": 1, + "status": "ok" + }, + { + "title": "日期时间选择器组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/date-time-picker.md", + "file": "raw/feishu-cards__card-json-v2-components__interactive-components__date-time-picker.md", + "depth": 1, + "status": "ok" + }, + { + "title": "多图选择组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/image-picker.md", + "file": "raw/feishu-cards__card-json-v2-components__interactive-components__image-picker.md", + "depth": 1, + "status": "ok" + }, + { + "title": "勾选器组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/checker.md", + "file": "raw/feishu-cards__card-json-v2-components__interactive-components__checker.md", + "depth": 1, + "status": "ok" + }, + { + "title": "新增组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/create.md", + "file": "raw/cardkit-v1__card-element__create.md", + "depth": 1, + "status": "ok" + }, + { + "title": "音频", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/audio.md", + "file": "raw/feishu-cards__card-json-v2-components__content-components__audio.md", + "depth": 1, + "status": "ok" + }, + { + "title": "折叠面板", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/collapsible-panel.md", + "file": "raw/feishu-cards__card-components__containers__collapsible-panel.md", + "depth": 1, + "status": "ok" + }, + { + "title": "更新已发送的消息卡片", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/patch.md", + "file": "raw/reference__im-v1__message__patch.md", + "depth": 1, + "status": "ok" + }, + { + "title": "全量更新卡片实体", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card/update.md", + "file": "raw/cardkit-v1__card__update.md", + "depth": 1, + "status": "ok" + }, + { + "title": "局部更新卡片实体", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card/batch_update.md", + "file": "raw/cardkit-v1__card__batch_update.md", + "depth": 1, + "status": "ok" + }, + { + "title": "更新组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/update.md", + "file": "raw/cardkit-v1__card-element__update.md", + "depth": 1, + "status": "ok" + }, + { + "title": "更新组件属性", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/patch.md", + "file": "raw/cardkit-v1__card-element__patch.md", + "depth": 1, + "status": "ok" + }, + { + "title": "删除组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/delete.md", + "file": "raw/cardkit-v1__card-element__delete.md", + "depth": 1, + "status": "ok" + }, + { + "title": "示例代码解释", + "url": "https://open.feishu.cn/document/uAjLw4CM/uMzNwEjLzcDMx4yM3ATM/develop-a-card-interactive-bot/explanation-of-example-code.md", + "file": "raw/develop-a-card-interactive-bot__explanation-of-example-code.md", + "depth": 1, + "status": "ok" + }, + { + "title": "应用配置说明", + "url": "https://open.feishu.cn/document/uAjLw4CM/uMzNwEjLzcDMx4yM3ATM/develop-a-card-interactive-bot/faqs.md", + "file": "raw/develop-a-card-interactive-bot__faqs.md", + "depth": 1, + "status": "ok" + }, + { + "title": "卡片搭建说明", + "url": "https://open.feishu.cn/document/uAjLw4CM/uMzNwEjLzcDMx4yM3ATM/develop-a-card-interactive-bot/card-building-steps.md", + "file": "raw/develop-a-card-interactive-bot__card-building-steps.md", + "depth": 1, + "status": "ok" + }, + { + "title": "分栏组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/column-set.md", + "file": "raw/feishu-cards__card-components__containers__column-set.md", + "depth": 1, + "status": "ok" + }, + { + "title": "交互容器", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/interactive-container.md", + "file": "raw/feishu-cards__card-components__containers__interactive-container.md", + "depth": 1, + "status": "ok" + }, + { + "title": "表单容器", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/form-container.md", + "file": "raw/feishu-cards__card-components__containers__form-container.md", + "depth": 2, + "status": "ok" + }, + { + "title": "备注组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/note.md", + "file": "raw/feishu-cards__card-components__content-components__note.md", + "depth": 2, + "status": "ok" + }, + { + "title": "表格", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/components/table.md", + "file": "raw/feishu-cards__feishu-card-cardkit__components__table.md", + "depth": 2, + "status": "ok" + }, + { + "title": "图表", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/components/chart.md", + "file": "raw/feishu-cards__feishu-card-cardkit__components__chart.md", + "depth": 2, + "status": "ok" + }, + { + "title": "日期选择器组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/date-picker.md", + "file": "raw/feishu-cards__card-components__interactive-components__date-picker.md", + "depth": 2, + "status": "ok" + }, + { + "title": "时间选择器组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/time-selector.md", + "file": "raw/feishu-cards__card-components__interactive-components__time-selector.md", + "depth": 2, + "status": "ok" + }, + { + "title": "日期时间选择器组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/date-time-picker.md", + "file": "raw/feishu-cards__card-components__interactive-components__date-time-picker.md", + "depth": 2, + "status": "ok" + }, + { + "title": "折叠按钮组组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/overflow.md", + "file": "raw/feishu-cards__card-components__interactive-components__overflow.md", + "depth": 2, + "status": "ok" + }, + { + "title": "人员选择-单选组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/single-select-user-picker.md", + "file": "raw/feishu-cards__card-components__interactive-components__single-select-user-picker.md", + "depth": 2, + "status": "ok" + }, + { + "title": "人员选择-多选组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/multi-select-user-picker.md", + "file": "raw/feishu-cards__card-components__interactive-components__multi-select-user-picker.md", + "depth": 2, + "status": "ok" + }, + { + "title": "下拉选择-单选组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/single-select-dropdown-menu.md", + "file": "raw/feishu-cards__card-components__interactive-components__single-select-dropdown-menu.md", + "depth": 2, + "status": "ok" + }, + { + "title": "下拉选择-多选组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/multi-select-dropdown-menu.md", + "file": "raw/feishu-cards__card-components__interactive-components__multi-select-dropdown-menu.md", + "depth": 2, + "status": "ok" + }, + { + "title": "多图混排组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/multi-image-laylout.md", + "file": "raw/feishu-cards__card-components__content-components__multi-image-laylout.md", + "depth": 2, + "status": "ok" + }, + { + "title": "典型案例", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/development-link-preview/typical-case.md", + "file": "raw/development-link-preview__typical-case.md", + "depth": 2, + "status": "ok" + }, + { + "title": "拉取链接预览数据", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/development-link-preview/pull-link-preview-data-callback-structure.md", + "file": "raw/development-link-preview__pull-link-preview-data-callback-structure.md", + "depth": 2, + "status": "ok" + }, + { + "title": "快速入门", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/development-link-preview/quick-start.md", + "file": "raw/development-link-preview__quick-start.md", + "depth": 2, + "status": "ok" + }, + { + "title": "图片组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/image.md", + "file": "raw/feishu-cards__card-components__content-components__image.md", + "depth": 2, + "status": "ok" + }, + { + "title": "人员组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/user-profile.md", + "file": "raw/feishu-cards__card-components__content-components__user-profile.md", + "depth": 2, + "status": "ok" + }, + { + "title": "人员列表组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/user-list.md", + "file": "raw/feishu-cards__card-components__content-components__user-list.md", + "depth": 2, + "status": "ok" + }, + { + "title": "分割线组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/divider.md", + "file": "raw/feishu-cards__card-components__content-components__divider.md", + "depth": 2, + "status": "ok" + }, + { + "title": "输入框组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/input.md", + "file": "raw/feishu-cards__card-components__interactive-components__input.md", + "depth": 2, + "status": "ok" + }, + { + "title": "按钮组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/button.md", + "file": "raw/feishu-cards__card-components__interactive-components__button.md", + "depth": 2, + "status": "ok" + }, + { + "title": "多图选择组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/image-picker.md", + "file": "raw/feishu-cards__card-components__interactive-components__image-picker.md", + "depth": 2, + "status": "ok" + }, + { + "title": "勾选器组件", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/checker.md", + "file": "raw/feishu-cards__card-components__interactive-components__checker.md", + "depth": 2, + "status": "ok" + }, + { + "title": "图片", + "url": "https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/components/image.md", + "file": "raw/feishu-cards__feishu-card-cardkit__components__image.md", + "depth": 2, + "status": "ok" + } +] diff --git a/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card-element__content.md b/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card-element__content.md new file mode 100644 index 0000000..824586f --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card-element__content.md @@ -0,0 +1,102 @@ +# 流式更新文本 + +对卡片中的普通文本元素(tag 为 plain_text 的元素)或富文本组件(tag 为 markdown 的组件)传入全量文本内容,以实现“打字机”式的文字输出效果。 + +## 输出效果说明 + +若旧文本为传入的新文本的前缀子串,新增文本将在旧文本末尾继续以打字机效果输出;若新旧文本前缀不同,全量文本将直接上屏输出,无打字机效果。参考[流式更新卡片](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/streaming-updates-openapi-overview),了解流式更新文本的效果和完整流程。 + +## 使用限制 + +- 调用该接口时,不支持将卡片设置为独享卡片模式。即不支持将卡片 JSON 数据中的 `update_multi` 属性设置为 `false`。 +- 对于搭建工具中的卡片,仅支持对富文本组件中的内容进行流式更新,不支持对普通文本元素进行文本流式更新。 +- 调用该接口的应用身份(tenant_access_token)需与创建目标卡片实体的应用身份一致。 + +## 前提条件 + +调用该接口时,需确保已开启卡片的流式更新模式: +- 在卡片 JSON 中,将 `streaming_mode` 设为 `true` +- 或在卡片搭建工具中,在设置中开启流式更新模式: + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/6051c2a7d1df743858d11d2ae89d96a2_pTDWhbUysD.png?maxWidth=400) + +## 请求 + +基本 |   +---|--- +HTTP URL | https://open.feishu.cn/open-apis/cardkit/v1/cards/:card_id/elements/:element_id/content +HTTP Method | PUT +接口频率限制 | [1000 次/分钟、50 次/秒](https://open.feishu.cn/document/ukTMukTMukTM/uUzN04SN3QjL1cDN) +支持的应用类型 | Custom App、Store App +权限要求
**调用该 API 所需的权限。开启其中任意一项权限即可调用** | 创建与更新卡片(cardkit:card:write) + +### 请求头 + +名称 | 类型 | 必填 | 描述 +---|---|---|--- +Authorization | string | 是 | `tenant_access_token`
**值格式**:"Bearer `access_token`"
**示例值**:"Bearer t-7f1bcd13fc57d46bac21793a18e560"
[了解更多:如何选择与获取 access token](https://open.feishu.cn/document/uAjLw4CM/ugTN1YjL4UTN24CO1UjN/trouble-shooting/how-to-choose-which-type-of-token-to-use) +Content-Type | string | 是 | **固定值**:"application/json; charset=utf-8" + +### 路径参数 + +名称 | 类型 | 描述 +---|---|--- +card_id | string | 卡片实体 ID。通过[创建卡片实体](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card/create)获取
**示例值**:"7355439197428236291"
**数据校验规则**:
- 长度范围:`1` ~ `20` 字符 +element_id | string | 卡片实体中,普通文本元素或富文本组件的 ID。对应卡片 JSON 中的 `element_id` 属性或搭建工具中的组件 ID 属性,由开发者自定义。
**注意**:
- 仅支持[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)或卡片搭建工具搭建的[新版卡片](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/cardkit-upgraded-version-card-release-notes)。
- 对于搭建工具中的卡片,此处仅支持传入富文本组件的组件 ID。即仅支持对富文本组件中的内容进行流式更新。
**示例值**:"markdown_1"
**数据校验规则**:
- 长度范围:`1` ~ `20` 字符 + +### 请求体 + +名称 | 类型 | 必填 | 描述 +---|---|---|--- +uuid | string | 否 | 幂等 ID,可通过传入唯一的 UUID 以保证相同批次的操作只进行一次。
**示例值**:"a0d69e20-1dd1-458b-k525-dfeca4015204"
**数据校验规则**:
- 长度范围:`1` ~ `64` 字符 +content | string | 是 | 新的全量文本内容。使用时请注意转义为字符串。
**注意**:
- 若 content 中含有代码块,你需将代码块前后的空格去掉,否则可能导致代码渲染失败。
- 若旧文本为传入的新文本的前缀子串,新增文本将在旧文本末尾继续以打字机效果输出;若新旧文本前缀不同,全量文本将直接上屏输出,无打字机效果。
**示例值**:"这是更新后的文本内容。将以打字机式的效果输出"
**数据校验规则**:
- 长度范围:`1` ~ `100000` 字符 +sequence | int | 是 | 操作卡片的序号。用于保证多次更新的时序性。
**注意**:
请确保在通过卡片 OpenAPI 操作同一张卡片时,sequence 的值相较于上一次操作严格递增。
**数据校验规则**:int32 范围( `1`~`2147483647`)内的正整数。
**示例值**:1 + +### 请求体示例 +```json +{ + "uuid": "a0d69e20-1dd1-458b-k525-dfeca4015204", + "content": "这是更新后的文本内容。将以打字机式的效果输出", + "sequence": 1 +} +``` + +## 响应 + +### 响应体 + +名称 | 类型 | 描述 +---|---|--- +code | int | 错误码,非 0 表示失败 +msg | string | 错误描述 +data | \- | \- + +### 响应体示例 +```json +{ + "code": 0, + "msg": "success", + "data": {} +} +``` + +### 错误码 + +HTTP状态码 | 错误码 | 描述 | 排查建议 +---|---|---|--- +400 | 10002 | Your request contains an invalid request parameter. | 参数错误,请根据接口返回的错误信息并参考文档检查输入参数。 +400 | 200740 | The card entity does not exist | 卡片实体不存在。请检查实体 ID 是否正确。 +400 | 200750 | The card entity has expired | 卡片实体已过期。卡片实体的有效期为 14 天。即创建卡片实体超出 14 天后,你将无法调用相关接口操作卡片。请重新创建卡片实体。 +400 | 200770 | UUID conflict | UUID 冲突。请传入唯一的 UUID 以保证相同批次的操作只进行一次。 +400 | 200810 | The card is in an ongoing interaction and cannot be updated | 在用户点击卡片[请求回调](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)交互期间,卡片无法实现流式更新。请等待交互结束后再尝试更新卡片。 +400 | 200850 | Card streaming timeout | 卡片流式更新模式因超时自动关闭。你可调用[更新卡片配置](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card/settings) 将 `streaming_mode` 字段值设置为 `true`。 +400 | 200860 | Card content exceeds limit. | 卡片体积超限。请将卡片大小控制在 30KB 以内。 +400 | 300302 | update_multi property is false | 卡片全局属性 update_multi 设置为了 false。在流式更新模式下,卡片全局属性 update_multi 需设置为 true。 +400 | 200220 | Failed to generate card content | 生成卡片内容失败。请检查卡片 JSON 格式是否有误。 +400 | 300307 | The card DSL is empty | 卡片 JSON 数据为空。请检查数据。 +400 | 300309 | Card streaming closed | 流式更新模式为关闭状态。你可调用[更新卡片配置](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card/settings) 将 `streaming_mode` 字段值设置为 `true`。 +400 | 300310 | Only update text | 该接口仅支持普通文本元素和富文本组件。请使用普通文本元素或富文本组件进行更新。 +400 | 300311 | The current application does not have permission to update/use this card | 当前应用没有更新或使用该卡片的权限。仅支持创建卡片实体的应用调用相关 OpenAPI 发送、操作卡片。 +400 | 300313 | Failed to update element properties | 更新组件属性失败。请根据接口返回的错误信息检查输入参数。 +400 | 300317 | The sequence number for operating on the card did not increment consecutively | 操作卡片的序号(sequence)未按顺序递增。请确保在通过卡片 OpenAPI 操作同一张卡片时,sequence 的值相较于上一次操作严格递增。 +400 | 300120 | Server Internal Error | 服务内部错误。请确保 `sequence` 依次递增,然后稍后重试。仍然出现可联系[技术支持](https://applink.feishu.cn/TLJpeNdW)。 diff --git a/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card-element__create.md b/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card-element__create.md new file mode 100644 index 0000000..e7d7484 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card-element__create.md @@ -0,0 +1,92 @@ +# 新增组件 + +为指定卡片实体新增组件,以扩展卡片内容,如在卡片中添加一个点击按钮。 + +## 使用限制 + +- 调用该接口时,不支持将卡片设置为独享卡片模式。即不支持将卡片 JSON 数据中的 `update_multi` 属性设置为 `false`。 +- 调用该接口的应用身份(tenant_access_token)需与创建目标卡片实体的应用身份一致。 + +## 请求 + +基本 |   +---|--- +HTTP URL | https://open.feishu.cn/open-apis/cardkit/v1/cards/:card_id/elements +HTTP Method | POST +接口频率限制 | [1000 次/分钟、50 次/秒](https://open.feishu.cn/document/ukTMukTMukTM/uUzN04SN3QjL1cDN) +支持的应用类型 | Custom App、Store App +权限要求
**调用该 API 所需的权限。开启其中任意一项权限即可调用** | 创建与更新卡片(cardkit:card:write) + +### 请求头 + +名称 | 类型 | 必填 | 描述 +---|---|---|--- +Authorization | string | 是 | `tenant_access_token`
**值格式**:"Bearer `access_token`"
**示例值**:"Bearer t-7f1bcd13fc57d46bac21793a18e560"
[了解更多:如何选择与获取 access token](https://open.feishu.cn/document/uAjLw4CM/ugTN1YjL4UTN24CO1UjN/trouble-shooting/how-to-choose-which-type-of-token-to-use) +Content-Type | string | 是 | **固定值**:"application/json; charset=utf-8" + +### 路径参数 + +名称 | 类型 | 描述 +---|---|--- +card_id | string | 要新增组件的卡片实体 ID。通过[创建卡片实体](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card/create)获取
**示例值**:"7355439197428236291"
**数据校验规则**:
- 长度范围:`1` ~ `20` 字符 + +### 请求体 + +名称 | 类型 | 必填 | 描述 +---|---|---|--- +type | string | 是 | 添加组件的方式。
**示例值**:"insert_after"
**可选值有**:
- insert_before:在目标组件前插入
- insert_after:在目标组件后插入
- append:在卡片或容器组件末尾添加 +target_element_id | string | 否 | 目标组件的 ID。 填写规则如下所示:
- 当 `type` 为 `insert_before`、`insert_after` 时,字段必填,为用于定位的目标组件
- 当 `type` 为 `append` 时,该字段仅支持容器类组件,用于指定在末尾添加的目标组件。若未填写,则默认在卡片 body 末尾添加
**示例值**:"markdown_1"
**数据校验规则**:
- 长度范围:`0` ~ `20` 字符 +uuid | string | 否 | 幂等 ID,可通过传入唯一的 UUID 以保证相同批次的操作只进行一次。
**示例值**:"a0d69e20-1dd1-458b-k525-dfeca4015204"
**数据校验规则**:
- 长度范围:`1` ~ `64` 字符 +sequence | int | 是 | 操作卡片的序号。用于保证多次更新的时序性。
**注意**:
请确保在通过卡片 OpenAPI 操作同一张卡片时,sequence 的值相较于上一次操作严格递增。
**数据校验规则**:int32 范围( `1`~`2147483647`)内的正整数。
**示例值**:1 +elements | string | 是 | 添加的组件列表。
**注意**:
- 以下示例值未转义,使用时请注意将其转为 JSON 序列化后的字符串。
- 本参数仅支持[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)。
**示例值**:"[{\"tag\":\"button\",\"element_id\":\"button_1\",\"text\":{\"tag\":\"plain_text\",\"content\":\"查看更多\"},\"type\":\"default\",\"width\":\"default\",\"size\":\"medium\",\"behaviors\":[{\"type\":\"open_url\",\"default_url\":\"https://open.feishu.cn/?lang=zh-CN\",\"pc_url\":\"\",\"ios_url\":\"\",\"android_url\":\"\"}]}]"
**数据校验规则**:
- 长度范围:`1` ~ `1000000` 字符 + +### 请求体示例 +```json +{ + "type": "insert_after", + "target_element_id": "markdown_1", + "uuid": "a0d69e20-1dd1-458b-k525-dfeca4015204", + "sequence": 1, + "elements": "[{\"tag\":\"button\",\"element_id\":\"button_1\",\"text\":{\"tag\":\"plain_text\",\"content\":\"查看更多\"},\"type\":\"default\",\"width\":\"default\",\"size\":\"medium\",\"behaviors\":[{\"type\":\"open_url\",\"default_url\":\"https://open.feishu.cn/?lang=zh-CN\",\"pc_url\":\"\",\"ios_url\":\"\",\"android_url\":\"\"}]}]" +} +``` + +## 响应 + +### 响应体 + +名称 | 类型 | 描述 +---|---|--- +code | int | 错误码,非 0 表示失败 +msg | string | 错误描述 +data | \- | \- + +### 响应体示例 +```json +{ + "code": 0, + "msg": "success", + "data": {} +} +``` + +### 错误码 + +HTTP状态码 | 错误码 | 描述 | 排查建议 +---|---|---|--- +400 | 10002 | Your request contains an invalid request parameter. | 参数错误,请根据接口返回的错误信息并参考本文档检查输入参数。 +400 | 200740 | The card entity does not exist | 卡片实体不存在。请检查实体 ID 是否正确。 +400 | 200750 | The card entity has expired | 卡片实体已过期。卡片实体的有效期为 14 天。即创建卡片实体超出 14 天后,你将无法调用相关接口操作卡片。请再次创建一个新的卡片实体。 +400 | 200770 | UUID conflict | UUID 冲突。请传入唯一的 UUID 以保证相同批次的操作只进行一次。 +400 | 200810 | The card is in an ongoing interaction and cannot be updated | 在用户点击卡片[请求回调](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)交互期间,卡片无法实现流式更新。请等待交互结束后再尝试更新卡片。 +400 | 200510 | Card streaming timeout | 卡片流式更新模式因超时自动关闭。你可调用[更新卡片配置](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card/settings) 将 `streaming_mode` 字段值设置为 `true`。 +400 | 200860 | Card content exceeds limit. | 卡片体积超限。请将卡片大小控制在 30KB 以内。 +400 | 300301 | Duplicate element_id in card component. | 卡片内部组件 ID (即 element_id)重复。 +400 | 300302 | update_multi property is false | 卡片全局属性 update_multi 为 false。在流式更新模式下,卡片全局属性 update_multi 需设置为 true。 +400 | 200220 | Failed to generate card content | 生成卡片内容失败。请检查卡片 JSON 格式是否有误。 +400 | 300305 | The number of card components exceeds 200 | 超出卡片组件限制。卡片 JSON 2.0 结构中,一张卡片最多支持 200 个元素(如 tag 为 plain_text 的文本元素)或组件。请将组件和元素的数量之和控制在 200 个以内。 +400 | 300307 | The card DSL is empty | 卡片 JSON 数据为空。请检查数据。 +400 | 300311 | The current application does not have permission to update/use this card | 当前应用没有更新或使用该卡片的权限。请使用创建卡片实体的应用调用相关 OpenAPI 发送、操作卡片。 +400 | 300315 | Failed to add element | 添加组件失败。请根据接口返回的错误信息检查输入参数。 +400 | 300317 | The sequence number for operating on the card did not increment consecutively | 操作卡片的序号(sequence)未按顺序递增。请确保在通过卡片 OpenAPI 操作同一张卡片时,sequence 的值相较于上一次操作严格递增。 +400 | 300120 | Server Internal Error | 服务内部错误。请稍后重试。仍然出现可联系[技术支持](https://applink.feishu.cn/TLJpeNdW)。 diff --git a/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card-element__delete.md b/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card-element__delete.md new file mode 100644 index 0000000..4a66aa9 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card-element__delete.md @@ -0,0 +1,87 @@ +# 删除组件 + +删除指定卡片实体中的组件。 + +## 注意事项 + +删除容器类组件时,容器中内嵌的组件将一并被删除。 + +## 使用限制 + +- 调用该接口时,不支持将卡片设置为独享卡片模式。即不支持将卡片 JSON 数据中的 `update_multi` 属性设置为 `false`。 +- 调用该接口的应用身份(tenant_access_token)需与创建目标卡片实体的应用身份一致。 + +## 请求 + +基本 |   +---|--- +HTTP URL | https://open.feishu.cn/open-apis/cardkit/v1/cards/:card_id/elements/:element_id +HTTP Method | DELETE +接口频率限制 | [1000 次/分钟、50 次/秒](https://open.feishu.cn/document/ukTMukTMukTM/uUzN04SN3QjL1cDN) +支持的应用类型 | Custom App、Store App +权限要求
**调用该 API 所需的权限。开启其中任意一项权限即可调用** | 创建与更新卡片(cardkit:card:write) + +### 请求头 + +名称 | 类型 | 必填 | 描述 +---|---|---|--- +Authorization | string | 是 | `tenant_access_token`
**值格式**:"Bearer `access_token`"
**示例值**:"Bearer t-7f1bcd13fc57d46bac21793a18e560"
[了解更多:如何选择与获取 access token](https://open.feishu.cn/document/uAjLw4CM/ugTN1YjL4UTN24CO1UjN/trouble-shooting/how-to-choose-which-type-of-token-to-use) +Content-Type | string | 是 | **固定值**:"application/json; charset=utf-8" + +### 路径参数 + +名称 | 类型 | 描述 +---|---|--- +card_id | string | 卡片实体 ID。通过[创建卡片实体](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card/create)获取
**示例值**:"7355439197428236291"
**数据校验规则**:
- 长度范围:`1` ~ `20` 字符 +element_id | string | 指定卡片实体内,要删除的组件 ID。对应卡片 JSON 中的 `element_id` 属性,由开发者自定义。
**示例值**:"markdown_1"
**数据校验规则**:
- 长度范围:`1` ~ `20` 字符 + +### 请求体 + +名称 | 类型 | 必填 | 描述 +---|---|---|--- +uuid | string | 否 | 幂等 id,可通过传入唯一的 uuid 以保证相同批次的操作只进行一次。
**示例值**:"a0d69e20-1dd1-458b-k525-dfeca4015204"
**数据校验规则**:
- 长度范围:`1` ~ `64` 字符 +sequence | int | 是 | 操作卡片的序号。用于保证多次更新的时序性。
**注意**:
请确保在通过卡片 OpenAPI 操作同一张卡片时,sequence 的值相较于上一次操作严格递增。
**数据校验规则**:int32 范围( `1`~`2147483647`)内的正整数。
**示例值**:1 + +### 请求体示例 +```json +{ + "uuid": "a0d69e20-1dd1-458b-k525-dfeca4015204", + "sequence": 1 +} +``` + +## 响应 + +### 响应体 + +名称 | 类型 | 描述 +---|---|--- +code | int | 错误码,非 0 表示失败 +msg | string | 错误描述 +data | \- | \- + +### 响应体示例 +```json +{ + "code": 0, + "msg": "success", + "data": {} +} +``` + +### 错误码 + +HTTP状态码 | 错误码 | 描述 | 排查建议 +---|---|---|--- +400 | 10002 | Your request contains an invalid request parameter. | 参数错误,请根据接口返回的错误信息并参考文档检查输入参数。 +400 | 200740 | The card entity does not exist | 卡片实体不存在。请检查实体 ID 是否正确。 +400 | 200750 | The card entity has expired | 卡片实体已过期。卡片实体的有效期为 14 天。即创建卡片实体超出 14 天后,你将无法调用相关接口操作卡片。请重新创建卡片实体。 +400 | 200770 | UUID conflict | UUID 冲突。请传入唯一的 UUID 以保证相同批次的操作只进行一次。 +400 | 200810 | The card is in an ongoing interaction and cannot be updated | 在用户点击卡片[请求回调](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)交互期间,卡片无法实现流式更新。请等待交互结束后再尝试更新。 +400 | 300302 | update_multi property is false | 在流式更新模式下,卡片全局属性 update_multi 需设置为 true。 +400 | 300303 | Only schema 2.0 is supported | 该接口仅支持 Schema v2.0 结构。详情参考[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)。 +400 | 200220 | Failed to generate card content | 生成卡片内容失败。请检查卡片 JSON 格式是否有误。 +400 | 300307 | The card DSL is empty | 卡片 JSON 数据为空。请检查数据。 +400 | 300311 | The current application does not have permission to update/use this card | 当前应用没有更新或使用该卡片的权限。仅支持创建卡片实体的应用调用相关 OpenAPI 发送、操作卡片。 +400 | 300314 | Failed to delete element | 删除组件失败。请根据接口返回的错误信息检查输入参数。 +400 | 300317 | The sequence number for operating on the card did not increment consecutively | 操作卡片的序号(sequence)未按顺序递增。请确保在通过卡片 OpenAPI 操作同一张卡片时,sequence 的值相较于上一次操作严格递增。 diff --git a/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card-element__patch.md b/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card-element__patch.md new file mode 100644 index 0000000..6805d77 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card-element__patch.md @@ -0,0 +1,89 @@ +# 更新组件属性 + +通过传入 `card_id`(卡片实体 ID)和 `element_id`(组件 ID),更新卡片实体中对应组件的属性。 + +## 使用限制 + +- 本接口不支持修改组件的标签(tag)属性。 +- 调用该接口时,不支持将卡片设置为独享卡片模式。即不支持将卡片 JSON 数据中的 `update_multi` 属性设置为 `false`。 +- 调用该接口的应用身份(tenant_access_token)需与创建目标卡片实体的应用身份一致。 + +## 请求 + +基本 |   +---|--- +HTTP URL | https://open.feishu.cn/open-apis/cardkit/v1/cards/:card_id/elements/:element_id +HTTP Method | PATCH +接口频率限制 | [1000 次/分钟、50 次/秒](https://open.feishu.cn/document/ukTMukTMukTM/uUzN04SN3QjL1cDN) +支持的应用类型 | Custom App、Store App +权限要求
**调用该 API 所需的权限。开启其中任意一项权限即可调用** | 创建与更新卡片(cardkit:card:write) + +### 请求头 + +名称 | 类型 | 必填 | 描述 +---|---|---|--- +Authorization | string | 是 | `tenant_access_token`
**值格式**:"Bearer `access_token`"
**示例值**:"Bearer t-7f1bcd13fc57d46bac21793a18e560"
[了解更多:如何选择与获取 access token](https://open.feishu.cn/document/uAjLw4CM/ugTN1YjL4UTN24CO1UjN/trouble-shooting/how-to-choose-which-type-of-token-to-use) +Content-Type | string | 是 | **固定值**:"application/json; charset=utf-8" + +### 路径参数 + +名称 | 类型 | 描述 +---|---|--- +card_id | string | 卡片实体 ID。通过[创建卡片实体](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card/create)获取
**示例值**:"7355439197428236291"
**数据校验规则**:
- 长度范围:`1` ~ `20` 字符 +element_id | string | 要更新的组件的 ID。对应 JSON 代码中的 `element_id` 属性,由开发者自定义。
**示例值**:"markdown_1"
**数据校验规则**:
- 长度范围:`1` ~ `20` 字符 + +### 请求体 + +名称 | 类型 | 必填 | 描述 +---|---|---|--- +partial_element | string | 是 | 组件的新的配置项字段。传入 `element_id` 参数后,原组件的 ID 将更新。
**注意**:
- 不支持修改 `tag` 参数。
- 以下示例值未转义,使用时请注意将其转为 JSON 序列化后的字符串。
- 仅支持[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)。
**示例值**:"{\"content\":\"更新后的组件文本\"}"
**数据校验规则**:
- 长度范围:`1` ~ `1000000` 字符 +uuid | string | 否 | 幂等 ID,可通过传入唯一的 UUID 以保证相同批次的操作只进行一次。
**示例值**:"a0d69e20-1dd1-458b-k525-dfeca4015204"
**数据校验规则**:
- 长度范围:`1` ~ `64` 字符 +sequence | int | 是 | 操作卡片的序号。用于保证多次更新的时序性。
**注意**:
请确保在通过卡片 OpenAPI 操作同一张卡片时,sequence 的值相较于上一次操作严格递增。
**数据校验规则**:int32 范围( `1`~`2147483647`)内的正整数。
**示例值**:1 + +### 请求体示例 +```json +{ + "partial_element": "{\"content\":\"更新后的组件文本\"}", + "uuid": "a0d69e20-1dd1-458b-k525-dfeca4015204", + "sequence": 1 +} +``` + +## 响应 + +### 响应体 + +名称 | 类型 | 描述 +---|---|--- +code | int | 错误码,非 0 表示失败 +msg | string | 错误描述 +data | \- | \- + +### 响应体示例 +```json +{ + "code": 0, + "msg": "success", + "data": {} +} +``` + +### 错误码 + +HTTP状态码 | 错误码 | 描述 | 排查建议 +---|---|---|--- +400 | 10002 | Your request contains an invalid request parameter. | 参数错误,请根据接口返回的错误信息并参考文档检查输入参数。 +400 | 200740 | The card entity does not exist | 卡片实体不存在。请检查实体 ID 是否正确。 +400 | 200750 | The card entity has expired | 卡片实体已过期。卡片实体的有效期为 14 天。即创建卡片实体超出 14 天后,你将无法调用相关接口操作卡片。请重新创建卡片实体。 +400 | 200770 | UUID conflict | UUID 冲突。请传入唯一的 UUID 以保证相同批次的操作只进行一次。 +400 | 200810 | The card is in an ongoing interaction and cannot be updated | 在用户点击卡片[请求回调](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)交互期间,卡片无法实现流式更新。请等待交互结束后再尝试更新卡片。 +400 | 200860 | Card content exceeds limit. | 卡片体积超限。请将卡片大小控制在 30KB 以内。 +400 | 300301 | Duplicate element_id in card component. | 卡片内部组件 ID (即 element_id)重复。 +400 | 300302 | update_multi property is false | update_multi 属性为 false。在流式更新模式下,卡片全局属性 update_multi 需设置为 true。 +400 | 300303 | Only schema 2.0 is supported | 该接口仅支持 Schema v2.0 结构。详情参考[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)。 +400 | 200220 | Failed to generate card content | 生成卡片内容失败。请检查卡片 JSON 格式是否有误。 +400 | 300307 | The card DSL is empty | 卡片 JSON 数据为空。请检查数据。 +400 | 300311 | The current application does not have permission to update/use this card | 当前应用没有更新或使用该卡片的权限。仅支持创建卡片实体的应用调用相关 OpenAPI 发送、操作卡片。 +400 | 300312 | Unable to update element tag | 更新卡片属性时,不能更新组件的标签(tag)属性。 +400 | 300313 | Failed to update element properties | 更新组件属性失败。请根据接口返回的错误信息检查输入参数。 +400 | 300317 | The sequence number for operating on the card did not increment consecutively | 操作卡片的序号(sequence)未按顺序递增。请确保在通过卡片 OpenAPI 操作同一张卡片时,sequence 的值相较于上一次操作严格递增。 diff --git a/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card-element__update.md b/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card-element__update.md new file mode 100644 index 0000000..137481f --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card-element__update.md @@ -0,0 +1,87 @@ +# 更新组件 + +更新卡片实体中的指定组件为新组件。 + +## 使用限制 + +- 调用该接口时,不支持将卡片设置为独享卡片模式。即不支持将卡片 JSON 数据中的 `update_multi` 属性设置为 `false`。 +- 调用该接口的应用身份(tenant_access_token)需与创建目标卡片实体的应用身份一致。 + +## 请求 + +基本 |   +---|--- +HTTP URL | https://open.feishu.cn/open-apis/cardkit/v1/cards/:card_id/elements/:element_id +HTTP Method | PUT +接口频率限制 | [1000 次/分钟、50 次/秒](https://open.feishu.cn/document/ukTMukTMukTM/uUzN04SN3QjL1cDN) +支持的应用类型 | Custom App、Store App +权限要求
**调用该 API 所需的权限。开启其中任意一项权限即可调用** | 创建与更新卡片(cardkit:card:write) + +### 请求头 + +名称 | 类型 | 必填 | 描述 +---|---|---|--- +Authorization | string | 是 | `tenant_access_token`
**值格式**:"Bearer `access_token`"
**示例值**:"Bearer t-7f1bcd13fc57d46bac21793a18e560"
[了解更多:如何选择与获取 access token](https://open.feishu.cn/document/uAjLw4CM/ugTN1YjL4UTN24CO1UjN/trouble-shooting/how-to-choose-which-type-of-token-to-use) +Content-Type | string | 是 | **固定值**:"application/json; charset=utf-8" + +### 路径参数 + +名称 | 类型 | 描述 +---|---|--- +card_id | string | 卡片实体 ID。通过[创建卡片实体](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card/create)获取。
**示例值**:"7355439197428236291"
**数据校验规则**:
- 长度范围:`1` ~ `20` 字符 +element_id | string | 要更新的组件 ID。对应卡片 JSON 中组件的 `element_id` 属性,由开发者自定义。
**提示**:同一张卡片内字段值唯一。仅允许使用字母、数字和下划线,必须以字母开头。
**示例值**:"markdown_1"
**数据校验规则**:
- 长度范围:`1` ~ `20` 字符 + +### 请求体 + +名称 | 类型 | 必填 | 描述 +---|---|---|--- +uuid | string | 否 | 幂等 ID,可通过传入唯一的 UUID 以保证相同批次的操作只进行一次。
**示例值**:"a0d69e20-1dd1-458b-k525-dfeca4015204"
**数据校验规则**:
- 长度范围:`1` ~ `64` 字符 +element | string | 是 | 新的组件的完整的 JSON 数据。
注意:
- 以下示例值未转义,使用时请注意将其转为 JSON 序列化后的字符串。
- 仅支持[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)。
**示例值**:"{\"tag\":\"markdown\",\"element_id\":\"md_1\",\"content\":\"这是一段更新后的文本\"}"
**数据校验规则**:
- 长度范围:`1` ~ `1000000` 字符 +sequence | int | 是 | 操作卡片的序号。用于保证多次更新的时序性。
**注意**:
请确保在通过卡片 OpenAPI 操作同一张卡片时,sequence 的值相较于上一次操作严格递增。
**数据校验规则**:int32 范围( `1`~`2147483647`)内的正整数。
**示例值**:1 + +### 请求体示例 +```json +{ + "uuid": "a0d69e20-1dd1-458b-k525-dfeca4015204", + "element": "{\"tag\":\"markdown\",\"element_id\":\"md_1\",\"content\":\"这是一段更新后的文本\"}", + "sequence": 1 +} +``` + +## 响应 + +### 响应体 + +名称 | 类型 | 描述 +---|---|--- +code | int | 错误码,非 0 表示失败 +msg | string | 错误描述 +data | \- | \- + +### 响应体示例 +```json +{ + "code": 0, + "msg": "success", + "data": {} +} +``` + +### 错误码 + +HTTP状态码 | 错误码 | 描述 | 排查建议 +---|---|---|--- +400 | 10002 | Your request contains an invalid request parameter. | 参数错误,请根据接口返回的错误信息并参考文档检查输入参数。 +400 | 200740 | The card entity does not exist | 卡片实体不存在。请检查实体 ID 是否正确。 +400 | 200750 | The card entity has expired | 卡片实体已过期。卡片实体的有效期为 14 天。即创建卡片实体超出 14 天后,你将无法调用相关接口操作卡片。请再创建一个新的卡片实体。 +400 | 200770 | UUID conflict | UUID 冲突。请传入唯一的 UUID 以保证相同批次的操作只进行一次。 +400 | 200810 | The card is in an ongoing interaction and cannot be updated | 在用户点击卡片[请求回调](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)交互期间,卡片无法实现流式更新。请等待交互结束后再尝试更新。 +400 | 200860 | Card content exceeds limit. | 卡片体积超限。请将卡片大小控制在 30KB 以内。 +400 | 300301 | Duplicate element_id in card component. | 卡片内部组件 ID (即 element_id)重复。 +400 | 300302 | update_multi property is false | 卡片全局属性 update_multi 为 false。在流式更新模式下,卡片全局属性 update_multi 需设置为 true。 +400 | 200220 | Failed to generate card content | 生成卡片内容失败。请检查卡片 JSON 格式是否有误。 +400 | 300305 | The number of card components exceeds 200 | 超出卡片组件限制。卡片 JSON 2.0 结构中,一张卡片最多支持 200 个元素(如 tag 为 plain_text 的文本元素)或组件。请将组件和元素的数量之和控制在 200 个以内。 +400 | 300307 | The card DSL is empty | 卡片 JSON 数据为空。请检查数据。 +400 | 300311 | The current application does not have permission to update/use this card | 当前应用没有更新或使用该卡片的权限。仅支持创建卡片实体的应用调用相关 OpenAPI 发送、操作卡片。 +400 | 300317 | The sequence number for operating on the card did not increment consecutively | 操作卡片的序号(sequence)未按顺序递增。请确保在通过卡片 OpenAPI 操作同一张卡片时,sequence 的值相较于上一次操作严格递增。 +400 | 300121 | Failed to replace element | 替换组件失败。请根据接口返回的错误信息检查输入参数。 diff --git a/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card__batch_update.md b/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card__batch_update.md new file mode 100644 index 0000000..33a13c0 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card__batch_update.md @@ -0,0 +1,93 @@ +# 局部更新卡片实体 + +更新卡片实体局部内容,包括配置和组件。支持同时对多个组件进行增删改等不同操作。 + +## 使用限制 + +- 本接口仅支持[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)。 +- 调用该接口时,不支持将卡片设置为独享卡片模式。即不支持将卡片 JSON 数据中的 `update_multi` 属性设置为 `false`。 +- 调用该接口的应用身份(tenant_access_token)需与创建目标卡片实体的应用身份一致。 + +## 请求 + +基本 |   +---|--- +HTTP URL | https://open.feishu.cn/open-apis/cardkit/v1/cards/:card_id/batch_update +HTTP Method | POST +接口频率限制 | [1000 次/分钟、50 次/秒](https://open.feishu.cn/document/ukTMukTMukTM/uUzN04SN3QjL1cDN) +支持的应用类型 | Custom App、Store App +权限要求
**调用该 API 所需的权限。开启其中任意一项权限即可调用** | 创建与更新卡片(cardkit:card:write) + +### 请求头 + +名称 | 类型 | 必填 | 描述 +---|---|---|--- +Authorization | string | 是 | `tenant_access_token`
**值格式**:"Bearer `access_token`"
**示例值**:"Bearer t-7f1bcd13fc57d46bac21793a18e560"
[了解更多:如何选择与获取 access token](https://open.feishu.cn/document/uAjLw4CM/ugTN1YjL4UTN24CO1UjN/trouble-shooting/how-to-choose-which-type-of-token-to-use) +Content-Type | string | 是 | **固定值**:"application/json; charset=utf-8" + +### 路径参数 + +名称 | 类型 | 描述 +---|---|--- +card_id | string | 卡片实体 ID。通过[创建卡片实体](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card/create)获取。
**示例值**:"7355439197428236291"
**数据校验规则**:
- 长度范围:`1` ~ `20` 字符 + +### 请求体 + +名称 | 类型 | 必填 | 描述 +---|---|---|--- +uuid | string | 否 | 幂等 ID,可通过传入唯一的 UUID 以保证相同批次的操作只进行一次。
**示例值**:"a0d69e20-1dd1-458b-k525-dfeca4015204"
**数据校验规则**:
- 长度范围:`1` ~ `64` 字符 +sequence | int | 是 | 操作卡片的序号。用于保证多次更新的时序性。
**注意**:
请确保在通过卡片 OpenAPI 操作同一张卡片时,sequence 的值相较于上一次操作严格递增。
**数据校验规则**:int32 范围( `1`~`2147483647`)内的正整数
**示例值**:1 +actions | string | 是 | 操作列表。参考示例更新配置或组件。支持的操作有:
- `partial_update_setting`:更新卡片配置,支持更新卡片的 config 和 card_link 字段。参数结构可参考[更新卡片配置](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card/settings);
- `add_elements`:添加组件,支持 type、 target_element_id、elements 字段。参数结构可参考[新增组件](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/create)接口请求体;
- `delete_elements`:删除组件,支持 element_ids 字段。参数值为组件 ID 数组。参数结构可参考[删除组件](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/delete);
- `partial_update_element`:更新组件的属性,支持 element_id 和 partial_element 字段。参数结构可参考[更新组件属性](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/patch)接口的路径参数 element_id 和请求体 partial_element 字段 ;
- `update_element`:全量更新组件,支持 element_id 和 element 字段。参数结构可参考[全量更新组件](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/update)接口的路径参数 element_id 和请求体 element 字段
**示例值**:"[{\"action\":\"partial_update_setting\",\"params\":{\"settings\":{\"config\":{\"streaming_mode\":true}}}},{\"action\":\"add_elements\",\"params\":{\"type\":\"insert_before\",\"target_element_id\":\"markdown_1\",\"elements\":[{\"tag\":\"markdown\",\"element_id\":\"md_1\",\"content\":\"欢迎使用[飞书卡片搭建工具](https://open.feishu.cn/cardkit?from=open_docs)。\"}]}},{\"action\":\"delete_elements\",\"params\":{\"element_ids\":[\"text_1\",\"text_2\"]}},{\"action\":\"partial_update_element\",\"params\":{\"element_id\":\"markdown_2\",\"partial_element\":{\"content\":\"详情参考飞书卡片相关文档。\"}}},{\"action\":\"update_element\",\"params\":{\"element_id\":\"markdown_3\",\"element\":{\"tag\":\"button\",\"text\":{\"tag\":\"plain_text\",\"content\":\"有帮助\"},\"size\":\"medium\",\"icon\":{\"tag\":\"standard_icon\",\"token\":\"emoji_outlined\"}}}}]"
**数据校验规则**:
- 长度范围:`1` ~ `1000000` 字符 + +### 请求体示例 +```json +{ + "uuid": "a0d69e20-1dd1-458b-k525-dfeca4015204", + "sequence": 1, + "actions": "[{\"action\":\"partial_update_setting\",\"params\":{\"settings\":{\"config\":{\"streaming_mode\":true}}}},{\"action\":\"add_elements\",\"params\":{\"type\":\"insert_before\",\"target_element_id\":\"markdown_1\",\"elements\":[{\"tag\":\"markdown\",\"element_id\":\"md_1\",\"content\":\"欢迎使用[飞书卡片搭建工具](https://open.feishu.cn/cardkit?from=open_docs)。\"}]}},{\"action\":\"delete_elements\",\"params\":{\"element_ids\":[\"text_1\",\"text_2\"]}},{\"action\":\"partial_update_element\",\"params\":{\"element_id\":\"markdown_2\",\"partial_element\":{\"content\":\"详情参考飞书卡片相关文档。\"}}},{\"action\":\"update_element\",\"params\":{\"element_id\":\"markdown_3\",\"element\":{\"tag\":\"button\",\"text\":{\"tag\":\"plain_text\",\"content\":\"有帮助\"},\"size\":\"medium\",\"icon\":{\"tag\":\"standard_icon\",\"token\":\"emoji_outlined\"}}}}]" +} +``` + +## 响应 + +### 响应体 + +名称 | 类型 | 描述 +---|---|--- +code | int | 错误码,非 0 表示失败 +msg | string | 错误描述 +data | \- | \- + +### 响应体示例 +```json +{ + "code": 0, + "msg": "success", + "data": {} +} +``` + +### 错误码 + +HTTP状态码 | 错误码 | 描述 | 排查建议 +---|---|---|--- +400 | 10002 | Your request contains an invalid request parameter. | 参数错误,请根据接口返回的错误信息并参考文档检查输入参数。 +400 | 200740 | The card entity does not exist | 卡片实体不存在。请检查实体 ID 是否正确。 +400 | 200750 | The card entity has expired | 卡片实体已过期。卡片实体的有效期为 14 天。即创建卡片实体超出 14 天后,你将无法调用相关接口操作卡片。请创建一个新的卡片实体。 +400 | 200770 | UUID conflict | UUID 冲突。请传入唯一的 UUID 以保证相同批次的操作只进行一次。 +400 | 200810 | The card is in an ongoing interaction and cannot be updated | 在用户点击卡片[请求回调](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)交互期间,卡片无法实现流式更新。请等待交互结束后再尝试更新卡片。 +400 | 200860 | Card content exceeds limit. | 卡片体积超限。请将卡片大小控制在 30KB 以内。 +400 | 300301 | Duplicate element_id in card component. | 卡片内部组件 ID (即 element_id)重复。 +400 | 300302 | update_multi property is false | 卡片属性参数 update_multi 设置为了 false。在流式更新模式下,你需将卡片属性 update_multi 设置为 true。 +400 | 300303 | Only schema 2.0 is supported | 该接口仅支持 Schema v2.0 结构。详情参考[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)。 +400 | 200220 | Failed to generate card content | 生成卡片内容失败。请检查卡片 JSON 格式是否有误。 +400 | 300305 | The number of card components exceeds 200 | 超出卡片组件限制。卡片 JSON 2.0 结构中,一张卡片最多支持 200 个元素(如 tag 为 plain_text 的文本元素)或组件。请将组件和元素的数量之和控制在 200 个以内。 +400 | 300307 | The card DSL is empty | 卡片 JSON 数据为空。请检查数据。 +400 | 300311 | The current application does not have permission to update/use this card | 当前应用没有更新或使用该卡片的权限。仅支持创建卡片实体的应用调用相关 OpenAPI 发送、操作卡片。 +400 | 300312 | Unable to update element tag | 更新卡片实体时,不能更新组件的标签(tag)属性。 +400 | 300313 | Failed to update element properties | 更新组件属性失败。请根据接口返回的错误信息检查输入参数。 +400 | 300314 | Failed to delete element | 删除组件失败。请根据接口返回的错误信息检查输入参数。 +400 | 300315 | Failed to add element | 添加组件失败。请根据接口返回的错误信息检查输入参数。 +400 | 300317 | The sequence number for operating on the card did not increment consecutively | 操作卡片的序号(sequence)未按顺序递增。请确保在通过卡片 OpenAPI 操作同一张卡片时,sequence 的值相较于上一次操作严格递增。 +400 | 300121 | Failed to replace element | 替换组件失败。请根据接口返回的错误信息检查输入参数。 +400 | 300122 | Failed to update card configuration | 更新卡片配置失败。请根据接口返回的错误信息检查输入参数。 diff --git a/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card__create.md b/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card__create.md new file mode 100644 index 0000000..33aab94 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card__create.md @@ -0,0 +1,82 @@ +# 创建卡片实体 + +基于卡片 JSON 代码或卡片搭建工具搭建的卡片,创建卡片实体。用于后续通过卡片实体 ID(card_id)发送卡片、更新卡片等。 + +## 使用限制 + +- 本接口仅支持[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)或卡片搭建工具搭建的[新版卡片](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/cardkit-upgraded-version-card-release-notes)。 +- 调用该接口时,不支持将卡片设置为独享卡片模式。即不支持将卡片 JSON 数据中的 `update_multi` 属性设置为 `false`。 +- 一个卡片实体,仅支持发送一次。 +- 卡片实体的有效期为 14 天。即创建卡片实体超出 14 天后,你将无法调用相关接口操作卡片。 + +## 请求 + +基本 |   +---|--- +HTTP URL | https://open.feishu.cn/open-apis/cardkit/v1/cards +HTTP Method | POST +接口频率限制 | [1000 次/分钟、50 次/秒](https://open.feishu.cn/document/ukTMukTMukTM/uUzN04SN3QjL1cDN) +支持的应用类型 | Custom App、Store App +权限要求
**调用该 API 所需的权限。开启其中任意一项权限即可调用** | 创建与更新卡片(cardkit:card:write) + +### 请求头 + +名称 | 类型 | 必填 | 描述 +---|---|---|--- +Authorization | string | 是 | `tenant_access_token`
**值格式**:"Bearer `access_token`"
**示例值**:"Bearer t-7f1bcd13fc57d46bac21793a18e560"
[了解更多:如何选择与获取 access token](https://open.feishu.cn/document/uAjLw4CM/ugTN1YjL4UTN24CO1UjN/trouble-shooting/how-to-choose-which-type-of-token-to-use) +Content-Type | string | 是 | **固定值**:"application/json; charset=utf-8" + +### 请求体 + +名称 | 类型 | 必填 | 描述 +---|---|---|--- +type | string | 是 | 卡片类型。可选值:
- `card_json`:由卡片 JSON 代码构建的卡片
- `template`:由[卡片搭建工具](https://open.feishu.cn/cardkit?from=open_docs)搭建的卡片模板
**示例值**:"card_json"
**数据校验规则**:
- 长度范围:`1` ~ `50` 字符 +data | string | 是 | 卡片数据。需要与 `type` 指定的类型一致:
- 若 `type` 为 `card_json`,则此处应传卡片 JSON 代码,并确保将其转义为字符串。仅支持[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure),即你必须声明 `schema` 为 `2.0`
- 若 `type` 为 `template`,则此处应传卡片模板的数据,并确保将其转义为字符串。仅支持新版卡片。即在搭建工具中,卡片名称旁应有“新版”标识
**示例值**:"请参考下文请求体示例"
**数据校验规则**:
- 长度范围:`1` ~ `3000000` 字符 + +### 请求体示例 +```json +{ // type 为 card_json 时 + "type": "card_json", + "data": "{\"schema\":\"2.0\",\"header\":{\"title\":{\"content\":\"项目进度更新提醒\",\"tag\":\"plain_text\"}},\"config\":{\"streaming_mode\":true,\"summary\":{\"content\":\"\"},\"streaming_config\":{\"print_frequency_ms\":{\"default\":70,\"android\":70,\"ios\":70,\"pc\":70},\"print_step\":{\"default\":1,\"android\":1,\"ios\":1,\"pc\":1},\"print_strategy\":\"fast\"}},\"body\":{\"elements\":[{\"tag\":\"markdown\",\"content\":\"截至今日,项目完成度已达80%\",\"element_id\":\"markdown_1\"}]}}" +} + +{ // type 为 template 时 + "type": "template", + "data": "{\"template_id\":\"AAqIi1B8abcef\",\"template_version_name\":\"1.0.0\",\"template_variable\":{\"open_id\":\"ou_5c6d1637498e704f541095bba3dabcef\"}}}" +} +``` + +## 响应 + +### 响应体 + +名称 | 类型 | 描述 +---|---|--- +code | int | 错误码,非 0 表示失败 +msg | string | 错误描述 +data | \- | \- +card_id | string | 创建的卡片实体 ID。后续可通过[发送消息](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/create)接口传入卡片实体 ID 发送卡片。 + +### 响应体示例 +```json +{ + "code": 0, + "msg": "success", + "data": { + "card_id": "7355372766134157313" + } +} +``` + +### 错误码 + +HTTP状态码 | 错误码 | 描述 | 排查建议 +---|---|---|--- +400 | 10002 | Your request contains an invalid request parameter. | 参数错误。请根据接口返回的错误信息并参考文档检查输入参数。 +400 | 200860 | Card content exceeds limit. | 卡片体积超限。建议卡片大小控制在 30KB 以内。 +400 | 300301 | Duplicate element_id in card component. | 卡片内部组件 ID (即 element_id)重复。请检查并修改。 +400 | 300302 | update_multi property is false | 卡片全局属性 update_multi 设置为了 false。在流式更新模式下,卡片全局属性 update_multi 需设置为 true。 +400 | 300303 | Only schema 2.0 is supported | 该接口仅支持 JSON 2.0 结构。详情参考[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)。 +400 | 200220 | Failed to generate card content | 生成卡片内容失败。请检查卡片 JSON 格式是否有误。 +400 | 300305 | The number of card components exceeds 200 | 超出卡片组件限制。卡片 JSON 2.0 结构中,一张卡片最多支持 200 个元素(如 tag 为 plain_text 的文本元素)或组件。请将组件和元素的数量之和控制在 200 个以内。 +400 | 300307 | The card DSL is empty | 卡片 JSON 数据为空。请检查并修改。 diff --git a/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card__settings.md b/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card__settings.md new file mode 100644 index 0000000..fc1dafc --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card__settings.md @@ -0,0 +1,84 @@ +# 更新卡片配置 + +更新指定卡片实体的配置,支持卡片配置 `config` 字段和卡片跳转链接 `card_link` 字段。 + +## 使用限制 + +- 调用该接口时,不支持将卡片设置为独享卡片模式。即不支持将卡片 JSON 数据中的 `update_multi` 属性设置为 `false`。 +- 调用该接口的应用身份(tenant_access_token)需与创建目标卡片实体的应用身份一致。 + +## 请求 + +基本 |   +---|--- +HTTP URL | https://open.feishu.cn/open-apis/cardkit/v1/cards/:card_id/settings +HTTP Method | PATCH +接口频率限制 | [1000 次/分钟、50 次/秒](https://open.feishu.cn/document/ukTMukTMukTM/uUzN04SN3QjL1cDN) +支持的应用类型 | Custom App、Store App +权限要求
**调用该 API 所需的权限。开启其中任意一项权限即可调用** | 创建与更新卡片(cardkit:card:write) + +### 请求头 + +名称 | 类型 | 必填 | 描述 +---|---|---|--- +Authorization | string | 是 | `tenant_access_token`
**值格式**:"Bearer `access_token`"
**示例值**:"Bearer t-7f1bcd13fc57d46bac21793a18e560"
[了解更多:如何选择与获取 access token](https://open.feishu.cn/document/uAjLw4CM/ugTN1YjL4UTN24CO1UjN/trouble-shooting/how-to-choose-which-type-of-token-to-use) +Content-Type | string | 是 | **固定值**:"application/json; charset=utf-8" + +### 路径参数 + +名称 | 类型 | 描述 +---|---|--- +card_id | string | 卡片实体 ID。通过[创建卡片实体](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card/create)获取
**示例值**:"7355372766134157313"
**数据校验规则**:
- 长度范围:`1` ~ `20` 字符 + +### 请求体 + +名称 | 类型 | 必填 | 描述 +---|---|---|--- +settings | string | 是 | 卡片配置相关字段转义后的字符串,包括 `config` 和 `card_link` 字段。
**注意**:
- 以下示例值未转义,使用时请注意将其转为 JSON 序列化后的字符串。
- 本字段仅支持[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)中的对应字段。
**示例值**:"{\"config\":{\"streaming_mode\":true,\"streaming_config\":{\"print_frequency_ms\":{\"default\":70,\"android\":70,\"ios\":70,\"pc\":70},\"print_step\":{\"default\":1,\"android\":1,\"ios\":1,\"pc\":1},\"print_strategy\":\"fast\"}}}"
**数据校验规则**:
- 长度范围:`1` ~ `100000` 字符 +uuid | string | 否 | 幂等 ID,可通过传入唯一的 UUID 以保证相同批次的操作只进行一次。
**示例值**:"a0d69e20-1dd1-458b-k525-dfeca4015204"
**数据校验规则**:
- 长度范围:`1` ~ `64` 字符 +sequence | int | 是 | 操作卡片的序号。用于保证多次更新的时序性。
**注意**:
请确保在通过卡片 OpenAPI 操作同一张卡片时,sequence 的值相较于上一次操作严格递增。
**数据校验规则**:int32 范围( `1`~`2147483647`)内的正整数
**示例值**:1 + +### 请求体示例 +```json +{ + "settings": "{\"config\":{\"streaming_mode\":true,\"streaming_config\":{\"print_frequency_ms\":{\"default\":70,\"android\":70,\"ios\":70,\"pc\":70},\"print_step\":{\"default\":1,\"android\":1,\"ios\":1,\"pc\":1},\"print_strategy\":\"fast\"}}}", + "uuid": "a0d69e20-1dd1-458b-k525-dfeca4015204", + "sequence": 1 +} +``` + +## 响应 + +### 响应体 + +名称 | 类型 | 描述 +---|---|--- +code | int | 错误码,非 0 表示失败 +msg | string | 错误描述 +data | \- | \- + +### 响应体示例 +```json +{ + "code": 0, + "msg": "success", + "data": {} +} +``` + +### 错误码 + +HTTP状态码 | 错误码 | 描述 | 排查建议 +---|---|---|--- +400 | 10002 | Your request contains an invalid request parameter. | 参数错误,请根据接口返回的错误信息并参考文档检查输入参数。 +400 | 200740 | The card entity does not exist | 卡片实体不存在。请检查实体 ID 是否正确。 +400 | 200750 | The card entity has expired | 卡片实体已过期。卡片实体的有效期为 14 天。即创建卡片实体超出 14 天后,你将无法调用相关接口操作卡片。请重新创建卡片实体。 +400 | 200770 | UUID conflict | UUID 冲突。请传入唯一的 UUID 以保证相同批次的操作只进行一次。 +400 | 200810 | The card is in an ongoing interaction and cannot be updated | 在用户点击卡片[请求回调](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)交互期间,卡片无法实现流式更新。请等待交互结束后再尝试更新卡片。 +400 | 200860 | Card content exceeds limit. | 卡片体积超限。请将卡片大小控制在 30KB 以内。 +400 | 300302 | update_multi property is false | 卡片全局属性 update_multi 设置为了 false。在流式更新模式下,卡片全局属性 update_multi 需设置为 true。 +400 | 200220 | Failed to generate card content | 生成卡片内容失败。请检查卡片 JSON 格式是否有误。 +400 | 300307 | The card DSL is empty | 卡片 JSON 数据为空。 +400 | 300311 | The current application does not have permission to update/use this card | 当前应用没有更新或使用该卡片的权限。仅支持创建卡片实体的应用调用相关 OpenAPI 发送、操作卡片。 +400 | 300317 | The sequence number for operating on the card did not increment consecutively | 操作卡片的序号(sequence)未按顺序递增。请确保在通过卡片 OpenAPI 操作同一张卡片时,sequence 的值相较于上一次操作严格递增。 +400 | 300122 | Failed to update card configuration | 更新卡片配置失败。请根据接口返回的错误信息检查输入参数。 diff --git a/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card__update.md b/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card__update.md new file mode 100644 index 0000000..24ded6e --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__card__update.md @@ -0,0 +1,91 @@ +# 全量更新卡片实体 + +传入新的卡片 JSON 代码,覆盖更新指定的卡片实体的所有内容。 + +## 使用限制 +- 本接口仅支持[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)。 +- 调用该接口时,不支持将卡片设置为独享卡片模式。即不支持将卡片 JSON 数据中的 `update_multi` 属性设置为 `false`。 +- 调用该接口的应用身份(tenant_access_token)需与创建目标卡片实体的应用身份一致。 + +## 请求 + +基本 |   +---|--- +HTTP URL | https://open.feishu.cn/open-apis/cardkit/v1/cards/:card_id +HTTP Method | PUT +接口频率限制 | [1000 次/分钟、50 次/秒](https://open.feishu.cn/document/ukTMukTMukTM/uUzN04SN3QjL1cDN) +支持的应用类型 | Custom App、Store App +权限要求
**调用该 API 所需的权限。开启其中任意一项权限即可调用** | 创建与更新卡片(cardkit:card:write) + +### 请求头 + +名称 | 类型 | 必填 | 描述 +---|---|---|--- +Authorization | string | 是 | `tenant_access_token`
**值格式**:"Bearer `access_token`"
**示例值**:"Bearer t-7f1bcd13fc57d46bac21793a18e560"
[了解更多:如何选择与获取 access token](https://open.feishu.cn/document/uAjLw4CM/ugTN1YjL4UTN24CO1UjN/trouble-shooting/how-to-choose-which-type-of-token-to-use) +Content-Type | string | 是 | **固定值**:"application/json; charset=utf-8" + +### 路径参数 + +名称 | 类型 | 描述 +---|---|--- +card_id | string | 卡片实体 ID。通过[创建卡片实体](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card/create)获取。
**示例值**:"7355372766134157313"
**数据校验规则**:
- 长度范围:`1` ~ `20` 字符 + +### 请求体 + +名称 | 类型 | 必填 | 描述 +---|---|---|--- +card | card | 是 | 更新后的完整卡片 JSON 内容。 +type | string | 是 | 卡片数据的类型。取固定值 `card_json`。
**示例值**:"card_json"
**可选值有**:
- card_json:卡片 JSON 数据类型
**数据校验规则**:
- 长度范围:`1` ~ `50` 字符 +data | string | 是 | 卡片 JSON 数据的内容。
**注意**:
- 仅支持 JSON 2.0 版本的卡片结构。
- 以下示例值未转义,使用时请注意将其转为 JSON 序列化后的字符串。
**示例值**:"{\"schema\":\"2.0\",\"header\":{\"title\":{\"content\":\"项目进度更新提醒\",\"tag\":\"plain_text\"}},\"body\":{\"elements\":[{\"tag\":\"markdown\",\"content\":\"截至今日,项目完成度已达80%\"}]}}"
**数据校验规则**:
- 长度范围:`1` ~ `1000000` 字符 +uuid | string | 否 | 幂等 ID,可通过传入唯一的 UUID 以保证相同批次的操作只进行一次。
**示例值**:"a0d69e20-1dd1-458b-k525-dfeca4015204"
**数据校验规则**:
- 长度范围:`1` ~ `64` 字符 +sequence | int | 是 | 操作卡片的序号。用于保证多次更新的时序性。
**注意**:
请确保在通过卡片 OpenAPI 操作同一张卡片时,sequence 的值相较于上一次操作严格递增。
**数据校验规则**:int32 范围( `1`~`2147483647`)内的正整数
**示例值**:1 + +### 请求体示例 +```json +{ + "card": { + "type": "card_json", + "data": "{\"schema\":\"2.0\",\"header\":{\"title\":{\"content\":\"项目进度更新提醒\",\"tag\":\"plain_text\"}},\"body\":{\"elements\":[{\"tag\":\"markdown\",\"content\":\"截至今日,项目完成度已达80%\"}]}}" + }, + "uuid": "a0d69e20-1dd1-458b-k525-dfeca4015204", + "sequence": 1 +} +``` + +## 响应 + +### 响应体 + +名称 | 类型 | 描述 +---|---|--- +code | int | 错误码,非 0 表示失败 +msg | string | 错误描述 +data | \- | \- + +### 响应体示例 +```json +{ + "code": 0, + "msg": "success", + "data": {} +} +``` + +### 错误码 + +HTTP状态码 | 错误码 | 描述 | 排查建议 +---|---|---|--- +400 | 10002 | Your request contains an invalid request parameter. | 参数错误,请根据接口返回的错误信息并参考文档检查输入参数。 +400 | 200740 | The card entity does not exist | 卡片实体不存在。请检查实体 ID 是否正确。 +400 | 200750 | The card entity has expired | 卡片实体已过期。卡片实体的有效期为 14 天。即创建卡片实体超出 14 天后,你将无法调用相关接口操作卡片。请重新创建卡片实体。 +400 | 200770 | UUID conflict | UUID 冲突。请传入唯一的 UUID 以保证相同批次的操作只进行一次。 +400 | 200810 | The card is in an ongoing interaction and cannot be updated | 在用户点击卡片[请求回调](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)交互期间,卡片无法实现流式更新。请等待交互结束后再尝试更新卡片。 +400 | 200860 | Card content exceeds limit. | 卡片体积超限。请将卡片大小控制在 30KB 以内。 +400 | 300301 | Duplicate element_id in card component. | 卡片内部组件 ID (即 element_id)重复。 +400 | 300302 | update_multi property is false | 卡片全局属性 update_multi 为 false。在流式更新模式下,卡片全局属性 update_multi 需设置为 true。 +400 | 300303 | Only schema 2.0 is supported | 该接口仅支持 Schema v2.0 结构。详情参考[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)。 +400 | 200220 | Failed to generate card content | 生成卡片内容失败。请检查卡片 JSON 格式是否有误。 +400 | 300305 | The number of card components exceeds 200 | 超出卡片组件限制。卡片 JSON 2.0 结构中,一张卡片最多支持 200 个元素(如 tag 为 plain_text 的文本元素)或组件。请将组件和元素的数量之和控制在 200 个以内。 +400 | 300307 | The card DSL is empty | 卡片 JSON 数据为空。请检查数据。 +400 | 300311 | The current application does not have permission to update/use this card | 当前应用没有更新或使用该卡片的权限。请使用创建该卡片实体的应用调用相关 OpenAPI 发送、操作卡片。 +400 | 300317 | The sequence number for operating on the card did not increment consecutively | 操作卡片的序号(sequence)未按顺序递增。请确保在通过卡片 OpenAPI 操作同一张卡片时,sequence 的值相较于上一次操作严格递增。 diff --git a/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__feishu-card-resource-overview.md b/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__feishu-card-resource-overview.md new file mode 100644 index 0000000..e0fad90 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/cardkit-v1__feishu-card-resource-overview.md @@ -0,0 +1,56 @@ +# 飞书卡片资源概述 +飞书卡片是应用的一种能力,包括构建卡片内容所需的组件和发送卡片所需的能力,并提供了[可视化搭建工具](https://open.feishu.cn/cardkit?from=open_docs_overview)。飞书开放平台针对飞书卡片提供了一系列 OpenAPI,使用这些 OpenAPI 你可以在卡片和组件维度,局部或流式更新卡片。 + +## 典型案例 + +开放平台提供了包含飞书卡片的案例,详情可参见: +- [智能审批管办一体,助力企业效能提升](https://open.feishu.cn/solutions/detail/automation) +- [运维工单智能派发,信息流转精准顺畅](https://open.feishu.cn/solutions/detail/ticke) +- [当项目管理遇见飞书,协同沉淀更便捷](https://open.feishu.cn/solutions/detail/project) +- [告别手动,基于飞书机器人实现自动群管理](https://open.feishu.cn/solutions/detail/group) +- [深度融合企业系统,飞书审批让流程更轻松](https://open.feishu.cn/solutions/detail/approval) + +## 接入流程 + +卡片 API 的基本接入流程如下图所示,如需了解详细的 API 接入流程,参见[流程概述](https://open.feishu.cn/document/ukTMukTMukTM/uITNz4iM1MjLyUzM)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/7e2c712313cbc2da9b298804cbcf94e2_MwxGtG3AQH.png?height=214&lazyload=true&maxWidth=900&width=2276) + +## 开发指南 + +- 前往[飞书卡片开发指南文档](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-overview),了解如何搭建卡片、发送卡片和更新卡片。 +- 参考[流式更新卡片](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/streaming-updates-openapi-overview),了解如何调用卡片接口实现文本流式等能力。 + +## 资源介绍 + +飞书卡片 OpenAPI 中,以卡片和组件资源为中心开放接口,支持创建、更新卡片。 + +资源 | 描述 +---|--- +卡片 | 飞书卡片能将结构化的内容以卡片形式嵌入至聊天消息、群置顶消息、链接预览等飞书协作场景中,提升信息传递效率。了解更多参见[飞书卡片概述](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-overview)。通过卡片实体 API,你可从卡片维度创建卡片、更新卡片。 +组件 | 飞书卡片中的组件可分为容器类、展示类和交互类组件。了解更多参见[组件概述](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/component-overview)。通过组件 API,你可以在一张卡片中新增、修改组件。 + +## 方法列表 + +以下提供创建和更新卡片的 API 列表。你可通过[创建卡片实体](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card/create)接口创建卡片,再调用[发送消息](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/create)接口通过卡片 ID 发送卡片。之后使用其它接口局部更新卡片。 +**注意事项**:- 下表中 **商店** 是指商店应用,**自建** 是指企业自建应用。应用类型说明参见[应用类型简介](https://open.feishu.cn/document/home/app-types-introduction/overview)。 +- 下列接口仅支持[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)。 + +### 卡片级 + +方法 (API) | 权限要求(满足任一) | 访问凭证 | 商店 | 自建 +---|---|---|---|--- +`POST`[创建卡片实体](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card/create) open-apis/cardkit/v1/cards | 创建与更新卡片(cardkit:card:write) | `tenant_access_token` | **✓** | **✓** +`PUT` [全量更新卡片实体](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card/update) /open-apis/cardkit/v1/cards/:card_id | 创建与更新卡片(cardkit:card:write) | `tenant_access_token` | **✓** | **✓** +`PATCH` [更新卡片配置](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card/settings) /open-apis/cardkit/v1/cards/:card_id/settings | 创建与更新卡片(cardkit:card:write) | `tenant_access_token` | **✓** | **✓** +`POST` [批量更新卡片实体](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card/batch_update) /open-apis/cardkit/v1/cards/:card_id/batch_update | 创建与更新卡片(cardkit:card:write) | `tenant_access_token` | **✓** | **✓** + +### 组件级 + +方法 (API) | 权限要求(满足任一) | 访问凭证 | 商店 | 自建 +---|---|---|---|--- +`POST`[新增组件](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/create) /open-apis/cardkit/v1/cards/:card_id/elements | 创建与更新卡片(cardkit:card:write) | `tenant_access_token` | **✓** | **✓** +`PUT` [更新组件](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/update) /open-apis/cardkit/v1/cards/:card_id/elements/:element_id | 创建与更新卡片(cardkit:card:write) | `tenant_access_token` | **✓** | **✓** +`PATCH` [更新组件属性](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/patch) /open-apis/cardkit/v1/cards/:card_id/elements/:element_id | 创建与更新卡片(cardkit:card:write) | `tenant_access_token` | **✓** | **✓** +`PUT` [流式更新文本](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/content) /open-apis/cardkit/v1/cards/:card_id/elements/:element_id/content | 创建与更新卡片(cardkit:card:write) | `tenant_access_token` | **✓** | **✓** +`DELETE` [删除组件](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/delete) /open-apis/cardkit/v1/cards/:card_id/elements/:element_id | 创建与更新卡片(cardkit:card:write) | `tenant_access_token` | **✓** | **✓** diff --git a/embedded-skills/lark-card-designer/docs/raw/client-docs__bot-v3__add-custom-bot.md b/embedded-skills/lark-card-designer/docs/raw/client-docs__bot-v3__add-custom-bot.md new file mode 100644 index 0000000..59e68a1 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/client-docs__bot-v3__add-custom-bot.md @@ -0,0 +1,801 @@ +# 自定义机器人使用指南 + +自定义机器人是一种只能在当前群聊中使用的机器人。该类机器人无需经过租户管理员审核,即可在当前群聊中通过调用 webhook 地址的方式完成消息推送。本文主要介绍自定义机器人的使用方式。 + +## 注意事项 + +- 自定义机器人只能在当前群聊内使用,同一个自定义机器人无法添加到其他群聊。 + +- 你需要具备一定的服务端开发基础,通过请求调用自定义机器人的 webhook 地址,实现消息推送功能。 + +- 自定义机器人在添加至群组后即可使用,无需租户管理员审核。该特性提升了开发机器人的便携性,但出于租户数据安全考虑,也限制了自定义机器人的使用场景,自定义机器人不具有任何数据访问权限。 + +- 如果你希望实现机器人群管理、获取用户信息等能力,建议参考[开发卡片交互机器人](https://open.feishu.cn/document/uAjLw4CM/uMzNwEjLzcDMx4yM3ATM/develop-a-card-interactive-bot/introduction),通过机器人应用实现。自定义机器人和机器人应用的能力对比,请参见[能力对比](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/bot-v3/bot-overview#6994dff4)。 + +- 自定义机器人的频率控制和普通应用不同,为单租户单机器人 100 次/分钟,5 次/秒。**建议发送消息尽量避开诸如 10:00、17:30 等整点及半点时间**,否则可能出现因系统压力导致的 11232 限流错误,导致消息发送失败。 + +- 发送消息时,请求体的数据大小不能超过 20 KB。 + +## 功能介绍 + +企业存在给特定群组自动推送消息的场景,例如,推送监控报警、销售线索、运营内容等。在该类场景下,你可以在群组中添加自定义机器人,自定义机器人默认提供 webhook,通过服务端调用 webhook 地址,即可将外部系统的消息通知即时推送到群组中。自定义机器人也包含了 **自定义关键词**、**IP 白名单** 和 **签名** 三种维度的安全配置,便于控制 webhook 的调用范围。 + +自定义机器人消息推送示例,如下图所示: + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/2b47757342ff761b33b92272125e5090_BFz2mPZ3QU.png?height=321&lazyload=true&maxWidth=600&width=883) + +## 在群组中添加自定义机器人 + +### 操作步骤 + +1. 邀请自定义机器人进群。 + 1. 进入目标群组,在群组右上角点击更多按钮,并点击 **设置**。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/0704e334f450754076202b574be3dff1_kQEGlTTPj7.png?height=1242&lazyload=true&maxWidth=600&width=1824) + +2. 在右侧 **设置** 界面,点击 **群机器人**。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/8ddf497adeeb5e42d4faf91a0955649f_3PaZ3J9uwz.png?height=1240&lazyload=true&maxWidth=600&width=1810) + +3. 在 **群机器人** 界面点击 **添加机器人**。 + +4. 在 **添加机器人** 对话框,找到并点击 **自定义机器人**。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/a9f4e16ea91fd15a272b0ba926e4c2fd_k0hrjUtKqR.png?height=1106&lazyload=true&maxWidth=600&width=1652) + +5. 设置自定义机器人的头像、名称与描述,并点击 **添加**。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/71f2339063c24779f13a9710bb4a0f6e_cVn7wSbnq2.png?height=1144&lazyload=true&maxWidth=600&width=1656) + +2. 获取自定义机器人的 webhook 地址,并点击 **完成**。 + +机器人对应的 **webhook 地址** 格式如下: + +``` + https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxxxxxxxxxxx + ```warning +**请妥善保存好此 webhook 地址**,不要公布在 Gitlab、博客等可公开查阅的网站上,避免地址泄露后被恶意调用发送垃圾消息。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/39d1233fc3276c71f6fce9707abf05c9_YdZveIV7gm.png?height=1134&lazyload=true&maxWidth=600&width=1654) + +后续你可以在群组名称右侧点击机器人图片,进入自定义机器人详情页,管理自定义机器人的配置信息。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/6370938ba204435cf190a93a53bd4d83_GKfn5wQXke.png?height=1478&lazyload=true&maxWidth=600&width=2284) + +3. 测试调用自定义机器人的 webhook 地址,向所在群组发送消息。 + +1. 用任意方式向 webhook 地址发起一个 HTTP POST 请求。 + +你需要具备一定的服务端开发基础,通过服务端 HTTP POST 请求方式调用 webhook 地址。以 curl 指令为例,请求示例如下。你可以通过 macOS 系统的终端,或者 Windows 系统的控制台应用,执行以下命令进行测试。 + +- macOS + +```bash + curl -X POST -H "Content-Type: application/json" \ + -d '{"msg_type":"text","content":{"text":"request example"}}' \ + https://open.feishu.cn/open-apis/bot/v2/hook/**** + ``` + +- Windows(cmd) + +```bash + curl -X POST -H "Content-Type: application/json" -d "{\"msg_type\":\"text\",\"content\":{\"text\":\"request example\"}}" https://open.feishu.cn/open-apis/bot/v2/hook/**** + ``` + +- Windows(PowerShell) + +```bash + curl.exe -X POST -H "Content-Type: application/json" -d '{\"msg_type\":\"text\",\"content\":{\"text\":\"requestexample\"}}' https://open.feishu.cn/open-apis/bot/v2/hook/**** + ``` + +示例命令说明: + +- 请求方式:`POST` + +- 请求头:`Content-Type: application/json` + +- 请求体:`{"msg_type":"text","content":{"text":"request example"}}` + +- webhook 地址:`https://open.feishu.cn/open-apis/bot/v2/hook/****` 为示例值,你在实际调用时需要替换为自定义机器人真实的 webhook 地址。 + +向自定义机器人发送请求时,支持发送文本、富文本、群名片以及消息卡片等多种消息类型。各类消息类型的请求说明,参见[支持发送的消息类型说明](#支持发送的消息类型说明)。 + +执行命令后: + +- 如果请求成功,命令行将会回显以下信息。 + +```json + { + "StatusCode": 0, //冗余字段,用于兼容存量历史逻辑,不建议使用 + "StatusMessage": "success", //冗余字段,用于兼容存量历史逻辑,不建议使用 + "code": 0, + "data": {}, + "msg": "success" + } + ``` + +- 如果请求体格式错误,则会返回以下信息。 + +```json + { + "code": 9499, + "msg": "Bad Request", + "data": {} + } + ``` + +你可以通过以下说明,检查请求体是否存在问题。 + +- 请求体内容格式是否与各消息类型的示例代码一致。 + +- 请求体大小不能超过 20 K。 + +2. 命令执行后,进入自定义机器人所在群组查看测试消息。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/b0c9862f7c53d6c3c7d1cdec150539c1_BImB3MewXE.png?height=244&lazyload=true&maxWidth=600&width=972) + +### 后续步骤 + +成功添加自定义机器人后,推荐你为自定义机器人添加安全设置,以保证机器人接收请求的安全性。具体操作参见下文[为自定义机器人添加安全设置](#为自定义机器人添加安全设置)。 + +## 为自定义机器人添加安全设置 + +在群组中添加自定义机器人后,你可以为机器人添加安全设置。安全设置用于保护自定义机器人不被恶意调用,例如,当 webhook 地址因保管不当而泄露后,可能会被恶意开发者调用发送垃圾信息。通过添加安全设置,只有在符合安全设置条件的情况下,才可以成功调用机器人。 + +目前提供的安全设置方式如下: +- 我们强烈建议为自定义机器人添加安全设置,以提高安全性。 + +- 在同一个自定义机器人中,你可以设置一个或多个方法。 + +- 自定义关键词:只有包含至少一个关键词的消息,可以成功发送。 + +- IP 白名单:只有在白名单内的 IP 地址,可以成功请求 webhook 发送消息。 + +- 签名校验:设置签名。发送的请求必须通过签名校验,才可以成功请求 webhook 发送消息。 + +### 方式一:设置自定义关键词 + +1. 在群组名称右侧点击机器人图标,打开机器人列表,找到自定义机器人并点击进入配置页面。 + +你也可以在群组设置中打开机器人列表。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/6370938ba204435cf190a93a53bd4d83_GKfn5wQXke.png?height=1478&lazyload=true&maxWidth=600&width=2284) + +2. 在 **安全设置** 区域,选择 **自定义关键词**。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/f239c67354d657b61822d9e52aac42ee_bvXPZpluyQ.png?height=1134&lazyload=true&maxWidth=600&width=1650) + +3. 在输入框添加关键词。 + +- 最多可以同时设置 10 个关键词,多个关键词之间使用回车键间隔。设置后,只有包含至少一个关键词的消息才会被成功发送。 + +例如,关键词设置了 `应用报警` 与 `项目更新`,则请求 webhook 发送的消息内容需要至少包含 `应用报警` 或 `项目更新` 其中一个关键词。 + +- 设置关键词后,如果发送请求时自定义关键词校验失败,则会返回以下信息。 + +```json + // 关键词校验失败 + { + "code": 19024, + "msg": "Key Words Not Found" + } + ``` + +4. 点击 **保存**,使生效配置。warning +**注意**:自定义关键词只对 `text`、`title` 这类文本参数值生效。例如,发送富文本消息时包含超链接标签 `{"tag":"a","text":"请查看","href":"http://www.example.com/"}`,则自定义关键词只过滤 `text` 参数值,不会过滤 `href` 参数值。 + +### 方式二:设置 IP 白名单 + +1. 在群组名称右侧点击机器人图标,打开机器人列表,找到自定义机器人并点击进入配置页面。 + +你也可以在群组设置中打开机器人列表。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/6370938ba204435cf190a93a53bd4d83_GKfn5wQXke.png?height=1478&lazyload=true&maxWidth=600&width=2284) + +2. 在 **安全设置** 区域,选择 **IP 白名单**。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/bc3b9622a9e80ed161658dbf4bb32bcd_eUGpv9hYsu.png?height=1134&lazyload=true&maxWidth=600&width=1646) + +3. 在输入框添加 IP 地址。 + +- 支持添加 IP 地址或地址段,最多可设置 10 个,使用回车键间隔。支持段输入,例如 `123.12.1.*` 或 `123.1.1.1/24`。设置后,机器人 webhook 地址只处理来自 IP 白名单范围内的请求。 + +- 设置 IP 白名单后,白名单之外的 IP 地址请求 webhook 时会校验失败,并返回以下信息。 + +```json + // IP校验失败 + { + "code": 19022, + "msg": "Ip Not Allowed" + } + ``` + +4. 点击 **保存**,使配置生效。 + +### 方式三:设置签名校验 + +1. 在群组名称右侧点击机器人图标,打开机器人列表,找到自定义机器人并点击进入配置页面。 + +你也可以在群组设置中打开机器人列表。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/6370938ba204435cf190a93a53bd4d83_GKfn5wQXke.png?height=1478&lazyload=true&maxWidth=600&width=2284) + +2. 在 **安全设置** 区域,选择 **签名校验**。 + +选择签名校验后,系统已默认提供了一个秘钥。你也可以点击 **重置**,更换秘钥。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/f18a644caf39b0ba7ad58a88758a6183_rkhZ9XrUTB.png?height=1130&lazyload=true&maxWidth=600&width=1648) + +3. 点击 **复制**,复制秘钥。 + +4. 点击 **保存**,使配置生效。 + +5. 计算签名字符串。 + +设置签名校验后,向 webhook 发送请求需要签名校验来保障来源可信。所校验的签名需要通过时间戳与秘钥进行算法加密,即将`timestamp + "\n" + 密钥`当做签名字符串,使用 HmacSHA256 算法计算空字符串的签名结果,再进行 Base64 编码。其中,`timestamp`是指距当前时间不超过 1 小时(3600 秒)的时间戳,时间单位:s。例如,1599360473。 + +本文提供了以下不同语言的代码示例,用于计算获得签名字符串。 + +- Java 示例代码 + +```java + package sign; + +import javax.crypto.Mac; + import javax.crypto.spec.SecretKeySpec; + import java.nio.charset.StandardCharsets; + import java.security.InvalidKeyException; + import java.security.NoSuchAlgorithmException; + import org.apache.commons.codec.binary.Base64; + +public class SignDemo { + public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException { + +String secret = "demo"; + int timestamp = 1599360473; + System.out.printf("sign: %s", GenSign(secret, timestamp)); + +} + private static String GenSign(String secret, int timestamp) throws NoSuchAlgorithmException, InvalidKeyException { + //把timestamp+"\n"+密钥当做签名字符串 + String stringToSign = timestamp + "\n" + secret; + +//使用HmacSHA256算法计算签名 + Mac mac = Mac.getInstance("HmacSHA256"); + mac.init(new SecretKeySpec(stringToSign.getBytes(StandardCharsets.UTF_8), "HmacSHA256")); + byte[] signData = mac.doFinal(new byte[]{}); + return new String(Base64.encodeBase64(signData)); + } + +} + ``` + +- Go 示例代码 + +```go + func GenSign(secret string, timestamp int64) (string, error) { + //timestamp + key 做sha256, 再进行base64 encode + stringToSign := fmt.Sprintf("%v", timestamp) + "\n" + secret + +var data []byte + h := hmac.New(sha256.New, []byte(stringToSign)) + _, err := h.Write(data) + if err != nil { + return "", err + } + +signature := base64.StdEncoding.EncodeToString(h.Sum(nil)) + return signature, nil + } + ``` + +- Python 示例代码 + +```Python + import hashlib + import base64 + import hmac + +def gen_sign(timestamp, secret): + # 拼接timestamp和secret + string_to_sign = '{}\n{}'.format(timestamp, secret) + hmac_code = hmac.new(string_to_sign.encode("utf-8"), digestmod=hashlib.sha256).digest() + +# 对结果进行base64处理 + sign = base64.b64encode(hmac_code).decode('utf-8') + +return sign + ``` + +6. 获取签名字符串。 + +以 Java 示例代码为例,获取当前时间戳以及密钥后,运行程序获得签名字符串。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/9578d3d77db27be88a572f0e67247607_M9dq4bZ89d.png?height=1234&lazyload=true&maxWidth=600&width=2090) + +获取签名字符串后,在向 webhook 发送请求时,需要加上时间戳(timestamp)和签名字符串(sign)字段信息。示例配置如下所示。 + +```json + // 开启签名验证后发送文本消息 + { + "timestamp": "1599360473", // 时间戳。 + "sign": "xxxxxxxxxxxxxxxxxxxxx", // 得到的签名字符串。 + "msg_type": "text", + "content": { + "text": "request example" + } + } + ``` + +如果发送请求时校验失败,你可以通过以下说明排查问题。 + +- 所使用的时间戳距离发送请求的时间已间隔 1 小时以上,签名已过期。 + +- 服务器时间与标准时间有较大偏差,导致签名过期。请注意检查、校准你的服务器时间。 + +- 签名不匹配导致的校验不通过,将返回以下信息。 + +```json + // 签名校验失败 + { + "code": 19021, + "msg": "sign match fail or timestamp is not within one hour from current time" + } + ``` + +## 删除自定义机器人 + +在飞书群组的 **设置** 中,打开 **群机器人** 列表,找到需要删除的自定义机器人,在卡片右侧点击删除图标。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/6e679de30f0ed674e2e5ef2f7551d5b0_bT6AripRP6.png?height=568&lazyload=true&maxWidth=600&width=1814) + +## 支持发送的消息类型说明 + +向自定义机器人 webhook 地址发送 POST 请求时,支持推送的消息格式有 **文本**、**富文本**、**图片消息** 以及 **群名片** 等,本章节介绍各消息类型的请求格式与展示效果。 + +### 发送文本消息 + +#### 请求消息体示例 + +```json +{ + "msg_type": "text", + "content": { + "text": "新更新提醒" + } +} +``` + +#### 实现效果 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/a2b95a3c351914e04ee47c6c00456065_TMMOAkNFNF.png?height=216&lazyload=true&maxWidth=600&width=916) + +#### 参数说明 + +- 参数 `msg_type` 值为对应消息类型的映射关系,文本消息的 `msg_type` 对应值为 `text`。 + +- 参数 `content` 包含消息内容,文本消息的消息内容参数说明如下表所示。 + +| **字段** | **类型** | **是否必填** | **示例值** | **描述** | + | ------ | ------ | -------- | ------------ | ------ | + | text | string | 是 | Test content | 文本内容。 | + +#### 文本消息的 @ 用法 + +```html +// @ 单个用户 +名字 +// @ 所有人 +所有人 +``` + +- @ 单个用户时,`user_id`字段需填入用户的 [Open ID](https://open.feishu.cn/document/uAjLw4CM/ugTN1YjL4UTN24CO1UjN/trouble-shooting/how-to-obtain-openid) 或 [User ID](https://open.feishu.cn/document/uAjLw4CM/ugTN1YjL4UTN24CO1UjN/trouble-shooting/how-to-obtain-user-id),且必须是有效值(仅支持 @ 自定义机器人所在群的群成员),否则取名字展示,并不产生实际的 @ 效果。 +**注意事项**:在外部群聊中,仅支持使用 Open ID @ 单个用户,不支持 User ID。 +- @ 所有人时,必须满足所在群开启 @ 所有人功能。 + +#### 文本消息 @ 用法示例 + +```json +{ + "msg_type": "text", + "content": { + "text": "Tom 新更新提醒" + } +} +``` + +### 发送富文本消息 + +富文本消息是指包含文本、超链接、图标等多种文本样式的复合文本信息。 + +#### 请求消息体示例 + +```json +{ + "msg_type": "post", + "content": { + "post": { + "zh_cn": { + "title": "项目更新通知", + "content": [ + [{ + "tag": "text", + "text": "项目有更新: " + }, { + "tag": "a", + "text": "请查看", + "href": "http://www.example.com/" + }, { + "tag": "at", + "user_id": "ou_18eac8********17ad4f02e8bbbb" + }] + ] + } + } + } +} +``` + +#### 实现效果 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/4470e4b7ae2926068a51d3b3d8df22bc_6tVLxfqvEh.png?height=246&lazyload=true&maxWidth=600&width=890) + +#### 参数说明 + +- 参数 `msg_type` 值为对应消息类型的映射关系,富文本消息的 `msg_type` 对应值为 `post`。 + +- 参数 `content` 包含消息内容,文本消息的消息内容参数说明如下表所示。 + +| **字段** | **类型** | **是否必填** | **示例值** | **描述** | + | ------- | ------ | -------- | ------- | --------------------------------------------------------------------------------------- | + | post | object | 是 | none | 富文本消息。 | + | ∟ zh_cn | object | 是 | none | `zh_cn`、`en_us` 分别是富文本的中、英文配置,富文本消息中至少需要包含一种语言的配置。包含的参数说明,参见下文的《`zh_cn`、`en_us` 字段说明表》。 | + | ∟ en_us | object | 是 | none | `zh_cn`、`en_us` 分别是富文本的中、英文配置,富文本消息中至少需要包含一种语言的配置。包含的参数说明,参见下文的《`zh_cn`、`en_us` 字段说明表》。 | + +- `zh_cn`、`en_us` 字段说明表。 + +| **字段** | **类型** | **是否必填** | **示例值** | **描述** | + | ------- | ------------ | -------- | -------------------------------------------- | ---------------------------------------- | + | title | string | 否 | Test title | 富文本消息的标题。 | + | content | []paragraph | 是 | [[{"tag": "text","text": "text content"}]] | 富文本消息内容。由多个段落组成,每个段落为一个`[]`节点,其中包含若干个节点。 | + +#### 富文本支持的标签和参数说明 + +**文本标签:text** + +| **字段** | **类型** | **是否必填** | **示例值** | **描述** | +| --------- | ------- | -------- | ------------ | ----------------------------------------------- | +| text | string | 是 | Text content | 文本内容。 | +| un_escape | boolean | 否 | false | 表示是否 unescape 解码。默认值为 false,未用到 unescape 时可以不填。 | + +**超链接标签:a** + +| **字段** | **类型** | **是否必填** | **示例值** | **描述** | +| ------ | ------ | -------- | ----------------------- | -------------------------------- | +| text | string | 是 | 测试地址 | 超链接的文本内容。 | +| href | string | 是 | https://open.feishu.cn | 默认的链接地址,你需要确保链接地址的合法性,否则消息会发送失败。 | + +**@ 标签:at** + +| **字段** | **类型** | **是否必填** | **示例值** | **描述** | +| --------- | ------ | -------- | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| user_id | string | 是 | ou_18eac85d35a26****02e8bbbb | 用户的 [Open ID](https://open.feishu.cn/document/home/user-identity-introduction/open-id) 或 [User ID](https://open.feishu.cn/document/uAjLw4CM/ugTN1YjL4UTN24CO1UjN/trouble-shooting/how-to-obtain-user-id)。
- @ 单个用户时,`user_id`字段必须是有效值(仅支持 @ 自定义机器人所在群的群成员)。
- @ 所有人时,填 `all`。 | +| user_name | string | 否 | Jian Li | 用户名称。 | + +**图片标签:img** + +| **字段** | **类型** | **是否必填** | **示例值** | **描述** | +| --------- | ------ | -------- | -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | +| image_key | string | 是 | d640eeea-4d2f-4cb3-88d8-c96fa5**** | 图片的唯一标识。可通过 [上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create) 接口获取 image_key。 | + +### 发送群名片 +机器人只能分享其所在群的群名片。 +#### 请求消息体示例 + +```json +{ + "msg_type": "share_chat", + "content":{ + "share_chat_id": "oc_f5b1a7eb27ae2****339ff" + } +} +``` + +#### 实现效果 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/f214f68f1fa9a44a181e14cedf6cef73_5F5IeT5z4Y.png?height=346&lazyload=true&maxWidth=600&width=958) + +#### 参数说明 + +| **字段** | **类型** | **是否必填** | **示例值** | **描述** | +| ------------- | ------ | -------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------ | +| share_chat_id | string | 是 | oc_f5b1a7eb27ae2****339ff | 群 ID。获取方式请参见 [群 ID 说明](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/chat-id-description)。 | + +### 发送图片 + +#### 请求消息体示例 + +```json +{ + "msg_type":"image", + "content":{ + "image_key": "img_ecffc3b9-8f14-400f-a014-05eca1a4310g" + } +} +``` + +#### 实现效果 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/2ac61380d8405b5579cb7fb7a5fb295e_JaNDWmDCgW.png?height=580&lazyload=true&maxWidth=600&width=896) + +#### 参数说明 + +| **字段** | **类型** | **是否必填** | **示例值** | **描述** | +| --------- | ------ | -------- | ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | +| image_key | string | 是 | img_ecffc3b9-8f14-400f-a014-05eca1a4310g | 图片Key。可通过 [上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create) 接口获取 image_key。 | + +### 发送飞书卡片 + +飞书卡片是一种轻量的消息推送应用,可由按钮、图片等多种组件搭建而成。了解飞书卡片,参考[飞书卡片概述](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-overview)。了解如何使用自定义机器人发送由搭建工具搭建的卡片模板(template),参考[使用自定义机器人发送飞书卡片](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/quick-start/send-message-cards-with-custom-bot)。 + +#### **注意事项** + +- 通过自定义机器人发送的消息卡片,只支持通过按钮、文字链方式跳转 URL,不支持点击后回调信息到服务端的[请求回调交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/configuring-card-interactions#5746ae32)。 + +- 在飞书卡片中如果需要 @ 某一用户,则需要注意:自定义机器人仅支持通过 [Open ID](https://open.feishu.cn/document/uAjLw4CM/ugTN1YjL4UTN24CO1UjN/trouble-shooting/how-to-obtain-openid) 或 [User ID](https://open.feishu.cn/document/uAjLw4CM/ugTN1YjL4UTN24CO1UjN/trouble-shooting/how-to-obtain-user-id) 实现 @ 用户,暂不支持`email`、`union_id`等其他方式。 + +- 发送卡片时,需要将消息体的 `content` 字符串替换为 `card` 结构体,并对整个请求消息体进行 JSON 转义。 + +#### **请求消息体示例** + +```json +{ + "msg_type": "interactive", + "card": { + "schema": "2.0", + "config": { + "update_multi": true, + "style": { + "text_size": { + "normal_v2": { + "default": "normal", + "pc": "normal", + "mobile": "heading" + } + } + } + }, + "body": { + "direction": "vertical", + "padding": "12px 12px 12px 12px", + "elements": [ + { + "tag": "markdown", + "content": "西湖,位于中国浙江省杭州市西湖区龙井路1号,杭州市区西部,汇水面积为21.22平方千米,湖面面积为6.38平方千米。", + "text_align": "left", + "text_size": "normal_v2", + "margin": "0px 0px 0px 0px" + }, + { + "tag": "button", + "text": { + "tag": "plain_text", + "content": "🌞更多景点介绍" + }, + "type": "default", + "width": "default", + "size": "medium", + "behaviors": [ + { + "type": "open_url", + "default_url": "https://baike.baidu.com/item/%E8%A5%BF%E6%B9%96/4668821", + "pc_url": "", + "ios_url": "", + "android_url": "" + } + ], + "margin": "0px 0px 0px 0px" + } + ] + }, + "header": { + "title": { + "tag": "plain_text", + "content": "今日旅游推荐" + }, + "subtitle": { + "tag": "plain_text", + "content": "" + }, + "template": "blue", + "padding": "12px 12px 12px 12px" + } + } +} +``` + +以上消息体压缩并转义的结果如下所示,你可将其放入 CURL 命令中的请求体中查看效果: + +``` +{\"msg_type\":\"interactive\",\"card\":{\"schema\":\"2.0\",\"config\":{\"update_multi\":true,\"style\":{\"text_size\":{\"normal_v2\":{\"default\":\"normal\",\"pc\":\"normal\",\"mobile\":\"heading\"}}}},\"body\":{\"direction\":\"vertical\",\"padding\":\"12px 12px 12px 12px\",\"elements\":[{\"tag\":\"markdown\",\"content\":\"西湖,位于中国浙江省杭州市西湖区龙井路1号,杭州市区西部,汇水面积为21.22平方千米,湖面面积为6.38平方千米。\",\"text_align\":\"left\",\"text_size\":\"normal_v2\",\"margin\":\"0px 0px 0px 0px\"},{\"tag\":\"button\",\"text\":{\"tag\":\"plain_text\",\"content\":\"🌞更多景点介绍\"},\"type\":\"default\",\"width\":\"default\",\"size\":\"medium\",\"behaviors\":[{\"type\":\"open_url\",\"default_url\":\"https://baike.baidu.com/item/%E8%A5%BF%E6%B9%96/4668821\",\"pc_url\":\"\",\"ios_url\":\"\",\"android_url\":\"\"}],\"margin\":\"0px 0px 0px 0px\"}]},\"header\":{\"title\":{\"tag\":\"plain_text\",\"content\":\"今日旅游推荐\"},\"subtitle\":{\"tag\":\"plain_text\",\"content\":\"\"},\"template\":\"blue\",\"padding\":\"12px 12px 12px 12px\"}}} +``` +#### 实现效果 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/2b47757342ff761b33b92272125e5090_BFz2mPZ3QU.png?height=321&lazyload=true&maxWidth=600&width=883) + +#### 相关操作 + +你可以通过[飞书卡片搭建工具](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/feishu-cardkit-overview)快速生成卡片,并获取数据结构进行使用,从工具中生成的数据结构对应请求消息体中的 `card` 字段。 + +## 常见问题 + +### 如何实现 @ 指定人、@ 所有人? + +你可以在机器人发送的普通文本消息(text)、富文本消息(post)、消息卡片(interactive)中,使用 `at` 标签实现 @ 人效果。具体请求示意如下: + +- 在普通文本消息(text)中 @ 人、@ 所有人 + +- `at`标签说明 + +```html + // @ 指定用户 + Name //取值须使用 open_id 或 user_id 来 @ 指定人 + +// @ 多个指定用户 + Name1Name2 //取值须使用 open_id 或 user_id 来 @ 指定人 + +// @ 所有人 + 所有人 + ``` + +- 请求体示意 + +```json + { + "msg_type": "text", + "content": { + "text": "Tom text content" + } + } + ``` + +- 在富文本消息(post)中 @ 人、@所有人: + +- `at`标签说明 + +```json + // @ 指定用户 + { + "tag": "at", + "user_id": "ou_xxxxxxx", //取值须使用 open_id 或 user_id 来 @ 指定人 + "user_name": "tom" + } + +// @ 多个指定用户 + { + "tag": "at", + "user_id": "ou_xxxxxxx1", //取值须使用 open_id 或 user_id 来 @ 指定人 + "user_name": "tom1" + }, + { + "tag": "at", + "user_id": "ou_xxxxxxx2", //取值须使用 open_id 或 user_id 来 @ 指定人 + "user_name": "tom2" + } + +// @ 所有人 + { + "tag": "at", + "user_id": "all", //取值使用"all"来at所有人 + "user_name": "所有人" + } + ``` + +- 请求体示意 + +```json + { + "msg_type": "post", + "content": { + "post": { + "zh_cn": { + "title": "我是一个标题", + "content": [ + [{ + "tag": "text", + "text": "第一行 :" + }, + { + "tag": "at", + "user_id": "ou_xxxxxx", //取值须使用 open_id 或 user_id 来 @ 指定人 + "user_name": "tom" + } + ], + [{ + "tag": "text", + "text": "第二行:" + }, + { + "tag": "at", + "user_id": "all", + "user_name": "所有人" + } + ] + ] + } + } + } + } + ``` + +- 在消息卡片 (interactive) 中@人、@所有人 + +- 可以使用消息卡片Markdown内容中的at人标签,标签示意如下 + +```html + // at 指定用户 + //取值须使用 open_id 或 user_id 来 @ 指定人 + // at 所有人 + + ``` + +- 请求体中的 `card` 内容示意: + +```json + { + "msg_type": "interactive", + "card": { + "elements": [{ + "tag": "div", + "text": { + "content": "at所有人 \n at指定人", //取值须使用 open_id 或 user_id 来 @ 指定人 + "tag": "lark_md" + } + }] + } + } + ``` + +### 如何获得 @ 指定人时所需要的 open_id? + +自定义机器人不需要租户管理员审核即可向所在的群(包括外部群)发送消息。这一开发上的灵活性也限制自定义机器人不具有任何数据访问权限,否则会在管理员不知情的条件下,泄露租户的隐私信息. + +基于这个前提,自定义机器人本身不能调用接口获取用户的 open_id,或直接通过用户的邮箱、手机号来 @ 人(恶意开发者可能用这种方式扫出群成员的头像、姓名等隐私信息)。因此,你可以开发一个机器人应用,使用以下受管控的方案获得用户的`open_id`,然后参考 [怎么实现机器人 @ 人](https://open.feishu.cn/document/ugTN1YjL4UTN24CO1UjN/uUzN1YjL1cTN24SN3UjN#acc98e1b),在自定义机器人推送的消息中 @ 人。 + +**方案一:通过邮箱或手机号反查用户的**`open_id` + +1. 你需要[创建一个自建应用](https://open.feishu.cn/document/home/introduction-to-custom-app-development/self-built-application-development-process)。 + +2. 为应用申请权限。 + +通过手机号或邮箱获取用户 ID(contact:user.id:readonly),并创建应用版本,提交发版审核。 + +3. 在版本发布审核通过后,调用[通过手机号或邮箱获取用户 ID](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/contact-v3/user/batch_get_id)接口,即可通过用户的手机号或邮箱获取用户的`open_id`。 + +**方案二:解析用户发送给机器人的带 @ 人内容的消息,获取目标用户的 `open_id`** + +1. 你需要[创建一个自建应用](https://open.feishu.cn/document/home/introduction-to-custom-app-development/self-built-application-development-process)。 + +2. 完成以下应用配置操作。 + +1. 为应用申请权限:获取用户发给机器人的单聊消息(im:message.p2p_msg)、获取与发送单聊、群组消息(im:message)。 + +2. 订阅 **消息与群组** 分类下的[接收消息](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/events/receive)事件。 + +3. 为这个自建应用创建应用版本,提交发版审核。 + +4. 在版本审核发布后,你可以在同机器人的单聊中发送 @ 某用户的消息。解析[接收消息](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/events/receive)事件的返回内容,其中的消息体内上报了被 @ 用户的`open_id`信息。 + +### 自定义机器人能响应用户消息吗? + +不能,自定义机器人只能用于在群聊中自动发送通知,不能响应用户 @ 机器人的消息。如需实现机器人接收响应用户消息的功能,建议使用[应用机器人](https://open.feishu.cn/document/ukTMukTMukTM/uATM04CMxQjLwEDN)。 + +### 如何撤回自定义机器人发送的消息? + +自定义机器人自身无法撤回自己发送的消息,必须由群聊内的群主或管理员进行撤回。撤回方式: + +- 方式一:群聊的群主或管理员在飞书客户端的群聊中直接撤回消息。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/e685a9fff074339291a64c04758866cc_dgAwKA3Pr3.png?height=836&lazyload=true&maxWidth=600&width=1812) + +- 方式二:调用[撤回消息](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/delete)接口,以群聊的群主或管理员身份调用该接口撤回消息。 diff --git a/embedded-skills/lark-card-designer/docs/raw/common-capabilities__message-card__introduction-of-message-cards.md b/embedded-skills/lark-card-designer/docs/raw/common-capabilities__message-card__introduction-of-message-cards.md new file mode 100644 index 0000000..f8b5932 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/common-capabilities__message-card__introduction-of-message-cards.md @@ -0,0 +1,22 @@ +# 消息卡片概述 + +飞书消息卡片是一种轻量的消息推送应用,能够帮助你实现一对多的信息触达方式,提高工作效率。 +在保持旧版消息卡片原有能力的基础上,飞书消息卡片进行了全面升级。你可参考[飞书卡片更新说明](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-release-notes)和[飞书卡片概述](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-overview)文档了解更新内容。 +## 什么是消息卡片 + +飞书消息卡片是飞书中的一种功能,它允许用户通过机器人或应用以结构化(JSON)的方式发送和接收消息。你可以通过以下视频介绍了解消息卡片的基本概念。 + +## 使用场景 + +* **静态消息卡片** + +飞书消息卡片能够自动根据聊天窗口大小,调整内容布局,保证展示空间的利用率。在静态内容中支持包括文本格式、图文混排布局的呈现能力。并且支持根据用户飞书语言环境,配置对应的国际化语言版本。详情可参考[快速了解消息卡片](https://open.feishu.cn/document/home/build-a-beautiful-message-card-in-5-minutes/add-interaction)。 + +如果你是运维工程师,你可以通过卡片及时推送**运维报警**,并直接在卡片上提交报警处理、屏蔽报警操作。 +
+ +## 如何发送消息卡片 + +你可以参考以下流程图,选择消息卡片发送方式然后发送消息卡片,详细操作步骤可参考[如何发送消息卡片](https://open.feishu.cn/document/ukTMukTMukTM/uAzMxEjLwMTMx4CMzETM)。 + +![消息卡片概述-中文.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/7f2f7077e6a30912e88b6b1b5675c3c1_zfU9pQdmWO.png?height=448&lazyload=true&maxWidth=750&width=2242) diff --git a/embedded-skills/lark-card-designer/docs/raw/develop-a-card-interactive-bot__card-building-steps.md b/embedded-skills/lark-card-designer/docs/raw/develop-a-card-interactive-bot__card-building-steps.md new file mode 100644 index 0000000..7410f4d --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/develop-a-card-interactive-bot__card-building-steps.md @@ -0,0 +1,64 @@ +# 卡片搭建说明 + +本文档介绍如何从 0 到 1 搭建卡片交互机器人教程中的三张卡片。通过本文档,你可了解搭建卡片、传入变量、配置交互动作所需步骤及对应原因解释。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/1c941e0c0724fcb0d550ad9431271892_YTNcLhl9Fn.png?height=412&lazyload=true&maxWidth=600&width=1121) + +## 搭建欢迎卡片 + +本步骤介绍搭建欢迎卡片的具体流程,包括搭建结构、配置内容和样式、配置组件的变量、交互动作和多语言。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/fdd6f55034a6ee0b90d16e3d5c44a178_0ieqcY3bjk.png?height=411&lazyload=true&maxWidth=400&width=815) + +步骤 | 搭建步骤 | 说明 | 具体操作(本教程已经自动完成以下配置) +---|---|---|--- +1 | 基于案例库创建卡片 | 基于案例库提供的卡片,你可了解常用组件的搭建方式,快速构建卡片。了解更多,参考[构建卡片内容](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/build-card-content)。 | 1. 在[飞书卡片搭建工具](https://open.feishu.cn/cardkit?from=open_docs_tutorial)首页,点击 **参考案例库**。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/72d387a8a22b35bde24446cd5a5fe25e_psfFyNdgaE.png?height=664&lazyload=true&maxWidth=500&width=1750)
2. 在 **参考案例库** 弹窗 **新版专区** 页面,找到 **欢迎卡片**,并点击 **使用**。
**提示**:新版专区的卡片新增 20+ 卡片能力。了解新旧版本卡片区别,参考[搭建工具新版卡片变更说明](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/cardkit-upgraded-version-card-release-notes)。
4. 将卡片名称设为 **欢迎卡片**,然后点击 **创建**。你将进入卡片的编辑页面。 +2 | 搭建卡片结构 | 一张新版卡片由标题(可选)组件和正文组成。正文中可放置其它多个组件。搭建卡片时,你可先设计卡片大纲,明确卡片基本结构,再填充内容。欢迎卡片的大纲如下所示:
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/4130453da6a9cdda5278997051deeea6_nEOrRAAit7.png?height=476&lazyload=true&maxWidth=200&width=340)
其中:
- 富文本、分割线组件为展示组件
- 分栏组件中用于更好布局卡片中的内容,可以添加多个列容器,每个列容器中可内嵌多个组件
- 按钮组件用于实现卡片的交互 | 要体验从 0 到 1 搭建欢迎卡片,你可参考以下步骤:
1. 在卡片编辑页面左侧 **组件** 页签下,依次点击标题、富文本、分割线、富文本、分栏、按钮、按钮组件。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/8f2d8adedc019b8684f33dc674e702c6_WS8TJjn2mu.png?height=798&lazyload=true&maxWidth=500&width=1541)
此时,卡片大纲树如下所示:
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/0c010f64ec81816118f09087a7dc9b93_MsQ60nZeWQ.png?height=489&lazyload=true&maxWidth=200&width=265)
3. 选中大纲树分栏中的 **列** 容器,然后点击卡片预览页面的删除按钮。保留一个列容器即可。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/51811ed2f093981457bda32e11b14009_Cfnf5RDRTe.png?height=620&lazyload=true&maxWidth=500&width=1303)
4. 选中两个按钮组件,将两个按钮组件分别拖拽放入列容器中。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/51b9795e820193d21bb42220d6d1f549_b0vrb4cU3p.gif?height=624&lazyload=true&maxWidth=500&width=1290)
5. 在左侧大纲树中选中 列 容器,在右侧配置页面,点击 样式 页签,在 **布局方式** 配置项中,选择 **流式**。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/eeb95bc97d2cb59d6d46dc231d54e87b_Z1T44FDtHL.png?height=761&lazyload=true&maxWidth=500&width=1920)
你已完成欢迎卡片基本结构和布局的构建,最终大纲如下所示:
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/c2d3209973344ac1fc1f85db6ea409fa_FpVC0EWGGL.png?height=412&lazyload=true&maxWidth=200&width=310) +3 | 配置组件文本内容和样式 | 基于卡片可视化搭建工具,你可实时为组件填充文本内容、改变组件样式,并预览效果。 | 为富文本和按钮组件分别配置内容,可参考文档[富文本](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/rich-text)。 +4 | 配置组件变量 | 你可将变量理解为卡片内容的占位符。具体的内容或数据可在发送卡片时携带。如果你希望机器人发送欢迎卡片时能够显示@用户的效果,你可添加用户 ID 变量,在发送卡片的代码中携带用户的 [Open ID](https://open.feishu.cn/document/uAjLw4CM/ugTN1YjL4UTN24CO1UjN/trouble-shooting/how-to-obtain-openid)。详情参考[发送卡片](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/send-feishu-card)和[示例代码解释](https://open.feishu.cn/document/uAjLw4CM/uMzNwEjLzcDMx4yM3ATM/develop-a-card-interactive-bot/explanation-of-example-code)。 | 1. 在画布区域右上角,点击变量图标,弹出 **变量** 页面,点击 **添加自定义变量**。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/b2a299e4f570368a2bc409dcfba89add_tUCs1ckmgY.png?height=746&lazyload=true&maxWidth=500&width=1551)
1. 在添加变量弹窗中,按照下图,添加一个 `open_id` 变量。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/b9addd9941e9228b3a50b96c89c2d0e9_FsXuBNdlUq.png?height=739&lazyload=true&maxWidth=300&width=840)
1. 在富文本组件的文本内容中,将光标定位至富文本组件的 @ 人语法中,然后点击右下角的变量图标,添加 `open_id` 变量。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/d13f89ab8e99fe9e18cdc284420c7f9b_oxHWM02QOY.png?height=352&lazyload=true&maxWidth=300&width=391) +5 | 配置组件交互动作 | 为按钮配置请求回调动作后,当用户点击该按钮时,飞书会向你的服务端发送[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)回调,其中包含了用户的交互信息,例如,当用户点击 **去体验:发起告警** 按钮后,卡片回调交互信息中将携带如下参数:
```JSON
{
"action": { // 用户操作交互组件回传的数据
"tag": "button", // 交互组件的标签,此处为按钮
"value": { // 交互组件绑定的开发者自定义的回传参数,此处类型为开发者自定义的对象
"action": "send_alarm"
}
}
}
```
你可基于此配置,继续处理用户点击按钮后的代码逻辑,详情参考[示例代码解释](https://open.feishu.cn/document/uAjLw4CM/uMzNwEjLzcDMx4yM3ATM/develop-a-card-interactive-bot/explanation-of-example-code)。 | 1. 为 **去体验:发起告警** 按钮配置 **请求回调** 动作,输入参数如下所示。详情参考[配置请求回调交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/configuring-card-interactions#5746ae32)。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/92179b6c08f08adfe4e72ea271a824a2_bxJfKWZeoS.png?height=652&lazyload=true&maxWidth=500&width=1463)
1. 为 **查看教程** 按钮配置 **打开链接** 动作。详情参考[配置打开链接交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/configuring-card-interactions#3867b9c6)。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/ec3b9172c890fec23f2e358a8360ea56_mENfc1NnM6.png?height=714&lazyload=true&maxWidth=500&width=1561) +6 | 配置卡片多语言 | 如果你想配置多语言卡片,你可在搭建工具中实现不同语言内容的配置。案例库中的卡片为中英双语卡片。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/f3a0772e30d0ac4b06811fa227879978_4ucybu4du3.png?height=553&lazyload=true&maxWidth=500&width=1232) | 参考[为新版卡片配置多语言](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/configure-multi-language-content#882164bf)了解如何配置多语言。 + +## 搭建发起告警卡片 + +本步骤介绍发起告警卡片的具体流程,包括搭建结构和布局、配置内容和样式、配置组件的变量、交互动作和多语言。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/80aa3420c44f221e1826fa5799aab8c7_BngZwYleCA.png?height=395&lazyload=true&maxWidth=400&width=801) + +步骤 | 搭建步骤 | 说明 | 具体操作(本教程已经自动完成以下配置) +---|---|---|--- +1 | 基于案例库创建卡片 | 基于案例库提供的卡片,你可了解常用组件的搭建方式,快速构建卡片。了解更多,参考[构建卡片内容](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/build-card-content)。 | 1. 在[飞书卡片搭建工具](https://open.feishu.cn/cardkit?from=open_docs_tutorial)首页,点击 **参考案例库**。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/72d387a8a22b35bde24446cd5a5fe25e_b1j7SvUh1z.png?height=664&lazyload=true&maxWidth=500&width=1750)
1. 在 **参考案例库** 弹窗 **新版专区** 页面,找到 **发起告警** 卡片,并点击 **使用**。
**提示**:新版专区的卡片新增 20+ 卡片能力。了解新旧版本卡片区别,参考[搭建工具新版卡片变更说明](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/cardkit-upgraded-version-card-release-notes)。
1. 将卡片名称设为 **发起告警**,然后点击 **创建**。你将进入卡片的编辑页面。 +2 | 搭建卡片结构和布局 | 一张新版卡片由标题(可选)组件和正文组成。正文中可放置其它多个组件。搭建卡片时,你可先设计卡片大纲,明确卡片基本结构,再填充内容。发起告警卡片的大纲如下所示:
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/85ffe961a612a8fa06f77bcfaf0bba1d_1uNsohuyIH.png?height=750&lazyload=true&maxWidth=200&width=276)
其中:
- 分栏组件中用于布局卡片中的内容,分栏包含多个列容器,每个列容器中可内嵌多个组件
- 富文本、分割线组件为展示组件
- 表单容器用于用户提交数据场合,包含一个提交按钮、一个取消按钮。你也可在其中放置输入框、下拉选项组件等结合使用 | 要体验从 0 到 1 搭建发起告警卡片,你可参考以下步骤:
1. 在卡片编辑页面左侧 **组件** 页签下,依次点击左列大纲图中的组件:标题、分栏、富文本、富文本、分栏、富文本、富文本、分割线、表单容器、输入框。
卡片大纲树将如下所示:
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/a894d983f6d93776eb6054f9b6055934_ZRbHXNYhYc.png?height=529&lazyload=true&maxWidth=200&width=270)
1. 在画布中,分别删除两个分栏容器中的一个 **列** 容器,然后将四个富文本组件分别拖入剩下的四个列容器中。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/0213700d13f186967fa44b4a215991ae_l9RlVT4ec4.gif?height=796&lazyload=true&maxWidth=500&width=1914)
1. 选中两个按钮组件,将两个按钮组件分别拖拽放入列容器中。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/51b9795e820193d21bb42220d6d1f549_ampliiWgd3.gif?height=624&lazyload=true&maxWidth=500&width=1290)
1. 在左侧大纲树中,将输入框组件拖拽上移,放入表单容器中。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/1881e2b4f885f5405300d8e785942ab3_Lt35CFH2EH.gif?height=738&lazyload=true&maxWidth=500&width=1552)
1. 在左侧大纲树中,选中表单容器中 **取消** 按钮所在的 **列** 容器,然后点击删除图标。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/fda344c13a4208445af11ed4408fd551_AeILGXV7QS.png?height=743&lazyload=true&maxWidth=500&width=1348)
1. 在画布中,选中输入框组件,在右侧 **属性** 页签下,将宽度模式改为 **填满父容器-fill**。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/707d782bf19aa38346952eca14370a4a_qrfyrfvGh7.png?height=707&lazyload=true&maxWidth=500&width=1346)
你已完成发起告警卡片基本结构和布局的构建,最终大纲如下所示:
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/85ffe961a612a8fa06f77bcfaf0bba1d_apfUc17SmD.png?height=750&lazyload=true&maxWidth=200&width=276) +3 | 配置组件文本内容和样式 | 基于卡片可视化搭建工具,你可实时为组件填充文本内容、改变组件样式,并预览效果。 | 为标题文本、富文本、输入框占位文本、按钮文本分别配置内容,富文本语法可参考[富文本](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/rich-text)。 +4 | 配置组件变量 | 你可将变量理解为卡片内容的占位符。具体的内容或数据可在发送卡片时携带。
在本教程中,发起告警卡片中传入了告警时间变量 `alarm_time`,并在代码逻辑中,将交互过程中告警卡片实际发送的时间传给变量 `alarm_time` 作为具体的数据。
详情参考[发送卡片](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/send-feishu-card)和[示例代码解释](https://open.feishu.cn/document/uAjLw4CM/uMzNwEjLzcDMx4yM3ATM/develop-a-card-interactive-bot/explanation-of-example-code)了解如何传入变量。 | 1. 在画布区域右上角,点击变量图标,弹出 **变量** 页面,点击 **添加自定义变量**。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/8ffec35122364682bfd3af866610e464_iR3tJrtWsH.png?height=821&lazyload=true&maxWidth=500&width=1458)
2. 在添加变量弹窗中,按照下图,添加一个 `alarm_time` 变量。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/7f22bbac4cea3e5991980786aa008c6f_USFXIukbNH.png?height=651&lazyload=true&maxWidth=300&width=730)
3. 在富文本组件的文本内容中,将光标定位至目标富文本组件内容框中,然后点击右下角的变量图标,添加 `alarm_time` 变量。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/0add9a40f9fe0d7c3248e01f83c7f3a4_KBkTSPsKvu.png?height=545&lazyload=true&maxWidth=500&width=1468)
添加完成后的效果如下所示: +5 | 配置组件交互动作 | 为按钮配置请求回调动作后,当用户点击该按钮时,飞书会向你的服务端发送[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)回调,其中包含了用户的交互信息。在本教程中,当用户点击 **处理完成** 按钮时,回传参数中需包含以下参数,以用于更新卡片。详情参考[示例代码解释](https://open.feishu.cn/document/uAjLw4CM/uMzNwEjLzcDMx4yM3ATM/develop-a-card-interactive-bot/explanation-of-example-code)。
```json
{
"action": { // 用户操作交互组件回传的数据
"tag": "button", // 交互组件的标签,此处为按钮
"value": { // 交互组件绑定的开发者自定义的回传参数,此处类型为开发者自定义的对象
"action": "complete_alarm", // 用户点击了处理完成按钮
"time": "${alarm_time}" // 告警时间
}
}
}
``` | 为 **处理完成** 按钮创建事件,配置 **请求回调** 动作,输入参数如下所示。详情参考[配置请求回调交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/configuring-card-interactions#5746ae32)。
![图片](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/24c84bb24826c7fb4a3c98cbc86a0562_Gp1J5QC3Fp.png?height=783&lazyload=true&maxWidth=500&width=1462) +6 | 配置卡片多语言 | 如果你想配置多语言卡片,你可在搭建工具中实现不同语言内容的配置。案例库中的卡片为中英双语卡片。![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/649559740c3432ca4385d69351ef091a_SWT2gScFHC.png?height=537&lazyload=true&maxWidth=500&width=1236) | 参考[为新版卡片配置多语言](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/configure-multi-language-content#882164bf)了解如何配置多语言。 + +## 搭建告警处理完成卡片 + +本步骤介绍告警处理完成卡片的具体流程,包括搭建结构、配置内容和样式、配置组件的变量、交互动作和多语言。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/c02bdbf08c1ecdfa833190e675f5a4a5_7KmTSGr6Gy.png?height=368&lazyload=true&maxWidth=400&width=823) + +步骤 | 搭建步骤 | 说明 | 具体操作(本教程已经自动完成以下配置) +---|---|---|--- +1 | 基于案例库创建卡片 | 基于案例库提供的卡片,你可了解常用组件的搭建方式,快速构建卡片。了解更多,参考[构建卡片内容](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/build-card-content)。 | 1. 在[飞书卡片搭建工具](https://open.feishu.cn/cardkit?from=open_docs_tutorial)首页,点击 **参考案例库**。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/72d387a8a22b35bde24446cd5a5fe25e_lMW3VXpMgC.png?height=664&lazyload=true&maxWidth=500&width=1750)
1. 在 **参考案例库** 弹窗 **新版专区** 页面,找到 **告警处理完成** 卡片,并点击 **使用**。
**提示**:新版专区的卡片新增 20+ 卡片能力。了解新旧版本卡片区别,参考[搭建工具新版卡片变更说明](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/cardkit-upgraded-version-card-release-notes)。
1. 将卡片名称设为 **告警处理完成**,然后点击 **创建**。你将进入卡片的编辑页面。 +2 | 搭建卡片结构和布局 | 一张新版卡片由标题(可选)组件和正文组成。正文中可放置其它多个组件。搭建卡片时,你可先设计卡片大纲,明确卡片基本结构,再填充内容。发起告警卡片的大纲如下所示:
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/c7f104a000bc00920fe9c37bd6fe0b6d_teG8Ir4iki.png?height=605&lazyload=true&maxWidth=200&width=307)
其中:
- 分栏组件中用于布局卡片中的内容,分栏包含多个列容器,每个列容器中可内嵌多个组件
- 富文本、分割线组件为展示组件 | 从 0 到 1 搭建告警处理完成卡片与搭建发起告警卡片步骤类似,你可参考上文 **搭建发起告警卡片** 一节。 +3 | 配置组件文本内容和样式 | 基于卡片可视化搭建工具,你可实时为组件填充文本内容、改变组件样式,并预览效果。 | 为标题文本、富文本、输入框占位文本、按钮文本分别配置内容,富文本语法可参考[富文本](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/rich-text)。 +4 | 配置组件变量 | 你可将变量理解为卡片内容的占位符。具体的内容或数据可在发送卡片时携带。在本教程中,告警处理完成卡片中传入以下变量,详情参考[示例代码解释](https://open.feishu.cn/document/uAjLw4CM/uMzNwEjLzcDMx4yM3ATM/develop-a-card-interactive-bot/explanation-of-example-code)。
- 告警时间变量 `alarm_time`。在示例代码逻辑中,该变量实际的值为开发者在搭建发起告警卡片时,为 **处理完成** 按钮配置的回传参数 2:
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/49fd64ccdc280d64fe50f38a45cfb192_TACw2MJaFC.png?height=786&lazyload=true&maxWidth=500&width=1452)
- 用户 ID 变量 `open_id`。[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)回调中包含了用户的 Open ID,示例代码中获取了回调中用户的 Open ID,并将其传给了变量 `open_id`。将该变量放置于[富文本](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/rich-text#6d6698b6)的人员语法中,即可实现展示用户名称、头像等效果。
- 处理时间变量 `complete_time`。在示例代码逻辑中,当服务在[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)回调的回传参数收到如下图中的参数 1 时,将会把当前实际的时间作为具体数据传给变量 `complete_time` 。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/f33b3cdeb3474a4d6339fd22c792c7cb_RrQnWBEbcw.png?height=791&lazyload=true&maxWidth=500&width=1449)
- 备注变量 `notes`。示例代码中,首先基于卡片回传交互中`form_value` 属性,使服务读取了告警卡片中用户填写的备注文本信息,之后将该信息作为具体数据传给变量 `notes`。 | 1. 在画布区域右上角,点击变量图标,弹出 **变量** 页面,点击 **添加自定义变量**。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/5678354fc847ea081366287a8f25ee0e_ZPQhPPchRH.png?height=824&lazyload=true&maxWidth=500&width=1455)
1. 在添加变量弹窗中,参考下图,添加以下四个变量。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/2066c477e73795e91dc2324ee91aca96_EFPndwGXa3.png?height=402&lazyload=true&maxWidth=300&width=785)
1. 在富文本组件的文本内容中,将光标定位至目标富文本组件内容框中,然后点击右下角的变量图标,依次添加变量。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/c32ee0132a93d84d949a3a25785a5913_QKCpAGaqPn.png?height=536&lazyload=true&maxWidth=500&width=1473)
添加完成后的效果如下所示:
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/964f063d6e6b0233931960fcf849c5f8_j4ng4lqqZu.png?height=555&lazyload=true&maxWidth=500&width=1462)![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/5a26ae63d4273421c1b8512a37658c1b_p223Kel4pt.png?height=542&lazyload=true&maxWidth=500&width=1469) +5 | 配置卡片多语言 | 如果你想配置多语言卡片,你可在搭建工具中实现不同语言内容的配置。案例库中的卡片为中英双语卡片。![图片名称](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/32583736699a98e313b55751cfe734cb_r74ogO21YQ.png?height=522&lazyload=true&maxWidth=500&width=1244) | 参考[为新版卡片配置多语言](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/configure-multi-language-content#882164bf)了解如何配置多语言。 + +## 后续操作 + +卡片搭建完成后,需要保存、发布、并为其添加应用,才可被应用通过 API 调用。在卡片交互机器人教程中,系统已自动帮助你完成上述配置。以下为具体操作步骤说明。 +1. 进入卡片编辑页面,在顶部菜单栏单击 **保存**,然后点击**发布**。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/bc9da9dd75ff050c1ccc709cb385d547_JSmZSmr481.png?height=875&lazyload=true&maxWidth=500&width=1920) +1. 在发布成功弹窗中,点击绑定应用。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/3d330b59176a359f8059d545d6df6515_AhGYSK35GC.png?height=258&lazyload=true&maxWidth=500&width=557) +1. 在 **添加自定义机器人/应用** 弹窗中,添加你创建的卡片交互机器人应用,使该应用拥有调用该卡片模板的权限。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/42fca79d71078808a897f5d44d012369_ZL2GQEaygW.png?height=250&lazyload=true&maxWidth=500&width=635) + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/e9ead1fa3c69a8dcf173c4d4add9d47b_hKbhL3FjpS.png?height=678&lazyload=true&maxWidth=500&width=653) diff --git a/embedded-skills/lark-card-designer/docs/raw/develop-a-card-interactive-bot__explanation-of-example-code.md b/embedded-skills/lark-card-designer/docs/raw/develop-a-card-interactive-bot__explanation-of-example-code.md new file mode 100644 index 0000000..0096f20 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/develop-a-card-interactive-bot__explanation-of-example-code.md @@ -0,0 +1,1087 @@ +# 示例代码解释 +本教程提供了卡片交互机器人 Demo 的多语言示例代码, 通过本文你可以了解各语言的业务代码逻辑。点击[此链接](https://github.com/larksuite/lark-samples/tree/main/card_interaction_bot)前往 GitHub 查看源码。 +**注意事项**:要获取其他接口的调用示例代码,可在 API 调试台调用接口成功后,复制调试台自动生成的示例代码,详情参考[在调试台发起 API 调用](https://open.feishu.cn/document/uAjLw4CM/uMzNwEjLzcDMx4yM3ATM/how-to-call-a-server-side-api/introduction#42c7c09a)。 +### Java 示例代码 + +业务代码路径:`card_interaction_bot/java/src/main/java/com/lark/oapi/Main.java`。复制该路径前往 GitHub 或代码包中找到 `Main.java` 文件。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/a0670a9f1c1258cc6185e8ace1a4b4d3_OXHLlDvlJP.png?height=282&lazyload=true&maxWidth=600&width=1075) + +代码实现逻辑说明如下。 + +1. 构建 API Client 用于调用 OpenAPI。 +1. 分别构造欢迎卡片、告警卡片,并构建发送逻辑。 +1. 使用 EventDispatcher 注册事件处理器,订阅并处理以下事件: + - 订阅[用户进入与机器人的会话](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/chat-access_event/events/bot_p2p_chat_entered)事件(onP2ChatAccessEventBotP2pChatEnteredV1)。用户进入会话后,会发送欢迎卡片 + - 订阅[机器人自定义菜单](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/application-v6/bot/events/menu)事件(onP2BotMenuV6)。用户点击悬浮菜单的“发起告警”按钮后,会发送告警卡片 + - 订阅[接收消息](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/events/receive)事件(onP2MessageReceiveV1)。用户发送消息后,会发送告警卡片 +1. 订阅[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)回调,处理用户点击卡片中的按钮后触发的回调: + - 当用户点击 **去体验** 按钮时,响应回调请求,保持卡片原内容不变,同时发送告警卡片 + - 当用户点击 **处理完成** 按钮时,读取用户填写的处理情况说明信息,再通过卡片回传交互 toast 提示操作成功,并将告警卡片更新为告警处理完成卡片 +1. 配置长连接功能,并关联事件处理器。 +1. 长连接用于建立项目与开放平台的数据连接通道,用于订阅、接收事件。功能介绍参考[使用长连接接收事件](https://open.feishu.cn/document/ukTMukTMukTM/uYDNxYjL2QTM24iN0EjN/event-subscription-configure-/request-url-configuration-case#d286cc88)。 + +代码与注释: +```java +package com.lark.oapi; + +import java.nio.charset.StandardCharsets; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.HashMap; + +import com.google.gson.JsonParser; +import com.lark.oapi.core.utils.Jsons; +import com.lark.oapi.event.EventDispatcher; +import com.lark.oapi.event.cardcallback.P2CardActionTriggerHandler; +import com.lark.oapi.event.cardcallback.model.CallBackCard; +import com.lark.oapi.event.cardcallback.model.CallBackToast; +import com.lark.oapi.event.cardcallback.model.P2CardActionTrigger; +import com.lark.oapi.event.cardcallback.model.P2CardActionTriggerResponse; +import com.lark.oapi.service.application.ApplicationService; +import com.lark.oapi.service.application.v6.model.P2BotMenuV6; +import com.lark.oapi.service.im.ImService; +import com.lark.oapi.service.im.v1.model.CreateMessageReq; +import com.lark.oapi.service.im.v1.model.CreateMessageReqBody; +import com.lark.oapi.service.im.v1.model.CreateMessageResp; +import com.lark.oapi.service.im.v1.model.P2ChatAccessEventBotP2pChatEnteredV1; +import com.lark.oapi.service.im.v1.model.P2MessageReceiveV1; +import com.lark.oapi.service.im.v1.model.ext.MessageTemplate; +import com.lark.oapi.service.im.v1.model.ext.MessageTemplateData; + +public class Main { + +private static final String APP_ID = System.getenv("APP_ID"); + private static final String APP_SECRET = System.getenv("APP_SECRET"); + private static final String WELCOME_CARD_ID = System.getenv("WELCOME_CARD_ID"); + private static final String ALERT_CARD_ID = System.getenv("ALERT_CARD_ID"); + private static final String ALERT_RESOLVED_CARD_ID = System.getenv("ALERT_RESOLVED_CARD_ID"); + private static final ZoneId SHANGHAI_ZONE_ID = ZoneId.of("Asia/Shanghai"); + +/** + * 创建 LarkClient 对象,用于请求OpenAPI。 + * Create LarkClient object for requesting OpenAPI + */ + private static final Client client = new Client.Builder(APP_ID, APP_SECRET).build(); + +/* + * + * 发送欢迎卡片 + * Send welcome card + * + */ + +private static void sendWelcomeCard(String openID) throws Exception { + /* + * 构造欢迎卡片 + * Construct a welcome card + * https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/send-feishu-card#718fe26b + */ + String replyContent = new MessageTemplate.Builder() + .data(new MessageTemplateData.Builder().templateId(WELCOME_CARD_ID) + .templateVariable(new HashMap() { + { + put("open_id", openID); + } + }) + .build()) + .build(); + +/** + * 使用发送OpenAPI发送通知卡片,你可以在API接口中打开 API 调试台,快速复制调用示例代码 + * Use send OpenAPI to send notice card. You can open the API debugging console in the API interface and quickly copy the sample code for API calls. + * https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/create + */ + CreateMessageReq req = CreateMessageReq.newBuilder() + .receiveIdType("open_id") + .createMessageReqBody(CreateMessageReqBody.newBuilder() + .receiveId(openID) + .msgType("interactive") + .content(replyContent) + .build()) + .build(); + +// 发起请求 + CreateMessageResp resp = client.im().v1().message().create(req); + +// 处理服务端错误 + if(!resp.success()) { + System.out.println(String.format("code:%s,msg:%s,reqId:%s, resp:%s", + resp.getCode(), resp.getMsg(), resp.getRequestId(), Jsons.createGSON(true, false).toJson(JsonParser.parseString(new String(resp.getRawResponse().getBody(), StandardCharsets.UTF_8))))); + return; + } + +// 调用成功,打印返回结果 + System.out.println(Jsons.DEFAULT.toJson(resp.getData())); + +} + +/** + * 发送告警卡片 + * Send alarm card + */ + private static void sendAlarmCard(String receiveIdType, String receiveId) throws Exception { + /* + * 构造告警卡片 + * Construct an alarm card + * https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/send-feishu-card#718fe26b + */ + String replyContent = new MessageTemplate.Builder() + .data(new MessageTemplateData.Builder().templateId(ALERT_CARD_ID) + .templateVariable(new HashMap() { + { + put("alarm_time", LocalDateTime.now(SHANGHAI_ZONE_ID).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + } + }) + .build()) + .build(); + +/** + * 使用发送OpenAPI发送告警卡片,根据传入的receiveIdType不同,可发送到用户单聊或群聊中。你可以在API接口中打开 API 调试台,快速复制调用示例代码 + * Use the Send OpenAPI to send an alarm card. Depending on the value of the incoming receiveIdType, it can be sent to an individual user chat or a group chat. You can open the API debugging console in the API interface and quickly copy the sample code for API calls. + * https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/create + */ + CreateMessageReq req = CreateMessageReq.newBuilder() + .receiveIdType(receiveIdType) + .createMessageReqBody(CreateMessageReqBody.newBuilder() + .receiveId(receiveId) + .msgType("interactive") + .content(replyContent) + .build()) + .build(); + +// 发起请求 + CreateMessageResp resp = client.im().v1().message().create(req); + +// 处理服务端错误 + if(!resp.success()) { + System.out.println(String.format("code:%s,msg:%s,reqId:%s, resp:%s", + resp.getCode(), resp.getMsg(), resp.getRequestId(), Jsons.createGSON(true, false).toJson(JsonParser.parseString(new String(resp.getRawResponse().getBody(), StandardCharsets.UTF_8))))); + return; + } + +// 调用成功,打印返回结果 + System.out.println(Jsons.DEFAULT.toJson(resp.getData())); + +} + +/** + * 注册事件处理器。 + * Register event handler. + */ + private static final EventDispatcher EVENT_HANDLER = EventDispatcher.newBuilder("", "") // 长连接不需要这两个参数,请保持空字符串 + /** + * 处理用户进入机器人单聊事件 + * handle user enter bot single chat event + * https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/chat-access_event/events/bot_p2p_chat_entered + */ + .onP2ChatAccessEventBotP2pChatEnteredV1(new ImService.P2ChatAccessEventBotP2pChatEnteredV1Handler() { + @Override + public void handle(P2ChatAccessEventBotP2pChatEnteredV1 event) throws Exception { + System.out.printf("[ onP2ChatAccessEventBotP2pChatEnteredV1 access ], data: %s\n", + Jsons.DEFAULT.toJson(event.getEvent())); + String openID = event.getEvent().getOperatorId().getOpenId(); + sendWelcomeCard(openID); + } + +}) + +/** + * 处理用户点击机器人菜单事件 + * handle user click bot menu event + * https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/application-v6/bot/events/menu + */ + .onP2BotMenuV6(new ApplicationService.P2BotMenuV6Handler() { + @Override + public void handle(P2BotMenuV6 event) throws Exception { + System.out.printf("[ onP2BotMenuV6 access ], data: %s\n", Jsons.DEFAULT.toJson(event.getEvent())); + /** + * 通过菜单 event_key 区分不同菜单。 你可以在开发者后台配置菜单的event_key + * Use event_key to distinguish different menus. You can configure the event_key + * of the menu in the developer console. + */ + if ("send_alarm".equals(event.getEvent().getEventKey())) { + String openID = event.getEvent().getOperator().getOperatorId().getOpenId(); + sendAlarmCard("open_id", openID); + } + +} + }) + +/** + * 接收用户发送的消息(包括单聊和群聊),接受到消息后发送告警卡片 + * Register event handler to handle received messages, including individual chats and group chats. + * https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/events/receive + */ + .onP2MessageReceiveV1(new ImService.P2MessageReceiveV1Handler() { + @Override + public void handle(P2MessageReceiveV1 event) throws Exception { + System.out.printf("[ onP2MessageReceiveV1 access ], data: %s\n", Jsons.DEFAULT.toJson(event.getEvent())); + String type = event.getEvent().getMessage().getChatType(); + String openID = event.getEvent().getSender().getSenderId().getOpenId(); + String chatID = event.getEvent().getMessage().getChatId(); + if (type.equals("group")) { + sendAlarmCard("chat_id", chatID); + } else if (type.equals("p2p")) { + sendAlarmCard("open_id", openID); + } + +} + }) + +/** + * 处理卡片按钮点击回调 + * handle card button click callback + * https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication + */ + .onP2CardActionTrigger(new P2CardActionTriggerHandler() { + @Override + public P2CardActionTriggerResponse handle(P2CardActionTrigger event) throws Exception { + System.out.printf("[ P2CardActionTrigger access ], data: %s\n", Jsons.DEFAULT.toJson(event.getEvent())); + String openID = event.getEvent().getOperator().getOpenId(); + +/** + * 通过 action 区分不同按钮点击,你可以在卡片搭建工具配置按钮的action。此处处理用户点击了欢迎卡片中的发起告警按钮 + * Use action to distinguish different buttons. You can configure the action of the button in the card building tool. + * Here, handle the situation where the user clicks the "Initiate Alarm" button on the welcome card. + * + */ + if (event.getEvent().getAction().getValue().get("action").equals("send_alarm")) { + +/** + * 响应回调请求,保持卡片原内容不变 + * Respond to the callback request and keep the original content of the card unchanged. + */ + P2CardActionTriggerResponse resp = new P2CardActionTriggerResponse(); + sendAlarmCard("open_id", openID); + return resp; + } + +/** + * 通过 action 区分不同按钮, 你可以在卡片搭建工具配置按钮的action。此处处理用户点击了告警卡片中的已处理按钮 + * Use action to distinguish different buttons. You can configure the action of the button in the card building tool. + * Here, handle the scenario where the user clicks the "Mark as resolved" button on the alarm card. + */ + +if (event.getEvent().getAction().getValue().get("action").equals("complete_alarm")) { + /** + * 读取告警卡片中用户填写的备注文本信息 + * Read the note text information filled in by the user in the alarm card. + */ + String notes; + if (event.getEvent().getAction().getFormValue() != null) { + notes =String.valueOf(event.getEvent().getAction().getFormValue().get("notes_input")); + } else { + notes= ""; + } + System.out.printf("[ notes ], data: %s\n", notes); + /** + * 通过卡片回传交互toast提示操作成功,并返回一个新卡片:已处理的卡片 + * Through the card callback interaction, display a toast to indicate successful operation and return a new card: the resolved card. + */ + P2CardActionTriggerResponse resp = new P2CardActionTriggerResponse(); + CallBackToast toast = new CallBackToast(); + toast.setType("info"); + toast.setContent("已处理完成!"); + toast.setI18n(new HashMap() { + { + put("zh_cn", "已处理完成!"); + put("en_us", "Resolved!"); + } + }); + +CallBackCard card = new CallBackCard(); + card.setType("template"); + card.setData(new MessageTemplateData.Builder().templateId(ALERT_RESOLVED_CARD_ID) + .templateVariable(new HashMap() { + { + put("alarm_time", event.getEvent().getAction().getValue().get("time")); + put("open_id", openID); + put("complete_time", LocalDateTime.now(SHANGHAI_ZONE_ID).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + put("notes", notes); + } + }).build()); + +resp.setCard(card); + resp.setToast(toast); + return resp; + } + return null; + } + }).build(); + +/** + * 启动长连接,并注册事件处理器。 + * Start long connection and register event handler. + * https://open.feishu.cn/document/server-docs/event-subscription-guide/event-subscription-configure-/request-url-configuration-case#d286cc88 + */ + private static final com.lark.oapi.ws.Client wsClient = new com.lark.oapi.ws.Client.Builder(APP_ID, APP_SECRET) + .eventHandler(EVENT_HANDLER).build(); // 静态成员变量,只初始化一次 + +public static void main(String[] args) { + System.out.println("Starting bot..."); + wsClient.start(); + } +} +``` + +### Python 示例代码 + +业务代码路径:`card_interaction_bot/python/main.py`,复制该路径前往 GitHub 或代码包中找到 `main.py` 文件。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/16aea52e818e72c138bfcb471f9338e5_9Kv2RRyfMV.png?height=493&lazyload=true&maxWidth=600&width=1040) + +代码实现逻辑说明如下。 +1. 构建 API Client 用于调用 OpenAPI。 +1. 分别构造欢迎卡片、告警卡片,并构建发送逻辑。 +3. 注册事件处理器,订阅并处理以下事件: + - 订阅[用户进入与机器人的会话](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/chat-access_event/events/bot_p2p_chat_entered)事件(onP2ChatAccessEventBotP2pChatEnteredV1)。用户进入会话后,会发送欢迎卡片 + - 订阅[机器人自定义菜单](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/application-v6/bot/events/menu)事件(onP2BotMenuV6)。用户点击悬浮菜单的 **发起告警** 按钮后,会发送告警卡片 + - 订阅[接收消息](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/events/receive)事件(onP2MessageReceiveV1)。用户发送消息后,会发送告警卡片 +1. 订阅[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)回调,处理用户点击卡片中的按钮后触发的回调: + - 当用户点击 **去体验** 按钮时,响应回调请求,保持卡片原内容不变,同时发送告警卡片 + - 当用户点击 **处理完成** 按钮时,读取用户填写的处理情况说明信息,再通过卡片回传交互 toast 提示操作成功,并将告警卡片更新为告警处理完成卡片 +1. 配置长连接功能,并关联事件处理器。 +1. 长连接用于建立项目与开放平台的数据连接通道,用于订阅、接收事件。功能介绍参考[使用长连接接收事件](https://open.feishu.cn/document/ukTMukTMukTM/uYDNxYjL2QTM24iN0EjN/event-subscription-configure-/request-url-configuration-case#d286cc88)。 + +代码与注释: +```python +import os +import json +from datetime import datetime, timezone, timedelta + +import lark_oapi as lark +from lark_oapi.api.im.v1 import * +from lark_oapi.api.application.v6 import * +from lark_oapi.event.callback.model.p2_card_action_trigger import ( + P2CardActionTrigger, + P2CardActionTriggerResponse, +) + +WELCOME_CARD_ID = os.getenv("WELCOME_CARD_ID") +ALERT_CARD_ID = os.getenv("ALERT_CARD_ID") +ALERT_RESOLVED_CARD_ID = os.getenv("ALERT_RESOLVED_CARD_ID") + +# 发送消息 +# Send a message +# # https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/create +def send_message(receive_id_type, receive_id, msg_type, content): + request = ( + CreateMessageRequest.builder() + .receive_id_type(receive_id_type) + .request_body( + CreateMessageRequestBody.builder() + .receive_id(receive_id) + .msg_type(msg_type) + .content(content) + .build() + ) + .build() + ) + +# 使用发送OpenAPI发送通知卡片,你可以在API接口中打开 API 调试台,快速复制调用示例代码 + # Use send OpenAPI to send notice card. You can open the API debugging console in the API interface and quickly copy the sample code for API calls. + # https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/create + response = client.im.v1.message.create(request) + if not response.success(): + raise Exception( + f"client.im.v1.message.create failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}" + ) + return response + +# 发送欢迎卡片 +# Construct a welcome card +# https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/send-feishu-card#718fe26b +def send_welcome_card(open_id): + content = json.dumps( + { + "type": "template", + "data": { + "template_id": WELCOME_CARD_ID, + "template_variable": {"open_id": open_id}, + }, + } + ) + return send_message("open_id", open_id, "interactive", content) + +# 发送告警卡片 +# Construct an alarm card +# https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/send-feishu-card#718fe26b +def send_alarm_card(receive_id_type, receive_id): + content = json.dumps( + { + "type": "template", + "data": { + "template_id": ALERT_CARD_ID, + "template_variable": { + "alarm_time": datetime.now(timezone(timedelta(hours=8))).strftime("%Y-%m-%d %H:%M:%S (UTC+8)"), + }, + }, + } + ) + return send_message(receive_id_type, receive_id, "interactive", content) + +# 处理用户进入机器人单聊事件 +# handle user enter bot single chat event +# https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/chat-access_event/events/bot_p2p_chat_entered +def do_p2_im_chat_access_event_bot_p2p_chat_entered_v1( + data: P2ImChatAccessEventBotP2pChatEnteredV1, +) -> None: + print(f"[ onP2ChatAccessEventBotP2pChatEnteredV1 access ], data: {data}") + open_id = data.event.operator_id.open_id + send_welcome_card(open_id) + +# 处理用户点击机器人菜单事件 +# handle user click bot menu event +# https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/application-v6/bot/events/menu +def do_p2_application_bot_menu_v6(data: P2ApplicationBotMenuV6) -> None: + print(f"[ onP2BotMenuV6 access ], data: {data}") + open_id = data.event.operator.operator_id.open_id + event_key = data.event.event_key + +# 通过菜单 event_key 区分不同菜单。 你可以在开发者后台配置菜单的event_key + # Use event_key to distinguish different menus. You can configure the event_key of the menu in the developer console. + if event_key == "send_alarm": + send_alarm_card("open_id", open_id) + +# 接收用户发送的消息(包括单聊和群聊),接受到消息后发送告警卡片 +# Register event handler to handle received messages, including individual chats and group chats. +# https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/events/receive +def do_p2_im_message_receive_v1(data: P2ImMessageReceiveV1) -> None: + print(f"[ onP2MessageReceiveV1 access ], data: {data}") + chat_type = data.event.message.chat_type + chat_id = data.event.message.chat_id + open_id = data.event.sender.sender_id.open_id + +if chat_type == "group": + send_alarm_card("chat_id", chat_id) + elif chat_type == "p2p": + send_alarm_card("open_id", open_id) + +# 处理卡片按钮点击回调 +# handle card button click callback +# https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication +def do_p2_card_action_trigger(data: P2CardActionTrigger) -> P2CardActionTriggerResponse: + print(f"[ P2CardActionTrigger access ], data: {data}") + open_id = data.event.operator.open_id + action = data.event.action + +# 通过 action 区分不同按钮点击,你可以在卡片搭建工具配置按钮的action。此处处理用户点击了欢迎卡片中的发起告警按钮 + # Use action to distinguish different buttons. You can configure the action of the button in the card building tool. + # Here, handle the situation where the user clicks the "Initiate Alarm" button on the welcome card. + if action.value["action"] == "send_alarm": + # 响应回调请求,保持卡片原内容不变 + # Respond to the callback request and keep the original content of the card unchanged. + send_alarm_card("open_id", open_id) + return P2CardActionTriggerResponse({}) + +# 通过 action 区分不同按钮, 你可以在卡片搭建工具配置按钮的action。此处处理用户点击了告警卡片中的已处理按钮 + # Use action to distinguish different buttons. You can configure the action of the button in the card building tool. + # Here, handle the scenario where the user clicks the "Mark as resolved" button on the alarm card. + if action.value["action"] == "complete_alarm": + # 读取告警卡片中用户填写的备注文本信息 + # Read the note text information filled in by the user in the alarm card. + notes = "" + if action.form_value and "notes_input" in action.form_value: + notes = str(action.form_value["notes_input"]) + +content = { + "toast": { + "type": "info", + "content": "已处理完成!", + "i18n": {"zh_cn": "已处理完成!", "en_us": "Resolved!"}, + }, + "card": { + "type": "template", + "data": { + "template_id": ALERT_RESOLVED_CARD_ID, + "template_variable": { + "alarm_time": action.value["time"], + "open_id": open_id, + "complete_time": datetime.now(timezone(timedelta(hours=8))).strftime("%Y-%m-%d %H:%M:%S (UTC+8)"), + "notes": notes, + }, + }, + }, + } + return P2CardActionTriggerResponse(content) + +# 注册事件回调 +# Register event handler. +event_handler = ( + lark.EventDispatcherHandler.builder("", "") + .register_p2_im_chat_access_event_bot_p2p_chat_entered_v1( + do_p2_im_chat_access_event_bot_p2p_chat_entered_v1 + ) + .register_p2_application_bot_menu_v6(do_p2_application_bot_menu_v6) + .register_p2_im_message_receive_v1(do_p2_im_message_receive_v1) + .register_p2_card_action_trigger(do_p2_card_action_trigger) + .build() +) + +# 创建 LarkClient 对象,用于请求OpenAPI, 并创建 LarkWSClient 对象,用于使用长连接接收事件。 +# Create LarkClient object for requesting OpenAPI, and create LarkWSClient object for receiving events using long connection. +client = lark.Client.builder().app_id(lark.APP_ID).app_secret(lark.APP_SECRET).build() +wsClient = lark.ws.Client( + lark.APP_ID, + lark.APP_SECRET, + event_handler=event_handler, + log_level=lark.LogLevel.DEBUG, +) + +def main(): + print("Starting bot...") + # 启动长连接,并注册事件处理器。 + # Start long connection and register event handler. + # https://open.feishu.cn/document/server-docs/event-subscription-guide/event-subscription-configure-/request-url-configuration-case#d286cc88 + wsClient.start() + +if __name__ == "__main__": + main() +``` + +### Go 示例代码 + +业务代码路径:`card_interaction_bot/go/main.go`,复制该路径前往 GitHub 或代码包中找到 `main.go` 文件。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/650868a2fd4214ca2c6df4830dd2c103_lnx1SjQkCD.png?height=544&lazyload=true&maxWidth=600&width=1046) + +代码实现逻辑说明如下。 +1. 构建 API Client 用于调用 OpenAPI。 +1. 分别构造欢迎卡片、告警卡片,并构建发送逻辑。 +3. 使用 dispatcher.NewEventDispatcher 注册事件处理器,订阅并处理以下事件: + - 订阅[用户进入与机器人的会话](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/chat-access_event/events/bot_p2p_chat_entered)事件(onP2ChatAccessEventBotP2pChatEnteredV1)。用户进入会话后,会发送欢迎卡片 + - 订阅[机器人自定义菜单](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/application-v6/bot/events/menu)事件(onP2BotMenuV6)。用户点击悬浮菜单的 **发起告警** 按钮后,会发送告警卡片 + - 订阅[接收消息](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/events/receive)事件(onP2MessageReceiveV1)。用户发送消息后,会发送告警卡片 +1. 订阅[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)回调,处理用户点击卡片中的按钮后触发的回调: + - 当用户点击 **去体验** 按钮时,响应回调请求,保持卡片原内容不变,同时发送告警卡片 + - 当用户点击 **处理完成** 按钮时,读取用户填写的处理情况说明信息,再通过卡片回传交互 toast 提示操作成功,并将告警卡片更新为告警处理完成卡片 +1. 配置长连接功能,并关联事件处理器。 +1. 长连接用于建立项目与开放平台的数据连接通道,用于订阅、接收事件。功能介绍参考[使用长连接接收事件](https://open.feishu.cn/document/ukTMukTMukTM/uYDNxYjL2QTM24iN0EjN/event-subscription-configure-/request-url-configuration-case#d286cc88)。 + +代码与注释: +```go +package main + +import ( + "context" + "encoding/json" + "fmt" + "os" + "time" + +lark "github.com/larksuite/oapi-sdk-go/v3" + larkcore "github.com/larksuite/oapi-sdk-go/v3/core" + "github.com/larksuite/oapi-sdk-go/v3/event/dispatcher" + "github.com/larksuite/oapi-sdk-go/v3/event/dispatcher/callback" + larkapplication "github.com/larksuite/oapi-sdk-go/v3/service/application/v6" + larkim "github.com/larksuite/oapi-sdk-go/v3/service/im/v1" + larkws "github.com/larksuite/oapi-sdk-go/v3/ws" +) + +var cstZone *time.Location = time.FixedZone("CST", 8*3600) // 东八区(+8小时) + +/** + * 发送欢迎卡片 + * Construct a welcome card + * https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/send-feishu-card#718fe26b + * + */ +func sendWelcomeCard(client *lark.Client, openID string) { + WELCOME_CARD_ID := os.Getenv("WELCOME_CARD_ID") + +card := &callback.Card{ + Type: "template", + Data: &callback.TemplateCard{ + TemplateID: WELCOME_CARD_ID, + TemplateVariable: map[string]interface{}{ + "open_id": openID, + }, + }, + } + +content, err := json.Marshal(card) + if err != nil { + fmt.Println(err) + return + } + +/* 使用发送OpenAPI发送通知卡片,你可以在API接口中打开 API 调试台,快速复制调用示例代码 + * Use send OpenAPI to send notice card. You can open the API debugging console in the API interface and quickly copy the sample code for API calls. + * https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/create + */ + resp, err := client.Im.Message.Create(context.Background(), larkim.NewCreateMessageReqBuilder(). + ReceiveIdType("open_id"). + Body(larkim.NewCreateMessageReqBodyBuilder(). + MsgType("interactive"). + ReceiveId(openID). + Content(string(content)). + Build()). + Build()) + +if err != nil { + fmt.Println(err) + return + } + if !resp.Success() { + fmt.Println(resp.Code, resp.Msg, resp.RequestId()) + return + } + fmt.Println(resp.Data.MessageId) +} + +/** + * 构造告警卡片 + * Construct an alarm card + * https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/send-feishu-card#718fe26b + * + */ +func sendAlarmCard(client *lark.Client, receiveIdType string, receiveId string) { + ALERT_CARD_ID := os.Getenv("ALERT_CARD_ID") + +card := &callback.Card{ + Type: "template", + Data: &callback.TemplateCard{ + TemplateID: ALERT_CARD_ID, + TemplateVariable: map[string]interface{}{ + "alarm_time": time.Now().In(cstZone).Format("2006-01-02 15:04:05 (UTC+8)"), + }, + }, + } + +fmt.Println(time.Now().In(cstZone).Format("2006-01-02 15:04:05 (UTC+8)")) + +content, err := json.Marshal(card) + if err != nil { + fmt.Println(err) + return + } + /* + * 使用发送OpenAPI发送告警卡片,根据传入的receiveIdType不同,可发送到用户单聊或群聊中。你可以在API接口中打开 API 调试台,快速复制调用示例代码 + * Use the Send OpenAPI to send an alarm card. Depending on the value of the incoming receiveIdType, it can be sent to an individual user chat or a group chat. You can open the API debugging console in the API interface and quickly copy the sample code for API calls. + * https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/create + */ + +resp, err := client.Im.Message.Create(context.Background(), larkim.NewCreateMessageReqBuilder(). + ReceiveIdType(receiveIdType). + Body(larkim.NewCreateMessageReqBodyBuilder(). + MsgType("interactive"). + ReceiveId(receiveId). + Content(string(content)). + Build()). + Build()) + +if err != nil { + fmt.Println(err) + return + } + if !resp.Success() { + fmt.Println(resp.Code, resp.Msg, resp.RequestId()) + return + } + fmt.Println(resp.Data.MessageId) +} + +func main() { + app_id := os.Getenv("APP_ID") + app_secret := os.Getenv("APP_SECRET") + ALERT_RESOLVED_CARD_ID := os.Getenv("ALERT_RESOLVED_CARD_ID") + +/** + * 创建 LarkClient 对象,用于请求OpenAPI。 + * Create LarkClient object for requesting OpenAPI + */ + client := lark.NewClient(app_id, app_secret) + +/** + * 注册事件处理器。 + * Register event handler. + */ + eventHandler := dispatcher.NewEventDispatcher("", ""). + /** + * 处理用户进入机器人单聊事件 + * handle user enter bot single chat event + * https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/chat-access_event/events/bot_p2p_chat_entered + */ + OnP2ChatAccessEventBotP2pChatEnteredV1(func(ctx context.Context, event *larkim.P2ChatAccessEventBotP2pChatEnteredV1) error { + +fmt.Printf("[ OnP2ChatAccessEventBotP2pChatEnteredV1 access ], data: %s\n", larkcore.Prettify(event)) + sendWelcomeCard(client, *event.Event.OperatorId.OpenId) + return nil + }). + /** + * 处理用户点击机器人菜单事件 + * handle user click bot menu event + * https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/application-v6/bot/events/menu + */ + OnP2BotMenuV6(func(ctx context.Context, event *larkapplication.P2BotMenuV6) error { + /** + * 通过菜单 event_key 区分不同菜单。 你可以在开发者后台配置菜单的event_key + * Use event_key to distinguish different menus. You can configure the event_key + * of the menu in the developer console. + */ + fmt.Printf("[ OnP2BotMenuV6 access ], data: %s\n", larkcore.Prettify(event)) + if *event.Event.EventKey == "send_alarm" { + sendAlarmCard(client, "open_id", *event.Event.Operator.OperatorId.OpenId) + } + return nil + }). + /** + * 接收用户发送的消息(包括单聊和群聊),接受到消息后发送告警卡片 + * Register event handler to handle received messages, including individual chats and group chats. + * https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/events/receive + */ + OnP2MessageReceiveV1(func(ctx context.Context, event *larkim.P2MessageReceiveV1) error { + fmt.Printf("[ OnP2MessageReceiveV1 access ], data: %s\n", larkcore.Prettify(event)) + if *event.Event.Message.ChatType == "group" { + sendAlarmCard(client, "chat_id", *event.Event.Message.ChatId) + } else if *event.Event.Message.ChatType == "p2p" { + sendAlarmCard(client, "open_id", *event.Event.Sender.SenderId.OpenId) + } + return nil + }). + /** + * 处理卡片按钮点击回调 + * handle card button click callback + * https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication + */ + OnP2CardActionTrigger(func(ctx context.Context, event *callback.CardActionTriggerEvent) (*callback.CardActionTriggerResponse, error) { + fmt.Printf("[ OnP2CardActionTrigger access ], data: %s\n", larkcore.Prettify(event)) + /** + * 通过 action 区分不同按钮点击,你可以在卡片搭建工具配置按钮的action。此处处理用户点击了欢迎卡片中的发起告警按钮 + * Use action to distinguish different buttons. You can configure the action of the button in the card building tool. + * Here, handle the situation where the user clicks the "Initiate Alarm" button on the welcome card. + */ + if event.Event.Action.Value["action"] == "send_alarm" { + /* + * 响应回调请求,保持卡片原内容不变 + * Respond to the callback request and keep the original content of the card unchanged. + */ + sendAlarmCard(client, "open_id", event.Event.Operator.OpenID) + return &callback.CardActionTriggerResponse{}, nil + } + /** + * 通过 action 区分不同按钮, 你可以在卡片搭建工具配置按钮的action。此处处理用户点击了告警卡片中的已处理按钮 + * Use action to distinguish different buttons. You can configure the action of the button in the card building tool. + * Here, handle the scenario where the user clicks the "Mark as resolved" button on the alarm card. + */ + if event.Event.Action.Value["action"] == "complete_alarm" { + /* + * 读取告警卡片中用户填写的备注文本信息 + * Read the note text information filled in by the user in the alarm card. + */ + notes := "" + if event.Event.Action.FormValue != nil { + if n, ok := event.Event.Action.FormValue["notes_input"]; ok { + if str, ok := n.(string); ok { + notes = str + } else { + notes = fmt.Sprintf("%v", n) + } + } + } + +card := callback.CardActionTriggerResponse{ + Toast: &callback.Toast{ + Type: "info", + Content: "已处理完成!", + I18nContent: map[string]string{ + "zh_cn": "已处理完成!", + "en_us": "Resolved!", + }, + }, + Card: &callback.Card{ + Type: "template", + Data: &callback.TemplateCard{ + TemplateID: ALERT_RESOLVED_CARD_ID, + TemplateVariable: map[string]interface{}{ + "alarm_time": event.Event.Action.Value["time"], + "open_id": event.Event.Operator.OpenID, + "complete_time": time.Now().In(cstZone).Format("2006-01-02 15:04:05 (UTC+8)"), + "notes": notes, + }, + }, + }, + } + return &card, nil + } + +return nil, nil + }) + +/** + * 启动长连接,并注册事件处理器。 + * Start long connection and register event handler. + * https://open.feishu.cn/document/server-docs/event-subscription-guide/event-subscription-configure-/request-url-configuration-case#d286cc88 + */ + cli := larkws.NewClient(app_id, app_secret, + larkws.WithEventHandler(eventHandler), + larkws.WithLogLevel(larkcore.LogLevelDebug), + ) + err := cli.Start(context.Background()) + if err != nil { + panic(err) + } +} +``` + +### Node.js 示例代码 + +业务代码路径:`card_interaction_bot/nodejs/index.js`,复制该路径前往 GitHub 或代码包中找到 `index.js` 文件。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/041b1a6c9553a5e273de1a36e039352c_Lg6hslrAGz.png?height=618&lazyload=true&maxWidth=600&width=1048) + +代码实现逻辑说明如下。 + +1. 构建 API Client 用于调用 OpenAPI。 +2. 构建 wsClient 用于构建长连接。长连接用于建立项目与开放平台的数据连接通道,用于订阅、接收事件。功能介绍参考[使用长连接接收事件](https://open.feishu.cn/document/ukTMukTMukTM/uYDNxYjL2QTM24iN0EjN/event-subscription-configure-/request-url-configuration-case#d286cc88)。 +3. 分别构造欢迎卡片、告警卡片,并构建发送逻辑。 +4. 使用 EventDispatcher 注册事件处理器,订阅并处理以下事件: + - 订阅[用户进入与机器人的会话](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/chat-access_event/events/bot_p2p_chat_entered)事件(onP2ChatAccessEventBotP2pChatEnteredV1)。用户进入会话后,会发送欢迎卡片 + - 订阅[机器人自定义菜单](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/application-v6/bot/events/menu)事件(onP2BotMenuV6)。用户点击悬浮菜单的 **发起告警** 按钮后,会发送告警卡片 + - 订阅[接收消息](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/events/receive)事件(onP2MessageReceiveV1)。用户发送消息后,会发送告警卡片 +5. 订阅[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)回调,处理用户点击卡片中的按钮后触发的回调: + - 当用户点击 **去体验** 按钮时,响应回调请求,保持卡片原内容不变,同时发送告警卡片 + - 当用户点击 **处理完成** 按钮时,读取用户填写的处理情况说明信息,再通过卡片回传交互 toast 提示操作成功,并将告警卡片更新为告警处理完成卡片 +6. 启动长连接并关联事件处理器。 + +代码与注释: +```javascript +import * as Lark from '@larksuiteoapi/node-sdk'; + +/** + * 配置应用基础信息和请求域名。 + * App base information and request domain name. + */ +const baseConfig = { + appId: process.env.APP_ID, // 应用的 AppID, 你可以在开发者后台获取。 + appSecret: process.env.APP_SECRET, // 应用的 AppSecret,你可以在开发者后台获取。 + domain: process.env.BASE_DOMAIN, // 请求域名,如:https://open.feishu.cn。 +}; + +const { WELCOME_CARD_ID, ALERT_CARD_ID, ALERT_RESOLVED_CARD_ID } = process.env; + +/** + * 创建 LarkClient 对象,用于请求OpenAPI, 并创建 LarkWSClient 对象,用于使用长连接接收事件。 + * Create LarkClient object for requesting OpenAPI, and create LarkWSClient object for receiving events using long connection. + */ +const client = new Lark.Client(baseConfig); +const wsClient = new Lark.WSClient(baseConfig); + +/** + * 发送欢迎卡片 + * Construct a welcome card + * https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/send-feishu-card#718fe26b + * @param {string} openID 用户 open_id + */ +async function sendWelcomeCard(openID) { + /** + * 使用发送OpenAPI发送通知卡片,你可以在API接口中打开 API 调试台,快速复制调用示例代码 + * Use send OpenAPI to send notice card. You can open the API debugging console in the API interface and quickly copy the sample code for API calls. + * https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/create + */ + await client.im.v1.message.create({ + params: { receive_id_type: 'open_id' }, + data: { + receive_id: openID, + msg_type: 'interactive', + content: JSON.stringify({ + type: 'template', + data: { + template_id: WELCOME_CARD_ID, + template_variable: { open_id: openID }, + }, + }), + }, + }); +} + +/** + * 发送告警卡片 + * Construct an alarm card + * https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/send-feishu-card#718fe26b + * @param {string} receiveIdType 接收者类型 + * @param {string} receiveId 接收者ID + */ +async function sendAlarmCard(receiveIdType, receiveId) { + /** + * 使用发送OpenAPI发送告警卡片,根据传入的receiveIdType不同,可发送到用户单聊或群聊中。你可以在API接口中打开 API 调试台,快速复制调用示例代码 + * Use the Send OpenAPI to send an alarm card. Depending on the value of the incoming receiveIdType, it can be sent to an individual user chat or a group chat. You can open the API debugging console in the API interface and quickly copy the sample code for API calls. + * https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/create + */ + await client.im.v1.message.create({ + params: { receive_id_type: receiveIdType }, + data: { + receive_id: receiveId, + msg_type: 'interactive', + content: JSON.stringify({ + type: 'template', + data: { + template_id: ALERT_CARD_ID, + template_variable: { + alarm_time: `${new Date().toLocaleString( + 'zh-CN', + { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + second: '2-digit', + hour12: false, + }, + { timeZone: 'Asia/Shanghai' } + )} (UTC+8)`, + }, + }, + }), + }, + }); +} + +/** + * 注册事件处理器。 + * Register event handler. + */ +const eventDispatcher = new Lark.EventDispatcher({}).register({ + /** + * 处理用户进入机器人单聊事件 + * handle user enter bot single chat event + * https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/chat-access_event/events/bot_p2p_chat_entered + */ + 'im.chat.access_event.bot_p2p_chat_entered_v1': async (data) => { + const { + operator_id: { open_id }, + } = data; + await sendWelcomeCard(open_id); + }, + +/** + * 处理用户点击机器人菜单事件 + * handle user click bot menu event + * https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/application-v6/bot/events/menu + */ + 'application.bot.menu_v6': async (data) => { + const { operator, event_key } = data; + const { + operator_id: { open_id }, + } = operator; + +console.log('Received bot menu event:', data); + +/** + * 通过菜单 event_key 区分不同菜单。 你可以在开发者后台配置菜单的event_key + * Use event_key to distinguish different menus. You can configure the event_key of the menu in the developer console. + */ + if (event_key === 'send_alarm') { + await sendAlarmCard('open_id', open_id); + } + }, + +/** + * 接收用户发送的消息(包括单聊和群聊),接受到消息后发送告警卡片 + * Register event handler to handle received messages, including individual chats and group chats. + * https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/events/receive + */ + 'im.message.receive_v1': async (data) => { + const { + message: { chat_type, chat_id }, + sender: { + sender_id: { open_id }, + }, + } = data; + console.log('Received message:', data); + +if (chat_type === 'group') { + await sendAlarmCard('chat_id', chat_id); + } else if (chat_type === 'p2p') { + await sendAlarmCard('open_id', open_id); + } + }, + +/** + * 处理卡片按钮点击回调 + * handle card button click callback + * https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication + */ + 'card.action.trigger': async (data) => { + const { + operator: { open_id }, + action: { value, form_value = {} }, + } = data; + console.log('Received card action:', data); + +/** + * 通过 action 区分不同按钮点击,你可以在卡片搭建工具配置按钮的action。此处处理用户点击了欢迎卡片中的发起告警按钮 + * Use action to distinguish different buttons. You can configure the action of the button in the card building tool. + * Here, handle the situation where the user clicks the "Initiate Alarm" button on the welcome card. + */ + if (value.action === 'send_alarm') { + /** + * 响应回调请求,保持卡片原内容不变 + * Respond to the callback request and keep the original content of the card unchanged. + */ + await sendAlarmCard('open_id', open_id); + return {}; + } + +/** + * 通过 action 区分不同按钮, 你可以在卡片搭建工具配置按钮的action。此处处理用户点击了告警卡片中的已处理按钮 + * Use action to distinguish different buttons. You can configure the action of the button in the card building tool. + * Here, handle the scenario where the user clicks the "Mark as resolved" button on the alarm card. + */ + if (value.action === 'complete_alarm') { + /** + * 读取告警卡片中用户填写的备注文本信息 + * Read the note text information filled in by the user in the alarm card. + */ + const notes = form_value.notes_input || ''; + +return { + toast: { + type: 'info', + content: '已处理完成!', + i18n: { + zh_cn: '已处理完成!', + en_us: 'Resolved!', + }, + }, + card: { + type: 'template', + data: { + template_id: ALERT_RESOLVED_CARD_ID, + template_variable: { + alarm_time: value.time, + open_id: open_id, + complete_time: `${new Date().toLocaleString( + 'zh-CN', + { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + second: '2-digit', + hour12: false, + }, + { timeZone: 'Asia/Shanghai' } + )} (UTC+8)`, + notes: notes, + }, + }, + }, + }; + } + }, +}); + +/** + * 启动长连接,并注册事件处理器。 + * Start long connection and register event handler. + * https://open.feishu.cn/document/server-docs/event-subscription-guide/event-subscription-configure-/request-url-configuration-case#d286cc88 + */ +wsClient.start({ eventDispatcher }); + +console.log('Starting bot...'); +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/develop-a-card-interactive-bot__faqs.md b/embedded-skills/lark-card-designer/docs/raw/develop-a-card-interactive-bot__faqs.md new file mode 100644 index 0000000..25cefd3 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/develop-a-card-interactive-bot__faqs.md @@ -0,0 +1,15 @@ +# 应用配置说明 + +如果你已成功开发卡片交互机器人,你可参考本文档了解开发该应用所需配置、为何配置、以及如何配置。 + +步骤 | 配置步骤 | 配置解释 | 如何配置(本教程已经自动完成以下配置) +---|---|---|--- +1 | 创建自建应用 | 要为用户提供服务,必须创建一个应用作为载体。详情参考[应用类型简介](https://open.feishu.cn/document/home/app-types-introduction/overview)。 | 1. 登录飞书 [开发者后台](https://open.feishu.cn/app)创建应用。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/4513dee3f665e568c87b61d2f3ca8eaf_o9hzp8SlFR.png?height=1396&lazyload=true&width=1190)
1. 在 **基础信息 > 凭证与基础信息** 页面,可以查看应用的 **App ID** 和 **App Secret**。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/e8090af728aaa15bf0686a83573aed34_K27tbcAUCa.png?height=402&lazyload=true&width=2714) +2 | 添加应用能力:
机器人 | 使应用可以接收消息、发送消息,必须为应用开启机器人能力。详情参考[机器人概述](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/bot-v3/bot-overview)。 | 在飞书开发者后台,**应用能力 > 添加应用能力** 页面,添加 **机器人** 能力。
![机器人能力](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/0b708f3c08f92b1856ccdc74954b4fc4_8ZSNcKsolW.png?height=938&lazyload=true&width=2298) +3 | 为机器人能力添加自定义菜单 | 要实现与应用单聊会话中用户可点击聊天输入框上的交互按钮,你需为机器人配置自定义菜单。详情参考[机器人菜单开发指南](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/bot-v3/bot-customized-menu)。 | 1. 在[开发者后台](https://open.feishu.cn/app)机器人能力配置页面,点击 **机器人自定义菜单** 右侧的编辑按钮,将 **菜单状态** 切换至 **开启**。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/8759bd370fcd0b0fa973f173063cb819_ANgMievXzL.png?lazyload=true&width=1511&height=654)
1. 在 **展示形式** 处,选择 **悬浮菜单**。
1. 在 **菜单配置** 处,将名称改为“发起告警”,响应动作选择 **推送事件**,将事件推送的 Key 填写为 `send_alarm`,并选择合适图标。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/010c2fc703bdca0bdf4c96b07b1a719f_XvJsKf6FHS.png?lazyload=true&width=463&height=649) +4 | 申请应用身份权限:
- 读取用户发给机器人的单聊消息(im:message.p2p_msg:readonly)
- 以应用的身份发消息(im:message:send_as_bot)
- 接收群聊中@机器人消息事件(im:message.group_at_msg:readonly) | - 要通过应用调用接口、订阅事件以操作数据,出于安全考虑,必须为应用申请对应权限。
- 要开通的具体权限可在要调用的接口和订阅的事件文档中查看。
- 如果是通过 tenant_access_token 调用接口则申请应用身份权限;如果是通过 user_access_token 调用接口则申请用户身份权限,详情参考[申请 API 权限](https://open.feishu.cn/document/ukTMukTMukTM/uQjN3QjL0YzN04CN2cDN)。 | 1. 参考以下接口、事件和回调文档,了解要开通的权限:
- [发送消息](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/create)接口
- [接收消息](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/events/receive)事件
- [用户进入与机器人的会话](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/chat-access_event/events/bot_p2p_chat_entered)事件
- [机器人自定义菜单](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/application-v6/bot/events/menu)事件
- [卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)回调
![API 权限](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/b1b8cfaf38a73f281109e69647656979_9m2pDCkPBn.png?height=672&lazyload=true&width=1085)
2. 在飞书开发者后台,**开发配置 > 权限管理 > API 权限** 页面,开通应用身份权限。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/98cf65b32bb7523fe87c17cca28ccb28_vYnpRCsz9y.png?height=867&lazyload=true&width=1893) +5 | 添加事件:
- [接收消息](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/events/receive)事件(im.message.receive_v1)
- [用户进入与机器人的会话](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/chat-access_event/events/bot_p2p_chat_entered)(im.chat.access_event.bot_p2p_chat_entered_v1)事件
- [机器人自定义菜单](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/application-v6/bot/events/menu)(application.bot.menu_v6)事件 | 要使应用及时收到用户发送的消息,需要为应用订阅接收消息事件。详情参考[事件概述](https://open.feishu.cn/document/ukTMukTMukTM/uUTNz4SN1MjL1UzM)。 | 1. 在飞书开发者后台,**开发配置 > 事件与回调 > 事件配置** 页面,编辑 **订阅方式**。
![事件配置](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/3edacf00e16195e88a4783b3afea92a1_qCq5uvGHhO.png?height=746&lazyload=true&width=2446)
2. 选择 **使用长连接接收事件**,并点击 **保存**。
**提示**:你需先运行示例代码建立长连接,再保存该订阅方式。
3. 在 **已添加事件** 区域点击 **添加事件**,并添加 **接收消息**、**用户进入与机器人的会话** 和 **机器人自定义菜单** 事件。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/223036c7a791325853e4c0d3ec8ce8fa_iPzQxpQ0R5.png?lazyload=true&width=1480&height=403) +6 | 添加回调:
[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)(card.action.trigger)回调 | 要使应用及时收到用于基于卡片的交互动作并立即更新卡片,需要为应用订阅卡片回传交互回调。详情参考 [回调概述](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/event-subscription-guide/callback-subscription/callback-overview)。 | 1. 在飞书开发者后台,**开发配置 > 事件与回调 > 回调配置** 页面,编辑 **订阅方式**。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/752534be0a8c4ed9de4d6ac792fc8d52_rFQjr3VoJd.png?lazyload=true&width=1356&height=541)
1. 选择 **使用长连接接收回调**,并点击 **保存**。
**提示**:你需先运行示例代码建立长连接,再保存该订阅方式。
1. 在 **已订阅的回调** 区域点击 **添加回调**,并添加 **卡片回传交互** 回调。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/f68a5af25a5bd7bed358c1cc2cf355d5_DtZj4m8Jcp.png?lazyload=true&width=1481&height=246) +7 | 发布应用 | 当应用的基本信息、权限范围和应用功能等信息发生变更时,都需要发布新的应用版本才能正式生效。自建应用发布流程可参见[发布应用](https://open.feishu.cn/document/home/introduction-to-custom-app-development/self-built-application-development-process#baf09c7d)。 | 在飞书开发者后台,**应用发布 > 版本管理与发布** 页面,点击 **创建版本**,填写版本信息并发布并申请发布应用。若本次发布需要管理员审核,建议创建一个新企业用于测试,避免审核耗时。
![发布应用](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/3477fc2d35d468f0e34bfb315fdf0c71_r0Ifd3mxrc.png?height=864&lazyload=true&width=2882) + +完成应用配置并发布应用、运行示例代码后,可体验应用效果。查看代码可参考[示例代码解释](https://open.feishu.cn/document/uAjLw4CM/uMzNwEjLzcDMx4yM3ATM/develop-an-echo-bot/explanation-of-example-code)。 diff --git a/embedded-skills/lark-card-designer/docs/raw/develop-a-card-interactive-bot__introduction.md b/embedded-skills/lark-card-designer/docs/raw/develop-a-card-interactive-bot__introduction.md new file mode 100644 index 0000000..dcd9d65 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/develop-a-card-interactive-bot__introduction.md @@ -0,0 +1,165 @@ +# 三分钟快速开发 + +卡片交互机器人允许用户在机器人发送的飞书卡片上,提交数据并更新卡片。通过本教程,你可以在 **三分钟内创建、发布一个应用并体验效果**,从而了解机器人应用的基本开发流程,以及搭建、发送与更新飞书卡片的流程,和通过服务端 SDK 调用 API 和回调的方法。目前暂不支持在[测试企业](https://open.feishu.cn/document/home/introduction-to-custom-app-development/testing-enterprise-and-personnel-functions)中体验本教程。 + +## 搭建步骤 + + + 创建后,系统将自动添加以下应用配置。详细配置说明参见[应用配置说明](https://open.feishu.cn/document/uAjLw4CM/uMzNwEjLzcDMx4yM3ATM/develop-a-card-interactive-bot/faqs)。 + + + + + 在本步骤中,你需要搭建欢迎卡片、发起告警、告警处理完成共 3 张卡片。点击 **创建卡片** 一键创建。了解如何手动搭建,参考[卡片搭建说明](https://open.feishu.cn/document/uAjLw4CM/uMzNwEjLzcDMx4yM3ATM/develop-a-card-interactive-bot/card-building-steps)。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/1c941e0c0724fcb0d550ad9431271892_YTNcLhl9Fn.png?height=412&lazyload=true&maxWidth=500&width=1121) + + + + +当应用的基本信息、权限范围和应用功能等信息发生变更时,都需要发布新的应用版本才能正式生效。自建应用发布流程可参见[发布应用](https://open.feishu.cn/document/home/introduction-to-custom-app-development/self-built-application-development-process#baf09c7d)。 + + +请选择你所需运行的语言后,根据视频提示启动示例代码,代码下载和说明参见[示例代码解释](https://open.feishu.cn/document/uAjLw4CM/uMzNwEjLzcDMx4yM3ATM/develop-a-card-interactive-bot/explanation-of-example-code)。 + + + + 点击 **打开** 按钮体验机器人。完整体验机器人的方式参考下文。 + + + +如果你在一键创建、发布、运行代码、体验应用的过程中有任何问题,欢迎点击此[表单](https://bytedance.larkoffice.com/share/base/form/shrcnC4hpksD9Z8etkdyJa87F5g?hide_docid=1&hide_userid=1&hide_%E4%B8%9A%E5%8A%A1%E5%9F%9F=1&hide_%E5%8F%8D%E9%A6%88%E4%B8%8A%E4%B8%8B%E6%96%87=1&hide_%E5%8F%8D%E9%A6%88%E6%9D%A5%E6%BA%90=1&hide_%E6%96%87%E6%A1%A3%E6%A0%87%E9%A2%98=1&hide_%E6%96%87%E6%A1%A3%E9%93%BE%E6%8E%A5=1&prefill_docid=7457433042430476292&prefill_%E4%B8%9A%E5%8A%A1%E5%9F%9F=7473534698498539548&prefill_%E5%8F%8D%E9%A6%88%E4%B8%8A%E4%B8%8B%E6%96%87=%E5%8D%A1%E7%89%87%E4%BA%A4%E4%BA%92%E6%9C%BA%E5%99%A8%E4%BA%BA&prefill_%E5%8F%8D%E9%A6%88%E6%9D%A5%E6%BA%90=%E5%88%92%E8%AF%8D%E5%8F%8D%E9%A6%88&prefill_%E6%96%87%E6%A1%A3%E6%A0%87%E9%A2%98=%E4%B8%89%E5%88%86%E9%92%9F%E5%BF%AB%E9%80%9F%E5%BC%80%E5%8F%91&prefill_%E6%96%87%E6%A1%A3%E9%93%BE%E6%8E%A5=https%3A%2F%2Fopen.feishu.cn%2Fdocument%2FuAjLw4CM%2FuMzNwEjLzcDMx4yM3ATM%2Fdevelop-a-card-interactive-bot%2Fintroduction)反馈。 + +## 实现效果 + +卡片交互机器人的的最终实现效果如下所示: + +用户与机器人单聊 | 用户在群组内@机器人 +---|--- +1. 用户进入与机器人单聊页面,机器人自动发送“欢迎”卡片
2. 用户点击欢迎卡片的 **去体验:发起告警** 按钮,机器人发送“发起告警”卡片
提示:用户也可点击输入框上方 **发起告警** 菜单按钮,或向机器人发送任意文字消息以触发机器人发送该卡片
3. 用户在卡片输入框中输入处理情况说明,然后点击 **处理完成** 按钮。卡片更新为“告警处理完成”卡片 | 1. 用户在群组内@机器人,机器人自动发送“发起告警”卡片
3. 用户在卡片输入框中输入处理情况说明,然后点击 **处理完成** 按钮。卡片更新为“告警处理完成”卡片 +![20250310183640_rec_-convert.gif](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/741a0e817d37dee2aa5b751768a623ba_I5mUSzD1hg.gif?height=952&lazyload=true&maxWidth=482&width=1556) | ![20250310183944_rec_-convert.gif](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/327a029c9d1666c32437e6fe47055203_B8zNX17CLe.gif?height=952&lazyload=true&maxWidth=482&width=1556) + +## 体验机器人 + +应用发布生效后,前往飞书客户端验证机器人的实现效果。 +**注意事项**:登录飞书客户端的用户必须要在[应用可用范围](https://open.feishu.cn/document/home/introduction-to-scope-and-authorization/availability)内。本教程中建议使用应用所有者身份登录飞书客户端进行测试。 +### 与机器人单聊 + +1. 在飞书客户端内搜索应用机器人名称,进入与机器人单聊页面。 +**注意事项**:你也可以通过 AppLink 打开机器人会话,链接地址 `https://applink.feishu.cn/client/bot/open?appId={appId}`,详情参见[打开机器人会话](https://open.feishu.cn/document/uAjLw4CM/uYjL24iN/applink-protocol/supported-protocol/open-a-bot)。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/e43222d51ba6936738e2abc8cabc7943_p8mSaZkYe3.png?height=403&lazyload=true&maxWidth=600&width=1399) + +机器人将自动发送“欢迎体验”卡片。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/77fa3553b6485e7ef6a2ab56448739c4_JD51vmuwit.png?height=957&lazyload=true&maxWidth=382&width=944) + +2. 点击 **去体验:发起告警** 按钮。 + +机器人将发送“发起告警”卡片。 +**注意事项**:你也可点击输入框上方 **发起告警** 菜单按钮,或向机器人发送任意文字消息以触发机器人发送“发起告警”卡片。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/a6aa146400711295a34434efe73270fd_gQOQZZxJ2d.png?height=957&lazyload=true&maxWidth=382&width=944) + +3. 在卡片输入框中输入处理情况说明,然后点击 **处理完成** 按钮。 + +卡片更新为“告警处理完成”卡片。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/c7e6dab9bc2253070cc394f196fbadb3_AYCV28oZoq.png?height=957&lazyload=true&maxWidth=382&width=944) + +### 在群聊中@机器人 + +1. 进入某一群组,在群组的 **设置** > **群机器人** 功能中,搜索应用机器人并添加。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/e3645df966e1ae129c2c3e89ca6664ef_G7ZtJD2ntl.png?height=957&lazyload=true&maxWidth=382&width=944) + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/c8627343af9ce15e7a154a551707100b_qNO2nm4suk.png?height=870&lazyload=true&maxWidth=382&width=1260) + +2. 在群组聊天中,发送@机器人消息。机器人将发送“发起告警”卡片。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/9f4a1914b2a1b6c9bfc9d42c3f5e4cbd_CP508QmBuM.png?height=957&lazyload=true&maxWidth=382&width=944) + +4. 在卡片输入框中输入处理情况说明,然后点击 **处理完成** 按钮。 + +卡片将更新为“告警处理完成”卡片。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/782664dbaaf95846f3f47a7a25e0affb_J3H92sdlcs.png?height=957&lazyload=true&maxWidth=382&width=944) +## 常见问题 +### 问题一:无法搜索到应用 + +当前用户不在[应用可用范围](https://open.feishu.cn/document/home/introduction-to-scope-and-authorization/availability)内。你可前往开发者后台 **版本管理与发布** 确认。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/a370e44b504c9877e30d9abef5430faf_wa2micsctT.png?height=624&lazyload=true&maxWidth=600&width=1322) + +### 问题二:进入机器人单聊后,机器人没有自动发送 “欢迎” 卡片 + +项目与开放平台的长连接已断开。请重新复制启动命令并重新启动程序,确保命令提示符中显示如下信息。 + +- Go + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/2006481551c016793a20542ed73053c3_x0OfJnP6tT.png?height=232&lazyload=true&maxWidth=700&width=1914) + +- Python + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/d5030af3ba58f2ae2830b2cb649dcb03_6NPdMGAFfY.png?height=128&lazyload=true&maxWidth=700&width=1846) + +- Java + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/b72ecd4410e0038f03b40adf944093c4_GWlNlvnsLu.png?height=72&lazyload=true&maxWidth=700&width=1924) + +- Node.js + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/a228cc501059e600a173d677a490a804_xxKfJVRKnb.png?height=432&lazyload=true&maxWidth=700&width=1878) + +### 问题三:与机器人单聊会话中,没有菜单按钮 + +这是因为机器人菜单的配置有延时。请稍等几分钟再查看。 + +### 问题四:运行代码报 SSLCertVerificationError 错误 + +该错误表示 SSL 证书验证失败,通常是由于本地环境服务器证书无效、过期、或自签名缺失等原因造成。你可尝试升级系统或升级系统依赖解决。 + +### 问题五:如何重复体验机器人 + +如需重复体验(例如体验创建发布应用、体验多种开发语言),可在第一步创建应用中,点击 **查看应用** 按钮右侧的 **重新创建应用**。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/85cb112cc7e1154b92a0077225fc97c9_s8OLncrYrj.png?height=521&lazyload=true&maxWidth=600&width=856) + +## 后续操作 + +如果你已完成本教程的搭建步骤、成功搭建了卡片交互机器人,你可以: + +- 在示例代码包中,选择所需代码语言的示例文件,基于你自己的业务场景,修改代码逻辑 +- 自行搭建服务器并部署代码,将启动指令中的 `APP_ID`、`APP_SECRET`、`CARD_ID` 等参数传入本地环境变量即可 + **注意事项**:本教程中的示例代码使用 **长连接** 接收事件方式,支持线上部署。但如果你在 FaaS 模型下部署代码、在生产环境中调试,推荐你选择[将事件发送至开发者服务器](https://open.feishu.cn/document/ukTMukTMukTM/uYDNxYjL2QTM24iN0EjN/event-subscription-configure-/choose-a-subscription-mode/send-notifications-to-developers-server)的方式,资源利用更高效,调试更便利。 + +## 了解更多 + +要了解如何开发一个自动回复机器人,可查看教程[开发一个自动回复机器人](https://open.feishu.cn/document/uAjLw4CM/uMzNwEjLzcDMx4yM3ATM/develop-an-echo-bot/introduction)。 diff --git a/embedded-skills/lark-card-designer/docs/raw/development-link-preview__link-preview-development-guide.md b/embedded-skills/lark-card-designer/docs/raw/development-link-preview__link-preview-development-guide.md new file mode 100644 index 0000000..40b94ef --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/development-link-preview__link-preview-development-guide.md @@ -0,0 +1,171 @@ +# 链接预览开发指南 + +链接预览能力可以将飞书消息中的链接,转换为文字或卡片的形式进行展示。本文将介绍什么是链接预览,以及如何配置链接预览。 + +## 功能概述 + +链接预览是把飞书消息、群置顶等场景内包含的链接解析为带图标的文本内容,或者是一张具备结构化样式、可进行简单交互的卡片,以便消息接收者在不进行链接跳转的情况下,快速了解链接所包含的内容,或者通过卡片交互完成业务操作。 + +没有实现链接预览和已实现链接预览的效果如下所示,其中: + +- 未实现链接预览时,飞书消息中的链接仅展示 URL,当用户查看消息时无法直接了解该 URL 包含的信息,必须点击访问后才可以进行下一步信息处理。 +- 实现链接预览时,飞书消息中的链接会被解析为带图标的文本内容,或者附带一张包含链接内容概览的卡片。这样用户在查看消息时,可便捷直观的了解该链接所包含的内容。 + +![Frame 1.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/21a955bd5e16e43332ba143490e44362_IDZwaPuTPn.png?height=1112&lazyload=true&maxWidth=700&width=2160) + +更多链接预览的应用案例,可参见[典型案例](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/development-link-preview/typical-case)。 + +## 实现方式 + +链接预览是飞书开放平台应用的能力之一。你可以在应用内定义 URL 规则,来指定生效预览能力的链接范围。在你本地业务服务器内,接收来自开放平台的链接预览回调请求,并通过响应请求的方式,实现链接预览的文本与卡片。链接预览能力在飞书中的实现流程如下图所示。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/7053ab0f557687ee5a3d6c4884e76525_suTZoMJyyl.png?height=1148&lazyload=true&maxWidth=700&width=2000) + +流程概述: +1. 查看者在飞书客户端的会话、群置顶等场景中查看链接。 +2. 飞书将会通过应用的链接预览能力,校验该链接是否命中 URL 规则。 + +命中则继续执行下一步,未命中则不会对该链接进行解析。 + +3. 命中 URL 规则后,飞书会向你本地的业务服务器发送回调请求。 +4. 在业务服务器内,你需要处理回调请求,并在 3 秒内响应该请求。 + +响应体中定义了链接预览的文本与卡片数据。 + +5. 在飞书客户端内,链接查看者可查看链接预览效果。 + +## 配置链接预览 + +本文以企业自建应用为例,介绍如何配置链接预览。商店应用的配置方式与企业自建应用类似。 + +### 步骤一:创建应用并启用链接预览能力 + +想要在飞书客户端内实现链接预览,需要在飞书开放平台创建一个应用并启用链接预览能力。企业自建应用发布后,链接预览将对[应用可用范围](https://open.feishu.cn/document/home/introduction-to-scope-and-authorization/availability)内的用户生效,即用户在发送消息时,链接如果命中 URL 规则,便会对应用可见范围内的用户展示预览效果。 + +应用开发流程参见[企业自建应用开发流程](https://open.feishu.cn/document/home/introduction-to-custom-app-development/self-built-application-development-process)或[商店应用上架流程](https://open.feishu.cn/document/uMzNwEjLzcDMx4yM3ATM/ugzNwEjL4cDMx4CO3ATM)。 +- 当企业内安装了具备链接预览能力的应用后,链接预览所注册的 URL 规则只对**应用可用范围**内的用户生效。 +- 仅正式版本的应用支持链接预览功能,且配置完成后需要发布应用使功能生效。测试版本的应用不支持配置链接预览。 + +#### 操作步骤 + +1. 登录[开发者后台](https://open.feishu.cn/app)。 +2. 创建一个用于实现链接预览能力的应用。 +3. 进入应用详情页,在左侧导航栏点击 **应用能力** > **添加应用能力**。 +4. 在 **添加应用能力** 页面的 **按能力添加** 页签,找到并添加 **链接预览**。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/4b546c4ffa451a8138327d61da5acc7d_AQAw6sEsap.png?height=1282&lazyload=true&maxWidth=600&width=2868) + +### 步骤二:注册链接预览的 URL 规则 + +链接预览的 URL 规则用于定义实现链接预览能力的链接范围。在 **链接预览** 功能页的 **①注册需要自定义预览的 URL 规则** 区域,你可以点击 **添加 URL 规则** 配置链接,最多可配置 10 个 URL 规则。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/c26d345adf52b23afabc003a978f085b_7sXniihMth.png?height=594&lazyload=true&maxWidth=600&width=1464) + +#### URL 规则输入要求 + +- URL 规则的格式为 `Host:Port/Path`。示例值 `example.com/demo` + - `Host`:URL 规则的域名部分,必填。 + - `Port`:端口号,选填。 + - `/Path`:子路径,选填。 + +- `Host:Port` 为主机地址,其中的 `Port` 是端口号、`/Path` 是子路径。示例值:`example.com/demo` + +- 不能以 `https`、`http` 等 schema 开头。 + +- 不能在 `Host` 部分使用 IP 地址。`Host` 部分必须包含顶级域名、二级域名,且顶级域名、二级域名部分禁止使用通配符。无效的 URL 规则示例:`*.cn`、`example.*`、`example` + +- 禁止注册包含恶意内容的非法网站为 URL 规则,开发者后台会对 URL 规则的安全性做校验。 + +#### URL 规则的匹配方式 + +链接预览能力提供了两种 URL 规则的注册匹配方式:warning +**注意**:配置 URL 规则时不能以 `https`、`http` 开头,但后续在飞书客户端内想要生效链接预览效果,对应的链接必须以 `https`、`http` 开头。 + +URL 规则匹配方式 | 说明 +---|--- +无通配符 | 你可以输入不包含通配符的 URL,该 URL 及其所有子路径均会匹配该应用的链接预览能力。
例如:应用 A 注册的 URL 规则为 `example.com`,安装该应用的租户下,用户发送、查看 `https://example.com/path?query` 时,会匹配应用 A 的 URL 规则。 +有通配符 | 你可以输入包含通配符的 URL,此时系统会严格按照通配符生效链接预览。
- **使用 `*` 通配符定义 URL 规则**
- 域名内通过 `.` 分割为多个域名级别。顶级域名、二级域名部分禁止使用通配符,其他级别可使用 `*` 匹配剩下的所有内容。该通配符后边不能再有其他字符,即 `*` 无法跨域名级别匹配,且 `*` 必然是当前域名级别的结尾。
示例配置:`*.example.com`
- 路径内通过 `/` 分割为多层级路径。在每层路径内,可使用 `*` 匹配剩下的所有内容。该通配符后边不能再有其他字符,即 `*` 无法跨路径层级匹配,且 `*` 必然是当前路径层级的结尾。
示例配置:`example.com/*/task`
- **使用 `**` 通配符定义 URL 规则**
- 在域名内,通过 `**` 匹配整个域名左侧的内容,且该通配符的左侧不能再有其他字符。示例配置:
- 正确配置:`**.example.com`
- 错误配置:`a.**.example.com`
- 在路径内,通过 `**` 匹配整个路径右侧的内容,且该通配符的右侧不能再有其他字符。示例配置:
- 正确配置:`/a/b*/**`
- 错误配置:`/a/b*/**/c`
场景示例:
- 应用 A 注册的 URL 规则为 `**.example.com`,安装该应用的租户下,用户发送、查看 `https://business1.example.com`、`https://project1.business1.example.com` 时,均会匹配应用 A 的 URL 规则。
- 应用 B 注册的 URL 规则为 `example.com/**`,安装该应用的租户下,用户发送、查看 `https://example.com/path` 时,会匹配应用 B 的 URL 规则。 + +#### URL 规则的排他性 + +- 对于企业自建应用:当一个自建应用成功注册、并提交发布链接预览的 URL 规则后,本企业内的其他自建应用将无法注册任何与该 URL 规则有交集的规则。 + +例如,应用 A 注册了 `example.com`,同企业内的应用 B 尝试注册 `example.com/path` 时将会报错规则冲突,无法注册。 +- 对于商店应用:当一个商店应用成功注册、并提交发布链接预览的 URL 规则后,其他商店应用将无法注册任何与该 URL 规则有交集的规则。 + +例如,应用 A 注册了 `example.com`,当应用 B 尝试注册 `example.com/path` 时将会报错规则冲突,无法注册。 +- 如果自建应用和商店应用配置的 URL 规则出现交集,则优先生效自建应用的 URL 规则。 +- 不能将飞书的保留域名注册为链接预览的 URL 规则。如果误注册了飞书的保留域名,开发者后台将会报错提示,并禁止提交该 URL 规则。 + +### 步骤三:配置订阅链接预览回调 +**注意**:URL 规则和订阅回调的配置操作都是必须的,否则将会造成链接预览功能异常。 + +完成 URL 规则的配置后,你需要在 **配置订阅链接预览回调** 区域点击 **去配置**,跳转至 **事件与回调** 功能页[配置回调订阅方式](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/event-subscription-guide/callback-subscription/callback-overview),然后订阅 [拉取链接预览数据(url.preview.get)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/development-link-preview/pull-link-preview-data-callback-structure)回调。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/11e567bc996c101a29eac71693f01b02_AFM6WWxEEz.png?height=617&lazyload=true&maxWidth=600&width=1514) + +后续当用户在飞书客户端发送、查看的链接命中当前应用的预览链接 URL 规则时,飞书服务器会向你注册的回调地址发送请求,请求包含了链接预览数据。示例回调数据如下: + +```json +{ + "schema": "2.0", + "header": { //回调的通用参数 + "event_id":"", + "token": "vi57noNQoGbhxxxxxWmmWdlsSn3FTzk1", + "create_time": "170134xxxxx18480", + "event_type": "url.preview.get", + "tenant_key": "736xxxxx260f175d", + "app_id": "cli_a40xxxxxe57e100c" + }, + "event": { //拉取链接预览回调的上下文参数 + "operator": { //查看链接的用户信息 + "tenant_key": "736588cxxxx175d", + "user_id": "c3xxxxd1", + "open_id": "ou_xxxxx54182ea7b8319f4d39823b79d2" + }, + "host": "im_message", //链接所在的宿主场景。枚举包括:1.im_message 聊天消息;2.im_top_notice 群置顶 + "delivery_type": "url_preview", //当 "delivery_type": "url_preview" 表示回调来自链接预览 + "context": { //这个场景下具体的上下文参数 + "url": "https://example.com/test/111", //匹配 URL 规则的原链接 + "preview_token": "e28r7df2-xxxx-477d-a8d0-2e1eb9971234", //用于标识链接预览的凭证,在返回链接预览数据时要用 + "open_message_id": "om_191d914xxxxx81c97a609c6634521234", //触发链接预览的消息 ID + "open_chat_id": "oc_20443194b65f9c8cf2935818dae31234" //触发链接预览的群 ID + } + } +} +``` + +### 步骤四:实现链接预览内容warning +- 链接预览支持千人千面,即不同用户的链接预览效果是独立拉取的,因此你需要确保预览内容的数据安全。如果涉及非公开数据请做好权限管控,避免数据泄露。 +- 在人数较多的群聊、热点传播等场景,实现链接预览效果时会产生并发流量,因此建议业务以 400 QPS 为阈值评估并发流量,做好系统防护措施,无法处理的流量应做好降级方案。 + +服务端接收到回调请求后,需要在 3 秒内响应请求,并在响应体内定义链接预览内容。响应体结构如下(详细说明参见[拉取链接预览数据](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/development-link-preview/pull-link-preview-data-callback-structure))。查看该结构可知,链接预览有两种实现形式。 + +- **链接解析**:必选预览形式。通过 `inline` 字段,设置链接解析的文本与图标。该形式可以概括介绍链接对应的网页内容。 +- **卡片**:可选预览形式。通过 `card` 字段,匹配指定的卡片 ID、版本、变量数据,以返回一张具备结构化样式、可进行简单交互的卡片。该形式可以通过卡片展示更加丰富的链接内容,包括可以直接通过卡片的交互能力管理链接对应的网页内容。如何配置卡片,可参见[飞书卡片概述](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-overview)。 + +```json +// 如需使用该示例代码,需要去除代码中以 // 开头的注释内容,并根据实际情况设置参数值。 +{ + "inline": { //返回文字预览内容,这部分是必填必须要返回的 + "i18n_title": { + "zh_cn": "smart card 测试点击跳转 & 富文本" //链接预览文本 + }, + "image_key": "img_v3_025m_5xxxxxf9-ed30-4980-afff-827e13d8xxxx" //链接预览的前缀图标 + }, + "card": {//返回卡片预览内容 + "type": "template", //卡片的组织形式。枚举包括 1.template:模板方式,用如下结构返回卡片内容 2.raw 返回完整的卡片JSON内容 + "data": { + "template_id": "AAqVG2xxxxxBS", //必填,卡片的模板id + "template_version_name": "1.0.0", //选填,卡片的版本号。不填则表示使用最新发布版本的卡片 + "template_variable": {} //选填,返回卡片绑定的变量列表数据 + } + } +} +``` + +## 相关文档 + +- 上手体验链接预览能力,参见[快速入门](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/development-link-preview/quick-start)。 +- 开放平台提供了更新链接预览卡片的 OpenAPI,详情参见[更新 URL 预览](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/group/im-v2/url_preview/batch_update)。 +更新链接预览时需要注意更新频率,如果更新时不指定用户,则可能会造成链接预览请求放大。例如,群聊中的链接预览,所有群成员均会尝试重新拉取预览请求。 diff --git a/embedded-skills/lark-card-designer/docs/raw/development-link-preview__pull-link-preview-data-callback-structure.md b/embedded-skills/lark-card-designer/docs/raw/development-link-preview__pull-link-preview-data-callback-structure.md new file mode 100644 index 0000000..fed5e31 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/development-link-preview__pull-link-preview-data-callback-structure.md @@ -0,0 +1,118 @@ +# 拉取链接预览数据 + +**拉取链接预览数据** 回调作用于应用的链接预览能力。当企业内发布了具备链接预览能力的应用后,企业成员在飞书客户端查看、发送链接时,如果链接命中了应用注册的 URL 规则,则应用会向指定的回调地址发送 **拉取链接预览数据** 回调。你需要在对应的业务服务器内接收回调请求,并在 3 秒内响应回调请求,飞书客户端会根据响应数据渲染链接预览效果。 +需应用配置并生效链接预览能力后,回调才可以推送生效。 + +## 回调 + +基本信息 |   +---|--- +回调类型 | url.preview.get +支持的应用类型 | Custom App、Store App +权限要求
**订阅该事件所需的权限,开启其中任意一项权限即可订阅**
开启任一权限即可 | 暂无 +字段权限要求 | **注意事项**:事件结构体中存在 `user_id` 敏感字段,仅当应用开启以下权限后才会返回。如果无需获取该字段,则不建议申请。
获取用户 user ID(contact:user.employee_id:readonly) +推送方式 | [Webhook](https://open.feishu.cn/document/ukTMukTMukTM/uUTNz4SN1MjL1UzM) + +## 结构体 + +字段 | 数据类型 | 描述 +---|---|--- +schema | string | 回调的版本。 +header | object | 回调的基本信息。 +event_id | string | 回调的唯一标识。 +token | string | 应用的 Verification Token。 +create_time | string | 回调发送的时间。 +event_type | string | 回调类型。拉取链接预览场景中,固定为 `"url.preview.get"`。 +tenant_key | string | 应用归属的 tenant key,即租户唯一标识。 +app_id | string | 应用的App ID。 +event | object | 回调的详细信息。 +operator | object | 回调触发者信息。 +tenant_key | string | 回调触发者的 tenant key,即租户唯一标识。 +user_id | string | 回调触发者的 user_id。了解不同的用户 ID,参见[用户身份概述](https://open.feishu.cn/document/home/user-identity-introduction/introduction)。 +open_id | string | 回调触发者的 open_id。 +host | string | 链接预览展示的场景。可能值:
- im_message:会话消息
- im_top_notice:群置顶 +context | object | 场景上下文。 +url | string | 预览链接。 +preview_token | string | 预览 Token。该 Token 用于调用[更新 URL 预览](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/group/im-v2/url_preview/batch_update)接口,主动更新 URL 预览。
**注意**:
- 同一条消息的同一个链接可能会触发多次拉取链接预览数据回调(例如多端登录飞书查看消息、群聊内多个用户查看消息等),这些回调包含的 preview_token 值相同。
- 消息发送后才会产生 preview_token,因此,临时预览场景(即在会话输入框输入链接,但消息还未发送时),不会产生 preview_token。 +open_message_id | string | 链接所在的消息 ID。
**注意**:临时预览场景(即在会话输入框输入链接,但消息还未发送时)open_message_id 为空值。 +open_chat_id | string | 链接所在的会话 ID。
**注意**:临时预览场景(即在会话输入框输入链接,但消息还未发送时)open_chat_id 为空值。 + +## 回调结构体示例 + +```json +{ + "schema": "2.0", + "header": { + "event_id": "f7984f25108f8137722bb63cee92xxxx", + "token": "066zT6pS4QCbgj5Do145GfDbbagCxxxx", + "create_time": "1603977298000000", + "event_type": "url.preview.get", + "tenant_key": "xxxxxxx", + "app_id": "cli_xxxxxxxx" + }, + "event": { + "operator": { + "tenant_key": "xxxxxxx", + "user_id": "xxxxxxx", + "open_id": "ou_xxx" + }, + "host": "im_message", + "context": { + // url相关参数 + "url": "xxx", + "preview_token": "xxx", + "open_message_id": "om_xxx", + "open_chat_id": "oc_xxx" + } + } +} +``` + +## 响应回调的结构体 + +当你在自建的业务服务器中接收 **拉取链接预览数据** 回调请求时,需要在 3 秒内响应该请求,飞书客户端会根据响应数据渲染链接预览效果。相应回调的结构体如下表所示。 + +字段 | 是否必选 | 数据类型 | 描述 +---|---|---|--- +inline | 否 | object | 链接预览数据。 +title | 否 | string | 链接预览的标题。
**注意事项**:**说明**:该参数与 `i18n_title` 同时设置时,优先生效 `i18n_title`。 +i18n_title | 否 | Map | 链接预览的多语言标题。
**注意事项**:**说明**:该参数与 `title` 同时设置时,优先生效 `i18n_title`。 +key | 否 | string | 语言。可选值:
- zh_cn:简体中文
- zh_tw:繁体中文(中国台湾)
- zh_hk:繁体中文(中国香港)
- en_us:英语
- ja_jp:日语
- fr_fr:法语
- hi_in:印地语
- id_id:印度尼西亚语
- it_it:意大利语
- ko_kr:韩语
- pt_br:葡萄牙语(巴西)
- ru_ru:俄语
- th_th:泰语
- vi_vn:越南语
- de_de:德语
- es_es:西班牙语 +value | 否 | string | 语言对应的标题。 +image_key | 否 | string | 链接的前缀图标对应的 image_key。你可以通过[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口,上传一张用于发送消息的图片,并在返回结果中获取 image_key。 +url | 否 | object | 链接预览地址。 +copy_url | 否 | string | 在消息中复制链接所获取到的 URL。 +ios | 否 | string | iOS 跳转 URL。 +android | 否 | string | Android 跳转 URL。 +pc | 否 | string | PC 端跳转 URL。 +web | 否 | string | Web 跳转 URL。 +card | 否 | object | 卡片数据。 +type | card 内必填 | string | 卡片类型。可选值:
- template:卡片模板类型,即通过卡片 ID、版本号定位卡片。
- raw:卡片 JSON,通过完整的卡片 JSON 构建卡片。
了解如何构建卡片,参见[构建卡片内容](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/build-card-content)。 +data | card 内必填 | object | 卡片内容。 +template_id | template 类型必填 | string | 卡片模板 ID。模板类型卡片使用的字段。 +template_variable | 否 | Map | 卡片模板变量。模板类型卡片使用的字段。 +template_version_name | 否 | string | 卡片模版版本。模板类型卡片使用的字段。 +config | 否 | object | 卡片配置。raw 类型卡片使用的字段。 +elements | raw 类型必填 | object | 卡片组件。raw 类型卡片使用的字段。 +header | 否 | string | 卡片标题。raw 类型卡片使用的字段。 + +## 响应回调结构体示例 + +```json +{ + "inline": { + "i18n_title": { + "zh_cn": "smart card test click jump & rich text" + }, + "image_key": "img_v3_025m_5xxxxxf9-ed30-4980-afff-827e13d8xxxx" + }, + "card": { + "type": "template", + "data": { + "template_id": "AAqVG2xxxxxBS", + "template_version_name": "1.0.0", + "template_variable": {} + } + } +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/development-link-preview__quick-start.md b/embedded-skills/lark-card-designer/docs/raw/development-link-preview__quick-start.md new file mode 100644 index 0000000..352b2b8 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/development-link-preview__quick-start.md @@ -0,0 +1,194 @@ +# 快速入门 + +本文提供完整的链接预览配置流程,供你参考并上手体验链接预览功能。 + +## 准备工作 + +- 已了解链接预览功能的实现方式与配置流程,详情参见[链接预览开发指南](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/development-link-preview/link-preview-development-guide)。 + +- 本地已配置 [Node.js](https://nodejs.org/en) 开发环境,或者 [Go](https://go.dev/) 开发环境。 + +本文提供了 [Node.js 示例代码](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/096e72afaf3b3086910dbab3217e86d4_O3xgFH04vt.js) 和 [Go 示例代码](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/ee10b1d29a2548e410976223949d4dc3_5gNzacrU1c.zip),你可以根据本地开发环境选择使用。 + +## 步骤一:创建并配置应用 + +1. 登录[开发者后台](https://open.feishu.cn/app)。 +2. 在 **企业自建应用** 页面,点击 **创建企业自建应用**。 + +本文以自建应用为例介绍配置流程。你也可以选择创建商店应用,其中的链接预览配置流程与自建应用相同。配置商店应用的具体操作,参见[流程概述](https://open.feishu.cn/document/uMzNwEjLzcDMx4yM3ATM/ugzNwEjL4cDMx4CO3ATM)。 +3. 配置应用的名称、描述与图标,并点击 **保存**。 + +例如,创建名为 `Card & URL Demo` 的应用,描述与图标自定义配置即可。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/0d13c3d4aaaecdfa20b081f7ad72d1ae_T80aq4Cf78.png?height=1392&lazyload=true&maxWidth=400&width=1184) + +## 步骤二:构建飞书卡片 + +你需要构建一张飞书卡片,后续用于绑定链接预览。了解飞书卡片可参见[飞书卡片概述](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-overview)。 + +1. 登录[飞书卡片搭建工具](https://open.feishu.cn/cardkit)。 +2. 点击 **创建空白卡片**,配置卡片名称并绑定已创建的应用,然后点击 **创建**。 + +本示例中,创建名为 `CardDemo` 卡片,并与 `Card & URL Demo` 应用进行绑定。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/97d129b59a413a59fd1eec3b9ccce7ed_Sfudws8x7V.png?height=604&lazyload=true&maxWidth=400&width=1168) + +3. 在搭建工具中,将卡片预览场景切换为 **消息链接预览**,便于预览效果。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/14c8e7cd3ad388b8f97345cb3ac34e69_y9kIUzGb99.png?height=928&lazyload=true&maxWidth=600&width=2730) +4. 在搭建工具左侧 **组件** 列表的底部,点击 **参考案例库**。 +5. 在 **团队文化** 模块内,使用 **周年庆典**。 + +本文使用 **周年庆典** 卡片作为示例,你也可以自行构建卡片内容。 + +6. 在弹出的对话框中,点击 **替换**。 + +7. 在工具右上角,保存并发布卡片。 + +发布时你需要设置 **卡片版本号**,首个版本使用 `1.0.0` 即可。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/e171087954d0f29ea99c2cfe401ffe85_5w2kvrwvdR.png?height=564&lazyload=true&maxWidth=400&width=824) + +8. 卡片发布后,在搭建工具的顶部,获取卡片 ID。 + +你需要保存卡片 ID 与版本号,在后续配置示例代码时需要使用。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/4391f7b39adb26671fa420ff66c19bab_8wqIi7UZxS.png?height=364&lazyload=true&maxWidth=600&width=2882) + +## 步骤三:下载并运行示例代码 + +使用本文提供的示例代码包,在本地构建一个业务服务器,用于处理来自飞书开放平台的回调请求。 + +### Node.js 代码包 + +1. 下载[示例代码](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/096e72afaf3b3086910dbab3217e86d4_O3xgFH04vt.js)。 + +```bash + curl https://sf3-cn.feishucdn.com/obj/open-platform-opendoc/096e72afaf3b3086910dbab3217e86d4_O3xgFH04vt.js -o url_preview.js + ``` +2. 下载完成后,进入示例代码所在的文件目录。 +3. 打开 url_preview.js 文件,修改卡片 ID 与卡片版本号。 + +使用你常用的打开文件方式即可。例如,在终端内使用 `vi/vim` 命令打开文件,或使用 VSCode 等本地开发工具打开文件。 + +- 找到 `template_id`,将代码中的示例值,修改为你构建的飞书卡片的真实 ID。 + +- 找到 `template_version_name`,将代码中的示例值,修改为你构建的飞书卡片的真实版本号。 + +- 如果你的飞书卡片配置了卡片变量,则需要通过 `template_variable` 字段为变量赋值。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/e5846ef22aeae34d01070fe3d23f27ed_5mCH5ro1aW.png?height=848&lazyload=true&maxWidth=600&width=1462) + +4. 在本地使用命令行工具,进入示例代码所在目录并运行以下命令,启动服务并监听 3000 端口。 + +```bash + node url_preview.js + ``` + +### Go 代码包 + +1. 下载 [Go 示例代码](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/ee10b1d29a2548e410976223949d4dc3_5gNzacrU1c.zip)。 + +``` + curl https://sf3-cn.feishucdn.com/obj/open-platform-opendoc/ee10b1d29a2548e410976223949d4dc3_5gNzacrU1c.zip -o preview_example.zip + ``` +2. 在本地解压已下载的代码包。 +3. 在代码包中打开 preview.go 文件,找到 `url_preview` 字段并根据实际情况修改回调结构。 + +本示例中,通过 [GoLand](https://www.jetbrains.com/go/) 工具打开并配置代码包。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/9315b7b1913f078cdef8e4f7b4ca1240_Qhjc9l3EVM.png?height=1338&lazyload=true&maxWidth=600&width=2848) + +回调结构配置说明: + +- 找到 `TemplateID`,将代码中的示例值,修改为你构建的飞书卡片的真实 ID。 + - 找到 `VersionName`,将代码中的示例值,修改为你构建的飞书卡片的真实版本号。 + - 如果你的飞书卡片配置了卡片变量,则需要通过 `Variable` 为变量赋值。 + +4. 在 main.go 中运行 `main` 函数,启动服务并监听 **3000** 端口。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/6b5bc3a6826c52d0efbc6d4cc164c56a_dvEXnVKVhd.png?height=1496&lazyload=true&maxWidth=600&width=2872) + +### 获取本地公网地址warning +**注意:**
+- 如果本机有公网地址,可跳过本步骤。 +- 如果本机没有公网地址,本教程为了方便实现,使用了反向代理工具([ngrok](https://ngrok.com/download))完成内网穿透,暴露本地服务的公网访问入口。**该工具仅适用于开发测试阶段,不可用于生产环境,使用前请确认是否符合所在公司网络安全政策。** +- **测试完成后,如需正式发布应用,你需要修改为真实有效的公网地址。** + +1. 注册并安装 [ngrok](https://ngrok.com/download),按照官方指引完成安装。 +2. 在个人的 [dashboard 页面](https://dashboard.ngrok.com/get-started/your-authtoken) 中,获取 Authtoken。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/3a6d48a86bbd55342a81f80e43561204_dLGeBfcu8M.png?height=624&lazyload=true&maxWidth=600&width=2480) + +3. 在本地依次运行以下命令,获得公网 URL。 + +```bash + ngrok authtoken "token" // token需替换为实际值 + ngrok http 3000 + ``` + +成功运行结果如下图: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/4c5eeb0e8ae06c9df51c0849e8923b35_mwLSArWG5Z.png?height=882&lazyload=true&maxWidth=600&width=2490) + +4. 保存本地公网地址。 + +后续用于配置链接预览回调。 + +## 步骤四:配置链接预览 + +1. 登录[开发者后台](https://open.feishu.cn/app)。 +2. 进入应用详情页,并在左侧导航栏选择 **应用能力** > **添加应用能力**。 +3. 在 **按能力添加** 页签中,找到并添加 **链接预览**。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/a97a1176f3a8f9f262a0beec7039f9f3_YJvw4ATKE1.png?height=1276&lazyload=true&maxWidth=600&width=2516) +4. 进入 **链接预览** 功能页,在 **注册需要自定义预览的 URL 规则** 区域,点击 **添加 URL 规则**。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/c26d345adf52b23afabc003a978f085b_7sXniihMth.png?height=594&lazyload=true&maxWidth=600&width=1464) + +本示例中,添加一条 `example.com/*` 规则,后续在飞书客户端内发送的链接如果命中该规则,则会实现链接预览。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/a10283c8255420ae03f4afd7343ba2a2_DbVpWeb306.png?height=270&lazyload=true&maxWidth=600&width=1253) +5. 配置应用回调。 + +1. 在 **配置订阅链接预览回调** 区域,点击 **去配置**。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/d764e93e62b22d4fd286a88b7e644053_I4l8AOWYiL.png?height=294&lazyload=true&maxWidth=600&width=1726) + 2. 在 **事件与回调** 页面的 **回调配置** 页签中,点击 **订阅方式** 右侧的编辑按钮。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/ab66f2c2b3fa666721873ec655de9b26_T99HMMukKp.png?height=639&lazyload=true&maxWidth=600&width=1478) + 3. 将运行示例代码获取到的公网地址,配置在 **请求地址** 输入框,并点击 **保存**。 + +你需要填写本地获取到的真实地址。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/09f5d04ee7a6a2f12339f946395d499f_R5OWZH4bmb.png?height=996&lazyload=true&maxWidth=600&width=1744) + 4. 在页面底部的 **已订阅的回调** 区域右侧,点击 **添加回调**。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/efe2f1373dd4451829d07ecea755f4ae_zX5jWE9JOC.png?height=1142&lazyload=true&maxWidth=600&width=2244) + 5. 在对话框左侧导航栏点击 **链接预览**,选中 **拉取链接预览数据**,并点击 **确认添加**。 + +回调详情参考[拉取链接预览数据](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/development-link-preview/pull-link-preview-data-callback-structure)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/40f5c450d5642d2ee36197cf7104a683_1WoH6IjXkC.png?height=1192&lazyload=true&maxWidth=600&width=1666) + 6. 返回应用的 **链接预览** 功能页,查看 **配置订阅链接预览回调** 的状态为 **已配置**。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/dc6c824554bd63a7df8b6e86e5e59caa_YiGNLB1J0y.png?height=726&lazyload=true&maxWidth=600&width=1780) + +6. 发布应用,使以上配置生效。 + +1. 在 **版本管理与发布** 页面,点击 **创建版本**。 + 2. 在 **版本详情** 页面,根据页面提示依次配置版本号、能力、说明等信息,并在页面底部点击 **保存**。 + 3. 在弹窗内确认提交应用审核。 + +你需要等待企业管理员通过应用审核,然后应用会自动发布。 + +## 步骤五:体验效果 + +登录飞书客户端,分别在以下消息场景中体验链接预览效果。warning +**注意**:链接需要以 https/http 开头(即使用 HTTPS/HTTP 协议的链接),才可以成功实现预览效果。 + +场景 | 图示 +---|--- +单独发送 `https://example.com/path` | ![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/10a85b69dd41eea0e48766ab951801b4_xO9s5mVFGj.png?height=776&lazyload=true&width=958) +富文本消息包含 `https://example.com/path` | ![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/cfc41a0432fb907fc0661ed172cb9ea9_LwgJQnGUxz.png?height=782&lazyload=true&width=956) +群置顶消息 `https://example.com/path` | ![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/7b3c8d54aa57bc750c0dc20152141474_9xf0Y2vQ62.png?height=185&lazyload=true&width=1280) diff --git a/embedded-skills/lark-card-designer/docs/raw/development-link-preview__typical-case.md b/embedded-skills/lark-card-designer/docs/raw/development-link-preview__typical-case.md new file mode 100644 index 0000000..4f5c1d3 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/development-link-preview__typical-case.md @@ -0,0 +1,22 @@ +# 典型案例 + +本文提供部分卡片案例供你参考,你可以根据案例构建符合自己业务需求的卡片内容。 +构建所需的卡片内容,需要使用飞书卡片搭建工具。详情参考[飞书卡片搭建工具概述](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/feishu-cardkit-overview)。 + +## 通用案例 + +案例 | 描述 | 富文本效果图 | 单独链接效果图 +---|---|---|--- +长文类 | 当链接指向概述、方案、教程等文本内容较多的网页时,可以配置卡片展示网页的内容概要。 | ![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/7a62bfea3a7ae5cf54990f00de40ac1d_nfCJZawLDy.png?height=920&lazyload=true&width=1124) | ![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/90f573a62698a9f299a21cd4b5be3027_5INruRupmm.png?height=720&lazyload=true&width=1076) +文档类 | 如果链接是云文档,或者其他包含业务操作的文档,可以通过卡片展示网页的内容概要,并配置简单的交互逻辑,用于在卡片内完成业务操作。 | ![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/9926147a0925ed78eb6f12f1444dc3f3_RNC2F7BmlE.png?height=904&lazyload=true&width=1124) | ![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/aa88968623bb481dff7f381c50d1507e_qET8HM2tKV.png?height=804&lazyload=true&width=1076) +直播类 | 如果链接指向的是直播间,则可以通过卡片展示直播信息,并配置简单的交互逻辑,实现预约直播等操作。 | ![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/60edbbfc6ea1a8ab7357efb9621d7058_tn24aefXzp.png?height=982&lazyload=true&width=1124) | ![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/7ba56a161248faf608fb73bcf7588046_63P4daC8VP.png?height=882&lazyload=true&width=1076) +应用类 | 如果链接是飞书应用,或者企业内的其他应用,则可以通过卡片展示应用的图标、简介等信息。 | ![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/4e2b4ad50f935c25ac8d6a225c24b935_N34DmpOXXE.png?height=498&lazyload=true&width=1040) | ![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/c97bb8c5914148b458e9b4b6ec733b6f_QkW04Jl9m4.png?height=398&lazyload=true&width=1124) + +## 开放案例 + +案例 | 描述 | 富文本效果图 | 单独链接效果图 +---|---|---|--- +飞书招聘 | 如果需要通过消息推送飞书人事相关数据,则可以通过卡片构建人员信息概要。 | ![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/f15547fdb8b707942df032baa19eaf72_z48CDbpTW3.png?height=672&lazyload=true&width=1124) | ![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/afdf5b7273803111558e90df9467f006_U8AoLNBoy6.png?height=572&lazyload=true&width=1076) +飞书项目 | 支持为企业项目管理平台配置链接预览。例如,为飞书项目链接配置文本预览以及卡片,在卡片内展示当前项目的关键信息。 | ![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/1927b7f4affc21b77353d3882197739e_hfKduqes8o.png?height=940&lazyload=true&width=1124) | ![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/576e30dc4a4360ae9d639f0ceaf91a0e_s7mxFmKmX3.png?height=840&lazyload=true&width=1076) +飞书 OKR | 发送飞书 OKR 时,可以为链接配置卡片预览,在卡片内展示 OKR 的核心内容。 | ![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/1051bfb6649060fc02dc17608c52c374_v6z3UoriMt.png?height=876&lazyload=true&width=1124) | ![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/dce77c025564dbbdb658c62a330d7105_8C7mYKjRJ3.png?height=776&lazyload=true&width=1076) +飞书会议 | 企业内组织的会议,可以将会连接配置预览效果。例如,为飞书会议配置链接预览,在卡片内展示会议名称、人员、状态等信息,并通过配置交互逻辑,支持一键加入会议。 | ![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/cdaed2ead50cb50fa0bf55fb36d4465c_Qz6cZrCeBt.png?height=604&lazyload=true&width=1124) | ![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/2009081a8c52dd6207de1c0f09cf8aad_bz1H07KOgU.png?height=504&lazyload=true&width=1076) diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-callback-communication.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-callback-communication.md new file mode 100644 index 0000000..0314001 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-callback-communication.md @@ -0,0 +1,256 @@ +# 卡片回传交互回调 + +**卡片回传交互**作用于飞书卡片的 **请求回调** 交互组件。当终端用户点击飞书卡片上的回传交互组件后,你在开发者后台应用内注册的回调请求地址将会收到 **卡片回传交互** 回调。该回调包含了用户与卡片之间的交互信息。 + +你的业务服务器接收到回调请求后,需要在 3 秒内响应回调请求,声明通过弹出 Toast 提示、更新卡片、保持原内容不变等方式响应用户交互。了解详细的操作步骤,参考[处理卡片回调](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/handle-card-callbacks)。 + +卡片回调和服务端响应回调的结构体参考下文。 +**注意事项**:- 本文档提供新版本的卡片回调结构和响应示例。开放平台 SDK 已全量支持新版卡片回调。 +- 了解旧版回调的 SDK 调用,参考[消息卡片回传交互(旧)](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/configuring-card-callbacks/card-callback-structure)。 + +## 回调 + +基本信息 |   +---|--- +回调类型 | card.action.trigger +支持的应用类型 | Custom App、Store App +权限要求
**订阅该事件所需的权限,开启其中任意一项权限即可订阅**
开启任一权限即可 | 暂无 +字段权限要求 | **注意事项**:事件结构体中存在 `user_id` 敏感字段,仅当应用开启“获取用户 user ID”权限后才会返回。
获取用户 user ID(contact:user.employee_id:readonly) +推送方式 | [Webhook](https://open.feishu.cn/document/ukTMukTMukTM/uUTNz4SN1MjL1UzM) + +## 回调结构体 + +字段 | 数据类型 | 描述 +---|---|--- +schema | string | 回调的版本。固定取值为 `2.0`,为最新版本回调。了解旧版本回调,参考[消息卡片回传交互(旧)](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/configuring-card-callbacks/card-callback-structure)。 +header | object | 回调基本信息。 +event_id | string | 回调的唯一标识。 +token | string | 应用的 Verification Token。 +create_time | string | 回调发送的时间,接近回调发生的时间。微秒级时间戳。 +event_type | string | 回调类型。卡片交互场景中,固定为 `"card.action.trigger"`。 +tenant_key | string | 应用归属的 tenant key,即租户唯一标识。 +app_id | string | 应用的 App ID。 +event | object | 回调的详细信息。 +operator | object | 回调触发者信息。 +tenant_key | string | 回调触发者的 tenant key,即租户唯一标识。 +user_id | string | 回调触发者的 user_id。了解不同的用户 ID,参见[用户身份概述](https://open.feishu.cn/document/home/user-identity-introduction/introduction)。 +union_id | string | 回调触发者的 union_id。 +open_id | string | 回调触发者的 open_id。 +token | string | [更新卡片](https://open.feishu.cn/document/ukTMukTMukTM/uMDO1YjLzgTN24yM4UjN)用的凭证,有效期为 30 分钟,最多可更新 2 次。 +action | object | 交互信息。 +value | object/ string | 交互组件绑定的开发者自定义回传数据,对应组件中的 value 属性。类型为 string 或 object,可由开发者指定。 +tag | string | 交互组件的标签。 +timezone | string | 用户当前所在地区的时区。当用户操作日期选择器、时间选择器、或日期时间选择器时返回。 +name | string | 组件的自定义唯一标识,用于识别内嵌在表单容器中的某个组件。 +form_value | object | 表单容器内用户提交的数据。示例值:
```JSON
{
"field name 1": [ // 表单容器内某多选组件的 name 和 value
"selectDemo1",
"selectDemo2"
],
"field name 2": "value 2", // 表单容器内某交互组件的 name 和 value
"field name 3": "value 3", // 表单容器内某交互组件的 name 和 value
}
``` +input_value | string | 当输入框组件未内嵌在表单容器中时,用户在输入框中提交的数据。 +option | string | 当折叠按钮组、下拉选择-单选、人员选择-单选、日期选择器、时间选择器、日期时间选择器组件未内嵌在表单容器中时,用户选择该类组件某个选项时,组件返回的选项回调值。 +options | string[] | 当下拉选择-多选组件和人员选择-多选组件未内嵌在表单容器中时,用户选择该类组件某个选项时,组件返回的选项回调值。 +checked | bool | 当勾选器组件未内嵌在表单容器中时,勾选器组件的回调数据。 +host | string | 卡片展示场景。 +delivery_type | string | 卡片分发类型,固定取值为 `url_preview`,表示链接预览卡片。仅链接预览卡片有此字段。 +context | object | 展示场景上下文。 +url | string | 链接地址(适用于链接预览场景)。 +preview_token | string | 链接预览的 token(适用于链接预览场景)。 +open_message_id | string | 消息 ID。 +open_chat_id | string | 会话 ID。 + +## 回调结构体示例 + +```json +{ + "schema": "2.0", // 回调的版本 + "header": { // 回调基本信息 + "event_id": "f7984f25108f8137722bb63c*****", // 回调的唯一标识 + "token": "066zT6pS4QCbgj5Do145GfDbbag*****", // 应用的 Verification Token + "create_time": "1603977298000000", // 回调发送的时间,接近回调发生的时间。微秒级时间戳 + "event_type": "card.action.trigger", // 回调类型卡片交互场景中,固定为 "card.action.trigger" + "tenant_key": "2df73991750*****", // 应用归属的 tenant key,即租户唯一标识 + "app_id": "cli_a5fb0ae6a4******" // 应用的 App ID + }, + "event": { // 回调的详细信息 + "operator": { // 回调触发者信息 + "tenant_key": "2df73991750*****", // 回调触发者的 tenant key,即租户唯一标识 + "user_id": "867*****", // 回调触发者的 user ID。当应用开启“获取用户 user ID”权限后,该参数返回 + "open_id": "ou_3c14f3a59eaf2825dbe25359f15*****", // 回调触发者的 Open ID + "union_id": "on_cad4860e7af114fb4ff6c5d496d*****" // 回调触发者的 Union ID + }, + "token": "c-295ee57216a5dc9de90fefd0aadb4b1d7d******", // 更新卡片用的凭证,有效期为 30 分钟,最多可更新 2 次 + "action": { // 用户操作交互组件回传的数据 + "value": { // 交互组件绑定的开发者自定义回传数据,对应组件中的 value 属性。类型为 string 或 object,可由开发者指定。 + "key": "value" + }, + "tag": "button", // 交互组件的标签 + "timezone": "Asia/Shanghai", // 用户当前所在地区的时区。当用户操作日期选择器、时间选择器、或日期时间选择器时返回 + "form_value": { // 表单容器内用户提交的数据 + "field name1": [ // 表单容器内某多选组件的 name 和 value + "selectDemo1", + "selectDemo2" + ], + "field name2": "value2", // 表单容器内某交互组件的 name 和 value + "DatePicker_bpqdq5puvn4": "2024-04-01 +0800", // 表单容器内日期选择器组件的 name 和 value + "DateTimePicker_ihz2d7a74i": "2024-04-29 07:07 +0800", // 表单容器内日期时间选择器组件的 name 和 value + "Input_lf4fmxwfrd9": "1234", // 表单容器内输入框组件的 name 和 value + "PersonSelect_2ejys7ype7m": "ou_3c14f3a59eaf2825dbe25359f15*****", // 表单容器内人员选择-单选组件的 name 和 value + "Select_a2d5b7l3zd": "1", // 表单容器内下拉选择-单选组件的 name 和 value + "TimePicker_7ecsf6xkqsq": "00:00 +0800" // 表单容器内时间选择器组件的 name 和 value + }, + "name": "Button_lvkepfu3" // 用户操作交互组件的名称,由开发者自定义 + }, + "host": "im_message", // 卡片展示场景 + "delivery_type": "url_preview", // 卡片分发类型,固定取值为 url_preview,表示链接预览卡片仅链接预览卡片有此字段 + "context": { // 卡片展示场景相关信息 + "url": "xxx", // 链接地址(适用于链接预览场景) + "preview_token": "xxx", // 链接预览的 token(适用于链接预览场景) + "open_message_id": "om_574d639e4a44e4dd646eaf628e2*****", // 卡片所在的消息 ID + "open_chat_id": "oc_e4d2605ca917e695f54f11aaf56*****" // 卡片所在的会话 ID + } + } +} +``` + +## 响应回调的结构体 + +你的业务服务器接收到回调请求后,需要在 3 秒内响应回调请求,声明通过弹出 Toast 提示、更新卡片、保持原内容不变等方式响应用户交互。以下为使用卡片 JSON 代码和卡片模板响应的字段说明。要了解响应方式,参考[处理卡片回调](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/handle-card-callbacks)。warning +业务服务端不可使用重定向状态码(`HTTP 3xx`)来响应卡片的回调请求,否则用户端将会出现交互请求错误。 + +### 使用卡片 JSON 代码响应 + +字段 | 数据类型 | 是否必填 | 描述 +---|---|---|--- +toast | object | 否 | 客户端的 Toast 弹窗提示。 +type | string | 否 | 弹窗提示的类型。可选值有:info、success、error、和 warning。
不同的值的展示效果如下图所示:
![img_v3_02ao_9fdce3f7-5ba1-4f86-941f-2e5e7f6fd4eg.jpg](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/e62145dca9a372b1b51f0ea2e2629160_y1gPzFePcx.jpg?height=844&lazyload=true&width=1280) +content | string | 否 | 单语言提示文案。要配置多语言提示文案,请使用 `i18n` 字段。 +i18n | Map | 否 | 多语言提示文案。示例配置:
```json
{
"i18n": {
"zh_cn": "更新成功!",
"en_us": "Successful update"
}
}
``` +key | string | 否 | 语言。可选值:
- `zh_cn`: 简体中文
- `en_us`: 英文
- `zh_hk`: 繁体中文(香港)
- `zh_tw`: 繁体中文(台湾)
- `ja_jp`: 日语
- `id_id`: 印尼语
- `vi_vn`: 越南语
- `th_th`: 泰语
- `pt_br`: 葡萄牙语
- `es_es`: 西班牙语
- `ko_kr`: 韩语
- `de_de`: 德语
- `fr_fr`: 法语
- `it_it`: 意大利语
- `ru_ru`: 俄语
- `ms_my`: 马来语 +value | string | 否 | 语言对应的文案。 +card | object | 否 | 卡片数据。 +type | string | 是 | 卡片类型。可选值:
- `template`:搭建工具构建的卡片,可视为一个卡片模板
- `raw`:由 JSON 构建的卡片
要使用卡片 JSON 代码响应,请选择 `raw`。 +data | object | 是 | 卡片的 JSON 数据。
- 若发送卡片时,卡片 JSON 结构为 1.0 版本,那么你需传入卡片 JSON 1.0 数据。详情参考[卡片 JSON 1.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-structure)
- 若发送卡片时,卡片 JSON 结构为 2.0 版本,那么你需传入卡片 JSON 2.0 数据。详情参考[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure) + +响应回调的结构体示例(以 JSON 2.0 结构为例) + +```json +{ + "toast": { + "type": "info", + "content": "卡片交互成功", + "i18n": { + "zh_cn": "卡片交互成功", + "en_us": "card action success" + } + }, + "card": { + "type": "raw", + "data": { + "schema": "2.0", + "config": { + "update_multi": true, + "style": { + "text_size": { + "normal_v2": { + "default": "normal", + "pc": "normal", + "mobile": "heading" + } + } + } + }, + "body": { + "direction": "vertical", + "padding": "12px 12px 12px 12px", + "elements": [ + { + "tag": "div", + "text": { + "tag": "plain_text", + "content": "示例文本", + "text_size": "normal_v2", + "text_align": "left", + "text_color": "default" + }, + "margin": "0px 0px 0px 0px" + } + ] + }, + "header": { + "title": { + "tag": "plain_text", + "content": "示例标题" + }, + "subtitle": { + "tag": "plain_text", + "content": "示例文本" + }, + "template": "blue", + "padding": "12px 12px 12px 12px" + } + } + } +} +``` + +### 使用卡片模板响应 + +字段 | 数据类型 | 是否必填 | 描述 +---|---|---|--- +toast | object | 否 | 客户端的 Toast 弹窗提示。 +type | string | 否 | 弹窗提示的类型。可选值有:info、success、error、和 warning。
不同的值的展示效果如下图所示:
![img_v3_02ao_9fdce3f7-5ba1-4f86-941f-2e5e7f6fd4eg.jpg](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/e62145dca9a372b1b51f0ea2e2629160_y1gPzFePcx.jpg?height=844&lazyload=true&width=1280) +content | string | 否 | 单语言提示文案。要配置多语言提示文案,请使用 `i18n` 字段。 +i18n | Map | 否 | 多语言提示文案。示例配置:
```json
{
"i18n": {
"zh_cn": "更新成功!",
"en_us": "Successful update"
}
}
``` +key | string | 否 | 语言。可选值:
- `zh_cn`: 简体中文
- `en_us`: 英文
- `zh_hk`: 繁体中文(香港)
- `zh_tw`: 繁体中文(台湾)
- `ja_jp`: 日语
- `id_id`: 印尼语
- `vi_vn`: 越南语
- `th_th`: 泰语
- `pt_br`: 葡萄牙语
- `es_es`: 西班牙语
- `ko_kr`: 韩语
- `de_de`: 德语
- `fr_fr`: 法语
- `it_it`: 意大利语
- `ru_ru`: 俄语
- `ms_my`: 马来语 +value | string | 否 | 语言对应的文案。 +card | object | 否 | 卡片数据。 +type | string | 是 | 卡片类型。可选值:
- `template`:搭建工具构建的卡片,可视为一个卡片模板
- `raw`:由 JSON 构建的卡片
要使用卡片模板响应,请选择 `template`。 +data | object | 是 | 卡片模板的数据。 +template_id | string | 是 | 搭建工具中创建的卡片(也称卡片模板)的 ID,如 AAqigYkzabcef。可在搭建工具中通过复制卡片模板 ID 获取。
![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/8bf97ff2bceed633b28f5ce2d2ec0270_zPTWqjljT8.png?height=329&lazyload=true&maxWidth=500&width=1574) +template_variable | object | 否 | 若卡片绑定了变量,你需在该字段中传入实际变量数据的值。示例:如果变量名称在搭建工具中被定义为 open_id,则此处需要对 open_id 变量传入值。以“ou_d506829e8b6a17607e56bcd6b1aabcef”为示例:
```json
{
"open_id": "ou_d506829e8b6a17607e56bcd6b1aabcef"
}
``` +template_version_name | string | 否 | 搭建工具中创建的卡片的版本号,如 1.0.0。卡片发布后,将生成版本号。可在搭建工具 **版本管理** 处获取。
![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/b3e96c8ca7c5c029bdbce6c0ca1ba413_aoV0ao7VUo.png?height=384&lazyload=true&maxWidth=500&width=1459) + +响应回调的结构体示例 + +```json +{ + "toast": { + "type": "info", + "content": "卡片交互成功", + "i18n": { + "zh_cn": "卡片交互成功", + "en_us": "card action success" + } + }, + "card": { + "type": "template", + "data": { + "template_id": "AAqi6xJ8rabcd", + "template_version_name": "1.0.0", + "template_variable": { + "open_id": "ou_d506829e8b6a17607e56bcd6b1aabcef" + } + } + } +} +``` +## 错误码 + +在飞书客户端进行卡片交互时,若交互出错,将返回如下图对应的错误码。错误码说明及解决方案如下表所示。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/29558d328f22a099dc8ce5c66bf4e5ba_DD7lIR8Lxk.png?height=64&lazyload=true&width=285) +错误码仅支持飞书客户端 7.28 及以上版本。若未返回错误码,请升级飞书客户端后重试。 + +错误码 | 描述 | 解决方案 +---|---|--- +200340 | 应用未配置飞书卡片回调地址或配置的请求地址无效。
若应用已配置,请确保你已创建并发布了最新的应用版本使修改生效。 | 1. 前往[开发者后台](https://open.feishu.cn/app),点击目标应用,选择 **开发配置** > **事件与回调**。
2. 在 **事件与回调** 页面 **回调配置** 页签下,填写正确有效的请求地址并保存。
3. 在 **已订阅的回调** 项中,确保已添加卡片回传交互回调。
**提示**:你也可以选择使用长连接接收回调。了解更多,参考[配置回调订阅方式](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/event-subscription-guide/callback-subscription/configure-callback-request-address)。 +200341 | 所请求的卡片回调服务未在规定时间内响应飞书卡片服务端。 | 请确保配置的回调地址能够在 3 秒内响应卡片回调请求。 +200342 | 飞书卡片服务端无法与该卡片回调地址建立 TCP 连接。 | 请检查并确保配置的回调地址可以正常访问。 +200343 | 飞书卡片服务端解析该卡片回调地址的 DNS 失败。 | 请检查并确保配置的回调地址的域名正确。 +200345 | 错误原因同错误码 200340。 | 参考错误码 200340 的解决方案。 +200346 | 错误原因同错误码 200340。 | 参考错误码 200340 的解决方案。 +200347 | 错误原因同错误码 200340。 | 参考错误码 200340 的解决方案。 +200530 | 在表单容器中的交互组件的 name (表单项标识)属性为空。 | `name` 是表单容器内组件的唯一标识,用于识别用户提交的数据属于哪个组件,在单张卡片内不可为空、不可重复。
- 如果你使用卡片 JSON 搭建卡片,请确保所有的 name 属性的值不为空。`name` 数据类型为字符串。
- 如果你使用卡片搭建工具搭建卡片:
1. 在卡片编辑页面,选中表单内的交互组件,在右侧属性页签下,确保 **表单项标识** 已填写。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/93894aaf05f60f3576e64cb5a0f22569_62E0goGKeA.png?height=482&lazyload=true&width=1547)
2. 点击右上角的 **保存**,然后点击 **发布**,确保修改生效。
![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/b704b7552c24d7956b402092c7c38775_c3K900pZqf.png?height=557&lazyload=true&width=1557) +200080 | 飞书卡片服务端请求该卡片回调地址时发生错误。 | 请联系[技术支持](https://applink.feishu.cn/TLJpeNdW)进行处理。 +200671 | 请求的卡片回调服务返回了非 `HTTP 200` 的状态码,导致无法进行正常的卡片交互。 | 请检查并确保接口代码逻辑正常,确保不会返回异常状态码。 +200672 | 请求的卡片回调服务返回了错误的响应体格式。 | - 如果你添加的是新版卡片回传交互(`card.action.trigger`)回调,请参考[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication#65787609)检查响应回调的结构体的格式是否有误。
- 如果你添加的是旧版卡片回传交互(`card.action.trigger_v1`)回调,请参考[消息卡片回传交互(旧)](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/configuring-card-callbacks/card-callback-structure)检查响应回调的结构体的格式是否有误。
- 如果你同时添加了新版和旧版卡片回传交互回调,响应其中任一回调即为成功响应。建议你删除多余的请求方式。 +200673 | 请求的卡片回调服务返回了错误的卡片。 | - 如果你添加的是新版卡片回传交互(`card.action.trigger`)回调,请参考[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication#65787609)检查响应回调的结构体中 `card` 部分是否有误。
- 如果你添加的是旧版卡片回传交互(`card.action.trigger_v1`)回调,请参考[消息卡片回传交互(旧)](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/configuring-card-callbacks/card-callback-structure)检查响应回调的结构体中除 `toast` 外的其它部分是否有误。 +200830 | JSON 2.0 结构的卡片无法更新为 JSON 1.0 结构卡片。 | 如果交互前卡片的结构为[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure),交互后的卡片结构仍必须为 2.0 结构。 +300000 | 服务内部错误。 | 请联系[技术支持](https://applink.feishu.cn/TLJpeNdW)。 diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__component-overview.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__component-overview.md new file mode 100644 index 0000000..a64776a --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__component-overview.md @@ -0,0 +1,57 @@ +# 卡片 JSON 1.0 版本组件概述 + +飞书卡片中的组件可分为容器类、展示类和交互类组件。除循环容器外,所有组件均支持通过卡片 JSON 代码构建。除折叠面板、多图选择和勾选器外,所有组件均支持通过卡片搭建工具搭建使用。在 JSON 结构中,组件通过定义 `tag` 字段声明: + +```json +{ + "tag": "" // 在此声明组件的标签。不同的组件标签不同。 +} +``` +本文档汇总并介绍基于[卡片 JSON 1.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-structure)构建的组件。要查看基于[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)构建的组件,参考[卡片 JSON 2.0 版本组件概述](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/component-json-v2-overview)。 +## 容器类组件 + +容器类组件可用于布局内容或配置交互逻辑。在容器组件中支持添加展示类组件和交互类组件。 + +组件 | 是否支持在搭建工具中使用 | 客户端版本要求 | 描述 +---|---|---|--- +[分栏(column_set)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/column-set) | ✓ | / | 分栏支持横向排布多列,在列内自由组合图文内容,搭建出如数据表、商品或文章列表、差旅信息等图文并茂、交互友好的卡片。 +[循环容器](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/recycling-container) | ✓ | / | 循环容器支持内嵌所有展示、交互类组件和分栏组件。通过使用循环容器,你可以高效地组织一系列排版类似、数据不同的内容。 +[表单容器(form)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/form-container) | ✓ | 飞书 V6.6 及以上 | 表单容器支持用户在前端本地录入一批表单项后,通过点击一次 提交 按钮,将这一批本地缓存的表单内容一次回调至开发者的服务端,实现异步提交多个表单项数据的效果。 +[交互容器(interactive_container)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/interactive-container) | ✓ | 飞书 V7.4 及以上 | 交互容器允许你基于业务需求在交互容器中内嵌组件,并灵活组合多个交互容器,并统一定义多个交互容器的样式、交互能力等,实现多种组合效果和丰富的卡片交互。 +[折叠面板(collapsible_panel)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/collapsible-panel) | × | 飞书 V7.9 及以上 | 折叠面板允许你在卡片中折叠次要信息,如备注、较长文本等,以突出主要信息。 + +## 展示类组件 + +展示类组件用于构成卡片的主要内容,不具备交互能力。 + +组件 | 是否支持在搭建工具中使用 | 客户端版本要求 | 描述 +---|---|---|--- +[标题(header)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/title) | ✓ | / | 标题组件用于构建飞书卡片的标题样式与内容,支持添加卡片主标题、副标题、后缀标签和标题图标。 +[普通文本(div)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/plain-text) | ✓ | / | 普通文本组件支持添加普通文本和前缀图标,并设置文本大小、颜色、对齐方式等展示样式。 +[富文本(markdown)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/rich-text) | ✓ | / | 富文本(Markdown)组件支持渲染文本、图片、分割线等元素。 +[图片(img)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/image) | ✓ | / | 图片组件支持通过调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口或在新版飞书卡片搭建工具中上传图片,在卡片内添加图片。 +[多图混排(img_combination)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/multi-image-laylout) | ✓ | / | 多图混排组件支持通过调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口或在新版飞书卡片搭建工具中上传图片,在卡片内添加多张图片。 +[人员(person)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/user-profile) | ✓ | / | 人员组件支持展示人员的用户名和头像。你可通过传入人员的 open_id、user_id 或 union_id 使用该组件。 +[人员列表(person_list)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/user-list) | ✓ | / | 人员列表组件支持展示多个人员的用户名和头像。你可通过传入人员的 open_id、user_id 或 union_id 使用该组件。 +[图表(chart)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/chart) | ✓ | 飞书 V7.1 及以上 | 图表组件基于 [VChart](https://www.visactor.io/) 的图表定义,支持折线图、面积图、柱状图、饼图、词云等多种数据呈现方式,帮助你可视化各类信息,提高信息沟通效率。 +[表格(table)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/table) | ✓ | 飞书 V7.4 及以上 | 表格组件支持在表格中添加普通文本、选项标签、人员列表以及数字格式的内容。 +[分割线(hr)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/divider) | ✓ | / | 分割线组件是一条长横线,用于分割卡片的内容,使呈现内容更清晰。 + +## 交互类组件 + +交互类组件为卡片提供了交互能力。用户在接收到包含交互组件的卡片时,可直接在卡片内访问链接或处理业务。 + +组件 | 是否支持在搭建工具中使用 | 客户端版本要求 | 描述 +---|---|---|--- +[输入框(input)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/input) | ✓ | 飞书 V6.8 及以上 | 输入框组件支持收集不固定的文本内容,如原因、评价、备注等。 +[按钮(button)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/button) | ✓ | / | 按钮组件提供配置按钮的回传交互能力或者链接跳转能力,并支持多种样式和尺寸。 +[折叠按钮组(overflow)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/overflow) | ✓ | / | 折叠按钮组组件支持将多个按钮添加在折叠按钮组中,默认情况下按钮组为折叠状态,点击按钮组将会展示组内所有按钮。 +[下拉选择-单选(select_static)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/single-select-dropdown-menu) | ✓ | / | 下拉选择-单选组件支持自定义单选菜单的选项文本、图标和回传参数。 +[下拉选择-多选(multi_select_static)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/multi-select-dropdown-menu) | ✓ | 飞书 V7.4 及以上 | 下拉选择-多选组件支持自定义多选菜单的选项文本、图标和回传参数。 +[人员选择-单选(select_person)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/single-select-user-picker) | ✓ | / | 人员选择-多选组件支持添加指定人员作为单选选项。 +[人员选择-多选(multi_select_person)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/multi-select-user-picker) | ✓ | 飞书 V7.4 及以上 | 人员选择-多选组件支持添加指定人员作为多选选项。 +[日期选择器(date_picker)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/date-picker) | ✓ | / | 日期选择器组件支持提供日期选项。 +[时间选择器(picker_time)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/time-selector) | ✓ | / | 时间选择器组件支持提供时间选项。 +[日期时间选择器(picker_datetime)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/date-time-picker) | ✓ | / | 日期时间选择器组件支持提供时间和日期选项。 +[多图选择(select_img)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/image-picker) | × | 飞书 V7.6 及以上 | 多图选择组件支持提供图片选项,支持单选、多选图片。 +[勾选器(checker)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/checker) | × | 飞书 V7.9 及以上 | 勾选器支持配置回调响应,主要用于任务勾选的场景。 diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__containers__collapsible-panel.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__containers__collapsible-panel.md new file mode 100644 index 0000000..69b45db --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__containers__collapsible-panel.md @@ -0,0 +1,219 @@ +# 折叠面板 + +折叠面板允许在卡片中折叠次要信息,如备注、较长文本等,以突出主要信息。 + +本文档介绍折叠面板的 JSON 1.0 结构,要查看新版 JSON 2.0 结构,参考[折叠面板](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/containers/collapsible-panel)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/a8b2044ee3ff261280c034b32b7e9848_kZfxdl7XMn.png?height=1118&lazyload=true&maxWidth=300&width=921) + +## 注意事项 + +- 折叠面板仅支持通过撰写卡片 JSON 代码的方式使用,暂不支持在卡片搭建工具上构建使用。 +- 折叠面板支持飞书 V7.9 及以上版本的客户端。在低于该版本的飞书客户端上,折叠面板的内容将展示为“请升级至最新版本客户端,以查看内容”的占位图。 +- 容器类组件最多支持嵌套五层组件。建议你避免在折叠面板中嵌套多层组件。多层嵌套会压缩内容的展示空间,影响卡片的展示效果。 + +## 嵌套规则 + +折叠面板不支持内嵌表单容器(form)组件。 + +## 组件属性 + +本小节介绍折叠面板的属性。 + +### JSON 结构 + +以下为一个折叠面板的卡片 JSON 数据: +```json +{ + "tag": "collapsible_panel", // 折叠面板的标签。 + "expanded": true, // 面板是否展开。默认值 false。 + "background_color": "grey", // 折叠面板的背景色,默认为透明 + "header": { + // 折叠面板的标题设置。 + "title": { + // 标题文本设置。支持 plain_text 和 markdown。 + "tag": "markdown", + "content": "**面板标题文本**" + }, + "vertical_align": "center", // 标题区的垂直居中方式。 + "padding": "4px 0px 4px 8px", // 标题区的内边距。 + "icon": { + // 标题前缀图标 + "tag": "standard_icon", // 图标类型. + "token": "chat-forbidden_outlined", // 图标库中图标的 token。当 tag 为 standard_icon 时生效。 + "color": "orange", // 图标的颜色。当 tag 为 standard_icon 时生效。 + "img_key": "img_v2_38811724", // 自定义前缀图标的图片 key。当 tag 为 custom_icon 时生效。 + "size": "16px 16px" // 图标的尺寸。默认值为 10px 10px。 + }, + "icon_position": "follow_text", // 图标的位置。默认值为 right。 + "icon_expanded_angle": -180 // 折叠面板展开时图标旋转的角度,正值为顺时针,负值为逆时针。默认值为 180。 + }, + "border": { + // 边框设置。默认不显示边框。 + "color": "grey", // 边框的颜色。 + "corner_radius": "5px" // 圆角设置。 + }, + "vertical_spacing": "8px", // 面板内元素垂直边距设置。默认值为 8px。 + "padding": "8px 8px 8px 8px", // 内容区的内边距。 + "elements": [ + // 此处可添加各个组件的 JSON 结构。暂不支持表单(form)组件。 + { + "tag": "markdown", + "content": "很长的文本" + } + ] +} +``` + +### 字段说明 + +折叠面板各字段说明如下表所示: + +字段名称 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 否 | string | / | 组件的标签。折叠面板取固定值为 collapsible_panel。 +expanded | 否 | Boolean | false | 面板是否展开。可选值:
- true:面板为展开状态
- false:面板为折叠状态。默认为折叠状态 +background_color | 否 | String | 空 | 折叠面板的背景色,默认为透明。枚举值参见[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。 +header | 是 | Object | - | 折叠面板的标题设置。 +└ title | 否 | Object | - | 标题文本设置。 +└└ tag | 是 | String | 空 | 文本类型的标签。可取值:
- plain_text:普通文本内容
- markdown:富文本内容。了解支持的 Markdown 语法,参考[富文本组件](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/rich-text)。 +└└ content | 否 | String | 空 | 折叠面板标题的内容。 +└ background_color | 否 | String | 空 | 折叠面板标题区域的背景颜色设置,默认为透明色。枚举值参见[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。
**注意**:如果你未设置此字段,则折叠面板的标题区域的背景色由 background_color 字段决定。 +└ vertical_align | 否 | String | center | 标题区域的垂直居中方式。可取值:
- top:标题区域垂直居中于面板区域的顶部
- center:标题区域垂直居中于面板区域的中间
- bottom:标题区域垂直居中于面板区域的底部 +└ padding | 否 | String | 0px 0px 0px 0px | 标题区域的内边距。值的取值范围为 [0,28]px。支持填写单值或多值:
- 单值:如 "4px",表示组件内四个内边距都为 4px
- 多值:如 "4px 12px 4px 12px",表示容器内上、右、下、左的内边距分别为 4px,12px,4px,12px。四个值必填,使用空格间隔 +└ icon | 否 | Object | / | 添加图标作为标题前缀或后缀图标。支持自定义或使用图标库中的图标。示例代码如下:
```json
"icon": {
"tag": "standard_icon",
"token": "down-small-ccm_outlined",
"color": "",
"size": "16px 16px"
}
``` +└└ tag | 否 | String | / | 图标类型的标签。可取值:
- standard_icon:使用图标库中的图标
- custom_icon:使用用自定义图片作为图标 +└ └ token | 否 | String | / | 图标库中图标的 token。当 tagstandard_icon 时生效。枚举值参见[图标库](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-icons)。 +└└ color | 否 | String | / | 图标的颜色。支持设置线性和面性图标(即 token 末尾为 outlinedfilled 的图标)的颜色。当 tagstandard_icon 时生效。枚举值参见[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。 +└└ img_key | 否 | String | / | 自定义前缀图标的图片 key。当 tagcustom_icon 时生效。图标 key 的获取方式:调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口,上传用于发送消息的图片,并在返回值中获取图片的 image_key。 +└ └ size | 否 | String | 10px 10px | 图标的尺寸。支持 "[1,999] [1,999]px"。 +└ icon_position | 否 | String | right | 图标的位置。可选值:
- left:图标在标题区域最左侧
- right:图标在标题区域最右侧
- follow_text:图标在文本右侧 +└ icon_expanded_angle | 否 | Number | 180 | 折叠面板展开时图标旋转的角度,正值为顺时针,负值为逆时针。可选值:
- -180:逆时针旋转 180 度
- -90:逆时针旋转 90 度
- 90:顺时针旋转 90 度
- 180:顺时针旋转 180 度 +border | 否 | Object | 空 | 边框设置。默认不显示边框。 +└ color | 否 | String | grey | 边框颜色设置。枚举值参见[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。 +└ corner_radius | 否 | String | 5px | 圆角设置。 +vertical_spacing | 否 | String | 8px | 面板内元素垂直边距设置。 +padding | 否 | String | 8px | 内容区的内边距。值的取值范围为 [0,28]px。支持填写单值或多值:
- 单值:如 "4px",表示组件内四个内边距都为 4px
- 多值:如 "4px 12px 4px 12px",表示容器内上、右、下、左的内边距分别为 4px,12px,4px,12px。四个值必填,使用空格间隔 +elements | 否 | Array | 空 | 各个组件的 JSON 结构。暂不支持表单(form)组件。 + +## 示例代码 + +以下的 JSON 示例代码可实现如下图所示的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/a8b2044ee3ff261280c034b32b7e9848_PfWtBx6CZX.png?height=1118&lazyload=true&maxWidth=300&width=921) +```json +{ + "header": { + "template": "yellow", + "title": { + "tag": "plain_text", + "content": "折叠面板展示" + } + }, + "elements": [ + { + "tag": "markdown", + "content": "下面是一个 默认折叠 的折叠面板组件" + }, + { + "tag": "collapsible_panel", + "expanded": false, + "header": { + "title": { + "tag": "plain_text", + "content": "面板标题文本" + }, + "vertical_align": "center", + "icon": { + "tag": "standard_icon", + "token": "down-small-ccm_outlined", + "color": "", + "size": "16px 16px" + }, + "icon_position": "right", + "icon_expanded_angle": -180 + }, + "border": { + "color": "grey", + "corner_radius": "5px" + }, + "vertical_spacing": "8px", + "padding": "8px 8px 8px 8px", + "elements": [ + { + "tag": "markdown", + "content": "很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本" + } + ] + }, + { + "tag": "markdown", + "content": "下面是一个 标题带背景色 且 默认展开 的折叠面板组件" + }, + { + "tag": "collapsible_panel", + "expanded": true, + "header": { + "title": { + "tag": "markdown", + "content": "**面板标题文本**" + }, + "background_color": "yellow", + "vertical_align": "center", + "icon": { + "tag": "standard_icon", + "token": "down-small-ccm_outlined", + "color": "white", + "size": "16px 16px" + }, + "icon_position": "right", + "icon_expanded_angle": -180 + }, + "border": { + "color": "grey", + "corner_radius": "5px" + }, + "vertical_spacing": "8px", + "padding": "8px 8px 8px 8px", + "elements": [ + { + "tag": "markdown", + "content": "很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本" + } + ] + }, + { + "tag": "markdown", + "content": "下面是一个无边框折叠面板组件" + }, + { + "tag": "collapsible_panel", + "expanded": true, + "header": { + "title": { + "tag": "markdown", + "content": "**面板标题文本**" + }, + "vertical_align": "center", + "padding": "4px 0px 4px 8px", + "icon": { + "tag": "standard_icon", + "token": "down-small-ccm_outlined", + "color": "", + "size": "16px 16px" + }, + "icon_position": "follow_text", + "icon_expanded_angle": -180 + }, + "vertical_spacing": "8px", + "padding": "8px 8px 8px 8px", + "elements": [ + { + "tag": "markdown", + "content": "很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本" + } + ] + } + ] +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__containers__column-set.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__containers__column-set.md new file mode 100644 index 0000000..4caec4c --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__containers__column-set.md @@ -0,0 +1,402 @@ +# 分栏组件 +分栏组件提供卡片内布局的能力,并提供对齐方式、容器宽度、交互方式等属性。你可以使用分栏组件横向排布多个列容器,在列容器内自由组合图文内容,搭建出如数据表、商品或文章列表、差旅信息等图文并茂、交互友好的卡片。 + +本文档介绍分栏组件的 JSON 1.0 结构,要查看新版 JSON 2.0 结构,参考[分栏](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/containers/column-set)。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/1af893c0c67b3a0fe89736d649304d48_gT8TUBv9IR.png?height=351&lazyload=true&maxWidth=500&width=822) +## 注意事项 + +分栏组件最多支持嵌套五层组件。建议你避免在分栏中嵌套多层组件。多层嵌套会压缩内容的展示空间,影响卡片的展示效果。 + +## 应用场景 + +- **数据报表推送场景**:使用分栏可以快速构建整齐、自适应屏幕的多列数据表,解决了传统报表构建时繁琐的排版过程,以及无法自适应各类屏幕的样式问题。 +- **图文混排场景**:分栏灵活的横纵列排版能力,使你可以快速构建理想的图文卡片。有效降低手动调整图文排版的耗时。 + +## 嵌套规则 + +分栏组件由分栏本身的属性(column_set)和列容器(column)组成。一个分栏组件中内可以添加多个列容器,每个列容器中可内嵌多个组件。 + +[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)支持内嵌除表单容器(form)和表格组件(table)外的其它所有组件。 + +[卡片 JSON 1.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-structure)支持内嵌的组件有: +- 容器类:分栏和循环容器组件 +- 展示类:除标题组件、表格组件以外的所有展示组件 +- 交互类:除折叠按钮组以外的所有交互类组件 + +整体的嵌套关系如下图所示。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/9b253ea6e463d2841c8295b26873c3f7_8BnIr3afv7.png?height=722&lazyload=true&maxWidth=600&width=1942) + +列容器中再嵌套分栏的层级关系如下图所示。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/e2b6909f3881bc78965466cc736d5ec6_FKkeg0UCcT.png?height=584&lazyload=true&maxWidth=600&width=2034) + +## 组件属性 + +### JSON 结构 + +以下为一个分栏组件的卡片 JSON 数据: + +```JSON +{ + "tag": "column_set", // 分栏的标签。 + "horizontal_spacing": "large", // 分栏中列容器之间的间距。默认值 default(为 8px)。 + "horizontal_align": "left", // 列容器水平对齐的方式。默认值 left。 + "margin": "0px", // 列容器的外边距。 + "flex_mode": "none", // 移动端和 PC 端的窄屏幕下,各列的自适应方式。默认值 none。 + "background_style": "default", // 分栏的背景色样式。默认值 default。 + "action": { // 在此处设置点击分栏时的交互配置。 + "multi_url": { + "url": "https://open.feishu.cn", + "pc_url": "https://open.feishu.com", + "ios_url": "https://developer.apple.com/", + "android_url": "https://developer.android.com/" + } + }, + "columns": [ + // 列配置 + { + "tag": "column", + "background_style": "default", // 列的背景色样式。默认值 default。 + "width": "auto", // 列容器的宽度。默认值 auto。 + "weight": 1, // 当 width 取值 weighted 时生效,表示当前列的宽度占比。 + "vertical_align": "center", // 列垂直居中的方式。 + "vertical_spacing": "4px", // 列内子组件纵向间距。默认值 default(8px)。 + "padding": "8px", // 列容器的内边距。默认值 0px。 + "action": { + // 在此处设置点击列时的交互配置。 + "multi_url": { + "url": "https://www.baidu.com", + "pc_url": "https://www.baidu.com", + "ios_url": "https://www.google.com", + "android_url": "https://www.apple.com.cn" + } + }, + "elements": [] // 列容器内嵌的组件,不支持内嵌表格组件、多图混排组件和表单容器。 + } + ] +} +``` + +### 分栏字段说明 + +分栏(column_set)各属性字段说明如下表所示。 + +字段名称 | 是否必填 | 类型 | 默认值 | 客户端版本要求 | 说明 +---|---|---|---|---|--- +tag | 是 | String | / | 无 | 组件的标签。分栏组件的固定值为 column_set。 +horizontal_spacing | 否 | String | default | 无 | 各列之间的水平分栏间距。取值:
- default:默认间距,8px
- small:窄间距,4px
- large:大间距,12px
- [0,28px]:自定义间距 +horizontal_align | 否 | String | left | V7.4 及以上版本 | 列容器水平对齐的方式。可取值:
- left:左对齐
- center:居中对齐
- right:右对齐 +margin | 否 | String | 0px | V7.4 及以上版本 | 列的外边距。值的取值范围为 [0,28]px。可选值:
- 单值,如 "10px",表示列的四个外边距都为 10 px。
- 多值,如 "4px 12px 4px 12px",表示列的上、右、下、左的外边距分别为 4px,12px,4px,12px。四个值必填,使用空格间隔。
**注意**:首行列的上外边距强制为 0,末行列的下外边距强制为 0。 +flex_mode | 否 | String | none | 无 | 移动端和 PC 端的窄屏幕下,各列的自适应方式。取值:
- none:不做布局上的自适应,在窄屏幕下按比例压缩列宽度
- stretch:列布局变为行布局,且每列(行)宽度强制拉伸为 100%,所有列自适应为上下堆叠排布
- flow:列流式排布(自动换行),当一行展示不下一列时,自动换至下一行展示
- bisect:两列等分布局
- trisect:三列等分布局 +background_style | 否 | String | default | 无 | 分栏的背景色样式。可取值:
- default:默认的白底样式,客户端深色主题下为黑底样式
- 卡片支持的颜色枚举值和 RGBA 语法自定义颜色。参考[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。
**注意**:当存在分栏的嵌套时,上层分栏的颜色覆盖下层分栏的颜色。 +columns | 是 | column[] | 空 | 无 | 分栏中列的配置。 +action | 否 | Action | / | 无 | 设置点击分栏时的交互配置。当前仅支持跳转交互。如果布局容器内有交互组件,则优先响应交互组件定义的交互。 +└ multi_url | 否 | Struct | 空 | 无 | 配置各个端的链接地址。 +└└ url | 否 | String | 空 | 无 | 兜底的跳转链接。 +└└ android_url | 否 | String | 空 | 无 | Android 端的跳转链接。可配置为 `lark://msgcard/unsupported_action` 声明当前端不允许跳转。 +└└ ios_url | 否 | String | 空 | 无 | iOS 端的跳转链接。可配置为 `lark://msgcard/unsupported_action` 声明当前端不允许跳转。 +└└ pc_url | 否 | String | 空 | 无 | PC 端的跳转链接。可配置为 `lark://msgcard/unsupported_action` 声明当前端不允许跳转。 + +### 列字段说明 + +分栏中列(column)的各属性字段说明如下表所示。 + +字段名称 | 是否必填 | 类型 | 默认值 | 客户端版本要求 | 说明 +---|---|---|---|---|--- +tag | 是 | String | / | 无 | 列的标签,固定取值为 `column`。 +background_style | 否 | String | default | V7.4 及以上版本 | 列的背景色样式。可取值:
- **default**:默认的白底样式,客户端深色主题下为黑底样式
- 卡片支持的颜色枚举值和 RGBA 语法自定义颜色。参考[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color) +width | 否 | String | auto | 无 | 列宽度。仅 `flex_mode` 为 `none` 时,生效此属性。取值:
- **auto**:列宽度与列内元素宽度一致
- **weighted**:列宽度按 `weight` 参数定义的权重分布
- 具体数值,如 100px。取值范围为 [16,600]px。V7.4 及以上版本支持该枚举 +weight | 否 | Number | 1 | 无 | 当 `width` 字段取值为 `weighted` 时生效,表示当前列的宽度占比。取值范围为 1 ~ 5 之间的整数。 +vertical_align | 否 | String | top | 无 | 列垂直居中的方式。可取值:
- **top**:上对齐
- **center**:居中对齐
- **bottom**:下对齐 +vertical_spacing | 否 | String |   | V7.4 及以上版本 | 列内组件的纵向间距。取值:
- **default**:默认间距,8px
- **medium**:中等间距
- **large**:大间距
- 具体数值,如 8px。取值范围为 [0,28]px +padding | 否 | String | 0px | V7.4 及以上版本 | 列的内边距。值的取值范围为 [0,28]px。可选值:
- 单值,如 "10px",表示列的四个外边距都为 10 px。
- 多值,如 "4px 12px 4px 12px",表示列的上、右、下、左的外边距分别为 4px,12px,4px,12px。四个值必填,使用空格间隔。 +elements | 否 | Element 或 ColumnSet[] | 空 | 空 | 列容器中内嵌的组件。可内嵌组件参考上文嵌套关系。 +action | 否 | Action | / | V7.4 及以上版本 | 设置点击列时的交互配置。当前仅支持跳转交互。如果布局容器内有交互组件,则优先响应交互组件定义的交互。 +└ multi_url | 否 | Struct | 空 | V7.4 及以上版本 | 配置各个端的链接地址。 +└└ url | 否 | String | 空 | V7.4 及以上版本 | 兜底的链接地址。 +└└ android_url | 否 | String | 空 | V7.4 及以上版本 | Android 端的链接地址。可配置为 `lark://msgcard/unsupported_action` 声明当前端不允许跳转。 +└└ ios_url | 否 | String | 空 | V7.4 及以上版本 | iOS 端的链接地址。可配置为 `lark://msgcard/unsupported_action` 声明当前端不允许跳转。 +└└ pc_url | 否 | String | 空 | V7.4 及以上版本 | PC 端的链接地址。可配置为 `lark://msgcard/unsupported_action` 声明当前端不允许跳转。 + +## 示例代码 + +### 示例一:数据报表 + +以下的 JSON 示例代码可实现如下图所示的卡片效果: + +| 桌面端效果 | 窄屏及移动端自适应效果 | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/f529248b7a996a5ce4b1d85e8fc8fecd_jC7m13DTzU.png?height=702&lazyload=true&maxWidth=400&width=1220) | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/5873cce25e30e42b1a375d342275e655_2WLvg3dEpD.png?height=884&lazyload=true&maxWidth=200&width=636) | +```json +{ + "elements": [ + { + "tag": "markdown", + "content": "**个人审批效率总览**\n" + }, + { + "tag": "column_set", + "flex_mode": "bisect", + "background_style": "grey", + "horizontal_spacing": "default", + "columns": [ + { + "tag": "column", + "width": "weighted", + "weight": 1, + "elements": [ + { + "tag": "markdown", + "text_align": "center", + "content": "已审批单量\n**${total_count}单**\n${total_percent}" + } + ] + }, + { + "tag": "column", + "width": "weighted", + "weight": 1, + "elements": [ + { + "tag": "markdown", + "text_align": "center", + "content": "平均审批耗时\n**${hours}小时**\n${hours_percent}" + } + ] + }, + { + "tag": "column", + "width": "weighted", + "weight": 1, + "elements": [ + { + "tag": "markdown", + "text_align": "center", + "content": "待批率\n**${pending}**\n${pending_rate}" + } + ] + } + ] + }, + { + "tag": "markdown", + "content": "**团队审批效率参考:**" + }, + { + "tag": "column_set", + "flex_mode": "none", + "background_style": "grey", + "columns": [ + { + "tag": "column", + "width": "weighted", + "weight": 1, + "vertical_align": "top", + "elements": [ + { + "tag": "markdown", + "content": "**审批人**", + "text_align": "center" + } + ] + }, + { + "tag": "column", + "width": "weighted", + "weight": 1, + "vertical_align": "top", + "elements": [ + { + "tag": "markdown", + "content": "**审批时长**", + "text_align": "center" + } + ] + }, + { + "tag": "column", + "width": "weighted", + "weight": 1, + "vertical_align": "top", + "elements": [ + { + "tag": "markdown", + "content": "**对比上周变化**", + "text_align": "center" + } + ] + } + ] + }, + { + "tag": "column_set", + "flex_mode": "none", + "background_style": "default", + "columns": [ + { + "tag": "column", + "width": "weighted", + "weight": 1, + "vertical_align": "top", + "elements": [ + { + "tag": "markdown", + "content": "${person}", + "text_align": "center" + } + ] + }, + { + "tag": "column", + "width": "weighted", + "weight": 1, + "vertical_align": "top", + "elements": [ + { + "tag": "markdown", + "content": "${time}", + "text_align": "center" + } + ] + }, + { + "tag": "column", + "width": "weighted", + "weight": 1, + "vertical_align": "top", + "elements": [ + { + "tag": "markdown", + "content": "${week_rate}", + "text_align": "center" + } + ] + } + ], + "_varloop": "${group_table}" + } + ] +} +``` + +### 示例二:差旅卡片 + +以下的 JSON 示例代码可实现如下图所示的卡片效果: +| 桌面端效果 | 窄屏及移动端自适应效果 | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/1c03620fb66177d4c1b864ddd9f2f8bd_vmjpIsseTa.png?height=802&lazyload=true&maxWidth=400&width=1218) | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/8c4e0e5674ecfce437e260e1a8a9c377_0lIVHPWXq3.png?height=566&lazyload=true&maxWidth=300&width=580) | +```json +{ + "header": { + "title": { + "tag": "plain_text", + "content": "🏨 酒店申请已通过,请选择房型" + }, + "template": "green" + }, + "elements": [ + { + "tag": "markdown", + "content": "入住酒店:杭州xxxx酒店\n📍 浙江省杭州市西湖区" + }, + { + "tag": "hr" + }, + { + "tag": "column_set", + "flex_mode": "none", + "background_style": "default", + "horizontal_spacing": "default", + "action": { + "multi_url": { + "url": "https://open.feishu.cn", + "android_url": "https://developer.android.com/", + "ios_url": "https://developer.apple.com/", + "pc_url": "https://www.windows.com" + } + }, + "columns": [ + { + "tag": "column", + "width": "weighted", + "weight": 1, + "vertical_align": "center", + "elements": [ + { + "tag": "img", + "img_key": "img_v2_120b03c8-27e3-456f-89c0-90ede1aa59ag", + "mode": "fit_horizontal", + "alt": { + "tag": "plain_text", + "content": "" + } + } + ] + }, + { + "tag": "column", + "width": "weighted", + "weight": 3, + "elements": [ + { + "tag": "markdown", + "text_align": "left", + "content": "**高级双床房**\n双早|40-47㎡|有窗户|双床\n¥699 起" + } + ] + } + ] + }, + { + "tag": "hr" + }, + { + "tag": "column_set", + "flex_mode": "none", + "background_style": "default", + "horizontal_spacing": "default", + "action": { + "multi_url": { + "url": "https://open.feishu.cn", + "android_url": "https://developer.android.com/", + "ios_url": "https://developer.apple.com/", + "pc_url": "https://www.windows.com" + } + }, + "columns": [ + { + "tag": "column", + "width": "weighted", + "weight": 1, + "vertical_align": "center", + "elements": [ + { + "tag": "img", + "img_key": "img_v2_120b03c8-27e3-456f-89c0-90ede1aa59ag", + "mode": "fit_horizontal", + "alt": { + "tag": "plain_text", + "content": "" + } + } + ] + }, + { + "tag": "column", + "width": "weighted", + "weight": 3, + "elements": [ + { + "tag": "markdown", + "text_align": "left", + "content": "**精品大床房**\n双早|40-47㎡|有窗户|大床\n¥666 起" + } + ] + } + ] + } + ] +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__containers__form-container.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__containers__form-container.md new file mode 100644 index 0000000..5b5d551 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__containers__form-container.md @@ -0,0 +1,260 @@ +# 表单容器 + +在使用卡片收集内容时,可能存在需要用户提交多个表单项的场景。表单容器允许用户在前端本地录入一批表单项后,通过点击一次 **提交** 按钮,将这一批本地缓存的表单内容一次回调至开发者的服务端,实现异步提交多个表单项数据的效果。 + +本文档介绍表单容器的 JSON 1.0 结构,要查看新版 JSON 2.0 结构,参考[表单容器](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/containers/form-container)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/a92dff5b6c098720a8909024c74078c1_VBz8XGXNPo.png?height=361&lazyload=true&maxWidth=500&width=947) + +## 注意事项 + +- 表单容器支持飞书 V6.6 及以上版本的客户端。在低于该版本的飞书客户端上,表单容器的内容将展示为“请升级至最新版本客户端,以查看内容”的占位图。 +- 容器类组件最多支持嵌套五层组件。建议你避免在表单容器中嵌套多层组件。多层嵌套会压缩内容的展示空间,影响卡片的展示效果。如你希望卡片承接更复杂的表单内容,建议通过卡片链接跳转至 H5 或小程序实现表单能力。 + +## 嵌套规则 + +在[卡片 JSON 1.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-structure)中: + - 表单容器不支持内嵌表格(table)、图表(chart)、和表单容器组件。 + - 表单容器中不可直接内嵌[标签为 div 的组件](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/component-list/common-components-and-elements#6bdb3f37)。你可先内嵌分栏组件,再在分栏组件中内嵌标签为 `div` 类型的组件。 +- 表单容器组件不可被内嵌在其它组件内,只可放在卡片根节点下。 + +在[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)中: +- 表单容器不支持内嵌表格(table)和表单容器组件。 +- 表单容器组件不可被内嵌在其它组件内,只可放在卡片根节点下。 + +## 组件属性 + +本小节介绍表单容器的属性。 + +### JSON 结构 + +以下为一个表单容器的卡片 JSON 结构示例,该容器内嵌了一个输入框组件和一个绑定了提交事件的提交按钮: + +```json +{ + "tag": "form", // 表单容器的标签。 + "name": "form_1", // 该表单容器的唯一标识。用于识别用户在交互后,提交的是哪个表单容器的数据。 + "elements": [ + { + "tag": "input", // 为表单容器内添加一个输入框组件。 + "name": "reason", // 输入框组件的唯一标识。用于识别用户在交互后,提交的是哪个表单项的数据。在表单容器中所有的交互组件中,该字段必填,否则数据会发送失败。 + "required": true // 是否必填。为 true 时点击按钮后会做必填校验。 + }, + { + "tag": "button", // 表单容器内的按钮组件。 + "action_type": "form_submit", // 将当前按钮与提交事件绑定。用户点击后,将触发表单容器的提交事件,异步提交所有已填写的表单项内容 + "name": "submit", // 按钮组件的唯一标识,用于识别用户在交互后,点击的是哪个按钮。在表单容器中所有的交互组件中,该字段必填,否则数据会发送失败。 + "text": { // 按钮上的文本。 + "content": "提交", + "tag": "lark_md" + }, + "type": "primary", // 按钮的样式类型。 + "confirm":{} // 配置二次确认弹窗。在表单容器中,仅在用户点击包含提交属性的按钮时才会触发二次确认弹窗。 + } + ] +} +``` + +### 字段说明 + +表单容器各字段说明如下表所示: + +字段名称 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | String | / | 表单容器的标签。固定值为 `form`。 +name | 是 | String | 无 | 表单容器的唯一标识。用于识别用户提交的数据属于哪个表单容器。在同一张卡片内,该字段的值全局唯一。 +elements | 是 | Array<element> | [] | 表单容器的子节点。可内嵌其它容器类组件和展示、交互组件,不支持内嵌表格、图表、和表单容器组件。 +└ tag | 是 | String | 无 | 表单容器内必须包含的、用于提交表单的按钮组件。固定取值 `button`。 +└ action_type | 是 | String | 无 | 用于提交表单的按钮组件的交互类型。固定取值 `form_submit`,表示提交表单。 +└ name | 是 | String | 无 | 用于提交表单的按钮组件的唯一标识,用于识别用户在交互后,点击的是哪个按钮。在表单容器中所有的交互组件中,该字段必填,否则数据会发送失败。 +└ text | 否 | Struct | 空 | 用于提交表单的按钮上的文本。 +└ └ tag | 否 | String | 无 | 文本的标签。固定值为 `lark_md`。 +└ └ content | 是 | String | 请输入 | 文本的内容,最多支持 100 个字符。 +└ type | 否 | String | default | 按钮的类型。可选值:
- **default**:黑色字体按钮,有边框
- **primary**:蓝色字体按钮,有边框
- **danger**:红色字体按钮,有边框
- **text**:黑色字体按钮,无边框
- **primary_text**:蓝色字体按钮,无边框
- **danger_text**:红色字体按钮,无边框
- **primary_filled**:蓝底白字按钮
- **danger_filled**:红底白字按钮
- **laser**:镭射按钮 +confirm | 否 | Struct | 空 | 二次确认弹窗配置。指在用户提交时弹出二次确认弹窗提示;只有用户点击确认后,才提交输入的内容。该字段默认提供了确认和取消按钮,你只需要配置弹窗的标题与内容即可。
**注意**:`confirm` 字段仅在用户点击包含提交属性的按钮时才会触发二次确认弹窗。 +confirm.title | 是 | Struct | / | 二次确认弹窗标题。 +confirm.title.tag | 是 | String | plain_text | 二次确认弹窗标题文本的标签。固定取值为 `plain_text`。 +confirm.title.content | 是 | String | / | 二次确认弹窗标题的内容。 +confirm.text | 是 | Struct | / | 二次确认弹窗的文本内容。 +confirm.text.tag | 是 | String | plain_text | 二次确认弹窗文本的标签。固定取值为 `plain_text`。 +confirm.text.content | 是 | String | / | 二次确认弹窗文本的具体内容。 + +### 扩展字段说明 + +内嵌在表单容器中的交互组件,新增 `name`、`required`、和 `action_type` 属性。详细说明如下表所示。 + +属性名称 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +name | 是 | String | 空 | 表单容器内组件的唯一标识。用于识别用户提交的数据属于哪个组件。
**注意**:该字段必填且需在卡片全局内唯一。 +required | 否 | Boolean | false | 组件的内容是否必填。当组件内嵌在表单容器中时,该属性生效。可取值:
- **true**:必填。当用户点击表单容器的“提交”时,未填写该组件,则前端提示“有必填项未填写”,不会向开发者的服务端发起回传请求。
- **false**:选填。当用户点击表单容器的“提交”时,未填写该组件,仍提交表单容器中的数据。 +action_type | 是 | String | 空 | 内嵌在表单容器中的按钮的交互类型。枚举值包括:
- link:当前按钮仅支持链接跳转
  • request:当前按钮仅支持回传交互

  • multi:当前按钮同时支持链接跳转和回传交互

  • form_submit:将当前按钮与提交事件绑定。用户点击后,将触发表单容器的提交事件,异步提交所有已填写的表单项内容

  • form_reset:将当前按钮与取消提交事件绑定。用户点击后,将触发表单容器的取消提交事件,重置所有表单组件的输入值为初始值
  • + +## 回调结构 + +当用户点击表单容器的提交按钮时,你在开发者后台配置的请求地址将会收到如下所示的回调数据。如果你添加的是新版卡片回传交互回调(`card.action.trigger`),回调数据的结构如下所示。更多参数说明可参考[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)。 + ```json + { + "schema": "2.0", // 回调的版本 + "header": { // 回调基本信息 + "event_id": "f7984f25108f8137722bb63c*****", // 回调的唯一标识 + "token": "066zT6pS4QCbgj5Do145GfDbbag*****", // 应用的 Verification Token + "create_time": "1603977298000000", // 回调发送的时间,接近回调发生的时间 + "event_type": "card.action.trigger", // 回调类型卡片交互场景中,固定为 "card.action.trigger" + "tenant_key": "2df73991750*****", // 应用归属的 tenant key,即租户唯一标识 + "app_id": "cli_a5fb0ae6a4******" // 应用的 App ID + }, + "event": { // 回调的详细信息 + "operator": { // 回调触发者信息 + "tenant_key": "2df73991750*****", // 回调触发者的 tenant key,即租户唯一标识 + "user_id": "867*****", // 回调触发者的 user ID当应用开启“获取用户 user ID”权限后,该参数返回 + "open_id": "ou_3c14f3a59eaf2825dbe25359f15*****" // 回调触发者的 Open ID + }, + "token": "c-295ee57216a5dc9de90fefd0aadb4b1d7d******", // 更新卡片用的凭证,有效期为 30 分钟,最多可更新 2 次 + "action": { // 用户操作交互组件回传的数据 + "value": { // 表单组件中按钮组件绑定的开发者自定义回传数据 + "key": "value" + }, + "tag": "button", // 表单组件中按钮组件的标签 + "timezone": "Asia/Shanghai", // 用户当前所在地区的时区。当用户操作日期选择器、时间选择器、或日期时间选择器时返回 + "form_value": { // 表单容器内用户提交的数据。以下为示例数据: + "DatePicker_bpqdq5puvn4": "2024-04-01 +0800", // 表单容器内日期选择器组件的 name 和 value。name 即搭建工具中的组件 ID,可自定义 + "DateTimePicker_ihz2d7a74i": "2024-04-29 07:07 +0800", // 表单容器内日期时间选择器组件的自定义 name 和 value + "Input_lf4fmxwfrd9": "1234", // 表单容器内输入框组件的 name 和 value + "PersonSelect_2ejys7ype7m": "ou_3c14f3a59eaf2825dbe25359f1595b00", // 表单容器内人员选择-单选组件的 name 和 value + "Select_a2d5b7l3zd": "1", // 表单容器内下拉选择-单选组件的 name 和 value + "TimePicker_7ecsf6xkqsq": "00:00 +0800" // 表单容器内时间选择器组件的 name 和 value + }, + "name": "Button_lvkepfu3" // 表单组件中按钮组件的 name + }, + "host": "im_message", // 卡片展示场景 + "context": { // 卡片展示场景相关信息 + "open_message_id": "om_574d639e4a44e4dd646eaf628e2*****", // 卡片所在的消息 ID + "open_chat_id": "oc_e4d2605ca917e695f54f11aaf56*****" // 卡片所在的会话 ID + } + } + } + ``` + +## 示例代码 + +以下的 JSON 示例代码可实现如下图所示的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/a92dff5b6c098720a8909024c74078c1_h4YqlevxIp.png?height=361&lazyload=true&maxWidth=500&width=947) + +```json +{ + "elements": [ + { + "tag": "form", + "name": "Form_lvxmxsxf", + "elements": [ + { + "tag": "column_set", + "flex_mode": "stretch", + "background_style": "default", + "columns": [ + { + "tag": "column", + "width": "weighted", + "weight": 1, + "vertical_align": "top", + "elements": [ + { + "tag": "markdown", + "content": "请选择:" + } + ] + }, + { + "tag": "column", + "width": "weighted", + "weight": 1, + "vertical_align": "top", + "elements": [ + { + "tag": "select_static", + "name": "Select_pj6kw7cxyl", + "placeholder": { + "tag": "plain_text", + "content": "这是一个选择菜单" + }, + "value": { + "key": "value" + }, + "options": [ + { + "text": { + "tag": "plain_text", + "content": "选项1" + }, + "value": "1" + }, + { + "text": { + "tag": "plain_text", + "content": "选项2" + }, + "value": "2" + }, + { + "text": { + "tag": "plain_text", + "content": "选项3" + }, + "value": "3" + }, + { + "text": { + "tag": "plain_text", + "content": "选项4" + }, + "value": "4" + } + ] + } + ] + } + ] + }, + { + "tag": "input", + "name": "Input_fhaty9jktke", + "placeholder": { + "tag": "plain_text", + "content": "请输入" + }, + "max_length": 5, + "label": { + "tag": "plain_text", + "content": "请输入文本:" + }, + "label_position": "left", + "value": { + "k": "v" + } + }, + { + "action_type": "form_submit", + "name": "Button_e4d9u982x5k", + "tag": "button", + "text": { + "content": "提交", + "tag": "lark_md" + }, + "type": "primary", + "confirm": { + "title": { + "tag": "plain_text", + "content": "title" + }, + "text": { + "tag": "plain_text", + "content": "确认提交吗" + } + } + } + ] + } + ] +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__containers__interactive-container.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__containers__interactive-container.md new file mode 100644 index 0000000..d848de5 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__containers__interactive-container.md @@ -0,0 +1,477 @@ +# 交互容器 + +你可基于业务需求在交互容器中内嵌组件,并灵活组合多个交互容器,并统一定义多个交互容器的样式、交互能力等,实现多种组合效果和丰富的卡片交互。 + +本文档介绍交互容器的 JSON 1.0 结构,要查看新版 JSON 2.0 结构,参考[交互容器](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/containers/interactive-container)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/0a42ddffcccd079b59087ccb8b86383f_18jEWFf4ZB.png?height=989&lazyload=true&maxWidth=300&width=829) + +## 注意事项 + +- 交互容器支持飞书 V7.4 及以上版本的客户端。在低于该版本的飞书客户端上,交互容器的内容将展示为“请升级至最新版本客户端,以查看内容”的占位图。 +- 容器类组件最多支持嵌套五层组件。建议你避免在交互容器中嵌套多层组件。多层嵌套会压缩内容的展示空间,影响卡片的展示效果。 + +## 嵌套规则 +在[卡片 JSON 1.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-structure)中: +- 交互容器仅支持内嵌普通文本、富文本、图片、备注、分栏、勾选器、交互容器组件。 +- 交互容器支持内嵌在卡片根节点、循环容器、分栏、表单容器、交互容器组件中。 + +在[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)中,交互容器可内嵌除表单容器(form)和表格组件(table)外的其它所有组件。 +## 组件属性 + +### JSON 结构 + +以下为一个交互容器的卡片 JSON 数据: +```json +{ + "tag": "interactive_container", // 交互容器的标签。 + "width": "fill", // 交互容器的宽度。默认值 fill。 + "height": "auto", // 交互容器的高度。默认值 auto。 + "background_style": "default", // 背景色。默认值 default(无背景色)。 + "has_border": false, // 是否展示边框,粗细固定为 1px。默认值 false。 + "border_color": "grey", // 交互容器的边框颜色,仅 has_border 为 true 时生效。 + "corner_radius": "40px", // 交互容器的圆角半径。可选。 + "padding": "10px 20px 10px 20px", // 交互容器的内边距。默认值 "4px 12px 4px 12px"。 + "behaviors": [ + { + "type": "open_url", // 声明交互类型是打开链接的跳转交互。 + "default_url": "https://www.baidu.com", // 兜底跳转地址。 + "android_url": "https://developer.android.com/", // 安卓端跳转地址。 + "ios_url": "lark://msgcard/unsupported_action", // iOS 端跳转地址。 + "pc_url": "https://www.windows.com" // 桌面端跳转地址。 + }, + { + "type": "callback", // 声明交互类型是回传数据到服务端的回传交互。 + "value": { + // 回传交互数据 + "key": "value" + } + } + ], + "disabled": false, + "disabled_tips": { "tag": "plain_text", "content": "demo" }, + "confirm": {}, + "hover_tips": { + "tag": "plain_text", + "content": "demo" + }, + "elements": [] // 容器子组件,仅支持内嵌普通文本、富文本、图片、备注、分栏、勾选器、交互容器组件。 +} +``` + +### 字段说明 + +交互容器各字段说明如下表所示。 + +字段名称 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | String | / | 交互容器的标签。固定值为 interactive_container。 +width | 否 | String | fill | 交互容器的宽度。可取值:
    - **fill**:卡片最大支持宽度
  • **auto**:自适应宽度

  • **[16,999]px**:自定义宽度,如 "20px"。最小宽度为 16px
  • +height | 否 | String | auto | 交互容器的高度。可取值:
    - **auto**:自适应高度
  • **[10,999]px**:自定义高度,如 "20px"

  • +background_style | 否 | String | default | 交互容器的背景色样式。可取值:
    - **default**:默认的白底样式,客户端深色主题下为黑底
  • **laser**:镭射渐变彩色样式

  • 卡片支持的颜色枚举值和 RGBA 语法自定义颜色。参考[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)

  • +has_border | 否 | Boolean | false | 是否展示边框,粗细固定为 1px。 +border_color | 否 | String | grey | 边框的颜色,仅 has_border 为 true 时,此字段生效。枚举值为卡片支持的颜色枚举值和 RGBA 语法自定义颜色,参考[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。 +corner_radius | 否 | String | 0px | 交互容器的圆角半径,单位是像素(px)或百分比(%)。取值遵循以下格式:
    - **[0,∞]px**,如 "10px"
  • **[0,100]%**,如 "30%"

  • +padding | 否 | String | 4px 12px 4px 12px | 交互容器的内边距。值的取值范围为 [0,28]px。支持填写单值或多值:
    - 单值:如 "10px",表示容器内四个内边距都为 10px
  • 多值:如 "4px 12px 4px 12px",表示容器内上、右、下、左的内边距分别为 4px,12px,4px,12px。四个值必填,使用空格间隔

  • +behaviors | 是 | [] | / | 设置点击交互容器时的交互配置。如果交互容器内有交互组件,则优先响应交互组件定义的交互。交互组件支持 callback 和 open_url 交互。详情参考[配置卡片交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/configuring-card-interactions)。 +hover_tips | 否 | Object | 空 | 用户在 PC 端将光标悬浮在交互容器上方时的文案提醒。默认为空。 +└ tag | 是 | String | plain_text | 文本的标签。固定取值为 plain_text。 +└ content | 是 | String | 空 | 文本的内容。 +disabled | 否 | Boolean | false | 是否禁用交互容器。可选值:
    - true:禁用整个容器
  • false:容器组件保持可用状态

  • +disabled_tips | 否 | Object | 空 | 禁用交互容器后,用户触发交互时的弹窗文案提醒。默认为空,即不弹窗。 +└ tag | 是 | String | plain_text | 弹窗标题文本的标签。固定取值为 plain_text。 +└ content | 是 | String | 空 | 弹窗标题的内容。 +confirm | 否 | Struct | 默认不生效此属性。 | 二次确认弹窗配置。指在用户提交时弹出二次确认弹窗提示;只有用户点击确认后,才提交输入的内容。该字段默认提供了确认和取消按钮,你只需要配置弹窗的标题与内容即可。
    **注意**:confirm 字段仅在用户点击包含提交属性的按钮时才会触发二次确认弹窗。 +confirm.title | 是 | Struct | / | 二次确认弹窗标题。 +confirm.title.tag | 是 | String | plain_text | 二次确认弹窗标题文本的标签。固定取值为 `plain_text`。 +confirm.title.content | 是 | String | / | 二次确认弹窗标题的内容。 +confirm.text | 是 | Struct | / | 二次确认弹窗的文本内容。 +confirm.text.tag | 是 | String | plain_text | 二次确认弹窗文本的标签。固定取值为 `plain_text`。 +confirm.text.content | 是 | String | / | 二次确认弹窗文本的具体内容。 +elements | 是 | Array<element> | [] | 交互容器内嵌的组件。仅支持内嵌普通文本、富文本、图片、备注、分栏、勾选器、交互容器组件。 + +## 回调结构 + +为组件成功配置交互后,用户基于组件进行交互时,你在开发者后台配置的请求地址将会收到回调数据。 +- 如果你添加的是新版卡片回传交互回调(`card.action.trigger`),可参考[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)了解回调结构。 +- 如果你添加的是旧版卡片回传交互回调(`card.action.trigger_v1`),可参考[消息卡片回传交互(旧)](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/configuring-card-callbacks/card-callback-structure)了解回调结构。 +- +## 示例代码 + +以下的 JSON 示例代码可实现如下图所示的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/0a42ddffcccd079b59087ccb8b86383f_Z569UhCFiC.png?height=989&lazyload=true&maxWidth=300&width=829) +```json +{ + "config": { + "compact_width": true + }, + "header": { + "title": { + "content": "交互容器示例(依赖端版本 7.4+)", + "tag": "plain_text" + }, + "ud_icon": { + "style": { + "color": "blue" + }, + "token": "chat-history_outlined" + } + }, + "elements": [ + { + "tag": "markdown", + "content": "在「内容创作」话题下,我可以帮助你进行产品方案、营销文案、工作报告等内容的创作。" + }, + { + "tag": "column_set", + "flex_mode": "none", + "background_style": "default", + "columns": [ + { + "tag": "column", + "width": "weighted", + "weight": 1, + "vertical_spacing": "8px", + "elements": [ + { + "tag": "markdown", + "content": "你可以对我说:", + "text_size": "notation" + }, + { + "tag": "interactive_container", + "width": "fill", + "height": "auto", + "background_style": "default", + "has_border": true, + "border_color": "grey", + "corner_radius": "8px", + "padding": "4px 12px 4px 12px", + "behaviors": [ + { + "type": "callback", + "value": { + "key": "value" + } + } + ], + "elements": [ + { + "tag": "markdown", + "content": "帮我生成一篇产品方案的框架", + "icon": { + "tag": "standard_icon", + "token": "frame-selection_outlined", + "color": "orange" + } + } + ] + }, + { + "tag": "interactive_container", + "width": "fill", + "height": "auto", + "background_style": "default", + "has_border": true, + "border_color": "grey", + "corner_radius": "8px", + "padding": "4px 12px 4px 12px", + "behaviors": [ + { + "type": "callback", + "value": { + "key": "value" + } + } + ], + "disabled": false, + "elements": [ + { + "tag": "markdown", + "content": "帮我生成一篇产品文案", + "icon": { + "tag": "standard_icon", + "token": "file-link-docx_outlined", + "color": "orange" + } + } + ] + }, + { + "tag": "interactive_container", + "width": "fill", + "height": "auto", + "background_style": "default", + "has_border": true, + "border_color": "grey", + "corner_radius": "8px", + "padding": "4px 12px 4px 12px", + "behaviors": [ + { + "type": "callback", + "value": { + "key": "value" + } + } + ], + "disabled": false, + "elements": [ + { + "tag": "markdown", + "content": "帮我写一篇周报", + "icon": { + "tag": "standard_icon", + "token": "pa-calibration-report_outlined", + "color": "orange" + } + } + ] + } + ] + } + ] + }, + { + "tag": "column_set", + "flex_mode": "none", + "background_style": "default", + "columns": [ + { + "tag": "column", + "width": "weighted", + "weight": 1, + "vertical_spacing": "8px", + "elements": [ + { + "tag": "markdown", + "content": "或者继续之前的话题", + "text_size": "notation" + }, + { + "tag": "interactive_container", + "width": "fill", + "height": "auto", + "background_style": "default", + "has_border": true, + "border_color": "grey", + "corner_radius": "8px", + "padding": "4px 12px 4px 12px", + "behaviors": [ + { + "type": "callback", + "value": { + "key": "value" + } + } + ], + "disabled": false, + "elements": [ + { + "tag": "column_set", + "flex_mode": "none", + "background_style": "default", + "columns": [ + { + "tag": "column", + "width": "weighted", + "weight": 1, + "elements": [ + { + "tag": "markdown", + "content": "内容创作:创作暑假营销活动文案", + "icon": { + "tag": "standard_icon", + "token": "chat-history_outlined" + } + } + ] + }, + { + "tag": "column", + "width": "auto", + "weight": 1, + "elements": [ + { + "tag": "markdown", + "content": "昨天", + "text_size": "notation" + } + ] + } + ] + } + ] + }, + { + "tag": "interactive_container", + "width": "fill", + "height": "auto", + "background_style": "default", + "has_border": true, + "border_color": "grey", + "corner_radius": "8px", + "padding": "4px 12px 4px 12px", + "behaviors": [ + { + "type": "callback", + "value": { + "key": "value" + } + } + ], + "disabled": false, + "elements": [ + { + "tag": "column_set", + "flex_mode": "none", + "background_style": "default", + "columns": [ + { + "tag": "column", + "width": "weighted", + "weight": 1, + "elements": [ + { + "tag": "markdown", + "content": "内容创作:生成了季度工作报告", + "icon": { + "tag": "standard_icon", + "token": "chat-history_outlined" + } + } + ] + }, + { + "tag": "column", + "width": "auto", + "weight": 1, + "elements": [ + { + "tag": "markdown", + "content": "上周", + "text_size": "notation" + } + ] + } + ] + } + ] + }, + { + "tag": "interactive_container", + "width": "fill", + "height": "auto", + "background_style": "default", + "has_border": true, + "border_color": "grey", + "corner_radius": "8px", + "padding": "4px 12px 4px 12px", + "behaviors": [ + { + "type": "callback", + "value": { + "key": "value" + } + } + ], + "disabled": false, + "elements": [ + { + "tag": "markdown", + "content": "更多历史话题", + "icon": { + "tag": "standard_icon", + "token": "chat-history_outlined" + } + } + ] + } + ] + } + ] + }, + { + "tag": "column_set", + "flex_mode": "none", + "background_style": "default", + "columns": [ + { + "tag": "column", + "width": "weighted", + "weight": 1, + "vertical_spacing": "8px", + "elements": [ + { + "tag": "note", + "elements": [ + { + "tag": "plain_text", + "content": "本话题中已选择以下插件" + } + ] + }, + { + "tag": "interactive_container", + "width": "auto", + "height": "auto", + "background_style": "grey", + "has_border": false, + "border_color": "grey", + "corner_radius": "40px", + "padding": "2px 8px 2px 4px", + "behaviors": [ + { + "type": "callback", + "value": { + "key": "value" + } + } + ], + "disabled": false, + "elements": [ + { + "tag": "column_set", + "flex_mode": "none", + "background_style": "default", + "horizontal_spacing": "4px", + "columns": [ + { + "tag": "column", + "width": "auto", + "weight": 1, + "vertical_spacing": "8px", + "elements": [ + { + "tag": "img", + "img_key": "img_v2_58e37110-6878-44ee-bce4-7a571c1bb70g", + "transparent": true, + "scale_type": "crop_center", + "size": "18px 18px", + "preview": false + } + ] + }, + { + "tag": "column", + "width": "weighted", + "weight": 1, + "vertical_spacing": "8px", + "elements": [ + { + "tag": "markdown", + "content": "妙记插件" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__containers__recycling-container.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__containers__recycling-container.md new file mode 100644 index 0000000..a61b5eb --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__containers__recycling-container.md @@ -0,0 +1,210 @@ +# 循环容器 + +循环容器是一个抽象的空容器,可内嵌所有展示、交互类组件和分栏组件。通过使用循环容器,你可以高效地组织一系列排版类似、数据不同的内容,适用于列表消息推送场景,如下图卡片中的内容列表。你还可以通过设置循环容器绑定的对象数组长度,控制列表内容内的条数。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/9ff17730c5e001c2ad60f1e9007ff910_LPFMz3qLV0.png?height=788&lazyload=true&maxWidth=600&width=1901) + +## 使用限制 + +- 循环容器仅支持在卡片搭建工具上使用,不支持通过卡片 JSON 代码构建。 +- 循环容器暂不支持设置容器内组件的间距。 + +## 参考案例 + +卡片搭建工具案例库中提供了循环容器的示例,你可直接前往卡片搭建工具试一试: + +- [循环容器案例](https://open.feishu.cn/cardkit?catalogId=10015&templateId=AAqIDyz6qpMTB) +- [表单容器内嵌循环容器案例](https://open.feishu.cn/cardkit?catalogId=10015&templateId=AAqBZKqVZHLLe) + +## 嵌套关系 + +循环容器支持内嵌所有展示、交互类组件和分栏组件。 + +## 操作步骤 + +1. 登录 [飞书卡片搭建工具](https://open.feishu.cn/cardkit?from=recycling_container)。 +1. 在指定的飞书卡片内,添加一个 **循环容器** 组件。 + +添加后系统会默认创建并绑定一个 **对象数组** 变量,你可在编辑页右侧点击该变量编辑变量名称和描述。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/135692c9970eaa17a9b4a92468392064_bCdjHE2ooT.gif?height=1012&lazyload=true&maxWidth=500&width=2050) + +1. 根据实际需求,添加任意组件至循环容器中。以下示例添加 **文本+图片** 复合组件至循环容器中。warning + 循环容器是一个抽象的空容器,你必须要在其中添加组件才可展示效果。 + ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/2be07984961859fa39dc348d0ff73f7c_ygfnBn6FAK.gif?height=1012&lazyload=true&maxWidth=500&width=2050) + +1. 确定样式后,在循环容器绑定的对象数组变量内,添加文本变量和图片变量,用于后续[富文本](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/components/markdown)组件和[图片](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/components/image)组件绑定子变量。不同组件支持的变量类型不同,详情参考[配置卡片变量](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/feishu-card-cardkit/configure-card-variables)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/3ca44ccf478aa8488dfc0a80ee1dd49a_QlEfg9eh9A.gif?height=1008&lazyload=true&maxWidth=500&width=2056) +1. 选中循环容器中的富文本组件,在右侧 **属性** 页签下,点击变量图标,绑定上一步添加的子变量文本变量。warning + 循环容器中的组件,必须要绑定对象数组的子变量,才可实现内容动态展示。 + ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/016dfb3d234f8c1ed5e24dc4bc36c88c_oYVu2Kiugp.png?height=1038&lazyload=true&maxWidth=500&width=2882) +1. 选中循环容器中的图片组件,在右侧 **属性** 页签下,点击 **绑定变量**,绑定上一步添加的子变量图片变量。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/3b29a87c7c2af53fb4079baca3f278d2_zaLvEKE6Jk.png?height=1030&lazyload=true&maxWidth=500&width=2882) +1. 设置对象数组变量的模拟数据,预览生效效果。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/2c39132ffaf8fce76f372adbd3c3b8f7_MSpUhEerVN.gif?height=1006&lazyload=true&maxWidth=500&width=2060) + +## 后续操作 + +在搭建工具中搭建并发布卡片后,你需在[发送卡片](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/send-feishu-card)时,通过 `template_variable` 字段为变量赋值。 + +`template_variable` 字段是卡片绑定的变量列表,格式为 `{key:value}`。其中 `key` 为变量名称,`value` 为变量的值,对应搭建工具中的模拟数据。建议你在搭建工具中通过模拟数据验证数据无误后再传值。 + +### 准备卡片数据,为变量赋值 + +以下以[循环容器案例卡片](https://open.feishu.cn/cardkit?catalogId=10015&templateId=AAqIDyz6qpMTB)为例,准备卡片消息数据,并为变量赋值: + +```json +{ + "type": "template", // 卡片类型,搭建工具传 template。 + "data": { + "template_id": "AAqi6xJ8rabcd", // 搭建工具中卡片的 ID。在卡片编辑页面左上角获取。 + "template_version_name": "1.0.0", // 卡片发布时的版本号。 + "template_variable": { // 卡片中的变量,你可在此自定义这些变量的值。 + "looping": [ // looping 即循环容器案例中,自定义的变量名称。循环容器中,支持添加一个对象数组变量,其中可包含多个子变量。此处数据即搭建工具中的模拟数据。 + { // 第一组循环中的数据。支持添加多组数据,控制列表内容内的条数。 + "link": { + "pc_url": "", + "android_url": "", + "ios_url": "", + "url": "https://open.feishu.cn" + }, + "description": "此款陶瓷采用传统日式风格,融合现代简约设计,轻橙色调营造温暖质感。每件作品均由资深陶艺师精心打造,呈现细腻纹理与自然色彩,既传承传统工艺精髓,又融入现代审美,是居家装饰与艺术收藏的理想之选。", + "title": "**和风陶韵**", + "image": { + "img_key": "img_v3_02jl_fcb7e989-14bd-4206-9e9c-30a83ae810cg" + } + }, + { // 第二组循环中的数据。 + "link": { + "pc_url": "", + "android_url": "", + "ios_url": "", + "url": "https://open.feishu.cn/document/home/index" + }, + "description": "传承古法手工制作,此陶瓷产品由经验丰富的工匠在温馨工作坊内精心铸就。每一道纹理都凝聚着匠人的热情与执着,独特造型和细腻手感使其成为提升空间格调的独特艺术品。", + "title": "**匠心之作**", + "image": { + "img_key": "img_v3_02jn_b33e62a2-de34-4181-8980-c0220ec2dadg" + } + }, + { // 第三组循环中的数据。 + "link": { + "pc_url": "", + "android_url": "", + "ios_url": "", + "url": "https://open.feishu.com/document/feishu-cards/feishu-card-overview" + }, + "description": "这款现代日式陶瓷以精美造型和艺术装饰风格脱颖而出。设计灵感源自传统与现代的交融,色彩明快、线条流畅,无论用作家居摆件还是实用器皿,都能为空间增添一份时尚雅致。", + "title": "**时尚陶韵**", + "image": { + "img_key": "img_v3_02jn_011f9680-2771-41ad-be5d-d3879563427g" + } + } + ] + } + } +} +``` + +### 发送卡片 + +将上述内容去除注释、传入实际值、并进行压缩转义后,传入[发送消息](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/create)接口的 `content` 参数中,即可发送卡片。最终通过应用发送循环容器案例卡片的请求体示例如下所示: + +```json +{ + "receive_id": "ou_b9600a00cda86b8fad2378eafe3abcef", + "msg_type": "interactive", + "content": "{\"type\":\"template\",\"data\":{\"template_id\":\"AAqIDd7labcef\",\"template_version_name\":\"1.0.0\",\"template_variable\":{\"looping\":[{\"link\":{\"pc_url\":\"\",\"android_url\":\"\",\"ios_url\":\"\",\"url\":\"https://open.feishu.cn\"},\"description\":\"此款陶瓷采用传统日式风格,融合现代简约设计,轻橙色调营造温暖质感。每件作品均由资深陶艺师精心打造,呈现细腻纹理与自然色彩,既传承传统工艺精髓,又融入现代审美,是居家装饰与艺术收藏的理想之选。\",\"title\":\"**和风陶韵**\",\"image\":{\"img_key\":\"img_v3_02jl_fcb7e989-14bd-4206-9e9c-30a83ae810cg\"}},{\"link\":{\"pc_url\":\"\",\"android_url\":\"\",\"ios_url\":\"\",\"url\":\"https://open.feishu.cn/document/home/index\"},\"description\":\"传承古法手工制作,此陶瓷产品由经验丰富的工匠在温馨工作坊内精心铸就。每一道纹理都凝聚着匠人的热情与执着,独特造型和细腻手感使其成为提升空间格调的独特艺术品。\",\"title\":\"**匠心之作**\",\"image\":{\"img_key\":\"img_v3_02jn_b33e62a2-de34-4181-8980-c0220ec2dadg\"}},{\"link\":{\"pc_url\":\"\",\"android_url\":\"\",\"ios_url\":\"\",\"url\":\"https://open.feishu.com/document/feishu-cards/feishu-card-overview\"},\"description\":\"这款现代日式陶瓷以精美造型和艺术装饰风格脱颖而出。设计灵感源自传统与现代的交融,色彩明快、线条流畅,无论用作家居摆件还是实用器皿,都能为空间增添一份时尚雅致。\",\"title\":\"**时尚陶韵**\",\"image\":{\"img_key\":\"img_v3_02jn_011f9680-2771-41ad-be5d-d3879563427g\"}}]}}}" +} +``` + +## 常见问题 + +### 循环容器是否支持再嵌套一层循环容器,再继续使用变量动态渲染? + +循环容器不支持再内嵌一个循环容器,即循环容器的子变量不再支持对象数组类型的变量。 + +### 如何灵活控制循环容器中内容的条数? + +你可通过控制循环容器中绑定的对象数组类型变量中的对象的条数,来控制动态展示多少条循环容器中的内容。 + +以下示例中添加了三组数据,你可根据自身需求增减数组中对象的条数,灵活控制循环容器中内容的条数。 + +```json +{ + "template_variable": { // 卡片中的变量,你可在此自定义这些变量的值。 + "looping": [ // looping 即循环容器案例中,自定义的变量名称。循环容器中,支持添加一个对象数组变量,其中可包含多个子变量。此处数据即搭建工具中的模拟数据。 + { // 第一组循环中的数据。支持添加多组数据,控制列表内容内的条数。 + "link": { + "pc_url": "", + "android_url": "", + "ios_url": "", + "url": "https://open.feishu.cn" + }, + "description": "此款陶瓷采用传统日式风格,融合现代简约设计,轻橙色调营造温暖质感。每件作品均由资深陶艺师精心打造,呈现细腻纹理与自然色彩,既传承传统工艺精髓,又融入现代审美,是居家装饰与艺术收藏的理想之选。", + "title": "**和风陶韵**", + "image": { + "img_key": "img_v3_02jl_fcb7e989-14bd-4206-9e9c-30a83ae810cg" + } + }, + { // 第二组循环中的数据。 + "link": { + "pc_url": "", + "android_url": "", + "ios_url": "", + "url": "https://open.feishu.cn/document/home/index" + }, + "description": "传承古法手工制作,此陶瓷产品由经验丰富的工匠在温馨工作坊内精心铸就。每一道纹理都凝聚着匠人的热情与执着,独特造型和细腻手感使其成为提升空间格调的独特艺术品。", + "title": "**匠心之作**", + "image": { + "img_key": "img_v3_02jn_b33e62a2-de34-4181-8980-c0220ec2dadg" + } + }, + { // 第三组循环中的数据。 + "link": { + "pc_url": "", + "android_url": "", + "ios_url": "", + "url": "https://open.feishu.com/document/feishu-cards/feishu-card-overview" + }, + "description": "这款现代日式陶瓷以精美造型和艺术装饰风格脱颖而出。设计灵感源自传统与现代的交融,色彩明快、线条流畅,无论用作家居摆件还是实用器皿,都能为空间增添一份时尚雅致。", + "title": "**时尚陶韵**", + "image": { + "img_key": "img_v3_02jn_011f9680-2771-41ad-be5d-d3879563427g" + } + } + ] + } +} +``` + +### 表单容器内嵌套循环容器,且循环容器内嵌可交互组件后,预览报错? + +如下图,表单容器中内嵌循环容器,且循环容器中内嵌了输入框组件,点击 **向我发送预览** 后报错。这可能是因为在表单容器中,交互组件的 **表单项标识** 在单张卡片重复了。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/31f3da63d45498a66e900e72b66b0eb6_Hx6gNktEnP.png?height=551&lazyload=true&maxWidth=600&width=1505) + +你需为输入框组件的 **表单项标识** 设置不重复的子变量。参考以下步骤解决。或直接前往卡片搭建工具使用[表单容器内嵌循环容器案例](https://open.feishu.cn/cardkit?catalogId=10015&templateId=AAqBZKqVZHLLe)。 +1. 选中交互组件(此处以 **输入框** 组件为例),在右侧 **表单项标识** 配置项处,点击变量按钮。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/a1a31e592551e310d5b8811bda645df7_6ljs9QAkjn.png?height=728&lazyload=true&maxWidth=600&width=1562) + +1. 点击 **+添加子变量**,在[循环容器](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/recycling-container)自动生成的变量中,添加一个子变量。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/9bfa2b6ffcd455d974e88e741ab447f6_VzY8GydxRH.png?height=730&lazyload=true&maxWidth=600&width=1565) + +1. 在 **编辑变量** 弹窗中,点击 **+添加子变量**,为输入框的表单项标识设置一个变量。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/5cd2ede8b0b21085f3e968d38bf69d37_3VoxI4yy4Q.png?height=783&lazyload=true&maxWidth=400&width=784) + +1. 参考下表为设置变量结构和模拟数据。 + +配置项 | 描述 | 示例值 +---|---|--- +**变量类型** | 为交互组件的表单项标识绑定的变量的类型。固定取值为 **文本** 即可。 | 文本 +**变量名称** | 一般为字母或字母与下划线的组合。在之后发送卡片时,你需要为该变量名(key)赋值(value)。 | input_name +**变量描述** | 此处可补充解释该变量的用法或说明。可不填。 | 输入框的表单项标识变量 +**模拟数据** | 为循环容器绑定的对象数组变量的子变量传入模拟数据。
    **注意**:由于交互组件的 **表单项标识** 在单张卡片不可重复,你必须为变量传入模拟数据,且数据不可重复。否则点击 **向我发送预览** 后将报错。 | ```json
    [
    {
    "input_name": "input1"
    },
    {
    "input_name": "input2"
    },
    {
    "input_name": "input3"
    }
    ]
    ``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__chart.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__chart.md new file mode 100644 index 0000000..18818c9 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__chart.md @@ -0,0 +1,221 @@ +# 图表组件 + +飞书卡片提供的图表组件基于 [VChart](https://www.visactor.io/) 的图表定义,支持折线图、面积图、柱状图、饼图、词云等多种数据呈现方式,帮助你可视化各类信息,提高信息沟通效率。 + +本文档介绍图表组件的 JSON 1.0 结构,要查看新版 JSON 2.0 结构,参考[图表](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/chart)。 + +![Frame 1321318175.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/ebf954a9756b7e0add5625832dcf9f06_bA4PiVAffn.png?height=1112&lazyload=true&maxWidth=600&width=2160) + +## 注意事项 + +- 单张卡片建议最多放置五个图表组件。 +- 图表组件支持飞书 V7.1 及以上版本的客户端。在低于该版本的飞书客户端上,图表的内容将展示为一句“请升级客户端为最新版本后查看图表”的占位图。 +- 图表组件暂不支持 JavaScript 语法。 +- 移动端暂不支持以下 VChart 相关属性,若在图表组件中指定以下 VChart 属性,图表将在移动端加载失败: + - [纹理属性(barChart.bar.style.texture)](https://www.visactor.io/vchart/option/barChart#bar.style.texture) + - [圆锥渐变属性](https://www.visactor.io/vchart/guide/tutorial_docs/Chart_Concepts/Series/Mark),即 gradient 设为 `conical` + - [形状词云基于 grid 像素布局](https://www.visactor.io/vchart/option/wordCloudChart#wordCloudConfig.layoutMode),即 `wordCloudChart.wordCloudConfig.layoutMode` 设为 `grid` + - [extensionMark 图片的 repeat 属性](https://www.visactor.io/vchart/option/barChart-extensionMark-image#style.repeatX)(extensionMark-image.style.repeatX 或 extensionMark-image.style.repeatY) + - [图元背景(barChart.bar.style.background)不支持 svg](https://www.visactor.io/vchart/option/barChart#bar.style.background) +## 嵌套规则 + +图表组件可在卡片根节点下或嵌套在分栏容器和折叠面板中使用。 + +## 功能特性 + +基于图表组件绘制的图表,支持以下功能: +- **图表可交互**:用户可通过点击图表展示数据标签、点击图例实现数据过滤、拖拽缩略轴进行数据筛选。 +- **样式自适应**:支持图表多种样式的呈现,并在不同设备端、不同色彩模式下有良好的自适应展示效果; +- **支持放大查看**:PC 端上,图表支持独立窗口查看;移动端上,图表支持点击后全屏查看。 + +## 组件属性 + +### JSON 结构 + +图表组件的完整 JSON 数据如下所示: +```json +// 飞书客户端 7.1 及之后版本支持的属性 +{ + "tag": "chart", // 组件的标签。 + "aspect_ratio": "16:9", // 图表宽高比。 + "color_theme": "brand", // 图表主题。默认值 brand。 + "chart_spec": {}, // 基于 VChart 的图表定义,详细用法参考 VChart 官方文档。 + "preview": false // 是否支持独立窗口查看,默认值 true。 + +// 飞书客户端 7.10 及之后版本支持的属性 + "height": "auto", // 图表组件的高度,默认值 auto,即根据宽高比自动计算。 +} +``` + +### 字段说明 + +图表组件的字段说明如下表。 + +字段名称 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | String | 空 | 组件的标签,图表组件的标签为固定值 `chart`。 +aspect_ratio | 否 | String | - PC 端:16:9
    - 移动端:1:1 | 图表的宽高比。支持以下比例:
    - 1:1
    - 2:1
    - 4:3
    - 16:9 +color_theme | 否 | String | brand | 图表的主题样式。当图表内存在多个颜色时,可使用该字段调整颜色样式。若你在 `chart_spec` 字段中声明了样式类属性,该字段无效。
    - brand:默认样式,与飞书客户端主题样式一致。
    - rainbow:同色系彩虹色。
    - complementary:互补色。
    - converse:反差色。
    - primary:主色。 +chart_spec | 是 | VChart spec 结构体 | 空 | 基于 VChart 的图表定义。详细用法参考 [VChart 官方文档](https://www.visactor.io/vchart/guide/tutorial_docs/Chart_Concepts/Understanding_VChart)。
    **提示**:
    - 在飞书 7.1 - 7.6 版本上,图表组件支持的 VChart 版本为 1.2.2;
    - 在飞书 7.7 - 7.9 版本上,图表组件支持的 VChart 版本为 1.6.6;
    - 在飞书 7.10 - 7.15 版本上,图表组件支持的 VChart 版本为 1.8.3;
    - 在飞书 7.16 -7.26 版本上,图表组件支持的 VChart 版本为 1.10.1。
    - 在飞书 7.27 及以上版本上,图表组件支持的 VChart 版本为 1.12.3。
    了解 VChart 版本更新,参考 [VChart Changelogs](https://www.visactor.io/vchart/changelog/release)。 +preview | 否 | Boolean | true | 图表是否可在独立窗口查看。可取值:
    - true:默认值。
    - PC 端:图表可在独立飞书窗口查看
    - 移动端:图表可在点击后全屏查看
    - false:
    - PC 端:图表不支持在独立飞书窗口查看
    - 移动端:图表不支持在点击后全屏查看 +height | 否 | String | auto | 图表组件的高度,可取值:
    - auto:默认值,高度将根据宽高比自动计算。
    - [1,999]px:自定义固定图表高度,此时宽高比属性 `aspect_ratio` 失效。
    **注意**:该属性仅在飞书 7.10 及以上版本生效。 + +## 图表类型与示例 + +图表组件基于 VChart 1.6.x 版本,当前支持折线图、面积图、柱状图、条形图等 13 种图表。本小节列出各个图表的卡片效果和 JSON 示例。要查看各类图表属性的详细说明,参考 [VChart 配置文档](https://www.visactor.io/vchart/option/barChart)。 + +### 折线图 + +折线图一般用于展示数据随时间变化的趋势。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/aee3ce3391ef509a7476ca63cec582d8_8qXzlXjQIz.png?height=764&lazyload=true&maxWidth=500&width=1144) + +上图中折线图的 JSON 结构和模拟数据如下所示: + +JSON 模板 | 模拟数据 +---|--- +```json
    {
    "elements": [
    {
    "tag": "chart",
    "chart_spec": {
    "type": "line",
    "title": {
    "text": "折线图"
    },
    "data": {
    "values": mock_data // 此处传入数据。
    },
    "xField": "time",
    "yField": "value"
    }
    }
    ],
    "header": {
    "template": "purple",
    "title": { "content": "卡片标题", "tag": "plain_text" }
    }
    }
    ``` | ```json
    [
    {
    "time": "2:00",
    "value": 8
    },
    {
    "time": "4:00",
    "value": 9
    },
    {
    "time": "6:00",
    "value": 11
    },
    {
    "time": "8:00",
    "value": 14
    },
    {
    "time": "10:00",
    "value": 16
    },
    {
    "time": "12:00",
    "value": 17
    },
    {
    "time": "14:00",
    "value": 17
    },
    {
    "time": "16:00",
    "value": 16
    },
    {
    "time": "18:00",
    "value": 15
    }
    ] + +### 面积图 + +面积图类似于折线图,可用于展示数据随时间变化的趋势。面积图下方的填充区域可用于强调累积的总体趋势。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/b283e95152ebbf54c06599a60502eb34_IrPGUpPSr3.png?height=766&lazyload=true&maxWidth=500&width=1140) + +上图中面积图的 JSON 结构和模拟数据如下所示: + +JSON 模板 | 模拟数据 +---|--- +```json
    {
    "elements": [
    {
    "tag": "chart",
    "chart_spec": {
    "type": "area",
    "title": {
    "text": "面积图"
    },
    "data": {
    "values": mock_data // 此处传入数据。
    },
    "xField": "time",
    "yField": "value"
    }
    }
    ],
    "header": {
    "template": "purple",
    "title": { "content": "卡片标题", "tag": "plain_text" }
    }
    } | ```json
    [
    {
    "time": "2:00",
    "value": 8
    },
    {
    "time": "4:00",
    "value": 9
    },
    {
    "time": "6:00",
    "value": 11
    },
    {
    "time": "8:00",
    "value": 14
    },
    {
    "time": "10:00",
    "value": 16
    },
    {
    "time": "12:00",
    "value": 17
    },
    {
    "time": "14:00",
    "value": 17
    },
    {
    "time": "16:00",
    "value": 16
    },
    {
    "time": "18:00",
    "value": 15
    }
    ]
    ``` + +### 柱状图 + +柱状图多用于比较不同组或类别之间的数据,可清晰地展示各组之间的差异。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/a34007ddecf9102af3e46f691c04e10e_zPiSWrwtu5.png?height=972&lazyload=true&maxWidth=500&width=1144) + +上图中柱状图的 JSON 结构和模拟数据如下所示: + +JSON 模板 | 模拟数据 +---|--- +```json
    {
    "elements": [
    {
    "tag": "chart",
    "chart_spec": {
    "type": "bar",
    "title": {
    "text": "柱状图"
    },
    "data": {
    "values": mock_data // 此处传入数据。
    },
    "xField": ["year", "type"],
    "yField": "value",
    "seriesField": "type",
    "legends": {
    "visible": true,
    "orient": "bottom"
    }
    }
    }
    ],
    "header": {
    "template": "purple",
    "title": { "content": "卡片标题", "tag": "plain_text" }
    }
    } | ```json
    [
    { "type": "Autoc", "year": "1930", "value": 129 },
    { "type": "Autoc", "year": "1940", "value": 133 },
    { "type": "Autoc", "year": "1950", "value": 130 },
    { "type": "Autoc", "year": "1960", "value": 126 },
    { "type": "Autoc", "year": "1970", "value": 117 },
    { "type": "Autoc", "year": "1980", "value": 114 },
    { "type": "Democ", "year": "1930", "value": 22 },
    { "type": "Democ", "year": "1940", "value": 13 },
    { "type": "Democ", "year": "1950", "value": 25 },
    { "type": "Democ", "year": "1960", "value": 29 },
    { "type": "Democ", "year": "1970", "value": 38 },
    { "type": "Democ", "year": "1980", "value": 41 }
    ]
    ``` + +### 条形图 + +条形图与柱状图类似,但是为横向显示。通常用于比较不同类别的数据,在数据标签较长或类别较多时更易于阅读。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/b34bb493daeb56b4962568cc77d3f7ea_f1gjZhfSPp.png?height=768&lazyload=true&maxWidth=500&width=1142) + +上图中条形图的 JSON 结构和模拟数据如下所示: + +JSON 模板 | 模拟数据 +---|--- +```json
    {
    "elements": [
    {
    "tag": "chart",
    "chart_spec": {
    "type": "bar",
    "title": {
    "text": "条形图"
    },
    "data": {
    "values": mock_data // 此处传入数据。
    },
    "direction": "horizontal",
    "xField": "value",
    "yField": "name"
    }
    }
    ],
    "header": {
    "template": "purple",
    "title": {
    "content": "卡片标题",
    "tag": "plain_text"
    }
    }
    }
    ``` | ```json
    [
    {
    "name": "Apple",
    "value": 214480
    },
    {
    "name": "Google",
    "value": 155506
    },
    {
    "name": "Amazon",
    "value": 100764
    },
    {
    "name": "Microsoft",
    "value": 92715
    },
    {
    "name": "Coca-Cola",
    "value": 66341
    },
    {
    "name": "Samsung",
    "value": 59890
    },
    {
    "name": "Toyota",
    "value": 53404
    },
    {
    "name": "Mercedes-Benz",
    "value": 48601
    }
    ]
    ``` + +### 环图 + +环图用于表示整体中各部分的相对比例。适用于展示数据的百分比分布,强调整体的结构。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/1f9972f212bc72abe4ab7e144dd71ff1_089Whyfkns.png?height=1036&lazyload=true&maxWidth=500&width=1320) + +上图中环图的 JSON 结构和模拟数据如下所示: + +JSON 模板 | 模拟数据 +---|--- +```json
    {
    "elements": [
    {
    "tag": "chart",
    "chart_spec": {
    "type": "pie",
    "title": {
    "text": "环图"
    },
    "data": {
    "values": mock_data // 此处传入数据。
    },
    "valueField": "value",
    "categoryField": "type",
    "outerRadius": 0.9,
    "innerRadius": 0.3,
    "label": {
    "visible": true
    },
    "legends": {
    "visible": true
    }
    }
    }
    ],
    "header": {
    "template": "purple",
    "title": { "content": "卡片标题", "tag": "plain_text" }
    }
    } | ```json
    [
    { "type": "oxygen", "value": "46.60" },
    { "type": "silicon", "value": "27.72" },
    { "type": "aluminum", "value": "8.13" },
    { "type": "iron", "value": "5" },
    { "type": "calcium", "value": "3.63" },
    { "type": "potassium", "value": "2.59" },
    { "type": "others", "value": "3.5" }
    ]
    ``` + +### 饼图 + +饼图可用于表示整体中各部分的相对比例,但通常适用于展示几个部分的数据。适用于呈现百分比或份额。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/6dd2f06c4de01e200cc6dbc4ca165966_xVUSruCyRc.png?height=854&lazyload=true&maxWidth=500&width=994) + +上图中饼图的 JSON 结构和模拟数据如下所示: + +JSON 模板 | 模拟数据 +---|--- +```json
    {
    "elements": [
    {
    "tag": "chart",
    "aspect_ratio": "4:3",
    "chart_spec": {
    "type": "pie",
    "title": {
    "text": "客户规划占比"
    },
    "data": {
    "values": mock_data // 此处传入数据。
    },
    "valueField": "value",
    "categoryField": "type",
    "outerRadius": 0.9,
    "legends": {
    "visible": true,
    "orient": "right"
    },
    "padding": {
    "left": 10,
    "top": 10,
    "bottom": 5,
    "right": 0
    },
    "label": {
    "visible": true
    }
    }
    }
    ]
    } | ```json
    [
    {
    "type": "S1",
    "value": "340"
    },
    {
    "type": "S2",
    "value": "170"
    },
    {
    "type": "S3",
    "value": "150"
    },
    {
    "type": "S4",
    "value": "120"
    },
    {
    "type": "S5",
    "value": "100"
    }
    ]
    ``` + +### 组合图 + +组合图可将多个图表类型组合在一起,同时呈现不同性质的数据。例如,折线图与柱状图的组合,可同时展示趋势和总量。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/af72cc20eb8606efd9f45e0a237f043b_ajiDpgkGOe.png?height=966&lazyload=true&maxWidth=500&width=1142) + +上图中组合图的 JSON 结构和模拟数据如下所示: + +JSON 模板 | 模拟数据 +---|--- +```json
    {
    "elements": [
    {
    "tag": "chart",
    "chart_spec": {
    "type": "common",
    "title": {
    "text": "组合图"
    },
    "data": [
    {
    "values": mock_data_1_1 // 此处传入数据。
    },
    {
    "values": mock_data_1_2 // 此处传入数据。
    }
    ],
    "series": [
    {
    "type": "bar",
    "dataIndex": 0,
    "label":
    {
    "visible": true
    },
    "seriesField": "type",
    "xField": ["x", "type"],
    "yField": "y"
    },
    {
    "type": "line",
    "dataIndex": 1,
    "label": {
    "visible": true
    },
    "seriesField": "type",
    "xField": "x",
    "yField": "y"
    }
    ],
    "axes": [
    {
    "orient": "bottom"
    },
    {
    "orient": "left"
    }
    ],
    "legends": {
    "visible": true,
    "orient": "bottom"
    }
    }
    }
    ],
    "header": {
    "template": "purple",
    "title": { "content": "卡片标题", "tag": "plain_text" }
    }
    } | ```json
    // mock_data_1_1
    [
    { "x": "周一", "type": "早餐", "y": 15 },
    { "x": "周一", "type": "午餐", "y": 25 },
    { "x": "周二", "type": "早餐", "y": 12 },
    { "x": "周二", "type": "午餐", "y": 30 },
    { "x": "周三", "type": "早餐", "y": 15 },
    { "x": "周三", "type": "午餐", "y": 24 },
    { "x": "周四", "type": "早餐", "y": 10 },
    { "x": "周四", "type": "午餐", "y": 25 },
    { "x": "周五", "type": "早餐", "y": 13 },
    { "x": "周五", "type": "午餐", "y": 20 },
    { "x": "周六", "type": "早餐", "y": 10 },
    { "x": "周六", "type": "午餐", "y": 22 },
    { "x": "周日", "type": "早餐", "y": 12 },
    { "x": "周日", "type": "午餐", "y": 19 }
    ]
    ```
    ```json
    // mock_data_1_2
    [
    { "x": "周一", "type": "饮料", "y": 22 },
    { "x": "周二", "type": "饮料", "y": 43 },
    { "x": "周三", "type": "饮料", "y": 33 },
    { "x": "周四", "type": "饮料", "y": 22 },
    { "x": "周五", "type": "饮料", "y": 10 },
    { "x": "周六", "type": "饮料", "y": 30 },
    { "x": "周日", "type": "饮料", "y": 50 }
    ]
    ``` + +### 漏斗图 + +漏斗图用于表示一系列步骤或阶段中的数据减少。适用于呈现转化率、展示销售漏斗等情况。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/62d4168a2a47d57fbc08aed32972299f_kxTsqD1AvS.png?height=768&lazyload=true&maxWidth=500&width=1140) + +上图中漏斗图的 JSON 结构和模拟数据如下所示: + +JSON 模板 | 模拟数据 +---|--- +```json
    {
    "elements": [
    {
    "tag": "chart",
    "chart_spec": {
    "type": "funnel",
    "title": {
    "text": "漏斗图"
    },
    "data": {
    "values": mock_data // 此处传入数据。
    },
    "categoryField": "name",
    "valueField": "value",
    "isTransform": true,
    "label": {
    "visible": true
    },
    "transformLabel": {
    "visible": true
    },
    "outerLabel": {
    "visible": false
    }
    }
    }
    ],
    "header": {
    "template": "purple",
    "title": { "content": "卡片标题", "tag": "plain_text" }
    }
    } | ```json
    [
    {
    "value": 5676,
    "name": "Sent"
    },
    {
    "value": 3872,
    "name": "Viewed"
    },
    {
    "value": 1668,
    "name": "Clicked"
    },
    {
    "value": 565,
    "name": "Purchased"
    }
    ]
    ``` + +### 散点图 + +散点图用于显示两个变量之间的关系,展示变量之间的相关性、趋势或异常值。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/00875a914b0448869a14ffbc6c685e72_unCKtVczbO.png?height=964&lazyload=true&maxWidth=500&width=1138) + +上图中散点图的 JSON 结构和模拟数据如下所示: + +JSON 模板 | 模拟数据 +---|--- +```json
    {
    "elements": [
    {
    "tag": "chart",
    "chart_spec":{
    "type": "scatter",
    "title": {
    "text": "散点图"
    },
    "data": {
    "values": mock_data // 此处传入数据。
    },
    "xField": "milesPerGallon",
    "yField": "horsepower",
    "axes": [
    {
    "title": {
    "visible": true,
    "text": "Horse Power"
    },
    "orient": "left",
    "range": { "min": 0 },
    "type": "linear"
    },
    {
    "title": {
    "visible": true,
    "text": "Miles Per Gallon"
    },
    "orient": "bottom",
    "range": { "min": 10 },
    "type": "linear"
    }
    ]
    }
    }
    ],
    "header": {
    "template": "purple",
    "title": { "content": "卡片标题", "tag": "plain_text" }
    }
    }
    ``` | ```json
    [
    { "name": "chevrolet woody", "milesPerGallon": 24.5, "cylinders": 4, "horsepower": 60 },
    { "name": "vw rabbit", "milesPerGallon": 29, "cylinders": 4, "horsepower": 70 },
    { "name": "honda civic", "milesPerGallon": 33, "cylinders": 4, "horsepower": 53 },
    { "name": "dodge aspen se", "milesPerGallon": 20, "cylinders": 6, "horsepower": 100 },
    { "name": "buick opel isuzu deluxe", "milesPerGallon": 30, "cylinders": 4, "horsepower": 80 },
    { "name": "renault 5 gtl", "milesPerGallon": 36, "cylinders": 4, "horsepower": 58 },
    { "name": "plymouth arrow gs", "milesPerGallon": 25.5, "cylinders": 4, "horsepower": 96 },
    { "name": "datsun f-10 hatchback", "milesPerGallon": 33.5, "cylinders": 4, "horsepower": 70 },
    { "name": "chevrolet caprice classic", "milesPerGallon": 17.5, "cylinders": 8, "horsepower": 145 },
    { "name": "oldsmobile cutlass supreme", "milesPerGallon": 17, "cylinders": 8, "horsepower": 110 },
    { "name": "dodge monaco brougham", "milesPerGallon": 15.5, "cylinders": 8, "horsepower": 145 },
    { "name": "mercury cougar brougham", "milesPerGallon": 15, "cylinders": 8, "horsepower": 130 },
    { "name": "chevrolet concours", "milesPerGallon": 17.5, "cylinders": 6, "horsepower": 110 },
    { "name": "buick skylark", "milesPerGallon": 20.5, "cylinders": 6, "horsepower": 105 },
    { "name": "plymouth volare custom", "milesPerGallon": 19, "cylinders": 6, "horsepower": 100 },
    { "name": "ford granada", "milesPerGallon": 18.5, "cylinders": 6, "horsepower": 98 },
    { "name": "pontiac grand prix lj", "milesPerGallon": 16, "cylinders": 8, "horsepower": 180 },
    { "name": "chevrolet monte carlo landau", "milesPerGallon": 15.5, "cylinders": 8, "horsepower": 170 },
    { "name": "chrysler cordoba", "milesPerGallon": 15.5, "cylinders": 8, "horsepower": 190 },
    { "name": "ford thunderbird", "milesPerGallon": 16, "cylinders": 8, "horsepower": 149 },
    { "name": "volkswagen rabbit custom", "milesPerGallon": 29, "cylinders": 4, "horsepower": 78 },
    { "name": "pontiac sunbird coupe", "milesPerGallon": 24.5, "cylinders": 4, "horsepower": 88 },
    { "name": "toyota corolla liftback", "milesPerGallon": 26, "cylinders": 4, "horsepower": 75 },
    { "name": "ford mustang ii 2+2", "milesPerGallon": 25.5, "cylinders": 4, "horsepower": 89 },
    { "name": "saab 99gle", "milesPerGallon": 21.6, "cylinders": 4, "horsepower": 115 },
    { "name": "ford country squire (sw)", "milesPerGallon": 15.5, "cylinders": 8, "horsepower": 142 },
    { "name": "chevrolet malibu classic (sw)", "milesPerGallon": 19.2, "cylinders": 8, "horsepower": 125 },
    { "name": "chrysler lebaron town @ country (sw)", "milesPerGallon": 18.5, "cylinders": 8, "horsepower": 150 },
    { "name": "vw rabbit custom", "milesPerGallon": 31.9, "cylinders": 4, "horsepower": 71 },
    { "name": "maxda glc deluxe", "milesPerGallon": 34.1, "cylinders": 4, "horsepower": 65 },
    { "name": "dodge colt hatchback custom", "milesPerGallon": 35.7, "cylinders": 4, "horsepower": 80 },
    { "name": "amc spirit dl", "milesPerGallon": 27.4, "cylinders": 4, "horsepower": 80 },
    { "name": "mercedes benz 300d", "milesPerGallon": 25.4, "cylinders": 5, "horsepower": 77 },
    { "name": "cadillac eldorado", "milesPerGallon": 23, "cylinders": 8, "horsepower": 125 },
    { "name": "peugeot 504", "milesPerGallon": 27.2, "cylinders": 4, "horsepower": 71 },
    { "name": "oldsmobile cutlass salon brougham", "milesPerGallon": 23.9, "cylinders": 8, "horsepower": 90 },
    { "name": "plymouth horizon", "milesPerGallon": 34.2, "cylinders": 4, "horsepower": 70 },
    { "name": "plymouth horizon tc3", "milesPerGallon": 34.5, "cylinders": 4, "horsepower": 70 },
    { "name": "datsun 210", "milesPerGallon": 31.8, "cylinders": 4, "horsepower": 65 },
    { "name": "fiat strada custom", "milesPerGallon": 37.3, "cylinders": 4, "horsepower": 69 },
    { "name": "buick skylark limited", "milesPerGallon": 28.4, "cylinders": 4, "horsepower": 90 },
    { "name": "chevrolet citation", "milesPerGallon": 28.8, "cylinders": 6, "horsepower": 115 },
    { "name": "oldsmobile omega brougham", "milesPerGallon": 26.8, "cylinders": 6, "horsepower": 115 },
    { "name": "pontiac phoenix", "milesPerGallon": 33.5, "cylinders": 4, "horsepower": 90 },
    { "name": "vw rabbit", "milesPerGallon": 41.5, "cylinders": 4, "horsepower": 76 },
    { "name": "toyota corolla tercel", "milesPerGallon": 38.1, "cylinders": 4, "horsepower": 60 },
    { "name": "chevrolet chevette", "milesPerGallon": 32.1, "cylinders": 4, "horsepower": 70 },
    { "name": "datsun 310", "milesPerGallon": 37.2, "cylinders": 4, "horsepower": 65 },
    { "name": "chevrolet citation", "milesPerGallon": 28, "cylinders": 4, "horsepower": 90 },
    { "name": "ford fairmont", "milesPerGallon": 26.4, "cylinders": 4, "horsepower": 88 },
    { "name": "amc concord", "milesPerGallon": 24.3, "cylinders": 4, "horsepower": 90 },
    { "name": "dodge aspen", "milesPerGallon": 19.1, "cylinders": 6, "horsepower": 90 },
    { "name": "audi 4000", "milesPerGallon": 34.3, "cylinders": 4, "horsepower": 78 },
    { "name": "toyota corona liftback", "milesPerGallon": 29.8, "cylinders": 4, "horsepower": 90 },
    { "name": "mazda 626", "milesPerGallon": 31.3, "cylinders": 4, "horsepower": 75 },
    { "name": "datsun 510 hatchback", "milesPerGallon": 37, "cylinders": 4, "horsepower": 92 },
    { "name": "toyota corolla", "milesPerGallon": 32.2, "cylinders": 4, "horsepower": 75 },
    { "name": "mazda glc", "milesPerGallon": 46.6, "cylinders": 4, "horsepower": 65 },
    { "name": "dodge colt", "milesPerGallon": 27.9, "cylinders": 4, "horsepower": 105 },
    { "name": "datsun 210", "milesPerGallon": 40.8, "cylinders": 4, "horsepower": 65 },
    { "name": "vw rabbit c (diesel)", "milesPerGallon": 44.3, "cylinders": 4, "horsepower": 48 },
    { "name": "vw dasher (diesel)", "milesPerGallon": 43.4, "cylinders": 4, "horsepower": 48 },
    { "name": "audi 5000s (diesel)", "milesPerGallon": 36.4, "cylinders": 5, "horsepower": 67 },
    { "name": "mercedes-benz 240d", "milesPerGallon": 30, "cylinders": 4, "horsepower": 67 },
    { "name": "honda civic 1500 gl", "milesPerGallon": 44.6, "cylinders": 4, "horsepower": 67 },
    { "name": "renault lecar deluxe", "milesPerGallon": 40.9, "cylinders": 4, "horsepower": 0 },
    { "name": "subaru dl", "milesPerGallon": 33.8, "cylinders": 4, "horsepower": 67 },
    { "name": "vokswagen rabbit", "milesPerGallon": 29.8, "cylinders": 4, "horsepower": 62 },
    { "name": "datsun 280-zx", "milesPerGallon": 32.7, "cylinders": 6, "horsepower": 132 },
    { "name": "mazda rx-7 gs", "milesPerGallon": 23.7, "cylinders": 3, "horsepower": 100 },
    { "name": "triumph tr7 coupe", "milesPerGallon": 35, "cylinders": 4, "horsepower": 88 },
    { "name": "ford mustang cobra", "milesPerGallon": 23.6, "cylinders": 4, "horsepower": 0 },
    { "name": "honda Accelerationord", "milesPerGallon": 32.4, "cylinders": 4, "horsepower": 72 },
    { "name": "plymouth reliant", "milesPerGallon": 27.2, "cylinders": 4, "horsepower": 84 },
    { "name": "buick skylark", "milesPerGallon": 26.6, "cylinders": 4, "horsepower": 84 },
    { "name": "dodge aries wagon (sw)", "milesPerGallon": 25.8, "cylinders": 4, "horsepower": 92 },
    { "name": "chevrolet citation", "milesPerGallon": 23.5, "cylinders": 6, "horsepower": 110 },
    { "name": "plymouth reliant", "milesPerGallon": 30, "cylinders": 4, "horsepower": 84 }
    ]
    ``` + +### 雷达图 + +雷达图用于比较多个变量在不同维度上的表现,也可展示多个指标之间的相对关系。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/503ae73a48f042fb11b607f6f229d64c_kOQFBPe2Me.png?height=966&lazyload=true&maxWidth=500&width=1140) + +上图中雷达图的 JSON 结构和模拟数据如下所示: + +JSON 模板 | 模拟数据 +---|--- +```json
    {
    "elements": [
    {
    "tag": "chart",
    "chart_spec": {
    "type": "radar",
    "title": {
    "text": "雷达图"
    },
    "data": {
    "values": mock_data // 此处传入数据。
    },
    "categoryField": "key",
    "valueField": "value",
    "area": {
    "visible": true
    },
    "outerRadius": 0.8,
    "axes": [
    {
    "orient": "radius",
    "label": {
    "visible": true,
    "style": {
    "textAlign": "center"
    }
    }
    }
    ]
    }
    }
    ],
    "header": {
    "template": "purple",
    "title": { "content": "卡片标题", "tag": "plain_text" }
    }
    }
    ``` | ```json
    [
    {
    "key": "力量",
    "value": 5
    },
    {
    "key": "速度",
    "value": 5
    },
    {
    "key": "射程",
    "value": 3
    },
    {
    "key": "持续",
    "value": 5
    },
    {
    "key": "精密",
    "value": 5
    },
    {
    "key": "成长",
    "value": 5
    }
    ]
    ``` + +### 条形进度 + +条形进度用于表示某个或多个指标的进度,如任务完成度、目标达成情况等。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/c9df7b7058779e5dec730d86b5a2a738_lF6E5uRTAi.png?height=698&lazyload=true&maxWidth=500&width=1136) + +上图中条形进度的 JSON 结构和模拟数据如下所示: + +JSON 模板 | 模拟数据 +---|--- +```json
    {
    "elements": [
    {
    "tag": "chart",
    "aspect_ratio": "2:1",
    "chart_spec": {
    "type": "linearProgress",
    "title": {
    "text": "条形进度图"
    },
    "data": {
    "values": mock_data // 此处传入数据。
    },
    "direction": "horizontal",
    "xField": "value",
    "yField": "type",
    "seriesField": "type",
    "axes": [
    {
    "orient": "left",
    "domainLine": { "visible": false }
    }
    ]
    }
    }
    ],
    "header": {
    "template": "purple",
    "title": { "content": "卡片标题", "tag": "plain_text" }
    }
    }
    ``` | ```json
    [
    {
    "type": "Tradition Industries",
    "value": 0.795,
    "text": "79.5%"
    },
    {
    "type": "Business Companies",
    "value": 0.25,
    "text": "25%"
    }
    ]
    ``` + +### 环形进度 + +环形进度类似于条形进度,但呈环状,可强调整体进度并突出部分的完成度。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/897414e4ba18d6806dae990cae424156_XwAlOFhR0B.png?height=962&lazyload=true&maxWidth=500&width=1144) + +上图中环形进度图的 JSON 结构和模拟数据如下所示: + +JSON 模板 | 模拟数据 +---|--- +```json
    {
    "elements": [
    {
    "tag": "chart",
    "chart_spec": {
    "type": "circularProgress",
    "title": {
    "text": "环形进度图"
    },
    "data": {
    "values": mock_data // 此处传入数据。
    },
    "valueField": "value",
    "categoryField": "type",
    "seriesField": "type",
    "radius": 0.7,
    "innerRadius": 0.4,
    "cornerRadius": 20,
    "progress": {
    "style": {
    "innerPadding": 5,
    "outerPadding": 5
    }
    },
    "indicator": {
    "visible": true,
    "trigger": "hover",
    "title": {
    "visible": true,
    "field": "type",
    "autoLimit": true
    },
    "content": [
    {
    "visible": true,
    "field": "text"
    }
    ]
    },
    "legends": {
    "visible": true,
    "orient": "bottom",
    "title": {
    "visible": false
    }
    }
    }
    }
    ],
    "header": {
    "template": "purple",
    "title": { "content": "卡片标题", "tag": "plain_text" }
    }
    }
    ``` | ```json
    [
    {
    "type": "Industries",
    "value": 0.795,
    "text": "79.5%"
    },
    {
    "type": "Companies",
    "value": 0.25,
    "text": "25%"
    }
    ]
    ``` + +### 词云 + +词云用于展示文本数据中词条的相对频率。可用于展示关键词或主题的重要性。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/5f45fba3d2e5232982ae55f319e8acc4_F6OX1hjMPL.png?height=964&lazyload=true&maxWidth=500&width=1140) + +上图中词云图的 JSON 结构和模拟数据如下所示: + +JSON 模板 | 模拟数据 +---|--- +```json
    {
    "elements": [
    {
    "tag": "chart",
    "chart_spec":{
    "type": "wordCloud",
    "title": {
    "text": "词云"
    },
    "data": {
    "values": mock_data // 此处传入数据。
    },
    "nameField": "challenge_name",
    "valueField": "sum_count",
    "seriesField": "challenge_name"
    }
    }
    ],
    "header": {
    "template": "purple",
    "title": { "content": "卡片标题", "tag": "plain_text" }
    }
    }
    ``` | ```json
    [
    {
    "challenge_id": 1658490688121879,
    "challenge_name": "宅家dou剧场宅家dou剧场",
    "sum_count": 128
    },
    {
    "challenge_id": 1640007327696910,
    "challenge_name": "我的观影报告",
    "sum_count": 103
    },
    {
    "challenge_id": 1557656100811777,
    "challenge_name": "抖瓜小助手",
    "sum_count": 76
    },
    {
    "challenge_id": 1553513807372289,
    "challenge_name": "搞笑",
    "sum_count": 70
    },
    {
    "challenge_id": 1599321527572563,
    "challenge_name": "我要上热门",
    "sum_count": 69
    },
    {
    "challenge_id": 1588489879306259,
    "challenge_name": "热门",
    "sum_count": 54
    },
    {
    "challenge_id": 1558589039423489,
    "challenge_name": "正能量",
    "sum_count": 52
    },
    {
    "challenge_id": 1565489422066689,
    "challenge_name": "上热门",
    "sum_count": 36
    },
    {
    "challenge_id": 1572618705886286,
    "challenge_name": "情感",
    "sum_count": 34
    },
    {
    "challenge_id": 1626948076237836,
    "challenge_name": "dou上热门",
    "sum_count": 32
    },
    {
    "challenge_id": 1585347546644558,
    "challenge_name": "影视剪辑",
    "sum_count": 25
    },
    {
    "challenge_id": 1589711040325639,
    "challenge_name": "抖瓜热门",
    "sum_count": 24
    },
    {
    "challenge_id": 1562208367689745,
    "challenge_name": "爱情",
    "sum_count": 24
    },
    {
    "challenge_id": 1657693004378126,
    "challenge_name": "美食趣胃计划",
    "sum_count": 21
    },
    {
    "challenge_id": 1565101681155074,
    "challenge_name": "搞笑视频",
    "sum_count": 20
    },
    {
    "challenge_id": 1581874377004045,
    "challenge_name": "涨知识",
    "sum_count": 19
    },
    {
    "challenge_id": 1577135789977693,
    "challenge_name": "教师节",
    "sum_count": 19
    },
    {
    "challenge_id": 1644832627937293,
    "challenge_name": "解锁人脸运镜术",
    "sum_count": 18
    },
    {
    "challenge_id": 1554036363744257,
    "challenge_name": "美食",
    "sum_count": 18
    },
    {
    "challenge_id": 1601049369390083,
    "challenge_name": "听说发第二遍会火",
    "sum_count": 17
    },
    {
    "challenge_id": 1643026562973710,
    "challenge_name": "我的观影视报告",
    "sum_count": 17
    },
    {
    "challenge_id": 1605694229498884,
    "challenge_name": "解说电影",
    "sum_count": 16
    },
    {
    "challenge_id": 1550712576368642,
    "challenge_name": "音乐",
    "sum_count": 15
    },
    {
    "challenge_id": 1571885391450145,
    "challenge_name": "沙雕",
    "sum_count": 15
    },
    {
    "challenge_id": 1577707248705566,
    "challenge_name": "悬疑",
    "sum_count": 15
    },
    {
    "challenge_id": 1573335406611469,
    "challenge_name": "家庭",
    "sum_count": 15
    },
    {
    "challenge_id": 1646248140767239,
    "challenge_name": "我在抖瓜看综艺",
    "sum_count": 15
    },
    {
    "challenge_id": 1640376658836494,
    "challenge_name": "我的影视报告",
    "sum_count": 14
    },
    {
    "challenge_id": 1580569530602573,
    "challenge_name": "亲爱的你在哪里",
    "sum_count": 14
    },
    {
    "challenge_id": 1581067386920973,
    "challenge_name": "夫妻",
    "sum_count": 14
    },
    {
    "challenge_id": 1570334853133377,
    "challenge_name": "健康",
    "sum_count": 14
    },
    {
    "challenge_id": 1576961841964061,
    "challenge_name": "感谢抖瓜",
    "sum_count": 13
    },
    {
    "challenge_id": 1668357679925262,
    "challenge_name": "浪计划",
    "sum_count": 13
    },
    {
    "challenge_id": 1676069567224840,
    "challenge_name": "一口吃个秋",
    "sum_count": 13
    },
    {
    "challenge_id": 1657707397301262,
    "challenge_name": "在逃公主",
    "sum_count": 13
    },
    {
    "challenge_id": 1674607865397325,
    "challenge_name": "萌宠出道计划",
    "sum_count": 13
    },
    {
    "challenge_id": 1647439075451907,
    "challenge_name": "秋日星分享",
    "sum_count": 12
    },
    {
    "challenge_id": 1563545971008513,
    "challenge_name": "电影",
    "sum_count": 12
    },
    {
    "challenge_id": 1582741603218446,
    "challenge_name": "科普",
    "sum_count": 11
    },
    {
    "challenge_id": 1586651415365645,
    "challenge_name": "婚姻",
    "sum_count": 11
    },
    {
    "challenge_id": 1578783394583565,
    "challenge_name": "传递正能量",
    "sum_count": 11
    },
    {
    "challenge_id": 1614856685574147,
    "challenge_name": "沙雕沙雕沙雕",
    "sum_count": 11
    },
    {
    "challenge_id": 1665561838764045,
    "challenge_name": "封校的当代大学生",
    "sum_count": 11
    },
    {
    "challenge_id": 1640393867132935,
    "challenge_name": "教师节快乐",
    "sum_count": 10
    },
    {
    "challenge_id": 1587559248197661,
    "challenge_name": "遇见她",
    "sum_count": 10
    },
    {
    "challenge_id": 1673432085422103,
    "challenge_name": "抖是剧中人",
    "sum_count": 10
    },
    {
    "challenge_id": 1645181053899788,
    "challenge_name": "dou出新知",
    "sum_count": 10
    },
    {
    "challenge_id": 1569728533702658,
    "challenge_name": "情侣日常",
    "sum_count": 10
    },
    {
    "challenge_id": 1668624557294599,
    "challenge_name": "百万赞演技大赏",
    "sum_count": 10
    },
    {
    "challenge_id": 1571636507998210,
    "challenge_name": "记录生活",
    "sum_count": 9
    },
    {
    "challenge_id": 1581943156410381,
    "challenge_name": "抖瓜电影",
    "sum_count": 9
    },
    {
    "challenge_id": 1593324788514820,
    "challenge_name": "婚姻家庭",
    "sum_count": 9
    },
    {
    "challenge_id": 1641293074512910,
    "challenge_name": "寻情记",
    "sum_count": 9
    },
    {
    "challenge_id": 1676080053705736,
    "challenge_name": "爱宠来狂欢",
    "sum_count": 9
    },
    {
    "challenge_id": 1589745110342676,
    "challenge_name": "夫妻日常",
    "sum_count": 9
    },
    {
    "challenge_id": 1574942323087374,
    "challenge_name": "开学",
    "sum_count": 9
    },
    {
    "challenge_id": 1660654219289607,
    "challenge_name": "娱乐播报台",
    "sum_count": 9
    },
    {
    "challenge_id": 1597705816677380,
    "challenge_name": "影视推荐",
    "sum_count": 9
    },
    {
    "challenge_id": 1675354540387336,
    "challenge_name": "萤火计划",
    "sum_count": 9
    },
    {
    "challenge_id": 1652979335878669,
    "challenge_name": "上海",
    "sum_count": 9
    },
    {
    "challenge_id": 1569327523145730,
    "challenge_name": "军训",
    "sum_count": 9
    },
    {
    "challenge_id": 1558926116325378,
    "challenge_name": "健身",
    "sum_count": 8
    },
    {
    "challenge_id": 1645373043400716,
    "challenge_name": "这个视频有点料",
    "sum_count": 8
    },
    {
    "challenge_id": 1563191800692737,
    "challenge_name": "情侣",
    "sum_count": 8
    },
    {
    "challenge_id": 1552496822290434,
    "challenge_name": "闺蜜",
    "sum_count": 8
    },
    {
    "challenge_id": 1603569303963651,
    "challenge_name": "平凡的荣耀",
    "sum_count": 8
    },
    {
    "challenge_id": 1673998740750349,
    "challenge_name": "暑期知识大作战",
    "sum_count": 8
    },
    {
    "challenge_id": 1567431196459009,
    "challenge_name": "汽车",
    "sum_count": 8
    },
    {
    "challenge_id": 1658389496684558,
    "challenge_name": "百亿剧好看计划",
    "sum_count": 8
    },
    {
    "challenge_id": 1574252919626782,
    "challenge_name": "教育",
    "sum_count": 8
    },
    {
    "challenge_id": 1591391074552852,
    "challenge_name": "农村生活",
    "sum_count": 8
    },
    {
    "challenge_id": 1566157607002417,
    "challenge_name": "反转",
    "sum_count": 8
    },
    {
    "challenge_id": 1577947638725661,
    "challenge_name": "老师辛苦了",
    "sum_count": 8
    },
    {
    "challenge_id": 1603426099923976,
    "challenge_name": "婆媳",
    "sum_count": 7
    },
    {
    "challenge_id": 1583473234973709,
    "challenge_name": "剧情",
    "sum_count": 7
    },
    {
    "challenge_id": 1571084981282833,
    "challenge_name": "恋爱",
    "sum_count": 7
    },
    {
    "challenge_id": 1677255352271879,
    "challenge_name": "不要贪心舞",
    "sum_count": 7
    },
    {
    "challenge_id": 1624332181128206,
    "challenge_name": "游戏",
    "sum_count": 7
    },
    {
    "challenge_id": 1592206883926023,
    "challenge_name": "惊悚悬疑",
    "sum_count": 7
    },
    {
    "challenge_id": 1550970194610178,
    "challenge_name": "换装",
    "sum_count": 7
    },
    {
    "challenge_id": 1570527559630850,
    "challenge_name": "安全",
    "sum_count": 7
    },
    {
    "challenge_id": 1671553348181070,
    "challenge_name": "贝勒爷的沙雕日常",
    "sum_count": 7
    },
    {
    "challenge_id": 1549715734089730,
    "challenge_name": "宿舍",
    "sum_count": 7
    },
    {
    "challenge_id": 1576425368139790,
    "challenge_name": "感谢官方",
    "sum_count": 7
    },
    {
    "challenge_id": 1551594539613185,
    "challenge_name": "萌宠",
    "sum_count": 7
    },
    {
    "challenge_id": 1642026158078987,
    "challenge_name": "抖瓜创作者大会",
    "sum_count": 7
    },
    {
    "challenge_id": 1550169395535874,
    "challenge_name": "舞蹈",
    "sum_count": 6
    },
    { "challenge_id": 1564101645806594, "challenge_name": "狗", "sum_count": 6 },
    {
    "challenge_id": 1569456397847553,
    "challenge_name": "班主任",
    "sum_count": 6
    },
    {
    "challenge_id": 1571995751044098,
    "challenge_name": "手机摄影",
    "sum_count": 6
    },
    {
    "challenge_id": 1571241227129857,
    "challenge_name": "刘德华",
    "sum_count": 6
    },
    {
    "challenge_id": 1674031131712524,
    "challenge_name": "画画的baby",
    "sum_count": 6
    },
    {
    "challenge_id": 1574972965820429,
    "challenge_name": "盛世美颜",
    "sum_count": 6
    },
    {
    "challenge_id": 1598181470695437,
    "challenge_name": "精彩片段",
    "sum_count": 6
    },
    {
    "challenge_id": 1566324012028929,
    "challenge_name": "迈克尔杰克逊",
    "sum_count": 6
    },
    {
    "challenge_id": 1555709753369601,
    "challenge_name": "抖瓜",
    "sum_count": 6
    },
    {
    "challenge_id": 1611500399287309,
    "challenge_name": "把嘴给我闭上",
    "sum_count": 6
    },
    {
    "challenge_id": 1619248233185284,
    "challenge_name": "抖瓜汽车",
    "sum_count": 6
    },
    {
    "challenge_id": 1677633728299016,
    "challenge_name": "电影禁锢之地",
    "sum_count": 6
    },
    {
    "challenge_id": 1574140351949838,
    "challenge_name": "花木兰",
    "sum_count": 6
    },
    {
    "challenge_id": 1591376183127134,
    "challenge_name": "林雨申",
    "sum_count": 6
    }
    ]
    ``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__divider.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__divider.md new file mode 100644 index 0000000..d1ebf02 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__divider.md @@ -0,0 +1,89 @@ +# 分割线组件 + +你可以在卡片中添加分割线组件,使卡片内容更清晰。 + +本文档介绍分割线组件的 JSON 1.0 结构,要查看新版 JSON 2.0 结构,参考[分割线](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/divider)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/062d8c93b9b67ee9fb8c4188c19097d5_bbVIhvzLdi.png?height=224&lazyload=true&maxWidth=300&width=559) + +## JSON 结构 + +分割线的完整 JSON 数据如下所示: +```json +{ + "tag": "hr" +} +``` + +## 字段说明 + +分割线组件的字段说明如下表。 +| 参数 | 是否必须 | 类型 | 描述 | +| --- | ---- | ------ | ----------------------- | +| tag | 是 | String | 组件的标签。分割线组件的固定取值为 `hr`。 | + +## 示例代码 + +以下的 JSON 示例代码可实现如下图所示的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/062d8c93b9b67ee9fb8c4188c19097d5_skrtnBe6Lz.png?height=224&lazyload=true&maxWidth=300&width=559) +```json +{ + "config": {}, + "card_link": { + "url": "", + "pc_url": "", + "ios_url": "", + "android_url": "" + }, + "i18n_elements": { + "zh_cn": [ + { + "tag": "column_set", + "flex_mode": "none", + "horizontal_spacing": "default", + "background_style": "default", + "columns": [ + { + "tag": "column", + "elements": [ + { + "tag": "div", + "text": { + "tag": "plain_text", + "content": "普通文本示例", + "text_size": "normal", + "text_align": "left", + "text_color": "default" + } + } + ], + "width": "weighted", + "weight": 1 + } + ] + }, + { + "tag": "hr" + }, + { + "tag": "action", + "actions": [ + { + "tag": "button", + "text": { + "tag": "plain_text", + "content": "查看更多" + }, + "type": "primary", + "complex_interaction": true, + "width": "default", + "size": "medium" + } + ] + } + ] + }, + "i18n_header": {} +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__image.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__image.md new file mode 100644 index 0000000..8c0e793 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__image.md @@ -0,0 +1,99 @@ +# 图片组件 + +飞书卡片支持图片组件。你可调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口或在搭建工具的图片组件中上传图片,获取图片的 key 传入图片组件中,使卡片内容更丰富。 + +本文档介绍图片组件的 JSON 1.0 结构,要查看新版 JSON 2.0 结构,参考[图片](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/image)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/21a2d415edcae0e25f9c6248423a9a2c_vVX17Ip7AI.png?height=354&lazyload=true&maxWidth=300&width=559) + +## 注意事项 + +为保证图片在聊天窗口中呈现的清晰度,建议你在组件中上传的图片遵从以下规范: + +- 图片尺寸在 1500 × 3000 px 的范围内。 +- 图片大小不超过 10 M。 +- 图片的 `高度:宽度` 不超过 `16:9`。 + +## JSON 结构 + +图片的完整 JSON 数据如下所示: + +```json +{ + "tag": "img", + "img_key": "img_v3_0238_073f1823-df2b-4377-86c6-e293f18abcef", // 图片的 Key。可通过上传图片接口或在搭建工具中上传图片后获得。 + "alt": { + // 光标悬浮(hover)在图片上时展示的说明。 + "tag": "plain_text", + "content": "" + }, + "title": { + // 图片标题。 + "tag": "plain_text", + "content": "" + }, + "corner_radius": "5px", // 图片的圆角半径,单位是像素(px)。 + "scale_type": "crop_top", // 图片的裁剪模式,当 size 字段的比例和图片的比例不一致时会触发裁剪。 + "size": "100px 100px", // 图片尺寸。仅在 scale_type 字段为 crop_center 或 crop_top 时生效。 + "transparent": false, // 是否为透明底色。默认为 false,即图片为白色底色。 + "preview": false, // 点击后是否放大图片。默认值为 true。 + // 历史属性 + "mode": "large", // 图片尺寸模式。 + "custom_width": 500, // 自定义图片的最大展示宽度。 + "compact_width": false // 是否展示为紧凑型的图片。 +} +``` + +## 字段说明 + +图片组件的字段说明如下表。 + +参数 | 是否必须 | 类型 | 默认值 | 描述 +---|---|---|---|--- +tag | 是 | String | 无 | 组件的标签,图片组件的固定取值为 img。 +img_key | 是 | String | / | 图片资源的 Key。你可以调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口或在搭建工具中上传图片,获取图片的 key。 +alt | 是 | Struct | / | 悬浮(hover)在图片上时展示的说明文案。示例值:
    ```json
    "alt": {
    "tag": "plain_text",
    "content": "悬浮(hover)在图片上时展示的说明文案,不需要可以传空"
    }
    ``` +title | 否 | Struct | / | 图片标题。示例值:
    ```json
    "title": {
    "tag": "plain_text",
    "content": "图片标题"
    }
    ``` +corner_radius | 否 | String | / | 图片的圆角半径,单位是像素(px)。取值遵循以下格式:
    - [0,∞]px
    - [0,100]% +scale_type | 否 | String | crop_center | 图片的裁剪模式,当 `size` 字段的比例和图片的比例不一致时会触发裁剪。 | 可取值:
    - crop_center:居中裁剪
    - crop_top:顶部裁剪
    - fit_horizontal:完整展示不裁剪 +size | 否 | String | / | 图片尺寸。仅在 `scale_type` 字段为 crop_center 或 crop_top 时生效。 | 可取值:
    - large:大图,尺寸为 160 × 160,适用于多图混排。
    - medium:中图,尺寸为 80 × 80,适用于图文混排的封面图。
    - small:小图,尺寸为 40 × 40,适用于人员头像。
    - tiny:超小图,尺寸为 16 × 16,适用于图标、备注。
    - stretch:超大图,适用于高宽比小于 `16:9` 的图片。
    - stretch_without_padding:通栏图,适用于高宽比小于 `16:9` 的图片,图片的宽度将撑满卡片宽度。
    **注意**: [卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)不再支持 `stretch_without_padding` 属性。你可设置 margin 字段为负数实现通栏效果。如:`"margin": "4px -12px"`。详情参考[组件统一支持布局相关能力](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-breaking-changes-release-notes#a967672)。
    - [1,1000]px [1,1000]px:自定义图片尺寸,单位为像素,中间用空格分隔。 +transparent | 否 | Boolean | false | 是否为透明底色。默认为 false,即图片为白色底色。 +preview | 否 | Boolean | true | 点击后是否放大图片。
    - true:点击图片后,弹出图片查看器放大查看当前点击的图片。
    - false:点击图片后,响应卡片本身的交互事件,不弹出图片查看器。
    **提示**:如果你为卡片配置了跳转链接`card_link`参数,可将该参数设置为 `false`,后续用户点击卡片上的图片也能响应 card_link 链接跳转。 + +### 历史字段说明 + +参数 | 是否必须 | 类型 | 默认值 | 描述 +---|---|---|---|--- +mode | 否 | String | / | 图片显示模式。取值:
    - **crop_center**:居中裁剪模式,对长图会限高,并居中裁剪后展示。
    - **fit_horizontal**:平铺模式,宽度撑满卡片完整展示上传的图片。
    - **stretch**:自适应。图片宽度撑满卡片宽度,当图片 `高:宽` 小于 `16:9` 时,完整展示原图。当图片 `高:宽` 大于 `16:9` 时,顶部对齐裁剪图片,并在图片底部展示 **长图** 脚标。
    - **large**:大图,尺寸为 160 × 160,适用于多图混排。
    - **medium**:中图,尺寸为 80 × 80,适用于图文混排的封面图。
    - **small**:小图,尺寸为 40 × 40,适用于人员头像。
    - **tiny**:超小图,尺寸为 16 × 16,适用于图标、备注。
    **注意**:设置该参数后,会覆盖 `custom_width` 参数。更多信息参见[消息卡片设计规范](https://open.feishu.cn/document/ukTMukTMukTM/ugDOwYjL4gDM24CO4AjN)。 +custom_width | 否 | int | / | 自定义图片的最大展示宽度,支持在 278px ~ 580px 范围内指定最大展示宽度。默认情况下图片宽度与图片组件所占区域的宽度一致。
    **注意**:该参数在飞书 V4.0 以上版本生效。 +compact_width | 否 | Boolean | false | 是否展示为紧凑型的图片。如果配置为 `true`,则展示最大宽度为 278px 的紧凑型图片。 + +## 示例代码 + +将以下示例代码中的 `img_key` 替换为实际的图片 Key,即可实现如下图示例的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/21a2d415edcae0e25f9c6248423a9a2c_J9r7wMzGkG.png?height=354&lazyload=true&maxWidth=300&width=559) + +```JSON +{ + "config": {}, + "card_link": { + "url": "", + "pc_url": "", + "ios_url": "", + "android_url": "" + }, + "i18n_elements": { + "zh_cn": [ + { + "tag": "img", + "img_key": "img_v2_ace8a4f2-ae13-420f-9eb3-b3530b4abcef", + "preview": true, + "scale_type": "crop_top", + "size": "stretch" + } + ] + }, + "i18n_header": {} +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__multi-image-laylout.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__multi-image-laylout.md new file mode 100644 index 0000000..86ae47e --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__multi-image-laylout.md @@ -0,0 +1,176 @@ +# 多图混排组件 + +飞书卡片支持多图混排组件。你可调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口或在新版飞书卡片搭建工具中上传图片,获取图片的 key 传入多图混排组件中,使卡片内容更丰富。 + +本文档介绍多图混排组件的 JSON 1.0 结构,要查看新版 JSON 2.0 结构,参考[多图混排](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/multi-image-laylout)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/fb315779524d13ae504b7b7252acfd49_Bc8bJyGzyt.png?height=390&lazyload=true&maxWidth=300&width=559) + +## 使用场景 + +在内容推送场景,你可能需要在卡片内组织编排多张图片。此时你可以使用多图混排组件,选择图片混排方式,快速构建多图样式。 + +双图混排 | 三图混排 | 四宫格图 +---|---|--- +  |   |   +六宫格图 | 九宫格图 |   +  |   + +## 注意事项 + +为保证图片在聊天窗口中呈现的清晰度,建议你在组件中上传的图片遵从以下规范: + +- 图片尺寸在 1500 × 3000 px 的范围内。 +- 图片大小不超过 10 M。 +- 图片的 `高度:宽度` 不超过 `16:9`。 + +## JSON 结构 + +多图混排的完整 JSON 数据如下所示: +```json +{ + "tag": "img_combination", + "combination_mode": "double", // 多图混排的方式。 + "corner_radius": "12px", // 多图混排图片的圆角半径,单位是像素(px)。 + "img_list": [ + // 图片资源数组,顺序与图片排列顺序一致。 + { + "img_key": "img_v3_0239_8347760e-3173-4072-b1aa-e4e7c835741j" + }, + { + "img_key": "img_v3_0239_d9a9b734-57f8-4247-baf3-ae178b55f96j" + } + ] +} +``` + +## 字段说明 + +多图混排组件的字段说明如下表。 + +参数 | 是否必须 | 类型 | 默认值 | 描述 +---|---|---|---|--- +tag | 是 | String | / | 多图混排组件的标签,固定取值:`img_combination`。 +combination_mode | 是 | String | 空 | 多图混排的方式,可取值:
    - double:双图混排,最多可排布两张图。
    - triple:三图混排,最多可排布三张图。
    - bisect:等分双列图混排,每行两个等大的正方形图,最多可排布三行,即六张图。
    - trisect:等分三列图混排,每行三个等大的正方形图,最多可排布三行,即九张图。
    **注意**:
    - 若上传的图片数量超过混排方式可容纳的上限,则系统将根据图片上传的顺序,优先展示排列顺序中靠前的图片。超出上限的图片将不再显示。
    - 若上传的图片数量未达到混排方式可容纳的上限,则未排布的部分将保留空白。 +corner_radius | 否 | String | / | 多图混排图片的圆角半径,单位是像素(px)。取值遵循以下格式:
    - [0,∞]px
    - [0,100]% +img_list | 是 | Object | 空 | 图片资源的 `img_key` 数组,顺序与图片排列顺序一致。 +└ img_key | 是 | String | / | 图片资源的 Key。你可以调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口或在搭建工具中上传图片,获取图片的 key。 + +## 示例代码 + +### 双图混排效果示例 + +将以下示例代码中的 `img_key` 替换为实际的图片 Key,即可实现如下图示例的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/8a03a4edd6a0813bced92cd383061ab8_6AePbfDCGW.png?height=506&lazyload=true&maxWidth=400&width=1081) + +```json +{ + "elements": [ + { + "tag": "img_combination", + "combination_mode": "double", + "img_list": [ + { + "img_key": "img_v2_4c772db0-9aff-4eba-bbf4-6e6121cabcef" + }, + { + "img_key": "img_v2_4c772db0-9aff-4eba-bbf4-6e6121cabcef" + } + ] + } + ] +} +``` + +### 三图混排效果示例 + +将以下示例代码中的 `img_key` 替换为实际的图片 Key,即可实现如下图示例的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/fb315779524d13ae504b7b7252acfd49_cQR9wIHOXZ.png?height=390&lazyload=true&maxWidth=400&width=559) + +```json +{ + "elements": [ + { + "tag": "img_combination", + "combination_mode": "triple", + "img_list": [ + { + "img_key": "img_v2_4c772db0-9aff-4eba-bbf4-6e6121cabcef" + }, + { + "img_key": "img_v2_4c772db0-9aff-4eba-bbf4-6e6121cabcef" + }, + { + "img_key": "img_v2_4c772db0-9aff-4eba-bbf4-6e6121cabcef" + } + ] + } + ] +} +``` + +### **等分双列效果示例** + +将以下示例代码中的 `img_key` 替换为实际的图片 Key,即可实现如下图示例的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/02236d7183ff1ca900ffc37dbec338dc_FpogForok4.png?height=819&lazyload=true&maxWidth=400&width=559) + +```json +{ + "elements": [ + { + "tag": "img_combination", + "combination_mode": "bisect", + "img_list": [ + { + "img_key": "img_v2_4c772db0-9aff-4eba-bbf4-6e6121cabcef" + }, + { + "img_key": "img_v2_4c772db0-9aff-4eba-bbf4-6e6121cabcef" + }, + { + "img_key": "img_v2_4c772db0-9aff-4eba-bbf4-6e6121cabcef" + }, + { + "img_key": "img_v2_4c772db0-9aff-4eba-bbf4-6e6121cabcef" + }, + { + "img_key": "img_v2_4c772db0-9aff-4eba-bbf4-6e6121cabcef" + }, + { + "img_key": "img_v2_4c772db0-9aff-4eba-bbf4-6e6121cabcef" + } + ] + } + ] +} +``` + +### 等分三列效果示例 + +将以下示例代码中的 `img_key` 替换为实际的图片 Key,即可实现如下图示例的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/7473f1d9907913c279f796e6022f7a95_Z5qFUWHIbL.png?height=212&lazyload=true&maxWidth=400&width=559) +```json +{ + "elements": [ + { + "tag": "img_combination", + "combination_mode": "trisect", + "img_list": [ + { + "img_key": "img_v2_4c772db0-9aff-4eba-bbf4-6e6121cabcef" + }, + { + "img_key": "img_v2_4c772db0-9aff-4eba-bbf4-6e6121cabcef" + }, + { + "img_key": "img_v2_4c772db0-9aff-4eba-bbf4-6e6121cabcef" + } + ] + } + ] +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__note.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__note.md new file mode 100644 index 0000000..f172f42 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__note.md @@ -0,0 +1,100 @@ +# 备注组件 + +你可以使用备注组件展示卡片内的一些次要信息,用于辅助说明。备注组件支持添加图标、图片以及文本。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/4ebb52dffa92f1e1815cfd28603052b1_epLOLnCQrG.png?height=175&lazyload=true&maxWidth=500&width=1051) + +## 注意事项 +[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)不再支持备注(note)组件。你可使用[普通文本](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/plain-text)组件配置 notation 字号、使用 grey 字体颜色和 icon 属性替代。 + +## JSON 结构 + +备注组件的完整 JSON 数据如下所示: +```json +{ + "tag": "note", // 组件的标签。 + "elements": [ // 备注信息。支持添加图标、图片以及文本。 + { + "tag": "standard_icon", // 图标类型。 + "token": "chat-forbidden_outlined", // 图标的 token。仅在 tag 为 standard_icon 时生效。 + "color": "orange", // 图标颜色。仅在 tag 为 standard_icon 时生效。 + "img_key": "img_v2_38811724" // 图片的 key。仅在 tag 为 custom_icon 时生效。 + }, + { + "tag": "plain_text" // 文本类型的标签。 + "content": "", // 文本内容。当 tag 为 lark_md 时,支持部分 Markdown 语法的文本内容。 + } + ] +} +``` + +## 字段说明 + +备注组件的字段说明如下表。 + +字段 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | String | / | 组件的标签。备注模块组件的固定值为 `note`。 +elements | 否 | Object | / | 配置卡片的备注模块信息。支持添加图标、图片以及文本。 + +备注组件支持添加图标、图片以及文本,其中,图标的字段说明如下表。 + +字段 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 否 | String | / | 图标类型的标签。可取值:
    - `standard_icon`:使用图标库中的图标
    - `custom_icon`:使用用自定义图片作为图标 +token | 否 | String | / | 图标库中图标的 token。当 `tag` 为 `standard_icon` 时生效。枚举值参见[图标库](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-icons)。 +color | 否 | String | / | 图标的颜色。支持设置线性和面性图标(即 token 末尾为 `outlined` 或 `filled` 的图标)的颜色。当 `tag` 为 `standard_icon` 时生效。枚举值参见[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。 +img_key | 否 | String | / | 自定义前缀图标的图片 key。当 `tag` 为 `custom_icon` 时生效。
    图标 key 的获取方式:调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口,上传用于发送消息的图片,并在返回值中获取图片的 image_key。 + +备注组件支持添加图标、图片以及文本,其中,图片的字段说明如下表。 + +字段 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | String | img | 图片组件的标签。 +img_key | 是 | String | / | 图片资源的 Key。你可以调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口或在搭建工具中上传图片,获取图片的 key。 +alt | 是 | Struct | / | 悬浮(hover)在图片上时展示的说明文案。示例值:
    ```json
    "alt": {
    "tag": "plain_text",
    "content": "悬浮(hover)在图片上时展示的说明文案,不需要可以传空"
    }
    ``` + +备注组件支持添加图标、图片以及文本,其中,文本的字段说明如下表。 + +字段名称 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | String | plain_text | 文本类型的标签。可取值:
    - `plain_text`:备注模块内容
    - `lark_md`:支持部分 Markdown 语法的文本内容。详情参考 [普通文本](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/plain-text)组件中 **lark_md 支持的 Markdown 语法** 一节。
    **注意**:飞书卡片搭建工具中仅支持使用 `plain_text` 类型的备注模块组件。你可使用富文本组件添加 Markdown 格式的文本。 +content | 是 | String | / | 文本内容。当 `tag` 为 `lark_md` 时,支持部分 Markdown 语法的文本内容。详情参考 [普通文本](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/plain-text)组件中 **lark_md 支持的 Markdown 语法** 一节。 + +## 示例代码 + +以下的 JSON 示例代码可实现如下图所示的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/4ebb52dffa92f1e1815cfd28603052b1_HGJVGGS4ev.png?height=175&lazyload=true&maxWidth=500&width=1051) +```json +{ + "elements": [ + { + "tag": "note", + "elements": [ + { + "tag": "custom_icon", + "token": "chat-forbidden_outlined", + "img_key": "img_v2_041b28e3-5680-48c2-9af2-497ace79333g" + }, + { + "tag": "plain_text", + "content": "备注信息1" + }, + { + "tag": "img", + "img_key": "img_v2_041b28e3-5680-48c2-9af2-497ace79333g", + "alt": { + "tag": "plain_text", + "content": "这是备注图片" + } + }, + { + "tag": "plain_text", + "content": "备注信息2" + } + ] + } + ] +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__plain-text.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__plain-text.md new file mode 100644 index 0000000..fc9f796 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__plain-text.md @@ -0,0 +1,140 @@ +# 普通文本组件 + +卡片的普通文本组件支持添加普通文本和前缀图标,并设置文本大小、颜色、对齐方式等展示样式。 + +本文档介绍普通文本组件的 JSON 1.0 结构,要查看新版 JSON 2.0 结构,参考[普通文本](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/plain-text)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/d44aee0423f960d0aeb0a309769e9cf1_oELkL3Rd0t.png?height=168&lazyload=true&maxWidth=400&width=559) + +## JSON 结构 + +普通文本组件的 JSON 数据如下所示: +```json +{ + "tag": "div", + "text": { // 配置普通文本信息。 + "tag": "plain_text", // 文本类型的标签。 + "content": "", // 文本内容。当 tag 为 lark_md 时,支持部分 Markdown 语法的文本内容。 + "text_size": "normal", // 文本大小。默认值 normal。 + "text_color": "default", // 文本颜色。仅在 tag 为 plain_text 时生效。默认值 default。 + "text_align": "left", // 文本对齐方式。默认值 left。 + "lines": 2, // 内容最大显示行数,超出设置行的内容用 ... 省略。 + }, + "icon": { + // 前缀图标。 + "tag": "standard_icon", // 图标类型。 + "token": "chat-forbidden_outlined", // 图标的 token。仅在 tag 为 standard_icon 时生效。 + "color": "orange", // 图标颜色。仅在 tag 为 standard_icon 时生效。 + "img_key": "img_v2_38811724" // 图片的 key。仅在 tag 为 custom_icon 时生效。 + } +} +``` + +## 字段说明 + +普通文本组件的字段说明如下表。 + +字段 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | String | / | 组件的标签。普通文本组件的标签为 `div`。 +text | 否 | Object | / | 配置卡片的普通文本信息。 +└ tag | 是 | String | plain_text | 文本类型的标签。可取值:
    - `plain_text`:普通文本内容或[表情](https://www.feishu.cn/docx/doxcnG6utI72jB4eHJF1s5IgVJf)
    - `lark_md`:支持部分 Markdown 语法的文本内容。详情参考下文 **lark_md 支持的 Markdown 语法**
    **注意**:飞书卡片搭建工具中仅支持使用 `plain_text` 类型的普通文本组件。你可使用富文本组件添加 Markdown 格式的文本。 +└ content | 是 | String | / | 文本内容。当 `tag` 为 `lark_md` 时,支持部分 Markdown 语法的文本内容。详情参考下文 **lark_md 支持的 Markdown 语法**。 +└ text_size | 否 | String | normal | 文本大小。可取值如下所示。如果你填写了其它值,卡片将展示为 `normal` 字段对应的字号。你也可分别为移动端和桌面端定义不同的字号,详细步骤参考下文 **为移动端和桌面端定义不同的字号**。
    - heading-0:特大标题(30px)
    - heading-1:一级标题(24px)
    - heading-2:二级标题(20 px)
    - heading-3:三级标题(18px)
    - heading-4:四级标题(16px)
    - heading:标题(16px)
    - normal:正文(14px)
    - notation:辅助信息(12px)
    - xxxx-large:30px
    - xxx-large:24px
    - xx-large:20px
    - x-large:18px
    - large:16px
    - medium:14px
    - small:12px
    - x-small:10px +└ text_color | 否 | String | default | 文本的颜色。仅在 `tag` 为 `plain_text` 时生效。可取值:
    - `default`:客户端浅色主题模式下为黑色;客户端深色主题模式下为白色
    - 颜色的枚举值。详情参考[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color) +└ text_align | 否 | String | left | 文本对齐方式。可取值:
    - `left`:左对齐
    - `center`:居中对齐
    - `right`:右对齐 +└ lines | 否 | Int | / | 内容最大显示行数,超出设置行的内容用 `...` 省略。 +icon | 否 | Object | / | 添加图标作为文本前缀图标。支持自定义或使用图标库中的图标。 +└ tag | 否 | String | / | 图标类型的标签。可取值:
    - `standard_icon`:使用图标库中的图标。
    - `custom_icon`:使用用自定义图片作为图标。 +└ token | 否 | String | / | 图标库中图标的 token。当 `tag` 为 `standard_icon` 时生效。枚举值参见[图标库](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-icons)。 +└ color | 否 | String | / | 图标的颜色。支持设置线性和面性图标(即 token 末尾为 `outlined` 或 `filled` 的图标)的颜色。当 `tag` 为 `standard_icon` 时生效。枚举值参见[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。 +└ img_key | 否 | String | / | 自定义前缀图标的图片 key。当 `tag` 为 `custom_icon` 时生效。
    图标 key 的获取方式:调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口,上传用于发送消息的图片,并在返回值中获取图片的 image_key。 +## 示例代码
    ### `plain_text` 类型示例
    以下的 JSON 示例代码可实现如下图所示的卡片效果:
    ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/a6b7004b7b1bd27ffd79329ca2c78e4d_Hpe4dWz7hc.png?height=85&lazyload=true&maxWidth=400&width=559)
    ```json
    {
    "i18n_elements": {
    "zh_cn": [
    {
    "tag": "column_set",
    "flex_mode": "none",
    "horizontal_spacing": "default",
    "background_style": "default",
    "columns": [
    {
    "tag": "column",
    "elements": [
    {
    "tag": "div",
    "text": {
    "tag": "plain_text",
    "content": "这是一段普通文本示例。",
    "text_size": "normal",
    "text_align": "center",
    "text_color": "default"
    },
    "icon": {
    "tag": "standard_icon",
    "token": "app-default_filled",
    "color": "blue"
    }
    }
    ],
    "width": "weighted",
    "weight": 1
    }
    ]
    }
    ]
    },
    "i18n_header": {}
    }
    ```
    ### `lark_md` 类型示例
    以下的 JSON 示例代码可实现如下图所示的卡片效果:
    ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/24de2acf3d2df6b0d9adfc1b62b199e8_quEsvQKuiE.png?height=400&lazyload=true&maxWidth=400&width=798)
    ```json
    {
    "elements": [
    {
    "tag": "div",
    "text": {
    "tag": "plain_text",
    "content": "text-lark_md",
    "lines": 1
    },
    "fields": [
    {
    "is_short": false,
    "text": {
    "tag": "lark_md",
    "content": "https://open.feishu.cn"
    }
    },
    {
    "is_short": false,
    "text": {
    "tag": "lark_md",
    "content": "ready\nnew line"
    }
    },
    {
    "is_short": false,
    "text": {
    "tag": "lark_md",
    "content": "*Italic*"
    }
    },
    {
    "is_short": false,
    "text": {
    "tag": "lark_md",
    "content": "**Bold**"
    }
    },
    {
    "is_short": false,
    "text": {
    "tag": "lark_md",
    "content": "~~delete line~~"
    }
    },
    {
    "is_short": false,
    "text": {
    "tag": "lark_md",
    "content": ""
    }
    }
    ]
    }
    ]
    }
    ```
    ## `lark_md` 支持的 Markdown 语法
    能力 | 语法 | 效果 +换行 | 第一行\n第二行 | 第一行
    第二行 +斜体 | `*斜体*` | *斜体* +粗体 | `**粗体**` 或 `__粗体__` | **粗体** +删除线 | `~~删除线~~` | ~~删除线~~ +文字链接 | `[文字链接](https://www.feishu.cn)` | [文字链接](https://www.feishu.cn) +超链接 | `<a href='https://open.feishu.cn'></a>` | [https://open.feishu.cn](https://open.feishu.cn/) +@ 人 | <at id=all>
    </at>
    <at id={{open_id}}></at>
    <at id={{user_id}}></at>
    <at email=test@email.com></at>
    提示:了解如何获取 open_id 或 user_id,参考[如何获取不同的用户 ID](https://open.feishu.cn/document/home/user-identity-introduction/open-id)。 | @所有人
    @test +彩色文本 | <font color=red>红色</font>
    **提示**:要查看 color 枚举,参考[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。 | 红色 +emoji | 😁😢🌞💼🏆❌✅
    **提示**:直接复制表情即可。了解更多 emoji 表情,参考 [Emoji 表情符号大全](https://www.feishu.cn/docx/doxcnG6utI72jB4eHJF1s5IgVJf)。 | 😁😢🌞💼🏆❌✅ +飞书表情 | :OK:
    **提示**:要查看表情枚举,参考[表情文案说明](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message-reaction/emojis-introduce)。 | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/14a7a076d1d02dc352915bf678f3f785_igT4IyBu6v.png?height=44&lazyload=true&width=54) +标签 | `<text_tag color='neutral'> neutral </text_tag>`
    color 的枚举值有:neutral、blue、turquoise、lime、orange、violet、indigo、wathet、green、yellow、red、purple、carmine | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/7f37d9bde5afa05511fce58f5fa8cab9_NGDoGSFVdr.png?height=646&lazyload=true&maxWidth=88&width=188) + +## 为移动端和桌面端定义不同的字号 + +在普通文本和富文本组件的表头文本中,你可通过配置 `text_size` 为同一段文本定义在移动端和桌面端的不同字号。相关字段描述如下表所示。 + +字段 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +text_size | 否 | Object | / | 文本大小。你可在此自定义移动端和桌面端的不同字号。 +└ custom_text_size_name | 否 | Object | / | 自定义的字号。你需自定义该字段的名称,如 `cus-0`、`cus-1` 等。 +└└ default | 否 | String | / | 在无法差异化配置字号的旧版飞书客户端上,生效的字号属性。建议填写此字段。可取值如下所示。
    - heading-0:特大标题(30px)
    - heading-1:一级标题(24px)
    - heading-2:二级标题(20 px)
    - heading-3:三级标题(18px)
    - heading-4:四级标题(16px)
    - heading:标题(16px)
    - normal:正文(14px)
    - notation:辅助信息(12px)
    - xxxx-large:30px
    - xxx-large:24px
    - xx-large:20px
    - x-large:18px
    - large:16px
    - medium:14px
    - small:12px
    - x-small:10px +└└ pc | 否 | String | / | 桌面端的字号。可取值如下所示。
    - heading-0:特大标题(30px)
    - heading-1:一级标题(24px)
    - heading-2:二级标题(20 px)
    - heading-3:三级标题(18px)
    - heading-4:四级标题(16px)
    - heading:标题(16px)
    - normal:正文(14px)
    - notation:辅助信息(12px)
    - xxxx-large:30px
    - xxx-large:24px
    - xx-large:20px
    - x-large:18px
    - large:16px
    - medium:14px
    - small:12px
    - x-small:10px +└└ mobile | 否 | String | / | 移动端的文本字号。可取值如下所示。
    **注意**:部分移动端的字号枚举值的具体大小与 PC 端有差异,使用时请注意区分。
    - heading-0:特大标题(26px)
    - heading-1:一级标题(24px)
    - heading-2:二级标题(20 px)
    - heading-3:三级标题(17px)
    - heading-4:四级标题(16px)
    - heading:标题(16px)
    - normal:正文(14px)
    - notation:辅助信息(12px)
    - xxxx-large:26px
    - xxx-large:24px
    - xx-large:20px
    - x-large:18px
    - large:17px
    - medium:14px
    - small:12px
    - x-small:10px + +具体步骤如下所示。 +1. 在卡片 JSON 代码的全局行为设置中的 `config` 字段中,配置 `style` 字段,并添加自定义字号: + +```json + { + "config": { + "style": { // 在此添加并配置 style 字段。 + "text_size": { // 分别为移动端和桌面端添加自定义字号,同时添加兜底字号。用于在组件 JSON 中设置字号属性。支持添加多个自定义字号对象。 + "cus-0": { + "default": "medium", // 在无法差异化配置字号的旧版飞书客户端上,生效的字号属性。选填。 + "pc": "medium", // 桌面端的字号。 + "mobile": "large" // 移动端的字号。 + }, + "cus-1": { + "default": "medium", // 在无法差异化配置字号的旧版飞书客户端上,生效的字号属性。选填。 + "pc": "normal", // 桌面端的字号。 + "mobile": "x-large" // 移动端的字号。 + } + } + } + } + } + ``` +1. 在普通文本组件或富文本组件的 `text_size` 属性中,应用自定义字号。以下为在普通文本组件中应用自定义字号的示例: + +```json + { + "i18n_elements": { + "zh_cn": [ + { + "tag": "column_set", + "flex_mode": "none", + "horizontal_spacing": "default", + "background_style": "default", + "columns": [ + { + "tag": "column", + "elements": [ + { + "tag": "div", + "text": { + "tag": "plain_text", + "content": "这是一段普通文本示例。", + "text_size": "cus-0", // 在此处应用自定义字号。 + "text_align": "center", + "text_color": "default" + }, + "icon": { + "tag": "standard_icon", + "token": "app-default_filled", + "color": "blue" + } + } + ], + "width": "weighted", + "weight": 1 + } + ] + } + ] + }, + "i18n_header": {} + } + ``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__rich-text.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__rich-text.md new file mode 100644 index 0000000..c557f1c --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__rich-text.md @@ -0,0 +1,290 @@ +# 富文本组件 + +卡片的富文本(Markdown)组件支持渲染表情、表格、图片、代码块、分割线等元素。 + +本文档介绍富文本组件的 JSON 1.0 结构,要查看新版 JSON 2.0 结构,参考[富文本(Markdown)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/rich-text)。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/78e939f34ac2c78858478abd301e4118_3uRxX4PiGZ.png?height=512&lazyload=true&maxWidth=300&width=800) + +## 注意事项 + +富文本组件中的标题、引用、行内引用、表格、数字角标等语法仅支持在 [JSON 2.0 结构的富文本组件](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/rich-text)中使用。 + +## 组件属性 + +### JSON 结构 + +富文本组件的完整 JSON 1.0 数据如下所示: +```json +{ + "tag": "markdown", + "text_size": "heading", // 文本大小。默认值 normal。 + "text_align": "center", // 文本对齐的方式。默认值 left。 + "icon": { + // 前缀图标。 + "tag": "standard_icon", // 图标类型。 + "token": "chat-forbidden_outlined", // 图标的 token。仅在 tag 为 standard_icon 时生效。 + "color": "orange", // 图标颜色。仅在 tag 为 standard_icon 时生效。 + "img_key": "img_v2_38811724" // 图片的 key。仅在 tag 为 custom_icon 时生效。 + }, + "href": { + // 在此处配置差异化跳转链接,声明 href 参数的变量,实现“不同设备跳转链接不同”的效果。2.0 结构不再支持该语法。 + "urlVal": { + // 变量名 + "url": "xxx", // 默认链接地址 + "pc_url": "xxx", // PC 端链接地址 + "ios_url": "xxx", // iOS 端链接地址 + "android_url": "xxx" // Android 端链接地址 + } + }, + "content": "notation字号\n标准emoji 😁😢🌞💼🏆❌✅\n*斜体*\n**粗体**\n~~删除线~~\n[差异化跳转]($urlVal)\n" // 采用 mardown 语法编写的内容。2.0 结构不再支持 "[差异化跳转]($urlVal)" 语法 +} +``` + +### 字段说明 + +富文本组件包含的参数说明如下表所示。 + +字段名称 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | String | / | 组件的标签。富文本组件固定取值为 `markdown`。 +text_align | 否 | String | left | 设置文本内容的对齐方式。可取值有:
    * left:左对齐
    * center:居中对齐
    * right:右对齐 +text_size | 否 | String | normal | 文本大小。可取值如下所示。如果你填写了其它值,卡片将展示为 `normal` 字段对应的字号。
    - heading-0:特大标题(30px)
    - heading-1:一级标题(24px)
    - heading-2:二级标题(20 px)
    - heading-3:三级标题(18px)
    - heading-4:四级标题(16px)
    - heading:标题(16px)
    - normal:正文(14px)
    - notation:辅助信息(12px)
    - xxxx-large:30px
    - xxx-large:24px
    - xx-large:20px
    - x-large:18px
    - large:16px
    - medium:14px
    - small:12px
    - x-small:10px +icon | 否 | Object | / | 添加图标作为文本前缀图标。支持自定义或使用图标库中的图标。 +└ tag | 否 | String | / | 图标类型的标签。可取值:
    - `standard_icon`:使用图标库中的图标。
    - `custom_icon`:使用用自定义图片作为图标。 +└ token | 否 | String | / | 图标库中图标的 token。当 `tag` 为 `standard_icon` 时生效。枚举值参见[图标库](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-icons)。 +└ color | 否 | String | / | 图标的颜色。支持设置线性和面性图标(即 token 末尾为 `outlined` 或 `filled` 的图标)的颜色。当 `tag` 为 `standard_icon` 时生效。枚举值参见[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。 +└ img_key | 否 | String | / | 自定义前缀图标的图片 key。当 `tag` 为 `custom_icon` 时生效。
    图标 key 的获取方式:调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口,上传用于发送消息的图片,并在返回值中获取图片的 image_key。 +href | 否 | Object | / | 配置差异化跳转链接,实现“不同设备跳转链接不同”的效果。JSON 2.0 结构不再支持该语法。 +└ urlVal | 否 | Object | / | URL 的变量。 +└ └ url | 是 | String | "https://www.baidu.com" | 默认的链接地址。 +└ └ pc_url | 否 | String | "https://developer.android.com" | PC 端的链接地址。 +└ └ ios_url | 否 | String | "https://developer.apple.com" | iOS 端的链接地址。 +└ └ android_url | 否 | String | "https://www.windows.com" | Android 端的链接地址。 +content | 是 | String | / | Markdown 文本内容。了解支持的语法,参考下文。 + +### 示例代码 + +以下的 JSON 示例代码可实现如下图所示的卡片效果: + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/78e939f34ac2c78858478abd301e4118_3uRxX4PiGZ.png?height=512&lazyload=true&maxWidth=300&width=800) + +```json +{ + "i18n_elements": { + "zh_cn": [ + { + "tag": "markdown", + "content": "标准emoji 😁😢🌞💼🏆❌✅\n飞书emoji :OK::THUMBSUP:\n*斜体* **粗体** ~~删除线~~ \n这是红色文本\n标签\n[文字链接](https://open.feishu.cn/document/home/index)\n带图标的链接\n\n- 无序列表1\n - 无序列表 1.1\n- 无序列表2\n1. 有序列表1\n 1. 有序列表 1.1\n2. 有序列表2\n```JSON\n{\"This is\": \"JSON demo\"}\n```", + "text_align": "left", + "text_size": "normal" + } + ] + } +} +``` + +## 支持的 Markdown 语法 + +[卡片 JSON 1.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-structure)仅支持 Markdown 语法的子集,详情参见下表。 + +[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)支持除 `SetextHeading`、`CodeBlock` 和 `HTMLBlock` 外所有标准的 Markdown 语法,以及部分 HTML 语法。详情参考[卡片 JSON 2.0 版本更新说明](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-breaking-changes-release-notes)。 + +名称 | 语法 | 效果 | 注意事项 +---|---|---|--- +换行 | ```
    第一行
    第二行
    第一行
    第二行
    ``` | 第一行
    第二行 | - 如果你使用卡片 JSON 构建卡片,也可使用字符串的换行语法 `\n` 换行。
    - 如果你使用卡片搭建工具构建卡片,也可使用回车键换行。 +斜体 | ```
    *斜体*
    ``` | *斜体* | 无 +加粗 | ```
    **粗体**

    __粗体__
    ``` | __粗体__ | 不要连续使用 4 个 `*` 或 `_` 加粗。该语法不规范,可能会导致渲染不正确。 +删除线 | ```
    ~~删除线~~
    ``` | ~~删除线~~ | 无 +@指定人 | ```




    ``` | @用户名 | - [自定义机器人](https://open.feishu.cn/document/ukTMukTMukTM/ucTM5YjL3ETO24yNxkjN)仅支持使用 `open_id`、`user_id` @指定人。
    - 支持使用 `` 传入多个 ID,使用 `,` 连接。
    - 了解如何获取 user_id、open_id,参考[如何获取不同的用户 ID](https://open.feishu.cn/document/home/user-identity-introduction/open-id)。 +@所有人 | ```

    ``` | @所有人 | @所有人需要群主开启权限。若未开启,卡片将发送失败。 +超链接 | ```


    ``` | [https://open.feishu.cn](https://open.feishu.cn) | 超链接必须包含 schema 才能生效,目前仅支持 HTTP 和 HTTPS。 +彩色文本样式 | ```
    这是一个绿色文本
    这是一个红色文本
    这是一个灰色文本
    ``` | ![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/3cb544894ff14bd08697aba80d8e45e6~tplv-goo7wpa0wc-image.image?height=46&lazyload=true&width=206)
    ![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/20cf2f954cc34e79b1a9083ddf1c5838~tplv-goo7wpa0wc-image.image?height=46&lazyload=true&width=200)
    ![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/4c1721ac3ea6437fb52661d0f59d5b63~tplv-goo7wpa0wc-image.image?height=40&lazyload=true&width=192) | * 彩色文本样式不支持对链接中的文本生效
    * color 取值:
    - **default**:默认的白底黑字样式
    - 卡片支持的颜色枚举值和 RGBA 语法自定义颜色。参考[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color) +可点击的电话号码 | ```
    [文本展示的电话号码或其他文案内容](tel://移动端弹窗唤起的电话号码)
    ``` | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/497e911ac70982442571a2671c7c178c_5i91YqPxhx.png?height=99&lazyload=true&width=789) | 该语法仅在移动端生效。 +文字链接 | ```
    [开放平台](https://open.feishu.cn/)
    ``` | [开放平台](https://open.feishu.cn/) | 超链接必须包含 schema 才能生效,目前仅支持 HTTP 和 HTTPS。 +差异化跳转链接 | ```
    {
    "tag": "markdown",
    "href": {
    "urlVal": {
    "url": "xxx",
    "pc_url":"xxx",
    "ios_url": "xxx",
    "android_url": "xxx"
    }
    },
    "content":
    "[差异化跳转]($urlVal)"
    }
    ``` | \- | * 超链接必须包含 schema 才能生效,目前仅支持 HTTP 和 HTTPS。
    - 仅在 PC 端、移动端需要跳转不同链接时使用。 +图片 | ```
    ![hover_text](image_key)
    ``` |   | * `hover_text` 指在 PC 端内光标悬浮(hover)图片所展示的文案。
    * **image_key** 可以调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口获取。 +分割线 | ```
    ---
    ``` | ![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/337cdbabf3944d4facd505a9f9883352~tplv-goo7wpa0wc-image.image?height=62&lazyload=true&width=346) | 分割线必须单独一行使用。即如果分割线前后有文本,你必须在分割线前后添加换行符。 +飞书表情 | ```
    :DONE:
    ``` | ![](https://sf3-ttcdn-tos.pstatp.com/obj/lark-reaction-cn/emoji_done.png?height=96&lazyload=true&width=96) | 支持的 Emoji Key 列表可以参看 [表情文案说明](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message-reaction/emojis-introduce)。 +标签 | ```
    标签文本
    ``` |   | `color`支持的枚举值范围包括:
    - `neutral`: 中性色
    - `blue`: 蓝色
    - `turquoise`: 青绿色
    - `lime`: 酸橙色
    - `orange`: 橙色
    - `violet`: 紫罗兰色
    - `indigo`: 靛青色
    - `wathet`: 天蓝色
    - `green`: 绿色
    - `yellow`: 黄色
    - `red`: 红色
    - `purple`: 紫色
    - `carmine`: 洋红色 +有序列表 | ```
    1. 有序列表1
    1. 有序列表 1.1
    2. 有序列表2
    ``` | 1. 有序列表1
    1. 有序列表 1.1
    2. 有序列表2 | * 序号需在行首使用
    * 4 个空格代表一层缩进
    **注意事项**:仅在飞书 7.6 及以上版本生效。在低版本飞书客户端中,包含该语法的 Markdown 组件将展示为升级提示占位图。 +无序列表 | ```
    - 无序列表1
    - 无序列表 1.1
    - 无序列表2
    ``` | - 无序列表1
    - 无序列表 1.1
    - 无序列表2 | * 序号需在行首使用
    * 4 个空格代表一层缩进
    **注意事项**:仅在飞书 7.6 及以上版本生效。在低版本飞书客户端中,包含该语法的 Markdown 组件将展示为升级提示占位图。 +代码块 | `````markdown
    ```JSON
    {"This is": "JSON demo"}
    ```
    ````` | ```JSON
    {"This is": "JSON demo"}
    ``` | * 代码块语法和代码内容需在行首使用
    * 支持指定编程语言解析。未指定默认为 Plain Text
    **注意事项**:仅在飞书 7.6 及以上版本生效。在低版本飞书客户端中,包含该语法的 Markdown 组件将展示为升级提示占位图。 +含图标的链接 | ```
    战略研讨会
    ``` | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/e6b63f8c225ce6c4cd09dbdc8158397f_HPk70nRLtr.png?height=97&lazyload=true&width=736) | 该语法中的字段说明如下所示:
    - `icon`:链接前缀的图标。仅支持图标库中的图标,枚举值参见[图标库](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-icons)。图标颜色固定为蓝色。可选。
    - `url`:默认的链接地址,未按设备配置下述字段时,该配置生效。必填。
    - `pc_url`:pc 端的链接地址,优先级高于 `url`。可选。
    - `ios_url`:ios 端的链接地址,优先级高于 `url`。可选。
    - `android_url`:android 端的链接地址,优先级高于 `url`。可选。
    **注意事项**:图标仅在飞书 7.12 及以上版本生效。 +人员 | `````markdown

    ````` | ![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/85c9e79807d0195cd3ecb331a965f418_eFVjQrqRjv.png?height=95&lazyload=true&width=736) | 该语法中的字段说明如下所示:
    - `id`:用户的 ID,支持 open_id、union_id 和 user_id。不填、为空、数据错误时展示为兜底的“未知用户”样式。了解更多,参考[如何获取不同的用户 ID](https://open.feishu.cn/document/home/user-identity-introduction/open-id)。
    - `show_name`:是否展示用户名。默认为 true。
    - `show_avatar`:是否展示用户头像,默认为 true。
    - `style`:人员组件的展示样式。可选值有:
    - `normal`:普通样式(默认)
    - `capsule`:胶囊样式 + +### 特殊字符转义说明 +如果要展示的字符命中了 markdown 语法使用的特殊字符(例如 `*、~、>、<` 这些特殊符号),需要对特殊字符进行 HTML 转义,才可正常展示。常见的转义符号对照表如下所示。查看更多转义符,参考 [HTML 转义通用标准](https://www.w3school.com.cn/charsets/ref_html_8859.asp)实现,转义后的格式为 `&#实体编号;`。 + +| **特殊字符** | **转义符** | **描述** | +| --- | --- | --- | +| ` ` | `  ` | 不换行空格 | +| ` ` | ` ` | 半角空格 | +| ` ` | ` ` | 全角空格 | +| `>` | `>` | 大于号 | +| `<` | `<` | 小于号 | +| `~` | `∼` | 飘号 | +| `-` | `-` | 连字符 | +| `!` | `!` | 惊叹号 | +| `*` | `*` | 星号 | +| `/` | `/` | 斜杠 | +| `\` | `\` | 反斜杠 | +| `[` | `[` | 中括号左边部分 | +| `]` | `]` | 中括号右边部分 | +| `(` | `(` | 小括号左边部分 | +| `)` | `)` | 小括号右边部分 | +| `#` | `#` | 井号 | +| `:` | `:` | 冒号 | +| `+` | `+` | 加号 | +| `"` | `"` | 英文引号 | +| `'` | `'` | 英文单引号 | +| \` | ``` | 反单引号 | +| `$` | `$` | 美金符号 | +| `_` | `_` | 下划线 | +| `-` | `-` | 无序列表 | + +### 代码块支持的编程语言 + +富文本组件支持通过代码块语法渲染代码,支持的编程语言如下列表所示,且对大小写不敏感: +`````markdown +```JSON +{"This is": "JSON demo"} +``` +````` +- plain_text +- abap +- ada +- apache +- apex +- assembly +- bash +- c_sharp +- cpp +- c +- cmake +- cobol +- css +- coffee_script +- d +- dart +- delphi +- diff +- django +- docker_file +- erlang +- fortran +- gherkin +- go +- graphql +- groovy +- html +- htmlbars +- http +- haskell +- json +- java +- javascript +- julia +- kotlin +- latex +- lisp +- lua +- matlab +- makefile +- markdown +- nginx +- objective_c +- opengl_shading_language +- php +- perl +- powershell +- prolog +- properties +- protobuf +- python +- r +- ruby +- rust +- sas +- scss +- sql +- scala +- scheme +- shell +- solidity +- swift +- toml +- thrift +- typescript +- vbscript +- visual_basic +- xml +- yaml +## 为移动端和桌面端定义不同的字号 + +在普通文本组件和富文本组件中,你可为同一段文本定义在移动端和桌面端的不同字号。相关字段描述如下表所示。 + +字段 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +text_size | 否 | Object | / | 文本大小。你可在此自定义移动端和桌面端的不同字号。 +└ custom_text_size_name | 否 | Object | / | 自定义的字号。你需自定义该字段的名称,如 `cus-0`、`cus-1` 等。 +└└ default | 否 | String | / | 在无法差异化配置字号的旧版飞书客户端上,生效的字号属性。建议填写此字段。可取值如下所示。
    - heading-0:特大标题(30px)
    - heading-1:一级标题(24px)
    - heading-2:二级标题(20 px)
    - heading-3:三级标题(18px)
    - heading-4:四级标题(16px)
    - heading:标题(16px)
    - normal:正文(14px)
    - notation:辅助信息(12px)
    - xxxx-large:30px
    - xxx-large:24px
    - xx-large:20px
    - x-large:18px
    - large:16px
    - medium:14px
    - small:12px
    - x-small:10px +└└ pc | 否 | String | / | 桌面端的字号。可取值如下所示。
    - heading-0:特大标题(30px)
    - heading-1:一级标题(24px)
    - heading-2:二级标题(20 px)
    - heading-3:三级标题(18px)
    - heading-4:四级标题(16px)
    - heading:标题(16px)
    - normal:正文(14px)
    - notation:辅助信息(12px)
    - xxxx-large:30px
    - xxx-large:24px
    - xx-large:20px
    - x-large:18px
    - large:16px
    - medium:14px
    - small:12px
    - x-small:10px +└└ mobile | 否 | String | / | 移动端的文本字号。可取值如下所示。
    **注意**:部分移动端的字号枚举值的具体大小与 PC 端有差异,使用时请注意区分。
    - heading-0:特大标题(26px)
    - heading-1:一级标题(24px)
    - heading-2:二级标题(20 px)
    - heading-3:三级标题(17px)
    - heading-4:四级标题(16px)
    - heading:标题(16px)
    - normal:正文(14px)
    - notation:辅助信息(12px)
    - xxxx-large:26px
    - xxx-large:24px
    - xx-large:20px
    - x-large:18px
    - large:17px
    - medium:14px
    - small:12px
    - x-small:10px + +具体步骤如下所示。 +1. 在卡片 JSON 代码的全局行为设置中的 `config` 字段中,配置 `style` 字段,并添加自定义字号: + ```json + { + "config": { + "style": { // 在此添加并配置 style 字段。 + "text_size": { // 分别为移动端和桌面端添加自定义字号,同时添加兜底字号。用于在组件 JSON 中设置字号属性。支持添加多个自定义字号对象。 + "cus-0": { + "default": "medium", // 在无法差异化配置字号的旧版飞书客户端上,生效的字号属性。选填。 + "pc": "medium", // 桌面端的字号。 + "mobile": "large" // 移动端的字号。 + }, + "cus-1": { + "default": "medium", // 在无法差异化配置字号的旧版飞书客户端上,生效的字号属性。选填。 + "pc": "normal", // 桌面端的字号。 + "mobile": "x-large" // 移动的字号。 + } + } + } + } + } + ``` +1. 在普通文本组件或富文本组件的 `text_size` 属性中,应用自定义字号。以下为在富文本组件中应用自定义字号的示例: + ```json + { + "elements": [ + { + "tag": "markdown", + "text_size": "cus-0", // 在此处应用自定义字号。 + "href": { + "urlVal": { + "url": "xxx1", + "pc_url": "xxx2", + "ios_url": "xxx3", + "android_url": "xxx4" + } + }, + "content": "普通文本\n标准emoji😁😢🌞💼🏆❌✅\n*斜体*\n**粗体**\n~~删除线~~\n文字链接\n差异化跳转\n" + }, + { + "tag": "hr" + }, + { + "tag": "markdown", + "content": "上面是一行分割线\n!hover_text\n上面是一个图片标签" + } + ], + "header": { + "template": "blue", + "title": { + "content": "这是卡片标题栏", + "tag": "plain_text" + } + } + } + ``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__table.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__table.md new file mode 100644 index 0000000..e784e32 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__table.md @@ -0,0 +1,358 @@ +# 表格组件 + +飞书卡片支持表格组件,并支持在表格中添加普通文本、富文本、选项标签、数字、人员列表、日期类型的内容。 + +本文档介绍表格组件的 JSON 1.0 结构,要查看新版 JSON 2.0 结构,参考[表格](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/table)。 + +![20240704120326_rec_.gif](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/0b621b9ae52f1106965dcfb022ffcb4b_CPQQAR3e0e.gif?height=392&lazyload=true&maxWidth=434&width=772) + +## 注意事项 + +- 表格组件支持飞书 V7.4 及以上版本的客户端。在低于该版本的飞书客户端上,表格的内容将展示为一句“请升级客户端为最新版本后查看内容”的占位图。 +- 单张卡片最多支持放置五个表格组件。若卡片配置了多语言,则单个语言最多支持放置五个表格组件。 +- 当单元格内剩余空间无法完整展示内容时,末尾将省略。在客户端,用户可通过光标悬浮或点击的方式查看被省略的内容。 + +## 嵌套规则 + +- 表格组件不可被内嵌在其它组件内,只可放在卡片根节点下。 +- 表格组件不支持内嵌其它组件。 + +## 组件属性 + +### JSON 结构 + +表格组件的完整 JSON 数据如下所示: +```json +// 7.4 支持 +{ + "tag": "table", // 组件的标签。表格组件的固定取值为 table。 + "page_size": 5, // 每页最大展示的数据行数。支持[1,10]整数。默认值 5。 + "row_height": "low", // 行高设置。默认值 low。 + "freeze_first_column": true, //是否冻结首列,默认 false。 + "header_style": { + // 在此设置表头。 + "text_align": "left", // 文本对齐方式。默认值 left。 + "text_size": "normal", // 字号。默认值 normal。 + "background_style": "none", // 背景色。默认值 none。 + "text_color": "grey", // 文本颜色。默认值 default。 + "bold": true, // 是否加粗。默认值 true。 + "lines": 1 // 文本行数。默认值 1。 + }, + "columns": [ // 在此添加列。最多支持添加 50 列,超出 50 列的内容不展示。 + { // 添加列,列的数据类型为不带格式的普通文本。 + "name": "customer_name", // 自定义列的标记。必填。用于唯一指定行数据对象数组中,需要将数据填充至这一行的具体哪个单元格中。 + "display_name": "客户名称", // 列名称。为空时不展示列名称。 + "width": "auto", // 列宽。默认值 auto。 + "data_type": "text", // 列的数据类型。 + "vertical_align": "top", // 列内数据垂直对齐方式。默认值 center。 + "horizontal_align": "left" // 列内数据水平对齐方式。默认值 left。 + }, + { // 添加列,列的数据类型为 lark_md 文本。 + "name": "customer_link", + "display_name": "相关链接", + "data_type": "lark_md" + }, + { // 添加类型为数字的列。 + "name": "customer_arr", + "display_name": "ARR(万元)", + "data_type": "number", + "format": { // 列的数据类型为 number 时的字段配置。 + "symbol": "¥", // 数字前展示的货币单位。支持 1 个字符的货币单位文本。可选。 + "precision": 2, // 数字的小数点位数。支持 [0,10] 的整数。默认不限制小数点位数。 + "separator": true // 是否生效按千分位逗号分割的数字样式。默认值 false。 + }, + "width": "120px" + }, + { // 添加类型为选项的列。 + "name": "customer_scale", + "display_name": "客户规模", + "data_type": "options" + }, + { // 添加类型为人员的列。 + "name": "customer_poc", + "display_name": "客户对接人", + "data_type": "persons" + }, + { // 添加类型为日期的列。 + "name": "meeting_date", + "display_name": "对接时间", + "data_type": "date", + "date_format": "YYYY/MM/DD" + }, + { // 添加类型为 markdown 文本的列。 + "name": "company_image", + "display_name": "企业图片", + "data_type": "markdown" + } + ], + "rows": [ // 在此添加与列定义对应的行数据。用 "name":VALUE 的形式,定义每一行的数据内容。name 即你自定义的列标记。 + { + "customer_name": "飞书科技", + "customer_date": 1699341315000, + "customer_scale": [ + { + "text": "S2", + "color": "blue" + } + ], + "customer_arr": 168, + "customer_poc": [ + "ou_14a32f1a02e64944cf19207aa43abcef", + "ou_e393cf9c22e6e617a4332210d2aabcef" + ], + "customer_link": "[飞书科技](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message-reaction/emojis-introduce)" + }, + { + "customer_name": "飞书科技_01", + "customer_date": 1606101072000, + "customer_scale": [ + { + "text": "S1", + "color": "red" + } + ], + "customer_arr": 168.23, + "customer_poc": "ou_14a32f1a02e64944cf19207aa43abcef", + "customer_link": "[飞书科技_01](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message-reaction/emojis-introduce)", + "company_image": "![image.png](image_key)" + }, + { + "customer_name": "飞书科技_02", + "customer_date": 1606101072000, + "customer_scale": [ + { + "text": "S3", + "color": "orange" + } + ], + "customer_arr": 168.23, + "customer_poc": "ou_14a32f1a02e64944cf19207aa43abcef", + "customer_link": "[飞书科技_02](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message-reaction/emojis-introduce)", + "company_image": "![image.png](image_key)" + +}, + { + "customer_name": "飞书科技_03", + "customer_date": 1606101072000, + "customer_scale": [ + { + "text": "S2", + "color": "blue" + } + ], + "customer_arr": 168.23, + "customer_poc": "ou_14a32f1a02e64944cf19207aa43abcef", + "customer_link": "[飞书科技_03](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message-reaction/emojis-introduce)", + "company_image": "![image.png](image_key)" + } + ] +} +``` + +### 字段说明 + +表格组件的字段说明如下表。 + +字段 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | String | / | 组件的标签。表格组件的固定取值为 `table`。 +page_size | 否 | Number | 5 | 每页最大展示的数据行数。支持 [1,10] 整数。 +row_height | 否 | String | low | 表格的行高。单元格高度如无法展示一整行内容,则上下裁剪内容。可取值:
    - low:低
    - middle:中
    - high:高
    - [32,124]px:自定义行高,单位为像素,如 40px。取值范围是 [32,124] +header_style | 否 | header_style | / | 表头样式风格。详见下方 `header_style` 字段说明。 +freeze_first_column | 否 | Boolean | false | 是否冻结首列。可取值:
    - true:冻结首列。即左右滚动表格时不滚动首列,其余列叠加展示在首列底下
    - false:不冻结首列。即左右滚动表格时所有表格均做滚动 +columns | 是 | column[] | [] | 列对象数组。详见下方 `column` 字段说明。 +rows | 是 | JSON | [] | 行对象数组。与列定义对应的数据。用 `"name":VALUE` 的形式,定义每一行的数据内容。`name`即你自定义的列标记。 + +#### `header_style` 字段说明 + +`header_style` 用于设置表头的样式、风格等。`header_style` 的子字段如下表所示。 + +字段 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +text_align | 否 | String | left | 表头文本对齐方式。可取值:
    - left:左对齐
    - center:居中对齐
    - right:右对齐 +text_size | 否 | String | normal | 表头文本大小。可取值:
    - normal:正文(14px)
    - heading:标题(16px) +background_style | 否 | String | none | 表头背景色。可取值:
    - grey:灰色
    - none:无背景色 +text_color | 否 | String | default | 文本颜色。可取值:
    - default:客户端浅色主题模式下为黑色;客户端深色主题模式下为白色
    - grey:灰色 +bold | 否 | Boolean | true | 表头文本是否加粗。可取值:
    - true:加粗
    - false:不加粗 +lines | 否 | Number | 1 | 表头文本的行数。支持大于等于 1 的整数。 + +#### **`column`** **字段说明** + +`column` 用于定义表格的列。最多支持添加 50 列,超出 50 列的内容不展示。 + +字段 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +name | 是 | String | 空 | 自定义列的标记。用于唯一指定行数据对象数组中,需要将数据填充至这一行的具体哪个单元格中。 +display_name | 否 | String | 空 | 在表头展示的列名称。不填或为空则不展示列名称。 +width | 否 | String | auto | 列宽度。可取值:
    - auto:自适应内容宽度
    - 自定义宽度:自定义表格的列宽度,如 120px。取值范围是 [80px,600px] 的整数
    - 自定义宽度百分比:自定义列宽度占当前表格画布宽度的百分比(表格画布宽度 = 卡片宽度-卡片左右内边距),如 25%。取值范围是 [1%,100%] +vertical_align | 否 | String | center | 列内数据垂直对齐方式。可选值:
    - top:顶部对齐
    - center:中间对齐
    - bottom:底部对齐 +horizontal_align | 否 | String | left | 列内数据水平对齐方式。可选值:
    - left:左对齐
    - center:居中对齐
    - right:右对齐 +data_type | 是 | String | text | 列数据类型。可选值如下所示。了解不同类型用法,参考 `data_type` 字段说明一节。
    - text:不带格式的普通文本。为 `data_type` 默认值。
    - lark_md:支持部分 markdown 格式的文本。飞书 v7.10 及之后版本支持。详情参考[普通文本-lark_md 支持的 Markdown 语法](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/plain-text)
    - options:选项标签。标签中的文本内容不可过长,否则可能会导致 PC 端或移动端内容显示不完整。如果文本过长,可使用 text 或者 lark_md 类型
    - number:数字。默认在单元格中右对齐展示。若选择该数据类型,你可继续在 `column` 中添加 `format` 字段,设置数字的格式属性
    - persons:人员列表。为用户名称+头像样式
    - date:日期时间。需输入 Unix 标准毫秒级时间戳,飞书客户端将按用户本地时区展示日期时间。飞书 v7.6 及之后版本支持
    - markdown:支持完整 Markdown 语法的文本内容。详情参考[富文本(Markdown)组件](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/rich-text)。飞书 v7.14 及之后版本支持 +format | 否 | Object | / | 该字段仅当 `data_type` 为 `number` 时生效,你可以在该字段内选择设置小数点位数、货币单位以及千分位样式。 +└ precision | 否 | Int | 空 | 数字的小数点位数。默认不限制小数点位数,原样透传展示开发者输入的数字。可填 0~10 的整数。小数点位数为 0 表示取整数。 +└ symbol | 否 | String | 空 | 数字前的货币单位。不填或为空不展示。可填 1 个字符的货币单位文本,如 “¥”。 +└ separator | 否 | Boolean | false | 是否生效按千分位逗号分割的数字样式。 +date_format | 否 | String | 空 | 该字段仅当 `data_type` 为 `date` 时生效。你可按需选择以下日期时间占位符,并使用任意分隔符组合。
    - YYYY:年
    - MM:月
    - DD:日
    - HH:小时
    - mm:分钟
    - ss:秒
    推荐使用以下日期格式。默认按 RFC 3339 标准格式展示日期时间。
    - YYYY/MM/DD
    - YYYY/MM/DD HH:mm
    - YYYY-MM-DD
    - YYYY-MM-DD HH:mm
    - DD/MM/YYYY
    - MM/DD/YYYY + +#### `data_type` 字段说明 + +`data_type` 用于指定列的数据类型。`data_type` 支持的枚举值及详细说明如下所示。 + +data_type 枚举 | 支持版本 | 描述 | 对应行的数据结构与示例 +---|---|---|--- +text | 飞书 v7.4 及以上 | 不带格式的普通文本。为 data_type 默认值。 | 结构:
    ```json
    "name":"plain text" // 不填或为空时展示空单元格,非字符串类型转换为字符串展示
    ```
    示例:
    ```json
    "business_domain_name": "飞书卡片"
    ``` +lark_md | 飞书 v7.10 及以上 | 支持部分 markdown 格式的文本。详情参考[普通文本-lark_md 支持的 Markdown 语法](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/plain-text)。 | 结构:
    ```json
    "name":"[文字链接](https://www.feishu.cn)" // 不填或为空时展示空单元格,非字符串类型转换为字符串展示
    ```
    示例:
    ```json
    "customer_link": "[飞书科技_01](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message-reaction/emojis-introduce)"
    ``` +options | 飞书 v7.4 及以上 | 选项标签。支持使用 color 参数自定义标签颜色。color 枚举值及展示效果如下所示。默认值为 blue。
    **注意**:标签中的文本内容不可过长,否则可能会导致 PC 端或移动端内容显示不完整。如果文本过长,可使用 text 或者 lark_md 类型。
    ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/7dce9769aa1475bb36bada6533775403_nCnDT2EAmq.png?height=494&lazyload=true&width=1722) | 结构:
    ```json
    // 支持仅展示一个默认样式的标签
    "name":"option"
    // 支持展示多个自定义样式的标签
    "name":[
    {
    "text":"option 1",
    "color":"red"
    },
    {
    "text":"option 2",
    "color":"green"
    }
    ]
    ```
    示例:
    ```json
    "customer_scale": [
    {
    "text": "S2",
    "color": "green"
    }
    ]
    ``` +number | 飞书 v7.4 及以上 | 数字。默认在单元格中右对齐展示。支持添加 format 字段,设置数字的格式属性。详情参考 format 字段说明。 | 结构:
    ```json
    "name":NUMBER
    ```
    示例:
    ```json
    "customer_arr": 26.57774928467545
    ``` +persons | 飞书 v7.4 及以上 | 人员列表。为用户名称+头像样式。支持传入用户 ID 指定人员,用户 ID 类型可以是 user_id、open_id、union_id和 lark_id。了解更多 ID 相关信息,参考[用户身份概述](https://open.feishu.cn/document/home/user-identity-introduction/introduction)。
    **注意**:当用户 ID 无效时,将展示“未知用户”样式。 | 结构:
    ```json
    "name":[
    "user_id_1",
    "user_id_2",

    ] //展示多人员

    "name":"user_id" //展示单人员
    ```
    示例:
    ```json
    "customer_name": "ou_c99c5f35d542efc7ee492afe11af19ef"
    ``` +date | 飞书 v7.6 及以上 | 日期时间。需输入 Unix 标准毫秒级时间戳,飞书客户端将按用户本地时区展示日期时间。
    支持添加 date_format 字段,设置日期的格式属性。默认按 RFC 3339 标准格式展示日期时间。详情参考 date_format 字段说明。 | 结构:
    ```json
    name":NUMBER
    ```
    示例:
    ```json
    "customer_date": 1606101072000 // 毫秒级时间戳
    ``` +markdown | 飞书 v7.14 及以上 | 支持完整 Markdown 语法的文本内容。详情参考[富文本(Markdown)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/rich-text)组件。 | 结构:
    ```json
    "name":"markdown text" // 不填或为空时展示空单元格,非字符串类型转换为字符串展示
    ```
    示例:
    ```json
    "company_image": "![image.png](img_v3_02cc_bf88cdee-6650-4b39-987c-f8e87c3227fg)"
    ``` + +## 示例代码 + +以下的 JSON 示例代码可实现如下图所示的卡片效果。 + +![20240704120326_rec_.gif](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/0b621b9ae52f1106965dcfb022ffcb4b_EI5Extg7gI.gif?height=392&lazyload=true&maxWidth=434&width=772) + +```json +{ + "header": { + "template": "blue", + "title": { + "content": "表格组件(依赖端版本 7.4+)", + "tag": "plain_text" + } + }, + "elements": [ + { + "tag": "table", + "page_size": 5, + "row_height": "low", + "header_style": { + "text_align": "left", + "text_size": "normal", + "background_style": "none", + "text_color": "grey", + "bold": true, + "lines": 1 + }, + "columns": [ + { + "name": "customer_name", + "display_name": "客户名称", + "data_type": "text", + "horizontal_align": "left", + "vertical_align": "top", + "width": "auto" + }, + { + "name": "customer_scale", + "display_name": "客户规模", + "data_type": "options", + "horizontal_align": "left", + "vertical_align": "top", + "width": "auto" + }, + { + "name": "customer_arr", + "display_name": "ARR(万元)", + "data_type": "number", + "format": { + "symbol": "¥", + "precision": 2, + "separator": true + }, + "width": "auto" + }, + { + "name": "customer_poc", + "display_name": "跟进人", + "data_type": "persons", + "horizontal_align": "left", + "vertical_align": "top", + "width": "auto" + }, + { + "name": "customer_date", + "display_name": "签约日期", + "data_type": "date", + "date_format": "YYYY/MM/DD", + "width": "auto" + }, + { + "name": "customer_link", + "display_name": "相关链接", + "data_type": "lark_md", + "width": "auto" + }, + { + "name": "company_image", + "display_name": "企业图片", + "data_type": "markdown" + } + ], + "rows": [ + { + "customer_name": "飞书科技", + "customer_date": 1699341315000, + "customer_scale": [ + { + "text": "S2", + "color": "blue" + } + ], + "customer_arr": 168, + "customer_poc": [ + "ou_14a32f1a02e64944cf19207aa43abcef", + "ou_e393cf9c22e6e617a4332210d2aabcef" + ], + "customer_link": "[飞书科技](/document-mod/index?fullPath=/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message-reaction/emojis-introduce)", + "company_image": "![image.png](img_v3_02cc_bf88cdee-6650-4b39-987c-f8e87c3227fg)" + }, + { + "customer_name": "飞书科技_01", + "customer_date": 1606101072000, + "customer_scale": [ + { + "text": "S1", + "color": "red" + } + ], + "customer_arr": 168.23, + "customer_poc": "ou_14a32f1a02e64944cf19207aa43abcef", + "customer_link": "[飞书科技_01](/document-mod/index?fullPath=/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message-reaction/emojis-introduce)", + "company_image": "![image.png](img_v3_02cc_bf88cdee-6650-4b39-987c-f8e87c3227fg)" + }, + { + "customer_name": "飞书科技_02", + "customer_date": 1606101072000, + "customer_scale": [ + { + "text": "S3", + "color": "orange" + } + ], + "customer_arr": 168.23, + "customer_poc": "ou_14a32f1a02e64944cf19207aa43abcef", + "customer_link": "[飞书科技_02](/document-mod/index?fullPath=/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message-reaction/emojis-introduce)", + "company_image": "![image.png](img_v3_02cc_bf88cdee-6650-4b39-987c-f8e87c3227fg)" + }, + { + "customer_name": "飞书科技_03", + "customer_date": 1606101072000, + "customer_scale": [ + { + "text": "S2", + "color": "blue" + } + ], + "customer_arr": 168.23, + "customer_poc": "ou_14a32f1a02e64944cf19207aa43abcef", + "customer_link": "[飞书科技_03](/document-mod/index?fullPath=/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message-reaction/emojis-introduce)", + "company_image": "![image.png](img_v3_02cc_bf88cdee-6650-4b39-987c-f8e87c3227fg)" + } + ] + } + ] +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__title.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__title.md new file mode 100644 index 0000000..f186882 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__title.md @@ -0,0 +1,255 @@ +# 标题组件 + +卡片的标题组件支持添加卡片主标题、副标题、后缀标签和标题图标。 + +本文档介绍标题组件的 JSON 1.0 结构,要查看新版 JSON 2.0 结构,参考[标题](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/title)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/e25a93c55a2992fb15573246ccf5d12d_tOm7v3g7k3.png?height=231&lazyload=true&maxWidth=500&width=1099) + +## 注意事项 + +同一张卡片仅支持添加一个标题组件。 + +## 组件属性 + +### JSON 结构 + +标题的完整 JSON 数据如下所示: + +```json +{ + "header": { + "title": { + // 卡片主标题。必填。 + "tag": "plain_text", // 文本类型的标签。可选值:plain_text 和 lark_md。 + "content": "示例标题", // 主标题内容。 + "i18n": { + // 多语言标题内容。必须配置 content 或 i18n 两个属性的其中一个。如果同时配置仅生效 i18n。 + "zh_cn": "", + "en_us": "", + "ja_jp": "", + "zh_hk": "", + "zh_tw": "" + } + }, + "subtitle": { + // 卡片副标题。可选。 + "tag": "plain_text", // 文本类型的标签。可选值:plain_text 和 lark_md。 + "content": "示例文本", // 副标题内容。 + "i18n": { + // 多语言副标题内容。必须配置 content 或 i18n 两个属性的其中一个。如果同时配置仅生效 i18n。 + "zh_cn": "", + "en_us": "", + "ja_jp": "", + "zh_hk": "", + "zh_tw": "" + } + }, + "text_tag_list": [ + // 标题后缀标签,最多设置 3 个 标签,超出不展示。可选。 + { + "tag": "text_tag", + "text": { + // 标签内容 + "tag": "plain_text", + "content": "标签 1" + }, + "color": "neutral" // 标签颜色 + } + ], + "i18n_text_tag_list": { + // 国际化标题后缀标签。每个语言环境最多设置 3 个 tag,超出不展示。可选。同时配置原字段和国际化字段,优先生效国际化配置。 + "zh_cn": [], + "en_us": [], + "ja_jp": [], + "zh_hk": [], + "zh_tw": [] + }, + "template": "blue", // 标题主题颜色。支持 "blue"|"wathet"|"turquoise"|"green"|"yellow"|"orange"|"red"|"carmine"|"violet"|"purple"|"indigo"|"grey"|"default"。默认值 default。 + "icon": { + // 自定义前缀图标 + "img_key": "img_v2_38811724" // 用作前缀图标的图片 key + }, + "ud_icon": { + // 图标库中的前缀图标,和 icon 同时设置时以 ud_icon 为准 + "token": "chat-forbidden_outlined", // 图标的 token + "style": { + "color": "red" // 图标颜色。支持设置线性和面性图标(即 token 末尾为 `outlined` 或 `filled` 的图标)的颜色。 + } + } + } +} +``` + +### 字段说明 + +标题组件的字段说明如下表。 + +字段名称 | 是否必填 | 类型 | 说明 +---|---|---|--- +title | 是 | Object | 配置卡片的主标题信息。 +└ tag | 是 | String | 文本类型的标签。可取值:
    - `plain_text`:普通文本内容或[表情](https://www.feishu.cn/docx/doxcnG6utI72jB4eHJF1s5IgVJf)
    - `lark_md`:支持以下 Markdown 语法的文本内容:
    - @指定人:
    ```




    ```
    - @所有人:``
    - emoji:😁😢🌞💼🏆❌✅。直接复制表情即可。了解更多 emoji 表情,参考 [Emoji 表情符号大全](https://www.feishu.cn/docx/doxcnG6utI72jB4eHJF1s5IgVJf)。
    - 飞书表情:如 `:OK:`。参考[表情文案说明](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message-reaction/emojis-introduce)。 +└ content | 否 | String | 卡片主标题内容。注意:
    - 必须配置 content 或 i18n 两个属性的其中一个。如果同时配置仅生效 i18n。
    - 主标题内容最多四行,超出四行的内容用 `...` 省略。 +└ i18n | 否 | Object | 多语言标题内容,支持设置的多语言枚举值如下:
    - zh_cn:简体中文
    - en_us:英文
    - ja_jp:日文
    - zh_hk:繁体中文(中国香港)
    - zh_tw:繁体中文(中国台湾)
    - id_id: 印尼语
    - vi_vn: 越南语
    - th_th: 泰语
    - pt_br: 葡萄牙语
    - es_es: 西班牙语
    - ko_kr: 韩语
    - de_de: 德语
    - fr_fr: 法语
    - it_it: 意大利语
    - ru_ru: 俄语
    - ms_my: 马来语
    示例配置:
    ```json
    {
    "zh_cn": "这是主标题",
    "en_us": "It is the title"
    }
    ```
    注意:
    - 必须配置 content 或 i18n 两个属性的其中一个。如果同时配置仅生效 i18n。
    - 主标题内容最多四行,超出四行的内容用 `...` 省略。 +subtitle | 否 | Object | 配置卡片的副标题信息。
    **注意**:不允许只配置副标题内容。如果只配置副标题,则实际展示为主标题效果。 +└ tag | 是 | String | 文本类型的标签。可取值:
    - `plain_text`:普通文本内容或[表情](https://www.feishu.cn/docx/doxcnG6utI72jB4eHJF1s5IgVJf)
    - `lark_md`:支持以下 Markdown 语法的文本内容:
    - @指定人:
    ```




    ```
    - @所有人:``
    - emoji:😁😢🌞💼🏆❌✅。直接复制表情即可。了解更多 emoji 表情,参考 [Emoji 表情符号大全](https://www.feishu.cn/docx/doxcnG6utI72jB4eHJF1s5IgVJf)。
    - 飞书表情:如 `:OK:`。参考[表情文案说明](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message-reaction/emojis-introduce)。 +└ content | 否 | String | 卡片副标题内容。注意:
    - 必须配置 content 或 i18n 两个属性的其中一个。如果同时配置仅生效 i18n。
    - 副标题内容最多一行,超出一行的内容用 `...` 省略。 +└ i18n | 否 | Object | 多语言标题内容,支持设置的多语言枚举值如下:
    - zh_cn:简体中文
    - en_us:英文
    - ja_jp:日文
    - zh_hk:繁体中文(中国香港)
    - zh_tw:繁体中文(中国台湾)
    - id_id: 印尼语
    - vi_vn: 越南语
    - th_th: 泰语
    - pt_br: 葡萄牙语
    - es_es: 西班牙语
    - ko_kr: 韩语
    - de_de: 德语
    - fr_fr: 法语
    - it_it: 意大利语
    - ru_ru: 俄语
    - ms_my: 马来语
    示例配置:
    ```json
    {
    "zh_cn": "这是副标题",
    "en_us": "It is the sub-title"
    }
    ```
    注意:
    - 必须配置 content 或 i18n 两个属性的其中一个。如果同时配置仅生效 i18n。
    - 副标题内容最多一行,超出一行的内容用 `...` 省略。 +text_tag_list | 否 | TextTagList | 添加标题的后缀标签。最多可添加 3 个标签内容,如果配置的标签数量超过 3 个,则取前 3 个标签进行展示。标签展示顺序与数组顺序一致。
    **注意**:
    - 标题标签在飞书 V6.11 及以上版本开始生效。在旧版本客户端内将不会展示标题标签内容。
    - `text_tag_lis`t 和 `i18n_text_tag_list` 只能配置其中之一。如果同时配置仅生效 `i18n_text_tag_list`。 +└ tag | 是 | String | 后缀标签的标识。固定取值:text_tag。 +└ text | 否 | Text Object | 后缀标签的内容。基于文本组件的 plain_text 模式定义内容。
    示例值:
    ```JSON
    "text": {
    "tag": "plain_text",
    "content": "这里是标签"
    }
    ``` +└ color | 否 | String | 后缀标签的颜色,默认为蓝色(blue)。可选值与示例效果参见下文的后缀标签颜色枚举。 +i18n_text_tag_list | 否 | Object | 配置后缀标签的多语言属性,在所需语种字段下添加完整的后缀标签结构体即可。每个语言最多可配置 3 个标签内容,如果配置的标签数量超过 3 个,则取前 3 个标签进行展示。标签展示顺序与数组顺序一致。支持设置的多语言枚举值如下:
    - zh_cn:简体中文
    - en_us:英文
    - ja_jp:日文
    - zh_hk:繁体中文(中国香港)
    - zh_tw:繁体中文(中国台湾)
    - id_id: 印尼语
    - vi_vn: 越南语
    - th_th: 泰语
    - pt_br: 葡萄牙语
    - es_es: 西班牙语
    - ko_kr: 韩语
    - de_de: 德语
    - fr_fr: 法语
    - it_it: 意大利语
    - ru_ru: 俄语
    - ms_my: 马来语
    示例配置:
    ```json
    "i18n_text_tag_list": {
    "zh_cn": [
    {
    "tag": "text_tag",
    "text": {
    "tag": "plain_text",
    "content": "标签内容"
    },
    "color": "carmine"
    }
    ],
    "en_us": [
    {
    "tag": "text_tag",
    "text": {
    "tag": "plain_text",
    "content": "Tag content"
    },
    "color": "carmine"
    }
    ]
    }
    ```
    **注意**:
    - 标题标签在飞书 V6.11 及以上版本开始生效。在旧版本客户端内将不会展示标题标签内容。
    - `text_tag_list` 和 `i18n_text_tag_list` 只能配置其中之一。如果同时配置两个字段,则优先生效多语言配置。 +template | 否 | String | 配置标题主题颜色。可选值与示例效果参见下文的标题主题样式枚举。 +icon | 否 | Object | 通过上传图片,自定义标题的前缀图标。
    **注意**:
    一个卡片仅可配置一个标题图标。如果同时配置 `icon` 和 `ud_icon`,仅生效 `ud_icon`。 +└ img_key | 否 | String | 自定义前缀图标的图片 key。
    图标 key 的获取方式:调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create))接口,上传用于发送消息的图片,并在返回值中获取图片的 image_key。 +ud_icon | 否 | Object | 添加图标库中已有的图标。
    **注意**:一个卡片仅可配置一个标题图标。如果同时配置 `icon` 和 `ud_icon`,仅生效 `ud_icon`。 +└ token | 否 | String | 图标库中图标的 token。枚举值参见[图标库](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-icons)。 +└ style | 否 | Object | 图标的样式。支持自定义图标颜色。 +└└ color | 否 | String | 图标的颜色。支持设置线性和面性图标(即 token 末尾为 `outlined` 或 `filled` 的图标)的颜色。默认为 `template` 字段设置的颜色。枚举值参见[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。
    **注意**:搭建工具暂不支持自定义图标颜色。 + +### 示例代码 + +以下的 JSON 示例代码可实现如下图所示的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/e25a93c55a2992fb15573246ccf5d12d_EMKfJRUbvN.png?height=231&lazyload=true&maxWidth=500&width=1099) + +```json +{ + "config": {}, + "card_link": { + "url": "", + "pc_url": "", + "ios_url": "", + "android_url": "" + }, + "i18n_elements": { + "zh_cn": [ + { + "tag": "column_set", + "flex_mode": "none", + "horizontal_spacing": "default", + "background_style": "default", + "columns": [ + { + "tag": "column", + "elements": [ + { + "tag": "div", + "text": { + "tag": "plain_text", + "content": "普通文本示例", + "text_size": "normal", + "text_align": "left", + "text_color": "default" + } + } + ], + "width": "weighted", + "weight": 1 + } + ] + } + ] + }, + "header": { + "title": { + "tag": "plain_text", + "content": "卡片主标题" + }, + "subtitle": { + "tag": "plain_text", + "content": "卡片副标题" + }, + "text_tag_list": [ + { + "tag": "text_tag", + "text": { + "tag": "plain_text", + "content": "后缀标签1" + }, + "color": "turquoise" + }, + { + "tag": "text_tag", + "text": { + "tag": "plain_text", + "content": "后缀标签2" + }, + "color": "orange" + }, + { + "tag": "text_tag", + "text": { + "tag": "plain_text", + "content": "后缀标签3" + }, + "color": "indigo" + } + ], + "template": "blue", + "ud_icon": { + "token": "larkcommunity_colorful" + } + } +} +``` + +## 枚举 + +### 标题主题样式枚举 + +标题组件中的 `template` 字段决定了卡片的标题主题样式。你可参考下表了解 `template` 的枚举值和对应的主题样式。 +| 枚举值 | 主题样式示例 | +| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| blue | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/0218ae6ce097798e66a7e935dd6c3fda_Qp3mGHzkAo.png?height=207&lazyload=true&width=1080) | +| wathet | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/bbbbb1f21738968a210e3cd58f0ceac2_p0k04F30KQ.png?height=205&lazyload=true&width=1079) | +| turquoise | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/6c429bdc5d5b3b3fc67b1c348b15c5c9_ao09ktRD5Z.png?height=210&lazyload=true&width=1077) | +| green | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/f19571778454b391c86e8faecb8b9fce_mLGWe9iNaH.png?height=209&lazyload=true&width=1078) | +| yellow | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/44ad929b370b06263ec09721ffde9fc2_OWDuBGcq9e.png?height=206&lazyload=true&width=1076) | +| orange | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/fddc48c22042f19def30a5ee9733940b_gz8S2BRH7t.png?height=207&lazyload=true&width=1074) | +| red | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/c5c3959cbcbe8de8d3173c4a15fdf19b_VTI955Zjl2.png?height=206&lazyload=true&width=1075) | +| carmine | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/f09a3ba6147dde821773dd612b0aedad_SGoLqjOAOD.png?height=203&lazyload=true&width=1078) | +| violet | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/9a13454a291cfa794a3a52306b603d68_RMp6KbXSEh.png?height=207&lazyload=true&width=1078) | +| purple | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/6845c6201575755e1684f149dc4a6772_xbdf7MlcdA.png?height=204&lazyload=true&width=1078) | +| indigo | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/36584f3f1ebf1838fa77db88413ba987_BOfl7QDd6J.png?height=206&lazyload=true&width=1074) | +| grey | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/97c72de5dbe7161c054790bffc947271_kno5sxKnBD.png?height=205&lazyload=true&width=1078) | +| default | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/f70ac3db3dab7db2096c7c23bcd04c99_Jr1xOkCYFB.png?height=183&lazyload=true&width=1074) | + +### 后缀标签颜色枚举 + +标题的后缀标签的颜色样式由`text_tag_list` 或 `i18n_text_tag_list` 中的 `color` 字段定义,该字段支持的枚举值与示例样式如下表所示。 +| 枚举值 | 颜色效果 | +| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| neutral | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/761076b831c55c5f94d2b56ebe8c04d9_TTBEjJgwKD.png?height=68&lazyload=true&width=84) | +| blue | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/827883431ea1e65e5fcd73638cbb999a_4dFihzf2Sn.png?height=58&lazyload=true&width=92) | +| turquoise | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/c5f286dc2f7dc0b3a95b62f27bda62e9_TmN1D8GQCa.png?height=70&lazyload=true&width=96) | +| lime | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/27dc172e5609fdc99d2a7e96c4a06c6f_rFFqBfYZla.png?height=74&lazyload=true&width=86) | +| orange | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/de108549d5b5c764994b540ecbb1353c_8ASPz3ARBu.png?height=78&lazyload=true&width=104) | +| violet | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/6ff286b66137b37745bd2e04cb5fbd1a_aawz4Ny9BN.png?height=80&lazyload=true&width=94) | +| indigo | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/ec24fb4da8d29c525505ab9db678694c_XG15qZBHv7.png?height=74&lazyload=true&width=108) | +| wathet | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/92241eb6dc69a648dd13bbac2bfe81fb_HAWERN9Msj.png?height=62&lazyload=true&width=94) | +| green | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/3c5c32b28dc75e5a6ca52f96d60e188a_2PACPcYXge.png?height=78&lazyload=true&width=102) | +| yellow | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/f576ac38660f0a85ad22d66bdcaab9a2_6upVXxpn7E.png?height=60&lazyload=true&width=100) | +| red | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/749a6988820ac78f7155f3f69bbc066b_N0TSK4RTdf.png?height=66&lazyload=true&width=98) | +| purple | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/e9aab9cb74258a506f66321fb085c144_xaCCNcz29R.png?height=88&lazyload=true&width=92) | +| carmine | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/99ff5fbe1d5d92fce54c99bd6fecd5c2_HAymg3iX4b.png?height=70&lazyload=true&width=100) | + +### 图标枚举 + +查看字段 `ud_icon` 的枚举,参考[图标库](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-icons)。 + +### 图标颜色枚举 + +你可通过 `ud_icon` 中的 `color` 字段设置图标颜色。查看 `color` 枚举,参考[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。 + +## 标题主题样式建议 + +在群聊中,可使用彩色标题。对于需高亮提醒的卡片信息,可将标题配置为应用的品牌色或表达状态的语义色,增强信息的视觉锚点。 +在单聊中,建议根据卡片的状态配置标题样式。你可以参考以下示例,配置不同语义下的主题样式。 +| **样式颜色** | **语义** | **示例** | +| ---------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 绿色(green) | 完成或成功。 | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/a31e60bfc5fb550252b6f42bebcc4662_zWVSUkjCWn.png?height=392&lazyload=true&width=3278) | +| 橙色(orange) | 警告或警示。 | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/ff8c11ce1d512ff0dde102e7fe2a396b_hhWyoZJQqH.png?height=396&lazyload=true&width=3278) | +| 红色(red) | 错误或异常。 | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/23fac81e7e6e1c0e0a7a3e80656aa196_CNFgcj7WF7.png?height=160&lazyload=true&width=1222) | +| 灰色(grey) | 失效。 | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/641178505b8a01e1b1be859d8453330d_cZIp2uZa3G.png?height=150&lazyload=true&width=1218) diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__user-list.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__user-list.md new file mode 100644 index 0000000..4e312f5 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__user-list.md @@ -0,0 +1,189 @@ +# 人员列表组件 + +人员列表组件支持展示多个人员的用户名和头像。用户点击头像或姓名后,还可展示人员的个人名片。你需通过传入人员的 `open_id`、`user_id` 或 `union_id` 使用该组件。 + +本文档介绍人员列表组件的 JSON 1.0 结构,要查看新版 JSON 2.0 结构,参考[人员列表](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/user-list)。 + +![4mddj-4u4k9.gif](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/52cf9cb6b6af7737c2e98979ee03e62e_wzv2uhNgPB.gif?height=950&lazyload=true&maxWidth=300&width=862) + +## 注意事项 + +若你要使用指定应用发送含有人员列表组件的卡片,你需保证该应用有访问用户 ID 的权限。否则卡片中的人员列表组件无法展示人员信息。 + +## JSON 结构 + +人员列表组件的完整 JSON 数据如下所示: +```json +{ + "tag": "person_list", + "drop_invalid_user_id": false, // 当人员列表中有无效用户 ID 时,是否忽略无效 ID。默认为 false,表示若存在无效用户 ID,将报错并返回无效的用户 ID 列表。 + "lines": 1, // 最大显示行数,默认关闭不限制最大显示行数。 + "show_name": true, // 是否展示人员对应的用户名。 + "show_avatar": true, // 是否展示人员对应的头像。 + "size": "large", // 人员头像的尺寸。 + "persons": [ + // 人员列表。人员的 ID 支持 open_id , user_id, union_id + { + "id": "ou_0fdb0e7663af7128e7d9f8adeb2abcef" + }, + { + "id": "ou_0fdb0e7663af7128e7d9f8adeb2abcef" + } + ], + "icon": { + // 前缀图标。 + "tag": "standard_icon", // 图标类型。 + "token": "chat-forbidden_outlined", // 图标的 token。仅在 tag 为 standard_icon 时生效。 + "color": "orange", // 图标颜色。仅在 tag 为 standard_icon 时生效。 + "img_key": "img_v2_38811724" // 图片的 key。仅在 tag 为 custom_icon 时生效。 + }, + "ud_icon": { + // 图标库中的前缀图标,和 icon 同时设置时以 icon 为准 + "token": "chat-forbidden_outlined", // 图标的 token + "style": { + "color": "red" // 图标颜色。支持设置线性和面性图标(即 token 末尾为 `outlined` 或 `filled` 的图标)的颜色。 + } + } +} +``` + +## 字段说明 + +人员组件的字段说明如下表。 + +参数 | 是否必须 | 类型 | 默认值 | 描述 +---|---|---|---|--- +tag | 是 | String | person_list | 组件的标签,人员列表组件的取值为 `person_list`。 +drop_invalid_user_id | 否 | Boolean | false | 当人员列表中有无效用户 ID 时,是否忽略无效 ID。默认为 false,表示若存在无效用户 ID,将报错并返回无效的用户 ID 列表。 +lines | 否 | Int | / | 最大显示行数,默认不限制最大显示行数。不可为 0。 +show_name | 否 | Boolean | true | 是否展示人员的用户名。
    **提示**:
    若不展示人员用户名,当 persons 字段中有多人 ID 时,人员列表样式将展示为“葫芦串”样式。
    ![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/c7212ce4016291a052083791eefca8a1_D4fuJKD6j0.png?height=107&lazyload=true&maxWidth=130&width=200) +show_avatar | 否 | Boolean | false | 是否展示人员的头像。 +size | 否 | String | medium | 人员的头像尺寸。可取值:
    - extra_small:超小尺寸
    - small:小尺寸
    - medium:中尺寸
    - large:大尺寸 +persons | 是 | Array | / | 人员列表。 +└ id | 是 | String | 空 | 人员的 ID。可选值有:
    - 人员的 Open ID:标识一个用户在某个应用中的身份。同一个用户在不同应用中的 Open ID 不同。详情参考[如何获取 Open ID](https://open.feishu.cn/document/uAjLw4CM/ugTN1YjL4UTN24CO1UjN/trouble-shooting/how-to-obtain-openid)
    - 人员的 Union ID:标识一个用户在某个应用开发商下的身份。同一用户在同一开发商下的应用中的 Union ID 是相同的,在不同开发商下的应用中的 Union ID 是不同的。通过 Union ID,应用开发商可以把同个用户在多个应用中的身份关联起来。详情参考[如何获取 Union ID](https://open.feishu.cn/document/uAjLw4CM/ugTN1YjL4UTN24CO1UjN/trouble-shooting/how-to-obtain-union-id)
    - 人员的 User ID :标识一个用户在某个租户内的身份。同一个用户在租户 A 和租户 B 内的 User ID 是不同的。在同一个租户内,一个用户的 User ID 在所有应用(包括商店应用)中都保持一致。User ID 主要用于在不同的应用间打通用户数据。详情参考[如何获取User ID](https://open.feishu.cn/document/uAjLw4CM/ugTN1YjL4UTN24CO1UjN/trouble-shooting/how-to-obtain-user-id) +icon | 否 | Object | / | 添加图标作为文本前缀图标。支持自定义或使用图标库中的图标。 +└ tag | 否 | String | / | 图标类型的标签。可取值:
    - `standard_icon`:使用图标库中的图标。
    - `custom_icon`:使用用自定义图片作为图标。 +└ token | 否 | String | / | 图标库中图标的 token。当 `tag` 为 `standard_icon` 时生效。枚举值参见[图标库](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-icons)。 +└ color | 否 | String | / | 图标的颜色。支持设置线性和面性图标(即 token 末尾为 `outlined` 或 `filled` 的图标)的颜色。当 `tag` 为 `standard_icon` 时生效。枚举值参见[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。 +└ img_key | 否 | String | / | 自定义前缀图标的图片 key。当 `tag` 为 `custom_icon` 时生效。
    图标 key 的获取方式:调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口,上传用于发送消息的图片,并在返回值中获取图片的 image_key。 +ud_icon | 否 | Object | / | 添加图标库中已有的图标。
    **注意**:一个人员组件仅可配置一个图标。如果同时配置 `icon` 和 `ud_icon`,仅生效 `icon`。 +└ token | 否 | String | / | 图标库中图标的 token。枚举值参见[图标库](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-icons)。 +└ style | 否 | Object | / | 图标的样式。支持自定义图标颜色。 +└└ color | 否 | String | / | 图标的颜色。支持设置线性和面性图标(即 token 末尾为 `outlined` 或 `filled` 的图标)的颜色。枚举值参见[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。
    **注意**:搭建工具暂不支持自定义图标颜色。 + +## 示例代码 + +将以下示例代码中的 `user_id` 替换为实际的用户 ID,即可实现如下图示例的卡片效果: + +![4mddj-4u4k9.gif](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/52cf9cb6b6af7737c2e98979ee03e62e_wzv2uhNgPB.gif?height=950&lazyload=true&maxWidth=500&width=862) + +```json +{ + "header": { + "template": "blue", + "title": { + "content": "人员列表示例", + "tag": "plain_text" + } + }, + "elements": [ + { + "tag": "markdown", + "content": "仅名字:" + }, + { + "tag": "person_list", + "persons": [ + { + "id": "ou_48d0958ee4b2ab3eaf0b5f6c968abcef" + }, + { + "id": "ou_f9d24af786a14340721288cda6aabcef" + }, + { + "id": "ou_b824f85713725c632e78887dc7fabcef" + } + ] + }, + { + "tag": "markdown", + "content": "名字+头像:" + }, + { + "tag": "person_list", + "show_name": true, + "show_avatar": true, + "lines": 2, + "size": "small", + "persons": [ + { + "id": "ou_48d0958ee4b2ab3eaf0b5f6c968abcef" + }, + { + "id": "ou_f9d24af786a14340721288cda6aabcef" + }, + { + "id": "ou_b824f85713725c632e78887dc7fabcef" + } + ] + }, + { + "tag": "markdown", + "content": "名字+头像+icon:" + }, + { + "tag": "person_list", + "show_name": true, + "show_avatar": true, + "lines": 2, + "size": "small", + "persons": [ + { + "id": "ou_48d0958ee4b2ab3eaf0b5f6c968abcef" + }, + { + "id": "ou_f9d24af786a14340721288cda6aabcef" + }, + { + "id": "ou_b824f85713725c632e78887dc7fabcef" + } + ], + "icon": { + "tag": "standard_icon", + "token": "group_outlined", + "color": "blue" + } + }, + { + "tag": "markdown", + "content": "名字葫芦串:" + }, + { + "tag": "person_list", + "persons": [ + { + "id": "ou_48d0958ee4b2ab3eaf0b5f6c968abcef" + }, + { + "id": "ou_f9d24af786a14340721288cda6aabcef" + }, + { + "id": "ou_b824f85713725c632e78887dc7fabcef" + }, + { + "id": "ou_48d0958ee4b2ab3eaf0b5f6c968abcef" + }, + { + "id": "ou_f9d24af786a14340721288cda6aabcef" + }, + { + "id": "ou_b824f85713725c632e78887dc7fabcef" + } + ], + "size": "small", + "show_avatar": true, + "show_name": false + } + ] +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__user-profile.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__user-profile.md new file mode 100644 index 0000000..222b510 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__content-components__user-profile.md @@ -0,0 +1,106 @@ +# 人员组件 + +人员组件支持展示人员的用户名和头像。用户点击头像或姓名后,还可展示人员的个人名片。你需通过传入人员的 `open_id`、`user_id` 或 `union_id` 使用该组件。 + +本文档介绍人员组件的 JSON 1.0 结构,要查看新版 JSON 2.0 结构,参考[人员](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/user-profile)。 + +![20240811145519_rec_.gif](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/c150c35475f11ae10f3d3f8c84995766_qZL4Wd4XMt.gif?height=646&lazyload=true&maxWidth=300&width=822) + +## 注意事项 + +若你要使用指定应用发送含有人员组件的卡片,你需保证该应用有访问用户 ID 的权限。否则卡片中的人员组件无法展示人员信息。 + +## JSON 结构 + +人员的完整 JSON 数据如下所示: +```json +{ + "tag": "person", + "size": "extra_small", // 人员头像尺寸。默认值为 medium。 + "user_id": "ou_4a136bca010747fc3bd7b6f8f4cabcef", //人员的 ID。 + "show_avatar": true, // 是否展示人员的头像。默认为 true。 + "show_name": false, // 是否展示人员的用户名。默认为 false。 + "style": "normal" // 人员组件的展示样式。可选值有 normal (默认样式)和 capsule (胶囊样式)。 +} +``` + +## 字段说明 + +人员组件的字段说明如下表。 + +参数 | 是否必须 | 类型 | 默认值 | 描述 +---|---|---|---|--- +tag | 是 | String | person | 组件的标签,人员组件的取值为 `person`。 +size | 否 | String | medium | 人员的头像尺寸。可取值:
    - extra_small:超小尺寸
    - small:小尺寸
    - medium:中尺寸
    - large:大尺寸 +show_avatar | 否 | Boolean | true | 是否展示人员的头像。 +show_name | 否 | Boolean | false | 是否展示人员的用户名。 +style | 否 | String | normal | 人员组件的展示样式。可选值有:
    - normal:默认样式
    - capsule:胶囊样式 +user_id | 是 | String | 空 | 人员的 ID。可选值有:
    - 人员的 Open ID:标识一个用户在某个应用中的身份。同一个用户在不同应用中的 Open ID 不同。详情参考[如何获取 Open ID](https://open.feishu.cn/document/uAjLw4CM/ugTN1YjL4UTN24CO1UjN/trouble-shooting/how-to-obtain-openid)
    - 人员的 Union ID:标识一个用户在某个应用开发商下的身份。同一用户在同一开发商下的应用中的 Union ID 是相同的,在不同开发商下的应用中的 Union ID 是不同的。通过 Union ID,应用开发商可以把同个用户在多个应用中的身份关联起来。详情参考[如何获取 Union ID](https://open.feishu.cn/document/uAjLw4CM/ugTN1YjL4UTN24CO1UjN/trouble-shooting/how-to-obtain-union-id)
    - 人员的 User ID :标识一个用户在某个租户内的身份。同一个用户在租户 A 和租户 B 内的 User ID 是不同的。在同一个租户内,一个用户的 User ID 在所有应用(包括商店应用)中都保持一致。User ID 主要用于在不同的应用间打通用户数据。详情参考[如何获取User ID](https://open.feishu.cn/document/uAjLw4CM/ugTN1YjL4UTN24CO1UjN/trouble-shooting/how-to-obtain-user-id) + +## 示例代码 + +将以下示例代码中的 `user_id` 替换为实际的用户 ID,即可实现如下图示例的卡片效果: + +![20240811145519_rec_.gif](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/c150c35475f11ae10f3d3f8c84995766_N3Fa33GsRt.gif?height=646&lazyload=true&maxWidth=500&width=822) + +```json +{ + "header": { + "template": "blue", + "title": { + "content": "人员示例", + "tag": "plain_text" + } + }, + "elements": [ + { + "tag": "markdown", + "content": "**extra_small 尺寸,默认样式**" + }, + { + "tag": "person", + "size": "extra_small", + "user_id": "ou_48d0958ee4b2ab3eaf0b5f6c968abcef", + "show_avatar": true, + "show_name": true, + "style": "normal" + }, + { + "tag": "markdown", + "content": "**small 尺寸,胶囊样式**" + }, + { + "tag": "person", + "size": "small", + "user_id": "ou_48d0958ee4b2ab3eaf0b5f6c968abcef", + "show_avatar": true, + "show_name": true, + "style": "capsule" + }, + { + "tag": "markdown", + "content": "**medium 尺寸,默认样式**" + }, + { + "tag": "person", + "size": "medium", + "user_id": "ou_48d0958ee4b2ab3eaf0b5f6c968abcef", + "show_avatar": true, + "show_name": true, + "style": "normal" + }, + { + "tag": "markdown", + "content": "**large 尺寸,胶囊样式**" + }, + { + "tag": "person", + "size": "large", + "user_id": "ou_48d0958ee4b2ab3eaf0b5f6c968abcef", + "show_avatar": true, + "show_name": true, + "style": "capsule" + } + ] +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__button.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__button.md new file mode 100644 index 0000000..9989723 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__button.md @@ -0,0 +1,345 @@ +# 按钮组件 + +按钮组件是一种交互组件,支持多种样式和尺寸,并支持添加图标作为前缀图标。本文档介绍按钮组件的 JSON 结构和相关属性。 + +本文档介绍按钮组件的 JSON 1.0 结构,要查看新版 JSON 2.0 结构,参考[按钮](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/button)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/fae9d121af371a94a077fbc09943b35c_MA2xpjPbyl.png?height=324&lazyload=true&maxWidth=500&width=999) + +## 注意事项 + +- 在[卡片 JSON 1.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-structure)中,若按钮组件直接位于卡片根节点,而非嵌套在其它组件中,你需将其 JSON 数据配置在[交互模块](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/component-list/common-components-and-elements)(`"tag": "action"`)的 `actions` 字段中使用。 + +- [卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)已不支持[交互模块](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/component-list/common-components-and-elements)(`"tag": "action"`)相关属性。你可直接将按钮放置于 `elements` 中,并配置合适的[组件间距 (vertical_spacing 和 horizontal_spacing)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-breaking-changes-release-notes#a967672) 使用。 +## 嵌套规则 + +按钮组件支持嵌套在分栏、表单容器、折叠面板、循环容器中使用。 + +## 组件属性 + +### JSON 结构 + +以下为一个按钮的卡片 JSON 数据: + +```json +{ + "tag": "button", // 组件的标签。按钮组件的固定值为 button。 + "type": "primary", // 按钮的类型。默认为 default。 + "size": "small", // 按钮的尺寸。默认值 medium。 + "width": "default", // 按钮的宽度。默认为 default。 + "text": { + // 按钮上的文本。 + "tag": "plain_text", + "content": "确定" + }, + "icon": { + // 前缀图标。 + "tag": "standard_icon", // 图标类型。 + "token": "chat-forbidden_outlined", // 图标的 token。仅在 tag 为 standard_icon 时生效。 + "color": "orange", // 图标颜色。仅在 tag 为 standard_icon 时生效。 + "img_key": "img_v2_38811724" // 图片的 key。仅在 tag 为 custom_icon 时生效。 + }, + "hover_tips": {}, // 用户在 PC 端将光标悬浮在按钮上方时的文案提醒。默认为空。 + "disabled": false, // 是否禁用该按钮。默认值 false。 + "disabled_tips": {}, // 禁用按钮后,用户在 PC 端将光标悬浮在按钮上方时的文案提醒。此字段生效后,hover_tips 不再生效。 + "confirm": { + // 二次确认弹窗配置 + "title": { + "tag": "plain_text", + "content": "title" + }, + "text": { + "tag": "plain_text", + "content": "content" + } + }, + "behaviors": [ + { + "type": "open_url", // 声明交互类型是打开链接的跳转交互 + "default_url": "https://www.baidu.com", // 兜底跳转地址 + "android_url": "https://developer.android.com/", // 安卓端跳转地址 + "ios_url": "lark://msgcard/unsupported_action", // iOS 端跳转地址。 + "pc_url": "https://www.windows.com" // 桌面端跳转地址 + }, + { + "type": "callback", // 声明交互类型是回传数据到服务端的回传交互。 + "value": { + // 回传交互数据。支持 string 或 object 数据类型。 + "key": "value" + } + }, + { + "type": "form_action", // 声明交互类型为表单事件。 + "behavior": "submit" // 声明表单事件类型。默认为 submit。 + } + ], + // 历史属性 + "url": "https://open.feishu.cn", + "multi_url": { + "android_url": "https://open.feishu.cn", + "ios_url": "https://open.feishu.cn", + "pc_url": "https://open.feishu.cn" + }, + "value": { + "key_1": "value_1" + } +} +``` + +### 字段说明 + +按钮组件各字段说明如下表所示: + +字段名称 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | String | / | 组件的标签。按钮组件的固定值为 `button`。 +type | 否 | String | default | 按钮的类型。可选值:
    - default:黑色字体按钮,有边框
    - primary:蓝色字体按钮,有边框
    - danger:红色字体按钮,有边框
    - text:黑色字体按钮,无边框
    - primary_text:蓝色字体按钮,无边框
    - danger_text:红色字体按钮,无边框
    - primary_filled:蓝底白字按钮
    - danger_filled:红底白字按钮
    - laser:镭射按钮 +size | 否 | String | medium | 按钮的尺寸。可选值:
    - tiny:超小尺寸,PC 端为 24 px;移动端为 28 px
    - small:小尺寸,PC 端为 28 px;移动端为 28 px
    - medium:中尺寸,PC 端为 32 px;移动端为 36 px
    - large:大尺寸,PC 端为 40 px;移动端为 48 px +width | 否 | String | default | 按钮的宽度。支持以下枚举值:
    - default:默认宽度
    - fill:卡片最大支持宽度
    - [100,∞)px:自定义宽度,如 `120px`。超出卡片宽度时将按最大支持宽度展示 +text | 否 | Struct | 空 | 按钮上的文本。 +└ tag | 是 | String | plain_text | 文本类型的标签。固定值为 `plain_text`。 +└ content | 是 | String | / | 文本的内容,最多支持 100 个字符。 +icon | 否 | Object | / | 添加图标作为文本前缀图标。支持自定义或使用图标库中的图标。 +└ tag | 否 | String | / | 图标类型的标签。可取值:
    - `standard_icon`:使用图标库中的图标。
    - `custom_icon`:使用用自定义图片作为图标。 +└ token | 否 | String | / | 图标库中图标的 token。当 `tag` 为 `standard_icon` 时生效。枚举值参见[图标库](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-icons)。 +└ color | 否 | String | / | 图标的颜色。支持设置线性和面性图标(即 token 末尾为 `outlined` 或 `filled` 的图标)的颜色。当 `tag` 为 `standard_icon` 时生效。枚举值参见[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。 +└ img_key | 否 | String | / | 自定义前缀图标的图片 key。当 `tag` 为 `custom_icon` 时生效。
    图标 key 的获取方式:调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口,上传用于发送消息的图片,并在返回值中获取图片的 image_key。 +hover_tips | 否 | Object | 空 | 用户在 PC 端将光标悬浮在交互容器上方时的文案提醒。默认为空。 +└ tag | 是 | String | plain_text | 文本的标签。固定取值为 plain_text。 +└ content | 是 | String | 空 | 文本的内容。 +disabled | 否 | Boolean | false | 是否禁按钮。可选值:
    - true:禁用按钮
    - false:按钮组件保持可用状态 +disabled_tips | 否 | Object | 空 | 禁用按钮后,用户触发交互时的弹窗文案提醒。默认为空,即不弹窗。 +└ tag | 是 | String | plain_text | 弹窗标题文本的标签。固定取值为 plain_text。 +└ content | 是 | String | 空 | 弹窗标题的内容。 +confirm | 否 | Struct | 默认不生效此属性。 | 二次确认弹窗配置。指在用户提交时弹出二次确认弹窗提示;只有用户点击确认后,才提交输入的内容。该字段默认提供了确认和取消按钮,你只需要配置弹窗的标题与内容即可。
    **注意**:confirm 字段仅在用户点击包含提交属性的按钮时才会触发二次确认弹窗。 +└ title | 是 | Struct | / | 二次确认弹窗标题。
    **注意**:要配置二次弹窗,title 字段必填。否则,历史版本的飞书客户端可能会出现点击按钮无反应的问题。 +└ └ tag | 是 | String | plain_text | 二次确认弹窗标题文本的标签。固定取值为 `plain_text`。 +└ └ content | 是 | String | / | 二次确认弹窗标题的内容。 +└ text | 是 | Struct | / | 二次确认弹窗文本。 +└ └ tag | 是 | String | plain_text | 二次确认弹窗文本的标签。固定取值为 `plain_text`。 +└ └ content | 是 | String | / | 二次确认弹窗文本的具体内容。 +behaviors | 是 | Struct | / | 配置交互类型和具体交互行为。支持同时生效跳转链接和回传交互。详情参考[配置卡片交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/configuring-card-interactions)。 +以下为支持交互的历史属性。
    字段名称 | 是否必填 | 类型 | 默认值 | 说明 +url | 否 | String | / | 点击按钮后的跳转链接。该字段与 `multi_url` 字段不可同时设置。 +multi_url | 否 | Struct | / | 基于 url 元素配置多端跳转链接,详情参见旧版文档[url 元素](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/component-list/common-components-and-elements#09a320b3)。该字段与 `url` 字段不可同时设置。 +value | 否 | JSON | / | 该字段用于配置回传交互。当用户点击交互组件后,会将 `value` 的值返回给接收回调数据的服务器。后续你可以通过服务器接收的 `value` 值进行业务处理。
    该字段值仅支持 key-value 形式的 JSON 结构,且 key 为 String 类型。示例值:
    ```json
    "value":{
    "key-1":Object-1,
    "key-2":Object-2,
    "key-3":Object-3,
    ······
    }
    ``` +complex_interaction | 否 | Boolean | false | 是否同时生效上述历史字段配置的跳转链接交互和回传交互。默认仅生效跳转链接交互。 +内嵌在表单容器中的按钮组件,新增 `name`、`required`、和 `action_type` 属性。详细说明如下表所示。
    属性名称 | 是否必填 | 类型 | 默认值 | 说明 +name | 是 | String | 空 | 表单容器内组件的唯一标识。用于识别用户提交的数据属于哪个组件。
    **注意**:该字段必填且需在卡片全局内唯一。 +required | 否 | Boolean | false | 组件的内容是否必填。当组件内嵌在表单容器中时,该属性生效。可取值:
    - **true**:必填。当用户点击表单容器的“提交”时,未填写该组件,则前端提示“有必填项未填写”,不会向开发者的服务端发起回传请求。
    - **false**:选填。当用户点击表单容器的“提交”时,未填写该组件,仍提交表单容器中的数据。 +action_type | 是 | String | 空 | 内嵌在表单容器中的按钮的交互类型。枚举值包括:
    - link:当前按钮仅支持链接跳转
  • request:当前按钮仅支持回传交互

  • multi:当前按钮同时支持链接跳转和回传交互

  • form_submit:将当前按钮与提交事件绑定。用户点击后,将触发表单容器的提交事件,异步提交所有已填写的表单项内容

  • form_reset:将当前按钮与取消提交事件绑定。用户点击后,将触发表单容器的取消提交事件,重置所有表单组件的输入值为初始值
  • + +### 回调结构 + +为按钮组件成功[配置卡片交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/configuring-card-interactions)后,用户基于按钮组件进行交互时,你在开发者后台配置的请求地址将会收到回调数据。 + +- 如果你添加的是新版卡片回传交互回调(`card.action.trigger`),可参考[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)了解回调结构。 +- 如果你添加的是旧版卡片回传交互回调(`card.action.trigger_v1`),可参考[消息卡片回传交互(旧)](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/configuring-card-callbacks/card-callback-structure)了解回调结构。 + +## 示例代码 + +以下的 JSON 示例代码可实现如下图所示的按钮效果。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/fae9d121af371a94a077fbc09943b35c_A9IfJJ2S1b.png?height=324&lazyload=true&maxWidth=500&width=999) + +```json +{ + "header": { + "template": "blue", + "title": { + "content": "Buttons", + "tag": "plain_text" + } + }, + "elements": [ + { + "tag": "column_set", + "flex_mode": "flow", + "background_style": "default", + "columns": [ + { + "tag": "column", + "width": "auto", + "weight": 1, + "vertical_align": "top", + "elements": [ + { + "tag": "button", + "text": { + "tag": "plain_text", + "content": "镭射按钮" + }, + "behaviors": [ + { + "type": "open_url", + "default_url": "https://open.feishu.cn/document", + "android_url": "https://developer.android.com/", + "ios_url": "lark://msgcard/unsupported_action", + "pc_url": "https://www.windows.com" + } + ], + "type": "laser", + "hover_tips": { + "tag": "plain_text", + "content": "hover提示" + }, + "value": { + "key": "value" + } + } + ] + }, + { + "tag": "column", + "width": "auto", + "weight": 1, + "vertical_align": "top", + "elements": [ + { + "tag": "button", + "type": "laser", + "text": { + "tag": "plain_text", + "content": "镭射禁用按钮" + }, + "disabled": true, + "disabled_tips": { + "tag": "plain_text", + "content": "禁用 hover 提示" + }, + "behaviors": [ + { + "type": "open_url", + "default_url": "https://open.feishu.cn/document", + "android_url": "https://developer.android.com/", + "ios_url": "lark://msgcard/unsupported_action", + "pc_url": "https://www.windows.com" + } + ] + } + ] + } + ] + }, + { + "tag": "column_set", + "flex_mode": "flow", + "background_style": "default", + "columns": [ + { + "tag": "column", + "width": "auto", + "weight": 1, + "vertical_align": "top", + "elements": [ + { + "tag": "button", + "text": { + "tag": "plain_text", + "content": "primary" + }, + "url": "https://open.feishu.cn/document", + "type": "primary", + "hover_tips": { + "tag": "plain_text", + "content": "我是 primary button" + }, + "value": { + "key": "value" + } + } + ] + }, + { + "tag": "column", + "width": "auto", + "weight": 1, + "vertical_align": "top", + "elements": [ + { + "tag": "button", + "type": "default", + "text": { + "tag": "plain_text", + "content": "default" + }, + "hover_tips": { + "tag": "plain_text", + "content": "我是 default 按钮" + }, + "behaviors": [ + { + "type": "open_url", + "default_url": "https://open.feishu.cn/document", + "android_url": "https://developer.android.com/", + "ios_url": "lark://msgcard/unsupported_action", + "pc_url": "https://www.windows.com" + } + ] + } + ] + }, + { + "tag": "column", + "width": "auto", + "weight": 1, + "vertical_align": "top", + "elements": [ + { + "tag": "button", + "type": "danger", + "text": { + "tag": "plain_text", + "content": "我是 danger 按钮" + }, + "hover_tips": { + "tag": "plain_text", + "content": "我是 danger 按钮" + }, + "behaviors": [ + { + "type": "open_url", + "default_url": "https://open.feishu.cn/document", + "android_url": "https://developer.android.com/", + "ios_url": "lark://msgcard/unsupported_action", + "pc_url": "https://www.windows.com" + } + ] + } + ] + }, + { + "tag": "column", + "width": "auto", + "weight": 1, + "vertical_align": "top", + "elements": [ + { + "tag": "button", + "type": "danger", + "text": { + "tag": "plain_text", + "content": "我是 disabled 按钮" + }, + "disabled": true, + "disabled_tips": { + "tag": "plain_text", + "content": "我是 disabled 按钮,我被禁用了" + }, + "behaviors": [ + { + "type": "open_url", + "default_url": "https://open.feishu.cn/document", + "android_url": "https://developer.android.com/", + "ios_url": "lark://msgcard/unsupported_action", + "pc_url": "https://www.windows.com" + } + ] + } + ] + } + ] + } + ] +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__checker.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__checker.md new file mode 100644 index 0000000..b7459df --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__checker.md @@ -0,0 +1,339 @@ +# 勾选器组件 + +勾选器是一种交互组件,支持配置回调响应,主要用于任务勾选的场景。 + +本文档介绍勾选器组件的 JSON 1.0 结构,要查看新版 JSON 2.0 结构,参考[勾选器](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/checker)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/c552a50e0f67b0f263c58f16cb52cee9_5ARZSm53ha.png?height=252&lazyload=true&maxWidth=400&width=1112) + +## 注意事项 + +- 勾选器仅支持通过撰写卡片 JSON 代码的方式使用,暂不支持在卡片搭建工具上构建使用。 +- 勾选器支持飞书 V7.9 及以上版本的客户端。在低于该版本的飞书客户端上,勾选器的内容将展示为“请升级至最新版本客户端,以查看内容”的占位图。 + +## 嵌套规则 + +勾选器组件支持内嵌在所有容器类组件(包括表单容器、交互容器、分栏和折叠面板)中使用。 + +## 组件属性 + +### JSON 结构 + +以下为勾选器组件的卡片 JSON 数据: +```json +{ + "tag": "checker", // 组件的标签。勾选器组件的固定值为 checker。 + "name": "check_1", // 勾选器组件的唯一标识。用于识别用户提交的数据属于哪个组件。 + "checked": false, // 勾选器的初始勾选状态。默认值 false。 + "text": { // 勾选器组件内的普通文本信息。 + "tag": "plain_text" // 文本类型的标签。 + "content": "", // 文本的内容。当 tag 为 lark_md 时,支持部分 Markdown 语法的文本内容。 + "text_size": "normal", // 文本大小。默认值 normal。 + "text_color": "default", // 文本颜色。仅在 tag 为 plain_text 时生效。默认值 default。 + "text_align": "left", // 文本对齐方式。默认值 left。 + }, + "overall_checkable": true, // 当光标悬浮在勾选器上时,勾选器整体是否有阴影效果。默认值 true。 + "button_area": { // 按钮区的配置。可选。 + "pc_display_rule": "always", // PC 端勾选器内按钮的展示规则。默认值 always,即始终显示按钮。 + "buttons": [ // 在勾选器中添加并配置按钮。最多可配置三个按钮。 + { + "tag": "button", // 按钮的标签,取固定值 button。 + "type": "text", // 按钮的类型。必填。 + "size": "small", // 按钮的尺寸。默认值 medium。 + "text": { // 按钮上的文本。 + "tag": "plain_text", + "content": "text按钮" + }, + "icon": { // 添加图标作为按钮文本上的前缀图标。支持自定义或使用图标库中的图标。 + "tag": "standard_icon", // 图标类型。 + "token": "chat-forbidden_outlined", // 图标的 token。仅在 tag 为 standard_icon 时生效。 + "color": "orange", // 图标颜色。仅在 tag 为 standard_icon 时生效。 + "img_key": "img_v2_38811724" // 图片的 key。仅在 tag 为 custom_icon 时生效。 + }, + "disabled": false, + "behaviors": [] + } + ] + }, + "checked_style": { // 勾选状态样式。 + "show_strikethrough": true, // 是否展示内容区的贯穿式删除线。默认值 false。 + "opacity": 1 // 内容区的不透明度。默认值 1。 + }, + "margin": "0px", // 组件整体的外边距,支持填写单值或多值。默认值为 0px。 + "padding": "0px", // 组件整体的内边距,支持填写单值或多值。默认值为 0px。 + +"confirm": {}, // 二次确认弹窗配置。用户点击确定后再执行 behaviors 中声明的交互 + "behaviors": [ // 配置交互类型和具体交互行为。未配置 behaviors 时,终端用户可勾选,但仅本地有效。 + { + "type": "callback", // 声明交互类型。仅支持 callback 请求回调交互。 + "value": { + // 回传交互数据 + "key": "value" + } + } + ], + "hover_tips": {}, //用户在 PC 端将光标悬浮在勾选器上方时的文案提醒。 + "disabled": false, // 是否禁用该勾选器。默认值 false。 + "disabled_tips": {} // 禁用勾选器后,用户在 PC 端将光标悬浮在勾选器上方时的文案提醒。 +} +``` + +### 字段说明 + +勾选器各字段说明如下表所示。 + +字段 | 是否必填 | 类型 | 默认值 | 描述 +---|---|---|---|--- +tag | 是 | String | / | 组件的标签。勾选器组件的固定值为 `checker`。 +name | 否 | String | 空 | 勾选器组件的唯一标识。用于识别用户提交的数据属于哪个组件。
    **注意**:当勾选器组件嵌套在表单容器中时,该字段必填且需在卡片全局内唯一。 +checked | 否 | Boolean | false | 勾选器的初始勾选状态。可选值:
    - true:已勾选状态
    - false:未勾选状态 +text | 否 | Object | / | 勾选器组件内的普通文本信息。 +└ tag | 是 | String | plain_text | 文本类型的标签。可取值:
    - `plain_text`:普通文本内容
    - `lark_md`:支持部分 Markdown 语法的文本内容。详情参考[lark_md 支持的 Markdown 语法](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/plain-text)
    **注意**:飞书卡片搭建工具中仅支持使用 `plain_text` 类型的普通文本组件。你可使用富文本组件添加 Markdown 格式的文本。 +└ content | 是 | String | / | 文本内容。当 `tag` 为 `lark_md` 时,支持部分 Markdown 语法的文本内容。详情参考[lark_md 支持的 Markdown 语法](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/plain-text) +└ text_size | 否 | String | normal | 文本大小。可取值:
    - `normal`:正文(14px)
    - `heading`:标题(16px)
    - `notation`:辅助信息(12px) +└ text_color | 否 | String | default | 文本的颜色。仅在 `tag` 为 `plain_text` 时生效。可取值:
    - `default`:客户端浅色主题模式下为黑色;客户端深色主题模式下为白色
    - 颜色的枚举值。详情参考[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color) +└ text_align | 否 | String | left | 文本对齐方式。可取值:
    - `left`:左对齐
    - `center`:居中对齐
    - `right`:右对齐 +overall_checkable | 否 | String | true | 当光标悬浮在勾选器上时,勾选器整体是否有阴影效果。
    **注意**:要取消阴影效果,你需确保 `overall_checkable` 为 `false` 且 `pc_display_rule` 不为 `on_hover`。 +button_area | 否 | Object | / | 按钮区配置。 +└ pc_display_rule | 否 | String | always | PC 端勾选器内按钮的展示规则。移动端始终显示按钮。可取值:
    - `always`:按钮始终显示。
    - `on_hover`:当光标悬浮在勾选器上时,按钮显示且勾选器整体有阴影效果。 +└ buttons | 否 | Array<Object> | [] | 在勾选器中添加并配置按钮。最多可配置三个按钮。详情参考下一小节 buttons 字段说明。 +checked_style | 否 | Object | / | 勾选状态样式。 +└ show_strikethrough | 否 | Boolean | false | 是否展示内容区的贯穿式删除线。 +└ opacity | 否 | Number | 1 | 内容区的不透明度。取值范围为 [0,1] 之间的数字,不限小数位数。 +margin | 否 | String | 0px | 组件整体的外边距,支持填写单值或多值:
    - 单值:如 "4px",表示组件的四个外边距都为 4px
    - 多值:如 "4px 12px 4px 12px",表示容器内上、右、下、左的内边距分别为 4px,12px,4px,12px。四个值必填,使用空格间隔 +padding | 否 | String | 0px | 组件整体的内边距,支持填写单值或多值:
    - 单值:如 "4px",表示组件内四个内边距都为 4px
    - 多值:如 "4px 12px 4px 12px",表示容器内上、右、下、左的内边距分别为 4px,12px,4px,12px。四个值必填,使用空格间隔 +confirm | 否 | Struct | 默认不生效此属性。 | 二次确认弹窗配置。指在用户提交时弹出二次确认弹窗提示;只有用户点击确认后,才提交输入的内容。该字段默认提供了确认和取消按钮,你只需要配置弹窗的标题与内容即可。
    **注意**:confirm 字段仅在用户点击包含提交属性的按钮时才会触发二次确认弹窗。 +confirm.title | 是 | Struct | / | 二次确认弹窗标题。 +confirm.title.tag | 是 | String | plain_text | 二次确认弹窗标题文本的标签。固定取值为 `plain_text`。 +confirm.title.content | 是 | String | / | 二次确认弹窗标题的内容。 +confirm.text | 是 | Struct | / | 二次确认弹窗的文本内容。 +confirm.text.tag | 是 | String | plain_text | 二次确认弹窗文本的标签。固定取值为 `plain_text`。 +confirm.text.content | 是 | String | / | 二次确认弹窗文本的具体内容。 +behaviors | 是 | Struct | / | 配置交互类型和具体交互行为。未配置 `behaviors` 时,终端用户可勾选,但仅本地有效。详情参考[配置卡片交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/configuring-card-interactions)。 +hover_tips | 否 | Object | 空 | 用户在 PC 端将光标悬浮在勾选器上方时的文案提醒。
    **注意**:当同时配置 `hover_tips` 和 `disabled_tips` 时,`disabled_tips` 将生效。 +└ tag | 否 | String | plain_text | 文案提醒的标签。固定值为 `plain_text`。 +└ content | 否 | String | 空 | 文案提醒的内容。 +disabled | 否 | Boolean | false | 是否禁用该勾选器。可选值:
    - true:禁用
    - false:勾选器组件保持可用状态
    +disabled_tips | 否 | Object | 空 | 禁用勾选器后,用户在 PC 端将光标悬浮在勾选器上方时的文案提醒。 +└ tag | 是 | String | plain_text | 禁用文案的标签。固定取值为 `plain_text`。 +└ content | 是 | String | 空 | 禁用文案的内容。 + +#### `buttons` 字段说明 + +你可在勾选器中通过 `buttons` 字段添加并配置按钮。最多可配置三个按钮。 + +字段名称 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | String | button | 按钮的标签,取固定值 `button`。 +type | 是 | String | 空 | 按钮的类型,可选值:
    - text:黑色字体按钮,无边框
    - primary_text:蓝色字体按钮,无边框
    - danger_text:红色字体按钮,无边框 +size | 否 | String | medium | 按钮的尺寸,可选值:
    - tiny:超小尺寸,PC 端为 24px;移动端为 28px
    - small:小尺寸,PC 端为 28 px;移动端为 28 px
    - medium:中尺寸,PC 端为 32 px;移动端为 36 px
    - large:大尺寸,PC 端为 40 px;移动端为 48 px +text | 否 | Struct | 空 | 按钮上的文本。 +└ tag | 是 | String | plain_text | 文本的标签。固定取值为 plain_text。 +└ content | 是 | String | 空 | 文本的内容。 +icon | 否 | Object | / | 添加图标作为文本前缀图标。支持自定义或使用图标库中的图标。 +└ tag | 否 | String | / | 图标类型的标签。可取值:
    - `standard_icon`:使用图标库中的图标。
    - `custom_icon`:使用用自定义图片作为图标。 +└ token | 否 | String | / | 图标库中图标的 token。当 `tag` 为 `standard_icon` 时生效。枚举值参见[图标库](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-icons)。 +└ color | 否 | String | / | 图标的颜色。支持设置线性和面性图标(即 token 末尾为 `outlined` 或 `filled` 的图标)的颜色。当 `tag` 为 `standard_icon` 时生效。枚举值参见[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。 +└ img_key | 否 | String | / | 自定义前缀图标的图片 key。当 `tag` 为 `custom_icon` 时生效。
    图标 key 的获取方式:调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口,上传用于发送消息的图片,并在返回值中获取图片的 image_key。 +disabled | 否 | Boolean | false | 是否禁用按钮。可选值:
    - true:禁用按钮
    - false:按钮组件保持可用状态 +behaviors | 是 | Struct | / | 配置交互类型和具体交互行为。详情参考[配置卡片交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/configuring-card-interactions)。 + +## 回调结构 + +为组件成功配置交互后,用户基于组件进行交互时,你在开发者后台配置的请求地址将会收到回调数据。 +- 如果你添加的是新版卡片回传交互回调(`card.action.trigger`),可参考[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)了解回调结构。 +- 如果你添加的是旧版卡片回传交互回调(`card.action.trigger_v1`),可参考[消息卡片回传交互(旧)](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/configuring-card-callbacks/card-callback-structure)了解回调结构。 + +## 示例代码 + +以下的 JSON 示例代码可实现如下图所示的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/c552a50e0f67b0f263c58f16cb52cee9_fCD4ON3zSz.png?height=252&lazyload=true&maxWidth=400&width=1112) +```json +{ + "header": { + "template": "blue", + "title": { + "tag": "plain_text", + "content": "勾选组件(依赖端版本 7.9+)" + } + }, + "elements": [ + { + "tag": "column_set", + "flex_mode": "none", + "background_style": "default", + "columns": [ + { + "tag": "column", + "width": "weighted", + "weight": 1, + "vertical_spacing": "1px", + "elements": [ + { + "tag": "checker", + "name": "check_1", + "checked": false, + "text": { + "tag": "lark_md", + "content": "完成新品上市计划报告 💬[战略研讨会](https://open.feishu.cn)" + }, + "overall_checkable": false, + "button_area": { + "pc_display_rule": "always", + "buttons": [ + { + "tag": "button", + "type": "text", + "size": "large", + "text": { + "tag": "plain_text", + "content": "" + }, + "icon": { + "tag": "standard_icon", + "token": "forward-com_outlined", + "color": "grey-500" + }, + "disabled": false, + "behaviors": [ + { + "type": "callback", + "value": { + "key": "btn1" + } + } + ] + }, + { + "tag": "button", + "type": "text", + "size": "large", + "text": { + "tag": "plain_text", + "content": "" + }, + "icon": { + "tag": "standard_icon", + "token": "tab-todo_outlined", + "color": "grey-500" + }, + "disabled": false, + "behaviors": [ + { + "type": "open_url", + "default_url": "https://www.baidu.com", + "android_url": "https://developer.android.com/", + "ios_url": "lark://msgcard/unsupported_action", + "pc_url": "https://www.windows.com" + } + ] + } + ] + }, + "checked_style": { + "show_strikethrough": true, + "opacity": 0.5 + }, + "padding": "2px 2px 2px 2px", + "behaviors": [ + { + "type": "callback", + "value": { + "key": "todo1" + } + } + ] + }, + { + "tag": "checker", + "name": "check_2", + "checked": false, + "text": { + "tag": "lark_md", + "content": "把材料提前给💬[业务数据共享群](https://open.feishu.cn)审阅" + }, + "overall_checkable": true, + "button_area": { + "pc_display_rule": "on_hover", + "buttons": [ + { + "tag": "button", + "type": "text", + "size": "large", + "text": { + "tag": "plain_text", + "content": "" + }, + "icon": { + "tag": "standard_icon", + "token": "forward-com_outlined", + "color": "grey-500" + }, + "disabled": false, + "behaviors": [ + { + "type": "callback", + "value": { + "key": "btn2" + } + } + ] + }, + { + "tag": "button", + "type": "text", + "size": "large", + "text": { + "tag": "plain_text", + "content": "" + }, + "icon": { + "tag": "standard_icon", + "token": "tab-todo_outlined", + "color": "grey-500" + }, + "disabled": false, + "behaviors": [ + { + "type": "open_url", + "default_url": "https://www.baidu.com", + "android_url": "https://developer.android.com/", + "ios_url": "lark://msgcard/unsupported_action", + "pc_url": "https://www.windows.com" + } + ] + } + ] + }, + "checked_style": { + "show_strikethrough": true, + "opacity": 0.5 + }, + "padding": "2px 2px 2px 2px", + "confirm": { + "title": { + "tag": "plain_text", + "content": "弹窗标题" + }, + "text": { + "tag": "plain_text", + "content": "确认提交吗" + } + }, + "behaviors": [ + { + "type": "callback", + "value": { + "key": "todo2" + } + } + ] + } + ] + } + ] + } + ] +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__date-picker.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__date-picker.md new file mode 100644 index 0000000..46ae8c0 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__date-picker.md @@ -0,0 +1,123 @@ +# 日期选择器组件 + +日期选择器组件是用于提供日期选项的交互组件。本文档介绍日期选择器组件的 JSON 结构和相关属性。 + +本文档介绍日期选择器组件的 JSON 1.0 结构,要查看新版 JSON 2.0 结构,参考[日期选择器](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/date-picker)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/7e668bf8bbc9b3d4c42b324d43100259_4F0wfw4is4.png?height=186&lazyload=true&maxWidth=400&width=561) + +## 注意事项 + +- 日期选择器组件支持飞书 V3.11.0 及以上版本的客户端。在低于该版本的飞书客户端上,表单容器的内容将展示为“当前版本不支持查看此消息”。 +- 在使用日期选择器时,你需提醒用户选择与当前日期场景相对应的时区信息。例如,在预定海外酒店的场景下,一般使用酒店所在地时区;设置日程场景下,一般使用用户当前所在地的时区。开放平台会返回用户当前的时区作为参考,但并不代表用户选择了该时区。 +- 在卡片 JSON 代码中,若日期选择器组件直接位于卡片根节点,而非嵌套在其它组件中,你需将其 JSON 数据配置在[交互模块](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/component-list/common-components-and-elements)(`"tag": "action"`)的 `actions` 字段中使用。 + +## 嵌套规则 + +日期选择器组件支持嵌套在分栏、表单容器、折叠面板、循环容器中使用。 + +## 组件属性 + +### JSON 结构 + +日期选择器组件的结构如下所示: +```json +{ + "tag": "date_picker", + "name": "date_picker1", // 日期选择器组件的唯一标识。当组件内嵌在表单容器中时,该属性生效,用于识别用户提交的文本属于哪个输入框。 + "required": false, // 日期是否必选,默认值 false。当日期选择器内嵌在表单容器时,该属性可用。其它情况将报错或不生效。 + "disabled": false, // 是否禁用该日期选择器组件。默认值 false。 + "width": "default", // 日期选择器的宽度。 + "initial_date": "2024-01-01", // 日期初始值。 + "placeholder": { + // 日期选择器组件内的占位文本。 + "tag": "plain_text", + "content": "请选择" + }, + "value": { + // 回传数据 + "key_1": "value_1" + }, + "confirm": { + // 二次确认弹窗配置 + "title": { + "tag": "plain_text", + "content": "title" + }, + "text": { + "tag": "plain_text", + "content": "content" + } + } +} +``` + +### 字段说明 + +日期选择器组件的字段说明如下表。 + +字段 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | string | / | 组件的标签。日期选择器组件取固定值 `date_picker`。 +name | 否 | String | 空 | 该日期选择器组件的唯一标识。当日期选择器内嵌在表单容器时,该属性生效,用于识别用户提交的数据属于哪个组件。
    **注意**: 当日期选择器组件嵌套在表单容器中时,该字段必填且需在卡片全局内唯一。 +required | 否 | Boolean | false | 日期的内容是否必选。当组件内嵌在表单容器中时,该属性可用。其它情况将报错或不生效。可取值:
    - true:日期必选。当用户点击表单容器的“提交”时,未填写日期,则前端提示“有必填项未填写”,不会向开发者的服务端发起回传请求。
    - false:日期选填。当用户点击表单容器的“提交”时,未填写日期,仍提交表单容器中的数据。 +disabled | 否 | Boolean | false | 是否禁用该日期选择器。该属性仅支持飞书 V7.4 及以上版本的客户端。可选值:
    - true:禁用日期选择器组件
    - false:日期选择器组件保持可用状态 +placeholder | 否 | object | / | 日期选择器组件内的占位文本。 +└ tag | 是 | String | plain_text | 占位提示标签。固定值为 plain_text。 +└ content | 否 | String | / | 占位文本的内容,最多支持 100 个字符。 +width | 否 | String | default | 日期选择器组件的宽度。支持以下枚举值:
    - default:默认宽度
    - fill:卡片最大支持宽度
    - [100,∞)px:自定义宽度。超出卡片宽度时将按最大支持宽度展示 +initial_date | 否 | String | 空 | 日期选择器组件的初始选项值。格式为 `yyyy-MM-dd`。该配置将会覆盖 `placeholder` 配置的占位文本。 +value | 是 | JSON | / | 设置交互的回传数据,当用户点击交互组件的选项后,会将 value 的值返回给接收回调数据的服务器。后续你可以通过服务器接收的 value 值进行业务处理。该字段值仅支持 key-value 形式的 JSON 结构,且 key 为 String 类型。
    示例值:
    ```json
    "value":{
    "key-1":Object-1,
    "key-2":Object-2,
    "key-3":Object-3,
    ······
    }
    ``` +confirm | 否 | Struct | 默认不生效此属性。 | 二次确认弹窗配置。指在用户提交时弹出二次确认弹窗提示;只有用户点击确认后,才提交输入的内容。该字段默认提供了确认和取消按钮,你只需要配置弹窗的标题与内容即可。
    **注意**:confirm 字段仅在用户点击包含提交属性的按钮时才会触发二次确认弹窗。 +confirm.title | 是 | Struct | / | 二次确认弹窗标题。 +confirm.title.tag | 是 | String | plain_text | 二次确认弹窗标题文本的标签。固定取值为 `plain_text`。 +confirm.title.content | 是 | String | / | 二次确认弹窗标题的内容。 +confirm.text | 是 | Struct | / | 二次确认弹窗的文本内容。 +confirm.text.tag | 是 | String | plain_text | 二次确认弹窗文本的标签。固定取值为 `plain_text`。 +confirm.text.content | 是 | String | / | 二次确认弹窗文本的具体内容。 + +## 回调结构 +为组件成功配置交互后,用户基于组件进行交互时,你在开发者后台配置的请求地址将会收到回调数据。 +- 如果你添加的是新版卡片回传交互回调(`card.action.trigger`),可参考[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)了解回调结构。 +- 如果你添加的是旧版卡片回传交互回调(`card.action.trigger_v1`),可参考[消息卡片回传交互(旧)](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/configuring-card-callbacks/card-callback-structure)了解回调结构。 +## 示例代码 + +以下的 JSON 示例代码可实现如下图所示的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/7e668bf8bbc9b3d4c42b324d43100259_4F0wfw4is4.png?height=186&lazyload=true&maxWidth=400&width=561) +```json +{ + "i18n_elements": { + "zh_cn": [ + { + "tag": "action", + "actions": [ + { + "tag": "date_picker", + "placeholder": { + "tag": "plain_text", + "content": "请选择" + }, + "width": "default", + "initial_date": "2024-01-01" + } + ] + }, + { + "tag": "action", + "actions": [ + { + "tag": "date_picker", + "placeholder": { + "tag": "plain_text", + "content": "请选择" + }, + "width": "default" + } + ] + } + ] + }, + "i18n_header": {} +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__date-time-picker.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__date-time-picker.md new file mode 100644 index 0000000..eb1971c --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__date-time-picker.md @@ -0,0 +1,126 @@ +# 日期时间选择器组件 + +日期时间选择器组件是用于提供时间和日期选项的交互组件。本文档介绍日期时间选择器组件的 JSON 结构和相关属性。 + +本文档介绍日期时间选择器组件的 JSON 1.0 结构,要查看新版 JSON 2.0 结构,参考[日期时间选择器](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/date-time-picker)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/ce9b460a1ec219bdd4481fc7fb80463d_2IrvXFZhDp.png?height=188&lazyload=true&maxWidth=400&width=559) + +## 注意事项 + +- 日期时间选择器组件支持飞书 V3.11.0 及以上版本的客户端。在低于该版本的飞书客户端上,表单容器的内容将展示为“当前版本不支持查看此消息”。 +- 在使用日期时间选择器时,你需提醒用户选择与当前场景相对应的时区信息。例如,在预定海外酒店的场景下,一般使用酒店所在地时区;设置日程场景下,一般使用用户当前所在地的时区。开放平台会返回用户当前的时区作为参考,但并不代表用户选择了该时区。 +- 在卡片 JSON 代码中,若日期时间选择器组件直接位于卡片根节点,而非嵌套在其它组件中,你需将其 JSON 数据配置在[交互模块](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/component-list/common-components-and-elements)(`"tag": "action"`)的 `actions` 字段中使用。 + +## 嵌套规则 + +日期时间选择器组件支持嵌套在分栏、表单容器、折叠面板、循环容器中使用。 + +## 组件属性 + +### JSON 结构 + +日期时间选择器组件的 JSON 结构如下所示: +```json +{ + "tag": "picker_datetime", // 日期时间选择器组件的标签。 + "name": "picker_datetime1", // 日期时间选择器组件的唯一标识。当组件内嵌在表单容器中时,该字段生效且必填。用于识别用户提交的数据属于哪个组件。 + "required": false, // 日期时间是否必选。默认值 false。当日期时间选择器内嵌在表单容器时,该属性可用。其它情况将报错或不生效。 + "disabled": false, // 是否禁用该日期时间选择器组件。默认值 false。 + "width": "default", // 日期时间选择器的宽度。 + "initial_datetime": "2024-01-01 11:30", // 日期时间初始值。默认为空。 + "placeholder": { + // 日期时间选择器组件内的占位文本。 + "tag": "plain_text", + "content": "请选择" + }, + "value": { + // 回传数据 + "key_1": "value_1" + }, + "confirm": { + // 二次确认弹窗配置 + "title": { + "tag": "plain_text", + "content": "title" + }, + "text": { + "tag": "plain_text", + "content": "content" + } + } +} +``` + +### 字段说明 + +日期时间选择器组件的字段说明如下表。 + +字段 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | string | / | 组件的标签。日期时间选择器组件取固定值 `picker_datetime`。 +name | 否 | String | 空 | 该日期时间选择器组件的唯一标识。当日期时间选择器内嵌在表单容器时,该属性生效,用于识别用户提交的数据属于哪个组件。
    **注意**: 当日期时间选择器组件嵌套在表单容器中时,该字段必填且需在卡片全局内唯一。 +required | 否 | Boolean | false | 日期时间否必选。当组件内嵌在表单容器中时,该属性可用。其它情况将报错或不生效。可取值:
    - true:日期时间必选。当用户点击表单容器的“提交”时,未填写日期时间,则前端提示“有必填项未填写”,不会向开发者的服务端发起回传请求。
    - false:日期时间选填。当用户点击表单容器的“提交”时,未填写日期时间,仍提交表单容器中的数据。 +disabled | 否 | Boolean | false | 是否禁用该日期时间选择器。该属性仅支持飞书 V7.4 及以上版本的客户端。可选值:
    - true:禁用日期时间选择器组件
    - false:日期时间选择器组件保持可用状态 +initial_datetime | 否 | String | 空 | 日期日期时间选择器组件的初始选项值。格式为 `yyyy-MM-dd HH:mm`。该配置将会覆盖 `placeholder` 配置的占位文本。 +placeholder | 否 | object | / | 日期时间选择器组件内的占位文本。
    **注意**:
    - 未配置 `initial_datetime` 字段设置初始选项值时,该字段必填。
    - 配置 `initial_datetime` 字段设置初始选项值后,该字段不再生效。 +└ tag | 是 | String | plain_text | 占位提示标签。固定值为 plain_text。 +└ content | 否 | String | / | 占位文本的内容,最多支持 100 个字符。 +width | 否 | String | default | 日期时间选择器组件的宽度。支持以下枚举值:
    - default:默认宽度
    - fill:卡片最大支持宽度
    - [100,∞)px:自定义宽度。超出卡片宽度时将按最大支持宽度展示 +value | 是 | JSON | / | 设置交互的回传数据,当用户点击交互组件的选项后,会将 value 的值返回给接收回调数据的服务器。后续你可以通过服务器接收的 value 值进行业务处理。
    该字段值仅支持 key-value 形式的 JSON 结构,且 key 为 String 类型。示例值:
    ```json
    "value":{
    "key-1":Object-1,
    "key-2":Object-2,
    "key-3":Object-3,
    ······
    }
    ``` +confirm | 否 | Struct | 默认不生效此属性。 | 二次确认弹窗配置。指在用户提交时弹出二次确认弹窗提示;只有用户点击确认后,才提交输入的内容。该字段默认提供了确认和取消按钮,你只需要配置弹窗的标题与内容即可。
    **注意**:confirm 字段仅在用户点击包含提交属性的按钮时才会触发二次确认弹窗。 +confirm.title | 是 | Struct | / | 二次确认弹窗标题。 +confirm.title.tag | 是 | String | plain_text | 二次确认弹窗标题文本的标签。固定取值为 `plain_text`。 +confirm.title.content | 是 | String | / | 二次确认弹窗标题的内容。 +confirm.text | 是 | Struct | / | 二次确认弹窗的文本内容。 +confirm.text.tag | 是 | String | plain_text | 二次确认弹窗文本的标签。固定取值为 `plain_text`。 +confirm.text.content | 是 | String | / | 二次确认弹窗文本的具体内容。 + +## 回调结构 + +为组件成功配置交互后,用户基于组件进行交互时,你在开发者后台配置的请求地址将会收到回调数据。 +- 如果你添加的是新版卡片回传交互回调(`card.action.trigger`),可参考[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)了解回调结构。 +- 如果你添加的是旧版卡片回传交互回调(`card.action.trigger_v1`),可参考[消息卡片回传交互(旧)](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/configuring-card-callbacks/card-callback-structure)了解回调结构。 + +## 示例代码 + +以下的 JSON 示例代码可实现如下图所示的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/ce9b460a1ec219bdd4481fc7fb80463d_caioJ5K6gF.png?height=188&lazyload=true&maxWidth=400&width=559) + +```json +{ + "i18n_elements": { + "zh_cn": [ + { + "tag": "action", + "actions": [ + { + "tag": "picker_datetime", + "placeholder": { + "tag": "plain_text", + "content": "请选择" + }, + "width": "default" + } + ] + }, + { + "tag": "action", + "actions": [ + { + "tag": "picker_datetime", + "placeholder": { + "tag": "plain_text", + "content": "请选择" + }, + "width": "default", + "initial_datetime": "2024-01-01 08:00" + } + ] + } + ] + }, + "i18n_header": {} +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__image-picker.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__image-picker.md new file mode 100644 index 0000000..9f7b999 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__image-picker.md @@ -0,0 +1,344 @@ +# 多图选择组件 + +多图选择组件是用于提供图片选项的交互组件,支持单选、多选图片。多图选择组件适用于以图片为主要选项的场景,如在卡片中展示商品图、模板图、AI生成的图片等供用户选择。本文档介绍多图选择组件的 JSON 结构和相关属性。 + +本文档介绍多图选择组件的 JSON 1.0 结构,要查看新版 JSON 2.0 结构,参考[多图选择](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/image-picker)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/3c0451b4d0aadd628e926864bf1857a0_J7nYYdj6jJ.png?height=925&lazyload=true&maxWidth=400&width=1118) + +## 注意事项 + +- 多图选择组件仅支持通过撰写卡片 JSON 代码的方式使用,暂不支持在卡片搭建工具上构建使用。 +- 多图选择组件支持飞书 V7.6 及以上版本的客户端。在低于该版本的飞书客户端上,多图选择的内容将展示为“请升级至最新版本客户端,以查看内容”的占位图。 + +## 嵌套规则 + +多图选择组件可嵌套在卡片的根节点、多列布局、表单容器组件中。在不同的嵌套关系中,多图选择组件支持的交互形态不同: +- 当多图选择组件不内嵌在表单容器中时,多图选择组件仅支持单选图片,且终端用户点击图片选项后立即提交,触发回传交互,不支持多选和异步提交。 +- 当多图选择组件内嵌在表单容器中时,多图选择组件支持单选、多选交互并支持异步提交,即终端用户需选择图片后,点击表单容器的提交按钮,将本地缓存的表单内容一次回调至开发者服务端,实现异步提交。 + +## 组件属性 + +### JSON 结构 + +多图选择组件的 JSON 数据结构如下所示: + +```json +{ + "elements": [ + { + "tag": "select_img", // 组件标签。 + "style": "laser", // 选填,不填为默认样式。声明为 laser 时为镭射样式。 + "multi_select": false, // 是否多选。 + "layout": "bisect", // 选项的布局模式。 + "name": "choice_123", // 自定义多图选择组件的名称作为唯一标识。当组件内嵌在表单容器中时,该字段生效且必填,用于识别用户提交的数据属于哪个组件。 + "required": false, // 多图选择的选项是否必选。当组件内嵌在表单容器中时,该属性可用。其它情况将报错或不生效。 + "can_preview": false, // 点击图片选项后是否弹窗放大图片。当多图选择组件嵌套在表单容器中时,该属性生效。 + "aspect_ratio": "16:9", // 选项中图片的宽高比。 + "disabled": false, // 是否禁用整个选择组件。 + "disabled_tips": { // 指禁用组件后,用户将光标悬浮在整个组件上时展示的禁用提示文案。 + "tag": "plain_text", + "content": "用户禁用提示文案" + }, + "value": { // 自定义回传参数,支持回传字符串,或 "key":"value" 构成的对象结构体。 + "key": "value" + }, + // 选项数组。在此配置多图选择组件中每个图片选项的属性。 + "options": [ + { + "img_key": "xxxxxxxxxxxxxx", // 图片资源的 Key。 + "value": "picture1", // 自定义每个图片选项的回传参数。 + "disabled": false, // 是否禁用当前图片选项。 + "disabled_tips": { // 禁用当前选项后,用户将光标悬浮在选项上或点击选项时展示的禁用提示文案。 + "tag": "plain_text", + "content": "用户禁用提示文案" + }, + "hover_tips": { // 用户在 PC 端将光标悬浮在选项上方时的文案提醒。 + "tag": "plain_text", + "content": "第一张图" + } + } + ] + } + ] +} +``` + +### 字段说明 + +多图选择组件各属性说明如下表所示。 + +字段 | 是否必填 | 类型 | 默认值 | 描述 +---|---|---|---|--- +tag | 是 | String | / | 组件的标签。多图选择的固定取值为 `select_img`。 +style | 否 | String | default | 图片加载等状态时的组件风格样式。可取值:
    - default:默认灰色样式
    - laser:彩色渐变样式,建议 AI 场景使用![示例图](http:////sf3-cn.feishucdn.com/obj/open-platform-opendoc/0ae7b865c1aa37f29d8647f0ea329b38_usdAFosDoT.png?height=163&lazyload=true&width=433) +multi_select | 否 | Boolean | false | 图片是否多选。可选值:
    - true:多选,仅支持异步提交。多图选择组件需内嵌在表单容器中,否则卡片 JSON 报错。
    - false:单选。
    - 组件在表单容器内时,图片选项展示为带单选按钮(radio button)的异步提交样式。
    - 组件不在表单容器内时,图片选项展示为不带单选按钮(radio button)的同步提交样式。 +layout | 否 | String | bisect | 图片选项的布局方式。可选值:
    - stretch:每个选项的图片宽度撑满父容器宽度,高度按图片大小等比例缩放。
    - bisect:二等分排布,每个选项图片宽度占父容器的 1/2,高度按图片大小等比例缩放。
    - trisect:三等分排布,每个选项图片宽度占父容器的 1/3,高度按图片大小等比例缩放。 +name | 否 | String | 空 | 自定义多图选择组件的名称作为唯一标识。用于识别用户提交的数据属于哪个组件。
    **注意**:当多图选择组件嵌套在表单容器中时,该字段生效、必填,且需在卡片全局内唯一。 +required | 否 | Boolean | false | 多图选择的选项是否必选。当组件内嵌在表单容器中时,该属性可用。其它情况将报错或不生效。可取值:
    - true:选项必填。当用户点击表单容器的“提交”时,未选择选项,则前端提示“有必填项未填写”,不会向开发者的服务端发起回传请求。
    - false:选项选填。当用户点击表单容器的“提交”时,未选择选项,仍提交表单容器中的数据。 +can_preview | 否 | Boolean | true | 点击图片选项后是否弹窗放大图片。当多图选择组件嵌套在表单容器中时,该属性生效。
    - true:点击图片后,弹出图片查看器放大查看当前点击的图片。
    - false:点击图片后,响应卡片本身的交互事件,不弹出图片查看器。 +aspect_ratio | 否 | String | 16:9 | 选项中图片的宽高比。图片按最短边撑满图片渲染容器,按照居中裁剪的方式自适应裁剪。可取值:
    - 1:1
    - 16:9
    - 4:3 +disabled | 否 | Boolean | false | 是否禁用整个选择组件。可选值:
    - true:禁用整个选择组件
    - false:选择组件保持可用状态
    +disabled_tips | 否 | Object | 空 | 禁用整个组件后,用户将光标悬浮在整个组件上时展示的禁用提示文案。 +└ tag | 否 | String | plain_text | 禁用提示文本的标签。固定值为 `plain_text`。 +└ content | 否 | String | 空 | 禁用提示文本的内容。 +value | 否 | String 或 Object | 空 | 你可在交互事件中自定义回传参数,支持回传字符串,或 `"key":"value"` 构成的对象结构体。 +options | 是 | Option object | / | 选项数组,用于配置多图选择组件中每个图片选项的属性。 +L img_key | 是 | String | / | 图片资源的 Key。你可以调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口或在搭建工具中上传图片,获取图片的 key。 +L value | 否 | String | 空 | 自定义每个图片选项的回传参数。在回传交互中指定的回传参数将透传至开发者的服务端。 +L disabled | 否 | Boolean | false | 是否禁用某个图片选项。可选值:
    - true:禁用该选项
    - false:选项保持可用状态 +L disabled_tips | 否 | Object | 空 | 禁用某个图片选项后,用户将光标悬浮在选项上或点击选项时展示的禁用提示文案。 +LL tag | 否 | String | plain_text | 禁用提示文本的标签。固定值为 `plain_text`。 +LL content | 否 | String | 空 | 禁用提示文本的内容。 +L hover_tips | 否 | Object | 空 | 用户在 PC 端将光标悬浮在多图选择上方时的文案提醒。默认为空。 +LL tag | 否 | String | plain_text | 悬浮提示文本的标签。固定值为 `plain_text`。 +LL content | 否 | String | 空 | 悬浮提示文本的内容。 + +## 回调结构 + +为组件成功配置交互后,用户基于组件进行交互时,你在开发者后台配置的请求地址将会收到回调数据。 +- 如果你添加的是新版卡片回传交互回调(`card.action.trigger`),可参考[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)了解回调结构。 +- 如果你添加的是旧版卡片回传交互回调(`card.action.trigger_v1`),可参考[消息卡片回传交互(旧)](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/configuring-card-callbacks/card-callback-structure)了解回调结构。 + +## 示例代码 + +### 单选后立即提交选项内容 + +以下示例中,多图选择组件不内嵌在表单容器中,仅支持单选图片。终端用户点击图片选项后,数据将立即提交,触发回传交互。你可将示例代码中的 `img_key` 替换为实际的图片 Key,实现如下图示例的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/3d96fd3eb0f3390e56dc283b9db5d58e_YjtwDw58SW.gif?height=980&lazyload=true&maxWidth=400&width=1144) + +```json +{ + "elements": [ + { + "tag": "select_img", + "name": "select_img-1", + "layout": "bisect", + "aspect_ratio": "16:9", + "disabled": false, + "disabled_tips": { + "tag": "plain_text", + "content": "用户禁用提示文案" + }, + "options": [ + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg", + "value": "picture1", + "disabled": false, + "disabled_tips": { + "tag": "plain_text", + "content": "用户禁用提示文案1" + }, + "hover_tips": { + "tag": "plain_text", + "content": "第一张图" + } + }, + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg", + "value": "picture2", + "disabled": false, + "disabled_tips": { + "tag": "plain_text", + "content": "用户禁用提示文案2" + }, + "hover_tips": { + "tag": "plain_text", + "content": "第二张图" + } + }, + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg", + "value": "picture3", + "disabled": false, + "disabled_tips": { + "tag": "plain_text", + "content": "用户禁用提示文案3" + }, + "hover_tips": { + "tag": "plain_text", + "content": "第三张图" + } + }, + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg", + "value": "picture4", + "disabled": false, + "disabled_tips": { + "tag": "plain_text", + "content": "用户禁用提示文案4" + }, + "hover_tips": { + "tag": "plain_text", + "content": "第四张图" + } + }, + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg", + "value": "picture5", + "disabled": false, + "disabled_tips": { + "tag": "plain_text", + "content": "用户禁用提示文案5" + }, + "hover_tips": { + "tag": "plain_text", + "content": "第五张图" + } + }, + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg", + "value": "picture6", + "disabled": false, + "disabled_tips": { + "tag": "plain_text", + "content": "用户禁用提示文案6" + }, + "hover_tips": { + "tag": "plain_text", + "content": "第六张图" + } + } + ] + } + ] +} +``` + +### 在表单容器中异步提交多选的选项内容 + +以下示例中,多图选择组件内嵌在表单容器中,且为单选交互的异步提交方式。在终端用户选择图片后,数据将缓存至本地;当用户点击表单容器的提交按钮后,本地缓存的所有表单内容将一次回调至开发者服务端,实现异步提交。你可将示例代码中的 `img_key` 替换为实际的图片 Key,实现如下图示例的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/52bf9baf0da30ae73c61479f7bcef232_Td0XUptnVd.gif?height=1140&lazyload=true&maxWidth=400&width=1116) + +```json +{ + "elements": [ + { + "tag": "form", + "name": "form1", + "elements": [ + { + "tag": "select_img", + "multi_select": false, + "name": "select_img-1", + "layout": "bisect", + "can_preview": false, + "aspect_ratio": "16:9", + "disabled": false, + "disabled_tips": { + "tag": "plain_text", + "content": "用户禁用提示文案" + }, + "options": [ + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg", + "value": "picture1", + "disabled": false, + "disabled_tips": { + "tag": "plain_text", + "content": "用户禁用提示文案1" + }, + "hover_tips": { + "tag": "plain_text", + "content": "第一张图" + } + }, + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg", + "value": "picture2", + "disabled": false, + "disabled_tips": { + "tag": "plain_text", + "content": "用户禁用提示文案2" + }, + "hover_tips": { + "tag": "plain_text", + "content": "第二张图" + } + }, + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg", + "value": "picture3", + "disabled": false, + "disabled_tips": { + "tag": "plain_text", + "content": "用户禁用提示文案3" + }, + "hover_tips": { + "tag": "plain_text", + "content": "第三张图" + } + }, + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg", + "value": "picture4", + "disabled": false, + "disabled_tips": { + "tag": "plain_text", + "content": "用户禁用提示文案4" + }, + "hover_tips": { + "tag": "plain_text", + "content": "第四张图" + } + }, + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg", + "value": "picture5", + "disabled": false, + "disabled_tips": { + "tag": "plain_text", + "content": "用户禁用提示文案5" + }, + "hover_tips": { + "tag": "plain_text", + "content": "第五张图" + } + }, + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg", + "value": "picture6", + "disabled": false, + "disabled_tips": { + "tag": "plain_text", + "content": "用户禁用提示文案6" + }, + "hover_tips": { + "tag": "plain_text", + "content": "第六张图" + } + } + ] + }, + { + "tag": "button", + "text": { + "tag": "plain_text", + "content": "提交" + }, + "type": "primary", + "name": "button-submit", + "form_action_type": "submit", + "behaviors": [ + { + "type": "callback", + "value": "form_callback" + } + ] + }, + { + "tag": "button", + "text": { + "tag": "plain_text", + "content": "取消" + }, + "name": "button-cancel", + "form_action_type": "reset" + } + ] + } + ] +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__input.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__input.md new file mode 100644 index 0000000..8512809 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__input.md @@ -0,0 +1,301 @@ +# 输入框组件 + +在使用卡片进行内容收集的场景下,你可能需要同时获取用户的主观内容,如原因、评价、备注等。在这种情况下,你可以使用输入框组件,实现简单的文本内容收集的场景。本文档介绍输入框组件的 JSON 结构和相关属性。 + +本文档介绍输入框组件的 JSON 1.0 结构,要查看新版 JSON 2.0 结构,参考[输入框](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/input)。 +**注意事项**:要结合使用输入框组件与[按钮](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/interactive-components/button)组件,你需将输入框组件与按钮组件内嵌于[表单容器](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/form-container)中。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/5678dab3ae875312a7b55b18067790ca_lLPEqFgVoR.png?height=565&lazyload=true&maxWidth=300&width=696) + +## 注意事项 + +- 输入框仅支持飞书 V6.8 及以上版本的客户端。在低于该版本的飞书客户端上,输入框的内容将默认展示为一句“请升级至最新版本客户端,以查看内容”的占位图。你也可通过卡片的 `fallback` 字段自定义组件的降级展示方式。 +- 在卡片 JSON 代码中,若输入框组件直接位于卡片根节点,而非嵌套在其它组件中,你需将其 JSON 数据配置在[交互模块](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/component-list/common-components-and-elements)(`"tag": "action"`)的 `actions` 字段中使用,并删除 `required` 字段,否则将报错。 + +## 嵌套规则 + +输入框组件支持嵌套在分栏、表单容器、折叠面板、循环容器中使用。在表单容器中,输入框组件的数据为异步提交的形式,即用户填写完所有表单项后,点击表单容器中绑定提交事件的按钮,才会将包括输入框组件的所有数据一次回调至开发者的服务端。 + +## 组件属性 + +### JSON 结构 + +以下为一个输入框的卡片 JSON 数据: +```json +{ + "tag": "input", // 输入框的标签。 + "name": "input1", // 输入框的唯一标识。当输入框内嵌在表单容器时,该属性生效,用于识别用户提交的文本属于哪个输入框。 + "required": false, // 输入框的内容是否必填。当输入框内嵌在表单容器时,该属性可用。其它情况将报错或不生效。 + "placeholder": { + // 输入框中的占位文本。 + "tag": "plain_text", + "content": "请输入" + }, + "default_value": "demo", // 输入框中为用户预填写的内容。 + "disabled": false, // 是否禁用该输入框组件。默认值 false。 + "width": "default", // 输入框的宽度。 + "max_length": 5, // 输入框可容纳的最大文本长度。默认值 1000。 + "input_type":"multiline_text",//指定输入框的输入类型。默认为 text,即文本类型。 + "rows":1, // 当输入类型为多行文本时,输入框的默认展示行数。 + "auto_resize":true, // 当输入类型为多行文本时,输入框高度是否自适应文本高度。仅在 PC 端生效。 + "max_rows":5, // 输入框的最大展示行数。仅当 `auto_resize` 为 true 时有效。 + "show_icon":false, // 当输入类型为密码类型时,是否展示前缀图标。 + "label": { + // 文本标签,即对输入框的描述,用于提示用户要填写的内容。 + "tag": "plain_text", + "content": "请输入文本:" + }, + "label_position": "left", // 文本标签的位置。默认值 top。 + "value": { + // 回传数据,支持 string 或 object 数据类型。 + "k": "v" + }, + "confirm": { + // 二次确认弹窗配置。 + "title": { + "tag": "plain_text", + "content": "title" + }, + "text": { + "tag": "plain_text", + "content": "content" + } + }, + "fallback": { + // 设置输入框组件的降级文案。 + "tag": "fallback_text", // 降级文案的标签。 + "text": { + "content": "自定义声明", // 自定义降级文案的具体内容。 + "tag": "plain_text" // 降级文案内容的标签。 + } + } +} +``` + +### 字段说明 + +输入框组件各字段说明如下表所示: + +字段名称 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | String | 空 | 输入框的标签。固定值为 `input`。 +name | 否 | String | 空 | 输入框的唯一标识。当输入框内嵌在表单容器时,该属性生效,用于识别用户提交的文本属于哪个输入框。
    **注意**:当输入框组件嵌套在表单容器中时,该字段必填且需在卡片全局内唯一。 +required | 否 | Boolean | false | 输入框的内容是否必填。当输入框内嵌在表单容器时,该属性可用。其它情况将报错或不生效。可取值:
    - true:输入框必填。当用户点击表单容器的“提交”时,未填写输入框,则前端提示“有必填项未填写”,不会向开发者的服务端发起回传请求。
    - false:输入框选填。当用户点击表单容器的“提交”时,未填写输入框,仍提交表单容器中的数据。 +disabled | 否 | Boolean | false | 是否禁用该输入框。该属性仅支持飞书 V7.4 及以上版本的客户端。可选值:
    - true:禁用输入框组件
    - false:输入框组件保持可用状态 +placeholder | 否 | text 结构体 | / | 输入框中的占位文本。 +└ tag | 否 | String | plain_text | 占位文本的标签。固定值为 plain_text。 +└ content | 否 | String | 请输入 | 占位文本的内容,最多支持 100 个字符。例如:“请输入内容”。 +default_value | 否 | String | 默认不生效此属性。 | 输入框中为用户预填写的内容。展示为用户在输入框中输入文本后待提交的样式。 +width | 否 | String | default | 输入框的宽度。支持以下枚举值:
    - default:默认宽度
    - fill:卡片最大支持宽度
    - [100,∞)px:自定义宽度。超出卡片宽度时将按最大支持宽度展示 +max_length | 否 | Number | 1,000 | 输入框可容纳的最大文本长度,可取 1~1,000 范围内的整数。当用户输入的文本字符数超过最大文本长度,组件将报错提示。 +input_type | 否 | String | text | 指定输入框的输入类型。默认为 text,即文本类型。支持以下枚举值:
    - text:普通文本
    - multiline_text:多行文本,即可输入包含换行符的多行文本内容。换行符在回调中以 `\n` 返回
    - password:密码。用户输入的文本内容将以“•”显示 +show_icon | 否 | Boolean | true | 当输入类型为密码类型时,是否展示如下所示的前缀图标。仅当 `input_type` 为 password 时有效。
    ![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/3cb2d826d9e86ce6e260b0e78c23c830_wWBdvVSdSu.png?height=74&lazyload=true&width=450) +rows | 否 | Number | 5 | 当输入类型为多行文本时,输入框的默认展示行数。仅当 `input_type` 为 multiline_text 时有效。 +auto_resize | 否 | Boolean | false | 当输入类型为多行文本时,输入框高度是否自适应文本高度。仅在 PC 端生效。仅当 `input_type` 为 multiline_text 时有效。可选值:
    - `true`:输入框高度自适应输入框内的文本高度
    - `false`:输入框高度固定为 `rows` 属性指定的高度,不随输入框中的内容变化而变化。 +max_rows | 否 | Number | 空 | 输入框的最大展示行数。仅当 `auto_resize` 为 true 时有效。
    注意:
    - 取值为大于等于 1 的整数。否则,小于 1 则自动取 1,不为整数则四舍五入取整。
    - 取值为空时不限制输入框的最大文本展示高度(默认值),但前端渲染时,输入框可展示的最大高度不超过 x 行。 +label | 否 | text 结构体 | 默认不生效此属性。 | 文本标签,即对输入框的描述,用于提示用户要填写的内容。多用于表单容器中内嵌的输入框组件。 +└ tag | 否 | String | plain_text | 输入框描述的标签。固定取值为 plain_text。 +└ content | 否 | String | / | 描述的内容。 +label_position | 否 | String | top | 文本标签的位置。可取值:
    - top:文本标签位于输入框上方
    - left:文本标签位于输入框左边
    **注意**:
    在移动端等窄屏幕场景下,文本标签将自适应固定展示在输入框上方。 +value | 否 | String 或 Object | 空 | 你可在交互事件中自定义回传数据,支持 string 或 object 数据类型。 +confirm | 否 | Struct | 默认不生效此属性。 | 二次确认弹窗配置。指在用户提交时弹出二次确认弹窗提示;只有用户点击确认后,才提交输入的内容。该字段默认提供了确认和取消按钮,你只需要配置弹窗的标题与内容即可。
    **注意**:confirm 字段仅在用户点击包含提交属性的按钮时才会触发二次确认弹窗。 +└ title | 是 | Struct | / | 二次确认弹窗标题。 +└ └ tag | 是 | String | plain_text | 二次确认弹窗标题文本的标签。固定取值为 plain_text。 +└ └ content | 是 | String | / | 二次确认弹窗标题的内容。 +└ text | 是 | Struct | / | 二次确认弹窗标题的内容。 +└ └ tag | 是 | String | plain_text | 二次确认弹窗文本的标签。固定取值为 plain_text。 +└ └ content | 是 | String | / | 二次确认弹窗文本的具体内容。 +fallback | 否 | Fallback Object | / | 设置输入框组件的降级文案。由于输入框仅支持飞书 V6.8 及以上版本的客户端,你需选择在低于此版本的客户端上,该组件的降级展示方式:
    - 不填写该字段,使用系统默认的降级文案:“请升级至最新版本客户端,以查看内容”
    - `"drop"`:填写 `"drop"`,在旧版本客户端上直接丢弃该输入框组件
    - 使用 text 文本对象自定义降级文案 +└ tag | 否 | String | fallback_text | 降级文案的标签,固定取值为 `fallback_text`。 +└ text | 否 | Struct | / | 降级文案的内容。 +└ └ tag | 否 | String | plain_text | 降级文案内容的标签,固定取值为 `plain_text`。 +└ └ content | 否 | String | 空 | 自定义降级文案的具体内容。 + +### 回调结构 + +使用输入框组件,你需要使卡片具备交互能力,详情参考[配置卡片交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/configuring-card-interactions)。配置成功后,用户点击输入框中的提交按钮后,将回传如下所示的交互事件。若输入框内嵌在表单容器中,你可参考[表单容器](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/form-container)的回调结构了解输入框回调。你也可参考[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)了解更多参数说明。 +```json +{ + "schema": "2.0", // 回调的版本 + "header": { // 回调基本信息 + "event_id": "f7984f25108f8137722bb63c*****", // 回调的唯一标识 + "token": "066zT6pS4QCbgj5Do145GfDbbag*****", // 应用的 Verification Token + "create_time": "1603977298000000", // 回调发送的时间,接近回调发生的时间 + "event_type": "card.action.trigger", // 回调类型卡片交互场景中,固定为 "card.action.trigger" + "tenant_key": "2df73991750*****", // 应用归属的 tenant key,即租户唯一标识 + "app_id": "cli_a5fb0ae6a4******" // 应用的 App ID + }, + "event": { // 回调的详细信息 + "operator": { // 回调触发者信息 + "tenant_key": "2df73991750*****", // 回调触发者的 tenant key,即租户唯一标识 + "user_id": "867*****", // 回调触发者的 user ID。当应用开启“获取用户 user ID”权限后,该参数返回 + "open_id": "ou_3c14f3a59eaf2825dbe25359f15*****" // 回调触发者的 Open ID + }, + "token": "c-295ee57216a5dc9de90fefd0aadb4b1d7d******", // 更新卡片用的凭证,有效期为 30 分钟,最多可更新 2 次 + "action": { // 用户操作交互组件回传的数据 + "value": { // 交互事件中的自定义回传数据,对应组件中的 value 属性 + "key": "value" + }, + "tag": "input", // 输入框组件的标签 + "input_value": "Zhang Min" //输入框中用户提交的数据 + "name": "Input_lf4fmxwfrd9" // 输入框组件 name,即搭建工具中的组件 ID,可自定义 + }, + "host": "im_message", // 卡片展示场景 + "context": { // 卡片展示场景相关信息 + "open_message_id": "om_574d639e4a44e4dd646eaf628e2*****", // 卡片所在的消息 ID + "open_chat_id": "oc_e4d2605ca917e695f54f11aaf56*****" // 卡片所在的会话 ID + } + } +} +``` + +## 示例代码 + +以下的 JSON 示例代码可实现如下图所示的卡片效果。该卡片由一个表单容器和内嵌的三个输入框组件组成: + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/5678dab3ae875312a7b55b18067790ca_dVmySAYLmB.png?height=565&lazyload=true&maxWidth=400&width=696) + +```json +{ + "config": { + "width_mode": "compact" + }, + "card_link": { + "url": "", + "pc_url": "", + "ios_url": "", + "android_url": "" + }, + "i18n_elements": { + "zh_cn": [ + { + "tag": "form", + "elements": [ + { + "tag": "input", + "placeholder": { + "tag": "plain_text", + "content": "请输入" + }, + "default_value": "", + "width": "default", + "label": { + "tag": "plain_text", + "content": "用户名:" + }, + "name": "Input_31q6mtuvdx9", + "fallback": { + "tag": "fallback_text", + "text": { + "tag": "plain_text", + "content": "仅支持在 V6.8 及以上版本使用" + } + } + }, + { + "tag": "input", + "input_type": "password", + "placeholder": { + "tag": "plain_text", + "content": "请输入" + }, + "default_value": "", + "width": "default", + "label": { + "tag": "plain_text", + "content": "密码:" + }, + "label_position": "top", + "name": "Input_5hez3q41fck", + "fallback": { + "tag": "fallback_text", + "text": { + "tag": "plain_text", + "content": "仅支持在 V6.8 及以上版本使用" + } + } + }, + { + "tag": "input", + "input_type": "multiline_text", + "rows": 4, + "auto_resize": true, + "placeholder": { + "tag": "plain_text", + "content": "请输入" + }, + "default_value": "", + "width": "default", + "label": { + "tag": "plain_text", + "content": "收货地址:" + }, + "name": "Input_u2k3lbrokvd", + "fallback": { + "tag": "fallback_text", + "text": { + "tag": "plain_text", + "content": "仅支持在 V6.8 及以上版本使用" + } + } + }, + { + "tag": "column_set", + "flex_mode": "none", + "background_style": "default", + "horizontal_spacing": "default", + "columns": [ + { + "tag": "column", + "width": "auto", + "vertical_align": "top", + "elements": [ + { + "tag": "button", + "text": { + "tag": "plain_text", + "content": "提交" + }, + "type": "primary", + "complex_interaction": true, + "action_type": "form_submit", + "name": "Button_lrocopxs" + } + ] + }, + { + "tag": "column", + "width": "auto", + "vertical_align": "top", + "elements": [ + { + "tag": "button", + "text": { + "tag": "plain_text", + "content": "取消" + }, + "type": "default", + "complex_interaction": true, + "action_type": "form_reset", + "name": "Button_lrocopxt" + } + ] + } + ], + "margin": "0px" + } + ], + "name": "Form_lrocopxr", + "fallback": { + "tag": "fallback_text", + "text": { + "tag": "plain_text", + "content": "仅支持在 V6.6 及以上版本使用" + } + } + } + ] + }, + "i18n_header": {} +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__multi-select-dropdown-menu.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__multi-select-dropdown-menu.md new file mode 100644 index 0000000..1e7a8c4 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__multi-select-dropdown-menu.md @@ -0,0 +1,264 @@ +# 下拉选择-多选组件 + +下拉选择-多选组件支持自定义多选菜单的选项文本、图标和回传参数,是一种交互组件,需嵌入在表单容器中使用。本文档介绍下拉选择-多选组件的 JSON 结构和相关属性。 + +本文档介绍下拉选择-多选组件的 JSON 1.0 结构,要查看新版 JSON 2.0 结构,参考[下拉选择-多选](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/multi-select-dropdown-menu)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/4be44d6bee1193690adb76ddbf6271ee_41d9tuYXZd.gif?height=208&lazyload=true&maxWidth=400&width=780) + +## 注意事项 + +下拉选择-多选组件支持飞书 V7.4 及以上版本的客户端。在低于该版本的飞书客户端上,下拉选择-多选组件的内容将展示为“请升级至最新版客户端以查看操作”。 + +## 嵌套规则 + +下拉选择-多选组件仅支持嵌入在表单容器中使用,通过表单容器的“提交”按钮提交选择的内容。了解表单容器及其交互配置,参考[表单容器](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/form-container)。 + +## 组件属性 + +### JSON 结构 + +下拉选择-多选组件的 JSON 数据结构如下所示: +```json +{ + "tag": "multi_select_static", // 组件标签。 + "type": "default", // 组件边框样式。默认值 default。 + "name":"multi_select_departments", // 表单容器中组件的自定义唯一标识,当多选组件内嵌在表单容器时,该属性生效,用于识别用户提交的是哪个组件的数据。 + "required": true, // 选项是否必填。当多选组件内嵌在表单容器时,该属性可用。其它情况将报错或不生效。 + "disabled": false, // 选项是否禁用。 + "placeholder": { + // 下拉选择组件内的占位文本。 + "tag": "plain_text", + "content": "默认提示文本" + }, + "width": "default", // 下拉选择组件的宽度。 + "selected_values": [], // 选项初始值。数组项的值需要和 options.value 对应。 + "options": [ + // 选项配置 + { + "text": { + // 选项名称 + "tag": "plain_text", + "content": "我是交互组件" + }, + "icon": { + // 添加图标作为选项前缀图标。支持自定义或使用图标库中的图标。 + "tag": "standard_icon", // 图标类型。 + "token": "chat-forbidden_outlined", // 图标的 token。仅在 tag 为 standard_icon 时生效。 + "color": "orange", // 图标颜色。仅在 tag 为 standard_icon 时生效。 + "img_key": "img_v2_38811724" // 图片的 key。仅在 tag 为 custom_icon 时生效。 + }, + "value": "selectDemo1" // 选项回调值,支持 string 类型数据。 + } + ], +} +``` + +### 字段说明 + +下拉选择-多选组件的字段说明如下表。 + +字段 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | String | / | 组件的标签。下拉选择-多选组件取固定值 `multi_select_static`。 +type | 否 | String | default | 组件边框样式。可选值:
    - default:带边框样式
    - text:不带边框的纯文本样式 +name | 是 | string | 空 | 表单容器中组件的唯一标识。当多选组件内嵌在表单容器时,该属性生效,用于识别用户提交的数据属于哪个组件。
    **注意**:当多选组件嵌套在表单容器中时,该字段必填且需在卡片全局内唯一。 +placeholder | 否 | Object | 空 | 用户未选择选项时,下拉选择组件内的占位文本。 +└ tag | 是 | String | plain_text | 占位提示的标签。固定值为 `plain_text`。 +└ content | 否 | String | 请选择 | 占位文本的内容,最多支持 100 个字符。 +width | 否 | String | default | 下拉选择组件的宽度。支持以下枚举值:
    - default:默认宽度:
    - 当组件带边框时(即 `"type":"default"`),默认宽度值固定为 282 px
    - 当组件不带边框时(即 `"type":"text"`),组件宽度自适应选择器的内容宽度
    - fill:组件宽度将撑满父容器宽度
    - [100,∞)px:自定义固定数值宽度,如 200px。最小值为 100px。超出父容器宽度时,按撑满父容器宽度展示 +required | 否 | Bool | true | 多选组件的选项是否必选。当组件内嵌在表单容器中时,该属性可用。其它情况将报错或不生效。可取值:
    - true:多选组件必选。当用户点击表单容器的“提交”时,未选择多选选项,则前端提示“有必填项未填写”,不会向开发者的服务端发起回传请求。
    - false:多选组件可选。当用户点击表单容器的“提交”时,未选择多选选项,仍提交表单容器中的数据。 +disabled | 否 | Bool | false | 是否禁用该多选组件。可选值:
    - true:禁用该多选组件,组件展示自定义的占位文本或选项初始值,且终端用户不可修改交互
    - false:多选组件保持可用状态 +selected_values | 否 | Array of string | 空 | 多选组件默认选中的选项。数组项的值需要和 `options.value` 对应。 +options | 否 | Array of objects | / | 选项值配置。按选项数组的顺序展示选项内容。 +└ text | 是 | Object | 空 | 选项名称。为空时展示空白选项。JSON 结构如下所示,使用 plain text 对象描述:
    ```json
    "text": {
    // 选项名称标签。固定值为 plain_text。
    "tag": "plain_text",
    // 选项名称文本。
    "content": "我是一个选项"
    }
    ``` +└ icon | 否 | Object | / | 添加图标作为选项前缀图标。支持自定义或使用图标库中的图标。 +└ └ tag | 否 | String | / | 图标类型的标签。可取值:
    - `standard_icon`:使用图标库中的图标。
    - `custom_icon`:使用自定义图片作为图标。 +└ └ token | 否 | String | / | 图标库中图标的 token。当 `tag` 为 `standard_icon` 时生效。枚举值参见[图标库](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-icons)。 +└ └ color | 否 | String | / | 图标的颜色。支持设置线性和面性图标(即 token 末尾为 `outlined` 或 `filled` 的图标)的颜色。当 `tag` 为 `standard_icon` 时生效。枚举值参见[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。 +└ └ img_key | 否 | String | / | 自定义前缀图标的图片 key。当 `tag` 为 `custom_icon` 时生效。
    图标 key 的获取方式:调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口,上传用于发送消息的图片,并在返回值中获取图片的 image_key。 +└ value | 是 | String | / | 自定义选项回调值。当用户点击交互组件的选项后,会将 value 的值返回给接收回调数据的服务器。后续你可以通过服务器接收的 value 值进行业务处理。
    **注意**:同一个选择组件内,各选项的 value 值不可重复,否则将无法识别用户点击的是哪个选项。 + +### 回调结构 + +当用户点击表单容器的提交按钮时,你在开发者后台配置的请求地址将会收到如下结构的回调数据。详情参考[表单容器](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/form-container)和[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)。 + +- 如果你添加的是新版卡片回传交互回调(`card.action.trigger`),回调数据的结构如下: + +```json + { + "schema": "2.0", + "header": { + "event_id": "f7984f25108f8137722bb63cee927e66", + "token": "066zT6pS4QCbgj5Do145GfDbbagCHGgF", + "create_time": "1603977298000000", + "event_type": "card.action.trigger", + "tenant_key": "xxxxxxx", + "app_id": "cli_xxxxxxxx" + }, + "event":{ + "operator": { + "tenant_key": "xxxxxxx", + "user_id": "xxxxxxx", + "open_id": "ou_xxx" + }, + "token": "c-xxxx", + "action": { // 表单容器“提交”按钮本身配置的回传交互的值 + "value": { + "key": "value" + }, + "tag": "button", + "name":"form_submit", // 表单容器中,“提交”按钮组件本身的回传属性 + "form_value": { // 表单容器中各组件的返回值 + "multi_select_departments":[ // 表单容器中下拉选择-多选组件的自定义标识 + "selectDemo1", // options.value 的值,用于判断用户选择的是哪个选项 + "selectDemo2" + ] + } + }, + "host": "im_message", + "context": { + "open_message_id":"om_xxx", + "open_chat_id":"oc_xxx" + } + } + } + ``` +- 如果你添加的是旧版卡片回传交互回调(`card.action.trigger_v1`),回调数据的结构如下: + +```json + { + "open_id": "ou_sdfimx9948345", + "user_id": "eu_sd923r0sdf5", + "open_message_id": "om_abcdefg1234567890", + "tenant_key": "d32004232", + "token": "c-xxxxx", + "action": + { + "value":{ + "key":"value" + }, + "tag": "button", + "name": "form_submit",// 自定义的按钮的唯一标识 + "form_value": { + "multi_select_departments":[ + "selectDemo1", // options.value 的值,用于判断用户选择的是哪个选项 + "selectDemo2" + ] + } + } + } + ``` +## 示例代码 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/4be44d6bee1193690adb76ddbf6271ee_af1qOua3DK.gif?height=208&lazyload=true&maxWidth=400&width=780) +```json +{ + "elements": [ + { + "tag": "form", + "elements": [ + { + "tag": "column_set", + "flex_mode": "none", + "horizontal_spacing": "default", + "background_style": "default", + "columns": [ + { + "tag": "column", + "elements": [ + { + "tag": "multi_select_static", + "type": "default", + "name": "multi_select_departments", + "placeholder": { + "tag": "plain_text", + "content": "默认提示文本" + }, + "width": "fill", + "required": true, + "disabled": false, + "selected_values": [], + "options": [ + { + "text": { + "tag": "plain_text", + "content": "选项1" + }, + "icon": { + "tag": "standard_icon", + "token": "chat-forbidden_outlined", + "color": "orange" + }, + "value": "selectDemo1" + }, + { + "text": { + "tag": "plain_text", + "content": "选项2" + }, + "icon": { + "tag": "standard_icon", + "token": "chat-forbidden_outlined", + "color": "orange" + }, + "value": "selectDemo2" + } + ] + } + ], + "width": "weighted", + "weight": 1 + } + ] + }, + { + "tag": "column_set", + "flex_mode": "none", + "background_style": "default", + "horizontal_spacing": "default", + "columns": [ + { + "tag": "column", + "width": "auto", + "vertical_align": "top", + "elements": [ + { + "tag": "button", + "text": { + "tag": "plain_text", + "content": "提交" + }, + "type": "primary", + "complex_interaction": true, + "action_type": "form_submit", + "name": "Button_lrztw8x3" + } + ] + }, + { + "tag": "column", + "width": "auto", + "vertical_align": "top", + "elements": [ + { + "tag": "button", + "text": { + "tag": "plain_text", + "content": "取消" + }, + "type": "default", + "complex_interaction": true, + "action_type": "form_reset", + "name": "Button_lrztw8x4" + } + ] + } + ] + } + ], + "name": "Form_lrztw8x2" + } + ] +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__multi-select-user-picker.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__multi-select-user-picker.md new file mode 100644 index 0000000..a68bc74 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__multi-select-user-picker.md @@ -0,0 +1,233 @@ +# 人员选择-多选组件 + +人员选择-多选组件支持添加指定人员作为多选选项。多选组件是一种交互组件,需嵌入在表单容器中使用。本文档介绍人员选择-多选组件的 JSON 结构和相关属性。 + +本文档介绍人员选择-多选组件的 JSON 1.0 结构,要查看新版 JSON 2.0 结构,参考[人员选择-多选](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/multi-select-user-picker)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/d72dbde0992982fadc50eb68979a9a1b_aueLESGXfe.gif?height=216&lazyload=true&maxWidth=500&width=792) + +## 注意事项 + +人员选择-多选组件支持飞书 V7.4 及以上版本的客户端。在低于该版本的飞书客户端上,人员选择-多选组件的内容将展示为“请升级至最新版客户端以查看操作”。 +## 嵌套规则 + +人员选择-多选组件仅支持嵌入在表单容器中使用,通过表单容器的“提交”按钮提交选择的内容。了解表单容器及其交互配置,参考[表单容器](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/form-container)。 + +## 组件属性 + +### JSON 结构 + +人员选择-多选组件的 JSON 数据结构如下所示: +```json +{ + "tag": "multi_select_person", // 组件的标签。 + "type": "text", // 组件边框样式。默认值 default。 + "name":"multi_select_users", // 表单容器中组件的自定义标识,用于识别用户提交的是哪个组件的数据。 + "placeholder": { + // 人员选择组件内的占位文本。 + "tag": "plain_text", + "content": "默认提示文本" + }, + "width": "default", // 下拉选择组件的宽度。 + "required":true, // 选项是否必填。 + "disabled":false, // 选项是否禁用。 + "selected_values": ["ou_48d0958ee4b2ab3eaf0b5f6c968xxxxx"], // 组件默认选中的选项。数组项的值需要和 options.value 对应。 + "options": [ + // 选项配置,仅支持添加候选用户的 open_id。 + { + "value": "ou_48d0958ee4b2ab3eaf0b5f6c968xxxxx" + }, + { + "value": "ou_f9d24af786a14340721288cda6axxxxx" + } + ] +} +``` + +### 字段说明 + +人员选择-多选组件的字段说明如下表。 + +字段 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | String | / | 组件的标签。人员选择-多选组件取固定值 `multi_select_person`。 +type | 否 | String | default | 组件边框样式。可选值:
    - default:带边框样式
    - text:不带边框的纯文本样式 +name | 是 | String | 空 | 表单容器中组件的唯一标识。用于识别用户提交的数据属于哪个组件。在同一张卡片内,该字段的值全局唯一。 +required | 否 | Boolean | false | 多选组件的内容是否必选。当组件内嵌在表单容器中时,该属性生效。可取值:
    - true:多选组件必选。当用户点击表单容器的“提交”时,未填写多选组件,则前端提示“有必填项未填写”,不会向开发者的服务端发起回传请求。
    - false:多选组件选填。当用户点击表单容器的“提交”时,未填写多选组件,仍提交表单容器中的数据。 +disabled | 否 | Boolean | false | 是否禁用该多选组件。可选值:
    - true:禁用多选组件
    - false:多选组件保持可用状态 +placeholder | 否 | Object | / | 人员选择组件内的占位文本。 +└ tag | 是 | String | plain_text | 占位提示标签。固定值为 plain_text。 +└ content | 否 | String | / | 占位文本的内容,最多支持 100 个字符。 +width | 否 | String | default | 人员选择组件的宽度。支持以下枚举值:
    - default:默认宽度
    - fill:卡片最大支持宽度
    - [100,∞)px:自定义宽度。超出卡片宽度时将按最大支持宽度展示 +selected_values | 否 | Array of objects | 空 | 多选组件默认选中的选项。数组项的值需要和 `options.value` 对应。 +options | 否 | Array of objects | / | 选项值配置。按选项数组的顺序展示选项内容。 +└ value | 否 | String | 空 | 选项配置,仅支持添加候选用户的 open_id。了解更多,参考[如何获取不同的用户 ID](https://open.feishu.cn/document/home/user-identity-introduction/open-id)。
    **注意**:当 options 数组为空,或 value 的值全部无效时,候选项展示为卡片所在会话中所有成员选项。 + +## 回调结构 + +当用户点击表单容器的提交按钮时,你在开发者后台配置的请求地址将会收到如下结构的回调数据。 + +- 如果你添加的是新版卡片回传交互回调(`card.action.trigger`),回调数据的结构如下所示。详细参数说明可参考[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)了解回调结构。 +```json +{ + "schema": "2.0", + "header": { + "event_id": "f7984f25108f8137722bb63cee927e66", + "token": "066zT6pS4QCbgj5Do145GfDbbagCHGgF", + "create_time": "1603977298000000", + "event_type": "card.action.trigger", + "tenant_key": "xxxxxxx", + "app_id": "cli_xxxxxxxx" + }, + "event":{ + "operator": { + "tenant_key": "xxxxxxx", + "user_id": "xxxxxxx", + "open_id": "ou_xxx" + }, + "token": "c-xxxx", + "action": { //表单容器“提交”按钮本身配置的回传交互 value + "value": { + "key": "value" + }, + "tag": "button", + "name":"form_submit", // 表单容器中,“提交”按钮组件本身的回传属性 + "form_value": { // 表单容器中各组件的返回值 + "multi_select_person":[ // 多选组件的 name 属性 + "123123123123", // 数组返回多选选项内容 + "223123123123" + ] + } + }, + "host": "im_message", + "context": { + "open_message_id":"om_xxx", + "open_chat_id":"oc_xxx" + } + } +} +``` +- 如果你添加的是旧版卡片回传交互回调(`card.action.trigger_v1`),回调数据的结构如下所示。详细参数说明可参考[消息卡片回传交互(旧)](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/configuring-card-callbacks/card-callback-structure)了解回调结构。 +```json +{ + "open_id": "ou_sdfimx9948345", + "user_id": "eu_sd923r0sdf5", + "open_message_id": "om_abcdefg1234567890", + "tenant_key": "d32004232", + "token": "c-xxxxx", + "action": + { + "value":{ + "key":"value" + }, + "tag": "button", + "name": "form_submit", //按钮的唯一标识 + "form_value": { + "multi_select_person":[ + "123123123123", // 数组返回提交多选的用户id信息 + "223123123123" + ] + } + } +} +``` +## 示例代码 + +将以下 JSON 示例代码中 value 的值替换为实际的用户的 `open_id`,可实现如下图所示的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/d72dbde0992982fadc50eb68979a9a1b_1I2B5ld2QB.gif?height=216&lazyload=true&maxWidth=500&width=792) + +```json +{ + "elements": [ + { + "tag": "form", + "elements": [ + { + "tag": "column_set", + "flex_mode": "none", + "horizontal_spacing": "default", + "background_style": "default", + "columns": [ + { + "tag": "column", + "elements": [ + { + "tag": "multi_select_person", + "type": "default", + "name": "multi_select_users", + "placeholder": { + "tag": "plain_text", + "content": "请选择" + }, + "width": "fill", + "required": true, + "disabled": false, + "selected_values": [ + "ou_48d0958ee4b2ab3eaf0b5f6c968xxxxx" + ], + "options": [ + { + "value": "ou_48d0958ee4b2ab3eaf0b5f6c968xxxxx" + }, + { + "value": "ou_f9d24af786a14340721288cda6axxxxx" + } + ] + } + ], + "width": "weighted", + "weight": 1 + } + ] + }, + { + "tag": "column_set", + "flex_mode": "none", + "background_style": "default", + "horizontal_spacing": "default", + "columns": [ + { + "tag": "column", + "width": "auto", + "vertical_align": "top", + "elements": [ + { + "tag": "button", + "text": { + "tag": "plain_text", + "content": "提交" + }, + "type": "primary", + "complex_interaction": true, + "action_type": "form_submit", + "name": "Button_lrztw8x3" + } + ] + }, + { + "tag": "column", + "width": "auto", + "vertical_align": "top", + "elements": [ + { + "tag": "button", + "text": { + "tag": "plain_text", + "content": "取消" + }, + "type": "default", + "complex_interaction": true, + "action_type": "form_reset", + "name": "Button_lrztw8x4" + } + ] + } + ] + } + ], + "name": "Form_lrztw8x2" + } + ] +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__overflow.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__overflow.md new file mode 100644 index 0000000..0a0287a --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__overflow.md @@ -0,0 +1,224 @@ +# 折叠按钮组组件 + +折叠按钮组支持添加多个按钮并将其折叠。点击按钮组将会展示组内所有按钮。本文档介绍折叠按钮组组件的 JSON 结构和相关属性。 + +本文档介绍折叠按钮组组件的 JSON 1.0 结构,要查看新版 JSON 2.0 结构,参考[折叠按钮组](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/overflow)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/dded93a79c281088c33102b2af4fea31_ubaZ7yDL26.png?height=206&lazyload=true&maxWidth=500&width=847) + +## 注意事项 + +- 折叠按钮组(overflow)最低支持的飞书版本为 V3.7.0,如果低于该版本,用户使用该组件时会提示 **当前版本不支持查看此消息**。 +- 在卡片 JSON 代码中,若折叠按钮组组件直接位于卡片根节点,而非嵌套在其它组件中,你需将其 JSON 数据配置在[交互模块](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/component-list/common-components-and-elements)(`"tag": "action"`)的 `actions` 字段中使用。 + +## 嵌套规则 + +按钮组件支持嵌套在表单容器、折叠面板、循环容器中使用。 + +## 组件属性 + +### JSON 结构 + +以下为一个折叠按钮组的卡片 JSON 数据: +```json +{ + "tag": "overflow", + "width": "fill", // 折叠按钮组的宽度。默认值为 default。 + "options": [ + // 在此添加折叠按钮组当中的选项按钮。 + { // 为按钮添加文本。 + "text": { + "tag": "plain_text", // 文本的标签。固定值为 plain_text。 + "content": "这是一个链接跳转" // 文本的内容,最多支持 100 个字符。 + }, + "multi_url": { // 为按钮添加跳转链接。 + "url": "https://open.feishu.cn/document/home/index", // 兜底的跳转地址。 + "pc_url": "", + "ios_url": "", + "android_url": "" + }, + "value": "document" // 该按钮的回传参数值。当用户点击选项后,应用会将该值返回至卡片请求地址。 + } + ], + "behaviors": [ // 当用户点击折叠按钮组内的任意按钮后,除按钮本身回传数据的以外,还可通过 behaviors 参数回传更多数据。 + { + "type": "callback", // 声明交互类型是回传数据到服务端的回传交互。 + "value": { + // 开发者自定义的回传交互数据。支持 object 数据类型。开放平台 SDK 仅支持 object 类型的回传交互数据。 + "key": "value" + } + } + ], + "value": { + // 历史属性。可使用 behaviors 参数代替。 + "key_1": "value_1" + }, + "confirm": { + // 二次确认弹窗配置 + "title": { + "tag": "plain_text", + "content": "title" + }, + "text": { + "tag": "plain_text", + "content": "content" + } + } +} +``` + +### 字段说明 + +折叠按钮组组件各字段说明如下表所示: + +字段名称 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | String | / | 折叠按钮组的标签。固定值为 `overflow`。 +width | 否 | String | default | 折叠按钮组的宽度。支持以下枚举值:
    - default:默认宽度
    - fill:卡片最大支持宽度
    - [100,∞)px:自定义宽度。超出卡片宽度时将按最大支持宽度展示 +options | 是 | Struct[] | 空 | 折叠按钮组当中的选项按钮。详见下文 `options` 字段说明。 +behaviors | 否 | Array | 空 | 当用户点击折叠按钮组内的任意按钮后,除按钮本身的回传数据以外,还可通过 behaviors 参数回传更多数据。配置示例如下:
    ```json
    {
    "behaviors": [
    {
    "type": "callback", // 声明交互类型是回传数据到服务端的请求回调交互。
    "value": {
    // 回传交互数据。支持 object 数据类型。开放平台 SDK 仅支持 object 类型的回传交互数据。
    "key_1": "value_1" // 示例数据。
    }
    }
    ]
    }
    ``` +confirm | 否 | Struct | 默认不生效此属性。 | 二次确认弹窗配置。指在用户提交时弹出二次确认弹窗。
    **提示**:该字段默认提供了确认和取消按钮,你只需要配置弹窗的标题与内容即可。 +└ title | 是 | Struct | / | 二次确认弹窗标题。 +└ └ tag | 是 | String | plain_text | 二次确认弹窗标题文本的标签。固定取值为 plain_text。 +└ └ content | 是 | String | / | 二次确认弹窗标题的内容。 +└ text | 是 | Struct | / | 二次确认弹窗文本的内容。 +└ └ tag | 是 | String | plain_text | 二次确认弹窗文本的标签。固定取值为 plain_text。 +└ └ content | 是 | String | / | 二次确认弹窗文本的具体内容。 + +#### `options` 字段说明 + +你可在 `option` 字段中添加并配置多个按钮。相关字段描述如下表所示。 + +字段名称 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +text | 否 | Struct | 空 | 按钮上的文本。 +└ tag | 否 | String | plain_text | 文本的标签。固定值为 `plain_text`。 +└ content | 否 | String | 请输入 | 文本的内容。最多支持 100 个字符。 +multi_url | 否 | Struct | 空 | 为按钮添加多端的跳转链接。 +└ url | 否 | String | 空 | 兜底的跳转链接。 +└ android_url | 否 | String | 空 | Android 端的跳转链接。可配置为 `lark://msgcard/unsupported_action` 声明当前端不允许跳转。 +└ ios_url | 否 | String | 空 | iOS 端的跳转链接。可配置为 `lark://msgcard/unsupported_action` 声明当前端不允许跳转。 +└ pc_url | 否 | String | 空 | PC 端的跳转链接。可配置为 `lark://msgcard/unsupported_action` 声明当前端不允许跳转。 +value | 否 | String | 空 | 该按钮的回传参数值。当用户点击选项后,应用会将该值返回至卡片请求地址。 + +## 回调结构 + +为组件成功配置交互后,用户基于组件进行交互时,你在开发者后台配置的请求地址将会收到回调数据。新版卡片回传交互回调(`card.action.trigger`)示例如下所示。 +- 如果你添加的是新版卡片回传交互回调(`card.action.trigger`),可参考[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)了解回调结构。 +- 如果你添加的是旧版卡片回传交互回调(`card.action.trigger_v1`),可参考[消息卡片回传交互(旧)](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/configuring-card-callbacks/card-callback-structure)了解回调结构。 +```json +{ + "schema": "2.0", // 回调的版本 + "header": { // 回调基本信息 + "event_id": "f7984f25108f8137722bb63c*****", // 回调的唯一标识 + "token": "066zT6pS4QCbgj5Do145GfDbbag*****", // 应用的 Verification Token + "create_time": "1603977298000000", // 回调发送的时间,接近回调发生的时间 + "event_type": "card.action.trigger", // 回调类型卡片交互场景中,固定为 "card.action.trigger" + "tenant_key": "2df73991750*****", // 应用归属的 tenant key,即租户唯一标识 + "app_id": "cli_a5fb0ae6a4******" // 应用的 App ID + }, + "event": { // 回调的详细信息 + "operator": { // 回调触发者信息 + "tenant_key": "2df73991750*****", // 回调触发者的 tenant key,即租户唯一标识 + "user_id": "867*****", // 回调触发者的 user ID。当应用开启“获取用户 user ID”权限后,该参数返回 + "open_id": "ou_3c14f3a59eaf2825dbe25359f15*****" // 回调触发者的 Open ID + }, + "token": "c-295ee57216a5dc9de90fefd0aadb4b1d7d******", // 更新卡片用的凭证,有效期为 30 分钟,最多可更新 2 次 + "action": { // 用户操作折叠按钮组内任意按钮回传的数据 + "value": { // 对应折叠按钮组组件中的 value (历史属性)或 behaviors 属性 + "key_1": "value_1" + }, + "tag": "overflow", // 折叠按钮组组件的标签 + "option": "C" // 折叠按钮组内用户点击的具体按钮的回传数据 + }, + "host": "im_message", // 卡片展示场景 + "context": { // 卡片展示场景相关信息 + "open_message_id": "om_574d639e4a44e4dd646eaf628e2*****", // 卡片所在的消息 ID + "open_chat_id": "oc_e4d2605ca917e695f54f11aaf56*****" // 卡片所在的会话 ID + } + } +} +``` +## 示例代码 + +以下的 JSON 示例代码可实现如下图所示的卡片效果。该卡片由三个按钮组件和一个折叠按钮组组件组成,该折叠按钮组中折叠了两个按钮: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/dded93a79c281088c33102b2af4fea31_UTEbSh584a.png?height=206&lazyload=true&maxWidth=500&width=847) +```json +{ + "i18n_elements": { + "zh_cn": [ + { + "tag": "action", + "layout": "default", + "actions": [ + { + "tag": "button", + "text": { + "tag": "plain_text", + "content": "按钮 1" + }, + "type": "default", + "complex_interaction": true, + "width": "default", + "size": "medium" + }, + { + "tag": "button", + "text": { + "tag": "plain_text", + "content": "按钮 2" + }, + "type": "default", + "complex_interaction": true, + "width": "default", + "size": "medium" + }, + { + "tag": "button", + "text": { + "tag": "plain_text", + "content": "按钮 3" + }, + "type": "default", + "complex_interaction": true, + "width": "default", + "size": "medium" + }, + { + "tag": "overflow", + "options": [ + { + "text": { + "tag": "plain_text", + "content": "按钮 4" + }, + "multi_url": { + "url": "https://open.feishu.cn/document/home/index", + "pc_url": "", + "ios_url": "", + "android_url": "" + }, + "value": "document", + "action_type": "multi" + }, + { + "text": { + "tag": "plain_text", + "content": "按钮 5" + }, + "multi_url": { + "url": "https://open.feishu.cn/", + "pc_url": "", + "ios_url": "", + "android_url": "" + } + } + ] + } + ] + } + ] + } +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__single-select-dropdown-menu.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__single-select-dropdown-menu.md new file mode 100644 index 0000000..65be72f --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__single-select-dropdown-menu.md @@ -0,0 +1,171 @@ +# 下拉选择-单选组件 + +下拉选择-单选组件支持自定义单选菜单的选项文本、图标和回传参数,是一种交互组件。本文档介绍下拉选择-单选组件的 JSON 结构和相关属性。 + +本文档介绍下拉选择-单选组件的 JSON 1.0 结构,要查看新版 JSON 2.0 结构,参考[下拉选择-单选](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/single-select-dropdown-menu)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/13ce9b48fa13821486eefd0dcb0b74e9_SIX5GpBGRj.png?height=339&lazyload=true&maxWidth=400&width=667) + +## 注意事项 + +- 下拉选择-单选组件最低支持的飞书版本为 V3.7.0。如果低于该版本,用户使用该组件时会提示 **当前版本不支持查看此消息**。 +- 在卡片 JSON 代码中,若下拉选择-单选组件直接位于卡片根节点,而非嵌套在其它组件中,你需将其 JSON 数据配置在[交互模块](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/component-list/common-components-and-elements)(`"tag": "action"`)的 `actions` 字段中使用。 + +## 嵌套规则 + +下拉选择-单选组件支持嵌套在分栏、表单容器、折叠面板、循环容器中使用。 + +## 组件属性 + +### JSON 结构 + +下拉选择-单选组件的结构如下所示: +```json +{ + "tag": "select_static", // 下拉选择-单选组件的标签。 + "type": "text", // 组件边框样式。默认值 default。 + "name": "select_static1", // 下拉选择-单选组件的唯一标识。当下拉选择-单选组件内嵌在表单容器时,该属性生效,用于识别用户提交的文本属于哪个下拉选择-单选组件。 + "required": false, // 下拉选择-单选组件的内容是否必填。默认值 false。当下拉选择-单选组件内嵌在表单容器时,该属性可用。其它情况将报错或不生效。 + "disabled": false, // 是否禁用该单选组件。默认值 false。 + "initial_option": "选项1", // 选项展示的初始内容。默认为空。 + "placeholder": { + // 下拉选择组件内的占位文本。 + "tag": "plain_text", + "content": "默认提示文本" + }, + "width": "default", // 下拉选择组件的宽度。 + "behaviors": [ + { // 为下拉选择组件配置回传交互。 + "type": "callback", + "value": { + // 回传交互数据。支持 string 或 object 数据类型。开放平台 SDK 仅支持 object 类型的回传交互数据。 + "key": "value" + } + } + ], + "options": [ + // 选项配置 + { + "text": { + // 选项名称 + "tag": "plain_text", + "content": "我是交互组件" + }, + "icon": { + // 添加图标作为选项前缀图标。支持自定义或使用图标库中的图标。 + "tag": "standard_icon", // 图标类型。 + "token": "chat-forbidden_outlined", // 图标的 token。仅在 tag 为 standard_icon 时生效。 + "color": "orange", // 图标颜色。仅在 tag 为 standard_icon 时生效。 + "img_key": "img_v2_38811724" // 图片的 key。仅在 tag 为 custom_icon 时生效。 + }, + "value": "selectDemo1" // 选项回调值,支持 string 类型数据。 + } + ], + "confirm": { + // 二次确认弹窗配置 + "title": { + "tag": "plain_text", + "content": "弹窗标题" + }, + "text": { + "tag": "plain_text", + "content": "弹窗正文文案" + } + } +} +``` + +### 字段说明 + +下拉选择-单选组件的字段说明如下表。 + +字段 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | string | / | 组件的标签。下拉选择-单选组件取固定值 `select_static`。 +type | 否 | string | default | 组件边框样式。可选值:
    - default:带边框样式
    - text:不带边框的纯文本样式 +name | 否 | String | 空 | 单选组件的唯一标识。当单选组件内嵌在表单容器时,该属性生效,用于识别用户提交的文本属于哪个单选组件。
    **注意**:当单选组件嵌套在表单容器中时,该字段必填且需在卡片全局内唯一。 +required | 否 | Boolean | false | 单选组件的内容是否必选。当组件内嵌在表单容器中时,该属性可用。其它情况将报错或不生效。可取值:
    - true:单选组件必选。当用户点击表单容器的“提交”时,未填写单选组件,则前端提示“有必填项未填写”,不会向开发者的服务端发起回传请求。
    - false:单选组件选填。当用户点击表单容器的“提交”时,未填写单选组件,仍提交表单容器中的数据。 +disabled | 否 | Boolean | false | 是否禁用该单选组件。该属性仅支持飞书 V7.4 及以上版本的客户端。可选值:
    - true:禁用单选组件组件
    - false:单选组件组件保持可用状态 +initial_option | 否 | String | 空 | 下拉选择组件的初始选项的内容。该配置将会覆盖 `placeholder` 配置的占位文本。 +placeholder | 否 | Object | / | 下拉选择组件内的占位文本。 +└ tag | 是 | String | plain_text | 占位提示标签。固定值为 `plain_text`。 +└ content | 否 | String | 空 | 占位文本的内容。 +width | 否 | String | default | 单选组件的宽度。支持以下枚举值:
    - default:默认宽度
    - fill:卡片最大支持宽度
    - [100,∞)px:自定义宽度。超出卡片宽度时将按最大支持宽度展示 +behaviors | 是 | Struct | / | 配置交互类型和具体交互行为。详情参考[配置卡片交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/configuring-card-interactions)中 behaviors 的字段说明。 +options | 否 | Array of objects | / | 选项的配置。 +└ text | 是 | Object | / | 选项的名称。 +└ └ tag | 是 | String | plain_text | 选项名称的标签。固定值为 `plain_text`。 +└ └ content | 是 | String | 空 | 选项名称的文本。 +└ icon | 否 | Object | / | 添加图标作为文本前缀图标。支持自定义或使用图标库中的图标。 +└└ tag | 否 | String | / | 图标类型的标签。可取值:
    - `standard_icon`:使用图标库中的图标。
    - `custom_icon`:使用用自定义图片作为图标。 +└└ token | 否 | String | / | 图标库中图标的 token。当 `tag` 为 `standard_icon` 时生效。枚举值参见[图标库](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-icons)。 +└└ color | 否 | String | / | 图标的颜色。支持设置线性和面性图标(即 token 末尾为 `outlined` 或 `filled` 的图标)的颜色。当 `tag` 为 `standard_icon` 时生效。枚举值参见[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。 +└└ img_key | 否 | String | / | 自定义前缀图标的图片 key。当 `tag` 为 `custom_icon` 时生效。
    图标 key 的获取方式:调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口,上传用于发送消息的图片,并在返回值中获取图片的 image_key。 +└ value | 是 | String | / | 自定义选项回调值。当用户点击交互组件的选项后,会将 value 的值返回给接收回调数据的服务器。后续你可以通过服务器接收的 value 值进行业务处理。
    **注意**:同一个选择组件内,各选项的 value 值不可重复,**否则将导致用户侧交互异常**,且服务器无法识别用户点击的是哪个选项。 +confirm | 否 | Struct | 默认不生效此属性。 | 二次确认弹窗配置。指在用户提交时弹出二次确认弹窗提示;只有用户点击确认后,才提交输入的内容。该字段默认提供了确认和取消按钮,你只需要配置弹窗的标题与内容即可。
    **注意**:confirm 字段仅在用户点击包含提交属性的按钮时才会触发二次确认弹窗。 +confirm.title | 是 | Struct | / | 二次确认弹窗标题。 +confirm.title.tag | 是 | String | plain_text | 二次确认弹窗标题文本的标签。固定取值为 `plain_text`。 +confirm.title.content | 是 | String | / | 二次确认弹窗标题的内容。 +confirm.text | 是 | Struct | / | 二次确认弹窗的文本内容。 +confirm.text.tag | 是 | String | plain_text | 二次确认弹窗文本的标签。固定取值为 `plain_text`。 +confirm.text.content | 是 | String | / | 二次确认弹窗文本的具体内容。 + +### 回调结构 + +为组件成功配置交互后,用户基于组件进行交互时,你在开发者后台配置的请求地址将会收到回调数据。 +- 如果你添加的是新版卡片回传交互回调(`card.action.trigger`),可参考[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)了解回调结构。 +- 如果你添加的是旧版卡片回传交互回调(`card.action.trigger_v1`),可参考[消息卡片回传交互(旧)](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/configuring-card-callbacks/card-callback-structure)了解回调结构。 + +## 示例代码 + +以下的 JSON 示例代码可实现如下图所示的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/13ce9b48fa13821486eefd0dcb0b74e9_Rk1KRWMzeC.png?height=339&lazyload=true&maxWidth=400&width=667) + +```json +{ + "i18n_elements": { + "zh_cn": [ + { + "tag": "action", + "actions": [ + { + "tag": "select_static", + "placeholder": { + "tag": "plain_text", + "content": "请选择" + }, + "options": [ + { + "text": { + "tag": "plain_text", + "content": "选项1" + }, + "value": "1", + "icon": { + "tag": "standard_icon", + "token": "signature_outlined" + } + }, + { + "text": { + "tag": "plain_text", + "content": "选项2" + }, + "value": "2", + "icon": { + "tag": "standard_icon", + "token": "signature_outlined" + } + } + ], + "type": "default", + "width": "default", + "initial_option": "选项1" + } + ] + } + ] + } +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__single-select-user-picker.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__single-select-user-picker.md new file mode 100644 index 0000000..55d2373 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__single-select-user-picker.md @@ -0,0 +1,121 @@ +# 人员选择-单选组件 + +人员选择-单选组件支持添加指定人员作为单选选项,是一种交互组件。本文档介绍人员选择-单选组件的 JSON 结构和相关属性。 + +本文档介绍人员选择-单选组件的 JSON 1.0 结构,要查看新版 JSON 2.0 结构,参考[人员选择-单选](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/single-select-user-picker)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/d85b31ecc22aac31e96f03611c115c30_JTuavGnynE.png?height=195&lazyload=true&maxWidth=500&width=819) + +## 注意事项 + +在卡片 JSON 代码中,若人员选择-单选组件直接位于卡片根节点,而非嵌套在其它组件中,你需将其 JSON 数据配置在[交互模块](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/component-list/common-components-and-elements)(`"tag": "action"`)的 `actions` 字段中使用。 + +## 嵌套规则 + +人员选择-单选组件支持嵌套在分栏、表单容器、折叠面板、循环容器中使用。 + +## 组件属性 + +### JSON 结构 + +人员选择-单选组件的结构如下所示: +```json +{ + "tag": "select_person", // 组件的标签 + "type": "text", // 组件边框样式。默认值为 default。 + "required":true, // 选项是否必填。 + "disabled":false, // 选项是否禁用。 + "placeholder": { + // 人员选择组件内的占位文本 + "tag": "plain_text", + "content": "默认提示文本" + }, + "width": "default", // 下拉选择组件的宽度 + "options": [ + // 选项配置,仅支持添加候选用户的 open_id。 + { + "value": "ou_48d0958ee4b2ab3eaf0b5f6c968xxxxx" // 候选用户的 open_id + }, + { + "value": "ou_f9d24af786a14340721288cda6axxxxx" // 候选用户的 open_id + } + ], + "confirm": { + // 二次确认弹窗配置 + "title": { + "tag": "plain_text", + "content": "弹窗标题" + }, + "text": { + "tag": "plain_text", + "content": "弹窗正文文案" + } + } +} +``` + +### 字段说明 + +人员选择-单选组件的字段说明如下表。 + +字段 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | string | / | 组件的标签。人员选择-单选组件取固定值 `select_person`。 +type | 否 | string | default | 组件边框样式。可选值:
    - default:带边框样式
    - text:不带边框的纯文本样式 +required | 否 | Boolean | false | 单选组件的内容是否必选。当组件内嵌在表单容器中时,该属性生效。可取值:
    - true:单选组件必选。当用户点击表单容器的“提交”时,未填写单选组件,则前端提示“有必填项未填写”,不会向开发者的服务端发起回传请求。
    - false:单选组件选填。当用户点击表单容器的“提交”时,未填写单选组件,仍提交表单容器中的数据。 +disabled | 否 | Boolean | false | 是否禁用该单选组件。可选值:
    - true:禁用单选组件组件
    - false:单选组件组件保持可用状态 +placeholder | 否 | object | / | 人员选择组件内的占位文本。 +└ tag | 是 | string | plain_text | 占位提示标签。固定值为 plain_text。 +└ content | 否 | String | / | 占位文本的内容,最多支持 100 个字符。 +width | 否 | String | default | 人员选择组件的宽度。支持以下枚举值:
    - default:默认宽度
    - fill:卡片最大支持宽度
    - [100,∞)px:自定义宽度。超出卡片宽度时将按最大支持宽度展示 +options | 否 | Array of objects | / | 选项值配置。按选项数组的顺序展示选项内容。 +└ value | 否 | String | 空 | 选项配置,仅支持添加候选用户的 open_id。了解更多,参考[如何获取不同的用户 ID](https://open.feishu.cn/document/home/user-identity-introduction/open-id)。
    **注意**:当 options 数组为空,或 value 的值全部无效时,候选项展示为卡片所在会话中所有成员选项。 +confirm | 否 | Struct | 默认不生效此属性。 | 二次确认弹窗配置。指在用户提交时弹出二次确认弹窗提示;只有用户点击确认后,才提交输入的内容。该字段默认提供了确认和取消按钮,你只需要配置弹窗的标题与内容即可。
    **注意**:confirm 字段仅在用户点击包含提交属性的按钮时才会触发二次确认弹窗。 +confirm.title | 是 | Struct | / | 二次确认弹窗标题。 +confirm.title.tag | 是 | String | plain_text | 二次确认弹窗标题文本的标签。固定取值为 `plain_text`。 +confirm.title.content | 是 | String | / | 二次确认弹窗标题的内容。 +confirm.text | 是 | Struct | / | 二次确认弹窗的文本内容。 +confirm.text.tag | 是 | String | plain_text | 二次确认弹窗文本的标签。固定取值为 `plain_text`。 +confirm.text.content | 是 | String | / | 二次确认弹窗文本的具体内容。 + +## 回调结构 + +为组件成功配置交互后,用户基于组件进行交互时,你在开发者后台配置的请求地址将会收到回调数据。 +- 如果你添加的是新版卡片回传交互回调(`card.action.trigger`),可参考[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)了解回调结构。 +- 如果你添加的是旧版卡片回传交互回调(`card.action.trigger_v1`),可参考[消息卡片回传交互(旧)](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/configuring-card-callbacks/card-callback-structure)了解回调结构。 + +## 示例代码 + +以下的 JSON 示例代码可实现如下图所示的卡片效果,你需填入实际的用户的 open_id。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/d85b31ecc22aac31e96f03611c115c30_q5kjDHzs72.png?height=195&lazyload=true&maxWidth=500&width=819) +```json +{ + "i18n_elements": { + "zh_cn": [ + { + "tag": "action", + "actions": [ + { + "tag": "select_person", + "placeholder": { + "tag": "plain_text", + "content": "请选择" + }, + "options": [ + { + "value": "ou_449b53ad6aee526f7ed311b216aabcef" + }, + { + "value": "ou_449b53ad6aee526f7ed311b216aabcef" + } + ], + "width": "default", + "type": "default" + } + ] + } + ] + } +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__time-selector.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__time-selector.md new file mode 100644 index 0000000..c348605 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-components__interactive-components__time-selector.md @@ -0,0 +1,126 @@ +# 时间选择器组件 + +时间选择器组件是用于提供时间选项的交互组件。本文档介绍时间选择器组件的 JSON 结构和相关属性。 + +本文档介绍时间选择器组件的 JSON 1.0 结构,要查看新版 JSON 2.0 结构,参考[时间选择器](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/time-selector)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/06e975e8c8296319e6c3ed1dc4f9d3a5_F8K0yHFkdG.png?height=188&lazyload=true&maxWidth=400&width=560) + +## 注意事项 + +- 时间选择器组件支持飞书 V3.11.0 及以上版本的客户端。在低于该版本的飞书客户端上,表单容器的内容将展示为“当前版本不支持查看此消息”。 +- 在使用时间选择器时,你需提醒用户选择与当前时间场景相对应的时区信息。例如,在预定海外酒店的场景下,一般使用酒店所在地时区;设置日程场景下,一般使用用户当前所在地的时区。开放平台会返回用户当前的时区作为参考,但并不代表用户选择了该时区。 +- 在卡片 JSON 代码中,若时间选择器组件直接位于卡片根节点,而非嵌套在其它组件中,你需将其 JSON 数据配置在[交互模块](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/component-list/common-components-and-elements)(`"tag": "action"`)的 `actions` 字段中使用。 + +## 嵌套规则 + +时间选择器组件支持嵌套在分栏、表单容器、折叠面板、循环容器中使用。 + +## 组件属性 + +### JSON 结构 + +时间选择器组件的 JSON 结构如下所示: +```json +{ + "tag": "picker_time", // 时间选择器组件的标签。 + "name": "picker_time1", // 时间选择器组件的唯一标识。当组件内嵌在表单容器中时,该字段生效且必填,用于识别用户提交的数据属于哪个组件。 + "required": false, // 时间是否必选。默认值 false。当时间选择器内嵌在表单容器时,该属性可用。其它情况将报错或不生效。 + "disabled": false, // 是否禁用该时间选择器组件。默认值 false。 + "width": "default", // 时间选择器的宽度。 + "initial_time": "11:30", // 时间初始值。 + "placeholder": { + // 时间选择器组件内的占位文本。 + "tag": "plain_text", + "content": "请选择" + }, + "value": { + // 回传数据 + "key_1": "value_1" + }, + "confirm": { + // 二次确认弹窗配置 + "title": { + "tag": "plain_text", + "content": "title" + }, + "text": { + "tag": "plain_text", + "content": "content" + } + } +} +``` + +### 字段说明 + +时间选择器组件的字段说明如下表。 + +字段 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | string | / | 组件的标签。时间选择器组件取固定值 `picker_time`。 +name | 否 | String | 空 | 该时间选择器组件的唯一标识。用于识别用户提交的数据属于哪个组件。
    **注意**: 当时间选择器组件嵌套在表单容器中时,该字段必填且需在卡片全局内唯一。 +required | 否 | Boolean | false | 时间否必选。当组件内嵌在表单容器中时,该属性可用。其它情况将报错或不生效。可取值:
    - true:时间必选。当用户点击表单容器的“提交”时,未填写时间,则前端提示“有必填项未填写”,不会向开发者的服务端发起回传请求。
    - false:时间选填。当用户点击表单容器的“提交”时,未填写时间,仍提交表单容器中的数据。 +disabled | 否 | Boolean | false | 是否禁用该时间选择器。该属性仅支持飞书 V7.4 及以上版本的客户端。可选值:
    - true:禁用时间选择器组件
    - false:时间选择器组件保持可用状态 +initial_time | 否 | String | 空 | 时间选择器组件的初始选项值。格式为 `HH:mm`。该配置将会覆盖 `placeholder` 配置的占位文本。 +placeholder | 否 | object | / | 时间选择器组件内的占位文本。
    **注意**:
    - 未配置 `initial_time` 字段设置初始选项值时,该字段必填。
    - 配置 `initial_time` 字段设置初始选项值后,该字段不再生效。 +└ tag | 是 | String | plain_text | 占位提示标签。固定值为 plain_text。 +└ content | 否 | String | / | 占位文本的内容,最多支持 100 个字符。 +width | 否 | String | default | 时间选择器组件的宽度。支持以下枚举值:
    - default:默认宽度
    - fill:卡片最大支持宽度
    - [100,∞)px:自定义宽度。超出卡片宽度时将按最大支持宽度展示 +value | 是 | JSON | / | 设置交互的回传数据,当用户点击交互组件的选项后,会将 value 的值返回给接收回调数据的服务器。后续你可以通过服务器接收的 value 值进行业务处理。
    该字段值仅支持 key-value 形式的 JSON 结构,且 key 为 String 类型。示例值:
    ```json
    "value":{
    "key-1":Object-1,
    "key-2":Object-2,
    "key-3":Object-3,
    ······
    }
    ``` +confirm | 否 | Struct | 默认不生效此属性。 | 二次确认弹窗配置。指在用户提交时弹出二次确认弹窗提示;只有用户点击确认后,才提交输入的内容。该字段默认提供了确认和取消按钮,你只需要配置弹窗的标题与内容即可。
    **注意**:confirm 字段仅在用户点击包含提交属性的按钮时才会触发二次确认弹窗。 +confirm.title | 是 | Struct | / | 二次确认弹窗标题。 +confirm.title.tag | 是 | String | plain_text | 二次确认弹窗标题文本的标签。固定取值为 `plain_text`。 +confirm.title.content | 是 | String | / | 二次确认弹窗标题的内容。 +confirm.text | 是 | Struct | / | 二次确认弹窗的文本内容。 +confirm.text.tag | 是 | String | plain_text | 二次确认弹窗文本的标签。固定取值为 `plain_text`。 +confirm.text.content | 是 | String | / | 二次确认弹窗文本的具体内容。 + +## 回调结构 + +为组件成功配置交互后,用户基于组件进行交互时,你在开发者后台配置的请求地址将会收到回调数据。 +- 如果你添加的是新版卡片回传交互回调(`card.action.trigger`),可参考[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)了解回调结构。 +- 如果你添加的是旧版卡片回传交互回调(`card.action.trigger_v1`),可参考[消息卡片回传交互(旧)](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/configuring-card-callbacks/card-callback-structure)了解回调结构。 + +## 示例代码 + +以下的 JSON 示例代码可实现如下图所示的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/06e975e8c8296319e6c3ed1dc4f9d3a5_9wvv0E6mVS.png?height=188&lazyload=true&maxWidth=400&width=560) + +```json +{ + "i18n_elements": { + "zh_cn": [ + { + "tag": "action", + "actions": [ + { + "tag": "picker_time", + "placeholder": { + "tag": "plain_text", + "content": "请选择" + }, + "width": "default", + "initial_time": "09:00" + } + ] + }, + { + "tag": "action", + "actions": [ + { + "tag": "picker_time", + "placeholder": { + "tag": "plain_text", + "content": "请选择" + }, + "width": "default" + } + ] + } + ] + }, + "i18n_header": {} +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-structure.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-structure.md new file mode 100644 index 0000000..c4fc269 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-structure.md @@ -0,0 +1,320 @@ +# 卡片 JSON 1.0 结构 + +本文档介绍卡片 JSON 1.0 的结构和属性。了解卡片 JSON 2.0 的结构和属性,参考[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)。 + +## 属性概述 + +卡片全局的字段包括全局行为设置、跳转链接设置、多语言设置、降级规则配置、标题组件配置和其它组件配置。 +各个字段说明如下所示。 +若这些字段均不传,则卡片 JSON 为 "{}"。飞书开放平台支持发送卡片 JSON 为 "{}" 的空白卡片。 + +字段 | 是否支持在搭建工具中设置 | 是否必填 | 描述 +---|---|---|--- +行为设置 `config` | 否 | 否 | `config` 用于配置卡片的全局行为,包括是否允许被转发、是否为共享卡片等。 +跳转链接 `card_link` | 是 | 否 | `card_link` 字段用于指定卡片整体的点击跳转链接。你可以配置一个默认链接,也可以分别为 PC 端、Android 端、iOS 端配置不同的跳转链接。 +多语言设置 `i18n_elements` 等 | 是 | 否 | 飞书卡片支持多语言设置。设置多语言后,卡片将根据用户的飞书客户端语言,自动展示对应语言的卡片内容,满足国际化业务需求。详情参考[配置卡片多语言](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/configure-multi-language-content)。 +标题组件 `header` | 是 | 否 | 标题组件 JSON 代码。详细字段说明参考[标题组件](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/title)。 +其它组件 `elements` | 是 | 否 | 在 `elements` 字段中添加各个组件的 JSON 数据,组件将按数组顺序纵向流式排列。了解各个组件,参考[组件概述](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/component-overview)。 +降级规则 `fallback` | 否 | 否 | `fallback` 用于为卡片添加全局降级规则。触发降级时,卡片将全局展示“请升级客户端至最新版本后查看”占位图。
    **注意**:
    该字段要求飞书客户端的版本为 V7.7 及以上。 + +## JSON 结构 + +以下为卡片整体的 JSON 代码结构。 + +```json +{ + "config": { + "enable_forward": true, // 是否支持转发卡片。默认值 true。 + "update_multi": true, // 是否为共享卡片。为 true 时即更新卡片的内容对所有收到这张卡片的人员可见。默认值 false。 + "width_mode": "fill", // 卡片宽度模式。支持 "compact"(紧凑宽度 400px)模式、"fill"(撑满聊天窗口宽度)模式和 "default" 默认模式(宽度上限为 600px)。 + "compact_width": true, // 已废弃字段。是否为紧凑型卡片宽度。与 width_mode 属性同时设置时,width_mode 将生效。 + "use_custom_translation": false, // 是否使用自定义翻译数据。默认值 false。为 true 时则在用户点击消息翻译后,使用 i18n 对应的目标语种作为翻译结果。若 i18n 取不到,则使用当前内容请求翻译,不使用自定义翻译数据。 + "enable_forward_interaction": false, // 转发的卡片是否仍然支持回传交互。默认值 false。 + "style": { // 添加自定义字号和颜色。可应用在组件 JSON 数据中,设置字号和颜色属性。 + "text_size": { // 分别为移动端和桌面端添加自定义字号,同时添加兜底字号。用于在组件 JSON 中设置字号属性。支持添加多个自定义字号对象。 + "cus-0": { + "default": "medium", // 在无法差异化配置字号的旧版飞书客户端上,生效的字号属性。选填。 + "pc": "medium", // 桌面端的字号。 + "mobile": "large" // 移动端的字号。 + } + }, + "color": { // 分别为飞书客户端浅色主题和深色主题添加 RGBA 语法。用于在组件 JSON 中设置颜色属性。支持添加多个自定义颜色对象。 + "cus-0": { + "light_mode": "rgba(5,157,178,0.52)", // 浅色主题下的自定义颜色语法 + "dark_mode": "rgba(78,23,108,0.49)" // 深色主题下的自定义颜色语法 + } + } + } + }, + "card_link": { + // 指定卡片整体的跳转链接。 + "url": "https://www.baidu.com", // 默认链接地址。未配置指定端地址时,该配置生效。 + "android_url": "https://developer.android.com/", + "ios_url": "https://developer.apple.com/", + "pc_url": "https://www.windows.com" + }, + "header": {}, // 卡片标题。 + "elements": [ + {} + ], // 用于传入各个组件的 JSON 数据,组件将按数组顺序纵向流式排列。 + "i18n_elements": { + // 除标题外其它组件的多语言配置。你可在每个语种下配置完整卡片,卡片将根据用户的飞书客户端语言,自动展示对应语言的卡片内容。 + "en_us": [{}], // 英文 + "zh_cn": [{}], // 简体中文 + "zh_hk": [{}], // 繁体中文(香港) + "zh_tw": [{}], // 繁体中文(台湾) + "ja_jp": [{}], // 日语 + "id_id": [{}], // 印尼语 + "vi_vn": [{}], // 越南语 + "th_th": [{}], // 泰语 + "pt_br": [{}], // 葡萄牙语 + "es_es": [{}], // 西班牙语 + "ko_kr": [{}], // 韩语 + "de_de": [{}], // 德语 + "fr_fr": [{}], // 法语 + "it_it": [{}], // 意大利语 + "ru_ru": [{}], // 俄语 + "ms_my": [{}] // 马来语 + }, + "fallback": { + // 在此处为卡片添加降级规则。触发降级时,卡片将全局展示“请升级客户端至最新版本后查看”占位图。 + // 该字段要求飞书客户端的版本为 V7.7 及以上。 + "trigger_conditions": [ + // 触发规则,满足以下任一条件时,触发降级。 + { // 条件一:设置最低客户端版本。当用户的客户端版本低于该设置时,触发降级。 + "type": "min_client_version", + "value": "7.4" + }, + { + // 条件二:指定组件。当用户的飞书客户端版本低于这些组件支持的最低客户端版本时,触发降级。 + "type": "element_tags", + "value": [ + "" + ] + } + ] + } +} +``` + +## 字段说明 + +本小节详细描述卡片结构中的各个字段。 + +### 卡片全局行为设置 `config` + +`config` 字段用于配置卡片的全局行为,包括是否允许被转发、是否为共享卡片等。 +**注意事项**:基于搭建工具生成的卡片模板(template)暂不支持自定义 `config` 字段。 + +```json +{ + "config": { + "enable_forward": true, // 是否支持转发卡片。默认值 true。 + "update_multi": true, // 是否为共享卡片。为 true 时即更新卡片的内容对所有收到这张卡片的人员可见。默认值 false。 + "width_mode": "fill", // 卡片宽度模式。支持 "compact"(紧凑宽度 400px)模式、"fill"(撑满聊天窗口宽度)模式和 "default" 默认模式(宽度上限为 600px)。 + "compact_width": true, // 已废弃字段。是否为紧凑型卡片宽度。与 width_mode 属性同时设置时,width_mode 将生效。 + "use_custom_translation": false, // 是否使用自定义翻译数据。默认值 false。为 true 时则在用户点击消息翻译后,使用 i18n 对应的目标语种作为翻译结果。若 i18n 取不到,则使用当前内容请求翻译,不使用自定义翻译数据。 + "enable_forward_interaction": false, // 转发的卡片是否仍然支持回传交互。默认值 false。 + "style": { // 添加自定义字号和颜色。可应用在组件 JSON 数据中,设置字号和颜色属性。 + "text_size": { // 分别为移动端和桌面端添加自定义字号,同时添加兜底字号。用于在组件 JSON 中设置字号属性。支持添加多个自定义字号对象。 + "cus-0": { + "default": "medium", // 在无法差异化配置字号的旧版飞书客户端上,生效的字号属性。选填。 + "pc": "medium", // 桌面端的字号。 + "mobile": "large" // 移动端的字号。 + } + }, + "color": { // 分别为飞书客户端浅色主题和深色主题添加 RGBA 语法。用于在组件 JSON 中设置颜色属性。支持添加多个自定义颜色对象。 + "cus-0": { + "light_mode": "rgba(5,157,178,0.52)", // 浅色主题下的自定义颜色语法 + "dark_mode": "rgba(78,23,108,0.49)" // 深色主题下的自定义颜色语法 + } + } + } + } +} +``` +`config` 下的各字段说明如下表所示。 + +字段名称 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +enable_forward | 否 | Boolean | true | 是否允许转发卡片。取值:
    - true:允许
    - false:不允许
    **注意**:
    该字段要求飞书客户端的版本为 V3.31.0 及以上。 +update_multi | 否 | Boolean | false | 是否为共享卡片。取值:
    - true:是共享卡片,更新卡片的内容对所有收到这张卡片的人员可见。
    - false:非共享卡片,仅操作用户可见卡片的更新内容。 +width_mode | 否 | String | default | 卡片宽度模式。取值:
    - default:默认宽度。PC 端宽版、iPad 端上的宽度上限为 600px。
    - compact:紧凑宽度模式。PC 端宽版、iPad 端上的宽度上限为 400px。
    - fill:撑满聊天窗口宽度。 +compact_width(已废弃) | 否 | Boolean | false | 是否为紧凑型卡片的宽度(400px)。该字段已废弃。
    **注意**:`width_mode` 与 `compact_width` 属性同时设置时,`width_mode` 属性将生效。 +use_custom_translation | 否 | Boolean | false | 是否使用自定义翻译数据。取值:
    - true:在用户点击消息翻译后,使用 i18n 对应的目标语种作为翻译结果。若 i18n 取不到,则使用当前内容请求飞书的机器翻译。
    - false:不使用自定义翻译数据,直接请求飞书的机器翻译。 +enable_forward_interaction | 否 | Boolean | false | 转发的卡片是否仍然支持回传交互。 +style | 否 | Object | 空 | 添加自定义字号和颜色。可应用于组件的 JSON 数据中,设置字号和颜色属性。 +└ text_size | 否 | Object | 空 | 分别为移动端和桌面端添加自定义字号。用于在普通文本组件和富文本组件 JSON 中设置字号属性。支持添加多个自定义字号对象。详情参考[普通文本组件](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/plain-text)和[富文本组件](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/rich-text)。 +└ color | 否 | Object | 空 | 分别为飞书客户端浅色主题和深色主题添加 RGBA 语法。用于在组件 JSON 中设置颜色属性。支持添加多个自定义颜色对象。详情参考[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。 + +### 卡片全局跳转链接 `card_link` + +`card_link` 字段用于指定卡片整体的点击跳转链接。你可以配置一个默认链接,也可以分别为 PC 端、Android 端、iOS 端配置不同的跳转链接。 + +```json +"card_link": { + // 指定卡片整体的跳转链接。 + "url": "https://www.baidu.com", // 默认链接地址。未配置指定端地址时,该配置生效。 + "android_url": "https://developer.android.com/", + "ios_url": "https://developer.apple.com/", + "pc_url": "https://www.windows.com" + } +``` +card_link 下的各字段说明如下表所示。 +**注意事项**:**注意** +- url 和各端的链接(android_url、ios_url、pc_url)必填其中一个。如果不填写 url,则必须完整填写 android_url、ios_url、pc_url 三个字段。如果同时填写了 url 和 android_url、ios_url、pc_url,url 字段生效。 +- 如果需要禁止某端进行跳转,可以将对应的参数值配置为 `lark://msgcard/unsupported_action`。 + +字段名称 | 是否必填 | 类型 | 说明 +---|---|---|--- +url | 否 | String | 默认的链接地址。 +pc_url | 否 | String | PC 端的链接地址。 +ios_url | 否 | String | iOS 端的链接地址。 +android_url | 否 | String | Android 端的链接地址。 + +### 卡片标题 `header` + +`header` 字段用于配置卡片的标题。了解`header` 字段说明,参见[标题组件](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/title)。 +```json + "header": {}, // 卡片标题 +``` + +### 卡片正文 `elements` + +在卡片的`elements` 字段中,你需要添加卡片组件作为卡片正文内容,组件将按数组顺序纵向流式排列。了解卡片组件,参考[组件概述](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/component-overview)。 +```json + "elements": [{...}] // 用于传入各个组件的 JSON 数据,组件将按数组顺序纵向流式排列。 +``` + +### 卡片多语言设置 `i18n_elements` 等 + +飞书卡片支持多语言设置。设置多语言后,卡片将根据用户的飞书客户端语言,自动展示对应语言的卡片内容,满足国际化业务需求。本小节介绍多语言设置相关的 JSON 结构,详细步骤可参见[配置卡片多语言](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/configure-multi-language-content)。 + +#### **卡片标题多语言设置** + +卡片标题多语言相关字段有:`title.i18n`、`subtitle.i18n` 和 `i18n_text_tag_list`。详情参考以下代码中相关字段的注释。 +```json +{ + "header": { + "title": { + "tag": "plain_text", + "content": "示例标题", + "i18n": { + // 卡片主标题多语言配置。必须配置 content 或 i18n 两个属性的其中一个。如果同时配置仅生效 i18n。 + "zh_cn": "", + "en_us": "", + "ja_jp": "", + "zh_hk": "", + "zh_tw": "" + } + }, + "subtitle": { + "tag": "plain_text", + "content": "示例文本", + "i18n": { + // 卡片副标题多语言配置。必须配置 content 或 i18n 两个属性的其中一个。如果同时配置仅生效 i18n。 + "zh_cn": "", + "en_us": "", + "ja_jp": "", + "zh_hk": "", + "zh_tw": "" + } + }, + "text_tag_list": [ + { + "tag": "text_tag", + "text": { + // 标签内容 + "tag": "plain_text", + "content": "标签 1" + }, + "color": "neutral" + } + ], + "i18n_text_tag_list": { + // 标题后缀标签多语言配置。每个语言环境最多设置 3 个 tag,超出不展示。如果同时配置仅生效 i18n_text_tag_list。 + "zh_cn": [], + "en_us": [], + "ja_jp": [], + "zh_hk": [], + "zh_tw": [] + }, + "template": "blue", + "icon": { + "img_key": "img_v2_38811724" + }, + "ud_icon": { + "token": "chat-forbidden_outlined", + "style": { + "color": "red" + } + } + } +} +``` + +#### **卡片正文多语言设置** + +卡片的 `i18n_elements` 字段用于为卡片正文的组件配置多语言。 +```json + "i18n_elements": { + // 卡片正文的多语言配置。你可在每个语种下配置完整卡片,卡片将根据用户的飞书客户端语言,自动展示对应语言的卡片内容。 + "en_us": [{}], // 英文 + "zh_cn": [{}], // 简体中文 + "zh_hk": [{}], // 繁体中文(香港) + "zh_tw": [{}], // 繁体中文(台湾) + "ja_jp": [{}], // 日语 + "id_id": [{}], // 印尼语 + "vi_vn": [{}], // 越南语 + "th_th": [{}], // 泰语 + "pt_br": [{}], // 葡萄牙语 + "es_es": [{}], // 西班牙语 + "ko_kr": [{}], // 韩语 + "de_de": [{}], // 德语 + "fr_fr": [{}], // 法语 + "it_it": [{}], // 意大利语 + "ru_ru": [{}], // 俄语 + "ms_my": [{}] // 马来语 + } +``` + +### 卡片全局降级规则 `fallback` + +在构建卡片时,若使用仅在较新版本客户端中支持的组件,那么在低版本的飞书客户端上,该组件将显示“请升级至飞书最新版本以查看内容”的提示。如果这类组件较多,不仅会丢失卡片的信息,还会降低卡片的视觉效果,影响用户体验。 + +为避免上述问题出现,你可以通过配置 `fallback` 字段为卡片添加以下降级规则,当满足以下任一规则时,将触发卡片降级并展示系统默认的卡片样式: +- 当用户的飞书客户端版本低于你指定的最低客户端版本时; +- 当用户的飞书客户端版本低于你指定的组件所支持的最低客户端版本时。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/9c19366d1be9c5b883e5496c8fdbc9cb_5N2vMREvFS.png?height=316&lazyload=true&maxWidth=500&width=904) + +相关 JSON 结构如下所示: + +```json +"fallback": { + // 在此处为卡片添加降级规则。触发降级时,卡片将全局展示“请升级客户端至最新版本后查看”占位图。 + // 该字段要求飞书客户端的版本为 V7.7 及以上。 + "trigger_conditions": [ + // 触发规则,满足以下任一条件就触发降级。 + { // 条件一:设置最低客户端版本。当用户的客户端版本低于该设置时,触发降级。 + "type": "min_client_version", + "value": "7.4" + }, + { + // 条件二:指定组件。当用户的飞书客户端版本低于这些组件支持的最低客户端版本时,触发降级。 + "type": "element_tags", + "value": [ + "" + ] + } + ] +} +``` +`fallback` 下的各字段说明如下表所示。 + +字段名称 | 是否必填 | 类型 | 示例值 | 说明 +---|---|---|---|--- +trigger_conditions | 否 | Array | / | 触发降级的条件数组。满足其中的任一条件就触发降级。 +└ type | 否 | String | "min_client_version" | 条件类型。可选值:
    - min_client_version:设置最低客户端版本,当用户的客户端版本低于该设置时,触发降级;
    - element_tags:指定组件。当用户的飞书客户端版本低于这些组件支持的最低客户端版本时,触发降级。 +└ value(当 type 为 "min_client_version"时) | 否 | String | "v7.4.1" | 最低飞书客户端版本的值,写法需符合以下格式之一:
    - 7.4、7.4.1、7.4.1-xxx
    - v7.4、v7.4.1、v7.4.1-xxx
    - v7.3.7(0.103)
    - v7.4.0-dev.d2666af5(0.14)
    +└ value(当 type 为 "element_tags"时) | 否 | Array | ["table"] | 指定组件。当用户的飞书客户端版本低于这些组件支持的最低客户端版本时,触发降级。 diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-breaking-changes-release-notes.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-breaking-changes-release-notes.md new file mode 100644 index 0000000..9278086 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-breaking-changes-release-notes.md @@ -0,0 +1,238 @@ +# 卡片 JSON 2.0 版本更新说明 + +本文档介绍卡片 JSON 2.0 版本与 1.0 版本结构之间的不兼容变更和优化说明。了解完整的 JSON 2.0 结构数据,参考[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)。 + +## 注意事项 + +- 卡片 JSON 2.0 结构支持飞书客户端 7.20 及之后版本。当使用 JSON 2.0 结构的卡片发送至低于 7.20 版本的客户端时,卡片标题可正常显示,但内容将展示兜底的升级提示文案。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/35efb2f0bfbe5d22fe4b7a420925d2af_g5UivxGopO.png?height=449&lazyload=true&maxWidth=400&width=742) + +- 卡片 JSON 2.0 结构暂时仅支持共享卡片,不支持独享卡片配置。即 `update_multi` 参数仅支持设为 `true`。 + +## 不兼容变更 + +本小节介绍卡片 JSON 2.0 版本相对于 1.0 版本所发生的不兼容变更。 + +### 卡片交互有效期变更 + +- 1.0 结构:发出卡片的可交互时间为 30 天,可更新时间为 14 天(如果在第 14-30 天交互卡片,且交互回调动作为更新卡片,更新动作将不会生效)。 +- 2.0 结构:卡片可交互和可更新时间统一为 14 天。 + +### 属性校验变更 + +在 JSON 2.0 版本中,传入不支持的属性将报错。 +| **1.0 结构** | **2.0 结构** | +| ------------- | ----------- | +| 传入不支持的属性作忽略处理 | 传入不支持的属性将报错 | + +### JSON 全局结构和字段变更 + +- **结构变更** + +- JSON 2.0 版本新增 `body` 字段,`elements` 属性放置在 `body` 层级下。了解 2.0 整体结构,参考[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)。 + - JSON 2.0 版本不再支持通过 `i18n_elements` 字段设置全局多语言。你可通过 `i18n_content` 等局部多语言字段实现组件级别的多语言配置,详情参考[配置卡片多语言](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/configure-multi-language-content)。 + +- **`fallback`** **字段变更** + +JSON 2.0 版本暂不支持使用 `fallback` 字段配置自定义的全局降级规则。 + +- **默认值变更** + +JSON 2.0 版本中的 `update_multi` 默认值变更为 `true`,且暂时仅支持设为 `true`。`update_multi` 属性用于设置卡片是否为共享卡片;`true` 表示设置卡片为共享卡片,更新卡片的内容对所有收到这张卡片的人员可见;`false` 表示设置卡片为独享卡片,更新卡片的内容对他人不可见。 + +1.0 结构 | 2.0 结构 +---|--- +```json
    {
    "schema": "1.0", // 不填默认为 1.0
    "config": {
    "update_multi": false // 默认值为 false。
    },
    "card_link": {},
    "header": {},
    "i18n_header": {},
    "elements": [],
    "i18n_elements": {},
    "fallback": {}
    }
    ``` | ```json
    {
    "schema": "2.0", // 2.0 需主动声明
    "config": {
    "update_multi": true // 默认值为 true,且暂时仅支持设为 `true`
    },
    "card_link": {},
    "header": {},
    "body": { // 新增 body 字段,elements 属性放置在 body 层级下。
    "elements": [] // 不再支持 i18n_elements 字段
    },
    "fallback": {}
    }
    ``` + +### 容器类组件布局属性默认值变更 + +- [表单容器](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/form-container)的 `vertical_spacing` 和 `horizontal_spacing` 字段的默认值由 `16px` 改为 `12px`,且支持开发者自定义配置。 + +1.0 结构 | 2.0 结构 +---|--- +```json
    {
    "margin": "0", // 容器的外边距设置。
    "padding": "0", // 容器的内边距设置。
    "vertical_spacing": "16px", // 容器内组件的垂直边距设置。
    "horizontal_spacing": "16px" // 容器内组件的水平边距设置。
    }
    ``` | ```json
    {
    "margin": "0",
    "padding": "0",
    "vertical_spacing": "12px", // 默认值变更,且支持自定义。
    "horizontal_spacing": "12px" // 默认值变更,且支持自定义。
    }
    ``` + +
    + +- [交互容器](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/interactive-container)的 `vertical_spacing` 和 `horizontal_spacing` 字段的默认值由 `12px` 改为 `4px` 和 `8px`,且支持开发者自定义配置。 + +1.0 结构 | 2.0 结构 +---|--- +```json
    {
    "margin": "0", // 容器的外边距设置。
    "padding": "4px 12px", // 容器的内边距设置。
    "vertical_spacing": "12px", // 容器内组件的垂直边距设置。
    "horizontal_spacing": "12px" // 容器内组件的水平边距设置。
    }
    ``` | ```json
    {
    "margin": "0",
    "padding": "4px 12px",
    "vertical_spacing": "4px", // 默认值变更,且支持自定义。
    "horizontal_spacing": "8px" // 默认值变更,且支持自定义。
    }
    ``` + +
    +- [折叠面板](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/collapsible-panel)的 `padding` 字段默认值变更: + - 当折叠面板配置了边框(border)或背景色(background_color)时,标题区 `padding` 字段的默认值变更为上下边距 4px,左右边距 8px。 + +1.0 结构 | 2.0 结构 +---|--- +```json
    // 有边框(border)或背景色(background_color)时
    {
    "header": {
    "margin": "0",
    "padding": "8px" // 标题区的内边距。
    },
    "margin": "0",
    "padding": "8px",
    "vertical_spacing": "8px",
    "horizontal_spacing": "8px"
    }
    ``` | ```json
    // 有边框(border)或背景色(background_color)时
    {
    "header": {
    "margin": "0",
    "padding": "4px 8px" // 标题区的内边距默认值变更。上下边距为 4px,左右边距为 8px。
    },
    "margin": "0",
    "padding": "8px",
    "vertical_spacing": "8px",
    "horizontal_spacing": "8px"
    }
    ``` + +- 当折叠面板未配置边框(border)或背景色(background_color)时,标题区 `padding` 字段的默认值变更为 0,内容区的内边距默认值变更为上边距 8px,右、下、左边距 0。 + +1.0 结构 | 2.0 结构 +---|--- +```json
    // 无边框(border)或背景色(background_color)时
    {
    "header": {
    "margin": "0",
    "padding": "8px 0 8px 0" // 标题区的内边距。
    },
    "margin": "0",
    "padding": "0",
    "vertical_spacing": "8px",
    "horizontal_spacing": "8px"
    } | ```json
    // 无边框(border)或背景色(background_color)时
    {
    "header": {
    "margin": "0",
    "padding": "0" // 标题区的内边距默认值变更
    },
    "margin": "0",
    "padding": "8px 0 0 0", // 内容区的内边距默认值变更。上边距为 8px,右、下、左边距为 0px。
    "vertical_spacing": "8px",
    "horizontal_spacing": "8px"
    } + +### `vertical_spacing` 和 `horizontal_spacing` 枚举值 & 映射数值变更 + +1.0 结构 | 2.0 结构 +---|--- +vertical_spacinghorizontal_spacing字段的枚举和对应的值为:
    - small:4px
    - medium:8px
    - large:16px | vertical_spacinghorizontal_spacing字段的枚举和对应的值为:
    - small:4px
    - medium:8px
    - large:12px
    - extra_large:16px + +### 标题组件配置变更 + +- 标题组件的 icon 配置结构变更,对齐其它组件: + +1.0 结构 | 2.0 结构 +---|--- +```json
    {
    "header": {
    "title": {},
    "icon": {
    "img_key": "img_v2_38811724"
    },
    "ud_icon": {
    "token": "chat-forbidden_outlined",
    "style": {
    "color": "red"
    }
    }
    }
    }
    ``` | ```json
    {
    "header": {
    "title": {},
    "icon": {
    "tag": "standard_icon",
    "token": "chat-forbidden_outlined",
    "color": "orange",
    "img_key": "img_v2_38811724"
    }
    }
    }
    ``` + +### 图片组件不再支持通栏配置 + +1.0 结构 | 2.0 结构 +---|--- +支持 stretch_without_padding 通栏配置,图片的宽度将撑满卡片宽度。
    ```json
    {
    "tag": "img",
    "img_key": "img_v3_0238_073f1823-df2b-4377-86c6-e293f183622j",
    "size": "stretch_without_padding" // 支持通栏配置,图片宽度将撑满卡片宽度。
    }
    ``` | 不再支持通栏配置,但可设置 margin 字段为负数实现通栏效果。
    ```json
    {
    "tag": "img",
    "img_key": "img_v3_0238_073f1823-df2b-4377-86c6-e293f183622j",
    "size": "crop_center",
    "margin": "4px -12px"
    }
    ``` + +### 富文本(Markdown)组件废弃差异化跳转语法 + +2.0 结构不再支持以下差异化跳转语法。你可使用`` 标签替代,如 ` `` 战略研讨会 `。 +```json +{ + "tag": "markdown", + "href": { + "urlVal": { + "url": "xxx", + "pc_url": "xxx", + "ios_url": "xxx", + "android_url": "xxx" + } + }, + "content": "[差异化跳转]($urlVal)" +} +``` + +### 兜底高度 & 宽度变更 + +1.0 结构 | 2.0 结构 +---|--- +- 卡片兜底高度:24px
    - 组件宽度设置的像素值如果大于父容器宽度,会收缩限制到父容器宽度,仅在交互容器中会截断展示 | - 卡片的兜底高度:40px
    - 组件宽度设置的像素值如果大于父容器宽度,将会截断展示 + +### 废弃备注组件 & 交互模块 + +2.0 结构不再支持[备注](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/note)(note)组件和[交互模块](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/component-list/common-components-and-elements)("tag" 为 "action"),相关效果可由以下组件和属性实现: +- 备注(note)组件:可由普通文本组件配置 notation 字号、grey 字体颜色、icon 属性替代; +- 交互模块:可由按钮(button)或折叠按钮组(overflow)组件配置合适的组件间距 (`vertical_spacing` 和 `horizontal_spacing`) 替代。 + +## 新增属性和优化说明 + +本小节介绍 2.0 结构新增的属性和优化点。 + +### 新增 `streaming_mode` 属性,支持流式更新 + +2.0 结构新增 `streaming_mode` 和 `summary` 字段,支持卡片流式更新、文本流式更新能力。详情参考[流式更新 OpenAPI 调用指南](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/streaming-updates-openapi-overview)。 +```json +{ + "schema": "2.0", // 卡片 JSON 结构的版本。默认为 1.0。 + "config": { + "streaming_mode": true, // 卡片是否处于流式更新模式,默认值为 false。 + "summary": { + "content": "自定义内容", // 自定义摘要信息。默认为“生成中”。 + "i18n_content": { // 摘要信息的多语言配置。了解支持的所有语种。参考。 + "zh_cn": "", + "en_us": "", + "ja_jp": "" + } + } + } +} +``` + +### 新增 `element_id` 属性,用于操作组件 + +所有组件和元素(如 `tag` 为 `plain_text` 的文本元素)新增 `element_id` 属性,作为操作组件或元素的唯一标识。在同一张卡片内,该字段的值全局唯一。仅允许使用字母、数字和下划线,必须以字母开头,不得超过 20 字符。 +```json +{ + "tag": "button", // 组件的标签。 + "element_id": "button_1" // 操作组件时的唯一标识。 +} +``` + +### 组件统一支持布局相关能力 + +卡片 JSON 2.0 结构中,各类组件统一新增了一批布局类属性。 +```json +// 卡片层级 +{ + "schema": "2.0", + "header": { + "title": {}, + "padding": "4px" // 支持设置[0,99]px + }, + "body": { + "vertical_spacing": "4px", // body 内子组件的垂直间距,支持设置[0,99]px + "padding": "4px", // body 的内边距配置,支持设置[0,99]px + "elements": [] + } +} +// 组件 +{ + "tag": "xxxx", + // 各组件均新增的布局类属性 + "margin": "4px", // 外边距,默认值 "0",支持范围 [-99,99]px + // 容器类组件(含elements)新增的布局类属性,用于控制子元素排列 + "padding": "4px", // 内边距,支持范围 [0,99]px + "direction": "vertical", // 布局方向,支持 "vertical"|"horizontal",默认值 "vertical" + "horizontal_spacing": "3px", // 水平间距,支持范围 [0,99]px + "vertical_spacing": "4px", // 垂直间距,支持范围 [0,99]px + "horizontal_align": "left", // 水平对齐,支持 "left"|"center"|"right",默认值 "left" + "vertical_align": "center", // 垂直对齐,支持 "top"|"center"|"bottom",默认值 "top" + // 其他 + "elements": [] +} +``` +[普通文本组件](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/plain-text)支持配置 width 属性。可取值: +- fill:文本的宽度将与组件宽度一致,撑满组件。 +- auto:文本的宽度自适应文本内容本身的长度。 +- [16,999]px:自定义文本宽度。 +```json +{ + "tag": "div", + "width": "fill", // 文本宽度。支持 "fill"|"auto"|"{{[16,999]}}px"。默认值为 fill。 + } +``` + +### 富文本组件支持标准 markdown 语法 + +[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)支持除 `HTMLBlock` 外所有标准的 Markdown 语法和部分 HTML 语法。了解 Markdown 标准语法,请参考 [CommonMark Spec 官方文档](https://spec.commonmark.org/0.31.2/)。你也可以使用 [CommonMark playground](https://spec.commonmark.org/dingus/) 预览 Markdown 效果。了解更多,参考[富文本(Markdown)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/rich-text)。 + +注意,在卡片的富文本组件中,以下语法的渲染效果与 CommonMark 有差异: +- 富文本组件支持使用一个 Enter 键作为软换行(Soft Break);支持两个 Enter 键作为硬换行(Hard Break)。软换行在渲染时可能会被忽略,具体取决于渲染器如何处理;硬换行在渲染时始终会显示为一个新行。 + +- 2.0 结构支持以下 HTML 语法: + - 开标签 `
    ` + - 自闭合标签 `
    ` + - 开标签 `
    ` + - 自闭合标签 `
    ` + - 闭合标签 `` + - 闭合标签 `` + - 闭合标签 `` + - 闭合标签 `` + - 闭合标签 `` + - 闭合标签 `` + - 闭合标签 `` + - 闭合标签 ``,支持嵌套其它标签,如 `redgreenagain`。其它标签包括: + - 闭合标签 `` + - 闭合标签 `` + - 闭合标签 `` + - 闭合标签 `` + - 闭合标签 `` + +### 容器类组件新增可内嵌的组件类型 + +JSON 2.0 结构中,表单容器、交互容器、折叠面板、分栏组件可内嵌除表单容器和表格组件外的其它所有组件。 + +1.0 结构 | 2.0 结构 +---|--- +- 表单容器:不支持内嵌表格、图表、和表单容器组件;不可直接内嵌普通文本组件
    - 交互容器:仅支持内嵌普通文本、富文本、图片、备注、分栏、勾选器、交互容器组件
    - 折叠面板:不支持内嵌表单容器(form)和表格组件(table)组件
    - 分栏:不支持内嵌表格(table)、表单(form)和多图混排(img_combination)组件 | 表单容器、交互容器、折叠面板、分栏组件可内嵌除表单容器(form)和表格组件(table)外的其它所有组件。 diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__component-json-v2-overview.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__component-json-v2-overview.md new file mode 100644 index 0000000..60746f8 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__component-json-v2-overview.md @@ -0,0 +1,64 @@ +# 卡片 JSON 2.0 版本组件概述 + +飞书卡片中的组件可分为容器类、展示类和交互类组件。除循环容器外,所有组件均支持通过卡片 JSON 代码构建。除折叠面板、多图选择和勾选器外,所有组件均支持通过卡片搭建工具搭建使用。在 JSON 结构中,组件通过定义 `tag` 字段声明: + +```json +{ + "tag": "" // 在此声明组件的标签。不同的组件标签不同。 +} +``` + +本文档汇总并介绍基于[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)构建的组件。 + +## 客户端版本要求 +卡片 JSON 2.0 结构支持飞书客户端 7.20 及之后版本。当使用 JSON 2.0 结构的卡片发送至低于 7.20 版本的客户端时,卡片标题可正常显示,但内容将展示兜底的升级提示文案。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/35efb2f0bfbe5d22fe4b7a420925d2af_g5UivxGopO.png?height=449&lazyload=true&maxWidth=400&width=742) + +## 容器类组件 + +容器类组件可用于布局内容或配置交互逻辑。在容器组件中支持添加展示类组件和交互类组件。 + +组件 | 是否支持在搭建工具中使用 | 描述 +---|---|--- +[分栏(column_set)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/containers/column-set) | ✓ | 分栏支持横向排布多列,在列内自由组合图文内容,搭建出如数据表、商品或文章列表、差旅信息等图文并茂、交互友好的卡片。 +[循环容器](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/recycling-container) | ✓ | 循环容器支持内嵌所有展示、交互类组件和分栏组件。通过使用循环容器,你可以高效地组织一系列排版类似、数据不同的内容。仅支持通过搭建工具搭建使用。 +[表单容器(form)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/containers/form-container) | ✓ | 表单容器支持用户在前端本地录入一批表单项后,通过点击一次 提交 按钮,将这一批本地缓存的表单内容一次回调至开发者的服务端,实现异步提交多个表单项数据的效果。 +[交互容器(interactive_container)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/containers/interactive-container) | ✓ | 交互容器允许你基于业务需求在交互容器中内嵌组件,并灵活组合多个交互容器,并统一定义多个交互容器的样式、交互能力等,实现多种组合效果和丰富的卡片交互。 +[折叠面板(collapsible_panel)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/containers/collapsible-panel) | × | 折叠面板允许你在卡片中折叠次要信息,如备注、较长文本等,以突出主要信息。 + +## 展示类组件 + +展示类组件用于构成卡片的主要内容,不具备交互能力。 + +组件 | 是否支持在搭建工具中使用 | 描述 +---|---|--- +[标题(header)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/title) | ✓ | 标题组件用于构建飞书卡片的标题样式与内容,支持添加卡片主标题、副标题、后缀标签和标题图标。 +[普通文本(div)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/plain-text) | ✓ | 普通文本组件支持添加普通文本和前缀图标,并设置文本大小、颜色、对齐方式等展示样式。 +[富文本(markdown)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/rich-text) | ✓ | 富文本(Markdown)组件支持渲染文本、图片、分割线等元素。 +[图片(img)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/image) | ✓ | 图片组件支持通过调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口或在新版飞书卡片搭建工具中上传图片,在卡片内添加图片。 +[多图混排(img_combination)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/multi-image-laylout) | ✓ | 多图混排组件支持通过调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口或在新版飞书卡片搭建工具中上传图片,在卡片内添加多张图片。 +[人员(person)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/user-profile) | ✓ | 人员组件支持展示人员的用户名和头像。你可通过传入人员的 open_id、user_id 或 union_id 使用该组件。 +[人员列表(person_list)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/user-list) | ✓ | 人员列表组件支持展示多个人员的用户名和头像。你可通过传入人员的 open_id、user_id 或 union_id 使用该组件。 +[图表(chart)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/chart) | ✓ | 图表组件基于 [VChart](https://www.visactor.io/) 的图表定义,支持折线图、面积图、柱状图、饼图、词云等多种数据呈现方式,帮助你可视化各类信息,提高信息沟通效率。 +[表格(table)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/table) | ✓ | 表格组件支持在表格中添加普通文本、选项标签、人员列表以及数字格式的内容。 +[分割线(hr)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/divider) | ✓ | 分割线组件是一条长横线,用于分割卡片的内容,使呈现内容更清晰。 + +## 交互类组件 + +交互类组件为卡片提供了交互能力。用户在接收到包含交互组件的卡片时,可直接在卡片内访问链接或处理业务。 + +组件 | 是否支持在搭建工具中使用 | 描述 +---|---|--- +[输入框(input)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/input) | ✓ | 输入框组件支持收集不固定的文本内容,如原因、评价、备注等。 +[按钮(button)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/button) | ✓ | 按钮组件提供配置按钮的回传交互能力或者链接跳转能力,并支持多种样式和尺寸。 +[折叠按钮组(overflow)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/overflow) | ✓ | 折叠按钮组组件支持将多个按钮添加在折叠按钮组中,默认情况下按钮组为折叠状态,点击按钮组将会展示组内所有按钮。 +[下拉选择-单选(select_static)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/single-select-dropdown-menu) | ✓ | 下拉选择-单选组件支持自定义单选菜单的选项文本、图标和回传参数。 +[下拉选择-多选(multi_select_static)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/multi-select-dropdown-menu) | ✓ | 下拉选择-多选组件支持自定义多选菜单的选项文本、图标和回传参数。 +[人员选择-单选(select_person)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/single-select-user-picker) | ✓ | 人员选择-多选组件支持添加指定人员作为单选选项。 +[人员选择-多选(multi_select_person)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/multi-select-user-picker) | ✓ | 人员选择-多选组件支持添加指定人员作为多选选项。 +[日期选择器(date_picker)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/date-picker) | ✓ | 日期选择器组件支持提供日期选项。 +[时间选择器(picker_time)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/time-selector) | ✓ | 时间选择器组件支持提供时间选项。 +[日期时间选择器(picker_datetime)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/date-time-picker) | ✓ | 日期时间选择器组件支持提供时间和日期选项。 +[多图选择(select_img)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/image-picker) | × | 多图选择组件支持提供图片选项,支持单选、多选图片。 +[勾选器(checker)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/checker) | × | 勾选器支持配置回调响应,主要用于任务勾选的场景。 diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__containers__collapsible-panel.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__containers__collapsible-panel.md new file mode 100644 index 0000000..17fd1a1 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__containers__collapsible-panel.md @@ -0,0 +1,246 @@ +# 折叠面板 + +折叠面板允许在卡片中折叠次要信息,如备注、较长文本等,以突出主要信息。 + +本文档介绍折叠面板组件的 JSON 2.0 结构,要查看历史 JSON 1.0 结构,参考[折叠面板](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/collapsible-panel)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/d72600eb4e82048a9e58b8354ca8303f_b0QmSYN4Jq.gif?height=660&lazyload=true&maxWidth=300&width=762) + +## 注意事项 + +- 折叠面板仅支持通过撰写卡片 JSON 代码的方式使用,暂不支持在卡片搭建工具上构建使用。 +- 容器类组件最多支持嵌套五层组件。建议你避免在折叠面板中嵌套多层组件。多层嵌套会压缩内容的展示空间,影响卡片的展示效果。 + +## 嵌套规则 + +折叠面板不支持内嵌表单容器(form)组件。 + +## 组件属性 + +本小节介绍折叠面板的属性。 + +### JSON 结构 + +折叠面板组件的完整 JSON 2.0 结构如下所示: +```json +{ + "schema": "2.0", // 卡片 JSON 结构的版本。默认为 1.0。要使用 JSON 2.0 结构,必须显示声明 2.0。 + "body": { + "elements": [ + { + "tag": "collapsible_panel", // 折叠面板的标签。 + "element_id": "custom_id", // 操作组件的唯一标识。JSON 2.0 新增属性。用于在调用组件相关接口中指定组件。需开发者自定义。 + "direction": "vertical", // 面板内组件的排列方向。JSON 2.0 新增属性。可选值:"vertical"(垂直排列)、"horizontal"(水平排列)。默认为 "vertical"。 + "vertical_spacing": "8px", // 面板内组件的垂直间距。JSON 2.0 新增属性。可选值:"small"(4px)、"medium"(8px)、"large"(12px)、"extra_large"(16px)或[0,99]px。 + "horizontal_spacing": "8px", // 面板内组件内的垂直间距。JSON 2.0 新增属性。可选值:"small"(4px)、"medium"(8px)、"large"(12px)、"extra_large"(16px)或[0,99]px。 + "vertical_align": "top", // 面板内组件的垂直居中方式。JSON 2.0 新增属性。默认值为 top。 + "horizontal_align": "left", // 面板内组件的水平居中方式。JSON 2.0 新增属性。默认值为 left。 + "padding": "8px 8px 8px 8px", // 折叠面板的内边距。JSON 2.0 新增属性。支持范围 [0,99]px。 + "margin": "0px 0px 0px 0px", // 折叠面板的外边距。JSON 2.0 新增属性。默认值 "0",支持范围 [-99,99]px。 + "expanded": true, // 面板是否展开。默认值 false。 + "background_color": "grey", // 折叠面板的背景色,默认为透明。 + "header": { + // 折叠面板的标题设置。 + "title": { + // 标题文本设置。支持 plain_text 和 markdown。 + "tag": "markdown", + "content": "**面板标题文本**" + }, + "background_color": "grey", // 标题区的背景色,默认为透明。 + "vertical_align": "center", // 标题区的垂直居中方式。 + "padding": "4px 0px 4px 8px", // 标题区的内边距。 + "position": "top", // 标题区的位置。 + "width": "auto", // 标题区的宽度。默认值为 fill。 + "icon": { + // 标题前缀图标 + "tag": "standard_icon", // 图标类型. + "token": "chat-forbidden_outlined", // 图标库中图标的 token。当 tag 为 standard_icon 时生效。 + "color": "orange", // 图标的颜色。当 tag 为 standard_icon 时生效。 + "img_key": "img_v2_38811724", // 自定义前缀图标的图片 key。当 tag 为 custom_icon 时生效。 + "size": "16px 16px" // 图标的尺寸。默认值为 10px 10px。 + }, + "icon_position": "follow_text", // 图标的位置。默认值为 right。 + "icon_expanded_angle": -180 // 折叠面板展开时图标旋转的角度,正值为顺时针,负值为逆时针。默认值为 180。 + }, + "border": { + // 边框设置。默认不显示边框。 + "color": "grey", // 边框的颜色。 + "corner_radius": "5px" // 圆角设置。 + }, + "elements": [ + // 此处可添加各个组件的 JSON 结构。暂不支持表单(form)组件。 + { + "tag": "markdown", + "content": "很长的文本" + } + ] + } + ] + } +} +``` + +### 字段说明 + +折叠面板各字段说明如下表所示: + +名称 | 必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 否 | string | / | 组件的标签。折叠面板取固定值为 collapsible_panel。 +expanded | 否 | Boolean | false | 面板是否展开。可选值:
    - true:面板为展开状态
    - false:面板为折叠状态。默认为折叠状态 +element_id | 否 | String | 空 | 操作组件的唯一标识。JSON 2.0 新增属性。用于在调用[组件相关接口](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/create)中指定组件。在同一张卡片内,该字段的值全局唯一。仅允许使用字母、数字和下划线,必须以字母开头,不得超过 20 字符。 +margin | 否 | String | 0px | 容器的外边距。值的取值范围为 [-99,99]px。可选值:
    - 单值,如 "10px",表示容器的四个外边距都为 10 px。
    - 双值,如 "4px 0",表示容器的上下外边距为 4 px,左右外边距为 0 px。使用空格间隔(边距为 0 时可不加单位)。
    - 多值,如 "4px 0 4px 0",表示容器的上、右、下、左的外边距分别为 4px,12px,4px,12px。使用空格间隔。 +horizontal_spacing | 否 | String | 8px | 容器内组件的水平间距,可选值:
    - small:小间距,4px
    - medium:中等间距,8px
    - large:大间距,12px
    - extra_large:超大间距,16px
    - 具体数值,如 20px。取值范围为 [0,99]px +horizontal_align | 否 | String | left | 容器内组件水平对齐的方式。可取值:
    - left:左对齐
    - center:居中对齐
    - right:右对齐 +vertical_spacing | 否 | String | 12px | 容器内组件的水平间距,可选值:
    - small:小间距,4px
    - medium:中等间距,8px
    - large:大间距,12px
    - extra_large:超大间距,16px
    - 具体数值,如 20px。取值范围为 [0,99]px +vertical_align | 否 | String | top | 容器内组件垂直对齐的方式。可取值:
    - top:上对齐
    - center:居中对齐
    - bottom:下对齐 +direction | 否 | String | vertical | 容器的排列方向。可选值:
    - vertical:垂直排列
    - horizontal:水平排列 +padding | 否 | String | 0px | 容器的内边距。值的取值范围为 [-99,99]px。可选值:
    - 单值,如 "10px",表示容器的四个外边距都为 10 px。
    - 双值,如 "4px 0",表示容器的上下外边距为 4 px,左右外边距为 0 px。使用空格间隔(边距为 0 时可不加单位)。
    - 多值,如 "4px 0 4px 0",表示容器的上、右、下、左的外边距分别为 4px,12px,4px,12px。使用空格间隔。 +background_color | 否 | String | 空 | 折叠面板的背景色,默认为透明。枚举值参见[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。 +header | 是 | Object | - | 折叠面板的标题设置。 +└ title | 否 | Object | - | 标题文本设置。 +└└ tag | 是 | String | 空 | 文本类型的标签。可取值:
    - plain_text:普通文本内容
    - markdown:富文本内容。了解支持的 Markdown 语法,参考[富文本组件](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/rich-text)。 +└└ content | 否 | String | 空 | 折叠面板标题的内容。 +└ background_color | 否 | String | 空 | 折叠面板标题区域的背景颜色设置,默认为透明色。枚举值参见[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。
    **注意**:如果你未设置此字段,则折叠面板的标题区域的背景色由 background_color 字段决定。 +└ width | 否 | String | fill | 标题元素的宽度。JSON 2.0 新增属性。支持飞书客户端 7.32 及以上版本。
    - `fill`:标题和折叠面板等宽
    - `auto`:标题自适应文本长度
    - `auto_when_fold`:仅在折叠面板收起后,标题自适应文本长度 +└ vertical_align | 否 | String | center | 标题区域的垂直居中方式。可取值:
    - top:标题区域垂直居中于面板区域的顶部
    - center:标题区域垂直居中于面板区域的中间
    - bottom:标题区域垂直居中于面板区域的底部 +└ padding | 否 | String | 0 | 标题区域的内边距。值的取值范围为 [-99,99]px。可选值:
    - 单值,如 "10px",表示标题区的四个外边距都为 10 px。
    - 双值,如 "4px 0",表示标题区的上下外边距为 4 px,左右外边距为 0 px。使用空格间隔(边距为 0 时可不加单位)。
    - 多值,如 "4px 0 4px 0",表示标题区的上、右、下、左的外边距分别为 4px,12px,4px,12px。使用空格间隔。 +└ icon | 否 | Object | / | 添加图标作为标题前缀或后缀图标。支持自定义或使用图标库中的图标。示例代码如下:
    ```json
    "icon": {
    "tag": "standard_icon",
    "token": "down-small-ccm_outlined",
    "color": "",
    "size": "16px 16px"
    }
    ``` +└└ tag | 否 | String | / | 图标类型的标签。可取值:
    - standard_icon:使用图标库中的图标
    - custom_icon:使用用自定义图片作为图标 +└ └ token | 否 | String | / | 图标库中图标的 token。当 tagstandard_icon 时生效。枚举值参见[图标库](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-icons)。 +└└ color | 否 | String | / | 图标的颜色。支持设置线性和面性图标(即 token 末尾为 outlinedfilled 的图标)的颜色。当 tagstandard_icon 时生效。枚举值参见[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。 +└└ img_key | 否 | String | / | 自定义前缀图标的图片 key。当 tagcustom_icon 时生效。图标 key 的获取方式:调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口,上传用于发送消息的图片,并在返回值中获取图片的 image_key。 +└ └ size | 否 | String | 10px 10px | 图标的尺寸。支持 "[1,999] [1,999]px"。 +└ icon_position | 否 | String | right | 图标的位置。可选值:
    - left:图标在标题区域最左侧
    - right:图标在标题区域最右侧
    - follow_text:图标在文本右侧 +└ icon_expanded_angle | 否 | Number | 180 | 折叠面板展开时图标旋转的角度,正值为顺时针,负值为逆时针。可选值:
    - -180:逆时针旋转 180 度
    - -90:逆时针旋转 90 度
    - 90:顺时针旋转 90 度
    - 180:顺时针旋转 180 度 +border | 否 | Object | 空 | 边框设置。默认不显示边框。 +└ color | 否 | String | grey | 边框颜色设置。枚举值参见[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。 +└ corner_radius | 否 | String | 5px | 圆角设置。 +elements | 否 | Array | 空 | 各个组件的 JSON 结构。暂不支持表单(form)组件。 + +## 示例代码 + +以下的 JSON 2.0 示例代码可实现如下图所示的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/d72600eb4e82048a9e58b8354ca8303f_b0QmSYN4Jq.gif?height=660&lazyload=true&maxWidth=300&width=762) + +```json +{ + "schema": "2.0", + "header": { + "template": "yellow", + "title": { + "tag": "plain_text", + "content": "折叠面板展示" + } + }, + "body": { + "elements": [ + { + "tag": "markdown", + "content": "下面是一个 默认折叠 的折叠面板组件" + }, + { + "tag": "collapsible_panel", + "expanded": false, + "header": { + "title": { + "tag": "plain_text", + "content": "面板标题文本" + }, + "vertical_align": "center", + "icon": { + "tag": "standard_icon", + "token": "down-small-ccm_outlined", + "color": "", + "size": "16px 16px" + }, + "icon_position": "right", + "icon_expanded_angle": -180 + }, + "border": { + "color": "grey", + "corner_radius": "5px" + }, + "vertical_spacing": "8px", + "padding": "8px 8px 8px 8px", + "elements": [ + { + "tag": "markdown", + "content": "很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本" + } + ] + }, + { + "tag": "markdown", + "content": "下面是一个 标题带背景色 且 默认展开 的折叠面板组件" + }, + { + "tag": "collapsible_panel", + "expanded": true, + "header": { + "title": { + "tag": "markdown", + "content": "**面板标题文本**" + }, + "background_color": "yellow", + "vertical_align": "center", + "icon": { + "tag": "standard_icon", + "token": "down-small-ccm_outlined", + "color": "white", + "size": "16px 16px" + }, + "icon_position": "right", + "icon_expanded_angle": -180 + }, + "border": { + "color": "grey", + "corner_radius": "5px" + }, + "vertical_spacing": "8px", + "padding": "8px 8px 8px 8px", + "elements": [ + { + "tag": "markdown", + "content": "很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本" + } + ] + }, + { + "tag": "markdown", + "content": "下面是一个无边框折叠面板组件" + }, + { + "tag": "collapsible_panel", + "expanded": true, + "header": { + "title": { + "tag": "markdown", + "content": "**面板标题文本**" + }, + "width": "auto_when_fold", + "vertical_align": "center", + "padding": "4px 0px 4px 8px", + "icon": { + "tag": "standard_icon", + "token": "down-small-ccm_outlined", + "color": "", + "size": "16px 16px" + }, + "icon_position": "follow_text", + "icon_expanded_angle": -180 + }, + "vertical_spacing": "8px", + "padding": "8px 8px 8px 8px", + "elements": [ + { + "tag": "markdown", + "content": "很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本很长的文本" + } + ] + } + ] + } +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__containers__column-set.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__containers__column-set.md new file mode 100644 index 0000000..28ceeb7 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__containers__column-set.md @@ -0,0 +1,612 @@ +# 分栏组件 +分栏组件提供卡片内布局的能力,并提供对齐方式、容器宽度、交互方式等属性。你可以使用分栏组件横向排布多个列容器,在列容器内自由组合图文内容,搭建出如数据表、商品或文章列表、差旅信息等图文并茂、交互友好的卡片。 + +本文档介绍分栏组件的 JSON 2.0 结构,要查看历史 JSON 1.0 结构,参考[分栏](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/column-set)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/ab0828f3677f4eaab0582cf8a13780ca_6dNbyUvuxR.png?height=691&lazyload=true&maxWidth=300&width=630) + +## 注意事项 + +分栏组件最多支持嵌套五层组件。建议你避免在分栏中嵌套多层组件。多层嵌套会压缩内容的展示空间,影响卡片的展示效果。 + +## 应用场景 + +- 分栏的使用场景非常广泛,在卡片中适当使用分栏,可以使信息排布更合理、主次更分明。常见场景如下所示。推荐你直接前往卡片搭建工具,查看[分栏示例](https://open.larkoffice.com/cardkit?catalogId=10015&templateId=AAqBEj6y7tTLV)。 + +- **数据报表推送:** 使用分栏可以快速构建整齐、自适应屏幕的多列数据表,解决了传统报表构建时繁琐的排版过程,以及无法自适应各类屏幕的样式问题。 + - **图文混排**:分栏灵活的横纵列排版能力,使你可以快速构建理想的图文卡片。有效降低手动调整图文排版的耗时。 + - **表单收集**:表单容器中内嵌分栏组件,将相关字段放在同一列,可有效提升内容的逻辑性和可读性。 +- 分栏中还可配置点击链接、变量,推荐你直接前往卡片搭建工具,查看[分栏配置链接案例](https://open.larkoffice.com/cardkit?catalogId=10015&templateId=AAqBEj6y7tTLV)。 + +## 嵌套规则 + +分栏组件由分栏本身的属性(column_set)和列容器(column)组成。一个分栏组件中内可以添加多个列容器,每个列容器中可内嵌多个组件。 + +[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)支持内嵌除表单容器(form)和表格组件(table)外的其它所有组件。 + +整体的嵌套关系如下图所示。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/9b253ea6e463d2841c8295b26873c3f7_8BnIr3afv7.png?height=722&lazyload=true&maxWidth=600&width=1942) + +列容器中再嵌套分栏的层级关系如下图所示。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/e2b6909f3881bc78965466cc736d5ec6_FKkeg0UCcT.png?height=584&lazyload=true&maxWidth=600&width=2034) + +## 组件属性 + +### JSON 结构 + +分栏组件的完整 JSON 2.0 结构如下所示: + +```JSON +{ + "schema": "2.0", + "body": { + "elements": [ + { + "tag": "column_set", // 分栏的标签。 + "element_id": "custom_id", // 操作组件的唯一标识。用于在调用组件相关接口中指定组件。需开发者自定义。 + "margin": "4px", // 分栏的外边距,默认值 "0",支持范围 [-99,99]px。 + "horizontal_spacing": "large", // 分栏内组件之间的间距,可选值:"small"(4px)、"medium"(8px)、"large"(12px)、"extra_large"(16px)或[0,99]px。默认 8px。 + "horizontal_align": "left", // 分栏内组件水平对齐的方式,可选值:"left"、"center"、"right",默认值为 "left"。 + "flex_mode": "none", // 移动端和 PC 端的窄屏幕下,各列的自适应方式。默认值 none。 + "background_style": "default", // 分栏的背景色样式。默认值 default。 + "action": { // 在此处设置点击分栏时的交互配置。 + "multi_url": { + "url": "https://open.feishu.cn", + "pc_url": "https://open.feishu.com", + "ios_url": "https://developer.apple.com/", + "android_url": "https://developer.android.com/" + } + }, + "columns": [ + // 列配置 + { + "tag": "column", + "element_id": "custom_id", // 操作组件的唯一标识。用于在调用组件相关接口中指定组件。需开发者自定义。 + "background_style": "default", // 列的背景色样式。默认值 default。 + "width": "auto", // 列的宽度。默认值 auto。 + "weight": 1, // 当 width 取值 weighted 时生效,表示当前列的宽度占比。 + "horizontal_spacing": "large", // 列内组件之间的间距,可选值:"small"(4px)、"medium"(8px)、"large"(12px)、"extra_large"(16px)或[0,99]px。默认 8px。 + "horizontal_align": "left", // 列内组件水平对齐的方式,可选值:"left"、"center"、"right",默认值为 "left"。 + "vertical_align": "center", // 列内组件的垂直对齐方式,可选值:"top"、"center"、"bottom",默认值为 "top"。 + "vertical_spacing": "4px", // 列内子组件纵向间距。默认值 default(8px)。 + "direction": "vertical", // 列的排列方向。可选值:"vertical"(垂直排列)、"horizontal"(水平排列)。默认为 "vertical"。 + "padding": "8px", // 列的内边距。默认值 0px。支持范围 [0,99]px。 + "margin": "4px", // 列的外边距,默认值 0px。支持范围 [-99,99]px。 + "action": { + // 在此处设置点击列时的交互配置。 + "multi_url": { + "url": "https://www.baidu.com", + "pc_url": "https://www.baidu.com", + "ios_url": "https://www.google.com", + "android_url": "https://www.apple.com.cn" + } + }, + "elements": [] // 列容器内嵌的组件,不支持内嵌表格和表单容器。 + } + ] + } + ] + } +} +``` + +### 分栏字段说明 + +分栏(column_set)各属性字段说明如下表所示。 + +名称 | 必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | String | / | 组件的标签。分栏组件的固定值为 column_set。 +element_id | 否 | String | 空 | 操作组件的唯一标识。JSON 2.0 新增属性。用于在调用[组件相关接口](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/create)中指定组件。在同一张卡片内,该字段的值全局唯一。仅允许使用字母、数字和下划线,必须以字母开头,不得超过 20 字符。 +horizontal_spacing | 否 | String | 8px | 分栏内组件的水平间距,可选值:
    - small:小间距,4px
    - medium:中等间距,8px
    - large:大间距,12px
    - extra_large:超大间距,16px
    - 具体数值,如 20px。取值范围为 [0,99]px +horizontal_align | 否 | String | left | 分栏内组件在水平方向上的对齐方式。可取值:
    - left:左对齐
    - center:居中对齐
    - right:右对齐 +margin | 否 | String | 0px | 分栏的外边距。值的取值范围为 [-99,99]px。可选值:
    - 单值,如 "10px",表示分栏的四个外边距都为 10 px。
    - 双值,如 "4px 0",表示分栏的上下外边距为 4 px,左右外边距为 0 px。使用空格间隔(边距为 0 时可不加单位)。
    - 多值,如 "4px 0 4px 0",表示分栏的上、右、下、左的外边距分别为 4px,12px,4px,12px。使用空格间隔。 +flex_mode | 否 | String | none | 移动端和 PC 端的窄屏幕下,各列的自适应方式。取值:
    - none:不做布局上的自适应,在窄屏幕下按比例压缩列宽度
    - stretch:列布局变为行布局,且每列(行)宽度强制拉伸为 100%,所有列自适应为上下堆叠排布
    - flow:列流式排布(自动换行),当一行展示不下一列时,自动换至下一行展示
    - bisect:两列等分布局
    - trisect:三列等分布局 +background_style | 否 | String | default | 分栏的背景色样式。可取值:
    - default:默认的白底样式,客户端深色主题下为黑底样式
    - 卡片支持的颜色枚举值和 RGBA 语法自定义颜色。参考[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。
    **注意**:当存在分栏的嵌套时,上层分栏的颜色覆盖下层分栏的颜色。 +action | 否 | Action | / | 设置点击分栏时的交互配置。当前仅支持跳转交互。如果布局容器内有交互组件,则优先响应交互组件定义的交互。 +└ multi_url | 否 | Struct | 空 | 配置各个端的链接地址。 +└└ url | 否 | String | 空 | 兜底的跳转链接。 +└└ android_url | 否 | String | 空 | Android 端的跳转链接。可配置为 `lark://msgcard/unsupported_action` 声明当前端不允许跳转。 +└└ ios_url | 否 | String | 空 | iOS 端的跳转链接。可配置为 `lark://msgcard/unsupported_action` 声明当前端不允许跳转。 +└└ pc_url | 否 | String | 空 | PC 端的跳转链接。可配置为 `lark://msgcard/unsupported_action` 声明当前端不允许跳转。 +columns | 是 | column[] | 空 | 分栏中列的配置。详情参考下文。 + +### 列字段说明 + +分栏中列(column)的各属性字段说明如下表所示。 + +名称 | 必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | String | / | 列的标签,固定取值为 `column`。 +element_id | 否 | String | 空 | 操作组件的唯一标识。JSON 2.0 新增属性。用于在调用[组件相关接口](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/create)中指定组件。在同一张卡片内,该字段的值全局唯一。仅允许使用字母、数字和下划线,必须以字母开头,不得超过 20 字符。 +background_style | 否 | String | default | 列的背景色样式。可取值:
    - default:默认的白底样式,客户端深色主题下为黑底样式
    - 卡片支持的颜色枚举值和 RGBA 语法自定义颜色。参考[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color) +width | 否 | String | auto | 列宽度。仅 `flex_mode` 为 `none` 时,生效此属性。取值:
    - auto:列宽度与列内元素宽度一致
    - weighted:列宽度按 `weight` 参数定义的权重分布
    - 具体数值,如 100px。取值范围为 [16,600]px。V7.4 及以上版本支持该枚举 +weight | 否 | Number | 1 | 当 `width` 字段取值为 `weighted` 时生效,表示当前列的宽度占比。取值范围为 1 ~ 5 之间的整数。 +horizontal_spacing | 否 | String | 8px | 列内组件的水平间距,可选值:
    - small:小间距,4px
    - medium:中等间距,8px
    - large:大间距,12px
    - extra_large:超大间距,16px
    - 具体数值,如 20px。取值范围为 [0,99]px +horizontal_align | 否 | String | left | 列内组件在水平方向上的对齐方式。可取值:
    - left:左对齐
    - center:居中对齐
    - right:右对齐 +vertical_align | 否 | String | top | 列内组件在垂直方向上的对齐方式。可取值:
    - top:上对齐
    - center:居中对齐
    - bottom:下对齐 +vertical_spacing | 否 | String | 8px | 列内组件的纵向间距。可选值:
    - small:小间距,4px
    - medium:中等间距,8px
    - large:大间距,12px
    - extra_large:超大间距,16px
    - 具体数值,如 20px。取值范围为 [0,99]px +direction | 否 | String | vertical | 列的排列方向。可选值:
    - vertical:垂直排列
    - horizontal:水平排列 +padding | 否 | String | 0px | 列的内边距。值的取值范围为 [0,99]px。可选值:
    - 单值,如 "10px",表示列的四个外边距都为 10 px。
    - 双值,如 "4px 0",表示列的上下外边距为 4 px,左右外边距为 0 px。使用空格间隔(边距为 0 时可不加单位)。
    - 多值,如 "4px 0 4px 0",表示列的上、右、下、左的外边距分别为 4px,12px,4px,12px。使用空格间隔。 +margin | 否 | String | 0px | 列的外边距。值的取值范围为 [-99,99]px。可选值:
    - 单值,如 "10px",表示容器的四个外边距都为 10 px。
    - 双值,如 "4px 0",表示容器的上下外边距为 4 px,左右外边距为 0 px。使用空格间隔(边距为 0 时可不加单位)。
    - 多值,如 "4px 0 4px 0",表示容器的上、右、下、左的外边距分别为 4px,12px,4px,12px。使用空格间隔。 +elements | 否 | Element 或 ColumnSet[] | 空 | 列中内嵌的组件。可内嵌组件参考上文嵌套关系。 +action | 否 | Action | / | 设置点击列时的交互配置。当前仅支持跳转交互。如果布局容器内有交互组件,则优先响应交互组件定义的交互。 +└ multi_url | 否 | Struct | 空 | 配置各个端的链接地址。 +└└ url | 否 | String | 空 | 兜底的链接地址。 +└└ android_url | 否 | String | 空 | Android 端的链接地址。可配置为 `lark://msgcard/unsupported_action` 声明当前端不允许跳转。 +└└ ios_url | 否 | String | 空 | iOS 端的链接地址。可配置为 `lark://msgcard/unsupported_action` 声明当前端不允许跳转。 +└└ pc_url | 否 | String | 空 | PC 端的链接地址。可配置为 `lark://msgcard/unsupported_action` 声明当前端不允许跳转。 + +## 示例代码 + +以下 JSON 2.0 结构的示例代码可实现如下图所示的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/ab0828f3677f4eaab0582cf8a13780ca_6dNbyUvuxR.png?height=691&lazyload=true&maxWidth=300&width=630) + +```json +{ + "schema": "2.0", + "body": { + "elements": [ + { + "tag": "markdown", + "content": ":YouAreTheBest:**个人效率总览** ", + "text_align": "left", + "text_size": "heading" + }, + { + "tag": "column_set", + "flex_mode": "bisect", + "horizontal_spacing": "", + "horizontal_align": "center", + "columns": [ + { + "tag": "column", + "width": "weighted", + "vertical_align": "top", + "vertical_spacing": "8px", + "direction": "horizontal", + "elements": [ + { + "tag": "column_set", + "flex_mode": "none", + "horizontal_spacing": "8px", + "horizontal_align": "left", + "columns": [ + { + "tag": "column", + "width": "weighted", + "vertical_align": "top", + "vertical_spacing": "8px", + "background_style": "grey", + "padding": "8px", + "elements": [ + { + "tag": "column_set", + "flex_mode": "none", + "horizontal_spacing": "default", + "background_style": "default", + "columns": [ + { + "tag": "column", + "elements": [ + { + "tag": "div", + "text": { + "tag": "plain_text", + "content": "已审批单量", + "text_size": "normal", + "text_align": "center", + "text_color": "grey" + } + } + ], + "width": "weighted", + "weight": 1 + } + ] + }, + { + "tag": "column_set", + "flex_mode": "none", + "horizontal_spacing": "default", + "background_style": "default", + "columns": [ + { + "tag": "column", + "elements": [ + { + "tag": "div", + "text": { + "tag": "plain_text", + "content": "29 单", + "text_size": "heading", + "text_align": "center", + "text_color": "default" + } + } + ], + "width": "weighted", + "weight": 1 + } + ] + }, + { + "tag": "markdown", + "content": "高于部门 86%", + "text_align": "center", + "text_size": "normal" + } + ], + "weight": 1 + } + ], + "margin": "0px 0px 0px 0px" + } + ], + "weight": 1 + }, + { + "tag": "column", + "width": "weighted", + "vertical_align": "top", + "vertical_spacing": "8px", + "elements": [ + { + "tag": "column_set", + "flex_mode": "none", + "horizontal_spacing": "8px", + "horizontal_align": "left", + "columns": [ + { + "tag": "column", + "width": "weighted", + "vertical_align": "top", + "vertical_spacing": "8px", + "background_style": "grey", + "padding": "8px", + "elements": [ + { + "tag": "column_set", + "flex_mode": "none", + "horizontal_spacing": "default", + "background_style": "default", + "columns": [ + { + "tag": "column", + "elements": [ + { + "tag": "div", + "text": { + "tag": "plain_text", + "content": "审批平均耗时", + "text_size": "normal", + "text_align": "center", + "text_color": "grey" + } + } + ], + "width": "weighted", + "weight": 1 + } + ] + }, + { + "tag": "column_set", + "flex_mode": "none", + "horizontal_spacing": "default", + "background_style": "default", + "columns": [ + { + "tag": "column", + "elements": [ + { + "tag": "div", + "text": { + "tag": "plain_text", + "content": "0.9 小时", + "text_size": "heading", + "text_align": "center", + "text_color": "default" + } + } + ], + "width": "weighted", + "weight": 1 + } + ] + }, + { + "tag": "markdown", + "content": "落后部门 61%", + "text_align": "center", + "text_size": "normal" + } + ], + "weight": 1 + } + ], + "margin": "0px 0px 0px 0px" + } + ], + "weight": 1 + }, + { + "tag": "column", + "width": "weighted", + "vertical_align": "top", + "vertical_spacing": "8px", + "elements": [ + { + "tag": "column_set", + "flex_mode": "none", + "horizontal_spacing": "8px", + "horizontal_align": "left", + "columns": [ + { + "tag": "column", + "width": "weighted", + "vertical_align": "top", + "vertical_spacing": "8px", + "background_style": "grey", + "padding": "8px", + "elements": [ + { + "tag": "column_set", + "flex_mode": "none", + "horizontal_spacing": "default", + "background_style": "default", + "columns": [ + { + "tag": "column", + "elements": [ + { + "tag": "div", + "text": { + "tag": "plain_text", + "content": "代批率", + "text_size": "normal", + "text_align": "center", + "text_color": "grey" + } + } + ], + "width": "weighted", + "weight": 1 + } + ] + }, + { + "tag": "column_set", + "flex_mode": "none", + "horizontal_spacing": "default", + "background_style": "default", + "columns": [ + { + "tag": "column", + "elements": [ + { + "tag": "div", + "text": { + "tag": "plain_text", + "content": "0%", + "text_size": "heading", + "text_align": "center", + "text_color": "default" + } + } + ], + "width": "weighted", + "weight": 1 + } + ] + }, + { + "tag": "markdown", + "content": "领先部门 100%", + "text_align": "center", + "text_size": "normal" + } + ], + "weight": 1 + } + ], + "margin": "0px 0px 0px 0px" + } + ], + "weight": 1 + } + ], + "margin": "16px 0px 0px 0px" + }, + { + "tag": "markdown", + "content": ":STRIVE: **待优化的任务类型**", + "text_align": "left", + "text_size": "heading" + }, + { + "tag": "column_set", + "flex_mode": "none", + "horizontal_spacing": "8px", + "horizontal_align": "left", + "columns": [ + { + "tag": "column", + "width": "weighted", + "vertical_align": "center", + "vertical_spacing": "4px", + "elements": [ + { + "tag": "markdown", + "content": "1 加班申请", + "text_align": "left", + "text_size": "normal" + } + ], + "weight": 1 + }, + { + "tag": "column", + "width": "weighted", + "vertical_align": "center", + "vertical_spacing": "8px", + "elements": [ + { + "tag": "markdown", + "content": "低于部门 95% 的审批人 ", + "text_align": "right", + "text_size": "notation" + } + ], + "weight": 1 + } + ], + "margin": "16px 0px 0px 0px" + }, + { + "tag": "column_set", + "flex_mode": "none", + "horizontal_spacing": "8px", + "horizontal_align": "left", + "columns": [ + { + "tag": "column", + "width": "weighted", + "vertical_align": "center", + "vertical_spacing": "4px", + "elements": [ + { + "tag": "markdown", + "content": "2 休假申请", + "text_align": "left", + "text_size": "normal" + } + ], + "weight": 1 + }, + { + "tag": "column", + "width": "weighted", + "vertical_align": "center", + "vertical_spacing": "4px", + "elements": [ + { + "tag": "markdown", + "content": "低于部门 55% 的审批人 ", + "text_align": "right", + "text_size": "notation" + } + ], + "weight": 1 + } + ], + "margin": "16px 0px 0px 0px" + }, + { + "tag": "markdown", + "content": ":CheckMark:**效率高的任务类型**", + "text_align": "left", + "text_size": "heading" + }, + { + "tag": "column_set", + "flex_mode": "none", + "horizontal_spacing": "8px", + "horizontal_align": "left", + "columns": [ + { + "tag": "column", + "width": "weighted", + "vertical_align": "center", + "vertical_spacing": "4px", + "elements": [ + { + "tag": "markdown", + "content": "1 数据权限申请", + "text_align": "left", + "text_size": "normal" + } + ], + "weight": 1 + }, + { + "tag": "column", + "width": "weighted", + "vertical_align": "center", + "vertical_spacing": "4px", + "elements": [ + { + "tag": "markdown", + "content": "高于部门 68% 的审批人 ", + "text_align": "right", + "text_size": "notation" + } + ], + "weight": 1 + } + ], + "margin": "16px 0px 0px 0px" + }, + { + "tag": "column_set", + "flex_mode": "none", + "horizontal_spacing": "8px", + "horizontal_align": "left", + "columns": [ + { + "tag": "column", + "width": "weighted", + "vertical_align": "center", + "vertical_spacing": "4px", + "elements": [ + { + "tag": "markdown", + "content": "2 BOT推送消息", + "text_align": "left", + "text_size": "normal" + } + ], + "weight": 1 + }, + { + "tag": "column", + "width": "weighted", + "vertical_align": "center", + "vertical_spacing": "4px", + "elements": [ + { + "tag": "markdown", + "content": "高于部门 56% 的审批人 ", + "text_align": "right", + "text_size": "notation" + } + ], + "weight": 1 + } + ], + "margin": "16px 0px 0px 0px" + } + ] + }, + "i18n_header": { + "zh_cn": { + "title": { + "tag": "plain_text", + "content": "我的近期审批效率" + }, + "subtitle": { + "tag": "plain_text", + "content": "日期范围:2024.03.01 至 2024.03.31" + }, + "template": "orange", + "icon": { + "tag": "standard_icon", + "token": "approval_colorful" + } + } + } +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__containers__form-container.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__containers__form-container.md new file mode 100644 index 0000000..2f74fd7 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__containers__form-container.md @@ -0,0 +1,147 @@ +# 表单容器 + +在使用卡片收集内容时,可能存在需要用户提交多个表单项的场景。表单容器允许用户在前端本地录入一批表单项后,通过点击一次 **提交** 按钮,将这一批本地缓存的表单内容一次回调至开发者的服务端,实现异步提交多个表单项数据的效果。 + +本文档介绍表单容器的 JSON 2.0 结构,要查看历史 JSON 1.0 结构,参考[表单容器](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/form-container)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/3431ef3f14bc707acaf00093f55df9b1_736bnZnIuR.png?height=491&lazyload=true&maxWidth=400&width=794) + +## 注意事项 + +容器类组件最多支持嵌套五层组件。建议你避免在表单容器中嵌套多层组件。多层嵌套会压缩内容的展示空间,影响卡片的展示效果。如你希望卡片承接更复杂的表单内容,建议通过卡片链接跳转至 H5 或小程序实现表单能力。 + +## 嵌套规则 + +在[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)中: +- 表单容器不支持内嵌表格(table)和表单容器组件。 +- 表单容器组件不可被内嵌在其它组件内,只可放在卡片根节点下。 + +## 组件属性 + +本小节介绍表单容器的属性。 + +### JSON 结构 + +以下为表单容器的卡片 JSON 2.0 结构。在该结构中,容器内嵌了一个输入框组件、一个提交按钮和一个清空所填内容的按钮,且两个按钮放置于分栏组件中: + +```json +{ + "schema": "2.0", + "body": { + "elements": [ + { + "tag": "form", // 表单容器的标签。 + "element_id": "custom_id", // 操作组件的唯一标识。用于在调用组件相关接口中指定组件。需开发者自定义。 + "direction": "horizontal", // 容器内组件的排列方向。可选值:"vertical"(垂直排列)、"horizontal"(水平排列)。默认为 "vertical"。 + "horizontal_spacing": "8px", // 容器内组件之间的间距,可选值:"small"(4px)、"medium"(8px)、"large"(12px)、"extra_large"(16px)或[0,99]px。 + "vertical_spacing": "8px", // 容器内组件的纵向间距。可选值:"small"(4px)、"medium"(8px)、"large"(12px)、"extra_large"(16px)或[0,99]px。 + "horizontal_align": "left", // 容器内组件水平对齐的方式。默认值 left。 + "vertical_align": "top", // 容器内组件的垂直对齐方式,可选值:"top"、"center"、"bottom",默认值为 "top"。 + "padding": "4px 0px 4px 0px", // 容器的内边距。默认值 0px。支持范围 [0,99]px。 + "margin": "0px 0px 0px 0px", // 容器的外边距,默认值 "0",支持范围 [-99,99]px。 + "name": "form_1", // 该表单容器的唯一标识。用于识别用户在交互后,提交的是哪个表单容器的数据。 + "elements": [ + { + "tag": "input", // 为表单容器内添加一个输入框组件。 + "name": "reason", // 输入框组件的唯一标识。用于识别用户在交互后,提交的是哪个表单项的数据。在表单容器中所有的交互组件中,该字段必填,否则数据会发送失败。 + "required": true // 是否必填。为 true 时点击按钮后会做必填校验。 + }, + { + "tag": "column_set", // 表单容器内嵌分栏组件。用于放置“提交”按钮和“取消”按钮。 + "columns": [ + { // 分栏容器中的列。 + "tag": "column", // 分栏组件内的第一列。 + "width": "auto", // 列宽设置。auto 为自适应。 + "elements": [ // 列容器内嵌的组件。 + { + "tag": "button", // 添加一个用于提交数据的按钮组件。表单容器中必须至少有一个带有提交属性的按钮。 + "type": "primary", // 按钮的样式类型。 + "text": { // 按钮上的文本。 + "tag": "plain_text", + "content": "提交" + }, + "behaviors": [ // 为按钮添加打开链接交互事件或请求回调交互。 + { + "type": "open_url", // 声明按钮的交互类型是打开链接的跳转交互。 + "default_url": "https://www.baidu.com", // 兜底跳转地址。 + "android_url": "https://developer.android.com/", // 安卓端跳转地址。 + "ios_url": "lark://msgcard/unsupported_action", // iOS 端跳转地址。 + "pc_url": "https://www.windows.com" // 桌面端跳转地址。 + }, + { + "type": "callback", // 声明交互类型是回传数据到服务端的请求回调交互。 + "value": { + // 回传交互数据 + "key": "value" + } + } + ], + "form_action_type": "submit", // 将当前按钮与提交事件绑定。用户点击后,将触发表单容器的提交事件,异步提交所有已填写的表单项内容。表单容器中必须至少有一个带有提交属性的按钮。 + "name": "Button_m8pn9lbf" // 按钮组件的唯一标识,用于识别用户在交互后,点击的是哪个按钮。在表单容器中所有的交互组件中,该字段必填,否则数据会发送失败。 + } + ] + }, + { + "tag": "column", // 分栏组件内的第二列。 + "width": "auto", // 列宽设置。auto 为自适应。 + "elements": [ // 列容器内嵌的组件。 + { + "tag": "button", //添加一个用于清空已填写内容的按钮组件 + "type": "default", // 按钮的样式类型。default 为次按钮样式。 + "text": { // 按钮上的文本。 + "tag": "plain_text", + "content": "取消" + }, + "behaviors": [ + { + "type": "open_url", // 声明交互类型是打开链接的跳转交互。 + "default_url": "https://www.baidu.com", // 兜底跳转地址。 + "android_url": "https://developer.android.com/", // 安卓端跳转地址。 + "ios_url": "lark://msgcard/unsupported_action", // iOS 端跳转地址。 + "pc_url": "https://www.windows.com" // 桌面端跳转地址。 + }, + { + "type": "callback", // 声明交互类型是回传数据到服务端的回传交互。 + "value": { + // 回传交互数据 + "key": "value" + } + } + ], + "form_action_type": "reset", // 将当前按钮设为重置。用户点击后,将重置所有已填写的表单项内容。 + "name": "Button_m8pn9lbg" // 按钮组件的唯一标识,用于识别用户在交互后,点击的是哪个按钮。在表单容器中所有的交互组件中,该字段必填,否则数据会发送失败。 + } + ] + } + ] + } + ] + } + ] + } +} +``` + +### 字段说明 + +表单容器各字段说明如下表所示: + +名称 | 必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | String | / | 表单容器的标签。固定值为 `form`。 +element_id | 否 | String | 空 | 操作组件的唯一标识。JSON 2.0 新增属性。用于在调用[组件相关接口](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/create)中指定组件。在同一张卡片内,该字段的值全局唯一。仅允许使用字母、数字和下划线,必须以字母开头,不得超过 20 字符。 +direction | 否 | String | vertical | 容器内组件的排列方向。可选值:
    - vertical:垂直排列
    - horizontal:水平排列 +margin | 否 | String | 0px | 容器的外边距。值的取值范围为 [-99,99]px。可选值:
    - 单值,如 "10px",表示容器的四个外边距都为 10 px。
    - 双值,如 "4px 0",表示容器的上下外边距为 4 px,左右外边距为 0 px。使用空格间隔(边距为 0 时可不加单位)。
    - 多值,如 "4px 0 4px 0",表示容器的上、右、下、左的外边距分别为 4px,12px,4px,12px。使用空格间隔。 +padding | 否 | String | 0px | 容器的内边距。值的取值范围为 [-99,99]px。可选值:
    - 单值,如 "10px",表示容器的四个外边距都为 10 px。
    - 双值,如 "4px 0",表示容器的上下外边距为 4 px,左右外边距为 0 px。使用空格间隔(边距为 0 时可不加单位)。
    - 多值,如 "4px 0 4px 0",表示容器的上、右、下、左的外边距分别为 4px,12px,4px,12px。使用空格间隔。 +horizontal_spacing | 否 | String | 8px | 容器内组件的水平间距,可选值:
    - small:小间距,4px
    - medium:中等间距,8px
    - large:大间距,12px
    - extra_large:超大间距,16px
    - 具体数值,如 20px。取值范围为 [0,99]px +horizontal_align | 否 | String | left | 容器内组件水平对齐的方式。可取值:
    - left:左对齐
    - center:居中对齐
    - right:右对齐 +vertical_align | 否 | String | top | 容器内组件垂直对齐的方式。可取值:
    - top:上对齐
    - center:居中对齐
    - bottom:下对齐 +vertical_spacing | 否 | String | 12px | 容器内组件的垂直间距,可选值:
    - small:小间距,4px
    - medium:中等间距,8px
    - large:大间距,12px
    - extra_large:超大间距,16px
    - 具体数值,如 20px。取值范围为 [0,99]px +name | 是 | String | 无 | 表单容器的唯一标识。用于识别用户提交的数据属于哪个表单容器。在同一张卡片内,该字段的值全局唯一。 +elements | 是 | Array<element> | [] | 表单容器的子节点。可内嵌其它容器类组件和展示、交互组件,不支持内嵌表格、图表、和表单容器组件。 +└ tag | 是 | String | 无 | 表单容器中内嵌的组件的标签,支持除表格(table)和表单容器以外的所有组件。
    **注意**:表单容器内必须包含一个用于提交表单的[按钮](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/button)组件。 +└ name | 是 | String | 无 | 表单容器内组件的唯一标识。用于识别用户提交的数据属于哪个组件。
    **注意**:
    在表单容器中所有的交互组件中,该字段必填且需在卡片全局内唯一,否则数据会发送失败。 +└ required | 否 | Boolean | false | 组件的内容是否必填。当组件内嵌在表单容器中时,该属性生效。可取值:
    - **true**:必填。当用户点击表单容器的“提交”时,未填写该组件,则前端提示“有必填项未填写”,不会向开发者的服务端发起回传请求。
    - **false**:选填。当用户点击表单容器的“提交”时,未填写该组件,仍提交表单容器中的数据。 +└ form_action_type | 是 | String | 空 | 内嵌在表单容器中的按钮的交互类型。枚举值包括:
    - submit:将当前按钮与提交事件绑定。用户点击后,将触发表单容器的提交事件,异步提交所有已填写的表单项内容
    - reset:将当前按钮与取消提交事件绑定。用户点击后,将触发表单容器的取消提交事件,重置所有表单组件的输入值为初始值 +└ action_type(历史属性) | 是 | String | 空 | 内嵌在表单容器中的按钮的交互类型。枚举值包括:
    - link:当前按钮仅支持链接跳转
  • request:当前按钮仅支持回传交互

  • multi:当前按钮同时支持链接跳转和回传交互

  • form_submit:将当前按钮与提交事件绑定。用户点击后,将触发表单容器的提交事件,异步提交所有已填写的表单项内容

  • form_reset:将当前按钮与取消提交事件绑定。用户点击后,将触发表单容器的取消提交事件,重置所有表单组件的输入值为初始值

  • **注意**:表单容器内必须包含一个用于提交表单的按钮组件。此时 `action_type` 固定取值 `form_submit`,表示提交表单。 +## 回调结构
    当用户点击表单容器的提交按钮时,你在开发者后台配置的请求地址将会收到如下所示的回调数据。如果你添加的是新版卡片回传交互回调(`card.action.trigger`),回调数据的结构如下所示。更多参数说明可参考[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)。
    ```json
    {
    "schema": "2.0", // 回调的版本
    "header": { // 回调基本信息
    "event_id": "f7984f25108f8137722bb63c*****", // 回调的唯一标识
    "token": "066zT6pS4QCbgj5Do145GfDbbag*****", // 应用的 Verification Token
    "create_time": "1603977298000000", // 回调发送的时间,接近回调发生的时间
    "event_type": "card.action.trigger", // 回调类型卡片交互场景中,固定为 "card.action.trigger"
    "tenant_key": "2df73991750*****", // 应用归属的 tenant key,即租户唯一标识
    "app_id": "cli_a5fb0ae6a4******" // 应用的 App ID
    },
    "event": { // 回调的详细信息
    "operator": { // 回调触发者信息
    "tenant_key": "2df73991750*****", // 回调触发者的 tenant key,即租户唯一标识
    "user_id": "867*****", // 回调触发者的 user ID当应用开启“获取用户 user ID”权限后,该参数返回
    "open_id": "ou_3c14f3a59eaf2825dbe25359f15*****", // 回调触发者的 Open ID
    "union_id": "on_cad4860e7af114fb4ff6c5d496d*****" // 回调触发者的 Union ID
    },
    "token": "c-295ee57216a5dc9de90fefd0aadb4b1d7d******", // 更新卡片用的凭证,有效期为 30 分钟,最多可更新 2 次
    "action": { // 用户操作交互组件回传的数据
    "value": { // 如果组件中配置了 value (历史属性)或 behaviors 属性,则在此处返回自定义的回传交互参数
    "key_1": "value_1"
    },
    "tag": "button", // 表单组件中按钮组件的标签。
    "timezone": "Asia/Shanghai", // 用户当前所在地区的时区。
    "form_value": { // 表单容器内用户提交的数据。以下为示例数据:
    "DatePicker_bpqdq5puvn4": "2024-04-01 +0800", // 表单容器内日期选择器组件的表单项标识 name(开发者可自定义)和用户提交的日期 value
    "DateTimePicker_ihz2d7a74i": "2024-04-29 07:07 +0800", // 表单容器内日期时间选择器组件的表单项标识 name(开发者可自定义)和用户提交的日期时间
    "Input_lf4fmxwfrd9": "1234", // 表单容器内输入框组件的表单项标识 name(开发者可自定义)和用户提交的值
    "PersonSelect_2ejys7ype7m": "ou_3c14f3a59eaf2825dbe25359f1595b00", // 表单容器内人员选择-单选组件的表单项标识 name(开发者可自定义)和用户提交的值
    "Select_a2d5b7l3zd": "1", // 表单容器内下拉选择-单选组件的表单项标识 name(开发者可自定义)和用户提交的值
    "TimePicker_7ecsf6xkqsq": "00:00 +0800"// 表单容器内时间选择器组件的表单项标识 name(开发者可自定义)和用户提交的时间
    },
    "name": "Button_lvkepfu3" // 表单容器中提交按钮的表单项标识 name
    },
    "host": "im_message", // 卡片展示场景
    "context": { // 卡片展示场景相关信息
    "open_message_id": "om_574d639e4a44e4dd646eaf628e2*****", // 卡片所在的消息 ID
    "open_chat_id": "oc_e4d2605ca917e695f54f11aaf56*****" // 卡片所在的会话 ID
    }
    }
    }
    ```
    ## 示例代码
    以下 JSON 2.0 结构的示例代码可实现如下图所示的卡片效果:
    ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/3431ef3f14bc707acaf00093f55df9b1_736bnZnIuR.png?height=491&lazyload=true&maxWidth=400&width=794)
    ```json
    {
    "schema": "2.0",
    "body": {
    "elements": [
    {
    "tag": "markdown",
    "content": "**项目名称**:业务做大做强",
    "text_align": "left",
    "text_size": "normal",
    "icon": {
    "tag": "standard_icon",
    "token": "add-app_outlined",
    "color": "grey"
    }
    },
    {
    "tag": "form",
    "elements": [
    {
    "tag": "column_set",
    "horizontal_spacing": "8px",
    "horizontal_align": "left",
    "columns": [
    {
    "tag": "column",
    "width": "weighted",
    "elements": [
    {
    "tag": "markdown",
    "content": "**经办人***",
    "text_align": "left",
    "text_size": "normal",
    "icon": {
    "tag": "standard_icon",
    "token": "member_outlined",
    "color": "light_grey"
    }
    }
    ],
    "padding": "0px 0px 0px 0px",
    "vertical_spacing": "8px",
    "weight": 1
    },
    {
    "tag": "column",
    "width": "weighted",
    "elements": [
    {
    "tag": "select_person",
    "placeholder": {
    "tag": "plain_text",
    "content": "请选择"
    },
    "options": [],
    "width": "fill",
    "type": "default",
    "required": true,
    "name": "PersonSelect_rg0ml5mh"
    }
    ],
    "padding": "0px 0px 0px 0px",
    "vertical_spacing": "8px",
    "weight": 4
    }
    ],
    "margin": "16px 0px 16px 0px"
    },
    {
    "tag": "column_set",
    "horizontal_spacing": "8px",
    "horizontal_align": "left",
    "columns": [
    {
    "tag": "column",
    "width": "weighted",
    "elements": [
    {
    "tag": "markdown",
    "content": "**优先级***",
    "text_align": "left",
    "text_size": "normal",
    "icon": {
    "tag": "standard_icon",
    "token": "msgcard-rectangle_outlined",
    "color": "grey"
    }
    }
    ],
    "padding": "0px 0px 0px 0px",
    "vertical_spacing": "8px",
    "weight": 1
    },
    {
    "tag": "column",
    "width": "weighted",
    "elements": [
    {
    "tag": "select_static",
    "placeholder": {
    "tag": "plain_text",
    "content": "请选择"
    },
    "options": [
    {
    "text": {
    "tag": "plain_text",
    "content": "P0"
    },
    "value": "1",
    "icon": {
    "tag": "standard_icon",
    "token": "sheet-iconsets-increase_filled"
    }
    },
    {
    "text": {
    "tag": "plain_text",
    "content": "P1"
    },
    "value": "P1",
    "icon": {
    "tag": "standard_icon",
    "token": "sheet-iconsets-stable_filled"
    }
    },
    {
    "text": {
    "tag": "plain_text",
    "content": "P2"
    },
    "value": "3",
    "icon": {
    "tag": "standard_icon",
    "token": "expand-down_filled"
    }
    }
    ],
    "type": "default",
    "width": "fill",
    "required": true,
    "name": "Select_01taxkgaqc6c"
    }
    ],
    "padding": "0px 0px 0px 0px",
    "vertical_spacing": "8px",
    "weight": 4
    }
    ],
    "margin": "16px 0px 16px 0px"
    },
    {
    "tag": "column_set",
    "horizontal_spacing": "8px",
    "horizontal_align": "left",
    "columns": [
    {
    "tag": "column",
    "width": "weighted",
    "elements": [
    {
    "tag": "markdown",
    "content": "**项目评论**",
    "text_align": "left",
    "text_size": "normal",
    "icon": {
    "tag": "standard_icon",
    "token": "chat_outlined",
    "color": "grey"
    }
    }
    ],
    "padding": "0px 0px 0px 0px",
    "vertical_spacing": "8px",
    "weight": 1
    },
    {
    "tag": "column",
    "width": "weighted",
    "elements": [
    {
    "tag": "input",
    "placeholder": {
    "tag": "plain_text",
    "content": "请输入"
    },
    "default_value": "",
    "width": "fill",
    "name": "Input_0bqcy75cxklr",
    "fallback": {
    "tag": "fallback_text",
    "text": {
    "tag": "plain_text",
    "content": "仅支持在 V6.8 及以上版本使用"
    }
    }
    }
    ],
    "padding": "0px 0px 0px 0px",
    "vertical_spacing": "8px",
    "weight": 4
    }
    ],
    "margin": "16px 0px 16px 0px"
    },
    {
    "tag": "column_set",
    "flex_mode": "bisect",
    "horizontal_spacing": "8px",
    "horizontal_align": "right",
    "columns": [
    {
    "tag": "column",
    "width": "auto",
    "elements": [
    {
    "tag": "button",
    "text": {
    "tag": "plain_text",
    "content": "提交"
    },
    "type": "primary_filled",
    "width": "default",
    "icon": {
    "tag": "standard_icon",
    "token": "thumbsup_outlined"
    },
    "form_action_type": "submit",
    "name": "Button_lq544v6r"
    }
    ],
    "padding": "0px 0px 0px 0px",
    "vertical_spacing": "8px"
    },
    {
    "tag": "column",
    "width": "auto",
    "elements": [
    {
    "tag": "button",
    "text": {
    "tag": "plain_text",
    "content": "取消"
    },
    "type": "default",
    "width": "default",
    "form_action_type": "reset",
    "name": "Button_lq544v6s"
    }
    ],
    "padding": "0px 0px 0px 0px",
    "vertical_spacing": "8px"
    }
    ],
    "margin": "0px 0px 0px 0px"
    }
    ],
    "name": "Form_lq544v6q",
    "fallback": {
    "tag": "fallback_text",
    "text": {
    "tag": "plain_text",
    "content": "仅支持在 V6.6 及以上版本使用"
    }
    }
    }
    ]
    }
    }
    ``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__containers__interactive-container.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__containers__interactive-container.md new file mode 100644 index 0000000..bb6ec80 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__containers__interactive-container.md @@ -0,0 +1,512 @@ +# 交互容器 + +你可基于业务需求在交互容器中内嵌组件,并灵活组合多个交互容器,并统一定义多个交互容器的样式、交互能力等,实现多种组合效果和丰富的卡片交互。 + +本文档介绍交互容器的 JSON 2.0 结构,要查看历史 JSON 1.0 结构,参考[交互容器](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/containers/interactive-container)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/a45907bdc812e07e913eeaba170044ee_muf1ajP42f.png?height=709&lazyload=true&maxWidth=300&width=707) + +## 注意事项 + +容器类组件最多支持嵌套五层组件。建议你避免在交互容器中嵌套多层组件。多层嵌套会压缩内容的展示空间,影响卡片的展示效果。 + +## 嵌套规则 + +在[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)中,交互容器可内嵌除表单容器(form)和表格组件(table)外的其它所有组件。 +## 组件属性 + +### JSON 结构 + +交互容器的完整 JSON 2.0 结构如下所示: +```json +{ + "schema": "2.0", + "body": { + "elements": [ + { + "tag": "interactive_container", // 交互容器的标签。 + "width": "fill", // 交互容器的宽度。默认值 fill。 + "height": "auto", // 交互容器的高度。默认值 auto。 + "element_id": "custom_id", // 操作组件的唯一标识。用于在调用组件相关接口中指定组件。需开发者自定义。 + "direction": "vertical", // 容器内组件的排列方向。可选值:"vertical"(垂直排列)、"horizontal"(水平排列)。默认为 "vertical"。 + "margin": "4px", // 容器的外边距,默认值 "0",支持范围 [-99,99]px。 + "horizontal_spacing": "large", // 容器内组件之间的间距,可选值:"small"(4px)、"medium"(8px)、"large"(12px)、"extra_large"(16px) 或 [0,99]px。 + "horizontal_align": "left", // 容器内组件水平对齐的方式。可选值:"left"、"center"、"right",默认值 left。 + "vertical_align": "center", // 容器内组件的垂直对齐方式,可选值:"top"、"center"、"bottom",默认值为 "top"。 + "vertical_spacing": "4px", // 容器内组件的纵向间距。可选值:"small"(4px)、"medium"(8px)、"large"(12px)、"extra_large"(16px) 或 [0,99]px。默认值 4px。 + "background_style": "default", // 背景色。默认值 default(无背景色)。 + "has_border": false, // 是否展示边框,粗细固定为 1px。默认值 false。 + "border_color": "grey", // 交互容器的边框颜色,仅 has_border 为 true 时生效。 + "corner_radius": "40px", // 交互容器的圆角半径。可选。 + "padding": "10px 20px 10px 20px", // 交互容器的内边距。默认值 "4px 12px 4px 12px"。 + "behaviors": [ + { + "type": "open_url", // 声明交互类型是打开链接的跳转交互。 + "default_url": "https://www.baidu.com", // 兜底跳转地址。 + "android_url": "https://developer.android.com/", // 安卓端跳转地址。 + "ios_url": "lark://msgcard/unsupported_action", // iOS 端跳转地址。 + "pc_url": "https://www.windows.com" // 桌面端跳转地址。 + }, + { + "type": "callback", // 声明交互类型是回传数据到服务端的回传交互。 + "value": { + // 回传交互数据 + "key": "value" + } + } + ], + "disabled": false, + "disabled_tips": { + "tag": "plain_text", + "content": "demo" + }, + "confirm": {}, + "hover_tips": { + "tag": "plain_text", + "content": "demo" + }, + "elements": [] // 容器子组件,支持除表单容器(form)和表格组件(table)外的其它所有组件。 + } + ] + } +} +``` + +### 字段说明 + +交互容器各字段说明如下表所示。 + +名称 | 必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | String | / | 交互容器的标签。固定值为 interactive_container。 +width | 否 | String | fill | 交互容器的宽度。可取值:
    - **fill**:卡片最大支持宽度
  • **auto**:自适应宽度

  • **[16,999]px**:自定义宽度,如 "20px"。最小宽度为 16px
  • +height | 否 | String | auto | 交互容器的高度。可取值:
    - **auto**:自适应高度
  • **[10,999]px**:自定义高度,如 "20px"

  • +element_id | 否 | String | 空 | 操作组件的唯一标识。JSON 2.0 新增属性。用于在调用[组件相关接口](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/create)中指定组件。在同一张卡片内,该字段的值全局唯一。仅允许使用字母、数字和下划线,必须以字母开头,不得超过 20 字符。 +margin | 否 | String | 0px | 容器的外边距。值的取值范围为 [-99,99]px。可选值:
    - 单值,如 "10px",表示容器的四个外边距都为 10 px。
    - 双值,如 "4px 0",表示容器的上下外边距为 4 px,左右外边距为 0 px。使用空格间隔(边距为 0 时可不加单位)。
    - 多值,如 "4px 0 4px 0",表示容器的上、右、下、左的外边距分别为 4px,12px,4px,12px。使用空格间隔。 +direction | 否 | String | vertical | 容器内组件的排列方向。可选值:
    - vertical:垂直排列
    - horizontal:水平排列 +horizontal_spacing | 否 | String | 8px | 容器内组件的水平间距,可选值:
    - small:小间距,4px
    - medium:中等间距,8px
    - large:大间距,12px
    - extra_large:超大间距,16px
    - 具体数值,如 20px。取值范围为 [0,99]px +horizontal_align | 否 | String | left | 容器内组件水平对齐的方式。可取值:
    - left:左对齐
    - center:居中对齐
    - right:右对齐 +vertical_spacing | 否 | String | 12px | 容器内组件的水平间距,可选值:
    - small:小间距,4px
    - medium:中等间距,8px
    - large:大间距,12px
    - extra_large:超大间距,16px
    - 具体数值,如 20px。取值范围为 [0,99]px +vertical_align | 否 | String | top | 容器内组件垂直对齐的方式。可取值:
    - top:上对齐
    - center:居中对齐
    - bottom:下对齐 +background_style | 否 | String | default | 交互容器的背景色样式。可取值:
    - **default**:默认的白底样式,客户端深色主题下为黑底
  • **laser**:镭射渐变彩色样式

  • 卡片支持的颜色枚举值和 RGBA 语法自定义颜色。参考[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)

  • +has_border | 否 | Boolean | false | 是否展示边框,粗细固定为 1px。 +border_color | 否 | String | grey | 边框的颜色,仅 has_border 为 true 时,此字段生效。枚举值为卡片支持的颜色枚举值和 RGBA 语法自定义颜色,参考[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。 +corner_radius | 否 | String | 0px | 交互容器的圆角半径,单位是像素(px)或百分比(%)。取值遵循以下格式:
    - **[0,∞]px**,如 "10px"
  • **[0,100]%**,如 "30%"

  • +padding | 否 | String | 4px, 12px | 容器的内边距。值的取值范围为 [-99,99]px。可选值:
    - 单值,如 "10px",表示容器的四个外边距都为 10 px。
    - 双值,如 "4px 0",表示容器的上下外边距为 4 px,左右外边距为 0 px。使用空格间隔(边距为 0 时可不加单位)。
    - 多值,如 "4px 0 4px 0",表示容器的上、右、下、左的外边距分别为 4px,12px,4px,12px。使用空格间隔。 +behaviors | 是 | [] | / | 设置点击交互容器时的交互配置。如果交互容器内有交互组件,则优先响应交互组件定义的交互。交互组件支持 callback 和 open_url 交互。详情参考[配置卡片交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/configuring-card-interactions)。 +hover_tips | 否 | Object | 空 | 用户在 PC 端将光标悬浮在交互容器上方时的文案提醒。默认为空。 +└ tag | 是 | String | plain_text | 文本的标签。固定取值为 plain_text。 +└ content | 是 | String | 空 | 文本的内容。 +disabled | 否 | Boolean | false | 是否禁用交互容器。可选值:
    - true:禁用整个容器
  • false:容器组件保持可用状态

  • +disabled_tips | 否 | Object | 空 | 禁用交互容器后,用户触发交互时的弹窗文案提醒。默认为空,即不弹窗。 +└ tag | 是 | String | plain_text | 弹窗标题文本的标签。固定取值为 plain_text。 +└ content | 是 | String | 空 | 弹窗标题的内容。 +confirm | 否 | Struct | 默认不生效此属性。 | 二次确认弹窗配置。指在用户提交时弹出二次确认弹窗提示;只有用户点击确认后,才提交输入的内容。该字段默认提供了确认和取消按钮,你只需要配置弹窗的标题与内容即可。
    **注意**:confirm 字段仅在用户点击包含提交属性的按钮时才会触发二次确认弹窗。 +└ title | 是 | Struct | / | 二次确认弹窗标题。 +└ └ tag | 是 | String | plain_text | 二次确认弹窗标题文本的标签。固定取值为 `plain_text`。 +└ └ content | 是 | String | / | 二次确认弹窗标题的内容。 +└ text | 是 | Struct | / | 二次确认弹窗的文本内容。 +└ └ tag | 是 | String | plain_text | 二次确认弹窗文本的标签。固定取值为 `plain_text`。 +└ └ content | 是 | String | / | 二次确认弹窗文本的具体内容。 +elements | 是 | Array<element> | [] | 交互容器内嵌的组件。支持除表单容器(form)和表格组件(table)外的其它所有组件。 + +## 回调结构 + +为组件成功配置交互后,用户基于组件进行交互时,你在开发者后台配置的请求地址将会收到回调数据。 +- 如果你添加的是新版卡片回传交互回调(`card.action.trigger`),可参考[卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)了解回调结构。 +- 如果你添加的是旧版卡片回传交互回调(`card.action.trigger_v1`),可参考[消息卡片回传交互(旧)](https://open.feishu.cn/document/ukTMukTMukTM/uYzM3QjL2MzN04iNzcDN/configuring-card-callbacks/card-callback-structure)了解回调结构。 +- +## Demo 示例 + +以下的 JSON 示例代码可实现如下图所示的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/a45907bdc812e07e913eeaba170044ee_muf1ajP42f.png?height=709&lazyload=true&maxWidth=300&width=707) +```json +{ + "schema": "2.0", + "header": { + "title": { + "content": "交互容器示例", + "tag": "plain_text" + }, + "icon": { + "tag": "standard_icon", + "token": "chat_outlined", + "color": "orange" + } + }, + "body": { + "elements": [ + { + "tag": "markdown", + "content": "在「内容创作」话题下,我可以帮助你进行产品方案、营销文案、工作报告等内容的创作。" + }, + { + "tag": "column_set", + "flex_mode": "none", + "background_style": "default", + "columns": [ + { + "tag": "column", + "width": "weighted", + "weight": 1, + "vertical_align": "top", + "vertical_spacing": "8px", + "elements": [ + { + "tag": "markdown", + "content": "你可以对我说:", + "text_size": "notation" + }, + { + "tag": "interactive_container", + "width": "fill", + "height": "auto", + "horizontal_align": "left", + "background_style": "default", + "has_border": true, + "border_color": "grey", + "corner_radius": "8px", + "padding": "4px 12px 4px 12px", + "behaviors": [ + { + "type": "callback", + "value": { + "key": "value" + } + } + ], + "elements": [ + { + "tag": "markdown", + "content": "帮我生成一篇产品方案的框架", + "icon": { + "tag": "standard_icon", + "token": "frame-selection_outlined", + "color": "orange" + } + } + ] + }, + { + "tag": "interactive_container", + "width": "fill", + "height": "auto", + "horizontal_align": "left", + "background_style": "default", + "has_border": true, + "border_color": "grey", + "corner_radius": "8px", + "padding": "4px 12px 4px 12px", + "behaviors": [ + { + "type": "callback", + "value": { + "key": "value" + } + } + ], + "disabled": false, + "elements": [ + { + "tag": "markdown", + "content": "帮我生成一篇产品文案", + "icon": { + "tag": "standard_icon", + "token": "file-link-docx_outlined", + "color": "orange" + } + } + ] + }, + { + "tag": "interactive_container", + "width": "fill", + "height": "auto", + "horizontal_align": "left", + "background_style": "default", + "has_border": true, + "border_color": "grey", + "corner_radius": "8px", + "padding": "4px 12px 4px 12px", + "behaviors": [ + { + "type": "callback", + "value": { + "key": "value" + } + } + ], + "disabled": false, + "elements": [ + { + "tag": "markdown", + "content": "帮我写一篇周报", + "icon": { + "tag": "standard_icon", + "token": "pa-calibration-report_outlined", + "color": "orange" + } + } + ] + } + ] + } + ] + }, + { + "tag": "column_set", + "flex_mode": "none", + "background_style": "default", + "columns": [ + { + "tag": "column", + "width": "weighted", + "weight": 1, + "vertical_align": "top", + "vertical_spacing": "8px", + "elements": [ + { + "tag": "markdown", + "content": "或者继续之前的话题", + "text_size": "notation" + }, + { + "tag": "interactive_container", + "width": "fill", + "height": "auto", + "horizontal_align": "left", + "background_style": "default", + "has_border": true, + "border_color": "grey", + "corner_radius": "8px", + "padding": "4px 12px 4px 12px", + "behaviors": [ + { + "type": "callback", + "value": { + "key": "value" + } + } + ], + "disabled": false, + "elements": [ + { + "tag": "column_set", + "flex_mode": "none", + "background_style": "default", + "columns": [ + { + "tag": "column", + "width": "weighted", + "weight": 1, + "vertical_align": "center", + "elements": [ + { + "tag": "markdown", + "content": "内容创作:创作暑假营销活动文案", + "icon": { + "tag": "standard_icon", + "token": "chat-history_outlined" + } + } + ] + }, + { + "tag": "column", + "width": "auto", + "weight": 1, + "vertical_align": "center", + "elements": [ + { + "tag": "markdown", + "content": "昨天", + "text_size": "notation" + } + ] + } + ] + } + ] + }, + { + "tag": "interactive_container", + "width": "fill", + "height": "auto", + "horizontal_align": "left", + "background_style": "default", + "has_border": true, + "border_color": "grey", + "corner_radius": "8px", + "padding": "4px 12px 4px 12px", + "behaviors": [ + { + "type": "callback", + "value": { + "key": "value" + } + } + ], + "disabled": false, + "elements": [ + { + "tag": "column_set", + "flex_mode": "none", + "background_style": "default", + "columns": [ + { + "tag": "column", + "width": "weighted", + "weight": 1, + "vertical_align": "center", + "elements": [ + { + "tag": "markdown", + "content": "内容创作:生成了季度工作报告", + "icon": { + "tag": "standard_icon", + "token": "chat-history_outlined" + } + } + ] + }, + { + "tag": "column", + "width": "auto", + "weight": 1, + "vertical_align": "center", + "elements": [ + { + "tag": "markdown", + "content": "上周", + "text_size": "notation" + } + ] + } + ] + } + ] + }, + { + "tag": "interactive_container", + "width": "fill", + "height": "auto", + "horizontal_align": "left", + "background_style": "default", + "has_border": true, + "border_color": "grey", + "corner_radius": "8px", + "padding": "4px 12px 4px 12px", + "behaviors": [ + { + "type": "callback", + "value": { + "key": "value" + } + } + ], + "disabled": false, + "elements": [ + { + "tag": "markdown", + "content": "更多历史话题", + "icon": { + "tag": "standard_icon", + "token": "chat-history_outlined" + } + } + ] + } + ] + } + ] + }, + { + "tag": "column_set", + "flex_mode": "none", + "background_style": "default", + "columns": [ + { + "tag": "column", + "width": "weighted", + "weight": 1, + "vertical_align": "top", + "vertical_spacing": "8px", + "elements": [ + { + "tag": "div", + "text": { + "tag": "plain_text", + "text_size": "notation", + "content": "本话题中已选择以下插件", + "text_color": "grey" + } + }, + { + "tag": "interactive_container", + "width": "auto", + "height": "auto", + "horizontal_align": "left", + "background_style": "grey", + "has_border": false, + "border_color": "grey", + "corner_radius": "40px", + "padding": "2px 8px 2px 4px", + "behaviors": [ + { + "type": "callback", + "value": { + "key": "value" + } + } + ], + "disabled": false, + "elements": [ + { + "tag": "column_set", + "flex_mode": "none", + "background_style": "default", + "horizontal_spacing": "4px", + "columns": [ + { + "tag": "column", + "width": "auto", + "weight": 1, + "vertical_align": "center", + "vertical_spacing": "8px", + "elements": [ + { + "tag": "img", + "img_key": "img_v2_58e37110-6878-44ee-bce4-7a571c1bb70g", + "transparent": true, + "scale_type": "crop_center", + "size": "18px 18px", + "preview": false + } + ] + }, + { + "tag": "column", + "width": "weighted", + "weight": 1, + "vertical_align": "center", + "vertical_spacing": "8px", + "elements": [ + { + "tag": "markdown", + "content": "妙记插件" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__audio.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__audio.md new file mode 100644 index 0000000..fa17a31 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__audio.md @@ -0,0 +1,332 @@ +# 音频 + +卡片的音频组件支持播放 OPUS 格式的音频。本文档介绍音频组件的 JSON 结构和字段说明,并提供音频组件的示例代码和效果。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/c8d2b7af7d28bfd14285f719f790a137_R3o2txLTAt.png?height=582&lazyload=true&maxWidth=324&width=624) + +## 前提条件 + +使用音频组件前,你需先调用[上传文件](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/file/create)接口,获取音频的 `file_key`,再传入音频组件中,使卡片具备音频播放能力。调用上传文件接口时,需确保: +- 指定文件类型(`file_type`)为 OPUS。音频文件仅支持 OPUS 编码,对于其他格式的音频文件,请转为 OPUS 格式后上传,具体方式可参考[上传文件](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/file/create)文档中 `file_type` 的字段说明。 +- 指定音频时长(`duration`),且确保与实际时长一致。否则会导致播放进度展示不准确。 +- 调用上传文件接口的应用与之后发送卡片的应用需保持一致。 + +## 注意事项 + +- 音频组件仅支持 JSON 2.0 版本的卡片。 +- 音频组件仅支持通过撰写卡片 JSON 代码的方式使用,暂不支持在卡片搭建工具上构建使用。 +- 音频组件仅支持飞书 V7.49 及以上版本的客户端。在低于该版本的飞书客户端上,音频组件的内容将默认展示为一句“请升级至最新版本客户端,以查看内容”的占位图。你也可通过卡片的 `fallback` 字段自定义组件的降级展示方式。 +- 包含音频组件的卡片不支持转发。你需要在卡片 JSON 的 `config` 配置中指定 `enable_forward` 为 `false`,否则会导致卡片发送失败。 +- 包含音频组件的卡片暂不支持使用 [发送仅特定人可见的消息卡片](https://open.feishu.cn/document/ukTMukTMukTM/uETOyYjLxkjM24SM5IjN) 接口发送。 + +## JSON 结构 + +```json +{ + "schema": "2.0", + "config": { + "update_multi": true, + "enable_forward": false, // 是否支持转发。此处必须设为 false,否则卡片将发送失败。 + "style": { // 在此添加并配置 style 字段。 详情参考 颜色枚举值-使用 RGBA 语法自定义颜色 文档。 + "color": { + "border-color": { // 分别为飞书客户端浅色主题和深色主题添加 RGBA 语法,支持添加多个自定义颜色对象。 + "light_mode": "rgba(5,157,178,0.52)", // 浅色主题下的自定义颜色语法。 + "dark_mode": "rgba(78,23,108,0.49)" // 深色主题下的自定义颜色语法。 + }, + "bg-color": { + "light_mode": "rgba(31,35,41,0.08)", + "dark_mode": "rgba(235,235,235,0.08)" + }, + "fill-color": { + "light_mode": "rgba(122,53,240,0.7)", + "dark_mode": "rgba(184,143,254,0.7)" + } + } + } + }, + "body": { + "elements": [ + { + "tag": "audio", // 音频组件的标签。 + "element_id": "custom_id", // 操作组件的唯一标识。用于在调用组件相关接口中指定组件。需开发者自定义。 + "margin": "0px 0px 0px 0px", // 组件的外边距,默认值 "0",支持范围 [-99,99]px。 + "file_key": "file_v3_00or_f2c1276b-9f24-463d-8911-xxxxxx", // 音频文件 key。参考本文档前提条件中的说明获取。 + "i18n_file_key": { // 多语言音频文件 key,配置多语言卡片时使用。详情参考配置卡片多语言文档。 + "zh_cn": "file_v3_00or_f2c1276b-9f24-463d-8911-xxxxx1", + "en_us": "file_v3_00or_f2c1276b-9f24-463d-8911-xxxxx2" + }, + "audio_id": "1", // 音频实例唯一标识。卡片发生更新时,具有相同 audio_id 和 file_key 的音频组件,播放状态不受影响。 + "disabled": false, // 是否禁用该组件,禁用后无法操作组件。 + "disabled_tips": { // 禁用提示。禁用组件后,用户操作组件时的文案提醒。 + "tag": "plain_text", + "content": "已禁用" + }, + "show_progress_bar": true, // 是否显示进度条。 + "show_time": true, // 是否显示时间。 + "time_display": "default", // 时间的展示方式。 + "time_position": "end", // 时间的位置。 + "border": { // 组件的边框设置,默认不显示边框。 + "color": "border-color", // 边框颜色,支持颜色枚举值和 RGBA 语法自定义颜色。 + "corner_radius": "8px" // 边框圆角设置,单位为 px。 + }, + "style": "normal", // 音频播放按钮的样式。 + "padding": "12px", // 组件外侧边缘到内部元素间的内边距。 + "background_style": "bg-color", // 背景色样式。支持 default、支持颜色枚举值和 RGBA 语法自定义颜色。 + "fill_color": "fill-color", // 按钮、进度条和时间的填充颜色。支持颜色枚举值和 RGBA 语法自定义颜色。 + "width": "default", // 组件的宽度。 + "fallback": { + // 自定义音频组件的降级文案。默认为“请升级至最新版本客户端,以查看内容。” + "tag": "fallback_text", // 降级文案的标签。 + "text": { + "content": "自定义降级文案", // 自定义降级文案的具体内容。 + "tag": "plain_text" // 降级文案内容类型的标签。 + } + } + } + ] + } +} +``` + +## 字段说明 + +音频组件的字段说明如下表。 + +名称 | 必须 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | String | / | 组件的标签,音频组件的固定取值为 `audio`。 +element_id | 否 | String | / | 操作组件的唯一标识。用于在调用[组件相关接口](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/create)中指定组件。在同一张卡片内,该字段的值全局唯一。仅允许使用字母、数字和下划线,必须以字母开头,不得超过 20 字符。 +margin | 否 | String | 0 | 组件的外边距。值的取值范围为 [-99,99]px。可选值:
    - 单值,如 "10px",表示组件的四个外边距都为 10 px。
    - 双值,如 "4px 0",表示组件的上下外边距为 4 px,左右外边距为 0 px。使用空格间隔(边距为 0 时可不加单位)。
    - 多值,如 "4px 0 4px 0",表示组件的上、右、下、左的外边距分别为 4px,12px,4px,12px。使用空格间隔。 +file_key | 是 | String | / | 音频文件 key,需调用 [上传文件](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/file/create) 接口获取,同时确保:
    - 指定待上传的文件类型(`file_type`)为 OPUS。
    - 传入音频时长(`duration`),且确保与实际时长一致。
    - 调用上传文件接口的应用与之后发送卡片的应用一致。 +i18n_file_key | 否 | Object | / | 如果卡片配置了多语言,可通过该字段指定多语言卡片的音频文件 key,参考 [配置卡片多语言](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/configure-multi-language-content)。 +audio_id | 否 | String | / | 音频实例唯一标识。卡片发生更新时,具有相同 `audio_id`、相同 `file_key` 的音频组件,播放状态不受影响。
    **注意**:
    - 在同一张卡片内,该字段的值全局唯一。
    - 若不指定,则卡片内部会默认生成随机值,卡片在发生更新时将停止当前音频播放。 +disabled | 否 | Boolean | false | 是否禁用音频组件。可选值:
    - `true`:禁用操作组件
    - `false`:组件保持可用状态
    ![图片](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/9dc254532028bb9dad0e4eafeefd5439_lZsDdNKxv1.png?height=229&lazyload=true&maxWidth=300&width=764) +disabled_tips | 否 | Object | / | 禁用音频组件后,用户在 PC 端鼠标悬浮组件时、或移动端点击组件时的文案提醒。默认无提醒。
    ![图片](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/4c57db6a19a5e5c8f1f3ac115c2ba53a_vkS0hBSHWB.png?height=159&lazyload=true&maxWidth=300&width=768) +tag | 是 | String | / | 提示文案的标签。固定取值为 `plain_text`。 +content | 是 | String | / | 提示文案的内容。如“已禁用”。 +show_progress_bar | 否 | Boolean | true | 是否显示进度条。可选值:
    - `true`:显示
    - `false`:不显示
    下图为不显示进度条的示意图:
    ![图片](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/a2fe565583b1581297862911bddbfc38_7Le9Aa5jbQ.png?height=216&lazyload=true&maxWidth=300&width=764) +show_time | 否 | Boolean | true | 是否显示音频总时长和当前已播放时长。可选值:
    - `true`:显示
    - `false`:不显示
    下图为不显示时长的示意图:
    ![图片](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/59db6e7005f6455c66cc2ba115a12162_340cCdPEAx.png?height=220&lazyload=true&maxWidth=300&width=770) +time_display | 否 | String | default | 时长显示方式,仅当 `show_time` 为 `true` 时生效。可选值:
    - `default`:仅展示一个时间。未播放时显示为总时长,播放或暂停时显示为当前已播放时长。
    ![图片](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/e4c519e31ad5fc86948b0b51b5db0842_GYAyK0ftYZ.png?height=96&lazyload=true&maxWidth=300&width=521)
    - `both`:同时显示总时长和当前已播放时长。
    ![图片](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/efd4796cd6c99cce3e8f99b304e2354b_YfyB5Mwurn.png?height=94&lazyload=true&maxWidth=300&width=527) +time_position | 否 | String | end | 时长显示位置,仅当 `show_time` 为 `true` 时生效。可选值:
    - `end`:总时长、当前已播放时长均显示在进度条右侧。
    - ![图片](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/397df2e7bb4abe87314f72fbfe1cd6fe_OzYWGAYacb.png?height=97&lazyload=true&maxWidth=300&width=524)
    - `start`:总时长、当前已播放时长均显示在进度条左侧。
    ![图片](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/2c1e0cb473189c5dfee8b0a997cc83e8_9gy4M2V6ZY.png?height=92&lazyload=true&maxWidth=300&width=530)
    - `both_sides`:左侧显示当前已播放时长,右侧显示总时长。
    ![图片](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/b85829a6025fa21fb07d279121514aad_Nf57AL3phj.png?height=85&lazyload=true&maxWidth=300&width=524) +border | 否 | Object | / | 边框设置,默认不显示边框。 +color | 否 | String | / | 边框的颜色,默认为透明色。支持[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)和 RGBA 语法自定义颜色。 +corner_radius | 否 | String | 8px | 圆角设置,单位为 px。 +style | 否 | String | normal | 播放按钮样式,可选值:
    - `normal`:默认值。三角形播放按钮,带圆底
    ![图片](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/11d59dfedd0c0ea5bc6723fe4fee788e_2y5P1yQZ1l.png?height=80&lazyload=true&maxWidth=90&width=90)
    - `flat`:三角形播放按钮,不带圆底
    ![图片](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/36b8ec70cdc721b0b5bb72412e5e4382_0s3lBFfwol.png?height=84&lazyload=true&maxWidth=90&width=93)
    - `speak`:语音样式
    ![图片](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/ab8fe4ccb7046515e0e738e4893ea9ff_Eh08ZVN7iu.png?height=83&lazyload=true&maxWidth=90&width=92) +padding | 否 | String | 12px | 组件外侧边缘到内部元素间的内边距。值的取值范围为 [-99,99]px。可选值:
    - 单值,如 "10px",表示容器的四个外边距都为 10 px。
    - 双值,如 "4px 0",表示容器的上下外边距为 4 px,左右外边距为 0 px。使用空格间隔(边距为 0 时可不加单位)。
    - 多值,如 "4px 0 4px 0",表示容器的上、右、下、左的外边距分别为 4px,12px,4px,12px。使用空格间隔。 +background_style | 否 | String | default | 音频组件背景色。可取值:
    - `default`:默认的浅灰色。
    - 卡片支持的颜色枚举值和 RGBA 语法自定义颜色。参考 [颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。 +fill_color | 否 | String | grey-800 | 组件内元素的填充颜色,元素包括:
    - 播放/暂停按钮图标
    - 进度条已播进度
    - 时间
    支持[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)和 RGBA 语法自定义颜色。下图为 `fill_color` 为 `blue-800` 时的效果:
    ![图片](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/4d52a3b9091b2c269c9cee718585eacc_X9Mvu6u1mZ.png?height=91&lazyload=true&maxWidth=300&width=533) +width | 否 | String | default | 组件的宽度。支持以下枚举值:
    - `default`:默认宽度
    - `fill`:卡片最大支持宽度
    - [100,∞)px:自定义宽度,如 `120px`
    默认宽度和最大支持效果示意图如下所示:
    ![图片](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/0c6fb4a4411be1e4cf1623c050693254_nssPtikODk.png?height=235&lazyload=true&maxWidth=300&width=529) +fallback | 否 | Object | / | 设置音频组件的降级文案。音频组件仅支持飞书 V7.49 及以上版本的客户端,你需选择在低于此版本的客户端上,该组件的降级展示方式:
    - 不填写该字段,使用系统默认的降级文案:“请升级至最新版本客户端,以查看内容”。
    - `"drop"`:填写 `"drop"`,在旧版本客户端上直接丢弃该组件。
    - 使用 `text` 文本对象自定义降级文案。
    ![图片](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/ecb79a1e546736d50a03f406fe5f0905_6oC4FDFe2c.jpeg?height=95&lazyload=true&maxWidth=300&width=591) +tag | 否 | String | fallback_text | 降级文案的标签,固定取值为 `fallback_text`。 +text | 否 | Object | / | 降级文案的内容。 +tag | 否 | String | plain_text | 降级文案内容的标签,固定取值为 `plain_text`。 +content | 否 | String | 空 | 自定义降级文案的具体内容。 + +## 示例代码 + +以下 JSON 2.0 结构的示例代码可实现如下图所示的卡片效果。请将 `file_key` 替换为实际值后再查看效果。获取音频文件 `file_key` 时,请确保调用[上传文件](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/file/create)接口的应用与发送卡片的应用一致。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/42fba98de89f57cb5d8705dd65422fdf_TGh5RpdQcp.png?height=1957&lazyload=true&maxWidth=400&width=777) +```json +{ + "schema": "2.0", + "config": { + "update_multi": true, + "enable_forward": false + }, + "header": { + "title": { + "tag": "plain_text", + "content": "音频组件示例" + }, + "template": "blue", + "padding": "12px 12px 12px 12px" + }, + "body": { + "direction": "vertical", + "padding": "12px 12px 12px 12px", + "elements": [ + { + "tag": "markdown", + "content": "参数均取默认值时,音频组件示例:" + }, + { + "tag": "audio", + "file_key": "file_v3_00or_f2c1276b-9f24-463d-8911-xxxxxxxx", + "audio_id": "1" + }, + { + "tag": "markdown", + "content": "禁用组件时示例:" + }, + { + "tag": "audio", + "file_key": "file_v3_00or_f2c1276b-9f24-463d-8911-xxxxxxxx", + "audio_id": "3", + "disabled": true, + "disabled_tips": { + "tag": "plain_text", + "content": "已禁用", + "text_size": "normal", + "text_align": "center", + "text_color": "default" + } + }, + { + "tag": "markdown", + "content": "组件宽度 `width` 取 `fill` 时示例:" + }, + { + "tag": "audio", + "file_key": "file_v3_00or_f2c1276b-9f24-463d-8911-xxxxxxxx", + "audio_id": "2", + "width": "fill" + }, + { + "tag": "markdown", + "content": "不显示进度条即 `show_progress_bar` 取 `false` 时示例:" + }, + { + "tag": "audio", + "file_key": "file_v3_00or_f2c1276b-9f24-463d-8911-xxxxxxxx", + "audio_id": "4", + "show_progress_bar": false, + "width": "fill" + }, + { + "tag": "audio", + "file_key": "file_v3_00or_f2c1276b-9f24-463d-8911-xxxxxxxx", + "audio_id": "41", + "show_progress_bar": false, + "width": "default" + }, + { + "tag": "markdown", + "content": "不显示时间即 `show_time` 取 `false` 时示例:" + }, + { + "tag": "audio", + "file_key": "file_v3_00or_f2c1276b-9f24-463d-8911-xxxxxxxx", + "audio_id": "5", + "show_progress_bar": false, + "show_time": false, + "width": "fill" + }, + { + "tag": "audio", + "file_key": "file_v3_00or_f2c1276b-9f24-463d-8911-xxxxxxxx", + "audio_id": "51", + "show_progress_bar": false, + "show_time": false, + "width": "default" + }, + { + "tag": "markdown", + "content": "时长显示位置 `time_position` 分别取 `end`、`start` 和 `both_sides` 时示例:" + }, + { + "tag": "audio", + "file_key": "file_v3_00or_f2c1276b-9f24-463d-8911-xxxxxxxx", + "audio_id": "6", + "show_progress_bar": true, + "show_time": true, + "time_display": "default", + "time_position": "end", + "width": "fill" + }, + { + "tag": "audio", + "file_key": "file_v3_00or_f2c1276b-9f24-463d-8911-xxxxxxxx", + "audio_id": "7", + "show_progress_bar": true, + "show_time": true, + "time_display": "default", + "time_position": "start", + "width": "fill" + }, + { + "tag": "audio", + "file_key": "file_v3_00or_f2c1276b-9f24-463d-8911-xxxxxxxx", + "audio_id": "8", + "show_progress_bar": true, + "show_time": true, + "time_display": "default", + "time_position": "both_sides", + "width": "fill" + }, + { + "tag": "markdown", + "content": "时长显示方式 `time_display` 分别取 `default` 和 `both` 时示例:" + }, + { + "tag": "audio", + "file_key": "file_v3_00or_f2c1276b-9f24-463d-8911-xxxxxxxx", + "audio_id": "9", + "show_progress_bar": true, + "show_time": true, + "time_display": "default", + "time_position": "end", + "width": "fill" + }, + { + "tag": "audio", + "file_key": "file_v3_00or_f2c1276b-9f24-463d-8911-xxxxxxxx", + "audio_id": "10", + "show_progress_bar": true, + "show_time": true, + "time_display": "both", + "time_position": "end", + "width": "fill" + }, + { + "tag": "markdown", + "content": "边框颜色 `border.color` 取 `red`、圆角 `border.corner_radius` 取 `4px`、背景色 `background_style` 取 `grey-200`、元素填充颜色 `fill_color` 取 `blue-800` 时示例:" + }, + { + "tag": "audio", + "file_key": "file_v3_00or_f2c1276b-9f24-463d-8911-xxxxxxxx", + "audio_id": "11", + "disabled": false, + "show_progress_bar": true, + "show_time": true, + "time_display": "both", + "time_position": "end", + "border": { + "color": "red", + "corner_radius": "4px" + }, + "style": "normal", + "background_style": "grey-200", + "fill_color": "blue-800", + "width": "fill" + }, + { + "tag": "markdown", + "content": "播放按钮样式 `style` 分别取 `flat` 和 `speak` 时示例:" + }, + { + "tag": "audio", + "file_key": "file_v3_00or_f2c1276b-9f24-463d-8911-xxxxxxxx", + "audio_id": "12", + "show_progress_bar": true, + "show_time": true, + "time_display": "both", + "time_position": "end", + "style": "flat", + "width": "fill" + }, + { + "tag": "audio", + "file_key": "file_v3_00or_f2c1276b-9f24-463d-8911-xxxxxxxx", + "audio_id": "13", + "show_progress_bar": true, + "show_time": true, + "time_display": "both", + "time_position": "end", + "style": "speak", + "width": "fill" + } + ] + } +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__chart.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__chart.md new file mode 100644 index 0000000..082e1e3 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__chart.md @@ -0,0 +1,227 @@ +# 图表组件 + +飞书卡片提供的图表组件基于 [VChart](https://www.visactor.io/) 的图表定义,支持折线图、面积图、柱状图、饼图、词云等多种数据呈现方式,帮助你可视化各类信息,提高信息沟通效率。 + +本文档介绍图表组件的 JSON 2.0 结构,要查看历史 JSON 1.0 结构,参考[图表](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/chart)。 + +![Frame 1321318175.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/ebf954a9756b7e0add5625832dcf9f06_bA4PiVAffn.png?height=1112&lazyload=true&maxWidth=600&width=2160) + +## 注意事项 + +- 单张卡片建议最多放置五个图表组件。 +- 图表组件暂不支持 JavaScript 语法。 +- 移动端暂不支持以下 VChart 相关属性,若在图表组件中指定以下 VChart 属性,图表将在移动端加载失败: + - [纹理属性(barChart.bar.style.texture)](https://www.visactor.io/vchart/option/barChart#bar.style.texture) + - [圆锥渐变属性](https://www.visactor.io/vchart/guide/tutorial_docs/Chart_Concepts/Series/Mark),即 gradient 设为 `conical` + - [形状词云基于 grid 像素布局](https://www.visactor.io/vchart/option/wordCloudChart#wordCloudConfig.layoutMode),即 `wordCloudChart.wordCloudConfig.layoutMode` 设为 `grid` + - [extensionMark 图片的 repeat 属性](https://www.visactor.io/vchart/option/barChart-extensionMark-image#style.repeatX)(extensionMark-image.style.repeatX 或 extensionMark-image.style.repeatY) + - [图元背景(barChart.bar.style.background)不支持 svg](https://www.visactor.io/vchart/option/barChart#bar.style.background) +- 为提升图表在不同终端的展示效果、优化终端用户体验,平台对你传入的图表定义(chart_spec)默认追加了[媒体查询](https://www.visactor.io/vchart/guide/tutorial_docs/Self-adaption/Media_Query)配置。若你希望自行控制图表的自适应展示逻辑,可在图表定义(chart_spec)中设置 `"media":[]` 以禁用默认追加的配置。 + +## 功能特性 + +基于图表组件绘制的图表,支持以下功能: +- **图表可交互**:用户可通过点击图表展示数据标签、点击图例实现数据过滤、拖拽缩略轴进行数据筛选。 +- **样式自适应**:支持图表多种样式的呈现,并在不同设备端、不同色彩模式下有良好的自适应展示效果; +- **支持放大查看**:PC 端上,图表支持独立窗口查看;移动端上,图表支持点击后全屏查看。 + +## 组件属性 + +### JSON 结构 + +图表组件的完整 JSON 2.0 结构如下所示: +```json +{ + "schema": "2.0", // 卡片 JSON 结构的版本。默认为 1.0。要使用 JSON 2.0 结构,必须显示声明 2.0。 + "body": { + "elements": [ + // 飞书客户端 7.1 及之后版本支持的属性 + { + "tag": "chart", // 组件的标签。 + "element_id": "custom_id", // 操作组件的唯一标识。JSON 2.0 新增属性。用于在调用组件相关接口中指定组件。需开发者自定义。 + "margin": "0px 0px 0px 0px", // 组件的外边距。JSON 2.0 新增属性。默认值 "0",支持范围 [-99,99]px。 + "aspect_ratio": "16:9", // 图表宽高比。 + "color_theme": "brand", // 图表主题。默认值 brand。 + "chart_spec": {}, // 基于 VChart 的图表定义,详细用法参考 VChart 官方文档。 + "preview": false, // 是否支持独立窗口查看,默认值 true。 + "height": "auto" // 图表组件的高度,默认值 auto,即根据宽高比自动计算。 + } + ] + } +} +``` + +### 字段说明 + +图表组件的字段说明如下表。 + +名称 | 必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | String | 空 | 组件的标签,图表组件的标签为固定值 `chart`。 +element_id | 否 | String | 空 | 操作组件的唯一标识。JSON 2.0 新增属性。用于在调用[组件相关接口](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/create)中指定组件。在同一张卡片内,该字段的值全局唯一。仅允许使用字母、数字和下划线,必须以字母开头,不得超过 20 字符。 +margin | 否 | String | 0 | 组件的外边距。JSON 2.0 新增属性。值的取值范围为 [-99,99]px。可选值:
    - 单值,如 "10px",表示组件的四个外边距都为 10 px。
    - 双值,如 "4px 0",表示组件的上下外边距为 4 px,左右外边距为 0 px。使用空格间隔(边距为 0 时可不加单位)。
    - 多值,如 "4px 0 4px 0",表示组件的上、右、下、左的外边距分别为 4px,12px,4px,12px。使用空格间隔。 +aspect_ratio | 否 | String | - PC 端:16:9
    - 移动端:1:1 | 图表的宽高比。支持以下比例:
    - 1:1
    - 2:1
    - 4:3
    - 16:9 +color_theme | 否 | String | brand | 图表的主题样式。当图表内存在多个颜色时,可使用该字段调整颜色样式。若你在 `chart_spec` 字段中声明了样式类属性,该字段无效。
    - brand:默认样式,与飞书客户端主题样式一致。
    - rainbow:同色系彩虹色。
    - complementary:互补色。
    - converse:反差色。
    - primary:主色。 +chart_spec | 是 | VChart spec 结构体 | 空 | 基于 VChart 的图表定义。详细用法参考 [VChart 官方文档](https://www.visactor.io/vchart/guide/tutorial_docs/Chart_Concepts/Understanding_VChart)。
    **提示**:
    - 在飞书 7.1 - 7.6 版本上,图表组件支持的 VChart 版本为 1.2.2;
    - 在飞书 7.7 - 7.9 版本上,图表组件支持的 VChart 版本为 1.6.6;
    - 在飞书 7.10 - 7.15 版本上,图表组件支持的 VChart 版本为 1.8.3;
    - 在飞书 7.16 -7.26 版本上,图表组件支持的 VChart 版本为 1.10.1。
    - 在飞书 7.27 及以上版本上,图表组件支持的 VChart 版本为 1.12.3。
    了解 VChart 版本更新,参考 [VChart Changelogs](https://www.visactor.io/vchart/changelog/release)。 +preview | 否 | Boolean | true | 图表是否可在独立窗口查看。可取值:
    - true:默认值。
    - PC 端:图表可在独立飞书窗口查看
    - 移动端:图表可在点击后全屏查看
    - false:
    - PC 端:图表不支持在独立飞书窗口查看
    - 移动端:图表不支持在点击后全屏查看 +height | 否 | String | auto | 图表组件的高度,可取值:
    - auto:默认值,高度将根据宽高比自动计算。
    - [1,999]px:自定义固定图表高度,此时宽高比属性 `aspect_ratio` 失效。 + +## 图表类型与示例 + +图表组件基于 VChart 1.6.x 版本,当前支持折线图、面积图、柱状图、条形图等 13 种图表。本小节列出各个图表的卡片效果和 JSON 2.0 结构示例。要查看各类图表属性的详细说明,参考 [VChart 配置文档](https://www.visactor.io/vchart/option/barChart)。 + +### 折线图 + +折线图一般用于展示数据随时间变化的趋势。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/aee3ce3391ef509a7476ca63cec582d8_8qXzlXjQIz.png?height=764&lazyload=true&maxWidth=500&width=1144) + +上图中折线图的 JSON 结构和模拟数据如下所示: + +JSON 模板 | 模拟数据 +---|--- +```json
    {
    "schema": "2.0",
    "body": {
    "elements": [
    {
    "tag": "chart",
    "chart_spec": {
    "type": "line",
    "title": {
    "text": "折线图"
    },
    "data": {
    "values": mock_data // 此处传入数据。
    },
    "xField": "time",
    "yField": "value"
    }
    }
    ]
    },
    "header": {
    "template": "purple",
    "title": {
    "content": "卡片标题",
    "tag": "plain_text"
    }
    }
    }
    ``` | ```json
    [
    {
    "time": "2:00",
    "value": 8
    },
    {
    "time": "4:00",
    "value": 9
    },
    {
    "time": "6:00",
    "value": 11
    },
    {
    "time": "8:00",
    "value": 14
    },
    {
    "time": "10:00",
    "value": 16
    },
    {
    "time": "12:00",
    "value": 17
    },
    {
    "time": "14:00",
    "value": 17
    },
    {
    "time": "16:00",
    "value": 16
    },
    {
    "time": "18:00",
    "value": 15
    }
    ] + +### 面积图 + +面积图类似于折线图,可用于展示数据随时间变化的趋势。面积图下方的填充区域可用于强调累积的总体趋势。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/b283e95152ebbf54c06599a60502eb34_IrPGUpPSr3.png?height=766&lazyload=true&maxWidth=500&width=1140) + +上图中面积图的 JSON 结构和模拟数据如下所示: + +JSON 模板 | 模拟数据 +---|--- +```json
    {
    "schema": "2.0",
    "body": {
    "elements": [
    {
    "tag": "chart",
    "chart_spec": {
    "type": "area",
    "title": {
    "text": "面积图"
    },
    "data": {
    "values": mock_data // 此处传入数据。
    },
    "xField": "time",
    "yField": "value"
    }
    }
    ]
    },
    "header": {
    "template": "purple",
    "title": {
    "content": "卡片标题",
    "tag": "plain_text"
    }
    }
    }
    ``` | ```json
    [
    {
    "time": "2:00",
    "value": 8
    },
    {
    "time": "4:00",
    "value": 9
    },
    {
    "time": "6:00",
    "value": 11
    },
    {
    "time": "8:00",
    "value": 14
    },
    {
    "time": "10:00",
    "value": 16
    },
    {
    "time": "12:00",
    "value": 17
    },
    {
    "time": "14:00",
    "value": 17
    },
    {
    "time": "16:00",
    "value": 16
    },
    {
    "time": "18:00",
    "value": 15
    }
    ]
    ``` + +### 柱状图 + +柱状图多用于比较不同组或类别之间的数据,可清晰地展示各组之间的差异。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/a34007ddecf9102af3e46f691c04e10e_zPiSWrwtu5.png?height=972&lazyload=true&maxWidth=500&width=1144) + +上图中柱状图的 JSON 结构和模拟数据如下所示: + +JSON 模板 | 模拟数据 +---|--- +```json
    {
    "schema": "2.0",
    "body": {
    "elements": [
    {
    "tag": "chart",
    "chart_spec": {
    "type": "bar",
    "title": {
    "text": "柱状图"
    },
    "data": {
    "values": mock_data // 此处传入数据。
    },
    "xField": [
    "year",
    "type"
    ],
    "yField": "value",
    "seriesField": "type",
    "legends": {
    "visible": true,
    "orient": "bottom"
    }
    }
    }
    ]
    },
    "header": {
    "template": "purple",
    "title": {
    "content": "卡片标题",
    "tag": "plain_text"
    }
    }
    } | ```json
    [
    { "type": "Autoc", "year": "1930", "value": 129 },
    { "type": "Autoc", "year": "1940", "value": 133 },
    { "type": "Autoc", "year": "1950", "value": 130 },
    { "type": "Autoc", "year": "1960", "value": 126 },
    { "type": "Autoc", "year": "1970", "value": 117 },
    { "type": "Autoc", "year": "1980", "value": 114 },
    { "type": "Democ", "year": "1930", "value": 22 },
    { "type": "Democ", "year": "1940", "value": 13 },
    { "type": "Democ", "year": "1950", "value": 25 },
    { "type": "Democ", "year": "1960", "value": 29 },
    { "type": "Democ", "year": "1970", "value": 38 },
    { "type": "Democ", "year": "1980", "value": 41 }
    ]
    ``` + +### 条形图 + +条形图与柱状图类似,但是为横向显示(`"direction": "horizontal"`)。通常用于比较不同类别的数据,在数据标签较长或类别较多时更易于阅读。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/b34bb493daeb56b4962568cc77d3f7ea_f1gjZhfSPp.png?height=768&lazyload=true&maxWidth=500&width=1142) + +上图中条形图的 JSON 结构和模拟数据如下所示: + +JSON 模板 | 模拟数据 +---|--- +```json
    {
    "schema": "2.0",
    "body": {
    "elements": [
    {
    "tag": "chart",
    "chart_spec": {
    "type": "bar",
    "title": {
    "text": "条形图"
    },
    "data": {
    "values": mock_data // 此处传入数据。
    },
    "direction": "horizontal",
    "xField": "value",
    "yField": "name"
    }
    }
    ]
    },
    "header": {
    "template": "purple",
    "title": {
    "content": "卡片标题",
    "tag": "plain_text"
    }
    }
    }
    ``` | ```json
    [
    {
    "name": "Apple",
    "value": 214480
    },
    {
    "name": "Google",
    "value": 155506
    },
    {
    "name": "Amazon",
    "value": 100764
    },
    {
    "name": "Microsoft",
    "value": 92715
    },
    {
    "name": "Coca-Cola",
    "value": 66341
    },
    {
    "name": "Samsung",
    "value": 59890
    },
    {
    "name": "Toyota",
    "value": 53404
    },
    {
    "name": "Mercedes-Benz",
    "value": 48601
    }
    ]
    ``` + +### 环图 + +环图用于表示整体中各部分的相对比例。适用于展示数据的百分比分布,强调整体的结构。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/1f9972f212bc72abe4ab7e144dd71ff1_089Whyfkns.png?height=1036&lazyload=true&maxWidth=500&width=1320) + +上图中环图的 JSON 结构和模拟数据如下所示: + +JSON 模板 | 模拟数据 +---|--- +```json
    {
    "schema": "2.0",
    "body": {
    "elements": [
    {
    "tag": "chart",
    "chart_spec": {
    "type": "pie",
    "title": {
    "text": "环图"
    },
    "data": {
    "values": mock_data // 此处传入数据。
    },
    "valueField": "value",
    "categoryField": "type",
    "outerRadius": 0.9,
    "innerRadius": 0.3,
    "label": {
    "visible": true
    },
    "legends": {
    "visible": true
    }
    }
    }
    ]
    },
    "header": {
    "template": "purple",
    "title": {
    "content": "卡片标题",
    "tag": "plain_text"
    }
    }
    } | ```json
    [
    { "type": "oxygen", "value": "46.60" },
    { "type": "silicon", "value": "27.72" },
    { "type": "aluminum", "value": "8.13" },
    { "type": "iron", "value": "5" },
    { "type": "calcium", "value": "3.63" },
    { "type": "potassium", "value": "2.59" },
    { "type": "others", "value": "3.5" }
    ]
    ``` + +### 饼图 + +饼图可用于表示整体中各部分的相对比例,但通常适用于展示几个部分的数据。适用于呈现百分比或份额。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/6dd2f06c4de01e200cc6dbc4ca165966_xVUSruCyRc.png?height=854&lazyload=true&maxWidth=500&width=994) + +上图中饼图的 JSON 结构和模拟数据如下所示: + +JSON 模板 | 模拟数据 +---|--- +```json
    {
    "schema": "2.0",
    "body": {
    "elements": [
    {
    "tag": "chart",
    "aspect_ratio": "4:3",
    "chart_spec": {
    "type": "pie",
    "title": {
    "text": "客户规划占比"
    },
    "data": {
    "values": mock_data // 此处传入数据。
    },
    "valueField": "value",
    "categoryField": "type",
    "outerRadius": 0.9,
    "legends": {
    "visible": true,
    "orient": "right"
    },
    "padding": {
    "left": 10,
    "top": 10,
    "bottom": 5,
    "right": 0
    },
    "label": {
    "visible": true
    }
    }
    }
    ]
    }
    } | ```json
    [
    {
    "type": "S1",
    "value": "340"
    },
    {
    "type": "S2",
    "value": "170"
    },
    {
    "type": "S3",
    "value": "150"
    },
    {
    "type": "S4",
    "value": "120"
    },
    {
    "type": "S5",
    "value": "100"
    }
    ]
    ``` + +### 组合图 + +组合图可将多个图表类型组合在一起,同时呈现不同性质的数据。例如,折线图与柱状图的组合,可同时展示趋势和总量。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/af72cc20eb8606efd9f45e0a237f043b_ajiDpgkGOe.png?height=966&lazyload=true&maxWidth=500&width=1142) + +上图中组合图的 JSON 结构和模拟数据如下所示: + +JSON 模板 | 模拟数据 +---|--- +```json
    {
    "schema": "2.0",
    "body": {
    "elements": [
    {
    "tag": "chart",
    "chart_spec": {
    "type": "common",
    "title": {
    "text": "组合图"
    },
    "data": [
    {
    "values": mock_data_1_1 // 此处传入数据。
    },
    {
    "values": mock_data_1_2 // 此处传入数据。
    }
    ],
    "series": [
    {
    "type": "bar",
    "dataIndex": 0,
    "label": {
    "visible": true
    },
    "seriesField": "type",
    "xField": [
    "x",
    "type"
    ],
    "yField": "y"
    },
    {
    "type": "line",
    "dataIndex": 1,
    "label": {
    "visible": true
    },
    "seriesField": "type",
    "xField": "x",
    "yField": "y"
    }
    ],
    "axes": [
    {
    "orient": "bottom"
    },
    {
    "orient": "left"
    }
    ],
    "legends": {
    "visible": true,
    "orient": "bottom"
    }
    }
    }
    ]
    },
    "header": {
    "template": "purple",
    "title": {
    "content": "卡片标题",
    "tag": "plain_text"
    }
    }
    } | ```json
    // mock_data_1_1
    [
    { "x": "周一", "type": "早餐", "y": 15 },
    { "x": "周一", "type": "午餐", "y": 25 },
    { "x": "周二", "type": "早餐", "y": 12 },
    { "x": "周二", "type": "午餐", "y": 30 },
    { "x": "周三", "type": "早餐", "y": 15 },
    { "x": "周三", "type": "午餐", "y": 24 },
    { "x": "周四", "type": "早餐", "y": 10 },
    { "x": "周四", "type": "午餐", "y": 25 },
    { "x": "周五", "type": "早餐", "y": 13 },
    { "x": "周五", "type": "午餐", "y": 20 },
    { "x": "周六", "type": "早餐", "y": 10 },
    { "x": "周六", "type": "午餐", "y": 22 },
    { "x": "周日", "type": "早餐", "y": 12 },
    { "x": "周日", "type": "午餐", "y": 19 }
    ]
    ```
    ```json
    // mock_data_1_2
    [
    { "x": "周一", "type": "饮料", "y": 22 },
    { "x": "周二", "type": "饮料", "y": 43 },
    { "x": "周三", "type": "饮料", "y": 33 },
    { "x": "周四", "type": "饮料", "y": 22 },
    { "x": "周五", "type": "饮料", "y": 10 },
    { "x": "周六", "type": "饮料", "y": 30 },
    { "x": "周日", "type": "饮料", "y": 50 }
    ]
    ``` + +### 漏斗图 + +漏斗图用于表示一系列步骤或阶段中的数据减少。适用于呈现转化率、展示销售漏斗等情况。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/62d4168a2a47d57fbc08aed32972299f_kxTsqD1AvS.png?height=768&lazyload=true&maxWidth=500&width=1140) + +上图中漏斗图的 JSON 结构和模拟数据如下所示: + +JSON 模板 | 模拟数据 +---|--- +```json
    {
    "schema": "2.0",
    "body": {
    "elements": [
    {
    "tag": "chart",
    "chart_spec": {
    "type": "funnel",
    "title": {
    "text": "漏斗图"
    },
    "data": {
    "values": mock_data // 此处传入数据。
    },
    "categoryField": "name",
    "valueField": "value",
    "isTransform": true,
    "label": {
    "visible": true
    },
    "transformLabel": {
    "visible": true
    },
    "outerLabel": {
    "visible": false
    }
    }
    }
    ]
    },
    "header": {
    "template": "purple",
    "title": {
    "content": "卡片标题",
    "tag": "plain_text"
    }
    }
    } | ```json
    [
    {
    "value": 5676,
    "name": "Sent"
    },
    {
    "value": 3872,
    "name": "Viewed"
    },
    {
    "value": 1668,
    "name": "Clicked"
    },
    {
    "value": 565,
    "name": "Purchased"
    }
    ]
    ``` + +### 散点图 + +散点图用于显示两个变量之间的关系,展示变量之间的相关性、趋势或异常值。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/00875a914b0448869a14ffbc6c685e72_unCKtVczbO.png?height=964&lazyload=true&maxWidth=500&width=1138) + +上图中散点图的 JSON 结构和模拟数据如下所示: + +JSON 模板 | 模拟数据 +---|--- +```json
    {
    "schema": "2.0",
    "body": {
    "elements": [
    {
    "tag": "chart",
    "chart_spec": {
    "type": "scatter",
    "title": {
    "text": "散点图"
    },
    "data": {
    "values": mock_data // 此处传入数据。
    },
    "xField": "milesPerGallon",
    "yField": "horsepower",
    "axes": [
    {
    "title": {
    "visible": true,
    "text": "Horse Power"
    },
    "orient": "left",
    "range": {
    "min": 0
    },
    "type": "linear"
    },
    {
    "title": {
    "visible": true,
    "text": "Miles Per Gallon"
    },
    "orient": "bottom",
    "range": {
    "min": 10
    },
    "type": "linear"
    }
    ]
    }
    }
    ]
    },
    "header": {
    "template": "purple",
    "title": {
    "content": "卡片标题",
    "tag": "plain_text"
    }
    }
    }
    ``` | ```json
    [
    { "name": "chevrolet woody", "milesPerGallon": 24.5, "cylinders": 4, "horsepower": 60 },
    { "name": "vw rabbit", "milesPerGallon": 29, "cylinders": 4, "horsepower": 70 },
    { "name": "honda civic", "milesPerGallon": 33, "cylinders": 4, "horsepower": 53 },
    { "name": "dodge aspen se", "milesPerGallon": 20, "cylinders": 6, "horsepower": 100 },
    { "name": "buick opel isuzu deluxe", "milesPerGallon": 30, "cylinders": 4, "horsepower": 80 },
    { "name": "renault 5 gtl", "milesPerGallon": 36, "cylinders": 4, "horsepower": 58 },
    { "name": "plymouth arrow gs", "milesPerGallon": 25.5, "cylinders": 4, "horsepower": 96 },
    { "name": "datsun f-10 hatchback", "milesPerGallon": 33.5, "cylinders": 4, "horsepower": 70 },
    { "name": "chevrolet caprice classic", "milesPerGallon": 17.5, "cylinders": 8, "horsepower": 145 },
    { "name": "oldsmobile cutlass supreme", "milesPerGallon": 17, "cylinders": 8, "horsepower": 110 },
    { "name": "dodge monaco brougham", "milesPerGallon": 15.5, "cylinders": 8, "horsepower": 145 },
    { "name": "mercury cougar brougham", "milesPerGallon": 15, "cylinders": 8, "horsepower": 130 },
    { "name": "chevrolet concours", "milesPerGallon": 17.5, "cylinders": 6, "horsepower": 110 },
    { "name": "buick skylark", "milesPerGallon": 20.5, "cylinders": 6, "horsepower": 105 },
    { "name": "plymouth volare custom", "milesPerGallon": 19, "cylinders": 6, "horsepower": 100 },
    { "name": "ford granada", "milesPerGallon": 18.5, "cylinders": 6, "horsepower": 98 },
    { "name": "pontiac grand prix lj", "milesPerGallon": 16, "cylinders": 8, "horsepower": 180 },
    { "name": "chevrolet monte carlo landau", "milesPerGallon": 15.5, "cylinders": 8, "horsepower": 170 },
    { "name": "chrysler cordoba", "milesPerGallon": 15.5, "cylinders": 8, "horsepower": 190 },
    { "name": "ford thunderbird", "milesPerGallon": 16, "cylinders": 8, "horsepower": 149 },
    { "name": "volkswagen rabbit custom", "milesPerGallon": 29, "cylinders": 4, "horsepower": 78 },
    { "name": "pontiac sunbird coupe", "milesPerGallon": 24.5, "cylinders": 4, "horsepower": 88 },
    { "name": "toyota corolla liftback", "milesPerGallon": 26, "cylinders": 4, "horsepower": 75 },
    { "name": "ford mustang ii 2+2", "milesPerGallon": 25.5, "cylinders": 4, "horsepower": 89 },
    { "name": "saab 99gle", "milesPerGallon": 21.6, "cylinders": 4, "horsepower": 115 },
    { "name": "ford country squire (sw)", "milesPerGallon": 15.5, "cylinders": 8, "horsepower": 142 },
    { "name": "chevrolet malibu classic (sw)", "milesPerGallon": 19.2, "cylinders": 8, "horsepower": 125 },
    { "name": "chrysler lebaron town @ country (sw)", "milesPerGallon": 18.5, "cylinders": 8, "horsepower": 150 },
    { "name": "vw rabbit custom", "milesPerGallon": 31.9, "cylinders": 4, "horsepower": 71 },
    { "name": "maxda glc deluxe", "milesPerGallon": 34.1, "cylinders": 4, "horsepower": 65 },
    { "name": "dodge colt hatchback custom", "milesPerGallon": 35.7, "cylinders": 4, "horsepower": 80 },
    { "name": "amc spirit dl", "milesPerGallon": 27.4, "cylinders": 4, "horsepower": 80 },
    { "name": "mercedes benz 300d", "milesPerGallon": 25.4, "cylinders": 5, "horsepower": 77 },
    { "name": "cadillac eldorado", "milesPerGallon": 23, "cylinders": 8, "horsepower": 125 },
    { "name": "peugeot 504", "milesPerGallon": 27.2, "cylinders": 4, "horsepower": 71 },
    { "name": "oldsmobile cutlass salon brougham", "milesPerGallon": 23.9, "cylinders": 8, "horsepower": 90 },
    { "name": "plymouth horizon", "milesPerGallon": 34.2, "cylinders": 4, "horsepower": 70 },
    { "name": "plymouth horizon tc3", "milesPerGallon": 34.5, "cylinders": 4, "horsepower": 70 },
    { "name": "datsun 210", "milesPerGallon": 31.8, "cylinders": 4, "horsepower": 65 },
    { "name": "fiat strada custom", "milesPerGallon": 37.3, "cylinders": 4, "horsepower": 69 },
    { "name": "buick skylark limited", "milesPerGallon": 28.4, "cylinders": 4, "horsepower": 90 },
    { "name": "chevrolet citation", "milesPerGallon": 28.8, "cylinders": 6, "horsepower": 115 },
    { "name": "oldsmobile omega brougham", "milesPerGallon": 26.8, "cylinders": 6, "horsepower": 115 },
    { "name": "pontiac phoenix", "milesPerGallon": 33.5, "cylinders": 4, "horsepower": 90 },
    { "name": "vw rabbit", "milesPerGallon": 41.5, "cylinders": 4, "horsepower": 76 },
    { "name": "toyota corolla tercel", "milesPerGallon": 38.1, "cylinders": 4, "horsepower": 60 },
    { "name": "chevrolet chevette", "milesPerGallon": 32.1, "cylinders": 4, "horsepower": 70 },
    { "name": "datsun 310", "milesPerGallon": 37.2, "cylinders": 4, "horsepower": 65 },
    { "name": "chevrolet citation", "milesPerGallon": 28, "cylinders": 4, "horsepower": 90 },
    { "name": "ford fairmont", "milesPerGallon": 26.4, "cylinders": 4, "horsepower": 88 },
    { "name": "amc concord", "milesPerGallon": 24.3, "cylinders": 4, "horsepower": 90 },
    { "name": "dodge aspen", "milesPerGallon": 19.1, "cylinders": 6, "horsepower": 90 },
    { "name": "audi 4000", "milesPerGallon": 34.3, "cylinders": 4, "horsepower": 78 },
    { "name": "toyota corona liftback", "milesPerGallon": 29.8, "cylinders": 4, "horsepower": 90 },
    { "name": "mazda 626", "milesPerGallon": 31.3, "cylinders": 4, "horsepower": 75 },
    { "name": "datsun 510 hatchback", "milesPerGallon": 37, "cylinders": 4, "horsepower": 92 },
    { "name": "toyota corolla", "milesPerGallon": 32.2, "cylinders": 4, "horsepower": 75 },
    { "name": "mazda glc", "milesPerGallon": 46.6, "cylinders": 4, "horsepower": 65 },
    { "name": "dodge colt", "milesPerGallon": 27.9, "cylinders": 4, "horsepower": 105 },
    { "name": "datsun 210", "milesPerGallon": 40.8, "cylinders": 4, "horsepower": 65 },
    { "name": "vw rabbit c (diesel)", "milesPerGallon": 44.3, "cylinders": 4, "horsepower": 48 },
    { "name": "vw dasher (diesel)", "milesPerGallon": 43.4, "cylinders": 4, "horsepower": 48 },
    { "name": "audi 5000s (diesel)", "milesPerGallon": 36.4, "cylinders": 5, "horsepower": 67 },
    { "name": "mercedes-benz 240d", "milesPerGallon": 30, "cylinders": 4, "horsepower": 67 },
    { "name": "honda civic 1500 gl", "milesPerGallon": 44.6, "cylinders": 4, "horsepower": 67 },
    { "name": "renault lecar deluxe", "milesPerGallon": 40.9, "cylinders": 4, "horsepower": 0 },
    { "name": "subaru dl", "milesPerGallon": 33.8, "cylinders": 4, "horsepower": 67 },
    { "name": "vokswagen rabbit", "milesPerGallon": 29.8, "cylinders": 4, "horsepower": 62 },
    { "name": "datsun 280-zx", "milesPerGallon": 32.7, "cylinders": 6, "horsepower": 132 },
    { "name": "mazda rx-7 gs", "milesPerGallon": 23.7, "cylinders": 3, "horsepower": 100 },
    { "name": "triumph tr7 coupe", "milesPerGallon": 35, "cylinders": 4, "horsepower": 88 },
    { "name": "ford mustang cobra", "milesPerGallon": 23.6, "cylinders": 4, "horsepower": 0 },
    { "name": "honda Accelerationord", "milesPerGallon": 32.4, "cylinders": 4, "horsepower": 72 },
    { "name": "plymouth reliant", "milesPerGallon": 27.2, "cylinders": 4, "horsepower": 84 },
    { "name": "buick skylark", "milesPerGallon": 26.6, "cylinders": 4, "horsepower": 84 },
    { "name": "dodge aries wagon (sw)", "milesPerGallon": 25.8, "cylinders": 4, "horsepower": 92 },
    { "name": "chevrolet citation", "milesPerGallon": 23.5, "cylinders": 6, "horsepower": 110 },
    { "name": "plymouth reliant", "milesPerGallon": 30, "cylinders": 4, "horsepower": 84 }
    ]
    ``` + +### 雷达图 + +雷达图用于比较多个变量在不同维度上的表现,也可展示多个指标之间的相对关系。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/503ae73a48f042fb11b607f6f229d64c_kOQFBPe2Me.png?height=966&lazyload=true&maxWidth=500&width=1140) + +上图中雷达图的 JSON 结构和模拟数据如下所示: + +JSON 模板 | 模拟数据 +---|--- +```json
    {
    "schema": "2.0",
    "body": {
    "elements": [
    {
    "tag": "chart",
    "chart_spec": {
    "type": "radar",
    "title": {
    "text": "雷达图"
    },
    "data": {
    "values": mock_data // 此处传入数据。
    },
    "categoryField": "key",
    "valueField": "value",
    "area": {
    "visible": true
    },
    "outerRadius": 0.8,
    "axes": [
    {
    "orient": "radius",
    "label": {
    "visible": true,
    "style": {
    "textAlign": "center"
    }
    }
    }
    ]
    }
    }
    ]
    },
    "header": {
    "template": "purple",
    "title": {
    "content": "卡片标题",
    "tag": "plain_text"
    }
    }
    }
    ``` | ```json
    [
    {
    "key": "力量",
    "value": 5
    },
    {
    "key": "速度",
    "value": 5
    },
    {
    "key": "射程",
    "value": 3
    },
    {
    "key": "持续",
    "value": 5
    },
    {
    "key": "精密",
    "value": 5
    },
    {
    "key": "成长",
    "value": 5
    }
    ]
    ``` + +### 条形进度 + +条形进度用于表示某个或多个指标的进度,如任务完成度、目标达成情况等。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/c9df7b7058779e5dec730d86b5a2a738_lF6E5uRTAi.png?height=698&lazyload=true&maxWidth=500&width=1136) + +上图中条形进度的 JSON 结构和模拟数据如下所示: + +JSON 模板 | 模拟数据 +---|--- +```json
    {
    "schema": "2.0",
    "body": {
    "elements": [
    {
    "tag": "chart",
    "aspect_ratio": "2:1",
    "chart_spec": {
    "type": "linearProgress",
    "title": {
    "text": "条形进度图"
    },
    "data": {
    "values": mock_data // 此处传入数据。
    },
    "direction": "horizontal",
    "xField": "value",
    "yField": "type",
    "seriesField": "type",
    "axes": [
    {
    "orient": "left",
    "domainLine": {
    "visible": false
    }
    }
    ]
    }
    }
    ]
    },
    "header": {
    "template": "purple",
    "title": {
    "content": "卡片标题",
    "tag": "plain_text"
    }
    }
    }
    ``` | ```json
    [
    {
    "type": "Tradition Industries",
    "value": 0.795,
    "text": "79.5%"
    },
    {
    "type": "Business Companies",
    "value": 0.25,
    "text": "25%"
    }
    ]
    ``` + +### 环形进度 + +环形进度类似于条形进度,但呈环状,可强调整体进度并突出部分的完成度。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/897414e4ba18d6806dae990cae424156_XwAlOFhR0B.png?height=962&lazyload=true&maxWidth=500&width=1144) + +上图中环形进度图的 JSON 结构和模拟数据如下所示: + +JSON 模板 | 模拟数据 +---|--- +```json
    {
    "schema": "2.0",
    "body": {
    "elements": [
    {
    "tag": "chart",
    "chart_spec": {
    "type": "circularProgress",
    "title": {
    "text": "环形进度图"
    },
    "data": {
    "values": mock_data // 此处传入数据。
    },
    "valueField": "value",
    "categoryField": "type",
    "seriesField": "type",
    "radius": 0.7,
    "innerRadius": 0.4,
    "cornerRadius": 20,
    "progress": {
    "style": {
    "innerPadding": 5,
    "outerPadding": 5
    }
    },
    "indicator": {
    "visible": true,
    "trigger": "hover",
    "title": {
    "visible": true,
    "field": "type",
    "autoLimit": true
    },
    "content": [
    {
    "visible": true,
    "field": "text"
    }
    ]
    },
    "legends": {
    "visible": true,
    "orient": "bottom",
    "title": {
    "visible": false
    }
    }
    }
    }
    ]
    },
    "header": {
    "template": "purple",
    "title": {
    "content": "卡片标题",
    "tag": "plain_text"
    }
    }
    }
    ``` | ```json
    [
    {
    "type": "Industries",
    "value": 0.795,
    "text": "79.5%"
    },
    {
    "type": "Companies",
    "value": 0.25,
    "text": "25%"
    }
    ]
    ``` + +### 词云 + +词云用于展示文本数据中词条的相对频率。可用于展示关键词或主题的重要性。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/5f45fba3d2e5232982ae55f319e8acc4_F6OX1hjMPL.png?height=964&lazyload=true&maxWidth=500&width=1140) + +上图中词云图的 JSON 结构和模拟数据如下所示: + +JSON 模板 | 模拟数据 +---|--- +```json
    {
    "schema": "2.0",
    "body": {
    "elements": [
    {
    "tag": "chart",
    "chart_spec": {
    "type": "wordCloud",
    "title": {
    "text": "词云"
    },
    "data": {
    "values": mock_data // 此处传入数据。
    },
    "nameField": "challenge_name",
    "valueField": "sum_count",
    "seriesField": "challenge_name"
    }
    }
    ]
    },
    "header": {
    "template": "purple",
    "title": {
    "content": "卡片标题",
    "tag": "plain_text"
    }
    }
    }
    ``` | ```json
    [
    {
    "challenge_id": 1658490688121879,
    "challenge_name": "宅家dou剧场宅家dou剧场",
    "sum_count": 128
    },
    {
    "challenge_id": 1640007327696910,
    "challenge_name": "我的观影报告",
    "sum_count": 103
    },
    {
    "challenge_id": 1557656100811777,
    "challenge_name": "抖瓜小助手",
    "sum_count": 76
    },
    {
    "challenge_id": 1553513807372289,
    "challenge_name": "搞笑",
    "sum_count": 70
    },
    {
    "challenge_id": 1599321527572563,
    "challenge_name": "我要上热门",
    "sum_count": 69
    },
    {
    "challenge_id": 1588489879306259,
    "challenge_name": "热门",
    "sum_count": 54
    },
    {
    "challenge_id": 1558589039423489,
    "challenge_name": "正能量",
    "sum_count": 52
    },
    {
    "challenge_id": 1565489422066689,
    "challenge_name": "上热门",
    "sum_count": 36
    },
    {
    "challenge_id": 1572618705886286,
    "challenge_name": "情感",
    "sum_count": 34
    },
    {
    "challenge_id": 1626948076237836,
    "challenge_name": "dou上热门",
    "sum_count": 32
    },
    {
    "challenge_id": 1585347546644558,
    "challenge_name": "影视剪辑",
    "sum_count": 25
    },
    {
    "challenge_id": 1589711040325639,
    "challenge_name": "抖瓜热门",
    "sum_count": 24
    },
    {
    "challenge_id": 1562208367689745,
    "challenge_name": "爱情",
    "sum_count": 24
    },
    {
    "challenge_id": 1657693004378126,
    "challenge_name": "美食趣胃计划",
    "sum_count": 21
    },
    {
    "challenge_id": 1565101681155074,
    "challenge_name": "搞笑视频",
    "sum_count": 20
    },
    {
    "challenge_id": 1581874377004045,
    "challenge_name": "涨知识",
    "sum_count": 19
    },
    {
    "challenge_id": 1577135789977693,
    "challenge_name": "教师节",
    "sum_count": 19
    },
    {
    "challenge_id": 1644832627937293,
    "challenge_name": "解锁人脸运镜术",
    "sum_count": 18
    },
    {
    "challenge_id": 1554036363744257,
    "challenge_name": "美食",
    "sum_count": 18
    },
    {
    "challenge_id": 1601049369390083,
    "challenge_name": "听说发第二遍会火",
    "sum_count": 17
    },
    {
    "challenge_id": 1643026562973710,
    "challenge_name": "我的观影视报告",
    "sum_count": 17
    },
    {
    "challenge_id": 1605694229498884,
    "challenge_name": "解说电影",
    "sum_count": 16
    },
    {
    "challenge_id": 1550712576368642,
    "challenge_name": "音乐",
    "sum_count": 15
    },
    {
    "challenge_id": 1571885391450145,
    "challenge_name": "沙雕",
    "sum_count": 15
    },
    {
    "challenge_id": 1577707248705566,
    "challenge_name": "悬疑",
    "sum_count": 15
    },
    {
    "challenge_id": 1573335406611469,
    "challenge_name": "家庭",
    "sum_count": 15
    },
    {
    "challenge_id": 1646248140767239,
    "challenge_name": "我在抖瓜看综艺",
    "sum_count": 15
    },
    {
    "challenge_id": 1640376658836494,
    "challenge_name": "我的影视报告",
    "sum_count": 14
    },
    {
    "challenge_id": 1580569530602573,
    "challenge_name": "亲爱的你在哪里",
    "sum_count": 14
    },
    {
    "challenge_id": 1581067386920973,
    "challenge_name": "夫妻",
    "sum_count": 14
    },
    {
    "challenge_id": 1570334853133377,
    "challenge_name": "健康",
    "sum_count": 14
    },
    {
    "challenge_id": 1576961841964061,
    "challenge_name": "感谢抖瓜",
    "sum_count": 13
    },
    {
    "challenge_id": 1668357679925262,
    "challenge_name": "浪计划",
    "sum_count": 13
    },
    {
    "challenge_id": 1676069567224840,
    "challenge_name": "一口吃个秋",
    "sum_count": 13
    },
    {
    "challenge_id": 1657707397301262,
    "challenge_name": "在逃公主",
    "sum_count": 13
    },
    {
    "challenge_id": 1674607865397325,
    "challenge_name": "萌宠出道计划",
    "sum_count": 13
    },
    {
    "challenge_id": 1647439075451907,
    "challenge_name": "秋日星分享",
    "sum_count": 12
    },
    {
    "challenge_id": 1563545971008513,
    "challenge_name": "电影",
    "sum_count": 12
    },
    {
    "challenge_id": 1582741603218446,
    "challenge_name": "科普",
    "sum_count": 11
    },
    {
    "challenge_id": 1586651415365645,
    "challenge_name": "婚姻",
    "sum_count": 11
    },
    {
    "challenge_id": 1578783394583565,
    "challenge_name": "传递正能量",
    "sum_count": 11
    },
    {
    "challenge_id": 1614856685574147,
    "challenge_name": "沙雕沙雕沙雕",
    "sum_count": 11
    },
    {
    "challenge_id": 1665561838764045,
    "challenge_name": "封校的当代大学生",
    "sum_count": 11
    },
    {
    "challenge_id": 1640393867132935,
    "challenge_name": "教师节快乐",
    "sum_count": 10
    },
    {
    "challenge_id": 1587559248197661,
    "challenge_name": "遇见她",
    "sum_count": 10
    },
    {
    "challenge_id": 1673432085422103,
    "challenge_name": "抖是剧中人",
    "sum_count": 10
    },
    {
    "challenge_id": 1645181053899788,
    "challenge_name": "dou出新知",
    "sum_count": 10
    },
    {
    "challenge_id": 1569728533702658,
    "challenge_name": "情侣日常",
    "sum_count": 10
    },
    {
    "challenge_id": 1668624557294599,
    "challenge_name": "百万赞演技大赏",
    "sum_count": 10
    },
    {
    "challenge_id": 1571636507998210,
    "challenge_name": "记录生活",
    "sum_count": 9
    },
    {
    "challenge_id": 1581943156410381,
    "challenge_name": "抖瓜电影",
    "sum_count": 9
    },
    {
    "challenge_id": 1593324788514820,
    "challenge_name": "婚姻家庭",
    "sum_count": 9
    },
    {
    "challenge_id": 1641293074512910,
    "challenge_name": "寻情记",
    "sum_count": 9
    },
    {
    "challenge_id": 1676080053705736,
    "challenge_name": "爱宠来狂欢",
    "sum_count": 9
    },
    {
    "challenge_id": 1589745110342676,
    "challenge_name": "夫妻日常",
    "sum_count": 9
    },
    {
    "challenge_id": 1574942323087374,
    "challenge_name": "开学",
    "sum_count": 9
    },
    {
    "challenge_id": 1660654219289607,
    "challenge_name": "娱乐播报台",
    "sum_count": 9
    },
    {
    "challenge_id": 1597705816677380,
    "challenge_name": "影视推荐",
    "sum_count": 9
    },
    {
    "challenge_id": 1675354540387336,
    "challenge_name": "萤火计划",
    "sum_count": 9
    },
    {
    "challenge_id": 1652979335878669,
    "challenge_name": "上海",
    "sum_count": 9
    },
    {
    "challenge_id": 1569327523145730,
    "challenge_name": "军训",
    "sum_count": 9
    },
    {
    "challenge_id": 1558926116325378,
    "challenge_name": "健身",
    "sum_count": 8
    },
    {
    "challenge_id": 1645373043400716,
    "challenge_name": "这个视频有点料",
    "sum_count": 8
    },
    {
    "challenge_id": 1563191800692737,
    "challenge_name": "情侣",
    "sum_count": 8
    },
    {
    "challenge_id": 1552496822290434,
    "challenge_name": "闺蜜",
    "sum_count": 8
    },
    {
    "challenge_id": 1603569303963651,
    "challenge_name": "平凡的荣耀",
    "sum_count": 8
    },
    {
    "challenge_id": 1673998740750349,
    "challenge_name": "暑期知识大作战",
    "sum_count": 8
    },
    {
    "challenge_id": 1567431196459009,
    "challenge_name": "汽车",
    "sum_count": 8
    },
    {
    "challenge_id": 1658389496684558,
    "challenge_name": "百亿剧好看计划",
    "sum_count": 8
    },
    {
    "challenge_id": 1574252919626782,
    "challenge_name": "教育",
    "sum_count": 8
    },
    {
    "challenge_id": 1591391074552852,
    "challenge_name": "农村生活",
    "sum_count": 8
    },
    {
    "challenge_id": 1566157607002417,
    "challenge_name": "反转",
    "sum_count": 8
    },
    {
    "challenge_id": 1577947638725661,
    "challenge_name": "老师辛苦了",
    "sum_count": 8
    },
    {
    "challenge_id": 1603426099923976,
    "challenge_name": "婆媳",
    "sum_count": 7
    },
    {
    "challenge_id": 1583473234973709,
    "challenge_name": "剧情",
    "sum_count": 7
    },
    {
    "challenge_id": 1571084981282833,
    "challenge_name": "恋爱",
    "sum_count": 7
    },
    {
    "challenge_id": 1677255352271879,
    "challenge_name": "不要贪心舞",
    "sum_count": 7
    },
    {
    "challenge_id": 1624332181128206,
    "challenge_name": "游戏",
    "sum_count": 7
    },
    {
    "challenge_id": 1592206883926023,
    "challenge_name": "惊悚悬疑",
    "sum_count": 7
    },
    {
    "challenge_id": 1550970194610178,
    "challenge_name": "换装",
    "sum_count": 7
    },
    {
    "challenge_id": 1570527559630850,
    "challenge_name": "安全",
    "sum_count": 7
    },
    {
    "challenge_id": 1671553348181070,
    "challenge_name": "贝勒爷的沙雕日常",
    "sum_count": 7
    },
    {
    "challenge_id": 1549715734089730,
    "challenge_name": "宿舍",
    "sum_count": 7
    },
    {
    "challenge_id": 1576425368139790,
    "challenge_name": "感谢官方",
    "sum_count": 7
    },
    {
    "challenge_id": 1551594539613185,
    "challenge_name": "萌宠",
    "sum_count": 7
    },
    {
    "challenge_id": 1642026158078987,
    "challenge_name": "抖瓜创作者大会",
    "sum_count": 7
    },
    {
    "challenge_id": 1550169395535874,
    "challenge_name": "舞蹈",
    "sum_count": 6
    },
    { "challenge_id": 1564101645806594, "challenge_name": "狗", "sum_count": 6 },
    {
    "challenge_id": 1569456397847553,
    "challenge_name": "班主任",
    "sum_count": 6
    },
    {
    "challenge_id": 1571995751044098,
    "challenge_name": "手机摄影",
    "sum_count": 6
    },
    {
    "challenge_id": 1571241227129857,
    "challenge_name": "刘德华",
    "sum_count": 6
    },
    {
    "challenge_id": 1674031131712524,
    "challenge_name": "画画的baby",
    "sum_count": 6
    },
    {
    "challenge_id": 1574972965820429,
    "challenge_name": "盛世美颜",
    "sum_count": 6
    },
    {
    "challenge_id": 1598181470695437,
    "challenge_name": "精彩片段",
    "sum_count": 6
    },
    {
    "challenge_id": 1566324012028929,
    "challenge_name": "迈克尔杰克逊",
    "sum_count": 6
    },
    {
    "challenge_id": 1555709753369601,
    "challenge_name": "抖瓜",
    "sum_count": 6
    },
    {
    "challenge_id": 1611500399287309,
    "challenge_name": "把嘴给我闭上",
    "sum_count": 6
    },
    {
    "challenge_id": 1619248233185284,
    "challenge_name": "抖瓜汽车",
    "sum_count": 6
    },
    {
    "challenge_id": 1677633728299016,
    "challenge_name": "电影禁锢之地",
    "sum_count": 6
    },
    {
    "challenge_id": 1574140351949838,
    "challenge_name": "花木兰",
    "sum_count": 6
    },
    {
    "challenge_id": 1591376183127134,
    "challenge_name": "林雨申",
    "sum_count": 6
    }
    ]
    ``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__divider.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__divider.md new file mode 100644 index 0000000..085b743 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__divider.md @@ -0,0 +1,78 @@ +# 分割线组件 + +你可以在卡片中添加分割线组件,使卡片内容更清晰。 + +本文档介绍分割线组件的 JSON 2.0 结构,要查看历史 JSON 1.0 结构,参考[分割线](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/divider)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/062d8c93b9b67ee9fb8c4188c19097d5_6kwLHW7Hfi.png?height=224&lazyload=true&maxWidth=300&width=559) + +## JSON 结构 + +分割线的完整 JSON 2.0 结构如下所示: +```json +{ + "schema": "2.0", + "body": { + "elements": [ + { + "tag": "hr", + "element_id": "custom_id", // 操作组件的唯一标识。JSON 2.0 新增属性。用于在调用组件相关接口中指定组件。需开发者自定义。 + "margin": "0px 0px 0px 0px" // 组件的外边距。JSON 2.0 新增属性。默认值 "0",支持范围 [-99,99]px。 + } + ] + } +} +``` + +## 字段说明 + +分割线组件的字段说明如下表。 + +名称 | 必须 | 类型 | 默认值 | 描述 +---|---|---|---|--- +tag | 是 | String | 空 | 组件的标签。分割线组件的固定取值为 `hr`。 +element_id | 否 | String | 空 | 操作组件的唯一标识。JSON 2.0 新增属性。用于在调用[组件相关接口](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/create)中指定组件。在同一张卡片内,该字段的值全局唯一。仅允许使用字母、数字和下划线,必须以字母开头,不得超过 20 字符。 +margin | 否 | String | 0 | 组件的外边距。JSON 2.0 新增属性。值的取值范围为 [-99,99]px。可选值:
    - 单值,如 "10px",表示组件的四个外边距都为 10 px。
    - 双值,如 "4px 0",表示组件的上下外边距为 4 px,左右外边距为 0 px。使用空格间隔(边距为 0 时可不加单位)。
    - 多值,如 "4px 0 4px 0",表示组件的上、右、下、左的外边距分别为 4px,12px,4px,12px。使用空格间隔。 + +## 示例代码 + +以下的 JSON 2.0 示例代码可实现如下图所示的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/062d8c93b9b67ee9fb8c4188c19097d5_skrtnBe6Lz.png?height=224&lazyload=true&maxWidth=300&width=559) +```json +{ + "schema": "2.0", + "body": { + "direction": "vertical", + "padding": "12px 12px 12px 12px", + "elements": [ + { + "tag": "div", + "text": { + "tag": "plain_text", + "content": "普通文本示例", + "text_size": "normal", + "text_align": "left", + "text_color": "default" + }, + "margin": "0px 0px 0px 0px" + }, + { + "tag": "hr", + "margin": "0px 0px 0px 0px" + }, + { + "tag": "button", + "text": { + "tag": "plain_text", + "content": "查看更多" + }, + "type": "primary", + "width": "default", + "size": "medium", + "margin": "0px 0px 0px 0px" + } + ] + } +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__image.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__image.md new file mode 100644 index 0000000..7bac6b5 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__image.md @@ -0,0 +1,129 @@ +# 图片组件 + +飞书卡片支持图片组件。你可调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口或在搭建工具的图片组件中上传图片,获取图片的 key 传入图片组件中,使卡片内容更丰富。 + +本文档介绍图片组件的 JSON 2.0 结构,要查看历史 JSON 1.0 结构,参考[图片](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/image)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/3373c8abfbe10a4fd850d45048fb5c97_TV8acJELCy.png?height=436&lazyload=true&maxWidth=300&width=626) + +## 注意事项 + +- 在 JSON 2.0 结构中,图片组件的 `size` 属性不再支持传入 `stretch_without_padding` 实现通栏效果,你需设置 `margin` 属性为负数实现通栏效果: + +```json + { + "schema": "2.0", // 卡片 JSON 结构的版本。默认为 1.0。要使用 JSON 2.0 结构,必须显示声明 2.0。 + "body": { + "elements": [ + { + "tag": "img", + "img_key": "img_v3_0238_073f1823-df2b-4377-86c6-e293f183622j", + "scale_type": "crop_center", + "margin": "4px -12px" + } + ] + } + } + ``` +为保证图片在聊天窗口中呈现的清晰度,建议你在组件中上传的图片遵从以下规范: + +- 图片尺寸在 1500 × 3000 px 的范围内。 +- 图片大小不超过 10 M。 +- 图片的 `高度:宽度` 不超过 `16:9`。 + +## JSON 结构 + +图片组件的完整 JSON 2.0 结构如下所示: +```json +{ + "schema": "2.0", // 卡片 JSON 结构的版本。默认为 1.0。要使用 JSON 2.0 结构,必须显示声明 2.0。 + "body": { + "elements": [ + { + "tag": "img", + "element_id": "custom_id", // 操作组件的唯一标识。JSON 2.0 新增属性。用于在调用组件相关接口中指定组件。需开发者自定义。 + "margin": "0px 0px 0px 0px", // 组件的外边距。JSON 2.0 新增属性。默认值 "0",支持范围 [-99,99]px。 + "img_key": "img_v3_0238_073f1823-df2b-4377-86c6-e293f18abcef", // 图片的 Key。可通过上传图片接口或在搭建工具中上传图片后获得。 + "alt": { + // 光标悬浮(hover)在图片上时展示的说明。 + "tag": "plain_text", + "content": "" + }, + "title": { + // 图片标题。 + "tag": "plain_text", + "content": "" + }, + "corner_radius": "5px", // 图片的圆角半径。 + "scale_type": "crop_top", // 图片的裁剪模式,当 size 字段的比例和图片的比例不一致时会触发裁剪。 + "size": "100px 100px", // 图片尺寸。仅在 scale_type 字段为 crop_center 或 crop_top 时生效。 + "transparent": false, // 是否为透明底色。默认为 false,即图片为白色底色。 + "preview": false, // 点击后是否放大图片。默认值为 true。 + // 历史属性 + "mode": "large", // 图片尺寸模式。 + "custom_width": "300px", // 自定义图片的最大展示宽度。 + "compact_width": false // 是否展示为紧凑型的图片。 + } + ] + } +} +``` + +## 字段说明 + +图片组件的字段说明如下表。 + +名称 | 必须 | 类型 | 默认值 | 描述 +---|---|---|---|--- +tag | 是 | String | 无 | 组件的标签,图片组件的固定取值为 img。 +element_id | 否 | String | 空 | 操作组件的唯一标识。JSON 2.0 新增属性。用于在调用[组件相关接口](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/create)中指定组件。在同一张卡片内,该字段的值全局唯一。仅允许使用字母、数字和下划线,必须以字母开头,不得超过 20 字符。 +margin | 否 | String | 0 | 组件的外边距。JSON 2.0 新增属性。值的取值范围为 [-99,99]px。可选值:
    - 单值,如 "10px",表示组件的四个外边距都为 10 px。
    - 双值,如 "4px 0",表示组件的上下外边距为 4 px,左右外边距为 0 px。使用空格间隔(边距为 0 时可不加单位)。
    - 多值,如 "4px 0 4px 0",表示组件的上、右、下、左的外边距分别为 4px,12px,4px,12px。使用空格间隔。 +img_key | 是 | String | / | 图片资源的 Key。你可以调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口或在搭建工具中上传图片,获取图片的 key。 +alt | 是 | Struct | / | 悬浮(hover)在图片上时展示的说明文案。示例值:
    ```json
    "alt": {
    "tag": "plain_text",
    "content": "悬浮(hover)在图片上时展示的说明文案,不需要可以传空"
    }
    ``` +title | 否 | Struct | / | 图片标题。示例值:
    ```json
    "title": {
    "tag": "plain_text",
    "content": "图片标题"
    }
    ``` +corner_radius | 否 | String | / | 图片的圆角半径。取值遵循以下格式:
    - [0,∞]px
    - [0,100]% +scale_type | 否 | String | crop_center | 图片的裁剪模式,当 `size` 字段的比例和图片的比例不一致时会触发裁剪。 | 可取值:
    - crop_center:居中裁剪
    - crop_top:顶部裁剪
    - fit_horizontal:完整展示不裁剪 +size | 否 | String | / | 图片尺寸。仅在 `scale_type` 字段为 crop_center 或 crop_top 时生效。可取值:
    - **stretch**:超大图,适用于高宽比小于 `16:9` 的图片。
    - **large**:大图,尺寸为 160 × 160,适用于多图混排。
    - **medium**:中图,尺寸为 80 × 80,适用于图文混排的封面图。
    - **small**:小图,尺寸为 40 × 40,适用于人员头像。
    - **tiny**:超小图,尺寸为 16 × 16,适用于图标、备注。
    - **[1,1000]px [1,1000]px**:自定义图片尺寸,单位为像素,中间用空格分隔。
    **注意**:
    在 JSON 2.0 结构中,图片组件的 `size` 属性不再支持传入 `stretch_without_padding` 实现通栏效果,你需设置 `margin` 属性为负数实现通栏效果:
    ```json
    {
    "tag": "img",
    "img_key": "img_v3_0238_073f1823-df2b-4377-86c6-e293f183622j",
    "scale_type": "crop_center",
    "margin": "4px -12px"
    }
    ``` +transparent | 否 | Boolean | false | 是否为透明底色。默认为 false,即图片为白色底色。 +preview | 否 | Boolean | true | 点击后是否放大图片。
    - true:点击图片后,弹出图片查看器放大查看当前点击的图片。
    - false:点击图片后,响应卡片本身的交互事件,不弹出图片查看器。
    **提示**:如果你为卡片配置了跳转链接`card_link`参数,可将该参数设置为 `false`,后续用户点击卡片上的图片也能响应 card_link 链接跳转。 + +### 历史字段说明 + +参数 | 是否必须 | 类型 | 默认值 | 描述 +---|---|---|---|--- +mode | 否 | String | / | 图片显示模式。取值:
    - **crop_center**:居中裁剪模式,对长图会限高,并居中裁剪后展示。
    - **fit_horizontal**:平铺模式,宽度撑满卡片完整展示上传的图片。
    - **stretch**:自适应。图片宽度撑满卡片宽度,当图片 `高:宽` 小于 `16:9` 时,完整展示原图。当图片 `高:宽` 大于 `16:9` 时,顶部对齐裁剪图片,并在图片底部展示 **长图** 脚标。
    - **large**:大图,尺寸为 160 × 160,适用于多图混排。
    - **medium**:中图,尺寸为 80 × 80,适用于图文混排的封面图。
    - **small**:小图,尺寸为 40 × 40,适用于人员头像。
    - **tiny**:超小图,尺寸为 16 × 16,适用于图标、备注。
    **注意**:设置该参数后,会覆盖 `custom_width` 参数。更多信息参见[消息卡片设计规范](https://open.feishu.cn/document/ukTMukTMukTM/ugDOwYjL4gDM24CO4AjN)。 +custom_width | 否 | int | / | 自定义图片的最大展示宽度,支持在 278px ~ 580px 范围内指定最大展示宽度。默认情况下图片宽度与图片组件所占区域的宽度一致。
    **注意**:该参数在飞书 V4.0 以上版本生效。 +compact_width | 否 | Boolean | false | 是否展示为紧凑型的图片。如果配置为 `true`,则展示最大宽度为 278px 的紧凑型图片。 + +## Demo 示例 + +以下 JSON 2.0 结构的示例代码可实现如下图所示的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/3373c8abfbe10a4fd850d45048fb5c97_04zjYIt2OP.png?height=436&lazyload=true&maxWidth=300&width=626) + +```JSON +{ + "schema": "2.0", + "body": { + "direction": "vertical", + "padding": "12px 12px 12px 12px", + "elements": [ + { + "tag": "img", + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg", + "preview": true, + "transparent": false, + "scale_type": "crop_center", + "size": "stretch", + "alt": { + "tag": "plain_text", + "content": "示例图片" + }, + "corner_radius": "5%", + "margin": "0px 0px 0px 0px", + "element_id": "demoimg01" + } + ] + } +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__multi-image-laylout.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__multi-image-laylout.md new file mode 100644 index 0000000..c71c370 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__multi-image-laylout.md @@ -0,0 +1,236 @@ +# 多图混排组件 + +飞书卡片支持多图混排组件。你可调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口或在新版飞书卡片搭建工具中上传图片,获取图片的 key 传入多图混排组件中,使卡片内容更丰富。 + +本文档介绍多图混排组件的 JSON 2.0 结构,要查看历史 JSON 1.0 结构,参考[多图混排](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/multi-image-laylout)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/fb315779524d13ae504b7b7252acfd49_Bc8bJyGzyt.png?height=390&lazyload=true&maxWidth=300&width=559) + +## 使用场景 + +在内容推送场景,你可能需要在卡片内组织编排多张图片。此时你可以使用多图混排组件,选择图片混排方式,快速构建多图样式。 + +双图混排 | 三图混排 | 四宫格图 +---|---|--- +  |   |   +六宫格图 | 九宫格图 |   +  |   + +## 注意事项 + +为保证图片在聊天窗口中呈现的清晰度,建议你在组件中上传的图片遵从以下规范: + +- 图片尺寸在 1500 × 3000 px 的范围内。 +- 图片大小不超过 10 M。 +- 图片的 `高度:宽度` 不超过 `16:9`。 + +## JSON 结构 + +多图混排的完整 JSON 2.0 结构如下所示: +```json +{ + "schema": "2.0", // 卡片 JSON 结构的版本。默认为 1.0。要使用 JSON 2.0 结构,必须显示声明 2.0。 + "body": { + "elements": [ + { + "tag": "img_combination", + "element_id": "custom_id", // 操作组件的唯一标识。JSON 2.0 新增属性。用于在调用组件相关接口中指定组件。需开发者自定义。 + "margin": "0px 0px 0px 0px", // 组件的外边距。JSON 2.0 新增属性。默认值 "0",支持范围 [-99,99]px。 + "combination_mode": "double", // 多图混排的方式。 + "combination_transparent": false, // 是否为透明底色。默认为 false,即图片为白色底色。 + "corner_radius": "12px", // 多图混排图片的圆角半径,单位是像素(px)。 + "img_list": [ + // 图片资源数组,顺序与图片排列顺序一致。 + { + "img_key": "img_v3_0239_8347760e-3173-4072-b1aa-e4e7c835741j", + "transparent": false // 是否为透明底色。默认为 false,即图片为白色底色。 + }, + { + "img_key": "img_v3_0239_d9a9b734-57f8-4247-baf3-ae178b55f96j" + } + ] + } + ] + } +} +``` + +## 字段说明 + +多图混排组件的字段说明如下表。 + +名称 | 必须 | 类型 | 默认值 | 描述 +---|---|---|---|--- +tag | 是 | String | / | 多图混排组件的标签,固定取值:`img_combination`。 +element_id | 否 | String | 空 | 操作组件的唯一标识。JSON 2.0 新增属性。用于在调用[组件相关接口](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/create)中指定组件。在同一张卡片内,该字段的值全局唯一。仅允许使用字母、数字和下划线,必须以字母开头,不得超过 20 字符。 +margin | 否 | String | 0 | 组件的外边距。JSON 2.0 新增属性。值的取值范围为 [-99,99]px。可选值:
    - 单值,如 "10px",表示组件的四个外边距都为 10 px。
    - 双值,如 "4px 0",表示组件的上下外边距为 4 px,左右外边距为 0 px。使用空格间隔(边距为 0 时可不加单位)。
    - 多值,如 "4px 0 4px 0",表示组件的上、右、下、左的外边距分别为 4px,12px,4px,12px。使用空格间隔。 +combination_mode | 是 | String | 空 | 多图混排的方式,可取值:
    - double:双图混排,最多可排布两张图。
    - triple:三图混排,最多可排布三张图。
    - bisect:等分双列图混排,每行两个等大的正方形图,最多可排布三行,即六张图。
    - trisect:等分三列图混排,每行三个等大的正方形图,最多可排布三行,即九张图。
    **注意**:
    - 若上传的图片数量超过混排方式可容纳的上限,则系统将根据图片上传的顺序,优先展示排列顺序中靠前的图片。超出上限的图片将不再显示。
    - 若上传的图片数量未达到混排方式可容纳的上限,则未排布的部分将保留空白。 +combination_transparent | 否 | Boolean | false | 是否为透明底色。默认为 false,即图片为白色底色。 +corner_radius | 否 | String | / | 多图混排图片的圆角半径,单位是像素(px)。取值遵循以下格式:
    - [0,∞]px
    - [0,100]% +img_list | 是 | Object | 空 | 图片资源的 `img_key` 数组,顺序与图片排列顺序一致。 +└ img_key | 是 | String | / | 图片资源的 Key。你可以调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口或在搭建工具中上传图片,获取图片的 key。 + +## 示例代码 + +### 双图混排效果示例 + +将以下示例代码中的 `img_key` 替换为实际的图片 Key,即可实现如下图示例的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/8a03a4edd6a0813bced92cd383061ab8_6AePbfDCGW.png?height=506&lazyload=true&maxWidth=400&width=1081) + +```json +{ + "schema": "2.0", + "body": { + "direction": "vertical", + "padding": "12px 12px 12px 12px", + "elements": [ + { + "tag": "img_combination", + "combination_mode": "double", + "img_list": [ + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg" + }, + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg" + } + ], + "combination_transparent": false, + "margin": "0px 0px 0px 0px" + } + ] + } +} +``` + +### 三图混排效果示例 + +将以下示例代码中的 `img_key` 替换为实际的图片 Key,即可实现如下图示例的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/fb315779524d13ae504b7b7252acfd49_cQR9wIHOXZ.png?height=390&lazyload=true&maxWidth=400&width=559) + +```json +{ + "schema": "2.0", + "body": { + "direction": "vertical", + "padding": "12px 12px 12px 12px", + "elements": [ + { + "tag": "img_combination", + "combination_mode": "triple", + "img_list": [ + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg" + }, + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg" + }, + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg" + } + ], + "combination_transparent": false, + "margin": "0px 0px 0px 0px" + } + ] + } +} +``` + +### **等分双列效果示例** + +将以下示例代码中的 `img_key` 替换为实际的图片 Key,即可实现如下图示例的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/02236d7183ff1ca900ffc37dbec338dc_FpogForok4.png?height=819&lazyload=true&maxWidth=300&width=559) + +```json +{ + "schema": "2.0", + "body": { + "direction": "vertical", + "padding": "12px 12px 12px 12px", + "elements": [ + { + "tag": "img_combination", + "combination_mode": "bisect", + "img_list": [ + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg" + }, + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg" + }, + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg" + }, + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg" + }, + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg" + }, + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg" + } + ], + "combination_transparent": false, + "margin": "0px 0px 0px 0px" + } + ] + } +} +``` + +### 等分三列效果示例 + +将以下示例代码中的 `img_key` 替换为实际的图片 Key,即可实现如下图示例的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/7473f1d9907913c279f796e6022f7a95_Z5qFUWHIbL.png?height=212&lazyload=true&maxWidth=400&width=559) +```json +{ + "schema": "2.0", + "body": { + "direction": "vertical", + "padding": "12px 12px 12px 12px", + "elements": [ + { + "tag": "img_combination", + "combination_mode": "trisect", + "img_list": [ + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg" + }, + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg" + }, + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg" + }, + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg" + }, + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg" + }, + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg" + }, + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg" + }, + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg" + }, + { + "img_key": "img_v2_9dd98485-2900-4d65-ada9-e31d1408dcfg" + } + ], + "combination_transparent": false, + "margin": "0px 0px 0px 0px" + } + ] + } +} +``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__plain-text.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__plain-text.md new file mode 100644 index 0000000..aa16d12 --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__plain-text.md @@ -0,0 +1,155 @@ +# 普通文本组件 + +卡片的普通文本组件支持添加普通文本和前缀图标,并设置文本大小、颜色、对齐方式等展示样式。 + +本文档介绍普通文本组件的 JSON 2.0 结构,要查看历史 JSON 1.0 结构,参考[普通文本](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/plain-text)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/d44aee0423f960d0aeb0a309769e9cf1_LIYjk3GZZB.png?height=168&lazyload=true&maxWidth=400&width=559) + +## JSON 结构 + +普通文本组件的完整 JSON 2.0 结构如下所示: +```json +{ + "schema": "2.0", // 卡片 JSON 结构的版本。默认为 1.0。要使用 JSON 2.0 结构,必须显示声明 2.0。 + "body": { + "elements": [ + { + "tag": "div", + "element_id": "custom_id", // 操作组件的唯一标识。JSON 2.0 新增属性。用于在调用组件相关接口中指定组件。需开发者自定义。 + "margin": "0px 0px 0px 0px", // 组件的外边距,默认值 "0"。JSON 2.0 新增属性。支持范围 [-99,99]px。 + "width": "fill", // 文本宽度。JSON 2.0 新增属性。支持 "fill"、"auto"、"[16,999]px"。默认值为 fill。 + "text": { // 配置普通文本信息。 + "tag": "plain_text", // 文本类型的标签。可取值:plain_text 和 lark_md。 + "element_id": "custom_id", // 普通文本元素的 ID。JSON 2.0 新增属性。在调用流式更新文本接口时,需传入该参数值指定要流式更新的文本内容。 + "content": "", // 文本内容。当 tag 为 lark_md 时,支持部分 Markdown 语法的文本内容。 + "text_size": "normal", // 文本大小。默认值 normal。支持自定义在移动端和桌面端的不同字号。 + "text_color": "default", // 文本颜色。仅在 tag 为 plain_text 时生效。默认值 default。 + "text_align": "left", // 文本对齐方式。默认值 left。 + "lines": 2 // 内容最大显示行数,超出设置行的内容用 ... 省略。 + }, + "icon": { + // 前缀图标。 + "tag": "standard_icon", // 图标类型。 + "token": "chat-forbidden_outlined", // 图标的 token。仅在 tag 为 standard_icon 时生效。 + "color": "orange", // 图标颜色。仅在 tag 为 standard_icon 时生效。 + "img_key": "img_v2_38811724" // 图片的 key。仅在 tag 为 custom_icon 时生效。 + } + } + ] + } +} +``` + +## 字段说明 + +普通文本组件的字段说明如下表。 + +名称 | 必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | String | / | 组件的标签。普通文本组件的标签为 `div`。 +element_id | 否 | String | 空 | 操作组件的唯一标识。用于在调用[组件相关接口](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/create)中指定组件。在同一张卡片内,该字段的值全局唯一。仅允许使用字母、数字和下划线,必须以字母开头,不得超过 20 字符。 +margin | 否 | String | 0 | 组件的外边距。JSON 2.0 新增属性。值的取值范围为 [-99,99]px。可选值:
    - 单值,如 "10px",表示组件的四个外边距都为 10 px。
    - 双值,如 "4px 0",表示组件的上下外边距为 4 px,左右外边距为 0 px。使用空格间隔(边距为 0 时可不加单位)。
    - 多值,如 "4px 0 4px 0",表示组件的上、右、下、左的外边距分别为 4px,12px,4px,12px。使用空格间隔。 +width | 否 | String | fill | 文本的宽度。JSON 2.0 新增属性。可取值:
    - fill:文本的宽度将与组件宽度一致,撑满组件。
    - auto:文本的宽度自适应文本内容本身的长度。
    - [16,999]px:自定义文本宽度。 +text | 否 | Object | / | 配置卡片的普通文本信息。 +└ tag | 是 | String | plain_text | 文本类型的标签。可取值:
    - `plain_text`:普通文本内容或[表情](https://www.feishu.cn/docx/doxcnG6utI72jB4eHJF1s5IgVJf)
    - `lark_md`:支持部分 Markdown 语法的文本内容。详情参考下文 **lark_md 支持的 Markdown 语法**
    **注意**:飞书卡片搭建工具中仅支持使用 `plain_text` 类型的普通文本组件。你可使用富文本组件添加 Markdown 格式的文本。 +└ element_id | 否 | String | 空 | 普通文本元素的 ID。JSON 2.0 新增属性。在调用[流式更新文本](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/content)接口时,需传入该参数值指定要流式更新的文本内容。在同一张卡片内,该字段的值全局唯一。仅允许使用字母、数字和下划线,必须以字母开头,不得超过 20 字符。 +└ content | 是 | String | / | 文本内容。当 `tag` 为 `lark_md` 时,支持部分 Markdown 语法的文本内容。详情参考下文 **lark_md 支持的 Markdown 语法**。 +└ text_size | 否 | String | normal | 文本大小。可取值如下所示。如果你填写了其它值,卡片将展示为 `normal` 字段对应的字号。你也可分别为移动端和桌面端定义不同的字号,详细步骤参考下文 **为移动端和桌面端定义不同的字号**。
    - heading-0:特大标题(30px)
    - heading-1:一级标题(24px)
    - heading-2:二级标题(20 px)
    - heading-3:三级标题(18px)
    - heading-4:四级标题(16px)
    - heading:标题(16px)
    - normal:正文(14px)
    - notation:辅助信息(12px)
    - xxxx-large:30px
    - xxx-large:24px
    - xx-large:20px
    - x-large:18px
    - large:16px
    - medium:14px
    - small:12px
    - x-small:10px +└ text_color | 否 | String | default | 文本的颜色。仅在 `tag` 为 `plain_text` 时生效。可取值:
    - `default`:客户端浅色主题模式下为黑色;客户端深色主题模式下为白色
    - 颜色的枚举值。详情参考[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color) +└ text_align | 否 | String | left | 文本对齐方式。可取值:
    - `left`:左对齐
    - `center`:居中对齐
    - `right`:右对齐 +└ lines | 否 | Int | / | 内容最大显示行数,超出设置行的内容用 `...` 省略。 +icon | 否 | Object | / | 添加图标作为文本前缀图标。支持自定义或使用图标库中的图标。 +└ tag | 否 | String | / | 图标类型的标签。可取值:
    - `standard_icon`:使用图标库中的图标。
    - `custom_icon`:使用用自定义图片作为图标。 +└ token | 否 | String | / | 图标库中图标的 token。当 `tag` 为 `standard_icon` 时生效。枚举值参见[图标库](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-icons)。 +└ color | 否 | String | / | 图标的颜色。支持设置线性和面性图标(即 token 末尾为 `outlined` 或 `filled` 的图标)的颜色。当 `tag` 为 `standard_icon` 时生效。枚举值参见[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。 +└ img_key | 否 | String | / | 自定义前缀图标的图片 key。当 `tag` 为 `custom_icon` 时生效。
    图标 key 的获取方式:调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口,上传用于发送消息的图片,并在返回值中获取图片的 image_key。 +## 示例代码
    ### `plain_text` 类型示例
    以下 JSON 2.0 结构的示例代码可实现如下图所示的卡片效果:
    ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/2ae341e32cc2786194c2e6d261862879_Lm2WFn53rr.png?height=84&lazyload=true&maxWidth=400&width=619)
    ```json
    {
    "schema": "2.0",
    "body": {
    "elements": [
    {
    "tag": "div",
    "element_id": "div01",
    "text": {
    "tag": "plain_text",
    "element_id": "plaintext01",
    "content": "这是示例文本。",
    "text_size": "normal",
    "text_align": "center",
    "text_color": "default"
    },
    "icon": {
    "tag": "standard_icon",
    "token": "reply-cn_filled",
    "color": "blue"
    },
    "margin": "0px 0px 0px 0px"
    }
    ]
    }
    }
    ```
    ### `lark_md` 类型示例
    以下 JSON 2.0 结构的示例代码可实现如下图所示的卡片效果:
    ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/caa68445ea80a561def27685da307427_CeCKgmYYAI.png?height=311&lazyload=true&maxWidth=400&width=618)
    ```json
    {
    "schema": "2.0",
    "body": {
    "elements": [
    {
    "tag": "div",
    "text": {
    "tag": "plain_text",
    "content": "text-lark_md",
    "lines": 1
    },
    "fields": [
    {
    "is_short": false,
    "text": {
    "tag": "lark_md",
    "content": "https://open.feishu.cn"
    }
    },
    {
    "is_short": false,
    "text": {
    "tag": "lark_md",
    "content": "ready\nnew line"
    }
    },
    {
    "is_short": false,
    "text": {
    "tag": "lark_md",
    "content": "*Italic*"
    }
    },
    {
    "is_short": false,
    "text": {
    "tag": "lark_md",
    "content": "**Bold**"
    }
    },
    {
    "is_short": false,
    "text": {
    "tag": "lark_md",
    "content": "~~delete line~~"
    }
    },
    {
    "is_short": false,
    "text": {
    "tag": "lark_md",
    "content": ""
    }
    }
    ]
    }
    ]
    }
    }
    ```
    ## `lark_md` 支持的 Markdown 语法
    能力 | 语法 | 效果 +换行 | 第一行\n第二行 | 第一行
    第二行 +斜体 | `*斜体*` | *斜体* +粗体 | `**粗体**` 或 `__粗体__` | **粗体** +删除线 | `~~删除线~~` | ~~删除线~~ +文字链接 | `[文字链接](https://www.feishu.cn)` | [文字链接](https://www.feishu.cn) +超链接 | `<a href='https://open.feishu.cn'></a>` | [https://open.feishu.cn](https://open.feishu.cn/) +@ 人 | <at id=all>
    </at>
    <at id={{open_id}}></at>
    <at id={{user_id}}></at>
    <at email=test@email.com></at>
    提示:了解如何获取 open_id 或 user_id,参考[如何获取不同的用户 ID](https://open.feishu.cn/document/home/user-identity-introduction/open-id)。 | @所有人
    @test +彩色文本 | <font color=red>红色</font>
    **提示**:要查看 color 枚举,参考[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。 | 红色 +emoji | 😁😢🌞💼🏆❌✅
    **提示**:直接复制表情即可。了解更多 emoji 表情,参考 [Emoji 表情符号大全](https://www.feishu.cn/docx/doxcnG6utI72jB4eHJF1s5IgVJf)。 | 😁😢🌞💼🏆❌✅ +飞书表情 | :OK:
    **提示**:要查看表情枚举,参考[表情文案说明](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message-reaction/emojis-introduce)。 | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/14a7a076d1d02dc352915bf678f3f785_igT4IyBu6v.png?height=44&lazyload=true&width=54) +标签 | `<text_tag color='neutral'> neutral </text_tag>`
    color 的枚举值有:neutral、blue、turquoise、lime、orange、violet、indigo、wathet、green、yellow、red、purple、carmine | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/7f37d9bde5afa05511fce58f5fa8cab9_NGDoGSFVdr.png?height=646&lazyload=true&maxWidth=88&width=188) + +## 为移动端和桌面端定义不同的字号 + +在普通文本和富文本组件的表头文本中,你可通过配置 `text_size` 为同一段文本定义在移动端和桌面端的不同字号。相关字段描述如下表所示。 + +字段 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +text_size | 否 | Object | / | 文本大小。你可在此自定义移动端和桌面端的不同字号。 +└ custom_text_size_name | 否 | Object | / | 自定义的字号。你需自定义该字段的名称,如 `cus-0`、`cus-1` 等。 +└└ default | 否 | String | / | 在无法差异化配置字号的旧版飞书客户端上,生效的字号属性。建议填写此字段。可取值如下所示。
    - heading-0:特大标题(30px)
    - heading-1:一级标题(24px)
    - heading-2:二级标题(20 px)
    - heading-3:三级标题(18px)
    - heading-4:四级标题(16px)
    - heading:标题(16px)
    - normal:正文(14px)
    - notation:辅助信息(12px)
    - xxxx-large:30px
    - xxx-large:24px
    - xx-large:20px
    - x-large:18px
    - large:16px
    - medium:14px
    - small:12px
    - x-small:10px +└└ pc | 否 | String | / | 桌面端的字号。可取值如下所示。
    - heading-0:特大标题(30px)
    - heading-1:一级标题(24px)
    - heading-2:二级标题(20 px)
    - heading-3:三级标题(18px)
    - heading-4:四级标题(16px)
    - heading:标题(16px)
    - normal:正文(14px)
    - notation:辅助信息(12px)
    - xxxx-large:30px
    - xxx-large:24px
    - xx-large:20px
    - x-large:18px
    - large:16px
    - medium:14px
    - small:12px
    - x-small:10px +└└ mobile | 否 | String | / | 移动端的文本字号。可取值如下所示。
    **注意**:部分移动端的字号枚举值的具体大小与 PC 端有差异,使用时请注意区分。
    - heading-0:特大标题(26px)
    - heading-1:一级标题(24px)
    - heading-2:二级标题(20 px)
    - heading-3:三级标题(17px)
    - heading-4:四级标题(16px)
    - heading:标题(16px)
    - normal:正文(14px)
    - notation:辅助信息(12px)
    - xxxx-large:26px
    - xxx-large:24px
    - xx-large:20px
    - x-large:18px
    - large:17px
    - medium:14px
    - small:12px
    - x-small:10px + +具体步骤如下所示。 +1. 在卡片 JSON 代码的全局行为设置中的 `config` 字段中,配置 `style` 字段,并添加自定义字号: + +```json + { + "config": { + "style": { // 在此添加并配置 style 字段。 + "text_size": { // 分别为移动端和桌面端添加自定义字号,同时添加兜底字号。用于在组件 JSON 中设置字号属性。支持添加多个自定义字号对象。 + "cus-0": { + "default": "medium", // 在无法差异化配置字号的旧版飞书客户端上,生效的字号属性。选填。 + "pc": "medium", // 桌面端的字号。 + "mobile": "large" // 移动端的字号。 + }, + "cus-1": { + "default": "medium", // 在无法差异化配置字号的旧版飞书客户端上,生效的字号属性。选填。 + "pc": "normal", // 桌面端的字号。 + "mobile": "x-large" // 移动端的字号。 + } + } + } + } + } + ``` +1. 在普通文本组件或富文本组件的 `text_size` 属性中,应用自定义字号。以下为在普通文本组件中应用自定义字号的示例: + +```json + { + "i18n_elements": { + "zh_cn": [ + { + "tag": "column_set", + "flex_mode": "none", + "horizontal_spacing": "default", + "background_style": "default", + "columns": [ + { + "tag": "column", + "elements": [ + { + "tag": "div", + "text": { + "tag": "plain_text", + "content": "这是一段普通文本示例。", + "text_size": "cus-0", // 在此处应用自定义字号。 + "text_align": "center", + "text_color": "default" + }, + "icon": { + "tag": "standard_icon", + "token": "app-default_filled", + "color": "blue" + } + } + ], + "width": "weighted", + "weight": 1 + } + ] + } + ] + }, + "i18n_header": {} + } + ``` diff --git a/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__rich-text.md b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__rich-text.md new file mode 100644 index 0000000..0dfd43e --- /dev/null +++ b/embedded-skills/lark-card-designer/docs/raw/feishu-cards__card-json-v2-components__content-components__rich-text.md @@ -0,0 +1,482 @@ +# 富文本组件 + +JSON 2.0 结构卡片的富文本(Markdown)组件支持渲染标题、表情、表格、图片、代码块、分割线等元素。 +**注意事项**:本文档介绍富文本组件的 JSON 2.0 结构,要查看历史 JSON 1.0 结构,参考[富文本(Markdown)](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components/content-components/rich-text)。 + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/e8b73582a4505b5d1e4b0a707aa41aa6_rrzqrVZJsX.png?height=653&lazyload=true&maxWidth=300&width=614) + +## 注意事项 +富文本 JSON 2.0 结构不再支持以下差异化跳转语法。你可使用含图标的链接语法(``)替代,如: +`差异化链接`。 +```json +{ + "tag": "markdown", + "href": { + "urlVal": { + "url": "xxx", + "pc_url":"xxx", + "ios_url": "xxx", + "android_url": "xxx" + } + }, + "content": + "[差异化跳转]($urlVal)" +} +``` + +## 组件属性 + +### JSON 结构 + +富文本组件的完整 JSON 2.0 结构如下所示: +```json +{ + "schema": "2.0", // 卡片 JSON 结构的版本。默认为 1.0。要使用 JSON 2.0 结构,必须显示声明 2.0。 + "body": { + "elements": [ + { + "tag": "markdown", + "element_id": "custom_id", // 操作组件的唯一标识。JSON 2.0 新增属性。用于在调用组件相关接口中指定组件。需开发者自定义。 + "margin": "0px 0px 0px 0px", // 组件的外边距,JSON 2.0 新增属性。默认值 "0",支持范围 [-99,99]px。 + "content": "人员", // 采用 mardown 语法编写的内容。2.0 结构不再支持 "[差异化跳转]($urlVal)" 语法 + "text_size": "normal", // 文本大小。默认值 normal。支持自定义在移动端和桌面端的不同字号。 + "text_align": "left", // 文本对齐方式。默认值 left。 + "icon": { + // 前缀图标。 + "tag": "standard_icon", // 图标类型。 + "token": "chat-forbidden_outlined", // 图标的 token。仅在 tag 为 standard_icon 时生效。 + "color": "orange", // 图标颜色。仅在 tag 为 standard_icon 时生效。 + "img_key": "img_v2_38811724" // 图片的 key。仅在 tag 为 custom_icon 时生效。 + } + } + ] + } +} +``` + +### 字段说明 + +富文本组件包含的参数说明如下表所示。 + +字段名称 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +tag | 是 | String | / | 组件的标签。富文本组件固定取值为 `markdown`。 +element_id | 否 | String | 空 | 操作组件的唯一标识。JSON 2.0 新增属性。用于在调用[组件相关接口](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/cardkit-v1/card-element/create)中指定组件。在同一张卡片内,该字段的值全局唯一。仅允许使用字母、数字和下划线,必须以字母开头,不得超过 20 字符。 +margin | 否 | String | 0 | 组件的外边距。JSON 2.0 新增属性。值的取值范围为 [-99,99]px。可选值:
    - 单值,如 "10px",表示组件的四个外边距都为 10 px。
    - 双值,如 "4px 0",表示组件的上下外边距为 4 px,左右外边距为 0 px。使用空格间隔(边距为 0 时可不加单位)。
    - 多值,如 "4px 0 4px 0",表示组件的上、右、下、左的外边距分别为 4px,12px,4px,12px。使用空格间隔。 +text_align | 否 | String | left | 设置文本内容的对齐方式。可取值有:
    * left:左对齐
    * center:居中对齐
    * right:右对齐 +text_size | 否 | String | normal | 文本大小。可取值如下所示。如果你填写了其它值,卡片将展示为 `normal` 字段对应的字号。
    - heading-0:特大标题(30px)
    - heading-1:一级标题(24px)
    - heading-2:二级标题(20 px)
    - heading-3:三级标题(18px)
    - heading-4:四级标题(16px)
    - heading:标题(16px)
    - normal:正文(14px)
    - notation:辅助信息(12px)
    - xxxx-large:30px
    - xxx-large:24px
    - xx-large:20px
    - x-large:18px
    - large:16px
    - medium:14px
    - small:12px
    - x-small:10px +icon | 否 | Object | / | 添加图标作为文本前缀图标。支持自定义或使用图标库中的图标。 +└ tag | 否 | String | / | 图标类型的标签。可取值:
    - `standard_icon`:使用图标库中的图标。
    - `custom_icon`:使用用自定义图片作为图标。 +└ token | 否 | String | / | 图标库中图标的 token。当 `tag` 为 `standard_icon` 时生效。枚举值参见[图标库](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-icons)。 +└ color | 否 | String | / | 图标的颜色。支持设置线性和面性图标(即 token 末尾为 `outlined` 或 `filled` 的图标)的颜色。当 `tag` 为 `standard_icon` 时生效。枚举值参见[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)。 +└ img_key | 否 | String | / | 自定义前缀图标的图片 key。当 `tag` 为 `custom_icon` 时生效。
    图标 key 的获取方式:调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口,上传用于发送消息的图片,并在返回值中获取图片的 image_key。 +content | 是 | String | / | Markdown 文本内容。了解支持的语法,参考下文。 + +### Demo 示例 + +以下 JSON 2.0 结构的示例代码可实现如下图所示的卡片效果: + +![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/e8b73582a4505b5d1e4b0a707aa41aa6_7srlrpdZna.png?height=653&lazyload=true&maxWidth=300&width=614) + +```json +{ + "schema": "2.0", + "body": { + "elements": [ + { + "tag": "markdown", + "content": "# 一级标题", + "margin": "0px 0px 0px 0px", + "text_align": "left", + "text_size": "normal" + }, + { + "tag": "markdown", + "content": "标准emoji 😁😢🌞💼🏆❌✅\n飞书emoji :OK::THUMBSUP:\n*斜体* **粗体** ~~删除线~~ \n这是红色文本<\/font>\n标签<\/text_tag>\n[文字链接](https:\/\/open.feishu.cn\/document\/server-docs\/im-v1\/message-reaction\/emojis-introduce)\n带图标的链接<\/link>\n<\/at>\n- 无序列表1\n - 无序列表 1.1\n- 无序列表2\n1. 有序列表1\n 1. 有序列表 1.1\n2. 有序列表2\n```JSON\n{\"This is\": \"JSON demo\"}\n```" + }, + { + "tag": "markdown", + "content": "行内引用`code`" + }, + { + "tag": "markdown", + "content": "数字角标,支持 1-99 数字1" + }, + { + "tag": "markdown", + "content": "默认数字角标展示1" + }, + { + "tag": "markdown", + "content": "人员" + }, + { + "tag": "markdown", + "content": "> 这是一段引用文字\n引用内换行 \n" + } + ] + } +} +``` + +## 支持的 Markdown 语法 + +[卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)支持除 `HTMLBlock` 外所有标准的 Markdown 语法和部分 HTML 语法。了解 Markdown 标准语法,请参考 [CommonMark Spec 官方文档](https://spec.commonmark.org/0.31.2/)。你也可以使用 [CommonMark playground](https://spec.commonmark.org/dingus/) 预览 Markdown 效果。 + +注意,在卡片的富文本组件中,以下语法的渲染效果与 CommonMark 有差异: + +- 富文本组件支持使用一个 Enter 键作为软换行(Soft Break);支持两个 Enter 键作为硬换行(Hard Break)。软换行在渲染时可能会被忽略,具体取决于渲染器如何处理;硬换行在渲染时始终会显示为一个新行。 + +- 2.0 结构支持以下 HTML 语法: + - 开标签 `
    ` + - 自闭合标签 `
    ` + - 开标签 `
    ` + - 自闭合标签 `
    ` + - 闭合标签 `` + - 闭合标签 `` + - 闭合标签 `` + - 闭合标签 `` + - 闭合标签 `` + - 闭合标签 `` + - 闭合标签 `` + - 闭合标签 ``,支持嵌套其它标签,如 `redgreenagain`。其它标签包括: + - 闭合标签 `` + - 闭合标签 `` + - 闭合标签 `` + - 闭合标签 `` + - 闭合标签 `` + +以下是一些常见的渲染效果及其对应的 Markdown 或 HTML 语法。 + +名称 | 语法 | 效果 | 注意事项 +---|---|---|--- +换行 | ```
    第一行
    第二行
    第一行
    第二行
    ``` | 第一行
    第二行 | - 如果你使用卡片 JSON 构建卡片,也可使用字符串的换行语法 `\n` 换行。
    - 如果你使用卡片搭建工具构建卡片,也可使用回车键换行。 +斜体 | ```
    *斜体*
    ``` | *斜体* | 无 +加粗 | ```
    **粗体**

    __粗体__
    ``` | __粗体__ | - 不要连续使用 4 个 `*` 或 `_` 加粗。该语法不规范,可能会导致渲染不正确。
    - 若加粗效果未显示,请确保加粗语法前后保留一个空格。 +删除线 | ```
    ~~删除线~~
    ``` | ~~删除线~~ | 无 +@指定人 | ```




    ``` | @用户名 | - 该语法用于在卡片中实现 @ 人的效果,被 @ 的用户将收到提及通知。但对于转发的卡片,用户将不再收到提及通知。
    - 要在卡片中展示人员的用户名、头像、个人名片等,你可使用[人员](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/user-profile)或[人员列表](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/user-list)组件。但人员和人员列表组件仅作为展示,用户不会收到提及通知。
    - [自定义机器人](https://open.feishu.cn/document/ukTMukTMukTM/ucTM5YjL3ETO24yNxkjN)仅支持使用 `open_id`、`user_id` @指定人。
    - 支持使用 `` 传入多个 ID,使用 `,` 连接。
    - 了解如何获取 user_id、open_id,参考[如何获取不同的用户 ID](https://open.feishu.cn/document/home/user-identity-introduction/open-id)。 +@所有人 | ```

    ``` | @所有人 | @所有人需要群主开启权限。若未开启,卡片将发送失败。 +超链接 | ```


    ``` | [https://open.feishu.cn](https://open.feishu.cn) | - 超链接必须包含 schema 才能生效,目前仅支持 HTTP 和 HTTPS。
    - 超链接文本的颜色不支持自定义。 +彩色文本样式 | ```
    这是一个绿色文本
    这是一个红色文本
    这是一个灰色文本
    ``` | ![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/3cb544894ff14bd08697aba80d8e45e6~tplv-goo7wpa0wc-image.image?height=46&lazyload=true&width=206)
    ![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/20cf2f954cc34e79b1a9083ddf1c5838~tplv-goo7wpa0wc-image.image?height=46&lazyload=true&width=200)
    ![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/4c1721ac3ea6437fb52661d0f59d5b63~tplv-goo7wpa0wc-image.image?height=40&lazyload=true&width=192) | * 彩色文本样式不支持对链接中的文本生效
    * color 取值:
    - **default**:默认的白底黑字样式
    - 卡片支持的颜色枚举值和 RGBA 语法自定义颜色。参考[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color) +可点击的电话号码 | ```
    [文本展示的电话号码或其他文案内容](tel://移动端弹窗唤起的电话号码)
    ``` | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/497e911ac70982442571a2671c7c178c_5i91YqPxhx.png?height=99&lazyload=true&width=789) | 该语法仅在移动端生效。 +文字链接 | ```
    [开放平台](https://open.feishu.cn/)
    ``` | [开放平台](https://open.feishu.cn/) | 超链接必须包含 schema 才能生效,目前仅支持 HTTP 和 HTTPS。 +差异化跳转链接 | ```
    {
    "tag": "markdown",
    "href": {
    "urlVal": {
    "url": "xxx",
    "pc_url":"xxx",
    "ios_url": "xxx",
    "android_url": "xxx"
    }
    },
    "content":
    "[差异化跳转]($urlVal)"
    }
    ``` | \- | * 超链接必须包含 schema 才能生效,目前仅支持 HTTP 和 HTTPS。
    - 仅在 PC 端、移动端需要跳转不同链接时使用。 +图片 | ```
    ![hover_text](image_key)
    ``` |   | * `hover_text` 指在 PC 端内光标悬浮(hover)图片所展示的文案。
    * **image_key** 可以调用[上传图片](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/image/create)接口获取。 +分割线 | ```



    ---
    ``` | ![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/337cdbabf3944d4facd505a9f9883352~tplv-goo7wpa0wc-image.image?height=62&lazyload=true&width=346) | - 推荐使用 `
    ` 语法
    - 分割线必须单独一行使用。即如果分割线前后有文本,你必须在分割线前后添加换行符。 +飞书表情 | ```
    :DONE:
    ``` | ![](https://sf3-ttcdn-tos.pstatp.com/obj/lark-reaction-cn/emoji_done.png?height=96&lazyload=true&width=96) | 支持的 Emoji Key 列表可以参看 [表情文案说明](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message-reaction/emojis-introduce)。 +标签 | ```
    标签文本
    ``` |   | `color`支持的枚举值范围包括:
    - `neutral`: 中性色
    - `blue`: 蓝色
    - `turquoise`: 青绿色
    - `lime`: 酸橙色
    - `orange`: 橙色
    - `violet`: 紫罗兰色
    - `indigo`: 靛青色
    - `wathet`: 天蓝色
    - `green`: 绿色
    - `yellow`: 黄色
    - `red`: 红色
    - `purple`: 紫色
    - `carmine`: 洋红色 +有序列表 | ```
    1. 有序列表1
    1. 有序列表 1.1
    2. 有序列表2
    ``` | 1. 有序列表1
    1. 有序列表 1.1
    2. 有序列表2 | * 序号需在行首使用
    * 4 个空格代表一层缩进 +无序列表 | ```
    - 无序列表1
    - 无序列表 1.1
    - 无序列表2
    ```
    在卡片 JSON 中,需添加 `\n` 换行符:
    ```
    \n- 无序列表1\n - 无序列表 1.1\n- 无序列表2\n1. 有序列表1\n
    ``` | - 无序列表1
    - 无序列表 1.1
    - 无序列表2 | * 序号需在行首使用
    * 4 个空格代表一层缩进 +代码块 | `````markdown
    ```JSON
    {"This is": "JSON demo"}
    ```
    ````` | ```JSON
    {"This is": "JSON demo"}
    ``` | * 代码块语法和代码内容需在行首使用
    * 支持指定编程语言解析。未指定默认为 Plain Text
    - 四个及以上空格([缩进式代码块语法](https://spec.commonmark.org/0.30/#indented-code-blocks))也将触发代码块效果 +含图标的链接 | ```
    战略研讨会
    ``` | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/e6b63f8c225ce6c4cd09dbdc8158397f_HPk70nRLtr.png?height=97&lazyload=true&width=736) | 该语法中的字段说明如下所示:
    - `icon`:链接前缀的图标。仅支持图标库中的图标,枚举值参见[图标库](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-icons)。图标颜色固定为蓝色。可选。
    - `url`:默认的链接地址,未按设备配置下述字段时,该配置生效。必填。
    - `pc_url`:pc 端的链接地址,优先级高于 `url`。可选。
    - `ios_url`:ios 端的链接地址,优先级高于 `url`。可选。
    - `android_url`:android 端的链接地址,优先级高于 `url`。可选。 +人员 | `````markdown

    ````` | ![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/85c9e79807d0195cd3ecb331a965f418_eFVjQrqRjv.png?height=95&lazyload=true&width=736) | 该语法中的字段说明如下所示:
    - `id`:用户的 ID,支持 open_id、union_id 和 user_id。不填、为空、数据错误时展示为兜底的“未知用户”样式。了解更多,参考[如何获取不同的用户 ID](https://open.feishu.cn/document/home/user-identity-introduction/open-id)。
    - `show_name`:是否展示用户名。默认为 true。
    - `show_avatar`:是否展示用户头像,默认为 true。
    - `style`:人员组件的展示样式。可选值有:
    - `normal`:普通样式(默认)
    - `capsule`:胶囊样式 +标题 | ```
    # 一级标题
    ## 二级标题
    ###### 六级标题
    ``` | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/9f20da4d88e999dd95fb3afa7e7c178e_QzyatvgRcl.png?height=113&lazyload=true&width=725) | 支持一级到 6 级标题。从一级到六级的字号梯度为 26, 22 , 20, 18, 17, 14px。 +引用 | ```
    >[空格]这是一段引用文字\n引用内换行
    ``` | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/3551041c80d4879301b805e1c78d5c0d_OrdqP5rWoe.png?height=84&lazyload=true&width=209) |   +行内引用 | ```
    `code`
    ``` | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/b89bc8e45736ed3d48707591cb109383_TBPlo20031.png?height=48&lazyload=true&width=104) |   +表格 | ```
    | Syntax | Description |
    | -------- | -------- |
    | Paragraph | Text |
    | Paragraph | Text |
    | Paragraph | Text |
    | Paragraph | Text |
    | Paragraph | Text |
    | Paragraph | Text |
    ``` | ![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/8f518b1bfa0e2f217893c379d4c5e07a_6SH7H9f5ew.png?height=411&lazyload=true&maxWidth=200&width=882) | - 除标题行外,最多展示五行数据,超出五行将分页展示。不支持自定义。
    - 该语法仅支持 JSON 2.0 结构。
    - 单个富文本组件中,最多可放置四个表格。
    - 表格的富文本语法不支持设置列宽等。要设置列宽、数据对齐方式等,可使用[表格](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/table)组件。 +数字角标 | `````markdown
    1
    `````
    `````markdown
    1````` | ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/d97f3d4f1c0e73bb5fb7a267b1a4ecf7_tLSJTnxEsn.png?height=45&lazyload=true&width=141) | 数字圆形角标,支持添加 0-99 之间的数字。该语法中的字段说明如下所示:
    - `background_color`:圆圈内的背景颜色。可选。
    - `font_color`:数字颜色。可选。
    - `url`:点击角标时默认的跳转链接,未按设备配置下述字段时,该配置生效。可选。
    - `pc_url`:点击角标时 PC 端的跳转链接,优先级高于 `url`。可选。
    - `ios_url`:点击角标时 iOS 端的跳转链接,优先级高于 `url`。可选。
    - `android_url`:点击角标时 Android 端的跳转链接,优先级高于 `url`。可选。 +国际化时间 | ```

    ``` | ![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/0dd7459a8fa40a1c83e6394f2f531136_HJ5KJcYUFU.png?height=362&lazyload=true&maxWidth=200&width=685) | 国际化时间标签。支持自动展示用户当地时区下的时间。该语法中的字段说明如下所示:
    - `millisecond`:要展示的时间的 Unix 毫秒时间戳。若不填,则:
    - 对于使用卡片 JSON 发送的卡片,默认展示发送卡片时的时间
    - 对于使用搭建工具搭建的卡片,默认展示卡片发布的时间
    - `format_type`:定义时间展示的格式。默认使用数字展示,如:`2019-03-15`。枚举值如下所示:
    - `date_num`:用数字表示的日期,例如 `2019-03-15`。
    - `date_short`:不含年份的简写日期,支持多语种自动适配,例如 `3月15日`、`Mar 15`。
    - `date`:完整国际化日期文案,支持多语种自动适配,例如 `2019年3月15日`、`Mar 15, 2019`。
    - `week`:完整星期文案,支持多语种自动适配,例如 `星期二`、`Tuesday`。
    - `week_short`:简写星期文案,支持多语种自动适配,例如 `周二`、`Tue`。
    - `time`:时间(小时:分钟)文案,例如 `13:42`。
    - `time_sec`:时间(小时:分钟:秒)文案,例如 `13:42:53`。
    - `timezone`:设备所属时区,格式为 `GMT±hh:mm`,例如 `GMT+8:00`。
    - `link`:点击该时间时跳转的链接地址。 +音频 | ```

    ```
    参考本文末尾了解音频语法使用示例。 | - style 为 normal 时:
    ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/c3911916d8534552e41f2c39cfed2f70_6yFptFISbo.png?height=130&lazyload=true&maxWidth=100&width=384)
    - style 为 speak 时:
    ![](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/e73b0599063b809363aa3d433b17530f_wSGfHVe0q3.png?height=120&lazyload=true&maxWidth=100&width=354) | 富文本内嵌音频播放器。该语法中的字段说明如下所示:
    - `file_key`:音频文件 key,需通过[上传文件](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/file/create)获取。详情参考[音频](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/audio)组件。必填。
    - `audio_id`:音频实例唯一标识,使用方式同[音频](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/audio)组件。可选。
    - `show_time`:是否显示时长。可选,默认值为 false。
    - `style`:音频样式。可选,支持以下值:
    - `normal`:默认值,三角形播放按钮样式
    - `speak`:语音样式
    - `background_color`:组件背景颜色。可选。支持 default、[颜色枚举值](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/enumerations-for-fields-related-to-color)和 RGBA 语法自定义颜色。
    - `fill_color`:图标和时间颜色。可选。支持颜色枚举值和 RGBA 语法自定义颜色。
    - `fallback_text`:在低于飞书 V7.49.0 版本客户端上,音频播放器将展示为文字链接。你可设置文本和 URL,引导用户点击链接访问音频。该字段指定显示文本。可选。若不指定,则低版本客户端展示时将丢弃该组件。
    - `fallback_url`:在低于飞书 V7.49.0 版本客户端上,音频播放器将展示为文字链接。你可设置文本和 URL,引导用户点击链接访问音频。该字段指定文字链接的兜底 URL。若指定`fallback_text`,则必须指定 `fallback_url`。
    - `fallback_pc_url`:为 PC 端低版本客户端上的音频播放器额外指定 URL,可选。优先级高于兜底的 `fallback_url`。
    - `fallback_ios_url`:为 iOS 端低版本客户端上的音频播放器额外指定 URL,可选。优先级高于兜底的 `fallback_url`。
    - `fallback_android_url`:为 Android 端低版本客户端上的音频播放器额外指定 URL,可选。优先级高于兜底的 `fallback_url`。
    - `fallback_harmony_url`:为原生鸿蒙端低版本客户端上的音频播放器额外指定 URL,可选。优先级高于兜底的 `fallback_url`。 + +### 特殊字符转义说明 +如果要展示的字符命中了 markdown 语法使用的特殊字符(例如 `*、~、>、<` 这些特殊符号),需要对特殊字符进行 HTML 转义,才可正常展示。常见的转义符号对照表如下所示。查看更多转义符,参考 [HTML 转义通用标准](https://www.w3school.com.cn/charsets/ref_html_8859.asp)实现,转义后的格式为 `&#实体编号;`。 + +| **特殊字符** | **转义符** | **描述** | +| --- | --- | --- | +| ` ` | `  ` | 不换行空格 | +| ` ` | ` ` | 半角空格 | +| ` ` | ` ` | 全角空格 | +| `>` | `>` | 大于号 | +| `<` | `<` | 小于号 | +| `~` | `∼` | 飘号 | +| `-` | `-` | 连字符 | +| `!` | `!` | 惊叹号 | +| `*` | `*` | 星号 | +| `/` | `/` | 斜杠 | +| `\` | `\` | 反斜杠 | +| `[` | `[` | 中括号左边部分 | +| `]` | `]` | 中括号右边部分 | +| `(` | `(` | 小括号左边部分 | +| `)` | `)` | 小括号右边部分 | +| `#` | `#` | 井号 | +| `:` | `:` | 冒号 | +| `+` | `+` | 加号 | +| `"` | `"` | 英文引号 | +| `'` | `'` | 英文单引号 | +| \` | ``` | 反单引号 | +| `$` | `$` | 美金符号 | +| `_` | `_` | 下划线 | +| `-` | `-` | 无序列表 | + +### 代码块支持的编程语言 + +富文本组件支持通过代码块语法渲染代码,支持的编程语言如下列表所示,且对大小写不敏感: +`````markdown +```JSON +{"This is": "JSON demo"} +``` +````` +- plain_text +- abap +- ada +- apache +- apex +- assembly +- bash +- c_sharp +- cpp +- c +- cmake +- cobol +- css +- coffee_script +- d +- dart +- delphi +- diff +- django +- docker_file +- erlang +- fortran +- gherkin +- go +- graphql +- groovy +- html +- htmlbars +- http +- haskell +- json +- java +- javascript +- julia +- kotlin +- latex +- lisp +- lua +- matlab +- makefile +- markdown +- nginx +- objective_c +- opengl_shading_language +- php +- perl +- powershell +- prolog +- properties +- protobuf +- python +- r +- ruby +- rust +- sas +- scss +- sql +- scala +- scheme +- shell +- solidity +- swift +- toml +- thrift +- typescript +- vbscript +- visual_basic +- xml +- yaml +## 为移动端和桌面端定义不同的字号 + +在普通文本组件和富文本组件中,你可为同一段文本定义在移动端和桌面端的不同字号。相关字段描述如下表所示。 + +字段 | 是否必填 | 类型 | 默认值 | 说明 +---|---|---|---|--- +text_size | 否 | Object | / | 文本大小。你可在此自定义移动端和桌面端的不同字号。 +└ custom_text_size_name | 否 | Object | / | 自定义的字号。你需自定义该字段的名称,如 `cus-0`、`cus-1` 等。 +└└ default | 否 | String | / | 在无法差异化配置字号的旧版飞书客户端上,生效的字号属性。建议填写此字段。可取值如下所示。
    - heading-0:特大标题(30px)
    - heading-1:一级标题(24px)
    - heading-2:二级标题(20 px)
    - heading-3:三级标题(18px)
    - heading-4:四级标题(16px)
    - heading:标题(16px)
    - normal:正文(14px)
    - notation:辅助信息(12px)
    - xxxx-large:30px
    - xxx-large:24px
    - xx-large:20px
    - x-large:18px
    - large:16px
    - medium:14px
    - small:12px
    - x-small:10px +└└ pc | 否 | String | / | 桌面端的字号。可取值如下所示。
    - heading-0:特大标题(30px)
    - heading-1:一级标题(24px)
    - heading-2:二级标题(20 px)
    - heading-3:三级标题(18px)
    - heading-4:四级标题(16px)
    - heading:标题(16px)
    - normal:正文(14px)
    - notation:辅助信息(12px)
    - xxxx-large:30px
    - xxx-large:24px
    - xx-large:20px
    - x-large:18px
    - large:16px
    - medium:14px
    - small:12px
    - x-small:10px +└└ mobile | 否 | String | / | 移动端的文本字号。可取值如下所示。
    **注意**:部分移动端的字号枚举值的具体大小与 PC 端有差异,使用时请注意区分。
    - heading-0:特大标题(26px)
    - heading-1:一级标题(24px)
    - heading-2:二级标题(20 px)
    - heading-3:三级标题(17px)
    - heading-4:四级标题(16px)
    - heading:标题(16px)
    - normal:正文(14px)
    - notation:辅助信息(12px)
    - xxxx-large:26px
    - xxx-large:24px
    - xx-large:20px
    - x-large:18px
    - large:17px
    - medium:14px
    - small:12px
    - x-small:10px + +具体步骤如下所示。 +1. 在卡片 JSON 代码的全局行为设置中的 `config` 字段中,配置 `style` 字段,并添加自定义字号: + ```json + { + "config": { + "style": { // 在此添加并配置 style 字段。 + "text_size": { // 分别为移动端和桌面端添加自定义字号,同时添加兜底字号。用于在组件 JSON 中设置字号属性。支持添加多个自定义字号对象。 + "cus-0": { + "default": "medium", // 在无法差异化配置字号的旧版飞书客户端上,生效的字号属性。选填。 + "pc": "medium", // 桌面端的字号。 + "mobile": "large" // 移动端的字号。 + }, + "cus-1": { + "default": "medium", // 在无法差异化配置字号的旧版飞书客户端上,生效的字号属性。选填。 + "pc": "normal", // 桌面端的字号。 + "mobile": "x-large" // 移动的字号。 + } + } + } + } + } + ``` +1. 在普通文本组件或富文本组件的 `text_size` 属性中,应用自定义字号。以下为在富文本组件中应用自定义字号的示例: + ```json + { + "elements": [ + { + "tag": "markdown", + "text_size": "cus-0", // 在此处应用自定义字号。 + "href": { + "urlVal": { + "url": "xxx1", + "pc_url": "xxx2", + "ios_url": "xxx3", + "android_url": "xxx4" + } + }, + "content": "普通文本\n标准emoji😁😢🌞💼🏆❌✅\n*斜体*\n**粗体**\n~~删除线~~\n文字链接\n差异化跳转\n" + }, + { + "tag": "hr" + }, + { + "tag": "markdown", + "content": "上面是一行分割线\n!hover_text\n上面是一个图片标签" + } + ], + "header": { + "template": "blue", + "title": { + "content": "这是卡片标题栏", + "tag": "plain_text" + } + } + } + ``` + +## 富文本语法使用示例 + +### 音频 + +以下富文本语法示例代码可实现如下图所示的卡片效果。请将 `file_key` 替换为实际值后再查看效果。获取音频文件 `file_key` 时,请确保调用[上传文件](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/file/create)接口的应用与发送卡片的应用一致。 + +![image.png](//sf3-cn.feishucdn.com/obj/open-platform-opendoc/8d7c3f4f3fe7f7ffe4f8f91b195a5b1b_pbRNEOkbKW.png?height=1161&lazyload=true&maxWidth=494&width=694) + +```json +{ + "schema": "2.0", + "config": { + "wide_screen_mode": true, + "enable_forward": false, + "update_multi": true, + "enable_forward_interaction": true, + "style": { + "color": { + "color_0": { + "light_mode": "rgba(20,86,240,1.000000)", + "dark_mode": "rgba(20,86,240,1.000000)" + }, + "color_1": { + "light_mode": "rgba(149,229,153,1.000000)", + "dark_mode": "rgba(149,229,153,1.000000)" + }, + "color_2": { + "light_mode": "rgba(253,198,196,1.000000)", + "dark_mode": "rgba(253,198,196,1.000000)" + } + } + } + }, + "body": { + "direction": "vertical", + "padding": "12px 12px 12px 12px", + "elements": [ + { + "tag": "markdown", + "content": "参数全默认效果示例:\n