openxiangda 1.0.152 → 1.0.154
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -1
- package/openxiangda-skills/SKILL.md +1 -1
- package/openxiangda-skills/references/component-guide.md +10 -1
- package/openxiangda-skills/references/pages/page-sdk.md +35 -2
- package/openxiangda-skills/references/troubleshooting.md +18 -5
- package/package.json +1 -1
- package/packages/sdk/dist/{ProcessPreview-B_HqjU7v.d.mts → ProcessPreview-DMkzccq4.d.mts} +55 -1
- package/packages/sdk/dist/{ProcessPreview-B_HqjU7v.d.ts → ProcessPreview-DMkzccq4.d.ts} +55 -1
- package/packages/sdk/dist/components/index.cjs +73 -12
- package/packages/sdk/dist/components/index.cjs.map +1 -1
- package/packages/sdk/dist/components/index.d.mts +7 -59
- package/packages/sdk/dist/components/index.d.ts +7 -59
- package/packages/sdk/dist/components/index.mjs +73 -12
- package/packages/sdk/dist/components/index.mjs.map +1 -1
- package/packages/sdk/dist/{dataManagementApi-CEDsA3tT.d.ts → dataManagementApi-C9O-Bb0j.d.ts} +1 -1
- package/packages/sdk/dist/{dataManagementApi-quq3Zhgo.d.mts → dataManagementApi-gpZkgRDM.d.mts} +1 -1
- package/packages/sdk/dist/runtime/index.cjs +10528 -10211
- package/packages/sdk/dist/runtime/index.cjs.map +1 -1
- package/packages/sdk/dist/runtime/index.d.mts +3 -3
- package/packages/sdk/dist/runtime/index.d.ts +3 -3
- package/packages/sdk/dist/runtime/index.mjs +9892 -9575
- package/packages/sdk/dist/runtime/index.mjs.map +1 -1
- package/packages/sdk/dist/runtime/react.cjs +2936 -451
- package/packages/sdk/dist/runtime/react.cjs.map +1 -1
- package/packages/sdk/dist/runtime/react.d.mts +57 -3
- package/packages/sdk/dist/runtime/react.d.ts +57 -3
- package/packages/sdk/dist/runtime/react.mjs +2945 -437
- package/packages/sdk/dist/runtime/react.mjs.map +1 -1
- package/templates/openxiangda-react-spa/.cursor/rules/openxiangda.mdc +1 -0
- package/templates/openxiangda-react-spa/.qoder/rules/openxiangda.md +1 -0
- package/templates/openxiangda-react-spa/AGENTS.md +4 -2
package/README.md
CHANGED
|
@@ -299,7 +299,19 @@ const file = await api.uploadPublicFile(imageFile, "public-assets")
|
|
|
299
299
|
|
|
300
300
|
图片字段和附件字段支持浏览器端压缩图。对用户上传的大图,可以在 `ImageField` 或 `AttachmentField` 上启用 `imageCompression`,运行时会保留原图 `url`,并额外上传缩略图和预览图,保存到 `thumbUrl`、`previewUrl` 和 `variants`。非图片、GIF、SVG、小于阈值的图片,以及浏览器不支持 canvas 压缩时会自动退回原上传流程。
|
|
301
301
|
|
|
302
|
-
|
|
302
|
+
图片和附件预览由运行时统一处理:图片点击后进入同组弹窗画廊,视频、音频和文档在站内弹窗中打开;预览动作只在平台 capability API 返回 `canPreview: true` 时展示。表单上下文继续使用 `ImageField` 和 `AttachmentField`;自定义 React SPA 页面展示任意业务数据里的文件时,直接使用 `ImagePreviewGrid`、`AttachmentPreviewList`,或用 `useFilePreview` 接入自定义卡片和表格。不要为只读附件伪造 `FormProvider`,也不要自行维护扩展名白名单。
|
|
303
|
+
|
|
304
|
+
```tsx
|
|
305
|
+
import {
|
|
306
|
+
AttachmentPreviewList,
|
|
307
|
+
ImagePreviewGrid,
|
|
308
|
+
} from "openxiangda/runtime/react"
|
|
309
|
+
|
|
310
|
+
<AttachmentPreviewList items={record.attachments || []} />
|
|
311
|
+
<ImagePreviewGrid items={record.photos || []} />
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
这些独立 API 必须在模板默认提供的 `OpenXiangdaProvider` 和 `OpenXiangdaPageProvider` 内使用。它们会从 PageSdk 获取当前 `appType`,并统一处理 preview ticket、metadata 和二进制文件响应。默认覆盖 PDF、常见媒体、文本、DOCX 和 XLSX,更多 DOC/XLS/PPT、ODF 格式由部署侧 ONLYOFFICE 配置决定。只有在需要复制、分享或新窗口打开预览页时,才通过 PageSdk `sdk.createFileAccessTicket(..., "preview", { appType })` 获取并打开 `previewPageUrl`;不要直接打开文件内容流 `previewUrl`。
|
|
303
315
|
|
|
304
316
|
```tsx
|
|
305
317
|
import { ImageField } from "openxiangda"
|
|
@@ -58,7 +58,7 @@ OpenXiangda supports two workspace modes. Classic `sy-lowcode-app-workspace` pub
|
|
|
58
58
|
- ✅ For form-entry UX, pick components in this order: OpenXiangda platform form components → `antd` / `antd-mobile` wrappers → custom component only when neither exists.
|
|
59
59
|
- ✅ In React SPA apps, keep imports on public package entrypoints such as `openxiangda`, `openxiangda/runtime`, and `openxiangda/runtime/react`. The default template already groups large vendor chunks; if a bundle is too large, use route-level lazy loading and Vite `manualChunks`, not `openxiangda/packages/sdk/dist/...` internal paths.
|
|
60
60
|
- ✅ For image thumbnails or lightweight previews, use `imageCompression` on `ImageField` or `AttachmentField`. Keep the original `url` for the source file and use `thumbUrl` / `previewUrl` / `variants` for smaller images.
|
|
61
|
-
- ✅
|
|
61
|
+
- ✅ In form context, let `ImageField` and `AttachmentField` own preview UX. In standalone React SPA pages, use `AttachmentPreviewList`, `ImagePreviewGrid`, or `useFilePreview` from `openxiangda/runtime/react`; do not create a fake form context or import internal `FilePreviewContent` / `useFilePreviewController`. All paths must honor platform capability checks, and apps must not maintain local previewable-extension allowlists.
|
|
62
62
|
- ✅ For data delivery with files, use `openxiangda form export <formCode> --mode xlsx|xlsx-images|package --profile <name>`. `package` writes a zip with `data.xlsx`, `attachments/`, and `manifest.json`; do not hand-write export URLs or stream binary content to stdout.
|
|
63
63
|
- ✅ List pages, linked options, remote selectors, and report drill-downs must use paginated server-side queries with explicit searchable fields. Do not fetch a large page and filter in local state.
|
|
64
64
|
- ✅ Treat workflow forms as an exception. Ordinary ticket/order/task/asset lifecycles use status fields, state machines, action logs, permissions, and automations; workflows are for real approval tasks.
|
|
@@ -87,7 +87,16 @@ OSS 浏览器直传所需的 CORS 规则在 `src/resources/storage/<code>.json`
|
|
|
87
87
|
|
|
88
88
|
`AttachmentField` 和 `ImageField` 都可设置 `imageCompression`。启用后只压缩图片文件,保存值会额外包含 `thumbUrl`、`previewUrl` 和 `variants`,用于列表缩略图、小图预览或详情页轻量展示;原图 `url` 仍保留用于下载和高清预览。
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
预览能力也由运行时统一接管:表单上下文使用 `ImageField` / `AttachmentField`;自定义 React SPA 页面展示任意业务数据中的只读附件时,从 `openxiangda/runtime/react` 使用 `ImagePreviewGrid` / `AttachmentPreviewList`,或使用 `useFilePreview({ items })` 接入自定义卡片、表格和详情操作。不要为只读附件伪造 `FormProvider`。
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
import { AttachmentPreviewList, ImagePreviewGrid } from "openxiangda/runtime/react"
|
|
94
|
+
|
|
95
|
+
<AttachmentPreviewList items={record.attachments || []} />
|
|
96
|
+
<ImagePreviewGrid items={record.photos || []} />
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
这些 API 先调用平台 capability,只为 `canPreview: true` 的文件显示或执行预览,并在站内弹窗中打开图片画廊、视频、音频、PDF、DOCX、XLSX、文本等内容。不要在应用代码中维护扩展名白名单,不要直接引用内部 `FilePreviewContent` / `useFilePreviewController`,也不要把文件流 URL 当成页面入口。DOC/XLS/PPT、ODF 等格式是否可预览由部署侧 ONLYOFFICE 配置决定。
|
|
91
100
|
|
|
92
101
|
声明式 OSS 文件需要 bucket CORS 允许应用域名读取对象,浏览器端 DOCX/XLSX/HEIC 解析才能工作;平台私有附件由 ticket 文件流处理,不直接暴露对象地址。
|
|
93
102
|
|
|
@@ -16,7 +16,7 @@ Guidelines:
|
|
|
16
16
|
- Use `sdk.function.invoke(code, { input })` for reusable backend business logic declared under `src/resources/functions/` and `src/functions/`. Do not implement multi-form orchestration, connector fan-out, notification orchestration, or permission-sensitive backend rules directly in a page component.
|
|
17
17
|
- Use `sdk.connector.invoke`, `sdk.connector.call("connector.api")`, or `sdk.connector.download` for external services. The SDK calls the platform runtime connector endpoint; it must not call third-party domains directly.
|
|
18
18
|
- Use `sdk.notification.sendByType` and `batchSendByType` for reusable business messages. Custom notification types must be declared in `src/resources/notifications/` and published with `openxiangda resource publish`.
|
|
19
|
-
- Use `sdk.createFileAccessTicket(bucketName, objectName, fileName, "preview", { appType })` when
|
|
19
|
+
- Use `AttachmentPreviewList`, `ImagePreviewGrid`, or `useFilePreview` from `openxiangda/runtime/react` for in-page attachment previews in a custom React SPA page. They use the current PageSdk context and enforce the platform capability and ticket contracts. Use `sdk.createFileAccessTicket(bucketName, objectName, fileName, "preview", { appType })` only when the page needs a shareable or new-window preview link. `appType` defaults to the current page context. Open `response.result.previewPageUrl`; do not use `previewUrl` or `/service/file/preview-by-ticket/:ticket` as the page entry.
|
|
20
20
|
- Use `sdk.organization.departments.*` and `sdk.organization.accounts.*` only for admin-style app pages that intentionally manage platform departments/accounts. The current user needs `app:organization:manage` on the app. Do not call legacy `/user` or `/department` write endpoints from pages.
|
|
21
21
|
- Use `sdk.workCenter.listItems({ boxType })` and `sdk.workCenter.getStats()` for current-user work center lists and counts. `boxType` is one of `todo`, `done`, `cc`, or `initiated`. This is the end-user task/handled/cc/initiated surface; do not build todo pages by reading workflow operation logs, automation logs, or raw process-task tables.
|
|
22
22
|
- `sdk.form.create` returns identifiers and generated serial number values only. Treat `formInstId` / `formInstanceId` as the required success contract; `serialNumber` / `serialNumbers` are present only when the form has `SerialNumberField`. Do not expect the save response to contain the full row, formula results, or other server-generated field values. Call `sdk.form.getDetail` explicitly after create when those values are needed.
|
|
@@ -101,7 +101,40 @@ const response = await sdk.dataSource.run("tickets", {
|
|
|
101
101
|
|
|
102
102
|
Data view filters, having, and fields use output aliases such as `customerName` or `ticketCount`, not source references such as `customer.name`. For option-like fields, prefer scalar aliases such as `statusValue` in the view definition and page filters. If the page only needs one form, prefer `sdk.form.advancedSearch`. If the page only needs a simple one-form dropdown, prefer linkedForm options.
|
|
103
103
|
|
|
104
|
-
|
|
104
|
+
Standalone in-page file preview:
|
|
105
|
+
|
|
106
|
+
```tsx
|
|
107
|
+
import { EyeOutlined } from "@ant-design/icons"
|
|
108
|
+
import { Button } from "antd"
|
|
109
|
+
import {
|
|
110
|
+
AttachmentPreviewList,
|
|
111
|
+
ImagePreviewGrid,
|
|
112
|
+
useFilePreview,
|
|
113
|
+
} from "openxiangda/runtime/react"
|
|
114
|
+
|
|
115
|
+
export function RecordFiles({ record }) {
|
|
116
|
+
const files = record.attachments || []
|
|
117
|
+
const preview = useFilePreview({ items: files })
|
|
118
|
+
const primary = files[0]
|
|
119
|
+
|
|
120
|
+
return (
|
|
121
|
+
<>
|
|
122
|
+
<AttachmentPreviewList items={files} />
|
|
123
|
+
<ImagePreviewGrid items={record.photos || []} />
|
|
124
|
+
{primary && preview.canPreview(primary) ? (
|
|
125
|
+
<Button icon={<EyeOutlined />} onClick={() => void preview.open(primary)}>
|
|
126
|
+
Preview primary file
|
|
127
|
+
</Button>
|
|
128
|
+
) : null}
|
|
129
|
+
{preview.host}
|
|
130
|
+
</>
|
|
131
|
+
)
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
These APIs must render below `OpenXiangdaProvider` and `OpenXiangdaPageProvider`. `useFilePreview` returns `canPreview`, `getCapability`, `open`, `download`, `isOpening`, and `host`. Render `host` once in the component tree. Do not import the internal `FilePreviewContent` or `useFilePreviewController`, create a fake `FormProvider`, or keep a local previewable-extension list.
|
|
136
|
+
|
|
137
|
+
Shareable file preview ticket:
|
|
105
138
|
|
|
106
139
|
```ts
|
|
107
140
|
const ticketResponse = await sdk.createFileAccessTicket(
|
|
@@ -14,12 +14,25 @@
|
|
|
14
14
|
| 6 | Tailwind 样式被清除(PurgeCSS) | 生产构建后样式丢失 |
|
|
15
15
|
| 7 | React 多实例冲突 | `Invalid hook call` |
|
|
16
16
|
| 8 | 移动端 antd-mobile 组件样式不生效 | 组件渲染但无样式 |
|
|
17
|
-
| 9 | 数据格式理解错误导致展示异常 | 页面显示 `[object Object]` |
|
|
18
|
-
| 10 | workspace publish 环境变量缺失 | `OPENXIANGDA_ACCESS_TOKEN is not set` |
|
|
17
|
+
| 9 | 数据格式理解错误导致展示异常 | 页面显示 `[object Object]` |
|
|
18
|
+
| 10 | workspace publish 环境变量缺失 | `OPENXIANGDA_ACCESS_TOKEN is not set` |
|
|
19
|
+
| 11 | DOCX 响应是 Base64 文本 | 文件流以 `UEsDB` 开头,`docx-preview` 无法解包 |
|
|
19
20
|
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
## 问题:
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 问题:DOCX 响应是 Base64 文本
|
|
24
|
+
|
|
25
|
+
**症状**:ticket metadata 正常返回 `renderMode: "docx-html"` 和 `canPreview: true`,`/service/file/preview-by-ticket/:ticket` 也是 HTTP 200,但响应内容以 `UEsDB` 开头,Word 预览仍然解析失败。
|
|
26
|
+
|
|
27
|
+
**根因**:DOCX 本质是 ZIP。原始二进制应以 `PK`(十六进制 `50 4B 03 04`)开头;`UEsDB` 是这个 ZIP 内容再次经过 Base64 编码后的文本,不能直接交给 `docx-preview`。这不是 MIME、ticket 或 ONLYOFFICE 配置问题。
|
|
28
|
+
|
|
29
|
+
**解决方案**:升级平台服务端和 OpenXiangda SDK 到包含 Base64 Office 兼容解码的版本。服务端会对历史 Base64 DOCX 对象做严格 ZIP 魔数校验后恢复原始二进制,并按解码后的长度返回 Range;SDK 对旧服务端和直连文件流保留同样的浏览器端兜底。不要在业务页面自行调用 `atob` 或复制一套文件类型判断。
|
|
30
|
+
|
|
31
|
+
**验证方式**:修复后的响应字节应以 `PK` 开头,`Content-Length` 应是解码后的二进制长度。若下载后的 DOCX 仍以可见文本 `UEsDB` 开头,说明服务端尚未升级或请求仍命中了旧节点。
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 问题:antd/antd-mobile 弹层样式丢失
|
|
23
36
|
|
|
24
37
|
**症状**:Select / Dropdown / Popup / Modal 等组件的弹出层没有样式,直接跑到屏幕外,或呈现为无样式的裸 HTML。
|
|
25
38
|
|
package/package.json
CHANGED
|
@@ -1188,6 +1188,60 @@ interface StatusMeta {
|
|
|
1188
1188
|
tone: 'brand' | 'success' | 'danger' | 'neutral' | 'warning';
|
|
1189
1189
|
}
|
|
1190
1190
|
|
|
1191
|
+
type FilePreviewType = 'image' | 'video' | 'audio' | 'pdf' | 'spreadsheet' | 'text' | 'office' | 'download';
|
|
1192
|
+
type FilePreviewRenderMode = 'inline' | 'image-transcode' | 'image-heic' | 'pdfjs' | 'excel-basic' | 'excel-client' | 'text' | 'text-client' | 'docx-html' | 'onlyoffice' | 'office-text' | 'download';
|
|
1193
|
+
type FilePreviewSurface = 'media' | 'document' | 'download';
|
|
1194
|
+
type FilePreviewProvider = 'browser' | 'platform' | 'onlyoffice' | 'none';
|
|
1195
|
+
interface FilePreviewCapability {
|
|
1196
|
+
key?: string;
|
|
1197
|
+
extension?: string;
|
|
1198
|
+
previewType?: FilePreviewType;
|
|
1199
|
+
renderMode?: FilePreviewRenderMode;
|
|
1200
|
+
previewSurface?: FilePreviewSurface;
|
|
1201
|
+
previewProvider?: FilePreviewProvider;
|
|
1202
|
+
canPreview?: boolean;
|
|
1203
|
+
canDownload?: boolean;
|
|
1204
|
+
unsupportedReason?: string;
|
|
1205
|
+
}
|
|
1206
|
+
interface FilePreviewMetadata extends FilePreviewCapability {
|
|
1207
|
+
capabilityVersion?: number;
|
|
1208
|
+
ticket?: string;
|
|
1209
|
+
appType?: string;
|
|
1210
|
+
fileName?: string;
|
|
1211
|
+
bucketName?: string;
|
|
1212
|
+
objectName?: string;
|
|
1213
|
+
size?: number;
|
|
1214
|
+
contentType?: string;
|
|
1215
|
+
downloadUrl?: string;
|
|
1216
|
+
previewUrl?: string;
|
|
1217
|
+
previewPageUrl?: string;
|
|
1218
|
+
metadataUrl?: string;
|
|
1219
|
+
imagePreviewUrl?: string;
|
|
1220
|
+
excelPreviewUrl?: string;
|
|
1221
|
+
textPreviewUrl?: string;
|
|
1222
|
+
officeTextPreviewUrl?: string;
|
|
1223
|
+
onlyofficeConfigUrl?: string;
|
|
1224
|
+
onlyofficeEnabled?: boolean;
|
|
1225
|
+
expiresIn?: number;
|
|
1226
|
+
}
|
|
1227
|
+
interface PreparedFilePreview {
|
|
1228
|
+
item: AttachmentItem;
|
|
1229
|
+
metadata: FilePreviewMetadata;
|
|
1230
|
+
direct: boolean;
|
|
1231
|
+
}
|
|
1232
|
+
type FilePreviewRequest = FormRuntimeApi['request'];
|
|
1233
|
+
interface FilePreviewCapabilityBatch {
|
|
1234
|
+
capabilityVersion?: number;
|
|
1235
|
+
onlyofficeEnabled?: boolean;
|
|
1236
|
+
items?: FilePreviewCapability[];
|
|
1237
|
+
}
|
|
1238
|
+
interface PreviewImageItem {
|
|
1239
|
+
key: string;
|
|
1240
|
+
src: string;
|
|
1241
|
+
name: string;
|
|
1242
|
+
revokeOnClose?: boolean;
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1191
1245
|
interface ApprovalTimelineProps {
|
|
1192
1246
|
tasks: ProcessTask[];
|
|
1193
1247
|
className?: string;
|
|
@@ -1207,4 +1261,4 @@ interface ProcessPreviewProps {
|
|
|
1207
1261
|
}
|
|
1208
1262
|
declare const ProcessPreview: React__default.FC<ProcessPreviewProps>;
|
|
1209
1263
|
|
|
1210
|
-
export { type
|
|
1264
|
+
export { type FormDataDeleteParams as $, type AddressFieldProps as A, type BaseFieldProps as B, type CascadeDateFieldProps as C, type DataFilter as D, type DepartmentSearchParams as E, type DepartmentSearchResult as F, type DepartmentSearchScope as G, type DepartmentSelectFieldProps as H, type DepartmentTreeNode as I, type DigitalSignatureFieldProps as J, type DigitalSignatureValue as K, type EditorChoiceOption as L, type EditorFieldProps as M, type EditorToolbarAction as N, type FieldBehavior as O, type FieldDefinition as P, type FieldLayoutNode as Q, type FieldValueSyncConfig as R, type FilePreviewCapability as S, type FilePreviewCapabilityBatch as T, type FilePreviewMetadata as U, type FilePreviewProvider as V, type FilePreviewRenderMode as W, type FilePreviewRequest as X, type FilePreviewSurface as Y, type FilePreviewType as Z, type FormAppearanceConfig as _, type AddressValue as a, type RuntimeDataQueryResult as a$, type FormDataQueryParams as a0, type FormEffect as a1, type FormEffectAction as a2, type FormEffectCondition as a3, type FormEffectConditionOperator as a4, type FormEngineConfig as a5, type FormEngineMode as a6, type FormInstanceData as a7, type FormLayoutNode as a8, type FormRuntimeApi as a9, type MultiSelectFieldProps as aA, type NumberFieldProps as aB, type OptionItem as aC, type OptionSourceConfig as aD, type OptionSourceType as aE, type PeopleShortcutConfig as aF, type PeopleShortcutType as aG, type PreparedFilePreview as aH, type PreviewImageItem as aI, type PreviewParams as aJ, type ProcessAction as aK, type ProcessBasicInfo as aL, type ProcessDefinition as aM, type ProcessNodeType as aN, ProcessPreview as aO, type ProcessPreviewProps as aP, type ProcessRoute as aQ, type ProcessStatus as aR, type ProcessTask as aS, type RadioFieldProps as aT, type ResubmitParams as aU, type ReturnParams as aV, type ReturnPolicy as aW, type ReturnableNode as aX, type ReturnableNodeResult as aY, type RuntimeAuthHeadersProvider as aZ, type RuntimeDataQueryParams as a_, type FormRuntimeApiConfig as aa, type FormRuntimeConfig as ab, type FormSchema as ac, FormSection as ad, type FormSectionProps as ae, type FormSubmitBehavior as af, type FormTemplateConfig as ag, type GridLayoutCell as ah, type GridLayoutNode as ai, type ImageCompressionConfig as aj, type ImageCompressionVariantConfig as ak, type ImageFieldProps as al, type ImageVariant as am, type InitiatorSelectCandidate as an, type InitiatorSelectRequirement as ao, type InitiatorSelectScope as ap, type InitiatorSelectedApprovers as aq, type JSONFieldProps as ar, type LayoutVisibleWhen as as, type LinkedFormOptionConfig as at, type LocationFieldProps as au, type LocationValue as av, type LowcodePageMeta as aw, type LowcodePageNode as ax, type LowcodePageNodeType as ay, type LowcodePageSchema as az, type ApprovalActionType as b, type RuntimeRequestConfig as b0, type RuntimeResponse as b1, type RuntimeUploadOptions as b2, type RuntimeUploadProvider as b3, type SaveTaskParams as b4, type SectionLayoutNode as b5, type SelectFieldProps as b6, type SerialNumberFieldProps as b7, type SignaturePoint as b8, type StandardFormPageMode as b9, type StatusMeta as ba, type StepLayoutItem as bb, type StepsLayoutNode as bc, type SubFormColumn as bd, type SubFormFieldProps as be, type TabLayoutItem as bf, type TabsLayoutNode as bg, type TaskStatus as bh, type TextAreaFieldProps as bi, type TextFieldProps as bj, type TextShortcutConfig as bk, type TextShortcutType as bl, type TransferParams as bm, type UserDisplayFormat as bn, type UserItem as bo, type UserSelectFieldProps as bp, type ValidationPreset as bq, type ValidationRule as br, type ViewPermissionQueryParams as bs, type ViewPermissionSummary as bt, type WithdrawParams as bu, type ApprovalPermission as c, ApprovalTimeline as d, type ApprovalTimelineProps as e, type ApproveParams as f, type AssociationFormConfig as g, type AssociationFormFieldProps as h, type AssociationValue as i, type AttachmentFieldProps as j, type AttachmentImageVariants as k, type AttachmentItem as l, type BaseLayoutNode as m, type CascadeSelectFieldProps as n, type ChangeRecord as o, type ChangeRecordListResponse as p, type ChangeRecordQueryParams as q, type CheckboxFieldProps as r, type DataLinkageCondition as s, type DataLinkageConfig as t, type DateFieldProps as u, type DateRangeRestriction as v, type DateRestrictionConfig as w, type DateShortcutConfig as x, type DateShortcutType as y, type DefaultValueLinkageConfig as z };
|
|
@@ -1188,6 +1188,60 @@ interface StatusMeta {
|
|
|
1188
1188
|
tone: 'brand' | 'success' | 'danger' | 'neutral' | 'warning';
|
|
1189
1189
|
}
|
|
1190
1190
|
|
|
1191
|
+
type FilePreviewType = 'image' | 'video' | 'audio' | 'pdf' | 'spreadsheet' | 'text' | 'office' | 'download';
|
|
1192
|
+
type FilePreviewRenderMode = 'inline' | 'image-transcode' | 'image-heic' | 'pdfjs' | 'excel-basic' | 'excel-client' | 'text' | 'text-client' | 'docx-html' | 'onlyoffice' | 'office-text' | 'download';
|
|
1193
|
+
type FilePreviewSurface = 'media' | 'document' | 'download';
|
|
1194
|
+
type FilePreviewProvider = 'browser' | 'platform' | 'onlyoffice' | 'none';
|
|
1195
|
+
interface FilePreviewCapability {
|
|
1196
|
+
key?: string;
|
|
1197
|
+
extension?: string;
|
|
1198
|
+
previewType?: FilePreviewType;
|
|
1199
|
+
renderMode?: FilePreviewRenderMode;
|
|
1200
|
+
previewSurface?: FilePreviewSurface;
|
|
1201
|
+
previewProvider?: FilePreviewProvider;
|
|
1202
|
+
canPreview?: boolean;
|
|
1203
|
+
canDownload?: boolean;
|
|
1204
|
+
unsupportedReason?: string;
|
|
1205
|
+
}
|
|
1206
|
+
interface FilePreviewMetadata extends FilePreviewCapability {
|
|
1207
|
+
capabilityVersion?: number;
|
|
1208
|
+
ticket?: string;
|
|
1209
|
+
appType?: string;
|
|
1210
|
+
fileName?: string;
|
|
1211
|
+
bucketName?: string;
|
|
1212
|
+
objectName?: string;
|
|
1213
|
+
size?: number;
|
|
1214
|
+
contentType?: string;
|
|
1215
|
+
downloadUrl?: string;
|
|
1216
|
+
previewUrl?: string;
|
|
1217
|
+
previewPageUrl?: string;
|
|
1218
|
+
metadataUrl?: string;
|
|
1219
|
+
imagePreviewUrl?: string;
|
|
1220
|
+
excelPreviewUrl?: string;
|
|
1221
|
+
textPreviewUrl?: string;
|
|
1222
|
+
officeTextPreviewUrl?: string;
|
|
1223
|
+
onlyofficeConfigUrl?: string;
|
|
1224
|
+
onlyofficeEnabled?: boolean;
|
|
1225
|
+
expiresIn?: number;
|
|
1226
|
+
}
|
|
1227
|
+
interface PreparedFilePreview {
|
|
1228
|
+
item: AttachmentItem;
|
|
1229
|
+
metadata: FilePreviewMetadata;
|
|
1230
|
+
direct: boolean;
|
|
1231
|
+
}
|
|
1232
|
+
type FilePreviewRequest = FormRuntimeApi['request'];
|
|
1233
|
+
interface FilePreviewCapabilityBatch {
|
|
1234
|
+
capabilityVersion?: number;
|
|
1235
|
+
onlyofficeEnabled?: boolean;
|
|
1236
|
+
items?: FilePreviewCapability[];
|
|
1237
|
+
}
|
|
1238
|
+
interface PreviewImageItem {
|
|
1239
|
+
key: string;
|
|
1240
|
+
src: string;
|
|
1241
|
+
name: string;
|
|
1242
|
+
revokeOnClose?: boolean;
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1191
1245
|
interface ApprovalTimelineProps {
|
|
1192
1246
|
tasks: ProcessTask[];
|
|
1193
1247
|
className?: string;
|
|
@@ -1207,4 +1261,4 @@ interface ProcessPreviewProps {
|
|
|
1207
1261
|
}
|
|
1208
1262
|
declare const ProcessPreview: React__default.FC<ProcessPreviewProps>;
|
|
1209
1263
|
|
|
1210
|
-
export { type
|
|
1264
|
+
export { type FormDataDeleteParams as $, type AddressFieldProps as A, type BaseFieldProps as B, type CascadeDateFieldProps as C, type DataFilter as D, type DepartmentSearchParams as E, type DepartmentSearchResult as F, type DepartmentSearchScope as G, type DepartmentSelectFieldProps as H, type DepartmentTreeNode as I, type DigitalSignatureFieldProps as J, type DigitalSignatureValue as K, type EditorChoiceOption as L, type EditorFieldProps as M, type EditorToolbarAction as N, type FieldBehavior as O, type FieldDefinition as P, type FieldLayoutNode as Q, type FieldValueSyncConfig as R, type FilePreviewCapability as S, type FilePreviewCapabilityBatch as T, type FilePreviewMetadata as U, type FilePreviewProvider as V, type FilePreviewRenderMode as W, type FilePreviewRequest as X, type FilePreviewSurface as Y, type FilePreviewType as Z, type FormAppearanceConfig as _, type AddressValue as a, type RuntimeDataQueryResult as a$, type FormDataQueryParams as a0, type FormEffect as a1, type FormEffectAction as a2, type FormEffectCondition as a3, type FormEffectConditionOperator as a4, type FormEngineConfig as a5, type FormEngineMode as a6, type FormInstanceData as a7, type FormLayoutNode as a8, type FormRuntimeApi as a9, type MultiSelectFieldProps as aA, type NumberFieldProps as aB, type OptionItem as aC, type OptionSourceConfig as aD, type OptionSourceType as aE, type PeopleShortcutConfig as aF, type PeopleShortcutType as aG, type PreparedFilePreview as aH, type PreviewImageItem as aI, type PreviewParams as aJ, type ProcessAction as aK, type ProcessBasicInfo as aL, type ProcessDefinition as aM, type ProcessNodeType as aN, ProcessPreview as aO, type ProcessPreviewProps as aP, type ProcessRoute as aQ, type ProcessStatus as aR, type ProcessTask as aS, type RadioFieldProps as aT, type ResubmitParams as aU, type ReturnParams as aV, type ReturnPolicy as aW, type ReturnableNode as aX, type ReturnableNodeResult as aY, type RuntimeAuthHeadersProvider as aZ, type RuntimeDataQueryParams as a_, type FormRuntimeApiConfig as aa, type FormRuntimeConfig as ab, type FormSchema as ac, FormSection as ad, type FormSectionProps as ae, type FormSubmitBehavior as af, type FormTemplateConfig as ag, type GridLayoutCell as ah, type GridLayoutNode as ai, type ImageCompressionConfig as aj, type ImageCompressionVariantConfig as ak, type ImageFieldProps as al, type ImageVariant as am, type InitiatorSelectCandidate as an, type InitiatorSelectRequirement as ao, type InitiatorSelectScope as ap, type InitiatorSelectedApprovers as aq, type JSONFieldProps as ar, type LayoutVisibleWhen as as, type LinkedFormOptionConfig as at, type LocationFieldProps as au, type LocationValue as av, type LowcodePageMeta as aw, type LowcodePageNode as ax, type LowcodePageNodeType as ay, type LowcodePageSchema as az, type ApprovalActionType as b, type RuntimeRequestConfig as b0, type RuntimeResponse as b1, type RuntimeUploadOptions as b2, type RuntimeUploadProvider as b3, type SaveTaskParams as b4, type SectionLayoutNode as b5, type SelectFieldProps as b6, type SerialNumberFieldProps as b7, type SignaturePoint as b8, type StandardFormPageMode as b9, type StatusMeta as ba, type StepLayoutItem as bb, type StepsLayoutNode as bc, type SubFormColumn as bd, type SubFormFieldProps as be, type TabLayoutItem as bf, type TabsLayoutNode as bg, type TaskStatus as bh, type TextAreaFieldProps as bi, type TextFieldProps as bj, type TextShortcutConfig as bk, type TextShortcutType as bl, type TransferParams as bm, type UserDisplayFormat as bn, type UserItem as bo, type UserSelectFieldProps as bp, type ValidationPreset as bq, type ValidationRule as br, type ViewPermissionQueryParams as bs, type ViewPermissionSummary as bt, type WithdrawParams as bu, type ApprovalPermission as c, ApprovalTimeline as d, type ApprovalTimelineProps as e, type ApproveParams as f, type AssociationFormConfig as g, type AssociationFormFieldProps as h, type AssociationValue as i, type AttachmentFieldProps as j, type AttachmentImageVariants as k, type AttachmentItem as l, type BaseLayoutNode as m, type CascadeSelectFieldProps as n, type ChangeRecord as o, type ChangeRecordListResponse as p, type ChangeRecordQueryParams as q, type CheckboxFieldProps as r, type DataLinkageCondition as s, type DataLinkageConfig as t, type DateFieldProps as u, type DateRangeRestriction as v, type DateRestrictionConfig as w, type DateShortcutConfig as x, type DateShortcutType as y, type DefaultValueLinkageConfig as z };
|
|
@@ -139,6 +139,8 @@ __export(components_exports, {
|
|
|
139
139
|
normalizeDataManagementList: () => normalizeDataManagementList,
|
|
140
140
|
normalizeFieldBehaviors: () => normalizeFieldBehaviors,
|
|
141
141
|
normalizeOperation: () => normalizeOperation,
|
|
142
|
+
normalizePreviewBlobContent: () => normalizePreviewBlobContent,
|
|
143
|
+
normalizePreviewBlobResponse: () => normalizePreviewBlobResponse,
|
|
142
144
|
normalizeRichTextHtml: () => normalizeRichTextHtml,
|
|
143
145
|
prepareFilePreview: () => prepareFilePreview,
|
|
144
146
|
previewProcess: () => previewProcess,
|
|
@@ -3371,6 +3373,64 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
3371
3373
|
"vue"
|
|
3372
3374
|
]);
|
|
3373
3375
|
var unwrapFilePreviewPayload = (payload) => payload?.data ?? payload?.result ?? payload;
|
|
3376
|
+
var getBinaryResponseMessage = (response) => String(
|
|
3377
|
+
response?.message || response?.error || response?.errorMessage || response?.data?.message || response?.data?.error || response?.result?.message || ""
|
|
3378
|
+
).trim();
|
|
3379
|
+
var normalizePreviewBlobResponse = (response) => {
|
|
3380
|
+
const payload = response;
|
|
3381
|
+
const candidates = [
|
|
3382
|
+
response,
|
|
3383
|
+
payload?.blob,
|
|
3384
|
+
payload?.data,
|
|
3385
|
+
payload?.data?.blob,
|
|
3386
|
+
payload?.result,
|
|
3387
|
+
payload?.result?.blob
|
|
3388
|
+
];
|
|
3389
|
+
const blob = candidates.find(
|
|
3390
|
+
(candidate) => typeof Blob !== "undefined" && candidate instanceof Blob
|
|
3391
|
+
);
|
|
3392
|
+
if (blob) return blob;
|
|
3393
|
+
throw new Error(getBinaryResponseMessage(payload) || "\u6587\u4EF6\u5185\u5BB9\u54CD\u5E94\u4E0D\u662F\u4E8C\u8FDB\u5236\u6570\u636E");
|
|
3394
|
+
};
|
|
3395
|
+
var isZipBytes = (bytes) => bytes.length >= 4 && bytes[0] === 80 && bytes[1] === 75 && (bytes[2] === 3 && bytes[3] === 4 || bytes[2] === 5 && bytes[3] === 6 || bytes[2] === 7 && bytes[3] === 8);
|
|
3396
|
+
var decodeBase64ZipBlob = async (blob) => {
|
|
3397
|
+
const prefix = (await blob.slice(0, 96).text()).replace(/^\uFEFF/, "").replace(/\s+/g, "");
|
|
3398
|
+
if (!prefix.startsWith("UEsDB")) return blob;
|
|
3399
|
+
if (blob.size > 32 * 1024 * 1024) {
|
|
3400
|
+
throw new Error("Base64 \u6587\u4EF6\u8D85\u8FC7\u6D4F\u89C8\u5668\u517C\u5BB9\u89E3\u7801\u4E0A\u9650");
|
|
3401
|
+
}
|
|
3402
|
+
const base64 = (await blob.text()).replace(/^\uFEFF/, "").replace(/\s+/g, "");
|
|
3403
|
+
if (!/^[A-Za-z0-9+/]+={0,2}$/.test(base64)) {
|
|
3404
|
+
throw new Error("\u6587\u4EF6\u5185\u5BB9\u662F\u65E0\u6548\u7684 Base64 \u4E8C\u8FDB\u5236\u6570\u636E");
|
|
3405
|
+
}
|
|
3406
|
+
let binary = "";
|
|
3407
|
+
try {
|
|
3408
|
+
binary = globalThis.atob(base64);
|
|
3409
|
+
} catch {
|
|
3410
|
+
throw new Error("\u6587\u4EF6\u5185\u5BB9\u662F\u65E0\u6548\u7684 Base64 \u4E8C\u8FDB\u5236\u6570\u636E");
|
|
3411
|
+
}
|
|
3412
|
+
const bytes = new Uint8Array(binary.length);
|
|
3413
|
+
for (let index = 0; index < binary.length; index += 1) {
|
|
3414
|
+
bytes[index] = binary.charCodeAt(index);
|
|
3415
|
+
}
|
|
3416
|
+
if (!isZipBytes(bytes)) {
|
|
3417
|
+
throw new Error("Base64 \u6587\u4EF6\u89E3\u7801\u540E\u4E0D\u662F\u6709\u6548\u7684 Office \u6587\u6863");
|
|
3418
|
+
}
|
|
3419
|
+
if (globalThis.btoa(binary).replace(/=+$/, "") !== base64.replace(/=+$/, "")) {
|
|
3420
|
+
throw new Error("\u6587\u4EF6\u5185\u5BB9\u662F\u65E0\u6548\u7684 Base64 \u4E8C\u8FDB\u5236\u6570\u636E");
|
|
3421
|
+
}
|
|
3422
|
+
return new Blob([bytes], { type: blob.type || "application/zip" });
|
|
3423
|
+
};
|
|
3424
|
+
var normalizePreviewBlobContent = async (response) => {
|
|
3425
|
+
const blob = normalizePreviewBlobResponse(response);
|
|
3426
|
+
if (String(blob.type || "").toLowerCase().includes("application/json")) {
|
|
3427
|
+
const payload = await blob.text().then((value) => JSON.parse(value)).catch(() => null);
|
|
3428
|
+
if (payload) {
|
|
3429
|
+
throw new Error(getBinaryResponseMessage(payload) || "\u6587\u4EF6\u5185\u5BB9\u8BF7\u6C42\u5931\u8D25");
|
|
3430
|
+
}
|
|
3431
|
+
}
|
|
3432
|
+
return decodeBase64ZipBlob(blob);
|
|
3433
|
+
};
|
|
3374
3434
|
var isDirectStorageItem = (item) => item.provider === "oss" || item.uploadProvider === "oss" || item.uploadProvider === "builtin-oss" || Boolean(item.storageCode);
|
|
3375
3435
|
var getPreviewItemKey = (item, index = 0) => getAttachmentItemIdentity(item) || item.id || item.uid || `${item.name || "file"}-${index}`;
|
|
3376
3436
|
var getPreviewSourceUrl = (item) => item.previewUrl || item.publicUrl || item.url || "";
|
|
@@ -3544,10 +3604,7 @@ var prepareFilePreview = async (options) => {
|
|
|
3544
3604
|
};
|
|
3545
3605
|
var loadPreviewBlob = async (request, url) => {
|
|
3546
3606
|
const response = await request({ url, method: "get", responseType: "blob" });
|
|
3547
|
-
|
|
3548
|
-
throw new Error("\u6587\u4EF6\u5185\u5BB9\u54CD\u5E94\u4E0D\u662F\u4E8C\u8FDB\u5236\u6570\u636E");
|
|
3549
|
-
}
|
|
3550
|
-
return response;
|
|
3607
|
+
return normalizePreviewBlobContent(response);
|
|
3551
3608
|
};
|
|
3552
3609
|
var convertHeicPreview = async (request, url) => {
|
|
3553
3610
|
const source = await loadPreviewBlob(request, url);
|
|
@@ -21392,14 +21449,18 @@ function createRuntimeRequest(context) {
|
|
|
21392
21449
|
}
|
|
21393
21450
|
});
|
|
21394
21451
|
}
|
|
21395
|
-
const
|
|
21396
|
-
|
|
21397
|
-
|
|
21398
|
-
|
|
21399
|
-
|
|
21400
|
-
|
|
21401
|
-
|
|
21402
|
-
|
|
21452
|
+
const isBinary = config.responseType === "blob";
|
|
21453
|
+
const response = await context.bridge?.invoke?.(
|
|
21454
|
+
isBinary ? "transport.download" : "transport.request",
|
|
21455
|
+
{
|
|
21456
|
+
path: config.url,
|
|
21457
|
+
method: config.method || "get",
|
|
21458
|
+
query: search?.toString(),
|
|
21459
|
+
body: config.data,
|
|
21460
|
+
headers: config.headers
|
|
21461
|
+
}
|
|
21462
|
+
);
|
|
21463
|
+
return isBinary ? normalizePreviewBlobResponse(response) : response;
|
|
21403
21464
|
};
|
|
21404
21465
|
}
|
|
21405
21466
|
function LowcodePageRenderer({ schema, context }) {
|