@lark-base-open/base-database-cli 1.1.0 → 1.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +86 -0
- package/LICENSE +6 -0
- package/README.md +55 -31
- package/dist/ai-functions.d.ts +42 -0
- package/dist/ai-functions.d.ts.map +1 -0
- package/dist/ai-functions.js +327 -0
- package/dist/ai-functions.js.map +1 -0
- package/dist/archive.d.ts +21 -0
- package/dist/archive.d.ts.map +1 -1
- package/dist/archive.js +65 -10
- package/dist/archive.js.map +1 -1
- package/dist/auth.d.ts +8 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +60 -6
- package/dist/auth.js.map +1 -1
- package/dist/check.d.ts +74 -0
- package/dist/check.d.ts.map +1 -0
- package/dist/check.js +283 -0
- package/dist/check.js.map +1 -0
- package/dist/dependency-policy.d.ts +10 -0
- package/dist/dependency-policy.d.ts.map +1 -0
- package/dist/dependency-policy.js +162 -0
- package/dist/dependency-policy.js.map +1 -0
- package/dist/deploy.d.ts +1 -0
- package/dist/deploy.d.ts.map +1 -1
- package/dist/deploy.js +122 -175
- package/dist/deploy.js.map +1 -1
- package/dist/environment-variables.d.ts +52 -0
- package/dist/environment-variables.d.ts.map +1 -0
- package/dist/environment-variables.js +563 -0
- package/dist/environment-variables.js.map +1 -0
- package/dist/environment.d.ts +1 -1
- package/dist/environment.js +1 -1
- package/dist/environment.js.map +1 -1
- package/dist/function-input-types.d.ts +10 -0
- package/dist/function-input-types.d.ts.map +1 -0
- package/dist/function-input-types.js +160 -0
- package/dist/function-input-types.js.map +1 -0
- package/dist/function-schema.d.ts.map +1 -1
- package/dist/function-schema.js +89 -36
- package/dist/function-schema.js.map +1 -1
- package/dist/init-field-retry.d.ts +17 -0
- package/dist/init-field-retry.d.ts.map +1 -0
- package/dist/init-field-retry.js +127 -0
- package/dist/init-field-retry.js.map +1 -0
- package/dist/init-journal.d.ts +98 -0
- package/dist/init-journal.d.ts.map +1 -0
- package/dist/init-journal.js +492 -0
- package/dist/init-journal.js.map +1 -0
- package/dist/init-schema.d.ts +8 -0
- package/dist/init-schema.d.ts.map +1 -0
- package/dist/init-schema.js +423 -0
- package/dist/init-schema.js.map +1 -0
- package/dist/init.d.ts +14 -0
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +886 -243
- package/dist/init.js.map +1 -1
- package/dist/lark-cli-error.d.ts +46 -0
- package/dist/lark-cli-error.d.ts.map +1 -0
- package/dist/lark-cli-error.js +171 -0
- package/dist/lark-cli-error.js.map +1 -0
- package/dist/lark-cli.d.ts +2 -1
- package/dist/lark-cli.d.ts.map +1 -1
- package/dist/lark-cli.js +292 -29
- package/dist/lark-cli.js.map +1 -1
- package/dist/mutation-schema.d.ts +146 -0
- package/dist/mutation-schema.d.ts.map +1 -0
- package/dist/mutation-schema.js +153 -0
- package/dist/mutation-schema.js.map +1 -0
- package/dist/mutation.d.ts +10 -0
- package/dist/mutation.d.ts.map +1 -0
- package/dist/mutation.js +131 -0
- package/dist/mutation.js.map +1 -0
- package/dist/npm.d.ts +1 -0
- package/dist/npm.d.ts.map +1 -1
- package/dist/npm.js +2 -2
- package/dist/npm.js.map +1 -1
- package/dist/preview-receipt.d.ts.map +1 -1
- package/dist/preview-receipt.js +15 -5
- package/dist/preview-receipt.js.map +1 -1
- package/dist/process.d.ts +3 -1
- package/dist/process.d.ts.map +1 -1
- package/dist/process.js +16 -4
- package/dist/process.js.map +1 -1
- package/dist/program.d.ts.map +1 -1
- package/dist/program.js +241 -42
- package/dist/program.js.map +1 -1
- package/dist/project-build.d.ts +25 -0
- package/dist/project-build.d.ts.map +1 -0
- package/dist/project-build.js +229 -0
- package/dist/project-build.js.map +1 -0
- package/dist/project-context.d.ts +344 -0
- package/dist/project-context.d.ts.map +1 -0
- package/dist/project-context.js +485 -0
- package/dist/project-context.js.map +1 -0
- package/dist/project-layout.d.ts +5 -0
- package/dist/project-layout.d.ts.map +1 -0
- package/dist/project-layout.js +24 -0
- package/dist/project-layout.js.map +1 -0
- package/dist/public-sql-error.d.ts +25 -0
- package/dist/public-sql-error.d.ts.map +1 -0
- package/dist/public-sql-error.js +81 -0
- package/dist/public-sql-error.js.map +1 -0
- package/dist/pull.d.ts.map +1 -1
- package/dist/pull.js +54 -15
- package/dist/pull.js.map +1 -1
- package/dist/site-readme.d.ts +3 -0
- package/dist/site-readme.d.ts.map +1 -0
- package/dist/site-readme.js +83 -0
- package/dist/site-readme.js.map +1 -0
- package/dist/workspace-fingerprint.d.ts +21 -1
- package/dist/workspace-fingerprint.d.ts.map +1 -1
- package/dist/workspace-fingerprint.js +81 -2
- package/dist/workspace-fingerprint.js.map +1 -1
- package/package.json +2 -1
- package/skills/lark-base-database/SKILL.md +70 -53
- package/skills/lark-base-database/references/ai-function.md +471 -0
- package/skills/lark-base-database/references/base-capability-routing.md +3 -3
- package/skills/lark-base-database/references/database-function-limitations.md +46 -0
- package/skills/lark-base-database/references/database-function.md +349 -0
- package/skills/lark-base-database/references/design/components/actions-fields.md +16 -0
- package/skills/lark-base-database/references/design/components/code/controls.css +122 -0
- package/skills/lark-base-database/references/design/components/code/controls.tsx +73 -0
- package/skills/lark-base-database/references/design/components/code/date-picker.tsx +42 -0
- package/skills/lark-base-database/references/design/components/code/floating.tsx +41 -0
- package/skills/lark-base-database/references/design/components/code/overlays.tsx +19 -0
- package/skills/lark-base-database/references/design/components/code/select.tsx +34 -0
- package/skills/lark-base-database/references/design/components/code/styles.d.ts +1 -0
- package/skills/lark-base-database/references/design/components/code/theme.css +49 -0
- package/skills/lark-base-database/references/design/components/code/usage.tsx +38 -0
- package/skills/lark-base-database/references/design/components/date-time-number.md +9 -0
- package/skills/lark-base-database/references/design/components/feedback-navigation.md +9 -0
- package/skills/lark-base-database/references/design/components/index.md +18 -0
- package/skills/lark-base-database/references/design/components/overlays.md +9 -0
- package/skills/lark-base-database/references/design/components/patterns/flat-business.md +7 -0
- package/skills/lark-base-database/references/design/components/selection.md +24 -0
- package/skills/lark-base-database/references/design/components.md +91 -0
- package/skills/lark-base-database/references/design/composition.md +90 -0
- package/skills/lark-base-database/references/design/control-recipes.md +107 -0
- package/skills/lark-base-database/references/design/examples.md +172 -0
- package/skills/lark-base-database/references/design/foundations.md +126 -0
- package/skills/lark-base-database/references/design/review.md +82 -0
- package/skills/lark-base-database/references/design/scenes/analysis-report.md +66 -0
- package/skills/lark-base-database/references/design/scenes/brand-showcase.md +70 -0
- package/skills/lark-base-database/references/design/scenes/business-operations.md +85 -0
- package/skills/lark-base-database/references/design/scenes/campaign-report.md +66 -0
- package/skills/lark-base-database/references/design/scenes/dashboard.md +77 -0
- package/skills/lark-base-database/references/design/scenes/festive-campaign.md +69 -0
- package/skills/lark-base-database/references/design/theme.md +27 -0
- package/skills/lark-base-database/references/design/typography.md +56 -0
- package/skills/lark-base-database/references/development.md +165 -32
- package/skills/lark-base-database/references/environment-variables.md +55 -0
- package/skills/lark-base-database/references/faas.md +41 -48
- package/skills/lark-base-database/references/file-transfer.md +25 -25
- package/skills/lark-base-database/references/frontend-design-guide.md +33 -77
- package/skills/lark-base-database/references/mutations.md +295 -0
- package/skills/lark-base-database/references/permission-design.md +24 -24
- package/skills/lark-base-database/references/release.md +54 -27
- package/skills/lark-base-database/references/style-guide.md +10 -67
- package/skills/lark-base-database/references/verification.md +17 -13
- package/skills/lark-base-database/references/workspace.md +71 -22
- package/templates/database-starter/README.md +34 -4
- package/templates/database-starter/database-functions/README.md +8 -0
- package/templates/database-starter/mutations/README.md +19 -0
- package/templates/database-starter/page/README.md +25 -19
- package/templates/database-starter/page/package-lock.json +8 -16
- package/templates/database-starter/page/package.json +2 -3
- package/templates/database-starter/page/src/App.tsx +23 -3
- package/templates/database-starter/page/src/components/UserSelectorEditor/index.tsx +32 -4
- package/templates/database-starter/page/src/components/UserSelectorPanel/index.tsx +104 -34
- package/templates/database-starter/page/src/components/UserSelectorPanel/user-search.test.ts +55 -11
- package/templates/database-starter/page/src/components/UserSelectorPanel/user-search.ts +68 -25
- package/templates/database-starter/page/src/components/database-runtime-ready.tsx +1 -1
- package/templates/database-starter/page/src/components/database-user-menu/index.tsx +4 -7
- package/templates/database-starter/page/src/components/feedback/page-state.tsx +40 -5
- package/templates/database-starter/page/src/components/floating-button/assets/edit-active.svg +3 -0
- package/templates/database-starter/page/src/components/floating-button/assets/edit-default.svg +3 -0
- package/templates/database-starter/page/src/components/floating-button/index.tsx +75 -112
- package/templates/database-starter/page/src/components/floating-button/utils/project-meta.test.ts +107 -37
- package/templates/database-starter/page/src/components/floating-button/utils/project-meta.ts +13 -50
- package/templates/database-starter/page/src/components/ui-language.test.tsx +101 -0
- package/templates/database-starter/page/src/examples/ai-function/ImageTaskOperation.tsx +202 -0
- package/templates/database-starter/page/src/examples/ai-function/README.md +14 -0
- package/templates/database-starter/page/src/examples/ai-function/TextStreamOperation.tsx +184 -0
- package/templates/database-starter/page/src/examples/ai-function/ai-copy.ts +173 -0
- package/templates/database-starter/page/src/examples/ai-function/ai-delta.test.ts +30 -0
- package/templates/database-starter/page/src/examples/ai-function/ai-delta.ts +26 -0
- package/templates/database-starter/page/src/examples/ai-function/ai-language.test.tsx +86 -0
- package/templates/database-starter/page/src/examples/ai-function/ai-media-panel.test.ts +201 -0
- package/templates/database-starter/page/src/examples/ai-function/ai-media-panel.tsx +382 -0
- package/templates/database-starter/page/src/lib/attachment-image.tsx +144 -0
- package/templates/database-starter/page/src/lib/database-function-inputs.generated.ts +4 -0
- package/templates/database-starter/page/src/lib/database-runtime-attachment.test.ts +180 -76
- package/templates/database-starter/page/src/lib/database-runtime.test.ts +130 -10
- package/templates/database-starter/page/src/lib/database-runtime.ts +484 -51
- package/templates/database-starter/page/src/lib/date-time.ts +61 -0
- package/templates/database-starter/page/src/lib/ui-language.ts +86 -0
- package/templates/database-starter/page/src/main.tsx +1 -1
- package/templates/database-starter/page/tsconfig.json +2 -2
- package/templates/database-starter/page/vite.config.ts +1 -2
- package/templates/database-starter/prettierignore +1 -1
- package/templates/database-starter/server-functions/README.md +2 -2
- package/templates/database-starter/server-functions/package-lock.json +4 -4
- package/templates/database-starter/server-functions/package.json +1 -1
- package/dist/agent-guide.d.ts +0 -19
- package/dist/agent-guide.d.ts.map +0 -1
- package/dist/agent-guide.js +0 -31
- package/dist/agent-guide.js.map +0 -1
- package/dist/database-skill.d.ts +0 -24
- package/dist/database-skill.d.ts.map +0 -1
- package/dist/database-skill.js +0 -151
- package/dist/database-skill.js.map +0 -1
- package/skills/lark-base-database/references/base-sql-unsupported.md +0 -42
- package/skills/lark-base-database/references/database-capability-skill.md +0 -40
- package/skills/lark-base-database/references/sql-function.md +0 -289
- package/templates/database-capability/SKILL.md.tmpl +0 -58
- package/templates/database-starter/page/src/components/floating-button/chatbot-entry.test.ts +0 -23
- package/templates/database-starter/page/src/components/floating-button/chatbot-entry.tsx +0 -873
- package/templates/database-starter/page/src/components/floating-button/local-chat-panel.test.ts +0 -25
- package/templates/database-starter/page/src/components/floating-button/local-chat-panel.tsx +0 -197
- package/templates/database-starter/page/src/components/floating-button/utils/env.ts +0 -18
- package/templates/database-starter/sql/README.md +0 -8
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
# 文件传输
|
|
2
2
|
|
|
3
|
-
实现附件能力时,先读取操作路由和公共约束,再读取当前操作章节。本文说明 Page
|
|
3
|
+
实现附件能力时,先读取操作路由和公共约束,再读取当前操作章节。本文说明 Page 如何编排附件流程;基础挂载/移除见[Mutation 附件写入](mutations.md#附件写入),需业务校验或编排时见[FaaS 与记录协议](faas.md#应用记录-写入协议),查询类型见[Database Function](database-function.md#查询类型与结果值)。不因仅需展示附件而实现上传或写入功能。
|
|
4
4
|
|
|
5
5
|
## 操作路由
|
|
6
6
|
|
|
7
7
|
| 目标 | 入口 | 必读章节 |
|
|
8
8
|
| --- | --- | --- |
|
|
9
9
|
| 上传文件字节 | `siteRuntime.uploadAttachment()` | [上传](#上传) |
|
|
10
|
-
| 展示缩略图或大图 | `
|
|
10
|
+
| 展示缩略图或大图 | `fetchAttachmentCover(ref, size)` | [展示与下载](#展示与下载) |
|
|
11
11
|
| 下载原文件 | `fetchAttachmentDownloadUrl(context, ref)` | [展示与下载](#展示与下载) |
|
|
12
|
-
| 将新文件挂载到单元格或移除引用 |
|
|
13
|
-
| 写入超时、结果不明 | 保留 token,通过固定
|
|
12
|
+
| 将新文件挂载到单元格或移除引用 | 基础写入用 Mutation;业务校验与编排用 FaaS | [写单元格](#写单元格)和 [Mutation 附件写入](mutations.md#附件写入) |
|
|
13
|
+
| 写入超时、结果不明 | 保留 token,通过固定 Database Function 有界核对 | [超时与结果未知](#超时与结果未知) |
|
|
14
14
|
|
|
15
15
|
## 公共约束
|
|
16
16
|
|
|
17
17
|
- `file_token` 是附件资源标识,不是可直接访问的 URL,也不是登录凭证。临时下载链接携带授权信息,不持久化、不记录到日志或作为长期公开链接。
|
|
18
|
-
- 表、字段 ID 来自 Catalog;已有附件的记录 ID、FILE.
|
|
19
|
-
- 上传依赖父页面 `attachment.upload
|
|
18
|
+
- 表、字段 ID 来自 Catalog;已有附件的记录 ID、FILE.token 来自 Database Function 查询结果。上传成功返回的新 fileToken 供后续挂载使用。不能通过伪造位置声明获取其他附件。
|
|
19
|
+
- 上传依赖父页面 `attachment.upload`;Mutation 挂载依赖目标环境的附件操作和服务端增量路由,FaaS 挂载依赖对应 runtime 和服务端增量路由。更新 starter 不证明平台已开通。能力不具备时报告具体限制,按用户决定调整需求,不猜网关或回退为旧列表整格覆盖。
|
|
20
20
|
- 上传校验应用权限与绑定关系。不要要求访客取得底层 Base 权限来绕过应用链路问题。
|
|
21
21
|
- 上传成功只证明文件字节已提交,不证明附件已挂载;移除只删除单元格引用,不删除云盘文件,也不承诺释放 Base 附件计数。
|
|
22
22
|
|
|
@@ -33,7 +33,7 @@ baseToken/tableId 取自 Catalog;file 必须是 File。不传 fieldId,目标
|
|
|
33
33
|
|
|
34
34
|
### 图片宽高
|
|
35
35
|
|
|
36
|
-
图片上传前从本地 File 解码读取原始宽高,不依赖上传结果中的可选 width/height,也不使用预览元素的 CSS 尺寸。服务端不会补齐省略的宽高,
|
|
36
|
+
图片上传前从本地 File 解码读取原始宽高,不依赖上传结果中的可选 width/height,也不使用预览元素的 CSS 尺寸。服务端不会补齐省略的宽高,Database Function 也不返回旧图片宽高。
|
|
37
37
|
|
|
38
38
|
```ts
|
|
39
39
|
async function readImageDimensions(file: File) {
|
|
@@ -56,7 +56,7 @@ async function readImageDimensions(file: File) {
|
|
|
56
56
|
const dimensions = await readImageDimensions(file)
|
|
57
57
|
const uploaded = await siteRuntime.uploadAttachment({ baseToken, tableId, file, onProgress })
|
|
58
58
|
const newAttachment = { file_token: uploaded.fileToken, ...dimensions }
|
|
59
|
-
//
|
|
59
|
+
// 基础写入:新建记录时随 create Mutation 提交,已有记录通过 append_attachments 追加。
|
|
60
60
|
```
|
|
61
61
|
|
|
62
62
|
非图片省略宽高;类型未知时先识别或提示用户,不能把可能的图片直接当非图片。图片解码失败或尺寸无效时停止上传和挂载,不伪造尺寸。
|
|
@@ -78,22 +78,22 @@ const context = await resolveDatabaseContext()
|
|
|
78
78
|
const ref = { tableId, fieldId, recordId, fileToken }
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
-
helper 负责生成 extra,其中
|
|
81
|
+
封面和下载 helper 负责生成 extra,其中 siteToken 和 siteEnv 指定应用及 Preview/正式环境,宿主校验其与当前页面一致。业务代码不手工拼接 extra,也不移除该字段来尝试底表鉴权。不存在、错位或无权限的附件可能返回错误或无可展示内容。
|
|
82
82
|
|
|
83
83
|
| 操作 | helper 与结果 | 前置条件 |
|
|
84
84
|
| --- | --- | --- |
|
|
85
|
-
| 封面/大图 | `
|
|
85
|
+
| 封面/大图 | `await fetchAttachmentCover(ref, 360)` 返回 Blob | 需要支持 HTTP 二进制响应的宿主和完整附件坐标;不需要 iframe 推断 gatewayOrigin |
|
|
86
86
|
| 原文件下载 | `await fetchAttachmentDownloadUrl(context, ref)` 返回临时链接 | 通过父页面代理取链接,不依赖封面 helper 的 gatewayOrigin |
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
不能因为封面加载失败就禁用下载。下载失败应显示 helper 返回的错误;任何动作入口都不能静默无响应。
|
|
89
89
|
|
|
90
|
-
###
|
|
90
|
+
### 缩略图和点击大图
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
基础取图入口是 starter `src/lib/database-runtime.ts` 的 `fetchAttachmentCover(ref, size, { signal })`,返回 Blob。图片由宿主以当前访问者身份请求,经通用 HTTP bridge 返回。调用方用 `URL.createObjectURL(blob)` 展示,替换或卸载时取消请求并 revoke。`size` 控制封面请求尺寸,默认 360、最大 1280,可按展示需求调整;页面显示尺寸由样式决定,大图仍是封面。
|
|
93
93
|
|
|
94
|
-
|
|
94
|
+
React 页面可选用 `src/lib/attachment-image.tsx` 的 `AttachmentImage`。它内部调用同一取图函数,封装可见时加载、取消请求、手动重试和 Blob URL 释放;例如预览使用 `<AttachmentImage attachment={ref} alt={name} size={1280} />`。需要自定义展示时直接使用取图函数即可。
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
封面异步生成,保留占位和失败状态;自动重试按[工程质量](style-guide.md)设置有限预算,替换或卸载时取消。遇到 `HTTP_RESPONSE_TYPE_UNSUPPORTED` 或 `INVALID_HTTP_URL` 时,先核对是否使用当前 starter 的 helper、完整附件坐标和匹配的依赖版本。修正本地接入后重新构建并发布;接入正确但仍报错时,保留错误码与请求标识,报告平台能力限制并向平台支持反馈,不自行猜测域名或绕过代理。
|
|
97
97
|
|
|
98
98
|
### 原文件下载
|
|
99
99
|
|
|
@@ -103,21 +103,21 @@ helper 负责生成 extra,其中 baseAppToken 将鉴权对象指向应用。
|
|
|
103
103
|
|
|
104
104
|
## 写单元格
|
|
105
105
|
|
|
106
|
-
|
|
106
|
+
按[写入方式选择](mutations.md#写入方式选择)确定是否需要 FaaS;基础追加/移除通过 `invokeDatabaseFunction` 调用 `append_attachments` / `remove_attachments` Mutation。声明、Page 参数和完整响应见[Mutation 附件写入](mutations.md#附件写入)。保持以下操作语义:
|
|
107
107
|
|
|
108
|
-
- 追加只提交本次新增项;图片附带本地读取的宽高。正常追加不要求先查询旧列表,不依赖
|
|
109
|
-
- 移除只提交目标 file_token,按 token 删除全部同名引用;
|
|
110
|
-
-
|
|
111
|
-
-
|
|
112
|
-
-
|
|
108
|
+
- 追加只提交本次新增项;图片附带本地读取的宽高。正常追加不要求先查询旧列表,不依赖 Database Function 重建旧图宽高。
|
|
109
|
+
- 移除只提交目标 file_token,按 token 删除全部同名引用;Database Function 返回附件对象中的 `token`,调用 Mutation 时将该值填入 `file_token`。不要直接提交查询返回对象。
|
|
110
|
+
- 没有新增或移除项时本地短路,批量只提交有改动的参数组。Mutation 拒绝空附件列表;FaaS 直调仍需过滤空字段数组和空记录映射,不能假定 append 空数组无副作用。
|
|
111
|
+
- Mutation 成功后用 `data.records` 中对应记录/字段的完整附件列表更新本地状态,不立即调用 Database Function 回读覆盖它;查询结果可能尚未同步。FaaS 直调使用 `data.attachments`,并处理 `ignored_fields`;不要混用两种返回结构。
|
|
112
|
+
- 新记录可通过 create Mutation 随记录提交附件;update 的整格写入只用于明确的替换或 clear 清空。重设旧图无法从 Database Function 补回宽高,不用于普通追加/移除。
|
|
113
113
|
|
|
114
|
-
|
|
114
|
+
附件增量写入不保证原子性、去重或并发不丢项。页面按单元格串行可减少本页交错,但不能保护多个访问者同时写入;不同记录或字段不应共用全局上传锁。严格并发一致性的需求须说明当前能力限制,不通过固定等待时间承诺安全。
|
|
115
115
|
|
|
116
116
|
### 超时与结果未知
|
|
117
117
|
|
|
118
118
|
页面区分上传中、已上传待挂载、挂载结果待确认,保留已有 fileToken 和图片宽高。append 与上传都不幂等,结果未知时不自动重提或重新上传。
|
|
119
119
|
|
|
120
|
-
1. 使用固定
|
|
120
|
+
1. 使用固定 Database Function 按记录核对目标 token。未立即读到不证明上一请求失败;读到也不保证不会被并发写入覆盖。
|
|
121
121
|
2. 延迟后进行有限次数或有限时长的只读核对。仍不能确认时保留待确认状态并提示用户,不拿旧列表整格覆盖。
|
|
122
122
|
3. 后续明确需要补挂时复用已有 token 与宽高,只处理已核对的目标,并说明可能重复引用和并发覆盖。没有可靠去重原语时不承诺只执行一次。
|
|
123
123
|
|
|
@@ -126,9 +126,9 @@ helper 负责生成 extra,其中 baseAppToken 将鉴权对象指向应用。
|
|
|
126
126
|
| 条件/错误 | 处理 |
|
|
127
127
|
| --- | --- |
|
|
128
128
|
| INVALID_ATTACHMENT_TARGET | 区分文件类型/大小与应用绑定配置;修正对应输入,不重复发送同一错误请求 |
|
|
129
|
-
| ATTACHMENT_UNAVAILABLE |
|
|
129
|
+
| ATTACHMENT_UNAVAILABLE | 父页面不支持当前附件接口,报告环境能力限制 |
|
|
130
130
|
| ATTACHMENT_UPLOAD_FAILED / STALLED | 显示进度或网络问题;检查是否已上传,不自动重传 |
|
|
131
|
-
|
|
|
131
|
+
| 位置不匹配或没有封面 | 核对坐标与应用鉴权;封面未就绪按有限重试处理 |
|
|
132
132
|
| 下载操作无响应 | 核对代理错误及 iframe 下载设置;不因缺 gatewayOrigin 直接禁用下载 |
|
|
133
133
|
| 单元格已满或出现 ignored_fields | 不报告全部成功;指出未写入项及原因 |
|
|
134
134
|
| property.capture 字段 | 上传挂载可能被忽略;读取和移除按对应协议处理 |
|
|
@@ -1,97 +1,53 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 前端设计入口
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
首次实现页面、整体视觉改版或视觉评审前读取本文件,并按下述路由继续读取所需文件。不同运行环境使用同一设计原则。局部视觉修改只读相关章节并沿用现有设计;仅修改数据逻辑时不重做视觉方案。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## 边界
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
使用主 Skill 已取得的用户目标、页面任务、数据模式与契约、品牌、现有工程和宿主约束。设计环节不新增提问、问卷、风格选择或确认节点;主 Skill 原有需求澄清、权限、授权、工程、验收与交付行为不变。不因设计分类补造业务目标、页面、指标或操作。
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
用户明确的设计要求优先于默认审美。修改已有应用时优先保留设计系统。主 Skill 的数据和运行协议、结果真实性、可访问性要求不被场景 Prompt 覆盖;通用工程与安全要求见[工程质量](style-guide.md),日期值和时区转换见[日期与时区](development.md#日期与时区)。所有场景继承通用规范的数据模式规则;统计口径与业务状态由业务定义决定,设计仅负责表达。
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
2. **排版**:确定标题、正文、辅助文字的字号、字重、行高与数字格式。
|
|
13
|
-
3. **布局与密度**:高频列表与工作台优先信息效率,表单与登记页优先阅读和输入空间;相同任务采用一致密度。
|
|
14
|
-
4. **业务辨识度**:用业务内容、导航结构、品牌色或关键状态表达建立特征。需要视觉强调时集中在少数位置,不让装饰占用核心操作区域。
|
|
15
|
-
5. **交互与动效**:确定控件状态、焦点、过渡时长和响应式策略,落实为可复用组件与设计变量。
|
|
11
|
+
## 读取顺序
|
|
16
12
|
|
|
17
|
-
|
|
13
|
+
1. 新建或整体改版:读取[通用设计规范](design/foundations.md),识别已有产品身份、全站设计基础和每个页面的主要任务,确定构图与字体。**首次实现或本次调整交互控件时,在决定尺寸、表面、颜色或选择组件库之前,读取[控件设计](design/components.md)、[A/B/C 配方与选择](design/control-recipes.md)及[组件索引](design/components/index.md)。**已有规范可继承,但仍需先读配方核对;本轮刚生成的样式及未经处理的库默认外观不算已有规范。需要新定或调整配色时读[组件主题](design/theme.md)。
|
|
14
|
+
2. 按下表读取当前页面适用的一份主场景规范。一个应用可有多种页面模式;不要把六份场景文件全部加载,也不要把一个页面的主题扩散到全站。
|
|
15
|
+
3. 局部修改:读取通用规范相关章节与受影响的场景章节,继承已有 token、组件和布局;涉及控件外观时同样按第 1 步读取对应组件参考。纯文案或纯数据逻辑修改不触发组件配方读取。
|
|
16
|
+
4. 实现后按[设计自检与按需评审](design/review.md)核对本次修改的代码与已有产物,再回到主 Skill 原有流程。本入口不触发浏览器、逐页遍历、截图或新增运行态验收;用户或主流程要求的专项验收沿用其范围与方法。
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
| 页面任务 | 布局重点 | 默认视觉取向 |
|
|
18
|
+
| 页面主要任务 | 继续读取 | 不要误用到 |
|
|
22
19
|
| --- | --- | --- |
|
|
23
|
-
|
|
|
24
|
-
|
|
|
25
|
-
|
|
|
26
|
-
|
|
|
27
|
-
|
|
|
28
|
-
|
|
|
29
|
-
|
|
30
|
-
工具页不默认使用大幅 hero、装饰插画或营销式首屏。并列内容可用网格,顺序内容用步骤或时间轴,层级内容用分组;结构必须反映真实信息关系,不把所有区块放入同一种白色阴影卡片。
|
|
31
|
-
|
|
32
|
-
## 排版与间距
|
|
33
|
-
|
|
34
|
-
以下作为默认层级,按用户品牌、中文可读性及目标设备调整:
|
|
35
|
-
|
|
36
|
-
| 层级 | 字号 | 字重 | 适用 |
|
|
37
|
-
| --- | --- | --- | --- |
|
|
38
|
-
| Display | 32–56px,使用 clamp | 700–800 | 表达页首屏或关键数字 |
|
|
39
|
-
| Heading | 20–28px | 600–700 | 页面和区块标题 |
|
|
40
|
-
| Card title | 15–17px | 600 | 卡片与表单分组 |
|
|
41
|
-
| Body | 13–15px | 400 | 表格和正文;长正文可增大 |
|
|
42
|
-
| Caption | 12px 起 | 400–500 | 辅助说明,不承载唯一关键信息 |
|
|
43
|
-
|
|
44
|
-
- 层级由字号、字重、对比度和间距共同形成,不能只放大标题。行高以内容可读性为准。
|
|
45
|
-
- 中文强调使用字重,不默认使用斜体或负字距。金额、编号和统计数字使用 `font-variant-numeric: tabular-nums`。
|
|
46
|
-
- 默认系统字体栈;特殊字体经允许的依赖或资源打包进入产物,仅加载所需字重,不引入运行时外链字体 CDN。
|
|
47
|
-
- 间距以 4px 基数和 8px 节奏组织;组间距大于组内间距。表格行高可从紧凑 40px、常规 48px、舒展 56px 选择,相同场景一致。
|
|
48
|
-
|
|
49
|
-
## 表格、表单与按钮
|
|
50
|
-
|
|
51
|
-
- 表格文本左对齐、数字右对齐;状态使用文字与语义色,不能只用颜色区分。操作列置于行尾,次要动作按需收纳。
|
|
52
|
-
- 空值表达一致,例如“-”;长内容截断时提供键盘和触屏可用的完整查看方式,不仅依赖 hover。
|
|
53
|
-
- 行分隔使用细线或斑马纹,避免冗余边框;列表同时设计加载、空、失败、部分数据和无权限状态。
|
|
54
|
-
- 表单标签明确且与控件关联,占位符只提供示例。必填与错误提示一致,提交失败定位首个错误字段。
|
|
55
|
-
- 主按钮、次按钮与文字按钮层级清晰,同一操作区域突出一个主要动作;危险动作写明对象和后果,不作为默认焦点。
|
|
56
|
-
- 提交期间阻止重复操作;成功反馈对应真实业务结果,部分成功明确哪些操作需要继续处理。
|
|
57
|
-
|
|
58
|
-
## 控件与组件体系
|
|
59
|
-
|
|
60
|
-
控件应纳入本应用设计变量和状态体系,同时优先保留可靠交互与可访问性:
|
|
20
|
+
| 录入、编辑、处理、审批、排班、批量操作 | [业务操作](design/scenes/business-operations.md) | 纯品牌展示或阅读型报告 |
|
|
21
|
+
| 扫描指标、比较、筛选、监控、定位异常 | [数据看板](design/scenes/dashboard.md) | 主要用于处理记录的列表 |
|
|
22
|
+
| 线性阅读结论及证据、形成分析理解 | [分析报告](design/scenes/analysis-report.md) | 高频筛选监控界面 |
|
|
23
|
+
| 展示业绩、活动成果、讲述数据故事 | [战报](design/scenes/campaign-report.md) | 日常业务操作、审慎分析报告 |
|
|
24
|
+
| 品牌介绍、门户、产品浏览与目录 | [品牌展示](design/scenes/brand-showcase.md) | 因含“产品”二字就套用到管理后台 |
|
|
25
|
+
| 节庆促销、领券、邀请、抽奖等活动参与 | [节庆活动](design/scenes/festive-campaign.md) | 活动配置、营销后台 |
|
|
61
26
|
|
|
62
|
-
|
|
63
|
-
- 下拉、菜单、弹窗、Tooltip 等优先复用 starter 的组件模式,按需使用 Radix 无头原语、Tailwind token 与 CVA 变体。日期选择可使用 react-day-picker 配 Popover,不手写复杂日历或定位内核。
|
|
64
|
-
- 移动端原生日期选择器等有明确体验收益时可以保留;同类使用场景保持一致。不要为视觉统一损害键盘或触屏体验。
|
|
65
|
-
- 修改既有项目沿用组件库和主题;新建默认不为单个控件引入第二套完整组件库。确需替换时统一全站主题和设计变量。
|
|
66
|
-
- 图标沿用 starter 的 lucide-react 线性风格,不混用不一致的图标库与 emoji。
|
|
27
|
+
## 模糊与混合场景
|
|
67
28
|
|
|
68
|
-
|
|
29
|
+
按用户明确要求 → 页面主要任务与交互 → 内容和数据形态 → 行业风格选择的顺序判断。行业关键词只辅助视觉方向,不单独决定页面类别。
|
|
69
30
|
|
|
70
|
-
|
|
31
|
+
- 已有系统:继承设计,处理本次范围;不重新随机选择风格。
|
|
32
|
+
- 主要任务明确、分类模糊:自主选择最接近的模式,采用其中有依据的规则。
|
|
33
|
+
- 多任务并存:按主要任务选一份场景,共享全站基础。次任务涉及主场景未覆盖的组织或交互时,仅补读对应章节,如操作页中的筛选图表读看板的图表/交互章节,报告内的编辑表单读业务操作的表单章节;不叠加完整主题。单个数字不触发看板路由,零值、比较与阶段语义直接遵守通用规范。
|
|
34
|
+
- 无法明确匹配或信息不足:只使用通用规范,由已知内容组织布局;不默认套后台、Hero 或看板,不向用户追加设计澄清。
|
|
35
|
+
- 主 Skill 后续获得新信息时,只重新判断受影响部分。
|
|
71
36
|
|
|
72
|
-
|
|
37
|
+
例如营销系统:经营总览可走看板,活动配置与线索管理走业务操作,面向参与者的活动页走节庆活动,复盘按阅读目标选分析报告或战报。“营销”不是整站使用节庆主题的理由。
|
|
73
38
|
|
|
74
|
-
##
|
|
39
|
+
## 实现链路
|
|
75
40
|
|
|
76
|
-
|
|
77
|
-
- 窄屏重新组织网格和导航;宽表放入独立横向滚动区域,页面整体不溢出。
|
|
78
|
-
- 触控目标默认至少 44×44px;固定控件考虑安全区,hover 有触屏替代反馈。
|
|
79
|
-
- 桌面高频业务保持信息密度,移动端保证核心任务可完成;不能仅缩小桌面页面。
|
|
80
|
-
- 工具页面动效用于反馈和状态过渡,默认 150–250ms;表达页才按内容需要增加入场编排。统一缓动并尊重 prefers-reduced-motion。
|
|
41
|
+
页面构图与信息主次 → 应用共用的主题、字体规范 → 本次需要的控件规范 → 共享样式与组件实现 → 页面复用并连接业务能力 → 按 review 自检,再进入主 Skill 的验证与交付。已有应用从现行规范出发,只补足任务涉及的缺项;这是一组实现依赖,不新增主 Skill 的外部流程节点。
|
|
81
42
|
|
|
82
|
-
|
|
43
|
+
“先定规范”要落成可复用的具体选择:文本角色的字号/字重/行高、控件的尺寸/表面/层级/状态,以及页面的宽度、重排和容器规则。普通业务页默认直接在页面上组织标题、工具栏、表单/列表/日历,不先垫一张卡片;布局分组无可见外壳。有独立用途才使用内容卡,普通内容卡默认无描边、无投影,必要输入边界与数据网格独立处理,具体见[直接排版与容器规则](design/composition.md#普通业务页直接排版)。不能只列候选范围或写一句“保持一致”后逐页自由取值。直接使用工程的 token、样式、组件和变体表达;同一应用同一角色复用同一规则,有明确用途时才扩展变体。只定义当前需要的部分,不预建完整设计系统。
|
|
83
44
|
|
|
84
|
-
|
|
45
|
+
控件配方按用户要求和已有规范优先,再匹配任务密度;通用或不明确时 A,密集操作优先 B,明确舒展输入优先 C。应用内保持同一基础,配色独立决定,不按页面随机换 A/B/C;具体规格和例外见配方文件。
|
|
85
46
|
|
|
86
|
-
|
|
47
|
+
任务出现下拉、日期、时间、菜单等控件时,从[组件索引](design/components/index.md)读取对应的 UI/UX 规格;首次实现或替换该类组件时继续读取相应源码和调用示例。已有可靠组件可以适配,不要求复制参考实现或引入另一套库。**本地演示、mock 数据、不发布、工期或实现成本,都不是把这些组件降级为浏览器默认弹层的理由**;除非用户明确要求原生控件,或现有平台有不可绕开的原生约束,否则应使用工程已有可主题化组件,缺失时适配本参考的最小实现。检查真实调用及展开面板,不以只读了配方、只修改按钮或只美化触发器替代完整落实。按需读本次用到的类型,不加载整个组件库。
|
|
87
48
|
|
|
88
|
-
|
|
49
|
+
设计决策直接落实到主题、组件和代码;默认不额外创建设计文件、不输出 Seed 或分类表要求用户确认。只在用户要求方案文档时单独交付。现有组件、包管理器、CSS 体系和平台接入按主 Skill 保留。Page starter 当前使用 React、Tailwind、Radix Slot、CVA 与 lucide-react;优先复用已有组件和交互原语。需要新的可主题化弹层时,可选适合现有工程的无头原语;日期可用成熟日历组件与 Popover 组合。组件参考源码用于适配,不要求复制整套代码或引入第二套完整组件库。
|
|
89
50
|
|
|
90
|
-
|
|
91
|
-
- 首屏内容和主要动作适合当前业务,无无关 hero、装饰卡片或过量渐变。
|
|
92
|
-
- 表格对齐、表单错误、按钮层级和日期数字格式一致;图表选择与比较任务匹配,避免无必要的 3D、仪表盘或过多饼图分类。
|
|
93
|
-
- 焦点、键盘、弹窗、空态、错误和部分成功均有实现;关键文本对比度充分。
|
|
94
|
-
- 桌面和窄屏核心任务可达,无页面级横向溢出;减少动效设置有效。
|
|
95
|
-
- 用户提供的品牌和已有界面得到保留。未做浏览器验证的项目明确列为未验证,不将静态自检报告为真实交互通过。
|
|
51
|
+
统一可读性、行为和同站语言,保留任务所需的结构差异。需要构图或组件关系的正向参考时,只读[设计示例](design/examples.md)中对应任务的段落;示例不是固定皮肤或模块清单。副标题默认不生成;品牌标记、控件外观与布局按通用规范落实。实现符合规范与实际美观分别判断,代码自检不等于视觉或运行态通过。
|
|
96
52
|
|
|
97
|
-
|
|
53
|
+
完成设计实现后回到主 Skill 的[发布与交付](release.md);用户要求专项视觉验收时按[诊断与验收](verification.md)确定范围。此设计入口本身不新增浏览器巡检。
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
# Mutation Function
|
|
2
|
+
|
|
3
|
+
Mutation 是固定单表的基础写入声明。读取继续用 Database Function;写入使用 `mutations/<functionId>/{meta.json,spec.json}`,Page 只传位置参数。表、可写字段、固定值和记录 ID 参数来源由发布者声明,不能由调用者扩展。写入方式按下节选择。
|
|
4
|
+
|
|
5
|
+
CLI 的 `deploy` 自动校验、打包并注册声明,`pull` 恢复 `mutations/`。全部类型共享 Function ID 和最多 200 个 Function 的限制。保存成功不代表写入一定成功,调用后仍需检查错误与部分完成结果。
|
|
6
|
+
|
|
7
|
+
## 写入方式选择
|
|
8
|
+
|
|
9
|
+
**读取使用 Database Function;声明能完整表达的普通单表创建、按记录 ID 更新和删除(含批量及附件写入)优先使用 Mutation;需要声明之外的服务端业务校验、计算或编排时使用 FaaS。按业务动作选择,已有 FaaS 无需主动迁移。**
|
|
10
|
+
|
|
11
|
+
| 业务要求 | 选择 |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| 固定单表、固定字段的创建,或按记录 ID 更新/删除;只需类型、缺失/null、长度、列表数量等声明内约束 | Mutation;支持一次改多个字段、批量记录和附件增量 |
|
|
14
|
+
| 需要校验记录归属、当前状态、查重、非空白等业务规则,或基于旧值计算、跨表写入、多个业务写入存在依赖 | FaaS;按 [FaaS 协议](faas.md)实现 |
|
|
15
|
+
|
|
16
|
+
例如修改指定任务的标题和状态、批量设置为完成属于基础写入;“只能修改自己的草稿”需要 FaaS。具体参数限制见[声明与参数](#声明与参数)。需要 FaaS 校验的动作不能另行暴露可绕过校验的 Mutation,也不经 FaaS 调用 Mutation。“上传文件 → 取得 token → Mutation 挂载”属于页面附件流程,本身不需要 FaaS;如需服务端业务校验再按上述边界选择。两条链路均不额外提供事务或 CAS。
|
|
17
|
+
|
|
18
|
+
## 声明与参数
|
|
19
|
+
|
|
20
|
+
`meta.json`:
|
|
21
|
+
|
|
22
|
+
```json
|
|
23
|
+
{"name":"创建任务","description":"提交一条待处理任务"}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Mutation 不声明角色;调用仍需通过应用统一准入。记录 ID 仅限定操作范围,不代表记录归属或行权限校验。
|
|
27
|
+
|
|
28
|
+
`spec.json` 中 `param` 是 **从 1 开始的位置编号**。记录条件的 `param: 2` 表示从第 2 个参数读取 ID,和“修改两条”没有关系。目标参数必须是必填的单值 `RECORD_ID`,不能设置 `list: true`;多条记录通过 `batch` 逐条传参。
|
|
29
|
+
|
|
30
|
+
支持 `TEXT / INT / DOUBLE / BOOL / TIMESTAMP / DURATION / USER_ID / GROUP_ID / RECORD_ID / ATTACHMENT`;`required` 默认 true,`list` 默认 false。`TEXT.max_length` 默认 100000,列表 `max_items` 默认 200。`required` 只拒绝缺失/null;TEXT 允许空字符串和纯空白,当前没有 `min_length`、正则或数字范围参数。不能额外传参、动态表/字段或任意 patch。
|
|
31
|
+
|
|
32
|
+
可选参数传 null 或省略末尾位置表示不修改。文本传 `""` 写入空文本;多选及 `list:true` 的人员参数按完整数组替换,`[]` 清空,单人字段最多一个 ID。其他清空使用固定 `{ "clear": true }`;需要在一次保存中动态选择写入或清空日期时,当前声明无法直接表达,可使用 FaaS。
|
|
33
|
+
|
|
34
|
+
`set` 每个字段只可选择一种来源:`const`、`param`、`current_user: true`、`now: true`、`clear: true`。人员参数使用内部数字 ID 字符串;调用者不能覆盖服务端注入的当前用户和时间。选项用 Catalog 中已有的选项名称,字段使用真实 field ID。附件的参数、整格替换与增量操作见[附件写入](#附件写入)。不要将公式、lookup、系统等不可写字段放入 `set`;调用后按下文检查 `ignored_fields` 等部分结果。
|
|
35
|
+
|
|
36
|
+
电话、邮箱和超链接使用 `TEXT` 参数或字符串 `const`,支持 create/update、批量写入及 `clear`。电话传完整号码字符串。超链接传地址(如 `https://example.com`)或 `[展示文字](https://example.com)`,不传对象。`returning` 保留本次提交的字符串;超链接可通过原生 Base 记录接口回读。
|
|
37
|
+
|
|
38
|
+
`TIMESTAMP` 参数接受毫秒整数或含时区的 RFC3339,保留毫秒精度。日期 `const` 使用含时区的字符串,例如 `{"const":"2026-09-15T08:00:00+08:00"}`,不要使用数字时间常量。`now` 使用服务端当前时间。验收日期写入时,通过 Database Function 回读核对实际时间,不能只检查 `returning`。
|
|
39
|
+
|
|
40
|
+
## 记录范围
|
|
41
|
+
|
|
42
|
+
`create` 不带 `precondition`。`update`、`delete`、`append_attachments`、`remove_attachments` 必须带 `precondition`,固定为 `conjunction: "and"`,`conditions` 中仅允许一个 `{"field_id":"rec_id","operator":"is","param":N}` 条件。`is` 表示等于单个记录 ID,每组参数只定位一条记录,不接受 ID 数组。
|
|
43
|
+
|
|
44
|
+
当前 `precondition` 只定位记录,不读取记录做业务预检,不支持其他字段、多个条件、嵌套 `groups`、`or` 或其他操作符;旧 `record_id_param/record_ids_param`、`target` 和 `on_error` 也会在保存时被拒绝。需要服务端检查归属、状态或其他业务条件时使用 FaaS。
|
|
45
|
+
|
|
46
|
+
不支持省略 ID 按条件修改或删除。可先通过 Database Function 查询 ID,再调用 Mutation;查询结果不保证写入时状态仍相同。
|
|
47
|
+
|
|
48
|
+
## 创建单条与批量创建
|
|
49
|
+
|
|
50
|
+
`mutations/createTask/spec.json` 示例;`tblTasks` / `fldTitle` 等替换成 Catalog 中的真实 ID。
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"table":{"table_id":"tblTasks"},
|
|
55
|
+
"operation":"create",
|
|
56
|
+
"params":[{"kind":"TEXT","max_length":100}],
|
|
57
|
+
"set":{
|
|
58
|
+
"fldTitle":{"param":1},
|
|
59
|
+
"fldStatus":{"const":"待处理"},
|
|
60
|
+
"fldOwner":{"current_user":true},
|
|
61
|
+
"fldCreatedAt":{"now":true}
|
|
62
|
+
},
|
|
63
|
+
"returning":["rec_id","fldTitle"]
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
调用单条:`{"params":["准备评审"]}`。创建多条、每条内容不同:
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{"batch":[{"params":["准备评审"]},{"params":["补充文档"]}]}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## 多条记录设置相同值
|
|
74
|
+
|
|
75
|
+
`mutations/renameTasks/spec.json`:
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"table":{"table_id":"tblTasks"},
|
|
80
|
+
"operation":"update",
|
|
81
|
+
"params":[{"kind":"TEXT"},{"kind":"RECORD_ID"}],
|
|
82
|
+
"precondition":{"conjunction":"and","conditions":[{"field_id":"rec_id","operator":"is","param":2}]},
|
|
83
|
+
"set":{"fldTitle":{"param":1}},
|
|
84
|
+
"returning":["rec_id","fldTitle"]
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
调用:
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{"batch":[{"params":["统一标题","recA"]},{"params":["统一标题","recB"]}]}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
每组的第 2 个参数都是单个记录 ID。
|
|
95
|
+
|
|
96
|
+
## 多条记录设置不同值
|
|
97
|
+
|
|
98
|
+
复用上例声明,分别传入每条记录的标题和 ID:
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{"batch":[{"params":["标题 A","recA"]},{"params":["标题 B","recB"]}]}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
批量模式按同一个声明解释每组参数,每组操作一条记录。同一请求最多 200 组,不允许重复目标 ID。`batch` 与顶层 `params` 互斥,不支持在一批中混合不同表、操作或 Function。
|
|
105
|
+
|
|
106
|
+
## 删除多条
|
|
107
|
+
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"table":{"table_id":"tblTasks"},
|
|
111
|
+
"operation":"delete",
|
|
112
|
+
"params":[{"kind":"RECORD_ID"}],
|
|
113
|
+
"precondition":{"conjunction":"and","conditions":[{"field_id":"rec_id","operator":"is","param":1}]},
|
|
114
|
+
"returning":["rec_id"]
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
调用:`{"batch":[{"params":["recA"]},{"params":["recB"]}]}`。delete 不接受 `set`,返回只能包含 record ID。
|
|
119
|
+
|
|
120
|
+
## 附件写入
|
|
121
|
+
|
|
122
|
+
附件上传仍使用 [文件传输](file-transfer.md#上传) 中的 `siteRuntime.uploadAttachment()`;上传成功后复用已有 `fileToken` 和本地图片宽高调用 Mutation。基础追加使用 `append_attachments`,不先查询并重写旧列表。只有创建新记录时随记录提交附件,或业务明确要求替换整个单元格时,才使用 `create` / `update`。
|
|
123
|
+
|
|
124
|
+
### 参数与操作边界
|
|
125
|
+
|
|
126
|
+
`ATTACHMENT` 参数单项是附件对象,例如:
|
|
127
|
+
|
|
128
|
+
```json
|
|
129
|
+
{"file_token":"fileNew","image_width":640,"image_height":480}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
将上传返回的 `fileToken` 映射为 `file_token`;非图片只传 token,图片附本地读取的原始宽高,见[图片宽高](file-transfer.md#图片宽高)。
|
|
133
|
+
|
|
134
|
+
`{"kind":"ATTACHMENT"}` 接收一个对象,`{"kind":"ATTACHMENT","list":true}` 接收对象数组。附件 `const` 使用数组,例如 `{"const":[{"file_token":"fileNew"}]}`。以下示例使用列表参数。
|
|
135
|
+
|
|
136
|
+
| 操作 | 声明与语义 |
|
|
137
|
+
| --- | --- |
|
|
138
|
+
| `create` | 附件字段的 `set` 使用 `param` 或 `const`,随新记录写入完整附件列表 |
|
|
139
|
+
| `update` | 附件字段的 `set` 使用 `param` 或 `const`,替换整格;`{"clear":true}` 清空该字段 |
|
|
140
|
+
| `append_attachments` / `remove_attachments` | `precondition` 与非空 `set` 必填,`set` 只包含附件字段,来源只允许 `param` / `const`;禁止 `clear`、`current_user`、`now` |
|
|
141
|
+
|
|
142
|
+
增量操作的每个目标字段必须有非空附件列表。**一次调用跨 batch、目标记录和字段展开后,附件条目累计最多 50 个**;例如 2 个附件追加到 10 条记录计 20 个。同一文件可以用于不同目标,但每个目标都计数。记录批量限制同样生效。50 条仅是附件增量操作的请求限制;普通 create/update 仍遵守 Mutation 的列表预算与目标平台附件限制。
|
|
143
|
+
|
|
144
|
+
### 追加已上传附件
|
|
145
|
+
|
|
146
|
+
建立 `mutations/appendTaskAttachments/meta.json`:
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{"name":"追加任务附件"}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
`mutations/appendTaskAttachments/spec.json`(ID 替换为 Catalog 中的真实值):
|
|
153
|
+
|
|
154
|
+
```json
|
|
155
|
+
{
|
|
156
|
+
"table":{"table_id":"tblTasks"},
|
|
157
|
+
"operation":"append_attachments",
|
|
158
|
+
"params":[
|
|
159
|
+
{"kind":"RECORD_ID"},
|
|
160
|
+
{"kind":"ATTACHMENT","list":true,"max_items":50}
|
|
161
|
+
],
|
|
162
|
+
"precondition":{"conjunction":"and","conditions":[{"field_id":"rec_id","operator":"is","param":1}]},
|
|
163
|
+
"set":{"fldFiles":{"param":2}},
|
|
164
|
+
"returning":["rec_id","fldFiles"]
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
继续上传示例中的 `newAttachment`,Page 传记录 ID 和本次新增列表:
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
const result = await invokeDatabaseFunction('appendTaskAttachments', ['recA', [newAttachment]])
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
对应调用 JSON 为:
|
|
175
|
+
|
|
176
|
+
```json
|
|
177
|
+
{"params":["recA",[{"file_token":"fileNew","image_width":640,"image_height":480}]]}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
假设原单元格已有 `fileOld`,成功响应是本次操作后的完整列表:
|
|
181
|
+
|
|
182
|
+
```json
|
|
183
|
+
{
|
|
184
|
+
"code":0,
|
|
185
|
+
"msg":"success",
|
|
186
|
+
"data":{
|
|
187
|
+
"record_ids":["recA"],
|
|
188
|
+
"records":[{
|
|
189
|
+
"rec_id":"recA",
|
|
190
|
+
"fldFiles":[
|
|
191
|
+
{"file_token":"fileOld","name":"需求.pdf","size":1200},
|
|
192
|
+
{"file_token":"fileNew","name":"设计.png","size":8000}
|
|
193
|
+
]
|
|
194
|
+
}]
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Page 检查一次顶层 `code`;成功后从 `data.records` 找到对应 `rec_id`,用 `fldFiles` 更新本地附件列表。这里的 `returning` 是操作后的完整附件列表,包含保留下来的旧附件;旧数据的 `name` 可以为空字符串,`size` 可以为 0。不能把请求中的增量列表当成最终列表,也不能把 FaaS 原始路由的 `data.attachments` 当成 Mutation 响应。
|
|
200
|
+
|
|
201
|
+
### 移除附件引用
|
|
202
|
+
|
|
203
|
+
`meta.json` 沿用追加示例,将名称改为“移除任务附件”。
|
|
204
|
+
|
|
205
|
+
`mutations/removeTaskAttachments/spec.json`:
|
|
206
|
+
|
|
207
|
+
```json
|
|
208
|
+
{
|
|
209
|
+
"table":{"table_id":"tblTasks"},
|
|
210
|
+
"operation":"remove_attachments",
|
|
211
|
+
"params":[
|
|
212
|
+
{"kind":"RECORD_ID"},
|
|
213
|
+
{"kind":"ATTACHMENT","list":true,"max_items":50}
|
|
214
|
+
],
|
|
215
|
+
"precondition":{"conjunction":"and","conditions":[{"field_id":"rec_id","operator":"is","param":1}]},
|
|
216
|
+
"set":{"fldFiles":{"param":2}},
|
|
217
|
+
"returning":["rec_id","fldFiles"]
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Page 只提交待移除 token;若来自 Database Function 的附件对象,将其 `token` 填入 `file_token`:
|
|
222
|
+
|
|
223
|
+
```ts
|
|
224
|
+
const result = await invokeDatabaseFunction('removeTaskAttachments', ['recA', [{ file_token: 'fileNew' }]])
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
对应调用 JSON 与移除 `fileNew` 后的成功响应:
|
|
228
|
+
|
|
229
|
+
```json
|
|
230
|
+
{"params":["recA",[{"file_token":"fileNew"}]]}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
```json
|
|
234
|
+
{"code":0,"msg":"success","data":{"record_ids":["recA"],"records":[{"rec_id":"recA","fldFiles":[{"file_token":"fileOld","name":"需求.pdf","size":1200}]}]}}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
移除仅删除单元格中的引用,不删除文件;移除后没有附件时返回该字段的空数组。多条记录使用 `invokeDatabaseMutationBatch`,每组传单个记录 ID,受上述附件总数限制。
|
|
238
|
+
|
|
239
|
+
附件增量操作不保证原子性、并发不丢项或重试去重。部分结果的判断见[调用与结果](#调用与结果)。超时后保留 token 和宽高,按[结果未知的处理](file-transfer.md#超时与结果未知)做有限只读核对,不自动重传、重试或用旧列表整格覆盖。
|
|
240
|
+
|
|
241
|
+
## 调用与结果
|
|
242
|
+
|
|
243
|
+
响应 `code=0` 后仍须检查 `record_not_found` 和 `ignored_fields`:非空表示未全部完成,展示缺失记录或被忽略字段及原因。删除结果的 `record_ids` 可能包含未找到的 ID,不能仅按其长度统计成功数。`records` 不包含缺失记录或被忽略字段的请求值。非零业务错误、无说明的结果缺失、重复或陌生 ID 仍报错;超时或结果异常先只读核对,不自动重试整批。部分完成时也刷新数据,避免页面仍显示写入前的状态。批量调用不额外提供事务或 CAS。
|
|
244
|
+
|
|
245
|
+
`returning` 仅允许 `rec_id` 和声明 `set` 中的字段。普通 create/update/delete 回显未被忽略字段的提交值(参数经过声明类型转换,常量保留原值),可选字段本次没提供时省略;append/remove 返回操作后的完整附件列表,见[附件写入](#附件写入)。普通 CRUD 的 `returning` 是提交值回显;需要最终存储值时在操作后重新查询。普通 CRUD 示例结果:
|
|
246
|
+
|
|
247
|
+
```json
|
|
248
|
+
{"code":0,"msg":"success","data":{"record_ids":["recA"],"records":[{"rec_id":"recA","fldTitle":"准备评审"}]}}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Page 结果类型与检查(单次、批量共用):
|
|
252
|
+
|
|
253
|
+
```ts
|
|
254
|
+
type MutationResult = {
|
|
255
|
+
record_ids: string[]
|
|
256
|
+
record_not_found?: string[]
|
|
257
|
+
ignored_fields?: {id: string; name: string; reason: string}[]
|
|
258
|
+
}
|
|
259
|
+
function assertComplete(result: MutationResult) {
|
|
260
|
+
const missing = result.record_not_found ?? []
|
|
261
|
+
const ignored = result.ignored_fields ?? []
|
|
262
|
+
if (missing.length || ignored.length) {
|
|
263
|
+
throw new Error([
|
|
264
|
+
missing.length ? `记录不存在:${missing.join('、')}` : '',
|
|
265
|
+
...ignored.map(field => `${field.name}:${field.reason}`),
|
|
266
|
+
].filter(Boolean).join(';'))
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Page 一组参数调用(对应上文 `renameTasks`,一组参数修改一条记录):
|
|
272
|
+
|
|
273
|
+
```ts
|
|
274
|
+
const result = await invokeDatabaseFunction<MutationResult>('renameTasks', ['统一标题', 'recA'])
|
|
275
|
+
if (result.code !== 0) throw new Error(result.msg || '写入失败')
|
|
276
|
+
if (!result.data) throw new Error('写入结果缺失,请刷新核对')
|
|
277
|
+
assertComplete(result.data)
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
Page 多组参数调用(对应上文 `createTask`,每组创建一条记录):
|
|
281
|
+
|
|
282
|
+
```ts
|
|
283
|
+
const result = await invokeDatabaseMutationBatch<MutationResult>('createTask', [['准备评审'], ['补充文档']])
|
|
284
|
+
if (result.code !== 0) throw new Error(result.msg || '写入失败')
|
|
285
|
+
if (!result.data) throw new Error('写入结果缺失,请刷新核对')
|
|
286
|
+
assertComplete(result.data)
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
两个 helper 均来自 starter 的 `page/src/lib/database-runtime.ts`,返回 `{code, data?, msg?}`。先检查顶层业务码,再检查 `data` 中的部分结果,不重复解包。
|
|
290
|
+
|
|
291
|
+
CLI 调用沿用项目级路由:
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
base-database-cli lark-cli -- api POST '/open-apis/base/v3/sites/<site-token>/invoke_function/<function-id>' --params '{"env":"preview"}' --data '{"batch":[{"params":["准备评审"]},{"params":["补充文档"]}]}' --json
|
|
295
|
+
```
|