openxiangda 1.0.148 → 1.0.150

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.
Files changed (35) hide show
  1. package/README.md +1 -1
  2. package/openxiangda-skills/SKILL.md +1 -1
  3. package/openxiangda-skills/references/automation-v3.md +1 -1
  4. package/openxiangda-skills/references/connector-resources.md +1 -1
  5. package/openxiangda-skills/references/pages/page-sdk.md +19 -0
  6. package/openxiangda-skills/references/resource-manifest-cheatsheet.md +2 -2
  7. package/openxiangda-skills/references/workflow-v3.md +1 -1
  8. package/openxiangda-skills/skills/openxiangda-workflow-automation/SKILL.md +1 -1
  9. package/package.json +1 -1
  10. package/packages/sdk/dist/{ProcessPreview-BoblxCUt.d.mts → ProcessPreview-BOCARAvP.d.mts} +9 -1
  11. package/packages/sdk/dist/{ProcessPreview-BoblxCUt.d.ts → ProcessPreview-BOCARAvP.d.ts} +9 -1
  12. package/packages/sdk/dist/components/index.cjs +33 -21
  13. package/packages/sdk/dist/components/index.cjs.map +1 -1
  14. package/packages/sdk/dist/components/index.d.mts +4 -4
  15. package/packages/sdk/dist/components/index.d.ts +4 -4
  16. package/packages/sdk/dist/components/index.mjs +33 -21
  17. package/packages/sdk/dist/components/index.mjs.map +1 -1
  18. package/packages/sdk/dist/{dataManagementApi-BCzfV88G.d.mts → dataManagementApi-CLMqf79O.d.mts} +1 -1
  19. package/packages/sdk/dist/{dataManagementApi-_FFNPv2e.d.ts → dataManagementApi-DhpRKmlp.d.ts} +1 -1
  20. package/packages/sdk/dist/runtime/index.cjs +670 -60
  21. package/packages/sdk/dist/runtime/index.cjs.map +1 -1
  22. package/packages/sdk/dist/runtime/index.d.mts +3 -3
  23. package/packages/sdk/dist/runtime/index.d.ts +3 -3
  24. package/packages/sdk/dist/runtime/index.mjs +672 -62
  25. package/packages/sdk/dist/runtime/index.mjs.map +1 -1
  26. package/packages/sdk/dist/runtime/react.cjs +299 -22
  27. package/packages/sdk/dist/runtime/react.cjs.map +1 -1
  28. package/packages/sdk/dist/runtime/react.d.mts +41 -2
  29. package/packages/sdk/dist/runtime/react.d.ts +41 -2
  30. package/packages/sdk/dist/runtime/react.mjs +299 -22
  31. package/packages/sdk/dist/runtime/react.mjs.map +1 -1
  32. package/templates/openxiangda-react-spa/AGENTS.md +7 -0
  33. package/templates/openxiangda-react-spa/src/app/router.tsx +6 -1
  34. package/templates/openxiangda-react-spa/src/pages/defaults/FilePreviewRoutePage.tsx +18 -33
  35. package/templates/sy-lowcode-app-workspace/examples/best-practices/src/js-code-nodes/sync_roles_to_platform/index.ts +1 -1
