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
@@ -667,6 +667,17 @@ var createPageSdk = (context) => {
667
667
  throw toSdkError(error, payload);
668
668
  }
669
669
  };
670
+ const createFileAccessTicket = (bucketName, objectName, fileName, action = "preview", options = {}) => request({
671
+ path: "/file/access-ticket",
672
+ method: "post",
673
+ body: {
674
+ bucketName,
675
+ objectName,
676
+ fileName,
677
+ action,
678
+ appType: resolveAppType(context, options.appType)
679
+ }
680
+ });
670
681
  const logout = () => request({
671
682
  path: "/api/auth/logout",
672
683
  method: "post"
@@ -1952,6 +1963,7 @@ var createPageSdk = (context) => {
1952
1963
  context,
1953
1964
  request,
1954
1965
  download,
1966
+ createFileAccessTicket,
1955
1967
  transport: {
1956
1968
  request,
1957
1969
  download
@@ -5543,14 +5555,14 @@ var useAuth = (options = {}) => {
5543
5555
  () => createAuthClient({
5544
5556
  appType: options.appType || runtime.appType,
5545
5557
  servicePrefix: options.servicePrefix || runtime.servicePrefix,
5546
- fetchImpl: options.fetchImpl || runtime.fetchImpl
5558
+ fetchImpl: options.fetchImpl || runtime.baseFetchImpl
5547
5559
  }),
5548
5560
  [
5549
5561
  options.appType,
5550
5562
  options.fetchImpl,
5551
5563
  options.servicePrefix,
5552
5564
  runtime.appType,
5553
- runtime.fetchImpl,
5565
+ runtime.baseFetchImpl,
5554
5566
  runtime.servicePrefix
5555
5567
  ]
5556
5568
  );
@@ -5829,7 +5841,19 @@ var LoginPage = ({
5829
5841
  };
5830
5842
  async function handleSuccess(data) {
5831
5843
  await onSuccess?.(data);
5832
- await runtime.reload();
5844
+ const accessToken = data.accessToken || data.token;
5845
+ const accessTokenOptions = {
5846
+ expiresAt: data.accessTokenExpiresAt
5847
+ };
5848
+ if (accessToken) {
5849
+ runtime.setAccessToken(accessToken, accessTokenOptions);
5850
+ }
5851
+ await runtime.reload(
5852
+ accessToken ? {
5853
+ accessToken,
5854
+ accessTokenOptions
5855
+ } : void 0
5856
+ );
5833
5857
  if (redirectOnSuccess && typeof window !== "undefined") {
5834
5858
  window.location.replace(
5835
5859
  redirectUrl || getCallbackUrl() || `/view/${auth.client.appType}`
@@ -6113,27 +6137,125 @@ var OpenXiangdaProvider = ({
6113
6137
  () => appType || resolveAppTypeFromLocation(),
6114
6138
  [appType]
6115
6139
  );
6116
- const [accessToken, setAccessTokenState] = useState9(null);
6140
+ const [, setAccessTokenState] = useState9(null);
6141
+ const [authState, setAuthState] = useState9({
6142
+ status: "unknown",
6143
+ error: null
6144
+ });
6117
6145
  const accessTokenRef = useRef5(null);
6118
- const setAccessToken = useCallback8(
6146
+ const refreshRequestRef = useRef5(null);
6147
+ const applyAccessToken = useCallback8(
6119
6148
  (nextAccessToken, options = {}) => {
6120
6149
  if (!nextAccessToken && options.clearIfToken && accessTokenRef.current?.token !== options.clearIfToken) {
6121
- return;
6150
+ return accessTokenRef.current;
6122
6151
  }
6123
6152
  const normalizedAccessToken = nextAccessToken || null;
6124
6153
  const nextState = normalizedAccessToken ? {
6125
6154
  token: normalizedAccessToken,
6126
6155
  scope: options.scope || "default",
6127
- path: options.path || null
6156
+ path: options.path || null,
6157
+ expiresAt: options.expiresAt
6128
6158
  } : null;
6129
6159
  accessTokenRef.current = nextState;
6130
6160
  setAccessTokenState(nextState);
6161
+ return nextState;
6131
6162
  },
6132
6163
  []
6133
6164
  );
6165
+ const setAccessToken = useCallback8(
6166
+ (nextAccessToken, options = {}) => {
6167
+ const previousState = accessTokenRef.current;
6168
+ const nextState = applyAccessToken(nextAccessToken, options);
6169
+ if (nextState) {
6170
+ if (nextState.scope === "public") return;
6171
+ setAuthState({
6172
+ status: "authenticated",
6173
+ error: null
6174
+ });
6175
+ } else if (previousState?.scope !== "public") {
6176
+ setAuthState({ status: "unauthenticated", error: null });
6177
+ }
6178
+ },
6179
+ [applyAccessToken]
6180
+ );
6181
+ const markUnauthenticated = useCallback8(
6182
+ (error) => {
6183
+ const runtimeError = normalizeRuntimeError(error);
6184
+ applyAccessToken(null);
6185
+ setAuthState({ status: "unauthenticated", error: runtimeError });
6186
+ },
6187
+ [applyAccessToken]
6188
+ );
6189
+ const refreshAccessToken = useCallback8(async () => {
6190
+ if (!resolvedAppType) return null;
6191
+ if (!refreshRequestRef.current) {
6192
+ setAuthState((prev) => ({ ...prev, status: "refreshing", error: null }));
6193
+ refreshRequestRef.current = (async () => {
6194
+ const response = await resolvedFetch(
6195
+ buildServiceUrl3(
6196
+ servicePrefix,
6197
+ `/openxiangda-api/v1/apps/${encodeURIComponent(
6198
+ resolvedAppType
6199
+ )}/auth/refresh`
6200
+ ),
6201
+ {
6202
+ method: "POST",
6203
+ credentials: "include",
6204
+ headers: {
6205
+ accept: "application/json",
6206
+ "content-type": "application/json"
6207
+ },
6208
+ body: "{}"
6209
+ }
6210
+ );
6211
+ const payload = await readJsonPayload(response);
6212
+ if (isRuntimeEnvelopeFailure(response, payload)) {
6213
+ throw createRuntimeHttpError(
6214
+ response,
6215
+ payload,
6216
+ payload?.message || `Token refresh failed: ${response.status}`
6217
+ );
6218
+ }
6219
+ const data = unwrapRuntimePayload(payload);
6220
+ const nextAccessToken = getRecordString(data, "accessToken") || getRecordString(data, "token");
6221
+ if (!nextAccessToken) {
6222
+ throw createRuntimeError({
6223
+ type: "unauthenticated",
6224
+ status: response.status,
6225
+ code: getRecordValue3(payload, "code"),
6226
+ message: "Token refresh response missing accessToken",
6227
+ payload
6228
+ });
6229
+ }
6230
+ const nextState = applyAccessToken(nextAccessToken, {
6231
+ expiresAt: getRecordNumber(data, "accessTokenExpiresAt")
6232
+ });
6233
+ setAuthState({
6234
+ status: "authenticated",
6235
+ error: null,
6236
+ refreshedAt: Date.now()
6237
+ });
6238
+ return nextState;
6239
+ })().catch((error) => {
6240
+ const runtimeError = normalizeRuntimeError(error);
6241
+ applyAccessToken(null);
6242
+ setAuthState({ status: "unauthenticated", error: runtimeError });
6243
+ throw runtimeError;
6244
+ }).finally(() => {
6245
+ refreshRequestRef.current = null;
6246
+ });
6247
+ }
6248
+ return refreshRequestRef.current;
6249
+ }, [applyAccessToken, resolvedAppType, resolvedFetch, servicePrefix]);
6134
6250
  const authorizedFetch = useMemo11(
6135
- () => createAuthorizedFetch(resolvedFetch, accessToken),
6136
- [accessToken, resolvedFetch]
6251
+ () => createAuthorizedFetch({
6252
+ appType: resolvedAppType,
6253
+ baseFetch: resolvedFetch,
6254
+ accessTokenRef,
6255
+ markUnauthenticated,
6256
+ refreshAccessToken
6257
+ }),
6258
+ [markUnauthenticated, refreshAccessToken, resolvedAppType, resolvedFetch]
6137
6259
  );
6138
6260
  const getAuthHeaders = useCallback8(() => {
6139
6261
  const state2 = accessTokenRef.current;
@@ -6159,13 +6281,13 @@ var OpenXiangdaProvider = ({
6159
6281
  return;
6160
6282
  }
6161
6283
  setState((prev) => ({ ...prev, loading: true, error: null }));
6162
- const requestFetch = options.accessToken !== void 0 ? createAuthorizedFetch(
6284
+ const requestFetch = options.accessToken !== void 0 ? createAccessTokenFetch(
6163
6285
  resolvedFetch,
6164
6286
  createAccessTokenState(
6165
6287
  options.accessToken || null,
6166
6288
  options.accessTokenOptions
6167
6289
  )
6168
- ) : createAuthorizedFetch(resolvedFetch, accessTokenRef.current);
6290
+ ) : authorizedFetch;
6169
6291
  try {
6170
6292
  const response = await requestFetch(
6171
6293
  buildServiceUrl3(
@@ -6187,19 +6309,29 @@ var OpenXiangdaProvider = ({
6187
6309
  payload?.message || `Runtime bootstrap failed: ${response.status}`
6188
6310
  );
6189
6311
  }
6312
+ const nextData = payload?.data || null;
6190
6313
  setState({
6191
- data: payload?.data || null,
6314
+ data: nextData,
6192
6315
  loading: false,
6193
6316
  error: null
6194
6317
  });
6318
+ if (isAuthenticatedBootstrap(nextData)) {
6319
+ setAuthState(
6320
+ (prev) => prev.status === "authenticated" ? prev : { status: "authenticated", error: null }
6321
+ );
6322
+ }
6195
6323
  } catch (error) {
6324
+ const runtimeError = normalizeRuntimeError(error);
6196
6325
  setState({
6197
6326
  data: null,
6198
6327
  loading: false,
6199
- error: normalizeRuntimeError(error)
6328
+ error: runtimeError
6200
6329
  });
6330
+ if (runtimeError.type === "unauthenticated") {
6331
+ setAuthState({ status: "unauthenticated", error: runtimeError });
6332
+ }
6201
6333
  }
6202
- }, [resolvedAppType, resolvedFetch, servicePrefix]);
6334
+ }, [authorizedFetch, resolvedAppType, resolvedFetch, servicePrefix]);
6203
6335
  useEffect9(() => {
6204
6336
  void reload();
6205
6337
  }, [reload]);
@@ -6210,6 +6342,7 @@ var OpenXiangdaProvider = ({
6210
6342
  servicePrefix,
6211
6343
  fetchImpl: authorizedFetch,
6212
6344
  baseFetchImpl: resolvedFetch,
6345
+ authState,
6213
6346
  getAuthHeaders,
6214
6347
  reload,
6215
6348
  setAccessToken
@@ -6221,7 +6354,8 @@ var OpenXiangdaProvider = ({
6221
6354
  resolvedAppType,
6222
6355
  resolvedFetch,
6223
6356
  servicePrefix,
6224
- state
6357
+ state,
6358
+ authState
6225
6359
  ]
6226
6360
  );
6227
6361
  return /* @__PURE__ */ jsx10(OpenXiangdaRuntimeContext.Provider, { value, children });
@@ -6488,7 +6622,7 @@ var useRuntimeAuth = () => {
6488
6622
  buildServiceUrl3(runtime.servicePrefix, "/api/sso/status"),
6489
6623
  { domain }
6490
6624
  );
6491
- const statusResponse = await runtime.fetchImpl(statusUrl, {
6625
+ const statusResponse = await runtime.baseFetchImpl(statusUrl, {
6492
6626
  credentials: "include",
6493
6627
  headers: { accept: "application/json" }
6494
6628
  });
@@ -6499,7 +6633,7 @@ var useRuntimeAuth = () => {
6499
6633
  enabled && (sso.forceLogin ?? sso.autoRedirect ?? true)
6500
6634
  );
6501
6635
  if (shouldUseSso) {
6502
- const loginUrlResponse = await runtime.fetchImpl(
6636
+ const loginUrlResponse = await runtime.baseFetchImpl(
6503
6637
  withQuery(buildServiceUrl3(runtime.servicePrefix, "/api/sso/login-url"), {
6504
6638
  domain,
6505
6639
  redirectUri,
@@ -6523,7 +6657,7 @@ var useRuntimeAuth = () => {
6523
6657
  }
6524
6658
  return attachCallback("/platform/login", redirectUri);
6525
6659
  },
6526
- [runtime.data?.app, runtime.fetchImpl, runtime.servicePrefix]
6660
+ [runtime.baseFetchImpl, runtime.data?.app, runtime.servicePrefix]
6527
6661
  );
6528
6662
  const redirectToLogin = useCallback8(
6529
6663
  async (options = {}) => {
@@ -6540,7 +6674,7 @@ var useRuntimeAuth = () => {
6540
6674
  [resolveLoginUrl2]
6541
6675
  );
6542
6676
  const logout = useCallback8(async () => {
6543
- const response = await runtime.fetchImpl(
6677
+ const response = await runtime.baseFetchImpl(
6544
6678
  buildServiceUrl3(runtime.servicePrefix, "/api/auth/logout"),
6545
6679
  {
6546
6680
  method: "POST",
@@ -6556,8 +6690,9 @@ var useRuntimeAuth = () => {
6556
6690
  payload?.message || `Logout failed: ${response.status}`
6557
6691
  );
6558
6692
  }
6693
+ runtime.setAccessToken(null);
6559
6694
  return payload;
6560
- }, [runtime.fetchImpl, runtime.servicePrefix]);
6695
+ }, [runtime.baseFetchImpl, runtime.servicePrefix, runtime.setAccessToken]);
6561
6696
  const logoutAndRedirect = useCallback8(
6562
6697
  async (options = {}) => {
6563
6698
  try {
@@ -6576,12 +6711,83 @@ var useRuntimeAuth = () => {
6576
6711
  resolveLoginUrl: resolveLoginUrl2
6577
6712
  };
6578
6713
  };
6714
+ var RuntimeAuthGuard = ({
6715
+ children,
6716
+ fallback = null,
6717
+ disabled = false,
6718
+ excludedPaths = [],
6719
+ ...redirectOptions
6720
+ }) => {
6721
+ const runtime = useOpenXiangda();
6722
+ const auth = useRuntimeAuth();
6723
+ const redirectedRef = useRef5(false);
6724
+ const currentPath = getCurrentPathname2();
6725
+ const excluded = isRuntimeAuthGuardExcluded(
6726
+ currentPath,
6727
+ runtime.appType,
6728
+ excludedPaths
6729
+ );
6730
+ const shouldRedirect = !disabled && !excluded && !runtime.loading && (runtime.authState.status === "unauthenticated" || runtime.error?.type === "unauthenticated");
6731
+ useEffect9(() => {
6732
+ if (!shouldRedirect || redirectedRef.current) return;
6733
+ redirectedRef.current = true;
6734
+ void auth.redirectToLogin({
6735
+ ...redirectOptions,
6736
+ redirectUri: redirectOptions.redirectUri || getCurrentHref4()
6737
+ }).catch(() => {
6738
+ redirectedRef.current = false;
6739
+ });
6740
+ }, [
6741
+ auth,
6742
+ redirectOptions.domain,
6743
+ redirectOptions.loginUrl,
6744
+ redirectOptions.redirectUri,
6745
+ redirectOptions.replace,
6746
+ shouldRedirect
6747
+ ]);
6748
+ if (excluded) return /* @__PURE__ */ jsx10(Fragment5, { children });
6749
+ if (shouldRedirect) return /* @__PURE__ */ jsx10(Fragment5, { children: fallback });
6750
+ return /* @__PURE__ */ jsx10(Fragment5, { children });
6751
+ };
6579
6752
  var buildServiceUrl3 = (servicePrefix, path) => {
6580
6753
  const prefix = servicePrefix.endsWith("/") ? servicePrefix.slice(0, -1) : servicePrefix;
6581
6754
  const suffix = path.startsWith("/") ? path : `/${path}`;
6582
6755
  return `${prefix}${suffix}`;
6583
6756
  };
6584
- var createAuthorizedFetch = (baseFetch, accessToken) => {
6757
+ var createAuthorizedFetch = ({
6758
+ appType,
6759
+ baseFetch,
6760
+ accessTokenRef,
6761
+ refreshAccessToken,
6762
+ markUnauthenticated
6763
+ }) => (async (input, init = {}) => {
6764
+ const currentTokenState = accessTokenRef.current;
6765
+ const response = await createAccessTokenFetch(
6766
+ baseFetch,
6767
+ currentTokenState
6768
+ )(input, init);
6769
+ if (!shouldAttemptAuthRefresh({
6770
+ appType,
6771
+ input,
6772
+ init,
6773
+ tokenState: currentTokenState
6774
+ })) {
6775
+ return response;
6776
+ }
6777
+ if (!await isUnauthenticatedResponse(response)) return response;
6778
+ try {
6779
+ const refreshedTokenState = await refreshAccessToken();
6780
+ if (!refreshedTokenState) return response;
6781
+ return await createAccessTokenFetch(
6782
+ baseFetch,
6783
+ refreshedTokenState
6784
+ )(input, init);
6785
+ } catch (error) {
6786
+ markUnauthenticated(error);
6787
+ return response;
6788
+ }
6789
+ });
6790
+ var createAccessTokenFetch = (baseFetch, accessToken) => {
6585
6791
  if (!accessToken) return baseFetch;
6586
6792
  return ((input, init = {}) => {
6587
6793
  const token = resolveAccessTokenForCurrentRoute(accessToken);
@@ -6599,8 +6805,53 @@ var createAuthorizedFetch = (baseFetch, accessToken) => {
6599
6805
  var createAccessTokenState = (accessToken, options = {}) => accessToken ? {
6600
6806
  token: accessToken,
6601
6807
  scope: options.scope || "default",
6602
- path: options.path || null
6808
+ path: options.path || null,
6809
+ expiresAt: options.expiresAt
6603
6810
  } : null;
6811
+ var shouldAttemptAuthRefresh = ({
6812
+ appType,
6813
+ input,
6814
+ init,
6815
+ tokenState
6816
+ }) => {
6817
+ if (!appType) return false;
6818
+ if (tokenState?.scope === "public") return false;
6819
+ if (isPublicRoutePath(normalizeRoutePath(getCurrentPathname2()))) return false;
6820
+ if (hasAuthorizationHeader(init?.headers)) return false;
6821
+ const pathname = getFetchInputPathname(input);
6822
+ if (!pathname) return false;
6823
+ if (/\/openxiangda-api\/v1\/apps\/[^/]+\/auth(?:\/|$)/.test(pathname)) {
6824
+ return false;
6825
+ }
6826
+ if (/\/openxiangda-api\/v1\/apps\/[^/]+\/public\/session(?:\/|$)/.test(pathname)) {
6827
+ return false;
6828
+ }
6829
+ if (/\/openxiangda-api\/v1\/auth(?:\/|$)/.test(pathname)) return false;
6830
+ if (/\/api\/auth\/logout(?:\/|$)/.test(pathname)) return false;
6831
+ if (/\/api\/sso(?:\/|$)/.test(pathname)) return false;
6832
+ return true;
6833
+ };
6834
+ var isUnauthenticatedResponse = async (response) => {
6835
+ if (response.status === 401) return true;
6836
+ const payload = await readJsonPayload(response.clone());
6837
+ const code = getRecordValue3(payload, "code");
6838
+ return classifyRuntimeError(response.status, code) === "unauthenticated";
6839
+ };
6840
+ var hasAuthorizationHeader = (headers) => {
6841
+ if (!headers) return false;
6842
+ const normalized = new Headers(headers);
6843
+ return normalized.has("authorization");
6844
+ };
6845
+ var getFetchInputPathname = (input) => {
6846
+ const text = typeof input === "string" ? input : input instanceof URL ? input.toString() : typeof Request !== "undefined" && input instanceof Request ? input.url : String(input || "");
6847
+ if (!text) return "";
6848
+ try {
6849
+ const base = typeof window !== "undefined" ? window.location.origin : "http://localhost";
6850
+ return new URL(text, base).pathname;
6851
+ } catch {
6852
+ return text.split(/[?#]/, 1)[0] || "";
6853
+ }
6854
+ };
6604
6855
  var resolveAccessTokenForCurrentRoute = (accessToken) => {
6605
6856
  if (accessToken.scope !== "public") return accessToken.token;
6606
6857
  const scopedPath = normalizeRoutePath(accessToken.path);
@@ -6785,6 +7036,31 @@ var getRecordString = (value, key) => {
6785
7036
  const result = getRecordValue3(value, key);
6786
7037
  return typeof result === "string" ? result : void 0;
6787
7038
  };
7039
+ var getRecordNumber = (value, key) => {
7040
+ const result = getRecordValue3(value, key);
7041
+ const numberValue = Number(result);
7042
+ return Number.isFinite(numberValue) ? numberValue : void 0;
7043
+ };
7044
+ var unwrapRuntimePayload = (payload) => {
7045
+ if (!payload || typeof payload !== "object") return payload;
7046
+ const record = payload;
7047
+ return "data" in record ? record.data : payload;
7048
+ };
7049
+ var isAuthenticatedBootstrap = (value) => {
7050
+ if (!value || typeof value !== "object") return false;
7051
+ const user = toRuntimeRecord(getRecordValue3(value, "user"));
7052
+ if (!getRecordValue3(user, "id") && !getRecordValue3(user, "username")) {
7053
+ return false;
7054
+ }
7055
+ return !getRecordValue3(user, "publicAccess");
7056
+ };
7057
+ var isRuntimeAuthGuardExcluded = (path, appType, excludedPaths) => {
7058
+ const normalizedPath = normalizeRoutePath(path);
7059
+ if (isPublicRoutePath(normalizedPath)) return true;
7060
+ const loginPath = normalizeRoutePath(`/view/${encodeURIComponent(appType)}/login`);
7061
+ if (appType && normalizedPath === loginPath) return true;
7062
+ return excludedPaths.map((item) => normalizeRoutePath(item)).some((item) => item && normalizedPath === item);
7063
+ };
6788
7064
  var resolveAppTypeFromLocation = () => {
6789
7065
  if (typeof window === "undefined") return "";
6790
7066
  const segments = window.location.pathname.split("/").filter(Boolean);
@@ -6921,7 +7197,7 @@ var readPathFromLocation = () => typeof window === "undefined" ? void 0 : window
6921
7197
 
6922
7198
  // packages/sdk/src/runtime/host/builtinRouteRenderer.tsx
6923
7199
  import { useCallback as useCallback27, useEffect as useEffect51, useMemo as useMemo37, useState as useState42 } from "react";
6924
- import { Alert as Alert4, Button as Button16, Card as Card2, Empty as Empty8, Spin as Spin6, Typography as Typography3 } from "antd";
7200
+ import { Alert as Alert4, Button as Button16, Card as Card2, Empty as Empty8, Spin as Spin6, Table as Table4, Tabs as Tabs2, Typography as Typography3 } from "antd";
6925
7201
 
6926
7202
  // packages/sdk/src/components/core/imageCompression.ts
6927
7203
  var DEFAULT_THUMB = {
@@ -7622,11 +7898,11 @@ function createFormRuntimeApi(config) {
7622
7898
  });
7623
7899
  return normalizeFileTicketResult(baseUrl, response.data || response.result);
7624
7900
  },
7625
- createFileAccessTicket: async (bucketName, objectName, fileName, purpose = "preview") => {
7901
+ createFileAccessTicket: async (bucketName, objectName, fileName, purpose = "preview", options = {}) => {
7626
7902
  const response = await request({
7627
7903
  url: "/file/access-ticket",
7628
7904
  method: "post",
7629
- data: { bucketName, objectName, fileName, purpose }
7905
+ data: { bucketName, objectName, fileName, purpose, appType: options.appType }
7630
7906
  });
7631
7907
  return normalizeFileTicketResult(baseUrl, response.data || response.result);
7632
7908
  },
@@ -10782,6 +11058,11 @@ function canPreview(item) {
10782
11058
  const ext = getFileExtension(item.name);
10783
11059
  return isImageFile(item.name, item.contentType) || ["mp4", "webm", "ogg", "mov", "m4v"].includes(ext) || PREVIEW_PAGE_EXTENSIONS.includes(ext);
10784
11060
  }
11061
+ function appendTicketIfMissing(url, ticket) {
11062
+ if (!url || !ticket || /[?&]ticket=/.test(url)) return url;
11063
+ const separator = url.includes("?") ? "&" : "?";
11064
+ return `${url}${separator}ticket=${encodeURIComponent(ticket)}`;
11065
+ }
10785
11066
  function AttachmentFieldPC({
10786
11067
  fieldId,
10787
11068
  behavior,
@@ -10897,16 +11178,15 @@ function AttachmentFieldPC({
10897
11178
  item.bucketName || bucketName,
10898
11179
  item.objectName,
10899
11180
  item.name,
10900
- "preview"
11181
+ "preview",
11182
+ { appType: item.appType || config.appType }
10901
11183
  );
10902
11184
  const ticketValue = typeof ticket === "string" ? { previewUrl: ticket } : ticket;
10903
- if (ticketValue?.previewPageUrl && ticketValue?.ticket) {
10904
- const separator = ticketValue.previewPageUrl.includes("?") ? "&" : "?";
10905
- return `${ticketValue.previewPageUrl}${separator}ticket=${encodeURIComponent(ticketValue.ticket)}`;
11185
+ if (ticketValue?.previewPageUrl) {
11186
+ return appendTicketIfMissing(ticketValue.previewPageUrl, ticketValue.ticket);
10906
11187
  }
10907
11188
  if (ticketValue?.ticket && PREVIEW_PAGE_EXTENSIONS.includes(getFileExtension(item.name))) {
10908
- const separator = previewPagePath.includes("?") ? "&" : "?";
10909
- return `${previewPagePath}${separator}ticket=${encodeURIComponent(ticketValue.ticket)}`;
11189
+ return appendTicketIfMissing(previewPagePath, ticketValue.ticket);
10910
11190
  }
10911
11191
  return ticketValue?.previewUrl || ticketValue?.url || "";
10912
11192
  }
@@ -11148,6 +11428,11 @@ function canPreview2(item) {
11148
11428
  const ext = getFileExtension(item.name);
11149
11429
  return isImageFile(item.name, item.contentType) || ["mp4", "webm", "ogg", "mov", "m4v"].includes(ext) || PREVIEW_PAGE_EXTENSIONS2.includes(ext);
11150
11430
  }
11431
+ function appendTicketIfMissing2(url, ticket) {
11432
+ if (!url || !ticket || /[?&]ticket=/.test(url)) return url;
11433
+ const separator = url.includes("?") ? "&" : "?";
11434
+ return `${url}${separator}ticket=${encodeURIComponent(ticket)}`;
11435
+ }
11151
11436
  function AttachmentFieldMobile({
11152
11437
  fieldId,
11153
11438
  behavior,
@@ -11296,16 +11581,15 @@ function AttachmentFieldMobile({
11296
11581
  item.bucketName || bucketName,
11297
11582
  item.objectName,
11298
11583
  item.name,
11299
- "preview"
11584
+ "preview",
11585
+ { appType: item.appType || config.appType }
11300
11586
  );
11301
11587
  const ticketValue = typeof ticket === "string" ? { previewUrl: ticket } : ticket;
11302
- if (ticketValue?.previewPageUrl && ticketValue?.ticket) {
11303
- const separator = ticketValue.previewPageUrl.includes("?") ? "&" : "?";
11304
- return `${ticketValue.previewPageUrl}${separator}ticket=${encodeURIComponent(ticketValue.ticket)}`;
11588
+ if (ticketValue?.previewPageUrl) {
11589
+ return appendTicketIfMissing2(ticketValue.previewPageUrl, ticketValue.ticket);
11305
11590
  }
11306
11591
  if (ticketValue?.ticket && PREVIEW_PAGE_EXTENSIONS2.includes(getFileExtension(item.name))) {
11307
- const separator = previewPagePath.includes("?") ? "&" : "?";
11308
- return `${previewPagePath}${separator}ticket=${encodeURIComponent(ticketValue.ticket)}`;
11592
+ return appendTicketIfMissing2(previewPagePath, ticketValue.ticket);
11309
11593
  }
11310
11594
  return ticketValue?.previewUrl || ticketValue?.url || "";
11311
11595
  }
@@ -11436,6 +11720,11 @@ function canPreview3(item) {
11436
11720
  const ext = getFileExtension(item.name);
11437
11721
  return isImageFile(item.name, item.contentType) || ["mp4", "webm", "ogg", "mov", "m4v"].includes(ext) || PREVIEW_PAGE_EXTENSIONS3.includes(ext);
11438
11722
  }
11723
+ function appendTicketIfMissing3(url, ticket) {
11724
+ if (!url || !ticket || /[?&]ticket=/.test(url)) return url;
11725
+ const separator = url.includes("?") ? "&" : "?";
11726
+ return `${url}${separator}ticket=${encodeURIComponent(ticket)}`;
11727
+ }
11439
11728
  function AttachmentFieldReadonly({
11440
11729
  fieldId,
11441
11730
  readonlyClassName,
@@ -11446,7 +11735,7 @@ function AttachmentFieldReadonly({
11446
11735
  showFileTypeBadge = false,
11447
11736
  previewPagePath = "/file-preview"
11448
11737
  }) {
11449
- const { formData, api } = useFormContext();
11738
+ const { formData, api, config } = useFormContext();
11450
11739
  const { isMobile } = useDeviceDetect();
11451
11740
  const value = formData[fieldId] ?? [];
11452
11741
  if (value.length === 0) {
@@ -11471,15 +11760,14 @@ function AttachmentFieldReadonly({
11471
11760
  item.bucketName || bucketName,
11472
11761
  item.objectName,
11473
11762
  item.name,
11474
- "preview"
11763
+ "preview",
11764
+ { appType: item.appType || config.appType }
11475
11765
  );
11476
11766
  const ticketValue = typeof ticket === "string" ? { previewUrl: ticket } : ticket;
11477
- if (ticketValue?.previewPageUrl && ticketValue?.ticket) {
11478
- const separator = ticketValue.previewPageUrl.includes("?") ? "&" : "?";
11479
- url = `${ticketValue.previewPageUrl}${separator}ticket=${encodeURIComponent(ticketValue.ticket)}`;
11767
+ if (ticketValue?.previewPageUrl) {
11768
+ url = appendTicketIfMissing3(ticketValue.previewPageUrl, ticketValue.ticket);
11480
11769
  } else if (ticketValue?.ticket && PREVIEW_PAGE_EXTENSIONS3.includes(getFileExtension(item.name))) {
11481
- const separator = previewPagePath.includes("?") ? "&" : "?";
11482
- url = `${previewPagePath}${separator}ticket=${encodeURIComponent(ticketValue.ticket)}`;
11770
+ url = appendTicketIfMissing3(previewPagePath, ticketValue.ticket);
11483
11771
  } else {
11484
11772
  url = getTicketUrl(ticketValue, url);
11485
11773
  }
@@ -17206,7 +17494,7 @@ async function fetchRuntimeFormData(api, appType, params) {
17206
17494
  order: order ? JSON.stringify(order) : void 0
17207
17495
  }
17208
17496
  });
17209
- const payload = unwrapRuntimePayload(response);
17497
+ const payload = unwrapRuntimePayload2(response);
17210
17498
  const data = Array.isArray(payload?.data) ? payload.data : Array.isArray(payload) ? payload : [];
17211
17499
  return {
17212
17500
  data,
@@ -17263,7 +17551,7 @@ function FormProvider({
17263
17551
  let cancelled = false;
17264
17552
  api.getUserById("current").then((payload) => {
17265
17553
  if (cancelled || !payload) return;
17266
- const currentUser = normalizeUser(unwrapRuntimePayload(payload));
17554
+ const currentUser = normalizeUser(unwrapRuntimePayload2(payload));
17267
17555
  const departments = normalizeDepartmentArray(currentUser.departments);
17268
17556
  const currentDepartment = departments[0];
17269
17557
  const currentUserManagers = normalizeUserArray(
@@ -17660,7 +17948,7 @@ function needsCurrentUserRuntime(shortcutType) {
17660
17948
  ].includes(shortcutType)
17661
17949
  );
17662
17950
  }
17663
- function unwrapRuntimePayload(payload) {
17951
+ function unwrapRuntimePayload2(payload) {
17664
17952
  return payload?.data || payload?.result || payload?.user || payload;
17665
17953
  }
17666
17954
  function isBlankFormValue(value) {
@@ -19615,7 +19903,7 @@ var DraftManager = ({
19615
19903
  // packages/sdk/src/components/templates/FormSubmitTemplate.tsx
19616
19904
  import { Fragment as Fragment14, jsx as jsx96, jsxs as jsxs47 } from "react/jsx-runtime";
19617
19905
  var SUPERVISOR_APPROVER_TYPE = "ext_target_approval_department_supervisor";
19618
- var unwrapRuntimePayload2 = (value) => value?.data ?? value?.result ?? value;
19906
+ var unwrapRuntimePayload3 = (value) => value?.data ?? value?.result ?? value;
19619
19907
  var normalizeSubmitFormType = (value) => {
19620
19908
  const raw = String(value || "").toLowerCase();
19621
19909
  return raw === "process" || raw === "flow" ? "process" : "form";
@@ -19812,7 +20100,7 @@ var InnerFormContent = ({
19812
20100
  return departmentId;
19813
20101
  }
19814
20102
  const runtimeUser = schema.runtime?.currentUser;
19815
- const loadedUser = runtimeUser || unwrapRuntimePayload2(await api.getUserById("current"));
20103
+ const loadedUser = runtimeUser || unwrapRuntimePayload3(await api.getUserById("current"));
19816
20104
  const departments = normalizeDepartmentOptions(loadedUser?.departments);
19817
20105
  if (departments.length === 0) {
19818
20106
  message4.error("\u5F53\u524D\u8D26\u53F7\u672A\u5206\u914D\u90E8\u95E8\uFF0C\u65E0\u6CD5\u53D1\u8D77\u4E3B\u7BA1\u5BA1\u6279\u6D41\u7A0B");
@@ -22791,7 +23079,7 @@ var downloadBlobResponse = async (response, fallbackName) => {
22791
23079
  anchor.remove();
22792
23080
  window.URL.revokeObjectURL(url);
22793
23081
  };
22794
- var unwrapRuntimePayload3 = (payload) => {
23082
+ var unwrapRuntimePayload4 = (payload) => {
22795
23083
  const data = payload?.data?.result ?? payload?.result ?? payload?.data ?? payload;
22796
23084
  return data?.items || data?.list || data?.data || data?.records || data || [];
22797
23085
  };
@@ -22890,14 +23178,14 @@ function AsyncEntityFilterSelect({
22890
23178
  method: "get",
22891
23179
  params: keyword ? { keyword, pageSize: 20 } : { pageSize: 20 }
22892
23180
  });
22893
- rows = unwrapRuntimePayload3(response);
23181
+ rows = unwrapRuntimePayload4(response);
22894
23182
  }
22895
23183
  } else {
22896
23184
  const response = await api.request({
22897
23185
  url: keyword ? "/department/list" : "/department/root",
22898
23186
  method: "get"
22899
23187
  });
22900
- rows = unwrapRuntimePayload3(response);
23188
+ rows = unwrapRuntimePayload4(response);
22901
23189
  if (keyword) {
22902
23190
  const normalizedKeyword = keyword.toLowerCase();
22903
23191
  rows = rows.filter(
@@ -24559,7 +24847,7 @@ var normalizeRuntimeFormSchema = (payload, options) => {
24559
24847
  };
24560
24848
 
24561
24849
  // packages/sdk/src/runtime/host/builtinRouteRenderer.tsx
24562
- import { jsx as jsx101, jsxs as jsxs51 } from "react/jsx-runtime";
24850
+ import { Fragment as Fragment16, jsx as jsx101, jsxs as jsxs51 } from "react/jsx-runtime";
24563
24851
  var DEFAULT_SERVICE_PREFIX = "/service";
24564
24852
  var trimTrailingSlash3 = (value) => String(value || DEFAULT_SERVICE_PREFIX).replace(/\/+$/, "") || DEFAULT_SERVICE_PREFIX;
24565
24853
  var appendQuery3 = (url, params) => {
@@ -24683,23 +24971,337 @@ var getDetailBasePath = (appType, formUuid, formType) => {
24683
24971
  const detailType = isProcessKind("data-manage-list", formType) ? "processDetail" : "formDetail";
24684
24972
  return `/view/${appType}/${detailType}/${formUuid}`;
24685
24973
  };
24974
+ var unwrapRuntimePayload5 = (payload) => payload?.data ?? payload?.result ?? payload;
24975
+ var formatFileSize2 = (size) => {
24976
+ const value = Number(size || 0);
24977
+ if (!value) return "0 B";
24978
+ const units = ["B", "KB", "MB", "GB"];
24979
+ const index = Math.min(
24980
+ units.length - 1,
24981
+ Math.floor(Math.log(value) / Math.log(1024))
24982
+ );
24983
+ return `${(value / Math.pow(1024, index)).toFixed(index === 0 ? 0 : 1)} ${units[index]}`;
24984
+ };
24985
+ var toColumnName = (index) => {
24986
+ let value = index + 1;
24987
+ let name = "";
24988
+ while (value > 0) {
24989
+ const mod = (value - 1) % 26;
24990
+ name = String.fromCharCode(65 + mod) + name;
24991
+ value = Math.floor((value - mod) / 26);
24992
+ }
24993
+ return name;
24994
+ };
24995
+ var buildRowsTable = (rows = []) => {
24996
+ const maxColumns = rows.reduce(
24997
+ (count, row) => Math.max(count, Array.isArray(row) ? row.length : 0),
24998
+ 0
24999
+ );
25000
+ const columns = Array.from({ length: maxColumns }).map((_, index) => ({
25001
+ title: toColumnName(index),
25002
+ dataIndex: `col_${index}`,
25003
+ key: `col_${index}`,
25004
+ width: 160,
25005
+ render: (value) => /* @__PURE__ */ jsx101(Typography3.Text, { ellipsis: { tooltip: String(value ?? "") }, children: String(value ?? "") })
25006
+ }));
25007
+ const dataSource = rows.map((row, rowIndex) => {
25008
+ const record = { key: rowIndex };
25009
+ (Array.isArray(row) ? row : []).forEach((value, colIndex) => {
25010
+ record[`col_${colIndex}`] = value;
25011
+ });
25012
+ return record;
25013
+ });
25014
+ return { columns, dataSource };
25015
+ };
25016
+ var loadScriptOnce = (src) => new Promise((resolve, reject) => {
25017
+ if (!src || typeof document === "undefined") {
25018
+ reject(new Error("ONLYOFFICE \u811A\u672C\u5730\u5740\u4E0D\u53EF\u7528"));
25019
+ return;
25020
+ }
25021
+ const existed = document.querySelector(`script[src="${src}"]`);
25022
+ if (existed) {
25023
+ resolve();
25024
+ return;
25025
+ }
25026
+ const script = document.createElement("script");
25027
+ script.src = src;
25028
+ script.async = true;
25029
+ script.onload = () => resolve();
25030
+ script.onerror = () => reject(new Error("ONLYOFFICE \u811A\u672C\u52A0\u8F7D\u5931\u8D25"));
25031
+ document.body.appendChild(script);
25032
+ });
25033
+ var OnlyOfficePreview = ({
25034
+ configUrl,
25035
+ request,
25036
+ servicePrefix,
25037
+ ticket
25038
+ }) => {
25039
+ const editorId = useMemo37(
25040
+ () => `openxiangda-onlyoffice-${ticket.replace(/[^a-zA-Z0-9_-]/g, "") || "editor"}`,
25041
+ [ticket]
25042
+ );
25043
+ const [loading, setLoading] = useState42(false);
25044
+ const [error, setError] = useState42("");
25045
+ useEffect51(() => {
25046
+ let disposed = false;
25047
+ const load = async () => {
25048
+ setLoading(true);
25049
+ setError("");
25050
+ try {
25051
+ const response = await request({
25052
+ url: configUrl || `/file/onlyoffice/config/${encodeURIComponent(ticket)}`,
25053
+ method: "get"
25054
+ });
25055
+ const payload = unwrapRuntimePayload5(response);
25056
+ const scriptUrl = `${String(payload.documentServerUrl || "").replace(
25057
+ /\/+$/,
25058
+ ""
25059
+ )}/web-apps/apps/api/documents/api.js`;
25060
+ await loadScriptOnce(joinServicePath2(servicePrefix, scriptUrl));
25061
+ if (!disposed && typeof window !== "undefined" && window.DocsAPI?.DocEditor) {
25062
+ new window.DocsAPI.DocEditor(editorId, payload.config);
25063
+ }
25064
+ } catch (currentError) {
25065
+ if (!disposed) {
25066
+ setError(currentError?.message || "ONLYOFFICE \u9884\u89C8\u52A0\u8F7D\u5931\u8D25");
25067
+ }
25068
+ } finally {
25069
+ if (!disposed) {
25070
+ setLoading(false);
25071
+ }
25072
+ }
25073
+ };
25074
+ void load();
25075
+ return () => {
25076
+ disposed = true;
25077
+ };
25078
+ }, [configUrl, editorId, request, servicePrefix, ticket]);
25079
+ return /* @__PURE__ */ jsxs51("div", { style: { minHeight: "calc(100vh - 180px)" }, children: [
25080
+ loading ? /* @__PURE__ */ jsx101(Spin6, { tip: "\u6B63\u5728\u52A0\u8F7D ONLYOFFICE..." }) : null,
25081
+ error ? /* @__PURE__ */ jsx101(Alert4, { type: "warning", showIcon: true, message: error }) : null,
25082
+ /* @__PURE__ */ jsx101("div", { id: editorId, style: { height: "calc(100vh - 180px)", minHeight: 520 } })
25083
+ ] });
25084
+ };
24686
25085
  var BuiltinFilePreview = ({
25086
+ request,
24687
25087
  route,
24688
25088
  servicePrefix
24689
25089
  }) => {
24690
25090
  const ticket = pickRouteValue(route, "ticket");
25091
+ const [metadata, setMetadata] = useState42(null);
25092
+ const [payload, setPayload] = useState42(null);
25093
+ const [loading, setLoading] = useState42(false);
25094
+ const [payloadLoading, setPayloadLoading] = useState42(false);
25095
+ const [error, setError] = useState42("");
25096
+ const [reloadKey, setReloadKey] = useState42(0);
25097
+ useEffect51(() => {
25098
+ let disposed = false;
25099
+ setMetadata(null);
25100
+ setPayload(null);
25101
+ setError("");
25102
+ if (!ticket) return () => {
25103
+ disposed = true;
25104
+ };
25105
+ const loadMetadata = async () => {
25106
+ setLoading(true);
25107
+ try {
25108
+ const response = await request({
25109
+ url: `/file/access-ticket/${encodeURIComponent(ticket)}`,
25110
+ method: "get"
25111
+ });
25112
+ if (!disposed) {
25113
+ setMetadata(unwrapRuntimePayload5(response));
25114
+ }
25115
+ } catch (currentError) {
25116
+ if (!disposed) {
25117
+ setError(currentError?.message || "\u6587\u4EF6\u9884\u89C8\u4FE1\u606F\u52A0\u8F7D\u5931\u8D25");
25118
+ }
25119
+ } finally {
25120
+ if (!disposed) {
25121
+ setLoading(false);
25122
+ }
25123
+ }
25124
+ };
25125
+ void loadMetadata();
25126
+ return () => {
25127
+ disposed = true;
25128
+ };
25129
+ }, [request, reloadKey, ticket]);
25130
+ const resolvePreviewUrl = (url) => joinServicePath2(
25131
+ servicePrefix,
25132
+ url || `/file/preview-by-ticket/${encodeURIComponent(ticket)}`
25133
+ );
25134
+ const downloadUrl = metadata?.downloadUrl ? joinServicePath2(servicePrefix, metadata.downloadUrl) : "";
25135
+ useEffect51(() => {
25136
+ let disposed = false;
25137
+ setPayload(null);
25138
+ if (!metadata?.renderMode || ["pdfjs", "inline", "download", "onlyoffice"].includes(metadata.renderMode)) {
25139
+ setPayloadLoading(false);
25140
+ return () => {
25141
+ disposed = true;
25142
+ };
25143
+ }
25144
+ const url = metadata.renderMode === "excel-basic" ? metadata.excelPreviewUrl : metadata.renderMode === "office-text" ? metadata.officeTextPreviewUrl : metadata.textPreviewUrl;
25145
+ if (!url) return () => {
25146
+ disposed = true;
25147
+ };
25148
+ const loadPayload = async () => {
25149
+ setPayloadLoading(true);
25150
+ try {
25151
+ const response = await request({ url, method: "get" });
25152
+ if (!disposed) {
25153
+ setPayload(unwrapRuntimePayload5(response));
25154
+ }
25155
+ } catch (currentError) {
25156
+ if (!disposed) {
25157
+ setError(currentError?.message || "\u6587\u4EF6\u9884\u89C8\u5185\u5BB9\u52A0\u8F7D\u5931\u8D25");
25158
+ }
25159
+ } finally {
25160
+ if (!disposed) {
25161
+ setPayloadLoading(false);
25162
+ }
25163
+ }
25164
+ };
25165
+ void loadPayload();
25166
+ return () => {
25167
+ disposed = true;
25168
+ };
25169
+ }, [metadata, request]);
24691
25170
  if (!ticket) {
24692
25171
  return /* @__PURE__ */ jsx101(Card2, { style: { margin: 16 }, children: /* @__PURE__ */ jsx101(Empty8, { description: "\u7F3A\u5C11\u6587\u4EF6\u8BBF\u95EE\u7968\u636E" }) });
24693
25172
  }
24694
- const src = joinServicePath2(servicePrefix, `/file/preview-by-ticket/${encodeURIComponent(ticket)}`);
24695
- return /* @__PURE__ */ jsx101("div", { style: { minHeight: "calc(100vh - 74px)", background: "#fff" }, children: /* @__PURE__ */ jsx101(
24696
- "iframe",
24697
- {
24698
- title: "\u6587\u4EF6\u9884\u89C8",
24699
- src,
24700
- style: { width: "100%", minHeight: "calc(100vh - 74px)", border: 0 }
25173
+ const renderContent = () => {
25174
+ if (loading && !metadata) return /* @__PURE__ */ jsx101(Spin6, { tip: "\u6B63\u5728\u52A0\u8F7D\u6587\u4EF6\u4FE1\u606F..." });
25175
+ if (error) {
25176
+ return /* @__PURE__ */ jsx101(
25177
+ Alert4,
25178
+ {
25179
+ type: "error",
25180
+ showIcon: true,
25181
+ message: error,
25182
+ action: /* @__PURE__ */ jsx101(Button16, { onClick: () => setReloadKey((value) => value + 1), children: "\u91CD\u8BD5" })
25183
+ }
25184
+ );
24701
25185
  }
24702
- ) });
25186
+ if (!metadata) return /* @__PURE__ */ jsx101(Empty8, { description: "\u672A\u83B7\u53D6\u5230\u6587\u4EF6\u4FE1\u606F" });
25187
+ if (metadata.renderMode === "pdfjs") {
25188
+ return /* @__PURE__ */ jsx101(
25189
+ "iframe",
25190
+ {
25191
+ title: "PDF \u9884\u89C8",
25192
+ src: resolvePreviewUrl(metadata.previewUrl),
25193
+ style: { width: "100%", minHeight: "calc(100vh - 180px)", border: 0 }
25194
+ }
25195
+ );
25196
+ }
25197
+ if (metadata.renderMode === "inline" && metadata.previewType === "image") {
25198
+ return /* @__PURE__ */ jsx101("div", { style: { textAlign: "center" }, children: /* @__PURE__ */ jsx101(
25199
+ "img",
25200
+ {
25201
+ alt: metadata.fileName || "\u9644\u4EF6\u9884\u89C8",
25202
+ src: resolvePreviewUrl(metadata.previewUrl),
25203
+ style: { maxWidth: "100%", maxHeight: "calc(100vh - 190px)" }
25204
+ }
25205
+ ) });
25206
+ }
25207
+ if (metadata.renderMode === "inline" && metadata.previewType === "video") {
25208
+ return /* @__PURE__ */ jsx101(
25209
+ "video",
25210
+ {
25211
+ controls: true,
25212
+ playsInline: true,
25213
+ preload: "metadata",
25214
+ src: resolvePreviewUrl(metadata.previewUrl),
25215
+ style: { width: "100%", maxHeight: "calc(100vh - 190px)" }
25216
+ }
25217
+ );
25218
+ }
25219
+ if (metadata.renderMode === "excel-basic") {
25220
+ if (payloadLoading) return /* @__PURE__ */ jsx101(Spin6, { tip: "\u6B63\u5728\u89E3\u6790 Excel..." });
25221
+ const sheets = Array.isArray(payload?.sheets) ? payload.sheets : [];
25222
+ if (!sheets.length) return /* @__PURE__ */ jsx101(Empty8, { description: "\u6682\u65E0\u53EF\u9884\u89C8\u7684\u5DE5\u4F5C\u8868" });
25223
+ return /* @__PURE__ */ jsx101(
25224
+ Tabs2,
25225
+ {
25226
+ items: sheets.map((sheet) => {
25227
+ const table = buildRowsTable(sheet.rows || []);
25228
+ return {
25229
+ key: String(sheet.id || sheet.name),
25230
+ label: sheet.name || "Sheet",
25231
+ children: /* @__PURE__ */ jsx101(
25232
+ Table4,
25233
+ {
25234
+ bordered: true,
25235
+ size: "small",
25236
+ pagination: false,
25237
+ scroll: { x: true, y: "calc(100vh - 250px)" },
25238
+ columns: table.columns,
25239
+ dataSource: table.dataSource
25240
+ }
25241
+ )
25242
+ };
25243
+ })
25244
+ }
25245
+ );
25246
+ }
25247
+ if (metadata.renderMode === "text" || metadata.renderMode === "office-text") {
25248
+ if (payloadLoading) return /* @__PURE__ */ jsx101(Spin6, { tip: "\u6B63\u5728\u8BFB\u53D6\u6587\u672C..." });
25249
+ return /* @__PURE__ */ jsxs51("pre", { style: { whiteSpace: "pre-wrap", wordBreak: "break-word", margin: 0 }, children: [
25250
+ payload?.text || "\u6682\u65E0\u6587\u672C\u5185\u5BB9",
25251
+ payload?.truncated ? "\n\n... \u6587\u4EF6\u8F83\u5927\uFF0C\u4EC5\u5C55\u793A\u524D\u90E8\u5185\u5BB9\u3002" : ""
25252
+ ] });
25253
+ }
25254
+ if (metadata.renderMode === "onlyoffice") {
25255
+ return /* @__PURE__ */ jsx101(
25256
+ OnlyOfficePreview,
25257
+ {
25258
+ configUrl: metadata.onlyofficeConfigUrl,
25259
+ request,
25260
+ servicePrefix,
25261
+ ticket
25262
+ }
25263
+ );
25264
+ }
25265
+ return /* @__PURE__ */ jsx101(
25266
+ Empty8,
25267
+ {
25268
+ description: "\u5F53\u524D\u6587\u4EF6\u7C7B\u578B\u6682\u4E0D\u652F\u6301\u9884\u89C8",
25269
+ image: Empty8.PRESENTED_IMAGE_SIMPLE,
25270
+ children: downloadUrl ? /* @__PURE__ */ jsx101(Button16, { type: "primary", onClick: () => window.location.assign(downloadUrl), children: "\u4E0B\u8F7D\u6587\u4EF6" }) : null
25271
+ }
25272
+ );
25273
+ };
25274
+ return /* @__PURE__ */ jsxs51("div", { style: { minHeight: "calc(100vh - 74px)", background: "#fff", padding: 16 }, children: [
25275
+ /* @__PURE__ */ jsxs51(
25276
+ Card2,
25277
+ {
25278
+ size: "small",
25279
+ style: { marginBottom: 16 },
25280
+ extra: /* @__PURE__ */ jsxs51(Fragment16, { children: [
25281
+ /* @__PURE__ */ jsx101(Button16, { size: "small", onClick: () => setReloadKey((value) => value + 1), children: "\u5237\u65B0" }),
25282
+ downloadUrl ? /* @__PURE__ */ jsx101(
25283
+ Button16,
25284
+ {
25285
+ size: "small",
25286
+ type: "primary",
25287
+ style: { marginLeft: 8 },
25288
+ onClick: () => window.location.assign(downloadUrl),
25289
+ children: "\u4E0B\u8F7D"
25290
+ }
25291
+ ) : null
25292
+ ] }),
25293
+ children: [
25294
+ /* @__PURE__ */ jsx101(Typography3.Text, { strong: true, children: metadata?.fileName || "\u9644\u4EF6\u9884\u89C8" }),
25295
+ metadata ? /* @__PURE__ */ jsxs51(Typography3.Text, { type: "secondary", style: { marginLeft: 12 }, children: [
25296
+ (metadata.extension || "FILE").toUpperCase(),
25297
+ " \xB7 ",
25298
+ formatFileSize2(metadata.size)
25299
+ ] }) : null
25300
+ ]
25301
+ }
25302
+ ),
25303
+ renderContent()
25304
+ ] });
24703
25305
  };
24704
25306
  var BuiltinRouteError = ({
24705
25307
  error,
@@ -24826,7 +25428,14 @@ function BuiltinRouteRenderer({
24826
25428
  }
24827
25429
  let defaultNode;
24828
25430
  if (route.kind === "file-preview") {
24829
- defaultNode = /* @__PURE__ */ jsx101(BuiltinFilePreview, { route, servicePrefix: normalizedServicePrefix });
25431
+ defaultNode = /* @__PURE__ */ jsx101(
25432
+ BuiltinFilePreview,
25433
+ {
25434
+ request,
25435
+ route,
25436
+ servicePrefix: normalizedServicePrefix
25437
+ }
25438
+ );
24830
25439
  } else if (route.kind === "data-manage-list") {
24831
25440
  if (!appType || !formUuid) {
24832
25441
  defaultNode = /* @__PURE__ */ jsx101(Card2, { style: { margin: 16 }, children: /* @__PURE__ */ jsx101(Empty8, { description: "\u6570\u636E\u7BA1\u7406\u9875\u7F3A\u5C11 formUuid\uFF0C\u8BF7\u5728 URL \u6216 resolver params \u4E2D\u63D0\u4F9B formUuid" }) });
@@ -24919,6 +25528,7 @@ export {
24919
25528
  ProcessTimeline,
24920
25529
  PublicAccessClientError,
24921
25530
  PublicAccessGate,
25531
+ RuntimeAuthGuard,
24922
25532
  createAuthClient,
24923
25533
  createBrowserPageBridge,
24924
25534
  createBrowserPageContext,