@zxiaosi/sdk 0.1.1 → 0.1.2

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.
@@ -0,0 +1,27 @@
1
+ //#region src/types.d.ts
2
+ interface SdkBase {
3
+ /** SDK 名称 */
4
+ name: string;
5
+ /** 插件列表 */
6
+ _plugins: Map<string, any>;
7
+ /** 挂载sdk - 主应用挂载 SDK 到 Window */
8
+ mount: (name: string) => void;
9
+ /** 继承sdk - 子应用从 Window 上继承 SDK */
10
+ extend: (name: string) => void;
11
+ }
12
+ //#endregion
13
+ //#region src/core/index.d.ts
14
+ declare class Sdk implements SdkBase {
15
+ name: SdkBase['name'];
16
+ _plugins: SdkBase['_plugins'];
17
+ constructor();
18
+ mount(name: string): void;
19
+ extend(name: string): void;
20
+ }
21
+ /**
22
+ * sdk 实例
23
+ */
24
+ declare const sdk: Sdk;
25
+ //#endregion
26
+ export { sdk };
27
+ //# sourceMappingURL=index.d.ts.map
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ const e=new class{name;_plugins;constructor(){this.name=``,this._plugins=new Map}mount(e){console.log(`%c SDK mounted:`,`color: green; font-weight: bold;`,e),this.name=e,window[this.name]=this}extend(e){window[e]?(console.log(`%c SDK extended:`,`color: blue; font-weight: bold;`,e),Object.assign(this,window[e])):console.error(`No SDK instance found on window with the name: ${e}`)}};export{e as sdk};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/core/index.ts"],"sourcesContent":["import type { SdkBase } from '@/types';\n\nclass Sdk implements SdkBase {\n name: SdkBase['name'];\n _plugins: SdkBase['_plugins'];\n\n constructor() {\n this.name = '';\n this._plugins = new Map();\n }\n\n mount(name: string) {\n console.log('%c SDK mounted:', 'color: green; font-weight: bold;', name);\n\n // 挂载到 Window 上\n this.name = name;\n window[this.name] = this;\n }\n\n extend(name: string) {\n // 继承实例属性\n if (window[name]) {\n console.log('%c SDK extended:', 'color: blue; font-weight: bold;', name);\n Object.assign(this, window[name]); // 合并实例属性\n } else {\n console.error(`No SDK instance found on window with the name: ${name}`);\n }\n }\n}\n\n/**\n * sdk 实例\n */\nconst sdk = new Sdk();\n\nexport { sdk };\n"],"mappings":"AAiCA,MAAM,EAAM,IA/BZ,KAA6B,CAC3B,KACA,SAEA,aAAc,CACZ,KAAK,KAAO,GACZ,KAAK,SAAW,IAAI,IAGtB,MAAM,EAAc,CAClB,QAAQ,IAAI,kBAAmB,mCAAoC,EAAK,CAGxE,KAAK,KAAO,EACZ,OAAO,KAAK,MAAQ,KAGtB,OAAO,EAAc,CAEf,OAAO,IACT,QAAQ,IAAI,mBAAoB,kCAAmC,EAAK,CACxE,OAAO,OAAO,KAAM,OAAO,GAAM,EAEjC,QAAQ,MAAM,kDAAkD,IAAO"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zxiaosi/sdk",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "A micro frontend kit",
5
5
  "repository": {
6
6
  "type": "git",
@@ -10,45 +10,25 @@
10
10
  "license": "MIT",
11
11
  "author": "zxiaosi",
12
12
  "type": "module",
13
- "main": "dist/cjs/index.cjs",
14
- "module": "dist/esm/index.mjs",
15
- "types": "dist/esm/index.d.mts",
13
+ "main": "dist/index.js",
14
+ "module": "dist/index.js",
15
+ "types": "dist/index.d.ts",
16
16
  "files": [
17
17
  "dist",
18
18
  "rolldown.config.ts",
19
19
  "tsconfig.json"
20
20
  ],
21
21
  "scripts": {
22
- "build": "npx rimraf dist && rolldown -c rolldown.config.ts",
22
+ "build": "rolldown -c rolldown.config.ts --minify",
23
23
  "dev": "rolldown -c rolldown.config.ts --watch"
24
24
  },
25
- "dependencies": {
26
- "@ant-design/pro-layout": "^7.22.7",
27
- "axios": "^1.12.2",
28
- "qiankun": "^2.10.16",
29
- "react-intl-universal": "^2.13.4"
30
- },
25
+ "dependencies": {},
31
26
  "devDependencies": {
32
- "@babel/preset-env": "^7.28.3",
33
- "@babel/preset-react": "^7.27.1",
34
- "@rollup/plugin-babel": "^6.0.4",
35
- "@types/react": "^18.3.12",
36
- "@types/react-dom": "^18.3.1",
37
- "es-toolkit": "^1.40.0",
38
- "rolldown": "^1.0.0-beta.42",
39
- "rolldown-plugin-dts": "^0.16.11",
40
- "rollup-plugin-node-externals": "^8.1.1"
41
- },
42
- "peerDependencies": {
43
- "@ant-design/icons": "^5.6.1",
44
- "antd": "^5.27.4",
45
- "echarts": "^6.0.0",
46
- "echarts-for-react": "^3.0.4",
47
- "react": "^18.3.1",
48
- "react-dom": "^18.3.1",
49
- "react-router-dom": "^6.30.1",
50
- "zustand": "^5.0.8"
27
+ "rolldown": "^1.0.0-beta.52",
28
+ "rolldown-plugin-dts": "^0.18.1",
29
+ "typescript": "^5.9.3"
51
30
  },
31
+ "peerDependencies": {},
52
32
  "publishConfig": {
53
33
  "access": "public",
54
34
  "registry": "https://registry.npmjs.org/"
@@ -1,78 +1,19 @@
1
- import babel, { RollupBabelInputPluginOptions } from '@rollup/plugin-babel';
2
1
  import { defineConfig } from 'rolldown';
3
2
  import { dts } from 'rolldown-plugin-dts';
4
- import nodeExternals from 'rollup-plugin-node-externals';
3
+ import { dependencies, peerDependencies } from './package.json';
5
4
 
6
- /** babel 配置 */
7
- const babelOptions: RollupBabelInputPluginOptions = {
8
- presets: [
9
- [
10
- '@babel/preset-env',
11
- {
12
- modules: false, // 不转换模块语法, 让 Rollup 处理模块语法
13
- targets: {
14
- node: 'current', // 当前 Node.js 版本
15
- },
16
- },
17
- ],
18
- '@babel/preset-react',
19
- ], // 使用 React 和 ES6+ 预设
20
- exclude: 'node_modules/**', // 排除 node_modules 中的文件
21
- babelHelpers: 'bundled', // 使用打包的 Babel 辅助函数, 避免重复打包
22
- };
23
-
24
- /** 通用配置 */
25
- const common = defineConfig({
26
- input: './src/index.ts',
5
+ const config = defineConfig({
27
6
  platform: 'browser', // 作用于浏览器环境
28
7
  tsconfig: './tsconfig.json', // 指定 tsconfig 文件
8
+ input: './src/index.ts', // 入口文件
9
+ external: [...Object.keys(dependencies), ...Object.keys(peerDependencies)], // 将 package.json 中的依赖设为外部依赖
10
+ plugins: [dts()],
29
11
  output: {
12
+ dir: 'dist', // 输出目录
13
+ format: 'es', // 输出格式为 ES 模块
14
+ cleanDir: true, // 构建前清理输出目录
30
15
  sourcemap: true, // 生成 sourcemap 文件
31
- minify: true, // 启用代码压缩, 调试时可以关闭
32
16
  },
33
17
  });
34
18
 
35
- const config = defineConfig([
36
- {
37
- ...common,
38
- plugins: [
39
- nodeExternals(), // 排除 deps、peerDeps 中的依赖
40
- babel(babelOptions),
41
- dts(),
42
- ],
43
- output: {
44
- dir: 'dist/esm',
45
- format: 'es',
46
- entryFileNames: '[name].mjs',
47
- chunkFileNames: '[name]-[hash].mjs',
48
- ...common.output,
49
- },
50
- },
51
- {
52
- ...common,
53
- plugins: [
54
- nodeExternals(), // 排除 deps、peerDeps 中的依赖
55
- babel(babelOptions),
56
- ],
57
- output: {
58
- dir: 'dist/cjs',
59
- format: 'cjs',
60
- entryFileNames: '[name].cjs',
61
- chunkFileNames: '[name]-[hash].cjs',
62
- ...common.output,
63
- },
64
- },
65
- {
66
- ...common,
67
- plugins: [dts({ emitDtsOnly: true })],
68
- output: {
69
- dir: 'dist/cjs',
70
- format: 'esm',
71
- entryFileNames: '[name].cjs',
72
- chunkFileNames: '[name]-[hash].cjs',
73
- ...common.output,
74
- },
75
- },
76
- ]);
77
-
78
19
  export default config;
package/tsconfig.json CHANGED
@@ -1,26 +1,21 @@
1
- {
2
- "compilerOptions": {
3
- "resolveJsonModule": true,
4
- "esModuleInterop": true,
5
- "moduleResolution": "node",
6
- "jsx": "react-jsx",
7
- "module": "commonjs",
8
- "target": "es5",
9
- "allowJs": false,
10
- "noUnusedLocals": false,
11
- "preserveConstEnums": true,
12
- "skipLibCheck": true,
13
- "sourceMap": true,
14
- "inlineSources": true,
15
- "declaration": true,
16
- "experimentalDecorators": true,
17
- "downlevelIteration": true,
18
- "lib": ["DOM", "ESNext"],
19
- "baseUrl": ".",
20
- "paths": {
21
- "@/*": ["src/*"]
22
- }
23
- },
24
- "include": ["src"],
25
- "exclude": ["rolldown.config.ts", "tsconfig.json"]
26
- }
1
+ {
2
+ "compilerOptions": {
3
+ "target": "esnext",
4
+ "jsx": "react-jsx",
5
+ "lib": ["es2023", "DOM"],
6
+ "moduleDetection": "force",
7
+ "module": "preserve",
8
+ "moduleResolution": "bundler",
9
+ "resolveJsonModule": true,
10
+ "types": [],
11
+ "declaration": true,
12
+ "emitDeclarationOnly": true,
13
+ "verbatimModuleSyntax": true,
14
+ "baseUrl": ".",
15
+ "paths": {
16
+ "@/*": ["src/*"]
17
+ }
18
+ },
19
+ "include": ["src"],
20
+ "exclude": ["rolldown.config.ts", "tsconfig.json"]
21
+ }
package/README.md DELETED
@@ -1,75 +0,0 @@
1
- ## 项目结构
2
-
3
- ```sh
4
- ├── src
5
- | └── core # sdk 实例
6
- | └── plugins # sdk 插件
7
- | └── config # SdkConfigPlugin 配置插件
8
- | └── storage # SdkStoragePlugin 本地缓存插件
9
- | └── index # 导出插件
10
- | └── utils
11
- ├── index # 入口
12
- ├── types # 类型定义
13
- ```
14
-
15
- ## 如何开发一个自己的插件?
16
-
17
- 1. 在 `/src/plugins` 下新建一个文件夹,比如 `custom`,然后在 `src/custom/index.ts` 中导出插件的构造函数
18
-
19
- ```ts
20
- import { merge } from 'es-toolkit';
21
-
22
- interface CustomProps {}
23
-
24
- interface CustomResult extends Required<CustomProps> {}
25
-
26
- /** 插件名称 */
27
- const pluginName = 'custom';
28
-
29
- /**
30
- * CustomPlugin 插件
31
- * - 详见配置 {@link CustomProps} {@link CustomResult}
32
- */
33
- const SdkCustomPlugin: Plugin<'custom'> = {
34
- name: pluginName,
35
- install(sdk, options = {}) {
36
- // 默认插件配置
37
- const defaultOptions = {} satisfies CustomResult;
38
-
39
- sdk[pluginName] = merge(defaultOptions, options);
40
- },
41
- };
42
-
43
- export { SdkCustomPlugin, CustomProps, CustomResult };
44
- ```
45
-
46
- 2. 在 `/src/plugins/index.ts` 导出插件
47
-
48
- ```ts
49
- export * from './custom';
50
- ```
51
-
52
- 3. 在 `/src/types` 中的 `PluginOptions` 和 `PluginResults` 加上自己的插件类型定义
53
-
54
- ```ts
55
- interface PluginOptions {
56
- custom?: CustomProps;
57
- }
58
-
59
- interface PluginResults {
60
- custom: CustomResult;
61
- }
62
- ```
63
-
64
- 4. 在 `/src/core/index.ts` 中定义插件变量
65
-
66
- ```ts
67
- class Sdk implements SdkResult {
68
- name: BaseProps['name'];
69
- plugins: BaseProps['plugins'];
70
-
71
- custom: SdkResult['custom'];
72
- }
73
- ```
74
-
75
- ## SDK 实现功能
@@ -1,2 +0,0 @@
1
- var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require(`antd`);c=s(c);let l=require(`react`);l=s(l);let u=require(`zustand`);u=s(u);let d=require(`zustand/shallow`);d=s(d);let f=require(`react/jsx-runtime`);f=s(f);let p=require(`@ant-design/icons`);p=s(p);let m=require(`react-router-dom`);m=s(m);let h=require(`qiankun`);h=s(h);let g=require(`axios`);g=s(g);let _=require(`react-intl-universal`);_=s(_);let v=require(`zustand/middleware`);v=s(v);let y=require(`@ant-design/pro-layout`);y=s(y);var b=class{constructor(){this.name=``,this._plugins=new Map}mount(e){if(e&&window[e])Object.assign(this,window[e]);else{this.name=e;let t=new Proxy(this,{get:(e,t,n)=>e?Reflect.get(e,t,n):null,set:()=>(console.error(`The SDK cannot be modified.`),!1),deleteProperty:()=>(console.error(`The SDK cannot be deleted.`),!1)});window[this.name]=t}}unmount(){this._plugins.clear(),delete window[this.name]}use(e,t){let{name:n,install:r}=e;if(!n)throw Error(`${n} plugin has no name`);if(typeof r!=`function`)throw Error(`${n} plugin is not a function`);return r(this,t),this._plugins.set(n,{...e,options:t}),this}};const x=new b;function S(e){return e==null||typeof e!=`object`&&typeof e!=`function`}function C(e){return ArrayBuffer.isView(e)&&!(e instanceof DataView)}function w(e){return Object.getOwnPropertySymbols(e).filter(t=>Object.prototype.propertyIsEnumerable.call(e,t))}function T(e){return e==null?e===void 0?`[object Undefined]`:`[object Null]`:Object.prototype.toString.call(e)}const ee=`[object RegExp]`,te=`[object String]`,ne=`[object Number]`,re=`[object Boolean]`,ie=`[object Arguments]`,ae=`[object Symbol]`,oe=`[object Date]`,se=`[object Map]`,ce=`[object Set]`,le=`[object Array]`,ue=`[object ArrayBuffer]`,de=`[object Object]`,fe=`[object DataView]`,pe=`[object Uint8Array]`,me=`[object Uint8ClampedArray]`,he=`[object Uint16Array]`,ge=`[object Uint32Array]`,_e=`[object Int8Array]`,ve=`[object Int16Array]`,ye=`[object Int32Array]`,be=`[object Float32Array]`,xe=`[object Float64Array]`;function E(e,t,n,r=new Map,i=void 0){let a=i?.(e,t,n,r);if(a!==void 0)return a;if(S(e))return e;if(r.has(e))return r.get(e);if(Array.isArray(e)){let t=Array(e.length);r.set(e,t);for(let a=0;a<e.length;a++)t[a]=E(e[a],a,n,r,i);return Object.hasOwn(e,`index`)&&(t.index=e.index),Object.hasOwn(e,`input`)&&(t.input=e.input),t}if(e instanceof Date)return new Date(e.getTime());if(e instanceof RegExp){let t=new RegExp(e.source,e.flags);return t.lastIndex=e.lastIndex,t}if(e instanceof Map){let t=new Map;r.set(e,t);for(let[a,o]of e)t.set(a,E(o,a,n,r,i));return t}if(e instanceof Set){let t=new Set;r.set(e,t);for(let a of e)t.add(E(a,void 0,n,r,i));return t}if(typeof Buffer<`u`&&Buffer.isBuffer(e))return e.subarray();if(C(e)){let t=new(Object.getPrototypeOf(e)).constructor(e.length);r.set(e,t);for(let a=0;a<e.length;a++)t[a]=E(e[a],a,n,r,i);return t}if(e instanceof ArrayBuffer||typeof SharedArrayBuffer<`u`&&e instanceof SharedArrayBuffer)return e.slice(0);if(e instanceof DataView){let t=new DataView(e.buffer.slice(0),e.byteOffset,e.byteLength);return r.set(e,t),D(t,e,n,r,i),t}if(typeof File<`u`&&e instanceof File){let t=new File([e],e.name,{type:e.type});return r.set(e,t),D(t,e,n,r,i),t}if(typeof Blob<`u`&&e instanceof Blob){let t=new Blob([e],{type:e.type});return r.set(e,t),D(t,e,n,r,i),t}if(e instanceof Error){let t=new e.constructor;return r.set(e,t),t.message=e.message,t.name=e.name,t.stack=e.stack,t.cause=e.cause,D(t,e,n,r,i),t}if(e instanceof Boolean){let t=new Boolean(e.valueOf());return r.set(e,t),D(t,e,n,r,i),t}if(e instanceof Number){let t=new Number(e.valueOf());return r.set(e,t),D(t,e,n,r,i),t}if(e instanceof String){let t=new String(e.valueOf());return r.set(e,t),D(t,e,n,r,i),t}if(typeof e==`object`&&O(e)){let t=Object.create(Object.getPrototypeOf(e));return r.set(e,t),D(t,e,n,r,i),t}return e}function D(e,t,n=e,r,i){let a=[...Object.keys(t),...w(t)];for(let o=0;o<a.length;o++){let s=a[o],c=Object.getOwnPropertyDescriptor(e,s);(c==null||c.writable)&&(e[s]=E(t[s],s,n,r,i))}}function O(e){switch(T(e)){case`[object Arguments]`:case`[object Array]`:case`[object ArrayBuffer]`:case`[object DataView]`:case`[object Boolean]`:case`[object Date]`:case`[object Float32Array]`:case`[object Float64Array]`:case`[object Int8Array]`:case`[object Int16Array]`:case`[object Int32Array]`:case`[object Map]`:case`[object Number]`:case`[object Object]`:case`[object RegExp]`:case`[object Set]`:case`[object String]`:case`[object Symbol]`:case`[object Uint8Array]`:case`[object Uint8ClampedArray]`:case`[object Uint16Array]`:case`[object Uint32Array]`:return!0;default:return!1}}function k(e){return E(e,void 0,e,new Map,void 0)}function A(e){if(!e||typeof e!=`object`)return!1;let t=Object.getPrototypeOf(e);return t===null||t===Object.prototype||Object.getPrototypeOf(t)===null?Object.prototype.toString.call(e)===`[object Object]`:!1}function j(e){return e===`__proto__`}function M(e,t){let n=Object.keys(t);for(let r=0;r<n.length;r++){let i=n[r];if(j(i))continue;let a=t[i],o=e[i];Array.isArray(a)?Array.isArray(o)?e[i]=M(o,a):e[i]=M([],a):A(a)?A(o)?e[i]=M(o,a):e[i]=M({},a):(o===void 0||a!==void 0)&&(e[i]=a)}return e}const N=e=>{let{children:t}=e,[n,r]=(0,u.useStore)(x.store,(0,d.useShallow)(e=>[e.locale,e.theme]));return(0,f.jsx)(c.ConfigProvider,{...(0,l.useMemo)(()=>M(k(x.config.antdConfig),e),[n,r]),children:t})},P={beforeLoad:[async e=>{console.log(`[LifeCycle] before load %c%s`,`color: green;`,e.name)}],beforeMount:[async e=>{console.log(`[LifeCycle] before mount %c%s`,`color: green;`,e.name)}],afterUnmount:[async e=>{console.log(`[LifeCycle] after unmount %c%s`,`color: green;`,e.name)}]},F=e=>{let t=e.storage.getTheme();if(t)return t;let n=e.config?.theme;if(n)return n;let r=window.matchMedia(`(prefers-color-scheme: dark)`);return r.matches&&r.matches?`dark`:`light`},I=e=>e.storage.getLocale()||e.config?.locale||navigator.language||`zh-CN`,L=e=>(0,l.createElement)(p[e]),R=(e,t)=>{let n=new Map,r=z(e,n,t);return{microApps:[...n.values()],menuData:r}},z=(e,t,n)=>!e||e?.length===0?[]:e.map(e=>{let r=null,{locale:i,path:a,icon:o,component:s,routeAttr:c,children:l}=e;if(c){let e={};try{e=JSON.parse(c)}catch{console.error(`子应用路由属性格式错误:`,c)}let{name:i,rootId:a,...o}=e,s={...o,name:i,container:`#${a}`,props:{sdk:n},loader:e=>n.store.getState().setMicroAppState(e)};t.set(i,s),r=n.ui.renderComponent(`Microapp`,{name:i,rootId:a})}else r=s===`Outlet`?(0,f.jsx)(m.Outlet,{}):n.ui.renderComponent(s);let u=l?.length?z(l,t,n):[];return{...e,key:`${i}_${o}_${a}`,element:r,icon:L(o),children:u,handle:{crumb:t=>({...e,...t})}}}),B=e=>{let t=`/`;return!e||e.length===0?t:(t=e?.[0]?.path,e?.[0]?.children&&e?.[0]?.children.length>0&&(t=B(e?.[0]?.children)),t)},V=e=>{let{requestId:t,url:n,method:r,params:i,data:a}=e;return t||`${r}:${n}?${JSON.stringify(i)}&${JSON.stringify(a)}`},H=e=>{let t=V(e),n=x.api.controllers.get(t);n&&(n.abort(),x.api.controllers.delete(t))},U=({children:e})=>{let t=(0,m.useLocation)(),n=(0,m.useNavigate)(),r=(0,m.useMatches)();return x.client.location||(x.client.location=t),x.client.navigate||(x.client.navigate=n),(0,l.useEffect)(()=>{x.client.matches=r},[r]),e};var W=U;const G=()=>{let e=x.config.loginPath,t=[{path:e,element:x.ui.renderComponent(`Login`)},{path:`*`,element:x.ui.renderComponent(`NotFound`)},...x.config.customRoutes],[n,r,i]=(0,u.useStore)(x.store,(0,d.useShallow)(e=>[e.setTheme,e.setLocale,e.setInitState])),[a,o]=(0,l.useState)(!1),[s,c]=(0,l.useState)(t),p=(e,t)=>{n(e||F(x)),r(t||I(x))},g=async()=>{try{o(()=>!0);let[{data:e={}},{data:n=[]}]=await Promise.all([x.api.getUserInfoApi(),x.api.getRoutesApi()]);o(()=>!1);let{theme:r,locale:a}=e?.settings||{};p(r,a);let{microApps:s,menuData:l}=R(n,x);x.config.qiankunMode===`router`&&s&&s.length&&((0,h.registerMicroApps)(s,P),(0,h.start)());let u=B(l),d=[...t,{path:`/`,element:(0,f.jsx)(m.Navigate,{to:u,replace:!0})},{path:`/`,element:x.ui.renderComponent(`Layout`),children:l,errorElement:(0,f.jsx)(f.Fragment,{children:`找不到页面`})}];c(d.map(e=>({...e,element:W(e.element)}))),x.app={...x.app,allRoutes:d,microApps:s,menuData:l},i(e)}catch(e){p(),o(()=>!1),console.error(`初始化数据错误:`,e)}};return(0,l.useEffect)(()=>{x.app.allRoutes=t;let n=x.config.customRoutes?.map(e=>e.path),r=window.location.pathname;[e,...n]?.includes(r)?p():g()},[]),a?(0,f.jsx)(f.Fragment,{children:`Loading...`}):(0,f.jsx)(N,{children:(0,f.jsx)(l.Suspense,{fallback:(0,f.jsx)(f.Fragment,{children:`Loading...`}),children:(0,f.jsx)(m.RouterProvider,{router:(0,m.createBrowserRouter)(s,{basename:`/`}),future:{v7_startTransition:!1}})})})};let K=0;function q(e=``){return`${e}${++K}`}var J=class{constructor(e={}){this.instance=g.default.create(e),this.defaultRequestInterceptor(),this.defaultResponseInterceptor()}defaultRequestInterceptor(){this.instance.interceptors.request.use(function(e){let t=x.storage.getToken(),n=V(e);H(e);let r=new AbortController;return x.api.controllers.set(n,r),e.requestId=n,e.signal=r.signal,e.headers.Authorization=t,e.headers.lang=x.config.locale,e},function(e){return console.error(`请求错误`),Promise.reject(e)})}defaultResponseInterceptor(){this.instance.interceptors.response.use(function(e){let{data:t,config:n}=e,{isOriginalData:r,isShowFailMsg:i}=n,{code:a,msg:o}=t;return a!==0&&(i&&c.message.error(o),console.error(`response error: `,n.url,o),a==20041&&x.app.pageToLogin()),x.api.controllers.delete(n.requestId),r?e:e.data},function(e){let{response:t,config:n}=e,{isShowFailMsg:r}=n;if(g.default.isCancel(e))return Promise.reject(e);if(t){let{status:e,data:n,statusText:i}=t;r&&c.message.error(n.msg||i),e==401&&x.app.pageToLogin()}else r&&c.message.error(`请求超时或服务器异常,请检查网络或联系管理员`),console.error(`Request error:`,n.url,e);return Promise.reject(e)})}getInstance(){return this.instance}},Se=J;const Ce=`api`,we={name:`api`,install(e,t={}){let n={baseURL:`/api`,timeout:0,...t.config},r=t?.instance||new Se(n).getInstance();e.api=M({config:n,controllers:new Map,instance:null,getUserInfoApi:()=>e.api.request(`/getUserInfo`,{method:`GET`}),getRoutesApi:()=>e.api.request(`/routes`,{method:`GET`}),request:(e,t={})=>r.request({url:e,isOriginalData:!1,isShowFailMsg:!0,...t}),request2:async(t,n={})=>{let r,i,a=null,o={url:t,...n};a=()=>H(o);try{r=await e.api.request(t,o)}catch(e){i=e}return[r,i,a]},download:async(t,n={})=>{let r,i,a=null,o={url:t,responseType:`blob`,...n},s=q();a=()=>H(o),c.message.loading({key:s,content:`正在下载中...`});try{r=await e.api.request(t,o),c.message.success({key:s,content:`下载成功`})}catch(e){i=e,c.message.error({key:s,content:`下载失败`})}return[r,i,a]}},t)}},Te=`app`,Ee={name:`app`,install(e,t={}){e.app=M({menuData:[],allRoutes:[],microApps:[],microAppsInstance:new Map,user:null,permissions:[],roles:[],settings:{},pageToLogin:()=>{e.storage.clearToken();let t=location.pathname,n=e.config.loginPath,r=t===n?n:`${n}?redirect=${encodeURIComponent(t||`/`)}`;window.location.replace(r)},getRedirectPath:()=>{let t=e.config.defaultPath;if(t)return t;let n=new URLSearchParams(window.location.search);return decodeURIComponent(n.get(`redirect`)||``)||`/`}},t)}},Y=`client`,De={name:Y,install(e,t={}){e[Y]=M({location:null,navigate:null,matches:null},t)}},X=`config`,Oe={name:X,install(e,t={}){e[X]=M({env:{},qiankunMode:`router`,theme:null,locale:null,loginPath:`/login`,defaultPath:``,customRoutes:[],antdConfig:{},proLayoutConfig:{title:`Demo`}},t)}},Z=`i18n`,ke={name:Z,install(e,t={}){e[Z]=M({intl:_.default,intlConfig:{},loadLocale:e=>void 0},t)}},Q=`storage`,Ae={name:Q,install(e,t={}){e[Q]=M({localeKey:`locale`,themeKey:`theme`,tokenKey:`token`,getLocale(){return localStorage.getItem(e.storage.localeKey)||`zh-CN`},setLocale(t){localStorage.setItem(e.storage.localeKey,t)},clearLocale(){localStorage.removeItem(e.storage.localeKey)},getTheme(){return localStorage.getItem(e.storage.themeKey)||`light`},setTheme(t){localStorage.setItem(e.storage.themeKey,t)},clearTheme(){localStorage.removeItem(e.storage.themeKey)},getToken(){return localStorage.getItem(e.storage.tokenKey)||null},setToken(t){localStorage.setItem(e.storage.tokenKey,t)},clearToken(){localStorage.removeItem(e.storage.tokenKey)}},t)}},je=(e,t)=>({microAppState:!1,setMicroAppState:t=>e(()=>({microAppState:t}))}),Me=(e,t)=>({initState:{},setInitState:t=>{e(()=>({initState:t})),x.app={...x.app,...t}}}),Ne=(e,t)=>({locale:null,setLocale:t=>{e(()=>({locale:t})),x.config.locale=t,x.storage.setLocale(t),document.documentElement.setAttribute(`lang`,t);let n=x.i18n.intlConfig;_.default.init({currentLocale:t,locales:n});try{let e=x.i18n.loadLocale?.(t)||void 0;x.config.antdConfig.locale=e}catch(e){console.error(`Load antd locale error:`,e)}}}),{defaultAlgorithm:Pe,darkAlgorithm:Fe}=c.theme,Ie=(e,t)=>({theme:null,setTheme:t=>{e(()=>({theme:t})),x.config.theme=t,x.storage.setTheme(t),document.documentElement.setAttribute(`data-theme`,t);let n=t===`light`?Pe:Fe;x.config.antdConfig.theme.algorithm=n}}),Le=(0,u.createStore)()((0,v.subscribeWithSelector)((...e)=>({...je(...e),...Me(...e),...Ne(...e),...Ie(...e)}))),$=`store`,Re={name:$,install(e,t={}){e[$]=Le}},ze=()=>{let e=(0,m.useNavigate)(),t=(0,m.useLocation)(),n=(0,m.useMatches)(),r=(0,u.useStore)(x.store,e=>e.locale),[i,a]=(0,l.useState)(!1),o=t=>{e(t.path)};return(0,l.useEffect)(()=>{x.client.navigate=e},[]),(0,l.useEffect)(()=>{x.client.matches=n},[n]),(0,f.jsx)(y.ProLayout,{locale:r,formatMessage:({id:e,defaultMessage:t})=>x.i18n.intl.get(e).d(t),location:t,menuItemRender:(e,t)=>(0,f.jsx)(`div`,{onClick:()=>o(e),children:t}),onMenuHeaderClick:()=>{e(`/`)},onPageChange:e=>{x.client.location=e;let t=e.pathname;if(!x.app.user||Object.keys(x.app.user).length===0)return x.app.pageToLogin();a(x.app.permissions.includes(t))},...x.config.proLayoutConfig,menu:{request:async()=>x.app.menuData||[],...x.config.proLayoutConfig.menu},children:(0,f.jsx)(l.Suspense,{fallback:(0,f.jsx)(f.Fragment,{children:`Loading...`}),children:i?(0,f.jsx)(m.Outlet,{}):(0,f.jsx)(f.Fragment,{children:`无权限`})})})};var Be=(0,l.memo)(ze);const Ve=()=>{let e=(0,m.useNavigate)(),[t,n]=(0,l.useState)(!1);return(0,f.jsx)(c.Flex,{style:{width:`100%`,height:`100%`,background:`var(--bg-color)`},justify:`center`,align:`center`,children:(0,f.jsxs)(c.Form,{labelCol:{span:8},wrapperCol:{span:16},style:{maxWidth:600},initialValues:{remember:!0},onFinish:async t=>{n(()=>!0);let r=await x.api.request(`/login`,{method:`POST`,data:t});n(()=>!1);let i=r?.data?.token||``;i&&(x.storage.setToken(i),e(x.app.getRedirectPath(),{replace:!0}))},autoComplete:`off`,children:[(0,f.jsx)(c.Form.Item,{label:`用户名`,name:`username`,rules:[{required:!0,message:`请输入用户名!`}],children:(0,f.jsx)(c.Input,{})}),(0,f.jsx)(c.Form.Item,{label:`密码`,name:`password`,rules:[{required:!0,message:`请输入密码!`}],children:(0,f.jsx)(c.Input.Password,{})}),(0,f.jsx)(c.Form.Item,{label:null,children:(0,f.jsx)(c.Button,{block:!0,type:`primary`,htmlType:`submit`,loading:t,children:`登录`})})]})})};var He=Ve;const Ue=({name:e,rootId:t})=>{let n=(0,u.useStore)(x.store,e=>e.microAppState);return(0,l.useEffect)(()=>{if(!e||x.config.qiankunMode!==`load`)return;let t=x.app.microAppsInstance.get(e);if(t)t.mount();else{let t=x.app.microApps.find(t=>t.name===e);if(!t)return;let n=(0,h.loadMicroApp)(t,{},P);x.app.microAppsInstance.set(e,n)}return console.log(`Microapp`,e),()=>{let t=x.app.microAppsInstance.get(e);t&&t.unmount()}},[e]),(0,f.jsxs)(f.Fragment,{children:[n&&(0,f.jsx)(`div`,{children:`Loading...`}),(0,f.jsx)(`main`,{id:t})]})};var We=(0,l.memo)(Ue);const Ge=()=>{let e=(0,m.useNavigate)();return x.client.navigate=e,(0,f.jsx)(c.Flex,{style:{width:`100%`,height:`100%`,background:`var(--bg-color)`},justify:`center`,align:`center`,children:(0,f.jsx)(c.Empty,{description:`找不到页面`})})};var Ke=Ge;const qe=`ui`,Je={name:`ui`,install(e,t={}){e.ui=M({Login:He,NotFound:Ke,Layout:Be,Microapp:We,getComponent:t=>{if(!t)throw Error(`Component name cannot be empty`);return e.ui[t]},renderComponent:(t,n={})=>{let r=e.ui.getComponent(t);if(!r)throw Error(`Component ${t} not found`);return(0,l.createElement)(r,n)}},t)}};exports.AntdConfigProvider=N,exports.MainApp=G,exports.SdkApiPlugin=we,exports.SdkAppPlugin=Ee,exports.SdkClientPlugin=De,exports.SdkConfigPlugin=Oe,exports.SdkI18nPlugin=ke,exports.SdkStoragePlugin=Ae,exports.SdkStorePlugin=Re,exports.SdkUIPlugin=Je,exports.sdk=x;
2
- //# sourceMappingURL=index.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs","names":["isPrimitive","value","isTypedArray","x","ArrayBuffer","isView","DataView","getSymbols","object","Object","getOwnPropertySymbols","filter","symbol","prototype","propertyIsEnumerable","call","getTag","value","undefined","Object","prototype","toString","call","regexpTag","stringTag","numberTag","booleanTag","argumentsTag","symbolTag","dateTag","mapTag","setTag","arrayTag","functionTag","arrayBufferTag","objectTag","errorTag","dataViewTag","uint8ArrayTag","uint8ClampedArrayTag","uint16ArrayTag","uint32ArrayTag","bigUint64ArrayTag","int8ArrayTag","int16ArrayTag","int32ArrayTag","bigInt64ArrayTag","float32ArrayTag","float64ArrayTag","getSymbols","getTag","uint32ArrayTag","uint16ArrayTag","uint8ClampedArrayTag","uint8ArrayTag","symbolTag","stringTag","setTag","regexpTag","objectTag","numberTag","mapTag","int32ArrayTag","int16ArrayTag","int8ArrayTag","float64ArrayTag","float32ArrayTag","dateTag","booleanTag","dataViewTag","arrayBufferTag","arrayTag","argumentsTag","isPrimitive","isTypedArray","cloneDeepWith","obj","cloneValue","cloneDeepWithImpl","undefined","Map","valueToClone","keyToClone","objectToClone","stack","cloned","has","get","Array","isArray","result","length","set","i","Object","hasOwn","index","input","Date","getTime","RegExp","source","flags","lastIndex","key","value","Set","add","Buffer","isBuffer","subarray","getPrototypeOf","constructor","ArrayBuffer","SharedArrayBuffer","slice","DataView","buffer","byteOffset","byteLength","copyProperties","File","name","type","Blob","Error","message","cause","Boolean","valueOf","Number","String","isCloneableObject","create","target","keys","descriptor","getOwnPropertyDescriptor","writable","object","cloneDeepWithImpl","cloneDeep","obj","undefined","Map","isPlainObject","value","proto","Object","getPrototypeOf","hasObjectPrototype","prototype","toString","call","isUnsafeProperty","key","isUnsafeProperty","isPlainObject","merge","target","source","sourceKeys","Object","keys","i","length","key","sourceValue","targetValue","Array","isArray","undefined","AntdConfigProvider: React.FC<ConfigProviderProps>","ConfigProvider","lifeCyclesUtil: FrameworkLifeCycles<ObjectType>","sdk","Icons","microAppsMap: MicroAppsMap","sdk","Outlet","location","MainApp: React.FC","defaulRoutes: RouteObject[]","allRoutes: RouteObject[]","Navigate","WithRouterInfo","Suspense","RouterProvider","idCounter","uniqueId","prefix","id","pluginName","SdkApiPlugin: Plugin<'api'>","Http","sdk","options","pluginName","SdkAppPlugin: Plugin<'app'>","sdk","pluginName","SdkClientPlugin: Plugin<'client'>","pluginName","SdkConfigPlugin: Plugin<'config'>","pluginName","SdkI18nPlugin: Plugin<'i18n'>","intl","pluginName","SdkStoragePlugin: Plugin<'storage'>","sdk","createAppStateSlice: StateCreator<AppStateStoreProps>","createInitStateSlice: StateCreator<InitStateStoreProps>","createLocaleSlice: StateCreator<LocaleStoreProps>","antdTheme","createThemeSlice: StateCreator<ThemeStoreProps>","pluginName","SdkStorePlugin: Plugin<'store'>","BaseLayout: React.FC","location","ProLayout","Suspense","Outlet","Login: React.FC","handleFinish: FormProps['onFinish']","Flex","Form","Input","Button","Microapp: React.FC<Props>","NotFound: React.FC","Flex","Empty","SdkUIPlugin: Plugin<'ui'>","sdk"],"sources":["../../src/core/index.ts","../../../node_modules/.pnpm/es-toolkit@1.41.0/node_modules/es-toolkit/dist/predicate/isPrimitive.mjs","../../../node_modules/.pnpm/es-toolkit@1.41.0/node_modules/es-toolkit/dist/predicate/isTypedArray.mjs","../../../node_modules/.pnpm/es-toolkit@1.41.0/node_modules/es-toolkit/dist/compat/_internal/getSymbols.mjs","../../../node_modules/.pnpm/es-toolkit@1.41.0/node_modules/es-toolkit/dist/compat/_internal/getTag.mjs","../../../node_modules/.pnpm/es-toolkit@1.41.0/node_modules/es-toolkit/dist/compat/_internal/tags.mjs","../../../node_modules/.pnpm/es-toolkit@1.41.0/node_modules/es-toolkit/dist/object/cloneDeepWith.mjs","../../../node_modules/.pnpm/es-toolkit@1.41.0/node_modules/es-toolkit/dist/object/cloneDeep.mjs","../../../node_modules/.pnpm/es-toolkit@1.41.0/node_modules/es-toolkit/dist/predicate/isPlainObject.mjs","../../../node_modules/.pnpm/es-toolkit@1.41.0/node_modules/es-toolkit/dist/_internal/isUnsafeProperty.mjs","../../../node_modules/.pnpm/es-toolkit@1.41.0/node_modules/es-toolkit/dist/object/merge.mjs","../../src/components/antdConfigProvider/index.tsx","../../src/utils/constant.ts","../../src/utils/menus.tsx","../../src/utils/request.ts","../../src/components/withRouterInfo/index.tsx","../../src/components/mainApp/index.tsx","../../../node_modules/.pnpm/es-toolkit@1.41.0/node_modules/es-toolkit/dist/compat/util/uniqueId.mjs","../../src/plugins/api/http.ts","../../src/plugins/api/index.ts","../../src/plugins/app/index.tsx","../../src/plugins/client/index.ts","../../src/plugins/config/index.ts","../../src/plugins/i18n/index.ts","../../src/plugins/storage/index.ts","../../src/plugins/store/createAppState.ts","../../src/plugins/store/createInitState.ts","../../src/plugins/store/createLocale.ts","../../src/plugins/store/createTheme.ts","../../src/plugins/store/index.ts","../../src/plugins/ui/layout/index.tsx","../../src/plugins/ui/login/index.tsx","../../src/plugins/ui/microapp/index.tsx","../../src/plugins/ui/notFound/index.tsx","../../src/plugins/ui/index.ts"],"sourcesContent":["import { Plugin, PluginOptions, SdkResult } from '@/types';\n\nclass Sdk implements SdkResult {\n name: SdkResult['name'];\n _plugins: SdkResult['_plugins'];\n\n api: SdkResult['api'];\n app: SdkResult['app'];\n client: SdkResult['client'];\n config: SdkResult['config'];\n i18n: SdkResult['i18n'];\n storage: SdkResult['storage'];\n store: SdkResult['store'];\n ui: SdkResult['ui'];\n\n constructor() {\n this.name = '';\n this._plugins = new Map();\n }\n\n mount(name: string) {\n // 如果已经存在同名的sdk实例,则直接返回(子应用)\n if (name && window[name]) {\n Object.assign(this, window[name]); // 合并实例属性\n } else {\n // 否则创建一个新的sdk实例, 并手动挂载到window上 (主应用)\n this.name = name;\n\n // 使用 new Proxy 禁止控制台对sdk属性的操作 (仅第一层属性)\n const _this = new Proxy(this, {\n get: (target, key, receiver) => {\n if (!target) return null;\n return Reflect.get(target, key, receiver);\n },\n set: () => {\n console.error('The SDK cannot be modified.');\n return false;\n },\n deleteProperty: () => {\n console.error('The SDK cannot be deleted.');\n return false;\n },\n });\n\n // 挂载到 Window 上\n window[this.name] = _this;\n }\n }\n\n unmount() {\n // 清空插件\n this._plugins.clear();\n // 删除window上的实例\n delete window[this.name];\n }\n\n use<K extends keyof PluginOptions>(plugin: Plugin<K>, options?: PluginOptions[K]) {\n const { name, install } = plugin;\n\n if (!name) throw new Error(`${name} plugin has no name`);\n\n if (typeof install !== 'function') throw new Error(`${name} plugin is not a function`);\n\n // 插件安装\n install(this as any, options);\n\n // 添加到插件列表\n this._plugins.set(name, { ...plugin, options });\n\n // 链式调用\n return this;\n }\n}\n\n/**\n * sdk 实例\n * @example sdk.use(SdkPlugin) // 使用插件\n * @example sdk.mount('SdkName') // 挂载到 window 上\n * @example sdk.unmount() // 卸载\n */\nconst sdk = new Sdk();\n\nexport { sdk };\n","function isPrimitive(value) {\n return value == null || (typeof value !== 'object' && typeof value !== 'function');\n}\n\nexport { isPrimitive };\n","function isTypedArray(x) {\n return ArrayBuffer.isView(x) && !(x instanceof DataView);\n}\n\nexport { isTypedArray };\n","function getSymbols(object) {\n return Object.getOwnPropertySymbols(object).filter(symbol => Object.prototype.propertyIsEnumerable.call(object, symbol));\n}\n\nexport { getSymbols };\n","function getTag(value) {\n if (value == null) {\n return value === undefined ? '[object Undefined]' : '[object Null]';\n }\n return Object.prototype.toString.call(value);\n}\n\nexport { getTag };\n","const regexpTag = '[object RegExp]';\nconst stringTag = '[object String]';\nconst numberTag = '[object Number]';\nconst booleanTag = '[object Boolean]';\nconst argumentsTag = '[object Arguments]';\nconst symbolTag = '[object Symbol]';\nconst dateTag = '[object Date]';\nconst mapTag = '[object Map]';\nconst setTag = '[object Set]';\nconst arrayTag = '[object Array]';\nconst functionTag = '[object Function]';\nconst arrayBufferTag = '[object ArrayBuffer]';\nconst objectTag = '[object Object]';\nconst errorTag = '[object Error]';\nconst dataViewTag = '[object DataView]';\nconst uint8ArrayTag = '[object Uint8Array]';\nconst uint8ClampedArrayTag = '[object Uint8ClampedArray]';\nconst uint16ArrayTag = '[object Uint16Array]';\nconst uint32ArrayTag = '[object Uint32Array]';\nconst bigUint64ArrayTag = '[object BigUint64Array]';\nconst int8ArrayTag = '[object Int8Array]';\nconst int16ArrayTag = '[object Int16Array]';\nconst int32ArrayTag = '[object Int32Array]';\nconst bigInt64ArrayTag = '[object BigInt64Array]';\nconst float32ArrayTag = '[object Float32Array]';\nconst float64ArrayTag = '[object Float64Array]';\n\nexport { argumentsTag, arrayBufferTag, arrayTag, bigInt64ArrayTag, bigUint64ArrayTag, booleanTag, dataViewTag, dateTag, errorTag, float32ArrayTag, float64ArrayTag, functionTag, int16ArrayTag, int32ArrayTag, int8ArrayTag, mapTag, numberTag, objectTag, regexpTag, setTag, stringTag, symbolTag, uint16ArrayTag, uint32ArrayTag, uint8ArrayTag, uint8ClampedArrayTag };\n","import { getSymbols } from '../compat/_internal/getSymbols.mjs';\nimport { getTag } from '../compat/_internal/getTag.mjs';\nimport { uint32ArrayTag, uint16ArrayTag, uint8ClampedArrayTag, uint8ArrayTag, symbolTag, stringTag, setTag, regexpTag, objectTag, numberTag, mapTag, int32ArrayTag, int16ArrayTag, int8ArrayTag, float64ArrayTag, float32ArrayTag, dateTag, booleanTag, dataViewTag, arrayBufferTag, arrayTag, argumentsTag } from '../compat/_internal/tags.mjs';\nimport { isPrimitive } from '../predicate/isPrimitive.mjs';\nimport { isTypedArray } from '../predicate/isTypedArray.mjs';\n\nfunction cloneDeepWith(obj, cloneValue) {\n return cloneDeepWithImpl(obj, undefined, obj, new Map(), cloneValue);\n}\nfunction cloneDeepWithImpl(valueToClone, keyToClone, objectToClone, stack = new Map(), cloneValue = undefined) {\n const cloned = cloneValue?.(valueToClone, keyToClone, objectToClone, stack);\n if (cloned !== undefined) {\n return cloned;\n }\n if (isPrimitive(valueToClone)) {\n return valueToClone;\n }\n if (stack.has(valueToClone)) {\n return stack.get(valueToClone);\n }\n if (Array.isArray(valueToClone)) {\n const result = new Array(valueToClone.length);\n stack.set(valueToClone, result);\n for (let i = 0; i < valueToClone.length; i++) {\n result[i] = cloneDeepWithImpl(valueToClone[i], i, objectToClone, stack, cloneValue);\n }\n if (Object.hasOwn(valueToClone, 'index')) {\n result.index = valueToClone.index;\n }\n if (Object.hasOwn(valueToClone, 'input')) {\n result.input = valueToClone.input;\n }\n return result;\n }\n if (valueToClone instanceof Date) {\n return new Date(valueToClone.getTime());\n }\n if (valueToClone instanceof RegExp) {\n const result = new RegExp(valueToClone.source, valueToClone.flags);\n result.lastIndex = valueToClone.lastIndex;\n return result;\n }\n if (valueToClone instanceof Map) {\n const result = new Map();\n stack.set(valueToClone, result);\n for (const [key, value] of valueToClone) {\n result.set(key, cloneDeepWithImpl(value, key, objectToClone, stack, cloneValue));\n }\n return result;\n }\n if (valueToClone instanceof Set) {\n const result = new Set();\n stack.set(valueToClone, result);\n for (const value of valueToClone) {\n result.add(cloneDeepWithImpl(value, undefined, objectToClone, stack, cloneValue));\n }\n return result;\n }\n if (typeof Buffer !== 'undefined' && Buffer.isBuffer(valueToClone)) {\n return valueToClone.subarray();\n }\n if (isTypedArray(valueToClone)) {\n const result = new (Object.getPrototypeOf(valueToClone).constructor)(valueToClone.length);\n stack.set(valueToClone, result);\n for (let i = 0; i < valueToClone.length; i++) {\n result[i] = cloneDeepWithImpl(valueToClone[i], i, objectToClone, stack, cloneValue);\n }\n return result;\n }\n if (valueToClone instanceof ArrayBuffer ||\n (typeof SharedArrayBuffer !== 'undefined' && valueToClone instanceof SharedArrayBuffer)) {\n return valueToClone.slice(0);\n }\n if (valueToClone instanceof DataView) {\n const result = new DataView(valueToClone.buffer.slice(0), valueToClone.byteOffset, valueToClone.byteLength);\n stack.set(valueToClone, result);\n copyProperties(result, valueToClone, objectToClone, stack, cloneValue);\n return result;\n }\n if (typeof File !== 'undefined' && valueToClone instanceof File) {\n const result = new File([valueToClone], valueToClone.name, {\n type: valueToClone.type,\n });\n stack.set(valueToClone, result);\n copyProperties(result, valueToClone, objectToClone, stack, cloneValue);\n return result;\n }\n if (typeof Blob !== 'undefined' && valueToClone instanceof Blob) {\n const result = new Blob([valueToClone], { type: valueToClone.type });\n stack.set(valueToClone, result);\n copyProperties(result, valueToClone, objectToClone, stack, cloneValue);\n return result;\n }\n if (valueToClone instanceof Error) {\n const result = new valueToClone.constructor();\n stack.set(valueToClone, result);\n result.message = valueToClone.message;\n result.name = valueToClone.name;\n result.stack = valueToClone.stack;\n result.cause = valueToClone.cause;\n copyProperties(result, valueToClone, objectToClone, stack, cloneValue);\n return result;\n }\n if (valueToClone instanceof Boolean) {\n const result = new Boolean(valueToClone.valueOf());\n stack.set(valueToClone, result);\n copyProperties(result, valueToClone, objectToClone, stack, cloneValue);\n return result;\n }\n if (valueToClone instanceof Number) {\n const result = new Number(valueToClone.valueOf());\n stack.set(valueToClone, result);\n copyProperties(result, valueToClone, objectToClone, stack, cloneValue);\n return result;\n }\n if (valueToClone instanceof String) {\n const result = new String(valueToClone.valueOf());\n stack.set(valueToClone, result);\n copyProperties(result, valueToClone, objectToClone, stack, cloneValue);\n return result;\n }\n if (typeof valueToClone === 'object' && isCloneableObject(valueToClone)) {\n const result = Object.create(Object.getPrototypeOf(valueToClone));\n stack.set(valueToClone, result);\n copyProperties(result, valueToClone, objectToClone, stack, cloneValue);\n return result;\n }\n return valueToClone;\n}\nfunction copyProperties(target, source, objectToClone = target, stack, cloneValue) {\n const keys = [...Object.keys(source), ...getSymbols(source)];\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const descriptor = Object.getOwnPropertyDescriptor(target, key);\n if (descriptor == null || descriptor.writable) {\n target[key] = cloneDeepWithImpl(source[key], key, objectToClone, stack, cloneValue);\n }\n }\n}\nfunction isCloneableObject(object) {\n switch (getTag(object)) {\n case argumentsTag:\n case arrayTag:\n case arrayBufferTag:\n case dataViewTag:\n case booleanTag:\n case dateTag:\n case float32ArrayTag:\n case float64ArrayTag:\n case int8ArrayTag:\n case int16ArrayTag:\n case int32ArrayTag:\n case mapTag:\n case numberTag:\n case objectTag:\n case regexpTag:\n case setTag:\n case stringTag:\n case symbolTag:\n case uint8ArrayTag:\n case uint8ClampedArrayTag:\n case uint16ArrayTag:\n case uint32ArrayTag: {\n return true;\n }\n default: {\n return false;\n }\n }\n}\n\nexport { cloneDeepWith, cloneDeepWithImpl, copyProperties };\n","import { cloneDeepWithImpl } from './cloneDeepWith.mjs';\n\nfunction cloneDeep(obj) {\n return cloneDeepWithImpl(obj, undefined, obj, new Map(), undefined);\n}\n\nexport { cloneDeep };\n","function isPlainObject(value) {\n if (!value || typeof value !== 'object') {\n return false;\n }\n const proto = Object.getPrototypeOf(value);\n const hasObjectPrototype = proto === null ||\n proto === Object.prototype ||\n Object.getPrototypeOf(proto) === null;\n if (!hasObjectPrototype) {\n return false;\n }\n return Object.prototype.toString.call(value) === '[object Object]';\n}\n\nexport { isPlainObject };\n","function isUnsafeProperty(key) {\n return key === '__proto__';\n}\n\nexport { isUnsafeProperty };\n","import { isUnsafeProperty } from '../_internal/isUnsafeProperty.mjs';\nimport { isPlainObject } from '../predicate/isPlainObject.mjs';\n\nfunction merge(target, source) {\n const sourceKeys = Object.keys(source);\n for (let i = 0; i < sourceKeys.length; i++) {\n const key = sourceKeys[i];\n if (isUnsafeProperty(key)) {\n continue;\n }\n const sourceValue = source[key];\n const targetValue = target[key];\n if (Array.isArray(sourceValue)) {\n if (Array.isArray(targetValue)) {\n target[key] = merge(targetValue, sourceValue);\n }\n else {\n target[key] = merge([], sourceValue);\n }\n }\n else if (isPlainObject(sourceValue)) {\n if (isPlainObject(targetValue)) {\n target[key] = merge(targetValue, sourceValue);\n }\n else {\n target[key] = merge({}, sourceValue);\n }\n }\n else if (targetValue === undefined || sourceValue !== undefined) {\n target[key] = sourceValue;\n }\n }\n return target;\n}\n\nexport { merge };\n","import { sdk } from '@/core';\nimport { ConfigProvider, ConfigProviderProps } from 'antd';\nimport { cloneDeep, merge } from 'es-toolkit';\nimport React, { useMemo } from 'react';\nimport { useStore } from 'zustand';\nimport { useShallow } from 'zustand/shallow';\n\n/**\n * Antd 配置\n * - 填充了 theme 和 locale 属性\n * - 详情参考: https://ant.design/components/config-provider-cn\n */\nconst AntdConfigProvider: React.FC<ConfigProviderProps> = (props) => {\n const { children } = props;\n\n const [locale, theme] = useStore(\n sdk.store,\n useShallow((state) => [state.locale, state.theme]),\n );\n\n const config = useMemo(() => {\n const antdConfig = cloneDeep(sdk.config.antdConfig); // 改变引用地址\n return merge(antdConfig, props);\n }, [locale, theme]);\n\n return <ConfigProvider {...config}>{children}</ConfigProvider>;\n};\n\nexport { AntdConfigProvider };\n","import { LocaleProps, SdkResult, ThemeProps } from '@/types';\nimport { FrameworkLifeCycles, ObjectType } from 'qiankun';\n\n/** qiankun 生命周期 钩子函数 */\nexport const lifeCyclesUtil: FrameworkLifeCycles<ObjectType> = {\n beforeLoad: [\n async (app) => {\n console.log('[LifeCycle] before load %c%s', 'color: green;', app.name);\n },\n ],\n beforeMount: [\n async (app) => {\n console.log('[LifeCycle] before mount %c%s', 'color: green;', app.name);\n },\n ],\n afterUnmount: [\n async (app) => {\n console.log('[LifeCycle] after unmount %c%s', 'color: green;', app.name);\n },\n ],\n};\n\n/**\n * 获取主题默认值\n * @param sdk sdk\n */\nexport const getDefaultThemeUtil = (sdk: SdkResult): ThemeProps => {\n // localStorage > sdk中主题 > 系统主题 > 默认\n\n // 1. localStorage\n const localTheme = sdk.storage.getTheme() as ThemeProps;\n if (localTheme) return localTheme;\n\n // 2. sdk中主题\n const sdkTheme = sdk.config?.theme;\n if (sdkTheme) return sdkTheme;\n\n // 3. 系统主题\n const media = window.matchMedia('(prefers-color-scheme: dark)');\n if (media.matches) return media.matches ? 'dark' : 'light';\n\n // 4. 默认\n return 'light';\n};\n\n/**\n * 获取国际化默认值\n * @param sdk sdk\n */\nexport const getDefaultLocaleUtil = (sdk: SdkResult): LocaleProps => {\n // localStorage > sdk中国际化 > 浏览器语言 > 默认\n\n // 1. localStorage\n const localLocale = sdk.storage.getLocale() as LocaleProps;\n if (localLocale) return localLocale;\n\n // 2. sdk中国际化\n const sdkLocale = sdk.config?.locale;\n if (sdkLocale) return sdkLocale;\n\n // 3. 浏览器语言\n const browserLocale = navigator.language as LocaleProps;\n if (browserLocale) return browserLocale;\n\n // 4. 默认\n return 'zh-CN';\n};\n","import { SdkResult } from '@/types';\nimport * as Icons from '@ant-design/icons';\nimport { ObjectType, RegistrableApp } from 'qiankun';\nimport { createElement } from 'react';\nimport { Outlet } from 'react-router-dom';\n\ntype MicroAppsMap = Map<string, RegistrableApp<ObjectType>>;\n\n/**\n * 动态创建Icon\n * @param icon icon名称\n */\nexport const dynamicIcon = (icon: string) => {\n const antIcon: { [key: string]: any } = Icons; // 防止类型报错\n return createElement(antIcon[icon]);\n};\n\n/**\n * 处理路由数据\n * @param routes 路由数据\n * @param sdk sdk\n */\nexport const handleRoutesUtil = (routes: any[], sdk: SdkResult) => {\n const microAppsMap: MicroAppsMap = new Map();\n const menuData = transformRoutesUtil(routes, microAppsMap, sdk);\n const microApps = [...microAppsMap.values()];\n return { microApps, menuData };\n};\n\n/**\n * 递归转换路由数据\n * @param routes 路由数据\n * @param microApps 子应用列表\n * @param sdk sdk\n */\nexport const transformRoutesUtil = (routes: any[], microAppsMap: MicroAppsMap, sdk: SdkResult) => {\n if (!routes || routes?.length === 0) return [];\n\n return routes.map((item) => {\n let element = null; // 组件\n\n const { locale, path, icon, component, routeAttr, children } = item;\n\n // 处理子应用路由\n if (routeAttr) {\n let newRouteAttr = {} as any;\n\n try {\n newRouteAttr = JSON.parse(routeAttr); // // 解析子应用路由属性\n } catch (error) {\n console.error('子应用路由属性格式错误:', routeAttr);\n }\n\n const { name, rootId, ...rest } = newRouteAttr;\n\n // 子应用信息\n const microAppInfo = {\n ...rest,\n name,\n container: `#${rootId}`,\n props: { sdk },\n loader: (loading) => sdk.store.getState().setMicroAppState(loading),\n };\n\n // 添加子应用信息\n microAppsMap.set(name, microAppInfo);\n\n element = sdk.ui.renderComponent('Microapp', { name, rootId }); // 子应用挂载组件\n } else if (component === 'Outlet') {\n element = <Outlet />; // 路由出口组件\n } else {\n element = sdk.ui.renderComponent(component); // 普通组件\n }\n\n // 转换子路由\n const processedChildren = children?.length\n ? transformRoutesUtil(children, microAppsMap, sdk)\n : [];\n\n return {\n ...item,\n key: `${locale}_${icon}_${path}`, // 唯一key, 判断菜单是否折叠\n element,\n icon: dynamicIcon(icon),\n children: processedChildren,\n handle: {\n // 用户面包屑 https://reactrouter.com/6.30.1/hooks/use-matches\n crumb: (data) => ({ ...item, ...data }),\n },\n };\n });\n};\n\n/**\n * 获取第一个页面的路径\n * @param routes 路由数据\n */\nexport const getFirstPagePathUtil = (routes: any[]) => {\n let firstPagePath = '/';\n\n if (!routes || routes.length === 0) return firstPagePath;\n\n firstPagePath = routes?.[0]?.path;\n\n if (routes?.[0]?.children && routes?.[0]?.children.length > 0) {\n firstPagePath = getFirstPagePathUtil(routes?.[0]?.children);\n }\n\n return firstPagePath;\n};\n","import { sdk } from '@/core';\nimport { ApiRequestOption } from '@/plugins/api/http';\nimport { AxiosResponse } from 'axios';\n\n/**\n * 生成请求id\n * @param config\n */\nexport const generateRequestIdUtil = (config: any) => {\n const { requestId, url, method, params, data } = config as ApiRequestOption;\n if (requestId) return requestId;\n\n return `${method}:${url}?${JSON.stringify(params)}&${JSON.stringify(data)}`;\n};\n\n/**\n * 取消请求\n * @param config 请求配置\n */\nexport const cancelRequestUtil = (config: any) => {\n const requestId = generateRequestIdUtil(config);\n\n const controller = sdk.api.controllers.get(requestId);\n if (!controller) return;\n\n controller.abort();\n sdk.api.controllers.delete(requestId);\n};\n\n/**\n * 下载文件\n * @param resp 响应数据\n */\nexport const downloadFileUtil = (resp: AxiosResponse) => {\n // 1. 从响应头中解析文件名\n const contentDisposition = resp.headers['content-disposition'];\n let filename = 'data.txt';\n\n if (contentDisposition) {\n // 使用正则匹配文件名(兼容带引号和不带引号的情况)\n const filenameMatch = contentDisposition.match(/filename=\"?(.+)\"?/);\n if (filenameMatch && filenameMatch[1]) {\n filename = filenameMatch[1];\n }\n }\n\n // 2. 创建 blob 对象\n const blob = new Blob([resp.data], { type: 'application/pdf' });\n\n // 3. 创建下载链接\n const url = window.URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = filename; // Specify the file name\n document.body.appendChild(link);\n link.click();\n\n // 4. 释放 blob 对象\n window.URL.revokeObjectURL(url);\n document.body.removeChild(link);\n};\n","import { sdk } from '@/core';\nimport { useEffect } from 'react';\nimport { useLocation, useMatches, useNavigate } from 'react-router-dom';\n\n/**\n * 记录路由信息\n * - 高阶HOC组件\n */\nconst WithRouterInfo = ({ children }: any) => {\n const location = useLocation();\n const navigate = useNavigate();\n const matches = useMatches();\n\n if (!sdk.client.location) sdk.client.location = location;\n if (!sdk.client.navigate) sdk.client.navigate = navigate;\n\n useEffect(() => {\n sdk.client.matches = matches;\n }, [matches]);\n\n return children;\n};\n\nexport default WithRouterInfo;\n","import { sdk } from '@/core';\nimport { LocaleProps, ThemeProps } from '@/types';\nimport {\n getDefaultLocaleUtil,\n getDefaultThemeUtil,\n getFirstPagePathUtil,\n handleRoutesUtil,\n lifeCyclesUtil,\n} from '@/utils';\nimport { registerMicroApps, start } from 'qiankun';\nimport React, { Suspense, useEffect, useState } from 'react';\nimport { createBrowserRouter, Navigate, RouteObject, RouterProvider } from 'react-router-dom';\nimport { useStore } from 'zustand';\nimport { useShallow } from 'zustand/shallow';\nimport { AntdConfigProvider } from '../antdConfigProvider';\nimport WithRouterInfo from '../withRouterInfo';\n\n/** 主应用的根组件 */\nconst MainApp: React.FC = () => {\n const loginPath = sdk.config.loginPath;\n\n const defaulRoutes: RouteObject[] = [\n { path: loginPath, element: sdk.ui.renderComponent('Login') },\n { path: '*', element: sdk.ui.renderComponent('NotFound') },\n ...sdk.config.customRoutes,\n ];\n\n const [setTheme, setLocale, setInitState] = useStore(\n sdk.store,\n useShallow((state) => [state.setTheme, state.setLocale, state.setInitState]),\n );\n\n const [loading, setLoading] = useState(false);\n const [router, setRouter] = useState<RouteObject[]>(defaulRoutes);\n\n /** 设置图标组件 */\n\n /** 设置主题和国际化 */\n const setThemeLocale = (apiTheme?: ThemeProps, apiLocale?: LocaleProps) => {\n setTheme(apiTheme || getDefaultThemeUtil(sdk));\n setLocale(apiLocale || getDefaultLocaleUtil(sdk));\n };\n\n /** 初始化数据方法 */\n const initData = async () => {\n try {\n // 获取数据\n setLoading(() => true);\n const [{ data: userInfo = {} }, { data: routes = [] }] = await Promise.all([\n sdk.api.getUserInfoApi(),\n sdk.api.getRoutesApi(),\n ]);\n setLoading(() => false);\n\n // 设置主题和语言\n const { theme, locale } = userInfo?.settings || {};\n setThemeLocale(theme, locale);\n\n // 处理路由数据\n const { microApps, menuData } = handleRoutesUtil(routes, sdk);\n\n if (sdk.config.qiankunMode === 'router' && microApps && microApps.length) {\n // 注册微应用\n registerMicroApps(microApps, lifeCyclesUtil);\n\n // 启动 qiankun\n start();\n }\n\n // 获取首页路径\n const firstPath = getFirstPagePathUtil(menuData);\n\n // 合并所有路由\n const allRoutes: RouteObject[] = [\n ...defaulRoutes,\n { path: '/', element: <Navigate to={firstPath} replace /> },\n {\n path: '/',\n element: sdk.ui.renderComponent('Layout'),\n children: menuData,\n errorElement: <>找不到页面</>,\n },\n ];\n\n setRouter(\n allRoutes.map((item) => ({\n ...item,\n element: WithRouterInfo(item.element),\n })),\n ); // 重新赋值,触发路由更新\n\n sdk.app = { ...sdk.app, allRoutes, microApps, menuData };\n setInitState(userInfo);\n } catch (error) {\n setThemeLocale();\n setLoading(() => false);\n console.error('初始化数据错误:', error);\n }\n };\n\n // 设置初始值\n useEffect(() => {\n // 记录值\n sdk.app.allRoutes = defaulRoutes;\n\n const paths = sdk.config.customRoutes?.map((item) => item.path);\n const pathName = window.location.pathname;\n const noNeedAuth = [loginPath, ...paths]?.includes(pathName);\n\n // 如果时登录页面\n if (noNeedAuth) setThemeLocale();\n else initData();\n }, []);\n\n if (loading) return <>Loading...</>;\n\n return (\n <AntdConfigProvider>\n <Suspense fallback={<>Loading...</>}>\n <RouterProvider\n router={createBrowserRouter(router, { basename: '/' })}\n future={{ v7_startTransition: false }}\n />\n </Suspense>\n </AntdConfigProvider>\n );\n};\n\nexport { MainApp };\n","let idCounter = 0;\nfunction uniqueId(prefix = '') {\n const id = ++idCounter;\n return `${prefix}${id}`;\n}\n\nexport { uniqueId };\n","import { sdk } from '@/core';\nimport { cancelRequestUtil, generateRequestIdUtil } from '@/utils';\nimport { message } from 'antd';\nimport axios, {\n AxiosError,\n AxiosInstance,\n AxiosRequestConfig,\n AxiosResponse,\n CreateAxiosDefaults,\n InternalAxiosRequestConfig,\n} from 'axios';\n\nexport interface ApiRequestOption extends AxiosRequestConfig {\n /** 请求唯一key(默认自动生成) */\n requestId?: string;\n /** 是否需要原始数据 */\n isOriginalData?: boolean;\n /** 是否显示错误信息 */\n isShowFailMsg?: boolean;\n}\n\n/** 请求类 */\nclass Http {\n instance: AxiosInstance;\n\n constructor(options: CreateAxiosDefaults = {}) {\n this.instance = axios.create(options); // 创建实例\n this.defaultRequestInterceptor(); // 添加默认请求拦截器\n this.defaultResponseInterceptor(); // 添加默认响应拦截器\n }\n\n /** 默认请求拦截器 */\n defaultRequestInterceptor() {\n this.instance.interceptors.request.use(\n function (config: InternalAxiosRequestConfig) {\n const token = sdk.storage.getToken();\n\n // 设置请求唯一标识\n const requestId = generateRequestIdUtil(config);\n\n // 取消重复请求\n cancelRequestUtil(config);\n\n // 创建取消请求控制器\n const controller = new AbortController();\n sdk.api.controllers.set(requestId, controller);\n\n config['requestId'] = requestId; // 记录请求id\n config.signal = controller.signal; // 取消请求标识\n config.headers.Authorization = token; // 添加token到请求头\n config.headers.lang = sdk.config.locale; // 添加语言到请求头\n return config;\n },\n function (error: AxiosError) {\n console.error(`请求错误`);\n return Promise.reject(error);\n },\n );\n }\n\n /** 默认响应拦截器 */\n defaultResponseInterceptor() {\n this.instance.interceptors.response.use(\n function (response: AxiosResponse) {\n const { data, config } = response;\n const { isOriginalData, isShowFailMsg } = config as ApiRequestOption;\n\n const { code, msg } = data;\n\n // 跟后端定义的成功标识 非0的都是失败\n if (code !== 0) {\n if (isShowFailMsg) message.error(msg);\n console.error('response error: ', config.url, msg);\n\n if (code == 20041) sdk.app.pageToLogin(); // 登录过期,跳转登录页\n }\n\n sdk.api.controllers.delete(config['requestId']);\n\n return isOriginalData ? response : response.data;\n },\n function (error: AxiosError) {\n const { response, config } = error;\n const { isShowFailMsg } = config as ApiRequestOption;\n\n // 如果是取消请求,则不显示错误信息\n if (axios.isCancel(error)) return Promise.reject(error);\n\n if (response) {\n // 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围\n const { status, data, statusText } = response as AxiosResponse;\n\n if (isShowFailMsg) message.error(data.msg || statusText);\n\n if (status == 401) sdk.app.pageToLogin(); // 登录过期,跳转登录页\n } else {\n // 请求已经成功发起,但没有收到响应\n if (isShowFailMsg) message.error('请求超时或服务器异常,请检查网络或联系管理员');\n\n console.error('Request error:', config.url, error);\n }\n\n return Promise.reject(error);\n },\n );\n }\n\n /** 获取实例 */\n getInstance() {\n return this.instance;\n }\n}\n\nexport default Http;\n","import { Plugin, UserInfo } from '@/types';\nimport { cancelRequestUtil } from '@/utils';\nimport { message } from 'antd';\nimport { AxiosError, AxiosInstance, AxiosResponse, CreateAxiosDefaults } from 'axios';\nimport { merge } from 'es-toolkit';\nimport { uniqueId } from 'es-toolkit/compat';\nimport { RouteObject } from 'react-router-dom';\nimport Http, { ApiRequestOption } from './http';\n\ninterface ApiOptions {\n /** Axios配置 */\n config?: CreateAxiosDefaults;\n\n /** 取消请求控制器 */\n controllers?: Map<string, AbortController>;\n\n /**\n * 自定义请求实例\n * - 将替代 SDK 内置的请求实例\n * @example instance = axios.create(options)\n */\n instance?: AxiosInstance;\n\n /**\n * 获取用户信息\n * {@link UserInfo}\n * @example { data: { user: { ... }, permissions: [], roles: [], settings: {} }, code: 200 }\n */\n getUserInfoApi?: () => Promise<AxiosResponse<UserInfo>>;\n /**\n * 获取路由数据\n * @example { data: [{path: '/', name: '首页', element: 'Home'}], code: 200 }\n */\n getRoutesApi?: () => Promise<AxiosResponse<RouteObject[]>>;\n}\n\ninterface ApiResult extends Required<ApiOptions> {\n /**\n * 请求\n * @param url 请求地址\n * @param options 自定义配置项\n */\n readonly request: (url: string, options?: ApiRequestOption) => Promise<AxiosResponse<any, any>>;\n\n /**\n * 二次加工请求\n * @param url 请求地址\n * @param options 自定义配置项\n * @returns [resp, err, cancel]\n */\n readonly request2: (\n url: string,\n options?: ApiRequestOption,\n ) => Promise<[AxiosResponse<any, any>, AxiosError, () => void]>;\n\n /**\n * 下载文件\n * @param url 请求地址\n * @param options 自定义配置项\n * @returns [resp, err, cancel]\n */\n readonly download: (\n url: string,\n options?: ApiRequestOption,\n ) => Promise<[AxiosResponse<any, any>, AxiosError, () => void]>;\n}\n\n/** 插件名称 */\nconst pluginName = 'api';\n\n/**\n * 请求插件\n * - 详情参考 {@link ApiOptions} {@link ApiResult}\n * - 内置了请求, 通过 sdk.api.request 发起请求\n * - 可通过外部传入 instance 自定义请求实例\n * - 预置了获取用户信息, 获取路由, 登录接口等接口, 以便组件使用\n * @example sdk.api.request('/getTemp', { method: 'POST', ... })\n * @example sdk.api.request('/getTemp', { method: 'POST', isOriginalData: true }) // 返回原始数据\n * @example sdk.api.request('/getTemp', { method: 'POST', isShowFailMsg: false }) // 不显示错误信息\n */\nconst SdkApiPlugin: Plugin<'api'> = {\n name: pluginName,\n install(sdk, options = {}) {\n // Axios 配置\n const axiosConfig = {\n baseURL: '/api',\n timeout: 0,\n ...options.config,\n } satisfies ApiOptions['config'];\n\n // 创建 Axios 实例\n const instance = options?.instance || new Http(axiosConfig).getInstance();\n\n // 默认插件配置\n const defaultOptions = {\n config: axiosConfig,\n controllers: new Map(),\n\n instance: null,\n\n getUserInfoApi: () => sdk.api.request('/getUserInfo', { method: 'GET' }),\n getRoutesApi: () => sdk.api.request('/routes', { method: 'GET' }),\n\n request: (url, options = {}) => {\n return instance.request({ url, isOriginalData: false, isShowFailMsg: true, ...options });\n },\n\n request2: async (url, options = {}) => {\n let resp,\n err,\n cancel = null;\n\n const allOptions = { url, ...options };\n cancel = () => cancelRequestUtil(allOptions);\n\n try {\n resp = await sdk.api.request(url, allOptions);\n } catch (e) {\n err = e;\n }\n\n return [resp, err, cancel];\n },\n download: async (url, options = {}) => {\n let resp,\n err,\n cancel = null;\n\n const allOptions = {\n url,\n responseType: 'blob',\n ...options,\n } satisfies ApiRequestOption;\n const messageId = uniqueId();\n cancel = () => cancelRequestUtil(allOptions);\n\n message.loading({ key: messageId, content: '正在下载中...' });\n try {\n resp = await sdk.api.request(url, allOptions);\n message.success({ key: messageId, content: '下载成功' });\n } catch (e) {\n err = e;\n message.error({ key: messageId, content: '下载失败' });\n }\n\n return [resp, err, cancel];\n },\n } satisfies ApiResult;\n\n sdk[pluginName] = merge(defaultOptions, options);\n },\n};\n\nexport { ApiOptions, ApiResult, SdkApiPlugin };\n","import { Plugin, UserInfo } from '@/types';\nimport { MenuDataItem } from '@ant-design/pro-layout';\nimport { merge } from 'es-toolkit';\nimport { MicroApp, ObjectType, RegistrableApp } from 'qiankun';\nimport { RouteObject } from 'react-router-dom';\n\ninterface AppOptions {\n /** 菜单数据 */\n menuData?: MenuDataItem[];\n /** 所有路由信息 */\n allRoutes?: RouteObject[];\n\n /** 微应用信息 */\n microApps?: RegistrableApp<ObjectType>[];\n /** 微应用实例 */\n microAppsInstance?: Map<string, MicroApp>;\n\n /** 用户信息 */\n user?: UserInfo['user'];\n /** 用户权限 */\n permissions?: UserInfo['permissions'];\n /** 用户角色 */\n roles?: UserInfo['roles'];\n /** 用户设置 */\n settings?: UserInfo['settings'];\n}\n\ninterface AppResult extends Required<AppOptions> {\n /**\n * 跳转登录页\n */\n readonly pageToLogin: () => void;\n /**\n * 获取重定向路径\n */\n readonly getRedirectPath: () => string;\n}\n\n/** 插件名称 */\nconst pluginName = 'app';\n\n/**\n * 项目插件\n * - 详情参考 {@link AppOptions} {@link AppResult}\n * - 主要存储接口数据\n */\nconst SdkAppPlugin: Plugin<'app'> = {\n name: pluginName,\n install(sdk, options = {}) {\n // 默认插件配置\n const defaultOptions = {\n menuData: [],\n allRoutes: [],\n\n microApps: [],\n microAppsInstance: new Map(),\n\n user: null,\n permissions: [],\n roles: [],\n settings: {},\n\n pageToLogin: () => {\n // 清除 Token\n sdk.storage.clearToken();\n\n // 获取当前页路由\n const path = location.pathname;\n const loginPath = sdk.config.loginPath;\n const redirect = encodeURIComponent(path || '/');\n const allPath = path === loginPath ? loginPath : `${loginPath}?redirect=${redirect}`;\n\n // 跳转登录页(这里必须刷新一下页面, 否则qiankun实例不会销毁, 登录后会直接mount子应用, 而不是bootstrap子应用)\n window.location.replace(allPath);\n },\n getRedirectPath: () => {\n // 1. 优先使用指定值\n const defaultPath = sdk.config.defaultPath;\n if (defaultPath) return defaultPath;\n\n // 2. 其次使用重定向的值\n const param = new URLSearchParams(window.location.search);\n const redirect = decodeURIComponent(param.get('redirect') || '');\n if (redirect) return redirect;\n\n // 3. 最后使用菜单中第一项\n return '/';\n },\n } satisfies AppResult;\n\n sdk[pluginName] = merge(defaultOptions, options);\n },\n};\n\nexport { AppOptions, AppResult, SdkAppPlugin };\n","import { Plugin } from '@/types';\nimport { merge } from 'es-toolkit';\nimport { Location, NavigateFunction, UIMatch } from 'react-router-dom';\n\ninterface ClientOptions {}\n\ninterface ClientResult extends Required<ClientOptions> {\n /** 主应用 location */\n location: Location;\n /** 主应用navigate(解决子应用跳转问题) */\n navigate: NavigateFunction;\n /** 路由匹配(用于面包屑) */\n matches: UIMatch[];\n}\n\n/** 插件名称 */\nconst pluginName = 'client';\n\n/**\n * 路由插件\n * - 详情参考 {@link ClientOptions} {@link ClientResult}\n * - 路由信息 sdk.client.location\n * - 路由跳转 sdk.client.navigate\n * - 面包屑信息 sdk.client.matches\n */\nconst SdkClientPlugin: Plugin<'client'> = {\n name: pluginName,\n install(sdk, options = {}) {\n // 默认插件配置\n const defaultOptions = {\n location: null,\n navigate: null,\n matches: null,\n } satisfies ClientResult;\n\n sdk[pluginName] = merge(defaultOptions, options);\n },\n};\n\nexport { ClientOptions, ClientResult, SdkClientPlugin };\n","import { LocaleProps, Plugin, ThemeProps } from '@/types';\nimport { ProLayoutProps } from '@ant-design/pro-layout';\nimport { ConfigProviderProps } from 'antd';\nimport { merge } from 'es-toolkit';\nimport { RouteObject } from 'react-router-dom';\n\ninterface ConfigOptions {\n /** 环境变量 */\n env?: Record<string, any>;\n\n /** 主题 */\n theme?: ThemeProps;\n /** 国际化 */\n locale?: LocaleProps;\n\n /**\n * qiankun模式(切换模式后请打开新的窗口)\n * - 'router': 基于路由模式\n * - 'load': 手动加载模式\n */\n qiankunMode?: 'router' | 'load';\n\n /** 登录页路由 */\n loginPath?: string;\n /**\n * 登录后跳转的路由\n * - 优先使用指定值\n * - 其次使用重定向的值\n * - 最后使用菜单中第一项\n */\n defaultPath?: string;\n /**\n * 自定义路由信息\n * - 目前只支持最外层路由自定义\n * - 会合并到 sdk.app.allRoutes 中\n */\n customRoutes?: RouteObject[];\n\n /** Antd 配置 */\n antdConfig?: ConfigProviderProps;\n /** ProLayout 配置 */\n proLayoutConfig?: ProLayoutProps;\n}\n\ninterface ConfigResult extends Required<ConfigOptions> {}\n\n/** 插件名称 */\nconst pluginName = 'config';\n\n/**\n * 配置项插件\n * - 详情参考 {@link ConfigOptions} {@link ConfigResult}\n * - 配置 localStorage 变量名称\n * - 配置 默认主题、国际化\n * - 配置 默认登录路径、跳转路径、自定义路由\n * - 配置 Antd 配置、ProLayout 配置\n */\nconst SdkConfigPlugin: Plugin<'config'> = {\n name: pluginName,\n install(sdk, options = {}) {\n // 默认插件配置\n const defaultOptions = {\n env: {},\n\n qiankunMode: 'router',\n\n theme: null,\n locale: null,\n\n loginPath: '/login',\n defaultPath: '',\n customRoutes: [],\n\n antdConfig: {},\n proLayoutConfig: {\n title: 'Demo',\n },\n } satisfies ConfigResult;\n\n sdk[pluginName] = merge(defaultOptions, options);\n },\n};\n\nexport { ConfigOptions, ConfigResult, SdkConfigPlugin };\n","import { Plugin } from '@/types';\nimport { merge } from 'es-toolkit';\nimport intl from 'react-intl-universal';\n\ninterface I18nOptions {\n /**\n * React Intl Universal\n * - 不要解构使用, const { get } = useIntl() 会报错\n * - 如果项目不使用 React Compiler, 可以直接使用 sdk.i18n.intl\n * - 如果使用 React Compiler, 请使用 useIntl() 方法获取\n * @example\n * const intl = useIntl();\n * intl.get(key).d(defaultValue)\n */\n intl?: typeof intl;\n /**\n * React Intl Universal 配置的语言包\n * @example\n * {\n * 'zh-CN': {\n * test: '测试国际化'\n * },\n * 'en-US': {\n * test: 'Test Intl'\n * }\n * }\n */\n intlConfig?: Record<string, any>;\n /**\n * 加载 Antd 语言包\n * @param locale 语言包名\n * @example\n * import enUS from 'antd/es/locale/en_US';\n * import zhCN from 'antd/es/locale/zh_CN';\n * import dayjs from 'dayjs';\n * import 'dayjs/locale/en';\n * import 'dayjs/locale/zh';\n *\n * const loadLocale = (locale: string) => {\n * switch (locale) {\n * case 'en-US':\n * dayjs.locale('en');\n * return enUS;\n * case 'zh-CN':\n * dayjs.locale('zh');\n * return zhCN;\n * default:\n * return undefined;\n * }\n * }\n */\n loadLocale?: (locale: string) => any;\n}\n\ninterface I18nResult extends Required<I18nOptions> {}\n\n/** 插件名称 */\nconst pluginName = 'i18n';\n\n/**\n * 国际化插件\n * - 详情参考 {@link I18nOptions} {@link I18nResult}\n * - 集成 React Intl Universal 和 Antd 国际化\n * - 需要从外部引入语言包, 详见 intlConfig 和 loadLocale 配置项\n */\nconst SdkI18nPlugin: Plugin<'i18n'> = {\n name: pluginName,\n install(sdk, options = {}) {\n // 默认插件配置\n const defaultOptions = {\n intl: intl,\n intlConfig: {},\n loadLocale: (locale: string) => undefined,\n } satisfies I18nResult;\n\n sdk[pluginName] = merge(defaultOptions, options);\n },\n};\n\nexport { I18nOptions, I18nResult, SdkI18nPlugin };\n","import { LocaleProps, Plugin, ThemeProps } from '@/types';\nimport { merge } from 'es-toolkit';\n\ninterface StorageOptions {\n /** 国际化存储名称 */\n localeKey?: string;\n /** 主题存储名称 */\n themeKey?: string;\n /** Token存储名称 */\n tokenKey?: string;\n}\n\ninterface StorageResult extends Required<StorageOptions> {\n /** 获取当前国际化 */\n readonly getLocale: () => LocaleProps;\n /** 设置/切换切换国际化 */\n readonly setLocale: (locale: LocaleProps) => void;\n /** 清除国际化 */\n readonly clearLocale: () => void;\n\n /** 获取当前主题 */\n readonly getTheme: () => ThemeProps;\n /** 设置/切换主题 */\n readonly setTheme: (theme: ThemeProps) => void;\n /** 清除主题 */\n readonly clearTheme: () => void;\n\n /** 获取当前 Token */\n readonly getToken: () => string | null;\n /** 设置 Token */\n readonly setToken: (token: string) => void;\n /** 清除 Token */\n readonly clearToken: () => void;\n}\n\n/** 插件名称 */\nconst pluginName = 'storage';\n\n/**\n * 本地缓存插件\n * - 详情参考 {@link StorageOptions} {@link StorageResult}\n * - 配置 localStorage 变量名称\n * - 提供 国际化、主题、Token 的 get、change、clear 方法\n * @example sdk.storage.getToken() // 获取 Token\n * @example sdk.storage.changeTheme('dark') // 切换主题\n * @example sdk.storage.clearLocale() // 清除国际化\n */\nconst SdkStoragePlugin: Plugin<'storage'> = {\n name: pluginName,\n install(sdk, options = {}) {\n // 默认插件配置\n const defaultOptions = {\n localeKey: 'locale',\n themeKey: 'theme',\n tokenKey: 'token',\n\n getLocale() {\n return localStorage.getItem(sdk.storage.localeKey) || 'zh-CN';\n },\n setLocale(locale: string) {\n localStorage.setItem(sdk.storage.localeKey, locale);\n },\n clearLocale() {\n localStorage.removeItem(sdk.storage.localeKey);\n },\n getTheme() {\n return localStorage.getItem(sdk.storage.themeKey) || 'light';\n },\n setTheme(theme: string) {\n localStorage.setItem(sdk.storage.themeKey, theme);\n },\n clearTheme() {\n localStorage.removeItem(sdk.storage.themeKey);\n },\n getToken() {\n return localStorage.getItem(sdk.storage.tokenKey) || null;\n },\n setToken(token: string) {\n localStorage.setItem(sdk.storage.tokenKey, token);\n },\n clearToken() {\n localStorage.removeItem(sdk.storage.tokenKey);\n },\n } satisfies StorageResult;\n\n sdk[pluginName] = merge(defaultOptions, options);\n },\n};\n\nexport { SdkStoragePlugin, StorageOptions, StorageResult };\n","import { StateCreator } from 'zustand';\n\ninterface AppStateStoreProps {\n /** 子应用加载状态 */\n microAppState: boolean;\n /** 设置子应用加载状态 */\n setMicroAppState: (state: boolean) => void;\n}\n\n/** 子应用状态切片 */\nconst createAppStateSlice: StateCreator<AppStateStoreProps> = (set, get) => ({\n microAppState: false,\n setMicroAppState: (microAppState) => set(() => ({ microAppState })),\n});\n\nexport { AppStateStoreProps, createAppStateSlice };\n","import { sdk } from '@/core';\nimport { UserInfo } from '@/types';\nimport { StateCreator } from 'zustand';\n\ninterface InitStateStoreProps {\n /** 初始变量 */\n initState: UserInfo;\n /** 设置初始变量 */\n setInitState: (initState: UserInfo) => void;\n}\n\n/** 初始变量切片 */\nconst createInitStateSlice: StateCreator<InitStateStoreProps> = (set, get) => ({\n initState: {},\n setInitState: (initState) => {\n set(() => ({ initState }));\n sdk.app = { ...sdk.app, ...initState };\n },\n});\n\nexport { createInitStateSlice, InitStateStoreProps };\n","import { sdk } from '@/core';\nimport { LocaleProps } from '@/types';\nimport intl from 'react-intl-universal';\nimport { StateCreator } from 'zustand';\n\ninterface LocaleStoreProps {\n /** 国际化 */\n locale: LocaleProps;\n /** 设置国际化 */\n setLocale: (locale: LocaleProps) => void;\n}\n\n/** 国际化状态切片 */\nconst createLocaleSlice: StateCreator<LocaleStoreProps> = (set, get) => ({\n locale: null,\n\n setLocale: (locale) => {\n set(() => ({ locale })); // 自动合并其他\n\n // 记录值\n sdk.config.locale = locale;\n sdk.storage.setLocale(locale);\n\n // 设置作用域\n document.documentElement.setAttribute('lang', locale);\n\n // 设置 React Intl Universal 语言包\n const intlConfig = sdk.i18n.intlConfig;\n intl.init({ currentLocale: locale, locales: intlConfig });\n\n // 加载 Antd 语言包\n try {\n const localeData = sdk.i18n.loadLocale?.(locale) || undefined;\n sdk.config.antdConfig.locale = localeData;\n } catch (e) {\n console.error('Load antd locale error:', e);\n }\n },\n});\n\nexport { createLocaleSlice, LocaleStoreProps };\n","import { sdk } from '@/core';\nimport { ThemeProps } from '@/types';\nimport { theme as antdTheme } from 'antd';\nimport { StateCreator } from 'zustand';\n\nconst { defaultAlgorithm, darkAlgorithm } = antdTheme;\n\ninterface ThemeStoreProps {\n /** 主题 */\n theme: ThemeProps;\n /** 设置主题 */\n setTheme: (theme: ThemeProps) => void;\n}\n\n/** 主题状态切片 */\nconst createThemeSlice: StateCreator<ThemeStoreProps> = (set, get) => ({\n theme: null,\n\n setTheme: (theme) => {\n set(() => ({ theme })); // 自动合并其他\n\n // 记录值\n sdk.config.theme = theme;\n sdk.storage.setTheme(theme);\n\n // 设置作用域\n document.documentElement.setAttribute('data-theme', theme);\n\n // 设置Antd主题算法\n const algorithm = theme === 'light' ? defaultAlgorithm : darkAlgorithm;\n sdk.config.antdConfig.theme.algorithm = algorithm;\n },\n});\n\nexport { createThemeSlice, ThemeStoreProps };\n","import { Plugin } from '@/types';\nimport { createStore } from 'zustand';\nimport { subscribeWithSelector } from 'zustand/middleware';\nimport { AppStateStoreProps, createAppStateSlice } from './createAppState';\nimport { createInitStateSlice, InitStateStoreProps } from './createInitState';\nimport { createLocaleSlice, LocaleStoreProps } from './createLocale';\nimport { createThemeSlice, ThemeStoreProps } from './createTheme';\n\ntype StoreOptions = AppStateStoreProps & InitStateStoreProps & LocaleStoreProps & ThemeStoreProps;\n\ntype StoreResult = typeof globalStore;\n\n/**\n * 创建 Store 切片\n * - 这里单独声明变量, 主要是为了使用返回类型 StoreResult 🤔\n */\nconst globalStore = createStore<StoreOptions>()(\n subscribeWithSelector((...a) => ({\n ...createAppStateSlice(...a),\n ...createInitStateSlice(...a),\n ...createLocaleSlice(...a),\n ...createThemeSlice(...a),\n })),\n);\n\n/** 插件名称 */\nconst pluginName = 'store';\n\n/**\n * 全局状态管理插件\n * - 详情参考 {@link StoreOptions} {@link StoreResult}\n * - 此插件不会合并传入属性\n * @example const setTheme = useStore(sdk.store, (state) => state.setTheme)\n * @example const { theme, setTheme } = useStore(sdk.store, useShallow((state) => { theme: state.theme, setTheme: state.setTheme }))\n * @example const [theme, setTheme] = useStore(sdk.store, useShallow((state) => [state.theme, state.setTheme]))\n * @example sdk.store?.getState()?.setTheme('light')\n * @example sdk.store.subscribe((state) => state.theme, (theme) => { console.log('theme', theme) }, { fireImmediately: true }) // fireImmediately 立即变更\n */\nconst SdkStorePlugin: Plugin<'store'> = {\n name: pluginName,\n install(sdk, options = {}) {\n sdk[pluginName] = globalStore satisfies StoreResult;\n },\n};\n\nexport { SdkStorePlugin, StoreOptions, StoreResult };\n","import { sdk } from '@/core';\nimport { ProLayout } from '@ant-design/pro-layout';\nimport { memo, Suspense, useEffect, useState } from 'react';\nimport { Outlet, useLocation, useMatches, useNavigate } from 'react-router-dom';\nimport { useStore } from 'zustand';\n\n/** 布局组件 */\nconst BaseLayout: React.FC = () => {\n const navigate = useNavigate();\n const location = useLocation();\n const matches = useMatches();\n\n const locale = useStore(sdk.store, (state) => state.locale);\n\n const [isAuth, setIsAuth] = useState(false);\n\n /** 菜单点击事件 */\n const handleMenuClick = (item: any) => {\n navigate(item.path);\n };\n\n /** 菜单头点击事件 */\n const handleMenuHeaderClick = () => {\n navigate('/');\n };\n\n /** 页面切换事件 */\n const handlePageChange = (location) => {\n sdk.client.location = location;\n\n const pathName = location.pathname;\n\n // 是否有用户信息\n if (!sdk.app.user || Object.keys(sdk.app.user).length === 0) return sdk.app.pageToLogin();\n\n // 是否有权限\n setIsAuth(sdk.app.permissions.includes(pathName));\n };\n\n useEffect(() => {\n sdk.client.navigate = navigate;\n }, []);\n\n useEffect(() => {\n sdk.client.matches = matches;\n }, [matches]);\n\n return (\n <ProLayout\n locale={locale as any}\n formatMessage={({ id, defaultMessage }) => sdk.i18n.intl.get(id).d(defaultMessage)}\n location={location}\n menuItemRender={(item, dom) => <div onClick={() => handleMenuClick(item)}>{dom}</div>}\n onMenuHeaderClick={handleMenuHeaderClick}\n onPageChange={handlePageChange}\n {...sdk.config.proLayoutConfig}\n menu={{\n request: async () => sdk.app.menuData || [],\n ...sdk.config.proLayoutConfig.menu,\n }}\n >\n <Suspense fallback={<>Loading...</>}>{isAuth ? <Outlet /> : <>无权限</>}</Suspense>\n </ProLayout>\n );\n};\n\nexport default memo(BaseLayout);\n","import { sdk } from '@/core';\nimport { Button, Flex, Form, FormProps, Input } from 'antd';\nimport { useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\n\n/** 默认登录页 */\nconst Login: React.FC = () => {\n const navigate = useNavigate();\n\n const [loading, setLoading] = useState(false);\n\n /** 表单提交成功事件 */\n const handleFinish: FormProps['onFinish'] = async (values) => {\n setLoading(() => true);\n const resp = await sdk.api.request('/login', {\n method: 'POST',\n data: values,\n });\n setLoading(() => false);\n const token = resp?.data?.token || '';\n if (!token) return;\n\n sdk.storage.setToken(token);\n const defaultPath = sdk.app.getRedirectPath();\n navigate(defaultPath, { replace: true }); // 这里可以用 navigation, 不用刷新页面, 因为下方调用了初始化接口\n };\n\n return (\n <Flex\n style={{ width: '100%', height: '100%', background: 'var(--bg-color)' }}\n justify={'center'}\n align={'center'}\n >\n <Form\n labelCol={{ span: 8 }}\n wrapperCol={{ span: 16 }}\n style={{ maxWidth: 600 }}\n initialValues={{ remember: true }}\n onFinish={handleFinish}\n autoComplete=\"off\"\n >\n <Form.Item\n label=\"用户名\"\n name=\"username\"\n rules={[{ required: true, message: '请输入用户名!' }]}\n >\n <Input />\n </Form.Item>\n\n <Form.Item\n label=\"密码\"\n name=\"password\"\n rules={[{ required: true, message: '请输入密码!' }]}\n >\n <Input.Password />\n </Form.Item>\n\n <Form.Item label={null}>\n <Button block type=\"primary\" htmlType=\"submit\" loading={loading}>\n 登录\n </Button>\n </Form.Item>\n </Form>\n </Flex>\n );\n};\n\nexport default Login;\n","import { sdk } from '@/core';\nimport { lifeCyclesUtil } from '@/utils';\nimport { loadMicroApp } from 'qiankun';\nimport React, { memo, useEffect } from 'react';\nimport { useStore } from 'zustand';\n\ninterface Props {\n name: string;\n rootId: string;\n}\n\n/** 子应用挂载节点 */\nconst Microapp: React.FC<Props> = ({ name, rootId }) => {\n const microAppState = useStore(sdk.store, (state) => state.microAppState);\n\n useEffect(() => {\n if (!name || sdk.config.qiankunMode !== 'load') return;\n\n const instance = sdk.app.microAppsInstance.get(name);\n if (instance) {\n instance.mount();\n } else {\n const microApp = sdk.app.microApps.find((item) => item.name === name);\n if (!microApp) return;\n const newInstance = loadMicroApp(microApp, {}, lifeCyclesUtil);\n sdk.app.microAppsInstance.set(name, newInstance);\n }\n\n console.log('Microapp', name);\n\n return () => {\n const ins = sdk.app.microAppsInstance.get(name);\n if (ins) ins.unmount();\n };\n }, [name]);\n\n return (\n <>\n {microAppState && <div>Loading...</div>}\n <main id={rootId}></main>\n </>\n );\n};\n\nexport default memo(Microapp);\n","import { sdk } from '@/core';\nimport { Empty, Flex } from 'antd';\nimport { useNavigate } from 'react-router-dom';\n\n/**\n * 404页面\n * - 需要注册 navigate 实例,用于跳转页面\n */\nconst NotFound: React.FC = () => {\n const navigate = useNavigate();\n sdk.client.navigate = navigate;\n\n return (\n <Flex\n style={{ width: '100%', height: '100%', background: 'var(--bg-color)' }}\n justify={'center'}\n align={'center'}\n >\n <Empty description={'找不到页面'} />\n </Flex>\n );\n};\n\nexport default NotFound;\n","import { Plugin } from '@/types';\nimport { ComponentType, createElement, ReactElement } from 'react';\n\nimport { merge } from 'es-toolkit';\nimport Layout from './layout';\nimport Login from './login';\nimport Microapp from './microapp';\nimport NotFound from './notFound';\n\ninterface UIOptions {\n /** 组件 */\n [key: string]: ComponentType | ((name: string) => ComponentType);\n}\n\ninterface UIResult extends Required<UIOptions> {\n /**\n * 获取组件\n * @param name 组件名称\n */\n readonly getComponent: (name: string) => ComponentType;\n /**\n * 渲染组件\n * @param name 组件名称\n */\n readonly renderComponent: (name: string, props?: any) => ReactElement;\n}\n\n/** 插件名称 */\nconst pluginName = 'ui';\n\n/**\n * 组件插件\n * - 详情参考 {@link UIOptions} {@link UIResult}\n * - 内置了 Login、NotFound、Microapp、Layout 等组件, 可传入覆盖\n * - 组件共享\n * - 在主应用中, 可通过 use(SdkUIPlugin, { MyComponent }) 传入组件\n * - 在子应用中, 可通过 sdk.ui.renderComponent('MyComponent') 使用组件\n */\nconst SdkUIPlugin: Plugin<'ui'> = {\n name: pluginName,\n install(sdk, options = {}) {\n // 默认插件配置\n const defaultOptions = {\n Login,\n NotFound,\n Layout, // 不要使用懒加载 - 防止多次渲染\n Microapp, // 不要使用懒加载 - 防止qiankun挂载不上\n\n getComponent: (name) => {\n if (!name) throw new Error('Component name cannot be empty');\n return sdk.ui[name] as ComponentType;\n },\n renderComponent: (name, props = {}) => {\n const Component = sdk.ui.getComponent(name);\n if (!Component) throw new Error(`Component ${name} not found`);\n return createElement(Component, props);\n },\n } satisfies UIResult;\n\n sdk[pluginName] = merge(defaultOptions, options);\n },\n};\n\nexport { SdkUIPlugin, UIOptions, UIResult };\n"],"x_google_ignoreList":[1,2,3,4,5,6,7,8,9,10,17],"mappings":"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"}