openxiangda 1.0.154 → 1.0.155

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.
@@ -59,6 +59,7 @@ OpenXiangda supports two workspace modes. Classic `sy-lowcode-app-workspace` pub
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
+ - ✅ When a custom editable React SPA surface genuinely needs `FormProvider`, set `config.api` from `usePageFormRuntimeApi()`; use `createPageFormRuntimeApi(sdk)` outside hooks. Never implement the bridge as `api.request: config => sdk.request(...)`, because JSON transport drops `responseType: "blob"` and breaks binary attachment previews.
62
63
  - ✅ 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
64
  - ✅ 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
65
  - ✅ 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.
@@ -89,6 +89,8 @@ OSS 浏览器直传所需的 CORS 规则在 `src/resources/storage/<code>.json`
89
89
 
90
90
  预览能力也由运行时统一接管:表单上下文使用 `ImageField` / `AttachmentField`;自定义 React SPA 页面展示任意业务数据中的只读附件时,从 `openxiangda/runtime/react` 使用 `ImagePreviewGrid` / `AttachmentPreviewList`,或使用 `useFilePreview({ items })` 接入自定义卡片、表格和详情操作。不要为只读附件伪造 `FormProvider`。
91
91
 
92
+ 自定义编辑页确需嵌入平台字段时,使用 `usePageFormRuntimeApi()` 生成 `FormProvider` 的 `config.api`;非 Hook 场景使用 `createPageFormRuntimeApi(sdk)`。不要把所有请求手工转给 `sdk.request()`,因为附件预览的 `responseType: "blob"` 必须走 PageSdk 二进制下载通道。
93
+
92
94
  ```tsx
93
95
  import { AttachmentPreviewList, ImagePreviewGrid } from "openxiangda/runtime/react"
94
96
 
@@ -134,6 +134,25 @@ export function RecordFiles({ record }) {
134
134
 
135
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
136
 
137
+ For a real custom edit surface that embeds platform form fields, adapt PageSdk with the public form runtime API instead of hand-writing a request bridge:
138
+
139
+ ```tsx
140
+ import { AttachmentField, FormProvider } from "openxiangda"
141
+ import { usePageFormRuntimeApi } from "openxiangda/runtime/react"
142
+
143
+ const api = usePageFormRuntimeApi()
144
+
145
+ <FormProvider
146
+ config={{ api, appType, formUuid: "training_lesson", mode: "edit" }}
147
+ schema={schema}
148
+ initialValues={values}
149
+ >
150
+ <AttachmentField fieldId="materials" label="Materials" />
151
+ </FormProvider>
152
+ ```
153
+
154
+ Use `createPageFormRuntimeApi(sdk)` when hooks are unavailable. Both APIs preserve JSON envelopes and route `responseType: "blob"` through `sdk.transport.download`. Never forward every form request to `sdk.request`; that method is the JSON channel and cannot return the Blob required by Office, image, audio, and video preview parsers.
155
+
137
156
  Shareable file preview ticket:
138
157
 
139
158
  ```ts
@@ -16,19 +16,19 @@
16
16
  | 8 | 移动端 antd-mobile 组件样式不生效 | 组件渲染但无样式 |
17
17
  | 9 | 数据格式理解错误导致展示异常 | 页面显示 `[object Object]` |
18
18
  | 10 | workspace publish 环境变量缺失 | `OPENXIANGDA_ACCESS_TOKEN is not set` |
19
- | 11 | DOCX 响应是 Base64 文本 | 文件流以 `UEsDB` 开头,`docx-preview` 无法解包 |
19
+ | 11 | DOCX 二进制契约异常 | 真实字节不是 `PK`,或自定义 FormProvider Blob 请求错误转给 JSON 通道 |
20
20
 
21
21
  ---
22
22
 
23
23
  ## 问题:DOCX 响应是 Base64 文本
24
24
 
25
- **症状**:ticket metadata 正常返回 `renderMode: "docx-html"` 和 `canPreview: true`,`/service/file/preview-by-ticket/:ticket` 也是 HTTP 200,但响应内容以 `UEsDB` 开头,Word 预览仍然解析失败。
25
+ **症状**:ticket metadata 正常返回 `renderMode: "docx-html"` 和 `canPreview: true`,`/service/file/preview-by-ticket/:ticket` 也是 HTTP 200,但 Word 预览仍然解析失败或提示“文件内容响应不是二进制数据”。
26
26
 
27
- **根因**:DOCX 本质是 ZIP。原始二进制应以 `PK`(十六进制 `50 4B 03 04`)开头;`UEsDB` 是这个 ZIP 内容再次经过 Base64 编码后的文本,不能直接交给 `docx-preview`。这不是 MIME、ticket ONLYOFFICE 配置问题。
27
+ **判定**:DOCX 本质是 ZIP,真实原始字节应以 `PK`(十六进制 `50 4B 03 04`)开头。Chrome DevTools 可能把二进制响应显示成 `UEsDB...`,这只是展示形式;使用 `response.arrayBuffer()`、下载文件或服务端探针检查真实前四字节。只有真实字节是 ASCII `UEsDB` 时,才是 Base64 包装对象。
28
28
 