@@ -43,6 +43,7 @@ __export(runtime_exports, {
43
43
  ProcessTimeline: () => ProcessTimeline,
44
44
  PublicAccessClientError: () => PublicAccessClientError,
45
45
  PublicAccessGate: () => PublicAccessGate,
46
+ RuntimeAuthGuard: () => RuntimeAuthGuard,
46
47
  createAuthClient: () => createAuthClient,
47
48
  createBrowserPageBridge: () => createBrowserPageBridge,
48
49
  createBrowserPageContext: () => createBrowserPageContext,
@@ -756,6 +757,17 @@ var createPageSdk = (context) => {
756
757
  throw toSdkError(error, payload);
757
758
  }
758
759
  };
760
+ const createFileAccessTicket = (bucketName, objectName, fileName, action = "preview", options = {}) => request({
761
+ path: "/file/access-ticket",
762
+ method: "post",
763
+ body: {
764
+ bucketName,
765
+ objectName,
766
+ fileName,
767
+ action,
768
+ appType: resolveAppType(context, options.appType)
769
+ }
770
+ });
759
771
  const logout = () => request({
760
772
  path: "/api/auth/logout",
761
773
  method: "post"
@@ -2041,6 +2053,7 @@ var createPageSdk = (context) => {
2041
2053
  context,
2042
2054
  request,
2043
2055
  download,
2056
+ createFileAccessTicket,
2044
2057
  transport: {
2045
2058
  request,
2046
2059
  download
@@ -5569,14 +5582,14 @@ var useAuth = (options = {}) => {
5569
5582
  () => createAuthClient({
5570
5583
  appType: options.appType || runtime.appType,
5571
5584
  servicePrefix: options.servicePrefix || runtime.servicePrefix,
5572
- fetchImpl: options.fetchImpl || runtime.fetchImpl
5585
+ fetchImpl: options.fetchImpl || runtime.baseFetchImpl
5573
5586
  }),
5574
5587
  [
5575
5588
  options.appType,
5576
5589
  options.fetchImpl,
5577
5590
  options.servicePrefix,
5578
5591
  runtime.appType,
5579
- runtime.fetchImpl,
5592
+ runtime.baseFetchImpl,
5580
5593
  runtime.servicePrefix
5581
5594
  ]
5582
5595
  );
@@ -5855,7 +5868,19 @@ var LoginPage = ({
5855
5868
  };
5856
5869
  async function handleSuccess(data) {
5857
5870
  await onSuccess?.(data);
5858
- await runtime.reload();
5871
+ const accessToken = data.accessToken || data.token;
5872
+ const accessTokenOptions = {
5873
+ expiresAt: data.accessTokenExpiresAt
5874
+ };
5875
+ if (accessToken) {
5876
+ runtime.setAccessToken(accessToken, accessTokenOptions);
5877
+ }
5878
+ await runtime.reload(
5879
+ accessToken ? {
5880
+ accessToken,
5881
+ accessTokenOptions
5882
+ } : void 0
5883
+ );
5859
5884
  if (redirectOnSuccess && typeof window !== "undefined") {
5860
5885
  window.location.replace(
5861
5886
  redirectUrl || getCallbackUrl() || `/view/${auth.client.appType}`
@@ -6139,27 +6164,125 @@ var OpenXiangdaProvider = ({
6139
6164
  () => appType || resolveAppTypeFromLocation(),
6140
6165
  [appType]
6141
6166
  );
6142
- const [accessToken, setAccessTokenState] = (0, import_react14.useState)(null);
6167
+ const [, setAccessTokenState] = (0, import_react14.useState)(null);
6168
+ const [authState, setAuthState] = (0, import_react14.useState)({
6169
+ status: "unknown",
6170
+ error: null
6171
+ });
6143
6172
  const accessTokenRef = (0, import_react14.useRef)(null);
6144
- const setAccessToken = (0, import_react14.useCallback)(
6173
+ const refreshRequestRef = (0, import_react14.useRef)(null);
6174
+ const applyAccessToken = (0, import_react14.useCallback)(
6145
6175
  (nextAccessToken, options = {}) => {
6146
6176
  if (!nextAccessToken && options.clearIfToken && accessTokenRef.current?.token !== options.clearIfToken) {
6147
- return;
6177
+ return accessTokenRef.current;
6148
6178
  }
6149
6179
  const normalizedAccessToken = nextAccessToken || null;
6150
6180
  const nextState = normalizedAccessToken ? {
6151
6181
  token: normalizedAccessToken,
6152
6182
  scope: options.scope || "default",
6153
- path: options.path || null
6183
+ path: options.path || null,
6184
+ expiresAt: options.expiresAt
6154
6185
  } : null;
6155
6186
  accessTokenRef.current = nextState;
6156
6187
  setAccessTokenState(nextState);
6188
+ return nextState;
6157
6189
  },
6158
6190
  []
6159
6191
  );
6192
+ const setAccessToken = (0, import_react14.useCallback)(
6193
+ (nextAccessToken, options = {}) => {
6194
+ const previousState = accessTokenRef.current;
6195
+ const nextState = applyAccessToken(nextAccessToken, options);
6196
+ if (nextState) {
6197
+ if (nextState.scope === "public") return;
6198
+ setAuthState({
6199
+ status: "authenticated",
6200
+ error: null
6201
+ });
6202
+ } else if (previousState?.scope !== "public") {
6203
+ setAuthState({ status: "unauthenticated", error: null });
6204
+ }
6205
+ },
6206
+ [applyAccessToken]
6207
+ );
6208
+ const markUnauthenticated = (0, import_react14.useCallback)(
6209
+ (error) => {
6210
+ const runtimeError = normalizeRuntimeError(error);
6211
+ applyAccessToken(null);
6212
+ setAuthState({ status: "unauthenticated", error: runtimeError });
6213
+ },
6214
+ [applyAccessToken]
6215
+ );
6216
+ const refreshAccessToken = (0, import_react14.useCallback)(async () => {
6217
+ if (!resolvedAppType) return null;
6218
+ if (!refreshRequestRef.current) {
6219
+ setAuthState((prev) => ({ ...prev, status: "refreshing", error: null }));
6220
+ refreshRequestRef.current = (async () => {
6221
+ const response = await resolvedFetch(
6222
+ buildServiceUrl3(
6223
+ servicePrefix,
6224
+ `/openxiangda-api/v1/apps/${encodeURIComponent(
6225
+ resolvedAppType
6226
+ )}/auth/refresh`
6227
+ ),
6228
+ {
6229
+ method: "POST",
6230
+ credentials: "include",
6231
+ headers: {
6232
+ accept: "application/json",
6233
+ "content-type": "application/json"
6234
+ },
6235
+ body: "{}"
6236
+ }
6237
+ );
6238
+ const payload = await readJsonPayload(response);
6239
+ if (isRuntimeEnvelopeFailure(response, payload)) {
6240
+ throw createRuntimeHttpError(
6241
+ response,
6242
+ payload,
6243
+ payload?.message || `Token refresh failed: ${response.status}`
6244
+ );
6245
+ }
6246
+ const data = unwrapRuntimePayload(payload);
6247
+ const nextAccessToken = getRecordString(data, "accessToken") || getRecordString(data, "token");
6248
+ if (!nextAccessToken) {
6249
+ throw createRuntimeError({
6250
+ type: "unauthenticated",
6251
+ status: response.status,
6252
+ code: getRecordValue3(payload, "code"),
6253
+ message: "Token refresh response missing accessToken",
6254
+ payload
6255
+ });
6256
+ }
6257
+ const nextState = applyAccessToken(nextAccessToken, {
6258
+ expiresAt: getRecordNumber(data, "accessTokenExpiresAt")
6259
+ });
6260
+ setAuthState({
6261
+ status: "authenticated",
6262
+ error: null,
6263
+ refreshedAt: Date.now()
6264
+ });
6265
+ return nextState;
6266
+ })().catch((error) => {
6267
+ const runtimeError = normalizeRuntimeError(error);
6268
+ applyAccessToken(null);
6269
+ setAuthState({ status: "unauthenticated", error: runtimeError });
6270
+ throw runtimeError;
6271
+ }).finally(() => {
6272
+ refreshRequestRef.current = null;
6273
+ });
6274
+ }
6275
+ return refreshRequestRef.current;
6276
+ }, [applyAccessToken, resolvedAppType, resolvedFetch, servicePrefix]);
6160
6277
  const authorizedFetch = (0, import_react14.useMemo)(
6161
- () => createAuthorizedFetch(resolvedFetch, accessToken),
6162
- [accessToken, resolvedFetch]
6278
+ () => createAuthorizedFetch({
6279
+ appType: resolvedAppType,
6280
+ baseFetch: resolvedFetch,
6281
+ accessTokenRef,
6282
+ markUnauthenticated,
6283
+ refreshAccessToken
6284
+ }),
6285
+ [markUnauthenticated, refreshAccessToken, resolvedAppType, resolvedFetch]
6163
6286
  );
6164
6287
  const getAuthHeaders = (0, import_react14.useCallback)(() => {
6165
6288
  const state2 = accessTokenRef.current;
@@ -6185,13 +6308,13 @@ var OpenXiangdaProvider = ({
6185
6308
  return;
6186
6309
  }
6187
6310
  setState((prev) => ({ ...prev, loading: true, error: null }));
6188
- const requestFetch = options.accessToken !== void 0 ? createAuthorizedFetch(
6311
+ const requestFetch = options.accessToken !== void 0 ? createAccessTokenFetch(
6189
6312
  resolvedFetch,
6190
6313
  createAccessTokenState(
6191
6314
  options.accessToken || null,
6192
6315
  options.accessTokenOptions
6193
6316
  )
6194
- ) : createAuthorizedFetch(resolvedFetch, accessTokenRef.current);
6317
+ ) : authorizedFetch;
6195
6318
  try {
6196
6319
  const response = await requestFetch(
6197
6320
  buildServiceUrl3(
@@ -6213,19 +6336,29 @@ var OpenXiangdaProvider = ({
6213
6336
  payload?.message || `Runtime bootstrap failed: ${response.status}`
6214
6337
  );
6215
6338
  }
6339
+ const nextData = payload?.data || null;
6216
6340
  setState({
6217
- data: payload?.data || null,
6341
+ data: nextData,
6218
6342
  loading: false,
6219
6343
  error: null
6220
6344
  });
6345
+ if (isAuthenticatedBootstrap(nextData)) {
6346
+ setAuthState(
6347
+ (prev) => prev.status === "authenticated" ? prev : { status: "authenticated", error: null }
6348
+ );
6349
+ }
6221
6350
  } catch (error) {
6351
+ const runtimeError = normalizeRuntimeError(error);
6222
6352
  setState({
6223
6353
  data: null,
6224
6354
  loading: false,
6225
- error: normalizeRuntimeError(error)
6355
+ error: runtimeError
6226
6356
  });
6357
+ if (runtimeError.type === "unauthenticated") {
6358
+ setAuthState({ status: "unauthenticated", error: runtimeError });
6359
+ }
6227
6360
  }
6228
- }, [resolvedAppType, resolvedFetch, servicePrefix]);
6361
+ }, [authorizedFetch, resolvedAppType, resolvedFetch, servicePrefix]);
6229
6362
  (0, import_react14.useEffect)(() => {
6230
6363
  void reload();
6231
6364
  }, [reload]);
@@ -6236,6 +6369,7 @@ var OpenXiangdaProvider = ({
6236
6369
  servicePrefix,
6237
6370
  fetchImpl: authorizedFetch,
6238
6371
  baseFetchImpl: resolvedFetch,
6372
+ authState,
6239
6373
  getAuthHeaders,
6240
6374
  reload,
6241
6375
  setAccessToken
@@ -6247,7 +6381,8 @@ var OpenXiangdaProvider = ({
6247
6381
  resolvedAppType,
6248
6382
  resolvedFetch,
6249
6383
  servicePrefix,
6250
- state
6384
+ state,
6385
+ authState
6251
6386
  ]
6252
6387
  );
6253
6388
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(OpenXiangdaRuntimeContext.Provider, { value, children });
@@ -6514,7 +6649,7 @@ var useRuntimeAuth = () => {
6514
6649
  buildServiceUrl3(runtime.servicePrefix, "/api/sso/status"),
6515
6650
  { domain }
6516
6651
  );
6517
- const statusResponse = await runtime.fetchImpl(statusUrl, {
6652
+ const statusResponse = await runtime.baseFetchImpl(statusUrl, {
6518
6653
  credentials: "include",
6519
6654
  headers: { accept: "application/json" }
6520
6655
  });
@@ -6525,7 +6660,7 @@ var useRuntimeAuth = () => {
6525
6660
  enabled && (sso.forceLogin ?? sso.autoRedirect ?? true)
6526
6661
  );
6527
6662
  if (shouldUseSso) {
6528
- const loginUrlResponse = await runtime.fetchImpl(
6663
+ const loginUrlResponse = await runtime.baseFetchImpl(
6529
6664
  withQuery(buildServiceUrl3(runtime.servicePrefix, "/api/sso/login-url"), {
6530
6665
  domain,
6531
6666
  redirectUri,
@@ -6549,7 +6684,7 @@ var useRuntimeAuth = () => {
6549
6684
  }
6550
6685
  return attachCallback("/platform/login", redirectUri);
6551
6686
  },
6552
- [runtime.data?.app, runtime.fetchImpl, runtime.servicePrefix]
6687
+ [runtime.baseFetchImpl, runtime.data?.app, runtime.servicePrefix]
6553
6688
  );
6554
6689
  const redirectToLogin = (0, import_react14.useCallback)(
6555
6690
  async (options = {}) => {
@@ -6566,7 +6701,7 @@ var useRuntimeAuth = () => {
6566
6701
  [resolveLoginUrl2]
6567
6702
  );
6568
6703
  const logout = (0, import_react14.useCallback)(async () => {
6569
- const response = await runtime.fetchImpl(
6704
+ const response = await runtime.baseFetchImpl(
6570
6705
  buildServiceUrl3(runtime.servicePrefix, "/api/auth/logout"),
6571
6706
  {
6572
6707
  method: "POST",
@@ -6582,8 +6717,9 @@ var useRuntimeAuth = () => {
6582
6717
  payload?.message || `Logout failed: ${response.status}`
6583
6718
  );
6584
6719
  }
6720
+ runtime.setAccessToken(null);
6585
6721
  return payload;
6586
- }, [runtime.fetchImpl, runtime.servicePrefix]);
6722
+ }, [runtime.baseFetchImpl, runtime.servicePrefix, runtime.setAccessToken]);
6587
6723
  const logoutAndRedirect = (0, import_react14.useCallback)(
6588
6724
  async (options = {}) => {
6589
6725
  try {
@@ -6602,12 +6738,83 @@ var useRuntimeAuth = () => {
6602
6738
  resolveLoginUrl: resolveLoginUrl2
6603
6739
  };
6604
6740
  };
6741
+ var RuntimeAuthGuard = ({
6742
+ children,
6743
+ fallback = null,
6744
+ disabled = false,
6745
+ excludedPaths = [],
6746
+ ...redirectOptions
6747
+ }) => {
6748
+ const runtime = useOpenXiangda();
6749
+ const auth = useRuntimeAuth();
6750
+ const redirectedRef = (0, import_react14.useRef)(false);
6751
+ const currentPath = getCurrentPathname2();
6752
+ const excluded = isRuntimeAuthGuardExcluded(
6753
+ currentPath,
6754
+ runtime.appType,
6755
+ excludedPaths
6756
+ );
6757
+ const shouldRedirect = !disabled && !excluded && !runtime.loading && (runtime.authState.status === "unauthenticated" || runtime.error?.type === "unauthenticated");
6758
+ (0, import_react14.useEffect)(() => {
6759
+ if (!shouldRedirect || redirectedRef.current) return;
6760
+ redirectedRef.current = true;
6761
+ void auth.redirectToLogin({
6762
+ ...redirectOptions,
6763
+ redirectUri: redirectOptions.redirectUri || getCurrentHref4()
6764
+ }).catch(() => {
6765
+ redirectedRef.current = false;
6766
+ });
6767
+ }, [
6768
+ auth,
6769
+ redirectOptions.domain,
6770
+ redirectOptions.loginUrl,
6771
+ redirectOptions.redirectUri,
6772
+ redirectOptions.replace,
6773
+ shouldRedirect
6774
+ ]);
6775
+ if (excluded) return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children });
6776
+ if (shouldRedirect) return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children: fallback });
6777
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children });
6778
+ };
6605
6779
  var buildServiceUrl3 = (servicePrefix, path) => {
6606
6780
  const prefix = servicePrefix.endsWith("/") ? servicePrefix.slice(0, -1) : servicePrefix;
6607
6781
  const suffix = path.startsWith("/") ? path : `/${path}`;
6608
6782
  return `${prefix}${suffix}`;
6609
6783
  };
6610
- var createAuthorizedFetch = (baseFetch, accessToken) => {
6784
+ var createAuthorizedFetch = ({
6785
+ appType,
6786
+ baseFetch,
6787
+ accessTokenRef,
6788
+ refreshAccessToken,
6789
+ markUnauthenticated
6790
+ }) => (async (input, init = {}) => {
6791
+ const currentTokenState = accessTokenRef.current;
6792
+ const response = await createAccessTokenFetch(
6793
+ baseFetch,
6794
+ currentTokenState
6795
+ )(input, init);
6796
+ if (!shouldAttemptAuthRefresh({
6797
+ appType,
6798
+ input,
6799
+ init,
6800
+ tokenState: currentTokenState
6801
+ })) {
6802
+ return response;
6803
+ }
6804
+ if (!await isUnauthenticatedResponse(response)) return response;
6805
+ try {
6806
+ const refreshedTokenState = await refreshAccessToken();
6807
+ if (!refreshedTokenState) return response;
6808
+ return await createAccessTokenFetch(
6809
+ baseFetch,
6810
+ refreshedTokenState
6811
+ )(input, init);
6812
+ } catch (error) {
6813
+ markUnauthenticated(error);
6814
+ return response;
6815
+ }
6816
+ });
6817
+ var createAccessTokenFetch = (baseFetch, accessToken) => {
6611
6818
  if (!accessToken) return baseFetch;
6612
6819
  return ((input, init = {}) => {
6613
6820
  const token = resolveAccessTokenForCurrentRoute(accessToken);
@@ -6625,8 +6832,53 @@ var createAuthorizedFetch = (baseFetch, accessToken) => {
6625
6832
  var createAccessTokenState = (accessToken, options = {}) => accessToken ? {
6626
6833
  token: accessToken,
6627
6834
  scope: options.scope || "default",
6628
- path: options.path || null
6835
+ path: options.path || null,
6836
+ expiresAt: options.expiresAt
6629
6837
  } : null;
6838
+ var shouldAttemptAuthRefresh = ({
6839
+ appType,
6840
+ input,
6841
+ init,
6842
+ tokenState
6843
+ }) => {
6844
+ if (!appType) return false;
6845
+ if (tokenState?.scope === "public") return false;
6846
+ if (isPublicRoutePath(normalizeRoutePath(getCurrentPathname2()))) return false;
6847
+ if (hasAuthorizationHeader(init?.headers)) return false;
6848
+ const pathname = getFetchInputPathname(input);
6849
+ if (!pathname) return false;
6850
+ if (/\/openxiangda-api\/v1\/apps\/[^/]+\/auth(?:\/|$)/.test(pathname)) {
6851
+ return false;
6852
+ }
6853
+ if (/\/openxiangda-api\/v1\/apps\/[^/]+\/public\/session(?:\/|$)/.test(pathname)) {
6854
+ return false;
6855
+ }
6856
+ if (/\/openxiangda-api\/v1\/auth(?:\/|$)/.test(pathname)) return false;
6857
+ if (/\/api\/auth\/logout(?:\/|$)/.test(pathname)) return false;
6858
+ if (/\/api\/sso(?:\/|$)/.test(pathname)) return false;
6859
+ return true;
6860
+ };
6861
+ var isUnauthenticatedResponse = async (response) => {
6862
+ if (response.status === 401) return true;
6863
+ const payload = await readJsonPayload(response.clone());
6864
+ const code = getRecordValue3(payload, "code");
6865
+ return classifyRuntimeError(response.status, code) === "unauthenticated";
6866
+ };
6867
+ var hasAuthorizationHeader = (headers) => {
6868
+ if (!headers) return false;
6869
+ const normalized = new Headers(headers);
6870
+ return normalized.has("authorization");
6871
+ };
6872
+ var getFetchInputPathname = (input) => {
6873
+ const text = typeof input === "string" ? input : input instanceof URL ? input.toString() : typeof Request !== "undefined" && input instanceof Request ? input.url : String(input || "");
6874
+ if (!text) return "";
6875
+ try {
6876
+ const base = typeof window !== "undefined" ? window.location.origin : "http://localhost";
6877
+ return new URL(text, base).pathname;
6878
+ } catch {
6879
+ return text.split(/[?#]/, 1)[0] || "";
6880
+ }
6881
+ };
6630
6882
  var resolveAccessTokenForCurrentRoute = (accessToken) => {
6631
6883
  if (accessToken.scope !== "public") return accessToken.token;
6632
6884
  const scopedPath = normalizeRoutePath(accessToken.path);
@@ -6811,6 +7063,31 @@ var getRecordString = (value, key) => {
6811
7063
  const result = getRecordValue3(value, key);
6812
7064
  return typeof result === "string" ? result : void 0;
6813
7065
  };
7066
+ var getRecordNumber = (value, key) => {
7067
+ const result = getRecordValue3(value, key);
7068
+ const numberValue = Number(result);
7069
+ return Number.isFinite(numberValue) ? numberValue : void 0;
7070
+ };
7071
+ var unwrapRuntimePayload = (payload) => {
7072
+ if (!payload || typeof payload !== "object") return payload;
7073
+ const record = payload;
7074
+ return "data" in record ? record.data : payload;
7075
+ };
7076
+ var isAuthenticatedBootstrap = (value) => {
7077
+ if (!value || typeof value !== "object") return false;
7078
+ const user = toRuntimeRecord(getRecordValue3(value, "user"));
7079
+ if (!getRecordValue3(user, "id") && !getRecordValue3(user, "username")) {
7080
+ return false;
7081
+ }
7082
+ return !getRecordValue3(user, "publicAccess");
7083
+ };
7084
+ var isRuntimeAuthGuardExcluded = (path, appType, excludedPaths) => {
7085
+ const normalizedPath = normalizeRoutePath(path);
7086
+ if (isPublicRoutePath(normalizedPath)) return true;
7087
+ const loginPath = normalizeRoutePath(`/view/${encodeURIComponent(appType)}/login`);
7088
+ if (appType && normalizedPath === loginPath) return true;
7089
+ return excludedPaths.map((item) => normalizeRoutePath(item)).some((item) => item && normalizedPath === item);
7090
+ };
6814
7091
  var resolveAppTypeFromLocation = () => {
6815
7092
  if (typeof window === "undefined") return "";
6816
7093
  const segments = window.location.pathname.split("/").filter(Boolean);
@@ -7648,11 +7925,11 @@ function createFormRuntimeApi(config) {
7648
7925
  });
7649
7926
  return normalizeFileTicketResult(baseUrl, response.data || response.result);
7650
7927
  },
7651
- createFileAccessTicket: async (bucketName, objectName, fileName, purpose = "preview") => {
7928
+ createFileAccessTicket: async (bucketName, objectName, fileName, purpose = "preview", options = {}) => {
7652
7929
  const response = await request({
7653
7930
  url: "/file/access-ticket",
7654
7931
  method: "post",
7655
- data: { bucketName, objectName, fileName, purpose }
7932
+ data: { bucketName, objectName, fileName, purpose, appType: options.appType }
7656
7933
  });
7657
7934
  return normalizeFileTicketResult(baseUrl, response.data || response.result);
7658
7935
  },
@@ -10757,6 +11034,11 @@ function canPreview(item) {
10757
11034
  const ext = getFileExtension(item.name);
10758
11035
  return isImageFile(item.name, item.contentType) || ["mp4", "webm", "ogg", "mov", "m4v"].includes(ext) || PREVIEW_PAGE_EXTENSIONS.includes(ext);
10759
11036
  }
11037
+ function appendTicketIfMissing(url, ticket) {
11038
+ if (!url || !ticket || /[?&]ticket=/.test(url)) return url;
11039
+ const separator = url.includes("?") ? "&" : "?";
11040
+ return `${url}${separator}ticket=${encodeURIComponent(ticket)}`;
11041
+ }
10760
11042
  function AttachmentFieldPC({
10761
11043
  fieldId,
10762
11044
  behavior,
@@ -10872,16 +11154,15 @@ function AttachmentFieldPC({
10872
11154
  item.bucketName || bucketName,
10873
11155
  item.objectName,
10874
11156
  item.name,
10875
- "preview"
11157
+ "preview",
11158
+ { appType: item.appType || config.appType }
10876
11159
  );
10877
11160
  const ticketValue = typeof ticket === "string" ? { previewUrl: ticket } : ticket;
10878
- if (ticketValue?.previewPageUrl && ticketValue?.ticket) {
10879
- const separator = ticketValue.previewPageUrl.includes("?") ? "&" : "?";
10880
- return `${ticketValue.previewPageUrl}${separator}ticket=${encodeURIComponent(ticketValue.ticket)}`;
11161
+ if (ticketValue?.previewPageUrl) {
11162
+ return appendTicketIfMissing(ticketValue.previewPageUrl, ticketValue.ticket);
10881
11163
  }
10882
11164
  if (ticketValue?.ticket && PREVIEW_PAGE_EXTENSIONS.includes(getFileExtension(item.name))) {
10883
- const separator = previewPagePath.includes("?") ? "&" : "?";
10884
- return `${previewPagePath}${separator}ticket=${encodeURIComponent(ticketValue.ticket)}`;
11165
+ return appendTicketIfMissing(previewPagePath, ticketValue.ticket);
10885
11166
  }
10886
11167
  return ticketValue?.previewUrl || ticketValue?.url || "";
10887
11168
  }
@@ -11123,6 +11404,11 @@ function canPreview2(item) {
11123
11404
  const ext = getFileExtension(item.name);
11124
11405
  return isImageFile(item.name, item.contentType) || ["mp4", "webm", "ogg", "mov", "m4v"].includes(ext) || PREVIEW_PAGE_EXTENSIONS2.includes(ext);
11125
11406
  }
11407
+ function appendTicketIfMissing2(url, ticket) {
11408
+ if (!url || !ticket || /[?&]ticket=/.test(url)) return url;
11409
+ const separator = url.includes("?") ? "&" : "?";
11410
+ return `${url}${separator}ticket=${encodeURIComponent(ticket)}`;
11411
+ }
11126
11412
  function AttachmentFieldMobile({
11127
11413
  fieldId,
11128
11414
  behavior,
@@ -11271,16 +11557,15 @@ function AttachmentFieldMobile({
11271
11557
  item.bucketName || bucketName,
11272
11558
  item.objectName,
11273
11559
  item.name,
11274
- "preview"
11560
+ "preview",
11561
+ { appType: item.appType || config.appType }
11275
11562
  );
11276
11563
  const ticketValue = typeof ticket === "string" ? { previewUrl: ticket } : ticket;
11277
- if (ticketValue?.previewPageUrl && ticketValue?.ticket) {
11278
- const separator = ticketValue.previewPageUrl.includes("?") ? "&" : "?";
11279
- return `${ticketValue.previewPageUrl}${separator}ticket=${encodeURIComponent(ticketValue.ticket)}`;
11564
+ if (ticketValue?.previewPageUrl) {
11565
+ return appendTicketIfMissing2(ticketValue.previewPageUrl, ticketValue.ticket);
11280
11566
  }
11281
11567
  if (ticketValue?.ticket && PREVIEW_PAGE_EXTENSIONS2.includes(getFileExtension(item.name))) {
11282
- const separator = previewPagePath.includes("?") ? "&" : "?";
11283
- return `${previewPagePath}${separator}ticket=${encodeURIComponent(ticketValue.ticket)}`;
11568
+ return appendTicketIfMissing2(previewPagePath, ticketValue.ticket);
11284
11569
  }
11285
11570
  return ticketValue?.previewUrl || ticketValue?.url || "";
11286
11571
  }
@@ -11411,6 +11696,11 @@ function canPreview3(item) {
11411
11696
  const ext = getFileExtension(item.name);
11412
11697
  return isImageFile(item.name, item.contentType) || ["mp4", "webm", "ogg", "mov", "m4v"].includes(ext) || PREVIEW_PAGE_EXTENSIONS3.includes(ext);
11413
11698
  }
11699
+ function appendTicketIfMissing3(url, ticket) {
11700
+ if (!url || !ticket || /[?&]ticket=/.test(url)) return url;
11701
+ const separator = url.includes("?") ? "&" : "?";
11702
+ return `${url}${separator}ticket=${encodeURIComponent(ticket)}`;
11703
+ }
11414
11704
  function AttachmentFieldReadonly({
11415
11705
  fieldId,
11416
11706
  readonlyClassName,
@@ -11421,7 +11711,7 @@ function AttachmentFieldReadonly({
11421
11711
  showFileTypeBadge = false,
11422
11712
  previewPagePath = "/file-preview"
11423
11713
  }) {
11424
- const { formData, api } = useFormContext();
11714
+ const { formData, api, config } = useFormContext();
11425
11715
  const { isMobile } = useDeviceDetect();
11426
11716
  const value = formData[fieldId] ?? [];
11427
11717
  if (value.length === 0) {
@@ -11446,15 +11736,14 @@ function AttachmentFieldReadonly({
11446
11736
  item.bucketName || bucketName,
11447
11737
  item.objectName,
11448
11738
  item.name,
11449
- "preview"
11739
+ "preview",
11740
+ { appType: item.appType || config.appType }
11450
11741
  );
11451
11742
  const ticketValue = typeof ticket === "string" ? { previewUrl: ticket } : ticket;
11452
- if (ticketValue?.previewPageUrl && ticketValue?.ticket) {
11453
- const separator = ticketValue.previewPageUrl.includes("?") ? "&" : "?";
11454
- url = `${ticketValue.previewPageUrl}${separator}ticket=${encodeURIComponent(ticketValue.ticket)}`;
11743
+ if (ticketValue?.previewPageUrl) {
11744
+ url = appendTicketIfMissing3(ticketValue.previewPageUrl, ticketValue.ticket);
11455
11745
  } else if (ticketValue?.ticket && PREVIEW_PAGE_EXTENSIONS3.includes(getFileExtension(item.name))) {
11456
- const separator = previewPagePath.includes("?") ? "&" : "?";
11457
- url = `${previewPagePath}${separator}ticket=${encodeURIComponent(ticketValue.ticket)}`;
11746
+ url = appendTicketIfMissing3(previewPagePath, ticketValue.ticket);
11458
11747
  } else {
11459
11748
  url = getTicketUrl(ticketValue, url);
11460
11749
  }
@@ -17163,7 +17452,7 @@ async function fetchRuntimeFormData(api, appType, params) {
17163
17452
  order: order ? JSON.stringify(order) : void 0
17164
17453
  }
17165
17454
  });
17166
- const payload = unwrapRuntimePayload(response);
17455
+ const payload = unwrapRuntimePayload2(response);
17167
17456
  const data = Array.isArray(payload?.data) ? payload.data : Array.isArray(payload) ? payload : [];
17168
17457
  return {
17169
17458
  data,
@@ -17220,7 +17509,7 @@ function FormProvider({
17220
17509
  let cancelled = false;
17221
17510
  api.getUserById("current").then((payload) => {
17222
17511
  if (cancelled || !payload) return;
17223
- const currentUser = normalizeUser(unwrapRuntimePayload(payload));
17512
+ const currentUser = normalizeUser(unwrapRuntimePayload2(payload));
17224
17513
  const departments = normalizeDepartmentArray(currentUser.departments);
17225
17514
  const currentDepartment = departments[0];
17226
17515
  const currentUserManagers = normalizeUserArray(
@@ -17617,7 +17906,7 @@ function needsCurrentUserRuntime(shortcutType) {
17617
17906
  ].includes(shortcutType)
17618
17907
  );
17619
17908
  }
17620
- function unwrapRuntimePayload(payload) {
17909
+ function unwrapRuntimePayload2(payload) {
17621
17910
  return payload?.data || payload?.result || payload?.user || payload;
17622
17911
  }
17623
17912
  function isBlankFormValue(value) {
@@ -19561,7 +19850,7 @@ var DraftManager = ({
19561
19850
  // packages/sdk/src/components/templates/FormSubmitTemplate.tsx
19562
19851
  var import_jsx_runtime96 = require("react/jsx-runtime");
19563
19852
  var SUPERVISOR_APPROVER_TYPE = "ext_target_approval_department_supervisor";
19564
- var unwrapRuntimePayload2 = (value) => value?.data ?? value?.result ?? value;
19853
+ var unwrapRuntimePayload3 = (value) => value?.data ?? value?.result ?? value;
19565
19854
  var normalizeSubmitFormType = (value) => {
19566
19855
  const raw = String(value || "").toLowerCase();
19567
19856
  return raw === "process" || raw === "flow" ? "process" : "form";
@@ -19758,7 +20047,7 @@ var InnerFormContent = ({
19758
20047
  return departmentId;
19759
20048
  }
19760
20049
  const runtimeUser = schema.runtime?.currentUser;
19761
- const loadedUser = runtimeUser || unwrapRuntimePayload2(await api.getUserById("current"));
20050
+ const loadedUser = runtimeUser || unwrapRuntimePayload3(await api.getUserById("current"));
19762
20051
  const departments = normalizeDepartmentOptions(loadedUser?.departments);
19763
20052
  if (departments.length === 0) {
19764
20053
  import_antd36.message.error("\u5F53\u524D\u8D26\u53F7\u672A\u5206\u914D\u90E8\u95E8\uFF0C\u65E0\u6CD5\u53D1\u8D77\u4E3B\u7BA1\u5BA1\u6279\u6D41\u7A0B");
@@ -22731,7 +23020,7 @@ var downloadBlobResponse = async (response, fallbackName) => {
22731
23020
  anchor.remove();
22732
23021
  window.URL.revokeObjectURL(url);
22733
23022
  };
22734
- var unwrapRuntimePayload3 = (payload) => {
23023
+ var unwrapRuntimePayload4 = (payload) => {
22735
23024
  const data = payload?.data?.result ?? payload?.result ?? payload?.data ?? payload;
22736
23025
  return data?.items || data?.list || data?.data || data?.records || data || [];
22737
23026
  };
@@ -22830,14 +23119,14 @@ function AsyncEntityFilterSelect({
22830
23119
  method: "get",
22831
23120
  params: keyword ? { keyword, pageSize: 20 } : { pageSize: 20 }
22832
23121
  });
22833
- rows = unwrapRuntimePayload3(response);
23122
+ rows = unwrapRuntimePayload4(response);
22834
23123
  }
22835
23124
  } else {
22836
23125
  const response = await api.request({
22837
23126
  url: keyword ? "/department/list" : "/department/root",
22838
23127
  method: "get"
22839
23128
  });
22840
- rows = unwrapRuntimePayload3(response);
23129
+ rows = unwrapRuntimePayload4(response);
22841
23130
  if (keyword) {
22842
23131
  const normalizedKeyword = keyword.toLowerCase();
22843
23132
  rows = rows.filter(
@@ -24623,23 +24912,337 @@ var getDetailBasePath = (appType, formUuid, formType) => {
24623
24912
  const detailType = isProcessKind("data-manage-list", formType) ? "processDetail" : "formDetail";
24624
24913
  return `/view/${appType}/${detailType}/${formUuid}`;
24625
24914
  };
24915
+ var unwrapRuntimePayload5 = (payload) => payload?.data ?? payload?.result ?? payload;
24916
+ var formatFileSize2 = (size) => {
24917
+ const value = Number(size || 0);
24918
+ if (!value) return "0 B";
24919
+ const units = ["B", "KB", "MB", "GB"];
24920
+ const index = Math.min(
24921
+ units.length - 1,
24922
+ Math.floor(Math.log(value) / Math.log(1024))
24923
+ );
24924
+ return `${(value / Math.pow(1024, index)).toFixed(index === 0 ? 0 : 1)} ${units[index]}`;
24925
+ };
24926
+ var toColumnName = (index) => {
24927
+ let value = index + 1;
24928
+ let name = "";
24929
+ while (value > 0) {
24930
+ const mod = (value - 1) % 26;
24931
+ name = String.fromCharCode(65 + mod) + name;
24932
+ value = Math.floor((value - mod) / 26);
24933
+ }
24934
+ return name;
24935
+ };
24936
+ var buildRowsTable = (rows = []) => {
24937
+ const maxColumns = rows.reduce(
24938
+ (count, row) => Math.max(count, Array.isArray(row) ? row.length : 0),
24939
+ 0
24940
+ );
24941
+ const columns = Array.from({ length: maxColumns }).map((_, index) => ({
24942
+ title: toColumnName(index),
24943
+ dataIndex: `col_${index}`,
24944
+ key: `col_${index}`,
24945
+ width: 160,
24946
+ render: (value) => /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_antd40.Typography.Text, { ellipsis: { tooltip: String(value ?? "") }, children: String(value ?? "") })
24947
+ }));
24948
+ const dataSource = rows.map((row, rowIndex) => {
24949
+ const record = { key: rowIndex };
24950
+ (Array.isArray(row) ? row : []).forEach((value, colIndex) => {
24951
+ record[`col_${colIndex}`] = value;
24952
+ });
24953
+ return record;
24954
+ });
24955
+ return { columns, dataSource };
24956
+ };
24957
+ var loadScriptOnce = (src) => new Promise((resolve, reject) => {
24958
+ if (!src || typeof document === "undefined") {
24959
+ reject(new Error("ONLYOFFICE \u811A\u672C\u5730\u5740\u4E0D\u53EF\u7528"));
24960
+ return;
24961
+ }
24962
+ const existed = document.querySelector(`script[src="${src}"]`);
24963
+ if (existed) {
24964
+ resolve();
24965
+ return;
24966
+ }
24967
+ const script = document.createElement("script");
24968
+ script.src = src;
24969
+ script.async = true;
24970
+ script.onload = () => resolve();
24971
+ script.onerror = () => reject(new Error("ONLYOFFICE \u811A\u672C\u52A0\u8F7D\u5931\u8D25"));
24972
+ document.body.appendChild(script);
24973
+ });
24974
+ var OnlyOfficePreview = ({
24975
+ configUrl,
24976
+ request,
24977
+ servicePrefix,
24978
+ ticket
24979
+ }) => {
24980
+ const editorId = (0, import_react83.useMemo)(
24981
+ () => `openxiangda-onlyoffice-${ticket.replace(/[^a-zA-Z0-9_-]/g, "") || "editor"}`,
24982
+ [ticket]
24983
+ );
24984
+ const [loading, setLoading] = (0, import_react83.useState)(false);
24985
+ const [error, setError] = (0, import_react83.useState)("");
24986
+ (0, import_react83.useEffect)(() => {
24987
+ let disposed = false;
24988
+ const load = async () => {
24989
+ setLoading(true);
24990
+ setError("");
24991
+ try {
24992
+ const response = await request({
24993
+ url: configUrl || `/file/onlyoffice/config/${encodeURIComponent(ticket)}`,
24994
+ method: "get"
24995
+ });
24996
+ const payload = unwrapRuntimePayload5(response);
24997
+ const scriptUrl = `${String(payload.documentServerUrl || "").replace(
24998
+ /\/+$/,
24999
+ ""
25000
+ )}/web-apps/apps/api/documents/api.js`;
25001
+ await loadScriptOnce(joinServicePath2(servicePrefix, scriptUrl));
25002
+ if (!disposed && typeof window !== "undefined" && window.DocsAPI?.DocEditor) {
25003
+ new window.DocsAPI.DocEditor(editorId, payload.config);
25004
+ }
25005
+ } catch (currentError) {
25006
+ if (!disposed) {
25007
+ setError(currentError?.message || "ONLYOFFICE \u9884\u89C8\u52A0\u8F7D\u5931\u8D25");
25008
+ }
25009
+ } finally {
25010
+ if (!disposed) {
25011
+ setLoading(false);
25012
+ }
25013
+ }
25014
+ };
25015
+ void load();
25016
+ return () => {
25017
+ disposed = true;
25018
+ };
25019
+ }, [configUrl, editorId, request, servicePrefix, ticket]);
25020
+ return /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { style: { minHeight: "calc(100vh - 180px)" }, children: [
25021
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_antd40.Spin, { tip: "\u6B63\u5728\u52A0\u8F7D ONLYOFFICE..." }) : null,
25022
+ error ? /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_antd40.Alert, { type: "warning", showIcon: true, message: error }) : null,
25023
+ /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { id: editorId, style: { height: "calc(100vh - 180px)", minHeight: 520 } })
25024
+ ] });
25025
+ };
24626
25026
  var BuiltinFilePreview = ({
25027
+ request,
24627
25028
  route,
24628
25029
  servicePrefix
24629
25030
  }) => {
24630
25031
  const ticket = pickRouteValue(route, "ticket");
25032
+ const [metadata, setMetadata] = (0, import_react83.useState)(null);
25033
+ const [payload, setPayload] = (0, import_react83.useState)(null);
25034
+ const [loading, setLoading] = (0, import_react83.useState)(false);
25035
+ const [payloadLoading, setPayloadLoading] = (0, import_react83.useState)(false);
25036
+ const [error, setError] = (0, import_react83.useState)("");
25037
+ const [reloadKey, setReloadKey] = (0, import_react83.useState)(0);
25038
+ (0, import_react83.useEffect)(() => {
25039
+ let disposed = false;
25040
+ setMetadata(null);
25041
+ setPayload(null);
25042
+ setError("");
25043
+ if (!ticket) return () => {
25044
+ disposed = true;
25045
+ };
25046
+ const loadMetadata = async () => {
25047
+ setLoading(true);
25048
+ try {
25049
+ const response = await request({
25050
+ url: `/file/access-ticket/${encodeURIComponent(ticket)}`,
25051
+ method: "get"
25052
+ });
25053
+ if (!disposed) {
25054
+ setMetadata(unwrapRuntimePayload5(response));
25055
+ }
25056
+ } catch (currentError) {
25057
+ if (!disposed) {
25058
+ setError(currentError?.message || "\u6587\u4EF6\u9884\u89C8\u4FE1\u606F\u52A0\u8F7D\u5931\u8D25");
25059
+ }
25060
+ } finally {
25061
+ if (!disposed) {
25062
+ setLoading(false);
25063
+ }
25064
+ }
25065
+ };
25066
+ void loadMetadata();
25067
+ return () => {
25068
+ disposed = true;
25069
+ };
25070
+ }, [request, reloadKey, ticket]);
25071
+ const resolvePreviewUrl = (url) => joinServicePath2(
25072
+ servicePrefix,
25073
+ url || `/file/preview-by-ticket/${encodeURIComponent(ticket)}`
25074
+ );
25075
+ const downloadUrl = metadata?.downloadUrl ? joinServicePath2(servicePrefix, metadata.downloadUrl) : "";
25076
+ (0, import_react83.useEffect)(() => {
25077
+ let disposed = false;
25078
+ setPayload(null);
25079
+ if (!metadata?.renderMode || ["pdfjs", "inline", "download", "onlyoffice"].includes(metadata.renderMode)) {
25080
+ setPayloadLoading(false);
25081
+ return () => {
25082
+ disposed = true;
25083
+ };
25084
+ }
25085
+ const url = metadata.renderMode === "excel-basic" ? metadata.excelPreviewUrl : metadata.renderMode === "office-text" ? metadata.officeTextPreviewUrl : metadata.textPreviewUrl;
25086
+ if (!url) return () => {
25087
+ disposed = true;
25088
+ };
25089
+ const loadPayload = async () => {
25090
+ setPayloadLoading(true);
25091
+ try {
25092
+ const response = await request({ url, method: "get" });
25093
+ if (!disposed) {
25094
+ setPayload(unwrapRuntimePayload5(response));
25095
+ }
25096
+ } catch (currentError) {
25097
+ if (!disposed) {
25098
+ setError(currentError?.message || "\u6587\u4EF6\u9884\u89C8\u5185\u5BB9\u52A0\u8F7D\u5931\u8D25");
25099
+ }
25100
+ } finally {
25101
+ if (!disposed) {
25102
+ setPayloadLoading(false);
25103
+ }
25104
+ }
25105
+ };
25106
+ void loadPayload();
25107
+ return () => {
25108
+ disposed = true;
25109
+ };
25110
+ }, [metadata, request]);
24631
25111
  if (!ticket) {
24632
25112
  return /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_antd40.Card, { style: { margin: 16 }, children: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_antd40.Empty, { description: "\u7F3A\u5C11\u6587\u4EF6\u8BBF\u95EE\u7968\u636E" }) });
24633
25113
  }
24634
- const src = joinServicePath2(servicePrefix, `/file/preview-by-ticket/${encodeURIComponent(ticket)}`);
24635
- return /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { style: { minHeight: "calc(100vh - 74px)", background: "#fff" }, children: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
24636
- "iframe",
24637
- {
24638
- title: "\u6587\u4EF6\u9884\u89C8",
24639
- src,
24640
- style: { width: "100%", minHeight: "calc(100vh - 74px)", border: 0 }
25114
+ const renderContent = () => {
25115
+ if (loading && !metadata) return /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_antd40.Spin, { tip: "\u6B63\u5728\u52A0\u8F7D\u6587\u4EF6\u4FE1\u606F..." });
25116
+ if (error) {
25117
+ return /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
25118
+ import_antd40.Alert,
25119
+ {
25120
+ type: "error",
25121
+ showIcon: true,
25122
+ message: error,
25123
+ action: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_antd40.Button, { onClick: () => setReloadKey((value) => value + 1), children: "\u91CD\u8BD5" })
25124
+ }
25125
+ );
24641
25126
  }
24642
- ) });
25127
+ if (!metadata) return /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_antd40.Empty, { description: "\u672A\u83B7\u53D6\u5230\u6587\u4EF6\u4FE1\u606F" });
25128
+ if (metadata.renderMode === "pdfjs") {
25129
+ return /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
25130
+ "iframe",
25131
+ {
25132
+ title: "PDF \u9884\u89C8",
25133
+ src: resolvePreviewUrl(metadata.previewUrl),
25134
+ style: { width: "100%", minHeight: "calc(100vh - 180px)", border: 0 }
25135
+ }
25136
+ );
25137
+ }
25138
+ if (metadata.renderMode === "inline" && metadata.previewType === "image") {
25139
+ return /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { style: { textAlign: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
25140
+ "img",
25141
+ {
25142
+ alt: metadata.fileName || "\u9644\u4EF6\u9884\u89C8",
25143
+ src: resolvePreviewUrl(metadata.previewUrl),
25144
+ style: { maxWidth: "100%", maxHeight: "calc(100vh - 190px)" }
25145
+ }
25146
+ ) });
25147
+ }
25148
+ if (metadata.renderMode === "inline" && metadata.previewType === "video") {
25149
+ return /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
25150
+ "video",
25151
+ {
25152
+ controls: true,
25153
+ playsInline: true,
25154
+ preload: "metadata",
25155
+ src: resolvePreviewUrl(metadata.previewUrl),
25156
+ style: { width: "100%", maxHeight: "calc(100vh - 190px)" }
25157
+ }
25158
+ );
25159
+ }
25160
+ if (metadata.renderMode === "excel-basic") {
25161
+ if (payloadLoading) return /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_antd40.Spin, { tip: "\u6B63\u5728\u89E3\u6790 Excel..." });
25162
+ const sheets = Array.isArray(payload?.sheets) ? payload.sheets : [];
25163
+ if (!sheets.length) return /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_antd40.Empty, { description: "\u6682\u65E0\u53EF\u9884\u89C8\u7684\u5DE5\u4F5C\u8868" });
25164
+ return /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
25165
+ import_antd40.Tabs,
25166
+ {
25167
+ items: sheets.map((sheet) => {
25168
+ const table = buildRowsTable(sheet.rows || []);
25169
+ return {
25170
+ key: String(sheet.id || sheet.name),
25171
+ label: sheet.name || "Sheet",
25172
+ children: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
25173
+ import_antd40.Table,
25174
+ {
25175
+ bordered: true,
25176
+ size: "small",
25177
+ pagination: false,
25178
+ scroll: { x: true, y: "calc(100vh - 250px)" },
25179
+ columns: table.columns,
25180
+ dataSource: table.dataSource
25181
+ }
25182
+ )
25183
+ };
25184
+ })
25185
+ }
25186
+ );
25187
+ }
25188
+ if (metadata.renderMode === "text" || metadata.renderMode === "office-text") {
25189
+ if (payloadLoading) return /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_antd40.Spin, { tip: "\u6B63\u5728\u8BFB\u53D6\u6587\u672C..." });
25190
+ return /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("pre", { style: { whiteSpace: "pre-wrap", wordBreak: "break-word", margin: 0 }, children: [
25191
+ payload?.text || "\u6682\u65E0\u6587\u672C\u5185\u5BB9",
25192
+ payload?.truncated ? "\n\n... \u6587\u4EF6\u8F83\u5927\uFF0C\u4EC5\u5C55\u793A\u524D\u90E8\u5185\u5BB9\u3002" : ""
25193
+ ] });
25194
+ }
25195
+ if (metadata.renderMode === "onlyoffice") {
25196
+ return /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
25197
+ OnlyOfficePreview,
25198
+ {
25199
+ configUrl: metadata.onlyofficeConfigUrl,
25200
+ request,
25201
+ servicePrefix,
25202
+ ticket
25203
+ }
25204
+ );
25205
+ }
25206
+ return /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
25207
+ import_antd40.Empty,
25208
+ {
25209
+ description: "\u5F53\u524D\u6587\u4EF6\u7C7B\u578B\u6682\u4E0D\u652F\u6301\u9884\u89C8",
25210
+ image: import_antd40.Empty.PRESENTED_IMAGE_SIMPLE,
25211
+ children: downloadUrl ? /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_antd40.Button, { type: "primary", onClick: () => window.location.assign(downloadUrl), children: "\u4E0B\u8F7D\u6587\u4EF6" }) : null
25212
+ }
25213
+ );
25214
+ };
25215
+ return /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { style: { minHeight: "calc(100vh - 74px)", background: "#fff", padding: 16 }, children: [
25216
+ /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(
25217
+ import_antd40.Card,
25218
+ {
25219
+ size: "small",
25220
+ style: { marginBottom: 16 },
25221
+ extra: /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(import_jsx_runtime101.Fragment, { children: [
25222
+ /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_antd40.Button, { size: "small", onClick: () => setReloadKey((value) => value + 1), children: "\u5237\u65B0" }),
25223
+ downloadUrl ? /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
25224
+ import_antd40.Button,
25225
+ {
25226
+ size: "small",
25227
+ type: "primary",
25228
+ style: { marginLeft: 8 },
25229
+ onClick: () => window.location.assign(downloadUrl),
25230
+ children: "\u4E0B\u8F7D"
25231
+ }
25232
+ ) : null
25233
+ ] }),
25234
+ children: [
25235
+ /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_antd40.Typography.Text, { strong: true, children: metadata?.fileName || "\u9644\u4EF6\u9884\u89C8" }),
25236
+ metadata ? /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(import_antd40.Typography.Text, { type: "secondary", style: { marginLeft: 12 }, children: [
25237
+ (metadata.extension || "FILE").toUpperCase(),
25238
+ " \xB7 ",
25239
+ formatFileSize2(metadata.size)
25240
+ ] }) : null
25241
+ ]
25242
+ }
25243
+ ),
25244
+ renderContent()
25245
+ ] });
24643
25246
  };
24644
25247
  var BuiltinRouteError = ({
24645
25248
  error,
@@ -24766,7 +25369,14 @@ function BuiltinRouteRenderer({
24766
25369
  }
24767
25370
  let defaultNode;
24768
25371
  if (route.kind === "file-preview") {
24769
- defaultNode = /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(BuiltinFilePreview, { route, servicePrefix: normalizedServicePrefix });
25372
+ defaultNode = /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
25373
+ BuiltinFilePreview,
25374
+ {
25375
+ request,
25376
+ route,
25377
+ servicePrefix: normalizedServicePrefix
25378
+ }
25379
+ );
24770
25380
  } else if (route.kind === "data-manage-list") {
24771
25381
  if (!appType || !formUuid) {
24772
25382
  defaultNode = /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_antd40.Card, { style: { margin: 16 }, children: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(import_antd40.Empty, { description: "\u6570\u636E\u7BA1\u7406\u9875\u7F3A\u5C11 formUuid\uFF0C\u8BF7\u5728 URL \u6216 resolver params \u4E2D\u63D0\u4F9B formUuid" }) });