29
- **解决方案**:升级平台服务端和 OpenXiangda SDK 到包含 Base64 Office 兼容解码的版本。服务端会对历史 Base64 DOCX 对象做严格 ZIP 魔数校验后恢复原始二进制,并按解码后的长度返回 Range;SDK 对旧服务端和直连文件流保留同样的浏览器端兜底。不要在业务页面自行调用 `atob` 或复制一套文件类型判断。
29
+ **解决方案**:若真实字节是 `UEsDB`,升级平台服务端和 OpenXiangda SDK,使用严格 ZIP 校验后的兼容解码。若真实字节已经是 `PK`,检查自定义编辑页的 `FormProvider`:`config.api` 必须来自 `usePageFormRuntimeApi()`,非 Hook 场景使用 `createPageFormRuntimeApi(sdk)`。不要手写 `api.request: config => sdk.request(...)`,也不要在业务页面自行调用 `atob`。
30
30
 
31
- **验证方式**:修复后的响应字节应以 `PK` 开头,`Content-Length` 应是解码后的二进制长度。若下载后的 DOCX 仍以可见文本 `UEsDB` 开头,说明服务端尚未升级或请求仍命中了旧节点。
31
+ **验证方式**:真实响应字节以 `PK` 开头;组件的 Blob 请求进入 `sdk.transport.download`,并最终向 DOCX 渲染器传入 `Blob`。若下载后的文件真实字节仍是 ASCII `UEsDB`,再检查服务端版本和多节点部署一致性。
32
32
 
33
33
  ---
34
34
 
@@ -164,6 +164,7 @@ Read these references only when writing or reviewing schema:
164
164
  - Always provide `options` for option components. `SelectField`, `MultiSelectField`, `RadioField`, `CheckboxField`, and `CascadeSelectField` must not be emitted with `options` undefined. See `references/component-guide.md` for the full list and `references/platform-data-model.md` for the `{label, value}` storage contract.
165
165
  - Do not emit raw native form controls in app/workspace source. For basic entry use `TextField`, `TextAreaField`, `NumberField`, `DateField`, `SelectField`, `RadioField`, etc.; for platform-specific entry use `UserSelectField`, `DepartmentSelectField`, `AttachmentField`, `ImageField`, `EditorField`, `DigitalSignatureField`, and `LocationField`.
166
166
  - For image thumbnails or lightweight detail previews, configure `imageCompression` on `ImageField` or `AttachmentField`. The submitted value still keeps the original `url`; compressed variants are written to `thumbUrl`, `previewUrl`, and `variants`.
167
+ - React SPA custom edit surfaces that render `FormProvider` must set `config.api` from `usePageFormRuntimeApi()` or `createPageFormRuntimeApi(sdk)`. Do not map all field requests to `sdk.request`, because attachment and image preview require the PageSdk Blob download channel.
167
168
  - For OSS-backed image or attachment fields, declare a storage resource first, then set `uploadProvider: "oss"` and `storageCode`. Do not hardcode OSS URLs or credentials in schema/page source; if compressed output uses `webp`, storage `allowedExtensions` must include `webp`.
168
169
  - Workflow form pages use the same workspace form structure plus workflow v3 configuration. In legacy workspaces, publish the form page bundle through workspace publish before treating it as complete. In React SPA workspaces, `workspace publish --form` syncs schema only, and the SPA default process pages render through `runtime deploy`.
169
170
  - After editing one form, use `workspace publish --form <formCode>` or preview `--changed --dry-run`; do not run full workspace publish by default.
@@ -128,5 +128,6 @@ Read these references only when editing page code:
128
128
  - Pick components per `references/component-guide.md`: prefer the platform component, fall back to Ant Design / antd-mobile wrappers, and only build a custom component when neither fits. In app/workspace page code, do not emit raw `<input>`, `<select>`, `<textarea>`, file inputs, hand-written pickers, or hand-written uploaders.
129
129
  - When a page misbehaves (lost styles, `options is undefined`, option labels showing raw values, etc.), consult `references/troubleshooting.md` before patching symptoms.
130
130
  - For custom portal pages and business modals, do not temporarily embed a single `FormProvider` field component from the standard form runtime. If a standard component is required, navigate to a full standard form page or render a complete `StandardFormPage` inside a dedicated carrier route.
131
+ - If a complete custom edit surface intentionally embeds platform fields in `FormProvider`, set `config.api` from `usePageFormRuntimeApi()` (or `createPageFormRuntimeApi(sdk)` outside hooks). Never hand-write a JSON-only `sdk.request` bridge; it breaks Blob preview and download contracts.
131
132
  - Keep PC and mobile portal styles separate. Do not share one form UI implementation across both viewports unless the surrounding shell, modal layer, date picker, and bottom-sheet behavior have been tested in both contexts.
132
133
  - After introducing Ant Design overlays, date/datetime fields, or mobile bottom-sheet selectors, verify that global button, modal, picker, and sheet styles do not leak into the host business page.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openxiangda",
3
- "version": "1.0.154",
3
+ "version": "1.0.155",
4
4
  "description": "OpenXiangda CLI, workspace build tools, runtime SDK, and form components.",
5
5
  "private": false,
6
6
  "bin": {